feat: m4 teil 1 — beute, inventar und affixe

- data/: [[loot_tables]] und [[affixes]] als Registries; LootEntry mit
  guaranteed, nothing, table-in-table, count und affixes
- game/loot.rs: EINE Ziehmaschinerie fuer Gegenstaende und Affixe,
  Tiefendeckel gegen wechselseitigen Bezug
- PickUp zieht erst beim Aufheben (Ticket 16) — moeglich nur, weil alle
  Haufen dasselbe Symbol zeigen
- UseItem/Equip/Unequip/Drop, Inventar-Screen als Registry-Schleife
- Affixe im Attributpfad, in der Resistenz und in der Trigger-Suche;
  item_label stellt Affixnamen voran, item_price multipliziert Faktoren
- Room haelt eine loot_table (nicht je Haufen eine), Prefab-loot
  ueberschreibt die Etagentabelle

53 Tests. Offen aus M4: Handel.
This commit is contained in:
2026-08-12 17:56:28 +02:00
parent cdcabcce21
commit 197f62ce33
16 changed files with 849 additions and 19 deletions

88
mods/core/loot.toml Normal file
View File

@@ -0,0 +1,88 @@
# Beutetabellen (Ticket 16). EINE Maschinerie fuer Gegenstaende und Affixe:
# dieselben Gewichte, dieselbe Tabelle-in-Tabelle, dieselben Nieten.
#
# Gewichte statt Prozent — Prozente muessten sich auf 100 summieren, und ein
# Eintrag, den ein Mod hinzufuegt, macht die Summe kaputt.
#
# Der MOD-EINHAENGEPUNKT ist Tabelle-in-Tabelle: Ein Mod legt seine eigene
# Tabelle an, bindet `core:floor_3_table` als Untertabelle ein und haengt die
# Etage um. Zwei gewoehnliche Ueberschreibungen, kein zweiter Mechanismus.
# --- Affixe ---------------------------------------------------------------
# Abstufungen sind EIGENE Eintraege mit kleinerem Gewicht, keine Zahl am
# Exemplar. Deshalb erhoeht ein zusaetzlicher Zug auch die Chance auf die
# staerkere Stufe.
[[loot_tables]]
id = "weapon_affixes"
rolls = "0-1"
entries = [
{ affix = "core:sharp", weight = 6 },
{ affix = "core:flaming", weight = 3 },
{ affix = "core:greater_flaming", weight = 1 },
{ nothing = true, weight = 14 },
]
[[loot_tables]]
id = "armor_affixes"
rolls = "0-1"
entries = [
{ affix = "core:sturdy", weight = 5 },
{ affix = "core:warding", weight = 2 },
{ nothing = true, weight = 16 },
]
# --- Etagen ---------------------------------------------------------------
[[loot_tables]]
id = "floor_1_table"
rolls = "1-2"
entries = [
{ item = "core:health_potion", weight = 12, count = "1-2" },
{ item = "core:gold", weight = 10, count = "3-9" },
{ item = "core:iron_sword", weight = 2, affixes = "core:weapon_affixes" },
{ item = "core:leather_cap", weight = 2, affixes = "core:armor_affixes" },
{ nothing = true, weight = 8 },
]
[[loot_tables]]
id = "floor_3_table"
rolls = "1-3"
entries = [
{ item = "core:health_potion", weight = 10, count = "1-2" },
{ item = "core:gold", weight = 10, count = "6-18" },
{ item = "core:iron_sword", weight = 3, affixes = "core:weapon_affixes" },
{ item = "core:thorn_mail", weight = 1, affixes = "core:armor_affixes" },
{ table = "core:rare_table", weight = 2 },
{ nothing = true, weight = 6 },
]
[[loot_tables]]
id = "floor_5_table"
rolls = "2-3"
entries = [
{ item = "core:health_potion", weight = 8, count = "2-3" },
{ item = "core:gold", weight = 10, count = "15-40" },
{ item = "core:iron_sword", weight = 4, affixes = "core:weapon_affixes" },
{ item = "core:thorn_mail", weight = 3, affixes = "core:armor_affixes" },
{ table = "core:rare_table", weight = 4 },
]
[[loot_tables]]
id = "rare_table"
rolls = "1-1"
entries = [
{ item = "core:bone_blade", weight = 3, affixes = "core:weapon_affixes" },
{ item = "core:thorn_mail", weight = 4, affixes = "core:armor_affixes" },
]
# `guaranteed` nimmt an der Gewichtung nicht teil und kommt immer — mit
# Gewichten allein laesst sich "sicher" nicht ausdruecken.
[[loot_tables]]
id = "boss_table"
rolls = "1-2"
entries = [
{ item = "core:bone_blade", guaranteed = true, affixes = "core:weapon_affixes" },
{ item = "core:gold", weight = 10, count = "50-120" },
{ item = "core:health_potion", weight = 6, count = "2-4" },
]