From 5408eae69750c5f5a2c3424c38da081eb3920b07 Mon Sep 17 00:00:00 2001 From: SylvaniaCore deploy Date: Sun, 30 Aug 2026 22:51:16 +0200 Subject: [PATCH] Rivage brise 1460 : UNIT_FLAG2_UNK5 rendait les demons inattaquables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signale en jeu, nommement : Gangreseigneur Rakkan, Legionnaire gangregarde, Molosse de l effroi gangrene. Et l observation decisive : « les demons inattaquables se battent avec les demons attaquables ». LA CAUSE EST DE MON FAIT. La transposition des modeles a importe unit_flags2 sur 147 entrees. Ces creatures valaient 0 avant ; elles ont recu 2097152, soit 0x200000 -- UNIT_FLAG2_UNK5. CE DRAPEAU EST PARTICULIER : notre serveur l IGNORE totalement, aucune de ses verifications ne le consulte. Le client, lui, l interprete et refuse de designer la creature comme cible. C est ce qui explique le symptome le plus deroutant de la serie : la sonde posee dans _IsValidAttackTarget n a JAMAIS produit la moindre ligne pour ces creatures. Le client refusait de lui-meme, sans jamais interroger le serveur. L ABSENCE DE TRACE ETAIT L INFORMATION -- j ai mis trois tours a la lire comme telle. CORRELATION QUI TRANCHE : demons INVOQUES (attaquables) : unit_flags2 = 0 demons STATIQUES (bloques) : bit 0x200000 present 67 entrees, 420 spawns. Seul ce bit est retire, le reste de la colonne est preserve. Le serveur ne s en sert pas : le retrait ne peut rien casser cote logique. Egalement dans ce lot, deux sondes conservees le temps de la validation : ATTDBG (recentree sur les factions 2780/1768) et SPAWNDBG (etat reel des creatures a leur creation). Deux divergences d API relevees au passage : getFaction() et getLevel(), en minuscule dans ce fork. Retour arriere joint. Co-Authored-By: Claude Opus 5 --- chantiers/rivage_brise/retour_unk5_1460.sql | 67 +++++++++++++++++++ sql/sylvania/rivage_unk5_1460.sql | 42 ++++++++++++ .../game/Entities/Creature/Creature.cpp | 21 ++++++ src/server/game/Entities/Unit/Unit.cpp | 14 +++- 4 files changed, 141 insertions(+), 3 deletions(-) create mode 100644 chantiers/rivage_brise/retour_unk5_1460.sql create mode 100644 sql/sylvania/rivage_unk5_1460.sql diff --git a/chantiers/rivage_brise/retour_unk5_1460.sql b/chantiers/rivage_brise/retour_unk5_1460.sql new file mode 100644 index 0000000..906d16d --- /dev/null +++ b/chantiers/rivage_brise/retour_unk5_1460.sql @@ -0,0 +1,67 @@ +UPDATE `creature_template` SET `unit_flags2`=2097152 WHERE `entry`=90686; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=97525; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=112920; +UPDATE `creature_template` SET `unit_flags2`=2097152 WHERE `entry`=100959; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=97527; +UPDATE `creature_template` SET `unit_flags2`=2099201 WHERE `entry`=112977; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=113054; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=113055; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=102706; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=113058; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=97528; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=94191; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=113056; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=113057; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=113053; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=94190; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=94189; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=91970; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=102701; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=113059; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=105217; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=110941; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=94223; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=97502; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=102698; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=91949; +UPDATE `creature_template` SET `unit_flags2`=2099201 WHERE `entry`=92122; +UPDATE `creature_template` SET `unit_flags2`=2099201 WHERE `entry`=97503; +UPDATE `creature_template` SET `unit_flags2`=2097152 WHERE `entry`=92121; +UPDATE `creature_template` SET `unit_flags2`=2099201 WHERE `entry`=94209; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=110615; +UPDATE `creature_template` SET `unit_flags2`=2099201 WHERE `entry`=97526; +UPDATE `creature_template` SET `unit_flags2`=2099201 WHERE `entry`=113290; +UPDATE `creature_template` SET `unit_flags2`=2099201 WHERE `entry`=108990; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=112921; +UPDATE `creature_template` SET `unit_flags2`=2099201 WHERE `entry`=97521; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=93704; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=110614; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=102704; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=102703; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=102705; +UPDATE `creature_template` SET `unit_flags2`=2097152 WHERE `entry`=109591; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=113036; +UPDATE `creature_template` SET `unit_flags2`=2097152 WHERE `entry`=109604; +UPDATE `creature_template` SET `unit_flags2`=2097152 WHERE `entry`=109592; +UPDATE `creature_template` SET `unit_flags2`=2099201 WHERE `entry`=113291; +UPDATE `creature_template` SET `unit_flags2`=2131968 WHERE `entry`=113038; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=90711; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=90712; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=90708; +UPDATE `creature_template` SET `unit_flags2`=2131968 WHERE `entry`=91588; +UPDATE `creature_template` SET `unit_flags2`=2131968 WHERE `entry`=109587; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=91353; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=97486; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=92586; +UPDATE `creature_template` SET `unit_flags2`=2113536 WHERE `entry`=92061; +UPDATE `creature_template` SET `unit_flags2`=2131968 WHERE `entry`=109586; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=101056; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=90714; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=93219; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=90710; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=97496; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=101057; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=90717; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=90705; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=90713; +UPDATE `creature_template` SET `unit_flags2`=2099200 WHERE `entry`=90709; diff --git a/sql/sylvania/rivage_unk5_1460.sql b/sql/sylvania/rivage_unk5_1460.sql new file mode 100644 index 0000000..bd91450 --- /dev/null +++ b/sql/sylvania/rivage_unk5_1460.sql @@ -0,0 +1,42 @@ +-- ===================================================================== +-- Rivage brisé (carte 1460) — retrait du drapeau UNIT_FLAG2_UNK5 +-- +-- Signalé en jeu : « les démons invoqués c'est ok mais pas les autres au +-- fond », puis « les fameux démons inattaquables se battent avec les +-- démons attaquables ». Nommément : Gangreseigneur Rakkan, Légionnaire +-- gangregarde, Molosse de l'effroi gangrené. +-- +-- LA CAUSE, et elle est de mon fait +-- La transposition des modèles depuis le dump de référence a importé +-- `unit_flags2` sur 147 entrées. Ces trois-là valaient 0 avant ; elles +-- ont reçu 2097152, soit 0x200000 — UNIT_FLAG2_UNK5 dans notre cœur. +-- +-- CE QUI REND CE DRAPEAU PARTICULIER : notre serveur l'IGNORE +-- totalement. Aucune de ses vérifications ne le consulte. Mais le client, +-- lui, l'interprète et refuse de désigner la créature comme cible. +-- +-- C'est ce qui explique le symptôme le plus déroutant de la série : une +-- sonde posée dans `Unit::_IsValidAttackTarget` n'a JAMAIS produit la +-- moindre ligne pour ces créatures. Le client refusait de lui-même, sans +-- jamais interroger le serveur. L'absence de trace était l'information. +-- +-- LA CORRÉLATION QUI TRANCHE +-- démons INVOQUÉS par le script (attaquables) : unit_flags2 = 0 +-- démons STATIQUES (bloqués) : bit 0x200000 présent +-- 67 entrées, 420 spawns concernés +-- +-- On retire UNIQUEMENT ce bit, en préservant le reste de la colonne. +-- Le serveur ne s'en sert pas : ce retrait ne peut rien casser côté +-- logique, il lève seulement le refus du client. +-- +-- Retour arrière : chantiers/rivage_brise/retour_unk5_1460.sql +-- ===================================================================== + +UPDATE `creature_template` ct + JOIN (SELECT DISTINCT c.id + FROM creature c + JOIN creature_template t ON t.entry = c.id + WHERE c.map = 1460 + AND (t.unit_flags2 & 2097152)) AS cible + ON cible.id = ct.entry + SET ct.unit_flags2 = ct.unit_flags2 & ~2097152; diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 4bbc29d..4484e4d 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -3336,6 +3336,27 @@ void Creature::ReLoad(bool skipDB) if (IsAIEnabled) AI()->EnterEvadeMode(); + // SONDE TEMPORAIRE - carte 1460 uniquement. Journalise l'etat REEL en + // memoire, pour le comparer a la base. Une creature sur dix suffit : + // il y en a 757, on veut un echantillon, pas un deluge. + if (GetMapId() == 1460) + { + static uint32 sondeSpawn = 0; + if ((++sondeSpawn % 10) == 1) + { + TC_LOG_ERROR("misc", + "SPAWNDBG %s (entree %u) | faction=%u niveau=%u | pv=" UI64FMTD "/" UI64FMTD + " | vivante=%u | drapeaux=%u drapeaux2=%u dynamiques=%u | phases=%u | reactState=%u", + GetName().c_str(), GetEntry(), getFaction(), getLevel(), + GetHealth(), GetMaxHealth(), + uint32(IsAlive() ? 1 : 0), + GetUInt32Value(UNIT_FIELD_FLAGS), GetUInt32Value(UNIT_FIELD_FLAGS_2), + GetUInt32Value(OBJECT_DYNAMIC_FLAGS), + uint32(GetPhaseShift().GetPhases().size()), + uint32(GetReactState())); + } + } + TC_LOG_DEBUG("sql.sql", "Creature SpawnID (" SI64FMTD ") reloaded.", GetSpawnId()); } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 19e8de5..b7c4cfd 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -8319,13 +8319,18 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo // au plus, et uniquement dans ce scenario. if (GetTypeId() == TYPEID_PLAYER && target->GetTypeId() == TYPEID_UNIT && GetMapId() == 1460) { + // On ne veut QUE les demons statiques : factions 2780 et 1768. + // Les invoques (faction 16) fonctionnent deja et polluaient le + // releve. + uint32 const factionCible = target->getFaction(); static uint32 sondeAtt = 0; - if ((++sondeAtt % 20) == 1) + if ((factionCible == 2780 || factionCible == 1768) && (++sondeAtt % 5) == 1) { TC_LOG_ERROR("misc", "ATTDBG cible %s (entree %u) | vivante=%u etatInattaquable=%u | drapeaux=%u " "(NON_ATTACKABLE=%u NOT_ATTACKABLE_1=%u UNK_16=%u IMMUNE_PC=%u NOT_SELECTABLE=%u) " - "| reaction=%d | jeLaVois=%u | mesPhases=%u sesPhases=%u", + "| reaction=%d | jeLaVois=%u | mesPhases=%u sesPhases=%u " + "| factionCible=%u maFaction=%u | elleMEstHostile=%u jeLuiSuisHostile=%u", target->GetName().c_str(), target->GetEntry(), uint32(target->IsAlive() ? 1 : 0), uint32(target->HasUnitState(UNIT_STATE_UNATTACKABLE) ? 1 : 0), @@ -8338,7 +8343,10 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo int32(GetReactionTo(target)), uint32(CanSeeOrDetect(target, true) ? 1 : 0), uint32(GetPhaseShift().GetPhases().size()), - uint32(target->GetPhaseShift().GetPhases().size())); + uint32(target->GetPhaseShift().GetPhases().size()), + factionCible, getFaction(), + uint32(target->IsHostileTo(this) ? 1 : 0), + uint32(IsHostileTo(target) ? 1 : 0)); } }