diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp index e88f8f6751..0ec8dce554 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp @@ -961,10 +961,22 @@ int CLuaElementDefs::GetElementsWithinColShape(lua_State* luaVM) } CClientEntityResult CLuaElementDefs::GetElementsWithinRange(CVector pos, float radius, std::optional type, std::optional interior, - std::optional dimension) + std::optional dimension, std::optional, CClientEntity*>> ignore) { const auto typeHash = (type.has_value() && !type.value().empty()) ? CClientEntity::GetTypeHashFromString(type.value()) : 0; + const std::vector ignoreEntities = [&]() + { + if (ignore.has_value()) + { + if (ignore.value().index() == 0) + return std::get>(ignore.value()); + else + return std::vector{std::get(ignore.value())}; + } + return std::vector{}; + }(); + CClientEntityResult result; GetClientSpatialDatabase()->SphereQuery(result, CSphere{pos, radius}); @@ -972,27 +984,30 @@ CClientEntityResult CLuaElementDefs::GetElementsWithinRange(CVector pos, float r if (interior || dimension || typeHash) { result.erase(std::remove_if(result.begin(), result.end(), - [&, radiusSq = radius * radius](CElement* pElement) { - if (typeHash && typeHash != pElement->GetTypeHash()) - return true; + [&, radiusSq = radius * radius](CElement* pElement) { + if (typeHash && typeHash != pElement->GetTypeHash()) + return true; - if (interior.has_value() && interior != pElement->GetInterior()) - return true; + if (interior.has_value() && interior != pElement->GetInterior()) + return true; - if (dimension.has_value() && dimension != pElement->GetDimension()) - return true; + if (dimension.has_value() && dimension != pElement->GetDimension()) + return true; - // Check if element is within the sphere, because the spatial database is 2D - CVector elementPos; - pElement->GetPosition(elementPos); - if ((elementPos - pos).LengthSquared() > radiusSq) - return true; + // Check if element is within the sphere, because the spatial database is 2D + CVector elementPos; + pElement->GetPosition(elementPos); + if ((elementPos - pos).LengthSquared() > radiusSq) + return true; - return pElement->IsBeingDeleted(); - }), - result.end()); - } + // Check if element is in the ignore list + if (std::find(ignoreEntities.begin(), ignoreEntities.end(), pElement) != ignoreEntities.end()) + return true; + return pElement->IsBeingDeleted(); + }), + result.end()); + } return result; } diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.h index 40f93761e4..b1c612647e 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.h @@ -42,7 +42,8 @@ class CLuaElementDefs : public CLuaDefs LUA_DECLARE(IsElementWithinMarker); LUA_DECLARE(GetElementsWithinColShape); static CClientEntityResult GetElementsWithinRange(CVector pos, float radius, std::optional type, std::optional interior, - std::optional dimension); + std::optional dimension, + std::optional, CClientEntity*>> ignore); LUA_DECLARE(GetElementDimension); LUA_DECLARE(GetElementZoneName); LUA_DECLARE_OOP(GetElementBoundingBox); diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp b/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp index f8effd7b89..2848d10ae3 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp +++ b/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp @@ -995,10 +995,22 @@ int CLuaElementDefs::getElementsWithinColShape(lua_State* luaVM) } CElementResult CLuaElementDefs::getElementsWithinRange(CVector pos, float radius, std::optional type, std::optional interior, - std::optional dimension) + std::optional dimension, std::optional, CElement*>> ignore) { const auto typeHash = (type.has_value() && !type.value().empty()) ? CElement::GetTypeHashFromString(type.value()) : 0; + const std::vector ignoreEntities = [&]() + { + if (ignore.has_value()) + { + if (ignore.value().index() == 0) + return std::get>(ignore.value()); + else + return std::vector{std::get(ignore.value())}; + } + return std::vector{}; + }(); + CElementResult result; GetSpatialDatabase()->SphereQuery(result, CSphere{pos, radius}); @@ -1006,25 +1018,28 @@ CElementResult CLuaElementDefs::getElementsWithinRange(CVector pos, float radius if (interior || dimension || typeHash) { result.erase(std::remove_if(result.begin(), result.end(), - [&, radiusSq = radius * radius](CElement* pElement) { - if (typeHash && typeHash != pElement->GetTypeHash()) - return true; + [&, radiusSq = radius * radius](CElement* pElement) { + if (typeHash && typeHash != pElement->GetTypeHash()) + return true; - if (interior.has_value() && interior != pElement->GetInterior()) - return true; + if (interior.has_value() && interior != pElement->GetInterior()) + return true; - if (dimension.has_value() && dimension != pElement->GetDimension()) - return true; + if (dimension.has_value() && dimension != pElement->GetDimension()) + return true; - // Check if element is within the sphere, because the spatial database is 2D - if ((pElement->GetPosition() - pos).LengthSquared() > radiusSq) - return true; + // Check if element is within the sphere, because the spatial database is 2D + if ((pElement->GetPosition() - pos).LengthSquared() > radiusSq) + return true; - return pElement->IsBeingDeleted(); - }), - result.end()); - } + // Check if element is in the ignore list + if (std::find(ignoreEntities.begin(), ignoreEntities.end(), pElement) != ignoreEntities.end()) + return true; + return pElement->IsBeingDeleted(); + }), + result.end()); + } return result; } diff --git a/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.h b/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.h index b58f613b59..2ee2aed985 100644 --- a/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.h +++ b/Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.h @@ -47,7 +47,7 @@ class CLuaElementDefs : public CLuaDefs LUA_DECLARE(getElementInterior); LUA_DECLARE(getElementsWithinColShape); static CElementResult getElementsWithinRange(CVector pos, float radius, std::optional type, std::optional interior, - std::optional dimension); + std::optional dimension, std::optional, CElement*>> ignore); LUA_DECLARE(getElementDimension); LUA_DECLARE(getElementZoneName); LUA_DECLARE(getElementColShape);