Skip to content

Commit 81506ab

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 64218fc + 6be860c commit 81506ab

19 files changed

Lines changed: 629 additions & 487 deletions

src/PlayerbotAI.cpp

Lines changed: 92 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,8 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal)
242242
nextAICheckDelay = 0;
243243

244244
// Early return if bot is in invalid state
245-
if (!bot || !bot->IsInWorld() || !bot->GetSession() || bot->GetSession()->isLogingOut() ||
246-
bot->IsDuringRemoveFromWorld())
245+
if (!bot || !bot->GetSession() || !bot->IsInWorld() || bot->IsBeingTeleported() ||
246+
bot->GetSession()->isLogingOut() || bot->IsDuringRemoveFromWorld())
247247
return;
248248

249249
// Handle cheat options (set bot health and power if cheats are enabled)
@@ -713,39 +713,59 @@ void PlayerbotAI::HandleTeleportAck()
713713
if (IsRealPlayer())
714714
return;
715715

716+
// Clearing motion generators and stopping movement which prevents
717+
// conflicts between teleport and any active motion (walk, run, swim, flight, etc.)
716718
bot->GetMotionMaster()->Clear(true);
717719
bot->StopMoving();
720+
721+
// Near teleport (within map/instance)
718722
if (bot->IsBeingTeleportedNear())
719723
{
720-
// Temporary fix for instance can not enter
721-
if (!bot->IsInWorld())
722-
{
723-
bot->GetMap()->AddPlayerToMap(bot);
724-
}
725-
while (bot->IsInWorld() && bot->IsBeingTeleportedNear())
726-
{
727-
Player* plMover = bot->m_mover->ToPlayer();
728-
if (!plMover)
729-
return;
730-
WorldPacket p = WorldPacket(MSG_MOVE_TELEPORT_ACK, 20);
731-
p << plMover->GetPackGUID();
732-
p << (uint32)0; // supposed to be flags? not used currently
733-
p << (uint32)0; // time - not currently used
734-
bot->GetSession()->HandleMoveTeleportAck(p);
735-
};
724+
// Previous versions manually added the bot to the map if it was not in the world.
725+
// not needed: HandleMoveTeleportAckOpcode() safely attaches the player to the map
726+
// and clears IsBeingTeleportedNear().
727+
728+
Player* plMover = bot->m_mover->ToPlayer();
729+
if (!plMover)
730+
return;
731+
732+
// Send the near teleport ACK packet
733+
WorldPacket p(MSG_MOVE_TELEPORT_ACK, 20);
734+
p << plMover->GetPackGUID();
735+
p << uint32(0);
736+
p << uint32(0);
737+
bot->GetSession()->HandleMoveTeleportAck(p);
738+
739+
// Simulate teleport latency and prevent AI from running too early (used cmangos delays)
740+
SetNextCheckDelay(urand(1000, 2000));
736741
}
742+
743+
// Far teleport (worldport / different map)
737744
if (bot->IsBeingTeleportedFar())
738745
{
739-
while (bot->IsBeingTeleportedFar())
746+
// Handle far teleport ACK:
747+
// Moves the bot to the new map, clears IsBeingTeleportedFar(), updates session/map references
748+
bot->GetSession()->HandleMoveWorldportAck();
749+
750+
// Ensure bot now has a valid map. If this fails, there is a core/session bug?
751+
if (!bot->GetMap())
740752
{
741-
bot->GetSession()->HandleMoveWorldportAck();
753+
LOG_ERROR("playerbot", "Bot {} has no map after worldport ACK", bot->GetGUID().ToString());
742754
}
743-
// SetNextCheckDelay(urand(2000, 5000));
755+
756+
// Instance strategies after teleport
744757
if (sPlayerbotAIConfig->applyInstanceStrategies)
745758
ApplyInstanceStrategies(bot->GetMapId(), true);
759+
760+
// healer DPS strategies if restrictions are enabled
746761
if (sPlayerbotAIConfig->restrictHealerDPS)
747762
EvaluateHealerDpsStrategy();
763+
764+
// Reset AI state to to before teleport conditions
748765
Reset(true);
766+
767+
// Slightly longer delay to simulate far teleport latency (used cmangos delays)
768+
SetNextCheckDelay(urand(2000, 5000));
749769
}
750770

751771
SetNextCheckDelay(sPlayerbotAIConfig->globalCoolDown);
@@ -988,10 +1008,10 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet)
9881008
{
9891009
if (packet.empty())
9901010
return;
1011+
9911012
if (!bot || !bot->IsInWorld() || bot->IsDuringRemoveFromWorld())
992-
{
9931013
return;
994-
}
1014+
9951015
switch (packet.GetOpcode())
9961016
{
9971017
case SMSG_SPELL_FAILURE:
@@ -4103,8 +4123,7 @@ Player* PlayerbotAI::FindNewMaster()
41034123
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
41044124
{
41054125
Player* member = gref->GetSource();
4106-
if (!member || member == bot || !member->IsInWorld() ||
4107-
!member->IsInSameRaidWith(bot))
4126+
if (!member || member == bot || !member->IsInWorld() || !member->IsInSameRaidWith(bot))
41084127
continue;
41094128

41104129
PlayerbotAI* memberBotAI = GET_PLAYERBOT_AI(member);
@@ -4339,6 +4358,11 @@ inline bool ZoneHasRealPlayers(Player* bot)
43394358

43404359
bool PlayerbotAI::AllowActive(ActivityType activityType)
43414360
{
4361+
// Early return if bot is in invalid state
4362+
if (!bot || !bot->GetSession() || !bot->IsInWorld() || bot->IsBeingTeleported() ||
4363+
bot->GetSession()->isLogingOut() || bot->IsDuringRemoveFromWorld())
4364+
return false;
4365+
43424366
// when botActiveAlone is 100% and smartScale disabled
43434367
if (sPlayerbotAIConfig->botActiveAlone >= 100 && !sPlayerbotAIConfig->botActiveAloneSmartScale)
43444368
{
@@ -4429,10 +4453,8 @@ bool PlayerbotAI::AllowActive(ActivityType activityType)
44294453
for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next())
44304454
{
44314455
Player* member = gref->GetSource();
4432-
if ((!member || !member->IsInWorld()) && member->GetMapId() != bot->GetMapId())
4433-
{
4456+
if (!member || !member->IsInWorld() || member->GetMapId() != bot->GetMapId())
44344457
continue;
4435-
}
44364458

44374459
if (member == bot)
44384460
{
@@ -4483,23 +4505,23 @@ bool PlayerbotAI::AllowActive(ActivityType activityType)
44834505
// HasFriend
44844506
if (sPlayerbotAIConfig->BotActiveAloneForceWhenIsFriend)
44854507
{
4486-
if (!bot || !bot->IsInWorld() || !bot->GetGUID())
4508+
// shouldnt be needed analyse in future
4509+
if (!bot->GetGUID())
44874510
return false;
44884511

44894512
for (auto& player : sRandomPlayerbotMgr->GetPlayers())
44904513
{
4491-
if (!player || !player->IsInWorld())
4514+
if (!player || !player->GetSession() || !player->IsInWorld() || player->IsDuringRemoveFromWorld() ||
4515+
player->GetSession()->isLogingOut())
44924516
continue;
44934517

4494-
Player* connectedPlayer = ObjectAccessor::FindPlayer(player->GetGUID());
4495-
if (!connectedPlayer)
4518+
PlayerbotAI* playerAI = GET_PLAYERBOT_AI(player);
4519+
if (!playerAI || !playerAI->IsRealPlayer())
44964520
continue;
44974521

4522+
// if a real player has the bot as a friend
44984523
PlayerSocial* social = player->GetSocial();
4499-
if (!social)
4500-
continue;
4501-
4502-
if (social->HasFriend(bot->GetGUID()))
4524+
if (social && social->HasFriend(bot->GetGUID()))
45034525
return true;
45044526
}
45054527
}
@@ -4513,7 +4535,7 @@ bool PlayerbotAI::AllowActive(ActivityType activityType)
45134535
}
45144536
}
45154537

4516-
// Bots don't need to move using PathGenerator.
4538+
// Bots don't need react to PathGenerator activities
45174539
if (activityType == DETAILED_MOVE_ACTIVITY)
45184540
{
45194541
return false;
@@ -4549,15 +4571,25 @@ bool PlayerbotAI::AllowActive(ActivityType activityType)
45494571

45504572
bool PlayerbotAI::AllowActivity(ActivityType activityType, bool checkNow)
45514573
{
4552-
if (!allowActiveCheckTimer[activityType])
4553-
allowActiveCheckTimer[activityType] = time(nullptr);
4574+
const int activityIndex = static_cast<int>(activityType);
45544575

4555-
if (!checkNow && time(nullptr) < (allowActiveCheckTimer[activityType] + 5))
4556-
return allowActive[activityType];
4576+
// Unknown/out-of-range avoid blocking, added logging for further analysing should not happen in the first place.
4577+
if (activityIndex <= 0 || activityIndex >= MAX_ACTIVITY_TYPE)
4578+
{
4579+
LOG_ERROR("playerbots", "AllowActivity received invalid activity type value: {}", activityIndex);
4580+
return true;
4581+
}
4582+
4583+
if (!allowActiveCheckTimer[activityIndex])
4584+
allowActiveCheckTimer[activityIndex] = time(nullptr);
4585+
4586+
if (!checkNow && time(nullptr) < (allowActiveCheckTimer[activityIndex] + 5))
4587+
return allowActive[activityIndex];
4588+
4589+
const bool allowed = AllowActive(activityType);
4590+
allowActive[activityIndex] = allowed;
4591+
allowActiveCheckTimer[activityIndex] = time(nullptr);
45574592

4558-
bool allowed = AllowActive(activityType);
4559-
allowActive[activityType] = allowed;
4560-
allowActiveCheckTimer[activityType] = time(nullptr);
45614593
return allowed;
45624594
}
45634595

@@ -5341,15 +5373,13 @@ Item* PlayerbotAI::FindStoneFor(Item* weapon) const
53415373
if (!item_template)
53425374
return nullptr;
53435375

5344-
static const std::vector<uint32_t> uPrioritizedSharpStoneIds = {
5345-
ADAMANTITE_SHARPENING_STONE, FEL_SHARPENING_STONE, ELEMENTAL_SHARPENING_STONE, DENSE_SHARPENING_STONE,
5346-
SOLID_SHARPENING_STONE, HEAVY_SHARPENING_STONE, COARSE_SHARPENING_STONE, ROUGH_SHARPENING_STONE
5347-
};
5376+
static const std::vector<uint32_t> uPrioritizedSharpStoneIds = {
5377+
ADAMANTITE_SHARPENING_STONE, FEL_SHARPENING_STONE, ELEMENTAL_SHARPENING_STONE, DENSE_SHARPENING_STONE,
5378+
SOLID_SHARPENING_STONE, HEAVY_SHARPENING_STONE, COARSE_SHARPENING_STONE, ROUGH_SHARPENING_STONE};
53485379

5349-
static const std::vector<uint32_t> uPrioritizedWeightStoneIds = {
5350-
ADAMANTITE_WEIGHTSTONE, FEL_WEIGHTSTONE, DENSE_WEIGHTSTONE, SOLID_WEIGHTSTONE,
5351-
HEAVY_WEIGHTSTONE, COARSE_WEIGHTSTONE, ROUGH_WEIGHTSTONE
5352-
};
5380+
static const std::vector<uint32_t> uPrioritizedWeightStoneIds = {
5381+
ADAMANTITE_WEIGHTSTONE, FEL_WEIGHTSTONE, DENSE_WEIGHTSTONE, SOLID_WEIGHTSTONE,
5382+
HEAVY_WEIGHTSTONE, COARSE_WEIGHTSTONE, ROUGH_WEIGHTSTONE};
53535383

53545384
Item* stone = nullptr;
53555385
ItemTemplate const* pProto = weapon->GetTemplate();
@@ -5385,7 +5415,6 @@ static const std::vector<uint32_t> uPrioritizedWeightStoneIds = {
53855415

53865416
Item* PlayerbotAI::FindOilFor(Item* weapon) const
53875417
{
5388-
53895418
if (!weapon)
53905419
return nullptr;
53915420

@@ -5394,12 +5423,12 @@ Item* PlayerbotAI::FindOilFor(Item* weapon) const
53945423
return nullptr;
53955424

53965425
static const std::vector<uint32_t> uPrioritizedWizardOilIds = {
5397-
BRILLIANT_WIZARD_OIL, SUPERIOR_WIZARD_OIL, WIZARD_OIL, LESSER_WIZARD_OIL, MINOR_WIZARD_OIL,
5398-
BRILLIANT_MANA_OIL, SUPERIOR_MANA_OIL, LESSER_MANA_OIL, MINOR_MANA_OIL};
5426+
BRILLIANT_WIZARD_OIL, SUPERIOR_WIZARD_OIL, WIZARD_OIL, LESSER_WIZARD_OIL, MINOR_WIZARD_OIL,
5427+
BRILLIANT_MANA_OIL, SUPERIOR_MANA_OIL, LESSER_MANA_OIL, MINOR_MANA_OIL};
53995428

54005429
static const std::vector<uint32_t> uPrioritizedManaOilIds = {
5401-
BRILLIANT_MANA_OIL, SUPERIOR_MANA_OIL, LESSER_MANA_OIL, MINOR_MANA_OIL,
5402-
BRILLIANT_WIZARD_OIL, SUPERIOR_WIZARD_OIL, WIZARD_OIL, LESSER_WIZARD_OIL, MINOR_WIZARD_OIL};
5430+
BRILLIANT_MANA_OIL, SUPERIOR_MANA_OIL, LESSER_MANA_OIL, MINOR_MANA_OIL, BRILLIANT_WIZARD_OIL,
5431+
SUPERIOR_WIZARD_OIL, WIZARD_OIL, LESSER_WIZARD_OIL, MINOR_WIZARD_OIL};
54035432

54045433
Item* oil = nullptr;
54055434
int botClass = bot->getClass();
@@ -5415,22 +5444,22 @@ Item* PlayerbotAI::FindOilFor(Item* weapon) const
54155444
prioritizedOils = &uPrioritizedWizardOilIds;
54165445
break;
54175446
case CLASS_DRUID:
5418-
if (specTab == 0) // Balance
5447+
if (specTab == 0) // Balance
54195448
prioritizedOils = &uPrioritizedWizardOilIds;
5420-
else if (specTab == 1) // Feral
5449+
else if (specTab == 1) // Feral
54215450
prioritizedOils = nullptr;
5422-
else // Restoration (specTab == 2) or any other/unspecified spec
5451+
else // Restoration (specTab == 2) or any other/unspecified spec
54235452
prioritizedOils = &uPrioritizedManaOilIds;
54245453
break;
54255454
case CLASS_HUNTER:
54265455
prioritizedOils = &uPrioritizedManaOilIds;
54275456
break;
54285457
case CLASS_PALADIN:
5429-
if (specTab == 1) // Protection
5458+
if (specTab == 1) // Protection
54305459
prioritizedOils = &uPrioritizedWizardOilIds;
5431-
else if (specTab == 2) // Retribution
5460+
else if (specTab == 2) // Retribution
54325461
prioritizedOils = nullptr;
5433-
else // Holy (specTab == 0) or any other/unspecified spec
5462+
else // Holy (specTab == 0) or any other/unspecified spec
54345463
prioritizedOils = &uPrioritizedManaOilIds;
54355464
break;
54365465
default:

0 commit comments

Comments
 (0)