Skip to content

Commit 7836640

Browse files
authored
refactor: code review on dismantle systems (#33)
1 parent 5352732 commit 7836640

7 files changed

Lines changed: 148 additions & 164 deletions

File tree

src/gameplay/logistics/path.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ use bevy::{platform::collections::HashSet, prelude::*};
22

33
use crate::gameplay::{
44
FactorySystems,
5-
structure::Structure,
6-
world::terrain::{Terrain, Worldly},
5+
world::{
6+
demolition::Demolishable,
7+
terrain::{Terrain, Worldly},
8+
},
79
y_sort::YSort,
810
};
911

@@ -151,7 +153,7 @@ fn build_paths(
151153
..default()
152154
},
153155
YSort(0.5),
154-
Structure,
156+
Demolishable,
155157
Pickable::default(),
156158
));
157159

@@ -183,7 +185,7 @@ fn spawn_intersection(
183185
Pathable::walkable(),
184186
Pickable::default(),
185187
YSort::default(),
186-
Structure,
188+
Demolishable,
187189
));
188190

189191
paths_updated_events.write(PathsUpdated);

src/gameplay/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub fn plugin(app: &mut App) {
1919
FactorySystems::Power,
2020
FactorySystems::Logistics,
2121
FactorySystems::Work,
22-
FactorySystems::Dismantle,
22+
FactorySystems::Demolish,
2323
FactorySystems::UI,
2424
)
2525
.chain()
@@ -44,6 +44,6 @@ pub enum FactorySystems {
4444
Power,
4545
Logistics,
4646
Work,
47-
Dismantle,
47+
Demolish,
4848
UI,
4949
}

src/gameplay/structure/dismantle.rs

Lines changed: 0 additions & 115 deletions
This file was deleted.
Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
use bevy::{picking::hover::PickingInteraction, prelude::*};
22

3-
use crate::gameplay::{
4-
structure::{
5-
Structure,
6-
dismantle::{DismantleTimer, Selection},
7-
},
8-
world::terrain::Terrain,
9-
};
3+
use crate::gameplay::{FactorySystems, world::terrain::Terrain};
104

115
const HIGHLIGHT_COLOR: Color = Color::hsl(60.0, 1.0, 0.5);
126

@@ -15,10 +9,7 @@ pub fn plugin(app: &mut App) {
159

1610
app.init_resource::<HighlightColor>();
1711

18-
app.add_systems(
19-
Update,
20-
(highlight_pickable, calculate_dismantle_color, highlight).chain(),
21-
);
12+
app.add_systems(Update, highlight_pickable.before(FactorySystems::Demolish));
2213
}
2314

2415
#[derive(Resource, Reflect)]
@@ -40,30 +31,3 @@ fn highlight_pickable(query: Query<(&mut Sprite, &PickingInteraction), Without<T
4031
}
4132
}
4233
}
43-
44-
fn highlight(
45-
building_sprites: Query<(Entity, &mut Sprite), With<Structure>>,
46-
highlight_color: Res<HighlightColor>,
47-
selection: Res<Selection>,
48-
) {
49-
for (building, mut sprite) in building_sprites {
50-
let color = if selection.contains(&building) {
51-
highlight_color.0
52-
} else {
53-
Default::default()
54-
};
55-
56-
sprite.color = color;
57-
}
58-
}
59-
60-
fn calculate_dismantle_color(
61-
timer: Res<DismantleTimer>,
62-
mut highlight_color: ResMut<HighlightColor>,
63-
) {
64-
let inverse_fraction = 1.0 - timer.fraction();
65-
66-
let hue = 60.0 * inverse_fraction;
67-
68-
highlight_color.0.set_hue(hue);
69-
}

src/gameplay/structure/mod.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ use std::time::Duration;
22

33
use bevy::prelude::*;
44

5-
use crate::gameplay::logistics::{path::Pathable, porter::PorterSpawnTimer};
5+
use crate::gameplay::{
6+
logistics::{path::Pathable, porter::PorterSpawnTimer},
7+
world::demolition::Demolishable,
8+
};
69

710
pub mod assets;
811
pub mod build;
9-
pub mod dismantle;
1012
pub mod highlight;
1113
pub mod interactable;
1214

@@ -16,7 +18,6 @@ pub fn plugin(app: &mut App) {
1618
app.add_plugins((
1719
assets::plugin,
1820
build::plugin,
19-
dismantle::plugin,
2021
highlight::plugin,
2122
interactable::plugin,
2223
));
@@ -26,6 +27,7 @@ pub fn plugin(app: &mut App) {
2627
#[reflect(Component)]
2728
#[require(
2829
Pathable,
29-
PorterSpawnTimer(Timer::new(Duration::from_secs(1), TimerMode::Repeating))
30+
PorterSpawnTimer(Timer::new(Duration::from_secs(1), TimerMode::Repeating)),
31+
Demolishable
3032
)]
3133
pub struct Structure;

src/gameplay/world/demolition.rs

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
use std::collections::HashSet;
2+
3+
use bevy::{input::common_conditions::input_just_pressed, prelude::*};
4+
5+
use crate::gameplay::FactorySystems;
6+
7+
pub const DEMOLISH_BUTTON: KeyCode = KeyCode::KeyF;
8+
pub const DEMOLISH_CANCEL_BUTTON: KeyCode = KeyCode::Escape;
9+
pub const DEMOLISH_DURATION_SECS: f32 = 1.0;
10+
11+
pub(super) fn plugin(app: &mut App) {
12+
app.register_type::<Demolishable>();
13+
14+
app.register_type::<DemolishSelection>();
15+
app.init_resource::<DemolishSelection>();
16+
17+
app.register_type::<DemolishTimer>();
18+
app.init_resource::<DemolishTimer>();
19+
20+
app.add_systems(
21+
Update,
22+
(
23+
add_to_selection.run_if(on_event::<Pointer<Over>>),
24+
remove_from_selection.run_if(on_event::<Pointer<Out>>),
25+
clear_selection.run_if(input_just_pressed(DEMOLISH_CANCEL_BUTTON)),
26+
)
27+
.in_set(FactorySystems::Demolish),
28+
);
29+
30+
app.add_systems(
31+
Update,
32+
(
33+
tick_demolish_timer,
34+
highlight_demolition,
35+
demolish_selection.run_if(demolish_timer_finished),
36+
)
37+
.chain()
38+
.in_set(FactorySystems::Demolish),
39+
);
40+
}
41+
42+
#[derive(Component, Reflect, Debug, Default)]
43+
#[reflect(Component)]
44+
pub struct Demolishable;
45+
46+
#[derive(Resource, Reflect, Debug, Default, Deref, DerefMut)]
47+
#[reflect(Resource)]
48+
pub struct DemolishSelection(HashSet<Entity>);
49+
50+
#[derive(Resource, Reflect, Debug, Deref, DerefMut)]
51+
#[reflect(Resource)]
52+
pub struct DemolishTimer(Timer);
53+
54+
impl Default for DemolishTimer {
55+
fn default() -> Self {
56+
Self(Timer::from_seconds(DEMOLISH_DURATION_SECS, TimerMode::Once))
57+
}
58+
}
59+
60+
fn tick_demolish_timer(
61+
mut timer: ResMut<DemolishTimer>,
62+
keys: Res<ButtonInput<KeyCode>>,
63+
time: Res<Time>,
64+
) {
65+
if keys.just_released(DEMOLISH_BUTTON) {
66+
timer.reset();
67+
}
68+
69+
if keys.pressed(DEMOLISH_BUTTON) {
70+
timer.tick(time.delta());
71+
}
72+
}
73+
74+
fn demolish_timer_finished(timer: Res<DemolishTimer>) -> bool {
75+
timer.just_finished()
76+
}
77+
78+
fn add_to_selection(
79+
mut events: EventReader<Pointer<Over>>,
80+
mut selection: ResMut<DemolishSelection>,
81+
demolishables: Query<Entity, With<Demolishable>>,
82+
) {
83+
for event in events.read() {
84+
if !demolishables.contains(event.target) {
85+
continue;
86+
}
87+
88+
selection.insert(event.target);
89+
}
90+
}
91+
92+
fn remove_from_selection(
93+
mut events: EventReader<Pointer<Out>>,
94+
mut selection: ResMut<DemolishSelection>,
95+
keys: Res<ButtonInput<KeyCode>>,
96+
) {
97+
for event in events.read() {
98+
if keys.pressed(KeyCode::ShiftLeft) {
99+
continue;
100+
}
101+
102+
selection.remove(&event.target);
103+
}
104+
}
105+
106+
fn clear_selection(mut selection: ResMut<DemolishSelection>) {
107+
selection.clear();
108+
}
109+
110+
fn highlight_demolition(
111+
timer: Res<DemolishTimer>,
112+
selection: Res<DemolishSelection>,
113+
mut sprites: Query<&mut Sprite, With<Demolishable>>,
114+
) {
115+
let inverse_fraction = 1.0 - timer.fraction();
116+
117+
let hue = 60.0 * inverse_fraction;
118+
119+
for entity in selection.iter() {
120+
if let Ok(mut sprite) = sprites.get_mut(*entity) {
121+
sprite.color = Color::hsl(hue, 1.0, 0.5);
122+
}
123+
}
124+
}
125+
126+
fn demolish_selection(mut selection: ResMut<DemolishSelection>, mut commands: Commands) {
127+
for demolishable in selection.drain() {
128+
commands.entity(demolishable).despawn();
129+
}
130+
}

0 commit comments

Comments
 (0)