Playerbots : la formation de groupe n'a jamais fonctionne
SIGNALE EN JEU : « les bots restent les uns sur les autres, il n existe
pas des commandes de strategie de placement ? ». Le systeme existait
bien -- il etait casse.
GetPositionFromGroup calcule correctement une place propre a chaque
membre : un angle reparti sur le cercle, a quatre metres du meneur. Mais
son resultat n etait jamais renvoye :
Position resultPos(distX, distY, distZ, ...); // calculee
Position pos; // vide
pCenterPlayer->GetFirstCollisionPosition(...); // resultat jete
return pos; // (0,0,0)
GetFirstCollisionPosition REND une Position ; son retour etait ignore et
l on renvoyait une variable jamais renseignee. La fonction rendait donc
l origine du monde a tous ses appelants -- BotGroupAI comme BotAITool.
Par-dessus, les deux MoveFollow de BotGroupAI employaient la meme
distance et le meme angle pour tout le monde : un metre devant le
meneur, a son orientation. Meme reparee, la formation aurait ete ecrasee
deux lignes plus loin. Chaque bot y prend desormais l angle de son rang
dans le groupe, a trois ou quatre metres selon l effectif.
Le defaut ne touchait pas que le scenario : il vaut pour tous les
playerbots du serveur, champs de bataille et donjons compris.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -502,9 +502,30 @@ Position BotUtility::GetPositionFromGroup(Player* pCenterPlayer, ObjectGuid self
|
|||||||
float distZ = centerPos.GetPositionZ();
|
float distZ = centerPos.GetPositionZ();
|
||||||
if (!pCenterPlayer->IsFlying())
|
if (!pCenterPlayer->IsFlying())
|
||||||
distZ = pCenterPlayer->GetMap()->GetHeight(pCenterPlayer->GetPhaseShift(), distX, distY, distZ);
|
distZ = pCenterPlayer->GetMap()->GetHeight(pCenterPlayer->GetPhaseShift(), distX, distY, distZ);
|
||||||
|
// =================================================================
|
||||||
|
// SylvaniaCore : la position calculee etait JETEE.
|
||||||
|
//
|
||||||
|
// SIGNALE EN JEU : « les bots restent les uns sur les autres ».
|
||||||
|
//
|
||||||
|
// Tout le calcul ci-dessus est juste -- un angle propre a chaque
|
||||||
|
// membre, reparti sur le cercle, a quatre metres du meneur. Mais le
|
||||||
|
// resultat n'etait jamais renvoye :
|
||||||
|
//
|
||||||
|
// Position resultPos(distX, distY, distZ, ...); // calculee
|
||||||
|
// Position pos; // vide
|
||||||
|
// pCenterPlayer->GetFirstCollisionPosition(...); // jete
|
||||||
|
// return pos; // (0,0,0)
|
||||||
|
//
|
||||||
|
// GetFirstCollisionPosition REND une Position ; son resultat etait
|
||||||
|
// ignore, et l'on renvoyait une variable jamais renseignee. La
|
||||||
|
// fonction rendait donc l'origine du monde a tous les appelants, et
|
||||||
|
// la formation n'a jamais fonctionne -- nulle part, pas seulement
|
||||||
|
// dans ce scenario.
|
||||||
|
// =================================================================
|
||||||
Position resultPos(distX, distY, distZ, pCenterPlayer->GetOrientation());
|
Position resultPos(distX, distY, distZ, pCenterPlayer->GetOrientation());
|
||||||
Position pos;
|
Position pos = pCenterPlayer->GetFirstCollisionPosition(
|
||||||
pCenterPlayer->GetFirstCollisionPosition(pCenterPlayer->GetDistance(resultPos), pCenterPlayer->GetRelativeAngle(&resultPos));
|
pCenterPlayer->GetDistance(resultPos), pCenterPlayer->GetRelativeAngle(&resultPos));
|
||||||
|
pos.SetOrientation(pCenterPlayer->GetOrientation());
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1528,18 +1528,44 @@ void BotGroupAI::ProcessFollowToMaster()
|
|||||||
}
|
}
|
||||||
Position targetPos = BotUtility::GetPositionFromGroup(m_MasterPlayer, me->GetGUID(), me->GetGroup());
|
Position targetPos = BotUtility::GetPositionFromGroup(m_MasterPlayer, me->GetGUID(), me->GetGroup());
|
||||||
m_Movement->MovementTo(targetPos.GetPositionX(), targetPos.GetPositionY(), targetPos.GetPositionZ(), 0);
|
m_Movement->MovementTo(targetPos.GetPositionX(), targetPos.GetPositionY(), targetPos.GetPositionZ(), 0);
|
||||||
|
// =================================================================
|
||||||
|
// ANGLE PROPRE A CHAQUE MEMBRE.
|
||||||
|
//
|
||||||
|
// Les deux MoveFollow ci-dessous employaient la MEME distance et le
|
||||||
|
// MEME angle pour tout le monde -- un metre devant le meneur, a son
|
||||||
|
// orientation. Tous les bots convergeaient donc vers un point unique
|
||||||
|
// et se superposaient, quand bien meme GetPositionFromGroup leur
|
||||||
|
// avait calcule une place distincte deux lignes plus haut.
|
||||||
|
//
|
||||||
|
// On reprend l'angle de cette formation : chacun garde son secteur.
|
||||||
|
float suiviAngle = 0.0f;
|
||||||
|
float suiviDistance = 3.0f;
|
||||||
|
{
|
||||||
|
uint32 index = 0;
|
||||||
|
uint32 count = 0;
|
||||||
|
ObjectGuid monGuid = me->GetGUID();
|
||||||
|
if (me->GetGroup() && me->GetGroup()->GiveAtGroupPos(monGuid, index, count))
|
||||||
|
{
|
||||||
|
if (count > 1)
|
||||||
|
--count;
|
||||||
|
if (count)
|
||||||
|
suiviAngle = (float(M_PI) * 2.0f / float(count)) * float(index);
|
||||||
|
suiviDistance = (count > 3) ? 4.0f : 3.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float distance = me->GetDistance(m_MasterPlayer->GetPosition());
|
float distance = me->GetDistance(m_MasterPlayer->GetPosition());
|
||||||
if (distance <= NEEDFLEE_CHECKRANGE && distance > 0.1f)
|
if (distance <= NEEDFLEE_CHECKRANGE && distance > 0.1f)
|
||||||
{
|
{
|
||||||
me->GetMotionMaster()->Clear();
|
me->GetMotionMaster()->Clear();
|
||||||
me->GetMotionMaster()->MoveFollow(m_MasterPlayer, 1.0f, m_MasterPlayer->GetOrientation());
|
me->GetMotionMaster()->MoveFollow(m_MasterPlayer, suiviDistance, suiviAngle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (me->IsWithinLOSInMap(m_MasterPlayer))
|
if (me->IsWithinLOSInMap(m_MasterPlayer))
|
||||||
{
|
{
|
||||||
me->GetMotionMaster()->Clear();
|
me->GetMotionMaster()->Clear();
|
||||||
me->GetMotionMaster()->MoveFollow(m_MasterPlayer, 1.0f, m_MasterPlayer->GetOrientation());
|
me->GetMotionMaster()->MoveFollow(m_MasterPlayer, suiviDistance, suiviAngle);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_Movement->MovementTo(m_MasterPlayer->GetPositionX(), m_MasterPlayer->GetPositionY(), m_MasterPlayer->GetPositionZ(), 1);
|
m_Movement->MovementTo(m_MasterPlayer->GetPositionX(), m_MasterPlayer->GetPositionY(), m_MasterPlayer->GetPositionZ(), 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user