mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fix loot protection bugs
This fixes: - Giving loot protection to the entity to be destroyed instead of the one who killed it. - Checking the destroyed entity for non-humanoid body instead of the entity receiving loot when deciding whether loot protection should be given or not. - Incorrect assumption that NPC groups are tracked in the group manager when cleaning up loot protections.
This commit is contained in:
parent
d5522b0401
commit
68c53a7d1c
@ -532,3 +532,9 @@ impl GroupManager {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl Group {
|
||||
/// Returns whether this is one of the special npc or enemy groups
|
||||
// FIXME: These groups are a HACK
|
||||
pub fn is_special(&self) -> bool { *self == NPC || *self == ENEMY }
|
||||
}
|
||||
|
@ -592,13 +592,11 @@ impl ServerEvent for DestroyEvent {
|
||||
|
||||
false
|
||||
} else {
|
||||
if let Some((_agent, uid, pos, alignment, vel, body)) = (
|
||||
if let Some((_agent, pos, alignment, vel)) = (
|
||||
&data.agents,
|
||||
&data.uids,
|
||||
&data.positions,
|
||||
data.alignments.maybe(),
|
||||
data.velocities.maybe(),
|
||||
data.bodies.maybe(),
|
||||
)
|
||||
.lend_join()
|
||||
.get(ev.entity, &data.entities)
|
||||
@ -614,16 +612,16 @@ impl ServerEvent for DestroyEvent {
|
||||
// Remove entries where zero exp was awarded - this happens because some
|
||||
// entities like Object bodies don't give EXP.
|
||||
let mut item_receivers = HashMap::new();
|
||||
for (_entity, exp, group) in exp_awards {
|
||||
for (entity, exp, group) in exp_awards {
|
||||
if exp >= f32::EPSILON {
|
||||
let loot_owner = if let Some(group) = group {
|
||||
Some(LootOwnerKind::Group(group))
|
||||
} else {
|
||||
let uid = body.and_then(|body| {
|
||||
let uid = data.bodies.get(entity).and_then(|body| {
|
||||
// Only humanoids are awarded loot ownership - if the winner
|
||||
// was a non-humanoid NPC the loot will be free-for-all
|
||||
if matches!(body, Body::Humanoid(_)) {
|
||||
Some(*uid)
|
||||
data.uids.get(entity).copied()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -655,12 +653,14 @@ impl ServerEvent for DestroyEvent {
|
||||
);
|
||||
Some(LootOwner::new(loot_owner, false))
|
||||
} else {
|
||||
debug!("No loot owner");
|
||||
None
|
||||
},
|
||||
})
|
||||
};
|
||||
|
||||
if item_receivers.is_empty() {
|
||||
debug!("No item receivers");
|
||||
for item in flatten_counted_items(&items, &data.ability_map, &data.msm)
|
||||
{
|
||||
spawn_item(item, None)
|
||||
|
@ -35,7 +35,11 @@ impl<'a> System<'a> for Sys {
|
||||
LootOwnerKind::Player(uid) => id_maps
|
||||
.uid_entity(uid)
|
||||
.map_or(true, |entity| !entities.is_alive(entity)),
|
||||
LootOwnerKind::Group(group) => group_manager.group_info(group).is_none(),
|
||||
LootOwnerKind::Group(group) => {
|
||||
// Special alignment groups (NPC and ENEMY) aren't tracked by the group
|
||||
// manager, check them separately here
|
||||
!group.is_special() && group_manager.group_info(group).is_none()
|
||||
},
|
||||
}
|
||||
})
|
||||
.map(|(entity, _)| entity)
|
||||
|
Loading…
Reference in New Issue
Block a user