feat: when-filter am trigger schliesst die luecke aus m3

condition fragt Wesen, when filtert das Ereignis. Getrennt, weil dieselbe
Bedingungsgrammatik auch beim Auslesen eines Attributs laeuft — dort gibt es
kein Event, und eine Nutzlast-Pruefung in condition waere im Trigger sinnvoll
und am Modifikator immer falsch, ohne dass der Modder es sieht.

Nutzlast zurueck: damage_type und prefab. critical und amount bleiben draussen,
bis jemand sie fordert.

Dazu Item.triggers/actions/abilities und Trigger-Suche in der Ausruestung —
mods/core/items.toml belegt es mit einem Dornenpanzer, der NUR Feuer
reflektiert.

45 Tests.
This commit is contained in:
2026-08-12 17:44:26 +02:00
parent b25dd1c49a
commit cdcabcce21
5 changed files with 170 additions and 24 deletions

View File

@@ -238,9 +238,14 @@ impl Game {
out.extend(def.triggers.iter());
}
}
// TODO(M4): Trigger an Gegenstaenden, Affixen und Charakteroptionen —
// sie brauchen dieselben drei Zeilen, sobald die Registries
// das Feld tragen.
// Getragene Ausruestung — der Dornenpanzer haengt hier.
for inst in c.equipment.values() {
if let Some(item) = reg.items.get(&inst.def) {
out.extend(item.triggers.iter());
}
// TODO(M4): Affix-Trigger des Exemplars, sobald die Affix-Registry
// steht — dieselben zwei Zeilen.
}
out.retain(|t| t.on == kind);
out
}
@@ -302,8 +307,12 @@ impl Game {
// Dornenpanzer haengt (Ticket 08/14). Beide feuern **nach** dem
// Schaden: Ein Trigger, der Brennen auflegt, ist ein eigener
// Schadensfall mit eigener Minderungskette.
self.events.push_back(Event::new(EventKind::AttackHit, source).to(victim));
self.events.push_back(Event::new(EventKind::DamageTaken, victim).to(source));
self.events.push_back(
Event::new(EventKind::AttackHit, source).to(victim).with_damage(*damage_type),
);
self.events.push_back(
Event::new(EventKind::DamageTaken, victim).to(source).with_damage(*damage_type),
);
self.check_death(victim, source);
}
@@ -409,6 +418,9 @@ impl Game {
let triggers = self.triggers_for(carrier, event.kind, reg);
for t in triggers {
if !t.when.matches(&event) {
continue;
}
let other = if carrier == event.source { event.target } else { Some(event.source) };
if !self.conditions_hold(&t.condition, carrier, other, reg) {
continue;
@@ -653,8 +665,10 @@ impl Game {
if room != self.floor.player_room {
self.floor.player_room = room;
if let Some(i) = room {
self.events
.push_back(Event::new(EventKind::RoomEntered, CreatureRef::Player));
let prefab = self.floor.rooms[i].prefab.clone();
self.events.push_back(
Event::new(EventKind::RoomEntered, CreatureRef::Player).in_prefab(prefab),
);
self.enter_room(i);
}
}