Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 90379f6e17 |
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(¢re) = 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()
|
||||
|
||||
@@ -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
@@ -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])
|
||||
|
||||
Reference in New Issue
Block a user