diff options
346 files changed, 5232 insertions, 4623 deletions
@@ -26,7 +26,7 @@ internal/ net/ Conn interface (tcpConn, wsConn), Hub, Session, session states, IAC echo game/ Game struct, HandleSession state machine, command registry, all game logic hacking/ Minigame interface + 3 implementations (Wumpus, Mastermind, Liar's Dice) - action/ Behavior structs (GatherConfig, TalkConfig, UseConfig), RecipeStore, SuccessChance + action/ Behavior structs (GatherConfig, TalkConfig, UseConfig), SuccessChance player/ Player struct, skills, inventory, bank, equipment, accounts, XP, validation world/ World, RoomDef, MobDef, MobInstance, ObjState, ground items, wandering combat/ Combat state tracking, OSRS-style formulas (HitChance, MaxHit, AttackRoll) @@ -52,7 +52,7 @@ internal/ ## Key Conventions -**YAML-driven.** Rooms, items, objects, mobs, drops, recipes, modules, courses are YAML files under `data/`. Read from disk on every access — edit and it takes effect immediately, no restart. Recipes are walked from disk on first access then cached in-memory with an `O(1)` ID index (see GetByID below). Items, rooms, and recipes are organized into subdirectories by category (items: `equipment/`, `tools/`, etc.; rooms: `town/`, `wilderness/`, etc.; recipes: `smithing/`, `crafting/`, etc.). All IDs remain globally unique across subdirectories via path-indexed loading. +**YAML-driven.** Rooms, items, objects, mobs, drops, modules, courses are YAML files under `data/`. Read from disk on every access — edit and it takes effect immediately, no restart. Crafting information lives in `craft:` blocks on item YAML files — no separate recipe directory. Items are organized into subdirectories by category (items: `equipment/`, `tools/`, etc.; rooms: `town/`, `wilderness/`, etc.). All IDs remain globally unique across subdirectories via path-indexed loading. **Live state.** Player data (characters, accounts) is written to YAML on every state change. Ground items, mob instances, and object states live in memory only and are lost on restart. @@ -86,12 +86,11 @@ The pattern is: lock, snapshot/unmarshal, unlock, then process. The engine creat ``` data/rooms/<id>.yaml Room definitions (exits, objects, mobs, item_spawns, on_enter) data/rooms/player_housing/ Player house rooms -data/items/<id>.yaml Item definitions (stats, equip_slot, tool_type, burn_ticks, search_table, etc.) +data/items/<id>.yaml Item definitions (stats, equip_slot, tool_type, craft, burn_ticks, search_table, etc.) data/mobs/<id>.yaml Mob definitions (combat stats, drops, behavior, steal config) data/objects/<id>.yaml Object definitions (name, behavior, hidden, inroom_description, removal_item) data/drops/<id>.yaml Shared drop tables (weighted item lists, sub-table references) data/help/<id>.yaml Help topics -data/recipes/<id>.yaml Recipe definitions — individual or consolidated format (see worldbuilding_guide/recipes.md) data/modules/<id>.yaml Science module definitions (id, level, max_hit, base_xp, junk_cost, category) data/courses/<id>.yaml Agility course definitions (name, required_level, start_room, obstacles) data/players/accounts/ Account YAML (gitignored) @@ -106,7 +105,7 @@ See `worldbuilding_guide/` for full YAML format reference with examples. At startup, the server runs comprehensive integrity checks on all data files. Errors cause the server to exit; warnings are informational. -**Duplicate ID checks** across all data directories (items, rooms, mobs, objects, drops, recipes, courses, modules, help). Detects collision from two files with the same ID in different subdirectories. +**Duplicate ID checks** across all data directories (items, rooms, mobs, objects, drops, courses, modules, help). Detects collision from two files with the same ID in different subdirectories. **Referential integrity checks:** - Room exits → target rooms exist @@ -115,8 +114,8 @@ At startup, the server runs comprehensive integrity checks on all data files. Er - Object removal items, steal tables, guard mobs, use_interaction items → exist - Object gather config drops → items/tables exist; bait items exist - Object talk config node actions (give_item, take_item, teleport, shop items) → exist -- Item search tables, made_from items/byproducts, farm_product → exist -- Recipe consume items, output, fail product → exist +- Item search tables, farm_product → exist +- Item craft blocks → consume items, fail products, station objects, tools → exist - Drop table sub-references → exist - Course start_room and obstacle rooms → exist @@ -481,8 +480,7 @@ Prompt variables: `%h` (HP), `%H` (max HP), `%b` (battery), `%B` (max battery), | `search_table` / `search_misc_table` | Drop tables for searching this item | | `search_ticks` | Ticks per search action | | `search_message` | Custom search message | -| `made_from` | MadeFrom entries for item-on-item combinations (with byproducts) | -| `ticks` | Ticks per production cycle for MadeFrom combines (default 2) | +| `craft` | Craft block — type, skill, level, XP, station, tool, consume, output_qty, fail, message, success, steps | | `farming` | Farming-related fields (seed type, patch, yield, level, xp) | | `potion` | Potion properties (buff levels for attack/strength/defense/agility) | @@ -516,47 +514,28 @@ Prompt variables: `%h` (HP), `%H` (max HP), `%b` (battery), `%B` (max battery), Production skills share a unified system in `core_production.go`: -1. Create recipe YAMLs in `data/recipes/<type>/` — either individual (one per product) or consolidated (one per material group, with shared fields at top level and a `products:` list). See `worldbuilding_guide/recipes.md`. +1. Create the output item YAML in `data/items/` with a `craft:` block. See `worldbuilding_guide/recipes.md`. 2. Create a station object in `data/objects/` if needed 3. Add a `cmd_<skill>.go` command handler following existing patterns 4. Add the command to `commandRegistry` in `cmd_registry.go` with the appropriate class 5. Wire up the `auto_start` option if desired -The unified production cycle handles: HowMany prompt, start message, timed loops, success/fail rolls, XP, output quantity, stackable stacking, byproducts, and end message. Tool requirements are checked in the command handler before calling `promptHowMany`. +The unified production cycle handles: HowMany prompt, start message, timed loops, success/fail rolls, XP, output quantity, stackable stacking, byproducts, multi-step messages, and end message. Tool requirements are checked in the command handler before calling `promptHowMany`. -## Recipe Loading and Lookup +## CraftIndex -Recipes have two YAML formats — **individual** (one file per recipe) and **consolidated** (shared `type`/`station`/`wait`/`consume` at top level, products listed under `products:`). The loader expands consolidated files into individual `RecipeDef` structs transparently. The production engine (`core_production.go`) sees only `RecipeDef` — no code changes needed for format. +`CraftIndex` (`internal/game/craft_index.go`) is built once at startup from all item YAMLs that have a `craft:` block. It provides `O(1)` lookups: -**RecipeStore** (`internal/action/recipe.go`) manages recipe access: - -### GetByID — Step by Step - -`GetByID(recipeID)` is an `O(1)` direct recipe lookup. Here's the full chain: - -1. **First call anywhere in the game** — a command like `cook`, `smith`, or the tick advancing an active production action calls `GetByID("smith_bronze_dagger")`. - -2. **Index check.** `GetByID` checks the `byID` map (`map[string]*RecipeDef`). On first call, it's empty, so the method calls `ensureLoaded()`. - -3. **`ensureLoaded()`** checks if the full recipe slice is already cached under key `"_all"` in `s.cache`. If not (cold cache), it calls `loadAllRaw()`. - -4. **`loadAllRaw()`** walks `data/recipes/` recursively. For each YAML file: - - First attempts to unmarshal as a plain `RecipeDef` (individual format). If `type` is non-empty, the recipe is appended. - - If that fails, attempts to unmarshal as `consolidatedRecipeDef`. If `type` is set and `products` is non-empty, it expands each product entry via `expandProduct()` into a full `RecipeDef` (inheriting top-level `type`, `station`, `wait`, `consume`; overriding with product-level fields where specified). - - **YAML parse errors are logged to stderr** — no more silent failures. - -5. **Index building.** `ensureLoaded()` caches the full recipe slice as `s.cache["_all"]` (permanent backing store), then populates `s.byID` with pointers into that slice: `byID["smith_bronze_dagger"] = &all[i]`. The cached slice keeps the backing array alive, so byID pointers never dangle. - -6. **GetByID returns.** The `*RecipeDef` pointer is returned and used by the caller (e.g., `loadProductionRecipe()` or `menuEntryName()`). - -7. **All subsequent calls** to `GetByID`, `LoadAll()`, or `LoadByType()` hit the in-memory cache — no filesystem walk. `LoadByType("smithing")` filters the cached `"_all"` slice and caches the filtered result. +- **`ByType("pharmacy")`** — all pharmacy-craftable items (used by `mix` command) +- **`ByStation("anvil")`** — all items craftable at that station +- **`ByInput("guam")`** — all items that consume that ingredient +- **`FindByTwoInputs(a, b)`** — items consuming both inputs in different consume entries (used by `use` command) **Key properties:** -- `GetByID` — `O(1)` map lookup, zero allocations -- `LoadByType` — `O(n)` filter pass on first call per type, `O(1)` copy on cache hits -- `LoadAll` — same as `LoadByType("")`, returns copy of `"_all"` cache -- All public methods return copies — callers can't mutate cached data -- No cache invalidation — recipes are static after startup. Server restart picks up changes. +- Built once at startup — `O(n)` one-pass scan over all items +- All indexes are `O(1)` lookups with zero allocations +- The CraftIndex stores `*ItemDef` pointers — no RecipeDef copies +- No cache invalidation — craft data is static after startup ## Adding a New Command diff --git a/data/items/ammo/adamant_arrow.yaml b/data/items/ammo/adamant_arrow.yaml index bbcdcab..cbed73f 100644 --- a/data/items/ammo/adamant_arrow.yaml +++ b/data/items/ammo/adamant_arrow.yaml @@ -1,9 +1,23 @@ +color: "120" +craft: + consume: + - items: + - headless_arrow + quantity: 15 + - items: + - adamant_arrowtips + quantity: 15 + level: 60 + output_qty: 15 + skill: fletching + type: fletching + wait: 2 + xp: 10 +description: An adamant-tipped arrow. +equip_slot: ammo id: adamant_arrow name: adamant arrow -color: "120" -description: "An adamant-tipped arrow." -value: 20 stackable: true -equip_slot: ammo stats: - ranged_strength: 31 + ranged_strength: 31 +value: 20 diff --git a/data/items/ammo/adamant_arrowtips.yaml b/data/items/ammo/adamant_arrowtips.yaml index 49ddb57..989a954 100644 --- a/data/items/ammo/adamant_arrowtips.yaml +++ b/data/items/ammo/adamant_arrowtips.yaml @@ -1,6 +1,19 @@ +color: "120" +craft: + consume: + - items: + - adamantite_bar + quantity: 1 + level: 75 + output_qty: 15 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 62 +description: A set of adamant arrowtips. id: adamant_arrowtips name: adamant arrowtips -color: "120" -description: "A set of adamant arrowtips." -value: 16 stackable: true +value: 16 diff --git a/data/items/ammo/adamant_bolts.yaml b/data/items/ammo/adamant_bolts.yaml index 47d088f..d1404d1 100644 --- a/data/items/ammo/adamant_bolts.yaml +++ b/data/items/ammo/adamant_bolts.yaml @@ -1,9 +1,23 @@ +color: "120" +craft: + consume: + - items: + - adamant_bolts_unf + quantity: 10 + - items: + - feather + quantity: 10 + level: 61 + output_qty: 10 + skill: fletching + type: fletching + wait: 0 + xp: 70 +description: Adamant crossbow bolts. +equip_slot: ammo id: adamant_bolts name: adamant bolts -color: "120" -description: "Adamant crossbow bolts." -value: 24 stackable: true -equip_slot: ammo stats: - ranged_strength: 43 + ranged_strength: 43 +value: 24 diff --git a/data/items/ammo/adamant_bolts_unf.yaml b/data/items/ammo/adamant_bolts_unf.yaml index db709db..9173679 100644 --- a/data/items/ammo/adamant_bolts_unf.yaml +++ b/data/items/ammo/adamant_bolts_unf.yaml @@ -1,6 +1,19 @@ +color: "120" +craft: + consume: + - items: + - adamantite_bar + quantity: 1 + level: 76 + output_qty: 10 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 62 +description: Unfinished adamant crossbow bolts. id: adamant_bolts_unf name: adamant bolts (unf) -color: "120" -description: "Unfinished adamant crossbow bolts." -value: 20 stackable: true +value: 20 diff --git a/data/items/ammo/arrow_shaft.yaml b/data/items/ammo/arrow_shaft.yaml index 715a3e6..ec2d625 100644 --- a/data/items/ammo/arrow_shaft.yaml +++ b/data/items/ammo/arrow_shaft.yaml @@ -1,6 +1,73 @@ +color: "137" +craft: + - consume: + - items: + - logs + quantity: 1 + level: 1 + output_qty: 15 + skill: fletching + tool: knife + type: fletching + wait: 5 + xp: 5 + - consume: + - items: + - oak_logs + quantity: 1 + level: 15 + output_qty: 20 + skill: fletching + tool: knife + type: fletching + wait: 5 + xp: 10 + - consume: + - items: + - willow_logs + quantity: 1 + level: 30 + output_qty: 25 + skill: fletching + tool: knife + type: fletching + wait: 5 + xp: 15 + - consume: + - items: + - maple_logs + quantity: 1 + level: 45 + output_qty: 30 + skill: fletching + tool: knife + type: fletching + wait: 5 + xp: 20 + - consume: + - items: + - yew_logs + quantity: 1 + level: 60 + output_qty: 35 + skill: fletching + tool: knife + type: fletching + wait: 5 + xp: 25 + - consume: + - items: + - magic_logs + quantity: 1 + level: 75 + output_qty: 40 + skill: fletching + tool: knife + type: fletching + wait: 5 + xp: 30 +description: A wooden arrow shaft. Needs feathers and a head. id: arrow_shaft name: arrow shaft -color: "137" -description: "A wooden arrow shaft. Needs feathers and a head." -value: 1 stackable: true +value: 1 diff --git a/data/items/ammo/bronze_arrow.yaml b/data/items/ammo/bronze_arrow.yaml index eb73a48..bc26583 100644 --- a/data/items/ammo/bronze_arrow.yaml +++ b/data/items/ammo/bronze_arrow.yaml @@ -1,9 +1,23 @@ +color: "178" +craft: + consume: + - items: + - headless_arrow + quantity: 15 + - items: + - bronze_arrowtips + quantity: 15 + level: 1 + output_qty: 15 + skill: fletching + type: fletching + wait: 2 + xp: 1 +description: A bronze-tipped arrow. +equip_slot: ammo id: bronze_arrow name: bronze arrow -color: "178" -description: "A bronze-tipped arrow." -value: 1 stackable: true -equip_slot: ammo stats: - ranged_strength: 7 + ranged_strength: 7 +value: 1 diff --git a/data/items/ammo/bronze_arrowtips.yaml b/data/items/ammo/bronze_arrowtips.yaml index df42e59..2a453ce 100644 --- a/data/items/ammo/bronze_arrowtips.yaml +++ b/data/items/ammo/bronze_arrowtips.yaml @@ -1,6 +1,19 @@ +color: "178" +craft: + consume: + - items: + - bronze_bar + quantity: 1 + level: 5 + output_qty: 15 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 12 +description: A set of bronze arrowtips. id: bronze_arrowtips name: bronze arrowtips -color: "178" -description: "A set of bronze arrowtips." -value: 1 stackable: true +value: 1 diff --git a/data/items/ammo/bronze_bolts.yaml b/data/items/ammo/bronze_bolts.yaml index 0d3afae..7cf0776 100644 --- a/data/items/ammo/bronze_bolts.yaml +++ b/data/items/ammo/bronze_bolts.yaml @@ -1,9 +1,23 @@ +color: "178" +craft: + consume: + - items: + - bronze_bolts_unf + quantity: 10 + - items: + - feather + quantity: 10 + level: 9 + output_qty: 10 + skill: fletching + type: fletching + wait: 0 + xp: 5 +description: Bronze crossbow bolts. +equip_slot: ammo id: bronze_bolts name: bronze bolts -color: "178" -description: "Bronze crossbow bolts." -value: 1 stackable: true -equip_slot: ammo stats: - ranged_strength: 10 + ranged_strength: 10 +value: 1 diff --git a/data/items/ammo/bronze_bolts_unf.yaml b/data/items/ammo/bronze_bolts_unf.yaml index 538d8ab..169b19a 100644 --- a/data/items/ammo/bronze_bolts_unf.yaml +++ b/data/items/ammo/bronze_bolts_unf.yaml @@ -1,6 +1,19 @@ +color: "178" +craft: + consume: + - items: + - bronze_bar + quantity: 1 + level: 6 + output_qty: 10 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 12 +description: Unfinished bronze crossbow bolts. id: bronze_bolts_unf name: bronze bolts (unf) -color: "178" -description: "Unfinished bronze crossbow bolts." -value: 1 stackable: true +value: 1 diff --git a/data/items/ammo/diamond_bolt_tips.yaml b/data/items/ammo/diamond_bolt_tips.yaml index 1529b11..1c925d6 100644 --- a/data/items/ammo/diamond_bolt_tips.yaml +++ b/data/items/ammo/diamond_bolt_tips.yaml @@ -1,6 +1,18 @@ +color: "255" +craft: + consume: + - items: + - uncut_diamond + quantity: 1 + level: 65 + output_qty: 12 + skill: fletching + tool: chisel + type: fletching + wait: 5 + xp: 7 +description: Bolt tips cut from a diamond. id: diamond_bolt_tips name: diamond bolt tips -color: "255" -description: "Bolt tips cut from a diamond." -value: 200 stackable: true +value: 200 diff --git a/data/items/ammo/diamond_bolts.yaml b/data/items/ammo/diamond_bolts.yaml index efe8013..e20349c 100644 --- a/data/items/ammo/diamond_bolts.yaml +++ b/data/items/ammo/diamond_bolts.yaml @@ -1,9 +1,23 @@ +color: "255" +craft: + consume: + - items: + - adamant_bolts + quantity: 10 + - items: + - diamond_bolt_tips + quantity: 10 + level: 65 + output_qty: 10 + skill: fletching + type: fletching + wait: 2 + xp: 7 +description: Bolts tipped with diamond. Can be enchanted via science. +equip_slot: ammo id: diamond_bolts name: diamond bolts -color: "255" -description: "Bolts tipped with diamond. Can be enchanted via science." -value: 130 stackable: true -equip_slot: ammo stats: - ranged_attack: 9 + ranged_attack: 9 +value: 130 diff --git a/data/items/ammo/emerald_bolt_tips.yaml b/data/items/ammo/emerald_bolt_tips.yaml index afd285b..068f3b6 100644 --- a/data/items/ammo/emerald_bolt_tips.yaml +++ b/data/items/ammo/emerald_bolt_tips.yaml @@ -1,6 +1,18 @@ +color: "83" +craft: + consume: + - items: + - uncut_emerald + quantity: 1 + level: 66 + output_qty: 12 + skill: fletching + tool: chisel + type: fletching + wait: 5 + xp: 5 +description: Bolt tips cut from an emerald. id: emerald_bolt_tips name: emerald bolt tips -color: "83" -description: "Bolt tips cut from an emerald." -value: 50 stackable: true +value: 50 diff --git a/data/items/ammo/emerald_bolts.yaml b/data/items/ammo/emerald_bolts.yaml index 1afdcd0..e90a562 100644 --- a/data/items/ammo/emerald_bolts.yaml +++ b/data/items/ammo/emerald_bolts.yaml @@ -1,9 +1,23 @@ +color: "34" +craft: + consume: + - items: + - mithril_bolts + quantity: 10 + - items: + - emerald_bolt_tips + quantity: 10 + level: 66 + output_qty: 10 + skill: fletching + type: fletching + wait: 2 + xp: 5 +description: Bolts tipped with emerald. Can be enchanted via science. +equip_slot: ammo id: emerald_bolts name: emerald bolts -color: "34" -description: "Bolts tipped with emerald. Can be enchanted via science." -value: 40 stackable: true -equip_slot: ammo stats: - ranged_attack: 5 + ranged_attack: 5 +value: 40 diff --git a/data/items/ammo/headless_arrow.yaml b/data/items/ammo/headless_arrow.yaml index acf1384..6f1c939 100644 --- a/data/items/ammo/headless_arrow.yaml +++ b/data/items/ammo/headless_arrow.yaml @@ -1,6 +1,21 @@ +color: "137" +craft: + consume: + - items: + - arrow_shaft + quantity: 15 + - items: + - feather + quantity: 15 + level: 1 + message: You attach feathers to the arrow shafts. + output_qty: 15 + skill: fletching + type: fletching + wait: 2 + xp: 1 +description: An arrow shaft with feathers attached. Needs a head. id: headless_arrow name: headless arrow -color: "137" -description: "An arrow shaft with feathers attached. Needs a head." -value: 1 stackable: true +value: 1 diff --git a/data/items/ammo/iron_arrow.yaml b/data/items/ammo/iron_arrow.yaml index ebadaec..4cd5bea 100644 --- a/data/items/ammo/iron_arrow.yaml +++ b/data/items/ammo/iron_arrow.yaml @@ -1,9 +1,23 @@ +color: "250" +craft: + consume: + - items: + - headless_arrow + quantity: 15 + - items: + - iron_arrowtips + quantity: 15 + level: 15 + output_qty: 15 + skill: fletching + type: fletching + wait: 2 + xp: 2 +description: An iron-tipped arrow. +equip_slot: ammo id: iron_arrow name: iron arrow -color: "250" -description: "An iron-tipped arrow." -value: 2 stackable: true -equip_slot: ammo stats: - ranged_strength: 10 + ranged_strength: 10 +value: 2 diff --git a/data/items/ammo/iron_arrowtips.yaml b/data/items/ammo/iron_arrowtips.yaml index 54ffd11..dd7e6d5 100644 --- a/data/items/ammo/iron_arrowtips.yaml +++ b/data/items/ammo/iron_arrowtips.yaml @@ -1,6 +1,19 @@ +color: "250" +craft: + consume: + - items: + - iron_bar + quantity: 1 + level: 25 + output_qty: 15 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 25 +description: A set of iron arrowtips. id: iron_arrowtips name: iron arrowtips -color: "250" -description: "A set of iron arrowtips." -value: 2 stackable: true +value: 2 diff --git a/data/items/ammo/iron_bolts.yaml b/data/items/ammo/iron_bolts.yaml index ed81578..d2aeb62 100644 --- a/data/items/ammo/iron_bolts.yaml +++ b/data/items/ammo/iron_bolts.yaml @@ -1,9 +1,23 @@ +color: "250" +craft: + consume: + - items: + - iron_bolts_unf + quantity: 10 + - items: + - feather + quantity: 10 + level: 39 + output_qty: 10 + skill: fletching + type: fletching + wait: 0 + xp: 15 +description: Iron crossbow bolts. +equip_slot: ammo id: iron_bolts name: iron bolts -color: "250" -description: "Iron crossbow bolts." -value: 3 stackable: true -equip_slot: ammo stats: - ranged_strength: 17 + ranged_strength: 17 +value: 3 diff --git a/data/items/ammo/iron_bolts_unf.yaml b/data/items/ammo/iron_bolts_unf.yaml index 0a51ca0..78746a8 100644 --- a/data/items/ammo/iron_bolts_unf.yaml +++ b/data/items/ammo/iron_bolts_unf.yaml @@ -1,6 +1,19 @@ +color: "250" +craft: + consume: + - items: + - iron_bar + quantity: 1 + level: 26 + output_qty: 10 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 25 +description: Unfinished iron crossbow bolts. id: iron_bolts_unf name: iron bolts (unf) -color: "250" -description: "Unfinished iron crossbow bolts." -value: 2 stackable: true +value: 2 diff --git a/data/items/ammo/mithril_arrow.yaml b/data/items/ammo/mithril_arrow.yaml index 23464e9..3f07c09 100644 --- a/data/items/ammo/mithril_arrow.yaml +++ b/data/items/ammo/mithril_arrow.yaml @@ -1,9 +1,23 @@ +color: "75" +craft: + consume: + - items: + - headless_arrow + quantity: 15 + - items: + - mithril_arrowtips + quantity: 15 + level: 45 + output_qty: 15 + skill: fletching + type: fletching + wait: 2 + xp: 7 +description: A mithril-tipped arrow. +equip_slot: ammo id: mithril_arrow name: mithril arrow -color: "75" -description: "A mithril-tipped arrow." -value: 10 stackable: true -equip_slot: ammo stats: - ranged_strength: 22 + ranged_strength: 22 +value: 10 diff --git a/data/items/ammo/mithril_arrowtips.yaml b/data/items/ammo/mithril_arrowtips.yaml index 8f68a34..8dca92c 100644 --- a/data/items/ammo/mithril_arrowtips.yaml +++ b/data/items/ammo/mithril_arrowtips.yaml @@ -1,6 +1,19 @@ +color: "75" +craft: + consume: + - items: + - mithril_bar + quantity: 1 + level: 55 + output_qty: 15 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 50 +description: A set of mithril arrowtips. id: mithril_arrowtips name: mithril arrowtips -color: "75" -description: "A set of mithril arrowtips." -value: 8 stackable: true +value: 8 diff --git a/data/items/ammo/mithril_bolts.yaml b/data/items/ammo/mithril_bolts.yaml index e160065..d9b4183 100644 --- a/data/items/ammo/mithril_bolts.yaml +++ b/data/items/ammo/mithril_bolts.yaml @@ -1,9 +1,23 @@ +color: "75" +craft: + consume: + - items: + - mithril_bolts_unf + quantity: 10 + - items: + - feather + quantity: 10 + level: 54 + output_qty: 10 + skill: fletching + type: fletching + wait: 0 + xp: 50 +description: Mithril crossbow bolts. +equip_slot: ammo id: mithril_bolts name: mithril bolts -color: "75" -description: "Mithril crossbow bolts." -value: 12 stackable: true -equip_slot: ammo stats: - ranged_strength: 32 + ranged_strength: 32 +value: 12 diff --git a/data/items/ammo/mithril_bolts_unf.yaml b/data/items/ammo/mithril_bolts_unf.yaml index 8015f1a..93a5358 100644 --- a/data/items/ammo/mithril_bolts_unf.yaml +++ b/data/items/ammo/mithril_bolts_unf.yaml @@ -1,6 +1,19 @@ +color: "75" +craft: + consume: + - items: + - mithril_bar + quantity: 1 + level: 56 + output_qty: 10 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 50 +description: Unfinished mithril crossbow bolts. id: mithril_bolts_unf name: mithril bolts (unf) -color: "75" -description: "Unfinished mithril crossbow bolts." -value: 10 stackable: true +value: 10 diff --git a/data/items/ammo/ruby_bolt_tips.yaml b/data/items/ammo/ruby_bolt_tips.yaml index 6ebe1a0..c5bc88c 100644 --- a/data/items/ammo/ruby_bolt_tips.yaml +++ b/data/items/ammo/ruby_bolt_tips.yaml @@ -1,6 +1,18 @@ +color: "196" +craft: + consume: + - items: + - uncut_ruby + quantity: 1 + level: 73 + output_qty: 12 + skill: fletching + tool: chisel + type: fletching + wait: 5 + xp: 6 +description: Bolt tips cut from a ruby. id: ruby_bolt_tips name: ruby bolt tips -color: "196" -description: "Bolt tips cut from a ruby." -value: 100 stackable: true +value: 100 diff --git a/data/items/ammo/ruby_bolts.yaml b/data/items/ammo/ruby_bolts.yaml index b83bec2..f10be7e 100644 --- a/data/items/ammo/ruby_bolts.yaml +++ b/data/items/ammo/ruby_bolts.yaml @@ -1,9 +1,23 @@ +color: "196" +craft: + consume: + - items: + - adamant_bolts + quantity: 10 + - items: + - ruby_bolt_tips + quantity: 10 + level: 73 + output_qty: 10 + skill: fletching + type: fletching + wait: 2 + xp: 6 +description: Bolts tipped with ruby. Can be enchanted via science. +equip_slot: ammo id: ruby_bolts name: ruby bolts -color: "196" -description: "Bolts tipped with ruby. Can be enchanted via science." -value: 75 stackable: true -equip_slot: ammo stats: - ranged_attack: 7 + ranged_attack: 7 +value: 75 diff --git a/data/items/ammo/rune_arrow.yaml b/data/items/ammo/rune_arrow.yaml index b00e922..0b497ff 100644 --- a/data/items/ammo/rune_arrow.yaml +++ b/data/items/ammo/rune_arrow.yaml @@ -1,9 +1,23 @@ +color: "87" +craft: + consume: + - items: + - headless_arrow + quantity: 15 + - items: + - rune_arrowtips + quantity: 15 + level: 75 + output_qty: 15 + skill: fletching + type: fletching + wait: 2 + xp: 12 +description: A rune-tipped arrow. +equip_slot: ammo id: rune_arrow name: rune arrow -color: "87" -description: "A rune-tipped arrow." -value: 40 stackable: true -equip_slot: ammo stats: - ranged_strength: 49 + ranged_strength: 49 +value: 40 diff --git a/data/items/ammo/rune_arrowtips.yaml b/data/items/ammo/rune_arrowtips.yaml index c2d80e0..e1cd229 100644 --- a/data/items/ammo/rune_arrowtips.yaml +++ b/data/items/ammo/rune_arrowtips.yaml @@ -1,6 +1,19 @@ +color: "87" +craft: + consume: + - items: + - runite_bar + quantity: 1 + level: 90 + output_qty: 15 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 75 +description: A set of rune arrowtips. id: rune_arrowtips name: rune arrowtips -color: "87" -description: "A set of rune arrowtips." -value: 30 stackable: true +value: 30 diff --git a/data/items/ammo/rune_bolts.yaml b/data/items/ammo/rune_bolts.yaml index 82ac597..f92a49e 100644 --- a/data/items/ammo/rune_bolts.yaml +++ b/data/items/ammo/rune_bolts.yaml @@ -1,9 +1,23 @@ +color: "87" +craft: + consume: + - items: + - rune_bolts_unf + quantity: 10 + - items: + - feather + quantity: 10 + level: 69 + output_qty: 10 + skill: fletching + type: fletching + wait: 0 + xp: 100 +description: Rune crossbow bolts. +equip_slot: ammo id: rune_bolts name: rune bolts -color: "87" -description: "Rune crossbow bolts." -value: 48 stackable: true -equip_slot: ammo stats: - ranged_strength: 55 + ranged_strength: 55 +value: 48 diff --git a/data/items/ammo/rune_bolts_unf.yaml b/data/items/ammo/rune_bolts_unf.yaml index ecaf494..20f0e1a 100644 --- a/data/items/ammo/rune_bolts_unf.yaml +++ b/data/items/ammo/rune_bolts_unf.yaml @@ -1,6 +1,19 @@ +color: "87" +craft: + consume: + - items: + - runite_bar + quantity: 1 + level: 91 + output_qty: 10 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 75 +description: Unfinished rune crossbow bolts. id: rune_bolts_unf name: rune bolts (unf) -color: "87" -description: "Unfinished rune crossbow bolts." -value: 40 stackable: true +value: 40 diff --git a/data/items/ammo/sapphire_bolt_tips.yaml b/data/items/ammo/sapphire_bolt_tips.yaml index 7513fd3..0469bb0 100644 --- a/data/items/ammo/sapphire_bolt_tips.yaml +++ b/data/items/ammo/sapphire_bolt_tips.yaml @@ -1,6 +1,18 @@ +color: "69" +craft: + consume: + - items: + - uncut_sapphire + quantity: 1 + level: 63 + output_qty: 12 + skill: fletching + tool: chisel + type: fletching + wait: 5 + xp: 4 +description: Bolt tips cut from a sapphire. id: sapphire_bolt_tips name: sapphire bolt tips -color: "69" -description: "Bolt tips cut from a sapphire." -value: 25 stackable: true +value: 25 diff --git a/data/items/ammo/sapphire_bolts.yaml b/data/items/ammo/sapphire_bolts.yaml index a7102c9..5443347 100644 --- a/data/items/ammo/sapphire_bolts.yaml +++ b/data/items/ammo/sapphire_bolts.yaml @@ -1,9 +1,23 @@ +color: "39" +craft: + consume: + - items: + - mithril_bolts + quantity: 10 + - items: + - sapphire_bolt_tips + quantity: 10 + level: 63 + output_qty: 10 + skill: fletching + type: fletching + wait: 2 + xp: 4 +description: Bolts tipped with sapphire. Can be enchanted via science. +equip_slot: ammo id: sapphire_bolts name: sapphire bolts -color: "39" -description: "Bolts tipped with sapphire. Can be enchanted via science." -value: 20 stackable: true -equip_slot: ammo stats: - ranged_attack: 3 + ranged_attack: 3 +value: 20 diff --git a/data/items/ammo/steel_arrow.yaml b/data/items/ammo/steel_arrow.yaml index e14171f..fb85c0d 100644 --- a/data/items/ammo/steel_arrow.yaml +++ b/data/items/ammo/steel_arrow.yaml @@ -1,9 +1,23 @@ +color: "253" +craft: + consume: + - items: + - headless_arrow + quantity: 15 + - items: + - steel_arrowtips + quantity: 15 + level: 30 + output_qty: 15 + skill: fletching + type: fletching + wait: 2 + xp: 5 +description: A steel-tipped arrow. +equip_slot: ammo id: steel_arrow name: steel arrow -color: "253" -description: "A steel-tipped arrow." -value: 5 stackable: true -equip_slot: ammo stats: - ranged_strength: 16 + ranged_strength: 16 +value: 5 diff --git a/data/items/ammo/steel_arrowtips.yaml b/data/items/ammo/steel_arrowtips.yaml index 49000d2..140fb9a 100644 --- a/data/items/ammo/steel_arrowtips.yaml +++ b/data/items/ammo/steel_arrowtips.yaml @@ -1,6 +1,19 @@ +color: "253" +craft: + consume: + - items: + - steel_bar + quantity: 1 + level: 35 + output_qty: 15 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 37 +description: A set of steel arrowtips. id: steel_arrowtips name: steel arrowtips -color: "253" -description: "A set of steel arrowtips." -value: 4 stackable: true +value: 4 diff --git a/data/items/ammo/steel_bolts.yaml b/data/items/ammo/steel_bolts.yaml index 7dfadf1..1e19e64 100644 --- a/data/items/ammo/steel_bolts.yaml +++ b/data/items/ammo/steel_bolts.yaml @@ -1,9 +1,23 @@ +color: "253" +craft: + consume: + - items: + - steel_bolts_unf + quantity: 10 + - items: + - feather + quantity: 10 + level: 46 + output_qty: 10 + skill: fletching + type: fletching + wait: 0 + xp: 35 +description: Steel crossbow bolts. +equip_slot: ammo id: steel_bolts name: steel bolts -color: "253" -description: "Steel crossbow bolts." -value: 6 stackable: true -equip_slot: ammo stats: - ranged_strength: 25 + ranged_strength: 25 +value: 6 diff --git a/data/items/ammo/steel_bolts_unf.yaml b/data/items/ammo/steel_bolts_unf.yaml index b65d5fa..2404129 100644 --- a/data/items/ammo/steel_bolts_unf.yaml +++ b/data/items/ammo/steel_bolts_unf.yaml @@ -1,6 +1,19 @@ +color: "253" +craft: + consume: + - items: + - steel_bar + quantity: 1 + level: 36 + output_qty: 10 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 37 +description: Unfinished steel crossbow bolts. id: steel_bolts_unf name: steel bolts (unf) -color: "253" -description: "Unfinished steel crossbow bolts." -value: 5 stackable: true +value: 5 diff --git a/data/items/consumables/amp_potion.yaml b/data/items/consumables/amp_potion.yaml index 8167932..ac98966 100644 --- a/data/items/consumables/amp_potion.yaml +++ b/data/items/consumables/amp_potion.yaml @@ -1,9 +1,23 @@ -id: amp_potion -name: "amp potion" color: "220" -description: "A glowing gold potion that amplifies physical strength." -value: 55 -stackable: false -potion_effect: "strength" +craft: + consume: + - items: + - tarromin_potion_unf + quantity: 1 + - items: + - limpwurt_root + quantity: 1 + level: 12 + message: You mix an amp potion. + skill: pharmacy + type: pharmacy + wait: 4 + xp: 50 +description: A glowing gold potion that amplifies physical strength. +id: amp_potion +name: amp potion potion_bonus: 10 potion_duration: 200 +potion_effect: strength +stackable: false +value: 55 diff --git a/data/items/consumables/anchovies.yaml b/data/items/consumables/anchovies.yaml index 0abd846..535585a 100644 --- a/data/items/consumables/anchovies.yaml +++ b/data/items/consumables/anchovies.yaml @@ -1,8 +1,24 @@ +color: "209" +craft: + consume: + - items: + - raw_anchovies + quantity: 1 + fail: burnt_fish + fail_message: You accidentally burn the anchovies. + level: 1 + message: Cooked to perfection. It looks great! + skill: cooking + station: + - fire + - cooking_range + type: cooking + wait: 6 + xp: 30 +description: Some nicely cooked anchovies. +eat_message: You eat the anchovies. +heal_value: 3 id: anchovies name: anchovies -color: "209" -description: "Some nicely cooked anchovies." -value: 5 stackable: false -heal_value: 3 -eat_message: "You eat the anchovies." +value: 5 diff --git a/data/items/consumables/avantoe_potion_unf.yaml b/data/items/consumables/avantoe_potion_unf.yaml index 62f2218..bd2ebb1 100644 --- a/data/items/consumables/avantoe_potion_unf.yaml +++ b/data/items/consumables/avantoe_potion_unf.yaml @@ -1,12 +1,16 @@ -id: avantoe_potion_unf -name: "avantoe potion (unf)" color: "48" -description: "An unfinished potion with avantoe floating in water." -value: 50 +craft: + type: combine + consume: + - items: + - avantoe + quantity: 1 + - items: + - vial_of_water + quantity: 1 + wait: 0 +description: An unfinished potion with avantoe floating in water. +id: avantoe_potion_unf +name: avantoe potion (unf) stackable: false -made_from: - - items: [avantoe] - quantity: 1 - - items: [vial_of_water] - quantity: 1 -ticks: 0 +value: 50 diff --git a/data/items/consumables/bio_serum.yaml b/data/items/consumables/bio_serum.yaml index b397e46..6a7e181 100644 --- a/data/items/consumables/bio_serum.yaml +++ b/data/items/consumables/bio_serum.yaml @@ -1,9 +1,23 @@ -id: bio_serum -name: "bio serum" color: "48" -description: "A green serum that neutralizes biological toxins and restores health." -value: 45 -stackable: false -potion_effect: "heal" +craft: + consume: + - items: + - marrentill_potion_unf + quantity: 1 + - items: + - antitoxin_powder + quantity: 1 + level: 5 + message: You mix a bio serum. + skill: pharmacy + type: pharmacy + wait: 4 + xp: 38 +description: A green serum that neutralizes biological toxins and restores health. +id: bio_serum +name: bio serum potion_bonus: 60 potion_duration: 0 +potion_effect: heal +stackable: false +value: 45 diff --git a/data/items/consumables/bread.yaml b/data/items/consumables/bread.yaml index 68cefdc..a00a3ef 100644 --- a/data/items/consumables/bread.yaml +++ b/data/items/consumables/bread.yaml @@ -1,8 +1,23 @@ +color: "222" +craft: + consume: + - items: + - bread_dough + quantity: 1 + fail: burnt_meat + fail_message: You burn the bread to a crisp. + level: 1 + message: You bake the dough into a fresh loaf of bread. + skill: cooking + station: + - cooking_range + type: cooking + wait: 6 + xp: 40 +description: A fresh loaf of bread, still warm from the oven. +eat_message: You eat the bread. Warm and satisfying. +heal_value: 5 id: bread name: bread -color: "222" -description: "A fresh loaf of bread, still warm from the oven." -value: 5 stackable: false -heal_value: 5 -eat_message: "You eat the bread. Warm and satisfying." +value: 5 diff --git a/data/items/consumables/bread_dough.yaml b/data/items/consumables/bread_dough.yaml index 73ac998..7e09f3d 100644 --- a/data/items/consumables/bread_dough.yaml +++ b/data/items/consumables/bread_dough.yaml @@ -1,14 +1,22 @@ +color: "222" +craft: + type: combine + consume: + - byproducts: + - empty_pot + items: + - pot_of_flour + quantity: 1 + - byproducts: + - empty_bucket + - empty_jug + items: + - bucket_of_water + - jug_of_water + quantity: 1 + wait: 2 +description: A ball of uncooked bread dough. It needs to be baked. id: bread_dough name: bread dough -color: "222" -description: "A ball of uncooked bread dough. It needs to be baked." -value: 3 stackable: false -ticks: 2 -made_from: - - items: [pot_of_flour] - quantity: 1 - byproducts: [empty_pot] - - items: [bucket_of_water, jug_of_water] - quantity: 1 - byproducts: [empty_bucket, empty_jug] +value: 3 diff --git a/data/items/consumables/cadantine_potion_unf.yaml b/data/items/consumables/cadantine_potion_unf.yaml index d1f13c6..5d5db0b 100644 --- a/data/items/consumables/cadantine_potion_unf.yaml +++ b/data/items/consumables/cadantine_potion_unf.yaml @@ -1,12 +1,16 @@ -id: cadantine_potion_unf -name: "cadantine potion (unf)" color: "48" -description: "An unfinished potion with cadantine floating in water." -value: 72 +craft: + type: combine + consume: + - items: + - cadantine + quantity: 1 + - items: + - vial_of_water + quantity: 1 + wait: 0 +description: An unfinished potion with cadantine floating in water. +id: cadantine_potion_unf +name: cadantine potion (unf) stackable: false -made_from: - - items: [cadantine] - quantity: 1 - - items: [vial_of_water] - quantity: 1 -ticks: 0 +value: 72 diff --git a/data/items/consumables/dwarf_weed_potion_unf.yaml b/data/items/consumables/dwarf_weed_potion_unf.yaml index 64f7faa..44f2eab 100644 --- a/data/items/consumables/dwarf_weed_potion_unf.yaml +++ b/data/items/consumables/dwarf_weed_potion_unf.yaml @@ -1,12 +1,16 @@ -id: dwarf_weed_potion_unf -name: "dwarf weed potion (unf)" color: "48" -description: "An unfinished potion with dwarf weed floating in water." -value: 88 +craft: + type: combine + consume: + - items: + - dwarf_weed + quantity: 1 + - items: + - vial_of_water + quantity: 1 + wait: 0 +description: An unfinished potion with dwarf weed floating in water. +id: dwarf_weed_potion_unf +name: dwarf weed potion (unf) stackable: false -made_from: - - items: [dwarf_weed] - quantity: 1 - - items: [vial_of_water] - quantity: 1 -ticks: 0 +value: 88 diff --git a/data/items/consumables/full_restore.yaml b/data/items/consumables/full_restore.yaml index 96f6036..28204e8 100644 --- a/data/items/consumables/full_restore.yaml +++ b/data/items/consumables/full_restore.yaml @@ -1,9 +1,23 @@ -id: full_restore -name: "full restore" color: "208" -description: "A powerful orange potion that completely restores health." -value: 200 -stackable: false -potion_effect: "heal" +craft: + consume: + - items: + - snapdragon_potion_unf + quantity: 1 + - items: + - arachnid_enzyme + quantity: 1 + level: 63 + message: You mix a full restore. + skill: pharmacy + type: pharmacy + wait: 4 + xp: 143 +description: A powerful orange potion that completely restores health. +id: full_restore +name: full restore potion_bonus: 500 potion_duration: 0 +potion_effect: heal +stackable: false +value: 200 diff --git a/data/items/consumables/guam_potion_unf.yaml b/data/items/consumables/guam_potion_unf.yaml index ba81e93..caddd74 100644 --- a/data/items/consumables/guam_potion_unf.yaml +++ b/data/items/consumables/guam_potion_unf.yaml @@ -1,12 +1,16 @@ -id: guam_potion_unf -name: "guam potion (unf)" color: "48" -description: "An unfinished potion with guam floating in water." -value: 5 +craft: + type: combine + consume: + - items: + - guam + quantity: 1 + - items: + - vial_of_water + quantity: 1 + wait: 0 +description: An unfinished potion with guam floating in water. +id: guam_potion_unf +name: guam potion (unf) stackable: false -made_from: - - items: [guam] - quantity: 1 - - items: [vial_of_water] - quantity: 1 -ticks: 0 +value: 5 diff --git a/data/items/consumables/harralander_potion_unf.yaml b/data/items/consumables/harralander_potion_unf.yaml index 522f8ea..22a7611 100644 --- a/data/items/consumables/harralander_potion_unf.yaml +++ b/data/items/consumables/harralander_potion_unf.yaml @@ -1,12 +1,16 @@ -id: harralander_potion_unf -name: "harralander potion (unf)" color: "48" -description: "An unfinished potion with harralander floating in water." -value: 18 +craft: + type: combine + consume: + - items: + - harralander + quantity: 1 + - items: + - vial_of_water + quantity: 1 + wait: 0 +description: An unfinished potion with harralander floating in water. +id: harralander_potion_unf +name: harralander potion (unf) stackable: false -made_from: - - items: [harralander] - quantity: 1 - - items: [vial_of_water] - quantity: 1 -ticks: 0 +value: 18 diff --git a/data/items/consumables/herring.yaml b/data/items/consumables/herring.yaml index adbbd95..1e20697 100644 --- a/data/items/consumables/herring.yaml +++ b/data/items/consumables/herring.yaml @@ -1,8 +1,24 @@ +color: "209" +craft: + consume: + - items: + - raw_herring + quantity: 1 + fail: burnt_fish + fail_message: You accidentally burn the herring. + level: 5 + message: Cooked to perfection. It looks great! + skill: cooking + station: + - fire + - cooking_range + type: cooking + wait: 6 + xp: 50 +description: A nicely cooked herring. +eat_message: You eat the herring. +heal_value: 5 id: herring name: herring -color: "209" -description: "A nicely cooked herring." -value: 7 stackable: false -heal_value: 5 -eat_message: "You eat the herring." +value: 7 diff --git a/data/items/consumables/irit_potion_unf.yaml b/data/items/consumables/irit_potion_unf.yaml index 76a8577..841487e 100644 --- a/data/items/consumables/irit_potion_unf.yaml +++ b/data/items/consumables/irit_potion_unf.yaml @@ -1,12 +1,16 @@ -id: irit_potion_unf -name: "irit potion (unf)" color: "48" -description: "An unfinished potion with irit floating in water." -value: 42 +craft: + type: combine + consume: + - items: + - irit + quantity: 1 + - items: + - vial_of_water + quantity: 1 + wait: 0 +description: An unfinished potion with irit floating in water. +id: irit_potion_unf +name: irit potion (unf) stackable: false -made_from: - - items: [irit] - quantity: 1 - - items: [vial_of_water] - quantity: 1 -ticks: 0 +value: 42 diff --git a/data/items/consumables/kwuarm_potion_unf.yaml b/data/items/consumables/kwuarm_potion_unf.yaml index 0448145..9ab2f67 100644 --- a/data/items/consumables/kwuarm_potion_unf.yaml +++ b/data/items/consumables/kwuarm_potion_unf.yaml @@ -1,12 +1,16 @@ -id: kwuarm_potion_unf -name: "kwuarm potion (unf)" color: "48" -description: "An unfinished potion with kwuarm floating in water." -value: 56 +craft: + type: combine + consume: + - items: + - kwuarm + quantity: 1 + - items: + - vial_of_water + quantity: 1 + wait: 0 +description: An unfinished potion with kwuarm floating in water. +id: kwuarm_potion_unf +name: kwuarm potion (unf) stackable: false -made_from: - - items: [kwuarm] - quantity: 1 - - items: [vial_of_water] - quantity: 1 -ticks: 0 +value: 56 diff --git a/data/items/consumables/lantadyme_potion_unf.yaml b/data/items/consumables/lantadyme_potion_unf.yaml index 3460a18..52ff04f 100644 --- a/data/items/consumables/lantadyme_potion_unf.yaml +++ b/data/items/consumables/lantadyme_potion_unf.yaml @@ -1,12 +1,16 @@ -id: lantadyme_potion_unf -name: "lantadyme potion (unf)" color: "48" -description: "An unfinished potion with lantadyme floating in water." -value: 80 +craft: + type: combine + consume: + - items: + - lantadyme + quantity: 1 + - items: + - vial_of_water + quantity: 1 + wait: 0 +description: An unfinished potion with lantadyme floating in water. +id: lantadyme_potion_unf +name: lantadyme potion (unf) stackable: false -made_from: - - items: [lantadyme] - quantity: 1 - - items: [vial_of_water] - quantity: 1 -ticks: 0 +value: 80 diff --git a/data/items/consumables/marrentill_potion_unf.yaml b/data/items/consumables/marrentill_potion_unf.yaml index 4424e5e..8a01b4a 100644 --- a/data/items/consumables/marrentill_potion_unf.yaml +++ b/data/items/consumables/marrentill_potion_unf.yaml @@ -1,12 +1,16 @@ -id: marrentill_potion_unf -name: "marrentill potion (unf)" color: "48" -description: "An unfinished potion with marrentill floating in water." -value: 8 +craft: + type: combine + consume: + - items: + - marrentill + quantity: 1 + - items: + - vial_of_water + quantity: 1 + wait: 0 +description: An unfinished potion with marrentill floating in water. +id: marrentill_potion_unf +name: marrentill potion (unf) stackable: false -made_from: - - items: [marrentill] - quantity: 1 - - items: [vial_of_water] - quantity: 1 -ticks: 0 +value: 8 diff --git a/data/items/consumables/nano_restore.yaml b/data/items/consumables/nano_restore.yaml index e430b49..dc55b1b 100644 --- a/data/items/consumables/nano_restore.yaml +++ b/data/items/consumables/nano_restore.yaml @@ -1,9 +1,23 @@ -id: nano_restore -name: "nano restore" color: "208" -description: "An orange potion containing nanobots that restore diminished attributes." -value: 70 -stackable: false -potion_effect: "heal" +craft: + consume: + - items: + - harralander_potion_unf + quantity: 1 + - items: + - arachnid_enzyme + quantity: 1 + level: 22 + message: You mix a nano restore. + skill: pharmacy + type: pharmacy + wait: 4 + xp: 63 +description: An orange potion containing nanobots that restore diminished attributes. +id: nano_restore +name: nano restore potion_bonus: 100 potion_duration: 0 +potion_effect: heal +stackable: false +value: 70 diff --git a/data/items/consumables/pastry_dough.yaml b/data/items/consumables/pastry_dough.yaml index b607c83..0bacf84 100644 --- a/data/items/consumables/pastry_dough.yaml +++ b/data/items/consumables/pastry_dough.yaml @@ -1,11 +1,16 @@ +color: "222" +craft: + type: combine + consume: + - items: + - pot_of_flour + quantity: 1 + - items: + - bucket_of_water + quantity: 1 + wait: 2 +description: A ball of uncooked pastry dough. It needs to be baked. id: pastry_dough name: pastry dough -color: "222" -description: "A ball of uncooked pastry dough. It needs to be baked." -value: 3 stackable: false -made_from: - - items: [pot_of_flour] - quantity: 1 - - items: [bucket_of_water] - quantity: 1 +value: 3 diff --git a/data/items/consumables/pie_dish.yaml b/data/items/consumables/pie_dish.yaml index bd6100b..a562b9e 100644 --- a/data/items/consumables/pie_dish.yaml +++ b/data/items/consumables/pie_dish.yaml @@ -1,5 +1,23 @@ +color: "130" +craft: + consume: + - items: + - unfired_pie_dish + quantity: 1 + fail_message: The pie dish cracks in the oven and is ruined. + level: 7 + message: You fire the pie dish in the oven successfully. + skill: crafting + station: + - pottery_oven + success: + base: 0.4 + cap: 0.95 + per_level: 0.02 + type: crafting + wait: 4 + xp: 10 +description: A clay pie dish for baking pies. id: pie_dish name: pie dish -color: "130" -description: "A clay pie dish for baking pies." value: 5 diff --git a/data/items/consumables/pizza_dough.yaml b/data/items/consumables/pizza_dough.yaml index 12d8b14..bb69aca 100644 --- a/data/items/consumables/pizza_dough.yaml +++ b/data/items/consumables/pizza_dough.yaml @@ -1,11 +1,16 @@ +color: "222" +craft: + type: combine + consume: + - items: + - pot_of_flour + quantity: 1 + - items: + - bucket_of_water + quantity: 1 + wait: 2 +description: A ball of uncooked pizza dough. It needs to be baked. id: pizza_dough name: pizza dough -color: "222" -description: "A ball of uncooked pizza dough. It needs to be baked." -value: 3 stackable: false -made_from: - - items: [pot_of_flour] - quantity: 1 - - items: [bucket_of_water] - quantity: 1 +value: 3 diff --git a/data/items/consumables/ranarr_potion_unf.yaml b/data/items/consumables/ranarr_potion_unf.yaml index d2c475d..941f5da 100644 --- a/data/items/consumables/ranarr_potion_unf.yaml +++ b/data/items/consumables/ranarr_potion_unf.yaml @@ -1,12 +1,16 @@ -id: ranarr_potion_unf -name: "ranarr potion (unf)" color: "48" -description: "An unfinished potion with ranarr floating in water." -value: 38 +craft: + type: combine + consume: + - items: + - ranarr + quantity: 1 + - items: + - vial_of_water + quantity: 1 + wait: 0 +description: An unfinished potion with ranarr floating in water. +id: ranarr_potion_unf +name: ranarr potion (unf) stackable: false -made_from: - - items: [ranarr] - quantity: 1 - - items: [vial_of_water] - quantity: 1 -ticks: 0 +value: 38 diff --git a/data/items/consumables/restoration_compound.yaml b/data/items/consumables/restoration_compound.yaml index 913153f..1bb2a14 100644 --- a/data/items/consumables/restoration_compound.yaml +++ b/data/items/consumables/restoration_compound.yaml @@ -1,9 +1,23 @@ -id: restoration_compound -name: "restoration compound" color: "51" -description: "A teal compound that enhances all combat capabilities." -value: 250 -stackable: false -potion_effect: "all_combat" +craft: + consume: + - items: + - toadflax_potion_unf + quantity: 1 + - items: + - crushed_nest + quantity: 1 + level: 81 + message: You mix a restoration compound. + skill: pharmacy + type: pharmacy + wait: 4 + xp: 180 +description: A teal compound that enhances all combat capabilities. +id: restoration_compound +name: restoration compound potion_bonus: 15 potion_duration: 150 +potion_effect: all_combat +stackable: false +value: 250 diff --git a/data/items/consumables/salmon.yaml b/data/items/consumables/salmon.yaml index 59b8237..e7988ed 100644 --- a/data/items/consumables/salmon.yaml +++ b/data/items/consumables/salmon.yaml @@ -1,8 +1,24 @@ +color: "209" +craft: + consume: + - items: + - raw_salmon + quantity: 1 + fail: burnt_fish + fail_message: You accidentally burn the salmon. + level: 25 + message: Cooked to perfection. It looks great! + skill: cooking + station: + - fire + - cooking_range + type: cooking + wait: 6 + xp: 90 +description: A nicely cooked salmon. +eat_message: You eat the salmon. Savory and satisfying! +heal_value: 9 id: salmon name: salmon -color: "209" -description: "A nicely cooked salmon." -value: 10 stackable: false -heal_value: 9 -eat_message: "You eat the salmon. Savory and satisfying!" +value: 10 diff --git a/data/items/consumables/sardine.yaml b/data/items/consumables/sardine.yaml index c11b42b..c094185 100644 --- a/data/items/consumables/sardine.yaml +++ b/data/items/consumables/sardine.yaml @@ -1,8 +1,24 @@ +color: "209" +craft: + consume: + - items: + - raw_sardine + quantity: 1 + fail: burnt_fish + fail_message: You accidentally burn the sardine. + level: 1 + message: Cooked to perfection. It looks great! + skill: cooking + station: + - fire + - cooking_range + type: cooking + wait: 6 + xp: 40 +description: A nicely cooked sardine. +eat_message: You eat the sardine. +heal_value: 4 id: sardine name: sardine -color: "209" -description: "A nicely cooked sardine." -value: 5 stackable: false -heal_value: 4 -eat_message: "You eat the sardine." +value: 5 diff --git a/data/items/consumables/science_serum.yaml b/data/items/consumables/science_serum.yaml index e78f915..b77cf58 100644 --- a/data/items/consumables/science_serum.yaml +++ b/data/items/consumables/science_serum.yaml @@ -1,9 +1,23 @@ -id: science_serum -name: "science serum" color: "141" -description: "A violet serum that heightens scientific cognition." -value: 200 -stackable: false -potion_effect: "science" +craft: + consume: + - items: + - lantadyme_potion_unf + quantity: 1 + - items: + - potato_cactus + quantity: 1 + level: 76 + message: You mix a science serum. + skill: pharmacy + type: pharmacy + wait: 4 + xp: 173 +description: A violet serum that heightens scientific cognition. +id: science_serum +name: science serum potion_bonus: 10 potion_duration: 200 +potion_effect: science +stackable: false +value: 200 diff --git a/data/items/consumables/shield_potion.yaml b/data/items/consumables/shield_potion.yaml index 4cd91e8..a0b65c2 100644 --- a/data/items/consumables/shield_potion.yaml +++ b/data/items/consumables/shield_potion.yaml @@ -1,9 +1,23 @@ -id: shield_potion -name: "shield potion" color: "21" -description: "A deep blue potion that reinforces defensive capability." -value: 85 -stackable: false -potion_effect: "defense" +craft: + consume: + - items: + - ranarr_potion_unf + quantity: 1 + - items: + - white_berries + quantity: 1 + level: 30 + message: You mix a shield potion. + skill: pharmacy + type: pharmacy + wait: 4 + xp: 75 +description: A deep blue potion that reinforces defensive capability. +id: shield_potion +name: shield potion potion_bonus: 10 potion_duration: 200 +potion_effect: defense +stackable: false +value: 85 diff --git a/data/items/consumables/shrimps.yaml b/data/items/consumables/shrimps.yaml index 9c280c8..03a7edb 100644 --- a/data/items/consumables/shrimps.yaml +++ b/data/items/consumables/shrimps.yaml @@ -1,8 +1,24 @@ +color: "209" +craft: + consume: + - items: + - raw_shrimps + quantity: 1 + fail: burnt_fish + fail_message: You accidentally burn the shrimps. + level: 1 + message: Cooked to perfection. It looks great! + skill: cooking + station: + - fire + - cooking_range + type: cooking + wait: 6 + xp: 30 +description: Some nicely cooked shrimps. +eat_message: You eat the shrimps. Tasty! +heal_value: 3 id: shrimps name: shrimps -color: "209" -description: "Some nicely cooked shrimps." -value: 5 stackable: false -heal_value: 3 -eat_message: "You eat the shrimps. Tasty!" +value: 5 diff --git a/data/items/consumables/snapdragon_potion_unf.yaml b/data/items/consumables/snapdragon_potion_unf.yaml index ee8e366..fc91a84 100644 --- a/data/items/consumables/snapdragon_potion_unf.yaml +++ b/data/items/consumables/snapdragon_potion_unf.yaml @@ -1,12 +1,16 @@ -id: snapdragon_potion_unf -name: "snapdragon potion (unf)" color: "48" -description: "An unfinished potion with snapdragon floating in water." -value: 68 +craft: + type: combine + consume: + - items: + - snapdragon + quantity: 1 + - items: + - vial_of_water + quantity: 1 + wait: 0 +description: An unfinished potion with snapdragon floating in water. +id: snapdragon_potion_unf +name: snapdragon potion (unf) stackable: false -made_from: - - items: [snapdragon] - quantity: 1 - - items: [vial_of_water] - quantity: 1 -ticks: 0 +value: 68 diff --git a/data/items/consumables/stim_potion.yaml b/data/items/consumables/stim_potion.yaml index de51291..e9ac25f 100644 --- a/data/items/consumables/stim_potion.yaml +++ b/data/items/consumables/stim_potion.yaml @@ -1,9 +1,23 @@ -id: stim_potion -name: "stim potion" color: "196" -description: "A bubbling red potion that temporarily boosts attack capability." -value: 30 -stackable: false -potion_effect: "attack" +craft: + consume: + - items: + - guam_potion_unf + quantity: 1 + - items: + - eye_of_newt + quantity: 1 + level: 1 + message: You mix a stim potion. + skill: pharmacy + type: pharmacy + wait: 4 + xp: 25 +description: A bubbling red potion that temporarily boosts attack capability. +id: stim_potion +name: stim potion potion_bonus: 10 potion_duration: 200 +potion_effect: attack +stackable: false +value: 30 diff --git a/data/items/consumables/super_amp.yaml b/data/items/consumables/super_amp.yaml index 3bea59b..361c99b 100644 --- a/data/items/consumables/super_amp.yaml +++ b/data/items/consumables/super_amp.yaml @@ -1,9 +1,23 @@ -id: super_amp -name: "super amp" color: "220" -description: "A concentrated gold potion that significantly amplifies physical strength." -value: 155 -stackable: false -potion_effect: "strength" +craft: + consume: + - items: + - kwuarm_potion_unf + quantity: 1 + - items: + - limpwurt_root + quantity: 1 + level: 55 + message: You mix a super amp. + skill: pharmacy + type: pharmacy + wait: 4 + xp: 125 +description: A concentrated gold potion that significantly amplifies physical strength. +id: super_amp +name: super amp potion_bonus: 20 potion_duration: 200 +potion_effect: strength +stackable: false +value: 155 diff --git a/data/items/consumables/super_bio_serum.yaml b/data/items/consumables/super_bio_serum.yaml index fbc5ebe..9f5796e 100644 --- a/data/items/consumables/super_bio_serum.yaml +++ b/data/items/consumables/super_bio_serum.yaml @@ -1,9 +1,23 @@ -id: super_bio_serum -name: "super bio serum" color: "48" -description: "A concentrated green serum that powerfully restores health." -value: 130 -stackable: false -potion_effect: "heal" +craft: + consume: + - items: + - irit_potion_unf + quantity: 1 + - items: + - antitoxin_powder + quantity: 1 + level: 48 + message: You mix a super bio serum. + skill: pharmacy + type: pharmacy + wait: 4 + xp: 106 +description: A concentrated green serum that powerfully restores health. +id: super_bio_serum +name: super bio serum potion_bonus: 120 potion_duration: 0 +potion_effect: heal +stackable: false +value: 130 diff --git a/data/items/consumables/super_shield.yaml b/data/items/consumables/super_shield.yaml index 7545b2e..9dc6430 100644 --- a/data/items/consumables/super_shield.yaml +++ b/data/items/consumables/super_shield.yaml @@ -1,9 +1,23 @@ -id: super_shield -name: "super shield" color: "21" -description: "A concentrated blue potion that provides significant defensive enhancement." -value: 175 -stackable: false -potion_effect: "defense" +craft: + consume: + - items: + - cadantine_potion_unf + quantity: 1 + - items: + - white_berries + quantity: 1 + level: 66 + message: You mix a super shield. + skill: pharmacy + type: pharmacy + wait: 4 + xp: 150 +description: A concentrated blue potion that provides significant defensive enhancement. +id: super_shield +name: super shield potion_bonus: 20 potion_duration: 200 +potion_effect: defense +stackable: false +value: 175 diff --git a/data/items/consumables/super_stim.yaml b/data/items/consumables/super_stim.yaml index c290c5f..38275ac 100644 --- a/data/items/consumables/super_stim.yaml +++ b/data/items/consumables/super_stim.yaml @@ -1,9 +1,23 @@ -id: super_stim -name: "super stim" color: "196" -description: "A potent red potion that dramatically boosts attack capability." -value: 120 -stackable: false -potion_effect: "attack" +craft: + consume: + - items: + - irit_potion_unf + quantity: 1 + - items: + - eye_of_newt + quantity: 1 + level: 45 + message: You mix a super stim. + skill: pharmacy + type: pharmacy + wait: 4 + xp: 100 +description: A potent red potion that dramatically boosts attack capability. +id: super_stim +name: super stim potion_bonus: 20 potion_duration: 200 +potion_effect: attack +stackable: false +value: 120 diff --git a/data/items/consumables/super_stim_cell.yaml b/data/items/consumables/super_stim_cell.yaml index 1f25597..3fb5761 100644 --- a/data/items/consumables/super_stim_cell.yaml +++ b/data/items/consumables/super_stim_cell.yaml @@ -1,9 +1,23 @@ -id: super_stim_cell -name: "super stim cell" color: "226" -description: "A concentrated yellow energy supplement that fully restores stamina." -value: 140 -stackable: false -potion_effect: "battery" +craft: + consume: + - items: + - avantoe_potion_unf + quantity: 1 + - items: + - blight_spore + quantity: 1 + level: 52 + message: You mix a super stim cell. + skill: pharmacy + type: pharmacy + wait: 4 + xp: 118 +description: A concentrated yellow energy supplement that fully restores stamina. +id: super_stim_cell +name: super stim cell potion_bonus: 50 potion_duration: 0 +potion_effect: battery +stackable: false +value: 140 diff --git a/data/items/consumables/targeting_serum.yaml b/data/items/consumables/targeting_serum.yaml index b10ebc5..5c94040 100644 --- a/data/items/consumables/targeting_serum.yaml +++ b/data/items/consumables/targeting_serum.yaml @@ -1,9 +1,23 @@ -id: targeting_serum -name: "targeting serum" color: "202" -description: "A pink serum that sharpens ranged targeting." -value: 190 -stackable: false -potion_effect: "ranged" +craft: + consume: + - items: + - dwarf_weed_potion_unf + quantity: 1 + - items: + - catalyst_wine + quantity: 1 + level: 72 + message: You mix a targeting serum. + skill: pharmacy + type: pharmacy + wait: 4 + xp: 163 +description: A pink serum that sharpens ranged targeting. +id: targeting_serum +name: targeting serum potion_bonus: 10 potion_duration: 200 +potion_effect: ranged +stackable: false +value: 190 diff --git a/data/items/consumables/tarromin_potion_unf.yaml b/data/items/consumables/tarromin_potion_unf.yaml index abc6438..c7d7dd3 100644 --- a/data/items/consumables/tarromin_potion_unf.yaml +++ b/data/items/consumables/tarromin_potion_unf.yaml @@ -1,12 +1,16 @@ -id: tarromin_potion_unf -name: "tarromin potion (unf)" color: "48" -description: "An unfinished potion with tarromin floating in water." -value: 12 +craft: + type: combine + consume: + - items: + - tarromin + quantity: 1 + - items: + - vial_of_water + quantity: 1 + wait: 0 +description: An unfinished potion with tarromin floating in water. +id: tarromin_potion_unf +name: tarromin potion (unf) stackable: false -made_from: - - items: [tarromin] - quantity: 1 - - items: [vial_of_water] - quantity: 1 -ticks: 0 +value: 12 diff --git a/data/items/consumables/tech_serum.yaml b/data/items/consumables/tech_serum.yaml index aac3fdc..c763216 100644 --- a/data/items/consumables/tech_serum.yaml +++ b/data/items/consumables/tech_serum.yaml @@ -1,9 +1,23 @@ -id: tech_serum -name: "tech serum" color: "75" -description: "A cyan serum that enhances technology interface." -value: 100 -stackable: false -potion_effect: "technology" +craft: + consume: + - items: + - ranarr_potion_unf + quantity: 1 + - items: + - snape_grass + quantity: 1 + level: 38 + message: You mix a tech serum. + skill: pharmacy + type: pharmacy + wait: 4 + xp: 88 +description: A cyan serum that enhances technology interface. +id: tech_serum +name: tech serum potion_bonus: 10 potion_duration: 200 +potion_effect: technology +stackable: false +value: 100 diff --git a/data/items/consumables/toadflax_potion_unf.yaml b/data/items/consumables/toadflax_potion_unf.yaml index f05b406..305807d 100644 --- a/data/items/consumables/toadflax_potion_unf.yaml +++ b/data/items/consumables/toadflax_potion_unf.yaml @@ -1,12 +1,16 @@ -id: toadflax_potion_unf -name: "toadflax potion (unf)" color: "48" -description: "An unfinished potion with toadflax floating in water." -value: 28 +craft: + type: combine + consume: + - items: + - toadflax + quantity: 1 + - items: + - vial_of_water + quantity: 1 + wait: 0 +description: An unfinished potion with toadflax floating in water. +id: toadflax_potion_unf +name: toadflax potion (unf) stackable: false -made_from: - - items: [toadflax] - quantity: 1 - - items: [vial_of_water] - quantity: 1 -ticks: 0 +value: 28 diff --git a/data/items/consumables/torstol_potion_unf.yaml b/data/items/consumables/torstol_potion_unf.yaml index cf551df..a25fdee 100644 --- a/data/items/consumables/torstol_potion_unf.yaml +++ b/data/items/consumables/torstol_potion_unf.yaml @@ -1,12 +1,16 @@ -id: torstol_potion_unf -name: "torstol potion (unf)" color: "48" -description: "An unfinished potion with torstol floating in water." -value: 102 +craft: + type: combine + consume: + - items: + - torstol + quantity: 1 + - items: + - vial_of_water + quantity: 1 + wait: 0 +description: An unfinished potion with torstol floating in water. +id: torstol_potion_unf +name: torstol potion (unf) stackable: false -made_from: - - items: [torstol] - quantity: 1 - - items: [vial_of_water] - quantity: 1 -ticks: 0 +value: 102 diff --git a/data/items/consumables/trout.yaml b/data/items/consumables/trout.yaml index df6cdcc..bb2b69c 100644 --- a/data/items/consumables/trout.yaml +++ b/data/items/consumables/trout.yaml @@ -1,8 +1,24 @@ +color: "209" +craft: + consume: + - items: + - raw_trout + quantity: 1 + fail: burnt_fish + fail_message: You accidentally burn the trout. + level: 15 + message: Cooked to perfection. It looks great! + skill: cooking + station: + - fire + - cooking_range + type: cooking + wait: 6 + xp: 70 +description: A nicely cooked trout. +eat_message: You eat the trout. Delicious! +heal_value: 7 id: trout name: trout -color: "209" -description: "A nicely cooked trout." -value: 8 stackable: false -heal_value: 7 -eat_message: "You eat the trout. Delicious!" +value: 8 diff --git a/data/items/equipment/adamant_dagger.yaml b/data/items/equipment/adamant_dagger.yaml index d78ecdc..a483667 100644 --- a/data/items/equipment/adamant_dagger.yaml +++ b/data/items/equipment/adamant_dagger.yaml @@ -1,17 +1,29 @@ +attack_type: stab +color: "120" +craft: + consume: + - items: + - adamantite_bar + quantity: 1 + level: 70 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 62 +description: A small adamant dagger. +equip_slot: main_hand id: adamant_dagger name: adamant dagger -color: "120" -description: "A small adamant dagger." -value: 400 +requirements: + attack: 30 +speed: 3 stackable: false -equip_slot: main_hand -weapon_type: melee -attack_type: stab stats: - stab_attack: 23 - slash_attack: 14 - crush_attack: -1 - strength_bonus: 19 -speed: 3 -requirements: - attack: 30 + crush_attack: -1 + slash_attack: 14 + stab_attack: 23 + strength_bonus: 19 +value: 400 +weapon_type: melee diff --git a/data/items/equipment/adamant_full_helm.yaml b/data/items/equipment/adamant_full_helm.yaml index 3c36c62..0b0f367 100644 --- a/data/items/equipment/adamant_full_helm.yaml +++ b/data/items/equipment/adamant_full_helm.yaml @@ -1,15 +1,27 @@ +color: "120" +craft: + consume: + - items: + - adamantite_bar + quantity: 2 + level: 77 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 125 +description: An adamant full helmet. +equip_slot: head id: adamant_full_helm name: adamant full helm -color: "120" -description: "An adamant full helmet." -value: 1000 +requirements: + defense: 30 stackable: false -equip_slot: head stats: - stab_defense: 22 - slash_defense: 24 - crush_defense: 16 - science_defense: -8 - ranged_defense: 22 -requirements: - defense: 30 + crush_defense: 16 + ranged_defense: 22 + science_defense: -8 + slash_defense: 24 + stab_defense: 22 +value: 1000 diff --git a/data/items/equipment/adamant_med_helm.yaml b/data/items/equipment/adamant_med_helm.yaml index 1fb6785..5058f37 100644 --- a/data/items/equipment/adamant_med_helm.yaml +++ b/data/items/equipment/adamant_med_helm.yaml @@ -1,15 +1,27 @@ +color: "120" +craft: + consume: + - items: + - adamantite_bar + quantity: 1 + level: 73 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 62 +description: An adamant medium helmet. +equip_slot: head id: adamant_med_helm name: adamant med helm -color: "120" -description: "An adamant medium helmet." -value: 400 +requirements: + defense: 30 stackable: false -equip_slot: head stats: - stab_defense: 14 - slash_defense: 16 - crush_defense: 10 - science_defense: -3 - ranged_defense: 14 -requirements: - defense: 30 + crush_defense: 10 + ranged_defense: 14 + science_defense: -3 + slash_defense: 16 + stab_defense: 14 +value: 400 diff --git a/data/items/equipment/adamant_platebody.yaml b/data/items/equipment/adamant_platebody.yaml index a37b781..d2bf9cb 100644 --- a/data/items/equipment/adamant_platebody.yaml +++ b/data/items/equipment/adamant_platebody.yaml @@ -1,15 +1,27 @@ +color: "120" +craft: + consume: + - items: + - adamantite_bar + quantity: 5 + level: 88 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 312 +description: An adamant platebody. +equip_slot: torso id: adamant_platebody name: adamant platebody -color: "120" -description: "An adamant platebody." -value: 5000 +requirements: + defense: 30 stackable: false -equip_slot: torso stats: - stab_defense: 49 - slash_defense: 55 - crush_defense: 40 - science_defense: -25 - ranged_defense: 49 -requirements: - defense: 30 + crush_defense: 40 + ranged_defense: 49 + science_defense: -25 + slash_defense: 55 + stab_defense: 49 +value: 5000 diff --git a/data/items/equipment/adamant_sword.yaml b/data/items/equipment/adamant_sword.yaml index 035b615..cce058c 100644 --- a/data/items/equipment/adamant_sword.yaml +++ b/data/items/equipment/adamant_sword.yaml @@ -1,17 +1,29 @@ +attack_type: slash +color: "120" +craft: + consume: + - items: + - adamantite_bar + quantity: 1 + level: 74 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 62 +description: An adamant sword. +equip_slot: main_hand id: adamant_sword name: adamant sword -color: "120" -description: "An adamant sword." -value: 700 +requirements: + attack: 30 +speed: 4 stackable: false -equip_slot: main_hand -weapon_type: melee -attack_type: slash stats: - stab_attack: 20 - slash_attack: 40 - crush_attack: -2 - strength_bonus: 27 -speed: 4 -requirements: - attack: 30 + crush_attack: -2 + slash_attack: 40 + stab_attack: 20 + strength_bonus: 27 +value: 700 +weapon_type: melee diff --git a/data/items/equipment/bronze_dagger.yaml b/data/items/equipment/bronze_dagger.yaml index 95ec968..8a3d2ec 100644 --- a/data/items/equipment/bronze_dagger.yaml +++ b/data/items/equipment/bronze_dagger.yaml @@ -1,15 +1,27 @@ +attack_type: stab +color: "178" +craft: + consume: + - items: + - bronze_bar + quantity: 1 + level: 1 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 12 +description: A small bronze dagger. +equip_slot: main_hand id: bronze_dagger name: bronze dagger -color: "178" -description: "A small bronze dagger." -value: 8 +speed: 3 stackable: false -equip_slot: main_hand -weapon_type: melee -attack_type: stab stats: - stab_attack: 5 - slash_attack: 3 - crush_attack: -1 - strength_bonus: 4 -speed: 3 + crush_attack: -1 + slash_attack: 3 + stab_attack: 5 + strength_bonus: 4 +value: 8 +weapon_type: melee diff --git a/data/items/equipment/bronze_full_helm.yaml b/data/items/equipment/bronze_full_helm.yaml index ed006a8..1d82567 100644 --- a/data/items/equipment/bronze_full_helm.yaml +++ b/data/items/equipment/bronze_full_helm.yaml @@ -1,13 +1,25 @@ +color: "178" +craft: + consume: + - items: + - bronze_bar + quantity: 2 + level: 7 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 25 +description: A bronze full helmet. +equip_slot: head id: bronze_full_helm name: bronze full helm -color: "178" -description: "A bronze full helmet." -value: 20 stackable: false -equip_slot: head stats: - stab_defense: 5 - slash_defense: 6 - crush_defense: 4 - science_defense: -3 - ranged_defense: 5 + crush_defense: 4 + ranged_defense: 5 + science_defense: -3 + slash_defense: 6 + stab_defense: 5 +value: 20 diff --git a/data/items/equipment/bronze_med_helm.yaml b/data/items/equipment/bronze_med_helm.yaml index c9635cf..b1cb0db 100644 --- a/data/items/equipment/bronze_med_helm.yaml +++ b/data/items/equipment/bronze_med_helm.yaml @@ -1,13 +1,25 @@ +color: "178" +craft: + consume: + - items: + - bronze_bar + quantity: 1 + level: 3 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 12 +description: A bronze medium helmet. +equip_slot: head id: bronze_med_helm name: bronze med helm -color: "178" -description: "A bronze medium helmet." -value: 8 stackable: false -equip_slot: head stats: - stab_defense: 3 - slash_defense: 4 - crush_defense: 2 - science_defense: -1 - ranged_defense: 3 + crush_defense: 2 + ranged_defense: 3 + science_defense: -1 + slash_defense: 4 + stab_defense: 3 +value: 8 diff --git a/data/items/equipment/bronze_platebody.yaml b/data/items/equipment/bronze_platebody.yaml index 8e6dd2c..95bc528 100644 --- a/data/items/equipment/bronze_platebody.yaml +++ b/data/items/equipment/bronze_platebody.yaml @@ -1,13 +1,25 @@ +color: "178" +craft: + consume: + - items: + - bronze_bar + quantity: 5 + level: 18 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 62 +description: A bronze platebody. +equip_slot: torso id: bronze_platebody name: bronze platebody -color: "178" -description: "A bronze platebody." -value: 60 stackable: false -equip_slot: torso stats: - stab_defense: 12 - slash_defense: 15 - crush_defense: 10 - science_defense: -10 - ranged_defense: 12 + crush_defense: 10 + ranged_defense: 12 + science_defense: -10 + slash_defense: 15 + stab_defense: 12 +value: 60 diff --git a/data/items/equipment/bronze_sword.yaml b/data/items/equipment/bronze_sword.yaml index 0cfdd0e..7645076 100644 --- a/data/items/equipment/bronze_sword.yaml +++ b/data/items/equipment/bronze_sword.yaml @@ -1,15 +1,27 @@ +attack_type: slash +color: "178" +craft: + consume: + - items: + - bronze_bar + quantity: 1 + level: 4 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 12 +description: A basic bronze sword. +equip_slot: main_hand id: bronze_sword name: bronze sword -color: "178" -description: "A basic bronze sword." -value: 12 +speed: 4 stackable: false -equip_slot: main_hand -weapon_type: melee -attack_type: slash stats: - stab_attack: 4 - slash_attack: 10 - crush_attack: -2 - strength_bonus: 7 -speed: 4 + crush_attack: -2 + slash_attack: 10 + stab_attack: 4 + strength_bonus: 7 +value: 12 +weapon_type: melee diff --git a/data/items/equipment/coif.yaml b/data/items/equipment/coif.yaml index 8d910d7..3ba300e 100644 --- a/data/items/equipment/coif.yaml +++ b/data/items/equipment/coif.yaml @@ -1,16 +1,31 @@ -id: coif -name: coif color: "94" -description: "A hard leather coif." -value: 45 +craft: + consume: + - items: + - hard_leather + quantity: 1 + - items: + - thread + quantity: 1 + level: 38 + message: You craft a coif. + skill: crafting + tool: needle + type: crafting + wait: 4 + xp: 37 +description: A hard leather coif. equip_slot: head -stats: - stab_defense: 2 - slash_defense: 4 - crush_defense: 2 - science_defense: 4 - ranged_defense: 6 - ranged_attack: 2 +id: coif +name: coif requirements: - defense: 20 - ranged: 20 + defense: 20 + ranged: 20 +stats: + crush_defense: 2 + ranged_attack: 2 + ranged_defense: 6 + science_defense: 4 + slash_defense: 4 + stab_defense: 2 +value: 45 diff --git a/data/items/equipment/diamond_amulet_u.yaml b/data/items/equipment/diamond_amulet_u.yaml index 55eaf45..f46fb8b 100644 --- a/data/items/equipment/diamond_amulet_u.yaml +++ b/data/items/equipment/diamond_amulet_u.yaml @@ -1,5 +1,26 @@ +color: "255" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - items: + - diamond + quantity: 1 + - byproducts: + - amulet_mould + items: + - amulet_mould + quantity: 1 + level: 70 + message: You cast a diamond amulet. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 100 +description: An unstrung gold amulet set with a diamond. id: diamond_amulet_u name: diamond amulet (u) -color: "255" -description: "An unstrung gold amulet set with a diamond." value: 200 diff --git a/data/items/equipment/diamond_bracelet.yaml b/data/items/equipment/diamond_bracelet.yaml index 5ba5778..c409d4a 100644 --- a/data/items/equipment/diamond_bracelet.yaml +++ b/data/items/equipment/diamond_bracelet.yaml @@ -1,6 +1,27 @@ +color: "255" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - items: + - diamond + quantity: 1 + - byproducts: + - bracelet_mould + items: + - bracelet_mould + quantity: 1 + level: 58 + message: You cast a diamond bracelet. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 95 +description: A bracelet set with a diamond. Can be enchanted. +equip_slot: hands id: diamond_bracelet name: diamond bracelet -color: "255" -description: "A bracelet set with a diamond. Can be enchanted." value: 1500 -equip_slot: hands diff --git a/data/items/equipment/diamond_necklace.yaml b/data/items/equipment/diamond_necklace.yaml index 5629b8c..c53d1cc 100644 --- a/data/items/equipment/diamond_necklace.yaml +++ b/data/items/equipment/diamond_necklace.yaml @@ -1,6 +1,27 @@ +color: "255" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - items: + - diamond + quantity: 1 + - byproducts: + - necklace_mould + items: + - necklace_mould + quantity: 1 + level: 56 + message: You cast a diamond necklace. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 90 +description: A necklace set with a diamond. Can be enchanted. +equip_slot: neck id: diamond_necklace name: diamond necklace -color: "255" -description: "A necklace set with a diamond. Can be enchanted." value: 1600 -equip_slot: neck diff --git a/data/items/equipment/diamond_ring.yaml b/data/items/equipment/diamond_ring.yaml index 54023c3..36d13d8 100644 --- a/data/items/equipment/diamond_ring.yaml +++ b/data/items/equipment/diamond_ring.yaml @@ -1,6 +1,27 @@ +color: "255" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - items: + - diamond + quantity: 1 + - byproducts: + - ring_mould + items: + - ring_mould + quantity: 1 + level: 43 + message: You cast a diamond ring. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 85 +description: A ring set with a diamond. Can be enchanted. +equip_slot: ring id: diamond_ring name: diamond ring -color: "255" -description: "A ring set with a diamond. Can be enchanted." value: 1500 -equip_slot: ring diff --git a/data/items/equipment/emerald_amulet_u.yaml b/data/items/equipment/emerald_amulet_u.yaml index 87261d4..69a76d5 100644 --- a/data/items/equipment/emerald_amulet_u.yaml +++ b/data/items/equipment/emerald_amulet_u.yaml @@ -1,5 +1,26 @@ +color: "83" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - items: + - emerald + quantity: 1 + - byproducts: + - amulet_mould + items: + - amulet_mould + quantity: 1 + level: 31 + message: You cast a emerald amulet. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 70 +description: An unstrung gold amulet set with a emerald. id: emerald_amulet_u name: emerald amulet (u) -color: "83" -description: "An unstrung gold amulet set with a emerald." value: 110 diff --git a/data/items/equipment/emerald_bracelet.yaml b/data/items/equipment/emerald_bracelet.yaml index 04e4979..a809c50 100644 --- a/data/items/equipment/emerald_bracelet.yaml +++ b/data/items/equipment/emerald_bracelet.yaml @@ -1,6 +1,27 @@ +color: "34" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - items: + - emerald + quantity: 1 + - byproducts: + - bracelet_mould + items: + - bracelet_mould + quantity: 1 + level: 30 + message: You cast a emerald bracelet. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 65 +description: A bracelet set with an emerald. Can be enchanted. +equip_slot: hands id: emerald_bracelet name: emerald bracelet -color: "34" -description: "A bracelet set with an emerald. Can be enchanted." value: 400 -equip_slot: hands diff --git a/data/items/equipment/emerald_necklace.yaml b/data/items/equipment/emerald_necklace.yaml index 2107ca4..44d7528 100644 --- a/data/items/equipment/emerald_necklace.yaml +++ b/data/items/equipment/emerald_necklace.yaml @@ -1,6 +1,27 @@ +color: "34" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - items: + - emerald + quantity: 1 + - byproducts: + - necklace_mould + items: + - necklace_mould + quantity: 1 + level: 29 + message: You cast a emerald necklace. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 60 +description: A necklace set with an emerald. Can be enchanted. +equip_slot: neck id: emerald_necklace name: emerald necklace -color: "34" -description: "A necklace set with an emerald. Can be enchanted." value: 450 -equip_slot: neck diff --git a/data/items/equipment/emerald_ring.yaml b/data/items/equipment/emerald_ring.yaml index 253f872..8ef1d4a 100644 --- a/data/items/equipment/emerald_ring.yaml +++ b/data/items/equipment/emerald_ring.yaml @@ -1,6 +1,27 @@ +color: "34" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - items: + - emerald + quantity: 1 + - byproducts: + - ring_mould + items: + - ring_mould + quantity: 1 + level: 27 + message: You cast a emerald ring. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 55 +description: A ring set with an emerald. Can be enchanted. +equip_slot: ring id: emerald_ring name: emerald ring -color: "34" -description: "A ring set with an emerald. Can be enchanted." value: 400 -equip_slot: ring diff --git a/data/items/equipment/gold_amulet_u.yaml b/data/items/equipment/gold_amulet_u.yaml index 8671941..2aebbe5 100644 --- a/data/items/equipment/gold_amulet_u.yaml +++ b/data/items/equipment/gold_amulet_u.yaml @@ -1,5 +1,23 @@ +color: "220" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - byproducts: + - amulet_mould + items: + - amulet_mould + quantity: 1 + level: 8 + message: You cast a gold amulet. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 30 +description: An unstrung gold amulet. id: gold_amulet_u name: gold amulet (u) -color: "220" -description: "An unstrung gold amulet." value: 70 diff --git a/data/items/equipment/gold_bracelet.yaml b/data/items/equipment/gold_bracelet.yaml index 2c4534f..8c3f2af 100644 --- a/data/items/equipment/gold_bracelet.yaml +++ b/data/items/equipment/gold_bracelet.yaml @@ -1,6 +1,24 @@ +color: "220" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - byproducts: + - bracelet_mould + items: + - bracelet_mould + quantity: 1 + level: 7 + message: You cast a gold bracelet. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 25 +description: A gold bracelet. +equip_slot: hands id: gold_bracelet name: gold bracelet -color: "220" -description: "A gold bracelet." value: 65 -equip_slot: hands diff --git a/data/items/equipment/gold_necklace.yaml b/data/items/equipment/gold_necklace.yaml index 4a22ac1..569e9b6 100644 --- a/data/items/equipment/gold_necklace.yaml +++ b/data/items/equipment/gold_necklace.yaml @@ -1,6 +1,24 @@ +color: "220" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - byproducts: + - necklace_mould + items: + - necklace_mould + quantity: 1 + level: 6 + message: You cast a gold necklace. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 20 +description: A gold necklace. +equip_slot: neck id: gold_necklace name: gold necklace -color: "220" -description: "A gold necklace." value: 60 -equip_slot: neck diff --git a/data/items/equipment/gold_ring.yaml b/data/items/equipment/gold_ring.yaml index 1a39165..7a71889 100644 --- a/data/items/equipment/gold_ring.yaml +++ b/data/items/equipment/gold_ring.yaml @@ -1,6 +1,24 @@ +color: "220" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - byproducts: + - ring_mould + items: + - ring_mould + quantity: 1 + level: 5 + message: You cast a gold ring. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 15 +description: A simple gold ring. +equip_slot: ring id: gold_ring name: gold ring -color: "220" -description: "A simple gold ring." value: 50 -equip_slot: ring diff --git a/data/items/equipment/hard_leather_body.yaml b/data/items/equipment/hard_leather_body.yaml index a5fe30f..6c48cee 100644 --- a/data/items/equipment/hard_leather_body.yaml +++ b/data/items/equipment/hard_leather_body.yaml @@ -1,14 +1,29 @@ -id: hard_leather_body -name: hard leather body color: "94" -description: "A hardened leather body armour." -value: 60 +craft: + consume: + - items: + - hard_leather + quantity: 1 + - items: + - thread + quantity: 1 + level: 28 + message: You craft a hard leather body. + skill: crafting + tool: needle + type: crafting + wait: 4 + xp: 35 +description: A hardened leather body armour. equip_slot: torso -stats: - stab_defense: 8 - slash_defense: 12 - crush_defense: 8 - science_defense: 6 - ranged_defense: 14 +id: hard_leather_body +name: hard leather body requirements: - defense: 10 + defense: 10 +stats: + crush_defense: 8 + ranged_defense: 14 + science_defense: 6 + slash_defense: 12 + stab_defense: 8 +value: 60 diff --git a/data/items/equipment/hard_leather_shield.yaml b/data/items/equipment/hard_leather_shield.yaml index fd7dabf..4d8e16d 100644 --- a/data/items/equipment/hard_leather_shield.yaml +++ b/data/items/equipment/hard_leather_shield.yaml @@ -1,14 +1,29 @@ -id: hard_leather_shield -name: hard leather shield color: "94" -description: "A shield made of hardened leather." -value: 55 +craft: + consume: + - items: + - hard_leather + quantity: 1 + - items: + - thread + quantity: 1 + level: 41 + message: You craft a hard leather shield. + skill: crafting + tool: needle + type: crafting + wait: 4 + xp: 40 +description: A shield made of hardened leather. equip_slot: off_hand -stats: - stab_defense: 5 - slash_defense: 7 - crush_defense: 5 - science_defense: 4 - ranged_defense: 8 +id: hard_leather_shield +name: hard leather shield requirements: - defense: 10 + defense: 10 +stats: + crush_defense: 5 + ranged_defense: 8 + science_defense: 4 + slash_defense: 7 + stab_defense: 5 +value: 55 diff --git a/data/items/equipment/iron_dagger.yaml b/data/items/equipment/iron_dagger.yaml index 8fa645c..5c332e2 100644 --- a/data/items/equipment/iron_dagger.yaml +++ b/data/items/equipment/iron_dagger.yaml @@ -1,15 +1,27 @@ +attack_type: stab +color: "250" +craft: + consume: + - items: + - iron_bar + quantity: 1 + level: 20 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 25 +description: A small iron dagger. +equip_slot: main_hand id: iron_dagger name: iron dagger -color: "250" -description: "A small iron dagger." -value: 20 +speed: 3 stackable: false -equip_slot: main_hand -weapon_type: melee -attack_type: stab stats: - stab_attack: 8 - slash_attack: 5 - crush_attack: -1 - strength_bonus: 7 -speed: 3 + crush_attack: -1 + slash_attack: 5 + stab_attack: 8 + strength_bonus: 7 +value: 20 +weapon_type: melee diff --git a/data/items/equipment/iron_full_helm.yaml b/data/items/equipment/iron_full_helm.yaml index 3a2fc0c..6f96338 100644 --- a/data/items/equipment/iron_full_helm.yaml +++ b/data/items/equipment/iron_full_helm.yaml @@ -1,13 +1,25 @@ +color: "250" +craft: + consume: + - items: + - iron_bar + quantity: 2 + level: 27 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 50 +description: An iron full helmet. +equip_slot: head id: iron_full_helm name: iron full helm -color: "250" -description: "An iron full helmet." -value: 50 stackable: false -equip_slot: head stats: - stab_defense: 8 - slash_defense: 9 - crush_defense: 6 - science_defense: -3 - ranged_defense: 8 + crush_defense: 6 + ranged_defense: 8 + science_defense: -3 + slash_defense: 9 + stab_defense: 8 +value: 50 diff --git a/data/items/equipment/iron_med_helm.yaml b/data/items/equipment/iron_med_helm.yaml index 6956283..7f6aef5 100644 --- a/data/items/equipment/iron_med_helm.yaml +++ b/data/items/equipment/iron_med_helm.yaml @@ -1,13 +1,25 @@ +color: "250" +craft: + consume: + - items: + - iron_bar + quantity: 1 + level: 22 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 25 +description: An iron medium helmet. +equip_slot: head id: iron_med_helm name: iron med helm -color: "250" -description: "An iron medium helmet." -value: 20 stackable: false -equip_slot: head stats: - stab_defense: 5 - slash_defense: 6 - crush_defense: 3 - science_defense: -1 - ranged_defense: 5 + crush_defense: 3 + ranged_defense: 5 + science_defense: -1 + slash_defense: 6 + stab_defense: 5 +value: 20 diff --git a/data/items/equipment/iron_platebody.yaml b/data/items/equipment/iron_platebody.yaml index 3c0be80..8d5d300 100644 --- a/data/items/equipment/iron_platebody.yaml +++ b/data/items/equipment/iron_platebody.yaml @@ -1,13 +1,25 @@ +color: "250" +craft: + consume: + - items: + - iron_bar + quantity: 5 + level: 33 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 125 +description: An iron platebody. +equip_slot: torso id: iron_platebody name: iron platebody -color: "250" -description: "An iron platebody." -value: 150 stackable: false -equip_slot: torso stats: - stab_defense: 18 - slash_defense: 22 - crush_defense: 14 - science_defense: -10 - ranged_defense: 18 + crush_defense: 14 + ranged_defense: 18 + science_defense: -10 + slash_defense: 22 + stab_defense: 18 +value: 150 diff --git a/data/items/equipment/iron_sword.yaml b/data/items/equipment/iron_sword.yaml index a5711fc..a975cc4 100644 --- a/data/items/equipment/iron_sword.yaml +++ b/data/items/equipment/iron_sword.yaml @@ -1,15 +1,27 @@ +attack_type: slash +color: "250" +craft: + consume: + - items: + - iron_bar + quantity: 1 + level: 24 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 25 +description: An iron sword. +equip_slot: main_hand id: iron_sword name: iron sword -color: "250" -description: "An iron sword." -value: 30 +speed: 4 stackable: false -equip_slot: main_hand -weapon_type: melee -attack_type: slash stats: - stab_attack: 7 - slash_attack: 15 - crush_attack: -2 - strength_bonus: 10 -speed: 4 + crush_attack: -2 + slash_attack: 15 + stab_attack: 7 + strength_bonus: 10 +value: 30 +weapon_type: melee diff --git a/data/items/equipment/leather_body.yaml b/data/items/equipment/leather_body.yaml index e69342c..0e5b864 100644 --- a/data/items/equipment/leather_body.yaml +++ b/data/items/equipment/leather_body.yaml @@ -1,12 +1,27 @@ -id: leather_body -name: leather body color: "130" -description: "A leather body armour." -value: 25 +craft: + consume: + - items: + - leather + quantity: 1 + - items: + - thread + quantity: 1 + level: 14 + message: You craft a leather body. + skill: crafting + tool: needle + type: crafting + wait: 4 + xp: 25 +description: A leather body armour. equip_slot: torso +id: leather_body +name: leather body stats: - stab_defense: 4 - slash_defense: 7 - crush_defense: 5 - science_defense: 4 - ranged_defense: 10 + crush_defense: 5 + ranged_defense: 10 + science_defense: 4 + slash_defense: 7 + stab_defense: 4 +value: 25 diff --git a/data/items/equipment/leather_boots.yaml b/data/items/equipment/leather_boots.yaml index 7716e95..7cea340 100644 --- a/data/items/equipment/leather_boots.yaml +++ b/data/items/equipment/leather_boots.yaml @@ -1,12 +1,27 @@ -id: leather_boots -name: leather boots color: "130" -description: "A pair of leather boots." -value: 12 +craft: + consume: + - items: + - leather + quantity: 1 + - items: + - thread + quantity: 1 + level: 7 + message: You craft a pair of leather boots. + skill: crafting + tool: needle + type: crafting + wait: 4 + xp: 16 +description: A pair of leather boots. equip_slot: feet +id: leather_boots +name: leather boots stats: - stab_defense: 1 - slash_defense: 1 - crush_defense: 1 - science_defense: 1 - ranged_defense: 2 + crush_defense: 1 + ranged_defense: 2 + science_defense: 1 + slash_defense: 1 + stab_defense: 1 +value: 12 diff --git a/data/items/equipment/leather_chaps.yaml b/data/items/equipment/leather_chaps.yaml index 1a17c16..0c2dd44 100644 --- a/data/items/equipment/leather_chaps.yaml +++ b/data/items/equipment/leather_chaps.yaml @@ -1,12 +1,27 @@ -id: leather_chaps -name: leather chaps color: "130" -description: "A pair of leather chaps." -value: 20 +craft: + consume: + - items: + - leather + quantity: 1 + - items: + - thread + quantity: 1 + level: 18 + message: You craft a pair of leather chaps. + skill: crafting + tool: needle + type: crafting + wait: 4 + xp: 27 +description: A pair of leather chaps. equip_slot: legs +id: leather_chaps +name: leather chaps stats: - stab_defense: 2 - slash_defense: 4 - crush_defense: 3 - science_defense: 3 - ranged_defense: 6 + crush_defense: 3 + ranged_defense: 6 + science_defense: 3 + slash_defense: 4 + stab_defense: 2 +value: 20 diff --git a/data/items/equipment/leather_cowl.yaml b/data/items/equipment/leather_cowl.yaml index aa5965a..0c1ab0d 100644 --- a/data/items/equipment/leather_cowl.yaml +++ b/data/items/equipment/leather_cowl.yaml @@ -1,12 +1,27 @@ -id: leather_cowl -name: leather cowl color: "130" -description: "A leather cowl." -value: 15 +craft: + consume: + - items: + - leather + quantity: 1 + - items: + - thread + quantity: 1 + level: 9 + message: You craft a leather cowl. + skill: crafting + tool: needle + type: crafting + wait: 4 + xp: 19 +description: A leather cowl. equip_slot: head +id: leather_cowl +name: leather cowl stats: - stab_defense: 1 - slash_defense: 2 - crush_defense: 1 - science_defense: 2 - ranged_defense: 4 + crush_defense: 1 + ranged_defense: 4 + science_defense: 2 + slash_defense: 2 + stab_defense: 1 +value: 15 diff --git a/data/items/equipment/leather_gloves.yaml b/data/items/equipment/leather_gloves.yaml index 7590fee..a526ab4 100644 --- a/data/items/equipment/leather_gloves.yaml +++ b/data/items/equipment/leather_gloves.yaml @@ -1,12 +1,27 @@ -id: leather_gloves -name: leather gloves color: "130" -description: "A pair of leather gloves." -value: 10 +craft: + consume: + - items: + - leather + quantity: 1 + - items: + - thread + quantity: 1 + level: 1 + message: You craft a pair of leather gloves. + skill: crafting + tool: needle + type: crafting + wait: 4 + xp: 14 +description: A pair of leather gloves. equip_slot: hands +id: leather_gloves +name: leather gloves stats: - stab_defense: 1 - slash_defense: 1 - crush_defense: 1 - science_defense: 1 - ranged_defense: 2 + crush_defense: 1 + ranged_defense: 2 + science_defense: 1 + slash_defense: 1 + stab_defense: 1 +value: 10 diff --git a/data/items/equipment/leather_vambraces.yaml b/data/items/equipment/leather_vambraces.yaml index fa59aa9..b23e190 100644 --- a/data/items/equipment/leather_vambraces.yaml +++ b/data/items/equipment/leather_vambraces.yaml @@ -1,13 +1,28 @@ -id: leather_vambraces -name: leather vambraces color: "130" -description: "A pair of leather vambraces." -value: 18 +craft: + consume: + - items: + - leather + quantity: 1 + - items: + - thread + quantity: 1 + level: 11 + message: You craft a pair of leather vambraces. + skill: crafting + tool: needle + type: crafting + wait: 4 + xp: 22 +description: A pair of leather vambraces. equip_slot: hands +id: leather_vambraces +name: leather vambraces stats: - stab_defense: 2 - slash_defense: 2 - crush_defense: 2 - science_defense: 2 - ranged_defense: 4 - ranged_attack: 4 + crush_defense: 2 + ranged_attack: 4 + ranged_defense: 4 + science_defense: 2 + slash_defense: 2 + stab_defense: 2 +value: 18 diff --git a/data/items/equipment/longbow.yaml b/data/items/equipment/longbow.yaml index f40c96d..ee6f68b 100644 --- a/data/items/equipment/longbow.yaml +++ b/data/items/equipment/longbow.yaml @@ -1,11 +1,24 @@ -id: longbow -name: longbow +attack_type: ranged color: "137" -description: "A longbow." -value: 20 +craft: + consume: + - items: + - longbow_u + quantity: 1 + - items: + - bowstring + quantity: 1 + level: 10 + skill: fletching + type: fletching + wait: 2 + xp: 10 +description: A longbow. equip_slot: main_hand -weapon_type: ranged -attack_type: ranged +id: longbow +name: longbow speed: 6 stats: - ranged_attack: 8 + ranged_attack: 8 +value: 20 +weapon_type: ranged diff --git a/data/items/equipment/longbow_u.yaml b/data/items/equipment/longbow_u.yaml index 93e5ff0..d368141 100644 --- a/data/items/equipment/longbow_u.yaml +++ b/data/items/equipment/longbow_u.yaml @@ -1,5 +1,16 @@ +color: "137" +craft: + consume: + - items: + - logs + quantity: 1 + level: 10 + skill: fletching + tool: knife + type: fletching + wait: 3 + xp: 10 +description: An unstrung longbow. id: longbow_u name: longbow (u) -color: "137" -description: "An unstrung longbow." value: 10 diff --git a/data/items/equipment/magic_longbow.yaml b/data/items/equipment/magic_longbow.yaml index 07797fb..ebc6adc 100644 --- a/data/items/equipment/magic_longbow.yaml +++ b/data/items/equipment/magic_longbow.yaml @@ -1,13 +1,26 @@ -id: magic_longbow -name: magic longbow +attack_type: ranged color: "63" -description: "A magic longbow." -value: 6000 +craft: + consume: + - items: + - magic_longbow_u + quantity: 1 + - items: + - bowstring + quantity: 1 + level: 85 + skill: fletching + type: fletching + wait: 2 + xp: 91 +description: A magic longbow. equip_slot: main_hand -weapon_type: ranged -attack_type: ranged +id: magic_longbow +name: magic longbow +requirements: + ranged: 50 speed: 6 stats: - ranged_attack: 69 -requirements: - ranged: 50 + ranged_attack: 69 +value: 6000 +weapon_type: ranged diff --git a/data/items/equipment/magic_longbow_u.yaml b/data/items/equipment/magic_longbow_u.yaml index 65682ed..45a211b 100644 --- a/data/items/equipment/magic_longbow_u.yaml +++ b/data/items/equipment/magic_longbow_u.yaml @@ -1,5 +1,16 @@ +color: "63" +craft: + consume: + - items: + - magic_logs + quantity: 1 + level: 85 + skill: fletching + tool: knife + type: fletching + wait: 3 + xp: 91 +description: An unstrung magic longbow. id: magic_longbow_u name: magic longbow (u) -color: "63" -description: "An unstrung magic longbow." value: 3000 diff --git a/data/items/equipment/magic_shortbow.yaml b/data/items/equipment/magic_shortbow.yaml index 893b287..ad28f22 100644 --- a/data/items/equipment/magic_shortbow.yaml +++ b/data/items/equipment/magic_shortbow.yaml @@ -1,13 +1,26 @@ -id: magic_shortbow -name: magic shortbow +attack_type: ranged color: "63" -description: "A magic shortbow." -value: 4000 +craft: + consume: + - items: + - magic_shortbow_u + quantity: 1 + - items: + - bowstring + quantity: 1 + level: 80 + skill: fletching + type: fletching + wait: 2 + xp: 83 +description: A magic shortbow. equip_slot: main_hand -weapon_type: ranged -attack_type: ranged +id: magic_shortbow +name: magic shortbow +requirements: + ranged: 50 speed: 4 stats: - ranged_attack: 69 -requirements: - ranged: 50 + ranged_attack: 69 +value: 4000 +weapon_type: ranged diff --git a/data/items/equipment/magic_shortbow_u.yaml b/data/items/equipment/magic_shortbow_u.yaml index 2075bd1..fa301b2 100644 --- a/data/items/equipment/magic_shortbow_u.yaml +++ b/data/items/equipment/magic_shortbow_u.yaml @@ -1,5 +1,16 @@ +color: "63" +craft: + consume: + - items: + - magic_logs + quantity: 1 + level: 80 + skill: fletching + tool: knife + type: fletching + wait: 3 + xp: 83 +description: An unstrung magic shortbow. id: magic_shortbow_u name: magic shortbow (u) -color: "63" -description: "An unstrung magic shortbow." value: 2000 diff --git a/data/items/equipment/maple_longbow.yaml b/data/items/equipment/maple_longbow.yaml index 1c86128..5ceeab6 100644 --- a/data/items/equipment/maple_longbow.yaml +++ b/data/items/equipment/maple_longbow.yaml @@ -1,13 +1,26 @@ -id: maple_longbow -name: maple longbow +attack_type: ranged color: "172" -description: "A maple longbow." -value: 1280 +craft: + consume: + - items: + - maple_longbow_u + quantity: 1 + - items: + - bowstring + quantity: 1 + level: 55 + skill: fletching + type: fletching + wait: 2 + xp: 58 +description: A maple longbow. equip_slot: main_hand -weapon_type: ranged -attack_type: ranged +id: maple_longbow +name: maple longbow +requirements: + ranged: 30 speed: 6 stats: - ranged_attack: 29 -requirements: - ranged: 30 + ranged_attack: 29 +value: 1280 +weapon_type: ranged diff --git a/data/items/equipment/maple_longbow_u.yaml b/data/items/equipment/maple_longbow_u.yaml index 120bf1d..3eb4f4d 100644 --- a/data/items/equipment/maple_longbow_u.yaml +++ b/data/items/equipment/maple_longbow_u.yaml @@ -1,5 +1,16 @@ +color: "172" +craft: + consume: + - items: + - maple_logs + quantity: 1 + level: 55 + skill: fletching + tool: knife + type: fletching + wait: 3 + xp: 58 +description: An unstrung maple longbow. id: maple_longbow_u name: maple longbow (u) -color: "172" -description: "An unstrung maple longbow." value: 640 diff --git a/data/items/equipment/maple_shortbow.yaml b/data/items/equipment/maple_shortbow.yaml index 38c27b5..0d02157 100644 --- a/data/items/equipment/maple_shortbow.yaml +++ b/data/items/equipment/maple_shortbow.yaml @@ -1,13 +1,26 @@ -id: maple_shortbow -name: maple shortbow +attack_type: ranged color: "172" -description: "A maple shortbow." -value: 640 +craft: + consume: + - items: + - maple_shortbow_u + quantity: 1 + - items: + - bowstring + quantity: 1 + level: 50 + skill: fletching + type: fletching + wait: 2 + xp: 50 +description: A maple shortbow. equip_slot: main_hand -weapon_type: ranged -attack_type: ranged +id: maple_shortbow +name: maple shortbow +requirements: + ranged: 30 speed: 4 stats: - ranged_attack: 29 -requirements: - ranged: 30 + ranged_attack: 29 +value: 640 +weapon_type: ranged diff --git a/data/items/equipment/maple_shortbow_u.yaml b/data/items/equipment/maple_shortbow_u.yaml index 6fc6b84..c734aad 100644 --- a/data/items/equipment/maple_shortbow_u.yaml +++ b/data/items/equipment/maple_shortbow_u.yaml @@ -1,5 +1,16 @@ +color: "172" +craft: + consume: + - items: + - maple_logs + quantity: 1 + level: 50 + skill: fletching + tool: knife + type: fletching + wait: 3 + xp: 50 +description: An unstrung maple shortbow. id: maple_shortbow_u name: maple shortbow (u) -color: "172" -description: "An unstrung maple shortbow." value: 320 diff --git a/data/items/equipment/mithril_dagger.yaml b/data/items/equipment/mithril_dagger.yaml index 8ffe595..0d531e1 100644 --- a/data/items/equipment/mithril_dagger.yaml +++ b/data/items/equipment/mithril_dagger.yaml @@ -1,17 +1,29 @@ +attack_type: stab +color: "75" +craft: + consume: + - items: + - mithril_bar + quantity: 1 + level: 50 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 50 +description: A small mithril dagger. +equip_slot: main_hand id: mithril_dagger name: mithril dagger -color: "75" -description: "A small mithril dagger." -value: 150 +requirements: + attack: 20 +speed: 3 stackable: false -equip_slot: main_hand -weapon_type: melee -attack_type: stab stats: - stab_attack: 17 - slash_attack: 10 - crush_attack: -1 - strength_bonus: 14 -speed: 3 -requirements: - attack: 20 + crush_attack: -1 + slash_attack: 10 + stab_attack: 17 + strength_bonus: 14 +value: 150 +weapon_type: melee diff --git a/data/items/equipment/mithril_full_helm.yaml b/data/items/equipment/mithril_full_helm.yaml index d317705..bf69b5f 100644 --- a/data/items/equipment/mithril_full_helm.yaml +++ b/data/items/equipment/mithril_full_helm.yaml @@ -1,15 +1,27 @@ +color: "75" +craft: + consume: + - items: + - mithril_bar + quantity: 2 + level: 57 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 100 +description: A mithril full helmet. +equip_slot: head id: mithril_full_helm name: mithril full helm -color: "75" -description: "A mithril full helmet." -value: 400 +requirements: + defense: 20 stackable: false -equip_slot: head stats: - stab_defense: 16 - slash_defense: 18 - crush_defense: 12 - science_defense: -6 - ranged_defense: 16 -requirements: - defense: 20 + crush_defense: 12 + ranged_defense: 16 + science_defense: -6 + slash_defense: 18 + stab_defense: 16 +value: 400 diff --git a/data/items/equipment/mithril_med_helm.yaml b/data/items/equipment/mithril_med_helm.yaml index f244a7c..c680ff4 100644 --- a/data/items/equipment/mithril_med_helm.yaml +++ b/data/items/equipment/mithril_med_helm.yaml @@ -1,15 +1,27 @@ +color: "75" +craft: + consume: + - items: + - mithril_bar + quantity: 1 + level: 53 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 50 +description: A mithril medium helmet. +equip_slot: head id: mithril_med_helm name: mithril med helm -color: "75" -description: "A mithril medium helmet." -value: 150 +requirements: + defense: 20 stackable: false -equip_slot: head stats: - stab_defense: 10 - slash_defense: 12 - crush_defense: 7 - science_defense: -3 - ranged_defense: 10 -requirements: - defense: 20 + crush_defense: 7 + ranged_defense: 10 + science_defense: -3 + slash_defense: 12 + stab_defense: 10 +value: 150 diff --git a/data/items/equipment/mithril_platebody.yaml b/data/items/equipment/mithril_platebody.yaml index 50e8ea0..1ff3d03 100644 --- a/data/items/equipment/mithril_platebody.yaml +++ b/data/items/equipment/mithril_platebody.yaml @@ -1,15 +1,27 @@ +color: "75" +craft: + consume: + - items: + - mithril_bar + quantity: 5 + level: 68 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 250 +description: A mithril platebody. +equip_slot: torso id: mithril_platebody name: mithril platebody -color: "75" -description: "A mithril platebody." -value: 1500 +requirements: + defense: 20 stackable: false -equip_slot: torso stats: - stab_defense: 36 - slash_defense: 42 - crush_defense: 30 - science_defense: -20 - ranged_defense: 36 -requirements: - defense: 20 + crush_defense: 30 + ranged_defense: 36 + science_defense: -20 + slash_defense: 42 + stab_defense: 36 +value: 1500 diff --git a/data/items/equipment/mithril_sword.yaml b/data/items/equipment/mithril_sword.yaml index 1824f5b..53dcd25 100644 --- a/data/items/equipment/mithril_sword.yaml +++ b/data/items/equipment/mithril_sword.yaml @@ -1,17 +1,29 @@ +attack_type: slash +color: "75" +craft: + consume: + - items: + - mithril_bar + quantity: 1 + level: 54 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 50 +description: A mithril sword. +equip_slot: main_hand id: mithril_sword name: mithril sword -color: "75" -description: "A mithril sword." -value: 250 +requirements: + attack: 20 +speed: 4 stackable: false -equip_slot: main_hand -weapon_type: melee -attack_type: slash stats: - stab_attack: 14 - slash_attack: 30 - crush_attack: -2 - strength_bonus: 20 -speed: 4 -requirements: - attack: 20 + crush_attack: -2 + slash_attack: 30 + stab_attack: 14 + strength_bonus: 20 +value: 250 +weapon_type: melee diff --git a/data/items/equipment/oak_longbow.yaml b/data/items/equipment/oak_longbow.yaml index 71e7c7c..07848d0 100644 --- a/data/items/equipment/oak_longbow.yaml +++ b/data/items/equipment/oak_longbow.yaml @@ -1,13 +1,26 @@ -id: oak_longbow -name: oak longbow +attack_type: ranged color: "136" -description: "An oak longbow." -value: 80 +craft: + consume: + - items: + - oak_longbow_u + quantity: 1 + - items: + - bowstring + quantity: 1 + level: 25 + skill: fletching + type: fletching + wait: 2 + xp: 25 +description: An oak longbow. equip_slot: main_hand -weapon_type: ranged -attack_type: ranged +id: oak_longbow +name: oak longbow +requirements: + ranged: 5 speed: 6 stats: - ranged_attack: 14 -requirements: - ranged: 5 + ranged_attack: 14 +value: 80 +weapon_type: ranged diff --git a/data/items/equipment/oak_longbow_u.yaml b/data/items/equipment/oak_longbow_u.yaml index 6df0dab..5ed7742 100644 --- a/data/items/equipment/oak_longbow_u.yaml +++ b/data/items/equipment/oak_longbow_u.yaml @@ -1,5 +1,16 @@ +color: "136" +craft: + consume: + - items: + - oak_logs + quantity: 1 + level: 25 + skill: fletching + tool: knife + type: fletching + wait: 3 + xp: 25 +description: An unstrung oak longbow. id: oak_longbow_u name: oak longbow (u) -color: "136" -description: "An unstrung oak longbow." value: 40 diff --git a/data/items/equipment/oak_shortbow.yaml b/data/items/equipment/oak_shortbow.yaml index 30ebbce..187970f 100644 --- a/data/items/equipment/oak_shortbow.yaml +++ b/data/items/equipment/oak_shortbow.yaml @@ -1,13 +1,26 @@ -id: oak_shortbow -name: oak shortbow +attack_type: ranged color: "136" -description: "An oak shortbow." -value: 40 +craft: + consume: + - items: + - oak_shortbow_u + quantity: 1 + - items: + - bowstring + quantity: 1 + level: 20 + skill: fletching + type: fletching + wait: 2 + xp: 16 +description: An oak shortbow. equip_slot: main_hand -weapon_type: ranged -attack_type: ranged +id: oak_shortbow +name: oak shortbow +requirements: + ranged: 5 speed: 4 stats: - ranged_attack: 14 -requirements: - ranged: 5 + ranged_attack: 14 +value: 40 +weapon_type: ranged diff --git a/data/items/equipment/oak_shortbow_u.yaml b/data/items/equipment/oak_shortbow_u.yaml index 5bebc38..1d6d8ee 100644 --- a/data/items/equipment/oak_shortbow_u.yaml +++ b/data/items/equipment/oak_shortbow_u.yaml @@ -1,5 +1,16 @@ +color: "136" +craft: + consume: + - items: + - oak_logs + quantity: 1 + level: 20 + skill: fletching + tool: knife + type: fletching + wait: 3 + xp: 16 +description: An unstrung oak shortbow. id: oak_shortbow_u name: oak shortbow (u) -color: "136" -description: "An unstrung oak shortbow." value: 20 diff --git a/data/items/equipment/ruby_amulet_u.yaml b/data/items/equipment/ruby_amulet_u.yaml index 031bf8b..e4123ea 100644 --- a/data/items/equipment/ruby_amulet_u.yaml +++ b/data/items/equipment/ruby_amulet_u.yaml @@ -1,5 +1,26 @@ +color: "196" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - items: + - ruby + quantity: 1 + - byproducts: + - amulet_mould + items: + - amulet_mould + quantity: 1 + level: 50 + message: You cast a ruby amulet. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 85 +description: An unstrung gold amulet set with a ruby. id: ruby_amulet_u name: ruby amulet (u) -color: "196" -description: "An unstrung gold amulet set with a ruby." value: 145 diff --git a/data/items/equipment/ruby_bracelet.yaml b/data/items/equipment/ruby_bracelet.yaml index e5f3f70..edc9658 100644 --- a/data/items/equipment/ruby_bracelet.yaml +++ b/data/items/equipment/ruby_bracelet.yaml @@ -1,6 +1,27 @@ +color: "196" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - items: + - ruby + quantity: 1 + - byproducts: + - bracelet_mould + items: + - bracelet_mould + quantity: 1 + level: 42 + message: You cast a ruby bracelet. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 80 +description: A bracelet set with a ruby. Can be enchanted. +equip_slot: hands id: ruby_bracelet name: ruby bracelet -color: "196" -description: "A bracelet set with a ruby. Can be enchanted." value: 800 -equip_slot: hands diff --git a/data/items/equipment/ruby_necklace.yaml b/data/items/equipment/ruby_necklace.yaml index e181777..8496eb6 100644 --- a/data/items/equipment/ruby_necklace.yaml +++ b/data/items/equipment/ruby_necklace.yaml @@ -1,6 +1,27 @@ +color: "196" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - items: + - ruby + quantity: 1 + - byproducts: + - necklace_mould + items: + - necklace_mould + quantity: 1 + level: 40 + message: You cast a ruby necklace. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 75 +description: A necklace set with a ruby. Can be enchanted. +equip_slot: neck id: ruby_necklace name: ruby necklace -color: "196" -description: "A necklace set with a ruby. Can be enchanted." value: 850 -equip_slot: neck diff --git a/data/items/equipment/ruby_ring.yaml b/data/items/equipment/ruby_ring.yaml index cb0cfde..335fbb0 100644 --- a/data/items/equipment/ruby_ring.yaml +++ b/data/items/equipment/ruby_ring.yaml @@ -1,6 +1,27 @@ +color: "196" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - items: + - ruby + quantity: 1 + - byproducts: + - ring_mould + items: + - ring_mould + quantity: 1 + level: 63 + message: You cast a ruby ring. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 70 +description: A ring set with a ruby. Can be enchanted. +equip_slot: ring id: ruby_ring name: ruby ring -color: "196" -description: "A ring set with a ruby. Can be enchanted." value: 800 -equip_slot: ring diff --git a/data/items/equipment/rune_dagger.yaml b/data/items/equipment/rune_dagger.yaml index 9e8507b..f1f53f6 100644 --- a/data/items/equipment/rune_dagger.yaml +++ b/data/items/equipment/rune_dagger.yaml @@ -1,17 +1,29 @@ +attack_type: stab +color: "87" +craft: + consume: + - items: + - runite_bar + quantity: 1 + level: 85 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 75 +description: A small rune dagger. +equip_slot: main_hand id: rune_dagger name: rune dagger -color: "87" -description: "A small rune dagger." -value: 5000 +requirements: + attack: 40 +speed: 3 stackable: false -equip_slot: main_hand -weapon_type: melee -attack_type: stab stats: - stab_attack: 30 - slash_attack: 18 - crush_attack: -1 - strength_bonus: 24 -speed: 3 -requirements: - attack: 40 + crush_attack: -1 + slash_attack: 18 + stab_attack: 30 + strength_bonus: 24 +value: 5000 +weapon_type: melee diff --git a/data/items/equipment/rune_full_helm.yaml b/data/items/equipment/rune_full_helm.yaml index 87d6973..273bfab 100644 --- a/data/items/equipment/rune_full_helm.yaml +++ b/data/items/equipment/rune_full_helm.yaml @@ -1,15 +1,27 @@ +color: "87" +craft: + consume: + - items: + - runite_bar + quantity: 2 + level: 92 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 150 +description: A rune full helmet. +equip_slot: head id: rune_full_helm name: rune full helm -color: "87" -description: "A rune full helmet." -value: 12000 +requirements: + defense: 40 stackable: false -equip_slot: head stats: - stab_defense: 30 - slash_defense: 33 - crush_defense: 22 - science_defense: -11 - ranged_defense: 30 -requirements: - defense: 40 + crush_defense: 22 + ranged_defense: 30 + science_defense: -11 + slash_defense: 33 + stab_defense: 30 +value: 12000 diff --git a/data/items/equipment/rune_med_helm.yaml b/data/items/equipment/rune_med_helm.yaml index 895d257..1b70577 100644 --- a/data/items/equipment/rune_med_helm.yaml +++ b/data/items/equipment/rune_med_helm.yaml @@ -1,15 +1,27 @@ +color: "87" +craft: + consume: + - items: + - runite_bar + quantity: 1 + level: 88 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 75 +description: A rune medium helmet. +equip_slot: head id: rune_med_helm name: rune med helm -color: "87" -description: "A rune medium helmet." -value: 5000 +requirements: + defense: 40 stackable: false -equip_slot: head stats: - stab_defense: 19 - slash_defense: 22 - crush_defense: 13 - science_defense: -4 - ranged_defense: 19 -requirements: - defense: 40 + crush_defense: 13 + ranged_defense: 19 + science_defense: -4 + slash_defense: 22 + stab_defense: 19 +value: 5000 diff --git a/data/items/equipment/rune_platebody.yaml b/data/items/equipment/rune_platebody.yaml index d1e5fb1..ce63d76 100644 --- a/data/items/equipment/rune_platebody.yaml +++ b/data/items/equipment/rune_platebody.yaml @@ -1,15 +1,27 @@ +color: "87" +craft: + consume: + - items: + - runite_bar + quantity: 5 + level: 99 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 375 +description: A rune platebody. +equip_slot: torso id: rune_platebody name: rune platebody -color: "87" -description: "A rune platebody." -value: 40000 +requirements: + defense: 40 stackable: false -equip_slot: torso stats: - stab_defense: 65 - slash_defense: 72 - crush_defense: 52 - science_defense: -30 - ranged_defense: 65 -requirements: - defense: 40 + crush_defense: 52 + ranged_defense: 65 + science_defense: -30 + slash_defense: 72 + stab_defense: 65 +value: 40000 diff --git a/data/items/equipment/rune_sword.yaml b/data/items/equipment/rune_sword.yaml index e0bfb74..3451450 100644 --- a/data/items/equipment/rune_sword.yaml +++ b/data/items/equipment/rune_sword.yaml @@ -1,17 +1,29 @@ +attack_type: slash +color: "87" +craft: + consume: + - items: + - runite_bar + quantity: 1 + level: 89 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 75 +description: A rune sword. +equip_slot: main_hand id: rune_sword name: rune sword -color: "87" -description: "A rune sword." -value: 10000 +requirements: + attack: 40 +speed: 4 stackable: false -equip_slot: main_hand -weapon_type: melee -attack_type: slash stats: - stab_attack: 27 - slash_attack: 52 - crush_attack: -2 - strength_bonus: 36 -speed: 4 -requirements: - attack: 40 + crush_attack: -2 + slash_attack: 52 + stab_attack: 27 + strength_bonus: 36 +value: 10000 +weapon_type: melee diff --git a/data/items/equipment/sapphire_amulet_u.yaml b/data/items/equipment/sapphire_amulet_u.yaml index 22ef39c..b342ae4 100644 --- a/data/items/equipment/sapphire_amulet_u.yaml +++ b/data/items/equipment/sapphire_amulet_u.yaml @@ -1,5 +1,26 @@ +color: "69" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - items: + - sapphire + quantity: 1 + - byproducts: + - amulet_mould + items: + - amulet_mould + quantity: 1 + level: 24 + message: You cast a sapphire amulet. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 65 +description: An unstrung gold amulet set with a sapphire. id: sapphire_amulet_u name: sapphire amulet (u) -color: "69" -description: "An unstrung gold amulet set with a sapphire." value: 100 diff --git a/data/items/equipment/sapphire_bracelet.yaml b/data/items/equipment/sapphire_bracelet.yaml index a2996eb..7d19018 100644 --- a/data/items/equipment/sapphire_bracelet.yaml +++ b/data/items/equipment/sapphire_bracelet.yaml @@ -1,6 +1,27 @@ +color: "39" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - items: + - sapphire + quantity: 1 + - byproducts: + - bracelet_mould + items: + - bracelet_mould + quantity: 1 + level: 23 + message: You cast a sapphire bracelet. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 60 +description: A bracelet set with a sapphire. Can be enchanted. +equip_slot: hands id: sapphire_bracelet name: sapphire bracelet -color: "39" -description: "A bracelet set with a sapphire. Can be enchanted." value: 200 -equip_slot: hands diff --git a/data/items/equipment/sapphire_necklace.yaml b/data/items/equipment/sapphire_necklace.yaml index e553973..e51a47f 100644 --- a/data/items/equipment/sapphire_necklace.yaml +++ b/data/items/equipment/sapphire_necklace.yaml @@ -1,6 +1,27 @@ +color: "39" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - items: + - sapphire + quantity: 1 + - byproducts: + - necklace_mould + items: + - necklace_mould + quantity: 1 + level: 22 + message: You cast a sapphire necklace. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 55 +description: A necklace set with a sapphire. Can be enchanted. +equip_slot: neck id: sapphire_necklace name: sapphire necklace -color: "39" -description: "A necklace set with a sapphire. Can be enchanted." value: 250 -equip_slot: neck diff --git a/data/items/equipment/sapphire_ring.yaml b/data/items/equipment/sapphire_ring.yaml index 40e8cc5..d880c75 100644 --- a/data/items/equipment/sapphire_ring.yaml +++ b/data/items/equipment/sapphire_ring.yaml @@ -1,6 +1,27 @@ +color: "39" +craft: + consume: + - items: + - gold_bar + quantity: 1 + - items: + - sapphire + quantity: 1 + - byproducts: + - ring_mould + items: + - ring_mould + quantity: 1 + level: 20 + message: You cast a sapphire ring. + skill: crafting + station: + - furnace + type: crafting + wait: 4 + xp: 40 +description: A ring set with a sapphire. Can be enchanted. +equip_slot: ring id: sapphire_ring name: sapphire ring -color: "39" -description: "A ring set with a sapphire. Can be enchanted." value: 200 -equip_slot: ring diff --git a/data/items/equipment/shortbow.yaml b/data/items/equipment/shortbow.yaml index ecd3630..50c77fe 100644 --- a/data/items/equipment/shortbow.yaml +++ b/data/items/equipment/shortbow.yaml @@ -1,11 +1,24 @@ -id: shortbow -name: shortbow +attack_type: ranged color: "137" -description: "A shortbow." -value: 10 +craft: + consume: + - items: + - shortbow_u + quantity: 1 + - items: + - bowstring + quantity: 1 + level: 5 + skill: fletching + type: fletching + wait: 2 + xp: 5 +description: A shortbow. equip_slot: main_hand -weapon_type: ranged -attack_type: ranged +id: shortbow +name: shortbow speed: 4 stats: - ranged_attack: 8 + ranged_attack: 8 +value: 10 +weapon_type: ranged diff --git a/data/items/equipment/shortbow_u.yaml b/data/items/equipment/shortbow_u.yaml index 6ffcafc..2d4e615 100644 --- a/data/items/equipment/shortbow_u.yaml +++ b/data/items/equipment/shortbow_u.yaml @@ -1,5 +1,16 @@ +color: "137" +craft: + consume: + - items: + - logs + quantity: 1 + level: 5 + skill: fletching + tool: knife + type: fletching + wait: 3 + xp: 5 +description: An unstrung shortbow. id: shortbow_u name: shortbow (u) -color: "137" -description: "An unstrung shortbow." value: 5 diff --git a/data/items/equipment/steel_dagger.yaml b/data/items/equipment/steel_dagger.yaml index e52b882..9df7d14 100644 --- a/data/items/equipment/steel_dagger.yaml +++ b/data/items/equipment/steel_dagger.yaml @@ -1,17 +1,29 @@ +attack_type: stab +color: "253" +craft: + consume: + - items: + - steel_bar + quantity: 1 + level: 30 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 37 +description: A small steel dagger. +equip_slot: main_hand id: steel_dagger name: steel dagger -color: "253" -description: "A small steel dagger." -value: 60 +requirements: + attack: 5 +speed: 3 stackable: false -equip_slot: main_hand -weapon_type: melee -attack_type: stab stats: - stab_attack: 12 - slash_attack: 7 - crush_attack: -1 - strength_bonus: 10 -speed: 3 -requirements: - attack: 5 + crush_attack: -1 + slash_attack: 7 + stab_attack: 12 + strength_bonus: 10 +value: 60 +weapon_type: melee diff --git a/data/items/equipment/steel_full_helm.yaml b/data/items/equipment/steel_full_helm.yaml index 7152ded..af6a113 100644 --- a/data/items/equipment/steel_full_helm.yaml +++ b/data/items/equipment/steel_full_helm.yaml @@ -1,15 +1,27 @@ +color: "253" +craft: + consume: + - items: + - steel_bar + quantity: 2 + level: 37 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 75 +description: A steel full helmet. +equip_slot: head id: steel_full_helm name: steel full helm -color: "253" -description: "A steel full helmet." -value: 150 +requirements: + defense: 5 stackable: false -equip_slot: head stats: - stab_defense: 12 - slash_defense: 13 - crush_defense: 9 - science_defense: -5 - ranged_defense: 12 -requirements: - defense: 5 + crush_defense: 9 + ranged_defense: 12 + science_defense: -5 + slash_defense: 13 + stab_defense: 12 +value: 150 diff --git a/data/items/equipment/steel_med_helm.yaml b/data/items/equipment/steel_med_helm.yaml index 9e15fdd..1a6a768 100644 --- a/data/items/equipment/steel_med_helm.yaml +++ b/data/items/equipment/steel_med_helm.yaml @@ -1,15 +1,27 @@ +color: "253" +craft: + consume: + - items: + - steel_bar + quantity: 1 + level: 33 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 37 +description: A steel medium helmet. +equip_slot: head id: steel_med_helm name: steel med helm -color: "253" -description: "A steel medium helmet." -value: 60 +requirements: + defense: 5 stackable: false -equip_slot: head stats: - stab_defense: 7 - slash_defense: 9 - crush_defense: 5 - science_defense: -2 - ranged_defense: 7 -requirements: - defense: 5 + crush_defense: 5 + ranged_defense: 7 + science_defense: -2 + slash_defense: 9 + stab_defense: 7 +value: 60 diff --git a/data/items/equipment/steel_platebody.yaml b/data/items/equipment/steel_platebody.yaml index f44dfa3..0769c55 100644 --- a/data/items/equipment/steel_platebody.yaml +++ b/data/items/equipment/steel_platebody.yaml @@ -1,15 +1,27 @@ +color: "253" +craft: + consume: + - items: + - steel_bar + quantity: 5 + level: 48 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 187 +description: A steel platebody. +equip_slot: torso id: steel_platebody name: steel platebody -color: "253" -description: "A steel platebody." -value: 500 +requirements: + defense: 5 stackable: false -equip_slot: torso stats: - stab_defense: 27 - slash_defense: 32 - crush_defense: 22 - science_defense: -15 - ranged_defense: 27 -requirements: - defense: 5 + crush_defense: 22 + ranged_defense: 27 + science_defense: -15 + slash_defense: 32 + stab_defense: 27 +value: 500 diff --git a/data/items/equipment/steel_sword.yaml b/data/items/equipment/steel_sword.yaml index e096dc9..b0ca858 100644 --- a/data/items/equipment/steel_sword.yaml +++ b/data/items/equipment/steel_sword.yaml @@ -1,17 +1,29 @@ +attack_type: slash +color: "253" +craft: + consume: + - items: + - steel_bar + quantity: 1 + level: 34 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 37 +description: A steel sword. +equip_slot: main_hand id: steel_sword name: steel sword -color: "253" -description: "A steel sword." -value: 100 +requirements: + attack: 5 +speed: 4 stackable: false -equip_slot: main_hand -weapon_type: melee -attack_type: slash stats: - stab_attack: 10 - slash_attack: 22 - crush_attack: -2 - strength_bonus: 14 -speed: 4 -requirements: - attack: 5 + crush_attack: -2 + slash_attack: 22 + stab_attack: 10 + strength_bonus: 14 +value: 100 +weapon_type: melee diff --git a/data/items/equipment/willow_longbow.yaml b/data/items/equipment/willow_longbow.yaml index e30528c..6b9c4c0 100644 --- a/data/items/equipment/willow_longbow.yaml +++ b/data/items/equipment/willow_longbow.yaml @@ -1,13 +1,26 @@ -id: willow_longbow -name: willow longbow +attack_type: ranged color: "107" -description: "A willow longbow." -value: 320 +craft: + consume: + - items: + - willow_longbow_u + quantity: 1 + - items: + - bowstring + quantity: 1 + level: 40 + skill: fletching + type: fletching + wait: 2 + xp: 41 +description: A willow longbow. equip_slot: main_hand -weapon_type: ranged -attack_type: ranged +id: willow_longbow +name: willow longbow +requirements: + ranged: 20 speed: 6 stats: - ranged_attack: 20 -requirements: - ranged: 20 + ranged_attack: 20 +value: 320 +weapon_type: ranged diff --git a/data/items/equipment/willow_longbow_u.yaml b/data/items/equipment/willow_longbow_u.yaml index 5e4e9da..3812dfa 100644 --- a/data/items/equipment/willow_longbow_u.yaml +++ b/data/items/equipment/willow_longbow_u.yaml @@ -1,5 +1,16 @@ +color: "107" +craft: + consume: + - items: + - willow_logs + quantity: 1 + level: 40 + skill: fletching + tool: knife + type: fletching + wait: 3 + xp: 41 +description: An unstrung willow longbow. id: willow_longbow_u name: willow longbow (u) -color: "107" -description: "An unstrung willow longbow." value: 160 diff --git a/data/items/equipment/willow_shortbow.yaml b/data/items/equipment/willow_shortbow.yaml index f75cfe9..8289742 100644 --- a/data/items/equipment/willow_shortbow.yaml +++ b/data/items/equipment/willow_shortbow.yaml @@ -1,13 +1,26 @@ -id: willow_shortbow -name: willow shortbow +attack_type: ranged color: "107" -description: "A willow shortbow." -value: 160 +craft: + consume: + - items: + - willow_shortbow_u + quantity: 1 + - items: + - bowstring + quantity: 1 + level: 35 + skill: fletching + type: fletching + wait: 2 + xp: 33 +description: A willow shortbow. equip_slot: main_hand -weapon_type: ranged -attack_type: ranged +id: willow_shortbow +name: willow shortbow +requirements: + ranged: 20 speed: 4 stats: - ranged_attack: 20 -requirements: - ranged: 20 + ranged_attack: 20 +value: 160 +weapon_type: ranged diff --git a/data/items/equipment/willow_shortbow_u.yaml b/data/items/equipment/willow_shortbow_u.yaml index b467455..642665a 100644 --- a/data/items/equipment/willow_shortbow_u.yaml +++ b/data/items/equipment/willow_shortbow_u.yaml @@ -1,5 +1,16 @@ +color: "107" +craft: + consume: + - items: + - willow_logs + quantity: 1 + level: 35 + skill: fletching + tool: knife + type: fletching + wait: 3 + xp: 33 +description: An unstrung willow shortbow. id: willow_shortbow_u name: willow shortbow (u) -color: "107" -description: "An unstrung willow shortbow." value: 80 diff --git a/data/items/equipment/yew_longbow.yaml b/data/items/equipment/yew_longbow.yaml index 1e7c0f5..b550e1f 100644 --- a/data/items/equipment/yew_longbow.yaml +++ b/data/items/equipment/yew_longbow.yaml @@ -1,13 +1,26 @@ -id: yew_longbow -name: yew longbow +attack_type: ranged color: "94" -description: "A yew longbow." -value: 2000 +craft: + consume: + - items: + - yew_longbow_u + quantity: 1 + - items: + - bowstring + quantity: 1 + level: 65 + skill: fletching + type: fletching + wait: 2 + xp: 75 +description: A yew longbow. equip_slot: main_hand -weapon_type: ranged -attack_type: ranged +id: yew_longbow +name: yew longbow +requirements: + ranged: 40 speed: 6 stats: - ranged_attack: 47 -requirements: - ranged: 40 + ranged_attack: 47 +value: 2000 +weapon_type: ranged diff --git a/data/items/equipment/yew_longbow_u.yaml b/data/items/equipment/yew_longbow_u.yaml index ac4fdb2..53f9f79 100644 --- a/data/items/equipment/yew_longbow_u.yaml +++ b/data/items/equipment/yew_longbow_u.yaml @@ -1,5 +1,16 @@ +color: "94" +craft: + consume: + - items: + - yew_logs + quantity: 1 + level: 65 + skill: fletching + tool: knife + type: fletching + wait: 3 + xp: 75 +description: An unstrung yew longbow. id: yew_longbow_u name: yew longbow (u) -color: "94" -description: "An unstrung yew longbow." value: 1000 diff --git a/data/items/equipment/yew_shortbow.yaml b/data/items/equipment/yew_shortbow.yaml index c302a38..8d41739 100644 --- a/data/items/equipment/yew_shortbow.yaml +++ b/data/items/equipment/yew_shortbow.yaml @@ -1,13 +1,26 @@ -id: yew_shortbow -name: yew shortbow +attack_type: ranged color: "94" -description: "A yew shortbow." -value: 1600 +craft: + consume: + - items: + - yew_shortbow_u + quantity: 1 + - items: + - bowstring + quantity: 1 + level: 60 + skill: fletching + type: fletching + wait: 2 + xp: 67 +description: A yew shortbow. equip_slot: main_hand -weapon_type: ranged -attack_type: ranged +id: yew_shortbow +name: yew shortbow +requirements: + ranged: 40 speed: 4 stats: - ranged_attack: 47 -requirements: - ranged: 40 + ranged_attack: 47 +value: 1600 +weapon_type: ranged diff --git a/data/items/equipment/yew_shortbow_u.yaml b/data/items/equipment/yew_shortbow_u.yaml index 4c2124b..2096ae9 100644 --- a/data/items/equipment/yew_shortbow_u.yaml +++ b/data/items/equipment/yew_shortbow_u.yaml @@ -1,5 +1,16 @@ +color: "94" +craft: + consume: + - items: + - yew_logs + quantity: 1 + level: 60 + skill: fletching + tool: knife + type: fletching + wait: 3 + xp: 67 +description: An unstrung yew shortbow. id: yew_shortbow_u name: yew shortbow (u) -color: "94" -description: "An unstrung yew shortbow." value: 800 diff --git a/data/items/materials/adamant_nails.yaml b/data/items/materials/adamant_nails.yaml index c40d228..4c16f8d 100644 --- a/data/items/materials/adamant_nails.yaml +++ b/data/items/materials/adamant_nails.yaml @@ -1,6 +1,19 @@ +color: "120" +craft: + consume: + - items: + - adamantite_bar + quantity: 1 + level: 74 + output_qty: 15 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 62 +description: A set of adamant nails. id: adamant_nails name: adamant nails -color: "120" -description: "A set of adamant nails." -value: 16 stackable: true +value: 16 diff --git a/data/items/materials/adamantite_bar.yaml b/data/items/materials/adamantite_bar.yaml index 5a9b827..1367d4e 100644 --- a/data/items/materials/adamantite_bar.yaml +++ b/data/items/materials/adamantite_bar.yaml @@ -1,6 +1,23 @@ +color: "71" +craft: + consume: + - items: + - adamantite_ore + quantity: 1 + - items: + - coal + quantity: 6 + fail_message: You fail to smelt a usable bar. + level: 65 + message: You remove a white hot adamantite bar! + skill: smithing + station: + - furnace + type: smelting + wait: 4 + xp: 37 +description: A bar of adamantite metal, extremely durable. id: adamantite_bar name: adamantite bar -color: "71" -description: "A bar of adamantite metal, extremely durable." -value: 200 stackable: false +value: 200 diff --git a/data/items/materials/avantoe.yaml b/data/items/materials/avantoe.yaml index d596096..47fc405 100644 --- a/data/items/materials/avantoe.yaml +++ b/data/items/materials/avantoe.yaml @@ -1,6 +1,17 @@ -id: avantoe -name: "avantoe" color: "48" -description: "A clean avantoe leaf, ready for use in pharmacy." -value: 48 +craft: + consume: + - items: + - grimy_avantoe + quantity: 1 + level: 48 + message: You clean the grimy avantoe leaf. + skill: pharmacy + type: clean + wait: 2 + xp: 10 +description: A clean avantoe leaf, ready for use in pharmacy. +id: avantoe +name: avantoe stackable: true +value: 48 diff --git a/data/items/materials/ball_of_wool.yaml b/data/items/materials/ball_of_wool.yaml index 1a680a4..0f2c000 100644 --- a/data/items/materials/ball_of_wool.yaml +++ b/data/items/materials/ball_of_wool.yaml @@ -1,6 +1,19 @@ +color: "255" +craft: + consume: + - items: + - wool + quantity: 1 + level: 1 + message: You spin the wool into a ball. + skill: crafting + station: + - spinning_wheel + type: crafting + wait: 3 + xp: 3 +description: A ball of spun wool. id: ball_of_wool name: ball of wool -color: "255" -description: "A ball of spun wool." -value: 5 stackable: false +value: 5 diff --git a/data/items/materials/bowstring.yaml b/data/items/materials/bowstring.yaml index a180081..ef17ce5 100644 --- a/data/items/materials/bowstring.yaml +++ b/data/items/materials/bowstring.yaml @@ -1,5 +1,18 @@ +color: "230" +craft: + consume: + - items: + - flax + quantity: 1 + level: 1 + message: You spin the flax into a bowstring. + skill: crafting + station: + - spinning_wheel + type: crafting + wait: 3 + xp: 15 +description: A string used for stringing bows. id: bowstring name: bowstring -color: "230" -description: "A string used for stringing bows." value: 10 diff --git a/data/items/materials/bronze_bar.yaml b/data/items/materials/bronze_bar.yaml index 053cfe8..7590114 100644 --- a/data/items/materials/bronze_bar.yaml +++ b/data/items/materials/bronze_bar.yaml @@ -1,6 +1,23 @@ +color: "178" +craft: + consume: + - items: + - copper_ore + quantity: 1 + - items: + - tin_ore + quantity: 1 + fail_message: You fail to smelt a usable bar. + level: 1 + message: You remove a white hot bronze bar! + skill: smithing + station: + - furnace + type: smelting + wait: 4 + xp: 6 +description: A bar of bronze metal, smelted from copper and tin ore. id: bronze_bar name: bronze bar -color: "178" -description: "A bar of bronze metal, smelted from copper and tin ore." -value: 4 stackable: false +value: 4 diff --git a/data/items/materials/bronze_nails.yaml b/data/items/materials/bronze_nails.yaml index 513e9c4..634c658 100644 --- a/data/items/materials/bronze_nails.yaml +++ b/data/items/materials/bronze_nails.yaml @@ -1,6 +1,19 @@ +color: "178" +craft: + consume: + - items: + - bronze_bar + quantity: 1 + level: 4 + output_qty: 15 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 12 +description: A set of bronze nails. id: bronze_nails name: bronze nails -color: "178" -description: "A set of bronze nails." -value: 1 stackable: true +value: 1 diff --git a/data/items/materials/cadantine.yaml b/data/items/materials/cadantine.yaml index f684f0d..24da88a 100644 --- a/data/items/materials/cadantine.yaml +++ b/data/items/materials/cadantine.yaml @@ -1,6 +1,17 @@ -id: cadantine -name: "cadantine" color: "48" -description: "A clean cadantine leaf, ready for use in pharmacy." -value: 70 +craft: + consume: + - items: + - grimy_cadantine + quantity: 1 + level: 65 + message: You clean the grimy cadantine leaf. + skill: pharmacy + type: clean + wait: 2 + xp: 13 +description: A clean cadantine leaf, ready for use in pharmacy. +id: cadantine +name: cadantine stackable: true +value: 70 diff --git a/data/items/materials/diamond.yaml b/data/items/materials/diamond.yaml index 2ec703f..aecdade 100644 --- a/data/items/materials/diamond.yaml +++ b/data/items/materials/diamond.yaml @@ -1,6 +1,18 @@ +color: "255" +craft: + consume: + - items: + - uncut_diamond + quantity: 1 + level: 43 + message: You cut the diamond into a beautiful gem. + skill: crafting + tool: chisel + type: crafting + wait: 3 + xp: 108 +description: A beautifully cut diamond. id: diamond name: diamond -color: "255" -description: "A beautifully cut diamond." -value: 400 stackable: false +value: 400 diff --git a/data/items/materials/dwarf_weed.yaml b/data/items/materials/dwarf_weed.yaml index 559edf3..13b54ec 100644 --- a/data/items/materials/dwarf_weed.yaml +++ b/data/items/materials/dwarf_weed.yaml @@ -1,6 +1,17 @@ -id: dwarf_weed -name: "dwarf weed" color: "48" -description: "A clean dwarf weed leaf, ready for use in pharmacy." -value: 85 +craft: + consume: + - items: + - grimy_dwarf_weed + quantity: 1 + level: 70 + message: You clean the grimy dwarf weed leaf. + skill: pharmacy + type: clean + wait: 2 + xp: 14 +description: A clean dwarf weed leaf, ready for use in pharmacy. +id: dwarf_weed +name: dwarf weed stackable: true +value: 85 diff --git a/data/items/materials/emerald.yaml b/data/items/materials/emerald.yaml index 9a0c71d..8b3a888 100644 --- a/data/items/materials/emerald.yaml +++ b/data/items/materials/emerald.yaml @@ -1,6 +1,18 @@ +color: "83" +craft: + consume: + - items: + - uncut_emerald + quantity: 1 + level: 27 + message: You cut the emerald into a beautiful gem. + skill: crafting + tool: chisel + type: crafting + wait: 3 + xp: 68 +description: A beautifully cut emerald. id: emerald name: emerald -color: "83" -description: "A beautifully cut emerald." -value: 100 stackable: false +value: 100 diff --git a/data/items/materials/gold_bar.yaml b/data/items/materials/gold_bar.yaml index 3272b04..e46bb1b 100644 --- a/data/items/materials/gold_bar.yaml +++ b/data/items/materials/gold_bar.yaml @@ -1,6 +1,20 @@ +color: "220" +craft: + consume: + - items: + - gold_ore + quantity: 1 + fail_message: You fail to smelt a usable bar. + level: 45 + message: You remove a white hot gold bar! + skill: smithing + station: + - furnace + type: smelting + wait: 4 + xp: 22 +description: A bar of gold metal. id: gold_bar name: gold bar -color: "220" -description: "A bar of gold metal." -value: 50 stackable: false +value: 50 diff --git a/data/items/materials/guam.yaml b/data/items/materials/guam.yaml index 8fe7972..191252a 100644 --- a/data/items/materials/guam.yaml +++ b/data/items/materials/guam.yaml @@ -1,6 +1,17 @@ -id: guam -name: "guam" color: "48" -description: "A clean guam leaf, ready for use in pharmacy." -value: 3 +craft: + consume: + - items: + - grimy_guam + quantity: 1 + level: 1 + message: You clean the grimy guam leaf. + skill: pharmacy + type: clean + wait: 2 + xp: 3 +description: A clean guam leaf, ready for use in pharmacy. +id: guam +name: guam stackable: true +value: 3 diff --git a/data/items/materials/harralander.yaml b/data/items/materials/harralander.yaml index 08e66ed..c8b42e7 100644 --- a/data/items/materials/harralander.yaml +++ b/data/items/materials/harralander.yaml @@ -1,6 +1,17 @@ -id: harralander -name: "harralander" color: "48" -description: "A clean harralander leaf, ready for use in pharmacy." -value: 16 +craft: + consume: + - items: + - grimy_harralander + quantity: 1 + level: 20 + message: You clean the grimy harralander leaf. + skill: pharmacy + type: clean + wait: 2 + xp: 6 +description: A clean harralander leaf, ready for use in pharmacy. +id: harralander +name: harralander stackable: true +value: 16 diff --git a/data/items/materials/irit.yaml b/data/items/materials/irit.yaml index 40f1956..3a6498e 100644 --- a/data/items/materials/irit.yaml +++ b/data/items/materials/irit.yaml @@ -1,6 +1,17 @@ -id: irit -name: "irit" color: "48" -description: "A clean irit leaf, ready for use in pharmacy." -value: 40 +craft: + consume: + - items: + - grimy_irit + quantity: 1 + level: 40 + message: You clean the grimy irit leaf. + skill: pharmacy + type: clean + wait: 2 + xp: 9 +description: A clean irit leaf, ready for use in pharmacy. +id: irit +name: irit stackable: true +value: 40 diff --git a/data/items/materials/iron_bar.yaml b/data/items/materials/iron_bar.yaml index 26c8352..ae474cd 100644 --- a/data/items/materials/iron_bar.yaml +++ b/data/items/materials/iron_bar.yaml @@ -1,6 +1,24 @@ +color: "250" +craft: + consume: + - items: + - iron_ore + quantity: 1 + fail_message: The iron is too impure to make a workable bar. + level: 20 + message: You remove a white hot iron bar! + skill: smithing + station: + - furnace + success: + base: 0.5 + cap: 0.5 + per_level: 0 + type: smelting + wait: 4 + xp: 12 +description: A bar of iron metal. id: iron_bar name: iron bar -color: "250" -description: "A bar of iron metal." -value: 12 stackable: false +value: 12 diff --git a/data/items/materials/iron_nails.yaml b/data/items/materials/iron_nails.yaml index 77323c9..3a15192 100644 --- a/data/items/materials/iron_nails.yaml +++ b/data/items/materials/iron_nails.yaml @@ -1,6 +1,19 @@ +color: "250" +craft: + consume: + - items: + - iron_bar + quantity: 1 + level: 24 + output_qty: 15 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 25 +description: A set of iron nails. id: iron_nails name: iron nails -color: "250" -description: "A set of iron nails." -value: 2 stackable: true +value: 2 diff --git a/data/items/materials/kwuarm.yaml b/data/items/materials/kwuarm.yaml index ab0d7ff..bcb9af4 100644 --- a/data/items/materials/kwuarm.yaml +++ b/data/items/materials/kwuarm.yaml @@ -1,6 +1,17 @@ -id: kwuarm -name: "kwuarm" color: "48" -description: "A clean kwuarm leaf, ready for use in pharmacy." -value: 54 +craft: + consume: + - items: + - grimy_kwuarm + quantity: 1 + level: 54 + message: You clean the grimy kwuarm leaf. + skill: pharmacy + type: clean + wait: 2 + xp: 11 +description: A clean kwuarm leaf, ready for use in pharmacy. +id: kwuarm +name: kwuarm stackable: true +value: 54 diff --git a/data/items/materials/lantadyme.yaml b/data/items/materials/lantadyme.yaml index d38b7da..ef55555 100644 --- a/data/items/materials/lantadyme.yaml +++ b/data/items/materials/lantadyme.yaml @@ -1,6 +1,17 @@ -id: lantadyme -name: "lantadyme" color: "48" -description: "A clean lantadyme leaf, ready for use in pharmacy." -value: 78 +craft: + consume: + - items: + - grimy_lantadyme + quantity: 1 + level: 67 + message: You clean the grimy lantadyme leaf. + skill: pharmacy + type: clean + wait: 2 + xp: 13 +description: A clean lantadyme leaf, ready for use in pharmacy. +id: lantadyme +name: lantadyme stackable: true +value: 78 diff --git a/data/items/materials/mahogany_planks.yaml b/data/items/materials/mahogany_planks.yaml index d551321..da50f67 100644 --- a/data/items/materials/mahogany_planks.yaml +++ b/data/items/materials/mahogany_planks.yaml @@ -1,6 +1,20 @@ +color: "96" +craft: + consume: + - items: + - mahogany_logs + quantity: 1 + level: 50 + message: You saw the mahogany logs into luxurious mahogany planks. + skill: construction + station: + - workbench + tool: saw + type: construction + wait: 20 + xp: 30 +description: Luxurious mahogany planks with a deep reddish hue. id: mahogany_planks name: mahogany planks -color: "96" -description: "Luxurious mahogany planks with a deep reddish hue." -value: 120 stackable: false +value: 120 diff --git a/data/items/materials/marrentill.yaml b/data/items/materials/marrentill.yaml index 4bd492d..1da0427 100644 --- a/data/items/materials/marrentill.yaml +++ b/data/items/materials/marrentill.yaml @@ -1,6 +1,17 @@ -id: marrentill -name: "marrentill" color: "48" -description: "A clean marrentill leaf, ready for use in pharmacy." -value: 6 +craft: + consume: + - items: + - grimy_marrentill + quantity: 1 + level: 5 + message: You clean the grimy marrentill leaf. + skill: pharmacy + type: clean + wait: 2 + xp: 4 +description: A clean marrentill leaf, ready for use in pharmacy. +id: marrentill +name: marrentill stackable: true +value: 6 diff --git a/data/items/materials/mithril_bar.yaml b/data/items/materials/mithril_bar.yaml index 00e97a4..aee681a 100644 --- a/data/items/materials/mithril_bar.yaml +++ b/data/items/materials/mithril_bar.yaml @@ -1,6 +1,23 @@ +color: "75" +craft: + consume: + - items: + - mithril_ore + quantity: 1 + - items: + - coal + quantity: 4 + fail_message: You fail to smelt a usable bar. + level: 50 + message: You remove a white hot mithril bar! + skill: smithing + station: + - furnace + type: smelting + wait: 4 + xp: 30 +description: A bar of mithril metal, light and strong. id: mithril_bar name: mithril bar -color: "75" -description: "A bar of mithril metal, light and strong." -value: 100 stackable: false +value: 100 diff --git a/data/items/materials/mithril_nails.yaml b/data/items/materials/mithril_nails.yaml index aeb0544..4fef9d0 100644 --- a/data/items/materials/mithril_nails.yaml +++ b/data/items/materials/mithril_nails.yaml @@ -1,6 +1,19 @@ +color: "75" +craft: + consume: + - items: + - mithril_bar + quantity: 1 + level: 54 + output_qty: 15 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 50 +description: A set of mithril nails. id: mithril_nails name: mithril nails -color: "75" -description: "A set of mithril nails." -value: 8 stackable: true +value: 8 diff --git a/data/items/materials/oak_planks.yaml b/data/items/materials/oak_planks.yaml index 29376c6..2975555 100644 --- a/data/items/materials/oak_planks.yaml +++ b/data/items/materials/oak_planks.yaml @@ -1,6 +1,20 @@ +color: "102" +craft: + consume: + - items: + - oak_logs + quantity: 1 + level: 15 + message: You saw the oak logs into sturdy oak planks. + skill: construction + station: + - workbench + tool: saw + type: construction + wait: 20 + xp: 10 +description: Sturdy oak planks, ideal for furniture. id: oak_planks name: oak planks -color: "102" -description: "Sturdy oak planks, ideal for furniture." -value: 40 stackable: false +value: 40 diff --git a/data/items/materials/planks.yaml b/data/items/materials/planks.yaml index 67de72e..ce0e68f 100644 --- a/data/items/materials/planks.yaml +++ b/data/items/materials/planks.yaml @@ -1,6 +1,20 @@ +color: "137" +craft: + consume: + - items: + - logs + quantity: 1 + level: 1 + message: You saw the logs into some regular planks. + skill: construction + station: + - workbench + tool: saw + type: construction + wait: 20 + xp: 5 +description: Some regular wooden planks, ready for construction. id: planks name: planks -color: "137" -description: "Some regular wooden planks, ready for construction." -value: 20 stackable: false +value: 20 diff --git a/data/items/materials/ranarr.yaml b/data/items/materials/ranarr.yaml index 683cce6..c34cbb7 100644 --- a/data/items/materials/ranarr.yaml +++ b/data/items/materials/ranarr.yaml @@ -1,6 +1,17 @@ -id: ranarr -name: "ranarr" color: "48" -description: "A clean ranarr leaf, ready for use in pharmacy." -value: 35 +craft: + consume: + - items: + - grimy_ranarr + quantity: 1 + level: 25 + message: You clean the grimy ranarr leaf. + skill: pharmacy + type: clean + wait: 2 + xp: 8 +description: A clean ranarr leaf, ready for use in pharmacy. +id: ranarr +name: ranarr stackable: true +value: 35 diff --git a/data/items/materials/ruby.yaml b/data/items/materials/ruby.yaml index 644e1bf..301bdd3 100644 --- a/data/items/materials/ruby.yaml +++ b/data/items/materials/ruby.yaml @@ -1,6 +1,18 @@ +color: "196" +craft: + consume: + - items: + - uncut_ruby + quantity: 1 + level: 63 + message: You cut the ruby into a beautiful gem. + skill: crafting + tool: chisel + type: crafting + wait: 3 + xp: 85 +description: A beautifully cut ruby. id: ruby name: ruby -color: "196" -description: "A beautifully cut ruby." -value: 200 stackable: false +value: 200 diff --git a/data/items/materials/rune_nails.yaml b/data/items/materials/rune_nails.yaml index 5d2dfc5..ce12da1 100644 --- a/data/items/materials/rune_nails.yaml +++ b/data/items/materials/rune_nails.yaml @@ -1,6 +1,19 @@ +color: "87" +craft: + consume: + - items: + - runite_bar + quantity: 1 + level: 89 + output_qty: 15 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 75 +description: A set of rune nails. id: rune_nails name: rune nails -color: "87" -description: "A set of rune nails." -value: 30 stackable: true +value: 30 diff --git a/data/items/materials/runite_bar.yaml b/data/items/materials/runite_bar.yaml index 1faff69..65f5209 100644 --- a/data/items/materials/runite_bar.yaml +++ b/data/items/materials/runite_bar.yaml @@ -1,6 +1,23 @@ +color: "39" +craft: + consume: + - items: + - runite_ore + quantity: 1 + - items: + - coal + quantity: 8 + fail_message: You fail to smelt a usable bar. + level: 80 + message: You remove a white hot runite bar! + skill: smithing + station: + - furnace + type: smelting + wait: 4 + xp: 50 +description: A bar of runite metal, the finest alloy known. id: runite_bar name: runite bar -color: "39" -description: "A bar of runite metal, the finest alloy known." -value: 500 stackable: false +value: 500 diff --git a/data/items/materials/sapphire.yaml b/data/items/materials/sapphire.yaml index 9710d45..e2a2bb3 100644 --- a/data/items/materials/sapphire.yaml +++ b/data/items/materials/sapphire.yaml @@ -1,6 +1,18 @@ +color: "69" +craft: + consume: + - items: + - uncut_sapphire + quantity: 1 + level: 20 + message: You cut the sapphire into a beautiful gem. + skill: crafting + tool: chisel + type: crafting + wait: 3 + xp: 50 +description: A beautifully cut sapphire. id: sapphire name: sapphire -color: "69" -description: "A beautifully cut sapphire." -value: 50 stackable: false +value: 50 diff --git a/data/items/materials/silver_bar.yaml b/data/items/materials/silver_bar.yaml index eccb25f..58c2056 100644 --- a/data/items/materials/silver_bar.yaml +++ b/data/items/materials/silver_bar.yaml @@ -1,6 +1,20 @@ +color: "255" +craft: + consume: + - items: + - silver_ore + quantity: 1 + fail_message: You fail to smelt a usable bar. + level: 25 + message: You remove a white hot silver bar! + skill: smithing + station: + - furnace + type: smelting + wait: 4 + xp: 14 +description: A bar of silver metal. id: silver_bar name: silver bar -color: "255" -description: "A bar of silver metal." -value: 20 stackable: false +value: 20 diff --git a/data/items/materials/snapdragon.yaml b/data/items/materials/snapdragon.yaml index 0c3ba2f..95ac4bf 100644 --- a/data/items/materials/snapdragon.yaml +++ b/data/items/materials/snapdragon.yaml @@ -1,6 +1,17 @@ -id: snapdragon -name: "snapdragon" color: "48" -description: "A clean snapdragon leaf, ready for use in pharmacy." -value: 65 +craft: + consume: + - items: + - grimy_snapdragon + quantity: 1 + level: 59 + message: You clean the grimy snapdragon leaf. + skill: pharmacy + type: clean + wait: 2 + xp: 12 +description: A clean snapdragon leaf, ready for use in pharmacy. +id: snapdragon +name: snapdragon stackable: true +value: 65 diff --git a/data/items/materials/soft_clay.yaml b/data/items/materials/soft_clay.yaml index 018e5ef..9a4dbe5 100644 --- a/data/items/materials/soft_clay.yaml +++ b/data/items/materials/soft_clay.yaml @@ -1,13 +1,20 @@ +color: "173" +craft: + type: combine + consume: + - items: + - clay + quantity: 1 + - byproducts: + - empty_bucket + - empty_jug + items: + - bucket_of_water + - jug_of_water + quantity: 1 + wait: 2 +description: Soft, workable clay ready for shaping on a pottery wheel. id: soft_clay name: soft clay -color: "173" -description: "Soft, workable clay ready for shaping on a pottery wheel." -value: 2 stackable: false -ticks: 2 -made_from: - - items: [clay] - quantity: 1 - - items: [bucket_of_water, jug_of_water] - quantity: 1 - byproducts: [empty_bucket, empty_jug] +value: 2 diff --git a/data/items/materials/steel_bar.yaml b/data/items/materials/steel_bar.yaml index 450fd5c..27ed65c 100644 --- a/data/items/materials/steel_bar.yaml +++ b/data/items/materials/steel_bar.yaml @@ -1,6 +1,23 @@ +color: "254" +craft: + consume: + - items: + - iron_ore + quantity: 1 + - items: + - coal + quantity: 2 + fail_message: You fail to smelt a usable bar. + level: 40 + message: You remove a white hot steel bar! + skill: smithing + station: + - furnace + type: smelting + wait: 4 + xp: 17 +description: A bar of steel, forged from iron ore and coal. id: steel_bar name: steel bar -color: "254" -description: "A bar of steel, forged from iron ore and coal." -value: 30 stackable: false +value: 30 diff --git a/data/items/materials/steel_nails.yaml b/data/items/materials/steel_nails.yaml index 4890d18..e9f9813 100644 --- a/data/items/materials/steel_nails.yaml +++ b/data/items/materials/steel_nails.yaml @@ -1,6 +1,19 @@ +color: "253" +craft: + consume: + - items: + - steel_bar + quantity: 1 + level: 34 + output_qty: 15 + skill: smithing + station: + - anvil + type: smithing + wait: 4 + xp: 37 +description: A set of steel nails. id: steel_nails name: steel nails -color: "253" -description: "A set of steel nails." -value: 4 stackable: true +value: 4 diff --git a/data/items/materials/stim_cell.yaml b/data/items/materials/stim_cell.yaml index b431532..c89191c 100644 --- a/data/items/materials/stim_cell.yaml +++ b/data/items/materials/stim_cell.yaml @@ -1,9 +1,23 @@ -id: stim_cell -name: "stim cell" color: "226" -description: "A bright yellow energy supplement that restores stamina." -value: 65 -stackable: false -potion_effect: "battery" +craft: + consume: + - items: + - harralander_potion_unf + quantity: 1 + - items: + - chocolate_dust + quantity: 1 + level: 26 + message: You mix a stim cell. + skill: pharmacy + type: pharmacy + wait: 4 + xp: 68 +description: A bright yellow energy supplement that restores stamina. +id: stim_cell +name: stim cell potion_bonus: 25 potion_duration: 0 +potion_effect: battery +stackable: false +value: 65 diff --git a/data/items/materials/tarromin.yaml b/data/items/materials/tarromin.yaml index 5af2573..3451e89 100644 --- a/data/items/materials/tarromin.yaml +++ b/data/items/materials/tarromin.yaml @@ -1,6 +1,17 @@ -id: tarromin -name: "tarromin" color: "48" -description: "A clean tarromin leaf, ready for use in pharmacy." -value: 10 +craft: + consume: + - items: + - grimy_tarromin + quantity: 1 + level: 11 + message: You clean the grimy tarromin leaf. + skill: pharmacy + type: clean + wait: 2 + xp: 5 +description: A clean tarromin leaf, ready for use in pharmacy. +id: tarromin +name: tarromin stackable: true +value: 10 diff --git a/data/items/materials/teak_planks.yaml b/data/items/materials/teak_planks.yaml index f0a0642..8a9effc 100644 --- a/data/items/materials/teak_planks.yaml +++ b/data/items/materials/teak_planks.yaml @@ -1,6 +1,20 @@ +color: "100" +craft: + consume: + - items: + - teak_logs + quantity: 1 + level: 35 + message: You saw the teak logs into fine teak planks. + skill: construction + station: + - workbench + tool: saw + type: construction + wait: 20 + xp: 20 +description: Fine teak planks with a rich grain. id: teak_planks name: teak planks -color: "100" -description: "Fine teak planks with a rich grain." -value: 80 stackable: false +value: 80 diff --git a/data/items/materials/toadflax.yaml b/data/items/materials/toadflax.yaml index 0de8f01..d3fa236 100644 --- a/data/items/materials/toadflax.yaml +++ b/data/items/materials/toadflax.yaml @@ -1,6 +1,17 @@ -id: toadflax -name: "toadflax" color: "48" -description: "A clean toadflax leaf, ready for use in pharmacy." -value: 25 +craft: + consume: + - items: + - grimy_toadflax + quantity: 1 + level: 30 + message: You clean the grimy toadflax leaf. + skill: pharmacy + type: clean + wait: 2 + xp: 8 +description: A clean toadflax leaf, ready for use in pharmacy. +id: toadflax +name: toadflax stackable: true +value: 25 diff --git a/data/items/materials/torstol.yaml b/data/items/materials/torstol.yaml index a8b8fbb..97cc20e 100644 --- a/data/items/materials/torstol.yaml +++ b/data/items/materials/torstol.yaml @@ -1,6 +1,17 @@ -id: torstol -name: "torstol" color: "48" -description: "A clean torstol leaf, ready for use in pharmacy." -value: 100 +craft: + consume: + - items: + - grimy_torstol + quantity: 1 + level: 75 + message: You clean the grimy torstol leaf. + skill: pharmacy + type: clean + wait: 2 + xp: 15 +description: A clean torstol leaf, ready for use in pharmacy. +id: torstol +name: torstol stackable: true +value: 100 diff --git a/data/items/misc/mahogany_table.yaml b/data/items/misc/mahogany_table.yaml index 245b929..f932fbe 100644 --- a/data/items/misc/mahogany_table.yaml +++ b/data/items/misc/mahogany_table.yaml @@ -1,6 +1,19 @@ +color: "96" +craft: + consume: + - items: + - mahogany_planks + quantity: 3 + level: 52 + message: You build a luxurious mahogany table. + skill: construction + station: + - workbench + type: construction + wait: 6 + xp: 120 +description: A luxurious mahogany table, the centerpiece of any room. id: mahogany_table name: mahogany table -color: "96" -description: "A luxurious mahogany table, the centerpiece of any room." -value: 240 stackable: false +value: 240 diff --git a/data/items/misc/oak_shelf.yaml b/data/items/misc/oak_shelf.yaml index 0f08fa5..b797d70 100644 --- a/data/items/misc/oak_shelf.yaml +++ b/data/items/misc/oak_shelf.yaml @@ -1,6 +1,19 @@ +color: "94" +craft: + consume: + - items: + - oak_planks + quantity: 2 + level: 18 + message: You assemble the oak planks into a sturdy shelf. + skill: construction + station: + - workbench + type: construction + wait: 6 + xp: 40 +description: A solid oak shelf, built to last. id: oak_shelf name: oak shelf -color: "94" -description: "A solid oak shelf, built to last." -value: 80 stackable: false +value: 80 diff --git a/data/items/misc/oak_table.yaml b/data/items/misc/oak_table.yaml index e94b372..407380f 100644 --- a/data/items/misc/oak_table.yaml +++ b/data/items/misc/oak_table.yaml @@ -1,6 +1,19 @@ +color: "94" +craft: + consume: + - items: + - oak_planks + quantity: 3 + level: 20 + message: You build a fine oak table. + skill: construction + station: + - workbench + type: construction + wait: 6 + xp: 50 +description: A fine oak table with carved legs. id: oak_table name: oak table -color: "94" -description: "A fine oak table with carved legs." -value: 100 stackable: false +value: 100 diff --git a/data/items/misc/teak_table.yaml b/data/items/misc/teak_table.yaml index 5c2c5c5..36c1be6 100644 --- a/data/items/misc/teak_table.yaml +++ b/data/items/misc/teak_table.yaml @@ -1,6 +1,19 @@ +color: "100" +craft: + consume: + - items: + - teak_planks + quantity: 3 + level: 38 + message: You build an elegant teak table. + skill: construction + station: + - workbench + type: construction + wait: 6 + xp: 80 +description: An elegant teak table with a polished surface. id: teak_table name: teak table -color: "100" -description: "An elegant teak table with a polished surface." -value: 160 stackable: false +value: 160 diff --git a/data/items/misc/wooden_chair.yaml b/data/items/misc/wooden_chair.yaml index 16220ef..786a818 100644 --- a/data/items/misc/wooden_chair.yaml +++ b/data/items/misc/wooden_chair.yaml @@ -1,6 +1,19 @@ +color: "130" +craft: + consume: + - items: + - planks + quantity: 2 + level: 8 + message: You craft a comfortable wooden chair. + skill: construction + station: + - workbench + type: construction + wait: 6 + xp: 30 +description: A comfortable wooden chair with a smooth finish. id: wooden_chair name: wooden chair -color: "130" -description: "A comfortable wooden chair with a smooth finish." -value: 35 stackable: false +value: 35 diff --git a/data/items/misc/wooden_shelf.yaml b/data/items/misc/wooden_shelf.yaml index 3b0d97d..a99c0a5 100644 --- a/data/items/misc/wooden_shelf.yaml +++ b/data/items/misc/wooden_shelf.yaml @@ -1,6 +1,19 @@ +color: "130" +craft: + consume: + - items: + - planks + quantity: 2 + level: 4 + message: You assemble the planks into a wooden shelf. + skill: construction + station: + - workbench + type: construction + wait: 6 + xp: 20 +description: A simple wooden shelf, useful for storing small items. id: wooden_shelf name: wooden shelf -color: "130" -description: "A simple wooden shelf, useful for storing small items." -value: 40 stackable: false +value: 40 diff --git a/data/items/misc/wooden_table.yaml b/data/items/misc/wooden_table.yaml index 171a9bb..c59c997 100644 --- a/data/items/misc/wooden_table.yaml +++ b/data/items/misc/wooden_table.yaml @@ -1,6 +1,19 @@ +color: "130" +craft: + consume: + - items: + - planks + quantity: 3 + level: 6 + message: You build a sturdy wooden table. + skill: construction + station: + - workbench + type: construction + wait: 6 + xp: 25 +description: A sturdy wooden table, perfect for dining or displaying objects. id: wooden_table name: wooden table -color: "130" -description: "A sturdy wooden table, perfect for dining or displaying objects." -value: 50 stackable: false +value: 50 diff --git a/data/items/tools/empty_pot.yaml b/data/items/tools/empty_pot.yaml index a57b441..0e1669a 100644 --- a/data/items/tools/empty_pot.yaml +++ b/data/items/tools/empty_pot.yaml @@ -1,6 +1,24 @@ +color: "130" +craft: + consume: + - items: + - unfired_pot + quantity: 1 + fail_message: The pot cracks in the oven and is ruined. + level: 1 + message: You fire the pot in the oven successfully. + skill: crafting + station: + - pottery_oven + success: + base: 0.5 + cap: 0.95 + per_level: 0.02 + type: crafting + wait: 4 + xp: 6 +description: An empty clay pot. id: empty_pot name: empty pot -color: "130" -description: "An empty clay pot." -value: 1 stackable: false +value: 1 diff --git a/data/items/tools/plant_pot.yaml b/data/items/tools/plant_pot.yaml index 2f81e08..bafd007 100644 --- a/data/items/tools/plant_pot.yaml +++ b/data/items/tools/plant_pot.yaml @@ -1,5 +1,23 @@ +color: "130" +craft: + consume: + - items: + - unfired_plant_pot + quantity: 1 + fail_message: The plant pot cracks in the oven and is ruined. + level: 19 + message: You fire the plant pot in the oven successfully. + skill: crafting + station: + - pottery_oven + success: + base: 0.3 + cap: 0.95 + per_level: 0.02 + type: crafting + wait: 4 + xp: 18 +description: A clay plant pot for growing plants. id: plant_pot name: plant pot -color: "130" -description: "A clay plant pot for growing plants." value: 5 diff --git a/data/items/tools/unfired_pie_dish.yaml b/data/items/tools/unfired_pie_dish.yaml index fddc4d1..ee3fc6b 100644 --- a/data/items/tools/unfired_pie_dish.yaml +++ b/data/items/tools/unfired_pie_dish.yaml @@ -1,5 +1,18 @@ +color: "173" +craft: + consume: + - items: + - soft_clay + quantity: 1 + level: 7 + message: You shape the clay into a pie dish. + skill: crafting + station: + - pottery_wheel + type: crafting + wait: 4 + xp: 15 +description: An unfired clay pie dish. It needs to be fired in a pottery oven. id: unfired_pie_dish name: unfired pie dish -color: "173" -description: "An unfired clay pie dish. It needs to be fired in a pottery oven." value: 1 diff --git a/data/items/tools/unfired_plant_pot.yaml b/data/items/tools/unfired_plant_pot.yaml index c088242..960112e 100644 --- a/data/items/tools/unfired_plant_pot.yaml +++ b/data/items/tools/unfired_plant_pot.yaml @@ -1,5 +1,18 @@ +color: "173" +craft: + consume: + - items: + - soft_clay + quantity: 1 + level: 19 + message: You shape the clay into a plant pot. + skill: crafting + station: + - pottery_wheel + type: crafting + wait: 4 + xp: 18 +description: An unfired clay plant pot. It needs to be fired in a pottery oven. id: unfired_plant_pot name: unfired plant pot -color: "173" -description: "An unfired clay plant pot. It needs to be fired in a pottery oven." value: 1 diff --git a/data/items/tools/unfired_pot.yaml b/data/items/tools/unfired_pot.yaml index 265a19f..654cd77 100644 --- a/data/items/tools/unfired_pot.yaml +++ b/data/items/tools/unfired_pot.yaml @@ -1,5 +1,18 @@ +color: "173" +craft: + consume: + - items: + - soft_clay + quantity: 1 + level: 1 + message: You shape the clay into a pot. + skill: crafting + station: + - pottery_wheel + type: crafting + wait: 4 + xp: 6 +description: An unfired clay pot. It needs to be fired in a pottery oven. id: unfired_pot name: unfired pot -color: "173" -description: "An unfired clay pot. It needs to be fired in a pottery oven." value: 1 diff --git a/data/recipes/clean/avantoe.yaml b/data/recipes/clean/avantoe.yaml deleted file mode 100644 index fe00db5..0000000 --- a/data/recipes/clean/avantoe.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: avantoe -type: clean -skill: pharmacy -level: 48 -xp: 10 -wait: 2 -consume: - - items: [grimy_avantoe] - quantity: 1 -output: avantoe -message: "You clean the grimy avantoe leaf." diff --git a/data/recipes/clean/cadantine.yaml b/data/recipes/clean/cadantine.yaml deleted file mode 100644 index 8acb2c5..0000000 --- a/data/recipes/clean/cadantine.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: cadantine -type: clean -skill: pharmacy -level: 65 -xp: 13 -wait: 2 -consume: - - items: [grimy_cadantine] - quantity: 1 -output: cadantine -message: "You clean the grimy cadantine leaf." diff --git a/data/recipes/clean/dwarf_weed.yaml b/data/recipes/clean/dwarf_weed.yaml deleted file mode 100644 index 70c6c42..0000000 --- a/data/recipes/clean/dwarf_weed.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: dwarf_weed -type: clean -skill: pharmacy -level: 70 -xp: 14 -wait: 2 -consume: - - items: [grimy_dwarf_weed] - quantity: 1 -output: dwarf_weed -message: "You clean the grimy dwarf weed leaf." diff --git a/data/recipes/clean/guam.yaml b/data/recipes/clean/guam.yaml deleted file mode 100644 index 410e309..0000000 --- a/data/recipes/clean/guam.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: guam -type: clean -skill: pharmacy -level: 3 -xp: 3 -wait: 2 -consume: - - items: [grimy_guam] - quantity: 1 -output: guam -message: "You clean the grimy guam leaf." diff --git a/data/recipes/clean/harralander.yaml b/data/recipes/clean/harralander.yaml deleted file mode 100644 index f60a737..0000000 --- a/data/recipes/clean/harralander.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: harralander -type: clean -skill: pharmacy -level: 20 -xp: 6 -wait: 2 -consume: - - items: [grimy_harralander] - quantity: 1 -output: harralander -message: "You clean the grimy harralander leaf." diff --git a/data/recipes/clean/irit.yaml b/data/recipes/clean/irit.yaml deleted file mode 100644 index 5853b89..0000000 --- a/data/recipes/clean/irit.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: irit -type: clean -skill: pharmacy -level: 40 -xp: 9 -wait: 2 -consume: - - items: [grimy_irit] - quantity: 1 -output: irit -message: "You clean the grimy irit leaf." diff --git a/data/recipes/clean/kwuarm.yaml b/data/recipes/clean/kwuarm.yaml deleted file mode 100644 index 04e50ad..0000000 --- a/data/recipes/clean/kwuarm.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: kwuarm -type: clean -skill: pharmacy -level: 54 -xp: 11 -wait: 2 -consume: - - items: [grimy_kwuarm] - quantity: 1 -output: kwuarm -message: "You clean the grimy kwuarm leaf." diff --git a/data/recipes/clean/lantadyme.yaml b/data/recipes/clean/lantadyme.yaml deleted file mode 100644 index 499dee9..0000000 --- a/data/recipes/clean/lantadyme.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: lantadyme -type: clean -skill: pharmacy -level: 67 -xp: 13 -wait: 2 -consume: - - items: [grimy_lantadyme] - quantity: 1 -output: lantadyme -message: "You clean the grimy lantadyme leaf." diff --git a/data/recipes/clean/marrentill.yaml b/data/recipes/clean/marrentill.yaml deleted file mode 100644 index 291ea21..0000000 --- a/data/recipes/clean/marrentill.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: marrentill -type: clean -skill: pharmacy -level: 5 -xp: 4 -wait: 2 -consume: - - items: [grimy_marrentill] - quantity: 1 -output: marrentill -message: "You clean the grimy marrentill leaf." diff --git a/data/recipes/clean/ranarr.yaml b/data/recipes/clean/ranarr.yaml deleted file mode 100644 index 989de1e..0000000 --- a/data/recipes/clean/ranarr.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: ranarr -type: clean -skill: pharmacy -level: 25 -xp: 8 -wait: 2 -consume: - - items: [grimy_ranarr] - quantity: 1 -output: ranarr -message: "You clean the grimy ranarr leaf." diff --git a/data/recipes/clean/snapdragon.yaml b/data/recipes/clean/snapdragon.yaml deleted file mode 100644 index 8819630..0000000 --- a/data/recipes/clean/snapdragon.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: snapdragon -type: clean -skill: pharmacy -level: 59 -xp: 12 -wait: 2 -consume: - - items: [grimy_snapdragon] - quantity: 1 -output: snapdragon -message: "You clean the grimy snapdragon leaf." diff --git a/data/recipes/clean/tarromin.yaml b/data/recipes/clean/tarromin.yaml deleted file mode 100644 index 89bdce3..0000000 --- a/data/recipes/clean/tarromin.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: tarromin -type: clean -skill: pharmacy -level: 11 -xp: 5 -wait: 2 -consume: - - items: [grimy_tarromin] - quantity: 1 -output: tarromin -message: "You clean the grimy tarromin leaf." diff --git a/data/recipes/clean/toadflax.yaml b/data/recipes/clean/toadflax.yaml deleted file mode 100644 index 77fb955..0000000 --- a/data/recipes/clean/toadflax.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: toadflax -type: clean -skill: pharmacy -level: 30 -xp: 8 -wait: 2 -consume: - - items: [grimy_toadflax] - quantity: 1 -output: toadflax -message: "You clean the grimy toadflax leaf." diff --git a/data/recipes/clean/torstol.yaml b/data/recipes/clean/torstol.yaml deleted file mode 100644 index 8833eb4..0000000 --- a/data/recipes/clean/torstol.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: torstol -type: clean -skill: pharmacy -level: 75 -xp: 15 -wait: 2 -consume: - - items: [grimy_torstol] - quantity: 1 -output: torstol -message: "You clean the grimy torstol leaf." diff --git a/data/recipes/construction/mahogany_planks.yaml b/data/recipes/construction/mahogany_planks.yaml deleted file mode 100644 index 3008a07..0000000 --- a/data/recipes/construction/mahogany_planks.yaml +++ /dev/null @@ -1,12 +0,0 @@ -id: mahogany_planks -type: construction -level: 50 -xp: 30 -wait: 20 -station: [workbench] -tool: saw -consume: - - items: [mahogany_logs] - quantity: 1 -output: mahogany_planks -message: "You saw the mahogany logs into luxurious mahogany planks." diff --git a/data/recipes/construction/mahogany_table.yaml b/data/recipes/construction/mahogany_table.yaml deleted file mode 100644 index 4b08c06..0000000 --- a/data/recipes/construction/mahogany_table.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: mahogany_table -type: construction -level: 52 -xp: 120 -wait: 6 -station: [workbench] -consume: - - items: [mahogany_planks] - quantity: 3 -output: mahogany_table -message: "You build a luxurious mahogany table." diff --git a/data/recipes/construction/oak_planks.yaml b/data/recipes/construction/oak_planks.yaml deleted file mode 100644 index da50f88..0000000 --- a/data/recipes/construction/oak_planks.yaml +++ /dev/null @@ -1,12 +0,0 @@ -id: oak_planks -type: construction -level: 15 -xp: 10 -wait: 20 -station: [workbench] -tool: saw -consume: - - items: [oak_logs] - quantity: 1 -output: oak_planks -message: "You saw the oak logs into sturdy oak planks." diff --git a/data/recipes/construction/oak_shelf.yaml b/data/recipes/construction/oak_shelf.yaml deleted file mode 100644 index c9f6242..0000000 --- a/data/recipes/construction/oak_shelf.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: oak_shelf -type: construction -level: 18 -xp: 40 -wait: 6 -station: [workbench] -consume: - - items: [oak_planks] - quantity: 2 -output: oak_shelf -message: "You assemble the oak planks into a sturdy shelf." diff --git a/data/recipes/construction/oak_table.yaml b/data/recipes/construction/oak_table.yaml deleted file mode 100644 index 6428200..0000000 --- a/data/recipes/construction/oak_table.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: oak_table -type: construction -level: 20 -xp: 50 -wait: 6 -station: [workbench] -consume: - - items: [oak_planks] - quantity: 3 -output: oak_table -message: "You build a fine oak table." diff --git a/data/recipes/construction/planks.yaml b/data/recipes/construction/planks.yaml deleted file mode 100644 index 9d202ff..0000000 --- a/data/recipes/construction/planks.yaml +++ /dev/null @@ -1,12 +0,0 @@ -id: planks -type: construction -level: 1 -xp: 5 -wait: 20 -station: [workbench] -tool: saw -consume: - - items: [logs] - quantity: 1 -output: planks -message: "You saw the logs into some regular planks." diff --git a/data/recipes/construction/teak_planks.yaml b/data/recipes/construction/teak_planks.yaml deleted file mode 100644 index 1780d8b..0000000 --- a/data/recipes/construction/teak_planks.yaml +++ /dev/null @@ -1,12 +0,0 @@ -id: teak_planks -type: construction -level: 35 -xp: 20 -wait: 20 -station: [workbench] -tool: saw -consume: - - items: [teak_logs] - quantity: 1 -output: teak_planks -message: "You saw the teak logs into fine teak planks." diff --git a/data/recipes/construction/teak_table.yaml b/data/recipes/construction/teak_table.yaml deleted file mode 100644 index ce579e1..0000000 --- a/data/recipes/construction/teak_table.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: teak_table -type: construction -level: 38 -xp: 80 -wait: 6 -station: [workbench] -consume: - - items: [teak_planks] - quantity: 3 -output: teak_table -message: "You build an elegant teak table." diff --git a/data/recipes/construction/wooden_chair.yaml b/data/recipes/construction/wooden_chair.yaml deleted file mode 100644 index a1db252..0000000 --- a/data/recipes/construction/wooden_chair.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: wooden_chair -type: construction -level: 8 -xp: 30 -wait: 6 -station: [workbench] -consume: - - items: [planks] - quantity: 2 -output: wooden_chair -message: "You craft a comfortable wooden chair." diff --git a/data/recipes/construction/wooden_shelf.yaml b/data/recipes/construction/wooden_shelf.yaml deleted file mode 100644 index 3ea97cc..0000000 --- a/data/recipes/construction/wooden_shelf.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: wooden_shelf -type: construction -level: 4 -xp: 20 -wait: 6 -station: [workbench] -consume: - - items: [planks] - quantity: 2 -output: wooden_shelf -message: "You assemble the planks into a wooden shelf." diff --git a/data/recipes/construction/wooden_table.yaml b/data/recipes/construction/wooden_table.yaml deleted file mode 100644 index 73050a7..0000000 --- a/data/recipes/construction/wooden_table.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: wooden_table -type: construction -level: 6 -xp: 25 -wait: 6 -station: [workbench] -consume: - - items: [planks] - quantity: 3 -output: wooden_table -message: "You build a sturdy wooden table." diff --git a/data/recipes/cooking/anchovies.yaml b/data/recipes/cooking/anchovies.yaml deleted file mode 100644 index 26bcc39..0000000 --- a/data/recipes/cooking/anchovies.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: anchovies -type: cooking -level: 1 -xp: 30 -wait: 6 -station: [fire, cooking_range] -consume: - - items: [raw_anchovies] - quantity: 1 -output: anchovies -fail: burnt_fish -message: "Cooked to perfection. It looks great!" -fail_message: "You accidentally burn the anchovies." diff --git a/data/recipes/cooking/bread.yaml b/data/recipes/cooking/bread.yaml deleted file mode 100644 index 0a27439..0000000 --- a/data/recipes/cooking/bread.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: bread -type: cooking -level: 1 -xp: 40 -wait: 6 -station: [cooking_range] -consume: - - items: [bread_dough] - quantity: 1 -output: bread -fail: burnt_meat -message: "You bake the dough into a fresh loaf of bread." -fail_message: "You burn the bread to a crisp." diff --git a/data/recipes/cooking/herring.yaml b/data/recipes/cooking/herring.yaml deleted file mode 100644 index 486476c..0000000 --- a/data/recipes/cooking/herring.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: herring -type: cooking -level: 5 -xp: 50 -wait: 6 -station: [fire, cooking_range] -consume: - - items: [raw_herring] - quantity: 1 -output: herring -fail: burnt_fish -message: "Cooked to perfection. It looks great!" -fail_message: "You accidentally burn the herring." diff --git a/data/recipes/cooking/salmon.yaml b/data/recipes/cooking/salmon.yaml deleted file mode 100644 index c3362c0..0000000 --- a/data/recipes/cooking/salmon.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: salmon -type: cooking -level: 25 -xp: 90 -wait: 6 -station: [fire, cooking_range] -consume: - - items: [raw_salmon] - quantity: 1 -output: salmon -fail: burnt_fish -message: "Cooked to perfection. It looks great!" -fail_message: "You accidentally burn the salmon." diff --git a/data/recipes/cooking/sardine.yaml b/data/recipes/cooking/sardine.yaml deleted file mode 100644 index c03b7f0..0000000 --- a/data/recipes/cooking/sardine.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: sardine -type: cooking -level: 1 -xp: 40 -wait: 6 -station: [fire, cooking_range] -consume: - - items: [raw_sardine] - quantity: 1 -output: sardine -fail: burnt_fish -message: "Cooked to perfection. It looks great!" -fail_message: "You accidentally burn the sardine." diff --git a/data/recipes/cooking/shrimps.yaml b/data/recipes/cooking/shrimps.yaml deleted file mode 100644 index 19ae396..0000000 --- a/data/recipes/cooking/shrimps.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: shrimps -type: cooking -level: 1 -xp: 30 -wait: 6 -station: [fire, cooking_range] -consume: - - items: [raw_shrimps] - quantity: 1 -output: shrimps -fail: burnt_fish -message: "Cooked to perfection. It looks great!" -fail_message: "You accidentally burn the shrimps." diff --git a/data/recipes/cooking/trout.yaml b/data/recipes/cooking/trout.yaml deleted file mode 100644 index 72587d5..0000000 --- a/data/recipes/cooking/trout.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: trout -type: cooking -level: 15 -xp: 70 -wait: 6 -station: [fire, cooking_range] -consume: - - items: [raw_trout] - quantity: 1 -output: trout -fail: burnt_fish -message: "Cooked to perfection. It looks great!" -fail_message: "You accidentally burn the trout." diff --git a/data/recipes/crafting/ball_of_wool.yaml b/data/recipes/crafting/ball_of_wool.yaml deleted file mode 100644 index 09fca8b..0000000 --- a/data/recipes/crafting/ball_of_wool.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: ball_of_wool -type: crafting -level: 1 -xp: 3 -wait: 3 -station: [spinning_wheel] -consume: - - items: [wool] - quantity: 1 -output: ball_of_wool -message: "You spin the wool into a ball." diff --git a/data/recipes/crafting/bowstring.yaml b/data/recipes/crafting/bowstring.yaml deleted file mode 100644 index dfb4ea7..0000000 --- a/data/recipes/crafting/bowstring.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: bowstring -type: crafting -level: 1 -xp: 15 -wait: 3 -station: [spinning_wheel] -consume: - - items: [flax] - quantity: 1 -output: bowstring -message: "You spin the flax into a bowstring." diff --git a/data/recipes/crafting/coif.yaml b/data/recipes/crafting/coif.yaml deleted file mode 100644 index 8e6cac9..0000000 --- a/data/recipes/crafting/coif.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: coif -type: crafting -level: 38 -xp: 37 -wait: 4 -tool: needle -consume: - - items: [hard_leather] - quantity: 1 - - items: [thread] - quantity: 1 -output: coif -message: "You craft a coif." diff --git a/data/recipes/crafting/cut_diamond.yaml b/data/recipes/crafting/cut_diamond.yaml deleted file mode 100644 index e1e7343..0000000 --- a/data/recipes/crafting/cut_diamond.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: cut_diamond -type: crafting -level: 43 -xp: 108 -wait: 3 -tool: chisel -consume: - - items: [uncut_diamond] - quantity: 1 -output: diamond -message: "You cut the diamond into a beautiful gem." diff --git a/data/recipes/crafting/cut_emerald.yaml b/data/recipes/crafting/cut_emerald.yaml deleted file mode 100644 index 405fb53..0000000 --- a/data/recipes/crafting/cut_emerald.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: cut_emerald -type: crafting -level: 27 -xp: 68 -wait: 3 -tool: chisel -consume: - - items: [uncut_emerald] - quantity: 1 -output: emerald -message: "You cut the emerald into a beautiful gem." diff --git a/data/recipes/crafting/cut_ruby.yaml b/data/recipes/crafting/cut_ruby.yaml deleted file mode 100644 index 02ab139..0000000 --- a/data/recipes/crafting/cut_ruby.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: cut_ruby -type: crafting -level: 63 -xp: 85 -wait: 3 -tool: chisel -consume: - - items: [uncut_ruby] - quantity: 1 -output: ruby -message: "You cut the ruby into a beautiful gem." diff --git a/data/recipes/crafting/cut_sapphire.yaml b/data/recipes/crafting/cut_sapphire.yaml deleted file mode 100644 index 330834f..0000000 --- a/data/recipes/crafting/cut_sapphire.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: cut_sapphire -type: crafting -level: 20 -xp: 50 -wait: 3 -tool: chisel -consume: - - items: [uncut_sapphire] - quantity: 1 -output: sapphire -message: "You cut the sapphire into a beautiful gem." diff --git a/data/recipes/crafting/diamond_amulet_u.yaml b/data/recipes/crafting/diamond_amulet_u.yaml deleted file mode 100644 index 9c90b8c..0000000 --- a/data/recipes/crafting/diamond_amulet_u.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: diamond_amulet_u -type: crafting -level: 70 -xp: 100 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [diamond] - quantity: 1 - - items: [amulet_mould] - quantity: 1 - byproducts: [amulet_mould] -output: diamond_amulet_u -message: "You cast a diamond amulet." diff --git a/data/recipes/crafting/diamond_bracelet.yaml b/data/recipes/crafting/diamond_bracelet.yaml deleted file mode 100644 index 0a15546..0000000 --- a/data/recipes/crafting/diamond_bracelet.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: diamond_bracelet -type: crafting -level: 58 -xp: 95 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [diamond] - quantity: 1 - - items: [bracelet_mould] - quantity: 1 - byproducts: [bracelet_mould] -output: diamond_bracelet -message: "You cast a diamond bracelet." diff --git a/data/recipes/crafting/diamond_necklace.yaml b/data/recipes/crafting/diamond_necklace.yaml deleted file mode 100644 index 9c15245..0000000 --- a/data/recipes/crafting/diamond_necklace.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: diamond_necklace -type: crafting -level: 56 -xp: 90 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [diamond] - quantity: 1 - - items: [necklace_mould] - quantity: 1 - byproducts: [necklace_mould] -output: diamond_necklace -message: "You cast a diamond necklace." diff --git a/data/recipes/crafting/diamond_ring.yaml b/data/recipes/crafting/diamond_ring.yaml deleted file mode 100644 index 3045b74..0000000 --- a/data/recipes/crafting/diamond_ring.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: diamond_ring -type: crafting -level: 43 -xp: 85 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [diamond] - quantity: 1 - - items: [ring_mould] - quantity: 1 - byproducts: [ring_mould] -output: diamond_ring -message: "You cast a diamond ring." diff --git a/data/recipes/crafting/emerald_amulet_u.yaml b/data/recipes/crafting/emerald_amulet_u.yaml deleted file mode 100644 index 4530fa2..0000000 --- a/data/recipes/crafting/emerald_amulet_u.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: emerald_amulet_u -type: crafting -level: 31 -xp: 70 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [emerald] - quantity: 1 - - items: [amulet_mould] - quantity: 1 - byproducts: [amulet_mould] -output: emerald_amulet_u -message: "You cast a emerald amulet." diff --git a/data/recipes/crafting/emerald_bracelet.yaml b/data/recipes/crafting/emerald_bracelet.yaml deleted file mode 100644 index 498b1ce..0000000 --- a/data/recipes/crafting/emerald_bracelet.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: emerald_bracelet -type: crafting -level: 30 -xp: 65 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [emerald] - quantity: 1 - - items: [bracelet_mould] - quantity: 1 - byproducts: [bracelet_mould] -output: emerald_bracelet -message: "You cast a emerald bracelet." diff --git a/data/recipes/crafting/emerald_necklace.yaml b/data/recipes/crafting/emerald_necklace.yaml deleted file mode 100644 index 2d0596e..0000000 --- a/data/recipes/crafting/emerald_necklace.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: emerald_necklace -type: crafting -level: 29 -xp: 60 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [emerald] - quantity: 1 - - items: [necklace_mould] - quantity: 1 - byproducts: [necklace_mould] -output: emerald_necklace -message: "You cast a emerald necklace." diff --git a/data/recipes/crafting/emerald_ring.yaml b/data/recipes/crafting/emerald_ring.yaml deleted file mode 100644 index c5cee62..0000000 --- a/data/recipes/crafting/emerald_ring.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: emerald_ring -type: crafting -level: 27 -xp: 55 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [emerald] - quantity: 1 - - items: [ring_mould] - quantity: 1 - byproducts: [ring_mould] -output: emerald_ring -message: "You cast a emerald ring." diff --git a/data/recipes/crafting/gold_amulet_u.yaml b/data/recipes/crafting/gold_amulet_u.yaml deleted file mode 100644 index d960be6..0000000 --- a/data/recipes/crafting/gold_amulet_u.yaml +++ /dev/null @@ -1,14 +0,0 @@ -id: gold_amulet_u -type: crafting -level: 8 -xp: 30 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [amulet_mould] - quantity: 1 - byproducts: [amulet_mould] -output: gold_amulet_u -message: "You cast a gold amulet." diff --git a/data/recipes/crafting/gold_bracelet.yaml b/data/recipes/crafting/gold_bracelet.yaml deleted file mode 100644 index 9669943..0000000 --- a/data/recipes/crafting/gold_bracelet.yaml +++ /dev/null @@ -1,14 +0,0 @@ -id: gold_bracelet -type: crafting -level: 7 -xp: 25 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [bracelet_mould] - quantity: 1 - byproducts: [bracelet_mould] -output: gold_bracelet -message: "You cast a gold bracelet." diff --git a/data/recipes/crafting/gold_necklace.yaml b/data/recipes/crafting/gold_necklace.yaml deleted file mode 100644 index e2a96c4..0000000 --- a/data/recipes/crafting/gold_necklace.yaml +++ /dev/null @@ -1,14 +0,0 @@ -id: gold_necklace -type: crafting -level: 6 -xp: 20 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [necklace_mould] - quantity: 1 - byproducts: [necklace_mould] -output: gold_necklace -message: "You cast a gold necklace." diff --git a/data/recipes/crafting/gold_ring.yaml b/data/recipes/crafting/gold_ring.yaml deleted file mode 100644 index dcb3c09..0000000 --- a/data/recipes/crafting/gold_ring.yaml +++ /dev/null @@ -1,14 +0,0 @@ -id: gold_ring -type: crafting -level: 5 -xp: 15 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [ring_mould] - quantity: 1 - byproducts: [ring_mould] -output: gold_ring -message: "You cast a gold ring." diff --git a/data/recipes/crafting/hard_leather_body.yaml b/data/recipes/crafting/hard_leather_body.yaml deleted file mode 100644 index 869867e..0000000 --- a/data/recipes/crafting/hard_leather_body.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: hard_leather_body -type: crafting -level: 28 -xp: 35 -wait: 4 -tool: needle -consume: - - items: [hard_leather] - quantity: 1 - - items: [thread] - quantity: 1 -output: hard_leather_body -message: "You craft a hard leather body." diff --git a/data/recipes/crafting/hard_leather_shield.yaml b/data/recipes/crafting/hard_leather_shield.yaml deleted file mode 100644 index b46222f..0000000 --- a/data/recipes/crafting/hard_leather_shield.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: hard_leather_shield -type: crafting -level: 41 -xp: 40 -wait: 4 -tool: needle -consume: - - items: [hard_leather] - quantity: 1 - - items: [thread] - quantity: 1 -output: hard_leather_shield -message: "You craft a hard leather shield." diff --git a/data/recipes/crafting/leather_body.yaml b/data/recipes/crafting/leather_body.yaml deleted file mode 100644 index 4f87c8f..0000000 --- a/data/recipes/crafting/leather_body.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: leather_body -type: crafting -level: 14 -xp: 25 -wait: 4 -tool: needle -consume: - - items: [leather] - quantity: 1 - - items: [thread] - quantity: 1 -output: leather_body -message: "You craft a leather body." diff --git a/data/recipes/crafting/leather_boots.yaml b/data/recipes/crafting/leather_boots.yaml deleted file mode 100644 index 569fb81..0000000 --- a/data/recipes/crafting/leather_boots.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: leather_boots -type: crafting -level: 7 -xp: 16 -wait: 4 -tool: needle -consume: - - items: [leather] - quantity: 1 - - items: [thread] - quantity: 1 -output: leather_boots -message: "You craft a pair of leather boots." diff --git a/data/recipes/crafting/leather_chaps.yaml b/data/recipes/crafting/leather_chaps.yaml deleted file mode 100644 index 82fdac9..0000000 --- a/data/recipes/crafting/leather_chaps.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: leather_chaps -type: crafting -level: 18 -xp: 27 -wait: 4 -tool: needle -consume: - - items: [leather] - quantity: 1 - - items: [thread] - quantity: 1 -output: leather_chaps -message: "You craft a pair of leather chaps." diff --git a/data/recipes/crafting/leather_cowl.yaml b/data/recipes/crafting/leather_cowl.yaml deleted file mode 100644 index 70fc500..0000000 --- a/data/recipes/crafting/leather_cowl.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: leather_cowl -type: crafting -level: 9 -xp: 19 -wait: 4 -tool: needle -consume: - - items: [leather] - quantity: 1 - - items: [thread] - quantity: 1 -output: leather_cowl -message: "You craft a leather cowl." diff --git a/data/recipes/crafting/leather_gloves.yaml b/data/recipes/crafting/leather_gloves.yaml deleted file mode 100644 index fa4cd37..0000000 --- a/data/recipes/crafting/leather_gloves.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: leather_gloves -type: crafting -level: 1 -xp: 14 -wait: 4 -tool: needle -consume: - - items: [leather] - quantity: 1 - - items: [thread] - quantity: 1 -output: leather_gloves -message: "You craft a pair of leather gloves." diff --git a/data/recipes/crafting/leather_vambraces.yaml b/data/recipes/crafting/leather_vambraces.yaml deleted file mode 100644 index 6167294..0000000 --- a/data/recipes/crafting/leather_vambraces.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: leather_vambraces -type: crafting -level: 11 -xp: 22 -wait: 4 -tool: needle -consume: - - items: [leather] - quantity: 1 - - items: [thread] - quantity: 1 -output: leather_vambraces -message: "You craft a pair of leather vambraces." diff --git a/data/recipes/crafting/pie_dish.yaml b/data/recipes/crafting/pie_dish.yaml deleted file mode 100644 index 5f49d62..0000000 --- a/data/recipes/crafting/pie_dish.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: pie_dish -type: crafting -level: 7 -xp: 10 -wait: 4 -station: [pottery_oven] -consume: - - items: [unfired_pie_dish] - quantity: 1 -output: pie_dish -message: "You fire the pie dish in the oven successfully." -fail_message: "The pie dish cracks in the oven and is ruined." -success: - base: 0.40 - per_level: 0.02 - cap: 0.95 diff --git a/data/recipes/crafting/plant_pot.yaml b/data/recipes/crafting/plant_pot.yaml deleted file mode 100644 index 2c4b228..0000000 --- a/data/recipes/crafting/plant_pot.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: plant_pot -type: crafting -level: 19 -xp: 18 -wait: 4 -station: [pottery_oven] -consume: - - items: [unfired_plant_pot] - quantity: 1 -output: plant_pot -message: "You fire the plant pot in the oven successfully." -fail_message: "The plant pot cracks in the oven and is ruined." -success: - base: 0.30 - per_level: 0.02 - cap: 0.95 diff --git a/data/recipes/crafting/pot.yaml b/data/recipes/crafting/pot.yaml deleted file mode 100644 index 3215036..0000000 --- a/data/recipes/crafting/pot.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: pot -type: crafting -level: 1 -xp: 6 -wait: 4 -station: [pottery_oven] -consume: - - items: [unfired_pot] - quantity: 1 -output: empty_pot -message: "You fire the pot in the oven successfully." -fail_message: "The pot cracks in the oven and is ruined." -success: - base: 0.50 - per_level: 0.02 - cap: 0.95 diff --git a/data/recipes/crafting/ruby_amulet_u.yaml b/data/recipes/crafting/ruby_amulet_u.yaml deleted file mode 100644 index 2958d77..0000000 --- a/data/recipes/crafting/ruby_amulet_u.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: ruby_amulet_u -type: crafting -level: 50 -xp: 85 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [ruby] - quantity: 1 - - items: [amulet_mould] - quantity: 1 - byproducts: [amulet_mould] -output: ruby_amulet_u -message: "You cast a ruby amulet." diff --git a/data/recipes/crafting/ruby_bracelet.yaml b/data/recipes/crafting/ruby_bracelet.yaml deleted file mode 100644 index 7f36bce..0000000 --- a/data/recipes/crafting/ruby_bracelet.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: ruby_bracelet -type: crafting -level: 42 -xp: 80 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [ruby] - quantity: 1 - - items: [bracelet_mould] - quantity: 1 - byproducts: [bracelet_mould] -output: ruby_bracelet -message: "You cast a ruby bracelet." diff --git a/data/recipes/crafting/ruby_necklace.yaml b/data/recipes/crafting/ruby_necklace.yaml deleted file mode 100644 index 7be562e..0000000 --- a/data/recipes/crafting/ruby_necklace.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: ruby_necklace -type: crafting -level: 40 -xp: 75 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [ruby] - quantity: 1 - - items: [necklace_mould] - quantity: 1 - byproducts: [necklace_mould] -output: ruby_necklace -message: "You cast a ruby necklace." diff --git a/data/recipes/crafting/ruby_ring.yaml b/data/recipes/crafting/ruby_ring.yaml deleted file mode 100644 index 78a6339..0000000 --- a/data/recipes/crafting/ruby_ring.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: ruby_ring -type: crafting -level: 63 -xp: 70 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [ruby] - quantity: 1 - - items: [ring_mould] - quantity: 1 - byproducts: [ring_mould] -output: ruby_ring -message: "You cast a ruby ring." diff --git a/data/recipes/crafting/sapphire_amulet_u.yaml b/data/recipes/crafting/sapphire_amulet_u.yaml deleted file mode 100644 index 36302d8..0000000 --- a/data/recipes/crafting/sapphire_amulet_u.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: sapphire_amulet_u -type: crafting -level: 24 -xp: 65 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [sapphire] - quantity: 1 - - items: [amulet_mould] - quantity: 1 - byproducts: [amulet_mould] -output: sapphire_amulet_u -message: "You cast a sapphire amulet." diff --git a/data/recipes/crafting/sapphire_bracelet.yaml b/data/recipes/crafting/sapphire_bracelet.yaml deleted file mode 100644 index 2e1031e..0000000 --- a/data/recipes/crafting/sapphire_bracelet.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: sapphire_bracelet -type: crafting -level: 23 -xp: 60 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [sapphire] - quantity: 1 - - items: [bracelet_mould] - quantity: 1 - byproducts: [bracelet_mould] -output: sapphire_bracelet -message: "You cast a sapphire bracelet." diff --git a/data/recipes/crafting/sapphire_necklace.yaml b/data/recipes/crafting/sapphire_necklace.yaml deleted file mode 100644 index 2671e6b..0000000 --- a/data/recipes/crafting/sapphire_necklace.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: sapphire_necklace -type: crafting -level: 22 -xp: 55 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [sapphire] - quantity: 1 - - items: [necklace_mould] - quantity: 1 - byproducts: [necklace_mould] -output: sapphire_necklace -message: "You cast a sapphire necklace." diff --git a/data/recipes/crafting/sapphire_ring.yaml b/data/recipes/crafting/sapphire_ring.yaml deleted file mode 100644 index f755b6f..0000000 --- a/data/recipes/crafting/sapphire_ring.yaml +++ /dev/null @@ -1,16 +0,0 @@ -id: sapphire_ring -type: crafting -level: 20 -xp: 40 -wait: 4 -station: [furnace] -consume: - - items: [gold_bar] - quantity: 1 - - items: [sapphire] - quantity: 1 - - items: [ring_mould] - quantity: 1 - byproducts: [ring_mould] -output: sapphire_ring -message: "You cast a sapphire ring." diff --git a/data/recipes/crafting/unfired_pie_dish.yaml b/data/recipes/crafting/unfired_pie_dish.yaml deleted file mode 100644 index d698cf4..0000000 --- a/data/recipes/crafting/unfired_pie_dish.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: unfired_pie_dish -type: crafting -level: 7 -xp: 15 -wait: 4 -station: [pottery_wheel] -consume: - - items: [soft_clay] - quantity: 1 -output: unfired_pie_dish -message: "You shape the clay into a pie dish." diff --git a/data/recipes/crafting/unfired_plant_pot.yaml b/data/recipes/crafting/unfired_plant_pot.yaml deleted file mode 100644 index e0675db..0000000 --- a/data/recipes/crafting/unfired_plant_pot.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: unfired_plant_pot -type: crafting -level: 19 -xp: 18 -wait: 4 -station: [pottery_wheel] -consume: - - items: [soft_clay] - quantity: 1 -output: unfired_plant_pot -message: "You shape the clay into a plant pot." diff --git a/data/recipes/crafting/unfired_pot.yaml b/data/recipes/crafting/unfired_pot.yaml deleted file mode 100644 index 04604e3..0000000 --- a/data/recipes/crafting/unfired_pot.yaml +++ /dev/null @@ -1,11 +0,0 @@ -id: unfired_pot -type: crafting -level: 1 -xp: 6 -wait: 4 -station: [pottery_wheel] -consume: - - items: [soft_clay] - quantity: 1 -output: unfired_pot -message: "You shape the clay into a pot." diff --git a/data/recipes/fletching/arrow_shafts.yaml b/data/recipes/fletching/arrow_shafts.yaml deleted file mode 100644 index c382340..0000000 --- a/data/recipes/fletching/arrow_shafts.yaml +++ /dev/null @@ -1,52 +0,0 @@ -type: fletching -tool: knife -wait: 5 -products: - - id: arrow_shaft - output: arrow_shaft - level: 1 - xp: 5 - output_qty: 15 - consume: - - items: [logs] - quantity: 1 - - id: arrow_shaft_oak - output: arrow_shaft - level: 15 - xp: 10 - output_qty: 20 - consume: - - items: [oak_logs] - quantity: 1 - - id: arrow_shaft_willow - output: arrow_shaft - level: 30 - xp: 15 - output_qty: 25 - consume: - - items: [willow_logs] - quantity: 1 - - id: arrow_shaft_maple - output: arrow_shaft - level: 45 - xp: 20 - output_qty: 30 - consume: - - items: [maple_logs] - quantity: 1 - - id: arrow_shaft_yew - output: arrow_shaft - level: 60 - xp: 25 - output_qty: 35 - consume: - - items: [yew_logs] - quantity: 1 - - id: arrow_shaft_magic - output: arrow_shaft - level: 75 - xp: 30 - output_qty: 40 - consume: - - items: [magic_logs] - quantity: 1 diff --git a/data/recipes/fletching/bolt_feathering.yaml b/data/recipes/fletching/bolt_feathering.yaml deleted file mode 100644 index 2197de1..0000000 --- a/data/recipes/fletching/bolt_feathering.yaml +++ /dev/null @@ -1,63 +0,0 @@ -type: fletching -wait: 0 -products: - - id: bronze_bolts - output: bronze_bolts - level: 9 - xp: 5 - output_qty: 10 - consume: - - items: [bronze_bolts_unf] - quantity: 10 - - items: [feather] - quantity: 10 - - id: iron_bolts - output: iron_bolts - level: 39 - xp: 15 - output_qty: 10 - consume: - - items: [iron_bolts_unf] - quantity: 10 - - items: [feather] - quantity: 10 - - id: steel_bolts - output: steel_bolts - level: 46 - xp: 35 - output_qty: 10 - consume: - - items: [steel_bolts_unf] - quantity: 10 - - items: [feather] - quantity: 10 - - id: mithril_bolts - output: mithril_bolts - level: 54 - xp: 50 - output_qty: 10 - consume: - - items: [mithril_bolts_unf] - quantity: 10 - - items: [feather] - quantity: 10 - - id: adamant_bolts - output: adamant_bolts - level: 61 - xp: 70 - output_qty: 10 - consume: - - items: [adamant_bolts_unf] - quantity: 10 - - items: [feather] - quantity: 10 - - id: rune_bolts - output: rune_bolts - level: 69 - xp: 100 - output_qty: 10 - consume: - - items: [rune_bolts_unf] - quantity: 10 - - items: [feather] - quantity: 10 diff --git a/data/recipes/fletching/gem_bolt_tips.yaml b/data/recipes/fletching/gem_bolt_tips.yaml deleted file mode 100644 index 5482140..0000000 --- a/data/recipes/fletching/gem_bolt_tips.yaml +++ /dev/null @@ -1,36 +0,0 @@ -type: fletching -tool: chisel -wait: 5 -products: - - id: sapphire_bolt_tips - output: sapphire_bolt_tips - level: 63 - xp: 4 - output_qty: 12 - consume: - - items: [uncut_sapphire] - quantity: 1 - - id: diamond_bolt_tips - output: diamond_bolt_tips - level: 65 - xp: 7 - output_qty: 12 - consume: - - items: [uncut_diamond] - quantity: 1 - - id: emerald_bolt_tips - output: emerald_bolt_tips - level: 66 - xp: 5 - output_qty: 12 - consume: - - items: [uncut_emerald] - quantity: 1 - - id: ruby_bolt_tips - output: ruby_bolt_tips - level: 73 - xp: 6 - output_qty: 12 - consume: - - items: [uncut_ruby] - quantity: 1 diff --git a/data/recipes/fletching/gem_tipped_bolts.yaml b/data/recipes/fletching/gem_tipped_bolts.yaml deleted file mode 100644 index 7ed5adc..0000000 --- a/data/recipes/fletching/gem_tipped_bolts.yaml +++ /dev/null @@ -1,43 +0,0 @@ -type: fletching -wait: 2 -products: - - id: sapphire_bolts - output: sapphire_bolts - level: 63 - xp: 4 - output_qty: 10 - consume: - - items: [mithril_bolts] - quantity: 10 - - items: [sapphire_bolt_tips] - quantity: 10 - - id: diamond_bolts - output: diamond_bolts - level: 65 - xp: 7 - output_qty: 10 - consume: - - items: [adamant_bolts] - quantity: 10 - - items: [diamond_bolt_tips] - quantity: 10 - - id: emerald_bolts - output: emerald_bolts - level: 66 - xp: 5 - output_qty: 10 - consume: - - items: [mithril_bolts] - quantity: 10 - - items: [emerald_bolt_tips] - quantity: 10 - - id: ruby_bolts - output: ruby_bolts - level: 73 - xp: 6 - output_qty: 10 - consume: - - items: [adamant_bolts] - quantity: 10 - - items: [ruby_bolt_tips] - quantity: 10 diff --git a/data/recipes/fletching/headless_arrow.yaml b/data/recipes/fletching/headless_arrow.yaml deleted file mode 100644 index 0c1e363..0000000 --- a/data/recipes/fletching/headless_arrow.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: headless_arrow -type: fletching -level: 1 -xp: 1 -wait: 2 -consume: - - items: [arrow_shaft] - quantity: 15 - - items: [feather] - quantity: 15 -output: headless_arrow -output_qty: 15 -message: "You attach feathers to the arrow shafts." diff --git a/data/recipes/fletching/strung_bows.yaml b/data/recipes/fletching/strung_bows.yaml deleted file mode 100644 index c7e2c3d..0000000 --- a/data/recipes/fletching/strung_bows.yaml +++ /dev/null @@ -1,111 +0,0 @@ -type: fletching -wait: 2 -products: - - id: shortbow - output: shortbow - level: 5 - xp: 5 - consume: - - items: [shortbow_u] - quantity: 1 - - items: [bowstring] - quantity: 1 - - id: longbow - output: longbow - level: 10 - xp: 10 - consume: - - items: [longbow_u] - quantity: 1 - - items: [bowstring] - quantity: 1 - - id: oak_shortbow - output: oak_shortbow - level: 20 - xp: 16 - consume: - - items: [oak_shortbow_u] - quantity: 1 - - items: [bowstring] - quantity: 1 - - id: oak_longbow - output: oak_longbow - level: 25 - xp: 25 - consume: - - items: [oak_longbow_u] - quantity: 1 - - items: [bowstring] - quantity: 1 - - id: willow_shortbow - output: willow_shortbow - level: 35 - xp: 33 - consume: - - items: [willow_shortbow_u] - quantity: 1 - - items: [bowstring] - quantity: 1 - - id: willow_longbow - output: willow_longbow - level: 40 - xp: 41 - consume: - - items: [willow_longbow_u] - quantity: 1 - - items: [bowstring] - quantity: 1 - - id: maple_shortbow - output: maple_shortbow - level: 50 - xp: 50 - consume: - - items: [maple_shortbow_u] - quantity: 1 - - items: [bowstring] - quantity: 1 - - id: maple_longbow - output: maple_longbow - level: 55 - xp: 58 - consume: - - items: [maple_longbow_u] - quantity: 1 - - items: [bowstring] - quantity: 1 - - id: yew_shortbow - output: yew_shortbow - level: 60 - xp: 67 - consume: - - items: [yew_shortbow_u] - quantity: 1 - - items: [bowstring] - quantity: 1 - - id: yew_longbow - output: yew_longbow - level: 65 - xp: 75 - consume: - - items: [yew_longbow_u] - quantity: 1 - - items: [bowstring] - quantity: 1 - - id: magic_shortbow - output: magic_shortbow - level: 80 - xp: 83 - consume: - - items: [magic_shortbow_u] - quantity: 1 - - items: [bowstring] - quantity: 1 - - id: magic_longbow - output: magic_longbow - level: 85 - xp: 91 - consume: - - items: [magic_longbow_u] - quantity: 1 - - items: [bowstring] - quantity: 1 diff --git a/data/recipes/fletching/tipped_arrows.yaml b/data/recipes/fletching/tipped_arrows.yaml deleted file mode 100644 index 8e4530b..0000000 --- a/data/recipes/fletching/tipped_arrows.yaml +++ /dev/null @@ -1,63 +0,0 @@ -type: fletching -wait: 2 -products: - - id: bronze_arrow - output: bronze_arrow - level: 1 - xp: 1 - output_qty: 15 - consume: - - items: [headless_arrow] - quantity: 15 - - items: [bronze_arrowtips] - quantity: 15 - - id: iron_arrow - output: iron_arrow - level: 15 - xp: 2 - output_qty: 15 - consume: - - items: [headless_arrow] - quantity: 15 - - items: [iron_arrowtips] - quantity: 15 - - id: steel_arrow - output: steel_arrow - level: 30 - xp: 5 - output_qty: 15 - consume: - - items: [headless_arrow] - quantity: 15 - - items: [steel_arrowtips] - quantity: 15 - - id: mithril_arrow - output: mithril_arrow - level: 45 - xp: 7 - output_qty: 15 - consume: - - items: [headless_arrow] - quantity: 15 - - items: [mithril_arrowtips] - quantity: 15 - - id: adamant_arrow - output: adamant_arrow - level: 60 - xp: 10 - output_qty: 15 - consume: - - items: [headless_arrow] - quantity: 15 - - items: [adamant_arrowtips] - quantity: 15 - - id: rune_arrow - output: rune_arrow - level: 75 - xp: 12 - output_qty: 15 - consume: - - items: [headless_arrow] - quantity: 15 - - items: [rune_arrowtips] - quantity: 15 diff --git a/data/recipes/fletching/unstrung_bows.yaml b/data/recipes/fletching/unstrung_bows.yaml deleted file mode 100644 index 3195c8d..0000000 --- a/data/recipes/fletching/unstrung_bows.yaml +++ /dev/null @@ -1,88 +0,0 @@ -type: fletching -tool: knife -wait: 3 -products: - - id: shortbow_u - output: shortbow_u - level: 5 - xp: 5 - consume: - - items: [logs] - quantity: 1 - - id: longbow_u - output: longbow_u - level: 10 - xp: 10 - consume: - - items: [logs] - quantity: 1 - - id: oak_shortbow_u - output: oak_shortbow_u - level: 20 - xp: 16 - consume: - - items: [oak_logs] - quantity: 1 - - id: oak_longbow_u - output: oak_longbow_u - level: 25 - xp: 25 - consume: - - items: [oak_logs] - quantity: 1 - - id: willow_shortbow_u - output: willow_shortbow_u - level: 35 - xp: 33 - consume: - - items: [willow_logs] - quantity: 1 - - id: willow_longbow_u - output: willow_longbow_u - level: 40 - xp: 41 - consume: - - items: [willow_logs] - quantity: 1 - - id: maple_shortbow_u - output: maple_shortbow_u - level: 50 - xp: 50 - consume: - - items: [maple_logs] - quantity: 1 - - id: maple_longbow_u - output: maple_longbow_u - level: 55 - xp: 58 - consume: - - items: [maple_logs] - quantity: 1 - - id: yew_shortbow_u - output: yew_shortbow_u - level: 60 - xp: 67 - consume: - - items: [yew_logs] - quantity: 1 - - id: yew_longbow_u - output: yew_longbow_u - level: 65 - xp: 75 - consume: - - items: [yew_logs] - quantity: 1 - - id: magic_shortbow_u - output: magic_shortbow_u - level: 80 - xp: 83 - consume: - - items: [magic_logs] - quantity: 1 - - id: magic_longbow_u - output: magic_longbow_u - level: 85 - xp: 91 - consume: - - items: [magic_logs] - quantity: 1 diff --git a/data/recipes/mixing/amp_potion.yaml b/data/recipes/mixing/amp_potion.yaml deleted file mode 100644 index 40aeb84..0000000 --- a/data/recipes/mixing/amp_potion.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: amp_potion -type: pharmacy -skill: pharmacy -level: 12 -xp: 50 -wait: 4 -consume: - - items: [tarromin_potion_unf] - quantity: 1 - - items: [limpwurt_root] - quantity: 1 -output: amp_potion -message: "You mix an amp potion." diff --git a/data/recipes/mixing/bio_serum.yaml b/data/recipes/mixing/bio_serum.yaml deleted file mode 100644 index f7f728a..0000000 --- a/data/recipes/mixing/bio_serum.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: bio_serum -type: pharmacy -skill: pharmacy -level: 5 -xp: 38 -wait: 4 -consume: - - items: [marrentill_potion_unf] - quantity: 1 - - items: [antitoxin_powder] - quantity: 1 -output: bio_serum -message: "You mix a bio serum." diff --git a/data/recipes/mixing/full_restore.yaml b/data/recipes/mixing/full_restore.yaml deleted file mode 100644 index c5ed30b..0000000 --- a/data/recipes/mixing/full_restore.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: full_restore -type: pharmacy -skill: pharmacy -level: 63 -xp: 143 -wait: 4 -consume: - - items: [snapdragon_potion_unf] - quantity: 1 - - items: [arachnid_enzyme] - quantity: 1 -output: full_restore -message: "You mix a full restore." diff --git a/data/recipes/mixing/nano_restore.yaml b/data/recipes/mixing/nano_restore.yaml deleted file mode 100644 index c14f151..0000000 --- a/data/recipes/mixing/nano_restore.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: nano_restore -type: pharmacy -skill: pharmacy -level: 22 -xp: 63 -wait: 4 -consume: - - items: [harralander_potion_unf] - quantity: 1 - - items: [arachnid_enzyme] - quantity: 1 -output: nano_restore -message: "You mix a nano restore." diff --git a/data/recipes/mixing/restoration_compound.yaml b/data/recipes/mixing/restoration_compound.yaml deleted file mode 100644 index 0613d47..0000000 --- a/data/recipes/mixing/restoration_compound.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: restoration_compound -type: pharmacy -skill: pharmacy -level: 81 -xp: 180 -wait: 4 -consume: - - items: [toadflax_potion_unf] - quantity: 1 - - items: [crushed_nest] - quantity: 1 -output: restoration_compound -message: "You mix a restoration compound." diff --git a/data/recipes/mixing/science_serum.yaml b/data/recipes/mixing/science_serum.yaml deleted file mode 100644 index 311f3c4..0000000 --- a/data/recipes/mixing/science_serum.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: science_serum -type: pharmacy -skill: pharmacy -level: 76 -xp: 173 -wait: 4 -consume: - - items: [lantadyme_potion_unf] - quantity: 1 - - items: [potato_cactus] - quantity: 1 -output: science_serum -message: "You mix a science serum." diff --git a/data/recipes/mixing/shield_potion.yaml b/data/recipes/mixing/shield_potion.yaml deleted file mode 100644 index f334b5a..0000000 --- a/data/recipes/mixing/shield_potion.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: shield_potion -type: pharmacy -skill: pharmacy -level: 30 -xp: 75 -wait: 4 -consume: - - items: [ranarr_potion_unf] - quantity: 1 - - items: [white_berries] - quantity: 1 -output: shield_potion -message: "You mix a shield potion." diff --git a/data/recipes/mixing/stim_cell.yaml b/data/recipes/mixing/stim_cell.yaml deleted file mode 100644 index ddf37f8..0000000 --- a/data/recipes/mixing/stim_cell.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: stim_cell -type: pharmacy -skill: pharmacy -level: 26 -xp: 68 -wait: 4 -consume: - - items: [harralander_potion_unf] - quantity: 1 - - items: [chocolate_dust] - quantity: 1 -output: stim_cell -message: "You mix a stim cell." diff --git a/data/recipes/mixing/stim_potion.yaml b/data/recipes/mixing/stim_potion.yaml deleted file mode 100644 index ad6abd3..0000000 --- a/data/recipes/mixing/stim_potion.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: stim_potion -type: pharmacy -skill: pharmacy -level: 3 -xp: 25 -wait: 4 -consume: - - items: [guam_potion_unf] - quantity: 1 - - items: [eye_of_newt] - quantity: 1 -output: stim_potion -message: "You mix a stim potion." diff --git a/data/recipes/mixing/super_amp.yaml b/data/recipes/mixing/super_amp.yaml deleted file mode 100644 index dc4ef81..0000000 --- a/data/recipes/mixing/super_amp.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: super_amp -type: pharmacy -skill: pharmacy -level: 55 -xp: 125 -wait: 4 -consume: - - items: [kwuarm_potion_unf] - quantity: 1 - - items: [limpwurt_root] - quantity: 1 -output: super_amp -message: "You mix a super amp." diff --git a/data/recipes/mixing/super_bio_serum.yaml b/data/recipes/mixing/super_bio_serum.yaml deleted file mode 100644 index 3c763a6..0000000 --- a/data/recipes/mixing/super_bio_serum.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: super_bio_serum -type: pharmacy -skill: pharmacy -level: 48 -xp: 106 -wait: 4 -consume: - - items: [irit_potion_unf] - quantity: 1 - - items: [antitoxin_powder] - quantity: 1 -output: super_bio_serum -message: "You mix a super bio serum." diff --git a/data/recipes/mixing/super_shield.yaml b/data/recipes/mixing/super_shield.yaml deleted file mode 100644 index 706d402..0000000 --- a/data/recipes/mixing/super_shield.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: super_shield -type: pharmacy -skill: pharmacy -level: 66 -xp: 150 -wait: 4 -consume: - - items: [cadantine_potion_unf] - quantity: 1 - - items: [white_berries] - quantity: 1 -output: super_shield -message: "You mix a super shield." diff --git a/data/recipes/mixing/super_stim.yaml b/data/recipes/mixing/super_stim.yaml deleted file mode 100644 index 8ef6819..0000000 --- a/data/recipes/mixing/super_stim.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: super_stim -type: pharmacy -skill: pharmacy -level: 45 -xp: 100 -wait: 4 -consume: - - items: [irit_potion_unf] - quantity: 1 - - items: [eye_of_newt] - quantity: 1 -output: super_stim -message: "You mix a super stim." diff --git a/data/recipes/mixing/super_stim_cell.yaml b/data/recipes/mixing/super_stim_cell.yaml deleted file mode 100644 index ec4a515..0000000 --- a/data/recipes/mixing/super_stim_cell.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: super_stim_cell -type: pharmacy -skill: pharmacy -level: 52 -xp: 118 -wait: 4 -consume: - - items: [avantoe_potion_unf] - quantity: 1 - - items: [blight_spore] - quantity: 1 -output: super_stim_cell -message: "You mix a super stim cell." diff --git a/data/recipes/mixing/targeting_serum.yaml b/data/recipes/mixing/targeting_serum.yaml deleted file mode 100644 index e91e20e..0000000 --- a/data/recipes/mixing/targeting_serum.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: targeting_serum -type: pharmacy -skill: pharmacy -level: 72 -xp: 163 -wait: 4 -consume: - - items: [dwarf_weed_potion_unf] - quantity: 1 - - items: [catalyst_wine] - quantity: 1 -output: targeting_serum -message: "You mix a targeting serum." diff --git a/data/recipes/mixing/tech_serum.yaml b/data/recipes/mixing/tech_serum.yaml deleted file mode 100644 index 3a21619..0000000 --- a/data/recipes/mixing/tech_serum.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: tech_serum -type: pharmacy -skill: pharmacy -level: 38 -xp: 88 -wait: 4 -consume: - - items: [ranarr_potion_unf] - quantity: 1 - - items: [snape_grass] - quantity: 1 -output: tech_serum -message: "You mix a tech serum." diff --git a/data/recipes/smelting/adamantite.yaml b/data/recipes/smelting/adamantite.yaml deleted file mode 100644 index af9283d..0000000 --- a/data/recipes/smelting/adamantite.yaml +++ /dev/null @@ -1,15 +0,0 @@ -id: adamantite -type: smelting -skill: smithing -level: 65 -xp: 37 -wait: 4 -station: [furnace] -consume: - - items: [adamantite_ore] - quantity: 1 - - items: [coal] - quantity: 6 -output: adamantite_bar -message: "You remove a white hot adamantite bar!" -fail_message: "You fail to smelt a usable bar." diff --git a/data/recipes/smelting/gold.yaml b/data/recipes/smelting/gold.yaml deleted file mode 100644 index 9ebb96b..0000000 --- a/data/recipes/smelting/gold.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: gold -type: smelting -skill: smithing -level: 45 -xp: 22 -wait: 4 -station: [furnace] -consume: - - items: [gold_ore] - quantity: 1 -output: gold_bar -message: "You remove a white hot gold bar!" -fail_message: "You fail to smelt a usable bar." diff --git a/data/recipes/smelting/runite.yaml b/data/recipes/smelting/runite.yaml deleted file mode 100644 index 36d44a4..0000000 --- a/data/recipes/smelting/runite.yaml +++ /dev/null @@ -1,15 +0,0 @@ -id: runite -type: smelting -skill: smithing -level: 80 -xp: 50 -wait: 4 -station: [furnace] -consume: - - items: [runite_ore] - quantity: 1 - - items: [coal] - quantity: 8 -output: runite_bar -message: "You remove a white hot runite bar!" -fail_message: "You fail to smelt a usable bar." diff --git a/data/recipes/smelting/silver.yaml b/data/recipes/smelting/silver.yaml deleted file mode 100644 index 05a76ef..0000000 --- a/data/recipes/smelting/silver.yaml +++ /dev/null @@ -1,13 +0,0 @@ -id: silver -type: smelting -skill: smithing -level: 25 -xp: 14 -wait: 4 -station: [furnace] -consume: - - items: [silver_ore] - quantity: 1 -output: silver_bar -message: "You remove a white hot silver bar!" -fail_message: "You fail to smelt a usable bar." diff --git a/data/recipes/smelting/smelt_bronze.yaml b/data/recipes/smelting/smelt_bronze.yaml deleted file mode 100644 index af28ca0..0000000 --- a/data/recipes/smelting/smelt_bronze.yaml +++ /dev/null @@ -1,15 +0,0 @@ -id: bronze -type: smelting -skill: smithing -level: 1 -xp: 6 -wait: 4 -station: [furnace] -consume: - - items: [copper_ore] - quantity: 1 - - items: [tin_ore] - quantity: 1 -output: bronze_bar -message: "You remove a white hot bronze bar!" -fail_message: "You fail to smelt a usable bar." diff --git a/data/recipes/smelting/smelt_iron.yaml b/data/recipes/smelting/smelt_iron.yaml deleted file mode 100644 index fa210d6..0000000 --- a/data/recipes/smelting/smelt_iron.yaml +++ /dev/null @@ -1,17 +0,0 @@ -id: iron -type: smelting -skill: smithing -level: 20 -xp: 12 -wait: 4 -station: [furnace] -consume: - - items: [iron_ore] - quantity: 1 -output: iron_bar -message: "You remove a white hot iron bar!" -fail_message: "The iron is too impure to make a workable bar." -success: - base: 0.5 - per_level: 0 - cap: 0.5 diff --git a/data/recipes/smelting/smelt_mithril.yaml b/data/recipes/smelting/smelt_mithril.yaml deleted file mode 100644 index 8e11e61..0000000 --- a/data/recipes/smelting/smelt_mithril.yaml +++ /dev/null @@ -1,15 +0,0 @@ -id: mithril -type: smelting -skill: smithing -level: 50 -xp: 30 -wait: 4 -station: [furnace] -consume: - - items: [mithril_ore] - quantity: 1 - - items: [coal] - quantity: 4 -output: mithril_bar -message: "You remove a white hot mithril bar!" -fail_message: "You fail to smelt a usable bar." diff --git a/data/recipes/smelting/smelt_steel.yaml b/data/recipes/smelting/smelt_steel.yaml deleted file mode 100644 index 86ee366..0000000 --- a/data/recipes/smelting/smelt_steel.yaml +++ /dev/null @@ -1,15 +0,0 @@ -id: steel -type: smelting -skill: smithing -level: 40 -xp: 17 -wait: 4 -station: [furnace] -consume: - - items: [iron_ore] - quantity: 1 - - items: [coal] - quantity: 2 -output: steel_bar -message: "You remove a white hot steel bar!" -fail_message: "You fail to smelt a usable bar." diff --git a/data/recipes/smithing/adamant.yaml b/data/recipes/smithing/adamant.yaml deleted file mode 100644 index bd9debe..0000000 --- a/data/recipes/smithing/adamant.yaml +++ /dev/null @@ -1,48 +0,0 @@ -type: smithing -station: [anvil] -wait: 4 -consume: - - items: [adamantite_bar] - quantity: 1 -products: - - id: adamant_dagger - output: adamant_dagger - level: 70 - xp: 62 - - id: adamant_med_helm - output: adamant_med_helm - level: 73 - xp: 62 - - id: adamant_sword - output: adamant_sword - level: 74 - xp: 62 - - id: adamant_nails - output: adamant_nails - level: 74 - xp: 62 - output_qty: 15 - - id: adamant_arrowtips - output: adamant_arrowtips - level: 75 - xp: 62 - output_qty: 15 - - id: adamant_bolts_unf - output: adamant_bolts_unf - level: 76 - xp: 62 - output_qty: 10 - - id: adamant_full_helm - output: adamant_full_helm - level: 77 - xp: 125 - consume: - - items: [adamantite_bar] - quantity: 2 - - id: adamant_platebody - output: adamant_platebody - level: 88 - xp: 312 - consume: - - items: [adamantite_bar] - quantity: 5 diff --git a/data/recipes/smithing/bronze.yaml b/data/recipes/smithing/bronze.yaml deleted file mode 100644 index da1b55f..0000000 --- a/data/recipes/smithing/bronze.yaml +++ /dev/null @@ -1,48 +0,0 @@ -type: smithing -station: [anvil] -wait: 4 -consume: - - items: [bronze_bar] - quantity: 1 -products: - - id: bronze_dagger - output: bronze_dagger - level: 1 - xp: 12 - - id: bronze_med_helm - output: bronze_med_helm - level: 3 - xp: 12 - - id: bronze_sword - output: bronze_sword - level: 4 - xp: 12 - - id: bronze_nails - output: bronze_nails - level: 4 - xp: 12 - output_qty: 15 - - id: bronze_arrowtips - output: bronze_arrowtips - level: 5 - xp: 12 - output_qty: 15 - - id: bronze_bolts_unf - output: bronze_bolts_unf - level: 6 - xp: 12 - output_qty: 10 - - id: bronze_full_helm - output: bronze_full_helm - level: 7 - xp: 25 - consume: - - items: [bronze_bar] - quantity: 2 - - id: bronze_platebody - output: bronze_platebody - level: 18 - xp: 62 - consume: - - items: [bronze_bar] - quantity: 5 diff --git a/data/recipes/smithing/iron.yaml b/data/recipes/smithing/iron.yaml deleted file mode 100644 index e39facd..0000000 --- a/data/recipes/smithing/iron.yaml +++ /dev/null @@ -1,48 +0,0 @@ -type: smithing -station: [anvil] -wait: 4 -consume: - - items: [iron_bar] - quantity: 1 -products: - - id: iron_dagger - output: iron_dagger - level: 20 - xp: 25 - - id: iron_med_helm - output: iron_med_helm - level: 22 - xp: 25 - - id: iron_sword - output: iron_sword - level: 24 - xp: 25 - - id: iron_nails - output: iron_nails - level: 24 - xp: 25 - output_qty: 15 - - id: iron_arrowtips - output: iron_arrowtips - level: 25 - xp: 25 - output_qty: 15 - - id: iron_bolts_unf - output: iron_bolts_unf - level: 26 - xp: 25 - output_qty: 10 - - id: iron_full_helm - output: iron_full_helm - level: 27 - xp: 50 - consume: - - items: [iron_bar] - quantity: 2 - - id: iron_platebody - output: iron_platebody - level: 33 - xp: 125 - consume: - - items: [iron_bar] - quantity: 5 diff --git a/data/recipes/smithing/mithril.yaml b/data/recipes/smithing/mithril.yaml deleted file mode 100644 index dfa4a6d..0000000 --- a/data/recipes/smithing/mithril.yaml +++ /dev/null @@ -1,48 +0,0 @@ -type: smithing -station: [anvil] -wait: 4 -consume: - - items: [mithril_bar] - quantity: 1 -products: - - id: mithril_dagger - output: mithril_dagger - level: 50 - xp: 50 - - id: mithril_med_helm - output: mithril_med_helm - level: 53 - xp: 50 - - id: mithril_sword - output: mithril_sword - level: 54 - xp: 50 - - id: mithril_nails - output: mithril_nails - level: 54 - xp: 50 - output_qty: 15 - - id: mithril_arrowtips - output: mithril_arrowtips - level: 55 - xp: 50 - output_qty: 15 - - id: mithril_bolts_unf - output: mithril_bolts_unf - level: 56 - xp: 50 - output_qty: 10 - - id: mithril_full_helm - output: mithril_full_helm - level: 57 - xp: 100 - consume: - - items: [mithril_bar] - quantity: 2 - - id: mithril_platebody - output: mithril_platebody - level: 68 - xp: 250 - consume: - - items: [mithril_bar] - quantity: 5 diff --git a/data/recipes/smithing/rune.yaml b/data/recipes/smithing/rune.yaml deleted file mode 100644 index fdffafc..0000000 --- a/data/recipes/smithing/rune.yaml +++ /dev/null @@ -1,48 +0,0 @@ -type: smithing -station: [anvil] -wait: 4 -consume: - - items: [runite_bar] - quantity: 1 -products: - - id: rune_dagger - output: rune_dagger - level: 85 - xp: 75 - - id: rune_med_helm - output: rune_med_helm - level: 88 - xp: 75 - - id: rune_sword - output: rune_sword - level: 89 - xp: 75 - - id: rune_nails - output: rune_nails - level: 89 - xp: 75 - output_qty: 15 - - id: rune_arrowtips - output: rune_arrowtips - level: 90 - xp: 75 - output_qty: 15 - - id: rune_bolts_unf - output: rune_bolts_unf - level: 91 - xp: 75 - output_qty: 10 - - id: rune_full_helm - output: rune_full_helm - level: 92 - xp: 150 - consume: - - items: [runite_bar] - quantity: 2 - - id: rune_platebody - output: rune_platebody - level: 99 - xp: 375 - consume: - - items: [runite_bar] - quantity: 5 diff --git a/data/recipes/smithing/steel.yaml b/data/recipes/smithing/steel.yaml deleted file mode 100644 index 204b427..0000000 --- a/data/recipes/smithing/steel.yaml +++ /dev/null @@ -1,48 +0,0 @@ -type: smithing -station: [anvil] -wait: 4 -consume: - - items: [steel_bar] - quantity: 1 -products: - - id: steel_dagger - output: steel_dagger - level: 30 - xp: 37 - - id: steel_med_helm - output: steel_med_helm - level: 33 - xp: 37 - - id: steel_sword - output: steel_sword - level: 34 - xp: 37 - - id: steel_nails - output: steel_nails - level: 34 - xp: 37 - output_qty: 15 - - id: steel_arrowtips - output: steel_arrowtips - level: 35 - xp: 37 - output_qty: 15 - - id: steel_bolts_unf - output: steel_bolts_unf - level: 36 - xp: 37 - output_qty: 10 - - id: steel_full_helm - output: steel_full_helm - level: 37 - xp: 75 - consume: - - items: [steel_bar] - quantity: 2 - - id: steel_platebody - output: steel_platebody - level: 48 - xp: 187 - consume: - - items: [steel_bar] - quantity: 5 diff --git a/internal/action/recipe.go b/internal/action/recipe.go deleted file mode 100644 index 8779d53..0000000 --- a/internal/action/recipe.go +++ /dev/null @@ -1,319 +0,0 @@ -package action - -import ( - "fmt" - "os" - "path/filepath" - - "gopkg.in/yaml.v3" -) - -type ConsumeEntry struct { - Items []string `yaml:"items"` - Quantity int `yaml:"quantity"` - Byproducts []string `yaml:"byproducts"` -} - -type RecipeDef struct { - ID string `yaml:"id"` - Type string `yaml:"type"` - Skill string `yaml:"skill"` - Level int `yaml:"level"` - XP int `yaml:"xp"` - Station []string `yaml:"station"` - Tool string `yaml:"tool"` - Consume []ConsumeEntry `yaml:"consume"` - Output string `yaml:"output"` - OutputQty int `yaml:"output_qty"` - Fail string `yaml:"fail"` - Message string `yaml:"message"` - FailMessage string `yaml:"fail_message"` - Wait float64 `yaml:"wait"` - Success *SuccessFormula `yaml:"success"` -} - -type consolidatedRecipeDef struct { - Type string `yaml:"type"` - Skill string `yaml:"skill"` - Station []string `yaml:"station"` - Tool string `yaml:"tool"` - Wait float64 `yaml:"wait"` - Consume []ConsumeEntry `yaml:"consume"` - Products []recipeProduct `yaml:"products"` -} - -type recipeProduct struct { - ID string `yaml:"id"` - Output string `yaml:"output"` - OutputQty int `yaml:"output_qty"` - Level int `yaml:"level"` - XP int `yaml:"xp"` - Consume []ConsumeEntry `yaml:"consume"` - Message string `yaml:"message"` - FailMessage string `yaml:"fail_message"` - Fail string `yaml:"fail"` - Success *SuccessFormula `yaml:"success"` -} - -type RecipeStore struct { - dataDir string - cache map[string][]RecipeDef - byID map[string]*RecipeDef -} - -func NewRecipeStore(dataDir string) *RecipeStore { - return &RecipeStore{ - dataDir: dataDir, - cache: make(map[string][]RecipeDef), - byID: make(map[string]*RecipeDef), - } -} - -func (s *RecipeStore) GetByID(recipeID string) *RecipeDef { - if r, ok := s.byID[recipeID]; ok { - return r - } - s.ensureLoaded() - if r, ok := s.byID[recipeID]; ok { - return r - } - return nil -} - -func (s *RecipeStore) ensureLoaded() { - if _, ok := s.cache["_all"]; ok { - return - } - all, err := s.loadAllRaw() - if err != nil { - return - } - s.cache["_all"] = all - for i := range all { - if all[i].ID != "" { - s.byID[all[i].ID] = &all[i] - } - } -} - -func (s *RecipeStore) LoadAll() ([]RecipeDef, error) { - return s.LoadByType("") -} - -func (s *RecipeStore) LoadByType(recipeType string) ([]RecipeDef, error) { - if recipeType == "" { - recipeType = "_all" - } - if cached, ok := s.cache[recipeType]; ok { - result := make([]RecipeDef, len(cached)) - copy(result, cached) - return result, nil - } - - s.ensureLoaded() - all := s.cache["_all"] - - if recipeType == "_all" { - result := make([]RecipeDef, len(all)) - copy(result, all) - return result, nil - } - - var filtered []RecipeDef - for _, r := range all { - if r.Type == recipeType { - filtered = append(filtered, r) - } - } - s.cache[recipeType] = filtered - result := make([]RecipeDef, len(filtered)) - copy(result, filtered) - return result, nil -} - -func (s *RecipeStore) loadAllRaw() ([]RecipeDef, error) { - dir := filepath.Join(s.dataDir, "recipes") - var recipes []RecipeDef - WalkYAMLDir(dir, func(path, id string, data []byte) error { - var r RecipeDef - if err := yaml.Unmarshal(data, &r); err == nil && r.Type != "" { - recipes = append(recipes, r) - return nil - } - - var cr consolidatedRecipeDef - if err := yaml.Unmarshal(data, &cr); err != nil { - fmt.Fprintf(os.Stderr, "recipe parse error %s: %v\n", path, err) - return nil - } - if cr.Type == "" || len(cr.Products) == 0 { - return nil - } - - for _, p := range cr.Products { - recipes = append(recipes, s.expandProduct(cr, p)) - } - return nil - }) - return recipes, nil -} - -func (s *RecipeStore) expandProduct(cr consolidatedRecipeDef, p recipeProduct) RecipeDef { - r := RecipeDef{ - ID: p.ID, - Output: p.Output, - OutputQty: p.OutputQty, - Type: cr.Type, - Skill: cr.Skill, - Level: p.Level, - XP: p.XP, - Station: cr.Station, - Tool: cr.Tool, - Wait: cr.Wait, - Consume: p.Consume, - Message: p.Message, - FailMessage: p.FailMessage, - Fail: p.Fail, - Success: p.Success, - } - if len(r.Consume) == 0 { - r.Consume = cr.Consume - } - return r -} - -func (r *RecipeDef) MatchesEntry(itemID string) bool { - for _, e := range r.Consume { - for _, id := range e.Items { - if id == itemID { - return true - } - } - } - return false -} - -func (s *RecipeStore) FindByInput(recipeType string, itemID string) *RecipeDef { - all, err := s.LoadByType(recipeType) - if err != nil { - return nil - } - for i := range all { - for _, e := range all[i].Consume { - for _, id := range e.Items { - if id == itemID { - return &all[i] - } - } - } - } - return nil -} - - -func (s *RecipeStore) FindByStation(itemID string, stationIDs []string, recipeType string) ([]RecipeDef, error) { - all, err := s.LoadByType(recipeType) - if err != nil { - return nil, err - } - var matches []RecipeDef - for _, r := range all { - if recipeType != "" && r.Type != recipeType { - continue - } - if !r.MatchesEntry(itemID) { - continue - } - if len(r.Station) == 0 { - continue - } - for _, station := range stationIDs { - for _, rs := range r.Station { - if rs == station { - matches = append(matches, r) - goto next - } - } - } - next: - } - return matches, nil -} - -func (r *RecipeDef) DisplayName() string { - return r.Output -} - -func (r *RecipeDef) EffectiveSkill() string { - if r.Skill != "" { - return r.Skill - } - return r.Type -} - - - -func (r *RecipeDef) FirstItemName(load func(string) (string, bool)) string { - for _, e := range r.Consume { - for _, id := range e.Items { - if name, ok := load(id); ok { - return name - } - return id - } - } - return "" -} - -func (r *RecipeDef) ConsumeAll(hasItem func(string) bool, removeItem func(string, int) bool) bool { - for _, e := range r.Consume { - found := false - for _, id := range e.Items { - if hasItem(id) { - removeItem(id, e.Quantity) - found = true - break - } - } - if !found { - return false - } -} -return true -} - -func (r *RecipeDef) HasAllItemsQty(countItem func(string) int) bool { - for _, e := range r.Consume { - found := false - for _, id := range e.Items { - qty := e.Quantity - if qty <= 0 { - qty = 1 - } - if countItem(id) >= qty { - found = true - break - } - } - if !found { - return false - } - } - return true -} - -func (r *RecipeDef) HasAllItems(hasItem func(string) bool) bool { - for _, e := range r.Consume { - found := false - for _, id := range e.Items { - if hasItem(id) { - found = true - break - } - } - if !found { - return false - } - } - return true -} diff --git a/internal/game/action_clean.go b/internal/game/action_clean.go index 7330883..b85a3e0 100644 --- a/internal/game/action_clean.go +++ b/internal/game/action_clean.go @@ -19,37 +19,31 @@ func (g *Game) advanceClean(sess *net.Session, p *player.Player) { return } - allRecipes, err := g.RecipeStore.LoadAll() - if err != nil { - g.cancelBgAction(p) - return - } + items := g.CraftIndex.ByType("clean") - var recipe *cleanMatch - for _, r := range allRecipes { - if r.Type != "clean" { - continue - } + var match *cleanMatch + for _, item := range items { + c := item.FirstCraft() if filter != "" { - if len(r.Consume) == 0 || len(r.Consume[0].Items) == 0 { + if len(c.Consume) == 0 || len(c.Consume[0].Items) == 0 { continue } - if !strings.Contains(r.Consume[0].Items[0], filter) && - !strings.Contains(r.Output, filter) { + if !strings.Contains(c.Consume[0].Items[0], filter) && + !strings.Contains(item.ID, filter) { continue } } - if p.Level(player.Pharmacy) < r.Level { + if p.Level(player.Pharmacy) < c.Level { continue } - if !r.HasAllItems(p.HasItem) { + if !craftHasAllItems(c, p.HasItem) { continue } - recipe = &cleanMatch{r.Consume[0].Items[0], r.Output, r.XP, r.Message} + match = &cleanMatch{c.Consume[0].Items[0], item.ID, c.XP, c.Message} break } - if recipe == nil { + if match == nil { sess.WriteLine("\nYou've finished cleaning herbs.") g.cancelBgAction(p) return @@ -57,47 +51,45 @@ func (g *Game) advanceClean(sess *net.Session, p *player.Player) { for i := 0; i < 28; i++ { slot := p.InvSlot(i) - if slot != nil && slot.ItemID == recipe.consumeID { - slot.ItemID = recipe.outputID + if slot != nil && slot.ItemID == match.consumeID { + slot.ItemID = match.outputID break } } - if recipe.xp > 0 { - g.awardSkillXP(sess, p, player.Pharmacy, recipe.xp) + if match.xp > 0 { + g.awardSkillXP(sess, p, player.Pharmacy, match.xp) } g.AccountStore.SaveCharacter(p) - msg := recipe.message + msg := match.message if msg == "" { - outDef, _ := g.ItemStore.Load(recipe.outputID) - outputName := recipe.outputID + outDef, _ := g.ItemStore.Load(match.outputID) + outputName := match.outputID if outDef != nil { outputName = outDef.Name } msg = fmt.Sprintf("You clean a %s.", outputName) } - if p.OptionBool("xp_drops") && recipe.xp > 0 { + if p.OptionBool("xp_drops") && match.xp > 0 { abbr := player.SkillAbbr[player.Pharmacy] - msg += g.colorize(sess, "xp", fmt.Sprintf(" (+%dxp %s)", recipe.xp, abbr)) + msg += g.colorize(sess, "xp", fmt.Sprintf(" (+%dxp %s)", match.xp, abbr)) } sess.WriteLine(msg) hasMore := false - for _, r := range allRecipes { - if r.Type != "clean" { - continue - } + for _, item := range items { + c := item.FirstCraft() if filter != "" { - if len(r.Consume) == 0 || len(r.Consume[0].Items) == 0 { + if len(c.Consume) == 0 || len(c.Consume[0].Items) == 0 { continue } - if !strings.Contains(r.Consume[0].Items[0], filter) && - !strings.Contains(r.Output, filter) { + if !strings.Contains(c.Consume[0].Items[0], filter) && + !strings.Contains(item.ID, filter) { continue } } - if p.Level(player.Pharmacy) >= r.Level && r.HasAllItems(p.HasItem) { + if p.Level(player.Pharmacy) >= c.Level && craftHasAllItems(c, p.HasItem) { hasMore = true break } diff --git a/internal/game/action_farm.go b/internal/game/action_farm.go index 21604aa..679af83 100644 --- a/internal/game/action_farm.go +++ b/internal/game/action_farm.go @@ -6,8 +6,8 @@ import ( "sort" "strings" - "thehouseoficarus/internal/action" "thehouseoficarus/internal/net" + "thehouseoficarus/internal/object" "thehouseoficarus/internal/player" "thehouseoficarus/internal/world" ) @@ -484,7 +484,7 @@ func (g *Game) farmMatchPrefix(p *player.Player, input string) (prefix string, d lower := strings.ToLower(input) for _, f := range farms { - if strings.Contains(lower, strings.ToLower(f.name)) || action.WordPrefixMatch(lower, f.name) { + if strings.Contains(lower, strings.ToLower(f.name)) || object.WordPrefixMatch(lower, f.name) { return f.prefix, f.defID, f.index } } diff --git a/internal/game/action_fletch.go b/internal/game/action_fletch.go index 3d8c30f..52de86b 100644 --- a/internal/game/action_fletch.go +++ b/internal/game/action_fletch.go @@ -6,43 +6,45 @@ import ( "thehouseoficarus/internal/action" "thehouseoficarus/internal/engine" "thehouseoficarus/internal/net" + "thehouseoficarus/internal/object" "thehouseoficarus/internal/player" ) -func (g *Game) startFletchAction(sess *net.Session, p *player.Player, recipe *action.RecipeDef, count int) { +func (g *Game) startFletchAction(sess *net.Session, p *player.Player, item *object.ItemDef, count int) { p.EnsureFlags() - p.Flags["last_fletch"] = recipe.ID + p.Flags["last_fletch"] = item.ID g.AccountStore.SaveCharacter(p) - if recipe.Wait <= 0 { - g.doInstantFletch(sess, p, recipe, count) + if item.FirstCraft().Wait <= 0 { + g.doInstantFletch(sess, p, item, count) return } - g.startTimedFletch(sess, p, recipe, count) + g.startTimedFletch(sess, p, item, count) } -func (g *Game) doInstantFletch(sess *net.Session, p *player.Player, recipe *action.RecipeDef, count int) { - outDef, _ := g.ItemStore.Load(recipe.Output) - outputQty := recipe.OutputQty +func (g *Game) doInstantFletch(sess *net.Session, p *player.Player, item *object.ItemDef, count int) { + c := item.FirstCraft() + outputQty := c.OutputQty if outputQty <= 0 { outputQty = 1 } batches := 0 totalOutput := 0 - skill := player.SkillName(recipe.EffectiveSkill()) + skill := player.SkillName(c.EffectiveSkill()) + tmpItem := &object.ItemDef{Craft: object.CraftList{*c}} for { - if !g.canDoFletchRecipe(p, recipe) { + if !g.canDoFletchItem(p, tmpItem) { break } placed := false - if outDef != nil && outDef.Stackable { + if item.Stackable { for i := 0; i < 28; i++ { slot := p.InvSlot(i) - if slot != nil && slot.ItemID == recipe.Output { - recipe.ConsumeAll(p.HasItem, p.RemoveItem) + if slot != nil && slot.ItemID == item.ID { + craftConsumeAll(c, p.HasItem, p.RemoveItem) slot.Quantity += outputQty placed = true break @@ -50,16 +52,16 @@ func (g *Game) doInstantFletch(sess *net.Session, p *player.Player, recipe *acti } } if !placed { - recipe.ConsumeAll(p.HasItem, p.RemoveItem) + craftConsumeAll(c, p.HasItem, p.RemoveItem) freeSlot := p.FirstFreeSlot() if freeSlot == -1 { break } - p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: recipe.Output, Quantity: outputQty}) + p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: item.ID, Quantity: outputQty}) } - if recipe.XP > 0 { - g.awardSkillXP(sess, p, skill, recipe.XP) + if c.XP > 0 { + g.awardSkillXP(sess, p, skill, c.XP) } batches++ @@ -80,57 +82,47 @@ func (g *Game) doInstantFletch(sess *net.Session, p *player.Player, recipe *acti g.AccountStore.SaveCharacter(p) - outputName := recipe.Output - if outDef != nil { - outputName = outDef.Name - } - - msg := fmt.Sprintf("You fletch %d %s.", totalOutput, outputName) - if p.OptionBool("xp_drops") && recipe.XP > 0 { - totalXP := recipe.XP * batches + msg := fmt.Sprintf("You fletch %d %s.", totalOutput, item.Name) + if p.OptionBool("xp_drops") && c.XP > 0 { + totalXP := c.XP * batches abbr := player.SkillAbbr[skill] msg += g.colorize(sess, "xp", fmt.Sprintf(" (+%dxp %s)", totalXP, abbr)) } sess.WriteLine(msg) } -func (g *Game) startTimedFletch(sess *net.Session, p *player.Player, recipe *action.RecipeDef, count int) { - outDef, _ := g.ItemStore.Load(recipe.Output) - outputName := recipe.Output - if outDef != nil { - outputName = outDef.Name - } - +func (g *Game) startTimedFletch(sess *net.Session, p *player.Player, item *object.ItemDef, count int) { p.BackgroundAction = &action.Action{ Type: "fletch", - TargetID: recipe.ID, - TargetName: outputName, + TargetID: item.ID, + TargetName: item.Name, Data: map[string]any{ - "recipe_id": recipe.ID, + "item_id": item.ID, "phase": 0, - "wait": recipe.Wait, + "wait": item.FirstCraft().Wait, "remaining": count, }, WaitLeft: engine.ToTicks(1), } - p.BackgroundActionState = &ActionState{Type: ActionFletching, TargetName: outputName} + p.BackgroundActionState = &ActionState{Type: ActionFletching, TargetName: item.Name} g.broadcastAction(sess, "\n%s starts fletching.", p.Name) - sess.WriteLine(fmt.Sprintf("\nYou begin fletching %s.", outputName)) + sess.WriteLine(fmt.Sprintf("\nYou begin fletching %s.", item.Name)) } func (g *Game) advanceFletch(sess *net.Session, p *player.Player) { - recipeID, _ := p.BackgroundAction.Data["recipe_id"].(string) + itemID, _ := p.BackgroundAction.Data["item_id"].(string) phase, _ := p.BackgroundAction.Data["phase"].(int) wait, _ := p.BackgroundAction.Data["wait"].(float64) remaining, _ := p.BackgroundAction.Data["remaining"].(int) - recipe := g.loadRecipe(recipeID) - if recipe == nil { + item := g.loadCraftItem(itemID) + if item == nil { g.cancelBgAction(p) return } + c := item.FirstCraft() if phase == 0 { p.BackgroundAction.Data["phase"] = 1 @@ -138,26 +130,26 @@ func (g *Game) advanceFletch(sess *net.Session, p *player.Player) { return } - if !g.canDoFletchRecipe(p, recipe) { + tmpItem := &object.ItemDef{Craft: object.CraftList{*c}} + if !g.canDoFletchItem(p, tmpItem) { sess.WriteLine("\nYou've run out of fletching materials.") g.cancelBgAction(p) return } - outDef, _ := g.ItemStore.Load(recipe.Output) - outputQty := recipe.OutputQty + outputQty := c.OutputQty if outputQty <= 0 { outputQty = 1 } - skill := player.SkillName(recipe.EffectiveSkill()) + skill := player.SkillName(c.EffectiveSkill()) placed := false - if outDef != nil && outDef.Stackable { + if item.Stackable { for i := 0; i < 28; i++ { slot := p.InvSlot(i) - if slot != nil && slot.ItemID == recipe.Output { - recipe.ConsumeAll(p.HasItem, p.RemoveItem) + if slot != nil && slot.ItemID == item.ID { + craftConsumeAll(c, p.HasItem, p.RemoveItem) slot.Quantity += outputQty placed = true break @@ -165,32 +157,28 @@ func (g *Game) advanceFletch(sess *net.Session, p *player.Player) { } } if !placed { - recipe.ConsumeAll(p.HasItem, p.RemoveItem) + craftConsumeAll(c, p.HasItem, p.RemoveItem) freeSlot := p.FirstFreeSlot() if freeSlot == -1 { sess.WriteLine("\nYour inventory is too full!") g.cancelBgAction(p) return } - p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: recipe.Output, Quantity: outputQty}) + p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: item.ID, Quantity: outputQty}) } - if recipe.XP > 0 { - g.awardSkillXP(sess, p, skill, recipe.XP) + if c.XP > 0 { + g.awardSkillXP(sess, p, skill, c.XP) } g.AccountStore.SaveCharacter(p) - outputName := recipe.Output - if outDef != nil { - outputName = outDef.Name - } - msg := recipe.Message + msg := c.Message if msg == "" { - msg = fmt.Sprintf("You fletch %s.", outputName) + msg = fmt.Sprintf("You fletch %s.", item.Name) } - if p.OptionBool("xp_drops") && recipe.XP > 0 { + if p.OptionBool("xp_drops") && c.XP > 0 { abbr := player.SkillAbbr[skill] - msg += g.colorize(sess, "xp", fmt.Sprintf(" (+%dxp %s)", recipe.XP, abbr)) + msg += g.colorize(sess, "xp", fmt.Sprintf(" (+%dxp %s)", c.XP, abbr)) } sess.WriteLine(msg) @@ -204,7 +192,7 @@ func (g *Game) advanceFletch(sess *net.Session, p *player.Player) { } } - if !g.canContinueProduction(p, recipe) { + if !g.canContinueProduction(p, item) { sess.WriteLine("\nYou've run out of fletching materials.") g.cancelBgAction(p) return diff --git a/internal/game/action_steal.go b/internal/game/action_steal.go index a95be25..259c914 100644 --- a/internal/game/action_steal.go +++ b/internal/game/action_steal.go @@ -169,7 +169,7 @@ func (g *Game) resolveStealTarget(sess *net.Session, p *player.Player, input str var matchingObjs []*object.ObjectDef for _, o := range stealObjs { - if action.WordPrefixMatch(searchName, o.Name) { + if object.WordPrefixMatch(searchName, o.Name) { matchingObjs = append(matchingObjs, o) } } diff --git a/internal/game/cmd_bank.go b/internal/game/cmd_bank.go index d91e115..5f9067d 100644 --- a/internal/game/cmd_bank.go +++ b/internal/game/cmd_bank.go @@ -5,8 +5,8 @@ import ( "sort" "strings" - "thehouseoficarus/internal/action" "thehouseoficarus/internal/net" + "thehouseoficarus/internal/object" "thehouseoficarus/internal/player" ) @@ -239,7 +239,7 @@ func (g *Game) doBankWithdraw(sess *net.Session, input string) { } lower := strings.ToLower(input) for _, e := range entries { - if action.WordPrefixMatch(e.name, lower) { + if object.WordPrefixMatch(e.name, lower) { matches = append(matches, e) } } diff --git a/internal/game/cmd_clean.go b/internal/game/cmd_clean.go index 951b41d..28758b8 100644 --- a/internal/game/cmd_clean.go +++ b/internal/game/cmd_clean.go @@ -7,6 +7,7 @@ import ( "thehouseoficarus/internal/combat" "thehouseoficarus/internal/engine" "thehouseoficarus/internal/net" + "thehouseoficarus/internal/object" "thehouseoficarus/internal/player" ) @@ -22,26 +23,19 @@ func (g *Game) doClean(sess *net.Session, input string) { return } - allRecipes, err := g.RecipeStore.LoadAll() - if err != nil { - sess.WriteLine("Error loading recipes.") - return - } + items := g.CraftIndex.ByType("clean") filter := strings.TrimSpace(input) found := false - for _, r := range allRecipes { - if r.Type != "clean" { - continue - } - if filter != "" && !matchesCleanFilter(r, filter) { + for _, item := range items { + if filter != "" && !matchesCleanFilter(item, filter) { continue } - if p.Level(player.Pharmacy) < r.Level { + if p.Level(player.Pharmacy) < item.FirstCraft().Level { continue } - if !r.HasAllItems(p.HasItem) { + if !craftHasAllItems(item.FirstCraft(), p.HasItem) { continue } found = true @@ -49,7 +43,21 @@ func (g *Game) doClean(sess *net.Session, input string) { } if !found { - sess.WriteLine("You don't have any herbs to clean.") + hasHerbs := false + for _, item := range items { + if filter != "" && !matchesCleanFilter(item, filter) { + continue + } + if craftHasAllItems(item.FirstCraft(), p.HasItem) { + hasHerbs = true + break + } + } + if hasHerbs { + sess.WriteLine("You don't have the Pharmacy level to clean any of your herbs.") + } else { + sess.WriteLine("You don't have any herbs to clean.") + } return } @@ -71,13 +79,13 @@ func (g *Game) doClean(sess *net.Session, input string) { sess.WriteLine("\nYou begin cleaning herbs.") } -func matchesCleanFilter(r action.RecipeDef, filter string) bool { - if len(r.Consume) > 0 && len(r.Consume[0].Items) > 0 { - if strings.Contains(r.Consume[0].Items[0], filter) { +func matchesCleanFilter(item *object.ItemDef, filter string) bool { + if len(item.Craft) > 0 && len(item.FirstCraft().Consume) > 0 && len(item.FirstCraft().Consume[0].Items) > 0 { + if strings.Contains(item.FirstCraft().Consume[0].Items[0], filter) { return true } } - if strings.Contains(r.Output, filter) { + if strings.Contains(item.ID, filter) { return true } return false diff --git a/internal/game/cmd_cook.go b/internal/game/cmd_cook.go index 04c98bb..6dfbcce 100644 --- a/internal/game/cmd_cook.go +++ b/internal/game/cmd_cook.go @@ -4,8 +4,8 @@ import ( "fmt" "strings" - "thehouseoficarus/internal/action" "thehouseoficarus/internal/net" + "thehouseoficarus/internal/object" "thehouseoficarus/internal/player" ) @@ -23,14 +23,10 @@ func (g *Game) doCook(sess *net.Session, input string) { return } - allRecipes, err := g.RecipeStore.LoadAll() - if err != nil { - sess.WriteLine("Error loading recipes.") - return - } + items := g.CraftIndex.ByType("cooking") if input == "" { - g.showCookMenu(sess, p, allRecipes, stationDefID, stationName) + g.showCookMenu(sess, p, items, stationDefID, stationName) return } @@ -51,13 +47,11 @@ func (g *Game) doCook(sess *net.Session, input string) { itemID := matches[0].ID - var recipes []action.RecipeDef - for _, r := range allRecipes { - if r.Type != "cooking" { - continue - } - if stationMatch(stationDefID, r.Station) && r.MatchesEntry(itemID) && r.HasAllItems(p.HasItem) { - recipes = append(recipes, r) + var recipes []*object.ItemDef + for _, item := range items { + c := item.FirstCraft() + if stationMatch(stationDefID, c.Station) && craftMatchesEntry(c, itemID) && craftHasAllItems(c, p.HasItem) { + recipes = append(recipes, item) } } @@ -65,25 +59,23 @@ func (g *Game) doCook(sess *net.Session, input string) { g.showRecipeChoice(sess, p, recipes, "You can't cook that.", title, "") } -func (g *Game) showCookMenu(sess *net.Session, p *player.Player, allRecipes []action.RecipeDef, stationDefID, stationName string) { +func (g *Game) showCookMenu(sess *net.Session, p *player.Player, items []*object.ItemDef, stationDefID, stationName string) { seen := make(map[string]bool) - var recipes []action.RecipeDef + var recipes []*object.ItemDef - for _, r := range allRecipes { - if r.Type != "cooking" { - continue - } - if !stationMatch(stationDefID, r.Station) { + for _, item := range items { + c := item.FirstCraft() + if !stationMatch(stationDefID, c.Station) { continue } - if seen[r.ID] { + if seen[item.ID] { continue } - if !r.HasAllItems(p.HasItem) { + if !craftHasAllItems(c, p.HasItem) { continue } - seen[r.ID] = true - recipes = append(recipes, r) + seen[item.ID] = true + recipes = append(recipes, item) } title := fmt.Sprintf("What would you like to cook on the %s?", stationName) diff --git a/internal/game/cmd_craft.go b/internal/game/cmd_craft.go index d061a9c..3290daa 100644 --- a/internal/game/cmd_craft.go +++ b/internal/game/cmd_craft.go @@ -3,8 +3,8 @@ package game import ( "strings" - "thehouseoficarus/internal/action" "thehouseoficarus/internal/net" + "thehouseoficarus/internal/object" "thehouseoficarus/internal/player" ) @@ -28,35 +28,27 @@ func (g *Game) doStationSkill(sess *net.Session, input string, recipeType string p := sess.Player g.cancelAction(p) - allRecipes, err := g.RecipeStore.LoadAll() - if err != nil { - sess.WriteLine("Error loading recipes.") - return - } + items := g.CraftIndex.ByType(recipeType) - var recipes []action.RecipeDef - for _, r := range allRecipes { - if r.Type != recipeType { - continue - } - if !g.recipeVisible(p, &r) { + var filtered []*object.ItemDef + for _, item := range items { + if !g.itemVisible(p, item) { continue } - recipes = append(recipes, r) + filtered = append(filtered, item) } if input != "" { - g.doWithInput(sess, p, recipes, input, skill, flagKey, label, verbCap) + g.doWithInput(sess, p, filtered, input, skill, flagKey, label, verbCap) return } - lastRecipeID, _ := p.Flags[flagKey].(string) - if lastRecipeID != "" { - for i := range recipes { - if recipes[i].ID == lastRecipeID { - r := &recipes[i] - if g.canDoRecipe(p, r, skill) { - g.startRecipe(sess, p, r, 0, flagKey) + lastItemID, _ := p.Flags[flagKey].(string) + if lastItemID != "" { + for _, item := range filtered { + if item.ID == lastItemID { + if g.canDoItem(p, item, skill) { + g.startItem(sess, p, item, 0, flagKey) return } break @@ -64,34 +56,33 @@ func (g *Game) doStationSkill(sess *net.Session, input string, recipeType string } } - available := g.availableRecipes(p, recipes) + available := g.availableItems(p, filtered) if len(available) == 0 { + if recipeType == "pharmacy" && g.hasGrimyHerbs(p) { + sess.WriteLine("Mix what? Grimy herbs? Clean those first!") + return + } sess.WriteLine("You don't have any materials to " + verbPast + ".") return } optionKey := verbPast + "_all" if p.OptionBool(optionKey) && len(available) == 1 { - g.startRecipe(sess, p, &available[0], 0, flagKey) + g.startItem(sess, p, available[0], 0, flagKey) return } g.showProductionTable(sess, p, available, label, recipeType, flagKey, verbCap, false) } -func (g *Game) doWithInput(sess *net.Session, p *player.Player, recipes []action.RecipeDef, input string, skill player.SkillName, flagKey, label, verbCap string) { +func (g *Game) doWithInput(sess *net.Session, p *player.Player, items []*object.ItemDef, input string, skill player.SkillName, flagKey, label, verbCap string) { qty, productName := parseQty(input) productName = strings.TrimSpace(productName) - var matched []action.RecipeDef - for _, r := range recipes { - outDef, _ := g.ItemStore.Load(r.Output) - name := r.Output - if outDef != nil { - name = outDef.Name - } - if action.WordPrefixMatch(productName, name) { - matched = append(matched, r) + var matched []*object.ItemDef + for _, item := range items { + if object.WordPrefixMatch(productName, item.Name) { + matched = append(matched, item) } } @@ -100,10 +91,10 @@ func (g *Game) doWithInput(sess *net.Session, p *player.Player, recipes []action return } - var available []action.RecipeDef - for _, r := range matched { - if g.canDoRecipe(p, &r, skill) { - available = append(available, r) + var available []*object.ItemDef + for _, item := range matched { + if g.canDoItem(p, item, skill) { + available = append(available, item) } } @@ -113,68 +104,85 @@ func (g *Game) doWithInput(sess *net.Session, p *player.Player, recipes []action } if len(available) == 1 { - g.startRecipe(sess, p, &available[0], qty, flagKey) + g.startItem(sess, p, available[0], qty, flagKey) return } g.showProductionTable(sess, p, available, label, label, flagKey, verbCap, false) } -func (g *Game) recipeVisible(p *player.Player, r *action.RecipeDef) bool { - if len(r.Station) > 0 { - stID, _ := g.findStation(p.RoomID, r.Station) - if stID == "" { +func (g *Game) itemVisible(p *player.Player, item *object.ItemDef) bool { + return item.FindCraft(func(c object.CraftDef) bool { + if len(c.Station) > 0 { + stID, _ := g.findStation(p.RoomID, c.Station) + if stID == "" { + return false + } + } + if c.Tool != "" && !g.hasToolType(p, c.Tool) { return false } - } - if r.Tool != "" && !g.hasToolType(p, r.Tool) { - return false - } - return true + return true + }) != nil } -func (g *Game) canDoRecipe(p *player.Player, r *action.RecipeDef, skill player.SkillName) bool { - if p.Level(skill) < r.Level { - return false - } - if !r.HasAllItemsQty(p.CountItem) { - return false - } - if len(r.Station) > 0 { - stID, _ := g.findStation(p.RoomID, r.Station) - if stID == "" { +func (g *Game) canDoItem(p *player.Player, item *object.ItemDef, skill player.SkillName) bool { + m := item.FindCraft(func(c object.CraftDef) bool { + if p.Level(skill) < c.Level { return false } - } - if r.Tool != "" && !g.hasToolType(p, r.Tool) { - return false - } - return true + if !craftHasAllItemsQty(&c, p.CountItem) { + return false + } + if len(c.Station) > 0 { + stID, _ := g.findStation(p.RoomID, c.Station) + if stID == "" { + return false + } + } + if c.Tool != "" && !g.hasToolType(p, c.Tool) { + return false + } + return true + }) + return m != nil } -func (g *Game) availableRecipes(p *player.Player, allRecipes []action.RecipeDef) []action.RecipeDef { - var result []action.RecipeDef - for _, r := range allRecipes { - if r.HasAllItemsQty(p.CountItem) { - result = append(result, r) +func (g *Game) availableItems(p *player.Player, allItems []*object.ItemDef) []*object.ItemDef { + var result []*object.ItemDef + for _, item := range allItems { + m := item.FindCraft(func(c object.CraftDef) bool { + return craftHasAllItemsQty(&c, p.CountItem) + }) + if m != nil { + result = append(result, item) } } return result } -func (g *Game) startRecipe(sess *net.Session, p *player.Player, recipe *action.RecipeDef, count int, flagKey string) { +func (g *Game) startItem(sess *net.Session, p *player.Player, item *object.ItemDef, count int, flagKey string) { p.EnsureFlags() - p.Flags[flagKey] = recipe.ID + p.Flags[flagKey] = item.ID g.AccountStore.SaveCharacter(p) - g.startProductionFromRecipe(sess, p, recipe, count) + g.startProductionFromItem(sess, p, item, count) } -func (g *Game) findCraftRecipes(p *player.Player, itemAID, itemBID string) []action.RecipeDef { - allRecipes, err := g.RecipeStore.LoadAll() - if err != nil { - return nil +func (g *Game) hasGrimyHerbs(p *player.Player) bool { + items := g.CraftIndex.ByType("clean") + for _, item := range items { + if item.FindCraft(func(c object.CraftDef) bool { + return craftHasAllItems(&c, p.HasItem) + }) != nil { + return true + } } + return false +} + +func (g *Game) findCraftItems(p *player.Player, itemAID, itemBID string) []*object.ItemDef { + items := g.CraftIndex.ByType("crafting") toolTypeA := "" toolTypeB := "" @@ -185,19 +193,22 @@ func (g *Game) findCraftRecipes(p *player.Player, itemAID, itemBID string) []act toolTypeB = defB.ToolType } - var matched []action.RecipeDef - for _, r := range allRecipes { - if r.Type != "crafting" { - continue - } - if r.Tool == "" { - continue - } - - if r.Tool == toolTypeA && r.MatchesEntry(itemBID) { - matched = append(matched, r) - } else if r.Tool == toolTypeB && r.MatchesEntry(itemAID) { - matched = append(matched, r) + var matched []*object.ItemDef + for _, item := range items { + match := item.FindCraft(func(c object.CraftDef) bool { + if c.Tool == "" { + return false + } + if c.Tool == toolTypeA && craftMatchesEntry(&c, itemBID) { + return true + } + if c.Tool == toolTypeB && craftMatchesEntry(&c, itemAID) { + return true + } + return false + }) + if match != nil { + matched = append(matched, item) } } return matched diff --git a/internal/game/cmd_fletch.go b/internal/game/cmd_fletch.go index 5a4bc19..088ce63 100644 --- a/internal/game/cmd_fletch.go +++ b/internal/game/cmd_fletch.go @@ -3,9 +3,9 @@ package game import ( "strings" - "thehouseoficarus/internal/action" "thehouseoficarus/internal/combat" "thehouseoficarus/internal/net" + "thehouseoficarus/internal/object" "thehouseoficarus/internal/player" ) @@ -23,34 +23,38 @@ var fletchGemItems = map[string]bool{ "uncut_ruby": true, "uncut_diamond": true, } -func fletchNeedsKnife(r *action.RecipeDef) bool { - if r.Tool == "knife" { - return true - } - for _, e := range r.Consume { - for _, id := range e.Items { - if fletchLogItems[id] { - if strings.Contains(r.Output, "shaft") || strings.Contains(r.Output, "bow") { - return true +func fletchNeedsKnife(item *object.ItemDef) bool { + return item.FindCraft(func(c object.CraftDef) bool { + if c.Tool == "knife" { + return true + } + for _, e := range c.Consume { + for _, id := range e.Items { + if fletchLogItems[id] { + if strings.Contains(item.ID, "shaft") || strings.Contains(item.ID, "bow") { + return true + } } } } - } - return false + return false + }) != nil } -func fletchNeedsChisel(r *action.RecipeDef) bool { - if r.Tool == "chisel" { - return true - } - for _, e := range r.Consume { - for _, id := range e.Items { - if fletchGemItems[id] { - return true +func fletchNeedsChisel(item *object.ItemDef) bool { + return item.FindCraft(func(c object.CraftDef) bool { + if c.Tool == "chisel" { + return true + } + for _, e := range c.Consume { + for _, id := range e.Items { + if fletchGemItems[id] { + return true + } } } - } - return false + return false + }) != nil } func (g *Game) doFletch(sess *net.Session, input string) { @@ -66,32 +70,19 @@ func (g *Game) doFletch(sess *net.Session, input string) { p.ActionState = nil } - allRecipes, err := g.RecipeStore.LoadAll() - if err != nil { - sess.WriteLine("Error loading recipes.") - return - } - - var fletchRecipes []action.RecipeDef - for _, r := range allRecipes { - if r.Type != "fletching" { - continue - } - fletchRecipes = append(fletchRecipes, r) - } + items := g.CraftIndex.ByType("fletching") if input != "" { - g.doFletchWithInput(sess, p, fletchRecipes, input) + g.doFletchWithInput(sess, p, items, input) return } - lastRecipeID, _ := p.Flags["last_fletch"].(string) - if lastRecipeID != "" { - for i := range fletchRecipes { - if fletchRecipes[i].ID == lastRecipeID { - r := &fletchRecipes[i] - if g.canDoFletchRecipe(p, r) { - g.startFletchAction(sess, p, r, 0) + lastItemID, _ := p.Flags["last_fletch"].(string) + if lastItemID != "" { + for _, item := range items { + if item.ID == lastItemID { + if g.canDoFletchItem(p, item) { + g.startFletchAction(sess, p, item, 0) return } break @@ -99,33 +90,28 @@ func (g *Game) doFletch(sess *net.Session, input string) { } } - available := g.availableFletchRecipes(p, fletchRecipes) + available := g.availableFletchItems(p, items) if len(available) == 0 { sess.WriteLine("You don't have any materials to fletch.") return } if p.OptionBool("fletch_all") && len(available) == 1 { - g.startFletchAction(sess, p, &available[0], 0) + g.startFletchAction(sess, p, available[0], 0) return } g.showProductionTable(sess, p, available, "Fletching", "fletching", "last_fletch", "Fletch", true) } -func (g *Game) doFletchWithInput(sess *net.Session, p *player.Player, fletchRecipes []action.RecipeDef, input string) { +func (g *Game) doFletchWithInput(sess *net.Session, p *player.Player, items []*object.ItemDef, input string) { qty, productName := parseQty(input) productName = strings.TrimSpace(productName) - var matched []action.RecipeDef - for _, r := range fletchRecipes { - outDef, _ := g.ItemStore.Load(r.Output) - name := r.Output - if outDef != nil { - name = outDef.Name - } - if action.WordPrefixMatch(productName, name) { - matched = append(matched, r) + var matched []*object.ItemDef + for _, item := range items { + if object.WordPrefixMatch(productName, item.Name) { + matched = append(matched, item) } } @@ -134,10 +120,10 @@ func (g *Game) doFletchWithInput(sess *net.Session, p *player.Player, fletchReci return } - var available []action.RecipeDef - for _, r := range matched { - if g.canDoFletchRecipe(p, &r) { - available = append(available, r) + var available []*object.ItemDef + for _, item := range matched { + if g.canDoFletchItem(p, item) { + available = append(available, item) } } @@ -147,48 +133,49 @@ func (g *Game) doFletchWithInput(sess *net.Session, p *player.Player, fletchReci } if len(available) == 1 { - count := qty - g.startFletchAction(sess, p, &available[0], count) + g.startFletchAction(sess, p, available[0], qty) return } g.showProductionTable(sess, p, available, "Fletching", "fletching", "last_fletch", "Fletch", true) } -func (g *Game) hasFletchTools(p *player.Player, r *action.RecipeDef) bool { - if r.Tool != "" { - return g.hasToolType(p, r.Tool) +func (g *Game) hasFletchTools(p *player.Player, item *object.ItemDef) bool { + c := item.FirstCraft() + if c.Tool != "" { + return g.hasToolType(p, c.Tool) } - if fletchNeedsKnife(r) && !g.hasToolType(p, "knife") { + if fletchNeedsKnife(item) && !g.hasToolType(p, "knife") { return false } - if fletchNeedsChisel(r) && !g.hasToolType(p, "chisel") { + if fletchNeedsChisel(item) && !g.hasToolType(p, "chisel") { return false } return true } -func (g *Game) canDoFletchRecipe(p *player.Player, r *action.RecipeDef) bool { - return p.Level(player.Fletching) >= r.Level && - r.HasAllItemsQty(p.CountItem) && - g.hasFletchTools(p, r) +func (g *Game) canDoFletchItem(p *player.Player, item *object.ItemDef) bool { + return item.FindCraft(func(c object.CraftDef) bool { + return p.Level(player.Fletching) >= c.Level && + craftHasAllItemsQty(&c, p.CountItem) + }) != nil && g.hasFletchTools(p, item) } -func (g *Game) availableFletchRecipes(p *player.Player, allFletch []action.RecipeDef) []action.RecipeDef { - var result []action.RecipeDef - for _, r := range allFletch { - if r.HasAllItemsQty(p.CountItem) && g.hasFletchTools(p, &r) { - result = append(result, r) +func (g *Game) availableFletchItems(p *player.Player, allItems []*object.ItemDef) []*object.ItemDef { + var result []*object.ItemDef + for _, item := range allItems { + match := item.FindCraft(func(c object.CraftDef) bool { + return craftHasAllItemsQty(&c, p.CountItem) + }) + if match != nil && g.hasFletchTools(p, item) { + result = append(result, item) } } return result } -func (g *Game) findFletchRecipes(p *player.Player, itemAID, itemBID string) []action.RecipeDef { - allRecipes, err := g.RecipeStore.LoadAll() - if err != nil { - return nil - } +func (g *Game) findFletchItems(p *player.Player, itemAID, itemBID string) []*object.ItemDef { + items := g.CraftIndex.ByType("fletching") toolTypeA := "" toolTypeB := "" @@ -201,26 +188,24 @@ func (g *Game) findFletchRecipes(p *player.Player, itemAID, itemBID string) []ac isToolA := toolTypeA == "knife" || toolTypeA == "chisel" isToolB := toolTypeB == "knife" || toolTypeB == "chisel" - var matched []action.RecipeDef - for _, r := range allRecipes { - if r.Type != "fletching" { - continue - } + var matched []*object.ItemDef + for _, item := range items { + c := item.FirstCraft() - if r.Tool != "" { - if r.Tool == toolTypeA && r.MatchesEntry(itemBID) { - matched = append(matched, r) + if c.Tool != "" { + if c.Tool == toolTypeA && craftMatchesEntry(c, itemBID) { + matched = append(matched, item) continue } - if r.Tool == toolTypeB && r.MatchesEntry(itemAID) { - matched = append(matched, r) + if c.Tool == toolTypeB && craftMatchesEntry(c, itemAID) { + matched = append(matched, item) continue } } aMatch := false bMatch := false - for _, e := range r.Consume { + for _, e := range c.Consume { for _, id := range e.Items { if id == itemAID { aMatch = true @@ -232,21 +217,21 @@ func (g *Game) findFletchRecipes(p *player.Player, itemAID, itemBID string) []ac } if aMatch && bMatch { - matched = append(matched, r) + matched = append(matched, item) continue } if isToolA && bMatch { - if (fletchNeedsKnife(&r) && toolTypeA == "knife") || - (fletchNeedsChisel(&r) && toolTypeA == "chisel") { - matched = append(matched, r) + if (fletchNeedsKnife(item) && toolTypeA == "knife") || + (fletchNeedsChisel(item) && toolTypeA == "chisel") { + matched = append(matched, item) continue } } if isToolB && aMatch { - if (fletchNeedsKnife(&r) && toolTypeB == "knife") || - (fletchNeedsChisel(&r) && toolTypeB == "chisel") { - matched = append(matched, r) + if (fletchNeedsKnife(item) && toolTypeB == "knife") || + (fletchNeedsChisel(item) && toolTypeB == "chisel") { + matched = append(matched, item) continue } } diff --git a/internal/game/cmd_shop.go b/internal/game/cmd_shop.go index 2742151..c6b7831 100644 --- a/internal/game/cmd_shop.go +++ b/internal/game/cmd_shop.go @@ -158,7 +158,7 @@ func (g *Game) findShopMatches(input string, cfg *action.ShopConfig) []shopMatch if def != nil { itemName = def.Name } - if action.WordPrefixMatch(input, itemName) { + if object.WordPrefixMatch(input, itemName) { matches = append(matches, shopMatch{si: si, name: itemName, def: def}) } } diff --git a/internal/game/cmd_smelt.go b/internal/game/cmd_smelt.go index f1ff4e2..8ad2391 100644 --- a/internal/game/cmd_smelt.go +++ b/internal/game/cmd_smelt.go @@ -4,8 +4,8 @@ import ( "fmt" "strings" - "thehouseoficarus/internal/action" "thehouseoficarus/internal/net" + "thehouseoficarus/internal/object" "thehouseoficarus/internal/player" ) @@ -23,14 +23,10 @@ func (g *Game) doSmelt(sess *net.Session, input string) { return } - allRecipes, err := g.RecipeStore.LoadAll() - if err != nil { - sess.WriteLine("Error loading recipes.") - return - } + items := g.CraftIndex.ByType("smelting") if input == "" { - g.showSmeltMenu(sess, p, allRecipes, stationDefID, stationName) + g.showSmeltMenu(sess, p, items, stationDefID, stationName) return } @@ -48,33 +44,35 @@ func (g *Game) doSmelt(sess *net.Session, input string) { itemID := matches[0].ID - var recipes []action.RecipeDef - for _, r := range allRecipes { - if r.Type != "smelting" || !stationMatch(stationDefID, r.Station) || !r.MatchesEntry(itemID) { + var recipes []*object.ItemDef + for _, item := range items { + c := item.FirstCraft() + if !stationMatch(stationDefID, c.Station) || !craftMatchesEntry(c, itemID) { continue } - if !r.HasAllItemsQty(p.CountItem) || p.Level(player.SkillName(r.EffectiveSkill())) < r.Level { + if !craftHasAllItemsQty(c, p.CountItem) || p.Level(player.SkillName(c.EffectiveSkill())) < c.Level { continue } - recipes = append(recipes, r) + recipes = append(recipes, item) } g.showRecipeChoice(sess, p, recipes, "You can't smelt that.", "What would you like to smelt?", "") } -func (g *Game) showSmeltMenu(sess *net.Session, p *player.Player, allRecipes []action.RecipeDef, stationDefID, stationName string) { +func (g *Game) showSmeltMenu(sess *net.Session, p *player.Player, items []*object.ItemDef, stationDefID, stationName string) { seen := make(map[string]bool) - var recipes []action.RecipeDef + var recipes []*object.ItemDef - for _, r := range allRecipes { - if r.Type != "smelting" || !stationMatch(stationDefID, r.Station) { + for _, item := range items { + c := item.FirstCraft() + if !stationMatch(stationDefID, c.Station) { continue } - if seen[r.ID] || !r.HasAllItemsQty(p.CountItem) || p.Level(player.SkillName(r.EffectiveSkill())) < r.Level { + if seen[item.ID] || !craftHasAllItemsQty(c, p.CountItem) || p.Level(player.SkillName(c.EffectiveSkill())) < c.Level { continue } - seen[r.ID] = true - recipes = append(recipes, r) + seen[item.ID] = true + recipes = append(recipes, item) } g.showRecipeChoice(sess, p, recipes, "You don't have anything you can smelt.", "What would you like to smelt?", "smelt_all") diff --git a/internal/game/cmd_smith.go b/internal/game/cmd_smith.go index c7a32cd..712c03c 100644 --- a/internal/game/cmd_smith.go +++ b/internal/game/cmd_smith.go @@ -5,8 +5,8 @@ import ( "sort" "strings" - "thehouseoficarus/internal/action" "thehouseoficarus/internal/net" + "thehouseoficarus/internal/object" "thehouseoficarus/internal/player" ) @@ -29,11 +29,7 @@ func (g *Game) doSmith(sess *net.Session, input string) { return } - allRecipes, err := g.RecipeStore.LoadAll() - if err != nil { - sess.WriteLine("Error loading recipes.") - return - } + items := g.CraftIndex.ByType("smithing") if input != "" { matches := g.findInventoryMatches(input, p) @@ -47,15 +43,15 @@ func (g *Game) doSmith(sess *net.Session, input string) { return } barID := matches[0].ID - if !hasSmithingRecipes(allRecipes, barID) { + if !hasSmithingItems(items, barID) { sess.WriteLine("You can't smith that.") return } - g.showSmithTable(sess, p, barID, allRecipes) + g.showSmithTable(sess, p, barID) return } - barTypes := findSmithableBars(allRecipes, p) + barTypes := findSmithableBars(items, p) if len(barTypes) == 0 { sess.WriteLine("You don't have any bars to smith.") return @@ -63,12 +59,12 @@ func (g *Game) doSmith(sess *net.Session, input string) { if len(barTypes) == 1 { if p.OptionBool("smith_all") { - if recipe := g.findSmithRecipe(p, barTypes[0], allRecipes); recipe != nil { - g.startProductionFromRecipe(sess, p, recipe, 0) + if item := g.findSmithItem(p, barTypes[0], items); item != nil { + g.startProductionFromItem(sess, p, item, 0) return } } - g.showSmithTable(sess, p, barTypes[0], allRecipes) + g.showSmithTable(sess, p, barTypes[0]) return } @@ -86,17 +82,18 @@ func (g *Game) doSmith(sess *net.Session, input string) { g.showMenuTable(sess, "Which bars would you like to smith?", names) } -func (g *Game) showSmithTable(sess *net.Session, p *player.Player, barID string, allRecipes []action.RecipeDef) { +func (g *Game) showSmithTable(sess *net.Session, p *player.Player, barID string) { barDef, _ := g.ItemStore.Load(barID) barName := barID if barDef != nil { barName = barDef.Name } - var recipes []action.RecipeDef - for _, r := range allRecipes { - if r.Type == "smithing" && r.MatchesEntry(barID) { - recipes = append(recipes, r) + allItems := g.CraftIndex.ByType("smithing") + var recipes []*object.ItemDef + for _, item := range allItems { + if craftMatchesEntry(item.FirstCraft(), barID) { + recipes = append(recipes, item) } } @@ -109,22 +106,19 @@ func (g *Game) showSmithTable(sess *net.Session, p *player.Player, barID string, g.showProductionTable(sess, p, recipes, titleCase(barName)+" Smithing", "smithing", lastFlag, "Produce", false) } -func hasSmithingRecipes(allRecipes []action.RecipeDef, barID string) bool { - for _, r := range allRecipes { - if r.Type == "smithing" && r.MatchesEntry(barID) { +func hasSmithingItems(items []*object.ItemDef, barID string) bool { + for _, item := range items { + if craftMatchesEntry(item.FirstCraft(), barID) { return true } } return false } -func findSmithableBars(allRecipes []action.RecipeDef, p *player.Player) []string { +func findSmithableBars(items []*object.ItemDef, p *player.Player) []string { barSet := make(map[string]bool) - for _, r := range allRecipes { - if r.Type != "smithing" { - continue - } - for _, e := range r.Consume { + for _, item := range items { + for _, e := range item.FirstCraft().Consume { for _, id := range e.Items { if p.HasItem(id) { barSet[id] = true @@ -148,15 +142,16 @@ func barMenuData(barIDs []string) []map[string]string { return out } -func (g *Game) findSmithRecipe(p *player.Player, barID string, allRecipes []action.RecipeDef) *action.RecipeDef { - var makeable []*action.RecipeDef +func (g *Game) findSmithItem(p *player.Player, barID string, items []*object.ItemDef) *object.ItemDef { + var makeable []*object.ItemDef skillLevel := p.Level(player.Smithing) - for i, r := range allRecipes { - if r.Type != "smithing" || !r.MatchesEntry(barID) { + for _, item := range items { + c := item.FirstCraft() + if !craftMatchesEntry(c, barID) { continue } - if skillLevel >= r.Level && r.HasAllItemsQty(p.CountItem) { - makeable = append(makeable, &allRecipes[i]) + if skillLevel >= c.Level && craftHasAllItemsQty(c, p.CountItem) { + makeable = append(makeable, item) } } if len(makeable) == 1 { diff --git a/internal/game/cmd_trigger_utility.go b/internal/game/cmd_trigger_utility.go index ce59975..69abc34 100644 --- a/internal/game/cmd_trigger_utility.go +++ b/internal/game/cmd_trigger_utility.go @@ -6,6 +6,7 @@ import ( "thehouseoficarus/internal/combat" "thehouseoficarus/internal/net" + "thehouseoficarus/internal/object" "thehouseoficarus/internal/player" ) @@ -169,18 +170,25 @@ func (g *Game) triggerSuperheat(sess *net.Session, p *player.Player, mod *ModDef return } - recipe := g.RecipeStore.FindByInput("smelt", inv.ItemID) - if recipe == nil { + var match *object.ItemDef + for _, item := range g.CraftIndex.ByType("smelting") { + if craftMatchesEntry(item.FirstCraft(), inv.ItemID) { + match = item + break + } + } + if match == nil { sess.WriteLine("You can't superheat that.") return } + c := match.FirstCraft() - if recipe.Level > 0 && p.Level(player.SkillName(recipe.Skill)) < recipe.Level { - sess.WriteLine(fmt.Sprintf("You need level %d %s to smelt that.", recipe.Level, recipe.Skill)) + if c.Level > 0 && p.Level(player.SkillName(c.Skill)) < c.Level { + sess.WriteLine(fmt.Sprintf("You need level %d %s to smelt that.", c.Level, c.Skill)) return } - for _, e := range recipe.Consume { + for _, e := range c.Consume { for _, itemID := range e.Items { qty := e.Quantity if qty <= 0 { @@ -202,24 +210,16 @@ func (g *Game) triggerSuperheat(sess *net.Session, p *player.Player, mod *ModDef g.cancelAction(p) } - for _, e := range recipe.Consume { - for _, itemID := range e.Items { - qty := e.Quantity - if qty <= 0 { - qty = 1 - } - p.RemoveItem(itemID, qty) - } - } + craftConsumeAll(c, p.HasItem, p.RemoveItem) - outputQty := recipe.OutputQty + outputQty := c.OutputQty if outputQty <= 0 { outputQty = 1 } placed := false for i := 0; i < 28; i++ { slot := p.InvSlot(i) - if slot != nil && slot.ItemID == recipe.Output { + if slot != nil && slot.ItemID == match.ID { slot.Quantity += outputQty placed = true break @@ -227,20 +227,16 @@ func (g *Game) triggerSuperheat(sess *net.Session, p *player.Player, mod *ModDef } if !placed { freeSlot := p.FirstFreeSlot() - p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: recipe.Output, Quantity: outputQty}) + p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: match.ID, Quantity: outputQty}) } var extraGains []xpGain - if recipe.XP > 0 { - extraGains = []xpGain{{recipe.Skill, recipe.XP}} + if c.XP > 0 { + extraGains = []xpGain{{c.EffectiveSkill(), c.XP}} } g.triggerModReward(sess, p, mod, 1.0, extraGains...) - outputDef, _ := g.ItemStore.Load(recipe.Output) - outputName := recipe.Output - if outputDef != nil { - outputName = outputDef.Name - } + outputName := match.Name inputDef, _ := g.ItemStore.Load(inv.ItemID) inputName := inv.ItemID if inputDef != nil { diff --git a/internal/game/cmd_use.go b/internal/game/cmd_use.go index e653c93..640e28b 100644 --- a/internal/game/cmd_use.go +++ b/internal/game/cmd_use.go @@ -4,7 +4,6 @@ import ( "fmt" "strings" - "thehouseoficarus/internal/action" "thehouseoficarus/internal/net" "thehouseoficarus/internal/object" "thehouseoficarus/internal/player" @@ -116,57 +115,42 @@ func (g *Game) useRoomObject(sess *net.Session, p *player.Player, input string) return true } -func (g *Game) stationRecipes(p *player.Player, stationDefID string) []action.RecipeDef { - allRecipes, err := g.RecipeStore.LoadAll() - if err != nil { - return nil - } - var results []action.RecipeDef - for _, r := range allRecipes { - if len(r.Station) == 0 { - continue - } - stationMatch := false - for _, sid := range r.Station { - if sid == stationDefID { - stationMatch = true - break - } - } - if !stationMatch { +func (g *Game) stationRecipes(p *player.Player, stationDefID string) []*object.ItemDef { + items := g.CraftIndex.ByStation(stationDefID) + var results []*object.ItemDef + for _, item := range items { + c := item.FirstCraft() + if !craftHasAllItemsQty(c, p.CountItem) { continue } - if !r.HasAllItemsQty(p.CountItem) { + skillName := player.SkillName(c.EffectiveSkill()) + if p.Level(skillName) < c.Level { continue } - skillName := player.SkillName(r.EffectiveSkill()) - if p.Level(skillName) < r.Level { - continue - } - if r.Tool != "" && !g.hasToolType(p, r.Tool) { + if c.Tool != "" && !g.hasToolType(p, c.Tool) { continue } if stationDefID == "anvil" && !g.hasToolType(p, "hammer") { continue } - results = append(results, r) + results = append(results, item) } return results } -func (g *Game) showRecipeMenu(sess *net.Session, p *player.Player, recipes []action.RecipeDef, stationName string) { - if len(recipes) == 0 { +func (g *Game) showRecipeMenu(sess *net.Session, p *player.Player, items []*object.ItemDef, stationName string) { + if len(items) == 0 { sess.WriteLine(fmt.Sprintf("You don't have anything you can make at the %s.", stationName)) return } - if len(recipes) == 1 { - g.promptHowMany(sess, recipes[0].ID) + if len(items) == 1 { + g.promptHowMany(sess, items[0].ID) return } needTypes := false - for i := range recipes { - for j := i + 1; j < len(recipes); j++ { - if recipes[i].Type != recipes[j].Type { + for i := range items { + for j := i + 1; j < len(items); j++ { + if len(items[i].Craft) > 0 && len(items[j].Craft) > 0 && items[i].FirstCraft().Type != items[j].FirstCraft().Type { needTypes = true break } @@ -175,17 +159,23 @@ func (g *Game) showRecipeMenu(sess *net.Session, p *player.Player, recipes []act break } } - menu := recipeMenuData(recipeDefIDs(recipes)) + menu := itemMenuData(itemIDs(items)) sess.PendingMenu = menu sess.State = net.StateRecipeChoice var names []string - for _, r := range recipes { - name := g.recipeName(sess, &r) + for _, item := range items { + cType := "" + if len(item.Craft) > 0 { + cType = item.FirstCraft().Type + } + if cType == "" { + cType = "combine" + } + typeLabel := strings.ToUpper(cType[:1]) + cType[1:] if needTypes { - typeLabel := strings.ToUpper(r.Type[:1]) + r.Type[1:] - names = append(names, fmt.Sprintf("%s (%s)", name, typeLabel)) + names = append(names, fmt.Sprintf("%s (%s)", g.itemName(sess, item), typeLabel)) } else { - names = append(names, name) + names = append(names, g.itemName(sess, item)) } } g.showMenuTable(sess, fmt.Sprintf("What would you like to make at the %s?", stationName), names) @@ -217,23 +207,28 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, return } - stationIDs := []string{def.ID} - recipes, err := g.RecipeStore.FindByStation(itemAID, stationIDs, "") - if err == nil && len(recipes) > 0 { - if recipes[0].Type == "smelting" { - filtered := recipes[:0:0] - for _, r := range recipes { - if r.Type != "smelting" { + recipes := g.CraftIndex.FindByStationInput(def.ID, itemAID) + + if len(recipes) > 0 { + cType := "" + if len(recipes[0].Craft) > 0 { + cType = recipes[0].FirstCraft().Type + } + if cType == "smelting" { + var filtered []*object.ItemDef + for _, item := range recipes { + c := item.FirstCraft() + if c.Type != "smelting" { continue } - if !r.HasAllItemsQty(p.CountItem) { + if !craftHasAllItemsQty(c, p.CountItem) { continue } - skillLevel := p.Level(player.SkillName(r.EffectiveSkill())) - if skillLevel < r.Level { + skillLevel := p.Level(player.SkillName(c.EffectiveSkill())) + if skillLevel < c.Level { continue } - filtered = append(filtered, r) + filtered = append(filtered, item) } if len(filtered) == 0 { sess.WriteLine("You can't smelt that here.") @@ -243,36 +238,35 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, g.promptHowMany(sess, filtered[0].ID) return } - sess.PendingMenu = recipeMenuData(recipeDefIDs(filtered)) - sess.State = net.StateRecipeChoice - var names []string - for _, r := range filtered { - names = append(names, g.recipeName(sess, &r)) - } - g.showMenuTable(sess, "What would you like to smelt?", names) - return + sess.PendingMenu = itemMenuData(itemIDs(filtered)) + sess.State = net.StateRecipeChoice + var names []string + for _, item := range filtered { + names = append(names, g.itemName(sess, item)) + } + g.showMenuTable(sess, "What would you like to smelt?", names) + return } - if recipes[0].Type == "smithing" { + if cType == "smithing" { if !g.hasToolType(p, "hammer") { sess.WriteLine("You need a hammer to smith.") return } - allRecipes, _ := g.RecipeStore.LoadAll() - g.showSmithTable(sess, p, itemAID, allRecipes) + g.showSmithTable(sess, p, itemAID) return } if len(recipes) == 1 { g.promptHowMany(sess, recipes[0].ID) return } - sess.PendingMenu = recipeMenuData(recipeDefIDs(recipes)) - sess.State = net.StateRecipeChoice - var names []string - for _, r := range recipes { - names = append(names, g.recipeName(sess, &r)) - } - g.showMenuTable(sess, fmt.Sprintf("What would you like to make with %s on the %s?", itemAName, def.Name), names) - return + sess.PendingMenu = itemMenuData(itemIDs(recipes)) + sess.State = net.StateRecipeChoice + var names []string + for _, item := range recipes { + names = append(names, g.itemName(sess, item)) + } + g.showMenuTable(sess, fmt.Sprintf("What would you like to make with %s on the %s?", itemAName, def.Name), names) + return } for _, ui := range def.UseInteractions { @@ -314,29 +308,19 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, itemBID := matchesB[0].ID - craftRecipes := g.findCraftRecipes(p, itemAID, itemBID) - fletchRecipes := g.findFletchRecipes(p, itemAID, itemBID) + craftItems := g.findCraftItems(p, itemAID, itemBID) + fletchItems := g.findFletchItems(p, itemAID, itemBID) - if len(craftRecipes) > 0 && len(fletchRecipes) > 0 { + if len(craftItems) > 0 && len(fletchItems) > 0 { var menu []map[string]string var names []string - for _, r := range craftRecipes { - menu = append(menu, map[string]string{"recipe_id": r.ID}) - outDef, _ := g.ItemStore.Load(r.Output) - name := r.Output - if outDef != nil { - name = outDef.Name - } - names = append(names, fmt.Sprintf("%s (Crafting)", name)) + for _, item := range craftItems { + menu = append(menu, map[string]string{"item_id": item.ID}) + names = append(names, fmt.Sprintf("%s (Crafting)", item.Name)) } - for _, r := range fletchRecipes { - menu = append(menu, map[string]string{"fletch_recipe_id": r.ID}) - outDef, _ := g.ItemStore.Load(r.Output) - name := r.Output - if outDef != nil { - name = outDef.Name - } - names = append(names, fmt.Sprintf("%s (Fletching)", name)) + for _, item := range fletchItems { + menu = append(menu, map[string]string{"item_id": item.ID}) + names = append(names, fmt.Sprintf("%s (Fletching)", item.Name)) } sess.PendingMenu = menu sess.State = net.StateRecipeChoice @@ -344,15 +328,15 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, return } - if len(craftRecipes) > 0 { - var available []action.RecipeDef - for _, r := range craftRecipes { - if g.canDoRecipe(p, &r, player.Crafting) { - available = append(available, r) + if len(craftItems) > 0 { + var available []*object.ItemDef + for _, item := range craftItems { + if g.canDoItem(p, item, player.Crafting) { + available = append(available, item) } } if len(available) == 1 { - g.startRecipe(sess, p, &available[0], 0, "last_craft") + g.startItem(sess, p, available[0], 0, "last_craft") return } if len(available) > 1 { @@ -361,15 +345,15 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, } } - if len(fletchRecipes) > 0 { - var available []action.RecipeDef - for _, r := range fletchRecipes { - if g.canDoFletchRecipe(p, &r) { - available = append(available, r) + if len(fletchItems) > 0 { + var available []*object.ItemDef + for _, item := range fletchItems { + if g.canDoFletchItem(p, item) { + available = append(available, item) } } if len(available) == 1 { - g.startFletchAction(sess, p, &available[0], 0) + g.startFletchAction(sess, p, available[0], 0) return } if len(available) > 1 { @@ -378,22 +362,33 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, } } - matched := g.findCombineResults(sess, p, itemAID, itemBID) - if len(matched) == 1 { - g.promptHowMany(sess, "combine_"+matched[0].ID) + matched := g.CraftIndex.FindByTwoInputs(itemAID, itemBID) + var matchable []*object.ItemDef + for _, item := range matched { + if craftHasAllItemsQty(item.FirstCraft(), p.CountItem) { + matchable = append(matchable, item) + } + } + if len(matchable) == 1 { + g.promptHowMany(sess, matchable[0].ID) return } - if len(matched) > 1 { - sess.PendingMenu = combineMenuData(matched) + if len(matchable) > 1 { + sess.PendingMenu = itemMenuData(itemIDs(matchable)) sess.State = net.StateRecipeChoice var names []string - for _, def := range matched { - names = append(names, g.itemColorize(sess, def, def.Name)) + for _, item := range matchable { + names = append(names, g.itemName(sess, item)) } g.showMenuTable(sess, "What would you like to make?", names) return } + if g.isGrimyHerb(itemAID) && itemBID == "vial_of_water" { + sess.WriteLine("Don't put a grimy herb in there! Clean it first!") + return + } + sess.WriteLine("You can't combine those items.") return } @@ -401,55 +396,16 @@ func (g *Game) doUseItemOnTarget(sess *net.Session, p *player.Player, itemAName, sess.WriteLine(fmt.Sprintf("There's no '%s' here to use that on.", itemBName)) } -func (g *Game) findCombineResults(sess *net.Session, p *player.Player, itemAID, itemBID string) []*object.ItemDef { - items, err := g.ItemStore.LoadAll() - if err != nil { - return nil - } - var matched []*object.ItemDef - for _, def := range items { - if len(def.MadeFrom) == 0 { - continue - } - aEntry := -1 - bEntry := -1 - for ei, entry := range def.MadeFrom { - for _, id := range entry.Items { - if id == itemAID && aEntry < 0 { - aEntry = ei - } - if id == itemBID && bEntry < 0 { - bEntry = ei +func (g *Game) isGrimyHerb(itemID string) bool { + items := g.CraftIndex.ByType("clean") + for _, item := range items { + for _, e := range item.FirstCraft().Consume { + for _, id := range e.Items { + if id == itemID { + return true } } } - if aEntry >= 0 && bEntry >= 0 && aEntry != bEntry && madeFromAvailable(p, def.MadeFrom) { - matched = append(matched, def) - } } - return matched -} - -func combineMenuData(defs []*object.ItemDef) []map[string]string { - out := make([]map[string]string, len(defs)) - for i, d := range defs { - out[i] = map[string]string{"combine_item": d.ID} - } - return out -} - -func madeFromAvailable(p *player.Player, madeFrom []object.MadeFromEntry) bool { - for _, entry := range madeFrom { - found := false - for _, id := range entry.Items { - if p.HasItem(id) { - found = true - break - } - } - if !found { - return false - } - } - return true + return false } diff --git a/internal/game/cmd_verbs.go b/internal/game/cmd_verbs.go index 7801903..f66dc74 100644 --- a/internal/game/cmd_verbs.go +++ b/internal/game/cmd_verbs.go @@ -88,12 +88,12 @@ func (g *Game) executeVerbs(sess *net.Session, args []string, rawInput string) { if len(recipes) > 0 { addUnique(§ionObjs, &seen, "use "+name) for _, r := range recipes { - if info, ok := productionTypes[r.Type]; ok { + if info, ok := productionTypes[r.FirstCraft().Type]; ok { if info.ActionType != "combine" && info.ActionType != "fletch" && info.ActionType != "mix" { addUnique(§ionObjs, &seen, info.ActionType) } } - for _, c := range r.Consume { + for _, c := range r.FirstCraft().Consume { for _, itemID := range c.Items { if itemDef, err := g.ItemStore.Load(itemID); err == nil { addUnique(§ionObjs, &seen, "use "+itemDef.Name+" on "+name) diff --git a/internal/game/core_production.go b/internal/game/core_production.go index 59517d5..4aecc54 100644 --- a/internal/game/core_production.go +++ b/internal/game/core_production.go @@ -13,47 +13,61 @@ import ( "thehouseoficarus/internal/net" "thehouseoficarus/internal/object" "thehouseoficarus/internal/player" - ) -func (g *Game) startProduction(sess *net.Session, p *player.Player, recipe *action.RecipeDef, actionType, displayVerb, startMsg, endMsg string, count int) { +func craftFirstItemName(c *object.CraftDef, load func(string) (string, bool)) string { + if c == nil { + return "" + } + for _, e := range c.Consume { + for _, id := range e.Items { + if name, ok := load(id); ok { + return name + } + return id + } + } + return "" +} + +func (g *Game) startProduction(sess *net.Session, p *player.Player, item *object.ItemDef, craft *object.CraftDef, actionType, displayVerb, startMsg, endMsg string, count int) { g.cancelAction(p) g.cancelBgAction(p) - skill := recipe.EffectiveSkill() + skill := craft.EffectiveSkill() if skill != "" { skillLevel := p.Level(player.SkillName(skill)) - if skillLevel < recipe.Level { - sess.WriteLine(fmt.Sprintf("You need level %d %s to do that.", recipe.Level, skill)) + if skillLevel < craft.Level { + sess.WriteLine(fmt.Sprintf("You need level %d %s to do that.", craft.Level, skill)) g.reprompt(sess) return } } - if !recipe.HasAllItemsQty(p.CountItem) { + if !craftHasAllItemsQty(craft, p.CountItem) { sess.WriteLine("You don't have the required materials.") g.reprompt(sess) return } - outDef, _ := g.ItemStore.Load(recipe.Output) + outDef, _ := g.ItemStore.Load(item.ID) - wait := recipe.Wait + wait := craft.Wait if wait <= 0 { wait = 4 } - outputName := recipe.Output + outputName := item.ID if outDef != nil { outputName = outDef.Name } p.Action = &action.Action{ Type: actionType, - TargetID: recipe.ID, + TargetID: item.ID, TargetName: outputName, Data: map[string]any{ - "recipe_id": recipe.ID, + "item_id": item.ID, "phase": 0, "wait": wait, "start_msg": startMsg, @@ -68,13 +82,18 @@ func (g *Game) startProduction(sess *net.Session, p *player.Player, recipe *acti g.broadcastAction(sess, "\n%s starts %s.", p.Name, displayVerb) } -func (g *Game) startProductionFromRecipe(sess *net.Session, p *player.Player, recipe *action.RecipeDef, count int) { - _, stationName := g.findStation(p.RoomID, recipe.Station) +func (g *Game) startProductionFromItem(sess *net.Session, p *player.Player, item *object.ItemDef, count int) { + craft := item.FirstCraft() + if craft == nil { + return + } + + _, stationName := g.findStation(p.RoomID, craft.Station) if stationName == "" { stationName = "inventory" } - firstItem := recipe.FirstItemName(func(id string) (string, bool) { + firstItem := craftFirstItemName(craft, func(id string) (string, bool) { def, err := g.ItemStore.Load(id) if err != nil { return id, false @@ -82,9 +101,9 @@ func (g *Game) startProductionFromRecipe(sess *net.Session, p *player.Player, re return def.Name, true }) - info, ok := productionTypes[recipe.Type] + info, ok := productionTypes[craft.Type] if !ok { - info = productionTypeInfo{recipe.Type, recipe.Type} + info = productionTypeInfo{craft.Type, craft.Type} } actionType := info.ActionType displayVerb := info.DisplayVerb @@ -97,67 +116,79 @@ func (g *Game) startProductionFromRecipe(sess *net.Session, p *player.Player, re } endMsg = fmt.Sprintf("You've finished %s.", displayVerb) - g.startProduction(sess, p, recipe, actionType, displayVerb, startMsg, endMsg, count) + g.startProduction(sess, p, item, craft, actionType, displayVerb, startMsg, endMsg, count) } -func (g *Game) loadRecipe(recipeID string) *action.RecipeDef { - if r := g.RecipeStore.GetByID(recipeID); r != nil { - return r +func (g *Game) loadCraftItem(itemID string) *object.ItemDef { + item, err := g.ItemStore.Load(itemID) + if err != nil || len(item.Craft) == 0 { + return nil } - if strings.HasPrefix(recipeID, "combine_") { - itemID := strings.TrimPrefix(recipeID, "combine_") - if itemDef, err := g.ItemStore.Load(itemID); err == nil && len(itemDef.MadeFrom) > 0 { - return g.buildCombineRecipe(itemDef) - } - } - return nil + return item } func (g *Game) advanceProduction(sess *net.Session, p *player.Player) bool { - recipeID := p.Action.Data["recipe_id"].(string) + itemID := p.Action.Data["item_id"].(string) phase := p.Action.Data["phase"].(int) wait := p.Action.Data["wait"].(float64) startMsg, _ := p.Action.Data["start_msg"].(string) endMsg, _ := p.Action.Data["end_msg"].(string) remaining, _ := p.Action.Data["remaining"].(int) - recipe := g.loadRecipe(recipeID) - if recipe == nil { + item := g.loadCraftItem(itemID) + if item == nil { g.cancelAction(p) return false } + craft := item.FirstCraft() if phase == 0 { if startMsg != "" { sess.WriteLine(fmt.Sprintf("\n%s", startMsg)) } + if len(craft.Steps) > 0 { + p.Action.Data["next_step_index"] = 0 + p.Action.Data["steps_accumulated_ticks"] = float64(0) + } p.Action.Data["phase"] = 1 p.Action.WaitLeft = engine.ToTicks(wait) return true } - skill := recipe.EffectiveSkill() + if stepsIdx, ok := p.Action.Data["next_step_index"].(int); ok && stepsIdx < len(craft.Steps) { + accTicks, _ := p.Action.Data["steps_accumulated_ticks"].(float64) + accTicks += wait + p.Action.Data["steps_accumulated_ticks"] = accTicks + for i := stepsIdx; i < len(craft.Steps); i++ { + if accTicks >= craft.Steps[i].Tick { + sess.WriteLine(craft.Steps[i].Message) + p.Action.Data["next_step_index"] = i + 1 + } + } + } + + skill := craft.EffectiveSkill() skillLevel := p.Level(player.SkillName(skill)) chance := 1.0 - if recipe.Success != nil { - chance = action.SuccessChance(*recipe.Success, skillLevel, recipe.Level) + if craft.Success != nil { + chance = action.SuccessChance(action.SuccessFormula(*craft.Success), skillLevel, craft.Level) } if rand.Float64() < chance { - outputQty := recipe.OutputQty + outputQty := craft.OutputQty if outputQty <= 0 { outputQty = 1 } - byproducts := g.collectByproducts(p, recipe) + byproducts := g.collectByproducts(p, item) placed := false - outDef, _ := g.ItemStore.Load(recipe.Output) + outDef, _ := g.ItemStore.Load(item.ID) if outDef != nil && outDef.Stackable { for i := 0; i < 28; i++ { slot := p.InvSlot(i) - if slot != nil && slot.ItemID == recipe.Output { - recipe.ConsumeAll(p.HasItem, p.RemoveItem) + if slot != nil && slot.ItemID == item.ID { + craftConsumeAll(craft, p.HasItem, p.RemoveItem) slot.Quantity += outputQty placed = true break @@ -165,14 +196,14 @@ func (g *Game) advanceProduction(sess *net.Session, p *player.Player) bool { } } if !placed { - recipe.ConsumeAll(p.HasItem, p.RemoveItem) + craftConsumeAll(craft, p.HasItem, p.RemoveItem) freeSlot := p.FirstFreeSlot() if freeSlot == -1 { sess.WriteLine("Your inventory is too full!") g.cancelAction(p) return false } - p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: recipe.Output, Quantity: outputQty}) + p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: item.ID, Quantity: outputQty}) } for _, bp := range byproducts { @@ -181,38 +212,38 @@ func (g *Game) advanceProduction(sess *net.Session, p *player.Player) bool { } } - if recipe.XP > 0 { - if newLevel := p.AddSkillXP(player.SkillName(skill), recipe.XP); newLevel > 0 { + if craft.XP > 0 { + if newLevel := p.AddSkillXP(player.SkillName(skill), craft.XP); newLevel > 0 { sess.WriteLine(g.colorize(sess, "level_up", fmt.Sprintf("*** You are now level %d %s! ***", newLevel, skill))) } } g.AccountStore.SaveCharacter(p) - msg := recipe.Message + msg := craft.Message if msg == "" { - outputName := recipe.Output + outputName := item.ID if outDef != nil { outputName = outDef.Name } msg = fmt.Sprintf("You produce %s.", outputName) } - if p.OptionBool("xp_drops") && recipe.XP > 0 { + if p.OptionBool("xp_drops") && craft.XP > 0 { abbr := player.SkillAbbr[player.SkillName(skill)] - msg += g.colorize(sess, "xp", fmt.Sprintf(" (+%dxp %s)", recipe.XP, abbr)) + msg += g.colorize(sess, "xp", fmt.Sprintf(" (+%dxp %s)", craft.XP, abbr)) } sess.WriteLine(msg) } else { - recipe.ConsumeAll(p.HasItem, p.RemoveItem) + craftConsumeAll(craft, p.HasItem, p.RemoveItem) - if recipe.Fail != "" { + if craft.Fail != "" { freeSlot := p.FirstFreeSlot() if freeSlot >= 0 { - p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: recipe.Fail, Quantity: 1}) + p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: craft.Fail, Quantity: 1}) } } g.AccountStore.SaveCharacter(p) - msg := recipe.FailMessage + msg := craft.FailMessage if msg == "" { msg = "You fail and the materials are lost." } @@ -231,7 +262,7 @@ func (g *Game) advanceProduction(sess *net.Session, p *player.Player) bool { } } - if g.canContinueProduction(p, recipe) { + if g.canContinueProduction(p, item) { p.Action.WaitLeft = engine.ToTicks(wait) return true } @@ -243,9 +274,13 @@ func (g *Game) advanceProduction(sess *net.Session, p *player.Player) bool { return false } -func (g *Game) collectByproducts(p *player.Player, recipe *action.RecipeDef) []string { +func (g *Game) collectByproducts(p *player.Player, item *object.ItemDef) []string { + craft := item.FirstCraft() + if craft == nil { + return nil + } var byproducts []string - for _, e := range recipe.Consume { + for _, e := range craft.Consume { if len(e.Byproducts) == 0 { continue } @@ -259,19 +294,23 @@ func (g *Game) collectByproducts(p *player.Player, recipe *action.RecipeDef) []s return byproducts } -func (g *Game) canContinueProduction(p *player.Player, recipe *action.RecipeDef) bool { - if !recipe.HasAllItemsQty(p.CountItem) { +func (g *Game) canContinueProduction(p *player.Player, item *object.ItemDef) bool { + craft := item.FirstCraft() + if craft == nil { return false } - outputQty := recipe.OutputQty + if !craftHasAllItemsQty(craft, p.CountItem) { + return false + } + outputQty := craft.OutputQty if outputQty <= 0 { outputQty = 1 } - outDef, _ := g.ItemStore.Load(recipe.Output) + outDef, _ := g.ItemStore.Load(item.ID) if outDef != nil && outDef.Stackable { for i := 0; i < 28; i++ { slot := p.InvSlot(i) - if slot != nil && slot.ItemID == recipe.Output { + if slot != nil && slot.ItemID == item.ID { return true } } @@ -316,7 +355,7 @@ func (g *Game) handleRecipeChoice(sess *net.Session, input string) { if name == "" { continue } - if strings.ToLower(name) == lower || action.WordPrefixMatch(input, name) { + if strings.ToLower(name) == lower || object.WordPrefixMatch(input, name) { if matchIdx >= 0 { sess.WriteLine("That's ambiguous.") return @@ -338,21 +377,11 @@ func (g *Game) handleRecipeChoice(sess *net.Session, input string) { } func (g *Game) menuEntryName(entry map[string]string) string { - if rid, ok := entry["recipe_id"]; ok { - if r := g.RecipeStore.GetByID(rid); r != nil { - if def, err := g.ItemStore.Load(r.Output); err == nil { - return def.Name - } - return r.Output - } - } - if rid, ok := entry["fletch_recipe_id"]; ok { - if r := g.RecipeStore.GetByID(rid); r != nil { - if def, err := g.ItemStore.Load(r.Output); err == nil { - return def.Name - } - return r.Output + if iid, ok := entry["item_id"]; ok { + if def, _ := g.ItemStore.Load(iid); def != nil { + return def.Name } + return iid } if barID, ok := entry["bar_id"]; ok { if def, _ := g.ItemStore.Load(barID); def != nil { @@ -360,51 +389,34 @@ func (g *Game) menuEntryName(entry map[string]string) string { } return barID } - if cid, ok := entry["combine_item"]; ok { - if def, _ := g.ItemStore.Load(cid); def != nil { - return def.Name - } - return cid - } return "" } func (g *Game) dispatchMenuEntry(sess *net.Session, entry map[string]string) { - if cid, ok := entry["combine_item"]; ok { - g.promptHowMany(sess, "combine_"+cid) + if iid, ok := entry["item_id"]; ok { + g.promptHowMany(sess, iid) return } if barID, ok := entry["bar_id"]; ok { - p := sess.Player - allRecipes, _ := g.RecipeStore.LoadAll() - g.showSmithTable(sess, p, barID, allRecipes) - return - } - if rid, ok := entry["fletch_recipe_id"]; ok { - p := sess.Player - if r := g.RecipeStore.GetByID(rid); r != nil { - g.startFletchAction(sess, p, r, 0) - return - } - g.reprompt(sess) - return - } - if rid, ok := entry["recipe_id"]; ok { - g.promptHowMany(sess, rid) + g.showSmithTable(sess, sess.Player, barID) return } g.reprompt(sess) } -func (g *Game) formatMaterials(r *action.RecipeDef) string { +func (g *Game) formatMaterials(item *object.ItemDef) string { + craft := item.FirstCraft() + if craft == nil { + return "" + } var parts []string - for _, e := range r.Consume { + for _, e := range craft.Consume { itemName := e.Items[0] if def, err := g.ItemStore.Load(e.Items[0]); err == nil { itemName = def.Name } - if e.Quantity > 1 { - parts = append(parts, fmt.Sprintf("%s x%d", itemName, e.Quantity)) + if e.Quantity > 1 { + parts = append(parts, fmt.Sprintf("%s x%d", itemName, e.Quantity)) } else { parts = append(parts, itemName) } @@ -412,9 +424,9 @@ func (g *Game) formatMaterials(r *action.RecipeDef) string { return strings.Join(parts, ", ") } -func (g *Game) showProductionTable(sess *net.Session, p *player.Player, recipes []action.RecipeDef, title, skill, lastFlagKey, promptVerb string, background bool) { - sort.Slice(recipes, func(i, j int) bool { - return recipes[i].Level < recipes[j].Level +func (g *Game) showProductionTable(sess *net.Session, p *player.Player, items []*object.ItemDef, title, skill, lastFlagKey, promptVerb string, background bool) { + sort.Slice(items, func(i, j int) bool { + return items[i].FirstCraft().Level < items[j].FirstCraft().Level }) mode := g.colorMode(sess) @@ -426,14 +438,15 @@ func (g *Game) showProductionTable(sess *net.Session, p *player.Player, recipes Columns: []string{"#", "Product", "Materials", "Level"}, } - for i, r := range recipes { - outDef, _ := g.ItemStore.Load(r.Output) - productName := r.Output + for i, item := range items { + craft := item.FirstCraft() + outDef, _ := g.ItemStore.Load(item.ID) + productName := item.ID if outDef != nil { productName = outDef.Name } - outputQty := r.OutputQty + outputQty := craft.OutputQty if outputQty <= 0 { outputQty = 1 } @@ -441,11 +454,11 @@ func (g *Game) showProductionTable(sess *net.Session, p *player.Player, recipes productName = fmt.Sprintf("%s x%d", productName, outputQty) } - matStr := g.formatMaterials(&r) - levelStr := fmt.Sprint(r.Level) + matStr := g.formatMaterials(item) + levelStr := fmt.Sprint(craft.Level) numStr := fmt.Sprintf("%d", i+1) - canMake := skillLevel >= r.Level && r.HasAllItemsQty(p.CountItem) + canMake := skillLevel >= craft.Level && craftHasAllItemsQty(craft, p.CountItem) if canMake { productName = g.itemColorize(sess, outDef, productName) } else { @@ -464,12 +477,12 @@ func (g *Game) showProductionTable(sess *net.Session, p *player.Player, recipes sess.WriteLine(line) } - lastRecipeID, _ := p.Flags[lastFlagKey].(string) + lastItemID, _ := p.Flags[lastFlagKey].(string) hint := "" - if lastRecipeID != "" { - for _, r := range recipes { - if r.ID == lastRecipeID { - if outDef, err := g.ItemStore.Load(r.Output); err == nil { + if lastItemID != "" { + for _, item := range items { + if item.ID == lastItemID { + if outDef, err := g.ItemStore.Load(item.ID); err == nil { hint = outDef.Name } break @@ -483,7 +496,7 @@ func (g *Game) showProductionTable(sess *net.Session, p *player.Player, recipes sess.Write(fmt.Sprintf("%s what: ", promptVerb)) } - sess.PendingMenu = recipeMenuData(recipeDefIDs(recipes)) + sess.PendingMenu = itemMenuData(itemIDs(items)) sess.PendingSkill = skill sess.PendingLastFlag = lastFlagKey sess.PendingBackground = background @@ -504,26 +517,26 @@ func (g *Game) handleProductChoice(sess *net.Session, input string) { input = strings.TrimSpace(input) - var recipes []action.RecipeDef + var items []*object.ItemDef for _, entry := range menuData { - rid := entry["recipe_id"] - if r := g.RecipeStore.GetByID(rid); r != nil { - recipes = append(recipes, *r) + iid := entry["item_id"] + if item := g.loadCraftItem(iid); item != nil { + items = append(items, item) } } - if len(recipes) == 0 { + if len(items) == 0 { g.reprompt(sess) return } - sort.Slice(recipes, func(i, j int) bool { - return recipes[i].Level < recipes[j].Level + sort.Slice(items, func(i, j int) bool { + return items[i].FirstCraft().Level < items[j].FirstCraft().Level }) - lastRecipeID, _ := p.Flags[lastFlagKey].(string) + lastItemID, _ := p.Flags[lastFlagKey].(string) - sel, errMsg := g.resolveRecipeByInput(input, recipes, lastRecipeID) + sel, errMsg := g.resolveCraftByInput(input, items, lastItemID) switch errMsg { case "ambiguous": sess.WriteLine("That's ambiguous.") @@ -535,26 +548,27 @@ func (g *Game) handleProductChoice(sess *net.Session, input string) { return } + craft := sel.Item.FirstCraft() skillLevel := p.Level(player.SkillName(skill)) - if skillLevel < sel.Recipe.Level { - sess.WriteLine(fmt.Sprintf("You need level %d %s to make that.", sel.Recipe.Level, skill)) + if skillLevel < craft.Level { + sess.WriteLine(fmt.Sprintf("You need level %d %s to make that.", craft.Level, skill)) g.reprompt(sess) return } - if !sel.Recipe.HasAllItemsQty(p.CountItem) { + if !craftHasAllItemsQty(craft, p.CountItem) { sess.WriteLine("You don't have the materials for that.") g.reprompt(sess) return } p.EnsureFlags() - p.Flags[lastFlagKey] = sel.Recipe.ID + p.Flags[lastFlagKey] = sel.Item.ID g.AccountStore.SaveCharacter(p) if background { - g.startFletchAction(sess, p, sel.Recipe, sel.Count) + g.startFletchAction(sess, p, sel.Item, sel.Count) } else { - g.startProductionFromRecipe(sess, p, sel.Recipe, sel.Count) + g.startProductionFromItem(sess, p, sel.Item, sel.Count) } } @@ -591,10 +605,6 @@ func (g *Game) hasToolType(p *player.Player, toolType string) bool { _, _, found := g.findTool(p, []string{toolType}) return found } -type recipeEntry struct { - ItemName string - Recipe action.RecipeDef -} type productionTypeInfo struct { ActionType string @@ -621,15 +631,15 @@ func init() { } } -func recipeMenuData(recipeIDs []string) []map[string]string { - out := make([]map[string]string, len(recipeIDs)) - for i, id := range recipeIDs { - out[i] = map[string]string{"recipe_id": id} +func itemMenuData(itemIDs []string) []map[string]string { + out := make([]map[string]string, len(itemIDs)) + for i, id := range itemIDs { + out[i] = map[string]string{"item_id": id} } return out } -func recipeDefIDs(defs []action.RecipeDef) []string { +func itemIDs(defs []*object.ItemDef) []string { ids := make([]string, len(defs)) for i, d := range defs { ids[i] = d.ID @@ -637,33 +647,25 @@ func recipeDefIDs(defs []action.RecipeDef) []string { return ids } -func entryMenuData(entries []recipeEntry) []map[string]string { - out := make([]map[string]string, len(entries)) - for i, e := range entries { - out[i] = map[string]string{"recipe_id": e.Recipe.ID} - } - return out -} - -func (g *Game) promptHowMany(sess *net.Session, recipeID string) { - sess.PendingRecipeID = recipeID +func (g *Game) promptHowMany(sess *net.Session, itemID string) { + sess.PendingItemID = itemID sess.State = net.StateHowMany sess.Write("How many (return for all)?: ") } -type recipeSelection struct { - Recipe *action.RecipeDef - Count int +type craftSelection struct { + Item *object.ItemDef + Count int } -func (g *Game) resolveRecipeByInput(input string, recipes []action.RecipeDef, lastRecipeID string) (sel recipeSelection, errMsg string) { +func (g *Game) resolveCraftByInput(input string, items []*object.ItemDef, lastItemID string) (sel craftSelection, errMsg string) { if input == "" { - if lastRecipeID == "" { + if lastItemID == "" { return sel, "never_mind" } - for i := range recipes { - if recipes[i].ID == lastRecipeID { - sel.Recipe = &recipes[i] + for i := range items { + if items[i].ID == lastItemID { + sel.Item = items[i] return sel, "" } } @@ -673,22 +675,22 @@ func (g *Game) resolveRecipeByInput(input string, recipes []action.RecipeDef, la qty, productName := parseQty(input) productName = strings.TrimSpace(productName) - if idx, err := strconv.Atoi(productName); err == nil && idx > 0 && idx <= len(recipes) { - sel.Recipe = &recipes[idx-1] + if idx, err := strconv.Atoi(productName); err == nil && idx > 0 && idx <= len(items) { + sel.Item = items[idx-1] sel.Count = qty return sel, "" } matchCount := 0 - for i := range recipes { - outDef, _ := g.ItemStore.Load(recipes[i].Output) - name := recipes[i].Output + for i := range items { + outDef, _ := g.ItemStore.Load(items[i].ID) + name := items[i].ID if outDef != nil { name = outDef.Name } - if action.WordPrefixMatch(productName, name) { + if object.WordPrefixMatch(productName, name) { if matchCount == 0 { - sel.Recipe = &recipes[i] + sel.Item = items[i] sel.Count = qty } matchCount++ @@ -697,7 +699,7 @@ func (g *Game) resolveRecipeByInput(input string, recipes []action.RecipeDef, la if matchCount > 1 { return sel, "ambiguous" } - if sel.Recipe == nil { + if sel.Item == nil { return sel, "never_mind" } return sel, "" @@ -716,41 +718,42 @@ func (g *Game) showMenuTable(sess *net.Session, title string, names []string) { } } -func (g *Game) recipeName(sess *net.Session, r *action.RecipeDef) string { - if r.Output != "" { - if def, err := g.ItemStore.Load(r.Output); err == nil { +func (g *Game) itemName(sess *net.Session, item *object.ItemDef) string { + if item != nil { + if def, err := g.ItemStore.Load(item.ID); err == nil { return g.itemColorize(sess, def, def.Name) } + return item.ID } - return r.DisplayName() + return "" } -func (g *Game) showRecipeChoice(sess *net.Session, p *player.Player, recipes []action.RecipeDef, emptyMsg, title string, autoOption string) { - if len(recipes) == 0 { +func (g *Game) showRecipeChoice(sess *net.Session, p *player.Player, items []*object.ItemDef, emptyMsg, title string, autoOption string) { + if len(items) == 0 { sess.WriteLine(emptyMsg) return } - if len(recipes) == 1 { + if len(items) == 1 { if autoOption != "" && p.OptionBool(autoOption) { - g.startProductionFromRecipe(sess, p, &recipes[0], 0) + g.startProductionFromItem(sess, p, items[0], 0) return } - g.promptHowMany(sess, recipes[0].ID) + g.promptHowMany(sess, items[0].ID) return } sess.State = net.StateRecipeChoice - sess.PendingMenu = recipeMenuData(recipeDefIDs(recipes)) + sess.PendingMenu = itemMenuData(itemIDs(items)) var names []string - for i := range recipes { - names = append(names, g.recipeName(sess, &recipes[i])) + for _, item := range items { + names = append(names, g.itemName(sess, item)) } g.showMenuTable(sess, title, names) } func (g *Game) handleHowMany(sess *net.Session, input string) { p := sess.Player - recipeID := sess.PendingRecipeID - sess.PendingRecipeID = "" + itemID := sess.PendingItemID + sess.PendingItemID = "" sess.State = net.StateGame input = strings.TrimSpace(input) @@ -766,46 +769,11 @@ func (g *Game) handleHowMany(sess *net.Session, input string) { return } - var recipe *action.RecipeDef - if strings.HasPrefix(recipeID, "combine_") { - itemID := strings.TrimPrefix(recipeID, "combine_") - itemDef, err := g.ItemStore.Load(itemID) - if err != nil || len(itemDef.MadeFrom) == 0 { - g.reprompt(sess) - return - } - recipe = g.buildCombineRecipe(itemDef) - } else { - recipe = g.RecipeStore.GetByID(recipeID) - } - - if recipe == nil { + item := g.loadCraftItem(itemID) + if item == nil { g.reprompt(sess) return } - g.startProductionFromRecipe(sess, p, recipe, count) -} - -func (g *Game) buildCombineRecipe(def *object.ItemDef) *action.RecipeDef { - var consume []action.ConsumeEntry - for _, mf := range def.MadeFrom { - consume = append(consume, action.ConsumeEntry{ - Items: mf.Items, - Quantity: mf.Quantity, - Byproducts: mf.Byproducts, - }) - } - wait := def.Ticks - if wait <= 0 { - wait = 2 - } - return &action.RecipeDef{ - ID: "combine_" + def.ID, - Type: "combine", - Wait: wait, - Consume: consume, - Output: def.ID, - Message: fmt.Sprintf("You create %s.", def.Name), - } + g.startProductionFromItem(sess, p, item, count) } diff --git a/internal/game/core_startup.go b/internal/game/core_startup.go index ef33ff7..4bdb50d 100644 --- a/internal/game/core_startup.go +++ b/internal/game/core_startup.go @@ -25,7 +25,6 @@ func (g *Game) ValidateStartup() []StartupIssue { issues = append(issues, validateIDs(g.DataDir, "mobs", "mob")...) issues = append(issues, validateIDs(g.DataDir, "objects", "object")...) issues = append(issues, validateIDs(g.DataDir, "drops", "drop table")...) - issues = append(issues, validateIDs(g.DataDir, "recipes", "recipe")...) issues = append(issues, validateIDs(g.DataDir, "courses", "course")...) issues = append(issues, validateIDs(g.DataDir, "modules", "module")...) issues = append(issues, validateIDs(g.DataDir, "help", "help topic")...) @@ -34,7 +33,7 @@ func (g *Game) ValidateStartup() []StartupIssue { issues = append(issues, validateMobs(g)...) issues = append(issues, validateObjects(g)...) issues = append(issues, validateItems(g)...) - issues = append(issues, validateRecipes(g)...) + issues = append(issues, validateCraftBlocks(g)...) issues = append(issues, validateDropTables(g)...) issues = append(issues, validateCourses(g)...) issues = append(issues, validateRoomWiring(g)...) @@ -368,29 +367,6 @@ func validateItems(g *Game) []StartupIssue { }) } - for _, mf := range def.MadeFrom { - for _, item := range mf.Items { - if item != "" && !itemIDs[item] { - issues = append(issues, StartupIssue{ - Level: "ERROR", - Type: "reference", - Message: fmt.Sprintf("Item %q: made_from item %q does not exist", - id, item), - }) - } - } - for _, bp := range mf.Byproducts { - if bp != "" && !itemIDs[bp] { - issues = append(issues, StartupIssue{ - Level: "ERROR", - Type: "reference", - Message: fmt.Sprintf("Item %q: made_from byproduct %q does not exist", - id, bp), - }) - } - } - } - if def.FarmProduct != "" && !itemIDs[def.FarmProduct] { issues = append(issues, StartupIssue{ Level: "ERROR", @@ -404,64 +380,61 @@ func validateItems(g *Game) []StartupIssue { return issues } -func validateRecipes(g *Game) []StartupIssue { +func validateCraftBlocks(g *Game) []StartupIssue { var issues []StartupIssue itemIDs := g.ItemStore.IDSet() + objIDs := g.ObjectStore.IDSet() - allRecipes, err := g.RecipeStore.LoadAll() + allItems, err := g.ItemStore.LoadAll() if err != nil { issues = append(issues, StartupIssue{ Level: "ERROR", Type: "reference", - Message: fmt.Sprintf("Failed to load recipes: %v", err), + Message: fmt.Sprintf("Failed to load items: %v", err), }) return issues } - recipeIDs := make(map[string]bool) - for _, r := range allRecipes { - if r.ID != "" { - if recipeIDs[r.ID] { + for _, item := range allItems { + if len(item.Craft) == 0 { + continue + } + for ci := range item.Craft { + c := &item.Craft[ci] + + for _, e := range c.Consume { + for _, consumeItem := range e.Items { + if consumeItem != "" && !itemIDs[consumeItem] { + issues = append(issues, StartupIssue{ + Level: "ERROR", + Type: "reference", + Message: fmt.Sprintf("Item %q (craft: %s): consumes nonexistent item %q", + item.ID, c.Type, consumeItem), + }) + } + } + } + + if c.Fail != "" && !itemIDs[c.Fail] { issues = append(issues, StartupIssue{ Level: "ERROR", - Type: "duplicate", - Message: fmt.Sprintf("Recipe %q: duplicate ID field (two recipe files with same ID value)", - r.ID), + Type: "reference", + Message: fmt.Sprintf("Item %q (craft: %s): fail product %q does not exist", + item.ID, c.Type, c.Fail), }) } - recipeIDs[r.ID] = true - } - for _, e := range r.Consume { - for _, item := range e.Items { - if item != "" && !itemIDs[item] { + for _, sid := range c.Station { + if sid != "" && !objIDs[sid] { issues = append(issues, StartupIssue{ Level: "ERROR", Type: "reference", - Message: fmt.Sprintf("Recipe %q (%s): consumes nonexistent item %q", - r.ID, r.Type, item), + Message: fmt.Sprintf("Item %q (craft: %s): station object %q does not exist", + item.ID, c.Type, sid), }) } } } - - if r.Output != "" && !itemIDs[r.Output] { - issues = append(issues, StartupIssue{ - Level: "ERROR", - Type: "reference", - Message: fmt.Sprintf("Recipe %q (%s): output item %q does not exist", - r.ID, r.Type, r.Output), - }) - } - - if r.Fail != "" && !itemIDs[r.Fail] { - issues = append(issues, StartupIssue{ - Level: "ERROR", - Type: "reference", - Message: fmt.Sprintf("Recipe %q (%s): fail product %q does not exist", - r.ID, r.Type, r.Fail), - }) - } } return issues @@ -778,4 +751,4 @@ func LogStartupIssues(issues []StartupIssue) { if errors > 0 { fmt.Fprintf(os.Stderr, "*** %d startup errors detected. The server may behave unexpectedly. ***\n", errors) } -}
\ No newline at end of file +} diff --git a/internal/game/craft_index.go b/internal/game/craft_index.go new file mode 100644 index 0000000..078ec3c --- /dev/null +++ b/internal/game/craft_index.go @@ -0,0 +1,234 @@ +package game + +import ( + "sync" + + "thehouseoficarus/internal/object" +) + +type CraftIndex struct { + mu sync.RWMutex + byType map[string][]*object.ItemDef + byInput map[string][]*object.ItemDef + byStation map[string][]*object.ItemDef +} + +func NewCraftIndex() *CraftIndex { + return &CraftIndex{ + byType: make(map[string][]*object.ItemDef), + byInput: make(map[string][]*object.ItemDef), + byStation: make(map[string][]*object.ItemDef), + } +} + +func (idx *CraftIndex) Build(items []*object.ItemDef) { + idx.mu.Lock() + defer idx.mu.Unlock() + + idx.byType = make(map[string][]*object.ItemDef) + idx.byInput = make(map[string][]*object.ItemDef) + idx.byStation = make(map[string][]*object.ItemDef) + + for _, def := range items { + if len(def.Craft) == 0 { + continue + } + for ci := range def.Craft { + craft := &def.Craft[ci] + t := craft.Type + if t == "" { + t = "combine" + } + idx.byType[t] = appendUnique(idx.byType[t], def) + + for _, e := range craft.Consume { + for _, id := range e.Items { + idx.byInput[id] = appendUnique(idx.byInput[id], def) + } + } + + for _, sid := range craft.Station { + idx.byStation[sid] = appendUnique(idx.byStation[sid], def) + } + } + } +} + +func appendUnique(items []*object.ItemDef, item *object.ItemDef) []*object.ItemDef { + for _, existing := range items { + if existing == item { + return items + } + } + return append(items, item) +} + +func (idx *CraftIndex) ByType(craftType string) []*object.ItemDef { + idx.mu.RLock() + defer idx.mu.RUnlock() + items := idx.byType[craftType] + out := make([]*object.ItemDef, len(items)) + copy(out, items) + return out +} + +func (idx *CraftIndex) ByStation(stationDefID string) []*object.ItemDef { + idx.mu.RLock() + defer idx.mu.RUnlock() + items := idx.byStation[stationDefID] + out := make([]*object.ItemDef, len(items)) + copy(out, items) + return out +} + +func (idx *CraftIndex) ByInput(itemID string) []*object.ItemDef { + idx.mu.RLock() + defer idx.mu.RUnlock() + items := idx.byInput[itemID] + out := make([]*object.ItemDef, len(items)) + copy(out, items) + return out +} + +func (idx *CraftIndex) FindByTwoInputs(itemA, itemB string) []*object.ItemDef { + idx.mu.RLock() + defer idx.mu.RUnlock() + + candidatesA := idx.byInput[itemA] + if len(candidatesA) == 0 { + return nil + } + + candidateSetB := make(map[string]bool) + for _, def := range idx.byInput[itemB] { + candidateSetB[def.ID] = true + } + + var results []*object.ItemDef + for _, def := range candidatesA { + if !candidateSetB[def.ID] { + continue + } + for _, craft := range def.Craft { + entryA := craftEntry(craft, itemA) + entryB := craftEntry(craft, itemB) + if entryA >= 0 && entryB >= 0 && entryA != entryB { + results = append(results, def) + break + } + } + } + return results +} + +func (idx *CraftIndex) FindByStationInput(stationDefID, itemID string) []*object.ItemDef { + idx.mu.RLock() + defer idx.mu.RUnlock() + + var results []*object.ItemDef + for _, def := range idx.byStation[stationDefID] { + for _, craft := range def.Craft { + if craftMatchesEntry(&craft, itemID) { + results = append(results, def) + break + } + } + } + return results +} + +func craftEntryFor(def *object.ItemDef, itemID string) int { + for _, craft := range def.Craft { + if ei := craftEntry(craft, itemID); ei >= 0 { + return ei + } + } + return -1 +} + +func craftEntry(craft object.CraftDef, itemID string) int { + for ei, e := range craft.Consume { + for _, id := range e.Items { + if id == itemID { + return ei + } + } + } + return -1 +} + +func craftMatchesEntry(c *object.CraftDef, itemID string) bool { + if c == nil { + return false + } + for _, e := range c.Consume { + for _, id := range e.Items { + if id == itemID { + return true + } + } + } + return false +} + +func craftHasAllItems(c *object.CraftDef, hasItem func(string) bool) bool { + if c == nil { + return false + } + for _, e := range c.Consume { + found := false + for _, id := range e.Items { + if hasItem(id) { + found = true + break + } + } + if !found { + return false + } + } + return true +} + +func craftHasAllItemsQty(c *object.CraftDef, countItem func(string) int) bool { + if c == nil { + return false + } + for _, e := range c.Consume { + found := false + for _, id := range e.Items { + qty := e.Quantity + if qty <= 0 { + qty = 1 + } + if countItem(id) >= qty { + found = true + break + } + } + if !found { + return false + } + } + return true +} + +func craftConsumeAll(c *object.CraftDef, hasItem func(string) bool, removeItem func(string, int) bool) bool { + if c == nil { + return false + } + for _, e := range c.Consume { + found := false + for _, id := range e.Items { + if hasItem(id) { + removeItem(id, e.Quantity) + found = true + break + } + } + if !found { + return false + } + } + return true +} diff --git a/internal/game/game.go b/internal/game/game.go index ac8622e..0dd5bdc 100644 --- a/internal/game/game.go +++ b/internal/game/game.go @@ -7,7 +7,6 @@ import ( "sync" "time" - "thehouseoficarus/internal/action" "thehouseoficarus/internal/combat" "thehouseoficarus/internal/config" "thehouseoficarus/internal/engine" @@ -40,7 +39,7 @@ type Game struct { ItemStore *object.ItemStore AccountStore *player.AccountStore MobStore *world.MobStore - RecipeStore *action.RecipeStore + CraftIndex *CraftIndex CourseStore *CourseStore Hub *net.Hub Ticks *engine.Engine @@ -67,7 +66,7 @@ func New(dataDir string, colorConfig *config.ColorsConfig, valConfig config.Vali ItemStore: object.NewItemStore(dataDir), AccountStore: player.NewAccountStore(dataDir), MobStore: world.NewMobStore(dataDir), - RecipeStore: action.NewRecipeStore(dataDir), + CraftIndex: NewCraftIndex(), CourseStore: NewCourseStore(dataDir), Ticks: engine.New(), WorldFlags: make(map[string]any), @@ -85,6 +84,7 @@ func New(dataDir string, colorConfig *config.ColorsConfig, valConfig config.Vali } g.CourseStore.LoadAll() g.LoadMods() + g.buildCraftIndex() g.ValidateAndLog() return g } @@ -331,6 +331,14 @@ func (g *Game) ProcessQueuedCommands() { g.flushPendingDepletions() } +func (g *Game) buildCraftIndex() { + items, err := g.ItemStore.LoadAll() + if err != nil { + return + } + g.CraftIndex.Build(items) +} + type pendingDepletion struct { instanceKey string objDefID string diff --git a/internal/net/server.go b/internal/net/server.go index 6706a3a..eaa8f17 100644 --- a/internal/net/server.go +++ b/internal/net/server.go @@ -51,7 +51,7 @@ type Session struct { PendingChar string PendingPass string PendingMenu []map[string]string - PendingRecipeID string + PendingItemID string PendingSkill string PendingLastFlag string PendingBackground bool diff --git a/internal/object/item.go b/internal/object/item.go index 8ec1565..241cc0b 100644 --- a/internal/object/item.go +++ b/internal/object/item.go @@ -1,11 +1,33 @@ package object import ( + "fmt" "strings" - "thehouseoficarus/internal/action" + "gopkg.in/yaml.v3" ) +func WordPrefixMatch(input, name string) bool { + inputWords := strings.Fields(strings.ToLower(input)) + if len(inputWords) == 0 { + return false + } + nameWords := strings.Fields(strings.ToLower(name)) + for _, iw := range inputWords { + found := false + for _, nw := range nameWords { + if strings.HasPrefix(nw, iw) || strings.HasPrefix(iw, nw) { + found = true + break + } + } + if !found { + return false + } + } + return true +} + type EquipSlot string const ( @@ -56,8 +78,7 @@ type ItemDef struct { SearchMessage string `yaml:"search_message"` HealValue int `yaml:"heal_value"` EatMessage string `yaml:"eat_message"` - MadeFrom []MadeFromEntry `yaml:"made_from,omitempty"` - Ticks float64 `yaml:"ticks"` + Craft CraftList `yaml:"craft,omitempty"` ProvidesJunk string `yaml:"provides_junk,omitempty"` FarmPatchType string `yaml:"farm_patch_type"` FarmLevel int `yaml:"farm_level"` @@ -72,12 +93,90 @@ type ItemDef struct { PotionDuration float64 `yaml:"potion_duration"` } -type MadeFromEntry struct { +type CraftList []CraftDef + +func (cl *CraftList) UnmarshalYAML(value *yaml.Node) error { + switch value.Kind { + case yaml.SequenceNode: + return value.Decode((*[]CraftDef)(cl)) + case yaml.MappingNode: + var single CraftDef + if err := value.Decode(&single); err != nil { + return err + } + *cl = []CraftDef{single} + return nil + } + return fmt.Errorf("craft: expected mapping or sequence") +} + +func (d *ItemDef) FirstCraft() *CraftDef { + if len(d.Craft) == 0 { + return nil + } + return &d.Craft[0] +} + +func (d *ItemDef) FindCraft(fn func(CraftDef) bool) *CraftDef { + for i := range d.Craft { + if fn(d.Craft[i]) { + return &d.Craft[i] + } + } + return nil +} + +func (d *ItemDef) MatchingCrafts(fn func(CraftDef) bool) []*CraftDef { + var result []*CraftDef + for i := range d.Craft { + if fn(d.Craft[i]) { + result = append(result, &d.Craft[i]) + } + } + return result +} + +type ConsumeEntry struct { Items []string `yaml:"items"` Quantity int `yaml:"quantity"` Byproducts []string `yaml:"byproducts"` } +type CraftStep struct { + Tick float64 `yaml:"tick"` + Message string `yaml:"message"` +} + +type SuccessFormula struct { + Base float64 `yaml:"base"` + PerLevel float64 `yaml:"per_level"` + Cap float64 `yaml:"cap"` +} + +type CraftDef struct { + Type string `yaml:"type"` + Skill string `yaml:"skill"` + Level int `yaml:"level"` + XP int `yaml:"xp"` + Wait float64 `yaml:"wait"` + Station []string `yaml:"station"` + Tool string `yaml:"tool"` + Consume []ConsumeEntry `yaml:"consume"` + OutputQty int `yaml:"output_qty"` + Fail string `yaml:"fail"` + Message string `yaml:"message"` + FailMessage string `yaml:"fail_message"` + Steps []CraftStep `yaml:"steps"` + Success *SuccessFormula `yaml:"success"` +} + +func (c *CraftDef) EffectiveSkill() string { + if c.Skill != "" { + return c.Skill + } + return c.Type +} + type ItemStats struct { StabAttack int `yaml:"stab_attack"` SlashAttack int `yaml:"slash_attack"` @@ -105,5 +204,5 @@ func (d *ItemDef) MatchesName(input string) bool { if strings.ToLower(d.Name) == lower { return true } - return action.WordPrefixMatch(lower, d.Name) + return WordPrefixMatch(lower, d.Name) } diff --git a/internal/world/mob.go b/internal/world/mob.go index 9d07532..9ca1a45 100644 --- a/internal/world/mob.go +++ b/internal/world/mob.go @@ -9,6 +9,7 @@ import ( "sync" "thehouseoficarus/internal/action" + "thehouseoficarus/internal/object" "gopkg.in/yaml.v3" ) @@ -122,7 +123,7 @@ func (m *MobInstance) MatchQuality(input string) int { if strings.ToLower(m.Name) == lower { return MatchExact } - if action.WordPrefixMatch(input, m.Name) { + if object.WordPrefixMatch(input, m.Name) { return MatchPrefix } return MatchNone diff --git a/internal/world/objects.go b/internal/world/objects.go index 72e4a6d..ae2586a 100644 --- a/internal/world/objects.go +++ b/internal/world/objects.go @@ -6,7 +6,7 @@ import ( "sort" "strings" - "thehouseoficarus/internal/action" + "thehouseoficarus/internal/object" ) type ObjState struct { @@ -181,7 +181,7 @@ func (w *World) FindObjInstances(roomID int, name string) []ObjState { } func wordMatchesObj(lower, defID, objName string) bool { - if action.WordPrefixMatch(lower, objName) { + if object.WordPrefixMatch(lower, objName) { return true } inputWords := strings.Fields(strings.ToLower(lower)) diff --git a/worldbuilding_guide/recipes.md b/worldbuilding_guide/recipes.md index 335a6cc..e442c8c 100644 --- a/worldbuilding_guide/recipes.md +++ b/worldbuilding_guide/recipes.md @@ -1,36 +1,52 @@ # The House of Icarus - World Building Guide -## Recipes +## Crafting -Recipes define how items are processed on stations to produce new items. They are the foundation for cooking, smithing, crafting, and fletching. +Crafting information lives on the **output item's YAML file** via the `craft:` block. There is no separate recipe directory. To find out how to make `bronze_dagger`, open `data/items/equipment/bronze_dagger.yaml` and look for the `craft:` block. -Recipe files live in `data/recipes/<type>/<id>.yaml`. Two formats are supported: **individual** (one recipe per file) and **consolidated** (multiple related recipes per file). Consolidated format is preferred when many recipes share the same type, station, and materials (e.g., all bronze smithing products in one file). - -### Recipe vs MadeFrom - -- **Recipes** (`data/recipes/`) use a station (fire, range, furnace, anvil, etc.). The player must be near the station object. -- **MadeFrom** (on the item YAML directly) is for item-on-item combinations that need no station. The player combines ingredients from their inventory. - -### Recipe YAML Reference +### Craft YAML Reference | Field | Type | Description | | -------------- | -------------- | ----------------------------------------------- | -| `id` | string | Unique recipe identifier | -| `type` | string | Recipe type (cooking, smithing, crafting, etc.) | -| `skill` | string | Skill checked for success | +| `type` | string | Craft type (pharmacy, smithing, cooking, smelting, crafting, fletching, construction, clean, or "" for skill-less) | +| `skill` | string | Skill checked (defaults to type if omitted) | | `level` | int | Required skill level | | `xp` | int | XP awarded on success | -| `wait` | float64 | Ticks per craft cycle (default 6) | -| `station` | []string | Station object IDs required | +| `wait` | float64 | Ticks per craft cycle | +| `station` | []string | Station object IDs required (optional) | +| `tool` | string | Required tool_type (optional) | | `consume` | []ConsumeEntry | Ingredients consumed (see below) | -| `output` | string | ItemID produced on success | | `output_qty` | int | Quantity produced (default 1, for stackables) | | `fail` | string | ItemID produced on failure (optional) | | `message` | string | Success message | | `fail_message` | string | Failure message | +| `steps` | []CraftStep | Multi-step messages at tick intervals (optional)| | `success` | SuccessFormula | Optional skill check formula (see Behaviors) | -The recipe's name in menus comes from the output item's `name` field, colored using the output item's `color`. +The output is the item itself — no `output` field needed. The item ID IS the craft ID. + +### CraftStep — Multi-Step Messages + +Optional interim messages fired at specific tick offsets during the craft cycle. The `tick` is the number of ticks elapsed since the start of the cycle. + +```yaml +craft: + type: "" + wait: 6 + consume: + - items: [map_piece_1] + quantity: 1 + - items: [map_piece_2] + quantity: 1 + - items: [map_piece_3] + quantity: 1 + steps: + - tick: 1 + message: "You try to puzzle how the pieces fit together." + - tick: 3 + message: "Aha, this edge lines up here!" + message: "You assemble the map!" +``` ### ConsumeEntry — Multi-Item Ingredient Slots @@ -51,199 +67,153 @@ consume: quantity: 1 byproducts: [empty_bucket, ""] # bucket returns empty, vial is consumed entirely - items: [herb] - quantity: 1 # no byproducts — herb is consumed entirely + quantity: 1 # no byproducts — herb is consumed entirely ``` -### Consolidated Format - -For recipe categories where many recipes share the same `type`, `station`, and `wait` (e.g., smithing all bronze items from bronze bars, fletching all arrow shafts from logs), use a **consolidated** file. Shared fields are set once at the top level; each product entry provides only the fields that differ. - -**Loader behavior:** At load time, the loader expands each `products` entry into an individual `RecipeDef` with the same shape as the individual format. The production engine sees no difference — all lookup, matching, and execution code works identically. - -**Inheritance:** Child fields override parent. `consume` at the top level provides a default ingredient list; any product with different `consume` (e.g., a platebody needing 5 bars instead of 1) specifies its own. `output_qty`, `message`, `fail`, and `level` are per-product. +### Skill-Based Production ```yaml -# data/recipes/smithing/bronze.yaml — consolidated: 8 products in one file - -type: smithing # shared by all products -station: [anvil] # shared by all products -wait: 4 # shared by all products -consume: # default ingredient list — overridden per-product if needed - - items: [bronze_bar] - quantity: 1 - -products: - - id: smith_bronze_dagger - output: bronze_dagger - level: 1 - xp: 12 - # inherits consume: 1 bronze_bar from parent - - - id: smith_bronze_nails - output: bronze_nails - level: 4 - xp: 12 - output_qty: 15 # stackable output, 15 per cycle - - - id: smith_bronze_full_helm - output: bronze_full_helm - level: 7 - xp: 25 - consume: # overrides parent — 2 bars instead of 1 - - items: [bronze_bar] - quantity: 2 - - - id: smith_bronze_platebody - output: bronze_platebody - level: 18 - xp: 62 - consume: # overrides parent — 5 bars - - items: [bronze_bar] - quantity: 5 - - # ... dagger, sword, med_helm, arrowtips, bolts_unf ... +# data/items/consumables/stim_potion.yaml +craft: + type: pharmacy + skill: pharmacy + level: 3 + xp: 25 + wait: 4 + consume: + - items: [guam_potion_unf] + quantity: 1 + - items: [eye_of_newt] + quantity: 1 + message: "You mix a stim potion." ``` -**Use consolidated files when:** -- Many recipes share the same `type`, `station`, and `material` -- Adding a new tier means copy-pasting identical consume/station/wait fields -- The relationship between recipes is easier to understand as a group - -**Use individual files when:** -- The recipe is unique and doesn't share structure with others (e.g., compound smelting recipes with different ore ratios) -- You want fine-grained version control on a single recipe -- The recipe is complex enough that a consolidated file would be harder to read - -Individual and consolidated files coexist — the loader handles both transparently. - -### Station-based recipe (cooking on a fire) +### Station-Based Production ```yaml -id: cook_trout -type: cooking -skill: cooking -level: 15 -xp: 70 -wait: 6 -station: [fire, cooking_range] -consume: - - items: [raw_trout] - quantity: 1 -output: trout -fail: burnt_fish -message: "Cooked to perfection. It looks great!" -fail_message: "You accidentally burn the trout." +# data/items/materials/bronze_bar.yaml +craft: + type: smelting + skill: smithing + level: 1 + xp: 6 + wait: 4 + station: [furnace] + consume: + - items: [copper_ore] + quantity: 1 + - items: [tin_ore] + quantity: 1 + message: "You smelt a bronze bar." ``` -### Station-specific recipe (range only, not fire) - ```yaml -id: cook_bread -type: cooking -skill: cooking -level: 1 -xp: 40 -wait: 6 -station: [cooking_range] -consume: - - items: [bread_dough] - quantity: 1 -output: bread -fail: burnt_meat -message: "You bake the dough into a fresh loaf of bread." -fail_message: "You burn the bread to a crisp." +# data/items/equipment/bronze_dagger.yaml +craft: + type: smithing + skill: smithing + level: 1 + xp: 12 + wait: 4 + station: [anvil] + consume: + - items: [bronze_bar] + quantity: 1 + message: "You hammer out a bronze dagger." ``` -### Smelting recipe (ore to bar at a furnace) - -Smelting recipes use `type: smelting` and `station: [furnace]`. The `smelt` command or `use <ore> on furnace` triggers them. Multi-ore recipes use `qty` on consume entries. +For stackable outputs, use `output_qty`: ```yaml -id: smelt_steel -type: smelting -skill: smithing -level: 40 -xp: 17 -wait: 4 -station: [furnace] -consume: - - items: [iron_ore] - quantity: 1 - - items: [coal] - quantity: 2 -output: steel_bar -message: "You remove a white hot steel bar!" -fail_message: "You fail to smelt a usable bar." +# data/items/ammo/bronze_nails.yaml +craft: + type: smithing + skill: smithing + level: 4 + xp: 12 + wait: 4 + station: [anvil] + consume: + - items: [bronze_bar] + quantity: 1 + output_qty: 15 + message: "You hammer out some bronze nails." ``` -Iron smelting uses a `success` formula for its 50% failure rate: +### Tool-Based Production ```yaml -success: - base: 0.5 - per_level: 0 - cap: 0.5 +# data/items/ammo/arrow_shafts.yaml +craft: + type: fletching + level: 1 + xp: 5 + wait: 3 + tool: knife + consume: + - items: [logs, oak_logs, willow_logs] + quantity: 1 + output_qty: 15 ``` -### Smithing recipe (bar to item at an anvil) - -Smithing recipes use `type: smithing` and `station: [anvil]`. The `smith` command or `use <bar> on anvil` triggers them. Requires a hammer (`tool_type: hammer`) in inventory. +The `tool` field requires the player to have an item with that `tool_type` equipped or in inventory. The tool is NOT consumed. -**Recommended:** Use consolidated format (one file per metal type) since all products for a given metal share the same bar, station, and wait. See [Consolidated Format](#consolidated-format) above. +### Skill-Less Combinations (Item-on-Item) -The individual format is also supported: +Omit `type` (or leave it empty) for combinations with no skill check, no XP, and 100% success: ```yaml -id: smith_steel_platebody -type: smithing -skill: smithing -level: 48 -xp: 187 -wait: 4 -station: [anvil] -consume: - - items: [steel_bar] - quantity: 5 -output: steel_platebody -message: "You hammer out a steel platebody." +# data/items/consumables/bucket_of_water.yaml +craft: + wait: 0 + consume: + - items: [vial_of_water, jug_of_water] + quantity: 1 + byproducts: [empty_vial, empty_jug] + - items: [empty_bucket] + quantity: 1 + message: "You pour water into the bucket." ``` -For stackable outputs, use `output_qty`: +### Multi-Piece Assembly (3+ items → 1) ```yaml -id: smith_iron_nails -type: smithing -skill: smithing -level: 24 -xp: 25 -wait: 4 -station: [anvil] -consume: - - items: [iron_bar] - quantity: 1 -output: iron_nails -output_qty: 15 -message: "You hammer out some iron nails." +# data/items/quest/ancient_map.yaml +craft: + wait: 0 + consume: + - items: [torn_page_1] + quantity: 1 + - items: [torn_page_2] + quantity: 1 + - items: [torn_page_3] + quantity: 1 + steps: + - tick: 1 + message: "You try to puzzle how the pieces fit together." + - tick: 3 + message: "Aha, this edge lines up here!" + message: "You assemble the ancient map." ``` -### MadeFrom — Item-on-item combinations +### Clean Recipes -Item-on-item combinations are defined directly on the output item via the `made_from` field. No recipe file needed. +Clean herb recipes use `type: clean` and are handled as background actions (one herb per cycle, directly mutating inventory): ```yaml -# data/items/bread_dough.yaml -id: bread_dough -name: bread dough -color: "222" -made_from: - - items: [pot_of_flour] - quantity: 1 - - items: [bucket_of_water, pitcher_of_water, vial_of_water] - quantity: 1 +# data/items/materials/guam.yaml (clean guam) +craft: + type: clean + skill: pharmacy + level: 3 + xp: 3 + wait: 2 + consume: + - items: [grimy_guam] + quantity: 1 + message: "You clean the grimy guam leaf." ``` -The player uses `use flour on water` to combine them. The system finds that `bread_dough` can be made from these ingredients and produces it. - ### Food/Healing Items Items with `heal_value` and `eat_message` can be consumed via the `eat` command. @@ -257,3 +227,13 @@ value: 5 heal_value: 5 eat_message: "You eat the bread. Warm and satisfying." ``` + +### Architecture + +The `CraftIndex` (`internal/game/craft_index.go`) is built once at startup from all item YAMLs that have a `craft:` block. It provides `O(1)` lookups by type, input item, and station. All crafting commands query the CraftIndex — no runtime file scanning. + +**Indexes:** +- `byType["pharmacy"]` → all pharmacy-craftable items (used by `mix`) +- `byInput["guam"]` → all items that consume guam (used by `use` to find combinations) +- `byStation["anvil"]` → all items craftable at an anvil (used by `use bar on anvil`) +- `FindByTwoInputs(a, b)` → items consuming both inputs in different consume entries |
