From 83647ae28d47ebf30f7e9363cd0364b3bc878d28 Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Tue, 4 Jan 2022 11:29:23 -0500 Subject: [PATCH] Add natural attack types, completing section 5.8 --- src/melee_combat_system.rs | 30 ++++++++++++++++++++++++------ src/raws/mob_structs.rs | 2 +- src/raws/rawmaster.rs | 21 +++++++++++++++++++++ 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/melee_combat_system.rs b/src/melee_combat_system.rs index d997c61..6fcd494 100644 --- a/src/melee_combat_system.rs +++ b/src/melee_combat_system.rs @@ -8,7 +8,7 @@ use crate::components::{ use crate::game_log::GameLog; use crate::gamesystem::skill_bonus; use crate::particle_system::ParticleBuilder; -use crate::{EquipmentSlot, Position, WeaponAttribute}; +use crate::{EquipmentSlot, NaturalAttackDefense, Position, WeaponAttribute}; pub struct MeleeCombatSystem {} @@ -30,6 +30,7 @@ impl<'a> System<'a> for MeleeCombatSystem { ReadStorage<'a, Equipped>, ReadStorage<'a, MeleeWeapon>, ReadStorage<'a, Wearable>, + ReadStorage<'a, NaturalAttackDefense>, ); fn run(&mut self, data: Self::SystemData) { @@ -49,6 +50,7 @@ impl<'a> System<'a> for MeleeCombatSystem { equipped_items, meleeweapons, wearables, + natural, ) = data; for (entity, wants_melee, name, attacker_attributes, attacker_skills, attacker_pools) in ( @@ -76,6 +78,23 @@ impl<'a> System<'a> for MeleeCombatSystem { damage_bonus: 0, }; + if let Some(nat) = natural.get(entity) { + if !nat.attacks.is_empty() { + let attack_index = if nat.attacks.len() == 1 { + 0 + } else { + rng.roll_dice(1, nat.attacks.len() as i32) as usize - 1 + }; + + let attk = &nat.attacks[attack_index]; + + weapon_info.hit_bonus = attk.hit_bonus; + weapon_info.damage_n_dice = attk.damage_n_dice; + weapon_info.damage_die_type = attk.damage_die_type; + weapon_info.damage_bonus = attk.damage_bonus; + } + } + for (wielded, melee) in (&equipped_items, &meleeweapons).join() { if wielded.owner == entity && wielded.slot == EquipmentSlot::Melee { weapon_info = melee.clone(); @@ -110,11 +129,10 @@ impl<'a> System<'a> for MeleeCombatSystem { } } - // let base_armor_class = match natural.get(wants_melee.target) { - // None => 10, - // Some(nat) = nat.armor_class.unwrap_or(10); - // }; - let base_armor_class = 10; + let base_armor_class = match natural.get(wants_melee.target) { + None => 10, + Some(nat) => nat.armor_class.unwrap_or(10), + }; let armor_quickness_bonus = target_attributes.quickness.bonus; let armor_skill_bonus = skill_bonus(Skill::Defense, &*target_skills); let armor_item_bonus = armor_item_bonus_f as i32; diff --git a/src/raws/mob_structs.rs b/src/raws/mob_structs.rs index c2e53c5..0d07e8d 100644 --- a/src/raws/mob_structs.rs +++ b/src/raws/mob_structs.rs @@ -18,7 +18,7 @@ pub struct Mob { pub hp: Option, pub mana: Option, pub equipped: Option>, - pub natural: Option, + pub natural: Option, } #[derive(Deserialize, Debug)] diff --git a/src/raws/rawmaster.rs b/src/raws/rawmaster.rs index 8505fa6..59952ea 100644 --- a/src/raws/rawmaster.rs +++ b/src/raws/rawmaster.rs @@ -383,6 +383,27 @@ pub fn spawn_named_mob( dirty: true, }); + if let Some(na) = &mob_template.natural { + let mut nature = NaturalAttackDefense { + armor_class: na.armor_class, + attacks: Vec::new(), + }; + if let Some(attacks) = &na.attacks { + for nattack in attacks.iter() { + let (n, d, b) = parse_dice_string(&nattack.damage); + let attack = NaturalAttack { + name: nattack.name.clone(), + hit_bonus: nattack.hit_bonus, + damage_n_dice: n, + damage_die_type: d, + damage_bonus: b, + }; + nature.attacks.push(attack); + } + } + eb = eb.with(nature); + } + let new_mob = eb.build(); // Are they weilding anything?