From 31148f7f7b8c0b788548256b030e0d82044a009c Mon Sep 17 00:00:00 2001 From: "Tristan Poland (Trident_For_U)" <34868944+tristanpoland@users.noreply.github.com> Date: Tue, 15 Oct 2024 23:34:35 -0400 Subject: [PATCH] Update README.md --- README.md | 249 +++++++++++++----------------------------------------- 1 file changed, 59 insertions(+), 190 deletions(-) diff --git a/README.md b/README.md index 17e9cc2..4fa4f8e 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,11 @@ # RecipeSmith -RecipeSmith is a rs-based module designed by: Asterisk for use with games that utilize the stars beyond horizon Server Backend as a framework for managing recipes, ingredients, and their interactions within a recipe book. This system integrates with PebbleVault for data storage and retrieval while being capable of communication with other submodules, ensuring modularity and independence. The goal is to enable dynamic recipe management, including creating, storing, retrieving, and crafting recipes based on available ingredients. +RecipeSmith is a Rust-based plugin designed for use with games that utilize the Stars Beyond Horizon Server Backend. It provides a framework for managing recipes, ingredients, and their interactions within a recipe book. This system is designed to be modular and independent, capable of communicating with other plugins through custom events. The goal is to enable dynamic recipe management, including creating, storing, retrieving, and crafting recipes based on available ingredients. ## Features - **Dynamic Recipe Management:** Create, store, retrieve, and craft recipes based on available ingredients. -- **Integration with PebbleVault:** Seamless data storage and retrieval with PebbleVault. -- **Modularity:** Designed to communicate with other submodules independently. +- **Event-Driven Architecture:** Utilizes custom events for communication with other plugins. - **Ingredient Interaction:** Detailed tracking and management of ingredients and their quantities. - **Outcome Prediction:** Automatically determine the outcome of recipes based on input ingredients. - **Loosely Coupled Architecture:** Ensures components can function independently, enhancing flexibility and scalability. @@ -17,37 +16,11 @@ RecipeSmith is a rs-based module designed by: Asterisk for use with games that u ### 1. Dynamic Recipe Management -#### Definition - -Recipes are defined in a JSON file containing the name, ingredients, and outcome of each recipe. Here is an example structure: - -```json -{ - "recipes": [ - { - "name": "Bread", - "ingredients": [ - {"name": "Flour", "quantity": 2}, - {"name": "Water", "quantity": 1}, - {"name": "Salt", "quantity": 1}, - {"name": "Yeast", "quantity": 1} - ], - "outcome": "Bread", - "crafters": ["Oven", "Bakery"], - "recipe_craftable": true, - "base_cook_time": 30, - "cook_count": 0 - } - // Add other recipes - ] -} -``` - #### Recipe Structure The `Recipe` struct represents a recipe with its name, ingredients, outcome, crafters, base cook time, and cook count. -```rs +```rust #[derive(Debug, Clone, Deserialize, Serialize)] pub struct Recipe { pub name: String, @@ -61,50 +34,31 @@ pub struct Recipe { #### Adding Recipes -Recipes can be added to the `RecipeBook` using the `add_recipe` method. +Recipes can be added to the `RecipeBook` using the `add_new_recipe` method. -```rs -pub fn add_recipe(&mut self, recipe: Recipe) { - for crafter in &recipe.crafters { - self.crafters.entry(crafter.clone()).or_insert_with(Vec::new).push(recipe.name.clone()); - } - self.recipes.insert(recipe.name.clone(), recipe.clone()); - let serialized_recipe = serde_json::to_string(&recipe).unwrap(); - self.vault.collect("recipe", &recipe.name, &serialized_recipe); +```rust +pub async fn add_new_recipe(&self, recipe: Recipe) { + let mut recipe_book = self.recipe_book.write().await; + recipe_book.add_recipe(recipe); } ``` -### 2. Integration with PebbleVault - -#### Seamless Data Storage and Retrieval - -Recipes and ingredients are securely stored and easily accessible through integration with PebbleVault. This ensures efficient operation within a larger ecosystem, enabling modular and independent submodule communication. - -```rs -let vault = Vault::new(); -vault.define_class("recipe", r#"{ - "name": "string", - "ingredients": "array", - "outcome": "string", - "base_cook_time": "u32", - "cook_count": "u32", - "crafters": "array" -}"#); -``` - -### 3. Modularity - -#### Independent Communication +### 2. Event-Driven Architecture -RecipeSmith is designed to communicate with other submodules independently, allowing for flexible and scalable integration into various projects. +RecipeSmith uses custom events for communication. Here are some of the key events: -### 4. Ingredient Interaction +- `craft_item`: Attempts to craft an item for a player. +- `add_recipe`: Adds a new recipe to the recipe book. +- `get_player_inventory`: Retrieves a player's inventory contents. +- `add_item_to_inventory`: Adds an item to a player's inventory. +- `remove_item_from_inventory`: Removes an item from a player's inventory. +- `create_storage_container`: Creates a new storage container. -#### Detailed Tracking and Management +### 3. Ingredient Interaction The `Ingredient` struct represents an ingredient with its name, quantity, and whether it can be crafted from a recipe. -```rs +```rust #[derive(Debug, Clone, Deserialize, Serialize)] pub struct Ingredient { pub name: String, @@ -113,162 +67,77 @@ pub struct Ingredient { } ``` -### 5. Outcome Prediction - -#### Automatically Determine Recipe Outcomes +### 4. Outcome Prediction When crafting a recipe, the outcome is determined based on the input ingredients. -```rs -pub fn craft(&mut self, recipe_name: &str, inventory: &mut HashMap) -> Option { - if self.can_craft(recipe_name, inventory) { - let recipe = self.get_recipe(recipe_name).unwrap().clone(); - for ingredient in &recipe.ingredients { - if let Some(inventory_ingredient) = inventory.get_mut(&ingredient.name) { - if inventory_ingredient.recipe_craftable { - inventory_ingredient.quantity -= ingredient.quantity; - } - } - } - Some(recipe.outcome.clone()) - } else { - None - } +```rust +pub async fn craft_item(&self, player_id: &str, recipe_name: &str, context: &mut PluginContext) -> Option { + // Implementation details... } ``` -### 6. Loosely Coupled Architecture - -#### Flexibility and Scalability - -Components can function independently, which enhances the flexibility and scalability of the system. - -### 7. Full Error Logging Functionality - -#### Comprehensive Error Logging - -Error logging captures and logs errors to facilitate debugging and maintain system integrity. This feature ensures that any issues can be quickly identified and resolved. - -```rs -// Initialize logger -env_logger::init(); - -// Setup error log file -let log_dir = "errorlogs"; -let log_file_path = format!("{}/lastlog.txt", log_dir); - -// Ensure log directory exists -fs::create_dir_all(log_dir).unwrap(); - -// Open log file -let log_file = OpenOptions::new() - .create(true) - .write(true) - .truncate(true) - .open(&log_file_path) - .unwrap(); -``` - -### 8. Extendable and Customizable - -#### Adding New Features - -RecipeSmith is easily extendable to add new features or customize existing ones to fit specific needs. This flexibility makes it suitable for a wide range of applications. - ## Example Usage ### Initialization -1. **Clone the Repository:** - ```sh - git clone https://github.com/Stars-Beyond/RecipeSmith.git - ``` - -2. **Navigate to the Project Directory:** - ```sh - cd RecipeSmith - ``` - -3. **Build the Project:** - ```sh - cargo build - ``` - -4. **Run the Project:** - ```sh - cargo run - ``` +The RecipeSmith plugin is initialized as part of the plugin system. It automatically registers for custom events and loads recipes from files. ### Recipe Management #### Adding a Recipe -```rs -let mut recipe_book = RecipeBook::new(); -recipe_book.add_recipe(Recipe { +To add a new recipe, emit a custom event: + +```rust +let new_recipe = Recipe { name: "Bread".to_string(), ingredients: vec![ - Ingredient { - name: "Flour".to_string(), - quantity: 2, - recipe_craftable: true, - }, - Ingredient { - name: "Water".to_string(), - quantity: 1, - recipe_craftable: true, - }, + Ingredient { name: "Flour".to_string(), quantity: 2, recipe_craftable: true }, + Ingredient { name: "Water".to_string(), quantity: 1, recipe_craftable: true }, ], outcome: "Bread".to_string(), crafters: vec![Crafter { name: "Oven".to_string() }], base_cook_time: 30, cook_count: 0, -}); +}; + +context.dispatch_custom_event(CustomEvent { + event_type: "add_recipe".to_string(), + data: Arc::new(new_recipe), +}).await; ``` #### Crafting a Recipe -```rs -let mut inventory = HashMap::new(); -inventory.insert("Flour".to_string(), Ingredient { - name: "Flour".to_string(), - quantity: 2, - recipe_craftable: true, -}); -inventory.insert("Water".to_string(), Ingredient { - name: "Water".to_string(), - quantity: 1, - recipe_craftable: true, -}); - -if recipe_book.can_craft("Bread", &inventory) { - if let Some(outcome) = recipe_book.craft("Bread", &mut inventory) { - println!("Crafted: {}", outcome); - } else { - println!("Failed to craft Bread."); - } -} else { - println!("Not enough ingredients to craft Bread."); -} +To craft a recipe, emit a custom event: + +```rust +context.dispatch_custom_event(CustomEvent { + event_type: "craft_item".to_string(), + data: Arc::new(("player1".to_string(), "Bread".to_string())), +}).await; ``` -## SkillScript Integration +### Inventory Management + +#### Adding an Item to Inventory -### Experience Gain and Reducing Cooking Time +```rust +let new_item = Item { /* ... */ }; +context.dispatch_custom_event(CustomEvent { + event_type: "add_item_to_inventory".to_string(), + data: Arc::new(("player1".to_string(), new_item)), +}).await; +``` -SkillScript can be integrated to give players experience over time, reduce cooking time, or gain rewards. This can be done by collecting experience points and updating the crafting system. +#### Removing an Item from Inventory -```rs -if recipe_book.can_craft("Bread", &inventory) { - if let Some(outcome) = recipe_book.craft("Bread", &mut inventory) { - recipe_book.vault.collect("skill_experience", "crafting", r#"{"experience": 10}"#); - println!("Crafted: {}", outcome); - } else { - println!("Failed to craft Bread."); - } -} else { - println!("Not enough ingredients to craft Bread."); -} +```rust +context.dispatch_custom_event(CustomEvent { + event_type: "remove_item_from_inventory".to_string(), + data: Arc::new(("player1".to_string(), "Bread".to_string())), +}).await; ``` ## Contributing @@ -277,4 +146,4 @@ Contributions are welcome! Please feel free to submit a Pull Request. ## License -This project is licensed under the Apache 2.0 License - see the [LICENSE](LICENSE) file for details. \ No newline at end of file +This project is licensed under the Apache 2.0 License - see the [LICENSE](LICENSE) file for details.