fix: buggy hitboxes during ag foot race (#1993)

* physics fixes

* check ptr
This commit is contained in:
David Markowitz
2026-06-11 07:12:31 -07:00
committed by GitHub
parent 707880b5fc
commit e5b8e5c6b7
3 changed files with 53 additions and 26 deletions

View File

@@ -4,6 +4,8 @@
#include "ControllablePhysicsComponent.h" #include "ControllablePhysicsComponent.h"
#include "EntityManager.h" #include "EntityManager.h"
#include "SimplePhysicsComponent.h" #include "SimplePhysicsComponent.h"
#include "Amf3.h"
#include "dpShapeSphere.h"
const std::unordered_set<LWOOBJID> ProximityMonitorComponent::m_EmptyObjectSet = {}; const std::unordered_set<LWOOBJID> ProximityMonitorComponent::m_EmptyObjectSet = {};
@@ -12,6 +14,7 @@ ProximityMonitorComponent::ProximityMonitorComponent(Entity* parent, const int32
SetProximityRadius(radiusSmall, "rocketSmall"); SetProximityRadius(radiusSmall, "rocketSmall");
SetProximityRadius(radiusLarge, "rocketLarge"); SetProximityRadius(radiusLarge, "rocketLarge");
} }
RegisterMsg(&ProximityMonitorComponent::OnGetObjectReportInfo);
} }
ProximityMonitorComponent::~ProximityMonitorComponent() { ProximityMonitorComponent::~ProximityMonitorComponent() {
@@ -60,6 +63,31 @@ bool ProximityMonitorComponent::IsInProximity(const std::string& name, LWOOBJID
return collisions.contains(objectID); return collisions.contains(objectID);
} }
bool ProximityMonitorComponent::OnGetObjectReportInfo(GameMessages::GetObjectReportInfo& reportInfo) {
auto& proxInfo = reportInfo.info->PushDebug("Proximity Monitor");
for (const auto& [name, entity] : m_ProximitiesData) {
if (!entity) continue;
auto& proxAmf = proxInfo.PushDebug(name);
const auto* const shape = entity->GetShape();
if (shape && shape->GetShapeType() == dpShapeType::Sphere) {
const auto* const sphere = static_cast<const dpShapeSphere*>(shape);
proxAmf.PushDebug<AMFDoubleValue>("Radius") = sphere->GetRadius();
}
proxAmf.PushDebug<AMFBoolValue>("Sleeping") = entity->GetSleeping();
proxAmf.PushDebug<AMFDoubleValue>("Scale") = entity->GetScale();
proxAmf.PushDebug<AMFBoolValue>("Gargantuan") = entity->GetIsGargantuan();
proxAmf.PushDebug<AMFBoolValue>("Static") = entity->GetIsStatic();
proxAmf.PushDebug("Position").PushDebug(entity->GetPosition());
proxAmf.PushDebug("Rotation").PushDebug(entity->GetRotation());
auto& collidingAmf = proxAmf.PushDebug("Colliding Objects");
for (const auto& colliding : entity->GetCurrentlyCollidingObjects()) {
collidingAmf.PushDebug(std::to_string(colliding));
}
}
return true;
}
void ProximityMonitorComponent::Update(float deltaTime) { void ProximityMonitorComponent::Update(float deltaTime) {
for (const auto& prox : m_ProximitiesData) { for (const auto& prox : m_ProximitiesData) {
if (!prox.second) continue; if (!prox.second) continue;

View File

@@ -64,6 +64,7 @@ public:
private: private:
bool OnGetObjectReportInfo(GameMessages::GetObjectReportInfo& reportInfo);
/** /**
* All the proximity sensors for this component, indexed by name * All the proximity sensors for this component, indexed by name
*/ */

View File

@@ -2,6 +2,7 @@
#include "dpEntity.h" #include "dpEntity.h"
#include <cmath> #include <cmath>
#include <ranges>
dpGrid::dpGrid(int numCells, int cellSize) { dpGrid::dpGrid(int numCells, int cellSize) {
NUM_CELLS = numCells; NUM_CELLS = numCells;
@@ -122,38 +123,35 @@ void dpGrid::HandleEntity(dpEntity* entity, dpEntity* other) {
void dpGrid::HandleCell(int x, int z, float deltaTime) { void dpGrid::HandleCell(int x, int z, float deltaTime) {
auto& entities = m_Cells[x][z]; //vector of entities contained within this cell. auto& entities = m_Cells[x][z]; //vector of entities contained within this cell.
for (auto en : entities) { for (auto* en : entities) {
if (!en) continue; if (!en) continue;
if (en->GetIsStatic() || en->GetSleeping()) continue; if (en->GetIsStatic() || en->GetSleeping()) continue;
//Check against all entities that are in the same cell as us //Check against all entities that are in the same cell as us
for (auto other : entities) for (auto other : entities) HandleEntity(en, other);
HandleEntity(en, other);
//To try neighbouring cells as well: (can be disabled if needed) // All 8 neighbours in one pass.
//we only check 4 of the 8 neighbouring cells, otherwise we'd get duplicates and cpu cycles wasted... // staticOnly=false — canonical 4: covers each dynamic-vs-dynamic pair exactly once,
// since the higher-index cell checks back to the lower-index cell.
if (x > 0 && z > 0) { // staticOnly=true — skipped 4: dynamic entities there are handled when those cells
for (auto other : m_Cells[x - 1][z - 1]) // process their own en loop; static ones never drive a loop, so
HandleEntity(en, other); // we handle them here explicitly to avoid missing exits.
struct NeighbourCheck { int dx, dz; bool staticOnly; };
constexpr NeighbourCheck kNeighbours[8] = {
{ -1, -1, false }, { -1, 0, false }, { 0, -1, false }, { -1, 1, false },
{ 1, -1, true }, { 1, 0, true }, { 0, 1, true }, { 1, 1, true },
};
for (auto [dx, dz, staticOnly] : kNeighbours) {
const int nx = x + dx;
const int nz = z + dz;
// Ensure the cell we're checking is within the valid range
if (nx < 0 || nx >= NUM_CELLS || nz < 0 || nz >= NUM_CELLS) continue;
for (auto* other : m_Cells[nx][nz]) {
if (!staticOnly || (other && other->GetIsStatic()))
HandleEntity(en, other);
}
} }
if (x > 0) { for (auto* entity : m_GargantuanObjects | std::views::values) HandleEntity(en, entity);
for (auto other : m_Cells[x - 1][z])
HandleEntity(en, other);
}
if (z > 0) {
for (auto other : m_Cells[x][z - 1])
HandleEntity(en, other);
}
if (x > 0 && z < NUM_CELLS - 1) {
for (auto other : m_Cells[x - 1][z + 1])
HandleEntity(en, other);
}
for (auto& [id, entity] : m_GargantuanObjects)
HandleEntity(en, entity);
} }
} }