mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-21 20:46:22 +00:00
Merge pull request #1418 from Boxhead78/bg-tactics-rewrite
Bots Bg Tactics rewrite (WSG, AB, AV, EYE)
This commit is contained in:
@@ -482,6 +482,19 @@ bool TimerTrigger::IsActive()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TimerBGTrigger::IsActive()
|
||||
{
|
||||
time_t now = time(nullptr);
|
||||
|
||||
if (now - lastCheck >= 60)
|
||||
{
|
||||
lastCheck = now;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HasNoAuraTrigger::IsActive() { return !botAI->HasAura(getName(), GetTarget()); }
|
||||
|
||||
bool TankAssistTrigger::IsActive()
|
||||
|
||||
@@ -655,6 +655,17 @@ private:
|
||||
time_t lastCheck;
|
||||
};
|
||||
|
||||
class TimerBGTrigger : public Trigger
|
||||
{
|
||||
public:
|
||||
TimerBGTrigger(PlayerbotAI* botAI) : Trigger(botAI, "timer bg"), lastCheck(0) {}
|
||||
|
||||
bool IsActive() override;
|
||||
|
||||
private:
|
||||
time_t lastCheck;
|
||||
};
|
||||
|
||||
class TankAssistTrigger : public NoAttackersTrigger
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -5,11 +5,14 @@
|
||||
|
||||
#include "PvpTriggers.h"
|
||||
|
||||
#include "BattleGroundTactics.h"
|
||||
#include "BattlegroundEY.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "BattlegroundWS.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ServerFacade.h"
|
||||
#include "BattlegroundAV.h"
|
||||
#include "BattlegroundEY.h"
|
||||
|
||||
bool EnemyPlayerNear::IsActive() { return AI_VALUE(Unit*, "enemy player target"); }
|
||||
|
||||
@@ -161,10 +164,26 @@ bool PlayerHasFlag::IsCapturingFlag(Player* bot)
|
||||
|
||||
if (bot->GetBattlegroundTypeId() == BATTLEGROUND_EY)
|
||||
{
|
||||
// TODO we should probably add similiar logic as WSG to allow combat
|
||||
// when bot has flag but no bases are available to take it to
|
||||
BattlegroundEY* bg = (BattlegroundEY*)bot->GetBattleground();
|
||||
return bot->GetGUID() == bg->GetFlagPickerGUID();
|
||||
|
||||
// Check if bot has the flag
|
||||
if (bot->GetGUID() == bg->GetFlagPickerGUID())
|
||||
{
|
||||
// Count how many bases the bot's team owns
|
||||
uint32 controlledBases = 0;
|
||||
for (uint8 point = 0; point < EY_POINTS_MAX; ++point)
|
||||
{
|
||||
if (bg->GetCapturePointInfo(point)._ownerTeamId == bot->GetTeamId())
|
||||
controlledBases++;
|
||||
}
|
||||
|
||||
// If no bases are controlled, bot should go aggressive
|
||||
if (controlledBases == 0)
|
||||
return false; // bot has flag but no place to take it
|
||||
|
||||
// Otherwise, return false and stay defensive / move to base
|
||||
return bot->GetGUID() == bg->GetFlagPickerGUID();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -175,28 +194,30 @@ bool PlayerHasFlag::IsCapturingFlag(Player* bot)
|
||||
|
||||
bool TeamHasFlag::IsActive()
|
||||
{
|
||||
if (botAI->GetBot()->InBattleground())
|
||||
{
|
||||
if (botAI->GetBot()->GetBattlegroundTypeId() == BattlegroundTypeId::BATTLEGROUND_WS)
|
||||
{
|
||||
BattlegroundWS* bg = (BattlegroundWS*)botAI->GetBot()->GetBattleground();
|
||||
|
||||
if (bot->GetGUID() == bg->GetFlagPickerGUID(TEAM_ALLIANCE) ||
|
||||
bot->GetGUID() == bg->GetFlagPickerGUID(TEAM_HORDE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bg->GetFlagState(bg->GetOtherTeamId(bot->GetTeamId())) == BG_WS_FLAG_STATE_ON_PLAYER)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!botAI->GetBot()->InBattleground())
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (botAI->GetBot()->GetBattlegroundTypeId() != BattlegroundTypeId::BATTLEGROUND_WS)
|
||||
return false;
|
||||
|
||||
BattlegroundWS* bg = (BattlegroundWS*)botAI->GetBot()->GetBattleground();
|
||||
|
||||
ObjectGuid botGuid = bot->GetGUID();
|
||||
TeamId teamId = bot->GetTeamId();
|
||||
TeamId enemyTeamId = bg->GetOtherTeamId(teamId);
|
||||
|
||||
// If the bot is carrying any flag, don't activate
|
||||
if (botGuid == bg->GetFlagPickerGUID(TEAM_ALLIANCE) || botGuid == bg->GetFlagPickerGUID(TEAM_HORDE))
|
||||
return false;
|
||||
|
||||
// Check: Own team has enemy flag, enemy team does NOT have your flag
|
||||
bool ownTeamHasFlag = bg->GetFlagState(enemyTeamId) == BG_WS_FLAG_STATE_ON_PLAYER;
|
||||
bool enemyTeamHasFlag = bg->GetFlagState(teamId) == BG_WS_FLAG_STATE_ON_PLAYER;
|
||||
|
||||
return ownTeamHasFlag && !enemyTeamHasFlag;
|
||||
}
|
||||
|
||||
|
||||
bool EnemyTeamHasFlag::IsActive()
|
||||
{
|
||||
if (botAI->GetBot()->InBattleground())
|
||||
@@ -226,11 +247,42 @@ bool EnemyTeamHasFlag::IsActive()
|
||||
bool EnemyFlagCarrierNear::IsActive()
|
||||
{
|
||||
Unit* carrier = AI_VALUE(Unit*, "enemy flag carrier");
|
||||
return carrier && sServerFacade->IsDistanceLessOrEqualThan(sServerFacade->GetDistance2d(bot, carrier), 200.f);
|
||||
|
||||
if (!carrier || !sServerFacade->IsDistanceLessOrEqualThan(sServerFacade->GetDistance2d(bot, carrier), 100.f))
|
||||
return false;
|
||||
|
||||
// Check if there is another enemy player target closer than the FC
|
||||
Unit* nearbyEnemy = AI_VALUE(Unit*, "enemy player target");
|
||||
|
||||
if (nearbyEnemy)
|
||||
{
|
||||
float distToFC = sServerFacade->GetDistance2d(bot, carrier);
|
||||
float distToEnemy = sServerFacade->GetDistance2d(bot, nearbyEnemy);
|
||||
|
||||
// If the other enemy is significantly closer, don't pursue FC
|
||||
if (distToEnemy + 15.0f < distToFC) // Add small buffer
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TeamFlagCarrierNear::IsActive()
|
||||
{
|
||||
if (bot->GetBattlegroundTypeId() == BATTLEGROUND_WS)
|
||||
{
|
||||
BattlegroundWS* bg = dynamic_cast<BattlegroundWS*>(bot->GetBattleground());
|
||||
if (bg)
|
||||
{
|
||||
bool bothFlagsNotAtBase =
|
||||
bg->GetFlagState(TEAM_ALLIANCE) != BG_WS_FLAG_STATE_ON_BASE &&
|
||||
bg->GetFlagState(TEAM_HORDE) != BG_WS_FLAG_STATE_ON_BASE;
|
||||
|
||||
if (bothFlagsNotAtBase)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Unit* carrier = AI_VALUE(Unit*, "team flag carrier");
|
||||
return carrier && sServerFacade->IsDistanceLessOrEqualThan(sServerFacade->GetDistance2d(bot, carrier), 200.f);
|
||||
}
|
||||
@@ -259,3 +311,28 @@ bool VehicleNearTrigger::IsActive()
|
||||
}
|
||||
|
||||
bool InVehicleTrigger::IsActive() { return botAI->IsInVehicle(); }
|
||||
|
||||
bool AllianceNoSnowfallGY::IsActive()
|
||||
{
|
||||
if (!bot || bot->GetTeamId() != TEAM_ALLIANCE)
|
||||
return false;
|
||||
|
||||
Battleground* bg = bot->GetBattleground();
|
||||
if (bg && BGTactics::GetBotStrategyForTeam(bg, TEAM_ALLIANCE) != AV_STRATEGY_BALANCED)
|
||||
return false;
|
||||
|
||||
float botX = bot->GetPositionX();
|
||||
if (botX <= -562.0f)
|
||||
return false;
|
||||
|
||||
if (bot->GetBattlegroundTypeId() != BATTLEGROUND_AV)
|
||||
return false;
|
||||
|
||||
if (BattlegroundAV* av = dynamic_cast<BattlegroundAV*>(bg))
|
||||
{
|
||||
const BG_AV_NodeInfo& snowfall = av->GetAVNodeInfo(BG_AV_NODES_SNOWFALL_GRAVE);
|
||||
return snowfall.OwnerId != TEAM_ALLIANCE; // Active if the Snowfall Graveyard is NOT fully controlled by the Alliance
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -140,4 +140,12 @@ public:
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class AllianceNoSnowfallGY : public Trigger
|
||||
{
|
||||
public:
|
||||
AllianceNoSnowfallGY(PlayerbotAI* botAI) : Trigger(botAI, "alliance no snowfall gy") {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,6 +34,7 @@ public:
|
||||
creators["collision"] = &TriggerContext::collision;
|
||||
|
||||
creators["timer"] = &TriggerContext::Timer;
|
||||
creators["timer bg"] = &TriggerContext::TimerBG;
|
||||
creators["random"] = &TriggerContext::Random;
|
||||
creators["seldom"] = &TriggerContext::seldom;
|
||||
creators["often"] = &TriggerContext::often;
|
||||
@@ -177,6 +178,7 @@ public:
|
||||
creators["in Battleground"] = &TriggerContext::player_is_in_BATTLEGROUND;
|
||||
creators["in Battleground without flag"] = &TriggerContext::player_is_in_BATTLEGROUND_no_flag;
|
||||
creators["wants in bg"] = &TriggerContext::player_wants_in_bg;
|
||||
creators["alliance no snowfall gy"] = &TriggerContext::alliance_no_snowfall_gy;
|
||||
|
||||
creators["mounted"] = &TriggerContext::mounted;
|
||||
|
||||
@@ -307,6 +309,7 @@ private:
|
||||
static Trigger* NoAttackers(PlayerbotAI* botAI) { return new NoAttackersTrigger(botAI); }
|
||||
static Trigger* TankAssist(PlayerbotAI* botAI) { return new TankAssistTrigger(botAI); }
|
||||
static Trigger* Timer(PlayerbotAI* botAI) { return new TimerTrigger(botAI); }
|
||||
static Trigger* TimerBG(PlayerbotAI* botAI) { return new TimerBGTrigger(botAI); }
|
||||
static Trigger* NoTarget(PlayerbotAI* botAI) { return new NoTargetTrigger(botAI); }
|
||||
static Trigger* TargetInSight(PlayerbotAI* botAI) { return new TargetInSightTrigger(botAI); }
|
||||
static Trigger* not_dps_target_active(PlayerbotAI* botAI) { return new NotDpsTargetActiveTrigger(botAI); }
|
||||
@@ -377,10 +380,8 @@ private:
|
||||
static Trigger* enemy_team_has_flag(PlayerbotAI* botAI) { return new EnemyTeamHasFlag(botAI); }
|
||||
static Trigger* enemy_flagcarrier_near(PlayerbotAI* botAI) { return new EnemyFlagCarrierNear(botAI); }
|
||||
static Trigger* player_is_in_BATTLEGROUND(PlayerbotAI* botAI) { return new PlayerIsInBattleground(botAI); }
|
||||
static Trigger* player_is_in_BATTLEGROUND_no_flag(PlayerbotAI* botAI)
|
||||
{
|
||||
return new PlayerIsInBattlegroundWithoutFlag(botAI);
|
||||
}
|
||||
static Trigger* player_is_in_BATTLEGROUND_no_flag(PlayerbotAI* botAI) { return new PlayerIsInBattlegroundWithoutFlag(botAI); }
|
||||
static Trigger* alliance_no_snowfall_gy(PlayerbotAI* botAI) { return new AllianceNoSnowfallGY(botAI); }
|
||||
static Trigger* mounted(PlayerbotAI* botAI) { return new IsMountedTrigger(botAI); }
|
||||
static Trigger* at_dark_portal_outland(PlayerbotAI* botAI) { return new AtDarkPortalOutlandTrigger(botAI); }
|
||||
static Trigger* at_dark_portal_azeroth(PlayerbotAI* botAI) { return new AtDarkPortalAzerothTrigger(botAI); }
|
||||
|
||||
Reference in New Issue
Block a user