mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-13 00:58:33 +00:00
Compare commits
2 Commits
cafbd4681e
...
467b63b840
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
467b63b840 | ||
|
|
66f5f597bb |
@@ -239,24 +239,32 @@ public:
|
||||
|
||||
void OnPlayerGiveXP(Player* player, uint32& amount, Unit* /*victim*/, uint8 /*xpSource*/) override
|
||||
{
|
||||
if (sPlayerbotAIConfig->randomBotXPRate == 1.0f || !player || !player->IsInWorld())
|
||||
if (!player || !player->IsInWorld())
|
||||
return;
|
||||
|
||||
if (WorldSession* session = player->GetSession(); !session || !session->IsBot())
|
||||
return;
|
||||
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(player);
|
||||
if (!botAI || !sRandomPlayerbotMgr->IsRandomBot(player))
|
||||
if (!botAI)
|
||||
return;
|
||||
|
||||
// No XP gain if master is a real player with XP gain disabled
|
||||
if (const Player* master = botAI->GetMaster())
|
||||
{
|
||||
if (WorldSession* masterSession = master->GetSession();
|
||||
masterSession && !masterSession->IsBot() && master->HasPlayerFlag(PLAYER_FLAGS_NO_XP_GAIN))
|
||||
masterSession && !masterSession->IsBot() &&
|
||||
master->HasPlayerFlag(PLAYER_FLAGS_NO_XP_GAIN))
|
||||
{
|
||||
amount = 0; // disable XP multiplier
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// From here on we only care about random bots
|
||||
if (sPlayerbotAIConfig->randomBotXPRate == 1.0f || !sRandomPlayerbotMgr->IsRandomBot(player))
|
||||
return;
|
||||
|
||||
// No XP multiplier if bot is in a group with at least one real player
|
||||
if (Group* group = player->GetGroup())
|
||||
{
|
||||
@@ -264,14 +272,14 @@ public:
|
||||
{
|
||||
if (Player* member = gref->GetSource())
|
||||
{
|
||||
if (!member->GetSession()->IsBot())
|
||||
if (WorldSession* session = member->GetSession();session && !session->IsBot())
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise apply XP multiplier
|
||||
amount = static_cast<uint32>(std::round(amount * sPlayerbotAIConfig->randomBotXPRate));
|
||||
amount = static_cast<uint32>(std::round(static_cast<float>(amount) * sPlayerbotAIConfig->randomBotXPRate));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ bool AttumenTheHuntsmanMarkTargetAction::Execute(Event event)
|
||||
Unit* attumenMounted = GetFirstAliveUnitByEntry(botAI, NPC_ATTUMEN_THE_HUNTSMAN_MOUNTED);
|
||||
if (attumenMounted)
|
||||
{
|
||||
if (IsMapIDTimerManager(botAI, bot))
|
||||
if (IsInstanceTimerManager(botAI, bot))
|
||||
MarkTargetWithStar(bot, attumenMounted);
|
||||
|
||||
SetRtiTarget(botAI, "star", attumenMounted);
|
||||
@@ -57,7 +57,7 @@ bool AttumenTheHuntsmanMarkTargetAction::Execute(Event event)
|
||||
}
|
||||
else if (Unit* midnight = AI_VALUE2(Unit*, "find target", "midnight"))
|
||||
{
|
||||
if (IsMapIDTimerManager(botAI, bot))
|
||||
if (IsInstanceTimerManager(botAI, bot))
|
||||
MarkTargetWithStar(bot, midnight);
|
||||
|
||||
if (!botAI->IsAssistTankOfIndex(bot, 0))
|
||||
@@ -131,8 +131,10 @@ bool AttumenTheHuntsmanManageDpsTimerAction::Execute(Event event)
|
||||
if (!midnight)
|
||||
return false;
|
||||
|
||||
const uint32 instanceId = midnight->GetMap()->GetInstanceId();
|
||||
|
||||
if (midnight && midnight->GetHealth() == midnight->GetMaxHealth())
|
||||
attumenDpsWaitTimer.erase(KARAZHAN_MAP_ID);
|
||||
attumenDpsWaitTimer.erase(instanceId);
|
||||
|
||||
// Midnight is still present as a separate (invisible) unit after Attumen mounts
|
||||
// So this block can be reached
|
||||
@@ -143,7 +145,7 @@ bool AttumenTheHuntsmanManageDpsTimerAction::Execute(Event event)
|
||||
const time_t now = std::time(nullptr);
|
||||
|
||||
if (attumenMounted)
|
||||
attumenDpsWaitTimer.try_emplace(KARAZHAN_MAP_ID, now);
|
||||
attumenDpsWaitTimer.try_emplace(instanceId, now);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -178,7 +180,7 @@ bool MoroesMarkTargetAction::Execute(Event event)
|
||||
|
||||
if (target)
|
||||
{
|
||||
if (IsMapIDTimerManager(botAI, bot))
|
||||
if (IsInstanceTimerManager(botAI, bot))
|
||||
MarkTargetWithSkull(bot, target);
|
||||
|
||||
SetRtiTarget(botAI, "skull", target);
|
||||
@@ -297,19 +299,18 @@ bool BigBadWolfPositionBossAction::Execute(Event event)
|
||||
if (wolf->GetVictim() == bot)
|
||||
{
|
||||
const Position& position = BIG_BAD_WOLF_BOSS_POSITION;
|
||||
const float maxStep = 2.0f;
|
||||
float dist = wolf->GetExactDist2d(position);
|
||||
float distanceToPosition = wolf->GetExactDist2d(position);
|
||||
|
||||
if (dist > 0.0f && dist > maxStep)
|
||||
if (distanceToPosition > 2.0f)
|
||||
{
|
||||
float dX = position.GetPositionX() - wolf->GetPositionX();
|
||||
float dY = position.GetPositionY() - wolf->GetPositionY();
|
||||
float moveDist = std::min(maxStep, dist);
|
||||
float moveX = wolf->GetPositionX() + (dX / dist) * moveDist;
|
||||
float moveY = wolf->GetPositionY() + (dY / dist) * moveDist;
|
||||
float moveDist = std::min(5.0f, distanceToPosition);
|
||||
float moveX = wolf->GetPositionX() + (dX / distanceToPosition) * moveDist;
|
||||
float moveY = wolf->GetPositionY() + (dY / distanceToPosition) * moveDist;
|
||||
|
||||
return MoveTo(KARAZHAN_MAP_ID, moveX, moveY, position.GetPositionZ(), false, false, false, false,
|
||||
MovementPriority::MOVEMENT_COMBAT, true, false);
|
||||
MovementPriority::MOVEMENT_COMBAT, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,7 +405,7 @@ bool TheCuratorMarkAstralFlareAction::Execute(Event event)
|
||||
if (!flare)
|
||||
return false;
|
||||
|
||||
if (IsMapIDTimerManager(botAI, bot))
|
||||
if (IsInstanceTimerManager(botAI, bot))
|
||||
MarkTargetWithSkull(bot, flare);
|
||||
|
||||
SetRtiTarget(botAI, "skull", flare);
|
||||
@@ -429,17 +430,17 @@ bool TheCuratorPositionBossAction::Execute(Event event)
|
||||
if (curator->GetVictim() == bot)
|
||||
{
|
||||
const Position& position = THE_CURATOR_BOSS_POSITION;
|
||||
const float maxDistance = 3.0f;
|
||||
float distanceToBossPosition = curator->GetExactDist2d(position);
|
||||
float distanceToPosition = curator->GetExactDist2d(position);
|
||||
|
||||
if (distanceToBossPosition > maxDistance)
|
||||
if (distanceToPosition > 2.0f)
|
||||
{
|
||||
float dX = position.GetPositionX() - curator->GetPositionX();
|
||||
float dY = position.GetPositionY() - curator->GetPositionY();
|
||||
float mX = position.GetPositionX() + (dX / distanceToBossPosition) * maxDistance;
|
||||
float mY = position.GetPositionY() + (dY / distanceToBossPosition) * maxDistance;
|
||||
float moveDist = std::min(10.0f, distanceToPosition);
|
||||
float moveX = position.GetPositionX() + (dX / distanceToPosition) * moveDist;
|
||||
float moveY = position.GetPositionY() + (dY / distanceToPosition) * moveDist;
|
||||
|
||||
return MoveTo(KARAZHAN_MAP_ID, mX, mY, position.GetPositionZ(), false, false, false, false,
|
||||
return MoveTo(KARAZHAN_MAP_ID, moveX, moveY, position.GetPositionZ(), false, false, false, false,
|
||||
MovementPriority::MOVEMENT_COMBAT, true, false);
|
||||
}
|
||||
}
|
||||
@@ -997,6 +998,7 @@ bool NetherspiteManageTimersAndTrackersAction::Execute(Event event)
|
||||
if (!netherspite)
|
||||
return false;
|
||||
|
||||
const uint32 instanceId = netherspite->GetMap()->GetInstanceId();
|
||||
const ObjectGuid botGuid = bot->GetGUID();
|
||||
const time_t now = std::time(nullptr);
|
||||
|
||||
@@ -1005,8 +1007,8 @@ bool NetherspiteManageTimersAndTrackersAction::Execute(Event event)
|
||||
if (netherspite->GetHealth() == netherspite->GetMaxHealth() &&
|
||||
!netherspite->HasAura(SPELL_GREEN_BEAM_HEAL))
|
||||
{
|
||||
if (IsMapIDTimerManager(botAI, bot))
|
||||
netherspiteDpsWaitTimer.insert_or_assign(KARAZHAN_MAP_ID, now);
|
||||
if (IsInstanceTimerManager(botAI, bot))
|
||||
netherspiteDpsWaitTimer.insert_or_assign(instanceId, now);
|
||||
|
||||
if (botAI->IsTank(bot) && !bot->HasAura(SPELL_RED_BEAM_DEBUFF))
|
||||
{
|
||||
@@ -1016,8 +1018,8 @@ bool NetherspiteManageTimersAndTrackersAction::Execute(Event event)
|
||||
}
|
||||
else if (netherspite->HasAura(SPELL_NETHERSPITE_BANISHED))
|
||||
{
|
||||
if (IsMapIDTimerManager(botAI, bot))
|
||||
netherspiteDpsWaitTimer.erase(KARAZHAN_MAP_ID);
|
||||
if (IsInstanceTimerManager(botAI, bot))
|
||||
netherspiteDpsWaitTimer.erase(instanceId);
|
||||
|
||||
if (botAI->IsTank(bot))
|
||||
{
|
||||
@@ -1027,8 +1029,8 @@ bool NetherspiteManageTimersAndTrackersAction::Execute(Event event)
|
||||
}
|
||||
else if (!netherspite->HasAura(SPELL_NETHERSPITE_BANISHED))
|
||||
{
|
||||
if (IsMapIDTimerManager(botAI, bot))
|
||||
netherspiteDpsWaitTimer.try_emplace(KARAZHAN_MAP_ID, now);
|
||||
if (IsInstanceTimerManager(botAI, bot))
|
||||
netherspiteDpsWaitTimer.try_emplace(instanceId, now);
|
||||
|
||||
if (botAI->IsTank(bot) && bot->HasAura(SPELL_RED_BEAM_DEBUFF))
|
||||
{
|
||||
@@ -1443,6 +1445,7 @@ bool NightbaneManageTimersAndTrackersAction::Execute(Event event)
|
||||
if (!nightbane)
|
||||
return false;
|
||||
|
||||
const uint32 instanceId = nightbane->GetMap()->GetInstanceId();
|
||||
const ObjectGuid botGuid = bot->GetGUID();
|
||||
const time_t now = std::time(nullptr);
|
||||
|
||||
@@ -1455,18 +1458,18 @@ bool NightbaneManageTimersAndTrackersAction::Execute(Event event)
|
||||
if (botAI->IsRanged(bot))
|
||||
nightbaneRangedStep.erase(botGuid);
|
||||
|
||||
if (IsMapIDTimerManager(botAI, bot))
|
||||
nightbaneDpsWaitTimer.erase(KARAZHAN_MAP_ID);
|
||||
if (IsInstanceTimerManager(botAI, bot))
|
||||
nightbaneDpsWaitTimer.erase(instanceId);
|
||||
}
|
||||
// Erase flight phase timer and Rain of Bones tracker on ground phase and start DPS wait timer
|
||||
else if (nightbane->GetPositionZ() <= NIGHTBANE_FLIGHT_Z)
|
||||
{
|
||||
nightbaneRainOfBonesHit.erase(botGuid);
|
||||
|
||||
if (IsMapIDTimerManager(botAI, bot))
|
||||
if (IsInstanceTimerManager(botAI, bot))
|
||||
{
|
||||
nightbaneFlightPhaseStartTimer.erase(KARAZHAN_MAP_ID);
|
||||
nightbaneDpsWaitTimer.try_emplace(KARAZHAN_MAP_ID, now);
|
||||
nightbaneFlightPhaseStartTimer.erase(instanceId);
|
||||
nightbaneDpsWaitTimer.try_emplace(instanceId, now);
|
||||
}
|
||||
}
|
||||
// Erase DPS wait timer and tank and ranged position tracking and start flight phase timer
|
||||
@@ -1479,10 +1482,10 @@ bool NightbaneManageTimersAndTrackersAction::Execute(Event event)
|
||||
if (botAI->IsRanged(bot))
|
||||
nightbaneRangedStep.erase(botGuid);
|
||||
|
||||
if (IsMapIDTimerManager(botAI, bot))
|
||||
if (IsInstanceTimerManager(botAI, bot))
|
||||
{
|
||||
nightbaneDpsWaitTimer.erase(KARAZHAN_MAP_ID);
|
||||
nightbaneFlightPhaseStartTimer.try_emplace(KARAZHAN_MAP_ID, now);
|
||||
nightbaneDpsWaitTimer.erase(instanceId);
|
||||
nightbaneFlightPhaseStartTimer.try_emplace(instanceId, now);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -105,8 +105,8 @@ namespace KarazhanHelpers
|
||||
}
|
||||
}
|
||||
|
||||
// Only one bot is needed to set/reset mapwide timers
|
||||
bool IsMapIDTimerManager(PlayerbotAI* botAI, Player* bot)
|
||||
// Only one bot is needed to set/reset instance-wide timers
|
||||
bool IsInstanceTimerManager(PlayerbotAI* botAI, Player* bot)
|
||||
{
|
||||
if (Group* group = bot->GetGroup())
|
||||
{
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace KarazhanHelpers
|
||||
void MarkTargetWithCircle(Player* bot, Unit* target);
|
||||
void MarkTargetWithMoon(Player* bot, Unit* target);
|
||||
void SetRtiTarget(PlayerbotAI* botAI, const std::string& rtiName, Unit* target);
|
||||
bool IsMapIDTimerManager(PlayerbotAI* botAI, Player* bot);
|
||||
bool IsInstanceTimerManager(PlayerbotAI* botAI, Player* bot);
|
||||
Unit* GetFirstAliveUnit(const std::vector<Unit*>& units);
|
||||
Unit* GetFirstAliveUnitByEntry(PlayerbotAI* botAI, uint32 entry);
|
||||
Unit* GetNearestPlayerInRadius(Player* bot, float radius);
|
||||
|
||||
@@ -61,10 +61,11 @@ float AttumenTheHuntsmanWaitForDpsMultiplier::GetValue(Action* action)
|
||||
if (!attumenMounted)
|
||||
return 1.0f;
|
||||
|
||||
const uint32 instanceId = attumenMounted->GetMap()->GetInstanceId();
|
||||
const time_t now = std::time(nullptr);
|
||||
const uint8 dpsWaitSeconds = 8;
|
||||
|
||||
auto it = attumenDpsWaitTimer.find(KARAZHAN_MAP_ID);
|
||||
auto it = attumenDpsWaitTimer.find(instanceId);
|
||||
if (it == attumenDpsWaitTimer.end() || (now - it->second) < dpsWaitSeconds)
|
||||
{
|
||||
if (!botAI->IsMainTank(bot))
|
||||
@@ -201,10 +202,11 @@ float NetherspiteWaitForDpsMultiplier::GetValue(Action* action)
|
||||
if (!netherspite || netherspite->HasAura(SPELL_NETHERSPITE_BANISHED))
|
||||
return 1.0f;
|
||||
|
||||
const uint32 instanceId = netherspite->GetMap()->GetInstanceId();
|
||||
const time_t now = std::time(nullptr);
|
||||
const uint8 dpsWaitSeconds = 5;
|
||||
|
||||
auto it = netherspiteDpsWaitTimer.find(KARAZHAN_MAP_ID);
|
||||
auto it = netherspiteDpsWaitTimer.find(instanceId);
|
||||
if (it == netherspiteDpsWaitTimer.end() || (now - it->second) < dpsWaitSeconds)
|
||||
{
|
||||
if (!botAI->IsTank(bot))
|
||||
@@ -299,10 +301,11 @@ float NightbaneWaitForDpsMultiplier::GetValue(Action* action)
|
||||
if (!nightbane || nightbane->GetPositionZ() > NIGHTBANE_FLIGHT_Z)
|
||||
return 1.0f;
|
||||
|
||||
const uint32 instanceId = nightbane->GetMap()->GetInstanceId();
|
||||
const time_t now = std::time(nullptr);
|
||||
const uint8 dpsWaitSeconds = 8;
|
||||
|
||||
auto it = nightbaneDpsWaitTimer.find(KARAZHAN_MAP_ID);
|
||||
auto it = nightbaneDpsWaitTimer.find(instanceId);
|
||||
if (it == nightbaneDpsWaitTimer.end() || (now - it->second) < dpsWaitSeconds)
|
||||
{
|
||||
if (!botAI->IsMainTank(bot))
|
||||
|
||||
@@ -40,7 +40,7 @@ bool AttumenTheHuntsmanAttumenIsMountedTrigger::IsActive()
|
||||
|
||||
bool AttumenTheHuntsmanBossWipesAggroWhenMountingTrigger::IsActive()
|
||||
{
|
||||
if (!IsMapIDTimerManager(botAI, bot))
|
||||
if (!IsInstanceTimerManager(botAI, bot))
|
||||
return false;
|
||||
|
||||
Unit* midnight = AI_VALUE2(Unit*, "find target", "midnight");
|
||||
@@ -110,7 +110,7 @@ bool BigBadWolfBossIsChasingLittleRedRidingHoodTrigger::IsActive()
|
||||
|
||||
bool RomuloAndJulianneBothBossesRevivedTrigger::IsActive()
|
||||
{
|
||||
if (!IsMapIDTimerManager(botAI, bot))
|
||||
if (!IsInstanceTimerManager(botAI, bot))
|
||||
return false;
|
||||
|
||||
Unit* romulo = AI_VALUE2(Unit*, "find target", "romulo");
|
||||
@@ -126,7 +126,7 @@ bool RomuloAndJulianneBothBossesRevivedTrigger::IsActive()
|
||||
|
||||
bool WizardOfOzNeedTargetPriorityTrigger::IsActive()
|
||||
{
|
||||
if (!IsMapIDTimerManager(botAI, bot))
|
||||
if (!IsInstanceTimerManager(botAI, bot))
|
||||
return false;
|
||||
|
||||
Unit* dorothee = AI_VALUE2(Unit*, "find target", "dorothee");
|
||||
@@ -178,7 +178,7 @@ bool TheCuratorBossAstralFlaresCastArcingSearTrigger::IsActive()
|
||||
|
||||
bool TerestianIllhoofNeedTargetPriorityTrigger::IsActive()
|
||||
{
|
||||
if (!IsMapIDTimerManager(botAI, bot))
|
||||
if (!IsInstanceTimerManager(botAI, bot))
|
||||
return false;
|
||||
|
||||
Unit* illhoof = AI_VALUE2(Unit*, "find target", "terestian illhoof");
|
||||
@@ -202,7 +202,7 @@ bool ShadeOfAranFlameWreathIsActiveTrigger::IsActive()
|
||||
// Exclusion of Banish is so the player may Banish elementals if they wish
|
||||
bool ShadeOfAranConjuredElementalsSummonedTrigger::IsActive()
|
||||
{
|
||||
if (!IsMapIDTimerManager(botAI, bot))
|
||||
if (!IsInstanceTimerManager(botAI, bot))
|
||||
return false;
|
||||
|
||||
Unit* elemental = AI_VALUE2(Unit*, "find target", "conjured elemental");
|
||||
@@ -279,7 +279,7 @@ bool NetherspiteBossIsBanishedTrigger::IsActive()
|
||||
|
||||
bool NetherspiteNeedToManageTimersAndTrackersTrigger::IsActive()
|
||||
{
|
||||
if (!botAI->IsTank(bot) && !IsMapIDTimerManager(botAI, bot))
|
||||
if (!botAI->IsTank(bot) && !IsInstanceTimerManager(botAI, bot))
|
||||
return false;
|
||||
|
||||
Unit* netherspite = AI_VALUE2(Unit*, "find target", "netherspite");
|
||||
@@ -370,11 +370,12 @@ bool NightbaneBossIsFlyingTrigger::IsActive()
|
||||
if (!nightbane || nightbane->GetPositionZ() <= NIGHTBANE_FLIGHT_Z)
|
||||
return false;
|
||||
|
||||
const uint32 instanceId = nightbane->GetMap()->GetInstanceId();
|
||||
const time_t now = std::time(nullptr);
|
||||
const uint8 flightPhaseDurationSeconds = 35;
|
||||
|
||||
return nightbaneFlightPhaseStartTimer.find(KARAZHAN_MAP_ID) != nightbaneFlightPhaseStartTimer.end() &&
|
||||
(now - nightbaneFlightPhaseStartTimer[KARAZHAN_MAP_ID] < flightPhaseDurationSeconds);
|
||||
return nightbaneFlightPhaseStartTimer.find(instanceId) != nightbaneFlightPhaseStartTimer.end() &&
|
||||
(now - nightbaneFlightPhaseStartTimer[instanceId] < flightPhaseDurationSeconds);
|
||||
}
|
||||
|
||||
bool NightbaneNeedToManageTimersAndTrackersTrigger::IsActive()
|
||||
|
||||
Reference in New Issue
Block a user