Potion counts on the bottom bar and potion stacks in the inventory
- potioncounts.cpp: each potion slot shows how many potions of its kind the hero carries (stacks added up) - potionstack.cpp: potions of one type stack up to 20 per cell; every potion entering the hero's grid pours into stacks with room, the sort button stacks first, drinking takes one off a stack, counts drawn on the cells and saved in the JSON inventories - game/engine/items.h: potion kinds and grid helpers; ObjectManager and DestroyObject in objects.h - auto-attack: the projectile-weapon target radius is a design value - docs/potion-stacks.md: measured paths and the design Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
b2e886c7f5
commit
13b91cdd3d
13 files changed
+612
-10
No files matched your search
@@ -0,0 +1,59 @@
|
||||
# Potion counts and potion stacks
|
||||
|
||||
## Requests (2026-10-17)
|
||||
|
||||
1. The potion selector on the bottom bar always shows how many potions of
|
||||
each kind the hero carries (only when there are any).
|
||||
2. Potions of the same type stack in one inventory cell, up to 20 per stack.
|
||||
Every potion entering the inventory tries to stack. Drag, sell and drop
|
||||
move a whole stack. The inventory's sort button stacks first, then sorts.
|
||||
A stack dropped on the ground splits into single potions (agreed for now).
|
||||
|
||||
## Measured (diagnostic log, 2026-10-17)
|
||||
|
||||
| Action | Calls |
|
||||
|---|---|
|
||||
| Drink (potion key) | `cEngine::UseActionSlot` `0x613040` → `cCreature::UseItem` `0x54a8f0` → `RemoveItem` (from `0x54aa20`) → `DestroyObject` (from `0x54aa30`); then `UseActionSlot` calls `RemoveItem` again (`0x6130d8`, not found) |
|
||||
| Drag in the inventory | `RemoveAt` from `0x6c06fb` (cell → cursor), `PlaceItem` from `0x6c0583` (cursor → cell) |
|
||||
| Buy | trader grid (inventory 22) `RemoveItem` `0x6d96f5` → hero grid `PlaceItem` `0x6d98e8` |
|
||||
| Pick up from the ground | `PlaceItem` from `0x558db6` |
|
||||
| Trader restock | `RemoveItem` `0x6d9973` + `DestroyObject` `0x6d99cc`, new items `PlaceItem` `0x6d9bdf` |
|
||||
| Sort | `cInventoryEntry::Sort` `0x5db670`: all items removed (`0x5db8a5`) and placed again (`0x5dbb4c`, notify 0) |
|
||||
|
||||
Not seen yet: a sale, a right-click drink.
|
||||
|
||||
## Game side
|
||||
|
||||
- Potion kinds: `ItemPotionKind` `0x43f630` (ecx = item type table
|
||||
`*0xaa9564`) maps an item type to kind 1..5 (the bottom bar's potion
|
||||
slots); `GetPotionRef` `0x5da880` picks the potion a slot drinks.
|
||||
- Bottom bar: `cUI_Taskbar2::RenderPotionSlots` `0x6e39e0` draws the 5 slot
|
||||
controls (embedded at +0x258, stride 0xbc).
|
||||
- Inventory grid (`cInventoryEntry`, docs/skill-slots.md): cells of 0xc bytes
|
||||
at +0x18; an item's id only in its first cell, covered cells flagged.
|
||||
`CellRect` `0x5dd530` gives a cell's screen rect (32x32 from the origin
|
||||
+0x1164 / +0x1166, which the window sets before `DrawItems` `0x5dc3f0`).
|
||||
- Drinking: `cPotion3D::vf18` `0x5ca9d0` applies the effect and sets object
|
||||
flag +0x14 bit `0x8000000` (used up); `UseItem` then removes and destroys.
|
||||
- Sort button: `cUI_Inventory3::HandleEvent` `0x6c5f40`, button control at
|
||||
+0x158, mode from bit 4 of +0x168.
|
||||
- Hero files map saved item ids to new objects with `ReplaceItemId`
|
||||
`0x5d80e0`.
|
||||
|
||||
## Mods
|
||||
|
||||
- `src/mods/potioncounts.cpp`: counts per kind (stacks added up), drawn
|
||||
bottom-right on each potion slot after `RenderPotionSlots`.
|
||||
- `src/mods/potionstack.cpp`: stack counts by item id (with the item type),
|
||||
saved as `"count"` on the grid cell in the JSON inventories
|
||||
(`inventory_save.cpp`); entry pours into stacks with room on the next
|
||||
tick; `Sort` stacks the hero's potions first; a drink from a stack of more
|
||||
than one takes one off the count and keeps the object; the count is drawn
|
||||
on the cell after `DrawItems`.
|
||||
|
||||
## Open
|
||||
|
||||
- Selling a stack: the price is for one potion so far (sale path not measured).
|
||||
- Dropping a stack on the ground: it should split into single potions; for now
|
||||
the count stays with the object while the game runs, but a save keeps only
|
||||
the object (one potion).
|
||||
+11
-2
@@ -5,8 +5,8 @@
|
||||
Saving marks effect objects (cObjectFX) dead; loading keeps the buff but drops
|
||||
the aura effect (type 842) that follows the hero. `src/mods/aura_restore.cpp`
|
||||
recreates it after a load for Heldenmut (0x3f7) and Klingenblick (0x3f8). Spell
|
||||
auras (Steinhaut, Lichtschild, ...) use other effects and are not covered
|
||||
yet; check them if their visuals go missing too.
|
||||
auras (Steinhaut, Lichtschild, ...) use other effects; the user confirmed on
|
||||
2026-10-17 that their visuals are back after loading too.
|
||||
|
||||
## Data-driven arts instead of hardcoded art ids
|
||||
|
||||
@@ -125,3 +125,12 @@ in-game texts/tooltips that name the old keys):
|
||||
|
||||
Globally bound letters (engine `0x618130`, UI manager `0x757120`): A B C E F
|
||||
H I L M N O P Q R S T W, Space, ^, digits. Individual windows may use more.
|
||||
|
||||
## Potion stacks
|
||||
|
||||
Asked 2026-10-17 (after the potion counts on the bottom bar,
|
||||
`src/mods/potioncounts.cpp`): potions of the same type (e.g. minor healing)
|
||||
stack in one inventory cell, up to 20 per stack (a full stack starts a new
|
||||
one). Drag, sell and drop move the whole stack, as with any other item. The
|
||||
counts on the potion slots then add up the stacks. In progress, see
|
||||
docs/potion-stacks.md (open: sale price per stack, splitting on the ground).
|
||||
Reference in new issue
Block a user