# Rune master (`src/mods/runetrade.cpp`) ## Requests (2026-10-17) 1. Dropping a rune stack into the rune master takes one rune off the stack. 2. Buying: runes can always be exchanged directly for a chosen rune; the number of runes given lowers the price (decided: 4 runes 1,000, each missing rune x10: 3 runes 10,000, 2 runes 100,000, 1 rune 1,000,000). The rune to buy can always be chosen; Buy works only with at least one rune and enough gold. The last rune bought is remembered (decided: per hero, saved). ## The original window (`cUI_MasterLotto`, read) | Offset | What | |---|---| | +0x154 + i * 0x114 | slot control i (0..3), hit test vf1c(x, y) | | +0x24c + i * 0x114 | slot i's item descriptor {u16 kind 1, u16 class 0x1c, u32 id, ...} | | +0x5a4 / +0x620 | arrows: next / previous rune (`doLottoSelect` mode 1 / 0) | | +0x69c | the bought rune's control; +0x794 its descriptor, +0x798 id, +0x79c type | | +0x7b4 | the chosen rune (item type) | | +0x7c8 | Buy button | - Prices: u32 table at `0xad2aac` by rune count; the game fills 2..4 from its settings (`0x5efc7b`); read by the render, the button state (`0x6d4390`, `0x6d3df0`) and the pay helper `0x6d3ce0(pay)` (gold at hero +0x3ee, paid with `cCreatureArts::AddGold` `0x57fc40`). - Buy (`0x6d42a0`): 2 runes give a random rune, 3 a random one of the hero's class, 4 the chosen one. Buying needed 2 runes (`cmp dx, 2` at `0x6d3e20`, `0x6d4544`, `0x6d4a13`). - `0x6d3d50` after slot changes: with 4 runes shows the arrows and keeps the choice (`doLottoSelect(hero type, 2)`, index in the global `0x17e81d0`), otherwise hides them and clears +0x7b4. ## Mod - Owns the window's event hook (hud.cpp centres it via `hud::HandleCentred`). - Prices: `kPrices` written into the table (on game start and with each window event); the three `cmp dx, 2` become 1. - `0x6d3d50` replaced: arrows always shown (unless a bought rune waits), a rune always chosen; when none is chosen (window opened) the hero's last bought rune is chosen by stepping `doLottoSelect` forward to it. - Buy press handled here (`CanBuy`): at least one rune, a chosen rune, gold (`0x6d3ce0(0)`) and room in the backpack (a stack of that rune with room, or a free cell). Buying pays (`0x6d3ce0(1)`), destroys the slot runes and puts the rune straight into the backpack (follow-up 2026-10-17: a bought rune taken from the window vanished; the window's waiting slot +0x794 / +0x798 is no longer used). The rune is remembered for the hero. - The Buy button looks disabled whenever `CanBuy` fails: the render sets its colours each frame with `cUI_Button::SetColours` (`0x6d5d90`), hooked to hand it the disabled set (`0x9f0290`, text `0x9f028c`). - Remembered rune: `"hero": {"lastRune": type}` in the hero's inventory JSON (`inventory_save::RegisterHeroData`); cleared when the session ends. - Stack drops: see docs/item-stacks.md.