fb959731ceef9fbdde309fab31c900d4c2e1dcdc
174 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d681f73f54 |
Fief WoD : aucun moyen de rentrer dans un fief deja fonde
Les deux points d entree ne se declenchent que si le joueur n a PAS encore de fief : l objet Master Surveyor (233664, Horde) et Baros Alexston (79243, Alliance). Une fois le fief fonde, plus rien n y ramenait. Les trois joueurs du royaume qui en possedent un ne sont jamais alles dessus : aucun personnage n a jamais ete sur les cartes 1152, 1153, 1158, 1159, 1330 ni 1331. Gazlowe (78466) et Baros proposent desormais "Emmenez-moi a mon fief" aux proprietaires. L option est masquee quand on est deja sur une carte de fief, Gazlowe y etant aussi spawne. Le declencheur de proximite cote Horde n est pas touche : il aurait teleporte tout passant. TeleportOwnerAndPlayMovie renomme TeleportOwnerToGarrison, l ancien nom mentait depuis le retrait du film. |
||
|
|
c74de0d601 |
Fief WoD : le film d etablissement figeait le client
Signalement joueur du 05/09 : la cinematique du fief bloque le jeu, il faut se reconnecter pour continuer. Le film (189 Horde / 192 Alliance au niveau 1) etait envoye par SendMovieStart, et le teleport dans le fief etait accroche a CMSG_COMPLETE_MOVIE. Un client qui ne joue pas le film ne renvoie jamais ce paquet : le joueur restait bloque ET n arrivait jamais dans son fief. On teleporte donc directement. Meme demarche que pour les scenes 953 / 986 et 961 / 962 : la cause du gel cote client reste inconnue, on supprime le declencheur pour ne plus bloquer la progression. Le commentaire indique quoi remettre le jour ou on saura. |
||
|
|
44fad5a041 |
Tanaan : deux scenes WoD cassaient la fin de l intro
Signalements joueur du 05/09. Scenes 953 / 986 (bateau) : rendre "La derniere ligne droite" faisait planter le client. La scene est ecrite pour se jouer sur un transport en mouvement, alors que PlaySceneByPackageId l envoie ancree sur la position du joueur, TransportGUID vide et SceneID nul. On fait desormais directement le teleport et le succes que son declencheur "Teleport" produisait. Scenes 961 / 962 (marques de Tanaan) : cliquer une des deux pierres de la quete 34392 envoyait le joueur sous la map. Rien d autre sur ce chemin ne deplace le joueur (le sort du goober est un simple KILL_CREDIT, aucun hook de scene mal filtre, les marques sont au niveau du sol), et l ecart entre ancrer sur l objet ou sur le joueur est de deux metres : c est la scene elle-meme. Elle est decorative, le credit de quete est donne avant. |
||
|
|
35c52bd806 |
Scenarios : un evenement etait compte une fois par joueur present
SIGNALE EN JEU : « un petit groupe de demons m a valide les 33/33 et les
3/3 gangreseigneurs d un coup ». L exploitant a refuse mon explication --
« je ne vois pas en quoi c est une bonne nouvelle » -- et il avait
raison.
InstanceScript::DoSendEventScenario passait par DoUpdateCriteria, qui
diffuse a CHAQUE joueur de l instance. Or Player::UpdateCriteria
transmet ensuite au scenario :
if (Scenario* scenario = GetScenario())
scenario->UpdateCriteria(type, ...);
et ce compteur est PARTAGE par toute l instance. Chaque mort etait donc
comptee autant de fois qu il y avait de joueurs presents. Avec une
escorte de quatre mercenaires, sept demons suffisaient a remplir un
objectif qui en demande trente-trois.
Le defaut restait invisible tant qu on jouait seul : un joueur, un
credit. L escorte l a mis au jour. Il touche tous les scenarios du
serveur, pas seulement le Rivage brise.
L evenement credite desormais le scenario une seule fois, avec un joueur
de reference pour les conditions qui en dependent.
HAUT FAIT JCJ HORS SUJET. « J ai attaque un petit groupe de demons et
j ai recu le haut fait Courroux de l Alliance », qui demande de tuer
cinq joueurs de la Horde dans chaque grande ville.
KillRewarder::Reward creditait CRITERIA_TYPE_SPECIAL_PVP_KILL a chaque
membre du groupe pour n importe quelle mort, creatures comprises. Meme
mecanisme d apparition : ce bloc n est parcouru qu en groupe.
TrinityCore ne fait pas cette mise a jour du tout, ni en 3.3.5 ni en
master -- c est un ajout local, pose sans le garde-fou _isPvP que ce
fichier emploie partout ailleurs. Il est ajoute.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
24a0700853 |
Playerbots : les ordres n'atteignaient jamais leur destinataire
SIGNALE EN JEU : « !summon repond "You can't teleport yourself to
yourself", et !follow repond "There is no such command" ».
ChatHandler::ParseCommands traite le point d'exclamation comme un
prefixe de commande au meme titre que le point :
if (text[0] != '!' && text[0] != '.')
return false;
Il intercepte donc tout ordre ligne 202 de HandleChat, bien avant que
le message n'atteigne le canal de groupe ou Group::ProcessGroupBotCommand
l'attend, ligne 405. « !summon » partait vers la commande de maitre de
jeu du meme nom, « !follow » vers une commande inexistante.
Le systeme d'ordres aux playerbots -- summon, attack, follow, flee,
stop, equipement, talents -- etait donc inaccessible depuis toujours.
Comme la formation de groupe corrigee juste avant, il etait ecrit,
complet, et jamais atteint.
Les messages en « ! » passent desormais aux compagnons lorsque le joueur
en commande effectivement. Un maitre de jeu sans bot garde ses commandes
en « ! » ; celui qui en a passe par le point, qui reste le prefixe
principal.
Corrige aussi : le journal des mercenaires annoncait « a paye 100 po »
pour les recrutements offerts. Rien n'etait preleve -- le garde-fou est
bien en place -- mais un journal qui raconte le contraire de ce qui
s'est passe fait perdre du temps au diagnostic suivant.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
ba0caeece2 |
Playerbots : la formation de groupe n'a jamais fonctionne
SIGNALE EN JEU : « les bots restent les uns sur les autres, il n existe
pas des commandes de strategie de placement ? ». Le systeme existait
bien -- il etait casse.
GetPositionFromGroup calcule correctement une place propre a chaque
membre : un angle reparti sur le cercle, a quatre metres du meneur. Mais
son resultat n etait jamais renvoye :
Position resultPos(distX, distY, distZ, ...); // calculee
Position pos; // vide
pCenterPlayer->GetFirstCollisionPosition(...); // resultat jete
return pos; // (0,0,0)
GetFirstCollisionPosition REND une Position ; son retour etait ignore et
l on renvoyait une variable jamais renseignee. La fonction rendait donc
l origine du monde a tous ses appelants -- BotGroupAI comme BotAITool.
Par-dessus, les deux MoveFollow de BotGroupAI employaient la meme
distance et le meme angle pour tout le monde : un metre devant le
meneur, a son orientation. Meme reparee, la formation aurait ete ecrasee
deux lignes plus loin. Chaque bot y prend desormais l angle de son rang
dans le groupe, a trois ou quatre metres selon l effectif.
Le defaut ne touchait pas que le scenario : il vaut pour tous les
playerbots du serveur, champs de bataille et donjons compris.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
bd22c62631 |
Rivage brise : embarquement sur le navire, escorte de mercenaires, factions
L'exploitant a fourni une seconde video, en 1080p et sans ecran partage, qui montre le vrai depart cote Alliance. Elle a permis quatre corrections. L'EMBARQUEMENT. Le script d'Angelica deposait le joueur en (443.8, 2076.1, 1.2), le point d'ancrage de la plage -- une coordonnee inventee. Le sort officiel 199358 porte (441.2, 2023.75, 4.44) dans spell_target_position, marque VerifiedBuild 27843 : le pont de l'Alliance Battleship. On y teleporte desormais. La premiere etape s'intitule « Rendez-vous au rivage Brise » et ne s'acheve qu'une fois le joueur debarque, au lieu d'une minuterie de douze secondes qui s'ecoulait pendant le chargement du client. Sa condition exigeait par ailleurs que la quete 42740 soit EN COURS : deja rendue ou pas encore prise, l'option restait muette. Elle accepte maintenant les trois etats et explique le refus au lieu de ne rien faire. LES FACTIONS, et la resolution du paradoxe d'aout. On avait bascule les demons de cette carte en faction 16 parce que la 2780 les rendait inattaquables, sans comprendre pourquoi. Le prix etait invisible : la faction 16 porte EnemyGroup = 1, elle n'est hostile QU'AUX JOUEURS. Nos allies, eux, ont EnemyGroup = 0 et une liste d'ennemis qui designe la faction 1786. Les deux camps ne se reconnaissaient pas -- d'ou les soldats qui s'engagent puis n'ont personne a frapper, releve par la sonde d'evasion : onze fois pour la garde royale gilneenne, dix pour Jaina, dix pour Varian. On avait repare le joueur en supprimant la bataille. Les 102 entrees exclusives a la carte passent en 2898, qui porte la meme faction 1786 mais avec EnemyGroup = 15, hostile a tous. Verifie en jeu : attaquable. L'ESCORTE. Le scenario officiel se joue en groupe constitue par la file d'attente, que nous n'avons pas. A l'entree, une escorte est desormais offerte : un protecteur, un guerisseur et deux combattants, via le module des mercenaires. Un mode gratuit y est ajoute -- le contrat reste identique, rupture au premier depart du groupe, mais sans prelevement. Les invocations sont espacees d'une seconde et demie, faute de quoi elles se superposaient au meme point. LES DOUBLONS DE DISTRIBUTION. Quatrieme et cinquieme occurrences du meme defaut : le script invoquait Genn, Jaina, Mekkatorque, l'escorte et Arganoth alors que la carte les porte tous. Toutes les invocations de l'introduction sont supprimees ; c'est Genn qui ouvre la scene cote Alliance, Varian n'etant pas encore la -- ce qui est tout l'objet de l'etape « Trouver Varian ». Corrige aussi : Gul'dan Talk(1) n'existait pas, le script l'appelait dans la finale et rien ne se jouait. 263 allies passent en arme degainee, 131 recoivent un equipement recupere de la reference et la posture EMOTE_STATE_READY1H. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
346bd9c200 |
Rivage brise : Tirion introuvable, allies desarmes, intro inaudible
SIGNALE EN JEU : « p7 Tirion reste muet, le script ne se lance plus, mais Krosus est bien combattable ». Un seul defaut, deux symptomes. La verification de proximite sortait SANS SE REPLANIFIER quand Tirion n'etait pas encore charge -- sa zone se trouve a l'autre bout de la carte, et la grille ne se peuple qu'a l'approche du joueur. Au premier passage, deux secondes apres la fin de l'etape 6, il n'existait pas : la tache mourait la, definitivement. D'ou Tirion muet, et d'ou Krosus combattable, puisque c'est cette meme scene qui devait le figer. Le meme Repeat existait deja dans la detection de Varian ; je ne l'avais pas reporte ici. « Varian a un dialogue audio au lancement de la campagne, il ne se declenche pas. » StartIntro etait appele DANS OnPlayerEnter, pendant l'ajout du joueur a la carte : le cri partait quand le client chargeait encore la zone. Decale de quatre secondes. Corrige au passage le demarrage direct en phase 2, meme cause -- les douze secondes de la premiere phase s'ecoulaient avant l'arrivee effective. « Tous les PNJ allies doivent porter leurs armes. » L'etat de fourreau ne suffisait pas : il n'y avait rien a degainer. Sur les 51 entrees alliees de la carte, seules QUATRE avaient un equipement defini. Trente equipements recuperes du creature_equip_template de la reference : 131 spawns sont desormais armes, contre 11. Les 263 allies passent aussi en arme degainee, sans emote d'etat -- l'emote 27 demandee est celle du combat A MAINS NUES et aurait range leurs armes. Sans emote forcee, le client joue l'attitude propre a l'arme reellement portee, hache a deux mains comme epee courte. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
0032c28f21 |
Rivage brise : plus aucune vague, Krosus attaquable, Tirion atteignable
Trois signalements en jeu, une cause commune pour deux d'entre eux. « Il y a toujours ces vagues de demons qui m'attaquent, RETIRE-LES. » Le script a ete ecrit quand la carte etait VIDE : il fabriquait ses propres ennemis a la plage, chez le commandant, dans la cite et au tombeau. Elle porte aujourd'hui 748 creatures posees, et toutes ces invocations faisaient double emploi. Supprimees aux quatre endroits. « La p9 vaincre Gul'dan se valide toute seule. » Meme origine : elle s'achevait apres huit morts de demons, or le script en invoquait lui-meme quatre au tombeau puis quatre autres vingt secondes plus tard. Il declenchait sa propre condition de fin. L'etape se conclut desormais au terme de la sequence de Gul'dan, une fois ses repliques prononcees. « Le Krosus du lac de lave en p8 est inattaquable. » Il portait la faction 2878 -- exactement le defaut resolu en aout pour les autres demons de cette carte, ou 2780 et 1768 les rendaient inattaquables et avaient toutes ete basculees en 16. La 2878 n'etait pas dans le lot, personne n'etant jamais alle aussi loin dans le scenario. L'entree 90544 n'existe QUE sur la carte 1460, un seul exemplaire. « Le scenario ne se declenche que si on saute dans la lave. » Tirion agonise au bord du bassin a z=40, Krosus etant a z=35 : avec un rayon de 25 metres, le seul point qui satisfaisait la condition etait la lave elle-meme. Porte a 50. Les poids de la barre de l'etape 6 montent d'un cran -- 5 pour les demons ordinaires, 10 pour les elites -- la progression ayant ete jugee trop lente en jeu. Avec 2 et 5, la cite plafonnait a 273 points sur 300, ce qui expliquait aussi les vagues que j'avais ajoutees pour compenser puis retirees. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
5f5317dee3 |
Rivage brise : employer les PNJ de la carte, couper les vagues, etendre les voix
SIGNALE EN JEU, trois points.
« Tu ne les as pas implementes au Tirion et Krosus qu il y avait de base
sur la map, tu en as ajoute. » Exact, et c est la meme faute que pour
Varian avant-hier. Les protagonistes de la crevasse SONT poses sur la
carte, mais sous d autres entrees que celles du script :
91951 Highlord Tirion Fordring (1495, 1751)
94276 Gul dan (1530, 1742)
90544 Krosus (1481, 1716)
90705 Dread Commander Arganoth ( 613, 2085)
Le script invoquait des sosies aux entrees 90367 et 90413, qui ne
figurent nulle part. OnCreatureCreate retient desormais les quatre, et
la scene de la mort de Tirion emploie ceux de la base -- Krosus n est
plus duplique, il est seulement rendu inerte le temps de la sequence.
« Ces invocations de demon, il faut arreter ca, a chaque fois que je me
bats ils reviennent en vague, c est affreux. » Supprimees. Elles etaient
une addition de ma part pour permettre a la barre d atteindre ses 300
points -- un pansement pose sur une deduction incertaine, qui rendait le
combat interminable. Si la barre plafonne, c est la correspondance des
poids qu il faudra revoir, pas le nombre d ennemis.
« Les voix qui marchent, Tirion Krosus et Gul dan, c est les seules. »
Confirmation du mecanisme : seules ces repliques portaient un
BroadcastTextId. Les autres sont nos textes inventes, avec un zero dans
ce champ, donc muettes par construction. Sept repliques de mise en scene
recoivent leur identifiant et leur son officiels -- le ralliement de
Varian et de Vol jin, la mort de Varian, Jaina, Sylvanas, et les deux
repliques finales de Gul dan.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
a9f2fde270 |
Rivage brise : la mort de Tirion, et les renforts qui tombaient sur le joueur
SIGNALE EN JEU : « p7 c'est Krosus qui plonge Tirion dans le fiel normalement, et la pas de script de scenario ». Le script se contentait d'invoquer Krosus douze secondes apres avoir pose Tirion agenouille. La sequence officielle est relevee sur Warcraft Wiki, et ses huit repliques existent dans nos donnees avec leur BroadcastTextId ET leur Sound -- de 99237 a 99247. Elle est desormais jouee en trente-trois secondes : Tirion comprend le piege, Gul'dan lui repond depuis le tombeau, Krosus surgit de la lave, Gul'dan ordonne, Krosus souffle, Tirion sombre, le chef de faction riposte, Gul'dan raille puis lance l'assaut. Krosus n'est attaquable qu'a ce dernier signal. Gul'dan est invoque des cette scene, au sommet du tombeau, et y reste jusqu'a la fin -- c'est de la qu'il domine le champ de bataille. La finale le reutilise au lieu d'en invoquer un second. RENFORTS DE LA CITE : « en phase 6 j'ai des invocations de demon sur ma tronche ». Ils naissaient au point de ralliement, c'est-a-dire au milieu du combat. Ils arrivent desormais de la peripherie, sur un cercle de 45 a 60 metres dont l'orientation change a chaque vague, puis chargent. Ces vagues restent une addition de ma part, pas une donnee du jeu : la cite ne compte que 273 points de defenseurs pour une barre qui en demande 300. Si la correspondance des poids se revele fausse, elles n'auront plus lieu d'etre. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
82254cf627 |
Rivage brise : les neuf etapes ont enfin leurs criteres officiels
Suite du parcours joue de bout en bout avec l'exploitant. ETAPE 6, LA BARRE RESTAIT A 0 %. Son arbre 42770 porte l'operateur 9, SUM_CHILDREN_WEIGHT : la barre vaut 300 points et chaque enfant y contribue selon son poids -- 44384 vaut 1, 53062 vaut 2, 53063 vaut 5, 53064 vaut 10. Le script n'envoyait aucun des quatre : il comptait dix morts dans son coin et forcait le passage, laissant la barre morte. Les demons ordinaires alimentent desormais le poids 2, les elites le poids 5, et des vagues affluent pour que la barre puisse se remplir -- la zone ne compte pas assez de defenseurs pour ses 300 points. LES CAGES DE LA LEGION ne comptaient pour rien : aucun critere ne les mentionne, et elles n'avaient aucun script. Signale en jeu, puis confirme par l'observation (« la barre bouge de 1 % »). Elles portent le quatrieme poids, le seul qui restait libre. Les 39 exemplaires sont rattaches a go_legion_cage. ETAPE 7, TIRION se validait par une minuterie de douze secondes, sans le joueur, et disparaissait au bout de vingt -- impossible a atteindre meme en courant. Meme defaut que « Trouver Varian ». Il faut desormais le rejoindre, il reste en place, et Krosus n'apparait qu'ensuite. ETAPES 8 ET 9 cablees dans la foulee : 44669 a la mort de Krosus, 44826 quand Gul'dan est arrete. Plus aucune etape ne se valide par forcage. DOUBLONS DE PLACEMENT : neuf creatures de la 1460 et trente-huit de la 1666 occupaient une position strictement identique a une autre, au centimetre pres. L'import n'est pas en cause -- la reference les porte deja en double, guids 294825 et 294827 pour l'entree 92564. Ecart assume avec elle, au benefice du rendu. RESERVE : la correspondance des quatre poids de l'etape 6 reste une deduction. La cite ne contient que deux categories d'ennemis la ou les poids en supposent quatre. A verifier en jeu, chiffres en main. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
70fdf20075 |
Rivage brise 1460 : les vrais criteres, et le deroule de reference
SIGNALE EN JEU : « j ai passe ma phase 2 et ca m a switche jusqu a la 5 sans rien faire », puis « je suis en phase 4, juste a cote de Varian, et rien ne se valide ». Deux causes distinctes. La plage validait son etape DEUX fois : une fois par les criteres officiels que le moteur reconnait, une seconde par le CompleteStep() ajoute par-dessus. Le moteur avancait donc de deux crans. Le forcage est retire, les criteres suffisent. L etape « Trouver Varian » guettait une copie invoquee sur la plage, alors que la carte porte DEJA le vrai Varian en (1120, 2484) parmi les 757 creatures transposees -- comme Vol jin, Sylvanas et Jaina. Le joueur se tenait devant le bon personnage pendant que le script surveillait un sosie. On retient desormais celui de la base, distingue par son spawnId, et on ne le teleporte plus : l etape s appelle « Trouver ». L etape du portail comptait deux « ancres dimensionnelles » (90637) que le script fabriquait lui-meme. La video de la bataille affiche « 0/4 Ancres blindees detruites », et le wiki confirme : quatre 101667, dont la carte porte quinze exemplaires deja poses. Les criteres officiels 45131, 45228 et 45288 sont desormais alimentes. Le deroule de reference joint croise la video, les DB2 du build et le wiki. Il revele trois ecarts NON corriges : le commandant Horde est Azgalor et non Arganoth, l etape 4 Horde vise Sylvanas ET Baine, et l etape 9 Horde consiste a tenir la crete. Il etablit aussi que nos dialogues sont inventes -- BroadcastTextId a zero -- et que la replique de Jaina parlant d ancres « dimensionnelles » est ce qui a produit l erreur de code de l etape 5. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
5c8b82338e |
Coeur de Pierre : l'Eclat sismique d'Azil faisait tomber le serveur
Signale en jeu avec une reproduction exacte : « si on attend la phase
deux sans le frapper, le serveur plante ». Deux vidages memoire l'ont
confirmee, pile en main :
#0 spell_seismic_shard::HandleScript(SpellEffIndex)
#1 Spell::HandleEffects
#2 Spell::DoSpellHitOnUnit
...
#13 InstanceMap::Update
GetDynObject renvoie un pointeur NUL quand l'objet de visee n'existe pas
-- pas encore cree, ou deja expire. La ligne suivante le dereferencait
sans le moindre test :
DynamicObject* dynamicObject = GetCaster()->GetDynObject(...);
target->CastSpell(dynamicObject->GetPositionX(), ...);
Le plantage a lieu dans le fil de mise a jour de la carte, donc il
emporte le processus entier, pas seulement la session fautive.
GetCaster() et GetHitUnit() sont verifies au passage : rien ne garantit
leur presence au moment ou l'effet est traite, un lanceur mort entre le
lancement et l'impact suffit. Meme prudence sur le ExitVehicle du script
de changement de siege, juste au-dessus.
RESTE OUVERT, signale par le meme joueur et non traite ici : le deuxieme
boss du donjon se reinitialise des qu'on le deplace, et le bouclier du
dernier boss serait purement visuel, sans absorption.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
37796803c7 |
Passe de warnings sur tout le core : 12 bugs reels corriges
Scan de -fsyntax-only avec les vrais flags sur les 1767 fichiers du
serveur (compile_commands.json), warnings de logique actives. 3277
warnings, tries a la main. Le bruit (Wreorder, Wswitch) est ecarte ;
voici ce qui etait un vrai defaut.
Memoire morte et comportement indefini :
- ObjectMgr::GetGarrssionMissionReward rendait l adresse d un vecteur
local ; Garrison melangeait puis parcourait cet objet detruit.
- BattlePayDataStoreMgr::GetProduct faisait "return{}" sur une fonction
qui rend une reference : huit appelants lisaient un temporaire mort.
- Garrison::RewardMission reaffectait une initializer_list, ce qui ne
prolonge pas la duree de vie du tableau sous-jacent.
- WorldSession avait un destructeur non virtuel alors que
PlayerBotSession en derive : chaque delete d une session de bot ne
detruisait que la moitie de l objet. Idem FieldActing.
- boss_levantus lisait Waypointspawn[6] dans un tableau de 6 entrees,
a chaque declenchement de l evenement.
- boss_hyrja_tov modifiait expelLightSwitch deux fois sans point de
sequence, et replanifiait son evenement toutes les 20 ms au lieu de
20 secondes (IN_MILLISECONDS manquant).
Code jamais appele :
- cinq hooks OnRemoveTarget d areatrigger (Klaxxi, Blackfuse, Siege
d Orgrimmar, Ordos) : le hook du core s appelle OnUnitExit, ces
methodes n etaient rattachees a rien et les auras restaient sur le
joueur apres sa sortie de zone. Trois d entre elles n avaient meme
pas de return.
- boss_admiral_svirax declarait un membre bool du meme nom que
SetDungeonEncounterID, qui masquait la methode de BossAI ; l appel
avait ete "repare" par une virgule et ne faisait donc rien.
- WorldSession::HasSocket comparait l adresse d un tableau a NULL,
donc rendait toujours true.
Conditions toujours vraies :
- zone_vault_of_wardens : "== QUEST_STOP_GULDAN_H || QUEST_STOP_GULDAN_A"
jouait la scene de Gul dan pour n importe quelle quete acceptee.
- boss_vizaduum : "type == POINT_MOTION_TYPE || WAYPOINT_MOTION_TYPE".
- boss_council_of_elders : parenthese fermee au mauvais endroit,
"HasAura(SPELL_DISCHARGE || HasAura(SPELL_OVERLOAD))".
Valeurs tronquees :
- InstanceScript::m_ScenarioStep etait un uint8 alors qu il recoit des
ID de ScenarioStep (3195, 3207...), tronques a 135 ou 136.
- PetBattleTrainer passait 3000000000000000 a SetRespawnTime(uint32).
Nettoyage sans effet de bord : memcpy sur PetBattleRequest remplace par
une copie, et suppression d un getThreatList()/empty() sans effet dans
boss_wise_mari.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
5205a9b5f0 |
Dompteurs de mascottes : return manquant, le journal de quetes lu hors limites
Cliquer sur un dompteur de mascottes (88 PNJ, dont Julia Stevens 64330) tuait le worldserver. Player::QuestObjectiveActiveInPlayerByObject n avait aucun return sur le chemin de sortie de boucle. GCC en deduit que la boucle ne peut pas se terminer normalement -- sinon comportement indefini -- et supprime le test q < MAX_QUEST_LOG_SIZE. Le numero de slot grimpait donc au-dela de 25 jusqu a sortir du tableau de valeurs du joueur : ASSERT dans GetUInt32Value (index 4636, slot 275 dans la pile signalee). Le compilateur le disait deja : "control reaches end of non-void function" dans nos logs de build. C etait le seul cas du core, il n y en a plus. Au passage, PetBattleTrainer.cpp gardait ObjectId et isTrainer comme membres du CreatureScript, or celui-ci est un singleton partage par les 88 PNJ et par tous les joueurs : le dernier interlocuteur decidait de ce que pouvait faire le suivant. La verification se fait desormais sur le joueur et le PNJ courants. Signale sur le Discord avec une pile gdb par un utilisateur du core. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
6d98d5cbbd |
Rivage brise : l entree du scenario d assaut n existait nulle part
La carte 1666 etait peuplee et scriptee depuis hier, mais aucun chemin n y menait : le joueur restait plante devant Khadgar. Les quetes 45102 et 46734 restaient donc infranchissables malgre le portage. Le deroulement officiel, decrit par les joueurs : on prend la quete a l Anneau de Krasus, on choisit une option de dialogue, et l on est emporte par la voie des airs. Cette option n existe ni dans notre base ni dans le dump de reference -- donnee de capture jamais importee. Elle est donc recreee sur Khadgar 86563, qui est bien celui de l Anneau de Krasus : pose en (-841, 4258, 746), l altitude de Dalaran, et deja donneur d Assault on Broken Shore. Rien d invente sur la destination : le sort 240603 porte deja les coordonnees officielles dans spell_target_position. OnGossipHello reconstruit le menu complet avant d ajouter l option, sans quoi Khadgar perdrait les seize quetes qu il propose : le coeur saute PrepareGossipMenu des qu un script repond au dialogue. Verifie en jeu : le joueur arrive bien sur la carte 1666 aux coordonnees attendues. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
e0b2fcf3e0 |
Creatures volantes : aucun chemin vers une cible hors du maillage, evade et butin perdu
_setTargetLocation ne passait pas CanFly() en forceDest a CalculatePath. Une
creature volante dont la cible se tient sur un relief non navigable obtenait
PATHFIND_NOPATH, se marquait injoignable, puis evadait au bout de cinq secondes
(CREATURE_NOPATH_EVADE_TIME).
Chaque evade passe par CreatureAI::_EnterEvadeMode, qui lache le proprietaire de
butin et reinitialise m_PlayerDamageReq. A la mort, Unit::Kill force alors
SetLootRecipient(NULL) : le corps est vide et ne rapporte aucune experience. Le
symptome remonte comme un bug de table de butin alors que la table est saine.
Signale sur le Proto-drake perdu dans le temps (32491) aux Pics Foudroyes, qui
lachait l aggro tant que le joueur n etait pas sur une plateforme reliee au
maillage, puis n a rien donne une fois tue. 3709 creatures volantes du monde
etaient concernees.
Aligne sur TrinityCore amont, identique en 3.3.5 et master :
bool success = _path->CalculatePath(x, y, z, owner->CanFly());
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
0b2a042175 |
Arenes cotees : bracket 14 code en dur, hors plage et introuvable
BattlegroundMgr::Update forcait la mise a jour des files cotees avec BattlegroundBracketId(14) -- la boucle sur les brackets avait ete commentee en amont. Deux consequences : - m_QueuedGroups ne compte que MAX_BATTLEGROUND_BRACKETS (12) entrees : chaque passage lisait au-dela du tableau, toutes les 5 secondes. - aucune entree PVPDifficulty ne correspond au couple (carte du template BATTLEGROUND_AA, bracket 14), donc la fonction sortait aussitot en journalisant une erreur : 585 000 lignes dans dc-world.log, soit la moitie du fichier, et le force-update des arenes cotees ne servait a rien depuis toujours. On parcourt desormais les brackets reellement declares pour la carte, et BattlegroundQueueUpdate refuse un bracket hors plage au lieu de lire a cote. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
04b6dd20f5 |
Playerbots : opcodes manquants sur les paquets de sortie de champ de bataille
ProcessLeaveBG et ProcessLeaveAA construisaient BattlefieldLeave a partir dun WorldPacket() par defaut (opcode 65535), et ProcessInAAQueue passait CMSG_BATTLEMASTER_JOIN_SKIRMISH a BattlemasterJoinArena. Le constructeur de ClientPacket asserte GetOpcode() == expectedOpcode : le thread monde mourait des quun bot devait quitter un champ de bataille (fin de match ou depart dun vrai joueur), laissant le processus fige et les joueurs bloques a lecran de chargement. Signale sur le Discord avec une pile gdb par un utilisateur du core. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
ac40810f25 |
Champs de bataille : le vrai appelant hors limites, et un opcode client diffuse
Suite du signalement Discord. Le garde-fou pose dans GetBGObject a tenu
-- plus de lecture hors limites -- mais les appels avec 24 et 32
persistaient : le correctif precedent visait BattlegroundAB.cpp alors que
l'appelant fautif est le module BotFill.
CommandAB.cpp indexait les bannieres en abNode * 8, disposition de
l'ancien Bassin d'Arathi de TrinityCore ou chaque noeud possedait huit
objets. Le notre n'en a qu'UN par noeud, aux indices 0 a 4. Le calcul
etait donc faux pour TOUS les noeuds :
noeud 0 -> 0 banniere juste, par hasard
noeud 1 -> 8 REGENBUFF_STABLES
noeud 2 -> 16 SPEEDBUFF_LUMBER_MILL
noeud 3 -> 24 hors limites
noeud 4 -> 32 hors limites
Les bots visaient des objets de bonus au lieu des bannieres et ne
voyaient tout simplement pas la scierie ni la mine d'or. Les deux sites
etant proteges contre le pointeur nul, cela echouait en silence : seul le
garde-fou a fini par le rendre visible. Le controle de borne manquant sur
abNode est ajoute.
Verifie au passage : Gilneas a REELLEMENT huit objets par noeud
(BG_BFG_OBJECT_MAX = 37), son node * 8 + 5 est correct. Rien a y changer.
Second defaut, sans lien avec le premier : deux fonctions de l'IA des
bots construisaient un paquet portant l'opcode CLIENT CMSG_MOVE_FALL_LAND
et le diffusaient. WorldSession le refuse toujours et journalise une
ERREUR a chaque tentative -- des milliers de lignes par match dans le
journal du rapporteur. BotBGAIMovement::SyncPosition n'avait meme aucun
autre effet : elle ne deplacait pas le bot cote serveur. Les envois sont
retires ; aucun comportement de remplacement n'a ete invente, le defaut
n'etant pas reproductible chez nous.
RESERVE IMPORTANTE : rien de ceci n'explique le PLANTAGE signale. Les
deux sites fautifs testaient deja le pointeur nul, et le journal fourni
ne contient aucune trace d'arret. Une pile d'appels est necessaire.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
a95670ac0a |
Rivage brise : portage de l'Assaut 7.2 (scenario 1280, carte 1666)
La carte 1666 etait declaree mais entierement vide, et instance_template y reclamait un script fantome. Les quetes 45102 « Begin the Assault » et 46734 « Assault on Broken Shore » etaient donc infranchissables : elles relevent de ce scenario, et non de l'introduction 7.0 deja portee sur la carte 1460. PORTAGE, PAS TRANSCRIPTION. La source (dufernst/LegionCore-7.3.5, meme lignee uwow) repose sur quatre extensions que nous n'avons pas : onScenarionNextStep/getScenarionStep, CRITERIA_TYPE_SCRIPT_EVENT_2, FunctionProcessor et une surcharge de GetClosestGraveYard. La progression est donc inversee : au lieu d'etre rappele a chaque etape, le script alimente les criteres officiels et le moteur avance seul -- la meme architecture que sur la carte 1460. Les neuf criteres des huit etapes ont ete releves dans les DB2 du build 7.3.5.26972 (ScenarioStep, CriteriaTree, Criteria) et non recopies de la source ; ils confirment ses identifiants d'asset. Sept sont de type 92 (SEND_EVENT_SCENARIO), un de type 73, un de type 68. Six ecarts d'API traites, tous constates et non supposes : InstanceScript(InstanceMap*), Conversation::CreateConversation (Player n'a pas cette methode -- la source l'appelait sur une creature, cela n'aurait pas compile), UNIT_NPC_FLAGS avec SetFlag64, DamageTaken a 2 arguments, OnSpellClick a 2, MovePath a 2. NON PORTE : player_scripts_for_start_assault, qui sondait chaque joueur a chaque tick pour lui imposer la quete 46730. Un donneur en base fait le meme travail sans ce cout. SQL joint : - rattachement des 5 scripts a leurs 11 entrees, toutes verifiees exclusives a la carte 1666 ; - les 87 points des 5 chemins scriptes. Ils vivaient dans waypoint_data_script, table absente de notre schema, d'ou leur oubli lors de l'extraction du 27/08. Le 11322708 est le vol d'arrivee : l'atteinte de son point 20 declenche l'etape 0, sans lui rien ne demarrait ; - le donneur manquant de 45102, l'archimage Khadgar 116302, deja pose chez nous aux coordonnees de la reference mais jamais declare. Les 593 creatures et 59 objets de la carte etaient generes depuis le 27/08 et n'avaient jamais ete appliques ; ils le sont desormais. RESERVE : rien de tout ceci n'a ete verifie en jeu. Les credits de quete 116253 et 116279 sont en outre cables sur la fermeture des deux premiers portails par deduction -- la quete parle de « First » et « Second Legion Spire destroyed » -- et non sur une donnee. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
ce69bad85b |
Bassin d'Arathi : lecture hors limites de BgObjects
Signale par un utilisateur de SylvaniaCore : ses matchs de Bassin
d'Arathi avec pbotbg=1 faisaient tomber le serveur, avec dans le journal
GetBGObject: gameobject (type: 24, ... Entry: 7735234) not found
GetBGObject: gameobject (type: 32, ... Entry: 0) not found
soit des GUID manifestement arbitraires, sur une carte 529 dont le
tableau BgObjects ne compte que 22 cases.
GetNearGameObjectFlag, introduit par le module BG BotFill (
|
||
|
|
a4d245ecbe |
Commandes : .npc add perdait la phase du maitre de jeu
Les PNJ crees en jeu n'etaient visibles qu'en mode MJ. InheritPhaseShift donnait bien la phase du joueur a la creature, mais SaveToDB n'ecrit que GetDBPhase() -- la phase DECLAREE EN BASE, nulle pour une creature creee a la volee. La commande detruit ensuite l'objet et le recree depuis la ligne enregistree, donc sans phase. Dans une aire phasee, PhaseShift:: CanSee exigeant une intersection, la creature etait invisible a tout joueur normal ; le mode MJ masquait le defaut, SetAlwaysVisible court-circuitant le test de phase. TrinityCore 3.3.5 transmettait la phase explicitement a Create et a SaveToDB, via un GetPhaseMaskForSpawn qui ignorait volontairement l'etat « MJ voit tout ». La reecriture du systeme de phases a perdu ce principe : master a le meme defaut. On le restaure, en annoncant la phase retenue puisqu'un joueur moderne peut en porter plusieurs alors qu'une ligne de la table creature n'a qu'un champ. SQL joint : phase 6666 posee sur l'aubergiste deja pose au port de Hurlevent, et suppression de 18 options de dialogue de type 1 qui doublonnaient une option fonctionnelle et se placaient au-dessus d'elle. Les options porteuses de conditions sont preservees -- une premiere version avait supprime a tort les options d'Halloween. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
e1ccf30afc |
Sessions : les comptes au-dessus du niveau 0 ne sont plus coupes pour inactivite
Demande : « j aimerai que les comptes au-dessus du numero 0, c est a dire
les comptes GM/testeur/admin, ne soient pas soumis en jeu a la
deconnexion automatique en cas d absence prolongee ».
La coupure vient de WorldSession::Update :
if (!IsBotSession() && IsConnectionIdle())
m_Socket[CONNECTION_TYPE_REALM]->CloseSocket();
IsConnectionIdle() s appuie sur m_timeOutTime, initialise depuis
SocketTimeOutTime (900 000 ms, soit 15 minutes) et decremente a chaque
tick sans paquet entrant.
On ajoute GetSecurity() <= SEC_PLAYER a la condition. Les comptes de
niveau superieur restent connectes indefiniment ; les joueurs ordinaires
demeurent soumis au delai, la protection contre les sessions fantomes
gardant tout son interet pour eux.
Motif concret : ces comptes restent volontairement inactifs de longues
minutes pour observer une zone, suivre un evenement scripte ou attendre
le resultat d un test -- et se faisaient couper en plein travail, parfois
au milieu d une instance.
Portee actuelle : 5 comptes concernes (3 de niveau 1, 2 de niveau 4).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
80a4a589f6 | worldserver.conf.dist : pbotqa et les deux cles du Bond heroique manquaient | ||
|
|
0bc9b016d6 |
Commandes : .npc near faisait tomber le serveur
Signale en jeu : « la commande .npc near fait planter le serveur ». L hypothese de l utilisateur etait proche : ce n est pas le rayon en soi, c est l absence de plafond. La requete preparee WORLD_SEL_CREATURE_NEAREST n a AUCUNE limite : SELECT ... FROM creature WHERE map = ? AND (POW(x-?,2)+POW(y-?,2)+POW(z-?,2)) <= ? ORDER BY order_ Elle calcule trois puissances sur les 384 000 lignes de la table, sans index utilisable, puis la boucle d affichage envoie UN message de discussion PAR RESULTAT. Avec un rayon large cela represente des dizaines de milliers de paquets pour une seule commande, ce qui sature la session. La requete etant partagee avec d autres commandes, on pose les garde-fous cote appelant : rayon plafonne a 500, affichage plafonne a 150 lignes. Les omissions sont ANNONCEES et non silencieuses : la commande indique combien de resultats n ont pas ete montres et invite a reduire le rayon. Un plafond muet ferait croire a une recherche complete. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
3a4c6c01dd |
Hyjal : parler a Jaina faisait tomber le serveur -- et faction 16 au Rivage brise
1) PLANTAGE DU SERVEUR, cause reelle de la coupure de cette nuit Trace du vidage 3007513 : #0 Trinity::Assert(...) #1 npc_jaina_proudmoore::OnGossipHello(Player*, Creature*) #2 WorldSession::HandleGossipHelloOpcode hyjal.cpp utilisait ENSURE_AI(hyjalAI, creature->AI()), qui ASSERTE. Or GetAI() ne fabrique une hyjalAI que si GetHyjalAI() la trouve, donc uniquement dans l instance du Mont Hyjal. Ailleurs la creature recoit une IA quelconque et l assertion tue le process. Declencheur : un exemplaire de Jaina (17772) se trouve sur la carte 0, a Hurlevent (-8295, 1386), en plus de celui du Mont Hyjal. Lui parler suffisait a planter le serveur -- faille exploitable par n importe quel joueur, sans commande ni privilege. Les 5 occurrences passent en dynamic_cast avec sortie propre. J avais d abord conclu a une recursion en me fiant a la taille du vidage (387 Mo contre 133). C ETAIT FAUX : cette taille reflete la memoire allouee au moment du plantage, pas un debordement de pile. La trace, elle, etait parfaitement lisible. 2) RIVAGE BRISE : factions demoniaques ramenees a 16 Etabli par TEST A/B, pas par raisonnement. Une seule entree basculee en faction 16 (Molosse de l effroi gangrene, 90686), toutes choses egales par ailleurs. Verdict en jeu : « les molosses sont maintenant attaquables », les autres non. La sonde SPAWNDBG confirme que seule la faction distingue les deux : Felstalker Dreadhound faction=16 drapeaux=32768 drapeaux2=0 OK Felguard Legionnaire faction=2780 drapeaux=32768 drapeaux2=0 bloque Pourquoi 2780 echoue reste INEXPLIQUE : FactionTemplate.db2 lui donne EnemyGroup=15 (ennemi de tous) et sa faction 1786 a ReputationIndex=-1, donc aucune reputation n intervient. Sur le papier elle devrait etre hostile. Le refus vient du client, qu aucune sonde serveur ne peut observer. On retient donc la faction 16, demontree fonctionnelle dans ce scenario meme -- ecart assume avec la donnee de reference. 101 entrees, 464 spawns. Effet secondaire bienvenu : les demons cessent de s entretuer (Friend_0=14). 3) COMPTEUR : tout demon compte desormais Signale : « les molosses sont attaquables mais ne comptent pas dans l objectif ». OnUnitDeath ne reconnaissait que les cinq entrees invoquees par le script. On s appuie desormais sur le type demon plutot que sur une liste de 101 entrees qui vieillirait mal. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
fa7a543b94 | worldserver.conf.dist : les 10 cles du module Mercenaires manquaient | ||
|
|
5408eae697 |
Rivage brise 1460 : UNIT_FLAG2_UNK5 rendait les demons inattaquables
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 <noreply@anthropic.com> |
||
|
|
0ac509e421 |
Rivage brise 1460 : le phasage rendait les creatures inattaquables
Signale en jeu : creatures visibles, hostiles, mais impossibles a cibler
-- alors qu elles pouvaient attaquer le joueur.
J avais enchaine trois hypotheses (phase, factions, modeles souches).
Les trois etaient de VRAIS defauts et meritaient correction, mais aucune
n etait la cause. J aurais du poser la sonde d abord.
VERDICT DE LA SONDE, dans _IsValidAttackTarget :
Felblade Destroyer | vivante=1 | aucun drapeau bloquant
reaction=1 (hostile) | mesPhases=0 sesPhases=1
Le joueur n a AUCUNE phase, la creature en a une. PhaseShift::CanSee
exige une intersection des phases, et UpdateUnphasedFlag retire le
statut « non phase » des qu un objet en possede une. Aucune intersection
possible.
C est MA modification precedente qui a introduit ce decalage : j avais
place les 757 spawns en phase 169 en croyant que le joueur y etait,
en me fiant a un commentaire du script. Il ne l etait pas.
CORRECTIF : suppression du phasage des deux cotes, ce qui rejoint la
configuration de la reference -- le dump laisse les 757 placements de
cette carte SANS phase. La phase 169 n existe d ailleurs pas dans
Phase.db2 du build 7.3.5.26972.
- PhaseId remis a 0 sur les 757 creatures et les 101 objets ;
- AddPhase retire de OnPlayerEnter ;
- FinalizeSummon ne phase plus rien (conservee comme point de passage
unique, sans quoi les invocations deviendraient invisibles a un
joueur non phase -- le meme probleme en sens inverse).
La sonde ATTDBG est CONSERVEE le temps de la validation en jeu.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
966a866e7c |
Mardum : le point de foyer etait fixe a l origine au lieu de la destination
Signale en jeu : « j ai utilise ma pierre de foyer qui ne m a pas
teleporte, je devais atterrir en foret d Elwynn et il est ecrit vous
renvoie a Fleur-de-l hiver alors que je n ai pas change le lieu ».
La pierre fonctionnait parfaitement : elle renvoyait a Mardum, ou le
joueur se trouvait deja -- d ou l impression qu elle ne faisait rien.
CAUSE, dans spell_mardum_back_to_black_temple :
player->TeleportTo(1468, 4325.46f, -620.53f, -281.40f, 1.517563f);
player->SetHomebind(player->GetWorldLocation(), 7873);
TeleportTo est ASYNCHRONE : le joueur n est pas deplace a la ligne
suivante, si bien que GetWorldLocation() renvoyait encore la position de
MARDUM. Le point de foyer se retrouvait donc fixe la ou le joueur venait
de partir, au lieu du Caveau des Gardiennes (carte 1468) visé.
Constate en base : character_homebind du personnage pointait sur
mapId 1481 (Mardum), zone 6383.
On lie desormais explicitement a la DESTINATION, via une WorldLocation
construite une fois et passee aux deux appels.
Le point de foyer du personnage affecte a ete remis en foret d Elwynn,
avec des coordonnees reprises d un homebind Alliance deja valide dans
notre base plutot qu inventees.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
42427a8a72 |
Rivage brise 1460 : rebrancher les vrais compteurs de l etape 1
Signale en jeu : « la phase 1 ou il fallait tuer 33 demons ainsi que
d autres objectifs a ete skip et je suis passe en phase 3 direct », puis
« les objectifs ne se remplissent jamais ».
DEUX COMPTEURS VIVAIENT EN PARALLELE, et ne disaient pas la meme chose.
Le client affichait les criteres officiels de l arbre 42935 (« Broken
Shore - Stage 1 », operateur ALL) du build 7.3.5.26972 :
43010 Demons slain 33 critere 27653
46549 Fel Lords slain 3 critere 29377
46548 Spires of Woe destroyed 3 critere 27619
Tous trois de type CRITERIA_TYPE_SEND_EVENT_SCENARIO (92) : ils ne se
remplissent PAS en tuant, mais quand le script emet l evenement
correspondant. Le script ne l emettait jamais -- d ou le 0/33 fige.
En parallele, il tenait sa propre comptabilite et cloturait l etape a
KILLS_BEACH = 12, un chiffre invente. D ou l impression de saut : a 12
demons il invoquait Arganoth avec SetInCombatWithZone(), lequel mourait
aussitot et faisait franchir une seconde etape.
CORRECTIF -- on ne touche PAS aux objectifs, qui sont officiels et de
toute facon dans les donnees du client. On supprime le seuil invente et
on emet les vrais evenements :
- chaque demon tue emet 44095 ;
- chaque Seigneur gangrebois emet 52643 (les treize entrees placees
sur la carte sont enumerees explicitement, le nom n etant pas une
donnee stable) ;
- chaque Fleche actionnee emet 44077 ;
- l etape ne s acheve que si les TROIS seuils officiels sont atteints
(33 / 3 / 3), conformement a l operateur ALL de l arbre.
LES FLECHES sont des objets de type 10 : ACTIONNES, pas detruits. Ni
OnGameObjectCreate ni OnGameObjectRemove ne rapportent cette
utilisation. Le seul accrochage est GameObjectScript::OnGossipHello, que
GameObject::Use appelle avant tout traitement specifique
(GameObject.cpp:1379). D ou la classe go_spire_of_woe -- ET son
rattachement en base, sans lequel elle n aurait jamais ete invoquee.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
1507d1084d |
Brasserie : les vermifuges s accumulaient sans aucune limite
Signale en jeu : « il y a beaucoup trop de Cognedur et de Sautilleur, c est totalement anormal », et plus tot « les lapins bouclent ». Le script d instance appelle DoAction toutes les 12 a 14 secondes, EN BOUCLE, tant que l etat de Hoptallus n est pas SPECIAL -- c est-a-dire tant qu il n a pas jailli de son tonneau. La boucle demarre dix secondes apres la creation de l instance. Chaque passage invoquait 3 a 4 Sautillons et 1 a 2 Sautilleurs, sans AUCUNE limite et sans qu aucun joueur ait besoin d etre present. Consequence : pendant qu on affronte Ook-Ook, a 105 m de la (distance mesuree entre les deux spawns), la salle des tonneaux se remplit toute seule. Sur vingt minutes de donjon, de l ordre de quatre cents creatures vivantes accumulees. En jeu officiel ces vermifuges sortent quand le joueur CASSE les tonneaux. Faute de cette mecanique, on garde le minuteur mais on lui pose deux garde-fous : aucune invocation si aucun joueur n est a 60 m (portee choisie pour couvrir la salle sans jamais atteindre l arene d Ook-Ook, mesuree a 105 m), et vague sautee au-dela de 20 vermifuges vivants. summons suit deja les invocations vivantes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
7f8cdd2d4b |
Scenarios : la verification de l etape doit etre purement lectrice
Correctif du commit precedent, qui FAISAIT PLANTER LE SERVEUR.
Il appelait CheckCompletedCriteriaTree sur l arbre racine. Enchainement
du debordement de pile (SIGSEGV, vidage de 389 Mo contre 120 Mo en temps
normal) :
feuille achevee -> Scenario::CompletedCriteriaTree(feuille)
-> CheckCompletedCriteriaTree(racine)
-> operateur ALL : parcourt les enfants
-> CheckCompletedCriteriaTree(enfant)
-> enfant complet ET absent de _completedCriteriaTree
-> CompletedCriteriaTree(enfant) ... et on reboucle.
Le garde anti-reentrance existe pourtant (CriteriaHandler.cpp:1109),
mais l insertion dans _completedCriteriaTree se fait dans
CriteriaHandler::CompletedCriteriaTree -- que cette surcharge ne
rappelle jamais. L arbre n est donc jamais enregistre et le garde ne se
declenche pas.
On se contente desormais de LIRE la progression via IsCompletedCriteria,
en parcourant l arbre avec WalkCriteriaTree, sans jamais repasser par le
moteur d evaluation. Plus aucun effet de bord, donc plus de reentrance.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
85b0251bc1 |
Scenarios : le premier critere achevé cloturait toute l etape
Signale en jeu, capture a l appui : a la Brasserie brune d Orage, la liste des trois boss disparaissait entierement des qu Ook-Ook tombait, au lieu de cocher 1/1 et de conserver les deux autres. Le scenario 537 n a qu UNE etape (972), dont l arbre de criteres 36317 porte trois feuilles : 36318 Ook-Ook, 36319 Hoptallus, 36320 Yan-Zhu. CriteriaMgr::LoadCriteriaList attribue l etape via GetEntry, qui REMONTE la chaine des parents jusqu a trouver une correspondance -- chaque feuille herite donc de l etape 972. Et le moteur n evalue que les feuilles : GetCriteriaTreesByCriteria ne renvoie que les arbres portant directement le critere, jamais la racine. Resultat : la premiere feuille achevee marquait l ETAPE ENTIERE terminee. CompleteStep ne trouvait alors aucune etape suivante, IsComplete() repondait oui, et le scenario etait cloture des le premier boss. On verifie desormais l arbre RACINE de l etape avant de conclure. Un garde naif sur « tree doit etre la racine » ne conviendrait pas : la racine n etant jamais transmise ici, l etape ne s acheverait alors JAMAIS. CheckCompletedCriteriaTree pouvant rappeler cette fonction avec la racine, on relit l etat de l etape ensuite -- sans quoi CompleteStep serait execute deux fois et la quete de recompense octroyee en double. Correctif dans le moteur partage : il vaut pour tous les scenarios dont une etape porte plusieurs criteres. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
8238ca0925 |
Brasserie : l instance n enregistrait jamais rien
Signale en jeu : « le donjon semble avoir declenche le done total au
1er boss, je n ai plus la liste des autres boss a tuer ».
La chaine de sauvegarde etait construite par une methode Save() qui
n etait APPELEE NULLE PART. Le tampon SaveDataBuffer restait donc vide,
et InstanceScript::SaveToDB abandonne des que la chaine est vide :
std::string data = GetSaveData();
if (data.empty())
return;
Ni l etat des boss ni le masque des rencontres accomplies n atteignaient
la base. Constate directement : completedEncounters = 0 et data = '' sur
l instance 3 apres un boss tue.
Second defaut cumule : Save() n ecrivait pas l en-tete « S S B » que
Load() exige pour accepter la chaine. Meme appelee, la relecture aurait
echoue -- la progression aurait ete perdue a chaque rechargement.
GetSaveData() construit desormais la chaine lui-meme, en-tete compris
(motif habituel de TrinityCore), ce qui supprime le tampon et Save().
SetBossState declenche aussi une sauvegarde : auparavant seule la mort
d un hozen en provoquait une, via SetData.
Verifie au passage, et ecarte : les 7 lignes instance_encounters ajoutees
sont bien chargees (389 -> 396 au demarrage), le drapeau DUNGEON_BOSS est
pose dynamiquement au chargement et IsDungeonBoss le relit correctement,
et DifficultyID 0 est bien etendu a toutes les difficultes de la carte.
A noter : Yan-Zhu the Uncasked (59479) n a aucun spawn sur la carte 961.
Uncle Gao (59074) est present, donc l invocation par evenement reste
plausible -- a verifier quand le donjon sera jouable jusque-la.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
b0174ab55f |
Brasserie : ligne de vue refusee a bout portant dans l arene d Ook-Ook
Signale en jeu : « Paume du tigre » et les autres attaques de melee refusees sur Ook-Ook avec « cible hors du champ de vision ». Meme defaut qu au Temple du Serpent de jade juste au-dessus. MESURE PAR SONDE. Sur 17 echecs releves, 13 sont LEGITIMES : Ook-Ook depuis son perchoir (Z ~161,8, sol a 162,63) vers un joueur dans l arene (Z ~147), a 23-26 m -- il y a un plancher entre les deux. Les 2 autres ne le sont pas : Ook-Ook (-756,26 1353,21 146,97) -> joueur a 4,38 m joueur (-757,19 1356,00 147,06) -> Ook-Ook a 2,93 m Les deux extremites reposent sur le sol de l arene, a la meme altitude que le plancher sous leurs pieds, et l echec se produit DANS LES DEUX SENS. A trois metres sur un sol plat, une ligne de vue ne peut pas echouer legitimement. BORNES MESUREES. Tranche d altitude etroite (145-149) : le rez-de- chaussee est un plan unique (Z 146,6 a 147,5 sur 189 spawns), ce qui exclut le perchoir et preserve les 13 echecs legitimes. Rayon de 15 m autour du centre d arene : la repartition des spawns donne 6 creatures a moins de 10 m, AUCUNE entre 10 et 20 m, puis 46 au-dela -- ce vide est le mur de l arene. On s arrete avant les salles voisines pour ne pas laisser les monstres se voir a travers les cloisons. RESERVE ASSUMEE : deux echecs mesures seulement, la ou le correctif du Temple s appuyait sur trente-neuf. Bornes volontairement serrees. Egalement dans ce lot : - PV du hozen ivre bornes a 1 minimum. La sonde a montre que le calcul etait sain (pvMax=285568 -> 28556) : mon hypothese du zero etait FAUSSE. Le garde reste, mais le cadavre qui frappe n est pas explique. - Sonde CADAVREDBG conservee : elle journalise toute creature infligeant des degats alors qu elle est morte ou a zero PV. Elle attrapera le cas tout seule s il se represente. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
e657f4fb96 |
Brasserie : Ook-Ook ne descendait jamais, tonneaux encastres, barre decalee
Trois defauts distincts, tous confirmes par la sonde OOKDBG et par les
donnees de spawn.
1. OOK-OOK NE VENAIT PAS DANS L ARENE
La sonde montre que le chemin scripte fonctionne : « SEUIL ATTEINT »,
« Ook-Ook trouve, appel DoAction(0) », puis StartIntro. Le defaut etait
en aval, et double.
a) L appel passait CINQ arguments -- MoveJump(x, y, z, 25.0f, 25.0f) --
a une surcharge (x, y, z, o, speedXY, speedZ). Le premier 25.0f
atterrissait sur l ORIENTATION. On passe par la surcharge prenant
une Position.
b) Il passait en reaction AGRESSIVE juste avant de sauter. Les joueurs
sont 16 m plus bas, donc a portee : il acquerait une cible et le
mouvement de poursuite ecrasait le saut. N ayant aucun chemin pour
descendre, il restait plante sur son perchoir -- ce qui explique
aussi qu il ait ete attaquable trop tot. Il reste passif pendant le
saut et devient agressif a l atterrissage (MovementInform, en
EFFECT_MOTION_TYPE, que le filtre existant ecartait).
Le domicile est fixe avant le saut, sinon l evade le ramene en haut.
2. TONNEAUX ENCASTRES DANS LE DECOR (capture a l appui)
DoCastBarrel figeait l altitude a 146.79, soit le sol de l arene
(ookJumpPos = 146.92). Or les Hurleurs se tiennent entre 155,6 et 161,5 :
le tonneau etait depose 9 a 15 m SOUS son lanceur, a la verticale du
balcon mais a l altitude du plancher. On interroge desormais le sol reel
sous le point vise, et le tonneau suit le sol pendant qu il roule.
3. BARRE DE BANANES BLOQUEE A 39
Le test portait sur la valeur APRES incrementation (« + 1 < 40 ») : la
barre n atteignait jamais 40/40. Signale comme « Ook-Ook apparait avant
40/40 » -- il apparaissait au bon moment, c est l affichage qui etait en
retard d une unite. Le compteur d instance, lui, etait monte a 94.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
8e9b65291f |
Brasserie : roulement des tonneaux, et sonde sur le reveil d Ook-Ook
Signale en jeu : « les tonneaux sont completement bugges, ils se deplacent bizarrement ». Deux defauts certains dans npc_barrel : 1. Le trajet etait reinitialise en plein vol. Move() relancait un MovePoint vers un point a 5 m devant TOUTES LES 300 ms, alors que le tonneau avance a 0,85 de vitesse (environ 5,95 m/s) : parcourir ces 5 m lui demande 840 ms. Le trajet etait donc ecrase au tiers, quatre fois par segment. Cote client chaque reinitialisation est une rupture de trajectoire, d ou le roulement saccade. Le deplacement est desormais relance A L ARRIVEE via MovementInform, par segments de 20 m. 2. L orientation de depart n etait jamais fixee. Le tonneau est invoque par un sort a 5-10 m devant le Hurleur, mais rien ne lui donnait de cap propre. Il part maintenant dans la direction du lancer. Arbitrage assume : la generation de chemin de MovePoint est CONSERVEE. Un tonneau devrait rouler droit et la couper serait plus juste sur le papier, mais c est elle qui le maintient sur le sol praticable -- sans elle il traverserait les murs. Sur sol degage le chemin est de toute facon quasi rectiligne. Sonde OOKDBG ajoutee (4 points) : Ook-Ook se reveille avant le seuil de 40 hozens alors qu InitializeAI le pose en NON_ATTACKABLE et en reaction passive, et que le chemin scripte (SEUIL ATTEINT) n apparait jamais dans les traces. Pistes deja ecartees : les evenements 2 et 3 de l instance ne le concernent pas, et EVENT_INTROCHECK est programme mais traite nulle part -- evenement mort. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
8200eb3961 |
Serpent de jade : degats de l eau proportionnels a l effectif, sondes retirees
Le sort 106778 inflige 950 points fixes (EffectBasePoints, DB2 du build 7.3.5.26972 -- valeur confirmee par la sonde : exactement 950 par tic, sans mitigation). A quatre tics par seconde cela fait 3800 par seconde, un chiffre calibre pour cinq joueurs. Or ce sont des degats BRUTS : ni l armure ni les statistiques ne les reduisent, donc Solocraft n y peut rien (verifie, il s applique bien : +400 % de statistiques, 61 000 PV au lieu de 12 299). Un joueur seul encaissait la charge prevue pour cinq. La valeur est desormais multipliee par l effectif present et divisee par les cinq joueurs pour lesquels le contenu est calibre -- le meme rapport que celui de Solocraft. Un joueur seul prend un cinquieme. Les maitres de jeu ne comptent pas. La valeur de base est relue dans le sort plutot que recopiee. La cartographie du sol par la sonde (411 releves) a confirme que le combat est jouable tel quel : bassin central jusqu a 5 m, ANNEAU SEC de 5 a 8 m -- le « inner most circle of dry zone » de la consigne officielle --, rigole de 8 a 10 m, dallage sec au-dela. Le corps a corps se fait depuis l anneau interieur. Sondes TJSWATER et TJSDBG retirees. Celles de la Brasserie (SSBDBG) restent en place, le blocage d Ook-Ook n est toujours pas elucide. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
b03d31d161 |
Sagesse de Mari : l'eau brûlait partout et rendait le combat infaisable
Signalé en jeu par deux joueurs. Une sonde posée dans la boucle de dégâts
a montré que le joueur n'occupe que deux altitudes dans la salle :
174,698 sur la coursive sèche (103 relevés sur 124) et 174,157 dans la
cuvette centrale (12 relevés), à 3,1-4,5 m du centre — c'est-à-dire au
corps à corps.
Toute la cuvette infligeait 950 points toutes les 250 ms, soit 3 800 par
seconde, dès l'entrée en combat et sans aucune condition. Or la Sagesse
de Mari se tient dedans (174,24) : l'approcher revenait à se suicider.
Solocraft n'y peut rien, ces dégâts ignorent les statistiques — vérifié,
il s'applique correctement (+400 % de statistiques, 61 000 PV).
La sonde a aussi écarté deux fausses pistes : les dégâts ne venaient pas
de « Lessiver » (68 des 70 relevés portaient le sort 106778, lancé par le
joueur sur lui-même à zéro mètre), et les bandes d'altitude ne sont pas
mal calibrées — elles distinguent correctement la cuvette de la coursive.
CE QUE FAIT LE JEU OFFICIEL
L'infobulle du vrai sort (115167) dit : « les eaux corrompues DE LA
FONTAINE infligent des dégâts de Givre ». L'eau n'est pas dangereuse en
soi : elle le devient fontaine par fontaine, pendant que le boss les
souille l'une après l'autre — une toutes les 29 s dans son propre script.
D'où la consigne connue du combat : tourner le long des zones sèches
jusqu'à ce que les quatre Ondes vivantes soient mortes, puis se placer
sur l'anneau sec pour la phase du jet.
CORRECTIF
Un joueur dans l'eau ne prend des dégâts que s'il est à portée d'une
fontaine DÉJÀ corrompue (aura 106518, posée par le script du boss) :
- aucune fontaine souillée -> l'eau est inoffensive ;
- chaque fontaine corrompue noie la moitié de cuvette la plus proche
d'elle, les zones sèches se réduisent ;
- les quatre corrompues -> toute la cuvette est mortelle, et c'est le
moment où la phase 2 commence.
La portée de 30 m est le rayon du sort officiel 115167 (SpellRadius
ligne 10, build 7.3.5.26972), pas un chiffre choisi au jugé. Les
fontaines étant à 24,7-29,2 m du centre et la cuvette faisant une
dizaine de mètres de rayon, il découpe naturellement la cuvette en deux
par fontaine.
Reset() du boss purge les auras des fontaines : une mort de groupe
remet bien le compteur à zéro.
RESTE À FAIRE
- La sonde TJSWATER est conservée le temps de la validation en jeu ;
elle sera retirée ensuite.
- Nous lançons toujours 106778 « Corrupted Waters NOT READY », le
brouillon inachevé de Blizzard, au lieu de 115167. Dégâts comparables
(5 000 contre 4 749 en normal) mais sans les paliers héroïque et
mythique. Non basculé ici : 115167 utilise un ciblage par destination
qui demande d'être traité à part.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
39171026a7 |
Sagesse de Mari : « Lessiver » frappait aussi dans le dos du boss
Signalé en jeu : le jet d'eau de la phase 2 infligeait des dégâts aux
joueurs placés derrière le boss, « comme s'il y avait des dégâts de zone
autour ».
Le sort est en réalité une chaîne de trois. 106329 canalise — et son
effet 1 est un « script côté serveur », c'est-à-dire une logique Blizzard
jamais distribuée avec les données du client. 106331 est l'aura posée sur
le boss, qui déclenche 106334 toutes les 250 ms. C'est 106334 qui blesse :
école Givre, recul 200, rayon 60 m, drapeau « ignore la ligne de vue ».
Toute la forme du jet tenait donc à une seule valeur, et à une entrée DB2
facultative :
ConeAngle = _target ? _target->ConeDegrees : 0.f;
Le mode de contrôle associé au ciblage 110, TARGET_CHECK_ENTRY, ne filtre
par ailleurs — sans `conditions` — ni l'hostilité ni la position.
Valeurs officielles relevées dans les DB2 du build 7.3.5.26972 :
SpellTargetRestrictions ligne 7514 : ConeDegrees = 12
SpellRadius ligne 48 : Radius = 60
soit un cône frontal de 12° sur 60 mètres.
Le script `spell_wise_mari_wash_away` réimpose ces 12° en dur plutôt que
de dépendre d'une donnée invérifiable côté serveur (la table spell_effect
de dc_hotfixes est vide, ces données vivent dans les fichiers DB2), et
rétablit le contrôle d'hostilité laissé de côté par TARGET_CHECK_ENTRY.
Le boss pivote de PI/48 toutes les 300 ms, soit 3,75° : avec un jet de
12°, un joueur immobile est balayé environ une seconde par tour de salle.
C'est le comportement d'origine.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
673bad73b3 |
Sagesse de Mari : « Lessiver » ne balayait pas, le parametre force manquait
Signale en jeu apres le correctif de ligne de vue : le sort restait fige
au lieu de balayer la salle.
Unit::SetFacingTo abandonne en silence quand la creature nest pas a
larret :
if (!force && !IsStopped()) return;
Or la phase 2 lance MovePoint vers la position de depart juste avant :
elle EST en deplacement, la rotation ne partait donc jamais. Et le
SetOrientation qui precede ne met a jour que la valeur serveur, sans
prevenir les clients.
Seuls les deux appels de la phase 2 recoivent force = true. Le troisieme,
celui de lHydrolance en phase 1, est laisse tel quel : elle est a larret
a ce moment-la et il fonctionne.
Sondes retirees : la sonde a montre que la mecanique du combat est saine
— quatre fontaines trouvees, un elementaire invoque a chaque appel
(compteur 0 puis 1, 2, 3) et bouclier retire a foutainCount=4. Le seul
defaut etait la ligne de vue, corrigee au commit precedent. Le blocage
signale par le joueur — « les elementaires sont coinces, on ne peut pas
les buter, du coup le boss garde son bouclier » — sexplique entierement
par la : il ne pouvait frapper personne.
|
||
|
|
c880268e8c |
Temple du Serpent de jade : aucun sort a distance ne passait dans la salle du bassin
Signale par « le baltring » puis reproduit : aucun sort a distance naboutit sur aucun PNJ de la Fontaine des Temoins, et la Sagesse de Mari etait annoncee « hors de portee de vue » alors quelle est visible a 7 metres. Fausses pistes ecartees avant de trouver, toutes verifiees : les drapeaux (32832 est exactement celui du Sha du doute, jouable), un objet du monde qui bloquerait (aucun a moins de 15 m), des tuiles de collision manquantes (0960_36_30.vmtile fait 82 Ko, la plus grosse de la carte), une position aberrante, et le phasage. Mesure faite par une sonde posee dans IsWithinLOS. Sur 39 echecs : tous tiennent dans une boite de 26 x 18 m — la salle et rien quelle, le reste du donjon est indemne ; la tranche daltitude est etroite, 172,6 a 174,3 ; les distances vont de 4 a 18 m, donc meme a bout portant ca bloque ; et la Sagesse de Mari elle-meme echoue a viser les joueurs. Il y a donc de la matiere de collision A LINTERIEUR de la piece, dans la tranche ou tout le monde se tient : lextraction du modele est fautive, pas un fichier manquant. Deplacer les creatures ne servirait a rien, le joueur aussi est dans la zone fautive. La ligne de vue est donc neutralisee, mais UNIQUEMENT quand les DEUX extremites du rayon sont dans le bassin. Hors de cette boite, et sur toute autre carte, le calcul reste strictement inchange. A retirer si les cartes de collision de la carte 960 sont un jour re-extraites correctement. |
||
|
|
bfb9fe864b |
Plantage : m_playerStorage netait alloue nulle part
Le serveur est tombe le 24/08/2026 dans le Temple du Serpent de jade, SIGSEGV. Pile du vidage memoire, sans ambiguite : PlayerStorage::IsEntryExists <- spell_monk_mastery_combo_strikes::HandleHit <- Spell::HandleEffects <- HandleCastSpellOpcode Larret est a IsEntryExists+4, cest-a-dire au tout premier acces a this. m_playerStorage est DECLARE dans Player.h et lu par GetStorage(), mais alloue NULLE PART dans tout le depot : ni liste dinitialisation, ni corps du constructeur, aucune affectation. Le pointeur contenait donc des ordures des la construction du joueur. Quatre scripts du Moine le deferencent sans controle dans spell_monk.cpp — maitrise « Frappes combinees », Poings de furie. Le premier moine a en declencher un faisait tomber le worldserver. Ce netait quune question de temps : la classe est utilisee depuis toujours sans jamais avoir existe. La classe PlayerStorage est parfaitement fonctionnelle, il ne manquait que son allocation. Elle est desormais creee dans le constructeur et liberee dans le destructeur : le plantage disparait ET la maitrise du Moine devient operante. Ceinture et bretelles : les quatre appels recoivent en plus une garde de nullite, pour quun oubli similaire ne soit plus jamais fatal. |
||
|
|
82eb6e808e |
Nouveau type de condition : specialisation du joueur (53)
« Arretez Guldan ! » etait proposee en double par Maiev. Les quetes 38723 et 40253 partagent titre, prerequis, tri, et sont ouvertes a toutes les races : rien ne les departageait. Ce ne sont pas des variantes Horde/Alliance malgre le nom des constantes QUEST_STOP_GULDAN_H/_A — le meme fichier les nomme correctement plus bas DMG_SPEC et TANK_SPEC. Ce sont des jumelles de specialisation. Le gestionnaire de conditions navait aucun moyen de tester la specialisation. Le contournement par un sort caracteristique netait pas tenable : les sorts de specialisation ne sont quasiment pas enseignes sur ce serveur, les trois Chasseurs de demons existants ne connaissent que Morsure de demon et celui de niveau 98 na pas sa Metamorphose. Une condition batie dessus aurait masque les DEUX quetes. CONDITION_SPECIALIZATION lit Player::GetPrimarySpecialization() et valide la valeur contre ChrSpecialization.db2 au chargement. Formulation retenue en base : la quete Vengeance exige la spe Vengeance, la quete Devastation exige de NE PAS etre Vengeance. Il y a ainsi toujours exactement une quete proposee, meme si la specialisation vaut zero — un doublon agace, zero quete bloque. Reutilisable : le serveur compte 1488 paires de quetes homonymes partageant prerequis et races. |
||
|
|
cf21fde938 |
Glaives 38669 : les credits se declenchaient sur un evenement qui narrive jamais
Signale en jeu : le joueur arrive au Caveau des Gardiennes avec ses glaives DEJA EQUIPES. La quete « Notre dernier espoir » lui demande de les equiper, mais levenement dequipement a eu lieu avant quil ne prenne la quete. Ne guetter que OnItemLevelChange laissait donc la quete bloquee dans le cas le plus courant. Le script verifie desormais a trois moments : equipement dun glaive, acceptation de la quete, et connexion. Le dernier rattrape les personnages deja bloques — une simple reconnexion suffit. |
||
|
|
1474d24cc1 |
Zone DH : six quetes debloquees et butin realigne sur Wowhead
Audit complet des 42 quetes de Mardum (1481) et du Caveau des Gardiennes
(1468) apres une traversee de la campagne ou les blocages avaient ete
franchis a la commande GM. Six quetes restaient impossibles a terminer
normalement.
Quetes sans aucun donneur
38668 / 38669 « Notre dernier espoir » et 38689 « Infusion gangrenee »
n'avaient aucune ligne creature_queststarter. Attribuees a leur
recepteur deja en place (Maiev 92718, Altruis 92986), tous deux deja
porteurs du drapeau de donneur. L'ordre officiel de la chaine est
retabli via PrevQuestID (38668 -> 38669 -> 38672 -> 38689 -> 38690 ->
38723/40253), ce qui corrige au passage le piege signale en jeu :
accepter « La gangr'evasion » faisait partir Maiev avant que les
autres quetes aient pu etre prises.
Objectifs obligatoires sans aucune source
38690 : les huit « Warden Cell » (244588) etaient posees mais inertes
— aucun AIName, aucun script, tous les Data a zero. SmartAI
ajoute sur le motif de la « Scourge Cage » 187854.
38672 : les cellules 103655/103658 avaient tout leur SmartAI sauf
l'action 33. Le script C++ prevu n'aurait rien regle : non
rattache, lignes de credit commentees, et entrees erronees.
38723/40253 : le credit « Face Gul'dan » 99303 dependait d'une scene
absente de scene_template. Ajoute a la liste d'actions de
Maiev, qui reproduit deja la scene.
38689 : les quatre demons du caveau accordent desormais l'energie
gangrenee, dix par mort, comme le prevoyait npc_fel_infusion.
38765 : go_mardum_portal_shivarra appelait ForceCompleteQuest sous la
condition inverse de ses deux jumeaux. Remplace par les credits
94407 et 97831, sur le schema des portails Cendrelangue et
Glissentaille.
38669 : nouveau PlayerScript accordant les credits des glaives via
OnItemLevelChange. Aucun identifiant d'objet code en dur : on
verifie la sous-classe WARGLAIVES dans chaque emplacement.
Butin
Compare aux tables officielles de Wowhead pour les 17 creatures
tuables de la zone. Le menu fretin de Mardum ne lache officiellement
rien : lootid = 0 etait correct, rien n'a ete touche. Manquaient en
revanche 132753 « Rations de la Legion » (absente des 46 000 lignes de
butin du serveur), 129196 sur quatre creatures, 147430, 132138, et
sept des huit lignes de l'Inquisiteur Funeste. Les objets
post-Legion que Wowhead attribue a ces creatures sont ecartes, et les
taux existants ne sont pas modifies.
|
||
|
|
adaaa7d232 |
Bastillax : sorts lances en mode declenche, boss intuable en solo
Signale en jeu : boss juge trop puissant. Ses statistiques sont pourtant authentiques - modificateur de vie 14, rang elite, VerifiedBuild 25549 - et identiques a celles de Sledge, Crusher et Tyranna deja vaincus. Le probleme venait du script : les trois sorts etaient lances avec triggered = true, donc instantanes et non interruptibles. Or ils ont tous un temps dincantation cote client : 200007 Annihilation gangrenee : 3 s, cone frontal -> il faut en sortir 200027 Ombres ecrasantes : canalise 5 s -> interruptible 200002 Effacement tenebreux : 2 s, +100% desquive -> interruptible Toute la parade disparaissait. Surtout, le bouclier desquive a 100% montait instantanement toutes les 6 s : le boss esquivait la quasi-totalite des coups. Ce netait pas un boss surpuissant mais un boss intouchable. Passage en incantation normale sur les trois. Comportement authentique retabli, aucune statistique modifiee. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |