General NPC Hitbox Adjustments

This commit is contained in:
Scott Williams 2021-01-24 04:00:57 +00:00 committed by Samuel Keiffer
parent 82147653df
commit c7baf1fd86
4 changed files with 95 additions and 79 deletions

View File

@ -37,7 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Changed camera smoothing to be off by default. - Changed camera smoothing to be off by default.
- Fixed AI behavior so only humanoids will attempt to roll - Fixed AI behavior so only humanoids will attempt to roll
- Footstep SFX is now dependant on distance moved, not time since last play - Footstep SFX is now dependant on distance moved, not time since last play
- Increased the hitbox of the Stonework Defender and Mindflayer to better fit their models. - Adjusted most NPCs hitboxes to better fit their models.
### Removed ### Removed

View File

@ -141,49 +141,62 @@ impl Body {
// TODO: Improve these values (some might be reliant on more info in inner type) // TODO: Improve these values (some might be reliant on more info in inner type)
match self { match self {
Body::Humanoid(humanoid) => match (humanoid.species, humanoid.body_type) { Body::Humanoid(humanoid) => match (humanoid.species, humanoid.body_type) {
(humanoid::Species::Orc, humanoid::BodyType::Male) => 0.57, (humanoid::Species::Orc, humanoid::BodyType::Male) => 0.75,
(humanoid::Species::Orc, humanoid::BodyType::Female) => 0.51, (humanoid::Species::Orc, humanoid::BodyType::Female) => 0.75,
(humanoid::Species::Human, humanoid::BodyType::Male) => 0.51, (humanoid::Species::Human, humanoid::BodyType::Male) => 0.75,
(humanoid::Species::Human, humanoid::BodyType::Female) => 0.48, (humanoid::Species::Human, humanoid::BodyType::Female) => 0.75,
(humanoid::Species::Elf, humanoid::BodyType::Male) => 0.51, (humanoid::Species::Elf, humanoid::BodyType::Male) => 0.75,
(humanoid::Species::Elf, humanoid::BodyType::Female) => 0.48, (humanoid::Species::Elf, humanoid::BodyType::Female) => 0.75,
(humanoid::Species::Dwarf, humanoid::BodyType::Male) => 0.42, (humanoid::Species::Dwarf, humanoid::BodyType::Male) => 0.75,
(humanoid::Species::Dwarf, humanoid::BodyType::Female) => 0.39, (humanoid::Species::Dwarf, humanoid::BodyType::Female) => 0.75,
(humanoid::Species::Undead, humanoid::BodyType::Male) => 0.48, (humanoid::Species::Undead, humanoid::BodyType::Male) => 0.75,
(humanoid::Species::Undead, humanoid::BodyType::Female) => 0.45, (humanoid::Species::Undead, humanoid::BodyType::Female) => 0.75,
(humanoid::Species::Danari, humanoid::BodyType::Male) => 0.348, (humanoid::Species::Danari, humanoid::BodyType::Male) => 0.75,
(humanoid::Species::Danari, humanoid::BodyType::Female) => 0.348, (humanoid::Species::Danari, humanoid::BodyType::Female) => 0.75,
_ => 0.5, _ => 0.75,
}, },
Body::QuadrupedSmall(_) => 0.4, Body::QuadrupedSmall(_) => 0.7,
Body::QuadrupedMedium(body) => match body.species { Body::QuadrupedMedium(body) => match body.species {
quadruped_medium::Species::Grolgar => 1.9, quadruped_medium::Species::Grolgar => 2.0,
quadruped_medium::Species::Tarasque => 1.8, quadruped_medium::Species::Tarasque => 2.0,
quadruped_medium::Species::Lion => 1.9, quadruped_medium::Species::Lion => 2.0,
quadruped_medium::Species::Saber => 1.8, quadruped_medium::Species::Saber => 2.0,
quadruped_medium::Species::Catoblepas => 1.7, quadruped_medium::Species::Catoblepas => 2.0,
quadruped_medium::Species::Horse => 1.5,
quadruped_medium::Species::Deer => 1.5,
quadruped_medium::Species::Donkey => 1.5,
quadruped_medium::Species::Kelpie => 1.5,
_ => 1.5, _ => 1.5,
}, },
Body::QuadrupedLow(body) => match body.species { Body::QuadrupedLow(body) => match body.species {
quadruped_low::Species::Asp => 1.8, quadruped_low::Species::Asp => 2.5,
quadruped_low::Species::Monitor => 1.75, quadruped_low::Species::Monitor => 2.3,
quadruped_low::Species::Crocodile => 2.1, quadruped_low::Species::Crocodile => 2.4,
quadruped_low::Species::Salamander => 1.9, quadruped_low::Species::Salamander => 2.4,
quadruped_low::Species::Pangolin => 1.3, quadruped_low::Species::Pangolin => 2.0,
quadruped_low::Species::Lavadrake => 2.5,
_ => 1.6, _ => 1.6,
}, },
Body::Theropod(body) => match body.species { Body::Theropod(body) => match body.species {
theropod::Species::Snowraptor => 0.5, theropod::Species::Snowraptor => 1.5,
theropod::Species::Sandraptor => 0.5, theropod::Species::Sandraptor => 1.5,
theropod::Species::Woodraptor => 0.5, theropod::Species::Woodraptor => 1.5,
theropod::Species::Archaeos => 4.5,
theropod::Species::Odonto => 4.5,
_ => 1.8, _ => 1.8,
}, },
Body::BirdMedium(_) => 0.35, Body::BirdMedium(_) => 1.0,
Body::FishMedium(_) => 0.35, Body::FishMedium(_) => 1.0,
Body::Dragon(_) => 8.0, Body::Dragon(_) => 8.0,
Body::BirdSmall(_) => 0.3, Body::BirdSmall(_) => 0.6,
Body::FishSmall(_) => 0.3, Body::FishSmall(_) => 0.6,
Body::BipedLarge(_) => 1.5, Body::BipedLarge(body) => match body.species {
biped_large::Species::Slysaurok => 2.3,
biped_large::Species::Occultsaurok => 2.8,
biped_large::Species::Mightysaurok => 2.3,
biped_large::Species::Mindflayer => 1.8,
_ => 4.6,
},
Body::Golem(_) => 2.5, Body::Golem(_) => 2.5,
Body::Object(_) => 0.4, Body::Object(_) => 0.4,
} }
@ -192,18 +205,18 @@ impl Body {
pub fn height(&self) -> f32 { pub fn height(&self) -> f32 {
match self { match self {
Body::Humanoid(humanoid) => match (humanoid.species, humanoid.body_type) { Body::Humanoid(humanoid) => match (humanoid.species, humanoid.body_type) {
(humanoid::Species::Orc, humanoid::BodyType::Male) => 2.17, (humanoid::Species::Orc, humanoid::BodyType::Male) => 2.3,
(humanoid::Species::Orc, humanoid::BodyType::Female) => 1.94, (humanoid::Species::Orc, humanoid::BodyType::Female) => 2.2,
(humanoid::Species::Human, humanoid::BodyType::Male) => 1.94, (humanoid::Species::Human, humanoid::BodyType::Male) => 2.3,
(humanoid::Species::Human, humanoid::BodyType::Female) => 1.82, (humanoid::Species::Human, humanoid::BodyType::Female) => 2.2,
(humanoid::Species::Elf, humanoid::BodyType::Male) => 1.94, (humanoid::Species::Elf, humanoid::BodyType::Male) => 2.3,
(humanoid::Species::Elf, humanoid::BodyType::Female) => 1.82, (humanoid::Species::Elf, humanoid::BodyType::Female) => 2.2,
(humanoid::Species::Dwarf, humanoid::BodyType::Male) => 1.60, (humanoid::Species::Dwarf, humanoid::BodyType::Male) => 1.9,
(humanoid::Species::Dwarf, humanoid::BodyType::Female) => 1.48, (humanoid::Species::Dwarf, humanoid::BodyType::Female) => 1.8,
(humanoid::Species::Undead, humanoid::BodyType::Male) => 1.82, (humanoid::Species::Undead, humanoid::BodyType::Male) => 2.2,
(humanoid::Species::Undead, humanoid::BodyType::Female) => 1.71, (humanoid::Species::Undead, humanoid::BodyType::Female) => 2.1,
(humanoid::Species::Danari, humanoid::BodyType::Male) => 1.32, (humanoid::Species::Danari, humanoid::BodyType::Male) => 1.5,
(humanoid::Species::Danari, humanoid::BodyType::Female) => 1.32, (humanoid::Species::Danari, humanoid::BodyType::Female) => 1.4,
}, },
Body::QuadrupedSmall(body) => match body.species { Body::QuadrupedSmall(body) => match body.species {
quadruped_small::Species::Dodarock => 1.5, quadruped_small::Species::Dodarock => 1.5,
@ -212,10 +225,10 @@ impl Body {
_ => 1.0, _ => 1.0,
}, },
Body::QuadrupedMedium(body) => match body.species { Body::QuadrupedMedium(body) => match body.species {
quadruped_medium::Species::Tarasque => 2.5, quadruped_medium::Species::Tarasque => 2.6,
quadruped_medium::Species::Lion => 1.8, quadruped_medium::Species::Lion => 2.0,
quadruped_medium::Species::Saber => 1.8, quadruped_medium::Species::Saber => 2.0,
quadruped_medium::Species::Catoblepas => 2.8, quadruped_medium::Species::Catoblepas => 2.9,
_ => 1.6, _ => 1.6,
}, },
Body::QuadrupedLow(body) => match body.species { Body::QuadrupedLow(body) => match body.species {
@ -226,9 +239,9 @@ impl Body {
_ => 1.3, _ => 1.3,
}, },
Body::Theropod(body) => match body.species { Body::Theropod(body) => match body.species {
theropod::Species::Snowraptor => 2.5, theropod::Species::Snowraptor => 2.6,
theropod::Species::Sandraptor => 2.5, theropod::Species::Sandraptor => 2.6,
theropod::Species::Woodraptor => 2.5, theropod::Species::Woodraptor => 2.6,
_ => 8.0, _ => 8.0,
}, },
Body::BirdMedium(body) => match body.species { Body::BirdMedium(body) => match body.species {

View File

@ -199,12 +199,13 @@ impl<'a> System<'a> for Sys {
const LISTEN_DIST: f32 = 16.0; const LISTEN_DIST: f32 = 16.0;
const SEARCH_DIST: f32 = 48.0; const SEARCH_DIST: f32 = 48.0;
const SIGHT_DIST: f32 = 80.0; const SIGHT_DIST: f32 = 80.0;
const MIN_ATTACK_DIST: f32 = 2.0;
const MAX_FLEE_DIST: f32 = 20.0; const MAX_FLEE_DIST: f32 = 20.0;
const SNEAK_COEFFICIENT: f32 = 0.25; const SNEAK_COEFFICIENT: f32 = 0.25;
let scale = scales.get(entity).map(|s| s.0).unwrap_or(1.0); let scale = scales.get(entity).map(|s| s.0).unwrap_or(1.0);
let min_attack_dist = body.map_or(2.0, |b| b.radius() * scale * 1.5);
// This controls how picky NPCs are about their pathfinding. Giants are larger // This controls how picky NPCs are about their pathfinding. Giants are larger
// and so can afford to be less precise when trying to move around // and so can afford to be less precise when trying to move around
// the world (especially since they would otherwise get stuck on // the world (especially since they would otherwise get stuck on
@ -537,7 +538,7 @@ impl<'a> System<'a> for Sys {
// depending on the distance from the agent to the target // depending on the distance from the agent to the target
match tactic { match tactic {
Tactic::Melee => { Tactic::Melee => {
if dist_sqrd < (MIN_ATTACK_DIST * scale).powi(2) { if dist_sqrd < (min_attack_dist * scale).powi(2) {
inputs.primary.set_state(true); inputs.primary.set_state(true);
inputs.move_dir = Vec2::zero(); inputs.move_dir = Vec2::zero();
} else if dist_sqrd < MAX_CHASE_DIST.powi(2) } else if dist_sqrd < MAX_CHASE_DIST.powi(2)
@ -575,7 +576,7 @@ impl<'a> System<'a> for Sys {
} }
}, },
Tactic::Axe => { Tactic::Axe => {
if dist_sqrd < (MIN_ATTACK_DIST * scale).powi(2) { if dist_sqrd < (min_attack_dist * scale).powi(2) {
inputs.move_dir = Vec2::zero(); inputs.move_dir = Vec2::zero();
if *powerup > 6.0 { if *powerup > 6.0 {
inputs.secondary.set_state(false); inputs.secondary.set_state(false);
@ -624,7 +625,7 @@ impl<'a> System<'a> for Sys {
} }
}, },
Tactic::Hammer => { Tactic::Hammer => {
if dist_sqrd < (MIN_ATTACK_DIST * scale).powi(2) { if dist_sqrd < (min_attack_dist * scale).powi(2) {
inputs.move_dir = Vec2::zero(); inputs.move_dir = Vec2::zero();
if *powerup > 4.0 { if *powerup > 4.0 {
inputs.secondary.set_state(false); inputs.secondary.set_state(false);
@ -688,7 +689,7 @@ impl<'a> System<'a> for Sys {
} }
}, },
Tactic::Sword => { Tactic::Sword => {
if dist_sqrd < (MIN_ATTACK_DIST * scale).powi(2) { if dist_sqrd < (min_attack_dist * scale).powi(2) {
inputs.move_dir = Vec2::zero(); inputs.move_dir = Vec2::zero();
if stats.skill_set.has_skill(Skill::Sword(SwordSkill::UnlockSpin)) && *powerup < 2.0 && energy.current() > 600 { if stats.skill_set.has_skill(Skill::Sword(SwordSkill::UnlockSpin)) && *powerup < 2.0 && energy.current() > 600 {
inputs.ability3.set_state(true); inputs.ability3.set_state(true);
@ -747,7 +748,7 @@ impl<'a> System<'a> for Sys {
} }
}, },
Tactic::Bow => { Tactic::Bow => {
if body.map(|b| b.is_humanoid()).unwrap_or(false) && dist_sqrd < (2.0 * MIN_ATTACK_DIST * scale).powi(2) { if body.map(|b| b.is_humanoid()).unwrap_or(false) && dist_sqrd < (2.0 * min_attack_dist * scale).powi(2) {
inputs.roll.set_state(true); inputs.roll.set_state(true);
} else if dist_sqrd < MAX_CHASE_DIST.powi(2) } else if dist_sqrd < MAX_CHASE_DIST.powi(2)
|| (dist_sqrd < SIGHT_DIST.powi(2) && !*been_close) || (dist_sqrd < SIGHT_DIST.powi(2) && !*been_close)
@ -813,10 +814,10 @@ impl<'a> System<'a> for Sys {
} }
}, },
Tactic::Staff => { Tactic::Staff => {
if body.map(|b| b.is_humanoid()).unwrap_or(false) && dist_sqrd < (MIN_ATTACK_DIST * scale).powi(2) { if body.map(|b| b.is_humanoid()).unwrap_or(false) && dist_sqrd < (min_attack_dist * scale).powi(2) {
inputs.roll.set_state(true); inputs.roll.set_state(true);
} else if dist_sqrd } else if dist_sqrd
< (5.0 * MIN_ATTACK_DIST * scale).powi(2) < (5.0 * min_attack_dist * scale).powi(2)
{ {
if *powerup < 1.5 { if *powerup < 1.5 {
inputs.move_dir = (tgt_pos.0 - pos.0) inputs.move_dir = (tgt_pos.0 - pos.0)
@ -890,7 +891,7 @@ impl<'a> System<'a> for Sys {
} }
}, },
Tactic::StoneGolemBoss => { Tactic::StoneGolemBoss => {
if dist_sqrd < (MIN_ATTACK_DIST * scale * 2.0).powi(2) { // 2.0 is temporary correction factor to allow them to melee with their large hitbox if dist_sqrd < (min_attack_dist * scale).powi(2) {
inputs.move_dir = Vec2::zero(); inputs.move_dir = Vec2::zero();
inputs.primary.set_state(true); inputs.primary.set_state(true);
} else if dist_sqrd < MAX_CHASE_DIST.powi(2) } else if dist_sqrd < MAX_CHASE_DIST.powi(2)
@ -942,23 +943,23 @@ impl<'a> System<'a> for Sys {
radius, radius,
circle_time, circle_time,
} => { } => {
if dist_sqrd < (MIN_ATTACK_DIST * scale).powi(2) if dist_sqrd < (min_attack_dist * scale).powi(2)
&& thread_rng().gen_bool(0.5) && thread_rng().gen_bool(0.5)
{ {
inputs.move_dir = Vec2::zero(); inputs.move_dir = Vec2::zero();
inputs.primary.set_state(true); inputs.primary.set_state(true);
} else if dist_sqrd } else if dist_sqrd
< (radius as f32 * MIN_ATTACK_DIST * scale).powi(2) < (radius as f32 * min_attack_dist * scale).powi(2)
{ {
inputs.move_dir = (pos.0 - tgt_pos.0) inputs.move_dir = (pos.0 - tgt_pos.0)
.xy() .xy()
.try_normalized() .try_normalized()
.unwrap_or(Vec2::unit_y()); .unwrap_or(Vec2::unit_y());
} else if dist_sqrd } else if dist_sqrd
< ((radius as f32 + 1.0) * MIN_ATTACK_DIST * scale) < ((radius as f32 + 1.0) * min_attack_dist * scale)
.powi(2) .powi(2)
&& dist_sqrd && dist_sqrd
> (radius as f32 * MIN_ATTACK_DIST * scale).powi(2) > (radius as f32 * min_attack_dist * scale).powi(2)
{ {
if *powerup < circle_time as f32 { if *powerup < circle_time as f32 {
inputs.move_dir = (tgt_pos.0 - pos.0) inputs.move_dir = (tgt_pos.0 - pos.0)
@ -1012,7 +1013,7 @@ impl<'a> System<'a> for Sys {
} }
}, },
Tactic::QuadLowRanged => { Tactic::QuadLowRanged => {
if dist_sqrd < (5.0 * MIN_ATTACK_DIST * scale).powi(2) { if dist_sqrd < (5.0 * min_attack_dist * scale).powi(2) {
inputs.move_dir = (tgt_pos.0 - pos.0) inputs.move_dir = (tgt_pos.0 - pos.0)
.xy() .xy()
.try_normalized() .try_normalized()
@ -1074,7 +1075,7 @@ impl<'a> System<'a> for Sys {
} }
}, },
Tactic::TailSlap => { Tactic::TailSlap => {
if dist_sqrd < (1.5 * MIN_ATTACK_DIST * scale).powi(2) { if dist_sqrd < (1.5 * min_attack_dist * scale).powi(2) {
if *powerup > 4.0 { if *powerup > 4.0 {
inputs.primary.set_state(false); inputs.primary.set_state(false);
*powerup = 0.0; *powerup = 0.0;
@ -1119,12 +1120,12 @@ impl<'a> System<'a> for Sys {
} }
}, },
Tactic::QuadLowQuick => { Tactic::QuadLowQuick => {
if dist_sqrd < (1.5 * MIN_ATTACK_DIST * scale).powi(2) { if dist_sqrd < (1.5 * min_attack_dist * scale).powi(2) {
inputs.move_dir = Vec2::zero(); inputs.move_dir = Vec2::zero();
inputs.secondary.set_state(true); inputs.secondary.set_state(true);
} else if dist_sqrd } else if dist_sqrd
< (3.0 * MIN_ATTACK_DIST * scale).powi(2) < (3.0 * min_attack_dist * scale).powi(2)
&& dist_sqrd > (2.0 * MIN_ATTACK_DIST * scale).powi(2) && dist_sqrd > (2.0 * min_attack_dist * scale).powi(2)
{ {
inputs.primary.set_state(true); inputs.primary.set_state(true);
inputs.move_dir = (tgt_pos.0 - pos.0) inputs.move_dir = (tgt_pos.0 - pos.0)
@ -1161,7 +1162,7 @@ impl<'a> System<'a> for Sys {
} }
}, },
Tactic::QuadLowBasic => { Tactic::QuadLowBasic => {
if dist_sqrd < (1.5 * MIN_ATTACK_DIST * scale).powi(2) { if dist_sqrd < (1.5 * min_attack_dist * scale).powi(2) {
inputs.move_dir = Vec2::zero(); inputs.move_dir = Vec2::zero();
if *powerup > 5.0 { if *powerup > 5.0 {
*powerup = 0.0; *powerup = 0.0;
@ -1201,11 +1202,11 @@ impl<'a> System<'a> for Sys {
} }
}, },
Tactic::QuadMedJump => { Tactic::QuadMedJump => {
if dist_sqrd < (1.5 * MIN_ATTACK_DIST * scale).powi(2) { if dist_sqrd < (1.5 * min_attack_dist * scale).powi(2) {
inputs.move_dir = Vec2::zero(); inputs.move_dir = Vec2::zero();
inputs.secondary.set_state(true); inputs.secondary.set_state(true);
} else if dist_sqrd } else if dist_sqrd
< (5.0 * MIN_ATTACK_DIST * scale).powi(2) < (5.0 * min_attack_dist * scale).powi(2)
{ {
inputs.ability3.set_state(true); inputs.ability3.set_state(true);
} else if dist_sqrd < MAX_CHASE_DIST.powi(2) } else if dist_sqrd < MAX_CHASE_DIST.powi(2)
@ -1246,7 +1247,7 @@ impl<'a> System<'a> for Sys {
} }
}, },
Tactic::QuadMedBasic => { Tactic::QuadMedBasic => {
if dist_sqrd < (MIN_ATTACK_DIST * scale).powi(2) { if dist_sqrd < (min_attack_dist * scale).powi(2) {
inputs.move_dir = Vec2::zero(); inputs.move_dir = Vec2::zero();
if *powerup < 2.0 { if *powerup < 2.0 {
inputs.secondary.set_state(true); inputs.secondary.set_state(true);
@ -1286,11 +1287,11 @@ impl<'a> System<'a> for Sys {
} }
}, },
Tactic::Lavadrake => { Tactic::Lavadrake => {
if dist_sqrd < (2.5 * MIN_ATTACK_DIST * scale).powi(2) { if dist_sqrd < (2.5 * min_attack_dist * scale).powi(2) {
inputs.move_dir = Vec2::zero(); inputs.move_dir = Vec2::zero();
inputs.secondary.set_state(true); inputs.secondary.set_state(true);
} else if dist_sqrd } else if dist_sqrd
< (7.0 * MIN_ATTACK_DIST * scale).powi(2) < (7.0 * min_attack_dist * scale).powi(2)
{ {
if *powerup < 2.0 { if *powerup < 2.0 {
inputs.move_dir = (tgt_pos.0 - pos.0) inputs.move_dir = (tgt_pos.0 - pos.0)
@ -1343,7 +1344,7 @@ impl<'a> System<'a> for Sys {
} }
}, },
Tactic::Theropod => { Tactic::Theropod => {
if dist_sqrd < (2.0 * MIN_ATTACK_DIST * scale).powi(2) { if dist_sqrd < (2.0 * min_attack_dist * scale).powi(2) {
inputs.move_dir = Vec2::zero(); inputs.move_dir = Vec2::zero();
inputs.primary.set_state(true); inputs.primary.set_state(true);
} else if dist_sqrd < MAX_CHASE_DIST.powi(2) } else if dist_sqrd < MAX_CHASE_DIST.powi(2)

View File

@ -58,13 +58,14 @@ impl<'a> System<'a> for Sys {
let mut server_emitter = server_bus.emitter(); let mut server_emitter = server_bus.emitter();
let _local_emitter = local_bus.emitter(); let _local_emitter = local_bus.emitter();
// Attacks // Attacks
for (entity, uid, pos, ori, scale_maybe, attack) in ( for (entity, uid, pos, ori, scale_maybe, attack, body) in (
&entities, &entities,
&uids, &uids,
&positions, &positions,
&orientations, &orientations,
scales.maybe(), scales.maybe(),
&mut attacking_storage, &mut attacking_storage,
&bodies,
) )
.join() .join()
{ {
@ -92,6 +93,7 @@ impl<'a> System<'a> for Sys {
// Scales // Scales
let scale = scale_maybe.map_or(1.0, |s| s.0); let scale = scale_maybe.map_or(1.0, |s| s.0);
let scale_b = scale_b_maybe.map_or(1.0, |s| s.0); let scale_b = scale_b_maybe.map_or(1.0, |s| s.0);
let rad = body.radius() * scale;
let rad_b = body_b.radius() * scale_b; let rad_b = body_b.radius() * scale_b;
// Check if entity is dodging // Check if entity is dodging
@ -101,7 +103,7 @@ impl<'a> System<'a> for Sys {
if entity != b if entity != b
&& !health_b.is_dead && !health_b.is_dead
// Spherical wedge shaped attack field // Spherical wedge shaped attack field
&& pos.0.distance_squared(pos_b.0) < (rad_b + scale * attack.range).powi(2) && pos.0.distance_squared(pos_b.0) < (rad + rad_b + scale * attack.range).powi(2)
&& ori2.angle_between(pos_b2 - pos2) < attack.max_angle + (rad_b / pos2.distance(pos_b2)).atan() && ori2.angle_between(pos_b2 - pos2) < attack.max_angle + (rad_b / pos2.distance(pos_b2)).atan()
{ {
// See if entities are in the same group // See if entities are in the same group