From 2df20956bb1752700e52d1f24360865a9775d950 Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Tue, 25 Jan 2022 15:04:55 -0500 Subject: [PATCH] Cut down on player entity generation boilerplate --- src/components.rs | 61 ++++++++++++++++++++++++++++++-- src/spawner.rs | 90 ++++++++++------------------------------------- 2 files changed, 77 insertions(+), 74 deletions(-) diff --git a/src/components.rs b/src/components.rs index 08af218..6261142 100644 --- a/src/components.rs +++ b/src/components.rs @@ -177,6 +177,15 @@ pub struct HungerClock { pub duration: i32, } +impl Default for HungerClock { + fn default() -> Self { + HungerClock { + state: HungerState::WellFed, + duration: 20, + } + } +} + #[derive(Component, Debug, Serialize, Deserialize, Clone)] pub struct Door { pub open: bool, @@ -212,6 +221,17 @@ pub struct Attributes { pub intelligence: Attribute, } +impl Attributes { + pub fn new(base: i32) -> Self { + Attributes { + might: Attribute::new(base), + fitness: Attribute::new(base), + quickness: Attribute::new(base), + intelligence: Attribute::new(base), + } + } +} + #[derive(Component, Debug, Default, Serialize, Deserialize, Clone)] pub struct Skills { pub skills: HashMap, @@ -255,6 +275,23 @@ pub struct Pools { pub god_mode: bool, } +impl Pools { + pub fn player_pools() -> Self { + use crate::gamesystem::{mana_at_level, player_hp_at_level}; + + Pools { + hit_points: Pool::new(player_hp_at_level(11, 1)), + mana: Pool::new(mana_at_level(11, 1)), + xp: 0, + level: 1, + total_weight: 0., + total_initiative_penalty: 0., + gold: 0., + god_mode: false, + } + } +} + #[derive(Serialize, Deserialize, Clone)] pub struct NaturalAttack { pub name: String, @@ -288,7 +325,16 @@ pub struct LightSource { pub range: i32, } -#[derive(Component, Debug, Serialize, Deserialize, Clone)] +impl LightSource { + pub fn torch_light() -> Self { + LightSource { + color: crate::colors::TORCH_LIGHT, + range: 8, + } + } +} + +#[derive(Component, Debug, Default, Serialize, Deserialize, Clone)] pub struct Initiative { pub current: i32, } @@ -388,6 +434,17 @@ pub struct AttributeBonus { pub intelligence: Option, } +impl AttributeBonus { + pub fn hangover() -> Self { + AttributeBonus { + might: Some(-1), + fitness: None, + quickness: Some(-1), + intelligence: Some(-1), + } + } +} + #[derive(Component, Debug, Serialize, Deserialize, Clone)] pub struct Consumable { pub max_charges: i32, @@ -410,7 +467,7 @@ pub struct KnownSpell { pub mana_cost: i32, } -#[derive(Component, Debug, Serialize, Deserialize, Clone)] +#[derive(Component, Debug, Default, Serialize, Deserialize, Clone)] pub struct KnownSpells { pub spells: Vec, } diff --git a/src/spawner.rs b/src/spawner.rs index f565d2d..e40bee9 100644 --- a/src/spawner.rs +++ b/src/spawner.rs @@ -5,7 +5,6 @@ use ::specs::prelude::*; use ::specs::saveload::{MarkedBuilder, SimpleMarker}; use crate::components::*; -use crate::gamesystem::{mana_at_level, player_hp_at_level}; use crate::random_table::RandomTable; use crate::raws::{ get_spawn_table_for_depth, spawn_all_spells, spawn_named_entity, SpawnType, RAWS, @@ -17,10 +16,7 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity { spawn_all_spells(ecs); let player = ecs .create_entity() - .with(Position { - x: player_x, - y: player_y, - }) + .with(Position::from((player_x, player_y))) .with(Renderable { glyph: rltk::to_cp437('@'), fg: colors::YELLOW, @@ -30,92 +26,42 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity { .with(Player {}) .with(Viewshed::default()) .with(Name::from("Player")) - .with(HungerClock { - state: HungerState::WellFed, - duration: 20, - }) - .with(Attributes { - might: Attribute::new(11), - fitness: Attribute::new(11), - quickness: Attribute::new(11), - intelligence: Attribute::new(11), - }) + .with(HungerClock::default()) + .with(Attributes::new(11)) .with(Skills::new(1)) - .with(Pools { - hit_points: Pool::new(player_hp_at_level(11, 1)), - mana: Pool::new(mana_at_level(11, 1)), - xp: 0, - level: 1, - total_weight: 0., - total_initiative_penalty: 0., - gold: 0., - god_mode: false, - }) + .with(Pools::player_pools()) .with(EquipmentChanged {}) - .with(LightSource { - color: colors::TORCH_LIGHT, - range: 8, - }) - .with(Initiative { current: 0 }) + .with(LightSource::torch_light()) + .with(Initiative::default()) .with(Faction::from("Player")) - .with(KnownSpells { - spells: vec![KnownSpell { - display_name: "Zap".to_string(), - mana_cost: 1, - }], - }) + .with(KnownSpells::default()) .marked::>() .build(); // Starting equipment - spawn_named_entity( - &RAWS.lock().unwrap(), - ecs, + let starting_equipment = vec![ "Rusty Longsword", - SpawnType::Equipped { by: player }, - ); - spawn_named_entity( - &RAWS.lock().unwrap(), - ecs, "Dried Sausage", - SpawnType::Carried { by: player }, - ); - spawn_named_entity( - &RAWS.lock().unwrap(), - ecs, "Beer", - SpawnType::Carried { by: player }, - ); - spawn_named_entity( - &RAWS.lock().unwrap(), - ecs, "Stained Tunic", - SpawnType::Equipped { by: player }, - ); - spawn_named_entity( - &RAWS.lock().unwrap(), - ecs, "Torn Trousers", - SpawnType::Equipped { by: player }, - ); - spawn_named_entity( - &RAWS.lock().unwrap(), - ecs, "Old Boots", - SpawnType::Equipped { by: player }, - ); + ]; + for equipment in starting_equipment.iter() { + spawn_named_entity( + &RAWS.lock().unwrap(), + ecs, + *equipment, + SpawnType::Carried { by: player }, + ); + } // Starting hangover ecs.create_entity() .with(StatusEffect { target: player }) .with(Duration { turns: 10 }) .with(Name::from("Hangover")) - .with(AttributeBonus { - might: Some(-1), - fitness: None, - quickness: Some(-1), - intelligence: Some(-1), - }) + .with(AttributeBonus::hangover()) .marked::>() .build();