Made attacker entity and uid optional to remove potential for attacks to not be applied and some unwraps.

This commit is contained in:
Sam 2021-01-31 21:43:26 -05:00
parent af982ec0bb
commit 80954f3ba4
6 changed files with 101 additions and 97 deletions

View File

@ -72,10 +72,10 @@ impl Attack {
pub fn apply_attack( pub fn apply_attack(
&self, &self,
target_group: GroupTarget, target_group: GroupTarget,
attacker_entity: EcsEntity, attacker_entity: Option<EcsEntity>,
target_entity: EcsEntity, target_entity: EcsEntity,
target_inventory: Option<&Inventory>, target_inventory: Option<&Inventory>,
attacker_uid: Uid, attacker_uid: Option<Uid>,
attacker_energy: Option<&Energy>, attacker_energy: Option<&Energy>,
dir: Dir, dir: Dir,
target_dodging: bool, target_dodging: bool,
@ -93,7 +93,7 @@ impl Attack {
{ {
let change = damage.damage.modify_damage( let change = damage.damage.modify_damage(
target_inventory, target_inventory,
Some(attacker_uid), attacker_uid,
is_crit, is_crit,
self.crit_multiplier, self.crit_multiplier,
strength_modifier, strength_modifier,
@ -117,13 +117,15 @@ impl Attack {
} }
}, },
AttackEffect::EnergyReward(ec) => { AttackEffect::EnergyReward(ec) => {
server_events.push(ServerEvent::EnergyChange { if let Some(attacker_entity) = attacker_entity {
entity: attacker_entity, server_events.push(ServerEvent::EnergyChange {
change: EnergyChange { entity: attacker_entity,
amount: *ec as i32, change: EnergyChange {
source: EnergySource::HitEnemy, amount: *ec as i32,
}, source: EnergySource::HitEnemy,
}); },
});
}
}, },
AttackEffect::Buff(b) => { AttackEffect::Buff(b) => {
if thread_rng().gen::<f32>() < b.chance { if thread_rng().gen::<f32>() < b.chance {
@ -136,16 +138,16 @@ impl Attack {
} }
}, },
AttackEffect::Lifesteal(l) => { AttackEffect::Lifesteal(l) => {
let change = HealthChange { if let Some(attacker_entity) = attacker_entity {
amount: (applied_damage * l) as i32, let change = HealthChange {
cause: HealthSource::Heal { amount: (applied_damage * l) as i32,
by: Some(attacker_uid), cause: HealthSource::Heal { by: attacker_uid },
}, };
}; server_events.push(ServerEvent::Damage {
server_events.push(ServerEvent::Damage { entity: attacker_entity,
entity: attacker_entity, change,
change, });
}); }
}, },
AttackEffect::Poise(p) => { AttackEffect::Poise(p) => {
let change = PoiseChange::from_attack(*p, target_inventory); let change = PoiseChange::from_attack(*p, target_inventory);
@ -158,9 +160,7 @@ impl Attack {
AttackEffect::Heal(h) => { AttackEffect::Heal(h) => {
let change = HealthChange { let change = HealthChange {
amount: *h as i32, amount: *h as i32,
cause: HealthSource::Heal { cause: HealthSource::Heal { by: attacker_uid },
by: Some(attacker_uid),
},
}; };
server_events.push(ServerEvent::Damage { server_events.push(ServerEvent::Damage {
entity: target_entity, entity: target_entity,
@ -181,13 +181,15 @@ impl Attack {
Some(CombatRequirement::AnyDamage) => accumulated_damage > 0.0, Some(CombatRequirement::AnyDamage) => accumulated_damage > 0.0,
Some(CombatRequirement::SufficientEnergy(r)) => { Some(CombatRequirement::SufficientEnergy(r)) => {
if attacker_energy.map_or(true, |e| e.current() >= *r) { if attacker_energy.map_or(true, |e| e.current() >= *r) {
server_events.push(ServerEvent::EnergyChange { if let Some(attacker_entity) = attacker_entity {
entity: attacker_entity, server_events.push(ServerEvent::EnergyChange {
change: EnergyChange { entity: attacker_entity,
amount: -(*r as i32), change: EnergyChange {
source: EnergySource::Ability, amount: -(*r as i32),
}, source: EnergySource::Ability,
}); },
});
}
true true
} else { } else {
false false
@ -206,13 +208,15 @@ impl Attack {
} }
}, },
AttackEffect::EnergyReward(ec) => { AttackEffect::EnergyReward(ec) => {
server_events.push(ServerEvent::EnergyChange { if let Some(attacker_entity) = attacker_entity {
entity: attacker_entity, server_events.push(ServerEvent::EnergyChange {
change: EnergyChange { entity: attacker_entity,
amount: ec as i32, change: EnergyChange {
source: EnergySource::HitEnemy, amount: ec as i32,
}, source: EnergySource::HitEnemy,
}); },
});
}
}, },
AttackEffect::Buff(b) => { AttackEffect::Buff(b) => {
if thread_rng().gen::<f32>() < b.chance { if thread_rng().gen::<f32>() < b.chance {
@ -225,16 +229,16 @@ impl Attack {
} }
}, },
AttackEffect::Lifesteal(l) => { AttackEffect::Lifesteal(l) => {
let change = HealthChange { if let Some(attacker_entity) = attacker_entity {
amount: (accumulated_damage * l) as i32, let change = HealthChange {
cause: HealthSource::Heal { amount: (accumulated_damage * l) as i32,
by: Some(attacker_uid), cause: HealthSource::Heal { by: attacker_uid },
}, };
}; server_events.push(ServerEvent::Damage {
server_events.push(ServerEvent::Damage { entity: attacker_entity,
entity: attacker_entity, change,
change, });
}); }
}, },
AttackEffect::Poise(p) => { AttackEffect::Poise(p) => {
let change = PoiseChange::from_attack(p, target_inventory); let change = PoiseChange::from_attack(p, target_inventory);
@ -247,9 +251,7 @@ impl Attack {
AttackEffect::Heal(h) => { AttackEffect::Heal(h) => {
let change = HealthChange { let change = HealthChange {
amount: h as i32, amount: h as i32,
cause: HealthSource::Heal { cause: HealthSource::Heal { by: attacker_uid },
by: Some(attacker_uid),
},
}; };
server_events.push(ServerEvent::Damage { server_events.push(ServerEvent::Damage {
entity: target_entity, entity: target_entity,
@ -542,8 +544,13 @@ impl CombatBuffStrength {
} }
impl CombatBuff { impl CombatBuff {
fn to_buff(self, uid: Uid, damage: f32) -> Buff { fn to_buff(self, uid: Option<Uid>, damage: f32) -> Buff {
// TODO: Generate BufCategoryId vec (probably requires damage overhaul?) // TODO: Generate BufCategoryId vec (probably requires damage overhaul?)
let source = if let Some(uid) = uid {
BuffSource::Character { by: uid }
} else {
BuffSource::Unknown
};
Buff::new( Buff::new(
self.kind, self.kind,
BuffData::new( BuffData::new(
@ -551,7 +558,7 @@ impl CombatBuff {
Some(Duration::from_secs_f32(self.dur_secs)), Some(Duration::from_secs_f32(self.dur_secs)),
), ),
Vec::new(), Vec::new(),
BuffSource::Character { by: uid }, source,
) )
} }

View File

@ -168,26 +168,24 @@ impl<'a> System<'a> for Sys {
continue; continue;
} }
if let (Some(beam_owner), Some(owner_uid)) = (beam_owner, beam_segment.owner) { let server_events = beam_segment.properties.attack.apply_attack(
let server_events = beam_segment.properties.attack.apply_attack( target_group,
target_group, beam_owner,
beam_owner, b,
b, inventory_b_maybe,
inventory_b_maybe, beam_segment.owner,
owner_uid, beam_owner.and_then(|e| energies.get(e)),
energies.get(beam_owner), ori.0,
ori.0, false,
false, 1.0,
1.0, );
);
if !server_events.is_empty() { if !server_events.is_empty() {
hit_entities.push(*uid_b); hit_entities.push(*uid_b);
} }
for event in server_events { for event in server_events {
server_emitter.emit(event); server_emitter.emit(event);
}
} }
} }
} }

View File

@ -131,10 +131,10 @@ impl<'a> System<'a> for Sys {
let server_events = attack.attack.apply_attack( let server_events = attack.attack.apply_attack(
target_group, target_group,
entity, Some(entity),
b, b,
inventory_b_maybe, inventory_b_maybe,
*uid, Some(*uid),
energies.get(entity), energies.get(entity),
dir, dir,
is_dodge, is_dodge,

View File

@ -103,26 +103,26 @@ impl<'a> System<'a> for Sys {
for effect in projectile.hit_entity.drain(..) { for effect in projectile.hit_entity.drain(..) {
match effect { match effect {
projectile::Effect::Attack(attack) => { projectile::Effect::Attack(attack) => {
if let Some(owner) = projectile.owner { if let Some(target_entity) =
if let (Some(owner_entity), Some(target_entity)) = ( uid_allocator.retrieve_entity_internal(other.into())
uid_allocator.retrieve_entity_internal(owner.into()), {
uid_allocator.retrieve_entity_internal(other.into()), let owner_entity = projectile
) { .owner
let server_events = attack.apply_attack( .and_then(|u| uid_allocator.retrieve_entity_internal(u.into()));
target_group, let server_events = attack.apply_attack(
owner_entity, target_group,
target_entity, owner_entity,
inventories.get(target_entity), target_entity,
owner, inventories.get(target_entity),
energies.get(owner_entity), projectile.owner,
ori.0, owner_entity.and_then(|e| energies.get(e)),
false, ori.0,
1.0, false,
); 1.0,
);
for event in server_events { for event in server_events {
server_emitter.emit(event); server_emitter.emit(event);
}
} }
} }
}, },

View File

@ -70,9 +70,8 @@ impl<'a> System<'a> for Sys {
let dt = dt.0; let dt = dt.0;
// Shockwaves // Shockwaves
for (entity, uid, pos, ori, shockwave, shockwave_hit_list) in ( for (entity, pos, ori, shockwave, shockwave_hit_list) in (
&entities, &entities,
&uids,
&positions, &positions,
&orientations, &orientations,
&shockwaves, &shockwaves,
@ -198,10 +197,10 @@ impl<'a> System<'a> for Sys {
let server_events = shockwave.properties.attack.apply_attack( let server_events = shockwave.properties.attack.apply_attack(
target_group, target_group,
shockwave_owner.unwrap_or(entity), shockwave_owner,
b, b,
inventories.get(b), inventories.get(b),
shockwave.owner.unwrap_or(*uid), shockwave.owner,
shockwave_owner.and_then(|e| energies.get(e)), shockwave_owner.and_then(|e| energies.get(e)),
dir, dir,
false, false,

View File

@ -710,10 +710,10 @@ pub fn handle_explosion(
let server_events = attack.apply_attack( let server_events = attack.apply_attack(
target_group, target_group,
owner_entity.unwrap(), owner_entity,
entity_b, entity_b,
inventory_b_maybe, inventory_b_maybe,
owner.unwrap(), owner,
owner_entity.and_then(|e| energies.get(e)), owner_entity.and_then(|e| energies.get(e)),
dir, dir,
false, false,