304 lines
12 KiB
Rust
304 lines
12 KiB
Rust
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<Entity> = 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::<WantsToWhip>(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>(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<Entity> = Vec::new();
|
|
|
|
for (entity, _) in world.query_mut::<With<Player, With<Position, Without<WantsToWhip, ()>>>>() {
|
|
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;
|
|
}
|
|
}
|