PlayerBot : octroi des sorts de niveau et de specialisation au re-level
PlayerBotSetting::LearnSpells() n apprenait les sorts que depuis les donnees de dresseur de classe (GetNpcTrainerSpells). En 7.3.5 les dresseurs n enseignent plus le kit moderne : il s octroie a la montee de niveau et via la specialisation. Les bots re-leveles arrivaient donc avec stuff et talents mais un livre de sorts incomplet. LearnDefaultSkills(), LearnSpecializationSpells() et UpdateSkillsToMaxSkillsForLevel() sont desormais appeles avant le passage par les dresseurs. Mesure avant / apres sur les bots 110 du siege, nombre moyen de sorts connus : guerrier 43 -> 56 paladin 43 -> 51 chasseur 44 -> 55 voleur 44 -> 63 pretre 44 -> 56 chaman 44 -> 56 mage 44 -> 54 druide 44 -> 56 Concerne aussi le remplissage des champs de bataille, qui re-level par le meme chemin. Deuxieme correction : BotBGAIMovement::IsNearToPosition() repondait toujours pas encore arrive hors champ de bataille. Les appelants ne coupaient donc jamais court et relancaient un calcul de chemin a chaque tick, d ou le flot de messages de pathfinding en echec pendant le siege. Le mode siege passe desormais cette garde. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1766,12 +1766,49 @@ void BotBGAI::UpdateBotAI(uint32 diff)
|
||||
// mais passent leur temps sur sa garde rapprochee.
|
||||
if (m_SiegeMode && !m_SiegeTarget.IsEmpty())
|
||||
{
|
||||
if (Unit* siegeBoss = ObjectAccessor::GetUnit(*me, m_SiegeTarget))
|
||||
Unit* siegeBoss = ObjectAccessor::GetUnit(*me, m_SiegeTarget);
|
||||
if (siegeBoss)
|
||||
{
|
||||
if (siegeBoss->IsAlive() && me->IsValidAttackTarget(siegeBoss)
|
||||
&& me->GetDistance(siegeBoss) < sCapitalSiegeMgr->GetBossEngageRange())
|
||||
float const bossDistance = me->GetDistance(siegeBoss);
|
||||
bool const bossAttackable = me->IsValidAttackTarget(siegeBoss);
|
||||
bool const bossInRange = bossDistance < sCapitalSiegeMgr->GetBossEngageRange();
|
||||
|
||||
// Instrumentation temporaire du blocage sur le dirigeant : il ne
|
||||
// perd aucun point de vie alors que des bots meurent a trois
|
||||
// yards de lui, et ni sa faction, ni ses drapeaux, ni son
|
||||
// creature_template ne l expliquent.
|
||||
// Sonde declenchee des que le dirigeant est designe (60 yards),
|
||||
// et non seulement au contact : IsValidAttackTarget ne depend pas
|
||||
// de la distance, et la horde n arrive pas toujours jusqu a lui.
|
||||
{
|
||||
static uint32 s_siegeBossLog = 0;
|
||||
if (++s_siegeBossLog % 25 == 1)
|
||||
{
|
||||
Unit* victim = me->GetVictim();
|
||||
TC_LOG_ERROR("server.worldserver",
|
||||
"SIEGE-DBG: %s dist=%.1f attaquable=%u cible=%s victime=%s flags=0x%X | evade=%u visible=%u memephase=%u react=%d pv=%s",
|
||||
me->GetName().c_str(), bossDistance, uint32(bossAttackable),
|
||||
(me->GetTarget() == m_SiegeTarget) ? "dirigeant" : "autre",
|
||||
victim ? victim->GetName().c_str() : "aucune",
|
||||
siegeBoss->GetUInt32Value(UNIT_FIELD_FLAGS),
|
||||
uint32(siegeBoss->ToCreature() ? siegeBoss->ToCreature()->IsInEvadeMode() : 0),
|
||||
uint32(siegeBoss->IsVisible()),
|
||||
uint32(me->InSamePhase(siegeBoss->GetPhaseShift())),
|
||||
int32(siegeBoss->ToCreature() ? siegeBoss->ToCreature()->GetReactState() : -1),
|
||||
std::to_string(siegeBoss->GetHealth()).c_str());
|
||||
}
|
||||
}
|
||||
(void)bossInRange;
|
||||
|
||||
if (siegeBoss->IsAlive() && bossAttackable && bossInRange)
|
||||
me->SetSelection(m_SiegeTarget);
|
||||
}
|
||||
else
|
||||
{
|
||||
static uint32 s_siegeBossMissing = 0;
|
||||
if (++s_siegeBossMissing % 50 == 1)
|
||||
TC_LOG_ERROR("server.worldserver", "SIEGE-DBG: %s ne trouve pas le dirigeant en memoire.", me->GetName().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
Unit* pSelect = GetBotAIValidSelectedUnit();
|
||||
@@ -1784,7 +1821,13 @@ void BotBGAI::UpdateBotAI(uint32 diff)
|
||||
else if (pSelect && !IsInvincible(pSelect) && !HasAuraMechanic(pSelect, Mechanics::MECHANIC_POLYMORPH))
|
||||
{
|
||||
float distance = me->GetDistance(pSelect->GetPosition());
|
||||
if (distance < searchRange || inArena)
|
||||
// Module Siege des Capitales : le dirigeant echappe au seuil
|
||||
// d abandon de cible. Avec une portee d engagement courte, l IA le
|
||||
// lachait des 17 yards ( distance > searchRange * 1.7 ) et la
|
||||
// selection ne tenait pas une seule tick, meme a 28 yards de lui.
|
||||
float const engageDistance = (m_SiegeMode && !m_SiegeTarget.IsEmpty() && pSelect->GetGUID() == m_SiegeTarget)
|
||||
? sCapitalSiegeMgr->GetBossEngageRange() : searchRange;
|
||||
if (distance < engageDistance || inArena)
|
||||
{
|
||||
if (m_CurrentTargetTick < BOTAI_MAXTARGET_TICKTIME || inArena)
|
||||
{
|
||||
@@ -1805,7 +1848,7 @@ void BotBGAI::UpdateBotAI(uint32 diff)
|
||||
me->SetSelection(ObjectGuid::Empty);
|
||||
}
|
||||
}
|
||||
else if (distance > searchRange * 1.7f || me->GetMap() != pSelect->GetMap())
|
||||
else if (distance > engageDistance * 1.7f || me->GetMap() != pSelect->GetMap())
|
||||
{
|
||||
me->SetSelection(ObjectGuid::Empty);
|
||||
}
|
||||
|
||||
@@ -691,7 +691,12 @@ void BotBGAIMovement::SyncPosition(Position& pos, bool immed)
|
||||
|
||||
bool BotBGAIMovement::IsNearToPosition(float x, float y, float z, float range)
|
||||
{
|
||||
if (!m_Player->InBattleground())
|
||||
// Hors champ de bataille ce test repondait toujours pas encore arrive : les
|
||||
// appelants ne coupaient donc jamais court et relancaient un calcul de chemin
|
||||
// a chaque tick, d ou le flot de messages de pathfinding en echec pendant le
|
||||
// siege. Le mode siege doit passer.
|
||||
bool const siegeMode = m_BGAI && m_BGAI->IsSiegeMode();
|
||||
if (!siegeMode && !m_Player->InBattleground())
|
||||
return false;
|
||||
if (Unit* pVehicle = m_Player->GetVehicleBase())
|
||||
{
|
||||
|
||||
@@ -1903,6 +1903,18 @@ void PlayerBotSetting::RemoveSpells()
|
||||
void PlayerBotSetting::LearnSpells()
|
||||
{
|
||||
uint8 level = m_Player->getLevel();
|
||||
|
||||
// SylvaniaCore : en 7.3.5 le gros du kit de classe ne s apprend plus chez un
|
||||
// dresseur mais s octroie a la montee de niveau et via la specialisation. Se
|
||||
// limiter aux donnees de dresseur laissait les bots re-leveles sans sorts
|
||||
// d attaque : constate en jeu sur les demonistes 110 du siege, deux sorts de
|
||||
// degats sur la duree sur cinq et aucun sort de degats directs sur quatre.
|
||||
// Concerne aussi le remplissage des champs de bataille, qui re-level de la
|
||||
// meme facon.
|
||||
m_Player->LearnDefaultSkills();
|
||||
m_Player->LearnSpecializationSpells();
|
||||
m_Player->UpdateSkillsToMaxSkillsForLevel();
|
||||
|
||||
const TrainerSpellData* spellData = sObjectMgr->GetNpcTrainerSpells(classesTrainersGUID[m_Player->getClass()][(m_Player->GetTeamId() == TeamId::TEAM_ALLIANCE) ? 0 : 1]);
|
||||
if (!spellData)
|
||||
return;
|
||||
|
||||
@@ -4751,7 +4751,7 @@ siege_engage_range = 10
|
||||
# Default: 40
|
||||
#
|
||||
|
||||
siege_boss_engage_range = 40
|
||||
siege_boss_engage_range = 60
|
||||
|
||||
#
|
||||
# siege_stall_timeout
|
||||
|
||||
Reference in New Issue
Block a user