From 33ce2082527d5818b5390717eec9ac3ac276dedc Mon Sep 17 00:00:00 2001 From: Llywelwyn Date: Mon, 21 Aug 2023 11:21:19 +0100 Subject: [PATCH] race -> ancestries, adds ancestry stat maximums --- src/gamesystem.rs | 76 ++++++++++++++++--- ...ace_selection.rs => character_creation.rs} | 4 +- src/gui/mod.rs | 4 +- src/hunger_system.rs | 2 +- src/main.rs | 4 +- 5 files changed, 73 insertions(+), 17 deletions(-) rename src/gui/{race_selection.rs => character_creation.rs} (99%) diff --git a/src/gamesystem.rs b/src/gamesystem.rs index 884836b..241a59b 100644 --- a/src/gamesystem.rs +++ b/src/gamesystem.rs @@ -1,5 +1,5 @@ use super::{Skill, Skills}; -use crate::gui::Class; +use crate::gui::{Ancestry, Class}; use rltk::prelude::*; use std::cmp::max; @@ -77,20 +77,32 @@ pub fn roll_4d6(rng: &mut rltk::RandomNumberGenerator) -> i32 { } /// 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 { Class::Fighter => (10, 8, 10, 6, 6, 8), Class::Rogue => (8, 10, 8, 6, 8, 10), Class::Wizard => (6, 8, 6, 10, 10, 8), 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 { Class::Fighter => [30, 20, 30, 6, 7, 7], Class::Rogue => [18, 30, 20, 9, 8, 15], Class::Wizard => [10, 15, 20, 30, 15, 10], 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() .add("Strength", improve_chance[0]) .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("Wisdom", improve_chance[4]) .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); match roll.as_str() { - "Strength" => str += 1, - "Dexterity" => dex += 1, - "Constitution" => con += 1, - "Intelligence" => int += 1, - "Wisdom" => wis += 1, - "Charisma" => cha += 1, + "Strength" => { + if str < ancestry_maximums[0] { + str += 1; + remaining_points -= 1; + } else { + 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); } diff --git a/src/gui/race_selection.rs b/src/gui/character_creation.rs similarity index 99% rename from src/gui/race_selection.rs rename to src/gui/character_creation.rs index abe49a4..fa3f449 100644 --- a/src/gui/race_selection.rs +++ b/src/gui/character_creation.rs @@ -255,7 +255,7 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) { } /// 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::(); // ATTRIBUTES { @@ -264,7 +264,7 @@ pub fn setup_player_class(ecs: &mut World, class: Class) { let mut rng = ecs.write_resource::(); let mut attributes = ecs.write_storage::(); - 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 .insert( player, diff --git a/src/gui/mod.rs b/src/gui/mod.rs index c7fab2a..e6bd186 100644 --- a/src/gui/mod.rs +++ b/src/gui/mod.rs @@ -7,10 +7,10 @@ use super::{ use rltk::prelude::*; use specs::prelude::*; use std::collections::BTreeMap; +mod character_creation; mod cheat_menu; mod letter_to_option; -mod race_selection; -pub use race_selection::*; +pub use character_creation::*; mod tooltip; pub use cheat_menu::*; diff --git a/src/hunger_system.rs b/src/hunger_system.rs index de07b8a..c3f274a 100644 --- a/src/hunger_system.rs +++ b/src/hunger_system.rs @@ -17,7 +17,7 @@ const HUNGER_BREAKPOINTS: [(i32, HungerState); 5] = [ (200, HungerState::Weak), (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 { for (threshold, state) in HUNGER_BREAKPOINTS.iter() { diff --git a/src/main.rs b/src/main.rs index 1522a6a..359bc1c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,7 +41,7 @@ extern crate lazy_static; //Consts pub const SHOW_MAPGEN: bool = false; pub const LOG_SPAWNING: bool = true; -pub const LOG_TICKS: bool = true; +pub const LOG_TICKS: bool = false; #[derive(PartialEq, Copy, Clone)] pub enum RunState { @@ -410,7 +410,7 @@ impl GameState for State { new_runstate = RunState::MainMenu { menu_selection: gui::MainMenuSelection::NewGame }; } else { 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; } }