Block scripts and triggers: data model, Rhai translation and runtime

Editor missions keep a painted map or roll a random map per campaign run,
leave out goals they cannot have, and run their triggers in the fixed step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-05 16:51:43 +01:00
1 parent 5315709776
commit 5701124c4f
13 files changed
+1835 -483

No files matched your search

+13 -1
View File
@@ -541,6 +541,10 @@ pub struct Game {
#[serde(default)]
pub mission: Option<MissionState>, // campaign mission (None: free game)
#[serde(default)]
pub script: Option<crate::mscript::ScriptState>, // block scripts of an editor mission
#[serde(default)]
pub objective: Option<String>, // the objective a mission script set
#[serde(default)]
pub rivals: Vec<crate::rival::Rival>, // AI dungeon masters
#[serde(default = "yes")]
pub gate_on: bool, // free game: the humans' gate exists
@@ -866,6 +870,8 @@ impl Game {
towers_razed: 0,
contested: Vec::new(),
mission: None,
script: None,
objective: None,
rivals: Vec::new(),
gate_on: true,
springs: 0,
@@ -1340,6 +1346,11 @@ impl Game {
self.switch_to(side);
self.sync_treasury();
}
// mission scripts: always from the first player's side, the same on every computer
if self.script.is_some() {
self.switch_to(0);
self.run_scripts();
}
let local = self.local_side;
self.switch_to(local);
}
@@ -2729,7 +2740,7 @@ impl Game {
}
// the ground of tile i turned into river (bridge removed): units on it fall in
fn ground_lost(&mut self, i: usize) {
pub(crate) fn ground_lost(&mut self, i: usize) {
let lava = self.map.t[i].kind == Kind::Lava;
let (x, y) = xy(i);
for j in 0..self.ents.len() {
@@ -5231,6 +5242,7 @@ impl Game {
}
self.fx(2, x, y, 0.0, 0.0, 0.3, 0xffffffff);
self.sfx(Sfx::Slap, x, y);
self.script_event(crate::mscript::ScriptEvent::Slap);
return 1;
}
if self.ents[j].captive != 0 {