Use random table spawning for item drops

This commit is contained in:
Timothy Warren 2022-01-05 10:01:05 -05:00
parent 0c09f52eb6
commit da99923a1e
2 changed files with 54 additions and 3 deletions

View File

@ -1,7 +1,11 @@
use ::rltk::RandomNumberGenerator;
use ::specs::prelude::*; use ::specs::prelude::*;
use crate::components::{Equipped, InBackpack, Name, Player, Pools, Position, SufferDamage}; use crate::components::{
Equipped, InBackpack, LootTable, Name, Player, Pools, Position, SufferDamage,
};
use crate::game_log::GameLog; use crate::game_log::GameLog;
use crate::raws::{get_item_drop, spawn_named_item, SpawnType, RAWS};
use crate::{Map, RunState}; use crate::{Map, RunState};
pub struct DamageSystem {} pub struct DamageSystem {}
@ -62,6 +66,7 @@ pub fn delete_the_dead(ecs: &mut World) {
} }
// Drop everything held by dead people // Drop everything held by dead people
let mut to_spawn: Vec<(String, Position)> = Vec::new();
{ {
// To avoid hold of borrowed entires, use a scope // To avoid hold of borrowed entires, use a scope
let mut to_drop: Vec<(Entity, Position)> = Vec::new(); let mut to_drop: Vec<(Entity, Position)> = Vec::new();
@ -69,12 +74,15 @@ pub fn delete_the_dead(ecs: &mut World) {
let mut equipped = ecs.write_storage::<Equipped>(); let mut equipped = ecs.write_storage::<Equipped>();
let mut carried = ecs.write_storage::<InBackpack>(); let mut carried = ecs.write_storage::<InBackpack>();
let mut positions = ecs.write_storage::<Position>(); let mut positions = ecs.write_storage::<Position>();
let loot_tables = ecs.read_storage::<LootTable>();
let mut rng = ecs.write_resource::<RandomNumberGenerator>();
for victim in dead.iter() { for victim in dead.iter() {
let pos = positions.get(*victim);
for (entity, equipped) in (&entities, &equipped).join() { for (entity, equipped) in (&entities, &equipped).join() {
if equipped.owner == *victim { if equipped.owner == *victim {
// Drop their stuff // Drop their stuff
if let Some(pos) = positions.get(*victim) { if let Some(pos) = pos {
to_drop.push((entity, *pos)); to_drop.push((entity, *pos));
} }
} }
@ -82,11 +90,21 @@ pub fn delete_the_dead(ecs: &mut World) {
for (entity, backpack) in (&entities, &carried).join() { for (entity, backpack) in (&entities, &carried).join() {
if backpack.owner == *victim { if backpack.owner == *victim {
// Drop their stuff // Drop their stuff
if let Some(pos) = positions.get(*victim) { if let Some(pos) = pos {
to_drop.push((entity, *pos)); to_drop.push((entity, *pos));
} }
} }
} }
if let Some(table) = loot_tables.get(*victim) {
let drop_finder =
get_item_drop(&crate::raws::RAWS.lock().unwrap(), &mut rng, &table.table);
if let Some(tag) = drop_finder {
if let Some(pos) = pos {
to_spawn.push((tag, *pos));
}
}
}
} }
for drop in to_drop.iter() { for drop in to_drop.iter() {
@ -98,6 +116,20 @@ pub fn delete_the_dead(ecs: &mut World) {
} }
} }
{
for drop in to_spawn.iter() {
spawn_named_item(
&RAWS.lock().unwrap(),
ecs,
&drop.0,
SpawnType::AtPosition {
x: drop.1.x,
y: drop.1.y,
},
);
}
}
for victim in dead { for victim in dead {
ecs.delete_entity(victim) ecs.delete_entity(victim)
.expect("Unable to delete the dead"); .expect("Unable to delete the dead");

View File

@ -3,6 +3,7 @@ use std::collections::{HashMap, HashSet};
use ::regex::Regex; use ::regex::Regex;
use ::specs::prelude::*; use ::specs::prelude::*;
use ::specs::saveload::{MarkedBuilder, SimpleMarker}; use ::specs::saveload::{MarkedBuilder, SimpleMarker};
use rltk::RandomNumberGenerator;
use crate::components::*; use crate::components::*;
use crate::gamesystem::{mana_at_level, npc_hp}; use crate::gamesystem::{mana_at_level, npc_hp};
@ -530,3 +531,21 @@ pub fn get_spawn_table_for_depth(raws: &RawMaster, depth: i32) -> RandomTable {
rt rt
} }
pub fn get_item_drop(
raws: &RawMaster,
rng: &mut RandomNumberGenerator,
table: &str,
) -> Option<String> {
if raws.loot_index.contains_key(table) {
let mut rt = RandomTable::new();
let available_options = &raws.raws.loot_tables[raws.loot_index[table]];
for item in available_options.drops.iter() {
rt = rt.add(item.name.clone(), item.weight);
}
return Some(rt.roll(rng));
}
None
}