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 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::gamesystem::attr_bonus;
pub struct EncumbranceSystem {}
@ -16,9 +19,10 @@ impl<'a> System<'a> for EncumbranceSystem {
ReadStorage<'a, InBackpack>,
ReadStorage<'a, Equipped>,
WriteStorage<'a, Pools>,
ReadStorage<'a, Attributes>,
WriteStorage<'a, Attributes>,
ReadExpect<'a, Entity>,
WriteExpect<'a, GameLog>,
ReadStorage<'a, AttributeBonus>,
);
fn run(&mut self, data: Self::SystemData) {
@ -29,30 +33,47 @@ impl<'a> System<'a> for EncumbranceSystem {
backpacks,
wielded,
mut pools,
attributes,
mut attributes,
player,
mut gamelog,
attrbonus,
) = data;
if equip_dirty.is_empty() {
return;
}
#[derive(Default)]
struct ItemUpdate {
weight: f32,
initiative: f32,
might: i32,
fitness: i32,
quickness: i32,
intelligence: i32,
}
// 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() {
to_update.insert(entity, (0., 0.));
to_update.insert(entity, ItemUpdate::default());
}
// Remove all dirty statements
equip_dirty.clear();
// 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) {
let totals = to_update.get_mut(&equipped.owner).unwrap();
totals.0 += item.weight_lbs;
totals.1 += item.initiative_penalty;
totals.weight += item.weight_lbs;
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() {
if to_update.contains_key(&carried.owner) {
let totals = to_update.get_mut(&carried.owner).unwrap();
totals.0 += item.weight_lbs;
totals.1 += item.initiative_penalty;
totals.weight += item.weight_lbs;
totals.initiative += item.initiative_penalty;
}
}
// 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) {
pool.total_weight = *weight;
pool.total_initiative_penalty = *initiative;
pool.total_weight = item.weight;
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;
if pool.total_weight as i32 > carry_capacity_lbs {
// Overburdened

View File

@ -382,3 +382,11 @@ pub struct SpawnParticleBurst {
pub color: RGB,
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,
ApplyTeleport,
AreaOfEffect,
AttributeBonus,
Attributes,
BlocksTile,
BlocksVisibility,

View File

@ -14,6 +14,7 @@ pub struct Item {
pub base_value: Option<f32>,
pub vendor_category: Option<String>,
pub magic: Option<MagicItem>,
pub attributes: Option<ItemAttributeBonus>,
}
#[derive(Deserialize, Debug)]
@ -49,3 +50,11 @@ pub struct MagicItem {
pub naming: String,
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());
}

View File

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