diff --git a/src/config/char_create.rs b/src/config/char_create.rs new file mode 100644 index 0000000..28e5494 --- /dev/null +++ b/src/config/char_create.rs @@ -0,0 +1,26 @@ +// --- GUI --- +pub const ANCESTRY_INFO_HEADER: &str = "Your ancestry grants..."; +pub const CLASS_INFO_HEADER: &str = "Your class grants..."; +// --- ANCESTRY RENDERABLES --- +pub const ELF_GLYPH: char = '@'; +pub const ELF_COLOUR: (u8, u8, u8) = (0, 255, 0); +pub const DWARF_GLYPH: char = 'h'; +pub const DWARF_COLOUR: (u8, u8, u8) = (255, 0, 0); +pub const CATFOLK_GLYPH: char = '@'; +pub const CATFOLK_COLOUR: (u8, u8, u8) = (200, 200, 255); +// --- ANCESTRY BONUSES --- +pub const ELF_SPEED_BONUS: i32 = 1; +pub const ELF_TELEPATH_RANGE: i32 = 6; +pub const DWARF_DEFENCE_MOD: i32 = 1; +pub const CATFOLK_SPEED_BONUS: i32 = 2; +// --- CLASS STARTING ITEMS --- +pub const FIGHTER_STARTING_FOOD: &str = "1d2+1"; +pub const FIGHTER_STARTING_WEAPON: &str = "equip_shortsword"; +pub const FIGHTER_STARTING_ARMOUR: &str = "equip_body_ringmail"; +pub const FIGHTER_STARTING_SHIELD: &str = "equip_mediumshield"; +pub const ROGUE_STARTING_FOOD: &str = "1d2+2"; +pub const WIZARD_STARTING_FOOD: &str = "1d2+1"; +pub const WIZARD_MAX_SCROLL_LVL: i32 = 3; +pub const WIZARD_SCROLL_AMOUNT: &str = "1d3"; +pub const WIZARD_POTION_AMOUNT: &str = "1d3-1"; +pub const VILLAGER_STARTING_FOOD: &str = "1d3+2"; diff --git a/src/config/entity.rs b/src/config/entity.rs index 8972442..929b0d5 100644 --- a/src/config/entity.rs +++ b/src/config/entity.rs @@ -1,5 +1,12 @@ -pub const DEFAULT_VIEWSHED_STANDARD: i32 = 16; // Standard viewshed radius for almost all entities. -pub const CARRY_CAPACITY_PER_STRENGTH: i32 = 8; - -pub const NORMAL_SPEED: i32 = 12; // Normal speed for almost all entities. -pub const TURN_COST_MULTIPLIER: i32 = 4; // How many ticks per turn for an entity with NORMAL_SPEED. +pub const DEFAULT_VIEWSHED_STANDARD: i32 = 16; // Standard viewshed radius for almost all entities. +pub const CARRY_CAPACITY_PER_STRENGTH: i32 = 8; // How much weight can be carried per point of strength. +pub const NORMAL_SPEED: i32 = 12; // Normal speed for almost all entities. +pub const TURN_COST_MULTIPLIER: i32 = 4; // How many ticks for NORMAL_SPEED to get a turn. +pub const ATTR_BONUS_0: i32 = 10; // At this value, the attribute bonus is 0. +pub const ATTR_NEEDED_PER_POINT: i32 = 2; // How many points +- ATTR_BONUS_0 are needed per +- 1 bonus. +pub const STANDARD_HIT_DIE: i32 = 8; // Standard hit die used for rolling HP. +pub const STANDARD_HIT_DIE_0: i32 = 4; // Standard hit die used for rolling HP for level 0. +pub const STANDARD_MANA_DIE: i32 = 4; // Standard mana die used for rolling mana. +pub const MINIMUM_MANA: i32 = 0; // The minimum mana a monster can have. +pub const MINIMUM_MANA_PLAYER: i32 = 1; // The minimum mana a player can have. +pub const STANDARD_BAC: i32 = 10; // Standard BASE AC. diff --git a/src/config/mod.rs b/src/config/mod.rs index 689130c..415913f 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -2,6 +2,7 @@ pub mod entity; pub mod visuals; pub mod glyphs; pub mod messages; +pub mod char_create; pub const SHOW_MAPGEN: bool = false; pub const LOG_SPAWNING: bool = true; diff --git a/src/effects/damage.rs b/src/effects/damage.rs index 7613d42..1732351 100644 --- a/src/effects/damage.rs +++ b/src/effects/damage.rs @@ -9,9 +9,8 @@ use crate::{ Map, Player, Pools, - DEFAULT_PARTICLE_LIFETIME, - LONG_PARTICLE_LIFETIME, }; +use crate::config::visuals::{ DEFAULT_PARTICLE_LIFETIME, LONG_PARTICLE_LIFETIME }; use rltk::prelude::*; use specs::prelude::*; diff --git a/src/gamesystem.rs b/src/gamesystem.rs index a4566c4..00235c6 100644 --- a/src/gamesystem.rs +++ b/src/gamesystem.rs @@ -1,23 +1,24 @@ use super::{ Skill, Skills }; use crate::gui::{ Ancestry, Class }; +use crate::config::entity; use rltk::prelude::*; use std::cmp::max; /// 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; + return (value - entity::ATTR_BONUS_0) / entity::ATTR_NEEDED_PER_POINT; } /// 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 max(rng.roll_dice(1, 8) + attr_bonus(constitution), 1); + return max(rng.roll_dice(1, entity::STANDARD_HIT_DIE) + attr_bonus(constitution), 1); } #[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 = 8 + attr_bonus(constitution); + let mut total = entity::STANDARD_HIT_DIE + attr_bonus(constitution); for _i in 0..level { total += hp_per_level(rng, constitution); } @@ -27,23 +28,23 @@ pub fn player_hp_at_level(rng: &mut rltk::RandomNumberGenerator, constitution: i /// 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); + return rng.roll_dice(1, entity::STANDARD_HIT_DIE_0); } let mut total = 1; for _i in 0..level { - total += rng.roll_dice(1, 8) + attr_bonus(constitution); + total += rng.roll_dice(1, entity::STANDARD_HIT_DIE) + 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 max(rng.roll_dice(1, 4) + attr_bonus(intelligence), 1); + return max(rng.roll_dice(1, entity::STANDARD_MANA_DIE) + attr_bonus(intelligence), 1); } /// 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; + let mut total = entity::MINIMUM_MANA; for _i in 0..level { total += mana_per_level(rng, intelligence); } diff --git a/src/gui/character_creation.rs b/src/gui/character_creation.rs index d3da4d3..4abcd26 100644 --- a/src/gui/character_creation.rs +++ b/src/gui/character_creation.rs @@ -1,5 +1,6 @@ use super::{ gamesystem::attr_bonus, gamesystem::get_attribute_rolls, Attributes, Pools, Renderable, RunState, State }; -use crate::config::entity::NORMAL_SPEED; +use crate::config::entity; +use crate::config::char_create::*; use crate::{ raws, Attribute, @@ -181,13 +182,13 @@ pub fn character_creation(gs: &mut State, ctx: &mut Rltk) -> CharCreateResult { ctx.print_color(x, y + 3, fg, bg, "v. Villager"); // Selected ancestry/class benefits x += column_width; - ctx.print_color(x, y, selected_fg, bg, "Your ancestry grants..."); + ctx.print_color(x, y, selected_fg, bg, ANCESTRY_INFO_HEADER); for line in ANCESTRY_CLASS_DATA.get(race_str).unwrap().iter() { y += 1; ctx.print_color(x + 1, y, unselected_fg, bg, line); } y += 2; - ctx.print_color(x, y, selected_fg, bg, "Your class grants..."); + ctx.print_color(x, y, selected_fg, bg, CLASS_INFO_HEADER); for line in ANCESTRY_CLASS_DATA.get(class_str).unwrap().iter() { y += 1; ctx.print_color(x + 1, y, unselected_fg, bg, line); @@ -257,36 +258,44 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) { Ancestry::Dwarf => { renderables .insert(*player, Renderable { - glyph: rltk::to_cp437('h'), - fg: RGB::named(rltk::RED), + glyph: rltk::to_cp437(DWARF_GLYPH), + fg: RGB::named(DWARF_COLOUR), bg: RGB::named(rltk::BLACK), render_order: 0, }) .expect("Unable to insert renderable component"); - *player_skills.skills.entry(Skill::Defence).or_insert(0) += 1; + *player_skills.skills.entry(Skill::Defence).or_insert(0) += DWARF_DEFENCE_MOD; } Ancestry::Elf => { renderables .insert(*player, Renderable { - glyph: rltk::to_cp437('@'), - fg: RGB::named(rltk::GREEN), + glyph: rltk::to_cp437(ELF_GLYPH), + fg: RGB::named(ELF_COLOUR), bg: RGB::named(rltk::BLACK), render_order: 0, }) .expect("Unable to insert renderable component"); let mut telepaths = ecs.write_storage::(); telepaths - .insert(*player, Telepath { telepath_tiles: Vec::new(), range: 6, dirty: true }) + .insert(*player, Telepath { telepath_tiles: Vec::new(), range: ELF_TELEPATH_RANGE, dirty: true }) .expect("Unable to insert telepath component"); let mut speeds = ecs.write_storage::(); speeds - .insert(*player, Energy { current: 0, speed: NORMAL_SPEED + 1 }) + .insert(*player, Energy { current: 0, speed: entity::NORMAL_SPEED + ELF_SPEED_BONUS }) .expect("Unable to insert energy component"); } Ancestry::Catfolk => { + renderables + .insert(*player, Renderable { + glyph: rltk::to_cp437(CATFOLK_GLYPH), + fg: RGB::named(CATFOLK_COLOUR), + bg: RGB::named(rltk::BLACK), + render_order: 0, + }) + .expect("Unable to insert renderable component"); let mut speeds = ecs.write_storage::(); speeds - .insert(*player, Energy { current: 0, speed: NORMAL_SPEED + 2 }) + .insert(*player, Energy { current: 0, speed: entity::NORMAL_SPEED + CATFOLK_SPEED_BONUS }) .expect("Unable to insert energy component"); } _ => {} @@ -325,11 +334,11 @@ pub fn setup_player_class(ecs: &mut World, class: Class, ancestry: Ancestry) { let mut pools = ecs.write_storage::(); pools .insert(player, Pools { - 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) }, + hit_points: Pool { current: 8 + attr_bonus(con), max: entity::STANDARD_HIT_DIE + attr_bonus(con) }, + mana: Pool { current: 1 + attr_bonus(int), max: entity::MINIMUM_MANA_PLAYER + attr_bonus(int) }, xp: 0, level: 1, - bac: 10, + bac: entity::STANDARD_BAC, weight: 0.0, god: false, }) @@ -368,26 +377,26 @@ fn get_starting_inventory(class: Class, rng: &mut RandomNumberGenerator) -> (Vec let starting_food: &str; match class { Class::Fighter => { - starting_food = "1d2+1"; + starting_food = FIGHTER_STARTING_FOOD; equipped = vec![ - "equip_shortsword".to_string(), - "equip_body_ringmail".to_string(), - "equip_mediumshield".to_string() + FIGHTER_STARTING_WEAPON.to_string(), + FIGHTER_STARTING_ARMOUR.to_string(), + FIGHTER_STARTING_SHIELD.to_string() ]; } Class::Rogue => { - starting_food = "1d2+2"; + starting_food = ROGUE_STARTING_FOOD; equipped = vec!["equip_rapier".to_string(), "equip_body_weakleather".to_string()]; carried = vec!["equip_dagger".to_string(), "equip_dagger".to_string()]; } Class::Wizard => { - starting_food = "1d2+1"; + starting_food = WIZARD_STARTING_FOOD; equipped = vec!["equip_dagger".to_string(), "equip_back_protection".to_string()]; - pick_random_table_item(rng, &mut carried, "scrolls", "1d3", Some(3)); - pick_random_table_item(rng, &mut carried, "potions", "1d3-1", Some(3)); + pick_random_table_item(rng, &mut carried, "scrolls", WIZARD_SCROLL_AMOUNT, Some(WIZARD_MAX_SCROLL_LVL)); + pick_random_table_item(rng, &mut carried, "potions", WIZARD_POTION_AMOUNT, Some(WIZARD_MAX_SCROLL_LVL)); } Class::Villager => { - starting_food = "1d3+2"; + starting_food = VILLAGER_STARTING_FOOD; pick_random_table_item(rng, &mut equipped, "villager_equipment", "1", None); } } diff --git a/src/main.rs b/src/main.rs index 9eb6567..f32d015 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,7 +27,7 @@ mod trigger_system; use melee_combat_system::MeleeCombatSystem; mod inventory; mod particle_system; -use particle_system::{ ParticleBuilder, DEFAULT_PARTICLE_LIFETIME, LONG_PARTICLE_LIFETIME }; +use particle_system::ParticleBuilder; mod ai; mod config; mod effects; diff --git a/src/particle_system.rs b/src/particle_system.rs index aea4a8c..d83b9e6 100644 --- a/src/particle_system.rs +++ b/src/particle_system.rs @@ -1,13 +1,7 @@ use super::{ ParticleLifetime, Position, Renderable, Rltk }; use rltk::RGB; use specs::prelude::*; - -pub const SHORT_PARTICLE_LIFETIME: f32 = 100.0; -// For things which will happen frequently - i.e. attacking. -pub const DEFAULT_PARTICLE_LIFETIME: f32 = 200.0; -// For exceptional things, like large AOEs, to make sure the -// player can actually see what's being impacted - i.e. fireball. -pub const LONG_PARTICLE_LIFETIME: f32 = 300.0; +use crate::config::visuals::{ DEFAULT_PARTICLE_LIFETIME, SHORT_PARTICLE_LIFETIME }; /// Runs each tick, deleting particles who are past their expiry. // Should make an addition to this to also spawn delayed particles, diff --git a/src/raws/rawmaster.rs b/src/raws/rawmaster.rs index f0cf5ec..9285e7b 100644 --- a/src/raws/rawmaster.rs +++ b/src/raws/rawmaster.rs @@ -1,6 +1,5 @@ use super::{ Raws, Reaction }; use crate::components::*; -use crate::config::entity; use crate::gamesystem::*; use crate::gui::Ancestry; use crate::random_table::RandomTable;