Keep radar-controlled gun accuracy independent of darkness
This commit is contained in:
@@ -97,7 +97,8 @@ CI: `.gitea/workflows/build.yml` на каждый пуш собирает то
|
||||
перенацеливает ещё не взлетевшие Ланцеты и Шахеды на них; если цель-комплекс уничтожен, дроны идут к
|
||||
следующему известному. Дроны под обстрелом прижимаются к земле.
|
||||
|
||||
**Ночь.** Ночью пушки попадают втрое хуже, если цель не освещена. Освещают **прожекторы** (луч ведёт ближайшую
|
||||
**Ночь.** Исправные пушки с собственным свежим радарным сопровождением не теряют точность из-за темноты.
|
||||
Цели освещают **прожекторы** (луч ведёт ближайшую
|
||||
цель из сети, приоритет — цели пушек) и **осветительные ракеты**: пушечные комплексы пускают их сами (раз в
|
||||
25 с на цель в темноте), игрок — **осветительным пистолетом** или `/airdef flare`. Ракета висит ~30 с и
|
||||
освещает всё вокруг на ~60–90 м.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! Night fighting: guns aim by sight, and at night they hit far less unless
|
||||
//! the target is lit. Searchlights follow the network's tracks with their
|
||||
//! Night fighting: darkness penalizes aiming without fresh radar fire control,
|
||||
//! unless the target is lit. Searchlights follow the network's tracks with their
|
||||
//! beams; illumination flares (fired by the guns on their own, or by the
|
||||
//! player) hang over the sky for half a minute and light everything round.
|
||||
use super::*;
|
||||
@@ -24,6 +24,11 @@ pub const DARK_HITS: f64 = 0.4;
|
||||
/// Ticks between a gun's own flares.
|
||||
const FLARE_EVERY: u32 = 500;
|
||||
|
||||
/// Night only reduces a gun's hit chance when it has to aim by sight.
|
||||
pub(super) fn hit_factor(night: bool, lit: bool, radar_fire_control: bool) -> f64 {
|
||||
if night && !lit && !radar_fire_control { DARK_HITS } else { 1.0 }
|
||||
}
|
||||
|
||||
pub struct Flare {
|
||||
id: u32,
|
||||
pub pos: DVec3,
|
||||
|
||||
@@ -2728,8 +2728,11 @@ impl Sim {
|
||||
let event = if sam.kind == SamKind::Pantsir { "airdef:gun.pantsir" } else { "airdef:gun.gepard" };
|
||||
out.sound(event, mount, 1.0, 0.95 + self.vis.f() as f32 * 0.1);
|
||||
}
|
||||
// At night a gun sees what is lit (a searchlight, a flare) and little else.
|
||||
let dark = if self.night && !self.lit.contains(&t.id) { lights::DARK_HITS } else { 1.0 };
|
||||
// A fresh working own-radar fire-control track does not depend on seeing the target.
|
||||
// Guns without that radar picture still take the darkness penalty unless illuminated.
|
||||
let radar_fire_control = sam.radar_up()
|
||||
&& sam.track(gt).is_some_and(|tr| tr.own_within(now, sight::GUN_AGE));
|
||||
let dark = lights::hit_factor(self.night, self.lit.contains(&t.id), radar_fire_control);
|
||||
// The aim point is the track's forecast: the farther it is from the truth, the more shells miss.
|
||||
let off = est.distance(t.pos);
|
||||
let p = gun.p * sam.gun_fit() * dark / (t.kind.spec().stealth * (1.0 + (off / 8.0).powi(2))) * (1.0 - dist / (gun.range * 1.3)).max(0.35);
|
||||
|
||||
@@ -181,6 +181,34 @@ fn a_close_blast_can_leave_a_firing_but_immobile_system() {
|
||||
assert!(found, "no seed left it firing but immobile");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_fresh_own_radar_track_keeps_gun_hits_equal_day_and_night() {
|
||||
fn firing(seed: u64, night: bool) -> (u32, u32) {
|
||||
let mut sim = Sim::new(seed);
|
||||
let (mut ground, mut out) = flat();
|
||||
let gun = radar_at(&mut sim, SamKind::Gepard, 0.0);
|
||||
sim.night = night;
|
||||
sim.add_drone(
|
||||
DroneKind::Shahed,
|
||||
DVec3::new(0.0, 95.0, 35.0),
|
||||
DVec3::ZERO,
|
||||
DVec3::new(5000.0, 95.0, 35.0),
|
||||
);
|
||||
let starting_bursts = sim.sams[gun].bursts;
|
||||
for _ in 0..240 {
|
||||
sim.step(&mut ground, None, &mut out);
|
||||
}
|
||||
(starting_bursts - sim.sams[gun].bursts, sim.sams[gun].kills)
|
||||
}
|
||||
|
||||
for seed in 0..32 {
|
||||
let day = firing(seed, false);
|
||||
let night = firing(seed, true);
|
||||
assert!(day.0 > 0, "seed {seed} did not fire");
|
||||
assert_eq!(night, day, "seed {seed}: radar gun changed its fire or kills at night");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn failed_parts_block_what_they_serve_and_repair_restores_them() {
|
||||
let mut sim = Sim::new(2);
|
||||
|
||||
Reference in New Issue
Block a user