Chapter 20

This commit is contained in:
Kasper Juul Hermansen 2022-01-29 14:14:34 +01:00
parent fdeabefd75
commit 62240a42c1
Signed by: kjuulh
GPG Key ID: DCD9397082D97069
13 changed files with 75 additions and 27 deletions

File diff suppressed because one or more lines are too long

View File

@ -213,3 +213,7 @@ pub struct HungerClock {
#[derive(Component, Debug, Serialize, Deserialize, Clone)] #[derive(Component, Debug, Serialize, Deserialize, Clone)]
pub struct ProvidesFood {} pub struct ProvidesFood {}
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
pub struct MagicMapper {}

View File

@ -1,4 +1,4 @@
use rltk::console;
use specs::prelude::*; use specs::prelude::*;
use crate::components::{CombatStats, Player, SufferDamage}; use crate::components::{CombatStats, Player, SufferDamage};

View File

@ -8,7 +8,7 @@ use crate::Player;
use crate::Position; use crate::Position;
use crate::{CombatStats, InBackpack, RunState, State, Viewshed}; use crate::{CombatStats, InBackpack, RunState, State, Viewshed};
use crate::{Equipped, Map}; use crate::{Equipped, Map};
use crate::{HungerClock, HungerState, HungerSystem, Name}; use crate::{HungerClock, HungerState, Name};
pub fn draw_ui(ecs: &World, ctx: &mut Rltk) { pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
ctx.draw_box( ctx.draw_box(

View File

@ -1,6 +1,6 @@
use specs::prelude::*; use specs::prelude::*;
use crate::{CombatStats, GameLog, Heals}; use crate::{CombatStats, Heals};
pub struct HealingSystem {} pub struct HealingSystem {}

View File

@ -1,7 +1,7 @@
use specs::prelude::*; use specs::prelude::*;
use crate::spawner::player;
use crate::{GameLog, Heals, HungerClock, HungerState, ProvidesHealing, RunState, SufferDamage}; use crate::{GameLog, Heals, HungerClock, HungerState, RunState, SufferDamage};
pub struct HungerSystem {} pub struct HungerSystem {}
@ -24,7 +24,7 @@ impl<'a> System<'a> for HungerSystem {
run_state, run_state,
mut suffer_damage, mut suffer_damage,
mut game_log, mut game_log,
mut heals, _heals,
) = data; ) = data;
for (entity, mut clock) in (&entities, &mut hunger_clock).join() { for (entity, mut clock) in (&entities, &mut hunger_clock).join() {
let mut proceed = false; let mut proceed = false;

View File

@ -1,12 +1,8 @@
use specs::prelude::*; use specs::prelude::*;
use crate::{AreaOfEffect, CombatStats, Confusion, Consumable, Equippable, Equipped, HungerClock, HungerState, InBackpack, InflictsDamage, MagicMapper, Map, Name, Position, ProvidesFood, ProvidesHealing, Ranged, RunState, SufferDamage, WantsToDropItem, WantsToPickupItem, WantsToRemoveItem, WantsToUseItem};
use crate::gamelog::GameLog; use crate::gamelog::GameLog;
use crate::particle_system::ParticleBuilder; use crate::particle_system::ParticleBuilder;
use crate::{
AreaOfEffect, CombatStats, Confusion, Consumable, Equippable, Equipped, HungerClock,
HungerState, InBackpack, InflictsDamage, Map, Name, Position, ProvidesFood, ProvidesHealing,
Ranged, SufferDamage, WantsToDropItem, WantsToPickupItem, WantsToRemoveItem, WantsToUseItem,
};
pub struct ItemCollectionSystem {} pub struct ItemCollectionSystem {}
@ -63,7 +59,7 @@ impl<'a> System<'a> for ItemUseSystem {
ReadStorage<'a, ProvidesHealing>, ReadStorage<'a, ProvidesHealing>,
ReadStorage<'a, InflictsDamage>, ReadStorage<'a, InflictsDamage>,
ReadStorage<'a, Ranged>, ReadStorage<'a, Ranged>,
ReadExpect<'a, Map>, WriteExpect<'a, Map>,
WriteStorage<'a, SufferDamage>, WriteStorage<'a, SufferDamage>,
ReadStorage<'a, AreaOfEffect>, ReadStorage<'a, AreaOfEffect>,
WriteStorage<'a, Confusion>, WriteStorage<'a, Confusion>,
@ -74,6 +70,8 @@ impl<'a> System<'a> for ItemUseSystem {
ReadStorage<'a, Position>, ReadStorage<'a, Position>,
ReadStorage<'a, ProvidesFood>, ReadStorage<'a, ProvidesFood>,
WriteStorage<'a, HungerClock>, WriteStorage<'a, HungerClock>,
ReadStorage<'a, MagicMapper>,
WriteExpect<'a, RunState>
); );
fn run(&mut self, data: Self::SystemData) { fn run(&mut self, data: Self::SystemData) {
@ -87,8 +85,8 @@ impl<'a> System<'a> for ItemUseSystem {
mut combat_stats, mut combat_stats,
healing, healing,
inflicts_damage, inflicts_damage,
ranged, _ranged,
map, mut map,
mut suffer_damage, mut suffer_damage,
aoe, aoe,
mut confused, mut confused,
@ -99,6 +97,8 @@ impl<'a> System<'a> for ItemUseSystem {
positions, positions,
provides_food, provides_food,
mut hunger_clocks, mut hunger_clocks,
magic_mapper,
mut run_state
) = data; ) = data;
for (entity, use_item) in (&entities, &wants_use).join() { for (entity, use_item) in (&entities, &wants_use).join() {
@ -142,7 +142,13 @@ impl<'a> System<'a> for ItemUseSystem {
} }
} }
if let Some(item_edible) = provides_food.get(use_item.item) { if let Some(_mapper) = magic_mapper.get(use_item.item) {
used_item = true;
game_log.entries.push("The map is revealed to you!".to_string());
*run_state = RunState::MagicMapReveal {row: 0};
}
if let Some(_item_edible) = provides_food.get(use_item.item) {
used_item = true; used_item = true;
let target = targets[0]; let target = targets[0];
if let Some(hc) = hunger_clocks.get_mut(target) { if let Some(hc) = hunger_clocks.get_mut(target) {

View File

@ -59,6 +59,7 @@ pub enum RunState {
NextLevel, NextLevel,
ShowRemoveItem, ShowRemoveItem,
GameOver, GameOver,
MagicMapReveal { row: i32 },
} }
pub struct State { pub struct State {
@ -284,6 +285,10 @@ impl GameState for State {
RunState::PlayerTurn => { RunState::PlayerTurn => {
self.run_systems(); self.run_systems();
new_run_state = RunState::MonsterTurn; new_run_state = RunState::MonsterTurn;
match *self.ecs.fetch::<RunState>() {
RunState::MagicMapReveal { .. } => { new_run_state = RunState::MagicMapReveal { row: 0 } }
_ => { new_run_state = RunState::MonsterTurn; }
}
} }
RunState::MonsterTurn => { RunState::MonsterTurn => {
self.run_systems(); self.run_systems();
@ -416,6 +421,20 @@ impl GameState for State {
} }
} }
} }
RunState::MagicMapReveal {
row
} => {
let mut map = self.ecs.fetch_mut::<Map>();
for x in 0..MAP_WIDTH {
let idx = map.xy_idx(x as i32, row);
map.revealed_tiles[idx] = true;
}
if row as usize == MAP_HEIGHT - 1 {
new_run_state = RunState::MonsterTurn;
} else {
new_run_state = RunState::MagicMapReveal {row: row + 1}
}
}
} }
{ {
@ -471,6 +490,7 @@ fn main() -> rltk::BError {
gs.ecs.register::<HungerClock>(); gs.ecs.register::<HungerClock>();
gs.ecs.register::<Heals>(); gs.ecs.register::<Heals>();
gs.ecs.register::<ProvidesFood>(); gs.ecs.register::<ProvidesFood>();
gs.ecs.register::<MagicMapper>();
gs.ecs.insert(SimpleMarkerAllocator::<SerializeMe>::new()); gs.ecs.insert(SimpleMarkerAllocator::<SerializeMe>::new());

View File

@ -246,7 +246,7 @@ pub fn draw_map(ecs: &World, ctx: &mut Rltk) {
} }
fn wall_glyph(map: &Map, x: i32, y: i32) -> FontCharType { fn wall_glyph(map: &Map, x: i32, y: i32) -> FontCharType {
if x < 1 || x > map.width - 2 || y < 1 || y > map.height - 2 as i32 { if x < 1 || x > map.width - 2 || y < 1 || y > map.height - 2_i32 {
return 35; return 35;
} }
let mut mask: u8 = 0; let mut mask: u8 = 0;

View File

@ -7,7 +7,7 @@ pub fn cull_dead_particles(ecs: &mut World, ctx: &Rltk) {
let mut dead_particles: Vec<Entity> = Vec::new(); let mut dead_particles: Vec<Entity> = Vec::new();
{ {
let mut particles = ecs.write_storage::<ParticleLifetime>(); let mut particles = ecs.write_storage::<ParticleLifetime>();
let mut entities = ecs.entities(); let entities = ecs.entities();
for (entity, mut particle) in (&entities, &mut particles).join() { for (entity, mut particle) in (&entities, &mut particles).join() {
particle.lifetime_ms -= ctx.frame_time_ms; particle.lifetime_ms -= ctx.frame_time_ms;
if particle.lifetime_ms < 0. { if particle.lifetime_ms < 0. {

View File

@ -4,7 +4,7 @@ use rltk::{Point, Rltk, VirtualKeyCode};
use specs::prelude::*; use specs::prelude::*;
use crate::gamelog::GameLog; use crate::gamelog::GameLog;
use crate::spawner::player;
use crate::{ use crate::{
components::{CombatStats, Player, Position, Viewshed, WantsToMelee}, components::{CombatStats, Player, Position, Viewshed, WantsToMelee},
map::Map, map::Map,

View File

@ -80,7 +80,8 @@ pub fn save_game(ecs: &mut World) {
ParticleLifetime, ParticleLifetime,
HungerClock, HungerClock,
Heals, Heals,
ProvidesFood ProvidesFood,
MagicMapper
); );
} }
@ -163,7 +164,8 @@ pub fn load_game(ecs: &mut World) {
ParticleLifetime, ParticleLifetime,
HungerClock, HungerClock,
Heals, Heals,
ProvidesFood ProvidesFood,
MagicMapper
); );
} }

View File

@ -4,14 +4,9 @@ use rltk::{FontCharType, RandomNumberGenerator, RGB};
use specs::prelude::*; use specs::prelude::*;
use specs::saveload::{MarkedBuilder, SimpleMarker}; use specs::saveload::{MarkedBuilder, SimpleMarker};
use crate::{AreaOfEffect, BlocksTile, CombatStats, Confusion, Consumable, DefenseBonus, EquipmentSlot, Equippable, HungerClock, HungerState, InflictsDamage, Item, MagicMapper, MAP_WIDTH, MAX_MONSTER, MeleePowerBonus, Monster, Name, Player, Position, ProvidesFood, ProvidesHealing, Ranged, Renderable, SerializeMe, Viewshed};
use crate::random_table::RandomTable; use crate::random_table::RandomTable;
use crate::rect::Rect; use crate::rect::Rect;
use crate::{
AreaOfEffect, BlocksTile, CombatStats, Confusion, Consumable, DefenseBonus, EquipmentSlot,
Equippable, HungerClock, HungerState, InflictsDamage, Item, MeleePowerBonus, Monster, Name,
Player, Position, ProvidesFood, ProvidesHealing, Ranged, Renderable, SerializeMe, Viewshed,
MAP_WIDTH, MAX_MONSTER,
};
pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity { pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
ecs.create_entity() ecs.create_entity()
@ -131,6 +126,7 @@ pub fn spawn_room(ecs: &mut World, room: &Rect, map_depth: i32) {
"Leggings" => leggings(ecs, x, y), "Leggings" => leggings(ecs, x, y),
"Sabatons" => sabatons(ecs, x, y), "Sabatons" => sabatons(ecs, x, y),
"Rations" => rations(ecs, x, y), "Rations" => rations(ecs, x, y),
"Magic Mapping Scroll" => magic_mapper_scroll(ecs, x, y),
_ => {} _ => {}
} }
} }
@ -233,6 +229,7 @@ pub fn room_table(map_depth: i32) -> RandomTable {
.add("Leggings", map_depth - 4) .add("Leggings", map_depth - 4)
.add("Sabatons", map_depth - 4) .add("Sabatons", map_depth - 4)
.add("Rations", 10) .add("Rations", 10)
.add("Magic Mapping Scroll", 2)
} }
fn dagger(ecs: &mut World, x: i32, y: i32) { fn dagger(ecs: &mut World, x: i32, y: i32) {
@ -423,3 +420,22 @@ fn rations(ecs: &mut World, x: i32, y: i32) {
.marked::<SimpleMarker<SerializeMe>>() .marked::<SimpleMarker<SerializeMe>>()
.build(); .build();
} }
fn magic_mapper_scroll(ecs: &mut World, x: i32, y: i32) {
ecs.create_entity()
.with(Position { x, y })
.with(Renderable {
glyph: rltk::to_cp437(')'),
render_order: 2,
fg: RGB::named(rltk::CYAN3),
bg: RGB::named(rltk::BLACK),
})
.with(Item {})
.with(Name {
name: "Scroll to Magic Mapping".to_string(),
})
.with(Consumable {})
.with(MagicMapper {})
.marked::<SimpleMarker<SerializeMe>>()
.build();
}