diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index 03fea31e47f..4d24edee779 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -6311,20 +6311,30 @@ bool CStaticFunctionDefinitions::SetTime(unsigned char ucHour, unsigned char ucM } bool CStaticFunctionDefinitions::ProcessLineOfSight(const CVector& vecStart, const CVector& vecEnd, bool& bCollision, CColPoint** pColPoint, - CClientEntity** pColEntity, const SLineOfSightFlags& flags, CEntity* pIgnoredEntity, + CClientEntity** pColEntity, const SLineOfSightFlags& flags, std::vector vecIgnoredElements, SLineOfSightBuildingResult* pBuildingResult) { assert(pColPoint); assert(pColEntity); - if (pIgnoredEntity) - g_pGame->GetWorld()->IgnoreEntity(pIgnoredEntity); + vecIgnoredElements.erase(std::remove_if(vecIgnoredElements.begin(), vecIgnoredElements.end(), [](CClientEntity* pIgnoredElement) { + // Remove entities that already have their colision disabled. + // This prevents us from re-enabling them. + if (!CStaticFunctionDefinitions::GetElementCollisionsEnabled(*pIgnoredElement)) + return true; + + // Otherwise disable collision and keep it in the array + CStaticFunctionDefinitions::SetElementCollisionsEnabled(*pIgnoredElement, false); + + return false; + }), vecIgnoredElements.end()); CEntity* pColGameEntity = 0; bCollision = g_pGame->GetWorld()->ProcessLineOfSight(&vecStart, &vecEnd, pColPoint, &pColGameEntity, flags, pBuildingResult); - if (pIgnoredEntity) - g_pGame->GetWorld()->IgnoreEntity(NULL); + // Re-enable collisions + for (CClientEntity* pIgnoredElement : vecIgnoredElements) + CStaticFunctionDefinitions::SetElementCollisionsEnabled(*pIgnoredElement, true); CPools* pPools = g_pGame->GetPools(); *pColEntity = pColGameEntity ? pPools->GetClientEntity((DWORD*)pColGameEntity->GetInterface()) : nullptr; diff --git a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h index 9a1798c3dcd..aa7aaa9cbc3 100644 --- a/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h +++ b/Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h @@ -560,7 +560,7 @@ class CStaticFunctionDefinitions // World functions static bool GetTime(unsigned char& ucHour, unsigned char& ucMin); static bool ProcessLineOfSight(const CVector& vecStart, const CVector& vecEnd, bool& bCollision, CColPoint** pColPoint, CClientEntity** pColEntity, - const SLineOfSightFlags& flags = SLineOfSightFlags(), CEntity* pIgnoredEntity = NULL, + const SLineOfSightFlags& flags = SLineOfSightFlags(), std::vector vecIgnoredElements = {}, SLineOfSightBuildingResult* pBuildingResult = NULL); static bool IsLineOfSightClear(const CVector& vecStart, const CVector& vecEnd, bool& bIsClear, const SLineOfSightFlags& flags = SLineOfSightFlags(), CEntity* pIgnoredEntity = NULL); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp index 8642983bf10..2f68142eddd 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp @@ -232,13 +232,23 @@ int CLuaWorldDefs::ProcessLineOfSight(lua_State* luaVM) // bool float float float element float float float int int int processLineOfSight ( float startX, float startY, float startZ, float endX, float endY, // float endZ, // [ bool checkBuildings = true, bool checkVehicles = true, bool checkPlayers = true, bool checkObjects = true, bool checkDummies = true, - // bool seeThroughStuff = false, bool ignoreSomeObjectsForCamera = false, bool shootThroughStuff = false, element ignoredElement = nil, bool - // returnBuildingInfo = false, bCheckCarTires = false ] ) - CVector vecStart; - CVector vecEnd; - SLineOfSightFlags flags; - CClientEntity* pIgnoredElement; - bool bIncludeBuildingInfo; + // bool seeThroughStuff = false, bool ignoreSomeObjectsForCamera = false, bool shootThroughStuff = false, element ignoredElement = nil [, + // element ignoredElement2, + // element ignoredElement3, + // ... etc + // ], bool returnBuildingInfo = false, bCheckCarTires = false ] ) + + // bool float float float element float float float int int int processLineOfSight ( float startX, float startY, float startZ, float endX, float endY, + // float endZ, + // [ bool checkBuildings = true, bool checkVehicles = true, bool checkPlayers = true, bool checkObjects = true, bool checkDummies = true, + // bool seeThroughStuff = false, bool ignoreSomeObjectsForCamera = false, bool shootThroughStuff = false, table ignoredElements = nil, + // bool returnBuildingInfo = false, bCheckCarTires = false ] ) + + CVector vecStart; + CVector vecEnd; + SLineOfSightFlags flags; + std::vector vecIgnoredElements; + bool bIncludeBuildingInfo; CScriptArgReader argStream(luaVM); argStream.ReadVector3D(vecStart); @@ -251,18 +261,31 @@ int CLuaWorldDefs::ProcessLineOfSight(lua_State* luaVM) argStream.ReadBool(flags.bSeeThroughStuff, false); argStream.ReadBool(flags.bIgnoreSomeObjectsForCamera, false); argStream.ReadBool(flags.bShootThroughStuff, false); - argStream.ReadUserData(pIgnoredElement, NULL); + + if (argStream.NextIsTable()) // Is the next value a table? Read it as a user data table (will error if table contains invalid type) + { + argStream.ReadUserDataTable(vecIgnoredElements); + } + else { + CClientEntity* pIgnoredElement; + argStream.ReadUserData(pIgnoredElement, NULL); + + if (pIgnoredElement != NULL) + { + vecIgnoredElements.push_back(pIgnoredElement); + } + } + argStream.ReadBool(bIncludeBuildingInfo, false); argStream.ReadBool(flags.bCheckCarTires, false); if (!argStream.HasErrors()) { - CEntity* pIgnoredEntity = pIgnoredElement ? pIgnoredElement->GetGameEntity() : NULL; CColPoint* pColPoint = NULL; CClientEntity* pColEntity = NULL; bool bCollision; SLineOfSightBuildingResult buildingResult; - if (CStaticFunctionDefinitions::ProcessLineOfSight(vecStart, vecEnd, bCollision, &pColPoint, &pColEntity, flags, pIgnoredEntity, + if (CStaticFunctionDefinitions::ProcessLineOfSight(vecStart, vecEnd, bCollision, &pColPoint, &pColEntity, flags, vecIgnoredElements, bIncludeBuildingInfo ? &buildingResult : NULL)) { // Got a collision?