Compare commits

..

1 Commits

8 changed files with 38 additions and 13 deletions
+3 -3
View File
@@ -674,7 +674,7 @@ impl AirDef {
}
_ => replay::Mode::Map,
};
self.replay = Some(replay::Player::new(n - 1, mode, &self.sim));
self.replay = Some(replay::Player::new(rec.number, mode, &self.sim));
self.grid = false;
input::claim_wheel(true);
Ok(())
@@ -947,7 +947,7 @@ impl Mod for AirDef {
_ => replay::Control::Pause,
};
if let Some(r) = &mut self.replay
&& let Some(rec) = self.sim.replays.get(r.rec)
&& let Some(rec) = self.sim.replay(r.rec)
{
r.control(c, rec);
}
@@ -964,7 +964,7 @@ impl Mod for AirDef {
}
Event::Wheel(w) => {
if let Some(r) = &mut self.replay
&& let Some(rec) = self.sim.replays.get(r.rec)
&& let Some(rec) = self.sim.replay(r.rec)
{
r.wheel(w, rec);
}
+5 -5
View File
@@ -31,8 +31,8 @@ pub struct Clip {
}
pub struct Player {
/// Which of the sim's recordings.
pub rec: usize,
/// Which raid's recording (its number: the list drops the oldest as new ones come).
pub rec: u32,
pub mode: Mode,
t: f64,
speed: f64,
@@ -188,7 +188,7 @@ pub fn reel(rec: &Recording) -> Vec<Clip> {
}
impl Player {
pub fn new(rec: usize, mode: Mode, sim: &Sim) -> Self {
pub fn new(rec: u32, mode: Mode, sim: &Sim) -> Self {
let start = match &mode {
Mode::Clips { list, .. } => list.first().map_or(0.0, |c| c.from),
_ => 0.0,
@@ -291,7 +291,7 @@ impl Player {
/// One tick: time runs, the ghosts fly, the director films. Models and sounds go to `out`.
pub fn tick(&mut self, sim: &Sim, listener: DVec3, out: &mut Out) {
let Some(rec) = sim.replays.get(self.rec) else {
let Some(rec) = sim.replay(self.rec) else {
self.done = true;
return;
};
@@ -491,7 +491,7 @@ impl Player {
/// The replay's screen: the film with its titles, or the map.
pub fn hud(&self, sim: &Sim, (gw, gh): (f32, f32)) -> Vec<Shape> {
let Some(rec) = sim.replays.get(self.rec) else { return Vec::new() };
let Some(rec) = sim.replay(self.rec) else { return Vec::new() };
if matches!(self.mode, Mode::Map) {
return self.map(rec, gw, gh);
}
+4
View File
@@ -179,6 +179,10 @@ impl Sim {
sam.burn = 0;
sam.state = SamState::Search;
sam.reloading = 0;
sam.empty = false;
// Rebuilt where it stands: a march under way is called off.
sam.dest = None;
sam.march = 0;
sam.missiles = spec.missile.as_ref().map_or(0, |m| m.magazine);
sam.bursts = spec.gun.as_ref().map_or(0, |g| g.bursts);
}
+4 -2
View File
@@ -113,11 +113,13 @@ impl Sim {
self.lit.push(t);
}
let mut along = 1.0;
for k in 0..10u32 {
// Up to 14 segments (the unit's part ids 2..15), each longer than the last: one
// reaches about 550 blocks, past the beam's reach, about 9 blocks wide out there.
for k in 0..14u32 {
if along >= reach {
break;
}
let size = 0.8 + along * 0.025;
let size = 0.8 + along * 0.12;
let len = 3.0 * size;
out.model(id + 2 + k, "airdef:beam", head + dir * (along + len / 2.0), rot, size, true);
along += len;
+5 -1
View File
@@ -1272,6 +1272,10 @@ impl Sim {
self.queue.clear();
self.plan = None;
self.wave = None;
// Ammunition still to cook off, flares in the sky.
self.later.clear();
self.flares.clear();
self.lit.clear();
}
/// One game tick.
@@ -1845,7 +1849,7 @@ impl Sim {
};
for b in barrels {
let muzzle = mount + rot * *b * s;
let dir = (lead - muzzle).normalize();
let dir = (lead - muzzle).normalize_or(DVec3::NEG_Z);
let len = muzzle.distance(lead).min(gun.range * 1.2);
// Every round is a red tracer flying out at the shell's speed.
let scatter = DVec3::new(self.rng.s(), self.rng.s(), self.rng.s()) * 0.012;
+7 -1
View File
@@ -195,6 +195,11 @@ impl Sim {
/// (each route found in full, a few a tick) and launched when its plan is ready.
pub fn order_raid(&mut self, order: &RaidOrder, objects: &[DVec3], out: &mut Out) -> u32 {
let Some(&centre) = objects.first() else { return 0 };
// One raid is planned at a time: another order waits for this one's drones to be sent.
if self.plan.is_some() {
out.messages.push("Противник ещё готовит прошлый налёт: подожди пару секунд".into());
return 0;
}
let total: u32 = order.kinds.iter().map(|k| k.1).sum();
if total == 0 {
return 0;
@@ -473,7 +478,8 @@ impl Sim {
let kills = self.kills - w.kills;
let through = self.hits - w.hits;
let launched = self.launched - w.launched;
let fired: u32 = self.sams.iter().map(|s| s.fired).sum::<u32>() - w.fired;
// A system taken away during the raid takes its count along: never below none.
let fired: u32 = self.sams.iter().map(|s| s.fired).sum::<u32>().saturating_sub(w.fired);
let lost = w.sams.saturating_sub(self.sams.iter().filter(|s| s.alive()).count());
let objects = if self.target_health.is_empty() {
String::new()
+7
View File
@@ -142,6 +142,13 @@ impl Recording {
}
}
impl Sim {
/// The recording of raid `number`, while it is kept.
pub fn replay(&self, number: u32) -> Option<&Recording> {
self.replays.iter().find(|r| r.number == number)
}
}
impl Sim {
/// Something worth a replay happened.
pub(super) fn log(&mut self, pos: DVec3, kind: EventKind) {
+3 -1
View File
@@ -80,7 +80,9 @@ def fork():
capture_output=True, text=True).stdout.strip()
if dirty:
sys.exit("horizon/: есть незакоммиченные изменения, а движок надо обновить. Закоммить или убери их и запусти снова.")
if branch == "airdef":
exists = subprocess.run(["git", "-C", FORK, "rev-parse", "--verify", "-q", "refs/heads/airdef"],
capture_output=True).returncode == 0
if exists:
print("horizon/: коммит или патчи изменились, ветка airdef пересобирается (прежняя: airdef-prev)")
run(["git", "-C", FORK, "branch", "-f", "airdef-prev", "airdef"])
run(["git", "-C", FORK, "fetch", "--quiet", "origin", commit])