race -> ancestries, adds ancestry stat maximums

This commit is contained in:
Llywelwyn 2023-08-21 11:21:19 +01:00
parent 9e26c41aad
commit 33ce208252
5 changed files with 73 additions and 17 deletions

View file

@ -1,5 +1,5 @@
use super::{Skill, Skills}; use super::{Skill, Skills};
use crate::gui::Class; use crate::gui::{Ancestry, Class};
use rltk::prelude::*; use rltk::prelude::*;
use std::cmp::max; use std::cmp::max;
@ -77,20 +77,32 @@ pub fn roll_4d6(rng: &mut rltk::RandomNumberGenerator) -> i32 {
} }
/// Handles stat distribution for a player character. /// Handles stat distribution for a player character.
pub fn get_attribute_rolls(rng: &mut RandomNumberGenerator, class: Class) -> (i32, i32, i32, i32, i32, i32) { pub fn get_attribute_rolls(
rng: &mut RandomNumberGenerator,
class: Class,
ancestry: Ancestry,
) -> (i32, i32, i32, i32, i32, i32) {
let (mut str, mut dex, mut con, mut int, mut wis, mut cha) = match class { let (mut str, mut dex, mut con, mut int, mut wis, mut cha) = match class {
Class::Fighter => (10, 8, 10, 6, 6, 8), Class::Fighter => (10, 8, 10, 6, 6, 8),
Class::Rogue => (8, 10, 8, 6, 8, 10), Class::Rogue => (8, 10, 8, 6, 8, 10),
Class::Wizard => (6, 8, 6, 10, 10, 8), Class::Wizard => (6, 8, 6, 10, 10, 8),
Class::Villager => (6, 6, 6, 6, 6, 6), Class::Villager => (6, 6, 6, 6, 6, 6),
}; };
let remaining_points = 75 - (str + dex + con + int + wis + cha); let mut remaining_points = 75 - (str + dex + con + int + wis + cha);
let improve_chance: [i32; 6] = match class { let improve_chance: [i32; 6] = match class {
Class::Fighter => [30, 20, 30, 6, 7, 7], Class::Fighter => [30, 20, 30, 6, 7, 7],
Class::Rogue => [18, 30, 20, 9, 8, 15], Class::Rogue => [18, 30, 20, 9, 8, 15],
Class::Wizard => [10, 15, 20, 30, 15, 10], Class::Wizard => [10, 15, 20, 30, 15, 10],
Class::Villager => [15, 15, 25, 15, 15, 15], Class::Villager => [15, 15, 25, 15, 15, 15],
}; };
let ancestry_maximums: [i32; 6] = match ancestry {
Ancestry::Human => [19, 19, 19, 19, 19, 19], // 114
Ancestry::Elf => [15, 18, 15, 20, 20, 18], // 106
Ancestry::Dwarf => [19, 17, 20, 16, 16, 16], // 106
Ancestry::Gnome => [16, 18, 16, 20, 18, 18], // 106
Ancestry::Catfolk => [16, 20, 16, 16, 18, 20], // 106
_ => [18, 18, 18, 18, 18, 18],
};
let improve_table = crate::random_table::RandomTable::new() let improve_table = crate::random_table::RandomTable::new()
.add("Strength", improve_chance[0]) .add("Strength", improve_chance[0])
.add("Dexterity", improve_chance[1]) .add("Dexterity", improve_chance[1])
@ -98,17 +110,61 @@ pub fn get_attribute_rolls(rng: &mut RandomNumberGenerator, class: Class) -> (i3
.add("Intelligence", improve_chance[3]) .add("Intelligence", improve_chance[3])
.add("Wisdom", improve_chance[4]) .add("Wisdom", improve_chance[4])
.add("Charisma", improve_chance[5]); .add("Charisma", improve_chance[5]);
for _i in 0..remaining_points { let mut failed_attempts = 0;
while remaining_points > 0 && failed_attempts < 100 {
let roll = improve_table.roll(rng); let roll = improve_table.roll(rng);
match roll.as_str() { match roll.as_str() {
"Strength" => str += 1, "Strength" => {
"Dexterity" => dex += 1, if str < ancestry_maximums[0] {
"Constitution" => con += 1, str += 1;
"Intelligence" => int += 1, remaining_points -= 1;
"Wisdom" => wis += 1, } else {
"Charisma" => cha += 1, failed_attempts += 1;
}
}
"Dexterity" => {
if dex < ancestry_maximums[1] {
dex += 1;
remaining_points -= 1;
} else {
failed_attempts += 1;
}
}
"Constitution" => {
if con < ancestry_maximums[2] {
con += 1;
remaining_points -= 1;
} else {
failed_attempts += 1;
}
}
"Intelligence" => {
if int < ancestry_maximums[3] {
int += 1;
remaining_points -= 1;
} else {
failed_attempts += 1;
}
}
"Wisdom" => {
if wis < ancestry_maximums[4] {
wis += 1;
remaining_points -= 1;
} else {
failed_attempts += 1;
}
}
"Charisma" => {
if cha < ancestry_maximums[5] {
cha += 1;
remaining_points -= 1;
} else {
failed_attempts += 1;
}
}
_ => {} _ => {}
} }
} }
console::log(format!("{}, {}", failed_attempts, remaining_points));
return (str, dex, con, int, wis, cha); return (str, dex, con, int, wis, cha);
} }

View file

@ -255,7 +255,7 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) {
} }
/// Handles player class setup /// Handles player class setup
pub fn setup_player_class(ecs: &mut World, class: Class) { pub fn setup_player_class(ecs: &mut World, class: Class, ancestry: Ancestry) {
let player = *ecs.fetch::<Entity>(); let player = *ecs.fetch::<Entity>();
// ATTRIBUTES // ATTRIBUTES
{ {
@ -264,7 +264,7 @@ pub fn setup_player_class(ecs: &mut World, class: Class) {
let mut rng = ecs.write_resource::<RandomNumberGenerator>(); let mut rng = ecs.write_resource::<RandomNumberGenerator>();
let mut attributes = ecs.write_storage::<Attributes>(); let mut attributes = ecs.write_storage::<Attributes>();
let (str, dex, con, int, wis, cha) = get_attribute_rolls(&mut rng, class); let (str, dex, con, int, wis, cha) = get_attribute_rolls(&mut rng, class, ancestry);
attributes attributes
.insert( .insert(
player, player,

View file

@ -7,10 +7,10 @@ use super::{
use rltk::prelude::*; use rltk::prelude::*;
use specs::prelude::*; use specs::prelude::*;
use std::collections::BTreeMap; use std::collections::BTreeMap;
mod character_creation;
mod cheat_menu; mod cheat_menu;
mod letter_to_option; mod letter_to_option;
mod race_selection; pub use character_creation::*;
pub use race_selection::*;
mod tooltip; mod tooltip;
pub use cheat_menu::*; pub use cheat_menu::*;

View file

@ -17,7 +17,7 @@ const HUNGER_BREAKPOINTS: [(i32, HungerState); 5] = [
(200, HungerState::Weak), (200, HungerState::Weak),
(0, HungerState::Fainting), (0, HungerState::Fainting),
]; ];
const BASE_CLOCK_DECREMENT_PER_TURN: i32 = 4; const BASE_CLOCK_DECREMENT_PER_TURN: i32 = 1;
pub fn get_hunger_state(duration: i32) -> HungerState { pub fn get_hunger_state(duration: i32) -> HungerState {
for (threshold, state) in HUNGER_BREAKPOINTS.iter() { for (threshold, state) in HUNGER_BREAKPOINTS.iter() {

View file

@ -41,7 +41,7 @@ extern crate lazy_static;
//Consts //Consts
pub const SHOW_MAPGEN: bool = false; pub const SHOW_MAPGEN: bool = false;
pub const LOG_SPAWNING: bool = true; pub const LOG_SPAWNING: bool = true;
pub const LOG_TICKS: bool = true; pub const LOG_TICKS: bool = false;
#[derive(PartialEq, Copy, Clone)] #[derive(PartialEq, Copy, Clone)]
pub enum RunState { pub enum RunState {
@ -410,7 +410,7 @@ impl GameState for State {
new_runstate = RunState::MainMenu { menu_selection: gui::MainMenuSelection::NewGame }; new_runstate = RunState::MainMenu { menu_selection: gui::MainMenuSelection::NewGame };
} else { } else {
gui::setup_player_ancestry(&mut self.ecs, ancestry); gui::setup_player_ancestry(&mut self.ecs, ancestry);
gui::setup_player_class(&mut self.ecs, class); gui::setup_player_class(&mut self.ecs, class, ancestry);
new_runstate = RunState::PreRun; new_runstate = RunState::PreRun;
} }
} }