Don't give exp when killing self or group members

This commit is contained in:
Imbris 2020-07-31 00:30:17 -04:00 committed by Monty Marz
parent 1d69e85a50
commit ecf6a84b2f

View File

@ -55,28 +55,48 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
state.notify_registered_clients(comp::ChatType::Kill.server_msg(msg));
}
{
// Give EXP to the killer if entity had stats
(|| {
let mut stats = state.ecs().write_storage::<Stats>();
if let Some(entity_stats) = stats.get(entity).cloned() {
if let HealthSource::Attack { by } | HealthSource::Projectile { owner: Some(by) } =
let by = if let HealthSource::Attack { by } | HealthSource::Projectile { owner: Some(by) } =
cause
{
by
} else {
return;
};
let attacker = if let Some(attacker) = state.ecs().entity_from_uid(by.into()) {
attacker
} else {
return;
};
let entity_stats = if let Some(entity_stats) = stats.get(entity) {
entity_stats
} else {
return;
};
let groups = state.ecs().read_storage::<Group>();
let attacker_group = groups.get(attacker);
let destroyed_group = groups.get(entity);
// Don't give exp if attacker destroyed themselves or one of their group members
if (attacker_group.is_some() && attacker_group == destroyed_group) || attacker == entity {
return;
}
// Maximum distance for other group members to receive exp
const MAX_EXP_DIST: f32 = 150.0;
// Attacker gets same as exp of everyone else
const ATTACKER_EXP_WEIGHT: f32 = 1.0;
let mut exp_reward = (entity_stats.body_type.base_exp()
+ entity_stats.level.level() * entity_stats.body_type.base_exp_increase())
as f32;
state.ecs().entity_from_uid(by.into()).map(|attacker| {
// Distribute EXP to group
let groups = state.ecs().read_storage::<Group>();
let positions = state.ecs().read_storage::<Pos>();
if let (Some(attacker_group), Some(pos)) = (attacker_group, positions.get(entity)) {
// TODO: rework if change to groups makes it easier to iterate entities in a
// group
if let (Some(attacker_group), Some(pos)) =
(groups.get(attacker), positions.get(entity))
{
let members_in_range = (&state.ecs().entities(), &groups, &positions)
.join()
.filter(|(entity, group, member_pos)| {
@ -86,8 +106,7 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
})
.map(|(entity, _, _)| entity)
.collect::<Vec<_>>();
let exp =
exp_reward / (members_in_range.len() as f32 + ATTACKER_EXP_WEIGHT);
let exp = exp_reward / (members_in_range.len() as f32 + ATTACKER_EXP_WEIGHT);
exp_reward = exp * ATTACKER_EXP_WEIGHT;
members_in_range.into_iter().for_each(|e| {
if let Some(stats) = stats.get_mut(e) {
@ -101,10 +120,7 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
// Killing or not.
attacker_stats.exp.change_by(exp_reward.ceil() as i64);
}
});
}
}
}
})();
if state
.ecs()