refactor(game): extract EntityController from GameHandler (step 1.3)

Moves entity lifecycle, name/creature/game-object caches, transport GUID
tracking, and the entire update-object pipeline out of GameHandler into a
new EntityController class (friend-class pattern, same as CombatHandler
et al.).

What moved:
- applyUpdateObjectBlock() — 1,520-line core of all entity creation,
  field updates, and movement application
- processOutOfRangeObjects() / finalizeUpdateObjectBatch()
- handleUpdateObject() / handleCompressedUpdateObject() / handleDestroyObject()
- handleNameQueryResponse() / handleCreatureQueryResponse()
- handleGameObjectQueryResponse() / handleGameObjectPageText()
- handlePageTextQueryResponse()
- enqueueUpdateObjectWork() / processPendingUpdateObjectWork()
- playerNameCache, playerClassRaceCache_, pendingNameQueries
- creatureInfoCache, pendingCreatureQueries
- gameObjectInfoCache_, pendingGameObjectQueries_
- transportGuids_, serverUpdatedTransportGuids_
- EntityManager (accessed by other handlers via getEntityManager())

8 opcodes re-registered by EntityController::registerOpcodes():
  SMSG_UPDATE_OBJECT, SMSG_COMPRESSED_UPDATE_OBJECT, SMSG_DESTROY_OBJECT,
  SMSG_NAME_QUERY_RESPONSE, SMSG_CREATURE_QUERY_RESPONSE,
  SMSG_GAMEOBJECT_QUERY_RESPONSE, SMSG_GAMEOBJECT_PAGETEXT,
  SMSG_PAGE_TEXT_QUERY_RESPONSE

Other handler files (combat, movement, social, spell, inventory, quest,
chat) updated to access EntityManager via getEntityManager() and the
name cache via getPlayerNameCache() — no logic changes.

Also included:
- .clang-tidy: add modernize-use-nodiscard,
  modernize-use-designated-initializers; set -std=c++20 in ExtraArgs
- test.sh: prepend clang's own resource include dir before GCC's to
  silence xmmintrin.h / ia32intrin.h conflicts during clang-tidy runs

Line counts:
  entity_controller.hpp  147 lines  (new)
  entity_controller.cpp  2172 lines (new)
  game_handler.cpp       8095 lines (was 10143, −2048)

Build: 0 errors, 0 warnings.
This commit is contained in:
Paul 2026-03-29 08:21:27 +03:00
parent 4f2a4e5520
commit f5757aca83
15 changed files with 2497 additions and 2260 deletions

View file

@ -810,8 +810,8 @@ void InventoryHandler::handleLootRoll(network::Packet& packet) {
// Resolve player name
std::string playerName;
auto nit = owner_.playerNameCache.find(playerGuid);
if (nit != owner_.playerNameCache.end()) playerName = nit->second;
auto nit = owner_.getPlayerNameCache().find(playerGuid);
if (nit != owner_.getPlayerNameCache().end()) playerName = nit->second;
if (playerName.empty()) playerName = "Player";
if (pendingLootRollActive_ &&
@ -848,8 +848,8 @@ void InventoryHandler::handleLootRollWon(network::Packet& packet) {
uint8_t rollType = packet.readUInt8();
std::string winnerName;
auto nit = owner_.playerNameCache.find(winnerGuid);
if (nit != owner_.playerNameCache.end()) winnerName = nit->second;
auto nit = owner_.getPlayerNameCache().find(winnerGuid);
if (nit != owner_.getPlayerNameCache().end()) winnerName = nit->second;
if (winnerName.empty()) winnerName = "Player";
owner_.ensureItemInfo(itemId);
@ -1374,7 +1374,7 @@ void InventoryHandler::handleListInventory(network::Packet& packet) {
// Play vendor sound
if (owner_.npcVendorCallback_ && currentVendorItems_.vendorGuid != 0) {
auto entity = owner_.entityManager.getEntity(currentVendorItems_.vendorGuid);
auto entity = owner_.getEntityManager().getEntity(currentVendorItems_.vendorGuid);
if (entity && entity->getType() == ObjectType::UNIT) {
glm::vec3 pos(entity->getX(), entity->getY(), entity->getZ());
owner_.npcVendorCallback_(currentVendorItems_.vendorGuid, pos);
@ -2076,8 +2076,8 @@ void InventoryHandler::handleTradeStatus(network::Packet& packet) {
tradePeerGuid_ = packet.readUInt64();
tradeStatus_ = TradeStatus::PendingIncoming;
// Resolve name
auto nit = owner_.playerNameCache.find(tradePeerGuid_);
if (nit != owner_.playerNameCache.end()) tradePeerName_ = nit->second;
auto nit = owner_.getPlayerNameCache().find(tradePeerGuid_);
if (nit != owner_.getPlayerNameCache().end()) tradePeerName_ = nit->second;
else tradePeerName_ = "Unknown";
owner_.addSystemChatMessage(tradePeerName_ + " wants to trade with you.");
if (owner_.addonEventCallback_) owner_.addonEventCallback_("TRADE_REQUEST", {tradePeerName_});
@ -3098,7 +3098,7 @@ void InventoryHandler::maybeDetectVisibleItemLayout() {
" mismatches=", bestMismatches, " score=", bestScore, ")");
// Backfill existing player entities already in view.
for (const auto& [guid, ent] : owner_.entityManager.getEntities()) {
for (const auto& [guid, ent] : owner_.getEntityManager().getEntities()) {
if (!ent || ent->getType() != ObjectType::PLAYER) continue;
if (guid == owner_.playerGuid) continue;
updateOtherPlayerVisibleItems(guid, ent->getFields());