BG BotFill : doctrine de ciblage PvP en champ de bataille
Le bot prenait l ennemi le plus bas en vie sous 80 %, sinon un ennemi AU HASARD : aucun feu concentre, soigneurs ennemis jamais inquietes, porteur de drapeau ignore. Les cibles sont desormais notees selon la doctrine PvP de champ de bataille (Vanilla -> Legion) : porteur de drapeau +1000 (objectif du match) soigneur ennemi +400 (un soigneur libre rend le combat ingagnable) cible blessee +3 par point de vie manquant (achever plutot qu etaler) allie deja au contact +60 chacun (feu concentre) distance -1 par metre hors ligne de vue -250 Detection du soigneur par classe ET specialisation (un paladin protection n est plus traite comme un soigneur) ; le feu concentre se lit sur la liste des attaquants de la cible, sans recherche couteuse. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -754,12 +754,62 @@ void BotBGAI::SearchCreatureListFromRange(Unit* center, NearCreatureVec& nearCre
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SylvaniaCore (module BG BotFill): un soigneur ennemi prolonge indefiniment un combat ;
|
||||||
|
// la doctrine PvP le designe comme cible prioritaire apres le porteur de drapeau.
|
||||||
|
// Meme regle que Arena::IsHealerBot : classe + specialisation.
|
||||||
|
bool BotBGAI::TargetIsHealer(Player* pTarget)
|
||||||
|
{
|
||||||
|
if (!pTarget)
|
||||||
|
return false;
|
||||||
|
switch (pTarget->getClass())
|
||||||
|
{
|
||||||
|
case CLASS_PALADIN:
|
||||||
|
return (pTarget->FindTalentType() == 0);
|
||||||
|
case CLASS_PRIEST:
|
||||||
|
return (pTarget->FindTalentType() != 2);
|
||||||
|
case CLASS_SHAMAN:
|
||||||
|
case CLASS_DRUID:
|
||||||
|
return (pTarget->FindTalentType() == 2);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Porteur d un drapeau de champ de bataille (Chanteguerres ou Oeil du cyclone).
|
||||||
|
bool BotBGAI::TargetIsFlagCarrier(Player* pTarget)
|
||||||
|
{
|
||||||
|
if (!pTarget)
|
||||||
|
return false;
|
||||||
|
return pTarget->HasAura(23333) // etendard de Chanteguerre (Horde)
|
||||||
|
|| pTarget->HasAura(23335) // etendard d Aile-argent (Alliance)
|
||||||
|
|| pTarget->HasAura(34976); // drapeau du Nethertempete (Oeil du cyclone)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nombre d allies deja au corps a corps sur cette cible : base du feu concentre.
|
||||||
|
uint32 BotBGAI::CountFriendlyAttackers(Unit* pTarget)
|
||||||
|
{
|
||||||
|
if (!pTarget)
|
||||||
|
return 0;
|
||||||
|
uint32 count = 0;
|
||||||
|
Unit::AttackerSet const& attackers = pTarget->getAttackers();
|
||||||
|
for (Unit::AttackerSet::const_iterator itAtk = attackers.begin(); itAtk != attackers.end(); ++itAtk)
|
||||||
|
{
|
||||||
|
Unit* attacker = *itAtk;
|
||||||
|
if (!attacker || attacker == me)
|
||||||
|
continue;
|
||||||
|
if (attacker->IsPlayer() && attacker->ToPlayer()->GetTeamId() == me->GetTeamId())
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
Unit* BotBGAI::SearchEnemy(float range)
|
Unit* BotBGAI::SearchEnemy(float range)
|
||||||
{
|
{
|
||||||
NearPlayerList playersNearby;
|
NearPlayerList playersNearby;
|
||||||
QueryNearPlayerList(range, playersNearby);
|
QueryNearPlayerList(range, playersNearby);
|
||||||
NearPlayerVec enemyPlayers, invinciblePlayers;
|
NearPlayerVec enemyPlayers, invinciblePlayers;
|
||||||
Player* minHealthPlayer = NULL;
|
Player* minHealthPlayer = NULL;
|
||||||
|
float bestScore = 0.0f;
|
||||||
for (Player* pVisionPlayer : playersNearby)
|
for (Player* pVisionPlayer : playersNearby)
|
||||||
{
|
{
|
||||||
#ifdef EXCLUDE_PLAYER
|
#ifdef EXCLUDE_PLAYER
|
||||||
@@ -776,12 +826,25 @@ Unit* BotBGAI::SearchEnemy(float range)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// SylvaniaCore (module BG BotFill): notation tactique de la cible.
|
||||||
|
// Bareme issu de la doctrine PvP de champ de bataille : le porteur de
|
||||||
|
// drapeau passe avant tout, puis le soigneur, puis l ennemi a achever,
|
||||||
|
// puis la cible que les allies frappent deja (feu concentre).
|
||||||
float hp = pVisionPlayer->GetHealthPct();
|
float hp = pVisionPlayer->GetHealthPct();
|
||||||
if (hp < 80.0f)
|
float score = 0.0f;
|
||||||
|
if (TargetIsFlagCarrier(pVisionPlayer))
|
||||||
|
score += 1000.0f;
|
||||||
|
if (TargetIsHealer(pVisionPlayer))
|
||||||
|
score += 400.0f;
|
||||||
|
score += (100.0f - hp) * 3.0f;
|
||||||
|
score += float(CountFriendlyAttackers(pVisionPlayer)) * 60.0f;
|
||||||
|
score -= me->GetDistance(pVisionPlayer);
|
||||||
|
if (!me->IsWithinLOSInMap(pVisionPlayer))
|
||||||
|
score -= 250.0f;
|
||||||
|
|
||||||
|
if (!minHealthPlayer || score > bestScore)
|
||||||
{
|
{
|
||||||
if (!minHealthPlayer)
|
bestScore = score;
|
||||||
minHealthPlayer = pVisionPlayer;
|
|
||||||
else if (hp < minHealthPlayer->GetHealthPct())
|
|
||||||
minHealthPlayer = pVisionPlayer;
|
minHealthPlayer = pVisionPlayer;
|
||||||
}
|
}
|
||||||
if (m_NeedFindpathSearch)
|
if (m_NeedFindpathSearch)
|
||||||
@@ -809,6 +872,8 @@ Unit* BotBGAI::SearchEnemy(float range)
|
|||||||
Player* pVisionPlayer = invinciblePlayers[index];
|
Player* pVisionPlayer = invinciblePlayers[index];
|
||||||
return pVisionPlayer;
|
return pVisionPlayer;
|
||||||
}
|
}
|
||||||
|
// SylvaniaCore (module BG BotFill): la cible la mieux notee est retenue ; le tirage
|
||||||
|
// au hasard ne subsiste que si la notation n a rien pu departager.
|
||||||
if (!minHealthPlayer)
|
if (!minHealthPlayer)
|
||||||
{
|
{
|
||||||
uint32 index = urand(0, enemyPlayers.size() - 1);
|
uint32 index = urand(0, enemyPlayers.size() - 1);
|
||||||
|
|||||||
@@ -161,6 +161,10 @@ protected:
|
|||||||
virtual bool IsMeleeBotAI();
|
virtual bool IsMeleeBotAI();
|
||||||
virtual bool IsRangeBotAI();
|
virtual bool IsRangeBotAI();
|
||||||
virtual bool IsHealerBotAI();
|
virtual bool IsHealerBotAI();
|
||||||
|
// SylvaniaCore (module BG BotFill): doctrine de ciblage en champ de bataille
|
||||||
|
static bool TargetIsHealer(Player* pTarget);
|
||||||
|
static bool TargetIsFlagCarrier(Player* pTarget);
|
||||||
|
uint32 CountFriendlyAttackers(Unit* pTarget);
|
||||||
virtual bool IsAttacker() { return true; }
|
virtual bool IsAttacker() { return true; }
|
||||||
virtual bool TryStartControlCommand() { ClearCruxControlCommand(); return false; }
|
virtual bool TryStartControlCommand() { ClearCruxControlCommand(); return false; }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user