Projectiles ignore entities in the same group, pets no longer follow group leader

This commit is contained in:
Imbris 2020-08-03 17:54:33 -04:00 committed by Monty Marz
parent 3da7e27a7c
commit 543d971a19
3 changed files with 50 additions and 33 deletions

View File

@ -113,13 +113,17 @@ impl<'a> System<'a> for Sys {
.join()
{
// Hack, replace with better system when groups are more sophisticated
// Override alignment if in a group
let alignment = group
.and_then(|g| group_manager.group_info(*g))
.and_then(|info| uids.get(info.leader))
.copied()
.map(Alignment::Owned)
.or(alignment.copied());
// Override alignment if in a group unless entity is owned already
let alignment = if !matches!(alignment, Some(Alignment::Owned(_))) {
group
.and_then(|g| group_manager.group_info(*g))
.and_then(|info| uids.get(info.leader))
.copied()
.map(Alignment::Owned)
.or(alignment.copied())
} else {
alignment.copied()
};
// Skip mounted entities
if mount_state

View File

@ -1,12 +1,17 @@
use crate::{
comp::{Collider, Gravity, Mass, Mounting, Ori, PhysicsState, Pos, Scale, Sticky, Vel},
comp::{
Collider, Gravity, Group, Mass, Mounting, Ori, PhysicsState, Pos, Projectile, Scale,
Sticky, Vel,
},
event::{EventBus, ServerEvent},
state::DeltaTime,
sync::Uid,
sync::{Uid, UidAllocator},
terrain::{Block, BlockKind, TerrainGrid},
vol::ReadVol,
};
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage};
use specs::{
saveload::MarkerAllocator, Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage,
};
use vek::*;
pub const GRAVITY: f32 = 9.81 * 5.0;
@ -44,6 +49,7 @@ impl<'a> System<'a> for Sys {
ReadStorage<'a, Uid>,
ReadExpect<'a, TerrainGrid>,
Read<'a, DeltaTime>,
Read<'a, UidAllocator>,
Read<'a, EventBus<ServerEvent>>,
ReadStorage<'a, Scale>,
ReadStorage<'a, Sticky>,
@ -55,6 +61,8 @@ impl<'a> System<'a> for Sys {
WriteStorage<'a, Vel>,
WriteStorage<'a, Ori>,
ReadStorage<'a, Mounting>,
ReadStorage<'a, Group>,
ReadStorage<'a, Projectile>,
);
#[allow(clippy::or_fun_call)] // TODO: Pending review in #587
@ -66,6 +74,7 @@ impl<'a> System<'a> for Sys {
uids,
terrain,
dt,
uid_allocator,
event_bus,
scales,
stickies,
@ -77,6 +86,8 @@ impl<'a> System<'a> for Sys {
mut velocities,
mut orientations,
mountings,
groups,
projectiles,
): Self::SystemData,
) {
let mut event_emitter = event_bus.emitter();
@ -432,7 +443,7 @@ impl<'a> System<'a> for Sys {
}
// Apply pushback
for (pos, scale, mass, vel, _, _, _, physics) in (
for (pos, scale, mass, vel, _, _, _, physics, projectile) in (
&positions,
scales.maybe(),
masses.maybe(),
@ -441,9 +452,12 @@ impl<'a> System<'a> for Sys {
!&mountings,
stickies.maybe(),
&mut physics_states,
// TODO: if we need to avoid collisions for other things consider moving whether it
// should interact into the collider component or into a separate component
projectiles.maybe(),
)
.join()
.filter(|(_, _, _, _, _, _, sticky, physics)| {
.filter(|(_, _, _, _, _, _, sticky, physics, _)| {
sticky.is_none() || (physics.on_wall.is_none() && !physics.on_ground)
})
{
@ -452,16 +466,27 @@ impl<'a> System<'a> for Sys {
let scale = scale.map(|s| s.0).unwrap_or(1.0);
let mass = mass.map(|m| m.0).unwrap_or(scale);
for (other, pos_other, scale_other, mass_other, _, _) in (
// Group to ignore collisions with
let ignore_group = projectile
.and_then(|p| p.owner)
.and_then(|uid| uid_allocator.retrieve_entity_internal(uid.into()))
.and_then(|e| groups.get(e));
for (other, pos_other, scale_other, mass_other, _, _, group) in (
&uids,
&positions,
scales.maybe(),
masses.maybe(),
&colliders,
!&mountings,
groups.maybe(),
)
.join()
{
if ignore_group.is_some() && ignore_group == group {
continue;
}
let scale_other = scale_other.map(|s| s.0).unwrap_or(1.0);
let mass_other = mass_other.map(|m| m.0).unwrap_or(scale_other);

View File

@ -1,7 +1,7 @@
use crate::{
comp::{
projectile, Alignment, Damage, DamageSource, Energy, EnergySource, HealthChange,
HealthSource, Loadout, Ori, PhysicsState, Pos, Projectile, Vel,
projectile, Damage, DamageSource, Energy, EnergySource, HealthChange, HealthSource,
Loadout, Ori, PhysicsState, Pos, Projectile, Vel,
},
event::{EventBus, LocalEvent, ServerEvent},
state::DeltaTime,
@ -28,7 +28,6 @@ impl<'a> System<'a> for Sys {
WriteStorage<'a, Ori>,
WriteStorage<'a, Projectile>,
WriteStorage<'a, Energy>,
ReadStorage<'a, Alignment>,
ReadStorage<'a, Loadout>,
);
@ -46,7 +45,6 @@ impl<'a> System<'a> for Sys {
mut orientations,
mut projectiles,
mut energies,
alignments,
loadouts,
): Self::SystemData,
) {
@ -92,23 +90,13 @@ impl<'a> System<'a> for Sys {
healthchange: healthchange as f32,
source: DamageSource::Projectile,
};
if let Some(entity) =
uid_allocator.retrieve_entity_internal(other.into())
{
if let Some(loadout) = loadouts.get(entity) {
damage.modify_damage(false, loadout);
}
let other_entity = uid_allocator.retrieve_entity_internal(other.into());
if let Some(loadout) = other_entity.and_then(|e| loadouts.get(e)) {
damage.modify_damage(false, loadout);
}
// Hacky: remove this when groups get implemented
let passive = uid_allocator
.retrieve_entity_internal(other.into())
.and_then(|other| {
alignments
.get(other)
.map(|a| Alignment::Owned(owner_uid).passive_towards(*a))
})
.unwrap_or(false);
if other != projectile.owner.unwrap() && !passive {
if other != owner_uid {
server_emitter.emit(ServerEvent::Damage {
uid: other,
change: HealthChange {