From f316f1da60ca161d491559dd4f4e611bc4516265 Mon Sep 17 00:00:00 2001 From: holychowders Date: Wed, 14 Jul 2021 07:40:43 +0000 Subject: [PATCH] Make Guards Defend Villagers --- common/src/comp/agent.rs | 2 + common/src/comp/health.rs | 10 + common/systems/src/beam.rs | 8 +- common/systems/src/projectile.rs | 8 +- common/systems/src/shockwave.rs | 8 +- server/src/events/entity_manipulation.rs | 8 +- server/src/sys/agent.rs | 572 +++++++++++------------ 7 files changed, 308 insertions(+), 308 deletions(-) diff --git a/common/src/comp/agent.rs b/common/src/comp/agent.rs index 07f23ab54a..b46e144636 100644 --- a/common/src/comp/agent.rs +++ b/common/src/comp/agent.rs @@ -301,6 +301,8 @@ pub enum SoundKind { Beam, Shockwave, Utterance(UtteranceKind, Body), + // TODO: unify VillagerAlarm with Utterance + VillagerAlarm, } #[derive(Clone, Debug)] diff --git a/common/src/comp/health.rs b/common/src/comp/health.rs index 3015a01f44..7f39648b34 100644 --- a/common/src/comp/health.rs +++ b/common/src/comp/health.rs @@ -34,6 +34,16 @@ pub enum HealthSource { Unknown, } +impl HealthSource { + pub fn damage_by(&self) -> Option { + if let HealthSource::Damage { by, .. } = self { + *by + } else { + None + } + } +} + #[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)] pub struct Health { current: u32, diff --git a/common/systems/src/beam.rs b/common/systems/src/beam.rs index c3373a3533..dae48525d2 100644 --- a/common/systems/src/beam.rs +++ b/common/systems/src/beam.rs @@ -91,6 +91,10 @@ impl<'a> System<'a> for Sys { }; let end_time = creation_time + beam_segment.duration.as_secs_f64(); + let beam_owner = beam_segment + .owner + .and_then(|uid| read_data.uid_allocator.retrieve_entity_internal(uid.into())); + let mut rng = thread_rng(); if rng.gen_bool(0.005) { server_events.push(ServerEvent::Sound { @@ -119,10 +123,6 @@ impl<'a> System<'a> for Sys { (beam_segment.speed * (time_since_creation - frame_time)).max(0.0); let frame_end_dist = (beam_segment.speed * time_since_creation).max(frame_start_dist); - let beam_owner = beam_segment - .owner - .and_then(|uid| read_data.uid_allocator.retrieve_entity_internal(uid.into())); - // Group to ignore collisions with // Might make this more nuanced if beams are used for non damage effects let group = beam_owner.and_then(|e| read_data.groups.get(e)); diff --git a/common/systems/src/projectile.rs b/common/systems/src/projectile.rs index a1bab8cd96..e9d7a5a3e8 100644 --- a/common/systems/src/projectile.rs +++ b/common/systems/src/projectile.rs @@ -72,6 +72,10 @@ impl<'a> System<'a> for Sys { ) .join() { + let projectile_owner = projectile + .owner + .and_then(|uid| read_data.uid_allocator.retrieve_entity_internal(uid.into())); + let mut rng = thread_rng(); if physics.on_surface().is_none() && rng.gen_bool(0.05) { server_emitter.emit(ServerEvent::Sound { @@ -83,12 +87,10 @@ impl<'a> System<'a> for Sys { // Hit entity for other in physics.touch_entities.iter().copied() { - let same_group = projectile - .owner + let same_group = projectile_owner // Note: somewhat inefficient since we do the lookup for every touching // entity, but if we pull this out of the loop we would want to do it only // if there is at least one touching entity - .and_then(|uid| read_data.uid_allocator.retrieve_entity_internal(uid.into())) .and_then(|e| read_data.groups.get(e)) .map_or(false, |owner_group| Some(owner_group) == read_data.uid_allocator diff --git a/common/systems/src/shockwave.rs b/common/systems/src/shockwave.rs index 88c1aaaba0..2997821811 100644 --- a/common/systems/src/shockwave.rs +++ b/common/systems/src/shockwave.rs @@ -85,6 +85,10 @@ impl<'a> System<'a> for Sys { let end_time = creation_time + shockwave.duration.as_secs_f64(); + let shockwave_owner = shockwave + .owner + .and_then(|uid| read_data.uid_allocator.retrieve_entity_internal(uid.into())); + let mut rng = thread_rng(); if rng.gen_bool(0.05) { server_emitter.emit(ServerEvent::Sound { @@ -120,10 +124,6 @@ impl<'a> System<'a> for Sys { end: frame_end_dist, }; - let shockwave_owner = shockwave - .owner - .and_then(|uid| read_data.uid_allocator.retrieve_entity_internal(uid.into())); - // Group to ignore collisions with // Might make this more nuanced if shockwaves are used for non damage effects let group = shockwave_owner.and_then(|e| read_data.groups.get(e)); diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs index 2cb6fe3fe0..345984e2a2 100644 --- a/server/src/events/entity_manipulation.rs +++ b/server/src/events/entity_manipulation.rs @@ -692,6 +692,10 @@ pub fn handle_explosion(server: &Server, pos: Vec3, explosion: Explosion, o let ecs = &server.state.ecs(); let server_eventbus = ecs.read_resource::>(); let time = ecs.read_resource::