diff --git a/sql/sylvania/dh_loot_wowhead.sql b/sql/sylvania/dh_loot_wowhead.sql new file mode 100644 index 0000000..a9bab40 --- /dev/null +++ b/sql/sylvania/dh_loot_wowhead.sql @@ -0,0 +1,119 @@ +-- ===================================================================== +-- Zone de départ Chasseur de démons — butin comparé au butin officiel +-- +-- Méthode : les tables `creature_loot_template` des 17 créatures tuables +-- de Mardum (1481) et du Caveau des Gardiennes (1468) ont été comparées +-- une à une aux tables de butin de Wowhead, relevées sur les pages PNJ +-- elles-mêmes (les données de butin y sont rendues en JavaScript : ni +-- curl — 403 — ni un simple export de page ne les voit). +-- +-- CE QUI ÉTAIT DÉJÀ CONFORME +-- Le menu fretin de Mardum n'a aucune table de butin, et c'est CORRECT : +-- Foul Felstalker, Dread Felbat, Legion Razorwing, Hellish Imp, Wrath +-- Warrior, Queen's Centurion, Ash'golm et Questioner Arev'naal ne lâchent +-- officiellement RIEN. Aucune correction de ce côté. +-- Les tables des créatures qui en ont une contiennent bien les bons +-- objets ; il n'y avait aucun objet en trop. +-- +-- CE QUI MANQUAIT +-- 132753 « Rations de la Légion » — absente de TOUTES les tables de la +-- zone, et même des 46 000 lignes de butin du serveur entier. +-- Wowhead la donne sur 14 des 17 créatures, entre 1,4 et 3,1 %. +-- 129196 « Pierre de soin de la Légion » — déjà présente 28 fois +-- ailleurs, mais oubliée sur quatre créatures. +-- 147430 « Parchemin runique mystérieux » — objet de la 7.3, jamais +-- référencé sur le serveur. Taux officiel 0,01 à 0,02 %. +-- 132138 « Cendres gangrenées radieuses » — oubliée sur l'Éclat abyssal. +-- 93105 Inquisiteur Funeste n'avait qu'UNE SEULE ligne sur les huit. +-- +-- CE QUI A ÉTÉ ÉCARTÉ VOLONTAIREMENT +-- * Les objets 235052, 235911, 236854, 236856, 236857 et 236870, que +-- Wowhead attribue à ces mêmes créatures : leurs identifiants sont +-- très au-dessus de la plage de Legion, ils viennent d'extensions +-- postérieures et n'existent pas dans un client 7.3.5. +-- * 129888 et 134819 sur le Sombrepiste sauvage : taux officiel +-- inférieur à 0,005 %, sous le seuil du bruit statistique. +-- * Les TAUX des lignes déjà présentes n'ont PAS été touchés, même +-- lorsqu'ils s'écartent de Wowhead (le plus gros écart : Kethrazor, +-- 128945 à 70 % chez nous contre 95 % chez Wowhead). Les +-- pourcentages de Wowhead sont une moyenne de relevés joueurs sur +-- toute l'extension, pas une donnée serveur ; les nôtres semblent +-- issus de captures. Réaligner l'ensemble serait un choix de +-- réglage, pas une correction de bug — à décider séparément. +-- +-- Les taux ci-dessous sont ceux de Wowhead. `lootid` vaut l'entrée de la +-- créature pour les 17 concernées. +-- Rechargeable à chaud : reload creature_loot_template +-- ===================================================================== + +-- --- 132753 Rations de la Légion --------------------------------------- +DELETE FROM `creature_loot_template` WHERE `Item`=132753 AND `Entry` IN + (97058,97057,97370,96997,97069,98986,98497,93221,93105,93802,92776,97225,96682,96783); +INSERT INTO `creature_loot_template` + (`Entry`,`Item`,`Reference`,`Chance`,`QuestRequired`,`LootMode`,`GroupId`,`MinCount`,`MaxCount`,`Comment`) VALUES +(97058,132753,0,3.00,0,1,0,1,1,'Count Nefarious - Legion Rations'), +(97057,132753,0,1.64,0,1,0,1,1,'Overseer Brutarg - Legion Rations'), +(97370,132753,0,1.94,0,1,0,1,1,'General Volroth - Legion Rations'), +(96997,132753,0,1.75,0,1,0,1,1,'Kethrazor - Legion Rations'), +(97069,132753,0,1.94,0,1,0,1,1,'Wrath-Lord Lekos - Legion Rations'), +(98986,132753,0,1.39,0,1,0,1,1,'Prolifica - Legion Rations'), +(98497,132753,0,3.12,0,1,0,1,1,'Imp Mother - Legion Rations'), +(93221,132753,0,1.97,0,1,0,1,1,'Doom Commander Beliash - Legion Rations'), +(93105,132753,0,1.79,0,1,0,1,1,'Inquisitor Baleful - Legion Rations'), +(93802,132753,0,1.72,0,1,0,1,1,'Brood Queen Tyranna - Legion Rations'), +(92776,132753,0,2.18,0,1,0,1,1,'Fel Shocktrooper - Legion Rations'), +(97225,132753,0,2.59,0,1,0,1,1,'Wrathguard Legate - Legion Rations'), +(96682,132753,0,1.57,0,1,0,1,1,'Immolanth - Legion Rations'), +(96783,132753,0,1.70,0,1,0,1,1,'Bastillax - Legion Rations'); + +-- --- 129196 Pierre de soin de la Légion (oubliée sur quatre) ----------- +DELETE FROM `creature_loot_template` WHERE `Item`=129196 AND `Entry` IN (97057,97370,96997,96783); +INSERT INTO `creature_loot_template` + (`Entry`,`Item`,`Reference`,`Chance`,`QuestRequired`,`LootMode`,`GroupId`,`MinCount`,`MaxCount`,`Comment`) VALUES +(97057,129196,0,0.92,0,1,0,1,1,'Overseer Brutarg - Legion Healthstone'), +(97370,129196,0,0.81,0,1,0,1,1,'General Volroth - Legion Healthstone'), +(96997,129196,0,0.48,0,1,0,1,1,'Kethrazor - Legion Healthstone'), +(96783,129196,0,1.14,0,1,0,1,1,'Bastillax - Legion Healthstone'); + +-- --- 147430 Parchemin runique mystérieux ------------------------------- +-- Ajouté uniquement là où Wowhead le référence. Les relevés à 0,00 % +-- (Sombrepiste sauvage, Fantassin gangrené, Lekos, Funeste) sont +-- remontés au plancher de 0,01 % : l'écart entre 0,00 et 0,01 n'est que +-- la taille de l'échantillon. +DELETE FROM `creature_loot_template` WHERE `Item`=147430 AND `Entry` IN + (97058,97057,97059,97370,96997,97069,98986,98497,93221,93105,92782,92776,97225,97228); +INSERT INTO `creature_loot_template` + (`Entry`,`Item`,`Reference`,`Chance`,`QuestRequired`,`LootMode`,`GroupId`,`MinCount`,`MaxCount`,`Comment`) VALUES +(97058,147430,0,0.02,0,1,0,1,1,'Count Nefarious - Mysterious Runebound Scroll'), +(97057,147430,0,0.01,0,1,0,1,1,'Overseer Brutarg - Mysterious Runebound Scroll'), +(97059,147430,0,0.01,0,1,0,1,1,'King Voras - Mysterious Runebound Scroll'), +(97370,147430,0,0.01,0,1,0,1,1,'General Volroth - Mysterious Runebound Scroll'), +(96997,147430,0,0.01,0,1,0,1,1,'Kethrazor - Mysterious Runebound Scroll'), +(97069,147430,0,0.01,0,1,0,1,1,'Wrath-Lord Lekos - Mysterious Runebound Scroll'), +(98986,147430,0,0.01,0,1,0,1,1,'Prolifica - Mysterious Runebound Scroll'), +(98497,147430,0,0.02,0,1,0,1,1,'Imp Mother - Mysterious Runebound Scroll'), +(93221,147430,0,0.01,0,1,0,1,1,'Doom Commander Beliash - Mysterious Runebound Scroll'), +(93105,147430,0,0.01,0,1,0,1,1,'Inquisitor Baleful - Mysterious Runebound Scroll'), +(92782,147430,0,0.01,0,1,0,1,1,'Savage Felstalker - Mysterious Runebound Scroll'), +(92776,147430,0,0.01,0,1,0,1,1,'Fel Shocktrooper - Mysterious Runebound Scroll'), +(97225,147430,0,0.01,0,1,0,1,1,'Wrathguard Legate - Mysterious Runebound Scroll'), +(97228,147430,0,0.01,0,1,0,1,1,'Abyssal Shard - Mysterious Runebound Scroll'); + +-- --- 132138 Cendres gangrenées radieuses ------------------------------- +DELETE FROM `creature_loot_template` WHERE `Item`=132138 AND `Entry`=97228; +INSERT INTO `creature_loot_template` + (`Entry`,`Item`,`Reference`,`Chance`,`QuestRequired`,`LootMode`,`GroupId`,`MinCount`,`MaxCount`,`Comment`) VALUES +(97228,132138,0,0.04,0,1,0,1,1,'Abyssal Shard - Radiant Fel Ash'); + +-- --- 93105 Inquisiteur Funeste : sept lignes sur huit manquaient ------- +-- Sa table ne contenait QUE la pierre de soin à 0,8 %. C'est le PNJ le +-- plus incomplet de la zone, et c'est celui qui garde une quête de la +-- campagne (« L'œil rivé sur l'objectif »). +DELETE FROM `creature_loot_template` WHERE `Entry`=93105 AND `Item` IN (130264,130265,130267,130268,130317); +INSERT INTO `creature_loot_template` + (`Entry`,`Item`,`Reference`,`Chance`,`QuestRequired`,`LootMode`,`GroupId`,`MinCount`,`MaxCount`,`Comment`) VALUES +(93105,130267,0,85.35,0,1,0,1,1,'Inquisitor Baleful - Extinguished Demon Stone'), +(93105,130268,0,11.19,0,1,0,1,1,'Inquisitor Baleful - Bone Toothpick'), +(93105,130317,0,3.53,0,1,0,1,1,'Inquisitor Baleful - Fractured Trophy'), +(93105,130264,0,0.94,0,1,0,1,1,'Inquisitor Baleful - Fel-Stained Claw'), +(93105,130265,0,0.07,0,1,0,1,1,'Inquisitor Baleful - Sharpened Canine'); diff --git a/sql/sylvania/dh_quest_credits.sql b/sql/sylvania/dh_quest_credits.sql new file mode 100644 index 0000000..4ee00b5 --- /dev/null +++ b/sql/sylvania/dh_quest_credits.sql @@ -0,0 +1,180 @@ +-- ===================================================================== +-- Zone de départ Chasseur de démons — objectifs de quête que RIEN +-- n'accordait +-- +-- Audit du 22/08/2026. Quatre objectifs OBLIGATOIRES n'avaient aucune +-- source sur tout le serveur : ni créature apparue, ni `KillCredit` de +-- créature, ni `smart_scripts` action 33, ni script C++ rattaché. Les +-- quêtes concernées étaient donc impossibles à terminer sans commande GM. +-- +-- 38690 « Le soulèvement des Illidari » — crédit 96762 × 8 +-- 38672 « La gangr'évasion » — crédits 92848 et 92849 +-- 38723 / 40253 « Arrêtez Gul'dan ! » — crédit 99303 +-- 38689 « Infusion gangrenée » — crédit 89297 × 100 +-- +-- Les crédits FACULTATIFS restent sans source et le restent volontairement : +-- ils portent le drapeau 0x04 (OPTIONNEL) et 0x08 (MASQUÉ), n'apparaissent +-- pas dans le journal et n'empêchent pas la validation. Il s'agit des huit +-- Illidari nommés de 38690 (97614 à 97622) et des quatre compteurs de la +-- barre « War progress » de 38819. Les rattacher demanderait d'inventer +-- quelle cellule enferme quel personnage : la donnée n'existe pas ici. +-- ===================================================================== + + +-- --------------------------------------------------------------------- +-- 1. « Le soulèvement des Illidari » — les huit cellules des Gardiennes +-- +-- L'objet 244588 « Warden Cell » est bien posé HUIT fois sur la carte +-- 1468, aux emplacements attendus. Mais il était totalement inerte : +-- type 10 (levier), AUCUN `AIName`, aucun `ScriptName`, aucune ligne +-- `smart_scripts`, et tous ses champs `Data` à zéro sauf `Data10` = 193119 +-- (le sort « Déverrouillage », 0,8 s d'incantation) qui ne produit qu'une +-- animation. Cliquer sur une cellule ne déclenchait donc rien. +-- +-- Huit cellules pour un objectif de huit prisonniers libérés : la +-- correspondance est directe, il n'y a rien à deviner. +-- +-- Le motif employé est celui d'une cage déjà fonctionnelle sur ce +-- serveur, « Scourge Cage » 187854 : évènement 70 (changement d'état de +-- butin) avec paramètre 2 (GO_ACTIVATED), action 33 (crédit) sur la +-- cible 7 (celui qui a cliqué). Le verrou de 244588 est nul et +-- `playerCast` vaut 1 : l'objet est utilisable tel quel. +-- +-- Pas de disparition après usage : `AllowMultiInteract` vaut 1 dans les +-- données d'origine de Blizzard (plusieurs joueurs peuvent libérer le +-- même prisonnier) et le délai de réapparition est de 7200 s — faire +-- disparaître une cellule la retirerait deux heures à tout le monde. +-- --------------------------------------------------------------------- +UPDATE `gameobject_template` SET `AIName`='SmartGameObjectAI' WHERE `entry`=244588; + +DELETE FROM `smart_scripts` WHERE `source_type`=1 AND `entryorguid`=244588; +INSERT INTO `smart_scripts` + (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`, + `event_param1`,`event_param2`,`event_param3`,`event_param4`,`event_param5`,`event_param_string`, + `action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`, + `target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(244588,1,0,0,70,0,100,0, 2,0,0,0,0,'', 33,96762,0,0,0,0,0, 7,0,0,0, 0,0,0,0, + 'Warden Cell - Activee - Credit Illidari Prisoner (quete 38690)'); + + +-- --------------------------------------------------------------------- +-- 2. « La gangr'évasion » — cellules de Kayn et d'Altruis +-- +-- 103655 « Altruis's Cell » et 103658 « Kayn's Cell » possèdent déjà un +-- SmartAI complet : à la réapparition elles reçoivent le drapeau de clic +-- de sort, et au clic elles lancent une liste d'actions (10365500 / +-- 10365800) qui les fait disparaître, place une donnée sur l'Illidari +-- libéré et lui envoie la cible. Il n'y manquait QUE le crédit. +-- +-- Le script C++ prévu pour cela (`npc_kayn_cell`, `npc_altruis_cell`) +-- n'aurait rien réglé : il n'est rattaché à aucune créature, ses lignes +-- de crédit sont en commentaire, et les entrées qu'il cite (99326, +-- 112276, 112277, 112287) ne sont PAS celles des objectifs de la quête. +-- On ajoute donc le crédit là où le reste fonctionne déjà, sans toucher +-- aux lignes existantes. +-- +-- 92848 = « Kayn Sunfury » -> objectif 1, cellule de Kayn 103658 +-- 92849 = « Altruis the Sufferer » -> objectif 0, cellule d'Altruis 103655 +-- --------------------------------------------------------------------- +DELETE FROM `smart_scripts` WHERE `source_type`=0 AND `entryorguid` IN (103655,103658) AND `id`=10; +INSERT INTO `smart_scripts` + (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`, + `event_param1`,`event_param2`,`event_param3`,`event_param4`,`event_param5`,`event_param_string`, + `action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`, + `target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(103655,0,10,0,73,0,100,0, 0,0,0,0,0,'', 33,92849,0,0,0,0,0, 7,0,0,0, 0,0,0,0, + 'Altruis Cell 103655 - Au clic - Credit Altruis libere (quete 38672)'), +(103658,0,10,0,73,0,100,0, 0,0,0,0,0,'', 33,92848,0,0,0,0,0, 7,0,0,0, 0,0,0,0, + 'Kayn Cell 103658 - Au clic - Credit Kayn libere (quete 38672)'); + + +-- --------------------------------------------------------------------- +-- 3. « Arrêtez Gul'dan ! » — crédit « Face Gul'dan » (99303) +-- +-- Sur les serveurs officiels une scène se joue à l'acceptation de la +-- quête ; le crédit tombe à sa fin. Ce core possède bien le script +-- correspondant (`scene_guldan_stealing_illidan_corpse`, scène 1016) mais +-- il est INAPPLICABLE : `scene_template` ne contient aucune ligne pour la +-- scène 1016, et `SceneMgr::PlayScene` abandonne silencieusement quand la +-- scène est inconnue. Impossible d'ajouter cette ligne sans le véritable +-- `ScriptPackageID` du client, que rien ici ne permet de déduire (les +-- correspondances connues — 1053→1451, 1061→1460, 1106→1487 — ne suivent +-- aucune règle). +-- +-- Or Maiev reproduit DÉJÀ la scène par SmartAI : sa liste d'actions +-- 9271800 lance les deux mêmes sorts puis téléporte à (4084, -298, -282), +-- exactement la destination codée dans le script C++. Seul le crédit +-- manquait. On l'ajoute au bon moment : juste avant la téléportation, +-- comme le fait `OnSceneEnd`. +-- +-- La liste est réécrite en entier pour insérer l'action au bon rang ; +-- les trois actions d'origine sont conservées à l'identique, y compris +-- le délai de 100 s qui correspond à la durée de la scène. +-- --------------------------------------------------------------------- +DELETE FROM `smart_scripts` WHERE `source_type`=9 AND `entryorguid`=9271800; +INSERT INTO `smart_scripts` + (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`, + `event_param1`,`event_param2`,`event_param3`,`event_param4`,`event_param5`,`event_param_string`, + `action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`, + `target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(9271800,9,0,0,0,0,100,0, 0,0,0,0,0,'', 85,223661,0,0,0,0,0, 7,0,0,0, 0,0,0,0, + 'Maiev Shadowsong 92718 - Script - Invocateur lance 223661'), +(9271800,9,1,0,0,0,100,0, 0,0,0,0,0,'', 85,187864,0,0,0,0,0, 7,0,0,0, 0,0,0,0, + 'Maiev Shadowsong 92718 - Script - Invocateur lance 187864'), +(9271800,9,2,0,0,0,100,0, 100000,100000,0,0,0,'', 33,99303,0,0,0,0,0, 7,0,0,0, 0,0,0,0, + 'Maiev Shadowsong 92718 - Script - Credit Face Guldan (quetes 38723/40253)'), +(9271800,9,3,0,0,0,100,0, 0,0,0,0,0,'', 62,1468,0,0,0,0,0, 7,0,0,0, + 4084.52,-297.89,-282.28,3.132, + 'Maiev Shadowsong 92718 - Script - Teleportation dans la chambre'); + + +-- --------------------------------------------------------------------- +-- 4. « Infusion gangrenée » — 100 points d'énergie sur les démons +-- +-- Texte de la quête : « The Vault is overrun with demons. Kill them and +-- gather their souls to regain your strength. » +-- +-- Le script C++ prévu (`npc_fel_infusion`) accorde +10 d'énergie et DIX +-- crédits 89297 par démon tué — soit dix démons pour les 100 points. +-- Il n'est rattaché à rien, et le rattacher écraserait le SmartAI de deux +-- des quatre démons concernés. On reproduit donc son comportement en +-- données. +-- +-- Les quatre démons du caveau (type 3 = démon, faction 954, présents +-- UNIQUEMENT sur la carte 1468, 122 apparitions au total) : +-- 92782 Savage Felstalker (70) SmartAI déjà présent +-- 97225 Wrathguard Legate (29) pas d'IA -> SmartAI ajouté +-- 92776 Fel Shocktrooper (17) SmartAI déjà présent +-- 97228 Abyssal Shard ( 6) pas d'IA -> SmartAI ajouté +-- « Safety Net » 103093, également de type 3, est écarté : faction 35, +-- c'est un élément de décor. +-- +-- Cible 0 (SMART_TARGET_NONE) et non 7 : sur l'action 33, ce cas passe +-- par `RewardPlayerAndGroupAtEvent`, qui crédite le destinataire du butin +-- ET son groupe. C'est le comportement correct en groupe. +-- +-- Dix lignes par démon plutôt qu'une liste d'actions appelée à la mort : +-- une liste temporisée sur une créature en train de mourir n'a aucune +-- garantie d'aller à son terme. +-- +-- Les identifiants 20 à 29 sont libres sur les quatre entrées. +-- --------------------------------------------------------------------- +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry` IN (97225,97228) AND `AIName`=''; + +DELETE FROM `smart_scripts` WHERE `source_type`=0 AND `entryorguid` IN (92782,92776,97225,97228) AND `id` BETWEEN 20 AND 29; +INSERT INTO `smart_scripts` + (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`, + `event_param1`,`event_param2`,`event_param3`,`event_param4`,`event_param5`,`event_param_string`, + `action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`, + `target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) +SELECT d.entry, 0, 20+n.i, 0, 6, 0, 100, 0, + 0,0,0,0,0,'', + 33, 89297, 0,0,0,0,0, + 0,0,0,0, 0,0,0,0, + CONCAT(d.nom,' - A la mort - Credit Energie gangrenee (quete 38689)') +FROM (SELECT 92782 entry,'Savage Felstalker' nom UNION ALL + SELECT 97225,'Wrathguard Legate' UNION ALL + SELECT 92776,'Fel Shocktrooper' UNION ALL + SELECT 97228,'Abyssal Shard') d +CROSS JOIN (SELECT 0 i UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 + UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) n; diff --git a/sql/sylvania/vault_missing_queststarters.sql b/sql/sylvania/vault_missing_queststarters.sql new file mode 100644 index 0000000..58e42ba --- /dev/null +++ b/sql/sylvania/vault_missing_queststarters.sql @@ -0,0 +1,72 @@ +-- ===================================================================== +-- Caveau des Gardiennes — quêtes que PERSONNE ne proposait +-- +-- Relevé par l'audit du 22/08/2026 : trois quêtes de la campagne Chasseur +-- de démons n'avaient AUCUNE ligne `creature_queststarter`. Elles étaient +-- donc rigoureusement impossibles à obtenir en jeu ; seule une commande +-- GM permettait de poursuivre la chaîne. +-- +-- 38668 « Notre dernier espoir » — parler à Maiev (aucun objectif : +-- la quête se valide à l'acceptation), récepteur Maiev 92718 +-- 38669 « Notre dernier espoir » — récupérer les glaives de guerre, +-- récepteur Maiev 92718 +-- 38689 « Infusion gangrenée » — 100 points d'énergie gangrenée, +-- récepteur Altruis 92986 +-- +-- Attribution : au récepteur déjà en place dans chaque cas. Ce n'est pas +-- un choix arbitraire : +-- * Maiev 92718 porte déjà npcflag 3 (papotage + donneur de quête), +-- elle donne déjà « La gangr'évasion » (38672), et le texte officiel +-- de 38668 la place explicitement devant la porte ouverte de votre +-- cellule : « Your jailor, Maiev Shadowsong, stands outside the open +-- door to your cell. » +-- * Altruis 92986 porte npcflag 2 (donneur de quête). Il est le pendant +-- exact de Kayn 92980, qui donne déjà « Le soulèvement des Illidari » +-- (38690) : Altruis donne l'étape qui précède, Kayn celle qui suit. +-- +-- Écart assumé : sur les serveurs officiels 38668 est acceptée +-- automatiquement à l'arrivée dans le caveau. Ce core n'a aucun mécanisme +-- rattaché pour cela (le drapeau QUEST_FLAGS_AUTO_ACCEPT 0x00080000 est +-- absent de la quête, et `On100DHArrival` ne fait qu'apprendre des sorts). +-- La faire proposer par Maiev produit exactement le même parcours pour le +-- joueur — il lui parle, c'est l'objectif même de la quête — avec une +-- fenêtre d'acceptation en plus. +-- +-- ORDRE DE LA CHAÎNE (`PrevQuestID`) +-- Sans contrainte d'ordre, Maiev proposerait 38668, 38669 et 38672 en même +-- temps. Or accepter 38672 la fait disparaître : le joueur perdait alors +-- l'accès aux deux autres. C'est précisément le blocage signalé en jeu. +-- L'ordre officiel (source : chaîne « Vault of the Wardens » de Wowhead) +-- est rétabli : +-- 38668 → 38669 → 38672 → 38689 → 38690 → 38723 / 40253 +-- 38668 ne reçoit VOLONTAIREMENT aucun prérequis : la quête qui la précède +-- (38729 « Retourner au Temple noir ») n'a aucun récepteur sur ce serveur +-- et ne peut donc jamais passer à l'état « récompensée » — l'exiger +-- bloquerait la chaîne pour de bon. +-- +-- LIGNE FANTÔME +-- Maiev 92718 était déclarée donneuse de la quête 41226, absente de +-- `quest_template`. Supprimée. +-- +-- Rechargeable à chaud : reload quest_template ; reload creature_questender +-- (il n'existe pas de commande de rechargement pour creature_queststarter, +-- un redémarrage est nécessaire pour que les quêtes apparaissent). +-- ===================================================================== + +-- --- donneurs manquants ------------------------------------------------ +DELETE FROM `creature_queststarter` WHERE `quest` IN (38668,38669,38689); +INSERT INTO `creature_queststarter` (`id`,`quest`) VALUES +(92718,38668), +(92718,38669), +(92986,38689); + +-- --- ligne pointant vers une quête inexistante -------------------------- +DELETE FROM `creature_queststarter` WHERE `id`=92718 AND `quest`=41226; +DELETE FROM `creature_questender` WHERE `quest`=41226; + +-- --- ordre de la chaîne ------------------------------------------------- +UPDATE `quest_template_addon` SET `PrevQuestID`=38668 WHERE `ID`=38669; +UPDATE `quest_template_addon` SET `PrevQuestID`=38669 WHERE `ID`=38672; +UPDATE `quest_template_addon` SET `PrevQuestID`=38672 WHERE `ID`=38689; +UPDATE `quest_template_addon` SET `PrevQuestID`=38689 WHERE `ID`=38690; +UPDATE `quest_template_addon` SET `PrevQuestID`=38690 WHERE `ID` IN (38723,40253); diff --git a/src/server/scripts/BrokenIsles/DemonHunterZones/zone_mardum.cpp b/src/server/scripts/BrokenIsles/DemonHunterZones/zone_mardum.cpp index ad5ff49..a9cc4dc 100644 --- a/src/server/scripts/BrokenIsles/DemonHunterZones/zone_mardum.cpp +++ b/src/server/scripts/BrokenIsles/DemonHunterZones/zone_mardum.cpp @@ -106,6 +106,7 @@ enum MardumCreatures NPC_COLOSSAL_INFERNAL = 96159, NPC_LEGION_GATEWAY_KILL_CREDIT = 94406, NPC_FIRST_SUMMONED_GUARDIAN_QUEST_KILL_CREDIT = 97831, + NPC_SHIVARRA_GATEWAY_KILL_CREDIT = 94407, NPC_QUEEN_TYRANNA = 95048, NPC_BELIASH_CREDIT = 106003, NPC_ASHTONGUE_CAPTAIN = 90247, @@ -655,9 +656,22 @@ public: bool OnGossipHello(Player* player, GameObject* /*go*/) override { - if (player->GetQuestObjectiveData(QUEST_SHIVARRA_FORCES, 0)) + // Ce bloc etait le seul des trois portails a ne pas accorder de + // credit : il appelait ForceCompleteQuest, un raccourci de debogage + // qui valide la quete en sautant ses objectifs, et il le faisait sous + // la condition INVERSE de ses deux jumeaux (sans le '!'), donc + // seulement si l'objectif 0 etait DEJA acquis. + // Resultat : l'objectif 2 « Shivarra forces » (credit 94407), qui est + // obligatoire et sequence, n'avait aucune source sur tout le serveur + // et la quete 38765 restait bloquee. + // On applique ici exactement le schema des portails Cendrelangue et + // Glissentaille, avec les index d'objectif propres a 38765 : + // index 2 -> 94407 « Enter the Illidari: Shivarra » Legion Gateway + // index 3 -> 97831 First Summoned Guardian (facultatif) + if (!player->GetQuestObjectiveData(QUEST_SHIVARRA_FORCES, 2)) { - player->ForceCompleteQuest(QUEST_SHIVARRA_FORCES); + player->KilledMonsterCredit(NPC_SHIVARRA_GATEWAY_KILL_CREDIT); // storageIndex 2 + player->KilledMonsterCredit(NPC_FIRST_SUMMONED_GUARDIAN_QUEST_KILL_CREDIT); // storageIndex 3 player->CastSpell(player, SPELL_SCENE_MARDUM_SHIVARRA_FORCES, true); } diff --git a/src/server/scripts/BrokenIsles/DemonHunterZones/zone_vault_of_wardens.cpp b/src/server/scripts/BrokenIsles/DemonHunterZones/zone_vault_of_wardens.cpp index d342a0d..a70e383 100644 --- a/src/server/scripts/BrokenIsles/DemonHunterZones/zone_vault_of_wardens.cpp +++ b/src/server/scripts/BrokenIsles/DemonHunterZones/zone_vault_of_wardens.cpp @@ -28,6 +28,8 @@ #include "GameObjectAI.h" #include "ObjectAccessor.h" #include "SpellAuras.h" +#include "Item.h" +#include "ItemTemplate.h" #include "SpellScript.h" #include "SpellAuraEffects.h" #include "SpellHistory.h" @@ -2309,6 +2311,68 @@ public: } }; + +// 38669 « Notre dernier espoir » : recuperer ses glaives de guerre. +// Les deux objectifs sont des credits de type creature accordes par le +// serveur officiel au moment ou l'arme arrive dans son emplacement : +// index 0 -> 97574 « Main-hand glaive equipped » +// index 1 -> 98369 « Off-hand glaive equipped » +// Rien ne les accordait ici : aucune creature, aucun KillCredit, aucun +// smart_scripts, aucun script C++ ne mentionne ces deux entrees. La quete +// etait donc impossible a terminer. +// +// On ne code en dur AUCUN identifiant d'objet : l'objectif dit « un glaive +// equipe », on verifie donc exactement cela — une arme de sous-classe +// ITEM_SUBCLASS_WEAPON_WARGLAIVES dans l'emplacement correspondant. Cela +// reste vrai quels que soient les glaives remis au joueur. +// +// Le crochet employe est PlayerScript::OnItemLevelChange, appele par +// ScriptMgr::OnPlayerItemLevelChange depuis la fin de Player::EquipItem +// (Player.cpp) — c'est le seul point d'accroche du core sur un changement +// d'equipement, il n'existe aucun OnEquip. Les deux premiers tests (classe, +// puis etat de la quete) ecartent immediatement tous les autres joueurs, le +// cout est negligeable. +enum OurLastHopeGlaives +{ + QUEST_OUR_LAST_HOPE_GLAIVES = 38669, + CREDIT_MAINHAND_GLAIVE = 97574, + CREDIT_OFFHAND_GLAIVE = 98369, +}; + +class PlayerScript_our_last_hope_glaives : public PlayerScript +{ +public: + PlayerScript_our_last_hope_glaives() : PlayerScript("PlayerScript_our_last_hope_glaives") { } + + void OnItemLevelChange(Player* player) override + { + if (!player || player->getClass() != CLASS_DEMON_HUNTER) + return; + + if (player->GetQuestStatus(QUEST_OUR_LAST_HOPE_GLAIVES) != QUEST_STATUS_INCOMPLETE) + return; + + if (IsWarglaive(player, EQUIPMENT_SLOT_MAINHAND) && !player->GetQuestObjectiveData(QUEST_OUR_LAST_HOPE_GLAIVES, 0)) + player->KilledMonsterCredit(CREDIT_MAINHAND_GLAIVE); + + if (IsWarglaive(player, EQUIPMENT_SLOT_OFFHAND) && !player->GetQuestObjectiveData(QUEST_OUR_LAST_HOPE_GLAIVES, 1)) + player->KilledMonsterCredit(CREDIT_OFFHAND_GLAIVE); + } + +private: + static bool IsWarglaive(Player* player, uint8 slot) + { + Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot); + if (!item) + return false; + + ItemTemplate const* proto = item->GetTemplate(); + return proto + && proto->GetClass() == ITEM_CLASS_WEAPON + && proto->GetSubClass() == ITEM_SUBCLASS_WEAPON_WARGLAIVES; + } +}; + void AddSC_zone_vault_of_wardens() { new npc_kayn_cell(); @@ -2342,6 +2406,7 @@ void AddSC_zone_vault_of_wardens() new PlayerScript_follower_choice(); new On100DHArrival(); new PlayerScript_bonus_objective(); + new PlayerScript_our_last_hope_glaives(); new PlayerScript_switch_phases(); RegisterCreatureAI(npc_vault_of_the_wardens_sledge_or_crusher); new npc_altruis_sufferer_freed_99632();