sb-core: constants module (WI-2, issue #2)

This commit is contained in:
Jan-Peter von Hunnius 2026-10-03 11:58:02 +02:00
parent 337e9bcf2c
commit 093012af20
6 changed files with 223 additions and 45 deletions

View file

@ -1,3 +1,4 @@
use crate::constants;
use crate::spells;
use sb_shared::{Character, CharacterStats, Class, Race};
@ -186,11 +187,11 @@ pub const CLASSES: &[ClassInfo] = &[
];
pub fn stat_bonus(stat: i64) -> i64 {
(stat - 20) / 2
(stat - constants::STAT_BONUS_NEUTRAL) / constants::STAT_BONUS_STEP
}
fn roll_stat(rng: &mut impl rand::Rng, modifier: i64) -> i64 {
let base: i64 = rng.random_range(6..=16);
let base: i64 = rng.random_range(constants::STAT_ROLL_MIN..=constants::STAT_ROLL_MAX);
base + modifier
}
@ -221,7 +222,7 @@ pub fn calc_max_energy(class: &Class) -> i32 {
.iter()
.find(|c| &c.class == class)
.expect("invalid class");
30 + info.base_hp / 3
constants::BASE_MAX_ENERGY + info.base_hp / constants::MAX_ENERGY_PER_BASE_HP_DIVISOR
}
pub fn calc_max_nerve(class: &Class) -> i32 {
@ -229,19 +230,19 @@ pub fn calc_max_nerve(class: &Class) -> i32 {
.iter()
.find(|c| &c.class == class)
.expect("invalid class");
100 + info.base_hp / 2
constants::BASE_MAX_NERVE + info.base_hp / constants::MAX_NERVE_PER_BASE_HP_DIVISOR
}
pub fn energy_regen_rate() -> i64 {
180000
constants::ENERGY_REGEN_INTERVAL_MS
}
pub fn nerve_regen_rate() -> i64 {
300000
constants::NERVE_REGEN_INTERVAL_MS
}
pub fn hp_regen_rate() -> i64 {
300000
constants::HP_REGEN_INTERVAL_MS
}
pub fn apply_regen(char: &mut Character, now_ms: i64) {
@ -259,15 +260,16 @@ pub fn apply_regen(char: &mut Character, now_ms: i64) {
char.nerve = (char.nerve + nerve_ticks).min(char.max_nerve);
}
if hp_ticks > 0 && char.hp > 0 && char.hp < char.max_hp {
let regen_per_tick = (char.max_hp as f64 * 0.05).ceil() as i32;
let regen_per_tick =
(char.max_hp as f64 * constants::HP_REGEN_FRACTION_PER_TICK).ceil() as i32;
char.hp = (char.hp + regen_per_tick * hp_ticks).min(char.max_hp);
}
char.last_regen = now_ms;
}
pub fn training_cost(stat: i64) -> i32 {
let scaled = (stat as f64 / 10.0).floor() as i32;
(5.0_f64 * 1.3_f64.powi(scaled)) as i32
let scaled = (stat as f64 / constants::TRAINING_STAT_SCALER).floor() as i32;
(constants::TRAINING_BASE_COST * constants::TRAINING_GROWTH_FACTOR.powi(scaled)) as i32
}
pub fn create_character(
@ -299,7 +301,7 @@ pub fn create_character(
name,
race,
class,
level: 1,
level: constants::STARTING_LEVEL,
xp: 0,
stats,
hp: max_hp,
@ -308,7 +310,7 @@ pub fn create_character(
max_energy,
nerve: max_nerve,
max_nerve,
gold: 50,
gold: constants::STARTING_GOLD,
last_regen: 0,
equipment: [
("head".into(), None),
@ -342,11 +344,11 @@ pub fn xp_for_level(level: i32) -> i64 {
return 0;
}
let n = (level - 1) as f64;
XP_FACTOR * (100.0 * n * n) as i64
XP_FACTOR * (constants::XP_CURVE_COEFFICIENT * n * n) as i64
}
pub fn level_up_cost(level: i32) -> i32 {
500 * level
constants::LEVEL_UP_GOLD_PER_LEVEL * level
}
pub fn level_up(char: &mut Character) -> Result<i32, &'static str> {