add 'proc effects' to weapons

This commit is contained in:
Timothy Warren 2022-01-25 14:25:11 -05:00
parent 2f0b9b4535
commit 52235a571e
4 changed files with 39 additions and 1 deletions

View File

@ -156,6 +156,8 @@ pub struct MeleeWeapon {
pub damage_die_type: i32, pub damage_die_type: i32,
pub damage_bonus: i32, pub damage_bonus: i32,
pub hit_bonus: i32, pub hit_bonus: i32,
pub proc_chance: Option<f32>,
pub proc_target: Option<String>,
} }
#[derive(Component, ConvertSaveload, Clone)] #[derive(Component, ConvertSaveload, Clone)]

View File

@ -64,12 +64,15 @@ impl<'a> System<'a> for MeleeCombatSystem {
if attacker_pools.hit_points.current > 0 && target_pools.hit_points.current > 0 { if attacker_pools.hit_points.current > 0 && target_pools.hit_points.current > 0 {
let target_name = names.get(wants_melee.target).unwrap(); let target_name = names.get(wants_melee.target).unwrap();
// Define the basic unarmed attack -- overridden by wielding check below if a weapon is equipped
let mut weapon_info = MeleeWeapon { let mut weapon_info = MeleeWeapon {
attribute: WeaponAttribute::Might, attribute: WeaponAttribute::Might,
hit_bonus: 0, hit_bonus: 0,
damage_n_dice: 1, damage_n_dice: 1,
damage_die_type: 4, damage_die_type: 4,
damage_bonus: 0, damage_bonus: 0,
proc_chance: None,
proc_target: None,
}; };
if let Some(nat) = natural.get(entity) { if let Some(nat) = natural.get(entity) {
@ -89,9 +92,13 @@ impl<'a> System<'a> for MeleeCombatSystem {
} }
} }
for (wielded, melee) in (&equipped_items, &meleeweapons).join() { let mut weapon_entity: Option<Entity> = None;
for (weaponentity, wielded, melee) in
(&entities, &equipped_items, &meleeweapons).join()
{
if wielded.owner == entity && wielded.slot == EquipmentSlot::Melee { if wielded.owner == entity && wielded.slot == EquipmentSlot::Melee {
weapon_info = melee.clone(); weapon_info = melee.clone();
weapon_entity = Some(weaponentity);
} }
} }
@ -159,6 +166,26 @@ impl<'a> System<'a> for MeleeCombatSystem {
"{} hits {} for {} hp.", "{} hits {} for {} hp.",
&name.name, &target_name.name, damage &name.name, &target_name.name, damage
)); ));
// Proc effects
if let Some(chance) = &weapon_info.proc_chance {
if rng.roll_dice(1, 100) <= (chance * 100.0) as i32 {
let effect_target = if weapon_info.proc_target.unwrap() == "Self" {
Targets::Single { target: entity }
} else {
Targets::Single {
target: wants_melee.target,
}
};
add_effect(
Some(entity),
EffectType::ItemUse {
item: weapon_entity.unwrap(),
},
effect_target,
);
}
}
} else if natural_roll == 1 { } else if natural_roll == 1 {
// Natural 1 miss // Natural 1 miss
log.append(format!( log.append(format!(

View File

@ -37,6 +37,9 @@ pub struct Weapon {
pub attribute: String, pub attribute: String,
pub base_damage: String, pub base_damage: String,
pub hit_bonus: i32, pub hit_bonus: i32,
pub proc_chance: Option<f32>,
pub proc_target: Option<String>,
pub proc_effects: Option<HashMap<String, String>>,
} }
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]

View File

@ -401,6 +401,8 @@ pub fn spawn_named_item(
damage_die_type: die_type, damage_die_type: die_type,
damage_bonus: bonus, damage_bonus: bonus,
hit_bonus: weapon.hit_bonus, hit_bonus: weapon.hit_bonus,
proc_chance: weapon.proc_chance,
proc_target: weapon.proc_target.clone(),
}; };
wpn.attribute = match weapon.attribute.as_str() { wpn.attribute = match weapon.attribute.as_str() {
@ -409,6 +411,10 @@ pub fn spawn_named_item(
}; };
eb = eb.with(wpn); eb = eb.with(wpn);
if let Some(proc_effects) = &weapon.proc_effects {
apply_effects!(proc_effects, eb);
}
} }
if let Some(wearable) = &item_template.wearable { if let Some(wearable) = &item_template.wearable {