Add system to use items

This commit is contained in:
Daniel Lynn 2021-07-10 20:11:11 -05:00
parent 580f51efdc
commit feb02b5fba
4 changed files with 81 additions and 11 deletions

View File

@ -81,3 +81,9 @@ 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,
}

View File

@ -9,6 +9,7 @@ mod movement;
mod player_input;
mod random_move;
mod tooltips;
mod use_items;
use crate::prelude::*;
@ -26,6 +27,7 @@ pub fn build_input_scheduler() -> Schedule {
pub fn build_player_scheduler() -> Schedule {
Schedule::builder()
.add_system(use_items::use_items_system())
.add_system(combat::combat_system())
.flush()
.add_system(movement::movement_system())
@ -45,6 +47,7 @@ pub fn build_monster_scheduler() -> Schedule {
.add_system(chasing::chasing_system())
.add_system(random_move::random_move_system())
.flush()
.add_system(use_items::use_items_system())
.add_system(combat::combat_system())
.flush()
.add_system(movement::movement_system())

View File

@ -4,7 +4,6 @@ use crate::prelude::*;
#[read_component(Point)]
#[read_component(Player)]
#[read_component(Enemy)]
#[write_component(Health)]
#[read_component(Item)]
#[read_component(Carried)]
pub fn player_input(
@ -37,6 +36,15 @@ pub fn player_input(
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),
};
@ -77,16 +85,32 @@ 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;
}
}
fn use_item(n: usize, ecs: &mut SubWorld, commands: &mut CommandBuffer) -> Point {
let player_entity = <(Entity, &Player)>::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()
}

37
src/systems/use_items.rs Normal file
View File

@ -0,0 +1,37 @@
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);
}
}
}
}