diff --git a/data/sql/updates/pending_db_world/rev_1712081213502287312.sql b/data/sql/updates/pending_db_world/rev_1712081213502287312.sql new file mode 100644 index 000000000..df56db8d9 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1712081213502287312.sql @@ -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'); diff --git a/src/server/game/Spells/SpellInfoCorrections.cpp b/src/server/game/Spells/SpellInfoCorrections.cpp index 4fceae1bc..f75316ef2 100644 --- a/src/server/game/Spells/SpellInfoCorrections.cpp +++ b/src/server/game/Spells/SpellInfoCorrections.cpp @@ -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 diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp index cc22c9234..996ac270e 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp @@ -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 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 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::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); } diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp index ed4686ba5..2f45192b7 100644 --- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp +++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp @@ -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: diff --git a/src/server/scripts/Northrend/Naxxramas/naxxramas.h b/src/server/scripts/Northrend/Naxxramas/naxxramas.h index dcbeb811f..256ca8633 100644 --- a/src/server/scripts/Northrend/Naxxramas/naxxramas.h +++ b/src/server/scripts/Northrend/Naxxramas/naxxramas.h @@ -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