Use random table spawning for item drops
This commit is contained in:
parent
0c09f52eb6
commit
da99923a1e
@ -1,7 +1,11 @@
|
||||
use ::rltk::RandomNumberGenerator;
|
||||
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::raws::{get_item_drop, spawn_named_item, SpawnType, RAWS};
|
||||
use crate::{Map, RunState};
|
||||
|
||||
pub struct DamageSystem {}
|
||||
@ -62,6 +66,7 @@ pub fn delete_the_dead(ecs: &mut World) {
|
||||
}
|
||||
|
||||
// Drop everything held by dead people
|
||||
let mut to_spawn: Vec<(String, Position)> = Vec::new();
|
||||
{
|
||||
// To avoid hold of borrowed entires, use a scope
|
||||
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 carried = ecs.write_storage::<InBackpack>();
|
||||
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() {
|
||||
let pos = positions.get(*victim);
|
||||
for (entity, equipped) in (&entities, &equipped).join() {
|
||||
if equipped.owner == *victim {
|
||||
// Drop their stuff
|
||||
if let Some(pos) = positions.get(*victim) {
|
||||
if let Some(pos) = 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() {
|
||||
if backpack.owner == *victim {
|
||||
// Drop their stuff
|
||||
if let Some(pos) = positions.get(*victim) {
|
||||
if let Some(pos) = 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() {
|
||||
@ -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 {
|
||||
ecs.delete_entity(victim)
|
||||
.expect("Unable to delete the dead");
|
||||
|
@ -3,6 +3,7 @@ use std::collections::{HashMap, HashSet};
|
||||
use ::regex::Regex;
|
||||
use ::specs::prelude::*;
|
||||
use ::specs::saveload::{MarkedBuilder, SimpleMarker};
|
||||
use rltk::RandomNumberGenerator;
|
||||
|
||||
use crate::components::*;
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user