Add persisted radar emission switch
Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
@@ -30,6 +30,7 @@ pub struct SamRec {
|
||||
pub mode: sim::battery::SamMode,
|
||||
pub radar_role: sim::battery::RadarRole,
|
||||
pub spent_cells: u8,
|
||||
pub radar_on: bool,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -141,6 +142,7 @@ impl Layout {
|
||||
};
|
||||
let ground_request = l.num(28, "заявка RM48U", 0.0, 1.0)?.unwrap_or(0.0) == 1.0;
|
||||
if ground_request && kind != SamKind::S400 { return Err(l.bad("заявка RM48U", "нужен С-400")); }
|
||||
let radar_on = l.flag(29, "излучение РЛС")?.unwrap_or(true);
|
||||
if radar_role != sim::battery::RadarRole::Multifunction && kind != SamKind::Radar {
|
||||
return Err(l.bad("роль РЛС", "роль поддерживается только отдельной РЛС"));
|
||||
}
|
||||
@@ -153,7 +155,7 @@ impl Layout {
|
||||
if let Some((m, _, _, _)) = ammo && m + ground_rounds > 4 && kind == SamKind::S400 {
|
||||
return Err(l.bad("боезапас", "больше четырёх ячеек"));
|
||||
}
|
||||
out.sams.push(SamRec { kind, pos, heading, roles, health, cargo, ammo, dest, comps, ground_rounds, ground_stock, air_48n6_stock, mode, radar_role, spent_cells, ground_request });
|
||||
out.sams.push(SamRec { kind, pos, heading, roles, health, cargo, ammo, dest, comps, ground_rounds, ground_stock, air_48n6_stock, mode, radar_role, spent_cells, ground_request, radar_on });
|
||||
}
|
||||
"target" => {
|
||||
if out.targets.len() >= MAX_UNITS {
|
||||
|
||||
+13
-4
@@ -897,7 +897,7 @@ impl AirDef {
|
||||
let comps = if fresh { new.comps } else { s.comps };
|
||||
let parts = comps.0.iter().map(|v| format!("{v:.3}")).collect::<Vec<_>>().join(" ");
|
||||
text += &format!(
|
||||
"sam {} {} {} {} {} {} {} {} {} {} {} {} {dest} {parts} {} {} {} {} {} {} {}\n",
|
||||
"sam {} {} {} {} {} {} {} {} {} {} {} {} {dest} {parts} {} {} {} {} {} {} {} {}\n",
|
||||
s.kind.key(),
|
||||
s.pos.x,
|
||||
s.pos.y,
|
||||
@@ -910,7 +910,7 @@ impl AirDef {
|
||||
bursts,
|
||||
u8::from(empty),
|
||||
reloading,
|
||||
s.ground_rounds, s.ground_stock, s.air_48n6_stock, s.mode.key(), s.radar_role.key(), if fresh { 0 } else { s.spent_cells }, u8::from(!fresh && s.ground_request),
|
||||
s.ground_rounds, s.ground_stock, s.air_48n6_stock, s.mode.key(), s.radar_role.key(), if fresh { 0 } else { s.spent_cells }, u8::from(!fresh && s.ground_request), s.radar_on,
|
||||
);
|
||||
}
|
||||
for (i, t) in self.sim.targets.iter().enumerate() {
|
||||
@@ -1025,6 +1025,7 @@ impl AirDef {
|
||||
sam.fit_cells();
|
||||
sam.set_mode(r.mode);
|
||||
sam.set_radar_role(r.radar_role);
|
||||
sam.radar_on = r.radar_on;
|
||||
sam.spent_cells = r.spent_cells;
|
||||
sam.sync_tube_cells();
|
||||
self.sim.sams.push(sam);
|
||||
@@ -1120,7 +1121,7 @@ fn durable_mark(sim: &Sim) -> u64 {
|
||||
let ammo = u64::from(s.missiles) | u64::from(s.bursts) << 16 | u64::from(s.cargo) << 32 | u64::from(s.empty) << 48 | u64::from(s.reloading > 0) << 49;
|
||||
let typed = u64::from(s.ground_rounds) ^ u64::from(s.ground_stock).rotate_left(17) ^ u64::from(s.air_48n6_stock).rotate_left(39) ^ u64::from(s.ground_request).rotate_left(55);
|
||||
let parts = s.comps.0.iter().fold(0u64, |a, v| a.wrapping_mul(131).wrapping_add((v * 100.0) as u64));
|
||||
((s.health * 1000.0) as u64).wrapping_mul(1_000_003) ^ place ^ ammo.rotate_left(7) ^ parts.rotate_left(13) ^ typed.rotate_left(29) ^ (s.mode as u64).rotate_left(3) ^ (s.radar_role as u64).rotate_left(11) ^ u64::from(s.spent_cells).rotate_left(19)
|
||||
((s.health * 1000.0) as u64).wrapping_mul(1_000_003) ^ place ^ ammo.rotate_left(7) ^ parts.rotate_left(13) ^ typed.rotate_left(29) ^ (s.mode as u64).rotate_left(3) ^ (s.radar_role as u64).rotate_left(11) ^ u64::from(s.spent_cells).rotate_left(19) ^ u64::from(s.radar_on).rotate_left(23)
|
||||
})
|
||||
.chain(sim.target_health.iter().map(|h| (h * 10.0) as u64))
|
||||
.fold(sim.sams.len() as u64, |a, h| a.wrapping_mul(31).wrapping_add(h))
|
||||
@@ -2278,7 +2279,7 @@ impl Mod for AirDef {
|
||||
["battery"] => {
|
||||
let status = self.sim.battery_status();
|
||||
for line in &status { say(line); }
|
||||
Some("/airdef battery <номер> integrated|launcher; /airdef radar <номер> multi|search|engagement|height".into())
|
||||
Some("/airdef battery <номер> integrated|launcher; /airdef radar <номер> on|off|multi|search|engagement|height".into())
|
||||
}
|
||||
["battery", n, mode] => {
|
||||
let i = n.parse::<usize>().ok().and_then(|n| n.checked_sub(1)).ok_or("Нужен номер комплекса")?;
|
||||
@@ -2288,6 +2289,14 @@ impl Mod for AirDef {
|
||||
self.dirty = true;
|
||||
Some(format!("№{} {}: режим {}", i + 1, sam.kind.name(), mode.key()))
|
||||
}
|
||||
["radar", n, state @ ("on" | "off")] => {
|
||||
let i = n.parse::<usize>().ok().and_then(|n| n.checked_sub(1)).ok_or("Нужен номер комплекса")?;
|
||||
let sam = self.sim.sams.get_mut(i).ok_or("Нет такого комплекса")?;
|
||||
if sam.kind.spec().sensor <= 0.0 || sam.mode == sim::battery::SamMode::LauncherOnly { return Err("У комплекса нет активной РЛС".into()); }
|
||||
sam.radar_on = *state == "on";
|
||||
self.dirty = true;
|
||||
Some(format!("№{} {}: излучение РЛС {}", i + 1, sam.kind.name(), state))
|
||||
}
|
||||
["radar", n, role] => {
|
||||
let i = n.parse::<usize>().ok().and_then(|n| n.checked_sub(1)).ok_or("Нужен номер РЛС")?;
|
||||
let role = sim::battery::RadarRole::from_key(role).ok_or("Роль: multi, search, engagement или height")?;
|
||||
|
||||
@@ -1364,6 +1364,8 @@ pub struct Sam {
|
||||
pub kind: SamKind,
|
||||
pub mode: battery::SamMode,
|
||||
pub radar_role: battery::RadarRole,
|
||||
/// Player-controlled active radar emission; independent of component health and data link.
|
||||
pub radar_on: bool,
|
||||
pub spent_cells: u8,
|
||||
preparing: Option<launch::Prepare>,
|
||||
cap_cell: u8,
|
||||
@@ -1458,6 +1460,7 @@ impl Sam {
|
||||
kind,
|
||||
mode: battery::SamMode::Integrated,
|
||||
radar_role: battery::RadarRole::Multifunction,
|
||||
radar_on: true,
|
||||
spent_cells: 0,
|
||||
preparing: None,
|
||||
cap_cell: 0,
|
||||
|
||||
@@ -25,6 +25,7 @@ pub struct SamKey {
|
||||
parts: [f32; 6],
|
||||
mode: battery::SamMode,
|
||||
radar_role: battery::RadarRole,
|
||||
radar_on: bool,
|
||||
spent_cells: u8,
|
||||
cap_cell: u8,
|
||||
cap_open: f32,
|
||||
@@ -45,6 +46,7 @@ impl SamKey {
|
||||
parts: sam.comps.0.map(|v| v as f32),
|
||||
mode: sam.mode,
|
||||
radar_role: sam.radar_role,
|
||||
radar_on: sam.radar_on,
|
||||
spent_cells: sam.spent_cells,
|
||||
cap_cell: sam.cap_cell,
|
||||
cap_open: sam.cap_open,
|
||||
@@ -61,7 +63,7 @@ impl SamKey {
|
||||
&& self.beam == o.beam
|
||||
&& self.health == o.health
|
||||
&& self.parts == o.parts
|
||||
&& self.mode == o.mode && self.radar_role == o.radar_role
|
||||
&& self.mode == o.mode && self.radar_role == o.radar_role && self.radar_on == o.radar_on
|
||||
&& self.spent_cells == o.spent_cells && self.cap_cell == o.cap_cell
|
||||
&& near(self.cap_open, o.cap_open, 0.001)
|
||||
}
|
||||
@@ -108,6 +110,7 @@ impl SamTrack {
|
||||
parts: a.parts,
|
||||
mode: a.mode,
|
||||
radar_role: a.radar_role,
|
||||
radar_on: a.radar_on,
|
||||
spent_cells: a.spent_cells,
|
||||
cap_cell: a.cap_cell,
|
||||
cap_open: if a.cap_cell == b.cap_cell && a.spent_cells == b.spent_cells { l(a.cap_open, b.cap_open) } else { a.cap_open },
|
||||
@@ -127,6 +130,7 @@ impl SamTrack {
|
||||
sam.comps = Comps(k.parts.map(|v| v as f64));
|
||||
sam.mode = k.mode;
|
||||
sam.radar_role = k.radar_role;
|
||||
sam.radar_on = k.radar_on;
|
||||
sam.spent_cells = k.spent_cells;
|
||||
sam.cap_cell = k.cap_cell;
|
||||
sam.cap_open = k.cap_open;
|
||||
|
||||
@@ -327,7 +327,7 @@ impl Sam {
|
||||
}
|
||||
/// Its own radar works: it has one, it is not failed and the unit is deployed.
|
||||
pub fn radar_up(&self) -> bool {
|
||||
self.mode != battery::SamMode::LauncherOnly && self.alive() && !self.moving() && self.kind.spec().sensor > 0.0 && self.part(Part::Sensor) > 0.0
|
||||
self.radar_on && self.mode != battery::SamMode::LauncherOnly && self.alive() && !self.moving() && self.kind.spec().sensor > 0.0 && self.part(Part::Sensor) > 0.0
|
||||
}
|
||||
pub fn track(&self, id: u32) -> Option<&Track> {
|
||||
self.tracks.iter().find(|t| t.id == id)
|
||||
|
||||
Reference in New Issue
Block a user