Skip to content
Permalink
Browse files

fix #6328

  • Loading branch information...
rtri
rtri committed Nov 6, 2019
1 parent 8b4a75f commit 79d77cadad41cef728e9e3ab592802e7e1a5ddd9
Showing with 32 additions and 30 deletions.
  1. +16 −20 rts/Game/GameHelper.cpp
  2. +3 −3 rts/Game/GameHelper.h
  3. +12 −6 rts/Lua/LuaSyncedRead.cpp
  4. +1 −1 rts/Sim/Units/Unit.cpp
@@ -557,28 +557,26 @@ namespace {
* Search area just needs to touch the unit's radius: this query includes the
* target unit's radius.
*
* If canBeBlind is true then the LOS test is skipped.
* If checkSightDist is false then the LOS test is skipped.
*/
struct ClosestUnit_InLos : public Base
{
protected:
float closeDist;
CUnit* closeUnit;
const bool canBeBlind;
const bool checkSightDist;

public:
ClosestUnit_InLos(const float3& pos, float searchRadius, bool canBeBlind) :
ClosestUnit_InLos(const float3& pos, float searchRadius, bool checkSightDistance) :
Base(pos, searchRadius + unitHandler.MaxUnitRadius()),
closeDist(searchRadius), closeUnit(nullptr), canBeBlind(canBeBlind) {}
closeDist(searchRadius), closeUnit(nullptr), checkSightDist(checkSightDistance) {}

void AddUnit(CUnit* u) {
// FIXME: use volumeBoundingRadius?
// (more for consistency than need)
const float dist = pos.distance(u->midPos) - u->radius;

if (dist <= closeDist &&
(canBeBlind || (u->losRadius > dist))
) {
if (dist <= closeDist && (!checkSightDist || (dist <= u->losRadius))) {
closeDist = dist;
closeUnit = u;
}
@@ -591,21 +589,19 @@ namespace {
* Returns the closest unit (2D) which may have LOS on the search position.
* Whether it actually has LOS depends on nearby obstacles.
*
* If canBeBlind is true then the LOS test is skipped.
* If checkSightDist is false then the LOS test is skipped.
*/
struct ClosestUnit_InLos_Cylinder : public ClosestUnit
{
const bool canBeBlind;
const bool checkSightDist;

ClosestUnit_InLos_Cylinder(const float3& pos, float searchRadius, bool canBeBlind) :
ClosestUnit(pos, searchRadius), canBeBlind(canBeBlind) {}
ClosestUnit_InLos_Cylinder(const float3& pos, float searchRadius, bool checkSightDistance) :
ClosestUnit(pos, searchRadius), checkSightDist(checkSightDistance) {}

void AddUnit(CUnit* u) {
const float sqDist = (pos - u->midPos).SqLength2D();

if (sqDist <= closeSqDist &&
(canBeBlind || Square(u->losRadius) > sqDist)
) {
if (sqDist <= closeSqDist && (!checkSightDist || sqDist <= Square(u->losRadius))) {
closeSqDist = sqDist;
closeUnit = u;
}
@@ -779,22 +775,22 @@ CUnit* CGameHelper::GetClosestValidTarget(const float3& pos, float searchRadius,

CUnit* CGameHelper::GetClosestEnemyUnitNoLosTest(
const CUnit* excludeUnit,
const float3& pos,
const float3& searchPos,
float searchRadius,
int searchAllyteam,
bool testSphere,
bool canBeBlind
bool sphereDistTest,
bool checkSightDist
) {
CUnit* closestUnit = nullptr;

if (testSphere) {
if (sphereDistTest) {
// includes target radius
Query::ClosestUnit_InLos q(pos, searchRadius, canBeBlind);
Query::ClosestUnit_InLos q(searchPos, searchRadius, checkSightDist);
QueryUnits(Filter::Enemy(excludeUnit, searchAllyteam), q);
closestUnit = q.GetClosestUnit();
} else {
// excludes target radius
Query::ClosestUnit_InLos_Cylinder q(pos, searchRadius, canBeBlind);
Query::ClosestUnit_InLos_Cylinder q(searchPos, searchRadius, checkSightDist);
QueryUnits(Filter::Enemy(excludeUnit, searchAllyteam), q);
closestUnit = q.GetClosestUnit();
}
@@ -66,11 +66,11 @@ class CGameHelper
static CUnit* GetClosestValidTarget(const float3& pos, float radius, int searchAllyteam, const CMobileCAI* cai);
static CUnit* GetClosestEnemyUnitNoLosTest(
const CUnit* excludeUnit,
const float3& pos,
const float3& searchPos,
float searchRadius,
int searchAllyteam,
bool testSphere,
bool canBeBlind
bool sphereDistTest,
bool checkSightDist
);
static CUnit* GetClosestFriendlyUnit(const CUnit* excludeUnit, const float3& pos, float searchRadius, int searchAllyteam);
static CUnit* GetClosestEnemyAircraft(const CUnit* excludeUnit, const float3& pos, float searchRadius, int searchAllyteam);
@@ -2519,14 +2519,20 @@ int LuaSyncedRead::GetUnitNearestEnemy(lua_State* L)
const bool wantLOS = !lua_isboolean(L, 3) || lua_toboolean(L, 3);
const bool testLOS = !CLuaHandle::GetHandleFullRead(L) || wantLOS;

const CUnit* target = CGameHelper::GetClosestEnemyUnitNoLosTest(unit, unit->pos, luaL_optnumber(L, 2, 1.0e9f), unit->allyteam, false, !testLOS);
const bool sphereDistTest = luaL_optboolean(L, 4, false);
const bool checkSightDist = luaL_optboolean(L, 5, false);

if (target != nullptr) {
lua_pushnumber(L, target->id);
return 1;
}
// if ignoring LOS, pass checkSightDist=false (by default)
// such that enemies outside unit's los-range are included
const CUnit* target = testLOS?
CGameHelper::GetClosestEnemyUnit (unit, unit->pos, luaL_optnumber(L, 2, 1.0e9f), unit->allyteam ):
CGameHelper::GetClosestEnemyUnitNoLosTest(unit, unit->pos, luaL_optnumber(L, 2, 1.0e9f), unit->allyteam, sphereDistTest, checkSightDist);

return 0;
if (target == nullptr)
return 0;

lua_pushnumber(L, target->id);
return 1;
}


@@ -2383,7 +2383,7 @@ bool CUnit::GetNewCloakState(bool stunCheck) {
const CUnit* closestEnemy = this;

if (!stunCheck)
closestEnemy = CGameHelper::GetClosestEnemyUnitNoLosTest(this, midPos, decloakDistance, allyteam, unitDef->decloakSpherical, true);
closestEnemy = CGameHelper::GetClosestEnemyUnitNoLosTest(this, midPos, decloakDistance, allyteam, unitDef->decloakSpherical, false);

return (eventHandler.AllowUnitCloak(this, closestEnemy));
}

0 comments on commit 79d77ca

Please sign in to comment.
You can’t perform that action at this time.