From a62ae8dfe7acd7b8a85079006a35d6662761070d Mon Sep 17 00:00:00 2001 From: Ryan Walters Date: Mon, 1 Sep 2025 15:39:17 -0500 Subject: [PATCH] fix: energizers don't change dead (eyes) ghosts --- src/systems/item.rs | 6 +++-- tests/item.rs | 53 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/systems/item.rs b/src/systems/item.rs index 09ef60c..d6478f6 100644 --- a/src/systems/item.rs +++ b/src/systems/item.rs @@ -60,9 +60,11 @@ pub fn item_system( // Convert seconds to frames (assumes 60 FPS) let total_ticks = 60 * 5; // 5 seconds total - // Set all ghosts to frightened state + // Set all ghosts to frightened state, except those in Eyes state for mut ghost_state in ghost_query.iter_mut() { - *ghost_state = GhostState::new_frightened(total_ticks, FRIGHTENED_FLASH_START_TICKS); + if !matches!(*ghost_state, GhostState::Eyes) { + *ghost_state = GhostState::new_frightened(total_ticks, FRIGHTENED_FLASH_START_TICKS); + } } } } diff --git a/tests/item.rs b/tests/item.rs index 963d50b..f1b229f 100644 --- a/tests/item.rs +++ b/tests/item.rs @@ -4,8 +4,8 @@ use pacman::{ events::GameEvent, map::builder::Map, systems::{ - is_valid_item_collision, item_system, AudioEvent, AudioState, EntityType, ItemCollider, PacmanCollider, Position, - ScoreResource, + is_valid_item_collision, item_system, AudioEvent, AudioState, EntityType, Ghost, GhostCollider, GhostState, ItemCollider, + PacmanCollider, Position, ScoreResource, }, }; @@ -75,6 +75,18 @@ fn spawn_test_item(world: &mut World, item_type: EntityType) -> Entity { world.spawn((Position::Stopped { node: 1 }, item_type, ItemCollider)).id() } +fn spawn_test_ghost(world: &mut World, ghost_state: GhostState) -> Entity { + world + .spawn(( + Position::Stopped { node: 2 }, + Ghost::Blinky, + EntityType::Ghost, + GhostCollider, + ghost_state, + )) + .id() +} + fn send_collision_event(world: &mut World, entity1: Entity, entity2: Entity) { let mut events = world.resource_mut::>(); events.send(GameEvent::Collision(entity1, entity2)); @@ -251,3 +263,40 @@ fn test_item_system_preserves_existing_score() { let score = world.resource::(); assert_eq!(score.0, 110); } + +#[test] +fn test_power_pellet_does_not_affect_ghosts_in_eyes_state() { + let mut world = create_test_world(); + let pacman = spawn_test_pacman(&mut world); + let power_pellet = spawn_test_item(&mut world, EntityType::PowerPellet); + + // Spawn a ghost in Eyes state (returning to ghost house) + let eyes_ghost = spawn_test_ghost(&mut world, GhostState::Eyes); + + // Spawn a ghost in Normal state + let normal_ghost = spawn_test_ghost(&mut world, GhostState::Normal); + + send_collision_event(&mut world, pacman, power_pellet); + + world.run_system_once(item_system).expect("System should run successfully"); + + // Check that the power pellet was collected and score updated + let score = world.resource::(); + assert_eq!(score.0, 50); + + // Check that the power pellet was despawned + let power_pellet_count = world + .query::<&EntityType>() + .iter(&world) + .filter(|&entity_type| matches!(entity_type, EntityType::PowerPellet)) + .count(); + assert_eq!(power_pellet_count, 0); + + // Check that the Eyes ghost state was not changed + let eyes_ghost_state = world.entity(eyes_ghost).get::().unwrap(); + assert!(matches!(*eyes_ghost_state, GhostState::Eyes)); + + // Check that the Normal ghost state was changed to Frightened + let normal_ghost_state = world.entity(normal_ghost).get::().unwrap(); + assert!(matches!(*normal_ghost_state, GhostState::Frightened { .. })); +}