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

View File

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

View File

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

View File

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

View File

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

View File

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