mobs have a chance to drop held items on death
This commit is contained in:
parent
3e9f4f6fab
commit
875e6bfee7
1 changed files with 49 additions and 1 deletions
|
|
@ -1,7 +1,9 @@
|
||||||
use super::{
|
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 crate::gamesystem::{mana_per_level, player_hp_per_level};
|
||||||
|
use rltk::prelude::*;
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
|
|
||||||
pub struct DamageSystem {}
|
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 everything that died, increment the event log, and delete.
|
||||||
for victim in dead {
|
for victim in dead {
|
||||||
gamelog::record_event("death_count", 1);
|
gamelog::record_event("death_count", 1);
|
||||||
ecs.delete_entity(victim).expect("Unable to delete.");
|
ecs.delete_entity(victim).expect("Unable to delete.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn drop_some_held_items_and_return_the_rest(ecs: &mut World, dead: &Vec<Entity>) -> Vec<Entity> {
|
||||||
|
let mut to_drop: Vec<(Entity, Position)> = Vec::new();
|
||||||
|
let entities = ecs.entities();
|
||||||
|
let mut equipped = ecs.write_storage::<Equipped>();
|
||||||
|
let mut carried = ecs.write_storage::<InBackpack>();
|
||||||
|
let mut positions = ecs.write_storage::<Position>();
|
||||||
|
let mut rng = ecs.write_resource::<RandomNumberGenerator>();
|
||||||
|
// 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<Entity> = 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;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue