Free game against rival dungeon masters (green, blue) and/or the humans
- One opponent on maps up to 128x128, two on bigger maps; with a chance of one in two one of them is the humans' gate instead of a rival master - Simplified rival masters (rival.rs): own soul core and dungeon (lair, treasury to loot) that grows ring by ring, creatures appear and get stronger over time, guard the dungeon and attack in groups - the player, the other master or the humans' gate; a fallen core puts the master out and frees its ground - The humans attack everybody: waves now and then march on a rival master - Sides for units: all other sides are enemies; towers and contested ground follow them; the hand cannot pick up rival creatures; the flag next to a rival core attacks it - Difficulty (easy / medium / hard) in the New Game dialog - Colours: green and blue floors, cores, unit rings, minimap, HUD bars of the rival cores - Victory in free games: every rival core and the gate (if any) destroyed - Tests for setups, growth and attacks, elimination and victory, humans against rivals Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
52c4d1caf8
commit
dd16c684e5
11 files changed
+771
-38
No files matched your search
+25
-9
@@ -189,6 +189,7 @@ enum Btn {
|
||||
Change(usize, i32),
|
||||
MapW(i32),
|
||||
MapH(i32),
|
||||
Difficulty(i32),
|
||||
Start,
|
||||
Key(usize),
|
||||
ResetKeys,
|
||||
@@ -405,6 +406,10 @@ impl Menu {
|
||||
settings.map_w = (settings.map_w as i32 + d * 32).clamp(MIN_SIZE as i32, MAX_SIZE as i32) as usize;
|
||||
MenuAction::SettingsChanged
|
||||
}
|
||||
Some(Btn::Difficulty(d)) => {
|
||||
settings.difficulty = (settings.difficulty as i32 + d).rem_euclid(3) as u8;
|
||||
MenuAction::SettingsChanged
|
||||
}
|
||||
Some(Btn::MapH(d)) => {
|
||||
settings.map_h = (settings.map_h as i32 + d * 32).clamp(MIN_SIZE as i32, MAX_SIZE as i32) as usize;
|
||||
MenuAction::SettingsChanged
|
||||
@@ -631,13 +636,15 @@ impl Menu {
|
||||
let sw = sw();
|
||||
let sh = sh();
|
||||
let (mx, my) = mouse();
|
||||
let cols = 44;
|
||||
let rows = 17;
|
||||
let x = grid_center(sw, cols as f32 * CW());
|
||||
let cols = 48.min((sw / CW()) as i32);
|
||||
let rows = 22;
|
||||
let x = grid_center(sw, cols as f32 * CW()).max(0.0);
|
||||
let y = (grid_center_y(sh, rows as f32 * CH())).max(0.0);
|
||||
gfx.window_titled(x, y, cols, rows, S(), true, FRAME_HI, Color::new(0.05, 0.03, 0.04, 0.97), &tr("menu.new"), FRAME_HI);
|
||||
let lines = [("newgame.width", s.map_w, 0), ("newgame.height", s.map_h, 1)];
|
||||
for (k, &(key, val, which)) in lines.iter().enumerate() {
|
||||
let diff = tr(&format!("diff.{}", s.difficulty.min(2)));
|
||||
let lines = [("newgame.width", s.map_w.to_string(), 0), ("newgame.height", s.map_h.to_string(), 1), ("newgame.difficulty", diff, 2)];
|
||||
for (k, (key, val, which)) in lines.iter().enumerate() {
|
||||
let (key, which) = (*key, *which);
|
||||
let by = y + CH() * (2.0 + k as f32 * 2.5);
|
||||
gfx.text(&tr(key), x + CW() * 3.0, by + CH() * 0.5, S(), TXT);
|
||||
let vw = 14.0 * CW();
|
||||
@@ -646,9 +653,13 @@ impl Menu {
|
||||
let right = Rect::new(vx + vw - CW() * 2.5, by, CW() * 2.5, CH() * 2.0);
|
||||
button(gfx, left, "<", left.contains(vec2(mx, my)), FRAME);
|
||||
button(gfx, right, ">", right.contains(vec2(mx, my)), FRAME);
|
||||
let v = val.to_string();
|
||||
let v = val.clone();
|
||||
gfx.text(&v, vx + (vw - gfx.measure(&v, S())) * 0.5, by + CH() * 0.5, S(), GOLD);
|
||||
let (l, r) = if which == 0 { (Btn::MapW(-1), Btn::MapW(1)) } else { (Btn::MapH(-1), Btn::MapH(1)) };
|
||||
let (l, r) = match which {
|
||||
0 => (Btn::MapW(-1), Btn::MapW(1)),
|
||||
1 => (Btn::MapH(-1), Btn::MapH(1)),
|
||||
_ => (Btn::Difficulty(-1), Btn::Difficulty(1)),
|
||||
};
|
||||
self.buttons.push((left, l));
|
||||
self.buttons.push((right, r));
|
||||
}
|
||||
@@ -656,9 +667,14 @@ impl Menu {
|
||||
let area = (s.map_w * s.map_h) as f32 / 4096.0;
|
||||
let portals = (area.round() as usize).max(1);
|
||||
let info = trf("newgame.info", &[portals.to_string(), (portals - 1).to_string()]);
|
||||
gfx.text(&info, x + CW() * 3.0, y + CH() * 7.5, S(), DIM);
|
||||
gfx.text(&info, x + CW() * 3.0, y + CH() * 10.0, S(), DIM);
|
||||
let opp = tr(if s.map_w * s.map_h > 128 * 128 { "newgame.opponents2" } else { "newgame.opponents1" });
|
||||
let maxc = (cols - 6) as usize;
|
||||
for (k, l) in wrap(&opp, maxc).iter().take(2).enumerate() {
|
||||
gfx.text(l, x + CW() * 3.0, y + CH() * (11.0 + k as f32), S(), DIM);
|
||||
}
|
||||
let w = (cols - 6) as f32 * CW();
|
||||
self.column(gfx, x + CW() * 3.0, y + CH() * 9.5, w, &[(Btn::Start, tr("newgame.start")), (Btn::Back, tr("menu.back"))]);
|
||||
self.column(gfx, x + CW() * 3.0, y + CH() * 14.0, w, &[(Btn::Start, tr("newgame.start")), (Btn::Back, tr("menu.back"))]);
|
||||
}
|
||||
|
||||
fn draw_pause(&mut self, gfx: &Gfx) {
|
||||
|
||||
Reference in new issue
Block a user