healing potions
This commit is contained in:
parent
aee89fade7
commit
c17b62985b
@ -69,3 +69,19 @@ impl FieldOfView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
|
pub struct ProvidesHealing {
|
||||||
|
pub amount: i32,
|
||||||
|
}
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
|
pub struct ProvidesDungeonMap;
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq)]
|
||||||
|
pub struct Carried(pub Entity);
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
|
pub struct ActivateItem {
|
||||||
|
pub used_by: Entity,
|
||||||
|
pub item: Entity,
|
||||||
|
}
|
||||||
|
@ -44,7 +44,7 @@ impl State {
|
|||||||
map_builder
|
map_builder
|
||||||
.monster_spawns
|
.monster_spawns
|
||||||
.iter()
|
.iter()
|
||||||
.for_each(|pos| spawn_monster(&mut ecs, &mut rng, *pos));
|
.for_each(|pos| spawn_entity(&mut ecs, &mut rng, *pos));
|
||||||
resources.insert(map_builder.map);
|
resources.insert(map_builder.map);
|
||||||
resources.insert(Camera::new(map_builder.player_start));
|
resources.insert(Camera::new(map_builder.player_start));
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ impl State {
|
|||||||
map_builder
|
map_builder
|
||||||
.monster_spawns
|
.monster_spawns
|
||||||
.iter()
|
.iter()
|
||||||
.for_each(|pos| spawn_monster(&mut self.ecs, &mut rng, *pos));
|
.for_each(|pos| spawn_entity(&mut self.ecs, &mut rng, *pos));
|
||||||
self.resources.insert(map_builder.map);
|
self.resources.insert(map_builder.map);
|
||||||
self.resources.insert(Camera::new(map_builder.player_start));
|
self.resources.insert(Camera::new(map_builder.player_start));
|
||||||
self.resources.insert(TurnState::AwaitingInput);
|
self.resources.insert(TurnState::AwaitingInput);
|
||||||
|
@ -58,3 +58,36 @@ pub fn spawn_amulet_of_yala(ecs: &mut World, pos: Point) {
|
|||||||
Name("Amulet of Yala".to_string()),
|
Name("Amulet of Yala".to_string()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
pub fn spawn_healing_potion(ecs: &mut World, pos: Point) {
|
||||||
|
ecs.push((
|
||||||
|
Item,
|
||||||
|
pos,
|
||||||
|
Render {
|
||||||
|
color: ColorPair::new(WHITE, BLACK),
|
||||||
|
glyph: to_cp437('!'),
|
||||||
|
},
|
||||||
|
Name("Healing Potion".to_string()),
|
||||||
|
ProvidesHealing { amount: 6 },
|
||||||
|
));
|
||||||
|
}
|
||||||
|
pub fn spawn_magic_mapper(ecs: &mut World, pos: Point) {
|
||||||
|
ecs.push((
|
||||||
|
Item,
|
||||||
|
pos,
|
||||||
|
Render {
|
||||||
|
color: ColorPair::new(WHITE, BLACK),
|
||||||
|
glyph: to_cp437('{'),
|
||||||
|
},
|
||||||
|
Name("Magic Map".to_string()),
|
||||||
|
ProvidesDungeonMap {},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spawn_entity(ecs: &mut World, rng: &mut RandomNumberGenerator, pos: Point) {
|
||||||
|
let roll = rng.roll_dice(1, 6);
|
||||||
|
match roll {
|
||||||
|
1 => spawn_healing_potion(ecs, pos),
|
||||||
|
2 => spawn_magic_mapper(ecs, pos),
|
||||||
|
_ => spawn_monster(ecs, rng, pos),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,6 +3,9 @@ use crate::prelude::*;
|
|||||||
#[system]
|
#[system]
|
||||||
#[read_component(Health)]
|
#[read_component(Health)]
|
||||||
#[read_component(Player)]
|
#[read_component(Player)]
|
||||||
|
#[read_component(Item)]
|
||||||
|
#[read_component(Carried)]
|
||||||
|
#[read_component(Name)]
|
||||||
pub fn hud(ecs: &SubWorld) {
|
pub fn hud(ecs: &SubWorld) {
|
||||||
let mut health_query = <&Health>::query().filter(component::<Player>());
|
let mut health_query = <&Health>::query().filter(component::<Player>());
|
||||||
let player_health = health_query.iter(ecs).nth(0).unwrap();
|
let player_health = health_query.iter(ecs).nth(0).unwrap();
|
||||||
@ -22,5 +25,27 @@ pub fn hud(ecs: &SubWorld) {
|
|||||||
format!(" Health: {}/{} ", player_health.current, player_health.max,),
|
format!(" Health: {}/{} ", player_health.current, player_health.max,),
|
||||||
ColorPair::new(WHITE, RED),
|
ColorPair::new(WHITE, RED),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let player = <(Entity, &Player)>::query()
|
||||||
|
.iter(ecs)
|
||||||
|
.find_map(|(entity, _player)| Some(*entity))
|
||||||
|
.unwrap();
|
||||||
|
let mut item_query = <(&Item, &Name, &Carried)>::query();
|
||||||
|
let mut y = 3;
|
||||||
|
item_query
|
||||||
|
.iter(ecs)
|
||||||
|
.filter(|(_, _, carried)| carried.0 == player)
|
||||||
|
.for_each(|(_, name, _)| {
|
||||||
|
draw_batch.print(Point::new(3, y), format!("{} : {}", y - 2, &name.0));
|
||||||
|
y += 1;
|
||||||
|
});
|
||||||
|
if y > 3 {
|
||||||
|
draw_batch.print_color(
|
||||||
|
Point::new(3, 2),
|
||||||
|
"Items Carried",
|
||||||
|
ColorPair::new(YELLOW, BLACK),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
draw_batch.submit(10000).expect("Batch Error");
|
draw_batch.submit(10000).expect("Batch Error");
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ mod movement;
|
|||||||
mod player_input;
|
mod player_input;
|
||||||
mod random_move;
|
mod random_move;
|
||||||
mod tooltips;
|
mod tooltips;
|
||||||
|
mod use_items;
|
||||||
|
|
||||||
pub fn build_input_scheduler() -> Schedule {
|
pub fn build_input_scheduler() -> Schedule {
|
||||||
Schedule::builder()
|
Schedule::builder()
|
||||||
@ -24,6 +25,7 @@ pub fn build_input_scheduler() -> Schedule {
|
|||||||
}
|
}
|
||||||
pub fn build_player_scheduler() -> Schedule {
|
pub fn build_player_scheduler() -> Schedule {
|
||||||
Schedule::builder()
|
Schedule::builder()
|
||||||
|
.add_system(use_items::use_items_system())
|
||||||
.add_system(combat::combat_system())
|
.add_system(combat::combat_system())
|
||||||
.flush()
|
.flush()
|
||||||
.add_system(movement::movement_system())
|
.add_system(movement::movement_system())
|
||||||
@ -43,6 +45,7 @@ pub fn build_monster_scheduler() -> Schedule {
|
|||||||
.flush()
|
.flush()
|
||||||
.add_system(fov::fov_system())
|
.add_system(fov::fov_system())
|
||||||
.flush()
|
.flush()
|
||||||
|
.add_system(use_items::use_items_system())
|
||||||
.add_system(combat::combat_system())
|
.add_system(combat::combat_system())
|
||||||
.flush()
|
.flush()
|
||||||
.add_system(movement::movement_system())
|
.add_system(movement::movement_system())
|
||||||
|
@ -5,6 +5,8 @@ use crate::prelude::*;
|
|||||||
#[read_component(Player)]
|
#[read_component(Player)]
|
||||||
#[read_component(Enemy)]
|
#[read_component(Enemy)]
|
||||||
#[write_component(Health)]
|
#[write_component(Health)]
|
||||||
|
#[read_component(Item)]
|
||||||
|
#[read_component(Carried)]
|
||||||
pub fn player_input(
|
pub fn player_input(
|
||||||
ecs: &mut SubWorld,
|
ecs: &mut SubWorld,
|
||||||
commands: &mut CommandBuffer,
|
commands: &mut CommandBuffer,
|
||||||
@ -18,6 +20,30 @@ pub fn player_input(
|
|||||||
VirtualKeyCode::Right => Point::new(1, 0),
|
VirtualKeyCode::Right => Point::new(1, 0),
|
||||||
VirtualKeyCode::Up => Point::new(0, -1),
|
VirtualKeyCode::Up => Point::new(0, -1),
|
||||||
VirtualKeyCode::Down => Point::new(0, 1),
|
VirtualKeyCode::Down => Point::new(0, 1),
|
||||||
|
VirtualKeyCode::G => {
|
||||||
|
let (player, player_pos) = players
|
||||||
|
.iter(ecs)
|
||||||
|
.find_map(|(entity, pos)| Some((*entity, *pos)))
|
||||||
|
.unwrap();
|
||||||
|
let mut items = <(Entity, &Item, &Point)>::query();
|
||||||
|
items
|
||||||
|
.iter(ecs)
|
||||||
|
.filter(|(_entity, _item, &item_pos)| item_pos == player_pos)
|
||||||
|
.for_each(|(entity, _item, _item_pos)| {
|
||||||
|
commands.remove_component::<Point>(*entity);
|
||||||
|
commands.add_component(*entity, Carried(player));
|
||||||
|
});
|
||||||
|
Point::new(0, 0)
|
||||||
|
}
|
||||||
|
VirtualKeyCode::Key1 => use_item(0, ecs, commands),
|
||||||
|
VirtualKeyCode::Key2 => use_item(1, ecs, commands),
|
||||||
|
VirtualKeyCode::Key3 => use_item(2, ecs, commands),
|
||||||
|
VirtualKeyCode::Key4 => use_item(3, ecs, commands),
|
||||||
|
VirtualKeyCode::Key5 => use_item(4, ecs, commands),
|
||||||
|
VirtualKeyCode::Key6 => use_item(5, ecs, commands),
|
||||||
|
VirtualKeyCode::Key7 => use_item(6, ecs, commands),
|
||||||
|
VirtualKeyCode::Key8 => use_item(7, ecs, commands),
|
||||||
|
VirtualKeyCode::Key9 => use_item(8, ecs, commands),
|
||||||
_ => Point::new(0, 0),
|
_ => Point::new(0, 0),
|
||||||
};
|
};
|
||||||
let (player_entity, destination) = players
|
let (player_entity, destination) = players
|
||||||
@ -57,15 +83,30 @@ pub fn player_input(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !did_something {
|
|
||||||
if let Ok(mut health) = ecs
|
|
||||||
.entry_mut(player_entity)
|
|
||||||
.unwrap()
|
|
||||||
.get_component_mut::<Health>()
|
|
||||||
{
|
|
||||||
health.current = i32::min(health.max, health.current + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*turn_state = TurnState::PlayerTurn;
|
*turn_state = TurnState::PlayerTurn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn use_item(n: usize, ecs: &mut SubWorld, commands: &mut CommandBuffer) -> Point {
|
||||||
|
let player_entity = <(Entity, &Point)>::query()
|
||||||
|
.iter(ecs)
|
||||||
|
.find_map(|(entity, _player)| Some(*entity))
|
||||||
|
.unwrap();
|
||||||
|
let item_entity = <(Entity, &Item, &Carried)>::query()
|
||||||
|
.iter(ecs)
|
||||||
|
.filter(|(_, _, carried)| carried.0 == player_entity)
|
||||||
|
.enumerate()
|
||||||
|
.filter(|(item_count, (_, _, _))| *item_count == n)
|
||||||
|
.find_map(|(_, (item_entity, _, _))| Some(*item_entity));
|
||||||
|
if let Some(item_entity) = item_entity {
|
||||||
|
commands.push((
|
||||||
|
(),
|
||||||
|
ActivateItem {
|
||||||
|
used_by: player_entity,
|
||||||
|
item: item_entity,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Point::zero()
|
||||||
|
}
|
||||||
|
32
src/systems/use_items.rs
Normal file
32
src/systems/use_items.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
#[system]
|
||||||
|
#[read_component(ActivateItem)]
|
||||||
|
#[read_component(ProvidesHealing)]
|
||||||
|
#[write_component(Health)]
|
||||||
|
#[read_component(ProvidesDungeonMap)]
|
||||||
|
pub fn use_items(ecs: &mut SubWorld, commands: &mut CommandBuffer, #[resource] map: &mut Map) {
|
||||||
|
let mut healing_to_apply = Vec::<(Entity, i32)>::new();
|
||||||
|
<(Entity, &ActivateItem)>::query()
|
||||||
|
.iter(ecs)
|
||||||
|
.for_each(|(entity, activate)| {
|
||||||
|
let item = ecs.entry_ref(activate.item);
|
||||||
|
if let Ok(item) = item {
|
||||||
|
if let Ok(healing) = item.get_component::<ProvidesHealing>() {
|
||||||
|
healing_to_apply.push((activate.used_by, healing.amount));
|
||||||
|
}
|
||||||
|
if let Ok(_mapper) = item.get_component::<ProvidesDungeonMap>() {
|
||||||
|
map.revealed_tiles.iter_mut().for_each(|t| *t = true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
commands.remove(activate.item);
|
||||||
|
commands.remove(*entity);
|
||||||
|
});
|
||||||
|
for heal in healing_to_apply.iter() {
|
||||||
|
if let Ok(mut target) = ecs.entry_mut(heal.0) {
|
||||||
|
if let Ok(health) = target.get_component_mut::<Health>() {
|
||||||
|
health.current = i32::min(health.max, health.current + heal.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user