Remove pets from the group exp division calculation but still give them exp, fix bug with group code when pets are deleted

This commit is contained in:
Imbris 2020-08-06 23:53:19 -04:00 committed by Monty Marz
parent 390d289d35
commit af8560ea36
2 changed files with 40 additions and 13 deletions
common/src/comp
server/src/events

@ -462,10 +462,21 @@ impl GroupManager {
}
if let Some(info) = self.group_info_mut(group) {
info.num_members -= 1;
// If not pet, decrement number of members
if !matches!(alignments.get(member), Some(Alignment::Owned(owner)) if uids.get(member).map_or(true, |uid| uid != owner))
{
if info.num_members > 0 {
info.num_members -= 1;
} else {
error!("Group with invalid number of members")
}
}
let mut remaining_count = 0; // includes pets
// Inform remaining members
members(group, &*groups, entities, alignments, uids).for_each(
|(e, role)| match role {
members(group, &*groups, entities, alignments, uids).for_each(|(e, role)| {
remaining_count += 1;
match role {
Role::Member => {
notifier(e, ChangeNotification::Removed(member));
leaving_pets.iter().for_each(|p| {
@ -473,16 +484,16 @@ impl GroupManager {
})
},
Role::Pet => {},
},
);
}
});
// If leader is the last one left then disband the group
// Assumes last member is the leader
if info.num_members == 1 {
if remaining_count == 1 {
let leader = info.leader;
self.remove_group(group);
groups.remove(leader);
notifier(leader, ChangeNotification::NoGroup);
} else if info.num_members == 0 {
} else if remaining_count == 0 {
error!("Somehow group has no members")
}
}

@ -2,8 +2,8 @@ use crate::{client::Client, Server, SpawnPoint, StateExt};
use common::{
assets,
comp::{
self, item::lottery::Lottery, object, Body, Damage, DamageSource, Group, HealthChange,
HealthSource, Player, Pos, Stats,
self, item::lottery::Lottery, object, Alignment, Body, Damage, DamageSource, Group,
HealthChange, HealthSource, Player, Pos, Stats,
},
msg::{PlayerListUpdate, ServerMsg},
state::BlockChange,
@ -94,19 +94,35 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
// Distribute EXP to group
let positions = state.ecs().read_storage::<Pos>();
let alignments = state.ecs().read_storage::<Alignment>();
let uids = state.ecs().read_storage::<Uid>();
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)
let mut num_not_pets_in_range = 0;
let members_in_range = (
&state.ecs().entities(),
&groups,
&positions,
alignments.maybe(),
&uids,
)
.join()
.filter(|(entity, group, member_pos)| {
.filter(|(entity, group, member_pos, _, _)| {
// Check if: in group, not main attacker, and in range
*group == attacker_group
&& *entity != attacker
&& pos.0.distance_squared(member_pos.0) < MAX_EXP_DIST.powi(2)
})
.map(|(entity, _, _)| entity)
.map(|(entity, _, _, alignment, uid)| {
if !matches!(alignment, Some(Alignment::Owned(owner)) if owner != uid) {
num_not_pets_in_range += 1;
}
entity
})
.collect::<Vec<_>>();
let exp = exp_reward / (members_in_range.len() as f32 + ATTACKER_EXP_WEIGHT);
let exp = exp_reward / (num_not_pets_in_range 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) {