In-game campaign, map and block script editors

Mission graph with branches, mission settings and goals, map editor on the
3D view (terrain, places, units, towers, traps, forts, rivals, zones; undo,
brush, rectangle, fill, mirror), block editor with palette, nesting, live
problems, undo, copy/paste and search; test play with a script debug view;
demo campaign and built-in missions as templates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-05 17:10:11 +01:00
1 parent 65677504f6
commit 30dd8441b9
10 files changed
+3372 -19

No files matched your search

+11 -5
View File
@@ -507,10 +507,6 @@ fn start_mission_mode(i: usize, carry: Option<&Carry>, coop: bool) -> Game {
// A mission generated from the campaign editor file: same start pipeline, but without the
// built-in campaign table and without language-file story keys for the title.
pub fn start_mission_doc(d: &MissionDef, i: usize, carry: Option<&Carry>) -> Game {
start_mission_def(d, i, carry, false)
}
fn start_mission_def(d: &MissionDef, i: usize, carry: Option<&Carry>, coop: bool) -> Game {
let (w, h) = d.size;
let opts = GenOpts { portals: Some(d.portals), treasures: Some(d.treasures), gate: d.gate, core_y: None };
@@ -673,6 +669,16 @@ pub fn start_editor_mission(doc: &crate::campaign_doc::MissionDoc, i: usize, run
g
}
// the map editor sets a knight fortress with its middle at (x, y); level 1..3, with a shard
pub fn editor_fort(g: &mut Game, x: i32, y: i32, level: u32, shard: bool) {
let (w, h) = (g.map.w, g.map.h);
let lvl = level.clamp(1, 3);
let mut f = fort((x as f32 / w as f32, y as f32 / h as f32), (15 + 2 * lvl as i32, 13 + 2 * lvl as i32), &[3], &[TowerKind::Arrow, TowerKind::Arrow], lvl, 2 + 2 * lvl, lvl, lvl, 1, 800 * lvl as i32);
f.shard = shard;
g.build_fortress(&f.spec(w, h));
g.recount();
}
// a painted map: the game state saved by the map editor
pub fn load_fixed_map(json: &str) -> Option<Game> {
let mut g: Game = serde_json::from_str(json).ok()?;
@@ -732,7 +738,7 @@ mod tests {
assert_eq!(def.key, "custom01");
assert_eq!(def.goals, vec![Goal::KillAll]);
let g = start_mission_doc(&def, 0, None);
let g = start_mission_def(&def, 0, None, false);
let m = g.mission.as_ref().expect("the custom mission has mission state");
assert_eq!(m.goals, vec![Goal::KillAll]);
assert_eq!(g.gold, 3500.0);