Co-Authored-By: Codex <noreply@openai.com>
This commit is contained in:
+14
-12
@@ -2,15 +2,17 @@
|
||||
//! tail; from afar the muffled report and a late boom), and the camera's reaction (a brief
|
||||
//! exposure and bloom punch). Everything is a function of the blast, its distance and its age, so
|
||||
//! a replay hears and sees the same as the live raid did, from the replay's camera.
|
||||
use crate::sim::catalog::sound;
|
||||
|
||||
|
||||
/// The power (0 air burst .. 4 ballistic) of a blast sound event, if it is one.
|
||||
pub fn blast_power(event: &str) -> Option<usize> {
|
||||
Some(match event {
|
||||
"airdef:blast.air" => 0,
|
||||
"airdef:blast.medium" => 1,
|
||||
"airdef:blast.big" => 2,
|
||||
"airdef:blast.heavy" => 3,
|
||||
"airdef:blast.huge" => 4,
|
||||
sound::BLAST_AIR => 0,
|
||||
sound::BLAST_MEDIUM => 1,
|
||||
sound::BLAST_BIG => 2,
|
||||
sound::BLAST_HEAVY => 3,
|
||||
sound::BLAST_HUGE => 4,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
@@ -34,7 +36,7 @@ pub const FULL: usize = 3;
|
||||
/// nearest of its tick.
|
||||
pub fn layers(power: usize, dist: f64, far: f64, gain: f32, pitch: f32, rank: usize) -> Vec<Layer> {
|
||||
let g = gain.clamp(0.3, 2.0);
|
||||
let own = ["airdef:blast.air", "airdef:blast.medium", "airdef:blast.big", "airdef:blast.heavy", "airdef:blast.huge"][power.min(4)];
|
||||
let own = [sound::BLAST_AIR, sound::BLAST_MEDIUM, sound::BLAST_BIG, sound::BLAST_HEAVY, sound::BLAST_HUGE][power.min(4)];
|
||||
let layer = |name: &str, volume: f32, pitch: f32, delay: u64| Layer { name: name.to_string(), volume, pitch, delay };
|
||||
let far_away = dist > far;
|
||||
let suffix = if far_away { "_far" } else { "" };
|
||||
@@ -45,22 +47,22 @@ pub fn layers(power: usize, dist: f64, far: f64, gain: f32, pitch: f32, rank: us
|
||||
// The muffled report, then a deep boom that arrives late.
|
||||
return vec![
|
||||
layer(&format!("{own}_far"), g, pitch, 0),
|
||||
layer("airdef:blast.big_far", 0.7 * g, pitch * 0.6, 10 + 2 * power as u64),
|
||||
layer(sound::BLAST_BIG_FAR, 0.7 * g, pitch * 0.6, 10 + 2 * power as u64),
|
||||
];
|
||||
}
|
||||
let tail = (0.45 + 0.08 * power as f32) * g;
|
||||
if power == 0 {
|
||||
// An air burst has no body of its own: the crack, the thump, the roll.
|
||||
vec![
|
||||
layer("airdef:blast.air", g, pitch * 1.12, 0),
|
||||
layer("airdef:blast.big", 0.85 * g, pitch * 0.66, 2),
|
||||
layer("airdef:blast.huge", tail, pitch * 0.5, 7),
|
||||
layer(sound::BLAST_AIR, g, pitch * 1.12, 0),
|
||||
layer(sound::BLAST_BIG, 0.85 * g, pitch * 0.66, 2),
|
||||
layer(sound::BLAST_HUGE, tail, pitch * 0.5, 7),
|
||||
]
|
||||
} else {
|
||||
vec![
|
||||
layer(own, g, pitch, 0),
|
||||
layer("airdef:blast.air", 0.7 * g, pitch * 1.15, 0),
|
||||
layer("airdef:blast.huge", tail, pitch * 0.5, 7),
|
||||
layer(sound::BLAST_AIR, 0.7 * g, pitch * 1.15, 0),
|
||||
layer(sound::BLAST_HUGE, tail, pitch * 0.5, 7),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
//! for a tick or two (a step the simulation skipped) does not stop the sound; a *cut* (a replay
|
||||
//! seek, a new shot) stops every engine and starts them again under new ids, so nothing glides
|
||||
//! across the jump.
|
||||
use crate::sim::catalog::sound;
|
||||
|
||||
use glam::DVec3;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
@@ -52,12 +54,12 @@ pub enum Op {
|
||||
/// engine_sounds_has_no_hole` finds them (after the fade-in, before the sound begins to die).
|
||||
pub fn steady_part(event: &str) -> (f32, f32) {
|
||||
match event {
|
||||
"airdef:drone.shahed" => (0.2, 2.2),
|
||||
"airdef:drone.geran3" => (0.2, 2.0),
|
||||
"airdef:drone.lancet" => (0.2, 1.4),
|
||||
"airdef:drone.cruise" => (0.2, 2.6),
|
||||
"airdef:drone.rocket" => (0.2, 2.6),
|
||||
"airdef:missile.flight" => (0.2, 2.2),
|
||||
sound::DRONE_SHAHED => (0.2, 2.2),
|
||||
sound::DRONE_GERAN3 => (0.2, 2.0),
|
||||
sound::DRONE_LANCET => (0.2, 1.4),
|
||||
sound::DRONE_CRUISE => (0.2, 2.6),
|
||||
sound::DRONE_ROCKET => (0.2, 2.6),
|
||||
sound::MISSILE_FLIGHT => (0.2, 2.2),
|
||||
_ => (0.0, 0.0),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
//! world and a director's camera (a full-screen camera view) follows them —
|
||||
//! behind the drone, then behind the interceptor or from the side — slowing
|
||||
//! time round the moment itself.
|
||||
use crate::sim::catalog::sound;
|
||||
|
||||
use crate::film::{self, Film};
|
||||
use crate::panel::distance;
|
||||
use crate::sim::Ground;
|
||||
@@ -526,11 +528,11 @@ impl Player {
|
||||
for e in rec.events.iter().filter(|e| (self.heard..self.t).contains(&(e.at as f64))) {
|
||||
let event = match e.kind {
|
||||
EventKind::Kill { kind, outcome, .. } => crate::sim::outcome::look(kind, outcome).3,
|
||||
EventKind::Hit { power, .. } | EventKind::Crash { power, .. } => ["airdef:blast.air", "airdef:blast.medium", "airdef:blast.big", "airdef:blast.heavy", "airdef:blast.huge"][(power as usize).min(4)],
|
||||
EventKind::SamLost { .. } => "airdef:blast.big",
|
||||
EventKind::Split { .. } => "airdef:boom.sonic",
|
||||
EventKind::Hit { power, .. } | EventKind::Crash { power, .. } => [sound::BLAST_AIR, sound::BLAST_MEDIUM, sound::BLAST_BIG, sound::BLAST_HEAVY, sound::BLAST_HUGE][(power as usize).min(4)],
|
||||
EventKind::SamLost { .. } => sound::BLAST_BIG,
|
||||
EventKind::Split { .. } => sound::BOOM_SONIC,
|
||||
EventKind::Strike { result: StrikeResult::Halted, .. } => continue,
|
||||
EventKind::Strike { result, .. } => ["airdef:blast.air", "airdef:blast.medium", "airdef:blast.big", "airdef:blast.heavy", "airdef:blast.huge"][match result {
|
||||
EventKind::Strike { result, .. } => [sound::BLAST_AIR, sound::BLAST_MEDIUM, sound::BLAST_BIG, sound::BLAST_HEAVY, sound::BLAST_HUGE][match result {
|
||||
StrikeResult::Destroyed => 4,
|
||||
StrikeResult::Intercepted => 0,
|
||||
_ => 3,
|
||||
@@ -539,7 +541,7 @@ impl Player {
|
||||
let gain = if let EventKind::Kill { kind, outcome, .. } = e.kind { crate::sim::outcome::look(kind, outcome).2 } else { 1.0 };
|
||||
out.sound(event, heard(e.pos), gain, 1.0);
|
||||
if let EventKind::Kill { outcome: crate::sim::outcome::Outcome::AirDetonation, .. } = e.kind {
|
||||
out.sound("airdef:boom.sonic", heard(e.pos), 0.8, 1.2);
|
||||
out.sound(sound::BOOM_SONIC, heard(e.pos), 0.8, 1.2);
|
||||
}
|
||||
}
|
||||
// New recordings carry the exact launch and ignition sounds and their actual positions.
|
||||
@@ -570,7 +572,7 @@ impl Player {
|
||||
for tr in rec.tracks.iter().filter(|tr| matches!(tr.what, What::StrikeCarrier(_))) {
|
||||
let at = tr.first as f64 + crate::sim::strike::EJECT_TICKS as f64;
|
||||
if (self.heard..self.t).contains(&at) && let Some(p) = tr.at(rec.origin, at) {
|
||||
out.sound("airdef:launch.s400", heard(p), 1.0, 1.0);
|
||||
out.sound(sound::LAUNCH_S400, heard(p), 1.0, 1.0);
|
||||
}
|
||||
}
|
||||
self.heard = self.t;
|
||||
|
||||
@@ -7,16 +7,30 @@ pub const DRONE_ROCKET: &str = "airdef:drone.rocket";
|
||||
pub const MISSILE_FLIGHT: &str = "airdef:missile.flight";
|
||||
pub const DRONE_BALLISTIC: &str = "airdef:drone.ballistic";
|
||||
pub const BOOM_SONIC: &str = "airdef:boom.sonic";
|
||||
pub const BOOM_SONIC_FAR: &str = "airdef:boom.sonic_far";
|
||||
pub const LAUNCH_PATRIOT: &str = "airdef:launch.patriot";
|
||||
pub const LAUNCH_PATRIOT_FAR: &str = "airdef:launch.patriot_far";
|
||||
pub const LAUNCH_S400_EJECT: &str = "airdef:launch.s400_eject";
|
||||
pub const LAUNCH_S400_EJECT_FAR: &str = "airdef:launch.s400_eject_far";
|
||||
pub const LAUNCH_S400: &str = "airdef:launch.s400";
|
||||
pub const LAUNCH_S400_FAR: &str = "airdef:launch.s400_far";
|
||||
pub const LAUNCH_S500_EJECT: &str = "airdef:launch.s500_eject";
|
||||
pub const LAUNCH_S500_EJECT_FAR: &str = "airdef:launch.s500_eject_far";
|
||||
pub const LAUNCH_S500: &str = "airdef:launch.s500";
|
||||
pub const LAUNCH_S500_FAR: &str = "airdef:launch.s500_far";
|
||||
pub const LAUNCH_PANTSIR: &str = "airdef:launch.pantsir";
|
||||
pub const LAUNCH_PANTSIR_FAR: &str = "airdef:launch.pantsir_far";
|
||||
pub const GUN_GEPARD: &str = "airdef:gun.gepard";
|
||||
pub const GUN_GEPARD_FAR: &str = "airdef:gun.gepard_far";
|
||||
pub const GUN_PANTSIR: &str = "airdef:gun.pantsir";
|
||||
pub const GUN_PANTSIR_FAR: &str = "airdef:gun.pantsir_far";
|
||||
pub const BLAST_BIG: &str = "airdef:blast.big";
|
||||
pub const BLAST_BIG_FAR: &str = "airdef:blast.big_far";
|
||||
pub const BLAST_HEAVY: &str = "airdef:blast.heavy";
|
||||
pub const BLAST_HEAVY_FAR: &str = "airdef:blast.heavy_far";
|
||||
pub const BLAST_HUGE: &str = "airdef:blast.huge";
|
||||
pub const BLAST_HUGE_FAR: &str = "airdef:blast.huge_far";
|
||||
pub const BLAST_MEDIUM: &str = "airdef:blast.medium";
|
||||
pub const BLAST_MEDIUM_FAR: &str = "airdef:blast.medium_far";
|
||||
pub const BLAST_AIR: &str = "airdef:blast.air";
|
||||
pub const BLAST_AIR_FAR: &str = "airdef:blast.air_far";
|
||||
|
||||
+37
-36
@@ -12,6 +12,7 @@ use std::collections::HashMap;
|
||||
pub mod battery;
|
||||
pub mod launch;
|
||||
pub mod catalog;
|
||||
use catalog::sound;
|
||||
mod generated_bounds;
|
||||
mod damage;
|
||||
pub mod doctrine;
|
||||
@@ -680,11 +681,11 @@ impl DroneKind {
|
||||
/// The sound of a launch from the ground: a light catapult shot, a rocket booster, a heavy ballistic launch.
|
||||
pub fn launch_sound(self) -> &'static str {
|
||||
match self {
|
||||
DroneKind::Shahed | DroneKind::Geran3 | DroneKind::Lancet | DroneKind::Gerbera => "airdef:launch.s400_eject",
|
||||
DroneKind::Kh101 | DroneKind::Kalibr | DroneKind::Kh22 => "airdef:launch.patriot",
|
||||
DroneKind::Zircon => "airdef:launch.s400",
|
||||
DroneKind::Shahed | DroneKind::Geran3 | DroneKind::Lancet | DroneKind::Gerbera => sound::LAUNCH_S400_EJECT,
|
||||
DroneKind::Kh101 | DroneKind::Kalibr | DroneKind::Kh22 => sound::LAUNCH_PATRIOT,
|
||||
DroneKind::Zircon => sound::LAUNCH_S400,
|
||||
DroneKind::Iskander | DroneKind::Kinzhal | DroneKind::Oreshnik | DroneKind::OreshnikBlock | DroneKind::OreshnikSub => {
|
||||
"airdef:launch.s500"
|
||||
sound::LAUNCH_S500
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -704,7 +705,7 @@ impl DroneKind {
|
||||
engine: Engine::Prop(1.34, 1.0),
|
||||
decoy: false,
|
||||
stealth: 1.0,
|
||||
sound: ("airdef:drone.shahed", 1.0, 48),
|
||||
sound: (sound::DRONE_SHAHED, 1.0, 48),
|
||||
class: Class::Drone,
|
||||
ballistic: None,
|
||||
},
|
||||
@@ -722,7 +723,7 @@ impl DroneKind {
|
||||
engine: Engine::Jet(0.34, 1.55, 1.0),
|
||||
decoy: false,
|
||||
stealth: 1.1,
|
||||
sound: ("airdef:drone.geran3", 1.0, 40),
|
||||
sound: (sound::DRONE_GERAN3, 1.0, 40),
|
||||
class: Class::Jet,
|
||||
ballistic: None,
|
||||
},
|
||||
@@ -740,7 +741,7 @@ impl DroneKind {
|
||||
engine: Engine::Prop(0.93, 0.55),
|
||||
decoy: false,
|
||||
stealth: 1.4,
|
||||
sound: ("airdef:drone.lancet", 1.0, 32),
|
||||
sound: (sound::DRONE_LANCET, 1.0, 32),
|
||||
class: Class::Drone,
|
||||
ballistic: None,
|
||||
},
|
||||
@@ -758,7 +759,7 @@ impl DroneKind {
|
||||
engine: Engine::Prop(1.03, 0.9),
|
||||
decoy: true,
|
||||
stealth: 0.9,
|
||||
sound: ("airdef:drone.shahed", 1.3, 40),
|
||||
sound: (sound::DRONE_SHAHED, 1.3, 40),
|
||||
class: Class::Drone,
|
||||
ballistic: None,
|
||||
},
|
||||
@@ -776,7 +777,7 @@ impl DroneKind {
|
||||
engine: Engine::Jet(-0.27, 1.4, 0.6),
|
||||
decoy: false,
|
||||
stealth: 1.5,
|
||||
sound: ("airdef:drone.cruise", 1.0, 50),
|
||||
sound: (sound::DRONE_CRUISE, 1.0, 50),
|
||||
class: Class::Cruise,
|
||||
ballistic: None,
|
||||
},
|
||||
@@ -794,7 +795,7 @@ impl DroneKind {
|
||||
engine: Engine::Jet(-0.2, 1.5, 0.6),
|
||||
decoy: false,
|
||||
stealth: 1.3,
|
||||
sound: ("airdef:drone.cruise", 1.2, 50),
|
||||
sound: (sound::DRONE_CRUISE, 1.2, 50),
|
||||
class: Class::Cruise,
|
||||
ballistic: None,
|
||||
},
|
||||
@@ -812,7 +813,7 @@ impl DroneKind {
|
||||
engine: Engine::Rocket(1.5, 1.3),
|
||||
decoy: false,
|
||||
stealth: 1.4,
|
||||
sound: ("airdef:drone.rocket", 0.8, 46),
|
||||
sound: (sound::DRONE_ROCKET, 0.8, 46),
|
||||
class: Class::Supersonic,
|
||||
ballistic: None,
|
||||
},
|
||||
@@ -830,7 +831,7 @@ impl DroneKind {
|
||||
engine: Engine::Rocket(1.5, 1.1),
|
||||
decoy: false,
|
||||
stealth: 2.0,
|
||||
sound: ("airdef:drone.rocket", 1.35, 46),
|
||||
sound: (sound::DRONE_ROCKET, 1.35, 46),
|
||||
class: Class::Supersonic,
|
||||
ballistic: None,
|
||||
},
|
||||
@@ -848,7 +849,7 @@ impl DroneKind {
|
||||
engine: Engine::Rocket(1.5, 1.6),
|
||||
decoy: false,
|
||||
stealth: 1.6,
|
||||
sound: ("airdef:drone.rocket", 0.7, 46),
|
||||
sound: (sound::DRONE_ROCKET, 0.7, 46),
|
||||
class: Class::Ballistic,
|
||||
ballistic: Some(1000.0),
|
||||
},
|
||||
@@ -866,7 +867,7 @@ impl DroneKind {
|
||||
engine: Engine::Rocket(1.5, 1.5),
|
||||
decoy: false,
|
||||
stealth: 2.2,
|
||||
sound: ("airdef:drone.rocket", 0.6, 46),
|
||||
sound: (sound::DRONE_ROCKET, 0.6, 46),
|
||||
class: Class::Ballistic,
|
||||
ballistic: Some(1500.0),
|
||||
},
|
||||
@@ -884,7 +885,7 @@ impl DroneKind {
|
||||
engine: Engine::Rocket(1.5, 2.4),
|
||||
decoy: false,
|
||||
stealth: 3.0,
|
||||
sound: ("airdef:drone.rocket", 0.5, 46),
|
||||
sound: (sound::DRONE_ROCKET, 0.5, 46),
|
||||
class: Class::Ballistic,
|
||||
ballistic: Some(2600.0),
|
||||
},
|
||||
@@ -902,7 +903,7 @@ impl DroneKind {
|
||||
engine: Engine::Rocket(1.0, 1.0),
|
||||
decoy: false,
|
||||
stealth: 3.5,
|
||||
sound: ("airdef:drone.ballistic", 0.8, 9999),
|
||||
sound: (sound::DRONE_BALLISTIC, 0.8, 9999),
|
||||
class: Class::Ballistic,
|
||||
ballistic: None,
|
||||
},
|
||||
@@ -920,7 +921,7 @@ impl DroneKind {
|
||||
engine: Engine::Rocket(1.0, 1.0),
|
||||
decoy: false,
|
||||
stealth: 4.0,
|
||||
sound: ("airdef:drone.ballistic", 1.0, 9999),
|
||||
sound: (sound::DRONE_BALLISTIC, 1.0, 9999),
|
||||
class: Class::Ballistic,
|
||||
ballistic: None,
|
||||
},
|
||||
@@ -1106,13 +1107,13 @@ impl MissileKind {
|
||||
/// The sound of its launch.
|
||||
pub fn launch_sound(self) -> &'static str {
|
||||
match self {
|
||||
MissileKind::Pac3 => "airdef:launch.patriot",
|
||||
MissileKind::M57e6 => "airdef:launch.pantsir",
|
||||
MissileKind::M48n6 => "airdef:launch.s400_eject",
|
||||
MissileKind::M77n6 => "airdef:launch.s500_eject",
|
||||
MissileKind::IrisT | MissileKind::M9m338 => "airdef:launch.s400_eject",
|
||||
MissileKind::Amraam | MissileKind::M9m317 => "airdef:launch.patriot",
|
||||
MissileKind::P1sun => "airdef:drone.lancet",
|
||||
MissileKind::Pac3 => sound::LAUNCH_PATRIOT,
|
||||
MissileKind::M57e6 => sound::LAUNCH_PANTSIR,
|
||||
MissileKind::M48n6 => sound::LAUNCH_S400_EJECT,
|
||||
MissileKind::M77n6 => sound::LAUNCH_S500_EJECT,
|
||||
MissileKind::IrisT | MissileKind::M9m338 => sound::LAUNCH_S400_EJECT,
|
||||
MissileKind::Amraam | MissileKind::M9m317 => sound::LAUNCH_PATRIOT,
|
||||
MissileKind::P1sun => sound::DRONE_LANCET,
|
||||
}
|
||||
}
|
||||
fn spec(self) -> &'static MissileSpec {
|
||||
@@ -2075,13 +2076,13 @@ impl Sim {
|
||||
let v = (aim - d.pos).normalize_or(DVec3::NEG_Y) * 3.0;
|
||||
released.push((piece, d.pos + v.normalize_or_zero() * (i as f64 * 0.3), v, aim, d.sector));
|
||||
}
|
||||
out.sound("airdef:boom.sonic", d.pos, 1.0, 0.7);
|
||||
out.sound(sound::BOOM_SONIC, d.pos, 1.0, 0.7);
|
||||
splits.push((d.id, d.pos));
|
||||
// Its pieces count as launched instead of it.
|
||||
self.launched += 5;
|
||||
out.particles("minecraft:firework", d.pos, 1.5, DVec3::ZERO, 0.3, 40);
|
||||
if d.kind == DroneKind::OreshnikBlock && self.rng.chance(0.5) {
|
||||
out.sound("airdef:drone.ballistic", d.pos, 1.0, 1.1);
|
||||
out.sound(sound::DRONE_BALLISTIC, d.pos, 1.0, 1.1);
|
||||
}
|
||||
removed.push(d.id);
|
||||
continue;
|
||||
@@ -2106,8 +2107,8 @@ impl Sim {
|
||||
if d.vel.y < -1.0 && d.spin == 0.0 && d.pos.distance(d.target) < d.vel.length() * 80.0 {
|
||||
d.spin = 1.0;
|
||||
let p = if d.kind == DroneKind::Kinzhal { 0.85 } else { 1.0 };
|
||||
out.sound("airdef:drone.ballistic", d.pos, 1.0, p);
|
||||
out.sound("airdef:boom.sonic", d.pos, 1.0, p);
|
||||
out.sound(sound::DRONE_BALLISTIC, d.pos, 1.0, p);
|
||||
out.sound(sound::BOOM_SONIC, d.pos, 1.0, p);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -2401,7 +2402,7 @@ impl Sim {
|
||||
out.particles("minecraft:lava", pos, 1.0, DVec3::ZERO, 0.0, 16);
|
||||
out.particles("minecraft:campfire_signal_smoke", pos, 1.2, DVec3::new(0.0, 0.04, 0.0), 0.01, if big { 30 } else { 10 });
|
||||
let pitch = 0.9 + self.vis.f() as f32 * 0.2;
|
||||
let event = ["airdef:blast.air", "airdef:blast.medium", "airdef:blast.big", "airdef:blast.heavy", "airdef:blast.huge"][power];
|
||||
let event = [sound::BLAST_AIR, sound::BLAST_MEDIUM, sound::BLAST_BIG, sound::BLAST_HEAVY, sound::BLAST_HUGE][power];
|
||||
out.sound(event, pos, 1.0, if small { pitch * 1.15 } else { pitch });
|
||||
if power >= 3 {
|
||||
// A heavy warhead throws a column of dirt and a ring of dust.
|
||||
@@ -2518,7 +2519,7 @@ impl Sim {
|
||||
out.particles("minecraft:large_smoke", pos, size * 0.3, DVec3::new(0.0, 0.05, 0.0), 0.07, if self.shader { 20 } else { 40 });
|
||||
out.particles("minecraft:firework", pos, 0.6, DVec3::ZERO, 0.5, 50);
|
||||
// The shock arrives after the flash (`boom` sounds travel); the warhead's blast hurts what is near.
|
||||
out.sound("airdef:boom.sonic", pos, 0.8, 1.2);
|
||||
out.sound(sound::BOOM_SONIC, pos, 0.8, 1.2);
|
||||
self.blast_damage(pos, 0, ground, out);
|
||||
}
|
||||
}
|
||||
@@ -2828,7 +2829,7 @@ impl Sim {
|
||||
}
|
||||
// A gun sound holds a few shots: one every other burst.
|
||||
if sam.bursts % 2 == 0 {
|
||||
let event = if sam.kind == SamKind::Pantsir { "airdef:gun.pantsir" } else { "airdef:gun.gepard" };
|
||||
let event = if sam.kind == SamKind::Pantsir { sound::GUN_PANTSIR } else { sound::GUN_GEPARD };
|
||||
out.sound(event, mount, 1.0, 0.95 + self.vis.f() as f32 * 0.1);
|
||||
}
|
||||
// A fresh working own-radar fire-control track does not depend on seeing the target.
|
||||
@@ -2937,7 +2938,7 @@ impl Sim {
|
||||
if spec.cold > 0 {
|
||||
// Thrown out by gas: a puff, a thump; the motor lights later.
|
||||
out.particles("minecraft:cloud", muzzle, 0.6, dir * 0.05, 0.05, 30);
|
||||
let event = if kind == MissileKind::M77n6 { "airdef:launch.s500_eject" } else { "airdef:launch.s400_eject" };
|
||||
let event = if kind == MissileKind::M77n6 { sound::LAUNCH_S500_EJECT } else { sound::LAUNCH_S400_EJECT };
|
||||
out.sound(event, muzzle, 1.0, 1.0);
|
||||
self.scene_event(muzzle, record::SceneKind::MissileLaunch { missile: id, sam, target, kind, sound: event, pitch: 1.0 });
|
||||
} else {
|
||||
@@ -2946,7 +2947,7 @@ impl Sim {
|
||||
out.particles("minecraft:cloud", muzzle - dir * 2.0, 1.4, DVec3::new(0.0, 0.02, 0.0), 0.06, 70);
|
||||
out.particles("minecraft:campfire_cosy_smoke", muzzle - dir * 3.0, 1.2, DVec3::ZERO, 0.02, 20);
|
||||
}
|
||||
let event = if kind == MissileKind::M57e6 { "airdef:launch.pantsir" } else { "airdef:launch.patriot" };
|
||||
let event = if kind == MissileKind::M57e6 { sound::LAUNCH_PANTSIR } else { sound::LAUNCH_PATRIOT };
|
||||
let pitch = 0.95 + self.vis.f() as f32 * 0.1;
|
||||
out.sound(event, muzzle, 1.0, pitch);
|
||||
self.scene_event(muzzle, record::SceneKind::MissileLaunch { missile: id, sam, target, kind, sound: event, pitch });
|
||||
@@ -3142,7 +3143,7 @@ impl Sim {
|
||||
continue;
|
||||
}
|
||||
if lit && m.age == spec.cold + 1 {
|
||||
let sound = (spec.cold > 0 && spec.flame > 0.0).then_some(if m.kind == MissileKind::M77n6 { "airdef:launch.s500" } else { "airdef:launch.s400" });
|
||||
let sound = (spec.cold > 0 && spec.flame > 0.0).then_some(if m.kind == MissileKind::M77n6 { sound::LAUNCH_S500 } else { sound::LAUNCH_S400 });
|
||||
ignitions.push((m.pos, m.id, m.kind, sound));
|
||||
}
|
||||
if lit {
|
||||
@@ -3157,7 +3158,7 @@ impl Sim {
|
||||
out.particles("minecraft:cloud", back - new * 0.5, 0.12 * spec.scale as f32, DVec3::ZERO, 0.005, if m.age < 30 { 3 } else { 1 });
|
||||
}
|
||||
if m.age == spec.cold + 1 && spec.cold > 0 {
|
||||
let event = if m.kind == MissileKind::M77n6 { "airdef:launch.s500" } else { "airdef:launch.s400" };
|
||||
let event = if m.kind == MissileKind::M77n6 { sound::LAUNCH_S500 } else { sound::LAUNCH_S400 };
|
||||
out.sound(event, m.pos, 1.0, 1.0);
|
||||
out.particles("minecraft:cloud", m.pos, 1.0, DVec3::ZERO, 0.08, 40);
|
||||
}
|
||||
@@ -3187,7 +3188,7 @@ impl Sim {
|
||||
let m = self.missiles.swap_remove(i);
|
||||
self.fireball(m.pos, 2.5 * m.kind.spec().scale, 7);
|
||||
out.particles("minecraft:explosion", m.pos, 0.4, DVec3::ZERO, 0.0, 3);
|
||||
out.sound("airdef:blast.air", m.pos, 1.0, 1.25);
|
||||
out.sound(sound::BLAST_AIR, m.pos, 1.0, 1.25);
|
||||
if let Some(t) = target.and_then(|t| self.drones.iter().position(|d| d.id == t)) {
|
||||
self.drones[t].engaged = self.drones[t].engaged.saturating_sub(1);
|
||||
if kill {
|
||||
|
||||
@@ -35,6 +35,8 @@ def generate_sound_ids(entries):
|
||||
event = entry["event"]
|
||||
name = event.replace(".", "_").upper()
|
||||
lines.append(f'pub const {name}: &str = "airdef:{event}";')
|
||||
if entry["far"]:
|
||||
lines.append(f'pub const {name}_FAR: &str = "airdef:{event}_far";')
|
||||
return "\n".join(lines + [""])
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user