Compare commits
2 commits
ce05dcb194
...
38d3333635
Author | SHA1 | Date | |
---|---|---|---|
38d3333635 | |||
36d109654c |
11 changed files with 209 additions and 56 deletions
|
@ -13,3 +13,5 @@ pub const MAP_SIZE: usize = MAP_WIDTH * MAP_HEIGHT;
|
|||
|
||||
pub const MAP_X: usize = 1;
|
||||
pub const MAP_Y: usize = 1;
|
||||
|
||||
pub const BASE_WHIP_POWER: u32 = 2;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::constants::{SIDEBAR_POS_X, SIDEBAR_POS_Y};
|
||||
use crate::constants::*;
|
||||
use crate::graphics::vga_color as vga;
|
||||
use crate::resources::Resources;
|
||||
use bracket_lib::prelude::*;
|
||||
|
@ -48,7 +48,15 @@ pub fn draw(resources: &Resources, bterm: &mut BTerm) {
|
|||
let stats = &resources.stats;
|
||||
bterm.print_centered_at(SIDEBAR_POS_X + 6, SIDEBAR_POS_Y + 1, stats.score * 10);
|
||||
bterm.print_centered_at(SIDEBAR_POS_X + 6, SIDEBAR_POS_Y + 7, stats.gems);
|
||||
bterm.print_centered_at(SIDEBAR_POS_X + 6, SIDEBAR_POS_Y + 10, stats.whips);
|
||||
bterm.print_centered_at(
|
||||
SIDEBAR_POS_X + 6,
|
||||
SIDEBAR_POS_Y + 10,
|
||||
if stats.whip_power <= BASE_WHIP_POWER {
|
||||
stats.whips.to_string()
|
||||
} else {
|
||||
format!("{}+{}", stats.whips, stats.whip_power - BASE_WHIP_POWER)
|
||||
},
|
||||
);
|
||||
bterm.print_centered_at(SIDEBAR_POS_X + 6, SIDEBAR_POS_Y + 13, stats.teleports);
|
||||
bterm.print_centered_at(SIDEBAR_POS_X + 6, SIDEBAR_POS_Y + 16, stats.keys);
|
||||
|
||||
|
|
|
@ -25,6 +25,9 @@ pub fn handle_intent(bterm: &mut BTerm, _world: &mut World, resources: &mut Reso
|
|||
FlashingMessageIntent::Save => todo!(),
|
||||
FlashingMessageIntent::Restore => todo!(),
|
||||
FlashingMessageIntent::Restart => todo!(),
|
||||
&FlashingMessageIntent::NextLevel => {
|
||||
resources.should_advance_level = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,12 @@ use bracket_lib::prelude::*;
|
|||
use hecs::{Entity, With, Without, World};
|
||||
|
||||
use crate::{
|
||||
components::monster::*, components::*, constants::*, resources::*, systems, tile_data::TileType,
|
||||
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) {
|
||||
|
@ -60,6 +65,12 @@ pub fn try_move(delta_x: i32, delta_y: i32, world: &mut World, resources: &mut R
|
|||
} 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);
|
||||
}
|
||||
|
@ -78,16 +89,45 @@ fn try_step(point: Point, _world: &World, resources: &mut Resources) -> bool {
|
|||
crate::tile_data::TileType::Floor
|
||||
| crate::tile_data::TileType::Slow
|
||||
| crate::tile_data::TileType::Medium
|
||||
| crate::tile_data::TileType::Fast => true,
|
||||
crate::tile_data::TileType::Block | crate::tile_data::TileType::Wall => {
|
||||
| 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 => {
|
||||
|
@ -96,13 +136,27 @@ fn try_step(point: Point, _world: &World, resources: &mut Resources) -> bool {
|
|||
{
|
||||
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 => {
|
||||
resources.should_advance_level = true;
|
||||
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!(),
|
||||
|
@ -130,6 +184,14 @@ fn try_step(point: Point, _world: &World, resources: &mut Resources) -> bool {
|
|||
{
|
||||
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);
|
||||
|
@ -142,6 +204,13 @@ fn try_step(point: Point, _world: &World, resources: &mut Resources) -> bool {
|
|||
{
|
||||
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);
|
||||
|
@ -199,7 +268,6 @@ fn try_step(point: Point, _world: &World, resources: &mut Resources) -> bool {
|
|||
crate::tile_data::TileType::Trap11 => todo!(),
|
||||
crate::tile_data::TileType::Trap12 => todo!(),
|
||||
crate::tile_data::TileType::Trap13 => todo!(),
|
||||
crate::tile_data::TileType::Player => true,
|
||||
crate::tile_data::TileType::Punctuation => todo!(),
|
||||
crate::tile_data::TileType::Letter(_) => todo!(),
|
||||
}
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
use crate::constants::*;
|
||||
|
||||
pub enum Difficulty {
|
||||
Novice,
|
||||
Experienced,
|
||||
Advanced,
|
||||
Secret,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
|
||||
pub struct Difficulty {
|
||||
pub struct DifficultySettings {
|
||||
pub value: u32,
|
||||
pub starting_gems: u32,
|
||||
pub starting_whips: u32,
|
||||
|
@ -8,38 +17,49 @@ pub struct Difficulty {
|
|||
pub starting_whip_power: u32,
|
||||
}
|
||||
|
||||
pub const SECRET: Difficulty = Difficulty {
|
||||
impl From<&Difficulty> for DifficultySettings {
|
||||
fn from(difficulty: &Difficulty) -> Self {
|
||||
match difficulty {
|
||||
Difficulty::Novice => NOVICE,
|
||||
Difficulty::Experienced => EXPERIENCED,
|
||||
Difficulty::Advanced => ADVANCED,
|
||||
Difficulty::Secret => SECRET,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const SECRET: DifficultySettings = DifficultySettings {
|
||||
value: 9,
|
||||
starting_gems: 250,
|
||||
starting_whips: 100,
|
||||
starting_teleports: 50,
|
||||
starting_keys: 1,
|
||||
starting_whip_power: 3,
|
||||
starting_whip_power: BASE_WHIP_POWER + 1,
|
||||
};
|
||||
|
||||
pub const NOVICE: Difficulty = Difficulty {
|
||||
const NOVICE: DifficultySettings = DifficultySettings {
|
||||
value: 8,
|
||||
starting_gems: 20,
|
||||
starting_whips: 10,
|
||||
starting_teleports: 0,
|
||||
starting_keys: 0,
|
||||
starting_whip_power: 0,
|
||||
starting_whip_power: BASE_WHIP_POWER,
|
||||
};
|
||||
|
||||
pub const EXPERIENCED: Difficulty = Difficulty {
|
||||
const EXPERIENCED: DifficultySettings = DifficultySettings {
|
||||
value: 5,
|
||||
starting_gems: 15,
|
||||
starting_whips: 0,
|
||||
starting_teleports: 0,
|
||||
starting_keys: 0,
|
||||
starting_whip_power: 0,
|
||||
starting_whip_power: BASE_WHIP_POWER,
|
||||
};
|
||||
|
||||
pub const ADVANCED: Difficulty = Difficulty {
|
||||
const ADVANCED: DifficultySettings = DifficultySettings {
|
||||
value: 2,
|
||||
starting_gems: 10,
|
||||
starting_whips: 0,
|
||||
starting_teleports: 0,
|
||||
starting_keys: 0,
|
||||
starting_whip_power: 0,
|
||||
starting_whip_power: BASE_WHIP_POWER,
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@ pub enum FlashingMessageIntent {
|
|||
Save,
|
||||
Restore,
|
||||
Restart,
|
||||
NextLevel,
|
||||
}
|
||||
|
||||
pub struct FlashingMessage {
|
||||
|
|
|
@ -1,5 +1,24 @@
|
|||
#[derive(Debug, Default)]
|
||||
pub struct MessageShown {
|
||||
pub touched_boundary: bool,
|
||||
pub slow_time: bool,
|
||||
pub speed_time: bool,
|
||||
pub whip: bool,
|
||||
pub gem: bool,
|
||||
pub teleport_scroll: bool,
|
||||
pub stairs: bool,
|
||||
}
|
||||
|
||||
impl MessageShown {
|
||||
pub fn all_shown() -> Self {
|
||||
MessageShown {
|
||||
touched_boundary: true,
|
||||
slow_time: true,
|
||||
speed_time: true,
|
||||
whip: true,
|
||||
gem: true,
|
||||
teleport_scroll: true,
|
||||
stairs: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,10 +9,10 @@ pub mod stats;
|
|||
|
||||
use bracket_lib::prelude::*;
|
||||
pub use clock::{Clock, StopClock};
|
||||
pub use difficulty::Difficulty;
|
||||
pub use difficulty::DifficultySettings;
|
||||
pub use flashing_message::FlashingMessage;
|
||||
pub use map::Map;
|
||||
use message_shown::MessageShown;
|
||||
pub use message_shown::MessageShown;
|
||||
pub use sound_effects::SoundEffects;
|
||||
pub use sound_output::SoundOutput;
|
||||
pub use stats::Stats;
|
||||
|
@ -25,7 +25,7 @@ pub struct Resources {
|
|||
pub clock: Clock,
|
||||
pub stop_clock: bool,
|
||||
pub map: Map,
|
||||
pub selected_difficulty: Option<Difficulty>,
|
||||
pub difficulty: Option<DifficultySettings>,
|
||||
pub sound_effects: Option<SoundEffects>,
|
||||
pub sound_output: Option<SoundOutput>,
|
||||
pub flashing_message: Option<FlashingMessage>,
|
||||
|
|
|
@ -34,7 +34,8 @@ pub struct SoundEffects {
|
|||
pub blocked: SoundSamples,
|
||||
pub whipping: SoundSamples,
|
||||
pub whipping_hit: SoundSamples,
|
||||
pub whipping_hit_end: SoundSamples,
|
||||
pub whipping_hit_enemy: SoundSamples,
|
||||
pub whipping_hit_block: SoundSamples,
|
||||
pub slow_hit: SoundSamples,
|
||||
pub medium_hit: SoundSamples,
|
||||
pub fast_hit: SoundSamples,
|
||||
|
@ -121,23 +122,27 @@ impl SoundEffects {
|
|||
}],
|
||||
}),
|
||||
whipping_hit: sound_output.render_sound_effect(&SoundEffect {
|
||||
sounds: vec![
|
||||
Sound {
|
||||
sound_type: SoundType::Tone(400),
|
||||
duration: Duration::from_millis(20),
|
||||
},
|
||||
Sound {
|
||||
sound_type: SoundType::Tone(90),
|
||||
duration: Duration::from_secs(3),
|
||||
},
|
||||
],
|
||||
sounds: vec![Sound {
|
||||
sound_type: SoundType::Tone(90),
|
||||
duration: Duration::from_secs(3),
|
||||
}],
|
||||
}),
|
||||
whipping_hit_end: sound_output.render_sound_effect(&SoundEffect {
|
||||
whipping_hit_enemy: sound_output.render_sound_effect(&SoundEffect {
|
||||
sounds: vec![Sound {
|
||||
sound_type: SoundType::Tone(400),
|
||||
duration: Duration::from_millis(20),
|
||||
}],
|
||||
}),
|
||||
whipping_hit_block: sound_output.render_sound_effect(&SoundEffect {
|
||||
sounds: (20..=5700)
|
||||
.rev()
|
||||
.step_by(100)
|
||||
.map(|x| Sound {
|
||||
sound_type: SoundType::Noise(0, x),
|
||||
duration: Duration::from_millis(18),
|
||||
})
|
||||
.collect(),
|
||||
}),
|
||||
slow_hit: sound_output.render_sound_effect(&SoundEffect {
|
||||
sounds: vec![Sound {
|
||||
sound_type: SoundType::Tone(400),
|
||||
|
|
25
src/state.rs
25
src/state.rs
|
@ -1,10 +1,10 @@
|
|||
use instant::Instant;
|
||||
|
||||
use crate::resources::clock::Clock;
|
||||
use crate::resources::difficulty::*;
|
||||
use crate::resources::flashing_message::{FlashingMessage, FlashingMessageIntent};
|
||||
use crate::resources::sound_effects::SoundEffects;
|
||||
use crate::resources::stats::Stats;
|
||||
use crate::resources::{difficulty::*, MessageShown};
|
||||
use crate::resources::{Map, Resources, SoundOutput};
|
||||
use crate::{graphics, input, levels, systems};
|
||||
use bracket_lib::prelude::*;
|
||||
|
@ -43,7 +43,8 @@ impl State {
|
|||
}
|
||||
|
||||
let starting_level = 0;
|
||||
let selected_difficulty = SECRET;
|
||||
let selected_difficulty = Difficulty::Secret;
|
||||
let difficulty_settings = DifficultySettings::from(&selected_difficulty);
|
||||
|
||||
let mut world = World::new();
|
||||
|
||||
|
@ -56,11 +57,11 @@ impl State {
|
|||
player_input: None,
|
||||
stats: Stats {
|
||||
score: 0,
|
||||
gems: selected_difficulty.starting_gems,
|
||||
whips: selected_difficulty.starting_whips,
|
||||
whip_power: selected_difficulty.starting_whip_power,
|
||||
teleports: selected_difficulty.starting_teleports,
|
||||
keys: selected_difficulty.starting_keys,
|
||||
gems: difficulty_settings.starting_gems,
|
||||
whips: difficulty_settings.starting_whips,
|
||||
whip_power: difficulty_settings.starting_whip_power,
|
||||
teleports: difficulty_settings.starting_teleports,
|
||||
keys: difficulty_settings.starting_keys,
|
||||
},
|
||||
clock: Clock {
|
||||
last_ticked: Instant::now(),
|
||||
|
@ -71,12 +72,15 @@ impl State {
|
|||
map,
|
||||
sound_effects,
|
||||
sound_output,
|
||||
selected_difficulty: Some(selected_difficulty),
|
||||
difficulty: Some(difficulty_settings),
|
||||
flashing_message: Some(FlashingMessage::new(
|
||||
"Press any key to begin this level.",
|
||||
Some(FlashingMessageIntent::Start),
|
||||
)),
|
||||
message_shown: Default::default(),
|
||||
message_shown: match selected_difficulty {
|
||||
Difficulty::Novice | Difficulty::Experienced => Default::default(),
|
||||
_ => MessageShown::all_shown(),
|
||||
},
|
||||
should_advance_level: false,
|
||||
speed_time_ticks: 0,
|
||||
slow_time_ticks: 0,
|
||||
|
@ -92,9 +96,6 @@ impl State {
|
|||
self.resources.map = Map::from(levels::get_level(self.resources.level_number));
|
||||
self.resources.map.spawn_entities(&mut self.world);
|
||||
|
||||
self.resources.flashing_message =
|
||||
Some(FlashingMessage::from("Press any key to begin this level."));
|
||||
|
||||
self.resources.should_advance_level = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ use hecs::{Entity, World};
|
|||
use crate::{
|
||||
components::{monster::damage_for_kind, Monster, Position, WantsToWhip},
|
||||
resources::Resources,
|
||||
tile_data::TileType,
|
||||
};
|
||||
|
||||
pub fn run(world: &mut World, resources: &mut Resources) {
|
||||
|
@ -73,23 +74,15 @@ pub fn run(world: &mut World, resources: &mut Resources) {
|
|||
resources.stats.add_score(damage_for_kind(monster.kind));
|
||||
to_kill.push(e);
|
||||
resources.map.clear_tile_content_at(dest);
|
||||
if let Some(sound) = &mut wants_to_whip.sound {
|
||||
sound.control::<oddio::Stop<_>, _>().stop();
|
||||
}
|
||||
if wants_to_whip.frame == 7 {
|
||||
wants_to_whip.sound = None;
|
||||
if let (Some(sound_effects), Some(sound_output)) =
|
||||
(&mut resources.sound_effects, &mut resources.sound_output)
|
||||
{
|
||||
sound_output.play_sound(sound_effects.whipping_hit_end.clone());
|
||||
}
|
||||
} else if let (Some(sound_effects), Some(sound_output)) =
|
||||
if let (Some(sound_effects), Some(sound_output)) =
|
||||
(&mut resources.sound_effects, &mut resources.sound_output)
|
||||
{
|
||||
wants_to_whip.sound =
|
||||
Some(sound_output.play_sound(sound_effects.whipping_hit.clone()));
|
||||
sound_output.play_sound(sound_effects.whipping_hit_enemy.clone());
|
||||
}
|
||||
switch_to_hit_sound(resources, wants_to_whip);
|
||||
}
|
||||
} else {
|
||||
hit_tile(resources, wants_to_whip, dest);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,3 +108,36 @@ pub fn run(world: &mut World, resources: &mut Resources) {
|
|||
let _ = world.remove_one::<WantsToWhip>(e);
|
||||
}
|
||||
}
|
||||
|
||||
fn hit_tile(resources: &mut Resources, wants_to_whip: &mut WantsToWhip, location: Point) {
|
||||
let tile = resources.map.get_tile_at(location);
|
||||
match tile {
|
||||
TileType::Block | TileType::Tree => {
|
||||
let mut rng = RandomNumberGenerator::new();
|
||||
|
||||
if (rng.range(0, 7) as u32) < resources.stats.whip_power {
|
||||
resources.map.set_tile_at(location, TileType::Floor);
|
||||
if let (Some(sound_effects), Some(sound_output)) =
|
||||
(&mut resources.sound_effects, &mut resources.sound_output)
|
||||
{
|
||||
sound_output.play_sound(sound_effects.whipping_hit_block.clone());
|
||||
}
|
||||
switch_to_hit_sound(resources, wants_to_whip);
|
||||
}
|
||||
}
|
||||
TileType::Forest => todo!(),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn switch_to_hit_sound(resources: &mut Resources, wants_to_whip: &mut WantsToWhip) {
|
||||
if let Some(sound) = &mut wants_to_whip.sound {
|
||||
sound.control::<oddio::Stop<_>, _>().stop();
|
||||
}
|
||||
|
||||
if let (Some(sound_effects), Some(sound_output)) =
|
||||
(&mut resources.sound_effects, &mut resources.sound_output)
|
||||
{
|
||||
wants_to_whip.sound = Some(sound_output.play_sound(sound_effects.whipping_hit.clone()));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue