Add ability to handle item attribute bonuses

This commit is contained in:
Timothy Warren 2022-01-24 09:56:42 -05:00
parent 66e58733f7
commit 9e06be46f3
6 changed files with 75 additions and 14 deletions

View File

@ -2,8 +2,11 @@ use std::collections::HashMap;
use ::specs::prelude::*; use ::specs::prelude::*;
use crate::components::{Attributes, EquipmentChanged, Equipped, InBackpack, Item, Pools}; use crate::components::{
AttributeBonus, Attributes, EquipmentChanged, Equipped, InBackpack, Item, Pools,
};
use crate::game_log::GameLog; use crate::game_log::GameLog;
use crate::gamesystem::attr_bonus;
pub struct EncumbranceSystem {} pub struct EncumbranceSystem {}
@ -16,9 +19,10 @@ impl<'a> System<'a> for EncumbranceSystem {
ReadStorage<'a, InBackpack>, ReadStorage<'a, InBackpack>,
ReadStorage<'a, Equipped>, ReadStorage<'a, Equipped>,
WriteStorage<'a, Pools>, WriteStorage<'a, Pools>,
ReadStorage<'a, Attributes>, WriteStorage<'a, Attributes>,
ReadExpect<'a, Entity>, ReadExpect<'a, Entity>,
WriteExpect<'a, GameLog>, WriteExpect<'a, GameLog>,
ReadStorage<'a, AttributeBonus>,
); );
fn run(&mut self, data: Self::SystemData) { fn run(&mut self, data: Self::SystemData) {
@ -29,30 +33,47 @@ impl<'a> System<'a> for EncumbranceSystem {
backpacks, backpacks,
wielded, wielded,
mut pools, mut pools,
attributes, mut attributes,
player, player,
mut gamelog, mut gamelog,
attrbonus,
) = data; ) = data;
if equip_dirty.is_empty() { if equip_dirty.is_empty() {
return; return;
} }
#[derive(Default)]
struct ItemUpdate {
weight: f32,
initiative: f32,
might: i32,
fitness: i32,
quickness: i32,
intelligence: i32,
}
// Build the map of who needs updating // Build the map of who needs updating
let mut to_update: HashMap<Entity, (f32, f32)> = HashMap::new(); // (weight, initiative) let mut to_update: HashMap<Entity, ItemUpdate> = HashMap::new();
for (entity, _dirty) in (&entities, &equip_dirty).join() { for (entity, _dirty) in (&entities, &equip_dirty).join() {
to_update.insert(entity, (0., 0.)); to_update.insert(entity, ItemUpdate::default());
} }
// Remove all dirty statements // Remove all dirty statements
equip_dirty.clear(); equip_dirty.clear();
// Total up equipped items // Total up equipped items
for (item, equipped) in (&items, &wielded).join() { for (item, equipped, entity) in (&items, &wielded, &entities).join() {
if to_update.contains_key(&equipped.owner) { if to_update.contains_key(&equipped.owner) {
let totals = to_update.get_mut(&equipped.owner).unwrap(); let totals = to_update.get_mut(&equipped.owner).unwrap();
totals.0 += item.weight_lbs; totals.weight += item.weight_lbs;
totals.1 += item.initiative_penalty; totals.initiative += item.initiative_penalty;
if let Some(attr) = attrbonus.get(entity) {
totals.might += attr.might.unwrap_or(0);
totals.fitness += attr.fitness.unwrap_or(0);
totals.quickness += attr.quickness.unwrap_or(0);
totals.intelligence += attr.intelligence.unwrap_or(0);
}
} }
} }
@ -60,18 +81,29 @@ impl<'a> System<'a> for EncumbranceSystem {
for (item, carried) in (&items, &backpacks).join() { for (item, carried) in (&items, &backpacks).join() {
if to_update.contains_key(&carried.owner) { if to_update.contains_key(&carried.owner) {
let totals = to_update.get_mut(&carried.owner).unwrap(); let totals = to_update.get_mut(&carried.owner).unwrap();
totals.0 += item.weight_lbs; totals.weight += item.weight_lbs;
totals.1 += item.initiative_penalty; totals.initiative += item.initiative_penalty;
} }
} }
// Apply the data to Pools // Apply the data to Pools
for (entity, (weight, initiative)) in to_update.iter() { for (entity, item) in to_update.iter() {
if let Some(pool) = pools.get_mut(*entity) { if let Some(pool) = pools.get_mut(*entity) {
pool.total_weight = *weight; pool.total_weight = item.weight;
pool.total_initiative_penalty = *initiative; pool.total_initiative_penalty = item.initiative;
if let Some(attr) = attributes.get_mut(*entity) {
attr.might.modifiers = item.might;
attr.fitness.modifiers = item.fitness;
attr.quickness.modifiers = item.quickness;
attr.intelligence.modifiers = item.intelligence;
attr.might.bonus = attr_bonus(attr.might.base + attr.might.modifiers);
attr.fitness.bonus = attr_bonus(attr.fitness.base + attr.fitness.modifiers);
attr.quickness.bonus =
attr_bonus(attr.quickness.base + attr.quickness.modifiers);
attr.intelligence.bonus =
attr_bonus(attr.intelligence.base + attr.intelligence.modifiers);
if let Some(attr) = attributes.get(*entity) {
let carry_capacity_lbs = (attr.might.base + attr.might.modifiers) * 15; let carry_capacity_lbs = (attr.might.base + attr.might.modifiers) * 15;
if pool.total_weight as i32 > carry_capacity_lbs { if pool.total_weight as i32 > carry_capacity_lbs {
// Overburdened // Overburdened

View File

@ -382,3 +382,11 @@ pub struct SpawnParticleBurst {
pub color: RGB, pub color: RGB,
pub lifetime_ms: f32, pub lifetime_ms: f32,
} }
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
pub struct AttributeBonus {
pub might: Option<i32>,
pub fitness: Option<i32>,
pub quickness: Option<i32>,
pub intelligence: Option<i32>,
}

View File

@ -84,6 +84,7 @@ fn init_state() -> State {
ApplyMove, ApplyMove,
ApplyTeleport, ApplyTeleport,
AreaOfEffect, AreaOfEffect,
AttributeBonus,
Attributes, Attributes,
BlocksTile, BlocksTile,
BlocksVisibility, BlocksVisibility,

View File

@ -14,6 +14,7 @@ pub struct Item {
pub base_value: Option<f32>, pub base_value: Option<f32>,
pub vendor_category: Option<String>, pub vendor_category: Option<String>,
pub magic: Option<MagicItem>, pub magic: Option<MagicItem>,
pub attributes: Option<ItemAttributeBonus>,
} }
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
@ -49,3 +50,11 @@ pub struct MagicItem {
pub naming: String, pub naming: String,
pub cursed: Option<bool>, pub cursed: Option<bool>,
} }
#[derive(Deserialize, Debug)]
pub struct ItemAttributeBonus {
pub might: Option<i32>,
pub fitness: Option<i32>,
pub quickness: Option<i32>,
pub intelligence: Option<i32>,
}

View File

@ -438,6 +438,15 @@ pub fn spawn_named_item(
} }
} }
if let Some(ab) = &item_template.attributes {
eb = eb.with(AttributeBonus {
might: ab.might,
fitness: ab.fitness,
quickness: ab.quickness,
intelligence: ab.intelligence,
})
}
return Some(eb.build()); return Some(eb.build());
} }

View File

@ -63,6 +63,7 @@ pub fn save_game(ecs: &mut World) {
ApplyMove, ApplyMove,
ApplyTeleport, ApplyTeleport,
AreaOfEffect, AreaOfEffect,
AttributeBonus,
Attributes, Attributes,
BlocksTile, BlocksTile,
BlocksVisibility, BlocksVisibility,
@ -183,6 +184,7 @@ pub fn load_game(ecs: &mut World) {
ApplyMove, ApplyMove,
ApplyTeleport, ApplyTeleport,
AreaOfEffect, AreaOfEffect,
AttributeBonus,
Attributes, Attributes,
BlocksTile, BlocksTile,
BlocksVisibility, BlocksVisibility,