intrinsic speed + regeneration
This commit is contained in:
parent
e8b5f6d997
commit
921fee2ecc
7 changed files with 78 additions and 10 deletions
|
|
@ -10,6 +10,7 @@ use crate::{
|
||||||
Map,
|
Map,
|
||||||
TakingTurn,
|
TakingTurn,
|
||||||
Confusion,
|
Confusion,
|
||||||
|
Intrinsics,
|
||||||
};
|
};
|
||||||
use bracket_lib::prelude::*;
|
use bracket_lib::prelude::*;
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
|
|
@ -36,6 +37,7 @@ impl<'a> System<'a> for EnergySystem {
|
||||||
ReadStorage<'a, Name>,
|
ReadStorage<'a, Name>,
|
||||||
ReadExpect<'a, Point>,
|
ReadExpect<'a, Point>,
|
||||||
ReadStorage<'a, Confusion>,
|
ReadStorage<'a, Confusion>,
|
||||||
|
ReadStorage<'a, Intrinsics>,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn run(&mut self, data: Self::SystemData) {
|
fn run(&mut self, data: Self::SystemData) {
|
||||||
|
|
@ -53,6 +55,7 @@ impl<'a> System<'a> for EnergySystem {
|
||||||
names,
|
names,
|
||||||
player_pos,
|
player_pos,
|
||||||
confusion,
|
confusion,
|
||||||
|
intrinsics,
|
||||||
) = data;
|
) = data;
|
||||||
// If not ticking, do nothing.
|
// If not ticking, do nothing.
|
||||||
if *runstate != RunState::Ticking {
|
if *runstate != RunState::Ticking {
|
||||||
|
|
@ -89,10 +92,12 @@ impl<'a> System<'a> for EnergySystem {
|
||||||
).join() {
|
).join() {
|
||||||
let burden_modifier = get_burden_modifier(&burdens, entity);
|
let burden_modifier = get_burden_modifier(&burdens, entity);
|
||||||
let overmap_mod = get_overmap_modifier(&map);
|
let overmap_mod = get_overmap_modifier(&map);
|
||||||
|
let intrinsic_speed = get_intrinsic_speed(&intrinsics, entity);
|
||||||
// Every entity has a POTENTIAL equal to their speed.
|
// Every entity has a POTENTIAL equal to their speed.
|
||||||
let mut energy_potential: i32 = ((energy.speed as f32) *
|
let mut energy_potential: i32 = ((energy.speed as f32) *
|
||||||
burden_modifier *
|
burden_modifier *
|
||||||
overmap_mod) as i32;
|
overmap_mod *
|
||||||
|
intrinsic_speed) as i32;
|
||||||
// Increment current energy by NORMAL_SPEED for every
|
// Increment current energy by NORMAL_SPEED for every
|
||||||
// whole number of NORMAL_SPEEDS in their POTENTIAL.
|
// whole number of NORMAL_SPEEDS in their POTENTIAL.
|
||||||
while energy_potential >= NORMAL_SPEED {
|
while energy_potential >= NORMAL_SPEED {
|
||||||
|
|
@ -162,3 +167,12 @@ fn cull_turn_by_distance(player_pos: &Point, pos: &Position) -> bool {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_intrinsic_speed(intrinsics: &ReadStorage<Intrinsics>, entity: Entity) -> f32 {
|
||||||
|
if let Some(intrinsics) = intrinsics.get(entity) {
|
||||||
|
if intrinsics.list.contains(&crate::Intrinsic::Speed) {
|
||||||
|
return 4.0 / 3.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ use crate::{
|
||||||
Position,
|
Position,
|
||||||
RandomNumberGenerator,
|
RandomNumberGenerator,
|
||||||
TakingTurn,
|
TakingTurn,
|
||||||
|
Intrinsics,
|
||||||
};
|
};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
use crate::data::events::*;
|
use crate::data::events::*;
|
||||||
|
|
@ -36,10 +37,24 @@ impl<'a> System<'a> for RegenSystem {
|
||||||
ReadStorage<'a, HasClass>,
|
ReadStorage<'a, HasClass>,
|
||||||
ReadStorage<'a, Attributes>,
|
ReadStorage<'a, Attributes>,
|
||||||
WriteExpect<'a, RandomNumberGenerator>,
|
WriteExpect<'a, RandomNumberGenerator>,
|
||||||
|
ReadStorage<'a, Intrinsics>,
|
||||||
|
ReadExpect<'a, Entity>,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn run(&mut self, data: Self::SystemData) {
|
fn run(&mut self, data: Self::SystemData) {
|
||||||
let (clock, entities, positions, mut pools, turns, player, classes, attributes, mut rng) = data;
|
let (
|
||||||
|
clock,
|
||||||
|
entities,
|
||||||
|
positions,
|
||||||
|
mut pools,
|
||||||
|
turns,
|
||||||
|
player,
|
||||||
|
classes,
|
||||||
|
attributes,
|
||||||
|
mut rng,
|
||||||
|
intrinsics,
|
||||||
|
player_entity,
|
||||||
|
) = data;
|
||||||
let mut clock_turn = false;
|
let mut clock_turn = false;
|
||||||
for (_e, _c, _t) in (&entities, &clock, &turns).join() {
|
for (_e, _c, _t) in (&entities, &clock, &turns).join() {
|
||||||
clock_turn = true;
|
clock_turn = true;
|
||||||
|
|
@ -56,19 +71,29 @@ impl<'a> System<'a> for RegenSystem {
|
||||||
}
|
}
|
||||||
// Player HP regen
|
// Player HP regen
|
||||||
let level = gamelog::get_event_count(EVENT::COUNT_LEVEL);
|
let level = gamelog::get_event_count(EVENT::COUNT_LEVEL);
|
||||||
if current_turn % get_player_hp_regen_turn(level) == 0 {
|
if
|
||||||
|
current_turn % get_player_hp_regen_turn(level) == 0 ||
|
||||||
|
intrinsics.get(*player_entity).unwrap().list.contains(&crate::Intrinsic::Regeneration)
|
||||||
|
{
|
||||||
for (_e, _p, pool, _player) in (&entities, &positions, &mut pools, &player).join() {
|
for (_e, _p, pool, _player) in (&entities, &positions, &mut pools, &player).join() {
|
||||||
try_hp_regen_tick(pool, get_player_hp_regen_per_tick(level));
|
try_hp_regen_tick(pool, get_player_hp_regen_per_tick(level));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Both MP regen
|
// Both MP regen
|
||||||
for (e, _p, pool) in (&entities, &positions, &mut pools).join() {
|
for (e, _p, pool) in (&entities, &positions, &mut pools).join() {
|
||||||
let is_wizard = if let Some(class) = classes.get(e) { class.name == Class::Wizard } else { false };
|
let is_wizard = if let Some(class) = classes.get(e) {
|
||||||
|
class.name == Class::Wizard
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
let numerator = if is_wizard { WIZARD_MP_REGEN_MOD } else { NONWIZARD_MP_REGEN_MOD };
|
let numerator = if is_wizard { WIZARD_MP_REGEN_MOD } else { NONWIZARD_MP_REGEN_MOD };
|
||||||
let multiplier: f32 = (numerator as f32) / (MP_REGEN_DIVISOR as f32);
|
let multiplier: f32 = (numerator as f32) / (MP_REGEN_DIVISOR as f32);
|
||||||
let mp_regen_tick = (((MP_REGEN_BASE - pool.level) as f32) * multiplier) as i32;
|
let mp_regen_tick = (((MP_REGEN_BASE - pool.level) as f32) * multiplier) as i32;
|
||||||
if current_turn % mp_regen_tick == 0 {
|
if current_turn % mp_regen_tick == 0 {
|
||||||
try_mana_regen_tick(pool, rng.roll_dice(1, get_mana_regen_per_tick(e, &attributes)));
|
try_mana_regen_tick(
|
||||||
|
pool,
|
||||||
|
rng.roll_dice(1, get_mana_regen_per_tick(e, &attributes))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use specs::error::NoError;
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
use specs::saveload::{ ConvertSaveload, Marker };
|
use specs::saveload::{ ConvertSaveload, Marker };
|
||||||
use specs_derive::*;
|
use specs_derive::*;
|
||||||
use std::collections::HashMap;
|
use std::collections::{ HashMap, HashSet };
|
||||||
|
|
||||||
// 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.
|
||||||
|
|
@ -418,6 +418,17 @@ impl HasDamageModifiers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
|
pub enum Intrinsic {
|
||||||
|
Regeneration, // Regenerate 1 HP on every tick
|
||||||
|
Speed, // 4/3x speed multiplier
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct Intrinsics {
|
||||||
|
pub list: HashSet<Intrinsic>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
#[derive(Component, Debug, ConvertSaveload, Clone)]
|
||||||
pub struct InflictsDamage {
|
pub struct InflictsDamage {
|
||||||
pub damage_type: DamageType,
|
pub damage_type: DamageType,
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use super::{
|
||||||
HungerState,
|
HungerState,
|
||||||
TakingTurn,
|
TakingTurn,
|
||||||
DamageType,
|
DamageType,
|
||||||
|
Intrinsics,
|
||||||
};
|
};
|
||||||
use bracket_lib::prelude::*;
|
use bracket_lib::prelude::*;
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
|
|
@ -53,10 +54,11 @@ impl<'a> System<'a> for HungerSystem {
|
||||||
ReadExpect<'a, Entity>,
|
ReadExpect<'a, Entity>,
|
||||||
ReadStorage<'a, Clock>,
|
ReadStorage<'a, Clock>,
|
||||||
ReadStorage<'a, TakingTurn>,
|
ReadStorage<'a, TakingTurn>,
|
||||||
|
ReadStorage<'a, Intrinsics>,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn run(&mut self, data: Self::SystemData) {
|
fn run(&mut self, data: Self::SystemData) {
|
||||||
let (entities, mut hunger_clock, player_entity, turn_clock, turns) = data;
|
let (entities, mut hunger_clock, player_entity, turn_clock, turns, intrinsics) = data;
|
||||||
|
|
||||||
// If the turn clock isn't taking a turn this tick, don't bother ticking hunger.
|
// If the turn clock isn't taking a turn this tick, don't bother ticking hunger.
|
||||||
let mut ticked = false;
|
let mut ticked = false;
|
||||||
|
|
@ -72,7 +74,16 @@ impl<'a> System<'a> for HungerSystem {
|
||||||
if hunger_clock.duration >= MAX_SATIATION {
|
if hunger_clock.duration >= MAX_SATIATION {
|
||||||
hunger_clock.duration = MAX_SATIATION;
|
hunger_clock.duration = MAX_SATIATION;
|
||||||
} else {
|
} else {
|
||||||
hunger_clock.duration -= BASE_CLOCK_DECREMENT_PER_TURN;
|
let mut modifier = 0;
|
||||||
|
let intrinsic_regen = if let Some(i) = intrinsics.get(entity) {
|
||||||
|
i.list.contains(&crate::Intrinsic::Regeneration)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
if intrinsic_regen {
|
||||||
|
modifier += 1;
|
||||||
|
}
|
||||||
|
hunger_clock.duration -= BASE_CLOCK_DECREMENT_PER_TURN + modifier;
|
||||||
}
|
}
|
||||||
let initial_state = hunger_clock.state;
|
let initial_state = hunger_clock.state;
|
||||||
hunger_clock.state = get_hunger_state(hunger_clock.duration);
|
hunger_clock.state = get_hunger_state(hunger_clock.duration);
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,7 @@ fn main() -> BError {
|
||||||
gs.ecs.register::<SpawnParticleBurst>();
|
gs.ecs.register::<SpawnParticleBurst>();
|
||||||
gs.ecs.register::<SpawnParticleLine>();
|
gs.ecs.register::<SpawnParticleLine>();
|
||||||
gs.ecs.register::<HasDamageModifiers>();
|
gs.ecs.register::<HasDamageModifiers>();
|
||||||
|
gs.ecs.register::<Intrinsics>();
|
||||||
gs.ecs.register::<SimpleMarker<SerializeMe>>();
|
gs.ecs.register::<SimpleMarker<SerializeMe>>();
|
||||||
gs.ecs.register::<SerializationHelper>();
|
gs.ecs.register::<SerializationHelper>();
|
||||||
gs.ecs.register::<DMSerializationHelper>();
|
gs.ecs.register::<DMSerializationHelper>();
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ pub fn save_game(ecs: &mut World) {
|
||||||
IdentifiedItem,
|
IdentifiedItem,
|
||||||
InBackpack,
|
InBackpack,
|
||||||
InflictsDamage,
|
InflictsDamage,
|
||||||
|
Intrinsics,
|
||||||
Item,
|
Item,
|
||||||
KnownSpells,
|
KnownSpells,
|
||||||
LootTable,
|
LootTable,
|
||||||
|
|
@ -226,6 +227,7 @@ pub fn load_game(ecs: &mut World) {
|
||||||
IdentifiedItem,
|
IdentifiedItem,
|
||||||
InBackpack,
|
InBackpack,
|
||||||
InflictsDamage,
|
InflictsDamage,
|
||||||
|
Intrinsics,
|
||||||
Item,
|
Item,
|
||||||
KnownSpells,
|
KnownSpells,
|
||||||
LootTable,
|
LootTable,
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ use super::{
|
||||||
Viewshed,
|
Viewshed,
|
||||||
BlocksTile,
|
BlocksTile,
|
||||||
Bleeds,
|
Bleeds,
|
||||||
|
HasDamageModifiers,
|
||||||
|
Intrinsics,
|
||||||
};
|
};
|
||||||
use crate::data::entity;
|
use crate::data::entity;
|
||||||
use crate::data::visuals::BLOODSTAIN_COLOUR;
|
use crate::data::visuals::BLOODSTAIN_COLOUR;
|
||||||
|
|
@ -32,7 +34,7 @@ use crate::gamesystem::*;
|
||||||
use bracket_lib::prelude::*;
|
use bracket_lib::prelude::*;
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
use specs::saveload::{ MarkedBuilder, SimpleMarker };
|
use specs::saveload::{ MarkedBuilder, SimpleMarker };
|
||||||
use std::collections::HashMap;
|
use std::collections::{ HashMap, HashSet };
|
||||||
|
|
||||||
/// Spawns the player and returns his/her entity object.
|
/// Spawns the player and returns his/her entity object.
|
||||||
pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
|
pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
|
||||||
|
|
@ -86,7 +88,9 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
|
||||||
weight: 0.0,
|
weight: 0.0,
|
||||||
god: false,
|
god: false,
|
||||||
})
|
})
|
||||||
.with(EquipmentChanged {})
|
.with(HasDamageModifiers { modifiers: HashMap::new() })
|
||||||
|
.with(Intrinsics { list: HashSet::new() })
|
||||||
|
.with(EquipmentChanged {}) // To force re-calc of equipment bonuses.
|
||||||
.with(skills)
|
.with(skills)
|
||||||
.with(Energy { current: 0, speed: entity::NORMAL_SPEED })
|
.with(Energy { current: 0, speed: entity::NORMAL_SPEED })
|
||||||
.marked::<SimpleMarker<SerializeMe>>()
|
.marked::<SimpleMarker<SerializeMe>>()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue