Mercenaires : verifier l arrivee du mercenaire, et insister
Signale en jeu : sur une escorte de quatre, un compagnon restait a
l autre bout de la carte pour toute la duree du contrat.
L ordre de rappel -- ProcessBotCommand("!summon"), ou TeleportToPoint
quand un portail est connu -- partait une seule fois, et le contrat le
tenait aussitot pour honore : summonPending passait a false sans que
rien ne verifie que le mercenaire avait bouge. Un ordre perdu, et le
bot restait a la position ou il s etait connecte.
Le contrat retient maintenant ses tentatives et verifie l arrivee au
point de rendez-vous -- le portail s il y en a un, l employeur sinon.
Tant que le mercenaire n y est pas, l ordre est renouvele, jusqu a
quatre fois, avec trois secondes entre deux verifications : un teleport
de bot se joue en trois echanges et conclure au tick suivant reviendrait
a le declarer perdu alors qu il est en route.
Passe ce delai, on cesse d insister et on le dit au joueur, plutot que
de le laisser croire son groupe au complet.
Repare aussi le message de journal du recrutement offert, dont le format
avait ete abime lors de sa pose.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -460,8 +460,9 @@ MercenaryResult MercenaryMgr::Summon(Player* owner, uint8 role, Creature* portal
|
||||
}
|
||||
m_contracts.push_back(contract);
|
||||
|
||||
TC_LOG_INFO("server.worldserver", freeOfCharge ? "Mercenaires: %s recoit gratuitement un %3 (compte bot %4), cout %2 po non preleve." : "Mercenaires: %s a paye %u po pour un %s (compte bot %u).",
|
||||
owner->GetName().c_str(), GetCostGold(), GetRoleName(role), accountId);
|
||||
TC_LOG_INFO("server.worldserver", "Mercenaires: %s engage un %s (compte bot %u) -- %s.",
|
||||
owner->GetName().c_str(), GetRoleName(role), accountId,
|
||||
freeOfCharge ? "recrutement offert" : "100 po preleves");
|
||||
|
||||
return MERC_OK;
|
||||
}
|
||||
@@ -657,7 +658,34 @@ void MercenaryMgr::Update(uint32 diff)
|
||||
// le mercenaire a son ancienne place aux yeux de tout le monde.
|
||||
if (it->summonPending)
|
||||
{
|
||||
if (BotGroupAI* groupAI = dynamic_cast<BotGroupAI*>(bot->GetAI()))
|
||||
// Est-il arrive ? Le point de rendez-vous est le portail quand
|
||||
// il y en a un, l employeur sinon.
|
||||
bool arrive = false;
|
||||
if (it->hasPortal)
|
||||
arrive = bot->GetMapId() == it->portalMap
|
||||
&& bot->GetExactDist2d(it->portalPos.GetPositionX(),
|
||||
it->portalPos.GetPositionY()) < MERCENARY_ARRIVAL_RANGE;
|
||||
else
|
||||
arrive = bot->GetMapId() == owner->GetMapId()
|
||||
&& bot->GetExactDist2d(owner) < MERCENARY_ARRIVAL_RANGE;
|
||||
|
||||
if (arrive)
|
||||
it->summonPending = false;
|
||||
else if (it->summonCheckTimer > 0)
|
||||
--it->summonCheckTimer;
|
||||
else if (it->summonAttempts >= MERCENARY_SUMMON_RETRIES)
|
||||
{
|
||||
// On cesse d insister : mieux vaut un mercenaire annonce
|
||||
// perdu qu un mercenaire qu on croit present.
|
||||
it->summonPending = false;
|
||||
ChatHandler(owner->GetSession()).PSendSysMessage(
|
||||
"|cffff4444[Portail]|r %s n'a pas pu vous rejoindre.", bot->GetName().c_str());
|
||||
TC_LOG_ERROR("server.worldserver",
|
||||
"Mercenaires: %s n'a pas rejoint %s apres %u rappels (carte %u).",
|
||||
bot->GetName().c_str(), owner->GetName().c_str(),
|
||||
uint32(it->summonAttempts), bot->GetMapId());
|
||||
}
|
||||
else if (BotGroupAI* groupAI = dynamic_cast<BotGroupAI*>(bot->GetAI()))
|
||||
{
|
||||
// Repli : sans portail connu, ou si l armement immediat a
|
||||
// echoue, le mercenaire rejoint simplement son employeur.
|
||||
@@ -665,7 +693,9 @@ void MercenaryMgr::Update(uint32 diff)
|
||||
groupAI->TeleportToPoint(it->portalMap, BuildPortalExit(it->portalPos, bot));
|
||||
else
|
||||
groupAI->ProcessBotCommand(owner, "!summon");
|
||||
it->summonPending = false;
|
||||
|
||||
++it->summonAttempts;
|
||||
it->summonCheckTimer = MERCENARY_SUMMON_RECHECK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -748,7 +778,11 @@ void MercenaryMgr::Update(uint32 diff)
|
||||
if (BotGroupAI* groupAI = dynamic_cast<BotGroupAI*>(bot->GetAI()))
|
||||
{
|
||||
groupAI->TeleportToPoint(it->portalMap, BuildPortalExit(it->portalPos, bot));
|
||||
it->summonPending = false;
|
||||
// L ordre est parti, mais rien ne dit encore qu il aboutira :
|
||||
// on le compte comme une premiere tentative et la verification
|
||||
// d arrivee prend le relais au tick suivant.
|
||||
it->summonAttempts = 1;
|
||||
it->summonCheckTimer = MERCENARY_SUMMON_RECHECK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,18 @@ class Player;
|
||||
#define MERCENARY_GROUP_SIZE 5
|
||||
#define MERCENARY_HARD_CAP (MERCENARY_GROUP_SIZE - 1)
|
||||
#define MERCENARY_SUMMON_TIMEOUT 60 // secondes avant abandon + remboursement
|
||||
|
||||
// SIGNALE EN JEU : « Semid n est meme pas vers moi, elle est a l autre bout de
|
||||
// la map ». L ordre de rappel partait une seule fois et le contrat le tenait
|
||||
// aussitot pour honore. Quand il se perdait -- IA pas encore prete, teleport
|
||||
// deja en cours, changement de carte -- le mercenaire restait a sa derniere
|
||||
// position enregistree pour toute la duree du contrat.
|
||||
//
|
||||
// On verifie desormais l arrivee, et on renouvelle l ordre tant qu elle ne
|
||||
// vient pas.
|
||||
#define MERCENARY_ARRIVAL_RANGE 80.0f // distance au-dela de laquelle il n est pas arrive
|
||||
#define MERCENARY_SUMMON_RETRIES 4 // ordres de rappel au maximum
|
||||
#define MERCENARY_SUMMON_RECHECK 3 // secondes entre deux verifications
|
||||
#define MERCENARY_COPPER_PER_GOLD 10000
|
||||
|
||||
enum MercenaryStage
|
||||
@@ -66,7 +78,8 @@ enum MercenaryResult
|
||||
struct MercenaryContract
|
||||
{
|
||||
MercenaryContract() : accountId(0), role(0), stage(MERC_STAGE_SUMMONING), waitSeconds(0),
|
||||
pendingRelease(false), summonPending(false), hasPortal(false), portalMap(0) { }
|
||||
pendingRelease(false), summonPending(false), summonAttempts(0),
|
||||
summonCheckTimer(0), hasPortal(false), portalMap(0) { }
|
||||
|
||||
uint32 accountId; // compte bot reserve
|
||||
ObjectGuid ownerGuid; // joueur qui a paye
|
||||
@@ -84,6 +97,12 @@ struct MercenaryContract
|
||||
// groupe aura reconnu son maitre.
|
||||
bool summonPending;
|
||||
|
||||
// Ordres de rappel deja emis, et delai avant de reverifier l arrivee. Un
|
||||
// teleport de bot se joue en trois echanges : reverifier au tick suivant
|
||||
// conclurait a un echec alors qu il est simplement en cours de route.
|
||||
uint8 summonAttempts;
|
||||
uint32 summonCheckTimer;
|
||||
|
||||
// Le portail d ou part l invocation : le mercenaire doit en sortir, pas
|
||||
// se materialiser aux pieds de son employeur reste en retrait.
|
||||
bool hasPortal;
|
||||
|
||||
Reference in New Issue
Block a user