Enemies are moved along navmesh paths without collision, so a wall only stops
them if their path stops at it. dpWorld now keeps a list of such walls, each
with the collision filter it blocks with, and cuts a path where it first walks
into one (a little short of the wall; a mover inside one can walk out).
Which objects block comes from data (dpMovementBlockers::BlockingFilter):
- navmesh carvers (navmesh_carver in the level config, which the client reads
with add_to_navmesh and carver_only) block every mover;
- solid objects whose collision group touches enemies and not players (group 18,
e.g. "FV - Enemy Blocking Volume", "PR - Pet Blocker") block what that group
touches.
dpShapeBox gains SegmentEntry, a segment test against the rotated box.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The ActivatePhysics trigger command was a TODO. The client activates or
deactivates the object's physics component
(LWOPhysicsSystemComponent::msgActivatePhysics, 1.10.64 0x00ccf970);
the server now does the same to phantom physics: switching it off takes
the volume out of the physics world (dpWorld::DetachEntity, without
deleting it) and makes whatever was inside leave, switching it on adds
it back and whatever is inside enters on the next step. This lets
trigger driven volumes like the monument lasers turn on and off.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Volumes on the server touched far more than in the client:
- An enemy's body in the physics world was a sphere the size of its aggro
radius, so trigger and damage volumes caught enemies from far away
(Cavalry Hill enemies taking damage on spawn). It is now the enemy's
own radius and collision group from its physics component.
- Trigger volumes ignored their collision group and caught everything.
dpEntity now filters with the client's collision filter
(PeCollisionFilter, 1.10.64 0x00fb6940, group table from 0x00fcf9a0):
POI walls ignore enemies, threat clearing walls ignore players, and
so on. The aggro sensor keeps seeing only players.
- Rotated boxes were tested as the axis aligned box around them, which
for a turned wall covers a big square (the AG survival boundary).
Sphere and point tests now use the box's own axes.
Proximity monitors take an optional collision group like live's
SetProximityRadius; the AM shield generators use live's (10 finds
enemies, 1 finds players).
Fixes#1127
Refs #1971
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore: Remove dpEntity pointers from collision checking
* Update fn documentation in ProximityMonitorComponent.h
* use more idiomatic method to calculate vector index
* feedback
* missed a ranges::find replacement
* adjust for feedback. last changes tonight.
* okay, also remove unneeded include. then sleep.
* for real tho
* update to use unordered_set instead of set