Skip to content

Commit

Permalink
Apply radar error to lua spatial queries.
Browse files Browse the repository at this point in the history
  • Loading branch information
saurtron committed Dec 12, 2024
1 parent 05c5724 commit 0b35f6c
Showing 1 changed file with 109 additions and 48 deletions.
157 changes: 109 additions & 48 deletions rts/Lua/LuaSyncedRead.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2908,6 +2908,7 @@ int LuaSyncedRead::GetTeamUnitCount(lua_State* L)
// unit
// readTeam for MY_UNIT_TEST
// allegiance for SIMPLE_TEAM_TEST and VISIBLE_TEAM_TEST
// readAllyTeam, fullRead for UNIT_ERROR_POS

#define NULL_TEST ; // always passes

Expand All @@ -2931,6 +2932,26 @@ int LuaSyncedRead::GetTeamUnitCount(lua_State* L)
if (unit->allyteam == CLuaHandle::GetHandleReadAllyTeam(L)) { continue; } \
if (!LuaUtils::IsUnitVisible(L, unit)) { continue; }

#define UNIT_POS \
const float3& p = unit->midPos;

#define UNIT_ERROR_POS \
float3 p = unit->midPos; \
if (!LuaUtils::IsAllyUnit(L, unit)) \
p += unit->GetLuaErrorVector(readAllyTeam, fullRead);


/* Apply team error to planar mins/maxs boxes */
void ApplyPlanarTeamError(lua_State* L, int allegiance, float3& mins, float3& maxs) {
if ((allegiance >= 0 && !LuaUtils::IsAlliedTeam(L, allegiance)) ||
!(allegiance == LuaUtils::MyUnits || allegiance == LuaUtils::AllyUnits)) {
const int readAllyTeam = CLuaHandle::GetHandleReadAllyTeam(L);
const float allyTeamError = losHandler->GetAllyTeamRadarErrorSize(readAllyTeam);
const float3 allyTeamError3(allyTeamError, 0.0f, allyTeamError);
mins -= allyTeamError3;
maxs += allyTeamError3;
}
}

/***
*
Expand All @@ -2949,36 +2970,51 @@ int LuaSyncedRead::GetUnitsInRectangle(lua_State* L)
const float xmax = luaL_checkfloat(L, 3);
const float zmax = luaL_checkfloat(L, 4);

const float3 mins(xmin, 0.0f, zmin);
const float3 maxs(xmax, 0.0f, zmax);
float3 mins(xmin, 0.0f, zmin);
float3 maxs(xmax, 0.0f, zmax);

const int allegiance = LuaUtils::ParseAllegiance(L, __func__, 5);
const int readAllyTeam = CLuaHandle::GetHandleReadAllyTeam(L);
const bool fullRead = CLuaHandle::GetHandleFullRead(L);

#define RECTANGLE_TEST ; // no test, GetUnitsExact is sufficient
#define NULL_TEST ; // no test, GetUnitsExact is sufficient

#define RECTANGLE_TEST \
const float x = p.x; \
const float z = p.z; \
if ((x < xmin) || (x > xmax)) { \
continue; \
} \
if ((z < zmin) || (z > zmax)) { \
continue; \
}

if (!fullRead)
ApplyPlanarTeamError(L, allegiance, mins, maxs);

QuadFieldQuery qfQuery;
quadField.GetUnitsExact(qfQuery, mins, maxs);
const auto& units = (*qfQuery.units);

if (allegiance >= 0) {
if (LuaUtils::IsAlliedTeam(L, allegiance)) {
LOOP_UNIT_CONTAINER(SIMPLE_TEAM_TEST, RECTANGLE_TEST, true);
LOOP_UNIT_CONTAINER(SIMPLE_TEAM_TEST, NULL_TEST, true);
} else {
LOOP_UNIT_CONTAINER(VISIBLE_TEAM_TEST, RECTANGLE_TEST, true);
LOOP_UNIT_CONTAINER(VISIBLE_TEAM_TEST, UNIT_ERROR_POS RECTANGLE_TEST, true);
}
}
else if (allegiance == LuaUtils::MyUnits) {
const int readTeam = CLuaHandle::GetHandleReadTeam(L);
LOOP_UNIT_CONTAINER(MY_UNIT_TEST, RECTANGLE_TEST, true);
LOOP_UNIT_CONTAINER(MY_UNIT_TEST, NULL_TEST, true);
}
else if (allegiance == LuaUtils::AllyUnits) {
LOOP_UNIT_CONTAINER(ALLY_UNIT_TEST, RECTANGLE_TEST, true);
LOOP_UNIT_CONTAINER(ALLY_UNIT_TEST, NULL_TEST, true);
}
else if (allegiance == LuaUtils::EnemyUnits) {
LOOP_UNIT_CONTAINER(ENEMY_UNIT_TEST, RECTANGLE_TEST, true);
LOOP_UNIT_CONTAINER(ENEMY_UNIT_TEST, UNIT_ERROR_POS RECTANGLE_TEST, true);
}
else { // AllUnits
LOOP_UNIT_CONTAINER(VISIBLE_TEST, RECTANGLE_TEST, true);
LOOP_UNIT_CONTAINER(VISIBLE_TEST, UNIT_ERROR_POS RECTANGLE_TEST, true);
}

return 1;
Expand Down Expand Up @@ -3006,40 +3042,56 @@ int LuaSyncedRead::GetUnitsInBox(lua_State* L)
const float ymax = luaL_checkfloat(L, 5);
const float zmax = luaL_checkfloat(L, 6);

const float3 mins(xmin, 0.0f, zmin);
const float3 maxs(xmax, 0.0f, zmax);
float3 mins(xmin, 0.0f, zmin);
float3 maxs(xmax, 0.0f, zmax);

const int allegiance = LuaUtils::ParseAllegiance(L, __func__, 7);
const int readAllyTeam = CLuaHandle::GetHandleReadAllyTeam(L);
const bool fullRead = CLuaHandle::GetHandleFullRead(L);

#define BOX_TEST \
const float y = unit->midPos.y; \
const float y = p.y; \
if ((y < ymin) || (y > ymax)) { \
continue; \
continue; \
}

#define BOX_TEST_FULL \
BOX_TEST \
const float x = p.x; \
if ((x < xmin) || (x > xmax)) { \
continue; \
} \
const float z = p.z; \
if ((z < zmin) || (z > zmax)) { \
continue; \
}

if (!fullRead)
ApplyPlanarTeamError(L, allegiance, mins, maxs);

QuadFieldQuery qfQuery;
quadField.GetUnitsExact(qfQuery, mins, maxs);
const auto& units = (*qfQuery.units);

if (allegiance >= 0) {
if (LuaUtils::IsAlliedTeam(L, allegiance)) {
LOOP_UNIT_CONTAINER(SIMPLE_TEAM_TEST, BOX_TEST, true);
LOOP_UNIT_CONTAINER(SIMPLE_TEAM_TEST, UNIT_POS BOX_TEST, true);
} else {
LOOP_UNIT_CONTAINER(VISIBLE_TEAM_TEST, BOX_TEST, true);
LOOP_UNIT_CONTAINER(VISIBLE_TEAM_TEST, UNIT_ERROR_POS BOX_TEST_FULL, true);
}
}
else if (allegiance == LuaUtils::MyUnits) {
const int readTeam = CLuaHandle::GetHandleReadTeam(L);
LOOP_UNIT_CONTAINER(MY_UNIT_TEST, BOX_TEST, true);
LOOP_UNIT_CONTAINER(MY_UNIT_TEST, UNIT_POS BOX_TEST, true);
}
else if (allegiance == LuaUtils::AllyUnits) {
LOOP_UNIT_CONTAINER(ALLY_UNIT_TEST, BOX_TEST, true);
LOOP_UNIT_CONTAINER(ALLY_UNIT_TEST, UNIT_POS BOX_TEST, true);
}
else if (allegiance == LuaUtils::EnemyUnits) {
LOOP_UNIT_CONTAINER(ENEMY_UNIT_TEST, BOX_TEST, true);
LOOP_UNIT_CONTAINER(ENEMY_UNIT_TEST, UNIT_ERROR_POS BOX_TEST_FULL, true);
}
else { // AllUnits
LOOP_UNIT_CONTAINER(VISIBLE_TEST, BOX_TEST, true);
LOOP_UNIT_CONTAINER(VISIBLE_TEST, UNIT_ERROR_POS BOX_TEST_FULL, true);
}

return 1;
Expand All @@ -3061,43 +3113,47 @@ int LuaSyncedRead::GetUnitsInCylinder(lua_State* L)
const float radius = luaL_checkfloat(L, 3);
const float radSqr = (radius * radius);

const float3 mins(x - radius, 0.0f, z - radius);
const float3 maxs(x + radius, 0.0f, z + radius);
float3 mins(x - radius, 0.0f, z - radius);
float3 maxs(x + radius, 0.0f, z + radius);

const int allegiance = LuaUtils::ParseAllegiance(L, __func__, 4);
const int readAllyTeam = CLuaHandle::GetHandleReadAllyTeam(L);
const bool fullRead = CLuaHandle::GetHandleFullRead(L);

#define CYLINDER_TEST \
const float3& p = unit->midPos; \
const float dx = (p.x - x); \
const float dz = (p.z - z); \
const float dist = ((dx * dx) + (dz * dz)); \
if (dist > radSqr) { \
continue; \
} \

if (!fullRead)
ApplyPlanarTeamError(L, allegiance, mins, maxs);

QuadFieldQuery qfQuery;
quadField.GetUnitsExact(qfQuery, mins, maxs);
const auto& units = (*qfQuery.units);

if (allegiance >= 0) {
if (LuaUtils::IsAlliedTeam(L, allegiance)) {
LOOP_UNIT_CONTAINER(SIMPLE_TEAM_TEST, CYLINDER_TEST, true);
LOOP_UNIT_CONTAINER(SIMPLE_TEAM_TEST, UNIT_POS CYLINDER_TEST, true);
} else {
LOOP_UNIT_CONTAINER(VISIBLE_TEAM_TEST, CYLINDER_TEST, true);
LOOP_UNIT_CONTAINER(VISIBLE_TEAM_TEST, UNIT_ERROR_POS CYLINDER_TEST, true);
}
}
else if (allegiance == LuaUtils::MyUnits) {
const int readTeam = CLuaHandle::GetHandleReadTeam(L);
LOOP_UNIT_CONTAINER(MY_UNIT_TEST, CYLINDER_TEST, true);
LOOP_UNIT_CONTAINER(MY_UNIT_TEST, UNIT_POS CYLINDER_TEST, true);
}
else if (allegiance == LuaUtils::AllyUnits) {
LOOP_UNIT_CONTAINER(ALLY_UNIT_TEST, CYLINDER_TEST, true);
LOOP_UNIT_CONTAINER(ALLY_UNIT_TEST, UNIT_POS CYLINDER_TEST, true);
}
else if (allegiance == LuaUtils::EnemyUnits) {
LOOP_UNIT_CONTAINER(ENEMY_UNIT_TEST, CYLINDER_TEST, true);
LOOP_UNIT_CONTAINER(ENEMY_UNIT_TEST, UNIT_ERROR_POS CYLINDER_TEST, true);
}
else { // AllUnits
LOOP_UNIT_CONTAINER(VISIBLE_TEST, CYLINDER_TEST, true);
LOOP_UNIT_CONTAINER(VISIBLE_TEST, UNIT_ERROR_POS CYLINDER_TEST, true);
}

return 1;
Expand All @@ -3122,13 +3178,14 @@ int LuaSyncedRead::GetUnitsInSphere(lua_State* L)
const float radSqr = (radius * radius);

const float3 pos(x, y, z);
const float3 mins(x - radius, 0.0f, z - radius);
const float3 maxs(x + radius, 0.0f, z + radius);
float3 mins(x - radius, 0.0f, z - radius);
float3 maxs(x + radius, 0.0f, z + radius);

const int allegiance = LuaUtils::ParseAllegiance(L, __func__, 5);
const int readAllyTeam = CLuaHandle::GetHandleReadAllyTeam(L);
const bool fullRead = CLuaHandle::GetHandleFullRead(L);

#define SPHERE_TEST \
const float3& p = unit->midPos; \
const float dx = (p.x - x); \
const float dy = (p.y - y); \
const float dz = (p.z - z); \
Expand All @@ -3138,29 +3195,32 @@ int LuaSyncedRead::GetUnitsInSphere(lua_State* L)
continue; \
} \

if (!fullRead)
ApplyPlanarTeamError(L, allegiance, mins, maxs);

QuadFieldQuery qfQuery;
quadField.GetUnitsExact(qfQuery, mins, maxs);
const auto& units = (*qfQuery.units);

if (allegiance >= 0) {
if (LuaUtils::IsAlliedTeam(L, allegiance)) {
LOOP_UNIT_CONTAINER(SIMPLE_TEAM_TEST, SPHERE_TEST, true);
LOOP_UNIT_CONTAINER(SIMPLE_TEAM_TEST, UNIT_POS SPHERE_TEST, true);
} else {
LOOP_UNIT_CONTAINER(VISIBLE_TEAM_TEST, SPHERE_TEST, true);
LOOP_UNIT_CONTAINER(VISIBLE_TEAM_TEST, UNIT_ERROR_POS SPHERE_TEST, true);
}
}
else if (allegiance == LuaUtils::MyUnits) {
const int readTeam = CLuaHandle::GetHandleReadTeam(L);
LOOP_UNIT_CONTAINER(MY_UNIT_TEST, SPHERE_TEST, true);
LOOP_UNIT_CONTAINER(MY_UNIT_TEST, UNIT_POS SPHERE_TEST, true);
}
else if (allegiance == LuaUtils::AllyUnits) {
LOOP_UNIT_CONTAINER(ALLY_UNIT_TEST, SPHERE_TEST, true);
LOOP_UNIT_CONTAINER(ALLY_UNIT_TEST, UNIT_POS SPHERE_TEST, true);
}
else if (allegiance == LuaUtils::EnemyUnits) {
LOOP_UNIT_CONTAINER(ENEMY_UNIT_TEST, SPHERE_TEST, true);
LOOP_UNIT_CONTAINER(ENEMY_UNIT_TEST, UNIT_ERROR_POS SPHERE_TEST, true);
}
else { // AllUnits
LOOP_UNIT_CONTAINER(VISIBLE_TEST, SPHERE_TEST, true);
LOOP_UNIT_CONTAINER(VISIBLE_TEST, UNIT_ERROR_POS SPHERE_TEST, true);
}

return 1;
Expand All @@ -3172,12 +3232,11 @@ struct Plane {
};


static inline bool UnitInPlanes(const CUnit* unit, const vector<Plane>& planes)
static inline bool UnitInPlanes(const float3& pos, const float radius, const vector<Plane>& planes)
{
const float3& pos = unit->midPos;
for (const Plane& p: planes) {
const float dist = (pos.x * p.x) + (pos.y * p.y) + (pos.z * p.z) + p.d;
if ((dist - unit->radius) > 0.0f) {
if ((dist - radius) > 0.0f) {
return false; // outside
}
}
Expand Down Expand Up @@ -3245,11 +3304,13 @@ int LuaSyncedRead::GetUnitsInPlanes(lua_State* L)
}

#define PLANES_TEST \
if (!UnitInPlanes(unit, planes)) { \
if (!UnitInPlanes(p, unit->radius, planes)) { \
continue; \
}

const int readTeam = CLuaHandle::GetHandleReadTeam(L);
const int readAllyTeam = CLuaHandle::GetHandleReadAllyTeam(L);
const bool fullRead = CLuaHandle::GetHandleFullRead(L);

lua_newtable(L);

Expand All @@ -3259,32 +3320,32 @@ int LuaSyncedRead::GetUnitsInPlanes(lua_State* L)
if (allegiance >= 0) {
if (allegiance == team) {
if (LuaUtils::IsAlliedTeam(L, allegiance)) {
LOOP_UNIT_CONTAINER(NULL_TEST, PLANES_TEST, false);
LOOP_UNIT_CONTAINER(NULL_TEST, UNIT_POS PLANES_TEST, false);
} else {
LOOP_UNIT_CONTAINER(VISIBLE_TEST, PLANES_TEST, false);
LOOP_UNIT_CONTAINER(VISIBLE_TEST, UNIT_ERROR_POS PLANES_TEST, false);
}
}
}
else if (allegiance == LuaUtils::MyUnits) {
if (readTeam == team) {
LOOP_UNIT_CONTAINER(NULL_TEST, PLANES_TEST, false);
LOOP_UNIT_CONTAINER(NULL_TEST, UNIT_POS PLANES_TEST, false);
}
}
else if (allegiance == LuaUtils::AllyUnits) {
if (CLuaHandle::GetHandleReadAllyTeam(L) == teamHandler.AllyTeam(team)) {
LOOP_UNIT_CONTAINER(NULL_TEST, PLANES_TEST, false);
LOOP_UNIT_CONTAINER(NULL_TEST, UNIT_POS PLANES_TEST, false);
}
}
else if (allegiance == LuaUtils::EnemyUnits) {
if (CLuaHandle::GetHandleReadAllyTeam(L) != teamHandler.AllyTeam(team)) {
LOOP_UNIT_CONTAINER(VISIBLE_TEST, PLANES_TEST, false);
LOOP_UNIT_CONTAINER(VISIBLE_TEST, UNIT_ERROR_POS PLANES_TEST, false);
}
}
else { // AllUnits
if (LuaUtils::IsAlliedTeam(L, team)) {
LOOP_UNIT_CONTAINER(NULL_TEST, PLANES_TEST, false);
LOOP_UNIT_CONTAINER(NULL_TEST, UNIT_POS PLANES_TEST, false);
} else {
LOOP_UNIT_CONTAINER(VISIBLE_TEST, PLANES_TEST, false);
LOOP_UNIT_CONTAINER(VISIBLE_TEST, UNIT_ERROR_POS PLANES_TEST, false);
}
}
}
Expand Down

0 comments on commit 0b35f6c

Please sign in to comment.