added audio + visual effects for battery overload
This commit is contained in:
parent
ebe028d567
commit
b5e969f0f7
|
@ -47,6 +47,8 @@
|
||||||
- achieve.ogg: [UI Completed Status Alert Notification by Headphaze, CC BY 4.0](https://freesound.org/s/277033/)
|
- achieve.ogg: [UI Completed Status Alert Notification by Headphaze, CC BY 4.0](https://freesound.org/s/277033/)
|
||||||
- drink.ogg: [Pouring Beer into Short Glass by megashroom, CC0](https://freesound.org/s/390336/)
|
- drink.ogg: [Pouring Beer into Short Glass by megashroom, CC0](https://freesound.org/s/390336/)
|
||||||
- enter.ogg, exit.ogg: [Getting Out of Car.wav by kingsrow, CC0](https://freesound.org/s/181568/)
|
- enter.ogg, exit.ogg: [Getting Out of Car.wav by kingsrow, CC0](https://freesound.org/s/181568/)
|
||||||
|
- powerdown.ogg: [Energy Drain by qubodup, CC0](https://freesound.org/people/qubodup/sounds/742835/)
|
||||||
|
- spark.ogg: [Socket Connect Disconnect by JustHallowed, CC BY 4.0](https://freesound.org/people/JustHallowed/sounds/691007/), Tempo -40, Amplify 4
|
||||||
- Takeoff.ogg: [By Serat, CC BY 4.0](https://freemusicarchive.org/music/serat/route-remastered/takeoff-remastered/)
|
- Takeoff.ogg: [By Serat, CC BY 4.0](https://freemusicarchive.org/music/serat/route-remastered/takeoff-remastered/)
|
||||||
- JupiterRecording.ogg: An [actual Jupiter recording by NASA](https://archive.org/download/voyager-1-and-2-1990-jupiter-nasa-voyager-space-sounds-electronic), public domain.
|
- JupiterRecording.ogg: An [actual Jupiter recording by NASA](https://archive.org/download/voyager-1-and-2-1990-jupiter-nasa-voyager-space-sounds-electronic), public domain.
|
||||||
- Processed by cutting out min 1:47-3:47 and applying a 10s linear crossfade at the end. Exported as ogg with quality=3, see [.kdenlive file](src/audio/JupiterRecording.kdenlive).
|
- Processed by cutting out min 1:47-3:47 and applying a 10s linear crossfade at the end. Exported as ogg with quality=3, see [.kdenlive file](src/audio/JupiterRecording.kdenlive).
|
||||||
|
|
BIN
assets/sounds/powerdown.ogg
Normal file
BIN
assets/sounds/powerdown.ogg
Normal file
Binary file not shown.
BIN
assets/sounds/spark.ogg
Normal file
BIN
assets/sounds/spark.ogg
Normal file
Binary file not shown.
BIN
assets/sprites/dashboard_battery.png
Normal file
BIN
assets/sprites/dashboard_battery.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
30
src/actor.rs
30
src/actor.rs
|
@ -258,6 +258,7 @@ pub struct Battery {
|
||||||
pub power: f32, // Watt-seconds
|
pub power: f32, // Watt-seconds
|
||||||
pub capacity: f32, // Watt-seconds
|
pub capacity: f32, // Watt-seconds
|
||||||
pub reactor: f32, // Watt (production)
|
pub reactor: f32, // Watt (production)
|
||||||
|
pub overloaded_recovering: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Battery {
|
impl Default for Battery {
|
||||||
|
@ -266,6 +267,7 @@ impl Default for Battery {
|
||||||
power: 10e3 * 3600.0,
|
power: 10e3 * 3600.0,
|
||||||
capacity: 10e3 * 3600.0, // 10kWh
|
capacity: 10e3 * 3600.0, // 10kWh
|
||||||
reactor: 2000e3, // 2MW
|
reactor: 2000e3, // 2MW
|
||||||
|
overloaded_recovering: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -279,13 +281,14 @@ pub fn update_power(
|
||||||
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
|
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
|
||||||
mut ew_game: EventWriter<game::GameEvent>,
|
mut ew_game: EventWriter<game::GameEvent>,
|
||||||
) {
|
) {
|
||||||
|
let mut power_down = false;
|
||||||
let d = time.delta_seconds();
|
let d = time.delta_seconds();
|
||||||
for (mut battery, mut engine) in &mut q_battery {
|
for (mut battery, mut engine) in &mut q_battery {
|
||||||
if settings.flashlight_active {
|
if settings.flashlight_active {
|
||||||
battery.power -= POWER_DRAIN_FLASHLIGHT[prefs.flashlight_power] * d; // 2.4MW
|
battery.power -= POWER_DRAIN_FLASHLIGHT[prefs.flashlight_power] * d; // 2.4MW
|
||||||
if battery.power <= 0.0 {
|
if battery.power <= 0.0 {
|
||||||
|
power_down = true;
|
||||||
settings.flashlight_active = false;
|
settings.flashlight_active = false;
|
||||||
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Switch));
|
|
||||||
for mut flashlight_vis in &mut q_flashlight {
|
for mut flashlight_vis in &mut q_flashlight {
|
||||||
*flashlight_vis = Visibility::Hidden;
|
*flashlight_vis = Visibility::Hidden;
|
||||||
}
|
}
|
||||||
|
@ -296,26 +299,39 @@ pub fn update_power(
|
||||||
hud_drain += prefs.light_amp as f32 * 200e3; // 200kW per level
|
hud_drain += prefs.light_amp as f32 * 200e3; // 200kW per level
|
||||||
battery.power -= hud_drain * d;
|
battery.power -= hud_drain * d;
|
||||||
if battery.power <= 0.0 {
|
if battery.power <= 0.0 {
|
||||||
|
power_down = true;
|
||||||
ew_game.send(GameEvent::SetAR(Turn::Off));
|
ew_game.send(GameEvent::SetAR(Turn::Off));
|
||||||
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Switch));
|
|
||||||
for mut flashlight_vis in &mut q_flashlight {
|
for mut flashlight_vis in &mut q_flashlight {
|
||||||
*flashlight_vis = Visibility::Hidden;
|
*flashlight_vis = Visibility::Hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let drain = POWER_DRAIN_THRUSTER[prefs.thruster_boost];
|
let drain = POWER_DRAIN_THRUSTER[prefs.thruster_boost];
|
||||||
let boosting = prefs.thruster_boost != 2
|
let boosting = !battery.overloaded_recovering
|
||||||
&& (battery.power > drain * d * 20.0)
|
&& prefs.thruster_boost != 2
|
||||||
&& (prefs.thruster_boost == 1 || engine.currently_matching_velocity);
|
&& (prefs.thruster_boost == 1 || engine.currently_matching_velocity);
|
||||||
if boosting {
|
if boosting {
|
||||||
engine.current_boost_factor = THRUSTER_BOOST_FACTOR[prefs.thruster_boost];
|
if battery.power > drain * d * 100.0 {
|
||||||
if engine.currently_firing {
|
engine.current_boost_factor = THRUSTER_BOOST_FACTOR[prefs.thruster_boost];
|
||||||
battery.power -= drain * d;
|
if engine.currently_firing {
|
||||||
|
battery.power -= drain * d;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
power_down = true;
|
||||||
|
battery.overloaded_recovering = true;
|
||||||
|
engine.current_boost_factor = 1.0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
engine.current_boost_factor = 1.0;
|
engine.current_boost_factor = 1.0;
|
||||||
}
|
}
|
||||||
|
if power_down {
|
||||||
|
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::PowerDown));
|
||||||
|
}
|
||||||
battery.power = (battery.power + battery.reactor * d).clamp(0.0, battery.capacity);
|
battery.power = (battery.power + battery.reactor * d).clamp(0.0, battery.capacity);
|
||||||
|
if battery.overloaded_recovering && battery.power > battery.capacity * 0.5 {
|
||||||
|
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::PowerUp));
|
||||||
|
battery.overloaded_recovering = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,8 @@ const PATHS: &[(SfxType, Sfx, &str)] = &[
|
||||||
"sounds/connect.ogg",
|
"sounds/connect.ogg",
|
||||||
),
|
),
|
||||||
(SfxType::OneOff, Sfx::Ping, "sounds/connect.ogg"),
|
(SfxType::OneOff, Sfx::Ping, "sounds/connect.ogg"),
|
||||||
|
(SfxType::OneOff, Sfx::PowerDown, "sounds/powerdown.ogg"),
|
||||||
|
(SfxType::OneOff, Sfx::PowerUp, "sounds/spark.ogg"),
|
||||||
(SfxType::OneOff, Sfx::Switch, "sounds/click2.ogg"),
|
(SfxType::OneOff, Sfx::Switch, "sounds/click2.ogg"),
|
||||||
(SfxType::OneOff, Sfx::Refill, "sounds/refill.ogg"),
|
(SfxType::OneOff, Sfx::Refill, "sounds/refill.ogg"),
|
||||||
(SfxType::OneOff, Sfx::WakeUp, "sounds/wakeup.ogg"),
|
(SfxType::OneOff, Sfx::WakeUp, "sounds/wakeup.ogg"),
|
||||||
|
@ -103,6 +105,8 @@ pub enum Sfx {
|
||||||
IncomingChatMessage,
|
IncomingChatMessage,
|
||||||
Ion,
|
Ion,
|
||||||
Ping,
|
Ping,
|
||||||
|
PowerDown,
|
||||||
|
PowerUp,
|
||||||
Refill,
|
Refill,
|
||||||
Switch,
|
Switch,
|
||||||
Thruster,
|
Thruster,
|
||||||
|
@ -125,6 +129,8 @@ pub fn str2sfx(sfx_label: &str) -> Sfx {
|
||||||
"zoom" => Sfx::Zoom,
|
"zoom" => Sfx::Zoom,
|
||||||
"chat" => Sfx::IncomingChatMessage,
|
"chat" => Sfx::IncomingChatMessage,
|
||||||
"ping" => Sfx::Ping,
|
"ping" => Sfx::Ping,
|
||||||
|
"powerdown" => Sfx::PowerDown,
|
||||||
|
"powerup" => Sfx::PowerUp,
|
||||||
"connect" => Sfx::Connect,
|
"connect" => Sfx::Connect,
|
||||||
"refill" => Sfx::Refill,
|
"refill" => Sfx::Refill,
|
||||||
"entervehicle" => Sfx::EnterVehicle,
|
"entervehicle" => Sfx::EnterVehicle,
|
||||||
|
|
|
@ -38,6 +38,7 @@ pub const DASHBOARD_DEF: &[(Dashboard, &str)] = &[
|
||||||
(Dashboard::Leak, "leak"),
|
(Dashboard::Leak, "leak"),
|
||||||
(Dashboard::RotationStabiliser, "rotation_stabiliser"),
|
(Dashboard::RotationStabiliser, "rotation_stabiliser"),
|
||||||
(Dashboard::CruiseControl, "cruise_control"),
|
(Dashboard::CruiseControl, "cruise_control"),
|
||||||
|
(Dashboard::Battery, "battery"),
|
||||||
(Dashboard::Radioactivity, "radioactivity"),
|
(Dashboard::Radioactivity, "radioactivity"),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -142,6 +143,7 @@ pub enum Dashboard {
|
||||||
RotationStabiliser,
|
RotationStabiliser,
|
||||||
CruiseControl,
|
CruiseControl,
|
||||||
Radioactivity,
|
Radioactivity,
|
||||||
|
Battery,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component, Debug, Copy, Clone)]
|
#[derive(Component, Debug, Copy, Clone)]
|
||||||
|
@ -681,7 +683,7 @@ fn update_dashboard(
|
||||||
timer: ResMut<FPSUpdateTimer>,
|
timer: ResMut<FPSUpdateTimer>,
|
||||||
mut q_dashboard: Query<(&mut Visibility, &Dashboard)>,
|
mut q_dashboard: Query<(&mut Visibility, &Dashboard)>,
|
||||||
id2pos: Res<game::Id2Pos>,
|
id2pos: Res<game::Id2Pos>,
|
||||||
q_player: Query<(&actor::Suit, &Position), With<actor::Player>>,
|
q_player: Query<(&actor::Suit, &actor::Battery, &Position), With<actor::Player>>,
|
||||||
settings: Res<Settings>,
|
settings: Res<Settings>,
|
||||||
) {
|
) {
|
||||||
if !settings.hud_active || !timer.0.just_finished() {
|
if !settings.hud_active || !timer.0.just_finished() {
|
||||||
|
@ -691,12 +693,13 @@ fn update_dashboard(
|
||||||
if player.is_err() {
|
if player.is_err() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let (suit, pos) = player.unwrap();
|
let (suit, battery, pos) = player.unwrap();
|
||||||
|
|
||||||
for (mut vis, icon) in &mut q_dashboard {
|
for (mut vis, icon) in &mut q_dashboard {
|
||||||
*vis = bool2vis(match icon {
|
*vis = bool2vis(match icon {
|
||||||
Dashboard::Flashlight => settings.flashlight_active,
|
Dashboard::Flashlight => settings.flashlight_active,
|
||||||
Dashboard::Leak => suit.integrity < 0.5,
|
Dashboard::Leak => suit.integrity < 0.5,
|
||||||
|
Dashboard::Battery => battery.overloaded_recovering,
|
||||||
Dashboard::RotationStabiliser => !settings.rotation_stabilizer_active,
|
Dashboard::RotationStabiliser => !settings.rotation_stabilizer_active,
|
||||||
Dashboard::CruiseControl => settings.cruise_control_active,
|
Dashboard::CruiseControl => settings.cruise_control_active,
|
||||||
Dashboard::Radioactivity => {
|
Dashboard::Radioactivity => {
|
||||||
|
|
105
src/svg/dashboard_battery.svg
Normal file
105
src/svg/dashboard_battery.svg
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="256"
|
||||||
|
height="256"
|
||||||
|
viewBox="0 0 67.733334 67.733334"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
||||||
|
sodipodi:docname="dashboard_battery.svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
inkscape:export-filename="../../assets/sprites/dashboard_battery.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#000000"
|
||||||
|
bordercolor="#252525"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:showpageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#000000"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:zoom="1.6542969"
|
||||||
|
inkscape:cx="107.59858"
|
||||||
|
inkscape:cy="110.92326"
|
||||||
|
inkscape:window-width="1440"
|
||||||
|
inkscape:window-height="820"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="60"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="g227"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:export-bgcolor="#00000000"><inkscape:grid
|
||||||
|
id="grid1"
|
||||||
|
units="px"
|
||||||
|
originx="0"
|
||||||
|
originy="0"
|
||||||
|
spacingx="0.26458334"
|
||||||
|
spacingy="0.26458334"
|
||||||
|
empcolor="#0099e5"
|
||||||
|
empopacity="0.30196078"
|
||||||
|
color="#0099e5"
|
||||||
|
opacity="0.14901961"
|
||||||
|
empspacing="8"
|
||||||
|
dotted="false"
|
||||||
|
gridanglex="30"
|
||||||
|
gridanglez="30"
|
||||||
|
visible="true" /></sodipodi:namedview><defs
|
||||||
|
id="defs1"><filter
|
||||||
|
style="color-interpolation-filters:sRGB"
|
||||||
|
id="filter1"
|
||||||
|
inkscape:label="bloom"
|
||||||
|
x="-0.13048332"
|
||||||
|
y="-0.15460972"
|
||||||
|
width="1.2609666"
|
||||||
|
height="1.3092194"><feConvolveMatrix
|
||||||
|
order="1 1"
|
||||||
|
kernelMatrix="1.0000000 "
|
||||||
|
id="feConvolveMatrix1"
|
||||||
|
result="result1"
|
||||||
|
bias="0"
|
||||||
|
preserveAlpha="true"
|
||||||
|
edgeMode="none"
|
||||||
|
divisor="0" /><feGaussianBlur
|
||||||
|
stdDeviation="2"
|
||||||
|
id="feGaussianBlur1"
|
||||||
|
in="SourceGraphic" /><feComposite
|
||||||
|
id="feComposite1"
|
||||||
|
operator="arithmetic"
|
||||||
|
k1="1"
|
||||||
|
k2="0.99999999999999922"
|
||||||
|
k3="1"
|
||||||
|
k4="0"
|
||||||
|
in2="result1" /></filter></defs><g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"><g
|
||||||
|
id="g227"
|
||||||
|
style="filter:url(#filter1)"><g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1-5"
|
||||||
|
transform="matrix(0.86486189,0,0,0.86486189,5.6836111,4.3940895)"><path
|
||||||
|
style="font-variation-settings:'wght' 400;fill:none;fill-opacity:1;stroke:#be1251;stroke-width:3.05926;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 6.7381087,16.059295 4.5e-6,40.702599 54.2571138,-2.5e-5 -3e-6,-40.702598 h -7.398697 l -14.797395,2.4e-5 14.797397,8.8e-5 -2e-6,-5.087942 H 41.265364 v 5.08783 l -14.797395,2.4e-5 -14.180835,2.4e-5 14.180837,6.4e-5 -2e-6,-5.087918 H 14.136807 v 5.08783 z"
|
||||||
|
id="path9"
|
||||||
|
sodipodi:nodetypes="ccccccccccccccccc" /><path
|
||||||
|
style="font-variation-settings:'wght' 400;fill:none;fill-opacity:1;stroke:#be1251;stroke-width:5.29167;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 13.758334,30.691669 H 27.516668"
|
||||||
|
id="path10"
|
||||||
|
sodipodi:nodetypes="cc" /><path
|
||||||
|
style="font-variation-settings:'wght' 400;fill:none;fill-opacity:1;stroke:#be1251;stroke-width:5.29167;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 20.637501,23.283335 V 38.100002"
|
||||||
|
id="path11"
|
||||||
|
sodipodi:nodetypes="cc" /><path
|
||||||
|
style="font-variation-settings:'wght' 400;fill:none;fill-opacity:1;stroke:#be1251;stroke-width:5.29167;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 40.216669,30.691669 H 53.975003"
|
||||||
|
id="path12"
|
||||||
|
sodipodi:nodetypes="cc" /></g></g></g></svg>
|
After Width: | Height: | Size: 4.1 KiB |
Loading…
Reference in a new issue