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,56 +55,72 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
state.notify_registered_clients(comp::ChatType::Kill.server_msg(msg)); state.notify_registered_clients(comp::ChatType::Kill.server_msg(msg));
} }
{ // Give EXP to the killer if entity had stats
// Give EXP to the killer if entity had stats (|| {
let mut stats = state.ecs().write_storage::<Stats>(); let mut stats = state.ecs().write_storage::<Stats>();
if let Some(entity_stats) = stats.get(entity).cloned() { let by = if let HealthSource::Attack { by } | HealthSource::Projectile { owner: Some(by) } =
if let HealthSource::Attack { by } | HealthSource::Projectile { owner: Some(by) } = cause
cause {
{ by
const MAX_EXP_DIST: f32 = 150.0; } else {
// Attacker gets same as exp of everyone else return;
const ATTACKER_EXP_WEIGHT: f32 = 1.0; };
let mut exp_reward = (entity_stats.body_type.base_exp() let attacker = if let Some(attacker) = state.ecs().entity_from_uid(by.into()) {
+ entity_stats.level.level() * entity_stats.body_type.base_exp_increase()) attacker
as f32; } else {
state.ecs().entity_from_uid(by.into()).map(|attacker| { return;
// Distribute EXP to group };
let groups = state.ecs().read_storage::<Group>(); let entity_stats = if let Some(entity_stats) = stats.get(entity) {
let positions = state.ecs().read_storage::<Pos>(); entity_stats
// TODO: rework if change to groups makes it easier to iterate entities in a } else {
// group return;
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)| {
*group == attacker_group
&& *entity != attacker
&& pos.0.distance_squared(member_pos.0) < MAX_EXP_DIST.powi(2)
})
.map(|(entity, _, _)| entity)
.collect::<Vec<_>>();
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) {
stats.exp.change_by(exp.ceil() as i64);
}
});
}
if let Some(attacker_stats) = stats.get_mut(attacker) { let groups = state.ecs().read_storage::<Group>();
// TODO: Discuss whether we should give EXP by Player let attacker_group = groups.get(attacker);
// Killing or not. let destroyed_group = groups.get(entity);
attacker_stats.exp.change_by(exp_reward.ceil() as i64); // 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;
// Distribute EXP to 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
let members_in_range = (&state.ecs().entities(), &groups, &positions)
.join()
.filter(|(entity, group, member_pos)| {
*group == attacker_group
&& *entity != attacker
&& pos.0.distance_squared(member_pos.0) < MAX_EXP_DIST.powi(2)
})
.map(|(entity, _, _)| entity)
.collect::<Vec<_>>();
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) {
stats.exp.change_by(exp.ceil() as i64);
}
});
}
if let Some(attacker_stats) = stats.get_mut(attacker) {
// TODO: Discuss whether we should give EXP by Player
// Killing or not.
attacker_stats.exp.change_by(exp_reward.ceil() as i64);
}
})();
if state if state
.ecs() .ecs()