Skip to content

Commit

Permalink
reset the level after beign caught
Browse files Browse the repository at this point in the history
- prevent events handler/removalDetectors to crash by running `Commands::entity()` or `Query::get().unwrap()` after a level change
- chain systems
- FIXME: as issued [here](bevyengine/bevy#12344), the asset will wrongly unload while strong handle is alive after a State Change. It has been fixed in `13.1`
  • Loading branch information
Wabtey committed Aug 8, 2024
1 parent 8755bce commit 5a4bd66
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 70 deletions.
9 changes: 4 additions & 5 deletions src/characters/npcs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,16 @@ impl Plugin for NPCsPlugin {
.add_systems(
Update,
(
// -- Movement --
aggression::player_detection,
aggression::add_pursuit_urge,
movement::npc_walk,
movement::npc_chase,
movement::npc_walk_to,
movement::daze_wait,
movement::give_new_way_point_event,
// -- Aggression --
aggression::player_detection,
aggression::add_pursuit_urge,
aggression::reset_aggro,
movement::give_new_way_point_event,
)
.chain()
.run_if(in_state(Location::Level1000)),
);
}
Expand Down
29 changes: 15 additions & 14 deletions src/characters/npcs/movement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,22 +207,23 @@ pub fn give_new_way_point_event(
way_points_query: Query<Entity, With<WayPoint>>,
) {
for NewWayPointEvent(npc) in new_way_point_event.iter() {
let (mut target, _name) = npc_query.get_mut(*npc).unwrap();

if target.0.is_none() {
let mut rng = rand::thread_rng();
target.0 = Some(way_points_query.iter().choose(&mut rng).unwrap());
} else if let Ok(original_way_point) = way_points_query.get(target.0.unwrap()) {
for way_point in way_points_query.iter() {
if way_point != original_way_point {
target.0 = Some(way_point);
// The entity could have been despawned after a level change
if let Ok((mut target, _name)) = npc_query.get_mut(*npc) {
if target.0.is_none() {
let mut rng = rand::thread_rng();
target.0 = Some(way_points_query.iter().choose(&mut rng).unwrap());
} else if let Ok(original_way_point) = way_points_query.get(target.0.unwrap()) {
for way_point in way_points_query.iter() {
if way_point != original_way_point {
target.0 = Some(way_point);
}
}
// if no other waypoint is found, the npc will be stuck in the current
} else {
// the target is not a way point
let mut rng = rand::thread_rng();
target.0 = Some(way_points_query.iter().choose(&mut rng).unwrap());
}
// if no other waypoint is found, the npc will be stuck in the current
} else {
// the target is not a way point
let mut rng = rand::thread_rng();
target.0 = Some(way_points_query.iter().choose(&mut rng).unwrap());
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/locations/level_one/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ fn despawn_level_one(
for (entity, name) in level_1000_query.iter() {
info!("{name} despawn");
commands.entity(entity).despawn_recursive();
// NOTE: will despawn 40v3 and 40v2 twice
}
}

Expand Down Expand Up @@ -109,7 +110,8 @@ fn setup_level_one(
});

// -- Map --

// FIXME: as issued [here](https://github.com/bevyengine/bevy/issues/12344), the asset will wrongly unload while strong handle is alive after a State Change. It has been fixed in `13.1`
// Will not load a second time after being caught
let walls = asset_server.load("textures/level_one/lab_wall.png");
let floor = asset_server.load("textures/level_one/lab_floor.png");

Expand Down
5 changes: 5 additions & 0 deletions src/locations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ impl Plugin for LocationsPlugin {
app.add_event::<WinTriggerEvent>()
.add_state::<Location>()
.add_plugins(level_one::LevelOnePlugin)
.add_systems(OnEnter(Location::Void), void_transition)
.add_systems(
Update,
(
Expand All @@ -51,3 +52,7 @@ impl Plugin for LocationsPlugin {
);
}
}

fn void_transition(mut next_location: ResMut<NextState<Location>>) {
next_location.set(Location::Level1000);
}
3 changes: 1 addition & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,8 @@ fn main() {
.add_plugins((
debug::DebugPlugin,
spritesheet::CatSpritePlugin,
tablet::hack::HackPlugin,
locations::LocationsPlugin,
tablet::mind_control::MindControlPlugin,
tablet::TabletPlugin,
characters::CharactersPlugin,
))
.add_systems(Startup, spawn_camera);
Expand Down
73 changes: 25 additions & 48 deletions src/tablet/mind_control/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,42 +18,23 @@ pub struct MindControlPlugin;

impl Plugin for MindControlPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<CurrentlyMindControlled>()
.add_systems(
Update,
(
mind_control_button
.run_if(tablet_is_free)
.in_set(MindControlSet::Enter),
exit_mind_control
.run_if(tablet_is_mind_ctrl)
.in_set(MindControlSet::Exit)
.after(MindControlSet::Enter),
daze_cure_by_mind_control
.before(MindControlSet::Exit)
.after(MindControlSet::Enter),
movement::mind_control_movement
.in_set(MindControlSet::Movement)
.after(MindControlSet::Enter),
camera_follow.after(MindControlSet::Movement),
movement::freeze_dazed_character,
)
.run_if(in_state(Location::Level1000)),
app.init_resource::<CurrentlyMindControlled>().add_systems(
Update,
(
mind_control_button.run_if(tablet_is_free),
exit_mind_control.run_if(tablet_is_mind_ctrl),
daze_cure_by_mind_control,
daze_post_mind_control,
movement::mind_control_movement,
camera_follow,
movement::freeze_dazed_character,
)
.add_systems(
PostUpdate,
daze_post_mind_control.run_if(in_state(Location::Level1000)), //.after(MindControlSet::Exit)
);
.chain()
.run_if(in_state(Location::Level1000)),
);
}
}

#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
enum MindControlSet {
Enter,
Exit,
Movement,
}

#[derive(Component)]
pub struct MindControlled;

Expand Down Expand Up @@ -129,24 +110,20 @@ fn daze_post_mind_control(
mut mind_controled_removals: RemovedComponents<MindControlled>,

player_query: Query<Entity, With<Player>>,
npcs_query: Query<Entity, With<NPC>>,
) {
for entity in mind_controled_removals.iter() {
info!("{entity:?} removal MindControlled");
match player_query.get(entity) {
// This is prbly a npc
Err(_) => {
commands.entity(entity).insert(Dazed {
timer: Timer::new(Duration::from_secs(DAZE_TIMER), TimerMode::Once),
});
}
Ok(_) => {
// Will never be decreased (no system for it)
// Only removed by adding MindControlled back to the player
// So the content of the timer is useless
commands.entity(entity).insert(Dazed {
timer: Timer::new(Duration::from_secs(DAZE_TIMER), TimerMode::Repeating),
});
}
if player_query.get(entity).is_ok() {
// Will never be decreased (no system for it)
// Only removed by adding MindControlled back to the player
// So the content of the timer is useless
commands.entity(entity).insert(Dazed {
timer: Timer::new(Duration::from_secs(DAZE_TIMER), TimerMode::Repeating),
});
} else if npcs_query.get(entity).is_ok() {
commands.entity(entity).insert(Dazed {
timer: Timer::new(Duration::from_secs(DAZE_TIMER), TimerMode::Once),
});
}
}
}
Expand Down

0 comments on commit 5a4bd66

Please sign in to comment.