Title menu background: an endless battle at a bridge over an underground river
- dungeon creatures against knights, balanced reinforcements for the weaker side - towers on both banks; heavy units go for them, destroyed towers are rebuilt after 25 s - the camera slowly circles the bridge; battle sounds stay muted; the demo is never saved Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d06ce2edb5
commit
f359671dac
3 files changed
+351
-16
No files matched your search
+27
-14
@@ -445,6 +445,8 @@ pub struct Game {
|
||||
pub gate_on: bool, // free game: the humans' gate exists
|
||||
#[serde(skip)]
|
||||
pub springs: usize, // claimed mana springs (recounted)
|
||||
#[serde(skip)]
|
||||
pub demo: Option<crate::demo::Demo>, // the endless bridge battle behind the title menu
|
||||
#[serde(default)]
|
||||
pub dwarf_caves: Vec<crate::dwarves::DwarfCave>,
|
||||
#[serde(default)]
|
||||
@@ -603,6 +605,7 @@ impl Game {
|
||||
gate_on: true,
|
||||
springs: 0,
|
||||
freed: 0,
|
||||
demo: None,
|
||||
dwarf_caves: Vec::new(),
|
||||
dwarf_t: 30.0,
|
||||
rune_free: 0,
|
||||
@@ -964,7 +967,25 @@ impl Game {
|
||||
self.fx.retain(|f| f.t < f.max);
|
||||
}
|
||||
|
||||
pub(crate) fn update_units(&mut self, dt: f32) {
|
||||
for i in 0..self.ents.len() {
|
||||
if !self.ents[i].alive || self.ents[i].held {
|
||||
continue;
|
||||
}
|
||||
let mut e = std::mem::replace(&mut self.ents[i], Ent::dummy());
|
||||
let (x0, y0) = (e.x, e.y);
|
||||
self.update_ent(&mut e, dt);
|
||||
self.turn(&mut e, x0, y0);
|
||||
self.ents[i] = e;
|
||||
}
|
||||
self.ents.retain(|e| e.alive);
|
||||
}
|
||||
|
||||
fn step(&mut self, dt: f32) {
|
||||
if self.demo.is_some() {
|
||||
self.demo_step(dt);
|
||||
return;
|
||||
}
|
||||
self.time += dt;
|
||||
self.recount();
|
||||
self.mana = (self.mana + (1.0 + SPRING_MANA * self.springs as f32) * dt).min(self.mana_max());
|
||||
@@ -1014,17 +1035,7 @@ impl Game {
|
||||
self.reinforce_corners();
|
||||
}
|
||||
self.update_contested();
|
||||
for i in 0..self.ents.len() {
|
||||
if !self.ents[i].alive || self.ents[i].held {
|
||||
continue;
|
||||
}
|
||||
let mut e = std::mem::replace(&mut self.ents[i], Ent::dummy());
|
||||
let (x0, y0) = (e.x, e.y);
|
||||
self.update_ent(&mut e, dt);
|
||||
self.turn(&mut e, x0, y0);
|
||||
self.ents[i] = e;
|
||||
}
|
||||
self.ents.retain(|e| e.alive);
|
||||
self.update_units(dt);
|
||||
self.update_towers(dt);
|
||||
if !self.rivals.is_empty() {
|
||||
self.update_rivals(dt);
|
||||
@@ -1611,6 +1622,8 @@ impl Game {
|
||||
self.sfx(Sfx::Convert, e.x, e.y);
|
||||
self.msg("msg.creature_freed", vec![format!("@{}", st(e.kind).name)]);
|
||||
}
|
||||
} else if self.demo.is_some() {
|
||||
self.demo_ai(e, dt);
|
||||
} else if e.hero && e.captive != 0 {
|
||||
self.captive_update(e, dt);
|
||||
} else if e.rival() {
|
||||
@@ -1934,7 +1947,7 @@ impl Game {
|
||||
cap.saturating_sub(used)
|
||||
}
|
||||
|
||||
fn kill(&mut self, j: usize) {
|
||||
pub(crate) fn kill(&mut self, j: usize) {
|
||||
let e = &self.ents[j];
|
||||
if e.hero && e.captive == 0 && self.prison_space() > 0 {
|
||||
// knocked out instead of killed: imps carry the hero to the torture chamber
|
||||
@@ -4064,7 +4077,7 @@ impl Game {
|
||||
}
|
||||
}
|
||||
|
||||
fn update_towers(&mut self, dt: f32) {
|
||||
pub(crate) fn update_towers(&mut self, dt: f32) {
|
||||
for k in 0..self.towers.len() {
|
||||
if k >= self.towers.len() {
|
||||
break;
|
||||
@@ -4227,7 +4240,7 @@ impl Game {
|
||||
}
|
||||
|
||||
// a hero attacks a tower; false = tower gone or unreachable
|
||||
fn attack_tower(&mut self, e: &mut Ent, id: u32, dt: f32) -> bool {
|
||||
pub(crate) fn attack_tower(&mut self, e: &mut Ent, id: u32, dt: f32) -> bool {
|
||||
let Some(k) = self.towers.iter().position(|t| t.id == id) else { return false };
|
||||
let (tx, ty) = self.towers[k].pos();
|
||||
let hit_h = self.towers[k].top() * 0.6;
|
||||
|
||||
Reference in new issue
Block a user