fix(Scripts/Naxxramas): Gothik missing visuals at minions death (#18666)

* add sql rev

* enable NPC_TRIGGER

* add npc_gothik_trigger

* add rest of script

* spell info correction

* fix compile issue

* fix desummon call

* remove comment

* access gothik by GUID

* add missing function overrides

* add braces

* add missing trigger, adjust CGUID value

* fixup! add missing trigger, adjust CGUID value

* select skulls based on coordinates

style

invert remove

remove CGUID comment

fix remove_if check, use correct def

* JustSummoned: target same side with mapLOS

* select random initial target on the same side

* add REACT_AGGRESSIVE and increase CallForHelp radius

* refactor spellscript

* style
This commit is contained in:
Jelle Meeus
2024-06-29 20:12:12 +02:00
committed by GitHub
parent 6818b17b3d
commit ed38e6e550
5 changed files with 215 additions and 71 deletions

View File

@@ -0,0 +1,42 @@
--
-- trigger AI
UPDATE `creature_template` SET `ScriptName` = 'npc_gothik_trigger' WHERE `entry` = 16137;
-- re-do spawn locations for triggers
DELETE FROM `creature` WHERE `id1`=16137;
SET @CGUID = 127514;
INSERT INTO `creature` (`guid`, `id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`, `CreateObject`, `Comment`) VALUES
(@CGUID+0, 16137, 0, 0, 533, 3456, 3456, 3, 1, 0, 2643.73095703125, -3399.680908203125, 284.18292236328125, 6.091198921203613281, 7200, 0, 0, 17010, 0, 0, 0, 0, 0, '', 46248, 0, 'living side soul trigger (south)'),
(@CGUID+1, 16137, 0, 0, 533, 3456, 3456, 3, 1, 0, 2739.994873046875, -3399.779296875, 284.294647216796875, 6.108652114868164062, 7200, 0, 0, 17010, 0, 0, 0, 0, 0, '', 46248, 0, 'living side soul trigger (north)'),
(@CGUID+2, 16137, 0, 0, 533, 3456, 3456, 3, 1, 0, 2643.73095703125, -3321.72705078125, 284.23272705078125, 6.195918560028076171, 7200, 0, 0, 17010, 0, 0, 0, 0, 0, '', 46248, 0, 'spectral side soul trigger (south)'),
(@CGUID+3, 16137, 0, 0, 533, 3456, 3456, 3, 1, 0, 2739.994873046875, -3321.72705078125, 284.23162841796875, 2.827433347702026367, 7200, 0, 0, 17010, 0, 0, 0, 0, 0, '', 46248, 0, 'spectral side soul trigger (north)'),
(@CGUID+4, 16137, 0, 0, 533, 3456, 3456, 3, 1, 0, 2692.16064453125, -3430.745849609375, 268.64617919921875, 1.605702877044677734, 7200, 0, 0, 17010, 0, 0, 0, 0, 0, '', 46248, 0, 'living side spawn trigger (center back)'),
(@CGUID+5, 16137, 0, 0, 533, 3456, 3456, 3, 1, 0, 2714.561767578125, -3430.6103515625, 268.646240234375, 1.413716673851013183, 7200, 0, 0, 17010, 0, 0, 0, 0, 0, '', 46248, 0, 'living side spawn trigger (north back)'),
(@CGUID+6, 16137, 0, 0, 533, 3456, 3456, 3, 1, 0, 2669.581298828125, -3428.858642578125, 268.64617919921875, 1.378810048103332519, 7200, 0, 0, 17010, 0, 0, 0, 0, 0, '', 46248, 0, 'living side spawn trigger (south front)'),
(@CGUID+7, 16137, 0, 0, 533, 3456, 3456, 3, 1, 0, 2669.59033203125, -3431.460205078125, 268.64617919921875, 1.343903541564941406, 7200, 0, 0, 17010, 0, 0, 0, 0, 0, '', 46248, 0, 'living side spawn trigger (south back)'),
(@CGUID+8, 16137, 0, 0, 533, 3456, 3456, 3, 1, 0, 2692.212646484375, -3428.78271484375, 268.64617919921875, 1.48352980613708496, 7200, 0, 0, 17010, 0, 0, 0, 0, 0, '', 46248, 0, 'living side spawn trigger (center front)'),
(@CGUID+9, 16137, 0, 0, 533, 3456, 3456, 3, 1, 0, 2733.456787109375, -3349.387939453125, 267.7677001953125, 1.780235767364501953, 7200, 0, 0, 17010, 0, 0, 0, 0, 0, '', 46248, 0, 'living side spawn trigger (north front)'),
(@CGUID+10, 16137, 0, 0, 533, 3456, 3456, 3, 1, 0, 2714.4619140625, -3428.727783203125, 268.64617919921875, 1.65806281566619873, 7200, 0, 0, 17010, 0, 0, 0, 0, 0, '', 46248, 0, 'spectral side spawn trigger (northwest)'),
(@CGUID+11, 16137, 0, 0, 533, 3456, 3456, 3, 1, 0, 2725.818603515625, -3309.567626953125, 267.89178466796875, 2.827433347702026367, 7200, 0, 0, 17010, 0, 0, 0, 0, 0, '', 46248, 0, 'spectral side spawn trigger (northeast)'),
(@CGUID+12, 16137, 0, 0, 533, 3456, 3456, 3, 1, 0, 2700.268798828125, -3322.3544921875, 267.767791748046875, 3.525565147399902343, 7200, 0, 0, 17010, 0, 0, 0, 0, 0, '', 46248, 0, 'spectral side spawn trigger (center)'),
(@CGUID+13, 16137, 0, 0, 533, 3456, 3456, 3, 1, 0, 2683.885986328125, -3304.212890625, 267.76800537109375, 2.49582076072692871, 7200, 0, 0, 17010, 0, 0, 0, 0, 0, '', 46248, 0, 'spectral side spawn trigger (southwest)'),
(@CGUID+14, 16137, 0, 0, 533, 3456, 3456, 3, 1, 0, 2664.871826171875, -3340.7490234375, 267.767364501953125, 5.934119224548339843, 7200, 0, 0, 17010, 0, 0, 0, 0, 0, '', 46248, 0, 'spectral side spawn trigger (southeast)');
-- make visuals target proper triggers
-- to anchor 1: 27892 (Trainee), 27928 (DK), 27935 (Rider)
-- to anchor 2: 27893 (Trainee), 27929 (DK), 27936 (Rider)
-- anchor -> skull: 27915 (Trainee), 27931 (DK), 27937 (Rider)
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (27892,27928,27935,27893,27929,27936,27915,27931,27937);
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13,1,27892,0,0,31,0,3,16137,@CGUID+0,0,0,0,'','To Anchor 1 - Target Anchor Living South'),
(13,1,27892,0,1,31,0,3,16137,@CGUID+1,0,0,0,'','To Anchor 1 - Target Anchor Living North'),
(13,1,27928,0,0,31,0,3,16137,@CGUID+0,0,0,0,'','To Anchor 1 - Target Anchor Living South'),
(13,1,27928,0,1,31,0,3,16137,@CGUID+1,0,0,0,'','To Anchor 1 - Target Anchor Living North'),
(13,1,27935,0,0,31,0,3,16137,@CGUID+0,0,0,0,'','To Anchor 1 - Target Anchor Living South'),
(13,1,27935,0,1,31,0,3,16137,@CGUID+1,0,0,0,'','To Anchor 1 - Target Anchor Living North'),
(13,1,27893,0,0,31,0,3,16137,@CGUID+2,0,0,0,'','To Anchor 2 - Target Anchor Spectral South'),
(13,1,27893,0,1,31,0,3,16137,@CGUID+3,0,0,0,'','To Anchor 2 - Target Anchor Spectral North'),
(13,1,27929,0,0,31,0,3,16137,@CGUID+2,0,0,0,'','To Anchor 2 - Target Anchor Spectral South'),
(13,1,27929,0,1,31,0,3,16137,@CGUID+3,0,0,0,'','To Anchor 2 - Target Anchor Spectral North'),
(13,1,27936,0,0,31,0,3,16137,@CGUID+2,0,0,0,'','To Anchor 2 - Target Anchor Spectral South'),
(13,1,27936,0,1,31,0,3,16137,@CGUID+3,0,0,0,'','To Anchor 2 - Target Anchor Spectral North');

View File

@@ -384,12 +384,9 @@ void SpellMgr::LoadSpellInfoCorrections()
27892, // To Anchor 1
27928, // To Anchor 1
27935, // To Anchor 1
27915, // Anchor to Skulls
27931, // Anchor to Skulls
27937 // Anchor to Skulls
}, [](SpellInfo* spellInfo)
}, [](SpellInfo* spellInfo)
{
spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13);
spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS);
});
// Wrath of the Plaguebringer

View File

@@ -47,15 +47,15 @@ enum Spells
SPELL_TELEPORT_DEAD = 28025,
SPELL_TELEPORT_LIVE = 28026,
// Visual spells
SPELL_INFORM_LIVING_TRAINEE = 27892,
SPELL_INFORM_LIVING_KNIGHT = 27928,
SPELL_INFORM_LIVING_RIDER = 27935,
SPELL_INFORM_DEAD_TRAINEE = 27915,
SPELL_INFORM_DEAD_KNIGHT = 27931,
SPELL_INFORM_DEAD_RIDER = 27937,
/*SPELL_ANCHOR_2_TRAINEE = 27893,
SPELL_ANCHOR_1_TRAINEE = 27892,
SPELL_ANCHOR_1_DK = 27928,
SPELL_ANCHOR_1_RIDER = 27935,
SPELL_ANCHOR_2_TRAINEE = 27893,
SPELL_ANCHOR_2_DK = 27929,
SPELL_ANCHOR_2_RIDER = 27936, fix me */
SPELL_ANCHOR_2_RIDER = 27936,
SPELL_SKULLS_TRAINEE = 27915,
SPELL_SKULLS_DK = 27931,
SPELL_SKULLS_RIDER = 27937,
// Living trainee
SPELL_DEATH_PLAGUE = 55604,
// Dead trainee
@@ -82,7 +82,7 @@ enum Misc
NPC_DEAD_KNIGHT = 16148,
NPC_DEAD_HORSE = 16149,
NPC_DEAD_RIDER = 16150,
//NPC_TRIGGER = 16137, fix me
NPC_TRIGGER = 16137
};
enum Events
@@ -277,31 +277,41 @@ public:
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
if (Unit* target = SelectTarget(SelectTargetMethod::MinDistance, 0, 200.0f))
// If central gate is open, attack any one
if (gateOpened)
{
if (gateOpened)
if (Unit* target = SelectTarget(SelectTargetMethod::MinDistance, 0, 200.0f))
{
summon->AI()->AttackStart(target);
summon->CallForHelp(40.0f);
summon->SetInCombatWithZone();
summon->SetReactState(REACT_AGGRESSIVE);
summon->CallForHelp(150.0f);
}
else
}
// Else look for a random target on the side the summoned NPC is
else
{
Map::PlayerList const& pList = me->GetMap()->GetPlayers();
std::vector<Player*> tList;
for(Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
{
if (summon->GetEntry() == NPC_LIVING_TRAINEE ||
summon->GetEntry() == NPC_LIVING_KNIGHT ||
summon->GetEntry() == NPC_LIVING_RIDER )
if (!me->IsWithinDistInMap(itr->GetSource(), 200.0f, true, false) || !itr->GetSource()->IsAlive() || itr->GetSource()->IsGameMaster())
{
if (IN_LIVE_SIDE(target))
{
summon->AI()->AttackStart(target);
}
continue;
}
else
if (IN_LIVE_SIDE(itr->GetSource()) != IN_LIVE_SIDE(summon))
{
if (!IN_LIVE_SIDE(target))
{
summon->AI()->AttackStart(target);
}
continue;
}
tList.push_back(itr->GetSource());
}
if (!tList.empty())
{
Player* target = tList[urand(0, tList.size() - 1)];
summon->AI()->AttackStart(target);
summon->SetInCombatWithZone();
summon->SetReactState(REACT_AGGRESSIVE);
summon->CallForHelp(150.0f);
}
}
}
@@ -404,25 +414,6 @@ public:
return false;
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
{
uint8 pos = urand(0, 4);
switch (spellInfo->Id)
{
case SPELL_INFORM_LIVING_TRAINEE:
me->SummonCreature(NPC_DEAD_TRAINEE, PosSummonDead[pos].GetPositionX(), PosSummonDead[pos].GetPositionY(), PosSummonDead[pos].GetPositionZ(), PosSummonDead[pos].GetOrientation());
break;
case SPELL_INFORM_LIVING_KNIGHT:
me->SummonCreature(NPC_DEAD_KNIGHT, PosSummonDead[pos].GetPositionX(), PosSummonDead[pos].GetPositionY(), PosSummonDead[pos].GetPositionZ(), PosSummonDead[pos].GetOrientation());
break;
case SPELL_INFORM_LIVING_RIDER:
me->SummonCreature(NPC_DEAD_RIDER, PosSummonDead[pos].GetPositionX(), PosSummonDead[pos].GetPositionY(), PosSummonDead[pos].GetPositionZ(), PosSummonDead[pos].GetOrientation());
me->SummonCreature(NPC_DEAD_HORSE, PosSummonDead[pos].GetPositionX(), PosSummonDead[pos].GetPositionY(), PosSummonDead[pos].GetPositionZ(), PosSummonDead[pos].GetOrientation());
break;
}
me->HandleEmoteCommand(EMOTE_ONESHOT_SPELL_CAST);
}
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
if (!secondPhase)
@@ -593,13 +584,13 @@ public:
switch (me->GetEntry())
{
case NPC_LIVING_TRAINEE:
me->CastSpell(me, SPELL_INFORM_LIVING_TRAINEE, true);
DoCastAOE(SPELL_ANCHOR_1_TRAINEE, true);
break;
case NPC_LIVING_KNIGHT:
me->CastSpell(me, SPELL_INFORM_LIVING_KNIGHT, true);
DoCastAOE(SPELL_ANCHOR_1_DK, true);
break;
case NPC_LIVING_RIDER:
me->CastSpell(me, SPELL_INFORM_LIVING_RIDER, true);
DoCastAOE(SPELL_ANCHOR_1_RIDER, true);
break;
}
}
@@ -688,6 +679,109 @@ public:
};
};
class npc_gothik_trigger : public CreatureScript
{
public:
npc_gothik_trigger() : CreatureScript("npc_gothik_trigger") { }
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_gothik_triggerAI(creature);
}
struct npc_gothik_triggerAI : public ScriptedAI
{
npc_gothik_triggerAI(Creature* creature) : ScriptedAI(creature) { creature->SetDisableGravity(true); }
void EnterEvadeMode(EvadeReason /*why*/) override {}
void UpdateAI(uint32 /*diff*/) override {}
void JustEngagedWith(Unit* /*who*/) override {}
void DamageTaken(Unit* /*who*/, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override { damage = 0; }
Creature* SelectRandomSkullPile()
{
std::list<Creature*> triggers;
me->GetCreatureListWithEntryInGrid(triggers, NPC_TRIGGER, 150.0f);
// Remove triggers that are on live side or soul triggers on the platform
triggers.remove_if([](Creature* trigger){
return ((trigger->GetPositionY() < POS_Y_GATE) || (trigger->GetPositionZ() > 280.0f));
});
if (!triggers.empty())
{
std::list<Creature*>::iterator itr = triggers.begin();
std::advance(itr, urand(0, triggers.size() - 1));
return *itr;
}
return nullptr;
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
{
if (!spell)
{
return;
}
switch (spell->Id)
{
case SPELL_ANCHOR_1_TRAINEE:
DoCastAOE(SPELL_ANCHOR_2_TRAINEE, true);
break;
case SPELL_ANCHOR_1_DK:
DoCastAOE(SPELL_ANCHOR_2_DK, true);
break;
case SPELL_ANCHOR_1_RIDER:
DoCastAOE(SPELL_ANCHOR_2_RIDER, true);
break;
case SPELL_ANCHOR_2_TRAINEE:
if (Creature* target = SelectRandomSkullPile())
{
DoCast(target, SPELL_SKULLS_TRAINEE, true);
}
break;
case SPELL_ANCHOR_2_DK:
if (Creature* target = SelectRandomSkullPile())
{
DoCast(target, SPELL_SKULLS_DK, true);
}
break;
case SPELL_ANCHOR_2_RIDER:
if (Creature* target = SelectRandomSkullPile())
{
DoCast(target, SPELL_SKULLS_RIDER, true);
}
break;
case SPELL_SKULLS_TRAINEE:
DoSummon(NPC_DEAD_TRAINEE, me, 0.0f, 15 * IN_MILLISECONDS, TEMPSUMMON_CORPSE_TIMED_DESPAWN);
break;
case SPELL_SKULLS_DK:
DoSummon(NPC_DEAD_KNIGHT, me, 0.0f, 15 * IN_MILLISECONDS, TEMPSUMMON_CORPSE_TIMED_DESPAWN);
break;
case SPELL_SKULLS_RIDER:
DoSummon(NPC_DEAD_RIDER, me, 0.0f, 15 * IN_MILLISECONDS, TEMPSUMMON_CORPSE_TIMED_DESPAWN);
DoSummon(NPC_DEAD_HORSE, me, 0.0f, 15 * IN_MILLISECONDS, TEMPSUMMON_CORPSE_TIMED_DESPAWN);
break;
}
}
// dead side summons are "owned" by gothik
void JustSummoned(Creature* summon) override
{
if (Creature* gothik = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(DATA_GOTHIK_BOSS)))
{
gothik->AI()->JustSummoned(summon);
}
}
void SummonedCreatureDespawn(Creature* summon) override
{
if (Creature* gothik = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetGuidData(DATA_GOTHIK_BOSS)))
{
gothik->AI()->SummonedCreatureDespawn(summon);
}
}
};
};
class spell_gothik_shadow_bolt_volley : public SpellScript
{
PrepareSpellScript(spell_gothik_shadow_bolt_volley);
@@ -712,6 +806,7 @@ void AddSC_boss_gothik()
{
new boss_gothik();
new npc_boss_gothik_minion();
new npc_gothik_trigger();
RegisterSpellScript(spell_gothik_shadow_bolt_volley);
}

View File

@@ -137,6 +137,7 @@ public:
GuidList PatchwerkRoomTrash;
ObjectGuid _patchwerkGUID;
ObjectGuid _thaddiusGUID;
ObjectGuid _gothikGUID;
ObjectGuid _stalaggGUID;
ObjectGuid _feugenGUID;
ObjectGuid _zeliekGUID;
@@ -227,6 +228,9 @@ public:
case NPC_FEUGEN:
_feugenGUID = creature->GetGUID();
return;
case NPC_GOTHIK:
_gothikGUID = creature->GetGUID();
return;
case NPC_LADY_BLAUMEUX:
_blaumeuxGUID = creature->GetGUID();
return;
@@ -1092,6 +1096,8 @@ public:
return _stalaggGUID;
case DATA_FEUGEN_BOSS:
return _feugenGUID;
case DATA_GOTHIK_BOSS:
return _gothikGUID;
case DATA_LICH_KING_BOSS:
return _lichkingGUID;
default:

View File

@@ -58,25 +58,26 @@ enum NXData
DATA_STALAGG_BOSS = 108,
DATA_FEUGEN_BOSS = 109,
DATA_THADDIUS_GATE = 110,
DATA_GOTHIK_ENTER_GATE = 111,
DATA_GOTHIK_INNER_GATE = 112,
DATA_GOTHIK_EXIT_GATE = 113,
DATA_HORSEMEN_GATE = 114,
DATA_LICH_KING_BOSS = 115,
DATA_KELTHUZAD_FLOOR = 116,
DATA_ABOMINATION_KILLED = 117,
DATA_FRENZY_REMOVED = 118,
DATA_CHARGES_CROSSED = 119,
DATA_SPORE_KILLED = 120,
DATA_HUNDRED_CLUB = 121,
DATA_DANCE_FAIL = 122,
DATA_IMMORTAL_FAIL = 123,
DATA_KELTHUZAD_GATE = 124,
DATA_HAD_THADDIUS_GREET = 125,
DATA_KELTHUZAD_PORTAL_1 = 126,
DATA_KELTHUZAD_PORTAL_2 = 127,
DATA_KELTHUZAD_PORTAL_3 = 128,
DATA_KELTHUZAD_PORTAL_4 = 129
DATA_GOTHIK_BOSS = 111,
DATA_GOTHIK_ENTER_GATE = 112,
DATA_GOTHIK_INNER_GATE = 113,
DATA_GOTHIK_EXIT_GATE = 114,
DATA_HORSEMEN_GATE = 115,
DATA_LICH_KING_BOSS = 116,
DATA_KELTHUZAD_FLOOR = 117,
DATA_ABOMINATION_KILLED = 118,
DATA_FRENZY_REMOVED = 119,
DATA_CHARGES_CROSSED = 120,
DATA_SPORE_KILLED = 121,
DATA_HUNDRED_CLUB = 122,
DATA_DANCE_FAIL = 123,
DATA_IMMORTAL_FAIL = 124,
DATA_KELTHUZAD_GATE = 125,
DATA_HAD_THADDIUS_GREET = 126,
DATA_KELTHUZAD_PORTAL_1 = 127,
DATA_KELTHUZAD_PORTAL_2 = 128,
DATA_KELTHUZAD_PORTAL_3 = 129,
DATA_KELTHUZAD_PORTAL_4 = 130
};
enum NXGOs
@@ -162,6 +163,9 @@ enum NXNPCs
NPC_LIVING_MONSTROSITY = 16021,
NPC_SURGICAL_ASSIST = 16022,
NPC_SLUDGE_BELCHER = 16029,
// Gothik
NPC_GOTHIK = 16060
};
enum NXMisc