diff --git a/src/AiFactory.cpp b/src/AiFactory.cpp index 53d8f564..33b320a5 100644 --- a/src/AiFactory.cpp +++ b/src/AiFactory.cpp @@ -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"); diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 50f81aac..86341693 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -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) diff --git a/src/RandomPlayerbotMgr.cpp b/src/RandomPlayerbotMgr.cpp index 947dfdc9..440d9ed6 100644 --- a/src/RandomPlayerbotMgr.cpp +++ b/src/RandomPlayerbotMgr.cpp @@ -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); diff --git a/src/strategy/StrategyContext.h b/src/strategy/StrategyContext.h index 318e5387..0de14d19 100644 --- a/src/strategy/StrategyContext.h +++ b/src/strategy/StrategyContext.h @@ -90,7 +90,7 @@ class StrategyContext : public NamedObjectContext 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 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); } diff --git a/src/strategy/actions/BattleGroundJoinAction.cpp b/src/strategy/actions/BattleGroundJoinAction.cpp index 2af1f418..951f0dc1 100644 --- a/src/strategy/actions/BattleGroundJoinAction.cpp +++ b/src/strategy/actions/BattleGroundJoinAction.cpp @@ -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("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; +} \ No newline at end of file diff --git a/src/strategy/actions/BattleGroundJoinAction.h b/src/strategy/actions/BattleGroundJoinAction.h index 33285857..b112d508 100644 --- a/src/strategy/actions/BattleGroundJoinAction.h +++ b/src/strategy/actions/BattleGroundJoinAction.h @@ -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 diff --git a/src/strategy/actions/EquipAction.cpp b/src/strategy/actions/EquipAction.cpp index 0edc4191..bda823e6 100644 --- a/src/strategy/actions/EquipAction.cpp +++ b/src/strategy/actions/EquipAction.cpp @@ -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); } } diff --git a/src/strategy/actions/ReleaseSpiritAction.cpp b/src/strategy/actions/ReleaseSpiritAction.cpp index b950f9e1..50351bfd 100644 --- a/src/strategy/actions/ReleaseSpiritAction.cpp +++ b/src/strategy/actions/ReleaseSpiritAction.cpp @@ -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; diff --git a/src/strategy/actions/ReleaseSpiritAction.h b/src/strategy/actions/ReleaseSpiritAction.h index 4102ab37..00652188 100644 --- a/src/strategy/actions/ReleaseSpiritAction.h +++ b/src/strategy/actions/ReleaseSpiritAction.h @@ -7,6 +7,7 @@ #include "Action.h" #include "ReviveFromCorpseAction.h" +#include 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 diff --git a/src/strategy/actions/ReviveFromCorpseAction.cpp b/src/strategy/actions/ReviveFromCorpseAction.cpp index d8ae366f..7096283a 100644 --- a/src/strategy/actions/ReviveFromCorpseAction.cpp +++ b/src/strategy/actions/ReviveFromCorpseAction.cpp @@ -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("death count")->Set(0); // sRandomPlayerbotMgr->RandomTeleportForLevel(bot); sRandomPlayerbotMgr->Revive(bot); diff --git a/src/strategy/actions/WorldPacketActionContext.h b/src/strategy/actions/WorldPacketActionContext.h index 276b84e7..ed96eecb 100644 --- a/src/strategy/actions/WorldPacketActionContext.h +++ b/src/strategy/actions/WorldPacketActionContext.h @@ -77,6 +77,7 @@ class WorldPacketActionContext : public NamedObjectContext 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 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); } diff --git a/src/strategy/generic/BattlegroundStrategy.cpp b/src/strategy/generic/BattlegroundStrategy.cpp index 4a80ed8d..3c3abcd3 100644 --- a/src/strategy/generic/BattlegroundStrategy.cpp +++ b/src/strategy/generic/BattlegroundStrategy.cpp @@ -7,8 +7,9 @@ void BGStrategy::InitTriggers(std::vector &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) diff --git a/src/strategy/triggers/PvpTriggers.cpp b/src/strategy/triggers/PvpTriggers.cpp index c8704c53..4b00df4a 100644 --- a/src/strategy/triggers/PvpTriggers.cpp +++ b/src/strategy/triggers/PvpTriggers.cpp @@ -93,6 +93,11 @@ bool BgInviteActiveTrigger::IsActive() return false; } +bool InsideBGTrigger::IsActive() +{ + return bot->InBattleground() && bot->GetBattleground(); +} + bool PlayerIsInBattlegroundWithoutFlag::IsActive() { if (botAI->GetBot()->InBattleground()) diff --git a/src/strategy/triggers/PvpTriggers.h b/src/strategy/triggers/PvpTriggers.h index 19316838..11eeedd3 100644 --- a/src/strategy/triggers/PvpTriggers.h +++ b/src/strategy/triggers/PvpTriggers.h @@ -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: diff --git a/src/strategy/triggers/TriggerContext.h b/src/strategy/triggers/TriggerContext.h index de8ca78d..d030a9ba 100644 --- a/src/strategy/triggers/TriggerContext.h +++ b/src/strategy/triggers/TriggerContext.h @@ -146,6 +146,7 @@ class TriggerContext : public NamedObjectContext 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 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); } diff --git a/src/strategy/values/DpsTargetValue.cpp b/src/strategy/values/DpsTargetValue.cpp index 36f466f2..aee84ee2 100644 --- a/src/strategy/values/DpsTargetValue.cpp +++ b/src/strategy/values/DpsTargetValue.cpp @@ -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); }