Skip to content
Permalink
Browse files

fix #6096 #6093

call AllowWeaponTarget when auto-generating CAI attack commands
when targetID=-1 and weaponNum=-1 targetPriority determines the
target search radius; targetPriority=nil accompanies any actual
target being considered
  • Loading branch information...
rt
rt committed Dec 9, 2018
1 parent d24a712 commit 198e315d4d7c736794223d3c8aece278909ac967
Showing with 139 additions and 115 deletions.
  1. +26 −15 rts/Lua/LuaHandleSynced.cpp
  2. +67 −69 rts/Sim/Units/CommandAI/AirCAI.cpp
  3. +46 −31 rts/Sim/Units/CommandAI/MobileCAI.cpp
@@ -1235,6 +1235,7 @@ int CSyncedLuaHandle::AllowWeaponTargetCheck(unsigned int attackerID, unsigned i
return ret;

ret = lua_toint(L, -1);

lua_pop(L, 1);
return ret;
}
@@ -1245,10 +1246,8 @@ bool CSyncedLuaHandle::AllowWeaponTarget(
unsigned int targetID,
unsigned int attackerWeaponNum,
unsigned int attackerWeaponDefID,
float* targetPriority)
{
assert(targetPriority != nullptr);

float* targetPriority
) {
bool ret = true;

if (!watchWeaponDefs[attackerWeaponDefID])
@@ -1266,18 +1265,24 @@ bool CSyncedLuaHandle::AllowWeaponTarget(
lua_pushnumber(L, targetID);
lua_pushnumber(L, attackerWeaponNum + LUA_WEAPON_BASE_INDEX);
lua_pushnumber(L, attackerWeaponDefID);
lua_pushnumber(L, *targetPriority);

if (targetPriority != nullptr) {
// Weapon::AutoTarget
lua_pushnumber(L, *targetPriority);
} else {
// {Air,Mobile}CAI::AutoGenerateTarget
lua_pushnil(L);
}

if (!RunCallInTraceback(L, cmdStr, 5, 2, traceBack.GetErrFuncIdx(), false))
return ret;

ret = luaL_optboolean(L, -2, false);
if (targetPriority != nullptr)
*targetPriority = luaL_optnumber(L, -1, *targetPriority);

if (lua_isnumber(L, -1))
*targetPriority = lua_tonumber(L, -1);
ret = luaL_optboolean(L, -2, false);

lua_pop(L, 2);

return ret;
}

@@ -1308,6 +1313,7 @@ bool CSyncedLuaHandle::AllowWeaponInterceptTarget(
return ret;

ret = luaL_optboolean(L, -1, false);

lua_pop(L, 1);
return ret;
}
@@ -1319,6 +1325,11 @@ bool CSyncedLuaHandle::AllowWeaponInterceptTarget(

int CSyncedLuaHandle::SyncedRandom(lua_State* L)
{
#if 0
spring_lua_synced_rand(L);
return 1;
#endif

switch (lua_gettop(L)) {
case 0: {
lua_pushnumber(L, gsRNG.NextFloat());
@@ -1327,12 +1338,13 @@ int CSyncedLuaHandle::SyncedRandom(lua_State* L)

case 1: {
if (lua_isnumber(L, 1)) {
const int maxn = lua_toint(L, 1);
const int l = 1;
const int u = lua_toint(L, 1);

if (maxn < 1)
luaL_error(L, "error: too small upper limit (%d) given to math.random(), should be >= 1 {synced}", maxn);
if (u < 1)
luaL_error(L, "error: too small upper limit (%d) given to math.random(), should be >= 1 {synced}", u);

lua_pushnumber(L, 1 + gsRNG.NextInt(maxn));
lua_pushnumber(L, 1 + gsRNG.NextInt(u));
return 1;
}
} break;
@@ -1347,9 +1359,8 @@ int CSyncedLuaHandle::SyncedRandom(lua_State* L)

const float diff = (upper - lower);
const float r = gsRNG.NextFloat(); // [0,1], not [0,1) ?
const int value = lower + (int)(r * (diff + 1));

lua_pushnumber(L, Clamp(value, lower, upper));
lua_pushnumber(L, Clamp(lower + int(r * (diff + 1)), lower, upper));
return 1;
}
} break;
@@ -15,6 +15,7 @@
#include "Sim/Units/UnitHandler.h"
#include "Sim/Weapons/Weapon.h"
#include "Sim/Weapons/WeaponDefHandler.h"
#include "System/EventHandler.h"
#include "System/myMath.h"
#include "System/Log/ILog.h"
#include "System/StringUtil.h"
@@ -176,77 +177,76 @@ void CAirCAI::SlowUpdate()

#if (AUTO_GENERATE_ATTACK_ORDERS == 1)
if (commandQue.empty()) {
if (!AirAutoGenerateTarget(GetStrafeAirMoveType(owner))) {
// if no target found, queue is still empty so bail now
// queue remains empty if no target, can bail early
if (!AirAutoGenerateTarget(GetStrafeAirMoveType(owner)))
return;
}
}
#endif

// FIXME: check owner->UsingScriptMoveType() and skip rest if true?
AAirMoveType* myPlane = GetStrafeAirMoveType(owner);
Command& c = commandQue.front();

if (c.GetID() == CMD_WAIT) {
if ((myPlane->aircraftState == AAirMoveType::AIRCRAFT_FLYING)
&& !owner->unitDef->DontLand() && myPlane->autoLand)
{
StopMove();
}
return;
}

switch (c.GetID()) {
case CMD_WAIT: {
if ((myPlane->aircraftState == AAirMoveType::AIRCRAFT_FLYING) && myPlane->autoLand && !owner->unitDef->DontLand())
StopMove();

return;
} break;
case CMD_AREA_ATTACK: {
ExecuteAreaAttack(c);
return;
}
} break;
default: {
CMobileCAI::Execute();
return;
}
} break;
}
}

bool CAirCAI::AirAutoGenerateTarget(AAirMoveType* myPlane) {
assert(commandQue.empty());
assert(myPlane->owner == owner);

if (owner->weapons.empty())
return false;

const UnitDef* ownerDef = owner->unitDef;

const bool autoLand = !ownerDef->DontLand() && myPlane->autoLand;
const bool autoAttack = ((owner->fireState >= FIRESTATE_FIREATWILL) && (owner->moveState != MOVESTATE_HOLDPOS));
const bool isFlying = (myPlane->aircraftState == AAirMoveType::AIRCRAFT_FLYING);

if (myPlane->aircraftState == AAirMoveType::AIRCRAFT_FLYING && autoLand) {
StopMove();
}
// float searchRadius = 500.0f * owner->moveState;
float searchRadius = 1000.0f * owner->moveState;

if (ownerDef->canAttack && autoAttack && owner->maxRange > 0) {
if (ownerDef->IsFighterAirUnit()) {
const float3 P = owner->pos + (owner->speed * 10.0);
const float R = 1000.0f * owner->moveState;
const CUnit* enemy = CGameHelper::GetClosestEnemyAircraft(NULL, P, R, owner->allyteam);
if (!ownerDef->canAttack || !autoAttack || owner->maxRange <= 0.0f)
return false;

if (IsValidTarget(enemy)) {
Command nc(CMD_ATTACK, INTERNAL_ORDER, enemy->id);
commandQue.push_front(nc);
inCommand = false;
return true;
}
} else {
const float3 P = owner->pos + (owner->speed * 20.0f);
const float R = 500.0f * owner->moveState;
const CUnit* enemy = CGameHelper::GetClosestValidTarget(P, R, owner->allyteam, this);
// pass bogus target-id and weapon-number s.t. script knows context and can set radius
if (!eventHandler.AllowWeaponTarget(owner->id, -1, -1, 0, &searchRadius))
return false;

if (enemy != NULL) {
Command nc(CMD_ATTACK, INTERNAL_ORDER, enemy->id);
commandQue.push_front(nc);
inCommand = false;
return true;
}
}
if (isFlying && autoLand)
StopMove();

const CUnit* tgt = nullptr;
const CWeapon* wpn = owner->weapons[0];

if (ownerDef->IsFighterAirUnit()) {
tgt = CGameHelper::GetClosestEnemyAircraft(nullptr, owner->pos + owner->speed * 10.0f, searchRadius, owner->allyteam);
} else {
tgt = CGameHelper::GetClosestValidTarget(owner->pos + owner->speed * 20.0f, searchRadius, owner->allyteam, this);
}

return false;
if (!IsValidTarget(tgt))
return false;
if (!eventHandler.AllowWeaponTarget(owner->id, tgt->id, wpn->weaponNum, wpn->weaponDef->id, nullptr))
return false;

Command nc(CMD_ATTACK, INTERNAL_ORDER, tgt->id);
commandQue.push_front(nc);
inCommand = false;
return true;
}


@@ -257,21 +257,22 @@ void CAirCAI::ExecuteMove(Command& c)
AAirMoveType* myPlane = GetStrafeAirMoveType(owner);
SetGoal(cmdPos, owner->pos);

const CStrafeAirMoveType* airMT = (!owner->UsingScriptMoveType())? static_cast<const CStrafeAirMoveType*>(myPlane): NULL;
const float radius = (airMT != NULL)? std::max(airMT->turnRadius + 2 * SQUARE_SIZE, 128.f) : 127.f;
const CStrafeAirMoveType* airMT = (!owner->UsingScriptMoveType())? static_cast<const CStrafeAirMoveType*>(myPlane): nullptr;

const float mtRadius = (airMT != nullptr)? std::max(airMT->turnRadius + 2 * SQUARE_SIZE, 128.0f) : 127.0f;
const float sqRadius = Square(mtRadius);

// we're either circling or will get to the target in 8 frames
if ((owner->pos - cmdPos).SqLength2D() < (radius * radius)
|| (owner->pos + owner->speed*8 - cmdPos).SqLength2D() < 127*127)
{
if ((owner->pos - cmdPos).SqLength2D() < sqRadius || (owner->pos + owner->speed * 8.0f - cmdPos).SqLength2D() < Square(127.0f))
StopMoveAndFinishCommand();
}
}


void CAirCAI::ExecuteFight(Command& c)
{
assert((c.GetOpts() & INTERNAL_ORDER) || owner->unitDef->canFight);
const UnitDef* ownerDef = owner->unitDef;

assert((c.GetOpts() & INTERNAL_ORDER) || ownerDef->canFight);

// FIXME: check owner->UsingScriptMoveType() and skip rest if true?
AAirMoveType* myPlane = GetStrafeAirMoveType(owner);
@@ -289,9 +290,8 @@ void CAirCAI::ExecuteFight(Command& c)
}

if (c.GetNumParams() >= 6) {
if (!inCommand) {
if (!inCommand)
commandPos1 = c.GetPos(3);
}
} else {
// HACK to make sure the line (commandPos1,commandPos2) is NOT
// rotated (only shortened) if we reach this because the previous return
@@ -300,9 +300,8 @@ void CAirCAI::ExecuteFight(Command& c)
// outside the area close to the line (for a new command).
commandPos1 = ClosestPointOnLine(commandPos1, commandPos2, owner->pos);

if ((owner->pos - commandPos1).SqLength2D() > (150 * 150)) {
if ((owner->pos - commandPos1).SqLength2D() > Square(150.0f))
commandPos1 = owner->pos;
}
}

float3 goalPos = c.GetPos(0);
@@ -311,21 +310,19 @@ void CAirCAI::ExecuteFight(Command& c)
inCommand = true;
commandPos2 = goalPos;
}
if (c.GetNumParams() >= 6) {
if (c.GetNumParams() >= 6)
goalPos = ClosestPointOnLine(commandPos1, commandPos2, owner->pos);
}

// CMD_FIGHT is pretty useless if !canAttack, but we try to honour the modders wishes anyway...
if (owner->unitDef->canAttack && (owner->fireState >= FIRESTATE_FIREATWILL)
&& (owner->moveState != MOVESTATE_HOLDPOS) && (owner->maxRange > 0))
if ((owner->fireState >= FIRESTATE_FIREATWILL) && (owner->moveState != MOVESTATE_HOLDPOS) && (owner->maxRange > 0.0f) && ownerDef->canAttack)
{
CUnit* enemy = NULL;
CUnit* enemy = nullptr;

if (owner->unitDef->IsFighterAirUnit()) {
const float3 P = ClosestPointOnLine(commandPos1, commandPos2, owner->pos + owner->speed*10);
const float R = 1000.0f * owner->moveState;
if (ownerDef->IsFighterAirUnit()) {
const float3 ofs = owner->speed * 10.0f;
const float3 pos = ClosestPointOnLine(commandPos1, commandPos2, owner->pos + ofs);

enemy = CGameHelper::GetClosestEnemyAircraft(NULL, P, R, owner->allyteam);
enemy = CGameHelper::GetClosestEnemyAircraft(nullptr, pos, 1000.0f * owner->moveState, owner->allyteam);
}
if (IsValidTarget(enemy) && (owner->moveState != MOVESTATE_MANEUVER
|| LinePointDist(commandPos1, commandPos2, enemy->pos) < 1000))
@@ -348,12 +345,13 @@ void CAirCAI::ExecuteFight(Command& c)
lastPC1 = gs->frameNum;
SlowUpdate();
}

return;
} else {
const float3 P = ClosestPointOnLine(commandPos1, commandPos2, owner->pos + owner->speed * 20);
const float R = 500.0f * owner->moveState;
const float3 ofs = owner->speed * 20.0f;
const float3 pos = ClosestPointOnLine(commandPos1, commandPos2, owner->pos + ofs);

enemy = CGameHelper::GetClosestValidTarget(P, R, owner->allyteam, this);
enemy = CGameHelper::GetClosestValidTarget(pos, 500.0f * owner->moveState, owner->allyteam, this);

if (enemy != nullptr) {
PushOrUpdateReturnFight();
@@ -522,15 +520,15 @@ int CAirCAI::GetDefaultCmd(const CUnit* pointed, const CFeature* feature)
{
if (pointed) {
if (!teamHandler.Ally(gu->myAllyTeam, pointed->allyteam)) {
if (owner->unitDef->canAttack) {
if (owner->unitDef->canAttack)
return CMD_ATTACK;
}

} else {
if (owner->unitDef->canGuard) {
if (owner->unitDef->canGuard)
return CMD_GUARD;
}
}
}

return CMD_MOVE;
}

Oops, something went wrong.

0 comments on commit 198e315

Please sign in to comment.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.