enable battleground

This commit is contained in:
Yunfan Li
2023-10-19 00:20:45 +08:00
parent e5e05988b2
commit 29b748803e
16 changed files with 151 additions and 36 deletions

View File

@@ -604,11 +604,12 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
{
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig->nonCombatStrategies);
}
// nonCombatEngine->addStrategy("battleground");
// nonCombatEngine->addStrategy("warsong");
// Battleground switch
if (player->InBattleground() && player->GetBattleground())
{
nonCombatEngine->addStrategies("nc", "chat", "default", "buff", "food", "mount", "pvp", "collision", "dps assist", "attack tagged", nullptr);
nonCombatEngine->addStrategies("nc", "chat", "default", "buff", "food", "mount", "pvp", "dps assist", "attack tagged", nullptr);
nonCombatEngine->removeStrategy("custom::say");
nonCombatEngine->removeStrategy("travel");
nonCombatEngine->removeStrategy("rpg");

View File

@@ -1327,8 +1327,8 @@ void PlayerbotAI::ResetStrategies(bool load)
AiFactory::AddDefaultNonCombatStrategies(bot, this, engines[BOT_STATE_NON_COMBAT]);
AiFactory::AddDefaultDeadStrategies(bot, this, engines[BOT_STATE_DEAD]);
if (load)
sPlayerbotDbStore->Load(this);
// if (load)
// sPlayerbotDbStore->Load(this);
}
bool PlayerbotAI::IsRanged(Player* player)
@@ -1969,15 +1969,16 @@ bool PlayerbotAI::HasAura(uint32 spellId, Unit const* unit)
{
if (!spellId || !unit)
return false;
return unit->HasAura(spellId);
// for (uint8 effect = EFFECT_0; effect <= EFFECT_2; effect++)
// {
// AuraEffect const* aurEff = unit->GetAuraEffect(spellId, effect);
// if (IsRealAura(bot, aurEff, unit))
// return true;
// }
for (uint8 effect = EFFECT_0; effect <= EFFECT_2; effect++)
{
AuraEffect const* aurEff = unit->GetAuraEffect(spellId, effect);
if (IsRealAura(bot, aurEff, unit))
return true;
}
return false;
// return false;
}
Aura* PlayerbotAI::GetAura(std::string const name, Unit* unit, bool checkIsOwner, bool checkDuration, int checkStack)

View File

@@ -881,7 +881,7 @@ bool RandomPlayerbotMgr::ProcessBot(Player* player)
if (!GetEventValue(bot, "dead"))
{
uint32 randomTime = urand(sPlayerbotAIConfig->minRandomBotReviveTime, sPlayerbotAIConfig->maxRandomBotReviveTime);
LOG_INFO("playerbots", "Mark bot {} as dead, will be revived in {}s.", player->GetName().c_str(), randomTime);
// LOG_INFO("playerbots", "Mark bot {} as dead, will be revived in {}s.", player->GetName().c_str(), randomTime);
SetEventValue(bot, "dead", 1, sPlayerbotAIConfig->maxRandomBotInWorldTime);
SetEventValue(bot, "revive", 1, randomTime);
return false;
@@ -963,7 +963,7 @@ void RandomPlayerbotMgr::Revive(Player* player)
{
uint32 bot = player->GetGUID().GetCounter();
LOG_INFO("playerbots", "Bot {} revived", player->GetName().c_str());
// LOG_INFO("playerbots", "Bot {} revived", player->GetName().c_str());
SetEventValue(bot, "dead", 0, 0);
SetEventValue(bot, "revive", 0, 0);

View File

@@ -90,7 +90,7 @@ class StrategyContext : public NamedObjectContext<Strategy>
creators["ranged"] = &StrategyContext::ranged;
creators["behind"] = &StrategyContext::behind;
creators["bg"] = &StrategyContext::bg;
creators["Battleground"] = &StrategyContext::Battleground;
creators["battleground"] = &StrategyContext::battleground;
creators["warsong"] = &StrategyContext::warsong;
creators["alterac"] = &StrategyContext::alterac;
creators["arathi"] = &StrategyContext::arathi;
@@ -151,7 +151,7 @@ class StrategyContext : public NamedObjectContext<Strategy>
static Strategy* possible_adds(PlayerbotAI* botAI) { return new PossibleAddsStrategy(botAI); }
static Strategy* mount(PlayerbotAI* botAI) { return new MountStrategy(botAI); }
static Strategy* bg(PlayerbotAI* botAI) { return new BGStrategy(botAI); }
static Strategy* Battleground(PlayerbotAI* botAI) { return new BattlegroundStrategy(botAI); }
static Strategy* battleground(PlayerbotAI* botAI) { return new BattlegroundStrategy(botAI); }
static Strategy* warsong(PlayerbotAI* botAI) { return new WarsongStrategy(botAI); }
static Strategy* alterac(PlayerbotAI* botAI) { return new AlteracStrategy(botAI); }
static Strategy* arathi(PlayerbotAI* botAI) { return new ArathiStrategy(botAI); }

View File

@@ -8,6 +8,7 @@
#include "BattlegroundMgr.h"
#include "Event.h"
#include "GroupMgr.h"
#include "PlayerbotAI.h"
#include "Playerbots.h"
#include "PositionValue.h"
@@ -466,7 +467,8 @@ bool BGJoinAction::JoinQueue(uint32 type)
// get battlemaster
Unit* unit = botAI->GetUnit(AI_VALUE2(CreatureData const*, "bg master", bgTypeId));
if (!unit && isArena)
{
{
botAI->GetAiObjectContext()->GetValue<uint32>("bg type")->Set(0);
LOG_DEBUG("playerbots", "Bot {} could not find Battlemaster to join", bot->GetGUID().ToString().c_str());
return false;
}
@@ -1102,3 +1104,17 @@ bool BGStatusCheckAction::isUseful()
{
return bot->InBattlegroundQueue();
}
bool BGStrategyCheckAction::Execute(Event event)
{
bool inside_bg = bot->InBattleground() && bot->GetBattleground();;
if (!inside_bg && botAI->HasStrategy("battleground", BOT_STATE_NON_COMBAT)) {
botAI->ResetStrategies();
return true;
}
if (inside_bg && !botAI->HasStrategy("battleground", BOT_STATE_NON_COMBAT)) {
botAI->ResetStrategies();
return false;
}
return false;
}

View File

@@ -66,4 +66,11 @@ class BGStatusCheckAction : public Action
bool isUseful() override;
};
class BGStrategyCheckAction : public Action
{
public:
BGStrategyCheckAction(PlayerbotAI* botAI, std::string const name = "bg strategy check") : Action(botAI, name) { }
bool Execute(Event event) override;
};
#endif

View File

@@ -120,7 +120,7 @@ bool EquipUpgradesAction::Execute(Event event)
ItemUsage usage = AI_VALUE2(ItemUsage, "item usage", i->first);
if (usage == ITEM_USAGE_EQUIP || usage == ITEM_USAGE_REPLACE || usage == ITEM_USAGE_BAD_EQUIP)
{
LOG_INFO("playerbots", "Bot {} <{}> auto equips item {} ({})", bot->GetGUID().ToString().c_str(), bot->GetName().c_str(), i->first, usage == 1 ? "no item in slot" : usage == 2 ? "replace" : usage == 3 ? "wrong item but empty slot" : "");
// LOG_INFO("playerbots", "Bot {} <{}> auto equips item {} ({})", bot->GetGUID().ToString().c_str(), bot->GetName().c_str(), i->first, usage == 1 ? "no item in slot" : usage == 2 ? "replace" : usage == 3 ? "wrong item but empty slot" : "");
items.insert(i->first);
}
}

View File

@@ -5,6 +5,8 @@
#include "ReleaseSpiritAction.h"
#include "Event.h"
#include "GameGraveyard.h"
#include "ObjectDefines.h"
#include "ObjectGuid.h"
#include "Playerbots.h"
#include "ServerFacade.h"
@@ -43,17 +45,34 @@ bool ReleaseSpiritAction::Execute(Event event)
packet << uint8(0);
bot->GetSession()->HandleRepopRequestOpcode(packet);
// add waiting for ress aura
if (bot->InBattleground() && !botAI->HasAura(2584, bot))
{
// cast Waiting for Resurrect
bot->CastSpell(bot, 2584, true);
}
// add waiting for ress aura
if (bot->InBattleground())
bot->CastSpell(bot, 2584, true);
// // add waiting for ress aura
// if (bot->InBattleground() && !botAI->HasAura(SPELL_WAITING_FOR_RESURRECT, bot) && !bot->IsAlive())
// {
// // cast Waiting for Resurrect
// GuidVector npcs = AI_VALUE(GuidVector, "nearest npcs");
// ObjectGuid guid;
// Unit* unit;
// for (GuidVector::iterator i = npcs.begin(); i != npcs.end(); i++)
// {
// unit = botAI->GetUnit(*i);
// if (unit && unit->IsSpiritService())
// {
// guid = unit->GetGUID();
// break;
// }
// }
// if (!guid) {
// return true;
// }
// if (bot->GetDistance(unit) >= INTERACTION_DISTANCE) {
// bot->GetMotionMaster()->MoveChase(unit);
// } else {
// WorldPacket packet(CMSG_GOSSIP_HELLO);
// packet << guid;
// bot->GetSession()->HandleGossipHelloOpcode(packet);
// }
// }
return true;
}
@@ -75,10 +94,31 @@ bool AutoReleaseSpiritAction::Execute(Event event)
LOG_DEBUG("playerbots", "Bot {} {}:{} <{}> releases spirit", bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName().c_str());
if (bot->InBattleground() && !botAI->HasAura(2584, bot))
if (bot->InBattleground() && (time(NULL) - bg_gossip_time >= 15 || !bot->HasAura(SPELL_WAITING_FOR_RESURRECT)))
{
// cast Waiting for Resurrect
bot->CastSpell(bot, 2584, true);
GuidVector npcs = AI_VALUE(GuidVector, "nearest npcs");
ObjectGuid guid;
Unit* unit;
for (GuidVector::iterator i = npcs.begin(); i != npcs.end(); i++)
{
unit = botAI->GetUnit(*i);
if (unit && unit->IsSpiritService())
{
guid = unit->GetGUID();
break;
}
}
if (!guid) {
return true;
}
if (bot->GetDistance(unit) >= INTERACTION_DISTANCE) {
bot->GetMotionMaster()->MoveChase(unit);
} else {
bg_gossip_time = time(NULL);
WorldPacket packet(CMSG_GOSSIP_HELLO);
packet << guid;
bot->GetSession()->HandleGossipHelloOpcode(packet);
}
}
return true;
@@ -93,7 +133,7 @@ bool AutoReleaseSpiritAction::isUseful()
return false;
if (bot->InBattleground())
return !bot->GetCorpse();
return true;
if (bot->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
return false;

View File

@@ -7,6 +7,7 @@
#include "Action.h"
#include "ReviveFromCorpseAction.h"
#include <cstdint>
class PlayerbotAI;
@@ -25,6 +26,8 @@ class AutoReleaseSpiritAction : public ReleaseSpiritAction
bool Execute(Event event) override;
bool isUseful() override;
private:
uint32_t bg_gossip_time = 0;
};
class RepopAction : public SpiritHealerAction

View File

@@ -90,8 +90,8 @@ bool FindCorpseAction::Execute(Event event)
{
if (dCount >= 5)
{
LOG_INFO("playerbots", "Bot {} {}:{} <{}>: died too many times, was revived and teleported",
bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName().c_str());
// LOG_INFO("playerbots", "Bot {} {}:{} <{}>: died too many times, was revived and teleported",
// bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->getLevel(), bot->GetName().c_str());
context->GetValue<uint32>("death count")->Set(0);
// sRandomPlayerbotMgr->RandomTeleportForLevel(bot);
sRandomPlayerbotMgr->Revive(bot);

View File

@@ -77,6 +77,7 @@ class WorldPacketActionContext : public NamedObjectContext<Action>
creators["guild accept"] = &WorldPacketActionContext::guild_accept;
creators["inventory change failure"] = &WorldPacketActionContext::inventory_change_failure;
creators["bg status check"] = &WorldPacketActionContext::bg_status_check;
creators["bg strategy check"] = &WorldPacketActionContext::bg_strategy_check;
creators["bg status"] = &WorldPacketActionContext::bg_status;
creators["bg join"] = &WorldPacketActionContext::bg_join;
creators["bg leave"] = &WorldPacketActionContext::bg_leave;
@@ -129,6 +130,7 @@ class WorldPacketActionContext : public NamedObjectContext<Action>
static Action* bg_leave(PlayerbotAI* botAI) { return new BGLeaveAction(botAI); }
static Action* bg_status(PlayerbotAI* botAI) { return new BGStatusAction(botAI); }
static Action* bg_status_check(PlayerbotAI* botAI) { return new BGStatusCheckAction(botAI); }
static Action* bg_strategy_check(PlayerbotAI* botAI) { return new BGStrategyCheckAction(botAI); }
static Action* arena_tactics(PlayerbotAI* botAI) { return new ArenaTactics(botAI); }
static Action* petition_sign(PlayerbotAI* botAI) { return new PetitionSignAction(botAI); }
static Action* lfg_teleport(PlayerbotAI* botAI) { return new LfgTeleportAction(botAI); }

View File

@@ -7,8 +7,9 @@
void BGStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
{
triggers.push_back(new TriggerNode("random", NextAction::array(0, new NextAction("bg join", relevance), nullptr)));
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("bg join", relevance), nullptr)));
triggers.push_back(new TriggerNode("bg invite active", NextAction::array(0, new NextAction("bg status check", relevance), nullptr)));
triggers.push_back(new TriggerNode("timer", NextAction::array(0, new NextAction("bg strategy check", relevance), nullptr)));
}
BGStrategy::BGStrategy(PlayerbotAI* botAI) : PassTroughStrategy(botAI)

View File

@@ -93,6 +93,11 @@ bool BgInviteActiveTrigger::IsActive()
return false;
}
bool InsideBGTrigger::IsActive()
{
return bot->InBattleground() && bot->GetBattleground();
}
bool PlayerIsInBattlegroundWithoutFlag::IsActive()
{
if (botAI->GetBot()->InBattleground())

View File

@@ -97,6 +97,13 @@ class BgInviteActiveTrigger : public Trigger
bool IsActive() override;
};
class InsideBGTrigger : public Trigger
{
public:
InsideBGTrigger(PlayerbotAI* botAI) : Trigger(botAI, "inside bg", 1) { }
bool IsActive() override;
};
class PlayerIsInBattlegroundWithoutFlag : public Trigger
{
public:

View File

@@ -146,6 +146,7 @@ class TriggerContext : public NamedObjectContext<Trigger>
creators["bg waiting"] = &TriggerContext::bg_waiting;
creators["bg active"] = &TriggerContext::bg_active;
creators["bg invite active"] = &TriggerContext::bg_invite_active;
creators["inside bg"] = &TriggerContext::inside_bg;
creators["player has no flag"] = &TriggerContext::player_has_no_flag;
creators["player has flag"] = &TriggerContext::player_has_flag;
creators["team has flag"] = &TriggerContext::team_has_flag;
@@ -295,6 +296,7 @@ class TriggerContext : public NamedObjectContext<Trigger>
static Trigger* bg_waiting(PlayerbotAI* botAI) { return new BgWaitingTrigger(botAI); }
static Trigger* bg_active(PlayerbotAI* botAI) { return new BgActiveTrigger(botAI); }
static Trigger* bg_invite_active(PlayerbotAI* botAI) { return new BgInviteActiveTrigger(botAI); }
static Trigger* inside_bg(PlayerbotAI* botAI) { return new InsideBGTrigger(botAI); }
static Trigger* player_has_no_flag(PlayerbotAI* botAI) { return new PlayerHasNoFlag(botAI); }
static Trigger* player_has_flag(PlayerbotAI* botAI) { return new PlayerHasFlag(botAI); }
static Trigger* team_has_flag(PlayerbotAI* botAI) { return new TeamHasFlag(botAI); }

View File

@@ -29,6 +29,35 @@ class FindLeastHpTargetStrategy : public FindTargetStrategy
float minHealth;
};
class FindMaxThreatGapTargetStrategy : public FindTargetStrategy
{
public:
FindMaxThreatGapTargetStrategy(PlayerbotAI* botAI) : FindTargetStrategy(botAI), minThreat(0) { }
void CheckAttacker(Unit* attacker, ThreatMgr* threatMgr) override
{
if (Group* group = botAI->GetBot()->GetGroup())
{
ObjectGuid guid = group->GetTargetIcon(4);
if (guid && attacker->GetGUID() == guid)
return;
}
if (!attacker->IsAlive()) {
return;
}
Unit* victim = attacker->GetVictim();
if (!result || CalcThreatGap(attacker, threatMgr) > CalcThreatGap(result, &result->GetThreatMgr()))
result = attacker;
}
float CalcThreatGap(Unit* attacker, ThreatMgr* threatMgr) {
Unit* victim = attacker->GetVictim();
return threatMgr->GetThreat(victim) - threatMgr->GetThreat(attacker);
}
protected:
float minThreat;
};
Unit* DpsTargetValue::Calculate()
{
Unit* rti = RtiTargetValue::Calculate();
@@ -36,6 +65,7 @@ Unit* DpsTargetValue::Calculate()
return rti;
FindLeastHpTargetStrategy strategy(botAI);
// FindMaxThreatGapTargetStrategy strategy(botAI);
return TargetValue::FindTarget(&strategy);
}