char creation to config
This commit is contained in:
parent
424bf43ed5
commit
15e8ae13d0
9 changed files with 82 additions and 46 deletions
26
src/config/char_create.rs
Normal file
26
src/config/char_create.rs
Normal file
|
|
@ -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";
|
||||
|
|
@ -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 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 per turn for an entity with NORMAL_SPEED.
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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::*;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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::<Telepath>();
|
||||
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::<Energy>();
|
||||
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::<Energy>();
|
||||
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>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue