Every master of a match gets an own portal beside the dungeon
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
aeaa1eba36
commit
7b927b0df7
2 files changed
+48
-19
No files matched your search
+47
@@ -1597,6 +1597,8 @@ impl Game {
|
||||
continue;
|
||||
}
|
||||
self.carve_master_area(*side, cores[k]);
|
||||
// every master gets a portal of his own (side 0 has the map's portal)
|
||||
self.add_master_portal(*side, cores[k]);
|
||||
self.add_master(*side, cores[k]);
|
||||
self.switch_to(*side);
|
||||
let (cx, cy) = cores[k];
|
||||
@@ -1610,6 +1612,30 @@ impl Game {
|
||||
true
|
||||
}
|
||||
|
||||
// a master's own portal right beside his starting area (if there is room)
|
||||
pub(crate) fn add_master_portal(&mut self, side: u8, core: (i32, i32)) {
|
||||
let owner = Owner::of_side(side);
|
||||
let (px, py) = (core.0 + 6, core.1);
|
||||
if px + 3 >= mw() as i32 - 2 || py < 2 || py + 3 >= mh() as i32 - 2 {
|
||||
return;
|
||||
}
|
||||
for y in py..py + 3 {
|
||||
for x in px..px + 3 {
|
||||
let t = &mut self.map.t[idx(x, y)];
|
||||
if !matches!(t.kind, Kind::Core | Kind::Gate) {
|
||||
t.kind = Kind::Portal;
|
||||
t.owner = owner;
|
||||
t.gold = 0;
|
||||
t.marked = false;
|
||||
t.reinforced = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if !self.map.portals.contains(&(px, py)) {
|
||||
self.map.portals.push((px, py));
|
||||
}
|
||||
}
|
||||
|
||||
// the starting area of a master: a 9x9 room of his own floor and his 3x3 soul core
|
||||
pub(crate) fn carve_master_area(&mut self, side: u8, core: (i32, i32)) {
|
||||
let owner = Owner::of_side(side);
|
||||
@@ -6831,6 +6857,27 @@ mod tests {
|
||||
assert!(g.ents.iter().filter(|e| e.kind == EK::Chainbreaker).count() <= 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_master_of_a_coop_mission_has_an_own_portal() {
|
||||
let m = crate::campaign::coop_mission_indexes()[2];
|
||||
let mut g = crate::campaign::start_mission(m, None);
|
||||
g.coop = true;
|
||||
assert!(g.start_masters(&[0, 2, 3], 0));
|
||||
for side in [2u8, 3] {
|
||||
let owner = Owner::of_side(side);
|
||||
let core = g.masters.iter().find(|m| m.side == side).unwrap().core;
|
||||
let k = (0..g.map.portals.len()).find(|&k| g.map.portal_owner(k) == owner && g.map.portals[k] == (core.0 + 6, core.1)).expect("a portal of his own");
|
||||
let (px, py) = g.map.portals[k];
|
||||
let from = idx(core.0 + 1, core.1 + 4);
|
||||
assert!(g.map.creature_path(false, from, idx(px, py + 1)).is_some(), "reachable from his dungeon");
|
||||
}
|
||||
for n in crate::lobby::MATCH_SIZES {
|
||||
let seats = crate::lobby::seats_for(n);
|
||||
let mut m = Game::new(3, n, n);
|
||||
assert!(m.start_masters(seats, 0), "a {}x{} match with {} seats", n, n, seats.len());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_coop_ai_seat_fights_beside_the_host_not_against_him() {
|
||||
let mut g = Game::new(11, 96, 128);
|
||||
|
||||
+1
-19
@@ -97,25 +97,7 @@ impl Game {
|
||||
pub fn add_rival(&mut self, side: u8, cx: i32, cy: i32, difficulty: u8) {
|
||||
let core = (cx - 1, cy - 1);
|
||||
self.carve_master_area(side, core);
|
||||
// his own portal beside the dungeon (if there is room)
|
||||
let owner = Owner::of_side(side);
|
||||
let (px, py) = (core.0 + 6, core.1);
|
||||
if px + 3 < mw() as i32 - 2 && py >= 2 && py + 3 < mh() as i32 - 2 {
|
||||
for y in py..py + 3 {
|
||||
for x in px..px + 3 {
|
||||
let t = &mut self.map.t[idx(x, y)];
|
||||
if !matches!(t.kind, Kind::Core | Kind::Gate) {
|
||||
t.kind = Kind::Portal;
|
||||
t.owner = owner;
|
||||
t.gold = 0;
|
||||
t.reinforced = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if !self.map.portals.contains(&(px, py)) {
|
||||
self.map.portals.push((px, py));
|
||||
}
|
||||
}
|
||||
self.add_master_portal(side, core);
|
||||
self.rivals.push(Rival { side, core, hp: RIVAL_CORE_HP, alive: true, radius: 5, grow_t: 20.0, spawn_t: 5.0, attack_t: 0.0, difficulty, power: 0.0, gift_t: PARTNER_GIFT_EVERY, think_t: 2.0, attacking: false, army0: 0.0 });
|
||||
self.adopt_master(side, core, difficulty, true);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user