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 ::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");
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user