refactors hunger system
still works the same way, just cleaner
This commit is contained in:
parent
23a6d5e025
commit
454a8c7028
4 changed files with 120 additions and 53 deletions
|
|
@ -130,6 +130,7 @@ pub enum HungerState {
|
|||
Hungry,
|
||||
Weak,
|
||||
Fainting,
|
||||
Starving,
|
||||
}
|
||||
|
||||
#[derive(Component, Serialize, Deserialize, Clone)]
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use super::{
|
||||
ai::CARRY_CAPACITY_PER_STRENGTH, camera, gamelog, gamesystem, rex_assets::RexAssets, ArmourClassBonus, Attributes,
|
||||
Burden, Charges, Equipped, Hidden, HungerClock, HungerState, InBackpack, MagicItem, MagicItemClass, Map,
|
||||
MasterDungeonMap, Name, ObfuscatedName, Player, Point, Pools, Position, Prop, Renderable, RunState, Skill, Skills,
|
||||
State, Viewshed,
|
||||
ai::CARRY_CAPACITY_PER_STRENGTH, camera, gamelog, gamesystem, hunger_system::get_hunger_colour,
|
||||
hunger_system::get_hunger_state, rex_assets::RexAssets, ArmourClassBonus, Attributes, Burden, Charges, Equipped,
|
||||
Hidden, HungerClock, HungerState, InBackpack, MagicItem, MagicItemClass, Map, MasterDungeonMap, Name,
|
||||
ObfuscatedName, Player, Point, Pools, Position, Prop, Renderable, RunState, Skill, Skills, State, Viewshed,
|
||||
};
|
||||
use rltk::prelude::*;
|
||||
use specs::prelude::*;
|
||||
|
|
@ -113,17 +113,20 @@ pub fn draw_ui(ecs: &World, ctx: &mut Rltk) {
|
|||
// Draw hunger
|
||||
match hunger.state {
|
||||
HungerState::Satiated => {
|
||||
ctx.print_color_right(70, 53, RGB::named(rltk::GREEN), RGB::named(rltk::BLACK), "Satiated")
|
||||
ctx.print_color_right(70, 53, get_hunger_colour(hunger.state), RGB::named(rltk::BLACK), "Satiated")
|
||||
}
|
||||
HungerState::Normal => {}
|
||||
HungerState::Hungry => {
|
||||
ctx.print_color_right(70, 53, RGB::named(rltk::BROWN1), RGB::named(rltk::BLACK), "Hungry")
|
||||
ctx.print_color_right(70, 53, get_hunger_colour(hunger.state), RGB::named(rltk::BLACK), "Hungry")
|
||||
}
|
||||
HungerState::Weak => {
|
||||
ctx.print_color_right(70, 53, RGB::named(rltk::ORANGE), RGB::named(rltk::BLACK), "Weak")
|
||||
ctx.print_color_right(70, 53, get_hunger_colour(hunger.state), RGB::named(rltk::BLACK), "Weak")
|
||||
}
|
||||
HungerState::Fainting => {
|
||||
ctx.print_color_right(70, 53, RGB::named(rltk::RED), RGB::named(rltk::BLACK), "Fainting")
|
||||
ctx.print_color_right(70, 53, get_hunger_colour(hunger.state), RGB::named(rltk::BLACK), "Fainting")
|
||||
}
|
||||
HungerState::Starving => {
|
||||
ctx.print_color_right(70, 53, get_hunger_colour(hunger.state), RGB::named(rltk::BLACK), "Starving")
|
||||
}
|
||||
}
|
||||
// Burden
|
||||
|
|
|
|||
|
|
@ -1,62 +1,125 @@
|
|||
use super::{
|
||||
effects::{add_effect, EffectType, Targets},
|
||||
gamelog, HungerClock, HungerState, LOG_TICKS,
|
||||
gamelog, Clock, HungerClock, HungerState, TakingTurn, LOG_TICKS,
|
||||
};
|
||||
use rltk::prelude::*;
|
||||
use specs::prelude::*;
|
||||
|
||||
/// HungerSystem is in charge of ticking down the hunger clock for entities with a hunger clock,
|
||||
/// every time the turn clock ticks.
|
||||
pub struct HungerSystem {}
|
||||
|
||||
const MAX_SATIATION: i32 = 2000;
|
||||
const HUNGER_BREAKPOINTS: [(i32, HungerState); 5] = [
|
||||
(1000, HungerState::Satiated),
|
||||
(600, HungerState::Normal),
|
||||
(400, HungerState::Hungry),
|
||||
(200, HungerState::Weak),
|
||||
(0, HungerState::Fainting),
|
||||
];
|
||||
const BASE_CLOCK_DECREMENT_PER_TURN: i32 = 4;
|
||||
|
||||
pub fn get_hunger_state(duration: i32) -> HungerState {
|
||||
for (threshold, state) in HUNGER_BREAKPOINTS.iter() {
|
||||
if duration > *threshold {
|
||||
return *state;
|
||||
}
|
||||
}
|
||||
return HungerState::Starving;
|
||||
}
|
||||
|
||||
pub fn get_hunger_colour(state: HungerState) -> (u8, u8, u8) {
|
||||
match state {
|
||||
HungerState::Satiated => GREEN,
|
||||
HungerState::Normal => WHITE,
|
||||
HungerState::Hungry => BROWN1,
|
||||
HungerState::Weak => ORANGE,
|
||||
HungerState::Fainting => RED3,
|
||||
HungerState::Starving => RED,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> System<'a> for HungerSystem {
|
||||
#[allow(clippy::type_complexity)]
|
||||
type SystemData = (Entities<'a>, WriteStorage<'a, HungerClock>, ReadExpect<'a, Entity>);
|
||||
type SystemData = (
|
||||
Entities<'a>,
|
||||
WriteStorage<'a, HungerClock>,
|
||||
ReadExpect<'a, Entity>,
|
||||
ReadStorage<'a, Clock>,
|
||||
ReadStorage<'a, TakingTurn>,
|
||||
);
|
||||
|
||||
fn run(&mut self, data: Self::SystemData) {
|
||||
let (entities, mut hunger_clock, player_entity) = data;
|
||||
let (entities, mut hunger_clock, player_entity, turn_clock, turns) = data;
|
||||
|
||||
for (entity, mut clock) in (&entities, &mut hunger_clock).join() {
|
||||
if LOG_TICKS && entity == *player_entity {
|
||||
rltk::console::log(format!("HUNGER SYSTEM: Ticked for player entity. [clock: {}]", clock.duration));
|
||||
// If the turn clock isn't taking a turn this tick, don't bother ticking hunger.
|
||||
let mut ticked = false;
|
||||
for (_e, _c, _t) in (&entities, &turn_clock, &turns).join() {
|
||||
ticked = true;
|
||||
break;
|
||||
}
|
||||
clock.duration -= 1;
|
||||
if clock.duration > 0 {
|
||||
if !ticked {
|
||||
return;
|
||||
}
|
||||
|
||||
match clock.state {
|
||||
HungerState::Satiated => {
|
||||
clock.state = HungerState::Normal;
|
||||
clock.duration = 1200;
|
||||
if entity == *player_entity {
|
||||
gamelog::Logger::new().append("You are no longer satiated.").log();
|
||||
// Otherwise, tick down the hunger clock for all entities with one.
|
||||
for (entity, mut hunger_clock) in (&entities, &mut hunger_clock).join() {
|
||||
if hunger_clock.duration >= MAX_SATIATION {
|
||||
hunger_clock.duration = MAX_SATIATION;
|
||||
} else {
|
||||
hunger_clock.duration -= BASE_CLOCK_DECREMENT_PER_TURN;
|
||||
}
|
||||
}
|
||||
HungerState::Normal => {
|
||||
clock.state = HungerState::Hungry;
|
||||
clock.duration = 400;
|
||||
if entity == *player_entity {
|
||||
gamelog::Logger::new().colour(rltk::BROWN1).append("You feel hungry.").log();
|
||||
}
|
||||
}
|
||||
HungerState::Hungry => {
|
||||
clock.state = HungerState::Weak;
|
||||
clock.duration = 200;
|
||||
if entity == *player_entity {
|
||||
gamelog::Logger::new().colour(rltk::ORANGE).append("You feel weak with hunger.").log();
|
||||
}
|
||||
}
|
||||
HungerState::Weak => {
|
||||
clock.state = HungerState::Fainting;
|
||||
clock.duration = 200;
|
||||
if entity == *player_entity {
|
||||
gamelog::Logger::new().colour(rltk::RED).append("You feel hungry enough to faint.").log();
|
||||
}
|
||||
}
|
||||
HungerState::Fainting => {
|
||||
let initial_state = hunger_clock.state;
|
||||
hunger_clock.state = get_hunger_state(hunger_clock.duration);
|
||||
if hunger_clock.state == HungerState::Starving {
|
||||
add_effect(None, EffectType::Damage { amount: 1 }, Targets::Entity { target: entity });
|
||||
if entity == *player_entity {
|
||||
gamelog::Logger::new().colour(rltk::RED).append("You can't go on without food...").log();
|
||||
}
|
||||
}
|
||||
}
|
||||
if LOG_TICKS && entity == *player_entity {
|
||||
rltk::console::log(format!(
|
||||
"HUNGER SYSTEM: Ticked for player entity. [clock: {}]",
|
||||
hunger_clock.duration
|
||||
));
|
||||
}
|
||||
if hunger_clock.state == initial_state {
|
||||
continue;
|
||||
}
|
||||
if entity != *player_entity {
|
||||
continue;
|
||||
}
|
||||
// Things which only happen to the player.
|
||||
match hunger_clock.state {
|
||||
HungerState::Satiated => gamelog::Logger::new()
|
||||
.append("You feel")
|
||||
.colour(get_hunger_colour(hunger_clock.state))
|
||||
.append("satiated")
|
||||
.colour(WHITE)
|
||||
.period()
|
||||
.log(),
|
||||
HungerState::Normal => {}
|
||||
HungerState::Hungry => gamelog::Logger::new()
|
||||
.append("You feel")
|
||||
.colour(get_hunger_colour(hunger_clock.state))
|
||||
.append("hungry")
|
||||
.colour(WHITE)
|
||||
.period()
|
||||
.log(),
|
||||
HungerState::Weak => gamelog::Logger::new()
|
||||
.append("You feel")
|
||||
.colour(get_hunger_colour(hunger_clock.state))
|
||||
.append("weak with hunger")
|
||||
.colour(WHITE)
|
||||
.period()
|
||||
.log(),
|
||||
HungerState::Fainting => gamelog::Logger::new()
|
||||
.append("You feel")
|
||||
.colour(get_hunger_colour(hunger_clock.state))
|
||||
.append("hungry enough to faint")
|
||||
.colour(WHITE)
|
||||
.period()
|
||||
.log(),
|
||||
_ => gamelog::Logger::new()
|
||||
.colour(get_hunger_colour(hunger_clock.state))
|
||||
.append("You can't go on without food!")
|
||||
.log(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
|
|||
.with(Faction { name: "player".to_string() })
|
||||
.with(Viewshed { visible_tiles: Vec::new(), range: 12, dirty: true })
|
||||
.with(Name { name: "you".to_string(), plural: "you".to_string() })
|
||||
.with(HungerClock { state: HungerState::Satiated, duration: 200 })
|
||||
.with(HungerClock { state: HungerState::Satiated, duration: 1200 })
|
||||
.with(Attributes {
|
||||
strength: Attribute { base: str, modifiers: 0, bonus: attr_bonus(str) },
|
||||
dexterity: Attribute { base: dex, modifiers: 0, bonus: attr_bonus(dex) },
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue