Add buying and selling
This commit is contained in:
parent
6d4f87b184
commit
93a1c30b4a
@ -348,6 +348,11 @@ pub struct Chasing {
|
|||||||
pub target: Entity,
|
pub target: Entity,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct Vendor {
|
||||||
|
pub categories: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
// Serialization helper code. We need to implement ConvertSaveLoad for each type that contains an
|
// Serialization helper code. We need to implement ConvertSaveLoad for each type that contains an
|
||||||
// Entity.
|
// Entity.
|
||||||
|
|
||||||
|
214
src/gui.rs
214
src/gui.rs
@ -4,12 +4,12 @@ use ::rltk::{Point, Rltk, VirtualKeyCode, RGB};
|
|||||||
use ::specs::prelude::*;
|
use ::specs::prelude::*;
|
||||||
|
|
||||||
use crate::components::{
|
use crate::components::{
|
||||||
Attribute, Attributes, Consumable, HungerClock, HungerState, InBackpack, Name, Pools, Position,
|
Attribute, Attributes, Consumable, HungerClock, HungerState, InBackpack, Item, Name, Pools,
|
||||||
Viewshed,
|
Position, Vendor, Viewshed,
|
||||||
};
|
};
|
||||||
use crate::game_log::GameLog;
|
use crate::game_log::GameLog;
|
||||||
use crate::rex_assets::RexAssets;
|
use crate::rex_assets::RexAssets;
|
||||||
use crate::{camera, Equipped, Hidden, Map, RunState, State};
|
use crate::{camera, Equipped, Hidden, Map, RunState, State, VendorMode};
|
||||||
|
|
||||||
pub fn draw_hollow_box(
|
pub fn draw_hollow_box(
|
||||||
console: &mut Rltk,
|
console: &mut Rltk,
|
||||||
@ -987,3 +987,211 @@ pub fn show_cheat_mode(_gs: &mut State, ctx: &mut Rltk) -> CheatMenuResult {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Copy, Clone)]
|
||||||
|
pub enum VendorResult {
|
||||||
|
NoResponse,
|
||||||
|
Cancel,
|
||||||
|
Sell,
|
||||||
|
BuyMode,
|
||||||
|
SellMode,
|
||||||
|
Buy,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vendor_sell_menu(
|
||||||
|
gs: &mut State,
|
||||||
|
ctx: &mut Rltk,
|
||||||
|
_vendor: Entity,
|
||||||
|
_mode: VendorMode,
|
||||||
|
) -> (VendorResult, Option<Entity>, Option<String>, Option<f32>) {
|
||||||
|
let player_entity = gs.ecs.fetch::<Entity>();
|
||||||
|
let names = gs.ecs.read_storage::<Name>();
|
||||||
|
let backpack = gs.ecs.read_storage::<InBackpack>();
|
||||||
|
let items = gs.ecs.read_storage::<Item>();
|
||||||
|
let entities = gs.ecs.entities();
|
||||||
|
|
||||||
|
let inventory = (&backpack, &names)
|
||||||
|
.join()
|
||||||
|
.filter(|item| item.0.owner == *player_entity);
|
||||||
|
let count = inventory.count();
|
||||||
|
|
||||||
|
let mut y = (25 - (count / 2)) as i32;
|
||||||
|
ctx.draw_box(
|
||||||
|
15,
|
||||||
|
y - 2,
|
||||||
|
51,
|
||||||
|
(count + 3) as i32,
|
||||||
|
RGB::named(rltk::WHITE),
|
||||||
|
RGB::named(rltk::BLACK),
|
||||||
|
);
|
||||||
|
ctx.print_color(
|
||||||
|
18,
|
||||||
|
y - 2,
|
||||||
|
RGB::named(rltk::YELLOW),
|
||||||
|
RGB::named(rltk::BLACK),
|
||||||
|
"Sell Which Item? (space to switch to buy mode)",
|
||||||
|
);
|
||||||
|
ctx.print_color(
|
||||||
|
18,
|
||||||
|
y + count as i32 + 1,
|
||||||
|
RGB::named(rltk::YELLOW),
|
||||||
|
RGB::named(rltk::BLACK),
|
||||||
|
"ESCAPE to cancel",
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut equippable: Vec<Entity> = Vec::new();
|
||||||
|
for (j, (entity, _pack, name, item)) in (&entities, &backpack, &names, &items)
|
||||||
|
.join()
|
||||||
|
.filter(|item| item.1.owner == *player_entity)
|
||||||
|
.enumerate()
|
||||||
|
{
|
||||||
|
ctx.set(
|
||||||
|
17,
|
||||||
|
y,
|
||||||
|
RGB::named(rltk::WHITE),
|
||||||
|
RGB::named(rltk::BLACK),
|
||||||
|
rltk::to_cp437('('),
|
||||||
|
);
|
||||||
|
ctx.set(
|
||||||
|
18,
|
||||||
|
y,
|
||||||
|
RGB::named(rltk::YELLOW),
|
||||||
|
RGB::named(rltk::BLACK),
|
||||||
|
97 + j as rltk::FontCharType,
|
||||||
|
);
|
||||||
|
ctx.set(
|
||||||
|
19,
|
||||||
|
y,
|
||||||
|
RGB::named(rltk::WHITE),
|
||||||
|
RGB::named(rltk::BLACK),
|
||||||
|
rltk::to_cp437(')'),
|
||||||
|
);
|
||||||
|
|
||||||
|
ctx.print(21, y, &name.name.to_string());
|
||||||
|
ctx.print(50, y, &format!("{:.1} gp", item.base_value * 0.8));
|
||||||
|
equippable.push(entity);
|
||||||
|
y += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
match ctx.key {
|
||||||
|
None => (VendorResult::NoResponse, None, None, None),
|
||||||
|
Some(key) => match key {
|
||||||
|
VirtualKeyCode::Space => (VendorResult::BuyMode, None, None, None),
|
||||||
|
VirtualKeyCode::Escape => (VendorResult::Cancel, None, None, None),
|
||||||
|
_ => {
|
||||||
|
let selection = rltk::letter_to_option(key);
|
||||||
|
if selection > -1 && selection < count as i32 {
|
||||||
|
return (
|
||||||
|
VendorResult::Sell,
|
||||||
|
Some(equippable[selection as usize]),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
(VendorResult::NoResponse, None, None, None)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vendor_buy_menu(
|
||||||
|
gs: &mut State,
|
||||||
|
ctx: &mut Rltk,
|
||||||
|
vendor: Entity,
|
||||||
|
_mode: VendorMode,
|
||||||
|
) -> (VendorResult, Option<Entity>, Option<String>, Option<f32>) {
|
||||||
|
use crate::raws::*;
|
||||||
|
|
||||||
|
let vendors = gs.ecs.read_storage::<Vendor>();
|
||||||
|
|
||||||
|
let inventory = get_vendor_items(
|
||||||
|
&vendors.get(vendor).unwrap().categories,
|
||||||
|
&RAWS.lock().unwrap(),
|
||||||
|
);
|
||||||
|
let count = inventory.len();
|
||||||
|
|
||||||
|
let mut y = (25 - (count / 2)) as i32;
|
||||||
|
ctx.draw_box(
|
||||||
|
15,
|
||||||
|
y - 2,
|
||||||
|
51,
|
||||||
|
(count + 3) as i32,
|
||||||
|
RGB::named(rltk::WHITE),
|
||||||
|
RGB::named(rltk::BLACK),
|
||||||
|
);
|
||||||
|
ctx.print_color(
|
||||||
|
18,
|
||||||
|
y - 2,
|
||||||
|
RGB::named(rltk::YELLOW),
|
||||||
|
RGB::named(rltk::BLACK),
|
||||||
|
"Buy Which Item? (space to switch to sell mode)",
|
||||||
|
);
|
||||||
|
ctx.print_color(
|
||||||
|
18,
|
||||||
|
y + count as i32 + 1,
|
||||||
|
RGB::named(rltk::YELLOW),
|
||||||
|
RGB::named(rltk::BLACK),
|
||||||
|
"ESCAPE to cancel",
|
||||||
|
);
|
||||||
|
|
||||||
|
for (j, sale) in inventory.iter().enumerate() {
|
||||||
|
ctx.set(
|
||||||
|
17,
|
||||||
|
y,
|
||||||
|
RGB::named(rltk::WHITE),
|
||||||
|
RGB::named(rltk::BLACK),
|
||||||
|
rltk::to_cp437('('),
|
||||||
|
);
|
||||||
|
ctx.set(
|
||||||
|
18,
|
||||||
|
y,
|
||||||
|
RGB::named(rltk::YELLOW),
|
||||||
|
RGB::named(rltk::BLACK),
|
||||||
|
97 + j as rltk::FontCharType,
|
||||||
|
);
|
||||||
|
ctx.set(
|
||||||
|
19,
|
||||||
|
y,
|
||||||
|
RGB::named(rltk::WHITE),
|
||||||
|
RGB::named(rltk::BLACK),
|
||||||
|
rltk::to_cp437(')'),
|
||||||
|
);
|
||||||
|
|
||||||
|
ctx.print(21, y, &sale.0);
|
||||||
|
ctx.print(50, y, &format!("{:.1} gp", sale.1 * 1.2));
|
||||||
|
y += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
match ctx.key {
|
||||||
|
None => (VendorResult::NoResponse, None, None, None),
|
||||||
|
Some(key) => match key {
|
||||||
|
VirtualKeyCode::Space => (VendorResult::SellMode, None, None, None),
|
||||||
|
VirtualKeyCode::Escape => (VendorResult::Cancel, None, None, None),
|
||||||
|
_ => {
|
||||||
|
let selection = ::rltk::letter_to_option(key);
|
||||||
|
if selection > -1 && selection < count as i32 {
|
||||||
|
return (
|
||||||
|
VendorResult::Buy,
|
||||||
|
None,
|
||||||
|
Some(inventory[selection as usize].0.clone()),
|
||||||
|
Some(inventory[selection as usize].1),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
(VendorResult::NoResponse, None, None, None)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn show_vendor_menu(
|
||||||
|
gs: &mut State,
|
||||||
|
ctx: &mut Rltk,
|
||||||
|
vendor: Entity,
|
||||||
|
mode: VendorMode,
|
||||||
|
) -> (VendorResult, Option<Entity>, Option<String>, Option<f32>) {
|
||||||
|
match mode {
|
||||||
|
VendorMode::Buy => vendor_buy_menu(gs, ctx, vendor, mode),
|
||||||
|
VendorMode::Sell => vendor_sell_menu(gs, ctx, vendor, mode),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
66
src/main.rs
66
src/main.rs
@ -42,6 +42,7 @@ use map_indexing_system::MapIndexingSystem;
|
|||||||
use melee_combat_system::MeleeCombatSystem;
|
use melee_combat_system::MeleeCombatSystem;
|
||||||
use particle_system::ParticleSpawnSystem;
|
use particle_system::ParticleSpawnSystem;
|
||||||
use player::*;
|
use player::*;
|
||||||
|
use raws::*;
|
||||||
pub use rect::Rect;
|
pub use rect::Rect;
|
||||||
use trigger_system::TriggerSystem;
|
use trigger_system::TriggerSystem;
|
||||||
use visibility_system::VisibilitySystem;
|
use visibility_system::VisibilitySystem;
|
||||||
@ -59,6 +60,12 @@ macro_rules! register {
|
|||||||
|
|
||||||
const SHOW_MAPGEN_VISUALIZER: bool = false;
|
const SHOW_MAPGEN_VISUALIZER: bool = false;
|
||||||
|
|
||||||
|
#[derive(PartialEq, Copy, Clone)]
|
||||||
|
pub enum VendorMode {
|
||||||
|
Buy,
|
||||||
|
Sell,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Copy, Clone)]
|
#[derive(PartialEq, Copy, Clone)]
|
||||||
pub enum RunState {
|
pub enum RunState {
|
||||||
AwaitingInput,
|
AwaitingInput,
|
||||||
@ -83,6 +90,10 @@ pub enum RunState {
|
|||||||
},
|
},
|
||||||
MapGeneration,
|
MapGeneration,
|
||||||
ShowCheatMenu,
|
ShowCheatMenu,
|
||||||
|
ShowVendor {
|
||||||
|
vendor: Entity,
|
||||||
|
mode: VendorMode,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
@ -392,6 +403,60 @@ impl GameState for State {
|
|||||||
newrunstate = RunState::MapGeneration
|
newrunstate = RunState::MapGeneration
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
RunState::ShowVendor { vendor, mode } => {
|
||||||
|
let result = gui::show_vendor_menu(self, ctx, vendor, mode);
|
||||||
|
match result.0 {
|
||||||
|
gui::VendorResult::Cancel => newrunstate = RunState::AwaitingInput,
|
||||||
|
gui::VendorResult::NoResponse => {}
|
||||||
|
gui::VendorResult::Sell => {
|
||||||
|
let price = self
|
||||||
|
.ecs
|
||||||
|
.read_storage::<Item>()
|
||||||
|
.get(result.1.unwrap())
|
||||||
|
.unwrap()
|
||||||
|
.base_value
|
||||||
|
* 0.8;
|
||||||
|
self.ecs
|
||||||
|
.write_storage::<Pools>()
|
||||||
|
.get_mut(*self.ecs.fetch::<Entity>())
|
||||||
|
.unwrap()
|
||||||
|
.gold += price;
|
||||||
|
self.ecs
|
||||||
|
.delete_entity(result.1.unwrap())
|
||||||
|
.expect("Unable to delete sold item");
|
||||||
|
}
|
||||||
|
gui::VendorResult::Buy => {
|
||||||
|
let tag = result.2.unwrap();
|
||||||
|
let price = result.3.unwrap();
|
||||||
|
let mut pools = self.ecs.write_storage::<Pools>();
|
||||||
|
let player_pools = pools.get_mut(*self.ecs.fetch::<Entity>()).unwrap();
|
||||||
|
if player_pools.gold >= price {
|
||||||
|
player_pools.gold -= price;
|
||||||
|
std::mem::drop(pools);
|
||||||
|
|
||||||
|
let player_entity = *self.ecs.fetch::<Entity>();
|
||||||
|
spawn_named_item(
|
||||||
|
&RAWS.lock().unwrap(),
|
||||||
|
&mut self.ecs,
|
||||||
|
&tag,
|
||||||
|
SpawnType::Carried { by: player_entity },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gui::VendorResult::BuyMode => {
|
||||||
|
newrunstate = RunState::ShowVendor {
|
||||||
|
vendor,
|
||||||
|
mode: VendorMode::Buy,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gui::VendorResult::SellMode => {
|
||||||
|
newrunstate = RunState::ShowVendor {
|
||||||
|
vendor,
|
||||||
|
mode: VendorMode::Sell,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -509,6 +574,7 @@ fn main() -> ::rltk::BError {
|
|||||||
SingleActivation,
|
SingleActivation,
|
||||||
Skills,
|
Skills,
|
||||||
SufferDamage,
|
SufferDamage,
|
||||||
|
Vendor,
|
||||||
Viewshed,
|
Viewshed,
|
||||||
WantsToApproach,
|
WantsToApproach,
|
||||||
WantsToDropItem,
|
WantsToDropItem,
|
||||||
|
@ -5,11 +5,11 @@ use ::specs::prelude::*;
|
|||||||
|
|
||||||
use crate::components::{
|
use crate::components::{
|
||||||
Attributes, BlocksTile, BlocksVisibility, Door, EntityMoved, Faction, HungerClock, HungerState,
|
Attributes, BlocksTile, BlocksVisibility, Door, EntityMoved, Faction, HungerClock, HungerState,
|
||||||
Item, Player, Pools, Position, Renderable, Viewshed, WantsToMelee, WantsToPickupItem,
|
Item, Player, Pools, Position, Renderable, Vendor, Viewshed, WantsToMelee, WantsToPickupItem,
|
||||||
};
|
};
|
||||||
use crate::game_log::GameLog;
|
use crate::game_log::GameLog;
|
||||||
use crate::raws::{self, Reaction, RAWS};
|
use crate::raws::{self, Reaction, RAWS};
|
||||||
use crate::{spatial, Map, RunState, State, TileType};
|
use crate::{spatial, Map, RunState, State, TileType, VendorMode};
|
||||||
|
|
||||||
pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) -> RunState {
|
pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) -> RunState {
|
||||||
let mut positions = ecs.write_storage::<Position>();
|
let mut positions = ecs.write_storage::<Position>();
|
||||||
@ -25,6 +25,7 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) -> RunState
|
|||||||
let mut blocks_movement = ecs.write_storage::<BlocksTile>();
|
let mut blocks_movement = ecs.write_storage::<BlocksTile>();
|
||||||
let mut renderables = ecs.write_storage::<Renderable>();
|
let mut renderables = ecs.write_storage::<Renderable>();
|
||||||
let factions = ecs.read_storage::<Faction>();
|
let factions = ecs.read_storage::<Faction>();
|
||||||
|
let vendors = ecs.read_storage::<Vendor>();
|
||||||
let mut result = RunState::AwaitingInput;
|
let mut result = RunState::AwaitingInput;
|
||||||
|
|
||||||
let mut swap_entities: Vec<(Entity, i32, i32)> = Vec::new();
|
let mut swap_entities: Vec<(Entity, i32, i32)> = Vec::new();
|
||||||
@ -43,6 +44,13 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) -> RunState
|
|||||||
|
|
||||||
result =
|
result =
|
||||||
spatial::for_each_tile_content_with_gamemode(destination_idx, |potential_target| {
|
spatial::for_each_tile_content_with_gamemode(destination_idx, |potential_target| {
|
||||||
|
if vendors.get(potential_target).is_some() {
|
||||||
|
return Some(RunState::ShowVendor {
|
||||||
|
vendor: potential_target,
|
||||||
|
mode: VendorMode::Sell,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let mut hostile = true;
|
let mut hostile = true;
|
||||||
if combat_stats.get(potential_target).is_some() {
|
if combat_stats.get(potential_target).is_some() {
|
||||||
if let Some(faction) = factions.get(potential_target) {
|
if let Some(faction) = factions.get(potential_target) {
|
||||||
|
@ -12,6 +12,7 @@ pub struct Item {
|
|||||||
pub initiative_penalty: Option<f32>,
|
pub initiative_penalty: Option<f32>,
|
||||||
pub weight_lbs: Option<f32>,
|
pub weight_lbs: Option<f32>,
|
||||||
pub base_value: Option<f32>,
|
pub base_value: Option<f32>,
|
||||||
|
pub vendor_category: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
|
@ -23,6 +23,7 @@ pub struct Mob {
|
|||||||
pub light: Option<MobLight>,
|
pub light: Option<MobLight>,
|
||||||
pub faction: Option<String>,
|
pub faction: Option<String>,
|
||||||
pub gold: Option<String>,
|
pub gold: Option<String>,
|
||||||
|
pub vendor: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
|
@ -166,6 +166,20 @@ fn find_slot_for_equippable_item(tag: &str, raws: &RawMaster) -> EquipmentSlot {
|
|||||||
panic!("Trying to equip {}, but it has not slot tag", tag);
|
panic!("Trying to equip {}, but it has not slot tag", tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_vendor_items(categories: &[String], raws: &RawMaster) -> Vec<(String, f32)> {
|
||||||
|
let mut result = Vec::new();
|
||||||
|
|
||||||
|
for item in raws.raws.items.iter() {
|
||||||
|
if let Some(cat) = &item.vendor_category {
|
||||||
|
if categories.contains(cat) && item.base_value.is_some() {
|
||||||
|
result.push((item.name.clone(), item.base_value.unwrap()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
fn spawn_position<'a>(
|
fn spawn_position<'a>(
|
||||||
pos: SpawnType,
|
pos: SpawnType,
|
||||||
new_entity: EntityBuilder<'a>,
|
new_entity: EntityBuilder<'a>,
|
||||||
@ -406,7 +420,7 @@ pub fn spawn_named_mob(
|
|||||||
total_initiative_penalty: 0.,
|
total_initiative_penalty: 0.,
|
||||||
gold: if let Some(gold) = &mob_template.gold {
|
gold: if let Some(gold) = &mob_template.gold {
|
||||||
let mut rng = RandomNumberGenerator::new();
|
let mut rng = RandomNumberGenerator::new();
|
||||||
let (n, d, b) = parse_dice_string(&gold);
|
let (n, d, b) = parse_dice_string(gold);
|
||||||
(rng.roll_dice(n, d) + b) as f32
|
(rng.roll_dice(n, d) + b) as f32
|
||||||
} else {
|
} else {
|
||||||
0.0
|
0.0
|
||||||
@ -481,9 +495,15 @@ pub fn spawn_named_mob(
|
|||||||
eb = eb.with(Faction::from("Mindless"));
|
eb = eb.with(Faction::from("Mindless"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(vendor) = &mob_template.vendor {
|
||||||
|
eb = eb.with(Vendor {
|
||||||
|
categories: vendor.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
let new_mob = eb.build();
|
let new_mob = eb.build();
|
||||||
|
|
||||||
// Are they weilding anything?
|
// Are they wielding anything?
|
||||||
if let Some(wielding) = &mob_template.equipped {
|
if let Some(wielding) = &mob_template.equipped {
|
||||||
for tag in wielding.iter() {
|
for tag in wielding.iter() {
|
||||||
spawn_named_entity(raws, ecs, tag, SpawnType::Equipped { by: new_mob });
|
spawn_named_entity(raws, ecs, tag, SpawnType::Equipped { by: new_mob });
|
||||||
|
@ -104,6 +104,7 @@ pub fn save_game(ecs: &mut World) {
|
|||||||
SingleActivation,
|
SingleActivation,
|
||||||
Skills,
|
Skills,
|
||||||
SufferDamage,
|
SufferDamage,
|
||||||
|
Vendor,
|
||||||
Viewshed,
|
Viewshed,
|
||||||
WantsToApproach,
|
WantsToApproach,
|
||||||
WantsToDropItem,
|
WantsToDropItem,
|
||||||
@ -212,6 +213,7 @@ pub fn load_game(ecs: &mut World) {
|
|||||||
SingleActivation,
|
SingleActivation,
|
||||||
Skills,
|
Skills,
|
||||||
SufferDamage,
|
SufferDamage,
|
||||||
|
Vendor,
|
||||||
Viewshed,
|
Viewshed,
|
||||||
WantsToApproach,
|
WantsToApproach,
|
||||||
WantsToDropItem,
|
WantsToDropItem,
|
||||||
|
Loading…
Reference in New Issue
Block a user