From 5af9d71a8fa19758f1bc9d80d7dfe7c14d0c5d6e Mon Sep 17 00:00:00 2001 From: SylvaniaCore deploy Date: Wed, 22 Jul 2026 22:51:09 +0000 Subject: [PATCH] Harnais QA bot complet + 3 fixes gameplay majeurs des scenarios d artefact - PlayerBotSession : simulation de l ack de teleport PROCHE (CMSG_MOVE_TELEPORT_ACK), debloque les .tele enchaines sur un bot (le 1er passait, les suivants restaient coinces) - Runner artefacts, fixes issus de la passe bot in-game (7 scenarios certifies ACTIFS) : * vagues engagees explicitement (SetReactState AGGRESSIVE + SetInCombatWithZone) : les TempSummon de Map n aggro pas seuls -> mobs inertes sur TOUS les scenarios * phase 169 appliquee aux invocations (alignement avec OnPlayerEnter) * tolerance GetHeight 25->60m (Skywall : plateformes etagees, le garde-fou lachait les vagues dans le vide) + sonde QA-PROBE etiquetee par map (visibilite/combat/pos) Co-Authored-By: Claude Fable 5 --- src/server/game/Server/PlayerBotSession.cpp | 12 +++++++ .../Scenario/scenario_artifact_runner.cpp | 35 ++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/server/game/Server/PlayerBotSession.cpp b/src/server/game/Server/PlayerBotSession.cpp index 2e906d7..96bad33 100644 --- a/src/server/game/Server/PlayerBotSession.cpp +++ b/src/server/game/Server/PlayerBotSession.cpp @@ -23,6 +23,7 @@ #include "BotFieldAI.h" #include "LFGMgr.h" #include "CharacterPackets.h" +#include "MovementPackets.h" #include "DB2Structure.h" #include "LFGPackets.h" #include "LFGPacketsCommon.h" @@ -172,6 +173,17 @@ void PlayerBotSession::ProcessNoWorld(uint32 diff) return; } + // idem pour un teleport proche (meme map) : un client reel repond CMSG_MOVE_TELEPORT_ACK + if (player->IsBeingTeleportedNear()) + { + WorldPacket data(CMSG_MOVE_TELEPORT_ACK); + WorldPackets::Movement::MoveTeleportAck ack(std::move(data)); + ack.MoverGUID = player->GetGUID(); + HandleMoveTeleportAck(ack); + m_NoWorldTick = 500; + return; + } + if (player->IsInWorld()) { m_NoWorldTick = 0; diff --git a/src/server/scripts/BrokenIsles/Scenario/scenario_artifact_runner.cpp b/src/server/scripts/BrokenIsles/Scenario/scenario_artifact_runner.cpp index 7dbc1e4..e7e0bc8 100644 --- a/src/server/scripts/BrokenIsles/Scenario/scenario_artifact_runner.cpp +++ b/src/server/scripts/BrokenIsles/Scenario/scenario_artifact_runner.cpp @@ -126,6 +126,30 @@ struct scenario_artifact_runner : public InstanceScript { InstanceScript::Update(diff); scheduler.Update(diff); + probeTimer += diff; + if (probeTimer >= 10000) + { + probeTimer = 0; + for (ObjectGuid const& g : summonGuids) + { + Creature* c = instance->GetCreature(g); + if (!c) + TC_LOG_ERROR("server.worldserver", "QA-PROBE: summon %s DISPARU", g.ToString().c_str()); + else + { + TC_LOG_ERROR("server.worldserver", "QA-PROBE[m%u]: e%u alive=%d combat=%d victim=%d react=%d pos(%.0f,%.0f,%.0f)", + instance->GetId(), c->GetEntry(), (int)c->IsAlive(), (int)c->IsInCombat(), c->GetVictim() ? 1 : 0, (int)c->GetReactState(), + c->GetPositionX(), c->GetPositionY(), c->GetPositionZ()); + DoOnPlayers([c](Player* pl) + { + TC_LOG_ERROR("server.worldserver", "QA-PROBE[m%u]: joueur %s pos(%.0f,%.0f,%.0f) dist=%.1f mobVoitJoueur=%d joueurVoitMob=%d", + c->GetMapId(), pl->GetName().c_str(), pl->GetPositionX(), pl->GetPositionY(), pl->GetPositionZ(), + c->GetDistance(pl), (int)c->CanSeeOrDetect(pl), (int)pl->CanSeeOrDetect(c)); + }); + break; + } + } + } } void CompleteStep() @@ -150,6 +174,7 @@ struct scenario_artifact_runner : public InstanceScript stage = newStage; aliveCount = 0; stageEntries.clear(); + summonGuids.clear(); bool teleported = false; for (ArtifactRunner::StageSpawn const& s : itr->second) @@ -170,7 +195,7 @@ struct scenario_artifact_runner : public InstanceScript Position pos = { s.x + dx + 6.0f, s.y + dy + 4.0f, s.z, s.o }; // cale le Z au sol : les ancres sont sures mais les offsets peuvent sortir des plateformes float gz = instance->GetHeight(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ() + 8.0f, true, 60.0f); - if (gz > INVALID_HEIGHT && std::abs(gz - s.z) < 25.0f) + if (gz > INVALID_HEIGHT && std::abs(gz - s.z) < 60.0f) pos.m_positionZ = gz + 0.5f; else pos.Relocate(s.x, s.y, s.z); // repli : pile sur l ancre officielle @@ -185,10 +210,16 @@ struct scenario_artifact_runner : public InstanceScript summon->SetLevel(s.level); summon->SetFullHealth(); } + // meme phase que les joueurs (OnPlayerEnter les met en 169) + PhasingHandler::AddPhase(summon, 169, true); + // les TempSummon de Map n aggro pas seuls : on engage la vague explicitement + summon->SetReactState(REACT_AGGRESSIVE); + summon->SetInCombatWithZone(); // cri d apparition des boss (groupe 0 si defini en creature_text) if (s.level >= 102 && sCreatureTextMgr->TextExist(s.entry, 0)) summon->AI()->Talk(0); stageEntries.insert(s.entry); + summonGuids.push_back(summon->GetGUID()); ++aliveCount; } } @@ -247,6 +278,8 @@ private: uint8 stage = 0; uint32 aliveCount = 0; std::set stageEntries; + std::vector summonGuids; + uint32 probeTimer = 0; bool introDone = false; TaskScheduler scheduler; };