Skip to content

Commit 96601c4

Browse files
committed
Add heat/cooldown mechanics
1 parent 03794c7 commit 96601c4

File tree

7 files changed

+45
-9
lines changed

7 files changed

+45
-9
lines changed

assets/assets/styles.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"gun_beam": "#bc96e6ff",
1010
"exhaust": "#36bbf5ff",
1111
"bg_top": "#10020eff",
12-
"bg_bottom": "#040003ff"
12+
"bg_bottom": "#040003ff",
13+
"ship_heat": "#ac3939ff"
1314
},
1415
"buttons": {
1516
"default": {
@@ -81,4 +82,4 @@
8182
"padding": 20
8283
}
8384
}
84-
}
85+
}

src/spaced/spaced/game/arsenal.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ auto Arsenal::get_weapon() -> Weapon& {
2121
return const_cast<Weapon&>(std::as_const(*this).get_weapon()); // NOLINT(cppcoreguidelines-pro-type-const-cast)
2222
}
2323

24-
void Arsenal::tick(IWeaponRound::State const& round_state, bool const fire, Seconds const dt) {
24+
auto Arsenal::tick(IWeaponRound::State const& round_state, bool const fire, Seconds const dt) -> bool {
2525
tick_weapons(dt);
2626
check_switch_weapon();
27-
if (round_state.in_play && fire) { fire_weapon(round_state.muzzle_position); }
27+
bool has_fired = false;
28+
if (round_state.in_play && fire) { has_fired = fire_weapon(round_state.muzzle_position); }
2829
tick_rounds(round_state, dt);
30+
return has_fired;
2931
}
3032

3133
void Arsenal::draw(Shader& shader) const {
@@ -53,11 +55,13 @@ void Arsenal::check_switch_weapon() {
5355
}
5456
}
5557

56-
void Arsenal::fire_weapon(glm::vec2 const muzzle_position) {
58+
auto Arsenal::fire_weapon(glm::vec2 const muzzle_position) -> bool {
5759
if (auto round = get_weapon().fire(muzzle_position)) {
5860
m_rounds.push_back(std::move(round));
5961
++m_stats->player.shots_fired;
62+
return true;
6063
}
64+
return false;
6165
}
6266

6367
void Arsenal::tick_rounds(IWeaponRound::State const& round_state, Seconds const dt) {

src/spaced/spaced/game/arsenal.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ class Arsenal {
1818

1919
void set_special(std::unique_ptr<Weapon> weapon) { m_next = std::move(weapon); }
2020

21-
void tick(IWeaponRound::State const& round_state, bool fire, bave::Seconds dt);
21+
// returns whether a round was fired this frame
22+
auto tick(IWeaponRound::State const& round_state, bool fire, bave::Seconds dt) -> bool;
2223
void draw(bave::Shader& shader) const;
2324

2425
private:
2526
void tick_weapons(bave::Seconds dt);
2627
void check_switch_weapon();
27-
void fire_weapon(glm::vec2 muzzle_position);
28+
auto fire_weapon(glm::vec2 muzzle_position) -> bool;
2829
void tick_rounds(IWeaponRound::State const& round_state, bave::Seconds dt);
2930

3031
bave::NotNull<Stats*> m_stats;

src/spaced/spaced/game/player.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ Player::Player(Services const& services, std::unique_ptr<IController> controller
4646

4747
if (auto const death = resources.get<ParticleEmitter>("assets/particles/explode.json")) { m_death_source = *death; }
4848
m_death_source.config.respawn = false;
49+
50+
m_heat_color = rgbas["ship_heat"];
4951
}
5052

5153
void Player::on_focus(bave::FocusChange const& /*focus_changed*/) { m_controller->untap(); }
@@ -65,7 +67,20 @@ void Player::tick(State const& state, Seconds const dt) {
6567
.muzzle_position = get_muzzle_position(),
6668
.in_play = !m_health.is_dead(),
6769
};
68-
m_arsenal.tick(round_state, m_controller->is_firing(), dt);
70+
71+
auto const has_fired = m_arsenal.tick(round_state, m_controller->is_firing() && !m_is_cooling_down, dt);
72+
73+
if (has_fired) {
74+
m_heat += m_heat_increment;
75+
} else {
76+
m_heat -= (m_is_cooling_down ? m_heat_dissipated * 0.5f : m_heat_dissipated) * dt.count();
77+
}
78+
if (m_heat >= 1.0f) { m_is_cooling_down = true; }
79+
if (m_heat <= m_cooldown_threshold) { m_is_cooling_down = false; }
80+
m_heat = std::clamp(m_heat, 0.f, 1.0f);
81+
82+
m_heat_being_rendered = glm::mix(m_heat_being_rendered, m_heat, 0.5f);
83+
ship.tint = bave::Rgba::from(glm::mix(bave::white_v.to_vec4(), m_heat_color.to_vec4(), m_heat_being_rendered));
6984

7085
m_shield.set_position(ship.transform.position);
7186
m_shield.tick(dt);
@@ -188,6 +203,10 @@ void Player::do_inspect() {
188203
}
189204

190205
if (ImGui::Button("1up")) { one_up(); }
206+
207+
ImGui::DragFloat("heat dissipated per sec", &m_heat_dissipated, 0.05f, 0.f, 1.f);
208+
ImGui::DragFloat("heat per round fired", &m_heat_increment, 0.1f, 0.f, 1.f);
209+
ImGui::DragFloat("cooldown threshold", &m_cooldown_threshold, 0.1f, 0.f, 0.9f);
191210
}
192211
}
193212
} // namespace spaced

src/spaced/spaced/game/player.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ class Player : public IDamageable, public bave::IDrawable {
7474
bave::ParticleEmitter m_exhaust{};
7575
Shield m_shield;
7676

77+
float m_heat_being_rendered{};
78+
float m_heat{};
79+
float m_heat_increment = 0.1f;
80+
float m_heat_dissipated = 0.4f; // per second
81+
bave::Rgba m_heat_color;
82+
bool m_is_cooling_down{};
83+
float m_cooldown_threshold = 0.5f;
84+
7785
bave::ParticleEmitter m_death_source{};
7886
std::optional<bave::ParticleEmitter> m_death{};
7987

src/spaced/spaced/game/weapons/gun_kinetic.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ void GunKinetic::do_inspect() {
3838
auto tint = projectile_config.tint.to_vec4();
3939
if (ImGui::ColorEdit4("projectile tint", &tint.x)) { projectile_config.tint = Rgba::from(tint); }
4040
ImGui::DragFloat("damage", &projectile_config.damage, 0.25f, 0.25f, 10.0f);
41+
auto reload_delay_s = reload_delay.count();
42+
if (ImGui::DragFloat("reload delay", &reload_delay_s, 0.05f, 0.1f, 1.f)) { reload_delay = Seconds{reload_delay_s}; }
4143
}
4244
}
4345
} // namespace spaced

src/spaced/spaced/game/weapons/gun_kinetic.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#pragma once
2+
#include <bave/core/inclusive_range.hpp>
23
#include <bave/services/audio.hpp>
34
#include <spaced/game/weapon.hpp>
45
#include <spaced/game/weapons/projectile.hpp>
@@ -15,7 +16,7 @@ class GunKinetic final : public Weapon {
1516

1617
Projectile::Config projectile_config{};
1718
std::string_view fire_sfx{"assets/sfx/kinetic_fire.wav"};
18-
bave::Seconds reload_delay{0.25s};
19+
bave::Seconds reload_delay{0.15s};
1920

2021
private:
2122
auto do_fire(glm::vec2 muzzle_position) -> std::unique_ptr<Round> final;

0 commit comments

Comments
 (0)