PlayerBot : la monture d un bot de groupe calque celle de son maitre

Le core ne savait que monter, jamais descendre : TryUpMount() sortait des la
premiere ligne si l aura de monture etait deja posee, et rien n appelait
Dismount() hors lancement de sort. Un mercenaire recrute alors qu il galopait
sur le terrain restait donc en selle indefiniment, y compris derriere un maitre
a pied.

UpdateMountState() remplace TryUpMount() dans le tick et traite les trois cas :
maitre a pied, le bot descend (RemoveAurasByType, la monture portee pouvant
venir de l IA de terrain et ne pas etre m_UseMountID) ; maitre monte au sol,
monture terrestre ; maitre en vol, monture volante.

Le vol passe par BotAIFly::UpdateFly, qui etait neutralisee par un return sec en
tete de corps. Elle est retablie : c est le seul code qui fasse suivre un bot en
trois dimensions, et BotGroupAI est son unique appelant - aucun autre mode d IA
n est touche.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
SylvaniaCore deploy
2026-08-16 13:47:30 +02:00
parent 9e18ce4cec
commit 70e47be8b6
3 changed files with 45 additions and 2 deletions
+3 -1
View File
@@ -2659,7 +2659,9 @@ void BotAIFly::FlyToTarget(Player* player, bool offset)
void BotAIFly::UpdateFly(Player* masterPlayer, uint32 groundMountID, BotBGAIMovement* pMovement)
{
return;
// SylvaniaCore : cette fonction etait neutralisee par un return sec en
// tete de corps. Elle est le seul endroit qui fait suivre un bot en vol,
// et elle n est appelee que par BotGroupAI (NonCombatProcess).
if (m_FlyMountID == 0 || !masterPlayer || !pMovement)
return;
if (me->GetMap() != masterPlayer->GetMap())
@@ -928,7 +928,7 @@ me->SetPower(POWER_MANA, (me->GetMaxPower(POWER_MANA)));
}
Position pos = me->GetPosition();
m_Movement->SyncPosition(pos);
if (TryUpMount())
if (UpdateMountState())
return;
if (!me->HasAura(m_UseMountID) && !me->HasUnitState(UNIT_STATE_CASTING))
m_UsePotion.TryUsePotion();
@@ -1164,6 +1164,45 @@ bool BotGroupAI::TryUpMount()
return (TryCastSpell(m_UseMountID, me) == SPELL_CAST_OK);
}
// SylvaniaCore : le core ne savait que monter, jamais descendre. Un bot
// recrute alors qu il galopait sur le terrain restait en selle pour toujours,
// y compris derriere un maitre a pied. La monture suit desormais le maitre :
// a pied il pose pied a terre, monture terrestre au sol, monture volante en vol.
bool BotGroupAI::UpdateMountState()
{
if (!m_MasterPlayer)
return false;
if (me->IsInCombat() || me->HasUnitState(UNIT_STATE_CASTING))
return false;
if (me->GetMap() != m_MasterPlayer->GetMap())
return false;
// Maitre a pied : le bot descend. Le vol fait exception, c est BotAIFly qui
// le ramene au sol - le couper ici le ferait chuter du ciel.
if (!m_MasterPlayer->IsMounted())
{
if (m_Flying.HasFlying())
return false;
if (!me->IsMounted())
return false;
// RemoveAurasByType et pas Dismount() : la monture portee peut venir de
// l IA de terrain et ne pas etre m_UseMountID.
me->RemoveAurasByType(SPELL_AURA_MOUNTED);
return true;
}
// Maitre en vol : BotAIFly::UpdateFly pose la monture volante et assure le
// suivi en trois dimensions.
if (m_MasterPlayer->IsFlying())
return false;
// Maitre monte au sol : monture terrestre.
if (m_Flying.HasFlying())
m_Flying.CancelFly();
return TryUpMount();
}
void BotGroupAI::Dismount()
{
if (!me->HasAura(m_UseMountID))
@@ -93,6 +93,8 @@ public:
protected:
bool TryUpMount();
// Aligne la monture du bot sur celle du maitre : a pied, au sol ou en vol.
bool UpdateMountState();
bool CanReciveCommand(std::string& cmd, std::string& param);
void ProcessSummonCommand();
void ProcessAttackCommand();