From 0b35f6cad0005a396f2ff9168508f1baa8f535f5 Mon Sep 17 00:00:00 2001 From: Saurtron Date: Thu, 12 Dec 2024 18:18:30 +0100 Subject: [PATCH] Apply radar error to lua spatial queries. --- rts/Lua/LuaSyncedRead.cpp | 157 ++++++++++++++++++++++++++------------ 1 file changed, 109 insertions(+), 48 deletions(-) diff --git a/rts/Lua/LuaSyncedRead.cpp b/rts/Lua/LuaSyncedRead.cpp index d6164188d6..9029b49044 100644 --- a/rts/Lua/LuaSyncedRead.cpp +++ b/rts/Lua/LuaSyncedRead.cpp @@ -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 @@ -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; + } +} /*** * @@ -2949,12 +2970,27 @@ 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); @@ -2962,23 +2998,23 @@ int LuaSyncedRead::GetUnitsInRectangle(lua_State* L) 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; @@ -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; @@ -3061,13 +3113,14 @@ 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)); \ @@ -3075,29 +3128,32 @@ int LuaSyncedRead::GetUnitsInCylinder(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, 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; @@ -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); \ @@ -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; @@ -3172,12 +3232,11 @@ struct Plane { }; -static inline bool UnitInPlanes(const CUnit* unit, const vector& planes) +static inline bool UnitInPlanes(const float3& pos, const float radius, const vector& 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 } } @@ -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); @@ -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); } } }