mp regeneration
using nethack calcs as a placeholder for now
This commit is contained in:
parent
c46e302274
commit
4118783597
6 changed files with 64 additions and 11 deletions
|
|
@ -1,4 +1,6 @@
|
|||
use crate::{gamelog, Clock, Player, Pools, Position, TakingTurn};
|
||||
use crate::{
|
||||
gamelog, gui::Class, Attributes, Clock, HasClass, Player, Pools, Position, RandomNumberGenerator, TakingTurn,
|
||||
};
|
||||
use specs::prelude::*;
|
||||
|
||||
pub struct RegenSystem {}
|
||||
|
|
@ -6,6 +8,12 @@ pub struct RegenSystem {}
|
|||
const MONSTER_HP_REGEN_TURN: i32 = 20;
|
||||
const MONSTER_HP_REGEN_PER_TICK: i32 = 1;
|
||||
|
||||
const WIZARD_MP_REGEN_MOD: i32 = 3;
|
||||
const NONWIZARD_MP_REGEN_MOD: i32 = 4;
|
||||
const MP_REGEN_BASE: i32 = 38;
|
||||
const MP_REGEN_DIVISOR: i32 = 6;
|
||||
const MIN_MP_REGEN_PER_TURN: i32 = 1;
|
||||
|
||||
impl<'a> System<'a> for RegenSystem {
|
||||
#[allow(clippy::type_complexity)]
|
||||
type SystemData = (
|
||||
|
|
@ -15,10 +23,13 @@ impl<'a> System<'a> for RegenSystem {
|
|||
WriteStorage<'a, Pools>,
|
||||
ReadStorage<'a, TakingTurn>,
|
||||
ReadStorage<'a, Player>,
|
||||
ReadStorage<'a, HasClass>,
|
||||
ReadStorage<'a, Attributes>,
|
||||
WriteExpect<'a, RandomNumberGenerator>,
|
||||
);
|
||||
|
||||
fn run(&mut self, data: Self::SystemData) {
|
||||
let (clock, entities, positions, mut pools, turns, player) = data;
|
||||
let (clock, entities, positions, mut pools, turns, player, classes, attributes, mut rng) = data;
|
||||
let mut clock_turn = false;
|
||||
for (_e, _c, _t) in (&entities, &clock, &turns).join() {
|
||||
clock_turn = true;
|
||||
|
|
@ -26,18 +37,30 @@ impl<'a> System<'a> for RegenSystem {
|
|||
if !clock_turn {
|
||||
return;
|
||||
}
|
||||
// Monster HP regen
|
||||
let current_turn = gamelog::get_event_count("turns");
|
||||
if current_turn % MONSTER_HP_REGEN_TURN == 0 {
|
||||
for (_e, _p, pool, _player) in (&entities, &positions, &mut pools, !&player).join() {
|
||||
try_hp_regen_tick(pool, MONSTER_HP_REGEN_PER_TICK);
|
||||
}
|
||||
}
|
||||
// Player HP regen
|
||||
let level = gamelog::get_event_count("player_level");
|
||||
if current_turn % get_player_hp_regen_turn(level) == 0 {
|
||||
for (_e, _p, pool, _player) in (&entities, &positions, &mut pools, &player).join() {
|
||||
try_hp_regen_tick(pool, get_player_hp_regen_per_tick(level));
|
||||
}
|
||||
}
|
||||
// Both MP regen
|
||||
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 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 mp_regen_tick = ((MP_REGEN_BASE - pool.level) as f32 * multiplier) as i32;
|
||||
if current_turn % mp_regen_tick == 0 {
|
||||
try_mana_regen_tick(pool, rng.roll_dice(1, get_mana_regen_per_tick(e, &attributes)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -60,3 +83,15 @@ fn get_player_hp_regen_per_tick(level: i32) -> i32 {
|
|||
fn try_hp_regen_tick(pool: &mut Pools, amount: i32) {
|
||||
pool.hit_points.current = i32::min(pool.hit_points.current + amount, pool.hit_points.max);
|
||||
}
|
||||
|
||||
fn get_mana_regen_per_tick(e: Entity, attributes: &ReadStorage<Attributes>) -> i32 {
|
||||
return if let Some(attributes) = attributes.get(e) {
|
||||
((attributes.intelligence.bonus + attributes.wisdom.bonus) / 2) + MIN_MP_REGEN_PER_TURN
|
||||
} else {
|
||||
MIN_MP_REGEN_PER_TURN
|
||||
};
|
||||
}
|
||||
|
||||
fn try_mana_regen_tick(pool: &mut Pools, amount: i32) {
|
||||
pool.mana.current = i32::min(pool.mana.current + amount, pool.mana.max);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -190,6 +190,17 @@ pub struct Skills {
|
|||
pub skills: HashMap<Skill, i32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct KnownSpell {
|
||||
pub display_name: String,
|
||||
pub mana_cost: i32,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct KnownSpells {
|
||||
pub spells: Vec<KnownSpell>,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Attributes {
|
||||
pub strength: Attribute,
|
||||
|
|
|
|||
|
|
@ -284,8 +284,8 @@ pub fn setup_player_class(ecs: &mut World, class: Class, ancestry: Ancestry) {
|
|||
.insert(
|
||||
player,
|
||||
Pools {
|
||||
hit_points: Pool { current: 10 + attr_bonus(con), max: 10 + attr_bonus(con) },
|
||||
mana: Pool { current: 2 + attr_bonus(int), max: 2 + attr_bonus(int) },
|
||||
hit_points: Pool { current: 8 + attr_bonus(con), max: 8 + attr_bonus(con) },
|
||||
mana: Pool { current: 1 + attr_bonus(int), max: 1 + attr_bonus(int) },
|
||||
xp: 0,
|
||||
level: 1,
|
||||
bac: 10,
|
||||
|
|
|
|||
|
|
@ -659,6 +659,7 @@ fn main() -> rltk::BError {
|
|||
gs.ecs.register::<MultiAttack>();
|
||||
gs.ecs.register::<ProvidesRemoveCurse>();
|
||||
gs.ecs.register::<ProvidesIdentify>();
|
||||
gs.ecs.register::<KnownSpells>();
|
||||
gs.ecs.register::<ParticleLifetime>();
|
||||
gs.ecs.register::<SpawnParticleSimple>();
|
||||
gs.ecs.register::<SpawnParticleBurst>();
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ pub fn save_game(ecs: &mut World) {
|
|||
InBackpack,
|
||||
InflictsDamage,
|
||||
Item,
|
||||
KnownSpells,
|
||||
LootTable,
|
||||
MagicItem,
|
||||
MagicMapper,
|
||||
|
|
@ -209,6 +210,7 @@ pub fn load_game(ecs: &mut World) {
|
|||
InBackpack,
|
||||
InflictsDamage,
|
||||
Item,
|
||||
KnownSpells,
|
||||
LootTable,
|
||||
MagicItem,
|
||||
MagicMapper,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
use super::{
|
||||
ai::NORMAL_SPEED, random_table::RandomTable, raws, Clock, Energy, EquipmentChanged, Faction, HungerClock,
|
||||
HungerState, Map, Mind, Name, Player, Position, Rect, Renderable, SerializeMe, Skill, Skills, TileType, Viewshed,
|
||||
ai::NORMAL_SPEED, random_table::RandomTable, raws, Attribute, Attributes, Clock, Energy, EquipmentChanged, Faction,
|
||||
HungerClock, HungerState, Map, Mind, Name, Player, Pool, Pools, Position, Rect, Renderable, SerializeMe, Skill,
|
||||
Skills, TileType, Viewshed,
|
||||
};
|
||||
use crate::gamesystem::*;
|
||||
use rltk::{RandomNumberGenerator, RGB};
|
||||
use specs::prelude::*;
|
||||
use specs::saveload::{MarkedBuilder, SimpleMarker};
|
||||
|
|
@ -13,7 +15,7 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
|
|||
skills.skills.insert(Skill::Melee, 0);
|
||||
skills.skills.insert(Skill::Defence, 0);
|
||||
skills.skills.insert(Skill::Magic, 0);
|
||||
|
||||
let (int, con) = (10, 10);
|
||||
// We only create the player once, so create the Clock here for counting turns too.
|
||||
ecs.create_entity().with(Clock {}).with(Energy { current: 0, speed: NORMAL_SPEED }).build();
|
||||
let player = ecs
|
||||
|
|
@ -31,7 +33,8 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
|
|||
.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: 1200 })
|
||||
/*.with(Attributes {
|
||||
.with(Attributes {
|
||||
// These are overwritten with chargen later -- placeholders.
|
||||
strength: Attribute { base: 10, modifiers: 0, bonus: 0 },
|
||||
dexterity: Attribute { base: 10, modifiers: 0, bonus: 0 },
|
||||
constitution: Attribute { base: 10, modifiers: 0, bonus: 0 },
|
||||
|
|
@ -40,14 +43,15 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity {
|
|||
charisma: Attribute { base: 10, modifiers: 0, bonus: 0 },
|
||||
})
|
||||
.with(Pools {
|
||||
hit_points: Pool { current: 10 + attr_bonus(con), max: 10 + attr_bonus(con) },
|
||||
mana: Pool { current: 2 + attr_bonus(int), max: 2 + attr_bonus(int) },
|
||||
// These are overwritten with chargen later -- placeholders.
|
||||
hit_points: Pool { current: 8 + attr_bonus(con), max: 8 + attr_bonus(con) },
|
||||
mana: Pool { current: 1 + attr_bonus(int), max: 1 + attr_bonus(int) },
|
||||
xp: 0,
|
||||
level: 1,
|
||||
bac: 10,
|
||||
weight: 0.0,
|
||||
god: false,
|
||||
})*/
|
||||
})
|
||||
.with(EquipmentChanged {})
|
||||
.with(skills)
|
||||
.with(Energy { current: 0, speed: NORMAL_SPEED })
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue