diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp
index 4224aef..5b8ac70 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp
@@ -1,5 +1,5 @@
- /*
- * Copyright (C) 2008-2018 TrinityCore
+/*
+ * This file is part of the DestinyCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -15,6 +15,13 @@
* with this program. If not, see .
*/
+// Nalorakk n'avait qu'une coquille de script : il frappait en melee et rien d'autre,
+// ni sorts ni changement de forme. Le combat est ici ecrit a partir du script amont
+// TrinityCore, en gardant NOTRE numerotation de creature_text (0-11).
+// Ce qui n'est pas porte : les quatre vagues de trolls qui l'annoncent dans la rampe.
+// L'amont les pilote par des spawn groups et des chemins de waypoints que ce core
+// n'a pas (pas de table spawn_group) -- cela demanderait de recreer les donnees.
+
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "zulaman.h"
@@ -37,10 +44,33 @@ enum Says
enum Spells
{
+ // Forme troll
+ SPELL_BRUTAL_SWIPE = 42384,
+ SPELL_MANGLE = 42389,
+ SPELL_SURGE = 44019,
+
+ // Forme d'ours
+ SPELL_LACERATING_SLASH = 42395,
+ SPELL_REND_FLESH = 42397,
+ SPELL_DEAFENING_ROAR = 42398,
+
+ // Communs
+ SPELL_SHAPE_OF_THE_BEAR = 42377,
+ SPELL_BERSERK = 45078
};
enum Events
{
+ EVENT_BRUTAL_SWIPE = 1,
+ EVENT_MANGLE,
+ EVENT_SURGE,
+
+ EVENT_LACERATING_SLASH,
+ EVENT_REND_FLESH,
+ EVENT_DEAFENING_ROAR,
+
+ EVENT_SHAPESHIFT,
+ EVENT_BERSERK
};
class boss_nalorakk : public CreatureScript
@@ -51,17 +81,23 @@ class boss_nalorakk : public CreatureScript
struct boss_nalorakkAI : public BossAI
{
- boss_nalorakkAI(Creature* creature) : BossAI(creature, DATA_NALORAKK) { }
+ boss_nalorakkAI(Creature* creature) : BossAI(creature, DATA_NALORAKK), _bearForm(false) { }
void Reset() override
{
_Reset();
+ _bearForm = false;
+ me->RemoveAurasDueToSpell(SPELL_SHAPE_OF_THE_BEAR);
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
_EnterCombat();
+
+ ScheduleTrollEvents();
+ events.ScheduleEvent(EVENT_SHAPESHIFT, 45000);
+ events.ScheduleEvent(EVENT_BERSERK, 600000);
}
void JustDied(Unit* /*killer*/) override
@@ -76,6 +112,30 @@ class boss_nalorakk : public CreatureScript
Talk(SAY_PLAYER_KILL);
}
+ void ScheduleTrollEvents()
+ {
+ events.ScheduleEvent(EVENT_BRUTAL_SWIPE, urand(10000, 20000));
+ events.ScheduleEvent(EVENT_MANGLE, urand(15000, 20000));
+ events.ScheduleEvent(EVENT_SURGE, urand(20000, 25000));
+ }
+
+ void ScheduleBearEvents()
+ {
+ events.ScheduleEvent(EVENT_LACERATING_SLASH, urand(10000, 15000));
+ events.ScheduleEvent(EVENT_REND_FLESH, urand(12000, 18000));
+ events.ScheduleEvent(EVENT_DEAFENING_ROAR, urand(20000, 25000));
+ }
+
+ void CancelFormEvents()
+ {
+ events.CancelEvent(EVENT_BRUTAL_SWIPE);
+ events.CancelEvent(EVENT_MANGLE);
+ events.CancelEvent(EVENT_SURGE);
+ events.CancelEvent(EVENT_LACERATING_SLASH);
+ events.CancelEvent(EVENT_REND_FLESH);
+ events.CancelEvent(EVENT_DEAFENING_ROAR);
+ }
+
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
@@ -85,19 +145,76 @@ class boss_nalorakk : public CreatureScript
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
- /*
+
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
+ case EVENT_BRUTAL_SWIPE:
+ DoCastVictim(SPELL_BRUTAL_SWIPE);
+ events.ScheduleEvent(EVENT_BRUTAL_SWIPE, urand(10000, 20000));
+ break;
+ case EVENT_MANGLE:
+ DoCastVictim(SPELL_MANGLE);
+ events.ScheduleEvent(EVENT_MANGLE, urand(15000, 20000));
+ break;
+ case EVENT_SURGE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me)))
+ {
+ Talk(SAY_SURGE);
+ Talk(EMOTE_SURGE, target);
+ DoCast(target, SPELL_SURGE);
+ }
+ events.ScheduleEvent(EVENT_SURGE, urand(20000, 25000));
+ break;
+ case EVENT_LACERATING_SLASH:
+ DoCastVictim(SPELL_LACERATING_SLASH);
+ events.ScheduleEvent(EVENT_LACERATING_SLASH, urand(10000, 15000));
+ break;
+ case EVENT_REND_FLESH:
+ DoCastVictim(SPELL_REND_FLESH);
+ events.ScheduleEvent(EVENT_REND_FLESH, urand(12000, 18000));
+ break;
+ case EVENT_DEAFENING_ROAR:
+ DoCast(me, SPELL_DEAFENING_ROAR);
+ events.ScheduleEvent(EVENT_DEAFENING_ROAR, urand(20000, 25000));
+ break;
+ case EVENT_SHAPESHIFT:
+ CancelFormEvents();
+ _bearForm = !_bearForm;
+
+ if (_bearForm)
+ {
+ Talk(SAY_BEAR);
+ Talk(EMOTE_BEAR);
+ DoCast(me, SPELL_SHAPE_OF_THE_BEAR);
+ ScheduleBearEvents();
+ events.ScheduleEvent(EVENT_SHAPESHIFT, 45000);
+ }
+ else
+ {
+ Talk(SAY_TROLL);
+ me->RemoveAurasDueToSpell(SPELL_SHAPE_OF_THE_BEAR);
+ ScheduleTrollEvents();
+ events.ScheduleEvent(EVENT_SHAPESHIFT, 45000);
+ }
+ break;
+ case EVENT_BERSERK:
+ DoCast(me, SPELL_BERSERK);
+ break;
default:
break;
}
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
}
- */
DoMeleeAttackIfReady();
}
+
+ private:
+ bool _bearForm;
};
CreatureAI* GetAI(Creature* creature) const override
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp
index c91d4d9..4d1ad5f 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp
@@ -20,10 +20,27 @@
#include "GameObject.h"
#include "InstanceScript.h"
#include "Map.h"
+#include "Player.h"
#include "ScriptedCreature.h"
#include "WorldStatePackets.h"
#include "zulaman.h"
+// Les quatre captifs liberes par la course contre la montre. Chacun apparait la
+// ou son boss vient de tomber et remet un coffre de recompense quand on lui parle.
+struct HostageInfoEntry
+{
+ uint32 Npc;
+ float X, Y, Z, O;
+};
+
+static HostageInfoEntry const HostageInfo[4] =
+{
+ { 23790, -57.0f, 1343.0f, 40.77f, 3.2f }, // Tanzar - ours (Nalorakk)
+ { 23999, 400.0f, 1414.0f, 74.36f, 3.3f }, // Harkor - aigle (Akil'zon)
+ { 24001, -35.0f, 1134.0f, 18.71f, 1.9f }, // Ashli - dragonhalc (Jan'alai)
+ { 24024, 413.0f, 1117.0f, 6.32f, 3.1f } // Kraz - lynx (Halazzi)
+};
+
class instance_zulaman : public InstanceMapScript
{
public:
@@ -139,6 +156,28 @@ class instance_zulaman : public InstanceMapScript
return ObjectGuid::Empty;
}
+ // Rien n'invoquait les captifs : la course contre la montre se deroulait
+ // jusqu'au bout sans que personne n'apparaisse, donc sans recompense.
+ void SummonHostage(uint8 num)
+ {
+ if (ZulAmanState != IN_PROGRESS)
+ return;
+
+ Map::PlayerList const& playerList = instance->GetPlayers();
+ if (playerList.isEmpty())
+ return;
+
+ if (Player* player = playerList.begin()->GetSource())
+ {
+ HostageInfoEntry const& hostageInfo = HostageInfo[num];
+ if (Creature* hostage = player->SummonCreature(hostageInfo.Npc, hostageInfo.X, hostageInfo.Y, hostageInfo.Z, hostageInfo.O, TEMPSUMMON_DEAD_DESPAWN))
+ {
+ hostage->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ hostage->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ }
+ }
+ }
+
void SetData(uint32 type, uint32 data) override
{
switch (type)
@@ -202,12 +241,21 @@ class instance_zulaman : public InstanceMapScript
switch (type)
{
case DATA_AKILZON:
+ if (state == DONE)
+ SummonHostage(1);
break;
case DATA_NALORAKK:
+ if (state == DONE)
+ SummonHostage(0);
break;
case DATA_JANALAI:
+ if (state == DONE)
+ SummonHostage(2);
break;
case DATA_HALAZZI:
+ if (state == DONE)
+ SummonHostage(3);
+ break;
case DATA_HEXLORD:
case DATA_DAAKARA:
break;
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp
index fca2d98..a7a192c 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp
@@ -250,8 +250,73 @@ class spell_banging_the_gong : public SpellScriptLoader
}
};
+// Tanzar, Harkor, Ashli et Kraz : les captifs liberes par la course contre la
+// montre. Ils sont invoques par l'instance a la mort de leur boss ; leur seule
+// raison d'etre est de remettre le coffre de recompense quand on leur parle.
+// Rien ne les scriptait, donc meme invoques ils n'auraient rien donne.
+class npc_zulaman_hostage : public CreatureScript
+{
+public:
+ npc_zulaman_hostage() : CreatureScript("npc_zulaman_hostage") { }
+
+ enum Hostages
+ {
+ NPC_TANZAR = 23790,
+ NPC_HARKOR = 23999,
+ NPC_ASHLI = 24001,
+ NPC_KRAZ = 24024,
+
+ GO_HAZLEKS_TRUNK = 186648, // Tanzar
+ GO_BAKKALZUS_SATCHEL = 187021, // Harkor
+ GO_KASHAS_BAG = 186672, // Ashli
+ GO_NORKANIS_PACKAGE = 186667, // Kraz
+
+ ACTION_FREE_HOSTAGE = GOSSIP_ACTION_INFO_DEF + 1
+ };
+
+ static uint32 ChestForHostage(uint32 entry)
+ {
+ switch (entry)
+ {
+ case NPC_TANZAR: return GO_HAZLEKS_TRUNK;
+ case NPC_HARKOR: return GO_BAKKALZUS_SATCHEL;
+ case NPC_ASHLI: return GO_KASHAS_BAG;
+ case NPC_KRAZ: return GO_NORKANIS_PACKAGE;
+ default: return 0;
+ }
+ }
+
+ bool OnGossipHello(Player* player, Creature* creature) override
+ {
+ AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Vous etes libre ! Partez d'ici !", GOSSIP_SENDER_MAIN, ACTION_FREE_HOSTAGE);
+ SendGossipMenuFor(player, player->GetGossipTextId(creature), creature->GetGUID());
+ return true;
+ }
+
+ bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
+ {
+ CloseGossipMenuFor(player);
+
+ if (action != ACTION_FREE_HOSTAGE)
+ return true;
+
+ // Un seul coffre par captif, quel que soit le nombre de joueurs qui lui parlent.
+ if (!creature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP))
+ return true;
+
+ creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+
+ if (uint32 chest = ChestForHostage(creature->GetEntry()))
+ creature->SummonGameObject(chest, creature->GetPositionX() - 2.0f, creature->GetPositionY(),
+ creature->GetPositionZ(), 0.0f, QuaternionData(), WEEK);
+
+ return true;
+ }
+};
+
void AddSC_zulaman()
{
+ new npc_zulaman_hostage();
new npc_voljin_zulaman();
new spell_banging_the_gong();
}