Skip to content

Commit

Permalink
Add new function testSphereAgainstWorld (Close #646) (#3787)
Browse files Browse the repository at this point in the history
New scriptingfunction testSphereAgainstWorld, which allows checking if there are any obstacles within a given radius
  • Loading branch information
FileEX authored Dec 21, 2024
1 parent aa20c7d commit aa90aa5
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 1 deletion.
17 changes: 17 additions & 0 deletions Client/game_sa/CWorldSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,23 @@ bool CWorldSA::ProcessLineOfSight(const CVector* vecStart, const CVector* vecEnd
return bReturn;
}

CEntity* CWorldSA::TestSphereAgainstWorld(const CVector& sphereCenter, float radius, CEntity* ignoredEntity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool cameraIgnore, STestSphereAgainstWorldResult& result)
{
auto entity = ((CEntitySAInterface*(__cdecl*)(CVector, float, CEntitySAInterface*, bool, bool, bool, bool, bool, bool))FUNC_CWorld_TestSphereAgainstWorld)(sphereCenter, radius, ignoredEntity ? ignoredEntity->GetInterface() : nullptr, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, cameraIgnore);
if (!entity)
return nullptr;

result.collisionDetected = true;
result.modelID = entity->m_nModelIndex;
result.entityPosition = entity->Placeable.matrix->vPos;
ConvertMatrixToEulerAngles(*entity->Placeable.matrix, result.entityRotation.fX, result.entityRotation.fY, result.entityRotation.fZ);
result.entityRotation = -result.entityRotation;
result.lodID = entity->m_pLod ? entity->m_pLod->m_nModelIndex : 0;
result.type = static_cast<eEntityType>(entity->nType);

return pGame->GetPools()->GetEntity(reinterpret_cast<DWORD*>(entity));
}

void CWorldSA::IgnoreEntity(CEntity* pEntity)
{
CEntitySA* pEntitySA = dynamic_cast<CEntitySA*>(pEntity);
Expand Down
3 changes: 3 additions & 0 deletions Client/game_sa/CWorldSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define VAR_COcclusion_NumActiveOccluders 0xC73CC0
#define CALL_CCullZones_FindTunnelAttributesForCoors 0x55570D
#define FUNC_CWorld_FindPositionForTrackPosition 0x6F59E0
#define FUNC_CWorld_TestSphereAgainstWorld 0x569E20

#define VAR_IgnoredEntity 0xB7CD68
#define VAR_currArea 0xB72914
Expand Down Expand Up @@ -74,6 +75,8 @@ class CWorldSA : public CWorld
void ResetAllSurfaceInfo() override;
bool ResetSurfaceInfo(short sSurfaceID) override;

CEntity* TestSphereAgainstWorld(const CVector& sphereCenter, float radius, CEntity* ignoredEntity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool cameraIgnore, STestSphereAgainstWorldResult& result) override;

private:
float m_fAircraftMaxHeight;
CSurfaceType* m_pSurfaceInfo;
Expand Down
10 changes: 10 additions & 0 deletions Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,16 @@ ADD_ENUM(PreloadAreaOption::COLLISIONS, "collisions")
ADD_ENUM(PreloadAreaOption::ALL, "all")
IMPLEMENT_ENUM_CLASS_END("preload-area-option")

IMPLEMENT_ENUM_BEGIN(eEntityType)
ADD_ENUM(ENTITY_TYPE_NOTHING, "unknown")
ADD_ENUM(ENTITY_TYPE_BUILDING, "building")
ADD_ENUM(ENTITY_TYPE_VEHICLE, "vehicle")
ADD_ENUM(ENTITY_TYPE_PED, "ped")
ADD_ENUM(ENTITY_TYPE_OBJECT, "object")
ADD_ENUM(ENTITY_TYPE_DUMMY, "dummy")
ADD_ENUM(ENTITY_TYPE_NOTINPOOLS, "unknown")
IMPLEMENT_ENUM_END("entity-type")

//
// CResource from userdata
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ DECLARE_ENUM(ePools);
DECLARE_ENUM(eWorldProperty);
DECLARE_ENUM_CLASS(eModelLoadState);
DECLARE_ENUM_CLASS(PreloadAreaOption);
DECLARE_ENUM(eEntityType);

class CRemoteCall;

Expand Down
15 changes: 14 additions & 1 deletion Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ void CLuaWorldDefs::LoadFunctions()
{"isGarageOpen", IsGarageOpen},
{"isTimeFrozen", ArgumentParser<IsTimeFrozen>},
{"isVolumetricShadowsEnabled", ArgumentParser<IsVolumetricShadowsEnabled>},
{"isDynamicPedShadowsEnabled", ArgumentParser<IsDynamicPedShadowsEnabled>}};
{"isDynamicPedShadowsEnabled", ArgumentParser<IsDynamicPedShadowsEnabled>},
{"testSphereAgainstWorld", ArgumentParser<TestSphereAgainstWorld>}};

// Add functions
for (const auto& [name, func] : functions)
Expand Down Expand Up @@ -2297,3 +2298,15 @@ bool CLuaWorldDefs::ResetDynamicPedShadows() noexcept
{
return g_pGame->GetSettings()->ResetDynamicPedShadows();
}

CLuaMultiReturn<bool, CClientEntity*, int, float, float, float, float, float, float, int, eEntityType> CLuaWorldDefs::TestSphereAgainstWorld(CVector sphereCenter, float radius, std::optional<CClientEntity*> ignoredEntity, std::optional<bool> checkBuildings, std::optional<bool> checkVehicles, std::optional<bool> checkPeds, std::optional<bool> checkObjects, std::optional<bool> checkDummies, std::optional<bool> cameraIgnore)
{
STestSphereAgainstWorldResult result;
CClientEntity* collidedEntity = nullptr;

CEntity* entity = g_pGame->GetWorld()->TestSphereAgainstWorld(sphereCenter, radius, ignoredEntity.has_value() ? ignoredEntity.value()->GetGameEntity() : nullptr, checkBuildings.value_or(true), checkVehicles.value_or(true), checkPeds.value_or(true), checkObjects.value_or(true), checkDummies.value_or(true), cameraIgnore.value_or(false), result);
if (entity)
collidedEntity = reinterpret_cast<CClientEntity*>(entity->GetStoredPointer());

return {result.collisionDetected, collidedEntity, result.modelID, result.entityPosition.fX, result.entityPosition.fY, result.entityPosition.fZ, ConvertRadiansToDegrees(result.entityRotation.fX), ConvertRadiansToDegrees(result.entityRotation.fY), ConvertRadiansToDegrees(result.entityRotation.fZ), result.lodID, result.type};
}
3 changes: 3 additions & 0 deletions Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,5 +144,8 @@ class CLuaWorldDefs : public CLuaDefs
static bool SetDynamicPedShadowsEnabled(bool enable);
static bool IsDynamicPedShadowsEnabled() noexcept;
static bool ResetDynamicPedShadows() noexcept;

static CLuaMultiReturn<bool, CClientEntity*, int, float, float, float, float, float, float, int, eEntityType> TestSphereAgainstWorld(CVector sphereCenter, float radius, std::optional<CClientEntity*> ignoredEntity, std::optional<bool> checkBuildings, std::optional<bool> checkVehicles, std::optional<bool> checkPeds, std::optional<bool> checkObjects, std::optional<bool> checkDummies, std::optional<bool> cameraIgnore);

};

13 changes: 13 additions & 0 deletions Client/sdk/game/CWorld.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*****************************************************************************/

#pragma once
#include "CEntity.h"

class CEntitySAInterface;
class CVector;
Expand Down Expand Up @@ -61,6 +62,16 @@ struct SProcessLineOfSightMaterialInfoResult {
bool valid{}; //< Data found in this struct is only valid if this is `true`!
};

struct STestSphereAgainstWorldResult
{
bool collisionDetected{false};
std::uint32_t modelID{0};
CVector entityPosition{};
CVector entityRotation{};
std::uint32_t lodID{0};
eEntityType type{ENTITY_TYPE_NOTHING};
};

enum eDebugCaller
{
CEntity_SetMatrix,
Expand Down Expand Up @@ -274,4 +285,6 @@ class CWorld
virtual CSurfaceType* GetSurfaceInfo() = 0;
virtual void ResetAllSurfaceInfo() = 0;
virtual bool ResetSurfaceInfo(short sSurfaceID) = 0;

virtual CEntity* TestSphereAgainstWorld(const CVector& sphereCenter, float radius, CEntity* ignoredEntity, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool cameraIgnore, STestSphereAgainstWorldResult& result) = 0;
};

0 comments on commit aa90aa5

Please sign in to comment.