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

View File

@ -1,12 +1,17 @@
use crate::{ 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}, event::{EventBus, ServerEvent},
state::DeltaTime, state::DeltaTime,
sync::Uid, sync::{Uid, UidAllocator},
terrain::{Block, BlockKind, TerrainGrid}, terrain::{Block, BlockKind, TerrainGrid},
vol::ReadVol, vol::ReadVol,
}; };
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage}; use specs::{
saveload::MarkerAllocator, Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage,
};
use vek::*; use vek::*;
pub const GRAVITY: f32 = 9.81 * 5.0; pub const GRAVITY: f32 = 9.81 * 5.0;
@ -44,6 +49,7 @@ impl<'a> System<'a> for Sys {
ReadStorage<'a, Uid>, ReadStorage<'a, Uid>,
ReadExpect<'a, TerrainGrid>, ReadExpect<'a, TerrainGrid>,
Read<'a, DeltaTime>, Read<'a, DeltaTime>,
Read<'a, UidAllocator>,
Read<'a, EventBus<ServerEvent>>, Read<'a, EventBus<ServerEvent>>,
ReadStorage<'a, Scale>, ReadStorage<'a, Scale>,
ReadStorage<'a, Sticky>, ReadStorage<'a, Sticky>,
@ -55,6 +61,8 @@ impl<'a> System<'a> for Sys {
WriteStorage<'a, Vel>, WriteStorage<'a, Vel>,
WriteStorage<'a, Ori>, WriteStorage<'a, Ori>,
ReadStorage<'a, Mounting>, ReadStorage<'a, Mounting>,
ReadStorage<'a, Group>,
ReadStorage<'a, Projectile>,
); );
#[allow(clippy::or_fun_call)] // TODO: Pending review in #587 #[allow(clippy::or_fun_call)] // TODO: Pending review in #587
@ -66,6 +74,7 @@ impl<'a> System<'a> for Sys {
uids, uids,
terrain, terrain,
dt, dt,
uid_allocator,
event_bus, event_bus,
scales, scales,
stickies, stickies,
@ -77,6 +86,8 @@ impl<'a> System<'a> for Sys {
mut velocities, mut velocities,
mut orientations, mut orientations,
mountings, mountings,
groups,
projectiles,
): Self::SystemData, ): Self::SystemData,
) { ) {
let mut event_emitter = event_bus.emitter(); let mut event_emitter = event_bus.emitter();
@ -432,7 +443,7 @@ impl<'a> System<'a> for Sys {
} }
// Apply pushback // Apply pushback
for (pos, scale, mass, vel, _, _, _, physics) in ( for (pos, scale, mass, vel, _, _, _, physics, projectile) in (
&positions, &positions,
scales.maybe(), scales.maybe(),
masses.maybe(), masses.maybe(),
@ -441,9 +452,12 @@ impl<'a> System<'a> for Sys {
!&mountings, !&mountings,
stickies.maybe(), stickies.maybe(),
&mut physics_states, &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() .join()
.filter(|(_, _, _, _, _, _, sticky, physics)| { .filter(|(_, _, _, _, _, _, sticky, physics, _)| {
sticky.is_none() || (physics.on_wall.is_none() && !physics.on_ground) 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 scale = scale.map(|s| s.0).unwrap_or(1.0);
let mass = mass.map(|m| m.0).unwrap_or(scale); 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, &uids,
&positions, &positions,
scales.maybe(), scales.maybe(),
masses.maybe(), masses.maybe(),
&colliders, &colliders,
!&mountings, !&mountings,
groups.maybe(),
) )
.join() .join()
{ {
if ignore_group.is_some() && ignore_group == group {
continue;
}
let scale_other = scale_other.map(|s| s.0).unwrap_or(1.0); 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); let mass_other = mass_other.map(|m| m.0).unwrap_or(scale_other);

View File

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