Playerbot: hearthstone party port + priest keeps healing spec at L10

- Hearthstone/return-to-inn sync: module teleports every owned bot to its
  (owner-synced) homebind when the owner spell-ports to their own homebind.
- Leveling spec for Priest now Holy (257) instead of Shadow (258): the L10
  real-spec promotion was forcing Shadow, flipping her role to Dps and
  stopping her healing.
- Add the TeleportTo hearthstone hunk to the core-hooks patch.
This commit is contained in:
devbox
2026-08-22 21:19:28 +10:00
parent 1867d77c70
commit 75c0cc46a6
6 changed files with 64 additions and 1 deletions
@@ -5612,7 +5612,7 @@ uint32 LevelingSpecForClass(uint8 cls)
case 2: return 70; // Paladin -> Retribution
case 3: return 253; // Hunter -> Beast Mastery
case 4: return 259; // Rogue -> Assassination
case 5: return 258; // Priest -> Shadow
case 5: return 257; // Priest -> Holy (heals — Shadow kills the role)
case 6: return 252; // DK -> Unholy
case 7: return 263; // Shaman -> Enhancement
case 8: return 64; // Mage -> Frost
@@ -152,6 +152,11 @@ void OnPlayerLootItem(Player* player, uint32 item_id, uint32 count)
V2::Module::instance().OnLootItem(player, item_id, count);
}
void OnPlayerHearthstone(Player* player)
{
V2::Module::instance().OnHearthstone(player);
}
void OnPlayerSetHomebind(Player* player, WorldLocation const& loc, uint32 areaId)
{
V2::Module::instance().OnSetHomebind(player, loc, areaId);
@@ -157,6 +157,7 @@ void OnPlayerSellAllJunk(Player* player, ObjectGuid vendor);
// Quest-item loot propagation: when the owner loots a quest item,
// give copies to all owned bots who still need it. (f47eaa0740)
void OnPlayerLootItem(Player* player, uint32 item_id, uint32 count);
void OnPlayerHearthstone(Player* player);
// Hearthstone-homebind sync: when the owner sets their homebind,
// propagate to all altbots so they hearth to the same location.
@@ -232,6 +233,7 @@ inline void OnPlayerAreaExplored(Player*, uint32) {}
inline void OnPlayerAbandonQuest(Player*, uint32) {}
inline void OnPlayerSellAllJunk(Player*, ObjectGuid) {}
inline void OnPlayerLootItem(Player*, uint32, uint32) {}
inline void OnPlayerHearthstone(Player*) {}
#endif // TRINITY_PLAYERBOT_V2
+29
View File
@@ -3520,6 +3520,35 @@ void Module::OnSetHomebind(Player* player, WorldLocation const& loc, uint32 area
}
}
void Module::OnHearthstone(Player* player)
{
if (!initialized_ || !player) return;
if (player->GetSession()->IsBot()) return;
WorldSession* sess = player->GetSession();
if (!sess) return;
uint32 const account_id = sess->GetAccountId();
auto bots = Services::Altbots().AltsOfAccount(account_id);
if (bots.empty()) return;
for (BotId id : bots)
{
Player* bot = ObjectAccessor::FindConnectedPlayer(
ObjectGuid::Create<HighGuid::Player>(id));
if (!bot || !bot->IsInWorld()) continue;
Position const botPos = bot->GetPosition();
if (bot->GetMapId() == bot->m_homebind.GetMapId() &&
bot->m_homebind.GetExactDist2d(&botPos) < 5.0f)
continue; // already at the inn — nothing to do
bot->TeleportTo(bot->m_homebind, TELE_TO_SPELL);
TC_LOG_INFO("playerbot.v2",
"[Hearthstone] {} ported to inn map={} with owner {}",
bot->GetName(), bot->m_homebind.GetMapId(), player->GetName());
}
}
void Module::OnSellAllJunk(Player* player, ObjectGuid vendor_guid)
{
if (!initialized_ || !player) return;
+1
View File
@@ -90,6 +90,7 @@ public:
void OnAbandonQuest(Player* player, uint32 quest_id);
// Hearthstone-homebind sync: owner sets homebind → all altbots match.
void OnSetHomebind(Player* player, WorldLocation const& loc, uint32 areaId);
void OnHearthstone(Player* player);
// Sell-all-junk mimic.
void OnSellAllJunk(Player* player, ObjectGuid vendor_guid);
// Quest-item loot propagation: gives copies to bots who need it.
@@ -1305,6 +1305,32 @@ index b82bd78f34..d58f648db8 100644
if (newitem && (newitem->GetQuality() > ITEM_QUALITY_EPIC || (newitem->GetQuality() == ITEM_QUALITY_EPIC && newitem->GetItemLevel(this) >= MinNewsItemLevel)))
if (Guild* guild = GetGuild())
guild->AddGuildNews(GUILD_NEWS_ITEM_LOOTED, GetGUID(), 0, item->itemid);
@@ -1254,6 +1254,25 @@ bool Player::TeleportTo(TeleportLocation const& teleportLocation, TeleportToOpti
return false;
}
+#if TRINITY_PLAYERBOT_V2
+ // Hearthstone / return-to-inn sync (PlayerbotV2): when a human owner
+ // teleports to their OWN homebind via a spell (hearthstone 8690,
+ // garrison/dalaran hearths, /unstuck 7355, LFG-return), port all owned
+ // bots to their (owner-synced) homebinds so the party stays together.
+ // Guarded on IsBot() below so the bots' own TeleportTo calls don't recurse.
+ if (GetSession() && !GetSession()->IsBot())
+ {
+ bool const spellPort = teleportSpellId != 0 || (options & TELE_TO_SPELL) != 0;
+ if (spellPort)
+ {
+ WorldLocation const& home = m_homebind;
+ WorldLocation const& dst = teleportLocation.Location;
+ if (dst.GetMapId() == home.GetMapId() && home.GetExactDist2d(&dst) < 5.0f)
+ Playerbot::Hooks::OnPlayerHearthstone(this);
+ }
+ }
+#endif
+
if (!GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_DISABLE_MAP) && DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, teleportLocation.Location.GetMapId(), this))
{
TC_LOG_ERROR("entities.player.cheat", "Player::TeleportTo: Player '{}' ({}) tried to enter a forbidden map (MapID: {})", GetGUID().ToString(), GetName(), teleportLocation.Location.GetMapId());
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 4577fffa77..1126d89a09 100644
--- a/src/server/game/Entities/Player/Player.h