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:
Richard ZinkandClaude Opus 5.5 committed 2026-11-03 14:11:23 +01:00
1 parent 52c4d1caf8
commit dd16c684e5
11 files changed
+771 -38

No files matched your search

+23 -2
View File
@@ -1,7 +1,7 @@
// Procedurally generated pixel art: tile atlas, unit sprites and the bitmap font.
use crate::game::EK;
use crate::map::Kind;
use crate::map::{Kind, Owner};
use macroquad::prelude::*;
pub const CELL: f32 = 16.0;
@@ -67,6 +67,8 @@ pub const D_CRACK: u32 = 125; // a long crack through several stones
pub const T_AERIE: u32 = 126; // 4 variants: straw, twigs and feathers
pub const T_STEEL: u32 = 130; // 4 variants: riveted iron plates
pub const I_STEEL: u32 = 134;
pub const T_RIVAL1: u32 = 135; // 4 variants: floor of the green master
pub const T_RIVAL2: u32 = 139; // 4 variants: floor of the blue master
pub struct Gfx {
pub atlas: Texture2D,
@@ -746,6 +748,19 @@ fn gen_atlas() -> Image {
}
});
}
// floors of the rival masters: like the player's claimed floor, in their colours
for v in 0..4u32 {
for (id, base, grout, mark) in [(T_RIVAL1, (44, 74, 50), (20, 36, 24), (90, 170, 100)), (T_RIVAL2, (44, 54, 86), (20, 24, 44), (90, 120, 200))] {
cv.cell(id + v, |x, y| {
let col = stones(x, y, v + 250, base, grout, 10);
if (x % 8 == 4 && y % 8 == 4) && hash(x / 8, y / 8, v + 251) % 2 == 0 {
Some(c(mark.0, mark.1, mark.2))
} else {
Some(col)
}
});
}
}
// steel walls: riveted plates with a little rust
for v in 0..4u32 {
cv.cell(T_STEEL + v, |x, y| {
@@ -1323,7 +1338,9 @@ impl Gfx {
Rect::new((i * SPR_CELL) as f32, (row * SPR_CELL) as f32, SPR_CELL as f32, SPR_CELL as f32)
}
pub fn tile_tex(kind: Kind, claimed: bool, hero: bool, var: u8, reinforced: bool) -> u32 {
pub fn tile_tex(kind: Kind, owner: Owner, var: u8, reinforced: bool) -> u32 {
let claimed = owner == Owner::Player;
let hero = owner == Owner::Hero;
let v = var as u32 & 3;
match kind {
Kind::Rock => T_ROCK + v,
@@ -1337,6 +1354,10 @@ impl Gfx {
Kind::Floor => {
if claimed {
T_CLAIM + v
} else if owner == Owner::Rival1 {
T_RIVAL1 + v
} else if owner == Owner::Rival2 {
T_RIVAL2 + v
} else if hero {
T_HEROFLOOR + v
} else {