aboutsummaryrefslogtreecommitdiff
path: root/building_guide
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-07-01 16:37:45 -0400
committerhistoria <[not public]>2026-07-01 16:37:45 -0400
commite6b4cb9f5816c6ee239233bc85f74ee446a161c2 (patch)
tree1c3bf71c8b7f095baae989afe5e33183a7ed3929 /building_guide
parent649ef4b7416ce7053145878841fc9b0bff2f5fec (diff)
downloadthehouseoficarus-e6b4cb9f5816c6ee239233bc85f74ee446a161c2.tar.gz
feat: shop system overhauled, gui conversation tree editor overhauled
Diffstat (limited to 'building_guide')
-rw-r--r--building_guide/behaviors.md116
-rw-r--r--building_guide/mobs.md20
2 files changed, 94 insertions, 42 deletions
diff --git a/building_guide/behaviors.md b/building_guide/behaviors.md
index 3d35036..c94f787 100644
--- a/building_guide/behaviors.md
+++ b/building_guide/behaviors.md
@@ -263,7 +263,6 @@ talk:
| `teleport` | Moves the player to a room ID. |
| `heal` | Restores that many hitpoints. |
| `cost` | Credits charged for the action. |
-| `shop` | Opens a buy/sell shop interface. See Shop section below. |
| `assign_task` | Assigns a random assassin task based on assassin level. |
| `skip_task` | Cancels current assassin task, costs 30 reputation, resets streak. |
| `extend_task` | Adds 50% more kills to current task, costs 30 reputation. |
@@ -385,7 +384,7 @@ nodes:
```
If a node has both `goto` and options, the options take priority — `goto` is only used
-when no options are visible. A node with a shop action ignores `goto` entirely.
+when no options are visible.
#### Conditional nodes
@@ -428,62 +427,95 @@ passes, each option's own condition is then checked independently to determine
visibility — exactly as option conditions always work. When the node condition
fails, the node (and all its options) are skipped entirely.
-#### Shop (buy/sell interface)
+### Shops
-The `shop` node action opens a dedicated buy/sell interface. The player can browse items, buy
-with credits, and sell items back. Define a shop on a talk node:
+A shop is a **root-level `shop:` property on a mob def** (not part of the talk tree).
+Any mob in a room that has a `shop:` block can be traded with directly from the game
+prompt — there is no separate shop mode. Players use the ordinary commands:
-```yaml
-action:
- shop:
- message: "What would you like to buy or sell?"
- items:
- - item_id: fishing_rod
- buy_price: 10
- sell_price: 2
- - item_id: fishing_bait
- buy_price: 2
- sell_price: 0
```
+list Show the shop inventory of the mob in the room
+buy <item> Buy an item (partial names work, e.g. "buy bait")
+buy <N> <item> Buy a quantity
+buy all <item> Buy as many as you can afford and carry
+sell <item> Sell an item from your inventory
+sell <N> <item> Sell a quantity
+sell all <item> Sell your entire held stack
+```
+
+When a room has more than one shop mob, disambiguate with the mob name:
+
+```
+list <mob>
+buy <item> from <mob>
+sell <item> to <mob>
+```
+
+If several shops are present and no mob is named, the game replies "Which shop?"
+and lists the options.
+
+#### Pricing
+
+Shops never define per-item prices — prices derive from each item's `value:` field:
+
+- **Buy price** (player buying) is always **100% of the item's value**.
+- **Sell price** (player selling) uses the OSRS store formula:
+
+ ```
+ sell = value × max(10, buy_percentage − stock × change_percentage) / 100
+ ```
+
+ where `stock` is the shop's current holding of that item. With the defaults
+ (`buy_percentage: 40`, `change_percentage: 3`), an item the shop has none of
+ sells for 40% of value, dropping 3% per unit already in stock down to a floor
+ of 10% of value (reached at 10 in stock). Selling multiple units in one command
+ prices each unit at the rising stock level.
+
+#### Stock and restocking
+
+Each shop item carries a `stock` (its target/maximum, and its starting amount).
+Buying depletes stock — an item at 0 stock is out of stock. Selling raises stock,
+lowering subsequent sell prices. Every `restock_ticks` the current stock moves one
+step toward the configured target (refilling when low, decaying overstock when
+high). Items a player sold that the shop didn't originally list are held as dynamic
+stock that decays back to 0.
+
+#### Shop fields
| Field | Description |
|---|---|
-| `shop.message` | Greeting shown when entering the shop. |
-| `shop.items` | List of items for sale. |
-| `item_id` | Item definition ID. |
-| `buy_price` | Credits to buy from shop. |
-| `sell_price` | Credits shop pays (0 = won't buy). |
+| `shop.message` | Optional greeting shown at the top of `list`. |
+| `shop.buy_percentage` | Sell price at zero stock, as % of value (default 40). |
+| `shop.change_percentage` | Sell price drop per unit of stock, as % of value (default 3). |
+| `shop.restock_ticks` | Shop-wide default restock interval (default 100). |
+| `shop.buys_anything` | Whether the shop buys items not in its list (default true). |
+| `shop.items[].item_id` | Item definition ID. |
+| `shop.items[].stock` | Target/maximum and starting stock. |
+| `shop.items[].restock_ticks` | Per-item restock interval (overrides shop default). |
Full example — General Store:
```yaml
-name: General Store Clerk
+name: Shopkeeper
+protected: true
+hp: 50
+shop:
+ message: "\"Welcome to the General Store! Have a look around.\""
+ items:
+ - item_id: fishing_rod
+ stock: 10
+ - item_id: fishing_bait
+ stock: 1000
+ - item_id: hammer
+ stock: 10
talk:
nodes:
start:
- message: "\"Welcome to the General Store!\""
+ message: "\"Welcome! Type 'list' to see my wares.\""
options:
- - text: "\"I'd like to browse.\""
- goto: shop
- text: "\"Goodbye.\""
- shop:
- message: "\"Take your time.\""
- action:
- shop:
- message: "What would you like to buy or sell?"
- items:
- - item_id: fishing_rod
- buy_price: 10
- sell_price: 2
- - item_id: hammer
- buy_price: 20
- sell_price: 5
- options:
- - text: "\"I'm done.\""
- goto: start
```
-When the player leaves the shop, the current node's options are shown (or auto-advance
-fires if no options are visible). Use `goto: start` to loop back to the main greeting.
+A specialty shop that only buys back its own stock sets `buys_anything: false`.
### Object Interactions (levers, switches, gates)
diff --git a/building_guide/mobs.md b/building_guide/mobs.md
index c7331da..745fb49 100644
--- a/building_guide/mobs.md
+++ b/building_guide/mobs.md
@@ -126,6 +126,26 @@ showing the "Okay" option.
See the [Talk section of behaviors](behaviors.md#talk-dialog-trees) for the full
dialog tree format, including sequences and conditional nodes.
+### Shops
+
+Give a mob a root-level `shop:` block to make it a shopkeeper. Players trade with
+it using the ordinary `list`, `buy`, and `sell` commands from the game prompt.
+Prices derive from each item's `value:` field. See the
+[Shops section of behaviors](behaviors.md#shops) for the full format, pricing
+formula, and stock/restock rules.
+
+```yaml
+name: Shopkeeper
+protected: true
+hp: 50
+shop:
+ items:
+ - item_id: fishing_rod
+ stock: 10
+ - item_id: hammer
+ stock: 10
+```
+
Protected mob with combat stats (for internal testing or debug purposes):
```yaml
name: "Guard"