use super::{Skill, Skills}; use crate::gui::Classes; use rltk::prelude::*; /// Returns the attribute bonus for a given attribute score, where every 2 points above /// or below 10 is an additional +1 or -1. pub fn attr_bonus(value: i32) -> i32 { return (value - 10) / 2; } /// Returns the number of HP gained per level for a given constitution score. pub fn hp_per_level(rng: &mut rltk::RandomNumberGenerator, constitution: i32) -> i32 { return rng.roll_dice(1, 8) + attr_bonus(constitution); } #[allow(dead_code)] /// Returns a total HP roll for a player, based on a given constitution score and level. pub fn player_hp_at_level(rng: &mut rltk::RandomNumberGenerator, constitution: i32, level: i32) -> i32 { let mut total = 10 + attr_bonus(constitution); for _i in 0..level { total += hp_per_level(rng, constitution); } return total; } /// Returns a total HP roll for an NPC, based on a given constitution score and level. pub fn npc_hp_at_level(rng: &mut rltk::RandomNumberGenerator, constitution: i32, level: i32) -> i32 { if level == 0 { return rng.roll_dice(1, 4); } let mut total = 1; for _i in 0..level { total += rng.roll_dice(1, 8) + attr_bonus(constitution); } return total; } /// Returns the number of mana gained per level for a given intelligence score. pub fn mana_per_level(rng: &mut rltk::RandomNumberGenerator, intelligence: i32) -> i32 { return rng.roll_dice(1, 4) + attr_bonus(intelligence); } /// Returns the number of mana gained per level for a given intelligence score. pub fn mana_at_level(rng: &mut rltk::RandomNumberGenerator, intelligence: i32, level: i32) -> i32 { let mut total = 0; for _i in 0..level { total += mana_per_level(rng, intelligence); } return total; } /// Returns the skill bonus for a given skill, or -4 if the skill is not present. pub fn skill_bonus(skill: Skill, skills: &Skills) -> i32 { if skills.skills.contains_key(&skill) { return skills.skills[&skill]; } else { return -4; } } /// Roll 4d6 and drop the lowest, for rolling d20-style stats pub fn roll_4d6(rng: &mut rltk::RandomNumberGenerator) -> i32 { let mut rolls: Vec = Vec::new(); for _i in 0..4 { rolls.push(rng.roll_dice(1, 6)); } rolls.sort_unstable(); let mut roll = 0; for i in 1..rolls.len() { roll += rolls[i]; } return roll; } /// Handles stat distribution for a player character. pub fn get_attribute_rolls(rng: &mut RandomNumberGenerator, class: Classes) -> (i32, i32, i32, i32, i32, i32) { let (mut str, mut dex, mut con, mut int, mut wis, mut cha) = match class { Classes::Fighter => (10, 8, 10, 6, 6, 8), Classes::Rogue => (8, 12, 8, 6, 8, 10), Classes::Wizard => (6, 8, 6, 12, 10, 8), Classes::Villager => (6, 6, 6, 6, 6, 6), }; let remaining_points = 75 - (str + dex + con + int + wis + cha); let improve_chance: [i32; 6] = match class { Classes::Fighter => [30, 20, 30, 6, 7, 7], Classes::Rogue => [18, 30, 20, 9, 8, 15], Classes::Wizard => [10, 20, 20, 30, 10, 10], Classes::Villager => [15, 15, 25, 15, 15, 15], }; let improve_table = crate::random_table::RandomTable::new() .add("Strength", improve_chance[0]) .add("Dexterity", improve_chance[1]) .add("Constitution", improve_chance[2]) .add("Intelligence", improve_chance[3]) .add("Wisdom", improve_chance[4]) .add("Charisma", improve_chance[5]); for _i in 0..remaining_points { let roll = improve_table.roll(rng); match roll.as_str() { "Strength" => str += 1, "Dexterity" => dex += 1, "Constitution" => con += 1, "Intelligence" => int += 1, "Wisdom" => wis += 1, "Charisma" => cha += 1, _ => {} } } return (str, dex, con, int, wis, cha); }