Complete item attribute bonus system, finishing section 5.23
This commit is contained in:
parent
ee5db23f6b
commit
0353c658aa
@ -3,7 +3,7 @@ use std::collections::HashMap;
|
|||||||
use ::specs::prelude::*;
|
use ::specs::prelude::*;
|
||||||
|
|
||||||
use crate::components::{
|
use crate::components::{
|
||||||
AttributeBonus, Attributes, EquipmentChanged, Equipped, InBackpack, Item, Pools,
|
AttributeBonus, Attributes, EquipmentChanged, Equipped, InBackpack, Item, Pools, StatusEffect,
|
||||||
};
|
};
|
||||||
use crate::game_log::GameLog;
|
use crate::game_log::GameLog;
|
||||||
use crate::gamesystem::attr_bonus;
|
use crate::gamesystem::attr_bonus;
|
||||||
@ -23,6 +23,7 @@ impl<'a> System<'a> for EncumbranceSystem {
|
|||||||
ReadExpect<'a, Entity>,
|
ReadExpect<'a, Entity>,
|
||||||
WriteExpect<'a, GameLog>,
|
WriteExpect<'a, GameLog>,
|
||||||
ReadStorage<'a, AttributeBonus>,
|
ReadStorage<'a, AttributeBonus>,
|
||||||
|
ReadStorage<'a, StatusEffect>,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn run(&mut self, data: Self::SystemData) {
|
fn run(&mut self, data: Self::SystemData) {
|
||||||
@ -37,6 +38,7 @@ impl<'a> System<'a> for EncumbranceSystem {
|
|||||||
player,
|
player,
|
||||||
mut gamelog,
|
mut gamelog,
|
||||||
attrbonus,
|
attrbonus,
|
||||||
|
statuses,
|
||||||
) = data;
|
) = data;
|
||||||
|
|
||||||
if equip_dirty.is_empty() {
|
if equip_dirty.is_empty() {
|
||||||
@ -86,6 +88,17 @@ impl<'a> System<'a> for EncumbranceSystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Total up status effect modifiers
|
||||||
|
for (status, attr) in (&statuses, &attrbonus).join() {
|
||||||
|
if to_update.contains_key(&status.target) {
|
||||||
|
let totals = to_update.get_mut(&status.target).unwrap();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Apply the data to Pools
|
// Apply the data to Pools
|
||||||
for (entity, item) 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) {
|
||||||
|
@ -12,7 +12,7 @@ use ::rltk::{FontCharType, RGB};
|
|||||||
use ::specs::prelude::*;
|
use ::specs::prelude::*;
|
||||||
pub use targeting::*;
|
pub use targeting::*;
|
||||||
|
|
||||||
use crate::spatial;
|
use crate::{spatial, AttributeBonus};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// The shared queue of effects
|
/// The shared queue of effects
|
||||||
@ -51,6 +51,11 @@ pub enum EffectType {
|
|||||||
depth: i32,
|
depth: i32,
|
||||||
player_only: bool,
|
player_only: bool,
|
||||||
},
|
},
|
||||||
|
AttributeEffect {
|
||||||
|
bonus: AttributeBonus,
|
||||||
|
name: String,
|
||||||
|
duration: i32,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Who, or what the effect should affect.
|
/// Who, or what the effect should affect.
|
||||||
@ -117,6 +122,7 @@ fn tile_effect_hits_entities(effect: &EffectType) -> bool {
|
|||||||
| EffectType::Healing { .. }
|
| EffectType::Healing { .. }
|
||||||
| EffectType::Confusion { .. }
|
| EffectType::Confusion { .. }
|
||||||
| EffectType::TeleportTo { .. }
|
| EffectType::TeleportTo { .. }
|
||||||
|
| EffectType::AttributeEffect { .. }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,6 +158,7 @@ fn affect_entity(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
|
|||||||
EffectType::Healing { .. } => damage::heal_damage(ecs, effect, target),
|
EffectType::Healing { .. } => damage::heal_damage(ecs, effect, target),
|
||||||
EffectType::Confusion { .. } => damage::add_confusion(ecs, effect, target),
|
EffectType::Confusion { .. } => damage::add_confusion(ecs, effect, target),
|
||||||
EffectType::TeleportTo { .. } => movement::apply_teleport(ecs, effect, target),
|
EffectType::TeleportTo { .. } => movement::apply_teleport(ecs, effect, target),
|
||||||
|
EffectType::AttributeEffect { .. } => damage::attribute_effect(ecs, effect, target),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ use ::specs::saveload::{MarkedBuilder, SimpleMarker};
|
|||||||
use super::{add_effect, entity_position, EffectSpawner, EffectType, Targets};
|
use super::{add_effect, entity_position, EffectSpawner, EffectType, Targets};
|
||||||
use crate::components::{Attributes, Confusion, Duration, Name, Player, Pools, SerializeMe};
|
use crate::components::{Attributes, Confusion, Duration, Name, Player, Pools, SerializeMe};
|
||||||
use crate::gamesystem::{mana_at_level, player_hp_at_level};
|
use crate::gamesystem::{mana_at_level, player_hp_at_level};
|
||||||
use crate::{colors, GameLog, Map, StatusEffect};
|
use crate::{colors, EquipmentChanged, GameLog, Map, StatusEffect};
|
||||||
|
|
||||||
pub fn inflict_damage(ecs: &mut World, damage: &EffectSpawner, target: Entity) {
|
pub fn inflict_damage(ecs: &mut World, damage: &EffectSpawner, target: Entity) {
|
||||||
let mut pools = ecs.write_storage::<Pools>();
|
let mut pools = ecs.write_storage::<Pools>();
|
||||||
@ -140,3 +140,24 @@ pub fn add_confusion(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn attribute_effect(ecs: &mut World, effect: &EffectSpawner, target: Entity) {
|
||||||
|
if let EffectType::AttributeEffect {
|
||||||
|
bonus,
|
||||||
|
name,
|
||||||
|
duration,
|
||||||
|
} = &effect.effect_type
|
||||||
|
{
|
||||||
|
ecs.create_entity()
|
||||||
|
.with(StatusEffect { target })
|
||||||
|
.with(bonus.clone())
|
||||||
|
.with(Duration { turns: *duration })
|
||||||
|
.with(Name::from(name.clone()))
|
||||||
|
.marked::<SimpleMarker<SerializeMe>>()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
ecs.write_storage::<EquipmentChanged>()
|
||||||
|
.insert(target, EquipmentChanged {})
|
||||||
|
.expect("Failed to insert EquipmentChanged tag");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,9 +2,9 @@ use ::specs::prelude::*;
|
|||||||
|
|
||||||
use super::{add_effect, EffectType, Targets};
|
use super::{add_effect, EffectType, Targets};
|
||||||
use crate::components::{
|
use crate::components::{
|
||||||
Confusion, Consumable, Duration, Hidden, InflictsDamage, MagicMapper, Name, ProvidesFood,
|
AttributeBonus, Confusion, Consumable, Duration, Hidden, InflictsDamage, MagicMapper, Name,
|
||||||
ProvidesHealing, ProvidesRemoveCurse, SingleActivation, SpawnParticleBurst, SpawnParticleLine,
|
ProvidesFood, ProvidesHealing, ProvidesRemoveCurse, SingleActivation, SpawnParticleBurst,
|
||||||
TeleportTo, TownPortal,
|
SpawnParticleLine, TeleportTo, TownPortal,
|
||||||
};
|
};
|
||||||
use crate::effects::{entity_position, targeting};
|
use crate::effects::{entity_position, targeting};
|
||||||
use crate::{colors, GameLog, Map, RunState};
|
use crate::{colors, GameLog, Map, RunState};
|
||||||
@ -209,6 +209,21 @@ fn event_trigger(
|
|||||||
did_something = true;
|
did_something = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attribute Modifiers
|
||||||
|
if let Some(attr) = ecs.read_storage::<AttributeBonus>().get(entity) {
|
||||||
|
add_effect(
|
||||||
|
creator,
|
||||||
|
EffectType::AttributeEffect {
|
||||||
|
bonus: attr.clone(),
|
||||||
|
duration: 10,
|
||||||
|
name: ecs.read_storage::<Name>().get(entity).unwrap().name.clone(),
|
||||||
|
},
|
||||||
|
targets.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
did_something = true;
|
||||||
|
}
|
||||||
|
|
||||||
did_something
|
did_something
|
||||||
}
|
}
|
||||||
|
|
||||||
|
15
src/gui.rs
15
src/gui.rs
@ -248,10 +248,19 @@ pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
|
|||||||
let hunger = ecs.read_storage::<HungerClock>();
|
let hunger = ecs.read_storage::<HungerClock>();
|
||||||
let hc = hunger.get(*player_entity).unwrap();
|
let hc = hunger.get(*player_entity).unwrap();
|
||||||
match hc.state {
|
match hc.state {
|
||||||
HungerState::WellFed => ctx.print_color(50, 44, colors::GREEN, colors::BLACK, "Well Fed"),
|
HungerState::WellFed => {
|
||||||
|
ctx.print_color(50, y, colors::GREEN, colors::BLACK, "Well Fed");
|
||||||
|
y -= 1;
|
||||||
|
}
|
||||||
HungerState::Normal => {}
|
HungerState::Normal => {}
|
||||||
HungerState::Hungry => ctx.print_color(50, 44, colors::ORANGE, colors::BLACK, "Hungry"),
|
HungerState::Hungry => {
|
||||||
HungerState::Starving => ctx.print_color(50, 44, colors::RED, colors::BLACK, "Starving"),
|
ctx.print_color(50, y, colors::ORANGE, colors::BLACK, "Hungry");
|
||||||
|
y -= 1;
|
||||||
|
}
|
||||||
|
HungerState::Starving => {
|
||||||
|
ctx.print_color(50, y, colors::RED, colors::BLACK, "Starving");
|
||||||
|
y -= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let statuses = ecs.read_storage::<StatusEffect>();
|
let statuses = ecs.read_storage::<StatusEffect>();
|
||||||
let durations = ecs.read_storage::<Duration>();
|
let durations = ecs.read_storage::<Duration>();
|
||||||
|
@ -96,6 +96,20 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
|
|||||||
SpawnType::Equipped { by: player },
|
SpawnType::Equipped { by: player },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Starting hangover
|
||||||
|
ecs.create_entity()
|
||||||
|
.with(StatusEffect { target: player })
|
||||||
|
.with(Duration { turns: 10 })
|
||||||
|
.with(Name::from("Hangover"))
|
||||||
|
.with(AttributeBonus {
|
||||||
|
might: Some(-1),
|
||||||
|
fitness: None,
|
||||||
|
quickness: Some(-1),
|
||||||
|
intelligence: Some(-1),
|
||||||
|
})
|
||||||
|
.marked::<SimpleMarker<SerializeMe>>()
|
||||||
|
.build();
|
||||||
|
|
||||||
player
|
player
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user