Hero waves march on the strongest master
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
988f4a3333
commit
e3a9d32d61
22 files changed
+147
-22
No files matched your search
@@ -10,6 +10,8 @@ Multiplayer is only available for users of a server (not in the standalone file)
|
||||
- The match **pauses while a player is missing** (connection lost); a player who **leaves** is replaced by an AI.
|
||||
- Before the start, the host manually marks a free seat as AI with `{"t":"set_ai","side":n,"ai":true}` and clears it again with `ai:false`; side 0 stays human.
|
||||
- The humans (hero waves of the Order) as a third party (can be switched off), chat, alliances/teams.
|
||||
Every wave marches on the strongest master still standing (creatures, towers, gold) – player or
|
||||
AI rival – and is measured against him; the other players learn whom it attacks.
|
||||
- Coop is "separate but helpful": own heart, gold, mana, research and creatures; allies never fight each
|
||||
other, their creatures help each other, gold can be sent, allied ground can be walked; a fallen heart only
|
||||
knocks out that player (who may keep watching); the allies win when all enemies have fallen.
|
||||
|
||||
@@ -707,6 +707,8 @@ msg.rival2_out = Lady Nightwell je poražena - její jádro duše se roztříšt
|
||||
msg.rival_unit_slain = Padl tvor soupeřícího mistra: {0}! +{1} zlata.
|
||||
msg.wave_on_rival1 = Vlna {0}: hrdinové ({1}) táhnou na zeleného mistra.
|
||||
msg.wave_on_rival2 = Vlna {0}: hrdinové ({1}) táhnou na modrou mistryni.
|
||||
msg.wave_warn_on_master = Zvědové hlásí: vlna hrdinů {0} dorazí za 30 sekund a míří na pána {1}.
|
||||
msg.wave_on_master = Vlna {0}: {1} hrdinů táhne na pána {2}.
|
||||
hud.rival1 = Zelený
|
||||
hud.rival2 = Modrá
|
||||
msg.creature_freed = Tvor přetrhl řetězy a přidal se k tobě: {0}!
|
||||
|
||||
@@ -706,6 +706,8 @@ msg.rival2_out = Lady Nightwell er besejret - hendes sjælekerne er splintret!
|
||||
msg.rival_unit_slain = En {0} fra en rivaliserende mester falder! +{1} guld.
|
||||
msg.wave_on_rival1 = Bølge {0}: {1} helte marcherer mod den grønne mester.
|
||||
msg.wave_on_rival2 = Bølge {0}: {1} helte marcherer mod den blå mester.
|
||||
msg.wave_warn_on_master = Spejdere melder: heltebølge {0} kommer om 30 sekunder og går mod mester {1}.
|
||||
msg.wave_on_master = Bølge {0}: {1} helte marcherer mod mester {2}.
|
||||
hud.rival1 = Grøn
|
||||
hud.rival2 = Blå
|
||||
msg.creature_freed = En {0} sprænger sine lænker og slutter sig til dig!
|
||||
|
||||
@@ -706,6 +706,8 @@ msg.rival2_out = Lady Nightwell ist besiegt - ihr Seelenkern ist zersplittert!
|
||||
msg.rival_unit_slain = Ein {0} eines Rivalen fällt! +{1} Gold.
|
||||
msg.wave_on_rival1 = Welle {0}: {1} Helden ziehen gegen den grünen Meister.
|
||||
msg.wave_on_rival2 = Welle {0}: {1} Helden ziehen gegen den blauen Meister.
|
||||
msg.wave_warn_on_master = Späher melden: Heldenwelle {0} kommt in 30 Sekunden – sie zieht gegen Meister {1}.
|
||||
msg.wave_on_master = Welle {0}: {1} Helden ziehen gegen Meister {2}.
|
||||
hud.rival1 = Grün
|
||||
hud.rival2 = Blau
|
||||
msg.creature_freed = Ein {0} sprengt seine Ketten und schließt sich dir an!
|
||||
|
||||
@@ -707,6 +707,8 @@ msg.rival2_out = Η Λαίδη Νάιτγουελ νικήθηκε - ο πυρή
|
||||
msg.rival_unit_slain = Πέφτει πλάσμα αντίπαλου άρχοντα: {0}! +{1} χρυσός.
|
||||
msg.wave_on_rival1 = Κύμα {0}: {1} ήρωες βαδίζουν κατά του πράσινου άρχοντα.
|
||||
msg.wave_on_rival2 = Κύμα {0}: {1} ήρωες βαδίζουν κατά της γαλάζιας άρχοντος.
|
||||
msg.wave_warn_on_master = Οι ανιχνευτές αναφέρουν: το κύμα ηρώων {0} έρχεται σε 30 δευτερόλεπτα και κατευθύνεται στον άρχοντα {1}.
|
||||
msg.wave_on_master = Κύμα {0}: {1} ήρωες βαδίζουν κατά του άρχοντα {2}.
|
||||
hud.rival1 = Πράσινος
|
||||
hud.rival2 = Γαλάζια
|
||||
msg.creature_freed = Σπάει τις αλυσίδες του και έρχεται μαζί σου: {0}!
|
||||
|
||||
@@ -707,6 +707,8 @@ msg.rival2_out = Lady Nightwell is defeated - her soul core has shattered!
|
||||
msg.rival_unit_slain = A {0} of a rival master falls! +{1} gold.
|
||||
msg.wave_on_rival1 = Wave {0}: {1} heroes march on the green master.
|
||||
msg.wave_on_rival2 = Wave {0}: {1} heroes march on the blue master.
|
||||
msg.wave_warn_on_master = Scouts report: hero wave {0} comes in 30 seconds – it heads for master {1}.
|
||||
msg.wave_on_master = Wave {0}: {1} heroes march on master {2}.
|
||||
hud.rival1 = Green
|
||||
hud.rival2 = Blue
|
||||
msg.creature_freed = A {0} breaks its chains and joins you!
|
||||
|
||||
@@ -702,6 +702,8 @@ msg.rival2_out = Lady Nightwell ha sido derrotada: ¡su núcleo de alma se ha he
|
||||
msg.rival_unit_slain = ¡Cae un {0} de un señor rival! +{1} de oro.
|
||||
msg.wave_on_rival1 = Oleada {0}: {1} héroes marchan contra el señor verde.
|
||||
msg.wave_on_rival2 = Oleada {0}: {1} héroes marchan contra la señora azul.
|
||||
msg.wave_warn_on_master = Los exploradores informan: la oleada {0} llega en 30 segundos y va a por el maestro {1}.
|
||||
msg.wave_on_master = Oleada {0}: {1} héroes marchan contra el maestro {2}.
|
||||
hud.rival1 = Verde
|
||||
hud.rival2 = Azul
|
||||
msg.creature_freed = ¡Un {0} rompe sus cadenas y se une a ti!
|
||||
|
||||
@@ -707,6 +707,8 @@ msg.rival2_out = Lady Nightwell on voitettu - hänen sieluytimensä on murskattu
|
||||
msg.rival_unit_slain = Kilpailevan mestarin olento kaatuu: {0}! +{1} kultaa.
|
||||
msg.wave_on_rival1 = Aalto {0}: {1} sankaria marssii vihreää mestaria vastaan.
|
||||
msg.wave_on_rival2 = Aalto {0}: {1} sankaria marssii sinistä mestaria vastaan.
|
||||
msg.wave_warn_on_master = Tiedustelijat ilmoittavat: sankariaalto {0} saapuu 30 sekunnissa ja hyökkää mestari {1} vastaan.
|
||||
msg.wave_on_master = Aalto {0}: {1} sankaria marssii mestari {2} vastaan.
|
||||
hud.rival1 = Vihreä
|
||||
hud.rival2 = Sininen
|
||||
msg.creature_freed = Kahleet katkeavat ja uusi olento liittyy joukkoosi: {0}!
|
||||
|
||||
@@ -707,6 +707,8 @@ msg.rival2_out = Lady Nightwell je poražena - njezina jezgra duše se razbila!
|
||||
msg.rival_unit_slain = Palo je stvorenje suparničkog gospodara: {0}! +{1} zlata.
|
||||
msg.wave_on_rival1 = Val {0}: junaci ({1}) marširaju na zelenog gospodara.
|
||||
msg.wave_on_rival2 = Val {0}: junaci ({1}) marširaju na plavu gospodaricu.
|
||||
msg.wave_warn_on_master = Izvidnici javljaju: val junaka {0} stiže za 30 sekundi i kreće na gospodara {1}.
|
||||
msg.wave_on_master = Val {0}: {1} junaka maršira na gospodara {2}.
|
||||
hud.rival1 = Zeleni
|
||||
hud.rival2 = Plava
|
||||
msg.creature_freed = Raskida okove i pridružuje ti se: {0}!
|
||||
|
||||
@@ -707,6 +707,8 @@ msg.rival2_out = Lady Nightwell legyőzve - a lélekmagja darabokra tört!
|
||||
msg.rival_unit_slain = Elesett egy rivális mester lénye: {0}! +{1} arany.
|
||||
msg.wave_on_rival1 = {0}. hullám: {1} hős vonul a zöld mester ellen.
|
||||
msg.wave_on_rival2 = {0}. hullám: {1} hős vonul a kék mester ellen.
|
||||
msg.wave_warn_on_master = A felderítők jelentik: a(z) {0}. hősroham 30 másodperc múlva érkezik, és {1} mester ellen vonul.
|
||||
msg.wave_on_master = {0}. roham: {1} hős vonul {2} mester ellen.
|
||||
hud.rival1 = Zöld
|
||||
hud.rival2 = Kék
|
||||
msg.creature_freed = Széttépi a láncait, és hozzád csatlakozik: {0}!
|
||||
|
||||
@@ -702,6 +702,8 @@ msg.rival2_out = Lady Nightwell è sconfitta - il suo nucleo dell'anima è in fr
|
||||
msg.rival_unit_slain = Cade una creatura di un maestro rivale: {0}! +{1} oro.
|
||||
msg.wave_on_rival1 = Ondata {0}: {1} eroi marciano sul maestro verde.
|
||||
msg.wave_on_rival2 = Ondata {0}: {1} eroi marciano sulla maestra blu.
|
||||
msg.wave_warn_on_master = Gli esploratori riferiscono: l'ondata {0} arriva tra 30 secondi e punta sul maestro {1}.
|
||||
msg.wave_on_master = Ondata {0}: {1} eroi marciano contro il maestro {2}.
|
||||
hud.rival1 = Verde
|
||||
hud.rival2 = Blu
|
||||
msg.creature_freed = Spezza le catene e si unisce a te: {0}!
|
||||
|
||||
@@ -707,6 +707,8 @@ msg.rival2_out = Lady Nightwell is verslagen - haar zielenkern is verbrijzeld!
|
||||
msg.rival_unit_slain = Een {0} van een rivaliserende meester valt! +{1} goud.
|
||||
msg.wave_on_rival1 = Golf {0}: {1} helden trekken op tegen de groene meester.
|
||||
msg.wave_on_rival2 = Golf {0}: {1} helden trekken op tegen de blauwe meester.
|
||||
msg.wave_warn_on_master = Verkenners melden: heldengolf {0} komt over 30 seconden en trekt naar meester {1}.
|
||||
msg.wave_on_master = Golf {0}: {1} helden trekken op tegen meester {2}.
|
||||
hud.rival1 = Groen
|
||||
hud.rival2 = Blauw
|
||||
msg.creature_freed = Een {0} breekt zijn ketens en sluit zich bij je aan!
|
||||
|
||||
@@ -706,6 +706,8 @@ msg.rival2_out = Lady Nightwell er beseiret - sjelekjernen hennes er knust!
|
||||
msg.rival_unit_slain = En {0} fra en rivaliserende mester faller! +{1} gull.
|
||||
msg.wave_on_rival1 = Bølge {0}: {1} helter marsjerer mot den grønne mesteren.
|
||||
msg.wave_on_rival2 = Bølge {0}: {1} helter marsjerer mot den blå mesteren.
|
||||
msg.wave_warn_on_master = Speidere melder: heltebølge {0} kommer om 30 sekunder og går mot mester {1}.
|
||||
msg.wave_on_master = Bølge {0}: {1} helter marsjerer mot mester {2}.
|
||||
hud.rival1 = Grønn
|
||||
hud.rival2 = Blå
|
||||
msg.creature_freed = En {0} sprenger lenkene sine og slutter seg til deg!
|
||||
|
||||
@@ -707,6 +707,8 @@ msg.rival2_out = Lady Nightwell foi derrotada - o núcleo de alma dela despedaç
|
||||
msg.rival_unit_slain = Cai um {0} de um mestre rival! +{1} de ouro.
|
||||
msg.wave_on_rival1 = Vaga {0}: {1} heróis marcham contra o mestre verde.
|
||||
msg.wave_on_rival2 = Vaga {0}: {1} heróis marcham contra a mestra azul.
|
||||
msg.wave_warn_on_master = Os batedores informam: a onda {0} chega em 30 segundos e vai contra o mestre {1}.
|
||||
msg.wave_on_master = Onda {0}: {1} heróis marcham contra o mestre {2}.
|
||||
hud.rival1 = Verde
|
||||
hud.rival2 = Azul
|
||||
msg.creature_freed = Um {0} parte as correntes e junta-se a ti!
|
||||
|
||||
@@ -707,6 +707,8 @@ msg.rival2_out = Lady Nightwell e învinsă - miezul sufletului ei s-a sfărâma
|
||||
msg.rival_unit_slain = Un {0} al unui stăpân rival cade! +{1} aur.
|
||||
msg.wave_on_rival1 = Valul {0}: {1} eroi mărșăluiesc asupra stăpânului verde.
|
||||
msg.wave_on_rival2 = Valul {0}: {1} eroi mărșăluiesc asupra stăpânei albastre.
|
||||
msg.wave_warn_on_master = Cercetașii raportează: valul de eroi {0} sosește în 30 de secunde și merge spre stăpânul {1}.
|
||||
msg.wave_on_master = Valul {0}: {1} eroi mărșăluiesc spre stăpânul {2}.
|
||||
hud.rival1 = Verde
|
||||
hud.rival2 = Albastru
|
||||
msg.creature_freed = Un {0} își rupe lanțurile și ți se alătură!
|
||||
|
||||
@@ -702,6 +702,8 @@ msg.rival2_out = Леди Найтвелл повержена - её ядро д
|
||||
msg.rival_unit_slain = Пал боец соперника: {0}! +{1} золота.
|
||||
msg.wave_on_rival1 = Волна {0}: {1} героев идут на зелёного хозяина.
|
||||
msg.wave_on_rival2 = Волна {0}: {1} героев идут на синюю хозяйку.
|
||||
msg.wave_warn_on_master = Разведчики докладывают: волна {0} будет через 30 секунд и идёт на мастера {1}.
|
||||
msg.wave_on_master = Волна {0}: {1} героев идут на мастера {2}.
|
||||
hud.rival1 = Зелёный
|
||||
hud.rival2 = Синяя
|
||||
msg.creature_freed = Существо рвёт цепи и присоединяется к тебе: {0}!
|
||||
|
||||
@@ -707,6 +707,8 @@ msg.rival2_out = Lady Nightwell je porazená - jej jadro duše sa roztrieštilo!
|
||||
msg.rival_unit_slain = Padol tvor súperiaceho majstra: {0}! +{1} zlata.
|
||||
msg.wave_on_rival1 = Vlna {0}: hrdinovia ({1}) tiahnu na zeleného majstra.
|
||||
msg.wave_on_rival2 = Vlna {0}: hrdinovia ({1}) tiahnu na modrú majsterku.
|
||||
msg.wave_warn_on_master = Prieskumníci hlásia: vlna hrdinov {0} príde o 30 sekúnd a mieri na pána {1}.
|
||||
msg.wave_on_master = Vlna {0}: {1} hrdinov pochoduje na pána {2}.
|
||||
hud.rival1 = Zelený
|
||||
hud.rival2 = Modrá
|
||||
msg.creature_freed = Tvor roztrhol reťaze a pridal sa k tebe: {0}!
|
||||
|
||||
@@ -707,6 +707,8 @@ msg.rival2_out = Лејди Најтвел је поражена - њено је
|
||||
msg.rival_unit_slain = Пало је створење супарничког господара: {0}! +{1} злата.
|
||||
msg.wave_on_rival1 = Талас {0}: хероји ({1}) марширају на зеленог господара.
|
||||
msg.wave_on_rival2 = Талас {0}: хероји ({1}) марширају на плаву господарицу.
|
||||
msg.wave_warn_on_master = Извиђачи јављају: талас јунака {0} стиже за 30 секунди и креће на господара {1}.
|
||||
msg.wave_on_master = Талас {0}: {1} јунака маршира на господара {2}.
|
||||
hud.rival1 = Зелени
|
||||
hud.rival2 = Плава
|
||||
msg.creature_freed = Раскида окове и придружује ти се: {0}!
|
||||
|
||||
@@ -707,6 +707,8 @@ msg.rival2_out = Lady Nightwell är besegrad - hennes själskärna har krossats!
|
||||
msg.rival_unit_slain = En {0} hos en rivaliserande mästare faller! +{1} guld.
|
||||
msg.wave_on_rival1 = Våg {0}: {1} hjältar marscherar mot den gröna mästaren.
|
||||
msg.wave_on_rival2 = Våg {0}: {1} hjältar marscherar mot den blå mästaren.
|
||||
msg.wave_warn_on_master = Spejare rapporterar: hjältevåg {0} kommer om 30 sekunder och går mot mästare {1}.
|
||||
msg.wave_on_master = Våg {0}: {1} hjältar marscherar mot mästare {2}.
|
||||
hud.rival1 = Grön
|
||||
hud.rival2 = Blå
|
||||
msg.creature_freed = En {0} bryter sina kedjor och ansluter sig till dig!
|
||||
|
||||
+77
-21
@@ -1700,6 +1700,13 @@ impl Game {
|
||||
self.wave_timer -= dt;
|
||||
if !self.warned && self.wave_timer < 30.0 {
|
||||
self.warned = true;
|
||||
let goal = self.wave_goal();
|
||||
if goal != self.me_side {
|
||||
// the wave will march on another master: no entry markers in this dungeon
|
||||
self.planned_entries.clear();
|
||||
self.announce_wave("msg.wave_warn", "msg.wave_warn_on_master", vec![(self.wave + 1).to_string()], goal, Sfx::WaveAlarm);
|
||||
return;
|
||||
}
|
||||
self.plan_entries();
|
||||
if self.planned_entries.is_empty() {
|
||||
self.msg("msg.wave_warn", vec![(self.wave + 1).to_string()]);
|
||||
@@ -2084,12 +2091,14 @@ impl Game {
|
||||
}
|
||||
|
||||
// Endless waves: strength 60% -> 100% of the army value, with some randomness, at least 2 knights.
|
||||
fn spawn_wave(&mut self) {
|
||||
pub(crate) fn spawn_wave(&mut self) {
|
||||
use EK::*;
|
||||
let w = self.wave + 1;
|
||||
let ratio = (0.6 + 0.05 * (w - 1) as f32).min(1.0) * (0.88 + self.rng.f() * 0.24);
|
||||
let min_value = Self::squad_value(&[(Knight, 1), (Knight, 1)]);
|
||||
let target = (self.army_value() * ratio).max(min_value);
|
||||
// the humans march on the strongest master; the wave is measured against him
|
||||
let goal = self.wave_goal();
|
||||
let target = (self.side_army(goal) * ratio).max(min_value);
|
||||
let mut pool = vec![(Knight, 4), (Archer, 3)];
|
||||
if w >= 2 {
|
||||
pool.push((Dwarf, 2));
|
||||
@@ -2110,21 +2119,20 @@ impl Game {
|
||||
self.last_wave_value = Self::squad_value(&list);
|
||||
let before = self.ents.len();
|
||||
self.spawn_squad(&list, false);
|
||||
// the humans attack everybody: now and then a rival master instead of the player
|
||||
let alive: Vec<u8> = self.rivals.iter().filter(|r| r.alive).map(|r| r.side).collect();
|
||||
if !alive.is_empty() {
|
||||
let r = (self.rng.next() as usize) % (alive.len() + 2);
|
||||
if r >= 2 {
|
||||
let side = alive[r - 2];
|
||||
for e in self.ents[before..].iter_mut() {
|
||||
e.target = Some(side);
|
||||
e.waypoint = None;
|
||||
}
|
||||
self.planned_entries.clear();
|
||||
self.sfx_ui(Sfx::WaveStart);
|
||||
self.msg(if side == 2 { "msg.wave_on_rival1" } else { "msg.wave_on_rival2" }, vec![w.to_string(), list.len().to_string()]);
|
||||
return;
|
||||
if goal != self.me_side {
|
||||
for e in self.ents[before..].iter_mut() {
|
||||
e.target = Some(goal);
|
||||
e.waypoint = None;
|
||||
}
|
||||
self.planned_entries.clear();
|
||||
let args = vec![w.to_string(), list.len().to_string()];
|
||||
if self.is_master(goal) {
|
||||
self.announce_wave("msg.wave", "msg.wave_on_master", args, goal, Sfx::WaveStart);
|
||||
} else {
|
||||
self.sfx_ui(Sfx::WaveStart);
|
||||
self.msg(if goal == 2 { "msg.wave_on_rival1" } else { "msg.wave_on_rival2" }, args);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if self.planned_entries.is_empty() {
|
||||
self.plan_entries();
|
||||
@@ -2145,12 +2153,60 @@ impl Game {
|
||||
self.entry_history.drain(0..n - 4);
|
||||
}
|
||||
}
|
||||
self.sfx_ui(Sfx::WaveStart);
|
||||
if boss.is_some() {
|
||||
self.msg("msg.wave_boss", vec![w.to_string(), list.len().to_string()]);
|
||||
} else {
|
||||
self.msg("msg.wave", vec![w.to_string(), list.len().to_string()]);
|
||||
let key = if boss.is_some() { "msg.wave_boss" } else { "msg.wave" };
|
||||
let goal = self.me_side;
|
||||
self.announce_wave(key, "msg.wave_on_master", vec![w.to_string(), list.len().to_string()], goal, Sfx::WaveStart);
|
||||
}
|
||||
|
||||
// The side a hero wave marches on: the strongest master still standing (creatures, towers and
|
||||
// gold), players and rival masters alike; ties go to the lower side.
|
||||
pub fn wave_goal(&self) -> u8 {
|
||||
let mut best = (self.me_side, f32::MIN);
|
||||
let mut sides: Vec<u8> = self.master_sides().into_iter().filter(|&s| !self.is_out(s) && self.core_hp_of(s) > 0.0).collect();
|
||||
sides.extend(self.rivals.iter().filter(|r| r.alive).map(|r| r.side));
|
||||
sides.sort_unstable();
|
||||
for s in sides {
|
||||
let gold = if self.is_master(s) { self.gold_of(s) } else { 0.0 };
|
||||
let score = self.side_army(s) + 0.05 * gold;
|
||||
if score > best.1 {
|
||||
best = (s, score);
|
||||
}
|
||||
}
|
||||
best.0
|
||||
}
|
||||
|
||||
// the fighting strength of one side, like `army_value`: its creatures and (half) its towers
|
||||
pub fn side_army(&self, side: u8) -> f32 {
|
||||
let owner = Owner::of_side(side);
|
||||
let (mut h, mut d) = (0.0, 0.0);
|
||||
for e in &self.ents {
|
||||
if e.alive && !e.hero && !e.chained && e.kind != EK::Worker && e.side() == side {
|
||||
h += e.max_hp;
|
||||
d += e.atk() / st(e.kind).interval;
|
||||
}
|
||||
}
|
||||
for t in self.towers.iter().filter(|t| !t.hero && self.map.t[t.tile].owner == owner) {
|
||||
h += 0.5 * t.max_hp();
|
||||
d += 0.5 * t.dmg() / tower_stats(t.kind).interval;
|
||||
}
|
||||
(h * d).sqrt()
|
||||
}
|
||||
|
||||
// tells about a wave: the attacked master hears `key`; every other player of a match hears
|
||||
// `other` (with the attacked master's colour as last argument). A wave on a rival master is
|
||||
// told to the player like a normal warning.
|
||||
fn announce_wave(&mut self, key: &'static str, other: &'static str, args: Vec<String>, goal: u8, sfx: Sfx) {
|
||||
if !self.is_master(goal) || self.netplay.is_none() || self.local_side == goal {
|
||||
let me = self.me_side;
|
||||
self.switch_to(goal);
|
||||
self.msg(key, args);
|
||||
self.sfx_ui(sfx);
|
||||
self.switch_to(me);
|
||||
return;
|
||||
}
|
||||
let mut a = args;
|
||||
a.push(format!("@net.side{goal}"));
|
||||
self.tell_local(other, a, Some(sfx));
|
||||
}
|
||||
|
||||
// defenders at 75 / 50 / 25 % gate HP
|
||||
|
||||
+1
-1
@@ -152,7 +152,7 @@ impl Game {
|
||||
}
|
||||
|
||||
// a message and a sound for the player at this computer, whichever master is being processed
|
||||
fn tell_local(&mut self, key: &'static str, args: Vec<String>, sfx: Option<crate::game::Sfx>) {
|
||||
pub(crate) fn tell_local(&mut self, key: &'static str, args: Vec<String>, sfx: Option<crate::game::Sfx>) {
|
||||
let me = self.me_side;
|
||||
let local = self.local_side;
|
||||
self.switch_to(local);
|
||||
|
||||
@@ -507,4 +507,35 @@ mod tests {
|
||||
}
|
||||
assert!(fought, "heroes fight the rival master");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hero_waves_march_on_the_strongest_master() {
|
||||
let mut g = (1..200u32).map(|s| Game::new_free(s, 160, 160, 1)).find(|g| g.rivals.len() == 1 && g.gate_on).unwrap();
|
||||
let side = g.rivals[0].side;
|
||||
let (rx, ry) = g.rivals[0].centre();
|
||||
let army = |g: &mut Game, side: u8, x: f32, y: f32, n: usize| {
|
||||
for k in 0..n {
|
||||
let id = g.spawn(EK::Ogre, false, x + k as f32 * 0.2, y, 6);
|
||||
if let Some(e) = g.ents.iter_mut().find(|e| e.id == id) {
|
||||
e.side = side;
|
||||
}
|
||||
}
|
||||
};
|
||||
// the rival master is far stronger: the wave marches on him and is measured against him
|
||||
g.gold = 0.0;
|
||||
army(&mut g, side, rx, ry + 2.0, 8);
|
||||
assert_eq!(g.wave_goal(), side);
|
||||
let before = g.ents.len();
|
||||
g.spawn_wave();
|
||||
let heroes: Vec<&Ent> = g.ents[before..].iter().filter(|e| e.hero).collect();
|
||||
assert!(!heroes.is_empty());
|
||||
assert!(heroes.iter().all(|e| e.target == Some(side)), "the wave marches on the rival");
|
||||
// now the player is the strongest: the next wave comes for him
|
||||
let (cx, cy) = g.map.core;
|
||||
army(&mut g, 0, cx as f32 + 1.5, cy as f32 + 4.0, 20);
|
||||
assert_eq!(g.wave_goal(), 0);
|
||||
let before = g.ents.len();
|
||||
g.spawn_wave();
|
||||
assert!(g.ents[before..].iter().filter(|e| e.hero).all(|e| e.target.is_none()), "the wave comes for the player");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user