Skip to content

Commit

Permalink
add element/table ignore arg to getElementsWithinRange (shared)
Browse files Browse the repository at this point in the history
  • Loading branch information
Fernando-A-Rocha committed Nov 26, 2024
1 parent 6683086 commit 44efbae
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 34 deletions.
49 changes: 32 additions & 17 deletions Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -961,38 +961,53 @@ int CLuaElementDefs::GetElementsWithinColShape(lua_State* luaVM)
}

CClientEntityResult CLuaElementDefs::GetElementsWithinRange(CVector pos, float radius, std::optional<std::string> type, std::optional<unsigned short> interior,
std::optional<unsigned short> dimension)
std::optional<unsigned short> dimension, std::optional<std::variant<std::vector<CClientEntity*>, CClientEntity*>> ignore)
{
const auto typeHash = (type.has_value() && !type.value().empty()) ? CClientEntity::GetTypeHashFromString(type.value()) : 0;

const std::vector<CClientEntity*> ignoreEntities = [&]()
{
if (ignore.has_value())
{
if (ignore.value().index() == 0)
return std::get<std::vector<CClientEntity*>>(ignore.value());
else
return std::vector<CClientEntity*>{std::get<CClientEntity*>(ignore.value())};
}
return std::vector<CClientEntity*>{};
}();

CClientEntityResult result;
GetClientSpatialDatabase()->SphereQuery(result, CSphere{pos, radius});

// Remove elements that do not match the criterias
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;
}

Expand Down
3 changes: 2 additions & 1 deletion Client/mods/deathmatch/logic/luadefs/CLuaElementDefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ class CLuaElementDefs : public CLuaDefs
LUA_DECLARE(IsElementWithinMarker);
LUA_DECLARE(GetElementsWithinColShape);
static CClientEntityResult GetElementsWithinRange(CVector pos, float radius, std::optional<std::string> type, std::optional<unsigned short> interior,
std::optional<unsigned short> dimension);
std::optional<unsigned short> dimension,
std::optional<std::variant<std::vector<CClientEntity*>, CClientEntity*>> ignore);
LUA_DECLARE(GetElementDimension);
LUA_DECLARE(GetElementZoneName);
LUA_DECLARE_OOP(GetElementBoundingBox);
Expand Down
45 changes: 30 additions & 15 deletions Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -995,36 +995,51 @@ int CLuaElementDefs::getElementsWithinColShape(lua_State* luaVM)
}

CElementResult CLuaElementDefs::getElementsWithinRange(CVector pos, float radius, std::optional<std::string> type, std::optional<unsigned short> interior,
std::optional<unsigned short> dimension)
std::optional<unsigned short> dimension, std::optional<std::variant<std::vector<CElement*>, CElement*>> ignore)
{
const auto typeHash = (type.has_value() && !type.value().empty()) ? CElement::GetTypeHashFromString(type.value()) : 0;

const std::vector<CElement*> ignoreEntities = [&]()
{
if (ignore.has_value())
{
if (ignore.value().index() == 0)
return std::get<std::vector<CElement*>>(ignore.value());
else
return std::vector<CElement*>{std::get<CElement*>(ignore.value())};
}
return std::vector<CElement*>{};
}();

CElementResult result;
GetSpatialDatabase()->SphereQuery(result, CSphere{pos, radius});

// Remove elements that do not match the criterias
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;
}

Expand Down
2 changes: 1 addition & 1 deletion Server/mods/deathmatch/logic/luadefs/CLuaElementDefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class CLuaElementDefs : public CLuaDefs
LUA_DECLARE(getElementInterior);
LUA_DECLARE(getElementsWithinColShape);
static CElementResult getElementsWithinRange(CVector pos, float radius, std::optional<std::string> type, std::optional<unsigned short> interior,
std::optional<unsigned short> dimension);
std::optional<unsigned short> dimension, std::optional<std::variant<std::vector<CElement*>, CElement*>> ignore);
LUA_DECLARE(getElementDimension);
LUA_DECLARE(getElementZoneName);
LUA_DECLARE(getElementColShape);
Expand Down

0 comments on commit 44efbae

Please sign in to comment.