diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index 39a3a044..51d57d9f 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -502,8 +502,8 @@ AiPlayerbot.AutoGearScoreLimit = 0 # "power" (bots have infinite energy, rage, and runic power) # "taxi" (bots may use all flight paths, though they will not actually learn them) # "raid" (bots use cheats implemented into raid strategies) -# To use multiple cheats, separate them by commas below (e.g., to enable all, use "gold,health,mana,power,taxi") -# Default: taxi is enabled +# To use multiple cheats, separate them by commas below (e.g., to enable all, use "gold,health,mana,power,raid,taxi") +# Default: taxi and raid are enabled AiPlayerbot.BotCheats = "taxi,raid" # @@ -1117,7 +1117,7 @@ AiPlayerbot.RandomBotArenaTeamMinRating = 1000 AiPlayerbot.DeleteRandomBotArenaTeams = 0 # PvP Restricted Zones (bots don't pvp) -AiPlayerbot.PvpProhibitedZoneIds = "2255,656,2361,2362,2363,976,35,2268,3425,392,541,1446,3828,3712,3738,3565,3539,3623,4152,3988,4658,4284,4418,4436,4275,4323,4395,3703,4298,139,3951" +AiPlayerbot.PvpProhibitedZoneIds = "2255,656,2361,2362,2363,976,35,2268,3425,392,541,1446,3828,3712,3738,3565,3539,3623,4152,3988,4658,4284,4418,4436,4275,4323,4395,3703,4298,3951" # PvP Restricted Areas (bots don't pvp) AiPlayerbot.PvpProhibitedAreaIds = "976,35,392,2268,4161,4010,4317,4312,3649,3887,3958,3724,4080" diff --git a/src/PlayerbotAIConfig.cpp b/src/PlayerbotAIConfig.cpp index b081fbf0..e35d82e3 100644 --- a/src/PlayerbotAIConfig.cpp +++ b/src/PlayerbotAIConfig.cpp @@ -148,7 +148,7 @@ bool PlayerbotAIConfig::Initialize() LoadList>( sConfigMgr->GetOption("AiPlayerbot.PvpProhibitedZoneIds", "2255,656,2361,2362,2363,976,35,2268,3425,392,541,1446,3828,3712,3738,3565," - "3539,3623,4152,3988,4658,4284,4418,4436,4275,4323,4395,3703,4298,139,3951"), + "3539,3623,4152,3988,4658,4284,4418,4436,4275,4323,4395,3703,4298,3951"), pvpProhibitedZoneIds); LoadList>(sConfigMgr->GetOption("AiPlayerbot.PvpProhibitedAreaIds", "976,35"), pvpProhibitedAreaIds); diff --git a/src/Playerbots.cpp b/src/Playerbots.cpp index 27c4c685..76b32efa 100644 --- a/src/Playerbots.cpp +++ b/src/Playerbots.cpp @@ -209,16 +209,30 @@ public: void OnPlayerGiveXP(Player* player, uint32& amount, Unit* /*victim*/, uint8 /*xpSource*/) override { - if (!player->GetSession()->IsBot()) - return; - - if (!sRandomPlayerbotMgr->IsRandomBot(player)) + // early return + if (sPlayerbotAIConfig->randomBotXPRate == 1.0 || !player) return; - if (sPlayerbotAIConfig->randomBotXPRate != 1.0) + // no XP multiplier, when player is no bot. + if (!player->GetSession()->IsBot() || !sRandomPlayerbotMgr->IsRandomBot(player)) + return; + + // no XP multiplier, when bot has group where leader is a real player. + if (Group* group = player->GetGroup()) { - amount = static_cast(std::round(static_cast(amount) * sPlayerbotAIConfig->randomBotXPRate)); + Player* leader = group->GetLeader(); + if (leader && leader != player) + { + if (PlayerbotAI* leaderBotAI = GET_PLAYERBOT_AI(leader)) + { + if (leaderBotAI->HasRealPlayerMaster()) + return; + } + } } + + // otherwise apply bot XP multiplier. + amount = static_cast(std::round(static_cast(amount) * sPlayerbotAIConfig->randomBotXPRate)); } }; diff --git a/src/strategy/warlock/WarlockActions.cpp b/src/strategy/warlock/WarlockActions.cpp index b3b57871..82e1558a 100644 --- a/src/strategy/warlock/WarlockActions.cpp +++ b/src/strategy/warlock/WarlockActions.cpp @@ -21,8 +21,8 @@ const int ITEM_SOUL_SHARD = 6265; -// Checks if the bot has less than 20 soul shards, and if so, allows casting Drain Soul -bool CastDrainSoulAction::isUseful() { return AI_VALUE2(uint32, "item count", "soul shard") < 20; } +// Checks if the bot has less than 26 soul shards, and if so, allows casting Drain Soul +bool CastDrainSoulAction::isUseful() { return AI_VALUE2(uint32, "item count", "soul shard") < 26; } // Checks if the bot's health is above a certain threshold, and if so, allows casting Life Tap bool CastLifeTapAction::isUseful() { return AI_VALUE2(uint8, "health", "self target") > sPlayerbotAIConfig->lowHealth; } diff --git a/src/strategy/warlock/WarlockAiObjectContext.cpp b/src/strategy/warlock/WarlockAiObjectContext.cpp index f4bc5ae0..39672b3d 100644 --- a/src/strategy/warlock/WarlockAiObjectContext.cpp +++ b/src/strategy/warlock/WarlockAiObjectContext.cpp @@ -29,8 +29,6 @@ public: creators["boost"] = &WarlockStrategyFactoryInternal::boost; creators["cc"] = &WarlockStrategyFactoryInternal::cc; creators["pet"] = &WarlockStrategyFactoryInternal::pet; - creators["spellstone"] = &WarlockStrategyFactoryInternal::spellstone; - creators["firestone"] = &WarlockStrategyFactoryInternal::firestone; creators["meta melee"] = &WarlockStrategyFactoryInternal::meta_melee_aoe; creators["tank"] = &WarlockStrategyFactoryInternal::tank; creators["aoe"] = &WarlockStrategyFactoryInternal::aoe; @@ -42,8 +40,6 @@ private: static Strategy* boost(PlayerbotAI* botAI) { return new WarlockBoostStrategy(botAI); } static Strategy* cc(PlayerbotAI* botAI) { return new WarlockCcStrategy(botAI); } static Strategy* pet(PlayerbotAI* botAI) { return new WarlockPetStrategy(botAI); } - static Strategy* spellstone(PlayerbotAI* botAI) { return new UseSpellstoneStrategy(botAI); } - static Strategy* firestone(PlayerbotAI* botAI) { return new UseFirestoneStrategy(botAI); } static Strategy* meta_melee_aoe(PlayerbotAI* botAI) { return new MetaMeleeAoeStrategy(botAI); } static Strategy* tank(PlayerbotAI* botAI) { return new TankWarlockStrategy(botAI); } static Strategy* aoe(PlayerbotAI* botAI) { return new AoEWarlockStrategy(botAI); } @@ -125,6 +121,20 @@ private: static Strategy* curse_of_weakness(PlayerbotAI* botAI) { return new WarlockCurseOfWeaknessStrategy(botAI); } }; +class WarlockWeaponStoneStrategyFactoryInternal : public NamedObjectContext +{ +public: + WarlockWeaponStoneStrategyFactoryInternal() : NamedObjectContext(false, true) + { + creators["firestone"] = &WarlockWeaponStoneStrategyFactoryInternal::firestone; + creators["spellstone"] = &WarlockWeaponStoneStrategyFactoryInternal::spellstone; + } + +private: + static Strategy* firestone(PlayerbotAI* ai) { return new UseFirestoneStrategy(ai); } + static Strategy* spellstone(PlayerbotAI* ai) { return new UseSpellstoneStrategy(ai); } +}; + class WarlockTriggerFactoryInternal : public NamedObjectContext { public: @@ -333,19 +343,13 @@ private: static Action* devour_magic_purge(PlayerbotAI* botAI) { return new CastDevourMagicPurgeAction(botAI); } static Action* devour_magic_cleanse(PlayerbotAI* botAI) { return new CastDevourMagicCleanseAction(botAI); } static Action* seed_of_corruption(PlayerbotAI* botAI) { return new CastSeedOfCorruptionAction(botAI); } - static Action* seed_of_corruption_on_attacker(PlayerbotAI* botAI) - { - return new CastSeedOfCorruptionOnAttackerAction(botAI); - } + static Action* seed_of_corruption_on_attacker(PlayerbotAI* botAI) { return new CastSeedOfCorruptionOnAttackerAction(botAI); } static Action* rain_of_fire(PlayerbotAI* botAI) { return new CastRainOfFireAction(botAI); } static Action* hellfire(PlayerbotAI* botAI) { return new CastHellfireAction(botAI); } static Action* shadowfury(PlayerbotAI* botAI) { return new CastShadowfuryAction(botAI); } static Action* life_tap(PlayerbotAI* botAI) { return new CastLifeTapAction(botAI); } static Action* unstable_affliction(PlayerbotAI* ai) { return new CastUnstableAfflictionAction(ai); } - static Action* unstable_affliction_on_attacker(PlayerbotAI* ai) - { - return new CastUnstableAfflictionOnAttackerAction(ai); - } + static Action* unstable_affliction_on_attacker(PlayerbotAI* ai) { return new CastUnstableAfflictionOnAttackerAction(ai); } static Action* haunt(PlayerbotAI* ai) { return new CastHauntAction(ai); } static Action* demonic_empowerment(PlayerbotAI* ai) { return new CastDemonicEmpowermentAction(ai); } static Action* metamorphosis(PlayerbotAI* ai) { return new CastMetamorphosisAction(ai); } @@ -360,10 +364,7 @@ private: static Action* searing_pain(PlayerbotAI* botAI) { return new CastSearingPainAction(botAI); } static Action* shadow_ward(PlayerbotAI* botAI) { return new CastShadowWardAction(botAI); } static Action* curse_of_agony(PlayerbotAI* botAI) { return new CastCurseOfAgonyAction(botAI); } - static Action* curse_of_agony_on_attacker(PlayerbotAI* botAI) - { - return new CastCurseOfAgonyOnAttackerAction(botAI); - } + static Action* curse_of_agony_on_attacker(PlayerbotAI* botAI) { return new CastCurseOfAgonyOnAttackerAction(botAI); } static Action* curse_of_the_elements(PlayerbotAI* ai) { return new CastCurseOfTheElementsAction(ai); } static Action* curse_of_doom(PlayerbotAI* ai) { return new CastCurseOfDoomAction(ai); } static Action* curse_of_exhaustion(PlayerbotAI* ai) { return new CastCurseOfExhaustionAction(ai); } @@ -397,6 +398,7 @@ void WarlockAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContex strategyContexts.Add(new WarlockPetStrategyFactoryInternal()); strategyContexts.Add(new WarlockSoulstoneStrategyFactoryInternal()); strategyContexts.Add(new WarlockCurseStrategyFactoryInternal()); + strategyContexts.Add(new WarlockWeaponStoneStrategyFactoryInternal()); } void WarlockAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts) diff --git a/src/strategy/warlock/WarlockTriggers.cpp b/src/strategy/warlock/WarlockTriggers.cpp index 6a6aa865..c40c1a9d 100644 --- a/src/strategy/warlock/WarlockTriggers.cpp +++ b/src/strategy/warlock/WarlockTriggers.cpp @@ -46,7 +46,7 @@ bool WarlockConjuredItemTrigger::IsActive() bool OutOfSoulShardsTrigger::IsActive() { return GetSoulShardCount(botAI->GetBot()) == 0; } -bool TooManySoulShardsTrigger::IsActive() { return GetSoulShardCount(botAI->GetBot()) >= 6; } +bool TooManySoulShardsTrigger::IsActive() { return GetSoulShardCount(botAI->GetBot()) >= 26; } bool OutOfSoulstoneTrigger::IsActive() { return GetSoulstoneCount(botAI->GetBot()) == 0; }