2021-11-03 15:59:23 -04:00
|
|
|
use crate::{
|
2021-11-05 10:42:44 -04:00
|
|
|
game_log::GameLog, CombatStats, Consumable, InBackpack, InflictsDamage, Map, Name, Position,
|
|
|
|
ProvidesHealing, SufferDamage, WantsToDropItem, WantsToPickupItem, WantsToUseItem,
|
2021-11-03 15:59:23 -04:00
|
|
|
};
|
2021-11-03 15:11:19 -04:00
|
|
|
use specs::prelude::*;
|
|
|
|
|
|
|
|
pub struct ItemCollectionSystem {}
|
|
|
|
|
|
|
|
impl<'a> System<'a> for ItemCollectionSystem {
|
|
|
|
#[allow(clippy::type_complexity)]
|
|
|
|
type SystemData = (
|
|
|
|
ReadExpect<'a, Entity>,
|
|
|
|
WriteExpect<'a, GameLog>,
|
|
|
|
WriteStorage<'a, WantsToPickupItem>,
|
|
|
|
WriteStorage<'a, Position>,
|
|
|
|
ReadStorage<'a, Name>,
|
|
|
|
WriteStorage<'a, InBackpack>,
|
|
|
|
);
|
|
|
|
|
|
|
|
fn run(&mut self, data: Self::SystemData) {
|
|
|
|
let (player_entity, mut gamelog, mut wants_pickup, mut positions, names, mut backpack) =
|
|
|
|
data;
|
|
|
|
|
|
|
|
for pickup in wants_pickup.join() {
|
|
|
|
positions.remove(pickup.item);
|
|
|
|
backpack
|
|
|
|
.insert(
|
|
|
|
pickup.item,
|
|
|
|
InBackpack {
|
|
|
|
owner: pickup.collected_by,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
.expect("Failed to add item to backpack");
|
|
|
|
|
|
|
|
if pickup.collected_by == *player_entity {
|
|
|
|
gamelog.entries.push(format!(
|
|
|
|
"You pick up the {}.",
|
|
|
|
names.get(pickup.item).unwrap().name
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
wants_pickup.clear();
|
|
|
|
}
|
|
|
|
}
|
2021-11-03 15:59:23 -04:00
|
|
|
|
2021-11-04 15:06:04 -04:00
|
|
|
pub struct ItemUseSystem {}
|
2021-11-03 15:59:23 -04:00
|
|
|
|
2021-11-04 15:06:04 -04:00
|
|
|
impl<'a> System<'a> for ItemUseSystem {
|
2021-11-03 15:59:23 -04:00
|
|
|
#[allow(clippy::type_complexity)]
|
|
|
|
type SystemData = (
|
|
|
|
ReadExpect<'a, Entity>,
|
|
|
|
WriteExpect<'a, GameLog>,
|
2021-11-04 15:06:04 -04:00
|
|
|
ReadExpect<'a, Map>,
|
2021-11-03 15:59:23 -04:00
|
|
|
Entities<'a>,
|
2021-11-04 15:06:04 -04:00
|
|
|
WriteStorage<'a, WantsToUseItem>,
|
2021-11-03 15:59:23 -04:00
|
|
|
ReadStorage<'a, Name>,
|
2021-11-04 15:06:04 -04:00
|
|
|
ReadStorage<'a, Consumable>,
|
|
|
|
ReadStorage<'a, ProvidesHealing>,
|
2021-11-05 10:42:44 -04:00
|
|
|
ReadStorage<'a, InflictsDamage>,
|
2021-11-03 15:59:23 -04:00
|
|
|
WriteStorage<'a, CombatStats>,
|
2021-11-05 10:42:44 -04:00
|
|
|
WriteStorage<'a, SufferDamage>,
|
2021-11-03 15:59:23 -04:00
|
|
|
);
|
|
|
|
|
|
|
|
fn run(&mut self, data: Self::SystemData) {
|
|
|
|
let (
|
|
|
|
player_entity,
|
|
|
|
mut gamelog,
|
2021-11-04 15:06:04 -04:00
|
|
|
map,
|
2021-11-03 15:59:23 -04:00
|
|
|
entities,
|
2021-11-04 15:06:04 -04:00
|
|
|
mut wants_use,
|
2021-11-03 15:59:23 -04:00
|
|
|
names,
|
2021-11-04 15:06:04 -04:00
|
|
|
consumables,
|
|
|
|
healing,
|
2021-11-05 10:42:44 -04:00
|
|
|
inflict_damage,
|
2021-11-03 15:59:23 -04:00
|
|
|
mut combat_stats,
|
2021-11-05 10:42:44 -04:00
|
|
|
mut suffer_damage,
|
2021-11-03 15:59:23 -04:00
|
|
|
) = data;
|
|
|
|
|
2021-11-04 15:06:04 -04:00
|
|
|
for (entity, useitem, stats) in (&entities, &wants_use, &mut combat_stats).join() {
|
2021-11-05 10:42:44 -04:00
|
|
|
let mut used_item = true;
|
|
|
|
|
|
|
|
// If the item heals, apply the healing
|
2021-11-04 15:06:04 -04:00
|
|
|
match healing.get(useitem.item) {
|
2021-11-03 15:59:23 -04:00
|
|
|
None => {}
|
2021-11-04 15:06:04 -04:00
|
|
|
Some(healer) => {
|
2021-11-05 10:42:44 -04:00
|
|
|
used_item = false;
|
|
|
|
|
2021-11-04 15:06:04 -04:00
|
|
|
stats.hp = i32::min(stats.max_hp, stats.hp + healer.heal_amount);
|
2021-11-03 15:59:23 -04:00
|
|
|
if entity == *player_entity {
|
|
|
|
gamelog.entries.push(format!(
|
|
|
|
"You drink the {}, healing {} hp.",
|
2021-11-04 15:06:04 -04:00
|
|
|
names.get(useitem.item).unwrap().name,
|
|
|
|
healer.heal_amount
|
2021-11-03 15:59:23 -04:00
|
|
|
));
|
|
|
|
}
|
2021-11-05 10:42:44 -04:00
|
|
|
|
|
|
|
used_item = true;
|
2021-11-04 15:06:04 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-05 10:42:44 -04:00
|
|
|
// If it inflicts damage, apply it to the target cell
|
|
|
|
match inflict_damage.get(useitem.item) {
|
2021-11-04 15:06:04 -04:00
|
|
|
None => {}
|
2021-11-05 10:42:44 -04:00
|
|
|
Some(damage) => {
|
|
|
|
let target_point = useitem.target.unwrap();
|
|
|
|
let idx = map.xy_idx(target_point.x, target_point.y);
|
|
|
|
used_item = false;
|
|
|
|
|
|
|
|
for mob in map.tile_content[idx].iter() {
|
|
|
|
SufferDamage::new_damage(&mut suffer_damage, *mob, damage.damage);
|
|
|
|
if entity == *player_entity {
|
|
|
|
let mob_name = names.get(*mob).unwrap();
|
|
|
|
let item_name = names.get(useitem.item).unwrap();
|
|
|
|
|
|
|
|
gamelog.entries.push(format!(
|
|
|
|
"You use {} on {}, inflicting {} hp.",
|
|
|
|
item_name.name, mob_name.name, damage.damage
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
used_item = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If it's a consumable, delete it on use
|
|
|
|
if used_item {
|
|
|
|
let consumable = consumables.get(useitem.item);
|
|
|
|
match consumable {
|
|
|
|
None => {}
|
|
|
|
Some(_) => {
|
|
|
|
entities
|
|
|
|
.delete(useitem.item)
|
|
|
|
.expect("Failed to consume item");
|
|
|
|
}
|
2021-11-03 15:59:23 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-04 15:06:04 -04:00
|
|
|
wants_use.clear();
|
2021-11-03 15:59:23 -04:00
|
|
|
}
|
|
|
|
}
|
2021-11-04 09:40:58 -04:00
|
|
|
|
|
|
|
pub struct ItemDropSystem {}
|
|
|
|
|
|
|
|
impl<'a> System<'a> for ItemDropSystem {
|
|
|
|
type SystemData = (
|
|
|
|
ReadExpect<'a, Entity>,
|
|
|
|
WriteExpect<'a, GameLog>,
|
|
|
|
Entities<'a>,
|
|
|
|
WriteStorage<'a, WantsToDropItem>,
|
|
|
|
ReadStorage<'a, Name>,
|
|
|
|
WriteStorage<'a, Position>,
|
|
|
|
WriteStorage<'a, InBackpack>,
|
|
|
|
);
|
|
|
|
|
|
|
|
fn run(&mut self, data: Self::SystemData) {
|
|
|
|
let (
|
|
|
|
player_entity,
|
|
|
|
mut gamelog,
|
|
|
|
entities,
|
|
|
|
mut wants_drop,
|
|
|
|
names,
|
|
|
|
mut positions,
|
|
|
|
mut backpack,
|
|
|
|
) = data;
|
|
|
|
|
|
|
|
for (entity, to_drop) in (&entities, &wants_drop).join() {
|
|
|
|
let mut dropper_pos: Position = Position { x: 0, y: 0 };
|
|
|
|
{
|
|
|
|
let dropped_pos = positions.get(entity).unwrap();
|
|
|
|
dropper_pos.x = dropped_pos.x;
|
|
|
|
dropper_pos.y = dropped_pos.y;
|
|
|
|
}
|
|
|
|
|
|
|
|
positions
|
|
|
|
.insert(
|
|
|
|
to_drop.item,
|
|
|
|
Position {
|
|
|
|
x: dropper_pos.x,
|
|
|
|
y: dropper_pos.y,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
.expect("Unable to drop item to position");
|
|
|
|
|
|
|
|
backpack.remove(to_drop.item);
|
|
|
|
|
|
|
|
if entity == *player_entity {
|
|
|
|
gamelog.entries.push(format!(
|
|
|
|
"You drop the {}.",
|
|
|
|
names.get(to_drop.item).unwrap().name
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
wants_drop.clear();
|
|
|
|
}
|
|
|
|
}
|