From 875e6bfee73bb872533b118529f057bd1071d2e6 Mon Sep 17 00:00:00 2001 From: Llywelwyn Date: Sun, 30 Jul 2023 08:57:31 +0100 Subject: [PATCH] mobs have a chance to drop held items on death --- src/damage_system.rs | 50 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/damage_system.rs b/src/damage_system.rs index 4988f55..ac303ba 100644 --- a/src/damage_system.rs +++ b/src/damage_system.rs @@ -1,7 +1,9 @@ use super::{ - gamelog, Attributes, GrantsXP, Item, Map, Name, ParticleBuilder, Player, Pools, Position, RunState, SufferDamage, + gamelog, Attributes, Equipped, GrantsXP, InBackpack, Item, Map, Name, ParticleBuilder, Player, Pools, Position, + RunState, SufferDamage, }; use crate::gamesystem::{mana_per_level, player_hp_per_level}; +use rltk::prelude::*; use specs::prelude::*; pub struct DamageSystem {} @@ -153,9 +155,55 @@ pub fn delete_the_dead(ecs: &mut World) { } } } + let items_to_delete = drop_some_held_items_and_return_the_rest(ecs, &dead); + for item in items_to_delete { + ecs.delete_entity(item).expect("Unable to delete item."); + } // For everything that died, increment the event log, and delete. for victim in dead { gamelog::record_event("death_count", 1); ecs.delete_entity(victim).expect("Unable to delete."); } } + +fn drop_some_held_items_and_return_the_rest(ecs: &mut World, dead: &Vec) -> Vec { + let mut to_drop: Vec<(Entity, Position)> = Vec::new(); + let entities = ecs.entities(); + let mut equipped = ecs.write_storage::(); + let mut carried = ecs.write_storage::(); + let mut positions = ecs.write_storage::(); + let mut rng = ecs.write_resource::(); + // Make list of every item in every dead thing's inv/equip + for victim in dead.iter() { + for (entity, equipped) in (&entities, &equipped).join() { + if equipped.owner == *victim { + // Push equipped item entities and positions + let pos = positions.get(*victim); + if let Some(pos) = pos { + to_drop.push((entity, pos.clone())); + } + } + } + for (entity, backpack) in (&entities, &carried).join() { + if backpack.owner == *victim { + // Push backpack item entities and positions + let pos = positions.get(*victim); + if let Some(pos) = pos { + to_drop.push((entity, pos.clone())); + } + } + } + } + const DROP_ONE_IN_THIS_MANY_TIMES: i32 = 6; + let mut to_return: Vec = Vec::new(); + for drop in to_drop.iter() { + if rng.roll_dice(1, DROP_ONE_IN_THIS_MANY_TIMES) == 1 { + equipped.remove(drop.0); + carried.remove(drop.0); + positions.insert(drop.0, drop.1.clone()).expect("Unable to insert Position{}."); + } else { + to_return.push(drop.0); + } + } + return to_return; +}