use instant::Instant; use std::time::Duration; use bracket_lib::prelude::*; use hecs::{Entity, With, Without, World}; use crate::{ components::monster::*, components::*, constants::*, resources::{flashing_message::FlashingMessageIntent, *}, systems, tile_data::TileType, }; pub fn try_move(delta_x: i32, delta_y: i32, world: &mut World, resources: &mut Resources) { let mut to_kill: Vec = Vec::new(); for (player_entity, (player, pos)) in &mut world.query::<(&mut Player, &mut Position)>() { // The player shouldn't be able to move while whipping if let Ok(_wants_to_whip) = world.get::(player_entity) { continue; } let now = Instant::now(); if now - player.last_moved > Duration::from_secs_f32(PLAYER_STEP_PERIOD) { let destination = Point { x: pos.x + delta_x, y: pos.y + delta_y, }; if resources.map.in_bounds(destination) { if try_step(destination, world, resources) { if let Some(monster_entity) = resources.map.get_tile_content_at(destination) { if let Ok(monster) = world.get::(monster_entity) { resources.stats.add_score(damage_for_kind(monster.kind)); resources.stats.take_gems(damage_for_kind(monster.kind)); if let (Some(sound_effects), Some(sound_output)) = (&mut resources.sound_effects, &mut resources.sound_output) { sound_output .play_sound(sound_effect_for_kind(monster.kind, sound_effects)); } to_kill.push(monster_entity); } } resources.map.clear_tile_content_at(Point::from(*pos)); pos.x = destination.x; pos.y = destination.y; resources .map .set_tile_content_at(destination, player_entity); systems::time::force_tick(&mut resources.clock); if let (Some(sound_effects), Some(sound_output)) = (&mut resources.sound_effects, &mut resources.sound_output) { sound_output.play_sound(sound_effects.step.clone()); } } } else if let (Some(sound_effects), Some(sound_output)) = (&mut resources.sound_effects, &mut resources.sound_output) { if !resources.message_shown.touched_boundary { resources.flashing_message = Some(FlashingMessage::from( "An Electrified Wall blocks your way.", )); resources.message_shown.touched_boundary = true; } let static_sound = sound_effects.get_new_static_effect(sound_output); sound_output.play_sound(static_sound); } player.last_moved = now; } } for e in to_kill { let _ = world.despawn(e); } } fn try_step(point: Point, _world: &World, resources: &mut Resources) -> bool { match resources.map.get_tile_at(point) { crate::tile_data::TileType::Floor | crate::tile_data::TileType::Slow | crate::tile_data::TileType::Medium | crate::tile_data::TileType::Fast | crate::tile_data::TileType::Player => true, crate::tile_data::TileType::Block => { if let (Some(sound_effects), Some(sound_output)) = (&mut resources.sound_effects, &mut resources.sound_output) { sound_output.play_sound(sound_effects.blocked.clone()); } if !resources.message_shown.touched_boundary { resources.flashing_message = Some(FlashingMessage::from( "An Electrified Wall blocks your way.", )); resources.message_shown.touched_boundary = true; } if resources.stats.score > 2 { resources.stats.take_score(2); } false } crate::tile_data::TileType::Wall => { if let (Some(sound_effects), Some(sound_output)) = (&mut resources.sound_effects, &mut resources.sound_output) { sound_output.play_sound(sound_effects.blocked.clone()); } if !resources.message_shown.touched_boundary { resources.flashing_message = Some(FlashingMessage::from("A Solid Wall blocks your way.")); resources.message_shown.touched_boundary = true; } if resources.stats.score > 2 { resources.stats.take_score(2); } false } crate::tile_data::TileType::Whip => { if let (Some(sound_effects), Some(sound_output)) = (&mut resources.sound_effects, &mut resources.sound_output) { sound_output.play_sound(sound_effects.grab.clone()); } if !resources.message_shown.whip { resources.flashing_message = Some(FlashingMessage::from("You found a Whip.")); resources.message_shown.whip = true; } resources.stats.give_whips(1); resources.stats.add_score(1); resources.map.set_tile_at(point, TileType::Floor); true } crate::tile_data::TileType::Stairs => { if !resources.message_shown.stairs { resources.flashing_message = Some(FlashingMessage::new( "Stairs take you to the next lower level.", Some(FlashingMessageIntent::NextLevel), )); resources.message_shown.stairs = true; } else { resources.should_advance_level = true; } true } crate::tile_data::TileType::Chest => todo!(), crate::tile_data::TileType::SlowTime => { if let (Some(sound_effects), Some(sound_output)) = (&mut resources.sound_effects, &mut resources.sound_output) { sound_output.play_sound(sound_effects.slow_time.clone()); } if !resources.message_shown.slow_time { resources.flashing_message = Some(FlashingMessage::from( "You activated a Slow Creature spell.", )); resources.message_shown.slow_time = true; } resources.slow_time_ticks = 100; resources.map.set_tile_at(point, TileType::Floor); true } crate::tile_data::TileType::Gem => { if let (Some(sound_effects), Some(sound_output)) = (&mut resources.sound_effects, &mut resources.sound_output) { sound_output.play_sound(sound_effects.grab.clone()); } if !resources.message_shown.gem { resources.flashing_message = Some(FlashingMessage::from( "Gems give you both points and strength.", )); resources.message_shown.gem = true; } resources.stats.give_gems(1); resources.stats.add_score(1); resources.map.set_tile_at(point, TileType::Floor); true } crate::tile_data::TileType::Invisible => todo!(), crate::tile_data::TileType::Teleport => { if let (Some(sound_effects), Some(sound_output)) = (&mut resources.sound_effects, &mut resources.sound_output) { sound_output.play_sound(sound_effects.grab.clone()); } if !resources.message_shown.teleport_scroll { resources.flashing_message = Some(FlashingMessage::from("You found a Teleport scroll.")); resources.message_shown.teleport_scroll = true; } resources.stats.give_teleports(1); resources.stats.add_score(1); resources.map.set_tile_at(point, TileType::Floor); true } crate::tile_data::TileType::Key => todo!(), crate::tile_data::TileType::Door => todo!(), crate::tile_data::TileType::SpeedTime => { if let (Some(sound_effects), Some(sound_output)) = (&mut resources.sound_effects, &mut resources.sound_output) { sound_output.play_sound(sound_effects.speed_time.clone()); } if !resources.message_shown.speed_time { resources.flashing_message = Some(FlashingMessage::from( "You activated a Speed Creature spell.", )); resources.message_shown.speed_time = true; } resources.speed_time_ticks = 80; resources.map.set_tile_at(point, TileType::Floor); true } crate::tile_data::TileType::Trap => todo!(), crate::tile_data::TileType::River => todo!(), crate::tile_data::TileType::Power => todo!(), crate::tile_data::TileType::Forest => todo!(), crate::tile_data::TileType::Tree => todo!(), crate::tile_data::TileType::Bomb => todo!(), crate::tile_data::TileType::Lava => todo!(), crate::tile_data::TileType::Pit => todo!(), crate::tile_data::TileType::Tome => todo!(), crate::tile_data::TileType::Tunnel => todo!(), crate::tile_data::TileType::Freeze => todo!(), crate::tile_data::TileType::Nugget => todo!(), crate::tile_data::TileType::Quake => todo!(), crate::tile_data::TileType::InvisibleBlock => todo!(), crate::tile_data::TileType::InvisibleWall => todo!(), crate::tile_data::TileType::InvisibleDoor => todo!(), crate::tile_data::TileType::Stop => todo!(), crate::tile_data::TileType::Zap => todo!(), crate::tile_data::TileType::Create => todo!(), crate::tile_data::TileType::Generator => todo!(), crate::tile_data::TileType::Trap2 => todo!(), crate::tile_data::TileType::Trap3 => todo!(), crate::tile_data::TileType::Trap4 => todo!(), crate::tile_data::TileType::Trap5 => todo!(), crate::tile_data::TileType::Trap6 => todo!(), crate::tile_data::TileType::Trap7 => todo!(), crate::tile_data::TileType::Trap8 => todo!(), crate::tile_data::TileType::Trap9 => todo!(), crate::tile_data::TileType::Trap10 => todo!(), crate::tile_data::TileType::Trap11 => todo!(), crate::tile_data::TileType::Trap12 => todo!(), crate::tile_data::TileType::Trap13 => todo!(), crate::tile_data::TileType::Punctuation => todo!(), crate::tile_data::TileType::Letter(_) => todo!(), } } pub fn whip(world: &mut World, resources: &mut Resources) { let mut to_add: Vec = Vec::new(); for (entity, _) in world.query_mut::>>>() { if resources.stats.whips > 0 { to_add.push(entity); } } for e in to_add { let _ = world.insert_one( e, WantsToWhip { frame: 0, last_frame: Instant::now(), sound: { if let (Some(sound_effects), Some(sound_output)) = (&mut resources.sound_effects, &mut resources.sound_output) { Some(sound_output.play_sound(sound_effects.whipping.clone())) } else { None } }, }, ); resources.stats.whips -= 1; } }