Real AI masters: rivals, AI seats and the co-op partner play by the player's rules (imps dig, mine and claim, rooms, towers, tunnels and the attack flag); other masters are saved; portals belong to whoever claims them
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b940a959f1
commit
a00ae6a06b
11 files changed
+456
-223
No files matched your search
+9
-9
@@ -480,7 +480,8 @@ fn player_owner() -> Owner {
|
||||
// The state of a dungeon master that is not being processed right now. The Game's own fields
|
||||
// (gold, mana, hand, ...) always belong to the master whose side is `me_side`; switching swaps
|
||||
// them with the stored ones. A single player game has no stored masters at all.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct MasterState {
|
||||
pub side: u8,
|
||||
pub owner: Option<Owner>,
|
||||
@@ -656,8 +657,8 @@ pub struct Game {
|
||||
pub me_side: u8, // that master's side (0 = the first player)
|
||||
#[serde(skip)]
|
||||
pub local_side: u8, // the master who plays at this computer
|
||||
#[serde(skip)]
|
||||
pub masters: Vec<MasterState>, // the other masters (multiplayer)
|
||||
#[serde(default)]
|
||||
pub masters: Vec<MasterState>, // the other masters (multiplayer, AI masters), saved with the game
|
||||
#[serde(skip)]
|
||||
pub pending: Vec<Command>, // orders of this master, applied at the next step boundary
|
||||
#[serde(skip)]
|
||||
@@ -1291,7 +1292,7 @@ impl Game {
|
||||
}
|
||||
|
||||
pub fn portals_owned(&self) -> usize {
|
||||
(0..self.map.portals.len()).filter(|&k| self.map.portal_owned(k)).count()
|
||||
(0..self.map.portals.len()).filter(|&k| self.map.portal_owner(k) == self.me).count()
|
||||
}
|
||||
|
||||
// gate defenders alive (not the treasure guards)
|
||||
@@ -1610,8 +1611,7 @@ impl Game {
|
||||
}
|
||||
|
||||
// the starting area of a master: a 9x9 room of his own floor and his 3x3 soul core
|
||||
#[allow(dead_code)] // called by start_masters only
|
||||
fn carve_master_area(&mut self, side: u8, core: (i32, i32)) {
|
||||
pub(crate) fn carve_master_area(&mut self, side: u8, core: (i32, i32)) {
|
||||
let owner = Owner::of_side(side);
|
||||
for y in core.1 - 3..core.1 + 6 {
|
||||
for x in core.0 - 3..core.0 + 6 {
|
||||
@@ -2007,7 +2007,7 @@ impl Game {
|
||||
}
|
||||
r -= w;
|
||||
}
|
||||
let owned: Vec<usize> = (0..self.map.portals.len()).filter(|&k| self.map.portal_owned(k)).collect();
|
||||
let owned: Vec<usize> = (0..self.map.portals.len()).filter(|&k| self.map.portal_owner(k) == self.me).collect();
|
||||
let pk = owned[(self.rng.next() as usize) % owned.len()];
|
||||
let (px, py) = self.map.portals[pk];
|
||||
let id = self.spawn(kind, false, px as f32 + 1.5, py as f32 + 1.5, 1);
|
||||
@@ -2436,7 +2436,7 @@ impl Game {
|
||||
self.demo_ai(e, dt);
|
||||
} else if e.hero && e.captive != 0 {
|
||||
self.captive_update(e, dt);
|
||||
} else if self.is_rival_side(e.side) || (e.rival() && !self.is_master(e.side)) {
|
||||
} else if !self.is_master(e.side) && (self.is_rival_side(e.side) || e.rival()) {
|
||||
self.rival_ai(e, dt);
|
||||
} else if e.kind == EK::Trader {
|
||||
self.trader_ai(e, dt);
|
||||
@@ -2499,7 +2499,7 @@ impl Game {
|
||||
}
|
||||
}
|
||||
if !tile.walkable() && !(flies(e.kind) && tile.liquid()) {
|
||||
if (e.hero || self.is_rival_side(e.side) || (e.rival() && !self.is_master(e.side))) && tile.diggable() {
|
||||
if (e.hero || (!self.is_master(e.side) && (self.is_rival_side(e.side) || e.rival()))) && tile.diggable() {
|
||||
// heroes dig their way through
|
||||
e.working = true;
|
||||
let (tx, ty) = xy(next);
|
||||
|
||||
Reference in new issue
Block a user