Files
airdef/airdef-mod/src/sim/specs_generated.rs
T
chexit 1261c30724 Stage the cold launch and spool every interceptor's motor (#129)
The interceptor's launch is one sequence: the cap opens, the round is
thrown out unlit and slows under linear gas drag (`cold` ticks), the motor
lights where it has reached, it turns with a growing rate while thrust
spools up (`boost` ticks), and full guidance starts only at `cold + boost`.
A rail launch lights at once but spools over the same `boost` ticks; the
electric P1-SUN has no rocket spool or plume.

S-400/500 now hold the unlit ejection for 20/24 ticks (1.00/1.20 s at
20 Hz); IRIS-T/Tor keep shorter 8-tick throws. Ignition, its sound, flame
and recorded MotorIgnition event all use the missile's current position.
The RM48U strike follows the same 20-tick choreography, counts the throw
in its flight time and starts its recorded smoke at ignition.

Maximum speed, turn, accel, pk and every collision rule are unchanged.

Co-Authored-By: Kimi Code <noreply@kimi.com>
2026-11-06 13:35:35 +03:00

543 lines
13 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Generated by tools/gen_catalog.py from catalog/specs.json. Do not edit.
// Game-scale values, not real weapon data; the catalog is the only copy.
/// Share of the old slew speed a launcher keeps when it has no rate of its own.
const DRIVE_SCALE: f64 = 0.4;
/// Ticks a drive takes to reach its top speed (and to stop from it).
const DRIVE_RAMP: f64 = 8.0;
const DRIVE_TRAINABLE: (f64, f64) = (0.12, 0.0);
const DRIVE_VERTICAL: (f64, f64) = (0.15, 0.0);
const DRIVE_OTHER: (f64, f64) = (0.05, 0.05);
/// Ballistic flight's gravity, blocks a tick².
const GRAVITY: f64 = 0.05;
/// Height over the target where the Oreshnik's blocks release their submunitions.
const BLOCK_SPLIT: f64 = 300.0;
/// How near a depot a system reloads straight from it.
const DEPOT_REACH: f64 = 60.0;
/// How near a truck must come to hand a reload over, or to load up at a depot.
const HANDOVER: f64 = 10.0;
/// What a truck carries.
const TRUCK_LOAD: u32 = 2;
const STOCK_LIMIT: u32 = 1000000;
const DRONE_SPEC_SHAHED: DroneSpec = DroneSpec {
name: "Шахед-136",
key: "shahed",
model: "airdef:shahed",
speed: 0.6,
turn: 0.035,
cruise: 45.0,
clearance: 18.0,
dive: 32.0,
warhead: 3,
scale: 1.3,
engine: Engine::Prop(1.34, 1.0),
decoy: false,
stealth: 1.0,
rcs: 0.3,
sound: (sound::DRONE_SHAHED, 1.0, 48),
class: Class::Drone,
ballistic: None,
launch_sound: sound::LAUNCH_S400_EJECT,
};
const DRONE_SPEC_GERAN3: DroneSpec = DroneSpec {
name: "Герань-3",
key: "geran3",
model: "airdef:geran3",
speed: 1.6,
turn: 0.03,
cruise: 60.0,
clearance: 18.0,
dive: 50.0,
warhead: 2,
scale: 1.15,
engine: Engine::Jet(0.34, 1.55, 1.0),
decoy: false,
stealth: 1.1,
rcs: 0.4,
sound: (sound::DRONE_GERAN3, 1.0, 40),
class: Class::Jet,
ballistic: None,
launch_sound: sound::LAUNCH_S400_EJECT,
};
const DRONE_SPEC_LANCET: DroneSpec = DroneSpec {
name: "Ланцет-3",
key: "lancet",
model: "airdef:lancet",
speed: 1.1,
turn: 0.07,
cruise: 25.0,
clearance: 10.0,
dive: 38.0,
warhead: 1,
scale: 0.9,
engine: Engine::Prop(0.93, 0.55),
decoy: false,
stealth: 1.4,
rcs: 0.08,
sound: (sound::DRONE_LANCET, 1.0, 32),
class: Class::Drone,
ballistic: None,
launch_sound: sound::LAUNCH_S400_EJECT,
};
const DRONE_SPEC_GERBERA: DroneSpec = DroneSpec {
name: "Гербера",
key: "gerbera",
model: "airdef:gerbera",
speed: 0.5,
turn: 0.04,
cruise: 40.0,
clearance: 15.0,
dive: 30.0,
warhead: 0,
scale: 1.1,
engine: Engine::Prop(1.03, 0.9),
decoy: true,
stealth: 0.9,
rcs: 0.4,
sound: (sound::DRONE_SHAHED, 1.3, 40),
class: Class::Drone,
ballistic: None,
launch_sound: sound::LAUNCH_S400_EJECT,
};
const DRONE_SPEC_KH101: DroneSpec = DroneSpec {
name: "Х-101",
key: "kh101",
model: "airdef:kh101",
speed: 2.4,
turn: 0.025,
cruise: 0.0,
clearance: 12.0,
dive: 26.0,
warhead: 6,
scale: 1.6,
engine: Engine::Jet(-0.27, 1.4, 0.6),
decoy: false,
stealth: 1.5,
rcs: 0.05,
sound: (sound::DRONE_CRUISE, 1.0, 50),
class: Class::Cruise,
ballistic: None,
launch_sound: sound::LAUNCH_PATRIOT,
};
const DRONE_SPEC_KALIBR: DroneSpec = DroneSpec {
name: "Калибр",
key: "kalibr",
model: "airdef:kalibr",
speed: 2.1,
turn: 0.025,
cruise: 0.0,
clearance: 15.0,
dive: 26.0,
warhead: 5,
scale: 1.5,
engine: Engine::Jet(-0.2, 1.5, 0.6),
decoy: false,
stealth: 1.3,
rcs: 0.15,
sound: (sound::DRONE_CRUISE, 1.2, 50),
class: Class::Cruise,
ballistic: None,
launch_sound: sound::LAUNCH_PATRIOT,
};
const DRONE_SPEC_KH22: DroneSpec = DroneSpec {
name: "Х-22",
key: "kh22",
model: "airdef:kh22",
speed: 4.0,
turn: 0.03,
cruise: 140.0,
clearance: 40.0,
dive: 150.0,
warhead: 7,
scale: 1.8,
engine: Engine::Rocket(1.5, 1.3),
decoy: false,
stealth: 1.4,
rcs: 1.0,
sound: (sound::DRONE_ROCKET, 0.8, 46),
class: Class::Supersonic,
ballistic: None,
launch_sound: sound::LAUNCH_PATRIOT,
};
const DRONE_SPEC_ZIRCON: DroneSpec = DroneSpec {
name: "Циркон",
key: "zircon",
model: "airdef:zircon",
speed: 5.5,
turn: 0.025,
cruise: 90.0,
clearance: 30.0,
dive: 110.0,
warhead: 6,
scale: 1.4,
engine: Engine::Rocket(1.5, 1.1),
decoy: false,
stealth: 2.0,
rcs: 0.4,
sound: (sound::DRONE_ROCKET, 1.35, 46),
class: Class::Supersonic,
ballistic: None,
launch_sound: sound::LAUNCH_S400,
};
const DRONE_SPEC_ISKANDER: DroneSpec = DroneSpec {
name: "Искандер-М",
key: "iskander",
model: "airdef:iskander",
speed: 5.0,
turn: 0.04,
cruise: 0.0,
clearance: 0.0,
dive: 0.0,
warhead: 8,
scale: 1.8,
engine: Engine::Rocket(1.5, 1.6),
decoy: false,
stealth: 1.6,
rcs: 0.6,
sound: (sound::DRONE_ROCKET, 0.7, 46),
class: Class::Ballistic,
ballistic: Some(1000.0),
launch_sound: sound::LAUNCH_S500,
};
const DRONE_SPEC_KINZHAL: DroneSpec = DroneSpec {
name: "Кинжал",
key: "kinzhal",
model: "airdef:kinzhal",
speed: 7.5,
turn: 0.03,
cruise: 0.0,
clearance: 0.0,
dive: 0.0,
warhead: 8,
scale: 1.7,
engine: Engine::Rocket(1.5, 1.5),
decoy: false,
stealth: 2.2,
rcs: 0.5,
sound: (sound::DRONE_ROCKET, 0.6, 46),
class: Class::Ballistic,
ballistic: Some(1500.0),
launch_sound: sound::LAUNCH_S500,
};
const DRONE_SPEC_ORESHNIK: DroneSpec = DroneSpec {
name: "Орешник",
key: "oreshnik",
model: "airdef:iskander",
speed: 9.0,
turn: 0.0,
cruise: 0.0,
clearance: 0.0,
dive: 0.0,
warhead: 0,
scale: 2.6,
engine: Engine::Rocket(1.5, 2.4),
decoy: false,
stealth: 3.0,
rcs: 2.0,
sound: (sound::DRONE_ROCKET, 0.5, 46),
class: Class::Ballistic,
ballistic: Some(2600.0),
launch_sound: sound::LAUNCH_S500,
};
const DRONE_SPEC_ORESHNIKBLOCK: DroneSpec = DroneSpec {
name: "Орешник: блок",
key: "oreshnik_block",
model: "airdef:reentry",
speed: 9.0,
turn: 0.0,
cruise: 0.0,
clearance: 0.0,
dive: 0.0,
warhead: 4,
scale: 1.6,
engine: Engine::Rocket(1.0, 1.0),
decoy: false,
stealth: 3.5,
rcs: 0.4,
sound: (sound::DRONE_BALLISTIC, 0.8, 9999),
class: Class::Ballistic,
ballistic: None,
launch_sound: sound::LAUNCH_S500,
};
const DRONE_SPEC_ORESHNIKSUB: DroneSpec = DroneSpec {
name: "Орешник: суббоеприпас",
key: "oreshnik_sub",
model: "airdef:reentry",
speed: 9.0,
turn: 0.05,
cruise: 0.0,
clearance: 0.0,
dive: 0.0,
warhead: 3,
scale: 1.1,
engine: Engine::Rocket(1.0, 1.0),
decoy: false,
stealth: 4.0,
rcs: 0.08,
sound: (sound::DRONE_BALLISTIC, 1.0, 9999),
class: Class::Ballistic,
ballistic: None,
launch_sound: sound::LAUNCH_S500,
};
const MISSILE_SPEC_PAC3: MissileSpec = MissileSpec {
model: "airdef:pac3",
speed: 5.5,
accel: 0.35,
turn: 0.3,
boost: 8,
cold: 0,
eject: 0.0,
eject_drag: 0.0,
pk: 0.9,
fuse: 4.0,
life: 240,
scale: 1.0,
flame: 1.0,
rear: 28.0,
seeker: 110.0,
launch_sound: sound::LAUNCH_PATRIOT,
voice: (sound::MISSILE_FLIGHT, 1.0, 1.0),
};
const MISSILE_SPEC_M57E6: MissileSpec = MissileSpec {
model: "airdef:m57e6",
speed: 5.0,
accel: 0.5,
turn: 0.32,
boost: 5,
cold: 0,
eject: 0.0,
eject_drag: 0.0,
pk: 0.82,
fuse: 3.0,
life: 160,
scale: 0.85,
flame: 0.65,
rear: 28.0,
seeker: 0.0,
launch_sound: sound::LAUNCH_PANTSIR,
voice: (sound::MISSILE_FLIGHT, 1.0, 1.12),
};
const MISSILE_SPEC_M48N6: MissileSpec = MissileSpec {
model: "airdef:m48n6",
speed: 7.0,
accel: 0.5,
turn: 0.22,
boost: 8,
cold: 20,
eject: 2.4,
eject_drag: 0.07,
pk: 0.9,
fuse: 5.0,
life: 300,
scale: 1.5,
flame: 1.4,
rear: 30.0,
seeker: 120.0,
launch_sound: sound::LAUNCH_S400_EJECT,
voice: (sound::MISSILE_FLIGHT, 1.0, 0.88),
};
const MISSILE_SPEC_M77N6: MissileSpec = MissileSpec {
model: "airdef:m77n6",
speed: 9.0,
accel: 0.6,
turn: 0.22,
boost: 8,
cold: 24,
eject: 2.6,
eject_drag: 0.07,
pk: 0.95,
fuse: 6.0,
life: 320,
scale: 1.7,
flame: 1.6,
rear: 32.0,
seeker: 120.0,
launch_sound: sound::LAUNCH_S500_EJECT,
voice: (sound::MISSILE_FLIGHT, 1.0, 0.8),
};
const MISSILE_SPEC_IRIST: MissileSpec = MissileSpec {
model: "airdef:irist_missile",
speed: 7.0,
accel: 0.5,
turn: 0.35,
boost: 6,
cold: 8,
eject: 1.8,
eject_drag: 0.1,
pk: 0.9,
fuse: 4.0,
life: 260,
scale: 0.95,
flame: 0.9,
rear: 28.0,
seeker: 90.0,
launch_sound: sound::LAUNCH_S400_EJECT,
voice: (sound::MISSILE_FLIGHT, 1.0, 1.05),
};
const MISSILE_SPEC_AMRAAM: MissileSpec = MissileSpec {
model: "airdef:amraam_missile",
speed: 6.0,
accel: 0.45,
turn: 0.3,
boost: 6,
cold: 0,
eject: 0.0,
eject_drag: 0.0,
pk: 0.85,
fuse: 4.0,
life: 260,
scale: 0.9,
flame: 0.9,
rear: 28.0,
seeker: 130.0,
launch_sound: sound::LAUNCH_PATRIOT,
voice: (sound::MISSILE_FLIGHT, 1.0, 1.05),
};
const MISSILE_SPEC_M9M317: MissileSpec = MissileSpec {
model: "airdef:m48n6",
speed: 6.5,
accel: 0.5,
turn: 0.25,
boost: 8,
cold: 0,
eject: 0.0,
eject_drag: 0.0,
pk: 0.85,
fuse: 5.0,
life: 300,
scale: 1.1,
flame: 1.2,
rear: 32.0,
seeker: 90.0,
launch_sound: sound::LAUNCH_PATRIOT,
voice: (sound::MISSILE_FLIGHT, 1.0, 0.9),
};
const MISSILE_SPEC_M9M338: MissileSpec = MissileSpec {
model: "airdef:m57e6",
speed: 5.5,
accel: 0.6,
turn: 0.4,
boost: 4,
cold: 8,
eject: 1.6,
eject_drag: 0.1,
pk: 0.9,
fuse: 3.0,
life: 160,
scale: 1.0,
flame: 0.8,
rear: 28.0,
seeker: 70.0,
launch_sound: sound::LAUNCH_S400_EJECT,
voice: (sound::MISSILE_FLIGHT, 1.0, 1.15),
};
const MISSILE_SPEC_P1SUN: MissileSpec = MissileSpec {
model: "airdef:p1sun",
speed: 2.8,
accel: 0.12,
turn: 0.3,
boost: 4,
cold: 0,
eject: 0.0,
eject_drag: 0.0,
pk: 0.8,
fuse: 3.0,
life: 900,
scale: 0.8,
flame: 0.0,
rear: 10.0,
seeker: 60.0,
launch_sound: sound::DRONE_LANCET,
voice: (sound::DRONE_LANCET, 0.8, 1.6),
};
impl DroneKind {
/// Its row of numbers from `catalog/specs.json`.
pub fn spec(self) -> &'static DroneSpec {
match self {
DroneKind::Shahed => &DRONE_SPEC_SHAHED,
DroneKind::Geran3 => &DRONE_SPEC_GERAN3,
DroneKind::Lancet => &DRONE_SPEC_LANCET,
DroneKind::Gerbera => &DRONE_SPEC_GERBERA,
DroneKind::Kh101 => &DRONE_SPEC_KH101,
DroneKind::Kalibr => &DRONE_SPEC_KALIBR,
DroneKind::Kh22 => &DRONE_SPEC_KH22,
DroneKind::Zircon => &DRONE_SPEC_ZIRCON,
DroneKind::Iskander => &DRONE_SPEC_ISKANDER,
DroneKind::Kinzhal => &DRONE_SPEC_KINZHAL,
DroneKind::Oreshnik => &DRONE_SPEC_ORESHNIK,
DroneKind::OreshnikBlock => &DRONE_SPEC_ORESHNIKBLOCK,
DroneKind::OreshnikSub => &DRONE_SPEC_ORESHNIKSUB,
}
}
}
impl MissileKind {
fn spec(self) -> &'static MissileSpec {
match self {
MissileKind::Pac3 => &MISSILE_SPEC_PAC3,
MissileKind::M57e6 => &MISSILE_SPEC_M57E6,
MissileKind::M48n6 => &MISSILE_SPEC_M48N6,
MissileKind::M77n6 => &MISSILE_SPEC_M77N6,
MissileKind::IrisT => &MISSILE_SPEC_IRIST,
MissileKind::Amraam => &MISSILE_SPEC_AMRAAM,
MissileKind::M9m317 => &MISSILE_SPEC_M9M317,
MissileKind::M9m338 => &MISSILE_SPEC_M9M338,
MissileKind::P1sun => &MISSILE_SPEC_P1SUN,
}
}
}
/// Save keys by kind; a rename needs an explicit migration.
#[cfg(test)]
pub(super) const DRONE_SPEC_KEYS: [(DroneKind, &str); 13] = [
(DroneKind::Shahed, "shahed"),
(DroneKind::Geran3, "geran3"),
(DroneKind::Lancet, "lancet"),
(DroneKind::Gerbera, "gerbera"),
(DroneKind::Kh101, "kh101"),
(DroneKind::Kalibr, "kalibr"),
(DroneKind::Kh22, "kh22"),
(DroneKind::Zircon, "zircon"),
(DroneKind::Iskander, "iskander"),
(DroneKind::Kinzhal, "kinzhal"),
(DroneKind::Oreshnik, "oreshnik"),
(DroneKind::OreshnikBlock, "oreshnik_block"),
(DroneKind::OreshnikSub, "oreshnik_sub"),
];
#[cfg(test)]
pub(super) const MISSILE_SPEC_MODELS: [(MissileKind, &str); 9] = [
(MissileKind::Pac3, "airdef:pac3"),
(MissileKind::M57e6, "airdef:m57e6"),
(MissileKind::M48n6, "airdef:m48n6"),
(MissileKind::M77n6, "airdef:m77n6"),
(MissileKind::IrisT, "airdef:irist_missile"),
(MissileKind::Amraam, "airdef:amraam_missile"),
(MissileKind::M9m317, "airdef:m48n6"),
(MissileKind::M9m338, "airdef:m57e6"),
(MissileKind::P1sun, "airdef:p1sun"),
];