diff --git a/rts/Game/GameHelper.cpp b/rts/Game/GameHelper.cpp index d06c651f5ab..616c2fff7da 100644 --- a/rts/Game/GameHelper.cpp +++ b/rts/Game/GameHelper.cpp @@ -478,7 +478,7 @@ namespace { Enemy_InLos(nullptr, at), cai(cai) {} bool Unit(const CUnit* u) { - return Enemy_InLos::Unit(u) && cai->IsValidTarget(u); + return Enemy_InLos::Unit(u) && cai->IsValidTarget(u, nullptr); } }; diff --git a/rts/Sim/MoveTypes/GroundMoveType.cpp b/rts/Sim/MoveTypes/GroundMoveType.cpp index 1b7c664b197..bcab0f8a34d 100644 --- a/rts/Sim/MoveTypes/GroundMoveType.cpp +++ b/rts/Sim/MoveTypes/GroundMoveType.cpp @@ -1311,7 +1311,6 @@ void CGroundMoveType::ReRequestPath(bool forceRequest) { } wantRepath = true; - return; } diff --git a/rts/Sim/Units/CommandAI/AirCAI.cpp b/rts/Sim/Units/CommandAI/AirCAI.cpp index 2c27fddfd20..b0f78bfe90a 100644 --- a/rts/Sim/Units/CommandAI/AirCAI.cpp +++ b/rts/Sim/Units/CommandAI/AirCAI.cpp @@ -238,13 +238,12 @@ bool CAirCAI::AirAutoGenerateTarget(AAirMoveType* myPlane) { tgt = CGameHelper::GetClosestValidTarget(owner->pos + owner->speed * 20.0f, searchRadius, owner->allyteam, this); } - if (!IsValidTarget(tgt)) + if (!IsValidTarget(tgt, const_cast(wpn))) 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); + commandQue.push_front(Command(CMD_ATTACK, INTERNAL_ORDER, tgt->id)); inCommand = false; return true; } @@ -314,8 +313,7 @@ void CAirCAI::ExecuteFight(Command& c) goalPos = ClosestPointOnLine(commandPos1, commandPos2, owner->pos); // CMD_FIGHT is pretty useless if !canAttack, but we try to honour the modders wishes anyway... - if ((owner->fireState >= FIRESTATE_FIREATWILL) && (owner->moveState != MOVESTATE_HOLDPOS) && (owner->maxRange > 0.0f) && ownerDef->canAttack) - { + if ((owner->fireState >= FIRESTATE_FIREATWILL) && (owner->moveState != MOVESTATE_HOLDPOS) && (owner->maxRange > 0.0f) && ownerDef->canAttack) { CUnit* enemy = nullptr; if (ownerDef->IsFighterAirUnit()) { @@ -324,9 +322,8 @@ void CAirCAI::ExecuteFight(Command& c) enemy = CGameHelper::GetClosestEnemyAircraft(nullptr, pos, 1000.0f * owner->moveState, owner->allyteam); } - if (IsValidTarget(enemy) && (owner->moveState != MOVESTATE_MANEUVER - || LinePointDist(commandPos1, commandPos2, enemy->pos) < 1000)) - { + + if (IsValidTarget(enemy, nullptr) && (owner->moveState != MOVESTATE_MANEUVER || LinePointDist(commandPos1, commandPos2, enemy->pos) < 1000)) { // make the attack-command inherit 's options // (if is internal, then so are the attacks) // @@ -335,8 +332,7 @@ void CAirCAI::ExecuteFight(Command& c) // noAutoTarget set (although the CUnit* // is technically not a user-target, we treat it // as such) even when explicitly told to fight - Command nc(CMD_ATTACK, c.GetOpts(), enemy->id); - commandQue.push_front(nc); + commandQue.push_front(Command(CMD_ATTACK, c.GetOpts(), enemy->id)); tempOrder = true; inCommand = false; @@ -347,18 +343,17 @@ void CAirCAI::ExecuteFight(Command& c) } return; - } else { + } + + { const float3 ofs = owner->speed * 20.0f; const float3 pos = ClosestPointOnLine(commandPos1, commandPos2, owner->pos + ofs); - enemy = CGameHelper::GetClosestValidTarget(pos, 500.0f * owner->moveState, owner->allyteam, this); - - if (enemy != nullptr) { + if ((enemy = CGameHelper::GetClosestValidTarget(pos, 500.0f * owner->moveState, owner->allyteam, this)) != nullptr) { PushOrUpdateReturnFight(); // make the attack-command inherit 's options - Command nc(CMD_ATTACK, c.GetOpts(), enemy->id); - commandQue.push_front(nc); + commandQue.push_front(Command(CMD_ATTACK, c.GetOpts(), enemy->id)); tempOrder = true; inCommand = false; @@ -496,11 +491,10 @@ void CAirCAI::ExecuteGuard(Command& c) (owner->maxRange > 0.0f) && owner->unitDef->canAttack && ((guardee->lastAttackFrame + 40) < gs->frameNum) && - IsValidTarget(guardee->lastAttacker); + IsValidTarget(guardee->lastAttacker, nullptr); if (pushAttackCommand) { - Command nc(CMD_ATTACK, c.GetOpts() | INTERNAL_ORDER, guardee->lastAttacker->id); - commandQue.push_front(nc); + commandQue.push_front(Command(CMD_ATTACK, c.GetOpts() | INTERNAL_ORDER, guardee->lastAttacker->id)); SlowUpdate(); } else { Command c2(CMD_MOVE, c.GetOpts() | INTERNAL_ORDER); @@ -518,7 +512,7 @@ void CAirCAI::ExecuteGuard(Command& c) int CAirCAI::GetDefaultCmd(const CUnit* pointed, const CFeature* feature) { - if (pointed) { + if (pointed != nullptr) { if (!teamHandler.Ally(gu->myAllyTeam, pointed->allyteam)) { if (owner->unitDef->canAttack) return CMD_ATTACK; @@ -532,9 +526,11 @@ int CAirCAI::GetDefaultCmd(const CUnit* pointed, const CFeature* feature) return CMD_MOVE; } -bool CAirCAI::IsValidTarget(const CUnit* enemy) const { - if (!CMobileCAI::IsValidTarget(enemy)) return false; - if (enemy->IsCrashing()) return false; +bool CAirCAI::IsValidTarget(const CUnit* enemy, CWeapon* weapon) const { + if (!CMobileCAI::IsValidTarget(enemy, weapon)) + return false; + if (enemy->IsCrashing()) + return false; return (GetStrafeAirMoveType(owner)->isFighter || !enemy->unitDef->canfly); } diff --git a/rts/Sim/Units/CommandAI/AirCAI.h b/rts/Sim/Units/CommandAI/AirCAI.h index 108834f4bac..54fcd8ac064 100644 --- a/rts/Sim/Units/CommandAI/AirCAI.h +++ b/rts/Sim/Units/CommandAI/AirCAI.h @@ -32,7 +32,7 @@ class CAirCAI : public CMobileCAI void ExecuteFight(Command& c); void ExecuteMove(Command& c); - bool IsValidTarget(const CUnit* enemy) const; + bool IsValidTarget(const CUnit* enemy, CWeapon* weapon) const override; private: bool AirAutoGenerateTarget(AAirMoveType*); diff --git a/rts/Sim/Units/CommandAI/MobileCAI.cpp b/rts/Sim/Units/CommandAI/MobileCAI.cpp index 1939dc34c7b..f758b513091 100644 --- a/rts/Sim/Units/CommandAI/MobileCAI.cpp +++ b/rts/Sim/Units/CommandAI/MobileCAI.cpp @@ -556,7 +556,7 @@ void CMobileCAI::ExecuteFight(Command& c) ExecuteMove(c); } -bool CMobileCAI::IsValidTarget(const CUnit* enemy) const { +bool CMobileCAI::IsValidTarget(const CUnit* enemy, CWeapon* weapon) const { if (enemy == nullptr) return false; @@ -570,15 +570,18 @@ bool CMobileCAI::IsValidTarget(const CUnit* enemy) const { if (enemy->IsNeutral()) return false; + // test if given weapon belonging to owner can target + // the enemy unit; indicates an auto-targeting context + if (weapon != nullptr) + return (weapon->TestTarget(enemy->pos, {enemy}) && (owner->moveState != MOVESTATE_HOLDPOS || weapon->TryTargetRotate(enemy, false, false))); + + // test if any of owner's weapons can target the enemy unit if (owner->weapons.empty()) return false; - // test if any weapon can target the enemy unit for (CWeapon* w: owner->weapons) { - if (w->TestTarget(enemy->pos, SWeaponTarget(enemy)) && - (owner->moveState != MOVESTATE_HOLDPOS || w->TryTargetRotate(enemy, false, false))) { + if (w->TestTarget(enemy->pos, SWeaponTarget(enemy)) && (owner->moveState != MOVESTATE_HOLDPOS || w->TryTargetRotate(enemy, false, false))) return true; - } } return false; @@ -610,7 +613,7 @@ void CMobileCAI::ExecuteGuard(Command& c) const bool pushAttackCommand = owner->unitDef->canAttack && (guardee->lastAttackFrame + 40 < gs->frameNum) && - IsValidTarget(guardee->lastAttacker); + IsValidTarget(guardee->lastAttacker, nullptr); if (pushAttackCommand) { commandQue.push_front(Command(CMD_ATTACK, c.GetOpts(), guardee->lastAttacker->id)); @@ -1156,13 +1159,13 @@ bool CMobileCAI::GenerateAttackCmd() for (CWeapon* w: owner->weapons) { const SWeaponTarget& wTgt = w->GetCurrentTarget(); - if (w->HaveTarget() && !eventHandler.AllowWeaponTarget(owner->id, wTgt.unit->id, w->weaponNum, w->weaponDef->id, nullptr)) - continue; - + // no current target, and nothing to auto-target if (!w->HaveTarget() && !w->AutoTarget()) continue; - - if (wTgt.type != Target_Unit || !IsValidTarget(wTgt.unit)) + // maybe a current target, but invalid type or category etc + if (wTgt.type != Target_Unit || !IsValidTarget(wTgt.unit, w)) + continue; + if (!eventHandler.AllowWeaponTarget(owner->id, wTgt.unit->id, w->weaponNum, w->weaponDef->id, nullptr)) continue; newAttackTargetId = wTgt.unit->id; diff --git a/rts/Sim/Units/CommandAI/MobileCAI.h b/rts/Sim/Units/CommandAI/MobileCAI.h index 5a05cb39dc5..79ba87ffb28 100644 --- a/rts/Sim/Units/CommandAI/MobileCAI.h +++ b/rts/Sim/Units/CommandAI/MobileCAI.h @@ -54,7 +54,7 @@ class CMobileCAI : public CCommandAI int GetCancelDistance() { return cancelDistance; } - virtual bool IsValidTarget(const CUnit* enemy) const; + virtual bool IsValidTarget(const CUnit* enemy, CWeapon* weapon) const; virtual bool CanWeaponAutoTarget(const CWeapon* weapon) const override; void SetTransportee(CUnit* unit);