[svn] * Proper SVN structure

--HG--
branch : trunk
This commit is contained in:
Neo2003
2008-10-02 16:23:55 -05:00
commit 9b1c0e006f
2564 changed files with 621124 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
# Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
#
# 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 Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# interface folder is disabled for now
if USE_TSCRIPTS
SUBDIRS = scripts
else
SUBDIRS = interface
endif
+52
View File
@@ -0,0 +1,52 @@
# Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
#
# 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 Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## Process this file with automake to produce Makefile.in
## Sub-directories to parse
## Build MaNGOS script library as shared library.
# libmangosscript shared library will later be reused by world server daemon.
lib_LTLIBRARIES = libtrinityscript.la
libtrinityscript_la_CPPFLAGS = \
$(MYSQL_INCLUDES) \
$(POSTGRE_INCLUDES) \
-I$(top_srcdir)/dep/include \
-I$(top_srcdir)/src/shared \
-I$(top_srcdir)/src/framework \
-I$(top_srcdir)/src/game
libtrinityscript_la_SOURCES = \
ScriptMgr.cpp \
ScriptMgr.h \
config.h \
system.cpp \
Scripts/sc_default.cpp \
Scripts/sc_defines.cpp \
Scripts/sc_defines.h
## libtool settings
# API versioning
libtrinityscript_la_LIBFLAGS = -version-info 0:0:1
libtrinityscript_la_LIBADD = $(MYSQL_LIBS) $(POSTGRE_LIBS)
## Additional files to include when running 'make dist'
# Scripts defaults.
EXTRA_DIST = \
Scripts/sc_default.cpp \
Scripts/sc_defines.cpp \
Scripts/sc_defines.h
+32
View File
@@ -0,0 +1,32 @@
** HOW TO SCRIPT IN C++ **
1 - create a file myscript.cpp in scripts folder.
2 - copy the content of script_default.cpp, it as the structure on how the scripting fuctions are organized.
dont forget to change the name of fuctions, like GossipHello_default to GossipHello_myscript.
3 - in fuction AddSC_default change to AddSC_myscript.
4 - newscript->Name="default"; change the string to "myscript" this name is the one to be called from the db
5 - dont forget to change the name in here to newscript->pGossipHello = &GossipHello_default; this is where the scripted fuctions are stored.
6 - and last thing is in ScriptMgr.cpp
add your AddSC_myscript in here
// -- Scripts to be added --
extern void AddSC_default();
// -------------------
and here
// -- Inicialize the Scripts to be Added --
AddSC_default();
// ----------------------------------------
now start using the player fuctions to script ;)
see the sc_defines.h for some fuctions to use.
hope it helps, any question use our forum.
copy libscript.so and libscript.a to your server/lib path
made by: mmcs.
+328
View File
@@ -0,0 +1,328 @@
/*
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
*
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "ScriptMgr.h"
#include "../../game/GossipDef.h"
#include "../../game/GameObject.h"
#include "../../game/Player.h"
#include "../../game/Map.h"
#include "../../game/ObjectMgr.h"
//uint8 loglevel = 0;
int nrscripts;
Script *m_scripts[MAX_SCRIPTS];
InstanceDataScript* m_instance_scripts[MAX_INSTANCE_SCRIPTS];
int num_inst_scripts;
// -- Scripts to be added --
extern void AddSC_default();
// -------------------
MANGOS_DLL_EXPORT
void ScriptsFree()
{ // Free resources before library unload
for(int i=0;i<nrscripts;i++)
delete m_scripts[i];
for(int i=0;i<num_inst_scripts;i++)
delete m_instance_scripts[i];
nrscripts = 0;
num_inst_scripts = 0;
}
MANGOS_DLL_EXPORT
void ScriptsInit()
{
nrscripts = 0;
num_inst_scripts = 0;
for(int i=0;i<MAX_SCRIPTS;i++)
{
m_scripts[i]=NULL;
m_instance_scripts[i]=NULL;
}
// -- Inicialize the Scripts to be Added --
AddSC_default();
// ----------------------------------------
}
Script* GetScriptByName(std::string Name)
{
if(Name.empty())
return NULL;
for(int i=0;i<MAX_SCRIPTS;i++)
{
if( m_scripts[i] && m_scripts[i]->Name == Name )
return m_scripts[i];
}
return NULL;
}
MANGOS_DLL_EXPORT
bool GossipHello ( Player * player, Creature *_Creature )
{
Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
if(!tmpscript || !tmpscript->pGossipHello) return false;
player->PlayerTalkClass->ClearMenus();
return tmpscript->pGossipHello(player,_Creature);
}
MANGOS_DLL_EXPORT
bool GossipSelect( Player *player, Creature *_Creature,uint32 sender, uint32 action )
{
debug_log("DEBUG: Gossip selection, sender: %d, action: %d",sender, action);
Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
if(!tmpscript || !tmpscript->pGossipSelect) return false;
player->PlayerTalkClass->ClearMenus();
return tmpscript->pGossipSelect(player,_Creature,sender,action);
}
MANGOS_DLL_EXPORT
bool GossipSelectWithCode( Player *player, Creature *_Creature, uint32 sender, uint32 action, const char* sCode )
{
debug_log("DEBUG: Gossip selection, sender: %d, action: %d",sender, action);
Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
if(!tmpscript || !tmpscript->pGossipSelectWithCode) return false;
player->PlayerTalkClass->ClearMenus();
return tmpscript->pGossipSelectWithCode(player,_Creature,sender,action,sCode);
}
MANGOS_DLL_EXPORT
bool QuestAccept( Player *player, Creature *_Creature, Quest *_Quest )
{
Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
if(!tmpscript || !tmpscript->pQuestAccept) return false;
player->PlayerTalkClass->ClearMenus();
return tmpscript->pQuestAccept(player,_Creature,_Quest);
}
MANGOS_DLL_EXPORT
bool QuestSelect( Player *player, Creature *_Creature, Quest *_Quest )
{
Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
if(!tmpscript || !tmpscript->pQuestSelect) return false;
player->PlayerTalkClass->ClearMenus();
return tmpscript->pQuestSelect(player,_Creature,_Quest);
}
MANGOS_DLL_EXPORT
bool QuestComplete( Player *player, Creature *_Creature, Quest *_Quest )
{
Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
if(!tmpscript || !tmpscript->pQuestComplete) return false;
player->PlayerTalkClass->ClearMenus();
return tmpscript->pQuestComplete(player,_Creature,_Quest);
}
MANGOS_DLL_EXPORT
bool ChooseReward( Player *player, Creature *_Creature, Quest *_Quest, uint32 opt )
{
Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
if(!tmpscript || !tmpscript->pChooseReward) return false;
player->PlayerTalkClass->ClearMenus();
return tmpscript->pChooseReward(player,_Creature,_Quest,opt);
}
MANGOS_DLL_EXPORT
uint32 NPCDialogStatus( Player *player, Creature *_Creature )
{
Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
if(!tmpscript || !tmpscript->pNPCDialogStatus) return 100;
player->PlayerTalkClass->ClearMenus();
return tmpscript->pNPCDialogStatus(player,_Creature);
}
MANGOS_DLL_EXPORT
uint32 GODialogStatus( Player *player, GameObject *_GO )
{
Script *tmpscript = NULL;
tmpscript = GetScriptByName(_GO->GetGOInfo()->ScriptName);
if(!tmpscript || !tmpscript->pGODialogStatus) return 100;
player->PlayerTalkClass->ClearMenus();
return tmpscript->pGODialogStatus(player,_GO);
}
MANGOS_DLL_EXPORT
bool ItemHello( Player *player, Item *_Item, Quest *_Quest )
{
Script *tmpscript = NULL;
tmpscript = GetScriptByName(_Item->GetProto()->ScriptName);
if(!tmpscript || !tmpscript->pItemHello) return false;
player->PlayerTalkClass->ClearMenus();
return tmpscript->pItemHello(player,_Item,_Quest);
}
MANGOS_DLL_EXPORT
bool ItemQuestAccept( Player *player, Item *_Item, Quest *_Quest )
{
Script *tmpscript = NULL;
tmpscript = GetScriptByName(_Item->GetProto()->ScriptName);
if(!tmpscript || !tmpscript->pItemQuestAccept) return false;
player->PlayerTalkClass->ClearMenus();
return tmpscript->pItemQuestAccept(player,_Item,_Quest);
}
MANGOS_DLL_EXPORT
bool GOHello( Player *player, GameObject *_GO )
{
Script *tmpscript = NULL;
tmpscript = GetScriptByName(_GO->GetGOInfo()->ScriptName);
if(!tmpscript || !tmpscript->pGOHello) return false;
player->PlayerTalkClass->ClearMenus();
return tmpscript->pGOHello(player,_GO);
}
MANGOS_DLL_EXPORT
bool GOQuestAccept( Player *player, GameObject *_GO, Quest *_Quest )
{
Script *tmpscript = NULL;
tmpscript = GetScriptByName(_GO->GetGOInfo()->ScriptName);
if(!tmpscript || !tmpscript->pGOQuestAccept) return false;
player->PlayerTalkClass->ClearMenus();
return tmpscript->pGOQuestAccept(player,_GO,_Quest);
}
MANGOS_DLL_EXPORT
bool GOChooseReward( Player *player, GameObject *_GO, Quest *_Quest, uint32 opt )
{
Script *tmpscript = NULL;
tmpscript = GetScriptByName(_GO->GetGOInfo()->ScriptName);
if(!tmpscript || !tmpscript->pGOChooseReward) return false;
player->PlayerTalkClass->ClearMenus();
return tmpscript->pGOChooseReward(player,_GO,_Quest,opt);
}
MANGOS_DLL_EXPORT
bool AreaTrigger ( Player *player, AreaTriggerEntry* atEntry )
{
Script *tmpscript = NULL;
tmpscript = GetScriptByName(GetAreaTriggerScriptNameById(atEntry->id));
if(!tmpscript || !tmpscript->pAreaTrigger) return false;
return tmpscript->pAreaTrigger(player, atEntry);
}
MANGOS_DLL_EXPORT
bool ReceiveEmote ( Player *player, Creature *_Creature, uint32 emote )
{
Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
if(!tmpscript || !tmpscript->pReceiveEmote) return false;
return tmpscript->pReceiveEmote(player,_Creature, emote);
}
MANGOS_DLL_EXPORT
bool ItemUse( Player *player, Item* _Item, SpellCastTargets const& targets)
{
Script *tmpscript = NULL;
tmpscript = GetScriptByName(_Item->GetProto()->ScriptName);
if(!tmpscript || !tmpscript->pItemUse) return false;
return tmpscript->pItemUse(player,_Item,targets);
}
MANGOS_DLL_EXPORT
CreatureAI* GetAI(Creature *_Creature )
{
Script *tmpscript = GetScriptByName(_Creature->GetScriptName());
if(!tmpscript || !tmpscript->GetAI) return NULL;
return tmpscript->GetAI(_Creature);
}
MANGOS_DLL_EXPORT
InstanceData* CreateInstanceData(Map *map)
{
if(!map->IsDungeon()) return NULL;
std::string name = ((InstanceMap*)map)->GetScript();
if(!name.empty())
for(int i=0;i<num_inst_scripts;i++)
if(m_instance_scripts[i] && m_instance_scripts[i]->name == name)
return m_instance_scripts[i]->GetInstanceData(map);
return NULL;
}
void ScriptedAI::UpdateAI(const uint32)
{
//Check if we have a current target
if( m_creature->isAlive() && m_creature->SelectHostilTarget() && m_creature->getVictim())
{
//If we are within range melee the target
if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
{
if( m_creature->isAttackReady() )
{
m_creature->AttackerStateUpdate(m_creature->getVictim());
m_creature->resetAttackTimer();
}
}
}
}
void ScriptedAI::EnterEvadeMode()
{
if( m_creature->isAlive() )
DoGoHome();
}
void ScriptedAI::DoStartAttack(Unit* victim)
{
if( m_creature->Attack(victim, true) )
m_creature->GetMotionMaster()->MoveChase(victim);
}
void ScriptedAI::DoStopAttack()
{
if( m_creature->getVictim() != NULL )
{
m_creature->AttackStop();
}
}
void ScriptedAI::DoGoHome()
{
if( !m_creature->getVictim() && m_creature->isAlive() )
m_creature->GetMotionMaster()->MoveTargetedHome();
}
+159
View File
@@ -0,0 +1,159 @@
/*
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
*
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SCRIPTMGR_H
#define SCRIPTMGR_H
//Only required includes
#include "../../game/CreatureAI.h"
#include "../../game/Creature.h"
#include "../../game/InstanceData.h"
class Player;
class Creature;
class Quest;
class Item;
class GameObject;
class SpellCastTargets;
class Map;
#define MAX_SCRIPTS 1000
#define MAX_INSTANCE_SCRIPTS 1000
struct Script
{
Script() :
pGossipHello(NULL), pQuestAccept(NULL), pGossipSelect(NULL), pGossipSelectWithCode(NULL),
pQuestSelect(NULL), pQuestComplete(NULL), pNPCDialogStatus(NULL), pGODialogStatus(NULL), pChooseReward(NULL),
pItemHello(NULL), pGOHello(NULL), pAreaTrigger(NULL), pItemQuestAccept(NULL), pGOQuestAccept(NULL),
pGOChooseReward(NULL), pReceiveEmote(NULL), pItemUse(NULL), GetAI(NULL)
{}
std::string Name;
// -- Quest/gossip Methods to be scripted --
bool (*pGossipHello )(Player *player, Creature *_Creature);
bool (*pQuestAccept )(Player *player, Creature *_Creature, Quest const*_Quest );
bool (*pGossipSelect )(Player *player, Creature *_Creature, uint32 sender, uint32 action );
bool (*pGossipSelectWithCode)(Player *player, Creature *_Creature, uint32 sender, uint32 action, const char* sCode );
bool (*pQuestSelect )(Player *player, Creature *_Creature, Quest const*_Quest );
bool (*pQuestComplete )(Player *player, Creature *_Creature, Quest const*_Quest );
uint32 (*pNPCDialogStatus )(Player *player, Creature *_Creature );
uint32 (*pGODialogStatus )(Player *player, GameObject * _GO );
bool (*pChooseReward )(Player *player, Creature *_Creature, Quest const*_Quest, uint32 opt );
bool (*pItemHello )(Player *player, Item *_Item, Quest const*_Quest );
bool (*pGOHello )(Player *player, GameObject *_GO );
bool (*pAreaTrigger )(Player *player, AreaTriggerEntry* at);
bool (*pItemQuestAccept )(Player *player, Item *_Item, Quest const*_Quest );
bool (*pGOQuestAccept )(Player *player, GameObject *_GO, Quest const*_Quest );
bool (*pGOChooseReward )(Player *player, GameObject *_GO, Quest const*_Quest, uint32 opt );
bool (*pReceiveEmote )(Player *player, Creature *_Creature, uint32 emote );
bool (*pItemUse )(Player *player, Item* _Item, SpellCastTargets const& targets);
CreatureAI* (*GetAI)(Creature *_Creature);
// -----------------------------------------
};
class InstanceDataScript
{
public:
InstanceDataScript() : GetInstanceData(NULL) {};
std::string name;
InstanceData* (*GetInstanceData)(Map *_Map);
};
extern int nrscripts;
extern Script *m_scripts[MAX_SCRIPTS];
extern InstanceDataScript *m_instance_scripts[MAX_INSTANCE_SCRIPTS];
extern int num_inst_scripts;
#define VISIBLE_RANGE (50.0f)
struct MANGOS_DLL_DECL ScriptedAI : public CreatureAI
{
ScriptedAI(Creature* creature) : m_creature(creature) {}
~ScriptedAI() {}
// Called if IsVisible(Unit *who) is true at each *who move
void MoveInLineOfSight(Unit *) {}
// Called at each attack of m_creature by any victim
void AttackStart(Unit *) {}
// Called at stopping attack by any attacker
void EnterEvadeMode();
// Called at any heal cast/item used (call non implemented)
void HealBy(Unit* /*healer*/, uint32 /*amount_healed*/) {}
// Called at any Damage to any victim (before damage apply)
void DamageDeal(Unit* /*done_to*/, uint32& /*damage*/) {}
// Called at any Damage from any attacker (before damage apply)
void DamageTaken(Unit* /*done_by*/, uint32& /*damage*/) {}
// Is unit visible for MoveInLineOfSight
bool IsVisible(Unit* who) const
{
return !who->HasStealthAura() && m_creature->GetDistance(who) <= VISIBLE_RANGE;
}
// Called at World update tick
void UpdateAI(const uint32);
// Called when the creature is killed
void JustDied(Unit *){}
// Called when the creature kills a unit
void KilledUnit(Unit *){}
// Called when hit by a spell
void SpellHit(Unit *, const SpellEntry*){}
Creature* m_creature;
//= Some useful helpers =========================
// Start attack of victim and go to him
void DoStartAttack(Unit* victim);
// Stop attack of current victim
void DoStopAttack();
// Cast spell
void DoCast(Unit* victim, uint32 spelId)
{
m_creature->CastSpell(victim,spelId,true);
}
void DoCastSpell(Unit* who,SpellEntry *spellInfo)
{
m_creature->CastSpell(who,spellInfo,true);
}
void DoSay(char const* text, uint32 language)
{
m_creature->Say(text,language,0);
}
void DoGoHome();
};
#endif
@@ -0,0 +1,119 @@
/*
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
*
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sc_defines.h"
bool GossipHello_default(Player* /*player*/, Creature* /*_Creature*/)
{
return false;
}
bool GossipSelect_default(Player* /*player*/, Creature* /*_Creature*/, uint32 /*sender*/, uint32 /*action*/ )
{
return false;
}
bool GossipSelectWithCode_default( Player* /*player*/, Creature* /*_Creature*/, uint32 /*sender*/, uint32 /*action*/, const char* /*sCode*/ )
{
return false;
}
bool QuestAccept_default(Player* /*player*/, Creature* /*_Creature*/, Quest const* /*_Quest*/ )
{
return false;
}
bool QuestSelect_default(Player* /*player*/, Creature* /*_Creature*/, Quest const* /*_Quest*/ )
{
return false;
}
bool QuestComplete_default(Player* /*player*/, Creature* /*_Creature*/, Quest const* /*_Quest*/ )
{
return false;
}
bool ChooseReward_default(Player* /*player*/, Creature* /*_Creature*/, Quest const* /*_Quest*/, uint32 /*opt*/ )
{
return false;
}
uint32 NPCDialogStatus_default(Player* /*player*/, Creature* /*_Creature*/ )
{
return 128;
}
uint32 GODialogStatus_default(Player* /*player*/, GameObject* /*_Creature*/ )
{
return 128;
}
bool ItemHello_default(Player* /*player*/, Item* /*_Item*/, Quest const* /*_Quest*/ )
{
return false;
}
bool ItemQuestAccept_default(Player* /*player*/, Item* /*_Item*/, Quest const* /*_Quest*/ )
{
return false;
}
bool GOHello_default(Player* /*player*/, GameObject* /*_GO*/ )
{
return false;
}
bool GOQuestAccept_default(Player* /*player*/, GameObject* /*_GO*/, Quest const* /*_Quest*/ )
{
return false;
}
bool GOChooseReward_default(Player* /*player*/, GameObject* /*_GO*/, Quest const* /*_Quest*/, uint32 /*opt*/ )
{
return false;
}
bool AreaTrigger_default(Player* /*player*/, AreaTriggerEntry* /*atEntry*/ )
{
return false;
}
void AddSC_default()
{
Script *newscript;
newscript = new Script;
newscript->Name="default";
newscript->pGossipHello = &GossipHello_default;
newscript->pQuestAccept = &QuestAccept_default;
newscript->pGossipSelect = &GossipSelect_default;
newscript->pGossipSelectWithCode = &GossipSelectWithCode_default;
newscript->pQuestSelect = &QuestSelect_default;
newscript->pQuestComplete = &QuestComplete_default;
newscript->pNPCDialogStatus = &NPCDialogStatus_default;
newscript->pGODialogStatus = &GODialogStatus_default;
newscript->pChooseReward = &ChooseReward_default;
newscript->pItemHello = &ItemHello_default;
newscript->pGOHello = &GOHello_default;
newscript->pAreaTrigger = &AreaTrigger_default;
newscript->pItemQuestAccept = &ItemQuestAccept_default;
newscript->pGOQuestAccept = &GOQuestAccept_default;
newscript->pGOChooseReward = &GOChooseReward_default;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,152 @@
/*
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
*
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sc_defines.h"
#include "../../game/Player.h"
uint32 GetSkillLevel(Player *player,uint32 trskill)
{
// Returns the level of some tradetrskill known by player
// Need to add missing spells
uint32 spell_apprentice = 0;
uint32 spell_journeyman = 0;
uint32 spell_expert = 0;
uint32 spell_artisan = 0;
uint32 spell_master = 0;
switch(trskill)
{
case TRADESKILL_ALCHEMY:
spell_apprentice = 2259;
spell_journeyman = 3101;
spell_expert = 3464;
spell_artisan = 11611;
spell_master = 28596; // teached by 28597
break;
case TRADESKILL_BLACKSMITHING:
spell_apprentice = 2018;
spell_journeyman = 3100;
spell_expert = 8768;
spell_artisan = 11454;
spell_master = 29844; // teached by 29845
break;
case TRADESKILL_COOKING:
spell_apprentice = 2550;
spell_journeyman = 3102;
spell_expert = 3413;
spell_artisan = 18260;
spell_master = 33359; // teached by 33361
break;
case TRADESKILL_ENCHANTING:
spell_apprentice = 7411;
spell_journeyman = 7412;
spell_expert = 7413;
spell_artisan = 13920;
spell_master = 28029; // teached by 28030
break;
case TRADESKILL_ENGINEERING:
spell_apprentice = 4036;
spell_journeyman = 4037;
spell_expert = 4038;
spell_artisan = 12656;
spell_master = 30350; // teached by 30351
break;
case TRADESKILL_FIRSTAID:
spell_apprentice = 3273;
spell_journeyman = 3274;
spell_expert = 7924;
spell_artisan = 10846;
spell_master = 27028; // teached by 27029
break;
case TRADESKILL_HERBALISM:
spell_apprentice = 2372;
spell_journeyman = 2373;
spell_expert = 3571;
spell_artisan = 11994;
spell_master = 0;
break;
case TRADESKILL_LEATHERWORKING:
spell_apprentice = 2108;
spell_journeyman = 3104;
spell_expert = 20649;
spell_artisan = 10662;
spell_master = 32549; // teached by 32550
break;
case TRADESKILL_POISONS:
spell_apprentice = 0;
spell_journeyman = 0;
spell_expert = 0;
spell_artisan = 0;
spell_master = 0;
break;
case TRADESKILL_TAILORING:
spell_apprentice = 3908;
spell_journeyman = 3909;
spell_expert = 3910;
spell_artisan = 12180;
spell_master = 26790; // teached by 26791
break;
case TRADESKILL_MINING:
spell_apprentice = 2581;
spell_journeyman = 2582;
spell_expert = 3568;
spell_artisan = 10249;
spell_master = 29354; // teached by 29355
break;
case TRADESKILL_FISHING:
spell_apprentice = 7733;
spell_journeyman = 7734;
spell_expert = 7736;
spell_artisan = 18249;
spell_master = 33098; // teached by 33100
break;
case TRADESKILL_SKINNING:
spell_apprentice = 8615;
spell_journeyman = 8619;
spell_expert = 8620;
spell_artisan = 10769;
spell_master = 32679; // teached by 32678
break;
case TRADESKILL_JEWELCRAFTING:
spell_apprentice = 25229; // teached by 25245
spell_journeyman = 25230; // teached by 25246
spell_expert = 28894; // teached by 28896
spell_artisan = 28895; // teached by 28899
spell_master = 28897; // teached by 28901
break;
}
if (player->HasSpell(spell_master))
return TRADESKILL_LEVEL_MASTER;
if (player->HasSpell(spell_artisan))
return TRADESKILL_LEVEL_ARTISAN;
if (player->HasSpell(spell_expert))
return TRADESKILL_LEVEL_EXPERT;
if (player->HasSpell(spell_journeyman))
return TRADESKILL_LEVEL_JOURNEYMAN;
if (player->HasSpell(spell_apprentice))
return TRADESKILL_LEVEL_APPRENTICE;
return TRADESKILL_LEVEL_NONE;
}
@@ -0,0 +1,96 @@
/*
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
*
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SC_DEFINES_H
#define SC_DEFINES_H
#include "../ScriptMgr.h"
// Skill defines
#define TRADESKILL_ALCHEMY 1
#define TRADESKILL_BLACKSMITHING 2
#define TRADESKILL_COOKING 3
#define TRADESKILL_ENCHANTING 4
#define TRADESKILL_ENGINEERING 5
#define TRADESKILL_FIRSTAID 6
#define TRADESKILL_HERBALISM 7
#define TRADESKILL_LEATHERWORKING 8
#define TRADESKILL_POISONS 9
#define TRADESKILL_TAILORING 10
#define TRADESKILL_MINING 11
#define TRADESKILL_FISHING 12
#define TRADESKILL_SKINNING 13
#define TRADESKILL_JEWELCRAFTING 14
#define TRADESKILL_LEVEL_NONE 0
#define TRADESKILL_LEVEL_APPRENTICE 1
#define TRADESKILL_LEVEL_JOURNEYMAN 2
#define TRADESKILL_LEVEL_EXPERT 3
#define TRADESKILL_LEVEL_ARTISAN 4
#define TRADESKILL_LEVEL_MASTER 5
// Gossip defines
#define GOSSIP_ACTION_TRADE 1
#define GOSSIP_ACTION_TRAIN 2
#define GOSSIP_ACTION_TAXI 3
#define GOSSIP_ACTION_GUILD 4
#define GOSSIP_ACTION_BATTLE 5
#define GOSSIP_ACTION_BANK 6
#define GOSSIP_ACTION_INN 7
#define GOSSIP_ACTION_HEAL 8
#define GOSSIP_ACTION_TABARD 9
#define GOSSIP_ACTION_AUCTION 10
#define GOSSIP_ACTION_INN_INFO 11
#define GOSSIP_ACTION_UNLEARN 12
#define GOSSIP_ACTION_INFO_DEF 1000
#define GOSSIP_SENDER_MAIN 1
#define GOSSIP_SENDER_INN_INFO 2
#define GOSSIP_SENDER_INFO 3
#define GOSSIP_SENDER_SEC_PROFTRAIN 4
#define GOSSIP_SENDER_SEC_CLASSTRAIN 5
#define GOSSIP_SENDER_SEC_BATTLEINFO 6
#define DEFAULT_GOSSIP_MESSAGE 0xffffff
extern uint32 GetSkillLevel(Player *player,uint32 skill);
// Defined functions to use with player.
#define ADD_GOSSIP_ITEM(a,b,c,d,e,f) PlayerTalkClass->GetGossipMenu()->AddMenuItem(a,b,c,d,e,f)
#define SEND_GOSSIP_MENU(a,b) PlayerTalkClass->SendGossipMenu(a,b)
#define SEND_POI(a,b,c,d,e,f) PlayerTalkClass->SendPointOfInterest(a,b,c,d,e,f)
#define CLOSE_GOSSIP_MENU() PlayerTalkClass->CloseGossip();
#define QUEST_DIALOG_STATUS(a,b,c) GetSession()->getDialogStatus(a,b,c)
#define SEND_QUEST_DETAILS(a,b,c) PlayerTalkClass->SendQuestDetails(a,b,c)
#define SEND_REQUESTEDITEMS(a,b,c,d) PlayerTalkClass->SendRequestedItems(a,b,c,d)
#define SEND_VENDORLIST(a) GetSession()->SendListInventory(a)
#define SEND_TRAINERLIST(a) GetSession()->SendTrainerList(a)
#define SEND_BANKERLIST(a) GetSession()->SendShowBank(a)
#define SEND_TABARDLIST(a) GetSession()->SendTabardVendorActivate(a)
#define SEND_AUCTIONLIST(a) GetSession()->SendAuctionHello(a)
#define SEND_TAXILIST(a) GetSession()->SendTaxiStatus(a)
#define SEND_SPRESURRECT() GetSession()->SendSpiritResurrect()
#define GET_HONORRANK() GetHonorRank()
// -----------------------------------
#endif
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
*
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef CONFIG_H
#define CONFIG_H
#endif
//#define WIN32
#ifdef WIN32
//#include <windows.h>
#define MANGOS_DLL_EXPORT extern "C" __declspec(dllexport)
#elif defined( __GNUC__ )
#define MANGOS_DLL_EXPORT extern "C"
#else
#define MANGOS_DLL_EXPORT extern "C" export
#endif
+25
View File
@@ -0,0 +1,25 @@
/*
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
*
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef WIN32
#include <windows.h>
BOOL APIENTRY DllMain( HANDLE /*hModule*/, DWORD /*ul_reason_for_call*/, LPVOID /*lpReserved*/)
{
return true;
}
#endif
+32
View File
@@ -0,0 +1,32 @@
--- How to install ScriptDev2 ---
1) Download MaNGOS
2) Create a new folder under "src\bindings\" within the MaNGOS source called "ScriptDev2"
3) Checkout the ScriptDev2 trunk from "https://scriptdev2.svn.sourceforge.net/svnroot/scriptdev2"
4a) On Win32:
- Compile MaNGOS
- Compile ScriptDev2 using the ScriptVC70, ScriptVC80, or ScriptVC90 Solution within the ScriptDev2 folder (this will overwrite the Mangoscript dll in the output directory)
4b) On Linux:
- Apply MaNGOS-rXXXX-ScriptDev2.patch, where XXXX is the highest version to that of your MaNGOS revision, to Mangos Source
- Compile MaNGOS (ScriptDev2 will automatically be built when compiling Mangos from here on)
5) Create the default ScriptDev2 database using "sql\created_database.sql", then execute "sql\scriptdev2_structure.sql" on that database.
6) Execute the included "sql\scripts_mangosd_full.sql" and "sql\scripts_mangosd_additional_req.sql" on your MaNGOS database
7) Place the included "scriptdev2.conf" file within the directory containing your "mangosd.conf" and "realmd.conf" files. You may need to change this file to match the database you created and any custom settings you wish to use (such as a different locale).
8) Run mangosd from your output directory
To update ScriptDev2:
All you have to do is open src\bindings\ and right click on the ScriptDev2 folder and click "Update" and then follow steps 4, 6, 7, and 8 again. You must still compile MaNGOS before ScriptDev2 when on the Windows platform.
To update your Database with new Scriptdev2 SQL changes you can either:
a) apply only the changes that were made during that revision by looking in the sql\update folder or (files named rXXX_scriptdev2.sql should be executed on the scriptdev2 db while rXXX_mangos.sql should be executed on your mangos db)
b) reapply "mangos_full_scripts.sql" to your MaNGOS database along with executing "mangos_additional_req.sql" on your MaNGOS database.
You can view the ScriptDev2 Change Log at:
[url=http://scriptdev2.svn.sourceforge.net/viewvc/scriptdev2/?view=log]http://scriptdev2.svn.sourceforge.net/viewvc/scriptdev2/?view=log[/url]
+280
View File
@@ -0,0 +1,280 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
+421
View File
@@ -0,0 +1,421 @@
# Copyright © 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
#
# 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 Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## Process this file with automake to produce Makefile.in
## Sub-directories to parse
## SUBDIRS = sql
# build shared library
lib_LTLIBRARIES = libtrinityscript.la
libtrinityscript_la_CPPFLAGS = \
$(MYSQL_INCLUDES) \
$(POSTGRE_INCLUDES) \
-I$(top_srcdir)/dep/include \
-I$(top_srcdir)/src/shared \
-I$(top_srcdir)/src/framework \
-I$(top_srcdir)/src/game \
-I$(srcdir)/include \
-D_TRINITY_SCRIPT_CONFIG='"$(sysconfdir)/trinityscript.conf"'
libtrinityscript_la_SOURCES = \
ScriptMgr.cpp \
ScriptMgr.h \
include/precompiled.cpp \
include/precompiled.h \
include/sc_creature.cpp \
include/sc_creature.h \
include/sc_gossip.h \
include/sc_grid_searchers.h \
include/sc_instance.h \
include/sc_item.h \
scripts/areatrigger/areatrigger_scripts.cpp \
scripts/boss/boss_emeriss.cpp \
scripts/boss/boss_lethon.cpp \
scripts/boss/boss_taerar.cpp \
scripts/boss/boss_ysondre.cpp \
scripts/creature/mob_event_ai.cpp \
scripts/creature/mob_event_ai.h \
scripts/creature/mob_generic_creature.cpp \
scripts/creature/simple_ai.cpp \
scripts/creature/simple_ai.h \
scripts/custom/custom_example.cpp \
scripts/custom/custom_gossip_codebox.cpp \
scripts/custom/test.cpp \
scripts/go/go_scripts.cpp \
scripts/guard/guard_ai.cpp \
scripts/guard/guard_ai.h \
scripts/guard/guards.cpp \
scripts/item/item_scripts.cpp \
scripts/item/item_test.cpp \
scripts/npc/npc_escortAI.cpp \
scripts/npc/npc_escortAI.h \
scripts/npc/npc_innkeeper.cpp \
scripts/npc/npc_professions.cpp \
scripts/npc/npcs_special.cpp \
scripts/zone/alterac_mountains/alterac_mountains.cpp \
scripts/zone/aunchindoun/auchenai_crypts/boss_exarch_maladaar.cpp \
scripts/zone/aunchindoun/mana_tombs/boss_nexusprince_shaffar.cpp \
scripts/zone/aunchindoun/mana_tombs/boss_pandemonius.cpp \
scripts/zone/aunchindoun/sethekk_halls/boss_darkweaver_syth.cpp \
scripts/zone/aunchindoun/sethekk_halls/boss_tailonking_ikiss.cpp \
scripts/zone/aunchindoun/sethekk_halls/def_sethekk_halls.h \
scripts/zone/aunchindoun/sethekk_halls/instance_sethekk_halls.cpp \
scripts/zone/aunchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp \
scripts/zone/aunchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp \
scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp \
scripts/zone/aunchindoun/shadow_labyrinth/boss_murmur.cpp \
scripts/zone/aunchindoun/shadow_labyrinth/def_shadow_labyrinth.h \
scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp \
scripts/zone/azshara/azshara.cpp \
scripts/zone/azshara/boss_azuregos.cpp \
scripts/zone/azuremyst_isle/azuremyst_isle.cpp \
scripts/zone/barrens/the_barrens.cpp \
scripts/zone/black_temple/black_temple.cpp \
scripts/zone/black_temple/boss_bloodboil.cpp \
scripts/zone/black_temple/boss_illidan.cpp \
scripts/zone/black_temple/boss_mother_shahraz.cpp \
scripts/zone/black_temple/boss_reliquary_of_souls.cpp \
scripts/zone/black_temple/boss_shade_of_akama.cpp \
scripts/zone/black_temple/boss_supremus.cpp \
scripts/zone/black_temple/boss_teron_gorefiend.cpp \
scripts/zone/black_temple/boss_warlord_najentus.cpp \
scripts/zone/black_temple/def_black_temple.h \
scripts/zone/black_temple/illidari_council.cpp \
scripts/zone/black_temple/instance_black_temple.cpp \
scripts/zone/blackrock_depths/blackrock_depths.cpp \
scripts/zone/blackrock_depths/boss_ambassador_flamelash.cpp \
scripts/zone/blackrock_depths/boss_angerrel.cpp \
scripts/zone/blackrock_depths/boss_anubshiah.cpp \
scripts/zone/blackrock_depths/boss_doomrel.cpp \
scripts/zone/blackrock_depths/boss_doperel.cpp \
scripts/zone/blackrock_depths/boss_emperor_dagran_thaurissan.cpp \
scripts/zone/blackrock_depths/boss_general_angerforge.cpp \
scripts/zone/blackrock_depths/boss_gloomrel.cpp \
scripts/zone/blackrock_depths/boss_gorosh_the_dervish.cpp \
scripts/zone/blackrock_depths/boss_grizzle.cpp \
scripts/zone/blackrock_depths/boss_haterel.cpp \
scripts/zone/blackrock_depths/boss_high_interrogator_gerstahn.cpp \
scripts/zone/blackrock_depths/boss_magmus.cpp \
scripts/zone/blackrock_depths/boss_moira_bronzebeard.cpp \
scripts/zone/blackrock_depths/boss_seethrel.cpp \
scripts/zone/blackrock_depths/boss_vilerel.cpp \
scripts/zone/blackrock_spire/boss_drakkisath.cpp \
scripts/zone/blackrock_spire/boss_gyth.cpp \
scripts/zone/blackrock_spire/boss_halycon.cpp \
scripts/zone/blackrock_spire/boss_highlord_omokk.cpp \
scripts/zone/blackrock_spire/boss_mother_smolderweb.cpp \
scripts/zone/blackrock_spire/boss_overlord_wyrmthalak.cpp \
scripts/zone/blackrock_spire/boss_pyroguard_emberseer.cpp \
scripts/zone/blackrock_spire/boss_quartermaster_zigris.cpp \
scripts/zone/blackrock_spire/boss_rend_blackhand.cpp \
scripts/zone/blackrock_spire/boss_shadow_hunter_voshgajin.cpp \
scripts/zone/blackrock_spire/boss_the_beast.cpp \
scripts/zone/blackrock_spire/boss_warmaster_voone.cpp \
scripts/zone/blackwing_lair/boss_broodlord_lashlayer.cpp \
scripts/zone/blackwing_lair/boss_chromaggus.cpp \
scripts/zone/blackwing_lair/boss_ebonroc.cpp \
scripts/zone/blackwing_lair/boss_firemaw.cpp \
scripts/zone/blackwing_lair/boss_flamegor.cpp \
scripts/zone/blackwing_lair/boss_nefarian.cpp \
scripts/zone/blackwing_lair/boss_razorgore.cpp \
scripts/zone/blackwing_lair/boss_vaelastrasz.cpp \
scripts/zone/blackwing_lair/boss_victor_nefarius.cpp \
scripts/zone/blackwing_lair/instance_blackwing_lair.cpp \
scripts/zone/blades_edge_mountains/blades_edge_mountains.cpp \
scripts/zone/blasted_lands/blasted_lands.cpp \
scripts/zone/blasted_lands/boss_kruul.cpp \
scripts/zone/bloodmyst_isle/bloodmyst_isle.cpp \
scripts/zone/burning_steppes/burning_steppes.cpp \
scripts/zone/caverns_of_time/dark_portal/boss_aeonus.cpp \
scripts/zone/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp \
scripts/zone/caverns_of_time/dark_portal/boss_temporus.cpp \
scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp \
scripts/zone/caverns_of_time/hyjal/def_hyjal.h \
scripts/zone/caverns_of_time/hyjal/hyjal.cpp \
scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp \
scripts/zone/caverns_of_time/hyjal/hyjalAI.h \
scripts/zone/caverns_of_time/hyjal/instance_hyjal.cpp \
scripts/zone/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp \
scripts/zone/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp \
scripts/zone/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp \
scripts/zone/caverns_of_time/old_hillsbrad/def_old_hillsbrad.h \
scripts/zone/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp \
scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp \
scripts/zone/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp \
scripts/zone/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp \
scripts/zone/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp \
scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp \
scripts/zone/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp \
scripts/zone/coilfang_resevoir/serpent_shrine/def_serpent_shrine.h \
scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp \
scripts/zone/coilfang_resevoir/steam_vault/boss_hydromancer_thespia.cpp \
scripts/zone/coilfang_resevoir/steam_vault/boss_mekgineer_steamrigger.cpp \
scripts/zone/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp \
scripts/zone/coilfang_resevoir/steam_vault/def_steam_vault.h \
scripts/zone/coilfang_resevoir/steam_vault/instance_steam_vault.cpp \
scripts/zone/coilfang_resevoir/underbog/boss_hungarfen.cpp \
scripts/zone/darkshore/darkshore.cpp \
scripts/zone/deadmines/deadmines.cpp \
scripts/zone/dun_morogh/dun_morogh.cpp \
scripts/zone/dustwallow_marsh/dustwallow_marsh.cpp \
scripts/zone/eastern_plaguelands/eastern_plaguelands.cpp \
scripts/zone/elwynn_forest/elwynn_forest.cpp \
scripts/zone/eversong_woods/eversong_woods.cpp \
scripts/zone/felwood/felwood.cpp \
scripts/zone/feralas/feralas.cpp \
scripts/zone/ghostlands/ghostlands.cpp \
scripts/zone/gruuls_lair/boss_gruul.cpp \
scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp \
scripts/zone/gruuls_lair/def_gruuls_lair.h \
scripts/zone/gruuls_lair/instance_gruuls_lair.cpp \
scripts/zone/hellfire_citadel/blood_furnace/boss_broggok.cpp \
scripts/zone/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp \
scripts/zone/hellfire_citadel/blood_furnace/boss_the_maker.cpp \
scripts/zone/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp \
scripts/zone/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp \
scripts/zone/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp \
scripts/zone/hellfire_citadel/magtheridons_lair/def_magtheridons_lair.h \
scripts/zone/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp \
scripts/zone/hellfire_citadel/shattered_halls/boss_nethekurse.cpp \
scripts/zone/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp \
scripts/zone/hellfire_citadel/shattered_halls/def_shattered_halls.h \
scripts/zone/hellfire_citadel/shattered_halls/instance_shattered_halls.cpp \
scripts/zone/hellfire_peninsula/boss_doomlord_kazzak.cpp \
scripts/zone/hellfire_peninsula/hellfire_peninsula.cpp \
scripts/zone/ironforge/ironforge.cpp \
scripts/zone/isle_of_queldanas/isle_of_queldanas.cpp \
scripts/zone/karazhan/boss_curator.cpp \
scripts/zone/karazhan/boss_maiden_of_virtue.cpp \
scripts/zone/karazhan/boss_midnight.cpp \
scripts/zone/karazhan/boss_moroes.cpp \
scripts/zone/karazhan/boss_netherspite.cpp \
scripts/zone/karazhan/boss_nightbane.cpp \
scripts/zone/karazhan/boss_prince_malchezaar.cpp \
scripts/zone/karazhan/boss_shade_of_aran.cpp \
scripts/zone/karazhan/boss_terestian_illhoof.cpp \
scripts/zone/karazhan/bosses_opera.cpp \
scripts/zone/karazhan/def_karazhan.h \
scripts/zone/karazhan/instance_karazhan.cpp \
scripts/zone/karazhan/karazhan.cpp \
scripts/zone/loch_modan/loch_modan.cpp \
scripts/zone/magisters_terrace/boss_felblood_kaelthas.cpp \
scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp \
scripts/zone/magisters_terrace/boss_selin_fireheart.cpp \
scripts/zone/magisters_terrace/boss_vexallus.cpp \
scripts/zone/magisters_terrace/def_magisters_terrace.h \
scripts/zone/magisters_terrace/instance_magisters_terrace.cpp \
scripts/zone/maraudon/boss_celebras_the_cursed.cpp \
scripts/zone/maraudon/boss_landslide.cpp \
scripts/zone/maraudon/boss_noxxion.cpp \
scripts/zone/maraudon/boss_princess_theradras.cpp \
scripts/zone/molten_core/boss_baron_geddon.cpp \
scripts/zone/molten_core/boss_garr.cpp \
scripts/zone/molten_core/boss_gehennas.cpp \
scripts/zone/molten_core/boss_golemagg.cpp \
scripts/zone/molten_core/boss_lucifron.cpp \
scripts/zone/molten_core/boss_magmadar.cpp \
scripts/zone/molten_core/boss_majordomo_executus.cpp \
scripts/zone/molten_core/boss_ragnaros.cpp \
scripts/zone/molten_core/boss_shazzrah.cpp \
scripts/zone/molten_core/boss_sulfuron_harbinger.cpp \
scripts/zone/molten_core/def_molten_core.h \
scripts/zone/molten_core/instance_molten_core.cpp \
scripts/zone/molten_core/molten_core.cpp \
scripts/zone/moonglade/moonglade.cpp \
scripts/zone/mulgore/mulgore.cpp \
scripts/zone/nagrand/nagrand.cpp \
scripts/zone/naxxramas/boss_anubrekhan.cpp \
scripts/zone/naxxramas/boss_faerlina.cpp \
scripts/zone/naxxramas/boss_feugen.cpp \
scripts/zone/naxxramas/boss_gluth.cpp \
scripts/zone/naxxramas/boss_gothik.cpp \
scripts/zone/naxxramas/boss_grobbulus.cpp \
scripts/zone/naxxramas/boss_heigan.cpp \
scripts/zone/naxxramas/boss_highlord_mograine.cpp \
scripts/zone/naxxramas/boss_kelthuzad.cpp \
scripts/zone/naxxramas/boss_lady_blaumeux.cpp \
scripts/zone/naxxramas/boss_loatheb.cpp \
scripts/zone/naxxramas/boss_maexxna.cpp \
scripts/zone/naxxramas/boss_noth.cpp \
scripts/zone/naxxramas/boss_patchwerk.cpp \
scripts/zone/naxxramas/boss_razuvious.cpp \
scripts/zone/naxxramas/boss_sapphiron.cpp \
scripts/zone/naxxramas/boss_sir_zeliek.cpp \
scripts/zone/naxxramas/boss_stalagg.cpp \
scripts/zone/naxxramas/boss_thaddius.cpp \
scripts/zone/naxxramas/boss_thane_korthazz.cpp \
scripts/zone/naxxramas/instance_naxxramas.cpp \
scripts/zone/netherstorm/netherstorm.cpp \
scripts/zone/onyxias_lair/boss_onyxia.cpp \
scripts/zone/orgrimmar/orgrimmar.cpp \
scripts/zone/razorfen_downs/boss_amnennar_the_coldbringer.cpp \
scripts/zone/ruins_of_ahnqiraj/boss_ayamiss.cpp \
scripts/zone/ruins_of_ahnqiraj/boss_buru.cpp \
scripts/zone/ruins_of_ahnqiraj/boss_kurinnaxx.cpp \
scripts/zone/ruins_of_ahnqiraj/boss_moam.cpp \
scripts/zone/ruins_of_ahnqiraj/boss_ossirian.cpp \
scripts/zone/ruins_of_ahnqiraj/boss_rajaxx.cpp \
scripts/zone/ruins_of_ahnqiraj/instance_ruins_of_ahnqiraj.cpp \
scripts/zone/scarlet_monastery/boss_arcanist_doan.cpp \
scripts/zone/scarlet_monastery/boss_azshir_the_sleepless.cpp \
scripts/zone/scarlet_monastery/boss_bloodmage_thalnos.cpp \
scripts/zone/scarlet_monastery/boss_herod.cpp \
scripts/zone/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp \
scripts/zone/scarlet_monastery/boss_high_inquisitor_whitemane.cpp \
scripts/zone/scarlet_monastery/boss_houndmaster_loksey.cpp \
scripts/zone/scarlet_monastery/boss_interrogator_vishas.cpp \
scripts/zone/scarlet_monastery/boss_scarlet_commander_mograine.cpp \
scripts/zone/scarlet_monastery/boss_scorn.cpp \
scripts/zone/scholomance/boss_darkmaster_gandling.cpp \
scripts/zone/scholomance/boss_death_knight_darkreaver.cpp \
scripts/zone/scholomance/boss_doctor_theolen_krastinov.cpp \
scripts/zone/scholomance/boss_illucia_barov.cpp \
scripts/zone/scholomance/boss_instructor_malicia.cpp \
scripts/zone/scholomance/boss_jandice_barov.cpp \
scripts/zone/scholomance/boss_kormok.cpp \
scripts/zone/scholomance/boss_lord_alexei_barov.cpp \
scripts/zone/scholomance/boss_lorekeeper_polkelt.cpp \
scripts/zone/scholomance/boss_ras_frostwhisper.cpp \
scripts/zone/scholomance/boss_the_ravenian.cpp \
scripts/zone/scholomance/boss_vectus.cpp \
scripts/zone/scholomance/def_scholomance.h \
scripts/zone/scholomance/instance_scholomance.cpp \
scripts/zone/searing_gorge/searing_gorge.cpp \
scripts/zone/shadowfang_keep/def_shadowfang_keep.h \
scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp \
scripts/zone/shadowfang_keep/shadowfang_keep.cpp \
scripts/zone/shadowmoon_valley/boss_doomwalker.cpp \
scripts/zone/shadowmoon_valley/shadowmoon_valley.cpp \
scripts/zone/shattrath/shattrath_city.cpp \
scripts/zone/silithus/silithus.cpp \
scripts/zone/silvermoon/silvermoon_city.cpp \
scripts/zone/silverpine_forest/silverpine_forest.cpp \
scripts/zone/stonetalon_mountains/stonetalon_mountains.cpp \
scripts/zone/stormwind/stormwind_city.cpp \
scripts/zone/stranglethorn_vale/stranglethorn_vale.cpp \
scripts/zone/stratholme/boss_baron_rivendare.cpp \
scripts/zone/stratholme/boss_baroness_anastari.cpp \
scripts/zone/stratholme/boss_cannon_master_willey.cpp \
scripts/zone/stratholme/boss_dathrohan_balnazzar.cpp \
scripts/zone/stratholme/boss_magistrate_barthilas.cpp \
scripts/zone/stratholme/boss_maleki_the_pallid.cpp \
scripts/zone/stratholme/boss_nerubenkan.cpp \
scripts/zone/stratholme/boss_order_of_silver_hand.cpp \
scripts/zone/stratholme/boss_postmaster_malown.cpp \
scripts/zone/stratholme/boss_ramstein_the_gorger.cpp \
scripts/zone/stratholme/boss_timmy_the_cruel.cpp \
scripts/zone/stratholme/def_stratholme.h \
scripts/zone/stratholme/instance_stratholme.cpp \
scripts/zone/stratholme/stratholme.cpp \
scripts/zone/sunwell_plateau/boss_brutallus.cpp \
scripts/zone/sunwell_plateau/boss_kalecgos.cpp \
scripts/zone/sunwell_plateau/def_sunwell_plateau.h \
scripts/zone/sunwell_plateau/instance_sunwell_plateau.cpp \
scripts/zone/tanaris/tanaris.cpp \
scripts/zone/tempest_keep/arcatraz/arcatraz.cpp \
scripts/zone/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp \
scripts/zone/tempest_keep/arcatraz/def_arcatraz.h \
scripts/zone/tempest_keep/arcatraz/instance_arcatraz.cpp \
scripts/zone/tempest_keep/botanica/boss_high_botanist_freywinn.cpp \
scripts/zone/tempest_keep/botanica/boss_laj.cpp \
scripts/zone/tempest_keep/botanica/boss_warp_splinter.cpp \
scripts/zone/tempest_keep/the_eye/boss_astromancer.cpp \
scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp \
scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp \
scripts/zone/tempest_keep/the_eye/def_the_eye.h \
scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp \
scripts/zone/tempest_keep/the_eye/the_eye.cpp \
scripts/zone/tempest_keep/the_mechanar/boss_gatewatcher_gyrokill.cpp \
scripts/zone/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp \
scripts/zone/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp \
scripts/zone/temple_of_ahnqiraj/boss_bug_trio.cpp \
scripts/zone/temple_of_ahnqiraj/boss_cthun.cpp \
scripts/zone/temple_of_ahnqiraj/boss_fankriss.cpp \
scripts/zone/temple_of_ahnqiraj/boss_huhuran.cpp \
scripts/zone/temple_of_ahnqiraj/boss_ouro.cpp \
scripts/zone/temple_of_ahnqiraj/boss_sartura.cpp \
scripts/zone/temple_of_ahnqiraj/boss_skeram.cpp \
scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp \
scripts/zone/temple_of_ahnqiraj/boss_viscidus.cpp \
scripts/zone/temple_of_ahnqiraj/def_temple_of_ahnqiraj.h \
scripts/zone/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp \
scripts/zone/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp \
scripts/zone/terokkar_forest/terokkar_forest.cpp \
scripts/zone/thunder_bluff/thunder_bluff.cpp \
scripts/zone/tirisfal_glades/tirisfal_glades.cpp \
scripts/zone/uldaman/boss_ironaya.cpp \
scripts/zone/uldaman/uldaman.cpp \
scripts/zone/undercity/undercity.cpp \
scripts/zone/wailing_caverns/instance_wailing_caverns.cpp \
scripts/zone/western_plaguelands/western_plaguelands.cpp \
scripts/zone/winterspring/winterspring.cpp \
scripts/zone/zangarmarsh/zangarmarsh.cpp \
scripts/zone/zulaman/boss_janalai.cpp \
scripts/zone/zulaman/boss_nalorakk.cpp \
scripts/zone/zulaman/def_zulaman.h \
scripts/zone/zulaman/instance_zulaman.cpp \
scripts/zone/zulaman/zulaman.cpp \
scripts/zone/zulfarrak/zulfarrak.cpp \
scripts/zone/zulgurub/boss_arlokk.cpp \
scripts/zone/zulgurub/boss_gahzranka.cpp \
scripts/zone/zulgurub/boss_grilek.cpp \
scripts/zone/zulgurub/boss_hakkar.cpp \
scripts/zone/zulgurub/boss_hazzarah.cpp \
scripts/zone/zulgurub/boss_jeklik.cpp \
scripts/zone/zulgurub/boss_jindo.cpp \
scripts/zone/zulgurub/boss_mandokir.cpp \
scripts/zone/zulgurub/boss_marli.cpp \
scripts/zone/zulgurub/boss_renataki.cpp \
scripts/zone/zulgurub/boss_thekal.cpp \
scripts/zone/zulgurub/boss_venoxis.cpp \
scripts/zone/zulgurub/boss_wushoolay.cpp \
scripts/zone/zulgurub/def_zulgurub.h \
scripts/zone/zulgurub/instance_zulgurub.cpp \
system.cpp
## libtool settings
# API versioning
# Increase the last number, if you do bug fixes only, no interface change.
# Increase the middle number when you augmented the interface ( aka add new exported functions ).
# Increase the first number when you break old interface. ( aka remove/change previously exported functions ).
libtrinityscript_la_LIBFLAGS = -version-info 0:0:1
libtrinityscript_la_LIBADD = $(MYSQL_LIBS) $(POSTGRE_LIBS)
## Additional files to include when running 'make dist'
# Scripts defaults.
EXTRA_DIST = \
Scripts/sc_default.cpp \
Scripts/sc_defines.cpp \
Scripts/sc_defines.h
## Additional files to install
sysconf_DATA = \
trinityscript.conf.dist
## Prevend overwrite of the config file, if its already installed
install-data-hook:
@list='$(sysconf_DATA)'; for p in $$list; do \
dest=`echo $$p | sed -e s/.dist//`; \
if test -f $(DESTDIR)$(sysconfdir)/$$dest; then \
echo "$@ will not overwrite existing $(DESTDIR)$(sysconfdir)/$$dest"; \
else \
echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(sysconfdir)/$$dest"; \
$(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(sysconfdir)/$$dest; \
fi; \
done
File diff suppressed because it is too large Load Diff
+94
View File
@@ -0,0 +1,94 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef SCRIPTMGR_H
#define SCRIPTMGR_H
#include "Common.h"
#include "Platform/CompilerDefs.h"
#include "Database/DBCStructure.h"
class Player;
class Creature;
class CreatureAI;
class InstanceData;
class Quest;
class Item;
class GameObject;
class SpellCastTargets;
class Map;
class Unit;
class WorldObject;
#define MAX_SCRIPTS 1000 //72 bytes each (approx 71kb)
//MAX visible range (size of grid)
#define VISIBLE_RANGE (166.0f)
#define DEFAULT_TEXT "<ScriptDev2 Text Entry Missing!>"
//
struct Script
{
Script() :
pGossipHello(NULL), pQuestAccept(NULL), pGossipSelect(NULL), pGossipSelectWithCode(NULL),
pQuestSelect(NULL), pQuestComplete(NULL), pNPCDialogStatus(NULL), pGODialogStatus(NULL), pChooseReward(NULL),
pItemHello(NULL), pGOHello(NULL), pAreaTrigger(NULL), pItemQuestAccept(NULL), pGOQuestAccept(NULL),
pGOChooseReward(NULL),pReceiveEmote(NULL),pItemUse(NULL), GetAI(NULL), GetInstanceData(NULL)
{}
std::string Name;
// -- Quest/gossip Methods to be scripted --
bool (*pGossipHello )(Player*, Creature*);
bool (*pQuestAccept )(Player*, Creature*, Quest const* );
bool (*pGossipSelect )(Player*, Creature*, uint32 , uint32 );
bool (*pGossipSelectWithCode)(Player*, Creature*, uint32 , uint32 , const char* );
bool (*pQuestSelect )(Player*, Creature*, Quest const* );
bool (*pQuestComplete )(Player*, Creature*, Quest const* );
uint32 (*pNPCDialogStatus )(Player*, Creature* );
uint32 (*pGODialogStatus )(Player *player, GameObject * _GO );
bool (*pChooseReward )(Player*, Creature*, Quest const*, uint32 );
bool (*pItemHello )(Player*, Item*, Quest const* );
bool (*pGOHello )(Player*, GameObject* );
bool (*pAreaTrigger )(Player*, AreaTriggerEntry* );
bool (*pItemQuestAccept )(Player*, Item *, Quest const* );
bool (*pGOQuestAccept )(Player*, GameObject*, Quest const* );
bool (*pGOChooseReward )(Player*, GameObject*_GO, Quest const*, uint32 );
bool (*pReceiveEmote )(Player*, Creature*, uint32 );
bool (*pItemUse )(Player*, Item*, SpellCastTargets const& );
CreatureAI* (*GetAI)(Creature*);
InstanceData* (*GetInstanceData)(Map*);
// -----------------------------------------
};
extern int nrscripts;
extern Script *m_scripts[MAX_SCRIPTS];
// Localized Text function
const char* GetEventAILocalizedText(uint32 entry);
const char* GetScriptLocalizedText(uint32 entry);
//EventAI text function
const char* GetEventAIText(uint32 entry); // TODO: Locales
// Script Text function
void ProcessScriptText(uint32 id, WorldObject* pSource, Unit* target = NULL); // TODO: Locales
#if COMPILER == COMPILER_GNU
#define FUNC_PTR(name,callconvention,returntype,parameters) typedef returntype(*name)parameters __attribute__ ((callconvention));
#else
#define FUNC_PTR(name, callconvention, returntype, parameters) typedef returntype(callconvention *name)parameters;
#endif
#ifdef WIN32
#define MANGOS_DLL_EXPORT extern "C" __declspec(dllexport)
#elif defined( __GNUC__ )
#define MANGOS_DLL_EXPORT extern "C"
#else
#define MANGOS_DLL_EXPORT extern "C" export
#endif
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.
+701
View File
@@ -0,0 +1,701 @@
=========================================
Event AI documentation
=========================================
Scriptdev2 Revision 220 introduces a new database defined AI named EventAI.
This system allows users to create new creature scripts entierly within the Database.
ScriptName must still be set to "mob_eventai" within the MaNGOS database creature_template.scriptname field.
=========================================
Basic Structure of EventAI
=========================================
Event AI follows a basic if (Event) then do {Action} format.
Below is a the list of current fields within the Eventai_scripts table.
(Field_Name Discription)
id This value is mearly an incrementing counter of the current Event number. Required for sql queries.
creature_id Creature id which this event should occur on.
event_type Type of event (See Event Types below)
event_inverse_phase_mask Mask which phases this event should NOT trigger in*
event_chance Percent chance of this event occuring (1 - 100)
event_flags Event flags such as if the event is repeatable (see below)
event_param1 Variable for event (dependant on Event type)
event_param2
event_param3
event_param4
action1_type First Type of Action to take when event occurs (See Action Types below)
action1_param1 Variables used for Action1 (dependant on Action type)
action1_param2
action1_param3
action2_type Second Type of Action to take when event occurs (See Action Types below)
action2_param1 Variables used for Action2 (dependant on Action type)
action2_param2
action2_param3
action3_type Third Type of Action to take when event occurs (See Action Types below)
action3_param1 Variables used for Action3 (dependant on Action type)
action3_param2
action3_param3
All params are signed 32 bit values (+/- 2147483647). If param specifies time then time is in milliseconds. If param specifies percentage then percentages are value/100 (ex: if param = 500 then that means 500%, -50 = -50%)
*Phase mask is a bit mask of which phases this event should not trigger in. Example: Phase mask value of 12 (1100) would mean that this event would trigger 0, 1 and all other phases except for 2 and 3 (0 counts as the first phase).
=========================================
Event Types
=========================================
Below is the list of current Event types that EventAI can handle.
Each event type has its own specific interpretation of the params that accompany it.
Params are always read from Param1, then Param2, then Param3.
Events will not repeat until the creature exits combat unless EFLAG_REPEATABLE is set. Some events such as EVENT_T_AGGRO, EVENT_T_DEATH, EVENT_T_SPAWNED, and EVENT_T_EVADE cannot repeat.
# Internal Name Pamarm usage Description
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0 EVENT_T_TIMER InitialMin, InitialMax, RepeatMin, RepeatMax Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4). but only in combat.
1 EVENT_T_TIMER_OOC InitialMin, InitialMax, RepeatMin, RepeatMax Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4). but only out of combat.
2 EVENT_T_HP HPMax%, HPMin%, RepeatMin, RepeatMax Expires when HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
3 EVENT_T_MANA ManaMax%,ManaMin% RepeatMin, RepeatMax Expires once Mana% is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
4 EVENT_T_AGGRO NONE Expires upon initial aggro (does not repeat).
5 EVENT_T_KILL RepeatMin, RepeatMax Expires upon killing a player. Will repeat between every (Param1) and (Param2).
6 EVENT_T_DEATH NONE Expires upon Death of the Creature.
7 EVENT_T_EVADE NONE Expires upon creature EnterEvadeMode().
8 EVENT_T_SPELLHIT SpellID, School, RepeatMin, RepeatMax Expires upon Spell hit. If (param1) is set will only expire on that spell. If (param2) will only expire on spells of that school (-1 for all). Will repeat every (Param3) and (Param4) .
9 EVENT_T_RANGE MinDist, MaxDist, RepeatMin, RepeatMax Expires when the highest threat target distance is greater than (Param1) and less than (Param2). Will repeat every (Param3) and (Param4) .
10 EVENT_T_OOC_LOS NoHostile, NoFriendly, RepeatMin, RepeatMax Expires when a Player moves within visible distance to creature. Does not expire for Hostile Players if (Param1) is not 0. Does not expire for Friendly Players if (Param2) is not 0. Will repeat every (Param3) and (Param4) . Does not expire for creatures or pet or when the creature is in combat.
11 EVENT_T_SPAWNED NONE Expires at initial spawn and at creature respawn (useful for setting ranged movement type)
12 EVENT_T_TARGET_HP HPMax%, HPMin%, RepeatMin, RepeatMax Expires when Current Target's HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4) .
13 EVENT_T_TARGET_CASTING RepeatMin, RepeatatMax Expires when the current target is casting a spell. Will repeat every (Param1) and (Param2) .
14 EVENT_T_FRIENDLY_HP HPDeficit, Radius, RepeatMin, RepeatMax Expires when a friendly unit in radius has at least (param1) hp missing. Will repeat every (Param3) and (Param4) .
15 EVENT_T_FRIENDLY_IS_CC DispelType, Radius, RepeatMin, RepeatMax Expires when a friendly unit is Crowd controlled within the given radius (param2). Will repeat every (Param3) and (Param4) .
16 EVENT_T_MISSING_BUFF SpellId, Radius, RepeatMin, RepeatMax Expires when a friendly unit is missing aura's given by spell (param1) within radius (param2). Will repeat every (Param3) and (Param4) .
17 EVENT_T_SUMMONED_UNIT CreatureId, RepeatMin, RepeatMax Expires after creature with entry = (param1) is spawned or for all spawns if param1 = 0. Will repeat every (Param2) and (Param3) .
=========================================
Action Types
=========================================
Below is the list of current Action types that EventAI can handle.
Each event type has its own specific interpretation of the params that accompany it.
Params are always read from Param1, then Param2, then Param3.
(# Internal Name Param usage Discription)
0 ACTION_T_NONE No Action Does Nothing
1 ACTION_T_SAY TextId Says Text
2 ACTION_T_YELL TextId Yells Text
3 ACTION_T_TEXTEMOTE TextId Text Emotes Text
4 ACTION_T_SOUND SoundId Plays Sound
5 ACTION_T_EMOTE EmoteId Does emote
6 ACTION_T_RANDOM_SAY TextId1, TextId2, TextId3 Says random text between 3 params*
7 ACTION_T_RANDOM_YELL TextId1, TextId2, TextId3 Yells random text between 3 params*
8 ACTION_T_RANDOM_TEXTEMOTE TextId1, TextId2, TextId3 Text Emotes random text between 3 params*
9 ACTION_T_RANDOM_SOUND SoundId1, SoundId2, SoundId3 Plays random sound between 3 params*
10 ACTION_T_RANDOM_EMOTE EmoteId1, EmoteId2, EmoteId3 Emotes random emote between 3 params
11 ACTION_T_CAST SpellId, Target, CastFlags Casts spell (param1) on target type (param2). Uses Cast Flags (specified below target types)
12 ACTION_T_SUMMON CreatureID, Target, Duration Summons creature (param1) to attack target (param2) for (param3) duration. Spawns on top of current creature.
13 ACTION_T_THREAT_SINGLE_PCT Threat%, Target Modifies threat by (param1) on target type (param2)
14 ACTION_T_THREAT_ALL_PCT Threat% Modifies threat by (param1) on all targets (using -100% on all will result in full aggro dump)
15 ACTION_T_QUEST_EVENT QuestID, Target Calls AreaExploredOrEventHappens with (param1) for target type (Param2)
16 ACTION_T_QUEST_CASTCREATUREGO CreatureID, SpellId, Target Sends CastCreatureOrGo for CreatureId (param1) with SpellId (param2) for target (param3)
17 ACTION_T_SET_UNIT_FIELD Field_Number, Value, Target Sets Unit Field (param1) to Value (param2) on target type (param3)
18 ACTION_T_SET_UNIT_FLAG Flags, Target Sets flag (flags can be binary OR together to modify multiple flags at once) on for Target type (param2)
19 ACTION_T_REMOVE_UNIT_FLAG Flags, Target Removes flag (flags can be binary OR together to modify multiple flags at once) on for Target type (param2)
20 ACTION_T_AUTO_ATTACK AllowAutoAttack 0 = stop melee attack, anything else means continue attacking/allow melee attacking
21 ACTION_T_COMBAT_MOVEMENT AllowCombatMovement 0 = stop combat based movement, anything else continue/allow combat based movement (targeted movement generator)
22 ACTION_T_SET_PHASE Phase Sets the current phase to (param1)
23 ACTION_T_INC_PHASE Value Increments the phase by (param1). May be negative to decrement phase but should not be 0.
24 ACTION_T_EVADE No Params Forces the creature to evade. Wiping all threat and dropping combat.
25 ACTION_T_FLEE No Params Causes the .creature to flee. Please use this action instead of directly casting this spell so we may change this when a more correct approach is found.
26 ACTION_T_QUEST_EVENT_ALL QuestId Calls GroupEventHappens with (param1). Only used if it's _expected_ event should complete for all players in current party
27 ACTION_T_CASTCREATUREGO_ALL QuestId, SpellId Calls CastedCreatureOrGo for all players on the threat list with QuestID(Param1) and SpellId(Param2)
28 ACTION_T_REMOVEAURASFROMSPELL Target, Spellid Removes all auras on Target caused by Spellid
29 ACTION_T_RANGED_MOVEMENT Distance, Angle Changes the movement generator type to a ranged type. Note: Default melee type can still be done with this. Specify 0 angle and 0 distance.
30 ACTION_T_RANDOM_PHASE PhaseId1, PhaseId2, PhaseId3 Sets the phase to the id between 3 params*
31 ACTION_T_RANDOM_PHASE_RANGE PhaseMin, PhaseMax Sets the phase to a random id (Phase = PhaseMin + rnd % PhaseMin-PhaseMax). PhaseMax must be greater than PhaseMin.
32 ACTION_T_SUMMON CreatureID, Target, SummonID Summons creature (param1) to attack target (param2) at location specified by EventAI_Summons (param3).
33 ACTION_T_KILLED_MONSTER CreatureID, Target Calls KilledMonster (param1) for target of type (param2)
34 ACTION_T_SET_INST_DATA Field, Data Calls ScriptedInstance::SetData with field (param1) and data (param2)
35 ACTION_T_SET_INST_DATA64 Field, Target Calls ScriptedInstance::SetData64 with field (param1) and data (param2) target's GUID.
36 ACTION_T_UPDATE_TEMPLATE TemplateId, Team Changes the creature to a new creature template of (param1) with team = Alliance if (param2) = false or Horde if (param2) = true
37 ACTION_T_DIE No Params Kills the creature
38 ACTION_T_ZONE_COMBAT_PULSE No Params Places all players within the instance into combat with the creature. Only works in combat and only works inside of instances.
* = Use -1 to specify that if this param is picked to do nothing. Random is constant between actions within an event. So if you have a random Yell and a random Sound they will match up (ex: param2 with param2)
=========================================
Event Types
=========================================
Note:
COMBAT ONLY - Means that this event will only trigger durring combat.
OUT OF COMBAT ONLY - Means that this event will only trigger while out of combat.
BOTH - This event can trigger both in and out of combat.
Events that do not have lables on them are events that are directly involved with the in and out of combat state.
------------------
0 = EVENT_T_TIMER:
------------------
Parameter 1: InitialMin - Minumum Time used to calculate Random Initial Expire
Parameter 2: InitialMax - Maximum Time used to calculate Random Initial Expire
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
COMBAT ONLY! - Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4) from then on.
This is commonly used for spells that repeat cast during combat (Simulate Spell Cooldown).
----------------------
1 = EVENT_T_TIMER_OOC:
----------------------
Parameter 1: InitialMin - Minumum Time used to calculate Random Initial Expire
Parameter 2: InitialMax - Maximum Time used to calculate Random Initial Expire
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
OUT OF COMBAT ONLY! - Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4) from then on.
This is commonly used for events that occur and repeat outside of combat.
---------------
2 = EVENT_T_HP:
---------------
Parameter 1: HPMax% - Maximum HP% That this Event will Expire
Parameter 2: HPMin% - Minimum HP% That this Event will Expire
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
BOTH - Expires when HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
This is commonly used for events that trigger at a specific HP% (Such as Heal/Enrage Spells or NPC's that Flee).
-----------------
3 = EVENT_T_MANA:
-----------------
Parameter 1: ManaMax% - Maximum Mana% That this Event will Expire
Parameter 2: ManaMin% - Minimum Mana% That this Event will Expire
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
BOTH - Expires once Mana% is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
This is commonly used for events where an NPC low on Mana will do something (Such as stop casting spells and switch to melee).
------------------
4 = EVENT_T_AGGRO:
------------------
This Event Expires upon initial aggro (does not repeat).
-----------------
5 = EVENT_T_KILL:
-----------------
Parameter 1: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 2: RepeatMax - Maximum Time used to calculate Random Repeat Expire
COMBAT ONLY! - Expires upon killing a player. Will repeat every (Param1) and (Param2).
This Event Expires upon killing a player. It is commonly used for NPC's who yell or do something after killing a player.
------------------
6 = EVENT_T_DEATH:
------------------
This Event Expires upon Death of the Scripted NPC.
This is commonly used for NPC's who have a yell on death or cast some kind if summon spell when they die.
------------------
7 = EVENT_T_EVADE:
------------------
This Event Expires upon the creature EnterEvadeMode().
This is commonly used for NPC's who use phases, allows you to reset their phase to 0 upon evade to prevent possible strange behavior.
---------------------
8 = EVENT_T_SPELLHIT:
---------------------
Parameter 1: SpellID - The Spell ID that will trigger the event to occur (NOTE: If you use Spell School as the trigger set this value to 0)
Parameter 2: School - Spell School to trigger the event (NOTE: If you use a SpellID then set this value to -1) - *See Below for Spell School Bitmask Values*
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
BOTH - Expires upon Spell hit. If (param1) is set will only expire on that spell. If (param2) will only expire on spells of that school. Will repeat every (Param3) and (Param4).
This Event is commonly used for NPC's who can do special things when you cast a spell (Or specific spell) on them.
------------------
9 = EVENT_T_RANGE:
------------------
Parameter 1: MinDist - This Distance is the Minimum Distance between the NPC and it's target to allow this Event to Expire
Parameter 2: MaxDist - This Distance is the Maximum Distance between the NPC and it's target to allow this Event to Expire
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
COMBAT ONLY! - Expires when the highest threat target distance is greater than (Param1) and less than (Param2). Will repeat every (Param3) and (Param4).
This Event is commonly used for NPC's who have Ranged Combat and will Throw/Shoot between a certian distance.
---------------------
10 = EVENT_T_OOC_LOS:
---------------------
Parameter 1: NoHostile - This Value is to Prevent this Action from Expiring When Caused by a Player/Creature Hostile to them (0 = Prevent Event from Expiring, 1 = Allow Event to Expire)
Parameter 2: NoFriendly - This Value is to Prevent this Action from Expiring When Caused by a Player/Creature Friendly to them (0 = Prevent Event from Expiring, 1 = Allow Event to Expire)
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
OUT OF COMBAT ONLY! - Expires when a Player moves within visible distance to the NPC. Does not expire for Hostile Players if (Param1) is not 0. Does not expire for Friendly Players if (Param2) is not 0. Will repeat every (Param3) and (Param4). Does not expire for creatures or pets when they are in combat.
This Event is commonly used for NPC's who Do Something or Say Something when you walk past them Out of Combat.
---------------------
11 = EVENT_T_SPAWNED:
---------------------
Expires at initial spawn and at creature respawn.
This Event is commonly used for setting ranged movement type or Summoning a Pet on Spawn
-----------------------
12 = EVENT_T_TARGET_HP:
-----------------------
Parameter 1: HPMax% - Maximum HP% That this Event will Expire
Parameter 2: HPMin% - Minimum HP% That this Event will Expire
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
COMBAT ONLY! - Expires when Current NPC's Target's HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
This Event is commonly used for NPC's who have a special ability (Like Execute) that only casts when a Player HP is low.
----------------------------
13 = EVENT_T_TARGET_CASTING:
----------------------------
Parameter 1: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 2: RepeatMax - Maximum Time used to calculate Random Repeat Expire
COMBAT ONLY! - Expires when the current target is casting a spell. Will repeat every (Param1) and (Param2).
This event is commonly used for NPC's who will cast a counter spell when their target starts to cast a spell.
-------------------------
14 = EVENT_T_FRIENDLY_HP:
-------------------------
Parameter 1: HPDeficit - This is the Amount of HP Missing from Full HP to trigger this event (You would need to calculate the amount of HP the event happens and subtract that from Full HP Value to get this number)
Parameter 2: Radius - This is the Range in Yards the NPC will scan for nearby Friendlies (Faction is Friendly To) for the missing amount of HP in Param1.
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
COMBAT ONLY! - Expires when a friendly unit in radius(param2) has at least (param1) hp missing. Will repeat every (Param3) and (Param4).
This is commonly used when an NPC in Combat will heal a nearby Friendly NPC in Combat with a Heal/Renew Spell.
----------------------------
15 = EVENT_T_FRIENDLY_IS_CC:
----------------------------
Parameter 1: DispelType - Dispel Type to trigger the event - *See Below for Dispel Bitmask Values*
Parameter 2: Radius - This is the Range in Yards the NPC will scan for nearby Friendlies being Crowd Controlled
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
COMBAT ONLY! - Expires when a friendly unit is Crowd controlled within the given radius (param2). Will repeat every (Param3) and (Param4).
This is commonly used for NPC's who can come to the resule of other Friendly NPC's if being Crowd Controlled
--------------------------
16 = EVENT_T_MISSING_BUFF:
--------------------------
Parameter 1: SpellId - This is the SpellID That the Aura Check will look for (If it is missing this Aura)
Parameter 2: Radius - This is the Range in Yards the NPC will scan for nearby Friendlies (Faction is Friendly To) for the missing Aura.
Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
BOTH - Expires when a friendly unit is missing aura's given by spell (param1) within radius (param2). Will repeat every (Param3) and (Param4).
This is commonly used for NPC's who watch friendly units for a debuff to end so they can recast it on them again.
---------------------------
17 = EVENT_T_SUMMONED_UNIT:
---------------------------
Parameter 1: CreatureId - The CreatureID that the NPC is watching to spawn to trigger this event
Parameter 2: RepeatMin - Minimum Time used to calculate Random Repeat Expire
Parameter 3: RepeatMax - Maximum Time used to calculate Random Repeat Expire
BOTH - Expires after creature with entry(Param1) is spawned or for all spawns if param1 = 0. Will repeat every (Param2) and (Param3) .
This is commonly used for NPC's who will do something special once another NPC is summoned. Usually used is Complex Scripts or Special Events.
=========================================
Action Types
=========================================
-----------------
1 = ACTION_T_SAY:
-----------------
Parameter 1: The ID of the text that the NPC should SAY from the Localized_Texts Table.
This action is pretty straightforward. When activated, the creature will SAY the specified text (Speech Bubble).
------------------
2 = ACTION_T_YELL:
------------------
Parameter 1: The ID of the text that the NPC should YELL from the Localized_Texts Table.
The creature will YELL the specified text (Red Speech Bubble).
-----------------------
3 = ACTION_T_TEXTEMOTE:
-----------------------
Parameter 1: The ID of the text that the NPC should TEXTEMOTE from the Localized_Texts Table.
When activated, the creature will do a text emote using the specified text. A text emote is what you would regularly see by using the /em slash command.
NOTE: The text should be written with the assumption that the creature's name is the first word or words in the sentence (for example, "is doing a text emote" would appear as "XYZ is doing a text emote" for a creature named XYZ).
-------------------
4 = ACTION_T_SOUND:
-------------------
Parameter 1: The Sound ID to be played. (Sound IDs are contained in the DBC files.)
The creature will play the specified sound.
This is commonly used for Bosses who Yell and then also have a Voice for the same thing.
-------------------
5 = ACTION_T_EMOTE:
-------------------
Parameter 1: The Emote ID that the creature should perform. (Emote IDs are also contained in the DBC but they can be found in the mangos source as well).
The creature will perform a visual emote. Unlike a text emote, a visual emote is one where the creature will actually move or perform a gesture.
This is commonly used for NPC's who may perform a special action (Salute, Roar, ect...). Not all player emotes work for creature models.
------------------------
6 = ACTION_T_RANDOM_SAY:
------------------------
Parameter 1: The ID of the text that the NPC should SAY from the Localized_Texts Table (Random Choice #1).
Parameter 2: The ID of the text that the NPC should SAY from the Localized_Texts Table (Random Choice #2).
Parameter 3: The ID of the text that the NPC should SAY from the Localized_Texts Table (Random Choice #3).
Similar to the ACTION_T_SAY action, it will choose at random a text entry to SAY. This action will pick a random entry from the three.
NOTE: If you want any of the options if selected to do nothing you set that Param to -1 value. Then if selected it will do nothing.
NOTE: When using Random Select Actions, ALL The Actions using Random in a Single Event (Action 1,2,3) will select the SAME Random Choice when it expires. This can come in handy if you are doing a ACTION_T_RANDOM_YELL for Action1 and then the corresponding sounds for ACTION_T_RANDOM_SOUND in Action2. If it selects Random Choice #2 for the Yell it will Select Random Choice #2 for the sound so you can match them up as required.
This is commonly used for NPC's who have several different Aggro Say's and you would like one of them selected at random.
-------------------------
7 = ACTION_T_RANDOM_YELL:
-------------------------
Parameter 1: The ID of the text that the NPC should YELL from the Localized_Texts Table (Random Choice #1).
Parameter 2: The ID of the text that the NPC should YELL from the Localized_Texts Table (Random Choice #2).
Parameter 3: The ID of the text that the NPC should YELL from the Localized_Texts Table (Random Choice #3).
Similar to the ACTION_T_YELL action, it will choose at random a text entry to YELL.
------------------------------
8 = ACTION_T_RANDOM_TEXTEMOTE:
------------------------------
Parameter 1: The ID of the text that the NPC should TEXTEMOTE from the Localized_Texts Table (Random Choice #1).
Parameter 2: The ID of the text that the NPC should TEXTEMOTE from the Localized_Texts Table (Random Choice #2).
Parameter 3: The ID of the text that the NPC should TEXTEMOTE from the Localized_Texts Table (Random Choice #3).
Similar to the ACTION_T_TEXTEMOTE action, it will choose at random a text entry to TEXTEMOTE.
--------------------------
9 = ACTION_T_RANDOM_SOUND:
--------------------------
Parameter 1: The Sound ID to be played as Random Choice #1.
Parameter 2: The Sound ID to be played as Random Choice #2.
Parameter 3: The Sound ID to be played as Random Choice #3.
Similar to the ACTION_T_SOUND action, it will choose at random a sound to play.
---------------------------
10 = ACTION_T_RANDOM_EMOTE:
---------------------------
Parameter 1: The Emote ID to be played as Random Choice #1.
Parameter 2: The Emote ID to be played as Random Choice #2.
Parameter 3: The Emote ID to be played as Random Choice #3.
Similar to the ACTION_T_EMOTE action, it will choose at random an Emote to Visually Perform.
-------------------
11 = ACTION_T_CAST:
-------------------
Parameter 1: SpellId - The Spell ID to use for the NPC to cast. The value used in this field needs to be a valid Spell ID.
Parameter 2: Target - The Target Type defining who the creature should cast the spell at. The value in this field needs to be a valid Target Type as specified in the reference tables below.
Parameter 3: CastFlags - See Table Below for Cast Flag Bitmask Values. If you are unsure what to set this value at leave it at 0.
The creature will cast a spell specified by a spell ID on a target specified by the target type.
This is commonly used for NPC's who cast spells.
---------------------
12 = ACTION_T_SUMMON:
---------------------
Parameter 1: CreatureID - The Creature Template ID to be Summoned. The value here needs to be a valid Creature Template ID.
Parameter 2: Target - The Target Type defining who the Summoned creature will attack once spawned. The value in this field needs to be a valid Target Type as specified in the reference tables below.
Parameter 3: Duration - The duration until the summoned creature should be unsummoned AFTER Combat ends. The value in this field is in milliseconds or 0.
The NPC will Summon another creature at the same spot as itself that will attack the specified target.
NOTE: Almost all Creature Summons have proper Summon Spells that should be used when possible. This Action is a powerful last resort option only to be used if nothing else works.
NOTE: Using Target Type 0 will cause the Summoned creature to not attack anyone.
NOTE: If Duration is set at 0, then the summoned creature will not despawn until it has died.
This is used as a manual way to force an NPC to Summon.
--------------------------------
13 = ACTION_T_THREAT_SINGLE_PCT:
--------------------------------
Parameter 1: Threat% - Threat percent that should be modified. The value in this field can range from -100 to +100. If it is negative, threat will be taken away and if positive, threat will be added.
Parameter 2: Target - The Target Type defining on whom the threat change should occur. The value in this field needs to be a valid target type as specified in the reference tables below.
This action will modify the threat of a target in the creature's threat list by the specified percent.
This is commonly used to allow an NPC to adjust the Threat to a single player.
-----------------------------
14 = ACTION_T_THREAT_ALL_PCT:
-----------------------------
Parameter 1: Threat% - The percent that should be used in modifying everyone's threat in the creature's threat list. The value here can range from -100 to +100.
This action will modify the threat for everyone in the creature's threat list by the specified percent.
NOTE: Using -100 will cause the creature to reset everyone's threat to 0 so that everyone has the same amount of threat. It will NOT remove anyone from the threat list.
This is commonly used to allow an NPC to drop threat for all players to zero.
--------------------------
15 = ACTION_T_QUEST_EVENT:
--------------------------
Parameter 1: QuestID - The Quest Template ID. The value here must be a valid quest template ID. Furthermore, the quest should have SpecialFlags | 2 as it would need to be completed by an external event which is the activation of this action.
Parameter 2: Target - The Target Type defining whom the quest should be completed for. The value in this field needs to be a valid target type as specified in the reference tables below.
This action will satisfy the external completion requirement for the quest for the specified target defined by the target type.
NOTE: This action can only be used with player targets so it must be ensured that the target type will point to a player.
This is commonly used for Quests where only ONE player will gain credit for the quest.
-----------------------------
16 = ACTION_T_CASTCREATUREGO:
-----------------------------
Parameter 1: CreatureID - The Creature Template ID to be Summoned. The value here needs to be a valid Creature Template ID.
Parameter 2: SpellId - The Spell ID to use to simulate the cast. The value used in this field needs to be a valid Spell ID.
Parameter 3: Target - The Target Type defining whom the quest credit should be given to. The value in this field needs to be a valid target type as specified in the reference tables below.
This action will call CastedCreatureOrGO() function for the player. It can be used to give quest credit for casting a spell on the creature.
This is commonly used for NPC's who have a special requirement to have a Spell cast on them to complete a quest.
-----------------------------
17 = ACTION_T_SET_UNIT_FIELD:
-----------------------------
Parameter 1: Field_Number - The index of the Field Number to be changed. Use (http://wiki.udbforums.org/index.php/Character_data) for a list of indeces and what they control. Creatures only contain the OBJECT_FIELD_* and UNIT_FIELD_* fields. They do not contain the PLAYER_FIELD_* fields.
Parameter 2: Value - The new value to be put in the field.
Parameter 3: Target - The Target Type defining for whom the unit field should be changed. The value in this field needs to be a valid target type as specified in the reference tables below.
When activated, this action can change the target's unit field values. More information on the field value indeces can be found at (http://wiki.udbforums.org/index.php/Character_data)
----------------------------
18 = ACTION_T_SET_UNIT_FLAG:
----------------------------
Parameter 1: Flags - The flag(s) to be set. Multiple flags can be set by using bitwise-OR on them (adding them together).
Parameter 2: Target - The Target Type defining for whom the flags should be changed. The value in this field needs to be a valid Target Type as specified in the reference tables below.
When activated, this action changes the target's flags by adding (turning on) more flags. For example, this action can make the creature unattackable/unselectable if the right flags are used.
-------------------------------
19 = ACTION_T_REMOVE_UNIT_FLAG:
-------------------------------
Parameter 1: Flags - The flag(s) to be removed. Multiple flags can be set by using bitwise-OR on them (adding them together).
Parameter 2: Target - The target type defining for whom the flags should be changed. The value in this field needs to be a valid Target Type as specified in the reference tables below.
When activated, this action changes the target's flags by removing (turning off) flags. For example, this action can make the creature normal after it was unattackable/unselectable if the right flags are used.
--------------------------
20 = ACTION_T_AUTO_ATTACK:
--------------------------
Parameter 1: AllowAutoAttack - If zero, then the creature will stop its melee attacks. If non-zero, then the creature will either continue its melee attacks (the action would then have no effect) or it will start its melee attacks on the target with the top threat if its melee attacks were previously stopped.
This action controls whether or not the creature should stop or start the auto melee attack.
NOTE: The ACID Dev Team has conformed to using either 0 or 1 for the Param values (0 = Stop Melee, 1 = Start Melee).
This is commonly used in combination with EVENT_T_RANGE and ACTION_T_COMBAT_MOVEMENT for Ranged Combat for Mages and Spell Casters.
------------------------------
21 = ACTION_T_COMBAT_MOVEMENT:
------------------------------
Parameter 1: If zero, then the creature will stop moving towards its victim (if its victim gets out of melee range) and will be stationary. If non-zero, then the creature will either continue to follow its victim (the action would have no effect) or it will start to follow the target with the top threat if its movement was disabled before.
This action controls whether or not the creature will always move towards its target.
NOTE: The ACID Dev Team has conformed to using either 0 or 1 for the Param values. (0 = Stop Movement, 1 = Start Movement)
This is commonly used with EVENT_T_RANGE and ACTION_T_AUTO_ATTACK for NPC's who engage in Ranged Comabt (Either Spells or Ranged Attacks)
------------------------
22 = ACTION_T_SET_PHASE:
------------------------
Parameter 1: The new phase to set the creature in. This number must be an integer between 0 and 31. Numbers outside of that range will result in an error.
When activated, this action sets the creature's event to the specified value.
NOTE: The creature's current Phase is NOT reset at creature evade. You must manually set the phase back to 0 at EVENT_T_RESET.
NOTE: The value used for the Param is the actual Phase Number (Not The Event_Inverse_Phase_Mask)
This is commonly used for complex scripts with several phases and you need to switch to a different phase.
------------------------
23 = ACTION_T_INC_PHASE:
------------------------
Parameter 1: Value - The number of phases to increase or decrease. Use negative values to decrease the current phase.
When activated, this action will increase (or decrease) the current creature's phase.
NOTE: After increasing or decreasing the phase by this action, the current phase must NOT be lower than 0 or exceed 31.
This can be used instead of ACTION_T_SET_PHASE to change phases in scripts. Just a user friendly option for changing phases.
--------------------
24 = ACTION_T_EVADE:
--------------------
When activated, the creature will immediately exit out of combat, clear its threat list, and move back to its spawn point. Basically, this action will reset the whole encounter.
NOTE: All Param Values Are 0 for this Action.
-------------------
25 = ACTION_T_FLEE:
-------------------
When activated, the creature will try to flee from combat. Currently this is done by it casting a fear-like spell on itself called "Run Away". A Better Flee system is in Development but will take time before it is implimented.
NOTE: All Param Values Are 0 for this Action.
------------------------------
26 = ACTION_T_QUEST_EVENT_ALL:
------------------------------
Parameter 1: QuestId - The quest ID to finish for everyone.
This action does the same thing as the ACTION_T_QUEST_EVENT does but it does it for all players in the creature's threat list.
NOTE: If a player is not in the NPC's threat list for whatever reason, he/she won't get the quest completed.
---------------------------------
27 = ACTION_T_CASTCREATUREGO_ALL:
---------------------------------
Parameter 1: QuestId - The quest template ID.
Parameter 2: SpellId - The spell ID used to simulate the cast.
This action does the same thing as the ACTION_T_CASTCREATUREGO does but it does it for all players in the creature's threat list.
NOTE: If a player is not in its threat list for whatever reason, he/she won't receive the cast emulation.
-----------------------------------
28 = ACTION_T_REMOVEAURASFROMSPELL:
-----------------------------------
Parameter 1: Target - The target type defining for whom the unit field should be changed. The value in this field needs to be a valid target type as specified in the reference tables below.
Parameter 2: SpellId - The spell ID whose auras will be removed.
This action will remove all auras from a specific spell from the target.
This is commonly used for NPC's who have an OOC Aura that is removed at combat start or a similar idea (Like Stealth or Shape Shift)
------------------------------
29 = ACTION_T_RANGED_MOVEMENT:
------------------------------
Parameter 1: Distance - The distance the mob should keep between it and its target.
Parameter 2: Angle - The angle the mob should use.
This action changes the movement type generator to ranged type using the specified values for angle and distance.
NOTE: Specifying zero angle and distance will make it just melee instead.
This is commonly used for NPC's who always attack at range and you can specify the distance they will maintain from the target.
---------------------------
30 = ACTION_T_RANDOM_PHASE:
---------------------------
Parameter 1: PhaseId1 - A possible random phase choice.
Parameter 2: PhaseId2 - A possible random phase choice.
Parameter 3: PhaseId3 - A possible random phase choice.
Randomly sets the phase to one from the three parameter choices.
NOTE: Use -1 to specify that if this param is picked to do nothing. Random is constant between actions within an event. So if you have a random Yell and a random Sound they will match up (ex: param2 with param2)
NOTE 2: PLEASE NOTE THAT EACH OF THE PARAM VALUES ARE ACTUAL PHASE NUMBERS NOT THE INVERSE PHASE MASK VALUE.
This is commonly used for Spellcasting NPC's who on Aggro may select at random a school of spells to use for the fight. Use this if you have up to 3 phases used, otherwise use Action 31 for more then 3 phases.
---------------------------------
31 = ACTION_T_RANDOM_PHASE_RANGE:
---------------------------------
Parameter 1: PhaseMin - The minimum of the phase range.
Parameter 2: PhaseMax - The maximum of the phase range. The number here must be greater than PhaseMin.
Randomly sets the phase between a range of phases controlled by the parameters. Sets the phase to a random id (Phase = PhaseMin + rnd % PhaseMin-PhaseMax).
NOTE: PhaseMax must be greater than PhaseMin.
NOTE 2: PLEASE NOTE THAT EACH OF THE PARAM VALUES ARE ACTUAL PHASE NUMBERS NOT THE INVERSE PHASE MASK VALUE.
This is commonly used for Spellcasting NPC's who on Aggro may select at random a school of spells to use for the fight. Use this if you have MORE then 3 phases used, otherwise use Action 30.
---------------------
32 = ACTION_T_SUMMON:
---------------------
Parameter 1: CreatureID - The creature template ID to be summoned. The value here needs to be a valid creature template ID.
Parameter 2: Target - The target type defining who the summoned creature will attack. The value in this field needs to be a valid target type as specified in the reference tables below. NOTE: Using target type 0 will cause the summoned creature to not attack anyone.
Parameter 3: SummonID - The summon ID from the eventai_summons table controlling the position (and spawntime) where the summoned mob should be spawned at.
Summons creature (param1) to attack target (param2) at location specified by EventAI_Summons (param3).
NOTE: Param3 Value is the ID Value used for the entry used in EventAI_Summons for this action. You MUST have an EventAI_Summons entry to use this action.
This is commonly used for NPC's who need to Summon a creature at a specific location. (Normally used for complex events)
-----------------------------
33 = ACTION_T_KILLED_MONSTER:
-----------------------------
Parameter 1: CreatureID - The creature template ID. The value here must be a valid creature template ID.
Parameter 2: Target - The target type defining whom the quest kill count should be given to. The value in this field needs to be a valid target type as specified in the reference tables below.
When activated, this action will call KilledMonster() function for the player. It can be used to give creature credit for killing a creature. In general if the quest is set to be accompished on different creatures (e.g. "Credit" templates).
NOTE: It can be ANY creature including certain quest specific triggers
This is commonly used for giving the player Quest Credits for NPC kills (Many NPC's may use the same CreatureID for the Kill Credit)
----------------------------
34 = ACTION_T_SET_INST_DATA:
----------------------------
Parameter 1: Field - The field to change in the instance script. Again, this field needs to be a valid field that has been already defined in the instance's script.
Parameter 2: Data - The value to put at that field index.
Sets data for the instance. Note that this will only work when the creature is inside an instantiable zone that has a valid script (ScriptedInstance) assigned.
NOTE: Param1 Value is located in "def_<instance name>.h" SD2 File and Param2 value is generally found in the "sc_instance.h" file in SD2
This is commonly used to link an ACID script with a SD2 C++ Script. You make make things happen like opening doors on specific events that happen. ACID Just triggers the C++ Script to function.
------------------------------
35 = ACTION_T_SET_INST_DATA64:
------------------------------
Parameter 1: Field - The field to change in the instance script. Again, this field needs to be a valid field that has been already defined in the instance's script.
Parameter 2: Target - The target type to use to get the GUID that will be stored at the field index. The value in this field needs to be a valid target type as specified in the reference tables below.
Sets GUID (64 bits) data for the instance based on the target. Note that this will only work when the creature is inside an instantiable zone that has a valid script (ScriptedInstance) assigned.
Calls ScriptedInstance::SetData64 with field (param1) and data (param2) target's GUID.
------------------------------
36 = ACTION_T_UPDATE_TEMPLATE:
------------------------------
Parameter 1: TemplateId - The creature template ID. The value here must be a valid creature template ID.
Parameter 2: Team - Use model_id from team : Alliance(0) or Horde (1).
This function temporarily changes creature entry to new entry, display is changed, loot is changed, but AI is not changed. At respawn creature will be reverted to original entry.
Changes the creature to a new creature template of (param1) with team = Alliance if (param2) = false or Horde if (param2) = true
------------------
37 = ACTION_T_DIE:
------------------
Kills the creature
This is commonly used if you need to Instakill the creature for one reason or another.
--------------------------------
38 = ACTION_T_ZONE_COMBAT_PULSE:
--------------------------------
Places all players within the instance into combat with the creature. Only works in combat and only works inside of instances.
=========================================
Target Types
=========================================
Below is the list of current Target types that EventAI can handle.
Target types are used by certain actions and may effect actions differently
(# Internal Name Discription)
0 TARGET_T_SELF Self cast
1 TARGET_T_HOSTILE Our current target (ie: highest aggro)
2 TARGET_T_HOSTILE_SECOND_AGGRO Second highest aggro (generaly used for cleaves and some special attacks)
3 TARGET_T_HOSTILE_LAST_AGGRO Dead last on aggro (no idea what this could be used for)
4 TARGET_T_HOSTILE_RANDOM Just any random target on our threat list
5 TARGET_T_HOSTILE_RANDOM_NOT_TOP Any random target except top threat
6 TARGET_T_ACTION_INVOKER Unit who caused this Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP)
=========================================
Cast Flags
=========================================
Below is the list of current Cast Flags that EventAI's spell casting can handle.
Cast flags are handled bitwise. Bit 0 is Interrupt Previous, bit 1 is triggered, etc.
So for example the number "3" (11 in Binary, selecting first 2 options) would mean that this cast has both CAST_INTURRUPT_PREVIOUS and CAST_TRIGGERED.
Another example: the number "5" (101 in Binary, selecting first and third options) would mean that this cast has CAST_INTURRUPT_PREVIOUS and CAST_FORCE_CAST.
(bit# Decimal Internal Name Discription)
0 1 CAST_INTURRUPT_PREVIOUS Interrupts any previous spell casting (basicaly makes sure that this spell goes off)
1 2 CAST_TRIGGERED Forces the spell to be instant cast and require no mana/reagents.
2 4 CAST_FORCE_CAST Forces spell to cast even if the target is possibly out of range or the creature is possibly out of mana
3 8 CAST_NO_MELEE_IF_OOM Prevents creature from entering melee if out of mana or out of range
4 16 CAST_FORCE_TARGET_SELF Forces the target to cast this spell on itself
NOTE: You can add the numbers in the decimal column to combine flags.
For example if you wanted to use CAST_NO_MELEE_IF_OOM(8) and CAST_TRIGGERED(2) you would simply use 10 in the cast flags field (8 + 2 = 10).
=========================================
Event Flags
=========================================
Below is the list of current Event Flags that EventAI can handle. Event flags are handled bitwise.
(bit# Decimal Internal Name Discription)
0 1 EFLAG_REPEATABLE Event repeats (Does not repeat if this flag is not set)
1 2 EFLAG_NORMAL Event occurs in Normal instance difficulty (will not occur in Normal if not set)
2 4 EFLAG_HEROIC Event occurs in Heroic instance difficulty (will not occur in Heroic if not set)
3 8
4 16
5 32
6 64
7 128 EFLAG_DEBUG_ONLY Prevents events from occuring on Release builds of ScriptDev2. Useful for testing new features.
NOTE: You can add the numbers in the decimal column to combine flags.
@@ -0,0 +1,32 @@
--- How to install ScriptDev2 ---
1) Download MaNGOS
2) Create a new folder under "src\bindings\" within the MaNGOS source called "ScriptDev2"
3) Checkout the ScriptDev2 trunk from "https://scriptdev2.svn.sourceforge.net/svnroot/scriptdev2"
4a) On Win32:
- Compile MaNGOS
- Compile ScriptDev2 using the ScriptVC70, ScriptVC80, or ScriptVC90 Solution within the ScriptDev2 folder (this will overwrite the Mangoscript dll in the output directory)
4b) On Linux:
- Apply MaNGOS-rXXXX-ScriptDev2.patch, where XXXX is the highest version to that of your MaNGOS revision, to Mangos Source
- Compile MaNGOS (ScriptDev2 will automatically be built when compiling Mangos from here on)
5) Create the default ScriptDev2 database using "sql\created_database.sql", then execute "sql\scriptdev2_structure.sql" on that database.
6) Execute the included "sql\mangos_full_scripts.sql" on your MaNGOS database.
7) Place the included "scriptdev2.conf" file within the directory containing your "mangosd.conf" and "realmd.conf" files. You may need to change this file to match the database you created and any custom settings you wish to use (such as a different locale).
8) Run mangosd from your output directory
To update ScriptDev2:
All you have to do is open src\bindings\ and right click on the ScriptDev2 folder and click "Update" and then follow steps 4, 6, 7, and 8 again. You must still compile MaNGOS before ScriptDev2 when on the Windows platform.
To update your Database with new Scriptdev2 SQL changes you can either:
a) apply only the changes that were made during that revision by looking in the sql\update folder or (files named rXXX_scriptdev2.sql should be executed on the scriptdev2 db while rXXX_mangos.sql should be executed on your mangos db)
b) reapply "mangos_full_scripts.sql" to your MaNGOS database.
You can view the ScriptDev2 Change Log at:
[url=http://scriptdev2.svn.sourceforge.net/viewvc/scriptdev2/?view=log]http://scriptdev2.svn.sourceforge.net/viewvc/scriptdev2/?view=log[/url]
+280
View File
@@ -0,0 +1,280 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
@@ -0,0 +1,32 @@
--- Script Layout ---
A quick explination of the layout I hope everyone will follow for scriptdev2.
--- Sub Folders ---
Area - Contains scripts used solely by area triggers
Boss - Boss scripts for bosses that are not zone specific
Mob - Generic Creature scripts for creatures that are not zone specific
Custom - Intentionally empty folder from SVN. If you make a custom script please put it here.
GO - Contains scripts used solely by Game Objects (GOs) that do not have a specific zone
Guard - Scripts for Guard NPCs
Honor - Honor npcs (currently a blank script as these npcs do nothing special)
Item - Item scripts
NPC - Scripts for individual NPCs who do not have a specific zone
Servers - Generic NPC servers script for things such as flightmasters and guildmasters.
Zone - ALL zone specific scripts should be written within these folders. This includes creature scripts, boss scripts, go scripts, area scripts, and npc scripts.
--- Naming Conventions ---
Please keep file names to "type_objectname.cpp" where type is replaced by the type of object and objectname is replaced by the name of the object, creature, item, or area that this script will be used by.
AddSC functions should follow "void AddSC_creaturename(void);" format. Do not append AI or anything else.
+14
View File
@@ -0,0 +1,14 @@
--- TO DO ---
Simple list of things we need to do.
--- ScriptDev2 Framework ---
Move all text out of C++ code and into SD2 database.
--- Scripting with Priorities ---
1) Boss AI and Boss Event scripts
2) Specific NPC AI, Gossip, Quest, Event scripts
3) Spell and Item scripts
--- Core Problems ---
- Spell scripts are only scriptable within the core. Spell scripts should be done in SD2 since they are very specialized.
@@ -0,0 +1,5 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#include "precompiled.h"
@@ -0,0 +1,25 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef SC_PRECOMPILED_H
#define SC_PRECOMPILED_H
#include "../ScriptMgr.h"
#include "sc_creature.h"
#include "sc_gossip.h"
#include "sc_grid_searchers.h"
#include "sc_instance.h"
#ifdef WIN32
#include <windows.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return true;
}
#endif
#endif
@@ -0,0 +1,612 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#include "precompiled.h"
#include "Item.h"
#include "Spell.h"
#include "WorldPacket.h"
// Spell summary for ScriptedAI::SelectSpell
struct TSpellSummary {
uint8 Targets; // set of enum SelectTarget
uint8 Effects; // set of enum SelectEffect
} *SpellSummary;
bool ScriptedAI::IsVisible(Unit* who) const
{
if (!who)
return false;
return (m_creature->GetDistance(who) < VISIBLE_RANGE) && who->isVisibleForOrDetect(m_creature,true);
}
void ScriptedAI::MoveInLineOfSight(Unit *who)
{
if( !m_creature->getVictim() && who->isTargetableForAttack() && ( m_creature->IsHostileTo( who )) && who->isInAccessablePlaceFor(m_creature) )
{
if (m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
return;
float attackRadius = m_creature->GetAttackDistance(who);
if( m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who) )
{
DoStartAttackAndMovement(who);
who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
if (!InCombat)
{
Aggro(who);
InCombat = true;
}
}
}
}
void ScriptedAI::AttackStart(Unit* who)
{
if (!who)
return;
if (who->isTargetableForAttack())
{
//Begin attack
DoStartAttackAndMovement(who);
if (!InCombat)
{
Aggro(who);
InCombat = true;
}
}
}
void ScriptedAI::UpdateAI(const uint32 diff)
{
//Check if we have a current target
if( m_creature->isAlive() && m_creature->SelectHostilTarget() && m_creature->getVictim())
{
if( m_creature->isAttackReady() )
{
//If we are within range melee the target
if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
{
m_creature->AttackerStateUpdate(m_creature->getVictim());
m_creature->resetAttackTimer();
}
}
}
}
void ScriptedAI::EnterEvadeMode()
{
m_creature->InterruptNonMeleeSpells(true);
m_creature->RemoveAllAuras();
m_creature->DeleteThreatList();
m_creature->CombatStop();
m_creature->LoadCreaturesAddon();
if( m_creature->isAlive() )
m_creature->GetMotionMaster()->MoveTargetedHome();
m_creature->SetLootRecipient(NULL);
InCombat = false;
Reset();
}
void ScriptedAI::JustRespawned()
{
InCombat = false;
Reset();
}
void ScriptedAI::DoStartAttackAndMovement(Unit* victim, float distance, float angle)
{
if (!victim)
return;
if ( m_creature->Attack(victim, true) )
{
m_creature->GetMotionMaster()->MoveChase(victim, distance, angle);
m_creature->AddThreat(victim, 0.0f);
}
}
void ScriptedAI::DoStartAttackNoMovement(Unit* victim)
{
if (!victim)
return;
if ( m_creature->Attack(victim, true) )
{
m_creature->AddThreat(victim, 0.0f);
}
}
void ScriptedAI::DoMeleeAttackIfReady()
{
//Make sure our attack is ready and we aren't currently casting before checking distance
if( m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false))
{
//If we are within range melee the target
if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
{
m_creature->AttackerStateUpdate(m_creature->getVictim());
m_creature->resetAttackTimer();
}
}
}
void ScriptedAI::DoStopAttack()
{
if( m_creature->getVictim() != NULL )
{
m_creature->AttackStop();
}
}
void ScriptedAI::DoCast(Unit* victim, uint32 spellId, bool triggered)
{
if (!victim || m_creature->IsNonMeleeSpellCasted(false))
return;
m_creature->StopMoving();
m_creature->CastSpell(victim, spellId, triggered);
}
void ScriptedAI::DoCastSpell(Unit* who,SpellEntry const *spellInfo, bool triggered)
{
if (!who || m_creature->IsNonMeleeSpellCasted(false))
return;
m_creature->StopMoving();
m_creature->CastSpell(who, spellInfo, triggered);
}
void ScriptedAI::DoSay(const char* text, uint32 language, Unit* target)
{
if (target)m_creature->Say(text, language, target->GetGUID());
else m_creature->Say(text, language, 0);
}
void ScriptedAI::DoYell(const char* text, uint32 language, Unit* target)
{
if (target)m_creature->Yell(text, language, target->GetGUID());
else m_creature->Yell(text, language, 0);
}
void ScriptedAI::DoTextEmote(const char* text, Unit* target, bool IsBossEmote)
{
if (target)m_creature->TextEmote(text, target->GetGUID(), IsBossEmote);
else m_creature->TextEmote(text, 0, IsBossEmote);
}
void ScriptedAI::DoWhisper(const char* text, Unit* reciever, bool IsBossWhisper)
{
if (!reciever || reciever->GetTypeId() != TYPEID_PLAYER)
return;
m_creature->Whisper(text, reciever->GetGUID(), IsBossWhisper);
}
void ScriptedAI::DoPlaySoundToSet(Unit* unit, uint32 sound)
{
if (!unit)
return;
if (!GetSoundEntriesStore()->LookupEntry(sound))
{
error_log("SD2: Invalid soundId %u used in DoPlaySoundToSet (by unit TypeId %u, guid %u)", sound, unit->GetTypeId(), unit->GetGUID());
return;
}
WorldPacket data(4);
data.SetOpcode(SMSG_PLAY_SOUND);
data << uint32(sound);
unit->SendMessageToSet(&data,false);
}
Creature* ScriptedAI::DoSpawnCreature(uint32 id, float x, float y, float z, float angle, uint32 type, uint32 despawntime)
{
return m_creature->SummonCreature(id,m_creature->GetPositionX() + x,m_creature->GetPositionY() + y,m_creature->GetPositionZ() + z, angle, (TempSummonType)type, despawntime);
}
Unit* ScriptedAI::SelectUnit(SelectAggroTarget target, uint32 position)
{
//ThreatList m_threatlist;
std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
std::list<HostilReference*>::iterator i = m_threatlist.begin();
std::list<HostilReference*>::reverse_iterator r = m_threatlist.rbegin();
if (position >= m_threatlist.size() || !m_threatlist.size())
return NULL;
switch (target)
{
case SELECT_TARGET_RANDOM:
advance ( i , position + (rand() % (m_threatlist.size() - position ) ));
return Unit::GetUnit((*m_creature),(*i)->getUnitGuid());
break;
case SELECT_TARGET_TOPAGGRO:
advance ( i , position);
return Unit::GetUnit((*m_creature),(*i)->getUnitGuid());
break;
case SELECT_TARGET_BOTTOMAGGRO:
advance ( r , position);
return Unit::GetUnit((*m_creature),(*r)->getUnitGuid());
break;
}
return NULL;
}
SpellEntry const* ScriptedAI::SelectSpell(Unit* Target, int32 School, int32 Mechanic, SelectTarget Targets, uint32 PowerCostMin, uint32 PowerCostMax, float RangeMin, float RangeMax, SelectEffect Effects)
{
//No target so we can't cast
if (!Target)
return false;
//Silenced so we can't cast
if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
return false;
//Using the extended script system we first create a list of viable spells
SpellEntry const* Spell[4];
Spell[0] = 0;
Spell[1] = 0;
Spell[2] = 0;
Spell[3] = 0;
uint32 SpellCount = 0;
SpellEntry const* TempSpell;
SpellRangeEntry const* TempRange;
//Check if each spell is viable(set it to null if not)
for (uint32 i = 0; i < 4; i++)
{
TempSpell = GetSpellStore()->LookupEntry(m_creature->m_spells[i]);
//This spell doesn't exist
if (!TempSpell)
continue;
// Targets and Effects checked first as most used restrictions
//Check the spell targets if specified
if ( Targets && !(SpellSummary[m_creature->m_spells[i]].Targets & (1 << (Targets-1))) )
continue;
//Check the type of spell if we are looking for a specific spell type
if ( Effects && !(SpellSummary[m_creature->m_spells[i]].Effects & (1 << (Effects-1))) )
continue;
//Check for school if specified
if (School >= 0 && TempSpell->SchoolMask & School)
continue;
//Check for spell mechanic if specified
if (Mechanic >= 0 && TempSpell->Mechanic != Mechanic)
continue;
//Make sure that the spell uses the requested amount of power
if (PowerCostMin && TempSpell->manaCost < PowerCostMin)
continue;
if (PowerCostMax && TempSpell->manaCost > PowerCostMax)
continue;
//Continue if we don't have the mana to actually cast this spell
if (TempSpell->manaCost > m_creature->GetPower((Powers)TempSpell->powerType))
continue;
//Get the Range
TempRange = GetSpellRangeStore()->LookupEntry(TempSpell->rangeIndex);
//Spell has invalid range store so we can't use it
if (!TempRange)
continue;
//Check if the spell meets our range requirements
if (RangeMin && TempRange->maxRange < RangeMin)
continue;
if (RangeMax && TempRange->maxRange > RangeMax)
continue;
//Check if our target is in range
if (m_creature->IsWithinDistInMap(Target, TempRange->minRange) || !m_creature->IsWithinDistInMap(Target, TempRange->maxRange))
continue;
//All good so lets add it to the spell list
Spell[SpellCount] = TempSpell;
SpellCount++;
}
//We got our usable spells so now lets randomly pick one
if (!SpellCount)
return NULL;
return Spell[rand()%SpellCount];
}
bool ScriptedAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered)
{
//No target so we can't cast
if (!Target || !Spell)
return false;
//Silenced so we can't cast
if (!Triggered && m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))
return false;
//Check for power
if (!Triggered && m_creature->GetPower((Powers)Spell->powerType) < Spell->manaCost)
return false;
SpellRangeEntry const *TempRange = NULL;
TempRange = GetSpellRangeStore()->LookupEntry(Spell->rangeIndex);
//Spell has invalid range store so we can't use it
if (!TempRange)
return false;
//Unit is out of range of this spell
if (m_creature->GetDistance(Target) > TempRange->maxRange || m_creature->GetDistance(Target) < TempRange->minRange)
return false;
return true;
}
void FillSpellSummary()
{
SpellSummary = new TSpellSummary[GetSpellStore()->GetNumRows()];
SpellEntry const* TempSpell;
for (int i=0; i < GetSpellStore()->GetNumRows(); i++ )
{
SpellSummary[i].Effects = 0;
SpellSummary[i].Targets = 0;
TempSpell = GetSpellStore()->LookupEntry(i);
//This spell doesn't exist
if (!TempSpell)
continue;
for (int j=0; j<3; j++)
{
//Spell targets self
if ( TempSpell->EffectImplicitTargetA[j] == TARGET_SELF )
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SELF-1);
//Spell targets a single enemy
if ( TempSpell->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE ||
TempSpell->EffectImplicitTargetA[j] == TARGET_CURRENT_ENEMY_COORDINATES )
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_ENEMY-1);
//Spell targets AoE at enemy
if ( TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_AROUND_CASTER ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED )
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_ENEMY-1);
//Spell targets an enemy
if ( TempSpell->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE ||
TempSpell->EffectImplicitTargetA[j] == TARGET_CURRENT_ENEMY_COORDINATES ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_AROUND_CASTER ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED )
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_ENEMY-1);
//Spell targets a single friend(or self)
if ( TempSpell->EffectImplicitTargetA[j] == TARGET_SELF ||
TempSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_FRIEND ||
TempSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_PARTY )
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_FRIEND-1);
//Spell targets aoe friends
if ( TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER ||
TempSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_AROUND_CASTER)
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_FRIEND-1);
//Spell targets any friend(or self)
if ( TempSpell->EffectImplicitTargetA[j] == TARGET_SELF ||
TempSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_FRIEND ||
TempSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_PARTY ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER ||
TempSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY ||
TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_AROUND_CASTER)
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_FRIEND-1);
//Make sure that this spell includes a damage effect
if ( TempSpell->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE ||
TempSpell->Effect[j] == SPELL_EFFECT_INSTAKILL ||
TempSpell->Effect[j] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE ||
TempSpell->Effect[j] == SPELL_EFFECT_HEALTH_LEECH )
SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_DAMAGE-1);
//Make sure that this spell includes a healing effect (or an apply aura with a periodic heal)
if ( TempSpell->Effect[j] == SPELL_EFFECT_HEAL ||
TempSpell->Effect[j] == SPELL_EFFECT_HEAL_MAX_HEALTH ||
TempSpell->Effect[j] == SPELL_EFFECT_HEAL_MECHANICAL ||
(TempSpell->Effect[j] == SPELL_EFFECT_APPLY_AURA && TempSpell->EffectApplyAuraName[j]== 8 ))
SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_HEALING-1);
//Make sure that this spell applies an aura
if ( TempSpell->Effect[j] == SPELL_EFFECT_APPLY_AURA )
SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_AURA-1);
}
}
}
void ScriptedAI::DoZoneInCombat(Unit* pUnit)
{
if (!pUnit)
pUnit = m_creature;
Map *map = pUnit->GetMap();
if (!map->IsDungeon()) //use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated
{
error_log("SD2: DoZoneInCombat call for map that isn't an instance (pUnit entry = %d)", pUnit->GetTypeId() == TYPEID_UNIT ? ((Creature*)pUnit)->GetEntry() : 0);
return;
}
if (!pUnit->CanHaveThreatList() || pUnit->getThreatManager().isThreatListEmpty())
{
error_log("SD2: DoZoneInCombat called for creature that either cannot have threat list or has empty threat list (pUnit entry = %d)", pUnit->GetTypeId() == TYPEID_UNIT ? ((Creature*)pUnit)->GetEntry() : 0);
return;
}
InstanceMap::PlayerList const &PlayerList = ((InstanceMap*)map)->GetPlayers();
InstanceMap::PlayerList::const_iterator i;
for (i = PlayerList.begin(); i != PlayerList.end(); ++i)
{
if(!(*i)->isGameMaster())
pUnit->AddThreat(*i, 0.0f);
}
}
void ScriptedAI::DoResetThreat()
{
if (!m_creature->CanHaveThreatList() || m_creature->getThreatManager().isThreatListEmpty())
{
error_log("SD2: DoResetThreat called for creature that either cannot have threat list or has empty threat list (m_creature entry = %d)", m_creature->GetEntry());
return;
}
std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
std::list<HostilReference*>::iterator itr;
for(itr = m_threatlist.begin(); itr != m_threatlist.end(); ++itr)
{
Unit* pUnit = NULL;
pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid());
if(pUnit && m_creature->getThreatManager().getThreat(pUnit))
m_creature->getThreatManager().modifyThreatPercent(pUnit, -100);
}
}
void ScriptedAI::DoTeleportPlayer(Unit* pUnit, float x, float y, float z, float o)
{
if(!pUnit || pUnit->GetTypeId() != TYPEID_PLAYER)
{
if(pUnit)
error_log("SD2: Creature %u (Entry: %u) Tried to teleport non-player unit (Type: %u GUID: %u) to x: %f y:%f z: %f o: %f. Aborted.", m_creature->GetGUID(), m_creature->GetEntry(), pUnit->GetTypeId(), pUnit->GetGUID(), x, y, z, o);
return;
}
((Player*)pUnit)->TeleportTo(pUnit->GetMapId(), x, y, z, o, TELE_TO_NOT_LEAVE_COMBAT);
}
Unit* ScriptedAI::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
{
CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
Unit* pUnit = NULL;
MostHPMissingInRange u_check(m_creature, range, MinHPDiff);
MaNGOS::UnitLastSearcher<MostHPMissingInRange> searcher(pUnit, u_check);
/*
typedef TYPELIST_4(GameObject, Creature*except pets*, DynamicObject, Corpse*Bones*) AllGridObjectTypes;
This means that if we only search grid then we cannot possibly return pets or players so this is safe
*/
TypeContainerVisitor<MaNGOS::UnitLastSearcher<MostHPMissingInRange>, GridTypeMapContainer > grid_unit_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_unit_searcher, *(m_creature->GetMap()));
return pUnit;
}
std::list<Creature*> ScriptedAI::DoFindFriendlyCC(float range)
{
CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
std::list<Creature*> pList;
FriendlyCCedInRange u_check(m_creature, range);
MaNGOS::CreatureListSearcher<FriendlyCCedInRange> searcher(pList, u_check);
TypeContainerVisitor<MaNGOS::CreatureListSearcher<FriendlyCCedInRange>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_creature_searcher, *(m_creature->GetMap()));
return pList;
}
std::list<Creature*> ScriptedAI::DoFindFriendlyMissingBuff(float range, uint32 spellid)
{
CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
std::list<Creature*> pList;
FriendlyMissingBuffInRange u_check(m_creature, range, spellid);
MaNGOS::CreatureListSearcher<FriendlyMissingBuffInRange> searcher(pList, u_check);
TypeContainerVisitor<MaNGOS::CreatureListSearcher<FriendlyMissingBuffInRange>, GridTypeMapContainer > grid_creature_searcher(searcher);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_creature_searcher, *(m_creature->GetMap()));
return pList;
}
void Scripted_NoMovementAI::MoveInLineOfSight(Unit *who)
{
if( !m_creature->getVictim() && who->isTargetableForAttack() && ( m_creature->IsHostileTo( who )) && who->isInAccessablePlaceFor(m_creature) )
{
if (m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
return;
float attackRadius = m_creature->GetAttackDistance(who);
if( m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who) )
{
DoStartAttackNoMovement(who);
who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
if (!InCombat)
{
Aggro(who);
InCombat = true;
}
}
}
}
void Scripted_NoMovementAI::AttackStart(Unit* who)
{
if (!who)
return;
if (who->isTargetableForAttack())
{
//Begin attack
DoStartAttackNoMovement(who);
if (!InCombat)
{
Aggro(who);
InCombat = true;
}
}
}
+196
View File
@@ -0,0 +1,196 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef SC_CREATURE_H
#define SC_CREATURE_H
#include "CreatureAI.h"
#include "Creature.h"
//Spell targets used by SelectSpell
enum SelectTarget
{
SELECT_TARGET_DONTCARE = 0, //All target types allowed
SELECT_TARGET_SELF, //Only Self casting
SELECT_TARGET_SINGLE_ENEMY, //Only Single Enemy
SELECT_TARGET_AOE_ENEMY, //Only AoE Enemy
SELECT_TARGET_ANY_ENEMY, //AoE or Single Enemy
SELECT_TARGET_SINGLE_FRIEND, //Only Single Friend
SELECT_TARGET_AOE_FRIEND, //Only AoE Friend
SELECT_TARGET_ANY_FRIEND, //AoE or Single Friend
};
//Spell Effects used by SelectSpell
enum SelectEffect
{
SELECT_EFFECT_DONTCARE = 0, //All spell effects allowed
SELECT_EFFECT_DAMAGE, //Spell does damage
SELECT_EFFECT_HEALING, //Spell does healing
SELECT_EFFECT_AURA, //Spell applies an aura
};
//Selection method used by SelectTarget
enum SelectAggroTarget
{
SELECT_TARGET_RANDOM = 0, //Just selects a random target
SELECT_TARGET_TOPAGGRO, //Selects targes from top aggro to bottom
SELECT_TARGET_BOTTOMAGGRO, //Selects targets from bottom aggro to top
};
struct MANGOS_DLL_DECL ScriptedAI : public CreatureAI
{
ScriptedAI(Creature* creature) : m_creature(creature), InCombat(false) {}
~ScriptedAI() {}
//*************
//CreatureAI Functions
//*************
//Called if IsVisible(Unit *who) is true at each *who move
void MoveInLineOfSight(Unit *);
//Called at each attack of m_creature by any victim
void AttackStart(Unit *);
//Called at stoping attack by any attacker
void EnterEvadeMode();
//Called at any heal cast/item used (call non implemented in mangos)
void HealBy(Unit *healer, uint32 amount_healed) {}
// Called at any Damage to any victim (before damage apply)
void DamageDeal(Unit *done_to, uint32 &damage) {}
// Called at any Damage from any attacker (before damage apply)
void DamageTaken(Unit *done_by, uint32 &damage) {}
//Is unit visible for MoveInLineOfSight
bool IsVisible(Unit *who) const;
//Called at World update tick
void UpdateAI(const uint32);
//Called at creature death
void JustDied(Unit*){}
//Called at creature killing another unit
void KilledUnit(Unit*){}
// Called when the creature summon successfully other creature
void JustSummoned(Creature* ) {}
// Called when a summoned creature is despawned
void SummonedCreatureDespawn(Creature* /*unit*/) {}
// Called when hit by a spell
void SpellHit(Unit*, const SpellEntry*) {}
// Called when creature is spawned or respawned (for reseting variables)
void JustRespawned();
//Called at waypoint reached or PointMovement end
void MovementInform(uint32, uint32){}
//*************
// Variables
//*************
//Pointer to creature we are manipulating
Creature* m_creature;
//Bool for if we are in combat or not
bool InCombat;
//*************
//Pure virtual functions
//*************
//Called at creature reset either by death or evade
virtual void Reset() = 0;
//Called at creature aggro either by MoveInLOS or Attack Start
virtual void Aggro(Unit*) = 0;
//*************
//AI Helper Functions
//*************
//Start attack of victim and go to him
void DoStartAttackAndMovement(Unit* victim, float distance = 0, float angle = 0);
//Start attack on victim but do not move
void DoStartAttackNoMovement(Unit* victim);
//Do melee swing of current victim if in rnage and ready and not casting
void DoMeleeAttackIfReady();
//Stop attack of current victim
void DoStopAttack();
//Cast spell by Id
void DoCast(Unit* victim, uint32 spellId, bool triggered = false);
//Cast spell by spell info
void DoCastSpell(Unit* who,SpellEntry const *spellInfo, bool triggered = false);
//Creature say
void DoSay(const char* text, uint32 language, Unit* target);
//Creature Yell
void DoYell(const char* text, uint32 language, Unit* target);
//Creature Text emote, optional bool for boss emote text
void DoTextEmote(const char* text, Unit* target, bool IsBossEmote = false);
//Creature whisper, optional bool for boss whisper
void DoWhisper(const char* text, Unit* reciever, bool IsBossWhisper = false);
//Plays a sound to all nearby players
void DoPlaySoundToSet(Unit* unit, uint32 sound);
//Places the entire map into combat with creature
void DoZoneInCombat(Unit* pUnit = 0);
//Drops all threat to 0%. Does not remove players from the threat list
void DoResetThreat();
//Teleports a player without dropping threat (only teleports to same map)
void DoTeleportPlayer(Unit* pUnit, float x, float y, float z, float o);
//Returns friendly unit with the most amount of hp missing from max hp
Unit* DoSelectLowestHpFriendly(float range, uint32 MinHPDiff = 1);
//Returns a list of friendly CC'd units within range
std::list<Creature*> DoFindFriendlyCC(float range);
//Returns a list of all friendly units missing a specific buff within range
std::list<Creature*> DoFindFriendlyMissingBuff(float range, uint32 spellid);
//Spawns a creature relative to m_creature
Creature* DoSpawnCreature(uint32 id, float x, float y, float z, float angle, uint32 type, uint32 despawntime);
//Selects a unit from the creature's current aggro list
Unit* SelectUnit(SelectAggroTarget target, uint32 position);
//Returns spells that meet the specified criteria from the creatures spell list
SpellEntry const* SelectSpell(Unit* Target, int32 School, int32 Mechanic, SelectTarget Targets, uint32 PowerCostMin, uint32 PowerCostMax, float RangeMin, float RangeMax, SelectEffect Effect);
//Checks if you can cast the specified spell
bool CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered = false);
};
struct MANGOS_DLL_DECL Scripted_NoMovementAI : public ScriptedAI
{
Scripted_NoMovementAI(Creature* creature) : ScriptedAI(creature) {}
//Called if IsVisible(Unit *who) is true at each *who move
void MoveInLineOfSight(Unit *);
//Called at each attack of m_creature by any victim
void AttackStart(Unit *);
};
#endif
+183
View File
@@ -0,0 +1,183 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef SC_PLAYER_H
#define SC_PLAYER_H
#include "Player.h"
#include "GossipDef.h"
#include "QuestDef.h"
// Gossip Item Text
#define GOSSIP_TEXT_BROWSE_GOODS "I'd like to browse your goods."
#define GOSSIP_TEXT_TRAIN "Train me!"
#define GOSSIP_TEXT_BANK "The Bank"
#define GOSSIP_TEXT_WINDRIDER "Wind rider master"
#define GOSSIP_TEXT_GRYPHON "Gryphon Master"
#define GOSSIP_TEXT_BATHANDLER "Bat Handler"
#define GOSSIP_TEXT_HIPPOGRYPH "Hippogryph Master"
#define GOSSIP_TEXT_FLIGHTMASTER "Flight Master"
#define GOSSIP_TEXT_AUCTIONHOUSE "Auction House"
#define GOSSIP_TEXT_GUILDMASTER "Guild Master"
#define GOSSIP_TEXT_INN "The Inn"
#define GOSSIP_TEXT_MAILBOX "Mailbox"
#define GOSSIP_TEXT_STABLEMASTER "Stable Master"
#define GOSSIP_TEXT_WEAPONMASTER "Weapons Trainer"
#define GOSSIP_TEXT_BATTLEMASTER "Battlemaster"
#define GOSSIP_TEXT_CLASSTRAINER "Class Trainer"
#define GOSSIP_TEXT_PROFTRAINER "Profession Trainer"
#define GOSSIP_TEXT_OFFICERS "The officers` lounge"
#define GOSSIP_TEXT_ALTERACVALLEY "Alterac Valley"
#define GOSSIP_TEXT_ARATHIBASIN "Arathi Basin"
#define GOSSIP_TEXT_WARSONGULCH "Warsong Gulch"
#define GOSSIP_TEXT_ARENA "Arena"
#define GOSSIP_TEXT_EYEOFTHESTORM "Eye of The Storm"
#define GOSSIP_TEXT_DRUID "Druid"
#define GOSSIP_TEXT_HUNTER "Hunter"
#define GOSSIP_TEXT_PRIEST "Priest"
#define GOSSIP_TEXT_ROGUE "Rogue"
#define GOSSIP_TEXT_WARRIOR "Warrior"
#define GOSSIP_TEXT_PALADIN "Paladin"
#define GOSSIP_TEXT_SHAMAN "Shaman"
#define GOSSIP_TEXT_MAGE "Mage"
#define GOSSIP_TEXT_WARLOCK "Warlock"
#define GOSSIP_TEXT_ALCHEMY "Alchemy"
#define GOSSIP_TEXT_BLACKSMITHING "Blacksmithing"
#define GOSSIP_TEXT_COOKING "Cooking"
#define GOSSIP_TEXT_ENCHANTING "Enchanting"
#define GOSSIP_TEXT_ENGINEERING "Engineering"
#define GOSSIP_TEXT_FIRSTAID "First Aid"
#define GOSSIP_TEXT_HERBALISM "Herbalism"
#define GOSSIP_TEXT_LEATHERWORKING "Leatherworking"
#define GOSSIP_TEXT_POISONS "Poisons"
#define GOSSIP_TEXT_TAILORING "Tailoring"
#define GOSSIP_TEXT_MINING "Mining"
#define GOSSIP_TEXT_FISHING "Fishing"
#define GOSSIP_TEXT_SKINNING "Skinning"
#define GOSSIP_TEXT_JEWELCRAFTING "Jewelcrafting"
#define GOSSIP_TEXT_IRONFORGE_BANK "Bank of Ironforge"
#define GOSSIP_TEXT_STORMWIND_BANK "Bank of Stormwind"
#define GOSSIP_TEXT_DEEPRUNTRAM "Deeprun Tram"
#define GOSSIP_TEXT_ZEPPLINMASTER "Zeppelin master"
#define GOSSIP_TEXT_FERRY "Rut'theran Ferry"
// Skill defines
#define TRADESKILL_ALCHEMY 1
#define TRADESKILL_BLACKSMITHING 2
#define TRADESKILL_COOKING 3
#define TRADESKILL_ENCHANTING 4
#define TRADESKILL_ENGINEERING 5
#define TRADESKILL_FIRSTAID 6
#define TRADESKILL_HERBALISM 7
#define TRADESKILL_LEATHERWORKING 8
#define TRADESKILL_POISONS 9
#define TRADESKILL_TAILORING 10
#define TRADESKILL_MINING 11
#define TRADESKILL_FISHING 12
#define TRADESKILL_SKINNING 13
#define TRADESKILL_JEWLCRAFTING 14
#define TRADESKILL_LEVEL_NONE 0
#define TRADESKILL_LEVEL_APPRENTICE 1
#define TRADESKILL_LEVEL_JOURNEYMAN 2
#define TRADESKILL_LEVEL_EXPERT 3
#define TRADESKILL_LEVEL_ARTISAN 4
#define TRADESKILL_LEVEL_MASTER 5
// Gossip defines
#define GOSSIP_ACTION_TRADE 1
#define GOSSIP_ACTION_TRAIN 2
#define GOSSIP_ACTION_TAXI 3
#define GOSSIP_ACTION_GUILD 4
#define GOSSIP_ACTION_BATTLE 5
#define GOSSIP_ACTION_BANK 6
#define GOSSIP_ACTION_INN 7
#define GOSSIP_ACTION_HEAL 8
#define GOSSIP_ACTION_TABARD 9
#define GOSSIP_ACTION_AUCTION 10
#define GOSSIP_ACTION_INN_INFO 11
#define GOSSIP_ACTION_UNLEARN 12
#define GOSSIP_ACTION_INFO_DEF 1000
#define GOSSIP_SENDER_MAIN 1
#define GOSSIP_SENDER_INN_INFO 2
#define GOSSIP_SENDER_INFO 3
#define GOSSIP_SENDER_SEC_PROFTRAIN 4
#define GOSSIP_SENDER_SEC_CLASSTRAIN 5
#define GOSSIP_SENDER_SEC_BATTLEINFO 6
#define GOSSIP_SENDER_SEC_BANK 7
#define GOSSIP_SENDER_SEC_INN 8
#define GOSSIP_SENDER_SEC_MAILBOX 9
#define GOSSIP_SENDER_SEC_STABLEMASTER 10
#define DEFAULT_GOSSIP_MESSAGE 0xffffff
extern uint32 GetSkillLevel(Player *player,uint32 skill);
// Defined fuctions to use with player.
// This fuction add's a menu item,
// a - Icon Id
// b - Text
// c - Sender(this is to identify the current Menu with this item)
// d - Action (identifys this Menu Item)
// e - Text to be displayed in pop up box
// f - Money value in pop up box
#define ADD_GOSSIP_ITEM(a,b,c,d) PlayerTalkClass->GetGossipMenu()->AddMenuItem(a,b,c,d,"",0)
#define ADD_GOSSIP_ITEM_EXTENDED(a,b,c,d,e,f) PlayerTalkClass->GetGossipMenu()->AddMenuItem(a,b,c,d,e,f)
// This fuction Sends the current menu to show to client, a - NPCTEXTID(uint32) , b - npc guid(uint64)
#define SEND_GOSSIP_MENU(a,b) PlayerTalkClass->SendGossipMenu(a,b)
// This fuction shows POI(point of interest) to client.
// a - position X
// b - position Y
// c - Icon Id
// d - Flags
// e - Data
// f - Location Name
#define SEND_POI(a,b,c,d,e,f) PlayerTalkClass->SendPointOfInterest(a,b,c,d,e,f)
// Closes the Menu
#define CLOSE_GOSSIP_MENU() PlayerTalkClass->CloseGossip()
// Fuction to tell to client the details
// a - quest object
// b - npc guid(uint64)
// c - Activate accept(bool)
#define SEND_QUEST_DETAILS(a,b,c) PlayerTalkClass->SendQuestDetails(a,b,c)
// Fuction to tell to client the requested items to complete quest
// a - quest object
// b - npc guid(uint64)
// c - Iscompletable(bool)
// d - close at cancel(bool) - in case single incomplite ques
#define SEND_REQUESTEDITEMS(a,b,c,d) PlayerTalkClass->SendRequestedItems(a,b,c,d)
// Fuctions to send NPC lists, a - is always the npc guid(uint64)
#define SEND_VENDORLIST(a) GetSession()->SendListInventory(a)
#define SEND_TRAINERLIST(a) GetSession()->SendTrainerList(a)
#define SEND_BANKERLIST(a) GetSession()->SendShowBank(a)
#define SEND_TABARDLIST(a) GetSession()->SendTabardVendorActivate(a)
#define SEND_AUCTIONLIST(a) GetSession()->SendAuctionHello(a)
#define SEND_TAXILIST(a) GetSession()->SendTaxiStatus(a)
// Ressurect's the player if is dead.
#define SEND_SPRESURRECT() GetSession()->SendSpiritResurrect()
// Get the player's honor rank.
#define GET_HONORRANK() GetHonorRank()
// -----------------------------------
// defined fuctions to use with Creature
#define QUEST_DIALOG_STATUS(a,b,c) GetSession()->getDialogStatus(a,b,c)
#endif
@@ -0,0 +1,131 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef SC_GRIDSEARCH_H
#define SC_GRIDSEARCH_H
#include "Unit.h"
#include "GameObject.h"
#include "Cell.h"
#include "CellImpl.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
//Used in:
//sc_creature.cpp - DoSelectLowestHpFriendly()
class MostHPMissingInRange
{
public:
MostHPMissingInRange(Unit const* obj, float range, uint32 hp) : i_obj(obj), i_range(range), i_hp(hp) {}
bool operator()(Unit* u)
{
if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) && u->GetMaxHealth() - u->GetHealth() > i_hp)
{
i_hp = u->GetMaxHealth() - u->GetHealth();
return true;
}
return false;
}
private:
Unit const* i_obj;
float i_range;
uint32 i_hp;
};
//Used in:
//sc_creature.cpp - DoFindFriendlyCC()
class FriendlyCCedInRange
{
public:
FriendlyCCedInRange(Unit const* obj, float range) : i_obj(obj), i_range(range) {}
bool operator()(Unit* u)
{
if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) &&
(u->isFeared() || u->isCharmed() || u->isFrozen() || u->hasUnitState(UNIT_STAT_STUNDED) || u->hasUnitState(UNIT_STAT_STUNDED) || u->hasUnitState(UNIT_STAT_CONFUSED)))
{
return true;
}
return false;
}
private:
Unit const* i_obj;
float i_range;
};
//Used in:
//sc_creature.cpp - DoFindFriendlyMissingBuff()
class FriendlyMissingBuffInRange
{
public:
FriendlyMissingBuffInRange(Unit const* obj, float range, uint32 spellid) : i_obj(obj), i_range(range), i_spell(spellid) {}
bool operator()(Unit* u)
{
if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) &&
!(u->HasAura(i_spell, 0) || u->HasAura(i_spell, 1) || u->HasAura(i_spell, 2)))
{
return true;
}
return false;
}
private:
Unit const* i_obj;
float i_range;
uint32 i_spell;
};
//Used in:
//hyjalAI.cpp
class AllFriendlyCreaturesInGrid
{
public:
AllFriendlyCreaturesInGrid(Unit const* obj) : pUnit(obj) {}
bool operator() (Unit* u)
{
if(u->isAlive() && u->GetVisibility() == VISIBILITY_ON && u->IsFriendlyTo(pUnit))
return true;
return false;
}
private:
Unit const* pUnit;
};
//Used in:
//hyjalAI.cpp
class AllGameObjectsWithEntryInGrid
{
public:
AllGameObjectsWithEntryInGrid(uint32 ent) : entry(ent) {}
bool operator() (GameObject* g)
{
if(g->GetEntry() == entry)
return true;
return false;
}
private:
uint32 entry;
};
class AllCreaturesOfEntryInRange
{
public:
AllCreaturesOfEntryInRange(Unit const* obj, uint32 ent, float ran) : pUnit(obj), entry(ent), range(ran) {}
bool operator() (Unit* u)
{
if(u->GetEntry() == entry && pUnit->IsWithinDistInMap(u, range))
return true;
return false;
}
private:
Unit const* pUnit;
uint32 entry;
float range;
};
#endif
@@ -0,0 +1,48 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef SC_INSTANCE_H
#define SC_INSTANCE_H
#include "InstanceData.h"
#include "Map.h"
enum EncounterState
{
NOT_STARTED = 0,
IN_PROGRESS = 1,
FAIL = 2,
DONE = 3
};
#define OUT_SAVE_INST_DATA debug_log("SD2: Saving Instance Data for Instance %s (Map %d, Instance Id %d)", instance->GetMapName(), instance->GetId(), instance->GetInstanceId())
#define OUT_SAVE_INST_DATA_COMPLETE debug_log("SD2: Saving Instance Data for Instance %s (Map %d, Instance Id %d) completed.", instance->GetMapName(), instance->GetId(), instance->GetInstanceId())
#define OUT_LOAD_INST_DATA(a) debug_log("SD2: Loading Instance Data for Instance %s (Map %d, Instance Id %d). Input is '%s'", instance->GetMapName(), instance->GetId(), instance->GetInstanceId(), a)
#define OUT_LOAD_INST_DATA_COMPLETE debug_log("SD2: Instance Data Load for Instance %s (Map %d, Instance Id: %d) is complete.",instance->GetMapName(), instance->GetId(), instance->GetInstanceId())
#define OUT_LOAD_INST_DATA_FAIL error_log("SD2: Unable to load Instance Data for Instance %s (Map %d, Instance Id: %d).",instance->GetMapName(), instance->GetId(), instance->GetInstanceId())
class MANGOS_DLL_DECL ScriptedInstance : public InstanceData
{
public:
ScriptedInstance(Map *map) : InstanceData(map) {}
~ScriptedInstance() {}
//All-purpose data storage 64 bit
virtual uint64 GetData64(uint32) {return 0; }
virtual void SetData64(uint32, uint64) { }
//All-purpose data storage 32 bit
virtual uint32 GetData(uint32) { return 0; }
virtual void SetData(uint32, uint32 data) {}
// Called every instance update
virtual void Update(uint32) {}
// Save and Load instance data to the database
const char* Save() { return NULL; }
void Load(const char* in) { }
};
#endif
@@ -0,0 +1,40 @@
Index: configure.ac
===================================================================
--- configure.ac (revision 4106)
+++ configure.ac (working copy)
@@ -192,7 +192,9 @@
src/mangosd/Makefile
src/mangosd/mangosd.conf
src/bindings/Makefile
- src/bindings/universal/Makefile
+ src/bindings/ScriptDev2/Makefile
+ src/bindings/ScriptDev2/sql/Makefile
+ src/bindings/ScriptDev2/sql/Updates/Makefile
])
## Disabled Makefiles, until they are ready for a successful make and
Index: src/bindings/Makefile.am
===================================================================
--- src/bindings/Makefile.am (revision 4106)
+++ src/bindings/Makefile.am (working copy)
@@ -14,4 +14,4 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-SUBDIRS = universal
+SUBDIRS = ScriptDev2
Index: src/mangosd/Makefile.am
===================================================================
--- src/mangosd/Makefile.am (revision 4106)
+++ src/mangosd/Makefile.am (working copy)
@@ -33,8 +33,8 @@
WorldRunnable.h
## Link world daemon against the shared library
-mangos_worldd_LDADD = ../bindings/universal/libmangosscript.la ../game/libmangosgame.a ../shared/libmangosdatabase.a ../shared/libmangosconfig.a ../shared/libmangosauth.a ../shared/libmangosshared.a ../shared/libmangosvmaps.a ../shared/libmangosnetwork.a ../framework/libmangosframework.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
-mangos_worldd_LDFLAGS = -L../../dep/src/zthread -L../../dep/src/g3dlite -L../bindings/universal/ $(MYSQL_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB) -export-dynamic
+mangos_worldd_LDADD = ../bindings/ScriptDev2/libmangosscript.la ../game/libmangosgame.a ../shared/libmangosdatabase.a ../shared/libmangosconfig.a ../shared/libmangosauth.a ../shared/libmangosshared.a ../shared/libmangosvmaps.a ../shared/libmangosnetwork.a ../framework/libmangosframework.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
+mangos_worldd_LDFLAGS = -L../../dep/src/zthread -L../../dep/src/g3dlite -L../bindings/ScriptDev2/ $(MYSQL_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB) -export-dynamic
## Additional files to include when running 'make dist'
# Include world daemon configuration
@@ -0,0 +1,40 @@
Index: configure.ac
===================================================================
--- configure.ac (revision 4241)
+++ configure.ac (working copy)
@@ -223,7 +223,9 @@
src/mangosd/Makefile
src/mangosd/mangosd.conf
src/bindings/Makefile
- src/bindings/universal/Makefile
+ src/bindings/ScriptDev2/Makefile
+ src/bindings/ScriptDev2/sql/Makefile
+ src/bindings/ScriptDev2/sql/Updates/Makefile
])
## Disabled Makefiles, until they are ready for a successful make and
Index: src/bindings/Makefile.am
===================================================================
--- src/bindings/Makefile.am (revision 4241)
+++ src/bindings/Makefile.am (working copy)
@@ -14,4 +14,4 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-SUBDIRS = universal
+SUBDIRS = ScriptDev2
Index: src/mangosd/Makefile.am
===================================================================
--- src/mangosd/Makefile.am (revision 4241)
+++ src/mangosd/Makefile.am (working copy)
@@ -33,8 +33,8 @@
WorldRunnable.h
## Link world daemon against the shared library
-mangos_worldd_LDADD = ../bindings/universal/libmangosscript.la ../game/libmangosgame.a ../shared/libmangosdatabase.a ../shared/libmangosconfig.a ../shared/libmangosauth.a ../shared/libmangosshared.a ../shared/libmangosvmaps.a ../shared/libmangosnetwork.a ../framework/libmangosframework.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
-mangos_worldd_LDFLAGS = -L../../dep/src/zthread -L../../dep/src/g3dlite -L../bindings/universal/ $(MYSQL_LIBS) $(POSTGRE_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB) -export-dynamic
+mangos_worldd_LDADD = ../bindings/ScriptDev2/libmangosscript.la ../game/libmangosgame.a ../shared/libmangosdatabase.a ../shared/libmangosconfig.a ../shared/libmangosauth.a ../shared/libmangosshared.a ../shared/libmangosvmaps.a ../shared/libmangosnetwork.a ../framework/libmangosframework.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
+mangos_worldd_LDFLAGS = -L../../dep/src/zthread -L../../dep/src/g3dlite -L../bindings/ScriptDev2/ $(MYSQL_LIBS) $(POSTGRE_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB) -export-dynamic
## Additional files to include when running 'make dist'
# Include world daemon configuration
@@ -0,0 +1,40 @@
Index: configure.ac
===================================================================
--- configure.ac (revision 4241)
+++ configure.ac (working copy)
@@ -223,7 +223,9 @@
src/mangosd/Makefile
src/mangosd/mangosd.conf
src/bindings/Makefile
- src/bindings/universal/Makefile
+ src/bindings/ScriptDev2/Makefile
+ src/bindings/ScriptDev2/sql/Makefile
+ src/bindings/ScriptDev2/sql/Updates/Makefile
])
## Disabled Makefiles, until they are ready for a successful make and
Index: src/bindings/Makefile.am
===================================================================
--- src/bindings/Makefile.am (revision 4241)
+++ src/bindings/Makefile.am (working copy)
@@ -14,4 +14,4 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-SUBDIRS = universal
+SUBDIRS = ScriptDev2
Index: src/mangosd/Makefile.am
===================================================================
--- src/mangosd/Makefile.am (revision 4241)
+++ src/mangosd/Makefile.am (working copy)
@@ -33,8 +33,8 @@
WorldRunnable.h
## Link world daemon against the shared library
-mangos_worldd_LDADD = ../bindings/universal/libmangosscript.la ../game/libmangosgame.a ../shared/libmangosdatabase.a ../shared/libmangosconfig.a ../shared/libmangosauth.a ../shared/libmangosshared.a ../shared/libmangosvmaps.a ../shared/libmangosnetwork.a ../framework/libmangosframework.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
-mangos_worldd_LDFLAGS = -L../../dep/src/zthread -L../../dep/src/g3dlite -L../bindings/universal/ $(MYSQL_LIBS) $(POSTGRE_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB) -export-dynamic
+mangos_worldd_LDADD = ../bindings/ScriptDev2/libmangosscript.la ../game/libmangosgame.a ../shared/libmangosdatabase.a ../shared/libmangosconfig.a ../shared/libmangosauth.a ../shared/libmangosshared.a ../shared/libmangosvmaps.a ../shared/libmangosnetwork.a ../framework/libmangosframework.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
+mangos_worldd_LDFLAGS = -L../../dep/src/zthread -L../../dep/src/g3dlite -L../bindings/ScriptDev2/ $(MYSQL_LIBS) $(POSTGRE_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB) -export-dynamic
## Additional files to include when running 'make dist'
# Include world daemon configuration
@@ -0,0 +1,40 @@
Index: src/mangosd/Makefile.am
===================================================================
--- src/mangosd/Makefile.am (revision 4799)
+++ src/mangosd/Makefile.am (working copy)
@@ -33,8 +33,8 @@
WorldRunnable.h
## Link world daemon against the shared library
-mangos_worldd_LDADD = ../bindings/universal/libmangosscript.la ../game/libmangosgame.a ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/vmap/libmangosvmaps.a ../shared/Network/libmangosnetwork.a ../framework/libmangosframework.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
-mangos_worldd_LDFLAGS = -L../../dep/src/zthread -L../../dep/src/g3dlite -L../bindings/universal/ $(MYSQL_LIBS) $(POSTGRE_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB) -export-dynamic
+mangos_worldd_LDADD = ../bindings/ScriptDev2/libmangosscript.la ../game/libmangosgame.a ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/vmap/libmangosvmaps.a ../shared/Network/libmangosnetwork.a ../framework/libmangosframework.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
+mangos_worldd_LDFLAGS = -L../../dep/src/zthread -L../../dep/src/g3dlite -L../bindings/ScriptDev2/ $(MYSQL_LIBS) $(POSTGRE_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB) -export-dynamic
## Additional files to include when running 'make dist'
# Include world daemon configuration
Index: src/bindings/Makefile.am
===================================================================
--- src/bindings/Makefile.am (revision 4799)
+++ src/bindings/Makefile.am (working copy)
@@ -14,4 +14,4 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-SUBDIRS = universal
+SUBDIRS = ScriptDev2
Index: configure.ac
===================================================================
--- configure.ac (revision 4799)
+++ configure.ac (working copy)
@@ -228,7 +228,9 @@
src/mangosd/Makefile
src/mangosd/mangosd.conf
src/bindings/Makefile
- src/bindings/universal/Makefile
+ src/bindings/ScriptDev2/Makefile
+ src/bindings/ScriptDev2/sql/Makefile
+ src/bindings/ScriptDev2/sql/Updates/Makefile
])
## Disabled Makefiles, until they are ready for a successful make and
@@ -0,0 +1,42 @@
Index: src/mangosd/Makefile.am
===================================================================
--- src/mangosd/Makefile.am (revision 5049)
+++ src/mangosd/Makefile.am (working copy)
@@ -33,8 +33,8 @@
WorldRunnable.h
## Link world daemon against the shared library
-mangos_worldd_LDADD = ../bindings/universal/libmangosscript.la ../game/libmangosgame.a ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/vmap/libmangosvmaps.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
-mangos_worldd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/zthread -L../../dep/src/g3dlite -L../bindings/universal/ $(MYSQL_LIBS) $(POSTGRE_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB) -export-dynamic
+mangos_worldd_LDADD = ../bindings/ScriptDev2/libmangosscript.la ../game/libmangosgame.a ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/vmap/libmangosvmaps.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
+mangos_worldd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/zthread -L../../dep/src/g3dlite -L../bindings/ScriptDev2/ $(MYSQL_LIBS) $(POSTGRE_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB) -export-dynamic
## Additional files to include when running 'make dist'
# Include world daemon configuration
Index: src/bindings/Makefile.am
===================================================================
--- src/bindings/Makefile.am (revision 5049)
+++ src/bindings/Makefile.am (working copy)
@@ -14,4 +14,4 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-SUBDIRS = universal
+SUBDIRS = ScriptDev2
Index: configure.ac
===================================================================
--- configure.ac (revision 5049)
+++ configure.ac (working copy)
@@ -228,7 +228,10 @@
src/mangosd/Makefile
src/mangosd/mangosd.conf
src/bindings/Makefile
- src/bindings/universal/Makefile
+ src/bindings/ScriptDev2/Makefile
+ src/bindings/ScriptDev2/config.h
+ src/bindings/ScriptDev2/sql/Makefile
+ src/bindings/ScriptDev2/sql/Updates/Makefile
])
## Disabled Makefiles, until they are ready for a successful make and
@@ -0,0 +1,41 @@
Index: configure.ac
===================================================================
--- configure.ac (revision 6491)
+++ configure.ac (working copy)
@@ -238,7 +238,10 @@
src/mangosd/Makefile
src/mangosd/mangosd.conf
src/bindings/Makefile
- src/bindings/universal/Makefile
+ src/bindings/ScriptDev2/Makefile
+ src/bindings/ScriptDev2/config.h
+ src/bindings/ScriptDev2/sql/Makefile
+ src/bindings/ScriptDev2/sql/Updates/Makefile
])
## Disabled Makefiles, until they are ready for a successful make and
Index: src/bindings/Makefile.am
===================================================================
--- src/bindings/Makefile.am (revision 6491)
+++ src/bindings/Makefile.am (working copy)
@@ -14,4 +14,4 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-SUBDIRS = universal
+SUBDIRS = ScriptDev2
Index: src/mangosd/Makefile.am
===================================================================
--- src/mangosd/Makefile.am (revision 6491)
+++ src/mangosd/Makefile.am (working copy)
@@ -33,8 +33,8 @@
WorldRunnable.h
## Link world daemon against the shared library
-mangos_worldd_LDADD = ../bindings/universal/libmangosscript.la ../game/libmangosgame.a ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/vmap/libmangosvmaps.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
-mangos_worldd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/zthread -L../../dep/src/g3dlite -L../bindings/universal/ $(MYSQL_LIBS) $(POSTGRE_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB) -export-dynamic
+mangos_worldd_LDADD = ../bindings/ScriptDev2/libmangosscript.la ../game/libmangosgame.a ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/vmap/libmangosvmaps.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
+mangos_worldd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/zthread -L../../dep/src/g3dlite -L../bindings/ScriptDev2/ $(MYSQL_LIBS) $(POSTGRE_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB) -export-dynamic
## Additional files to include when running 'make dist'
# Include world daemon configuration
@@ -0,0 +1,42 @@
Index: src/mangosd/Makefile.am
===================================================================
--- src/mangosd/Makefile.am (revision 6657)
+++ src/mangosd/Makefile.am (working copy)
@@ -33,8 +33,8 @@
WorldRunnable.h
## Link world daemon against the shared library
-mangos_worldd_LDADD = ../bindings/universal/libmangosscript.la ../game/libmangosgame.a ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/vmap/libmangosvmaps.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
-mangos_worldd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/zthread -L../../dep/src/g3dlite -L../bindings/universal/ $(MYSQL_LIBS) $(POSTGRE_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB) -export-dynamic
+mangos_worldd_LDADD = ../bindings/ScriptDev2/libmangosscript.la ../game/libmangosgame.a ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/vmap/libmangosvmaps.a ../framework/libmangosframework.a ../../dep/src/sockets/libmangossockets.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
+mangos_worldd_LDFLAGS = -L../../dep/src/sockets -L../../dep/src/zthread -L../../dep/src/g3dlite -L../bindings/ScriptDev2/ $(MYSQL_LIBS) $(POSTGRE_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB) -export-dynamic
## Additional files to include when running 'make dist'
# Include world daemon configuration
Index: src/bindings/Makefile.am
===================================================================
--- src/bindings/Makefile.am (revision 6656)
+++ src/bindings/Makefile.am (working copy)
@@ -14,4 +14,4 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-SUBDIRS = universal
+SUBDIRS = ScriptDev2
Index: configure.ac
===================================================================
--- configure.ac (revision 6657)
+++ configure.ac (working copy)
@@ -238,7 +238,11 @@
src/mangosd/Makefile
src/mangosd/mangosd.conf.dist
src/bindings/Makefile
- src/bindings/universal/Makefile
+ src/bindings/ScriptDev2/Makefile
+ src/bindings/ScriptDev2/scriptdev2.conf.dist
+ src/bindings/ScriptDev2/config.h
+ src/bindings/ScriptDev2/sql/Makefile
+ src/bindings/ScriptDev2/sql/Updates/Makefile
])
## Disabled Makefiles, until they are ready for a successful make and
@@ -0,0 +1,44 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Areatrigger_Scripts
SD%Complete: 100
SDComment: Scripts for areatriggers
SDCategory: Areatrigger
EndScriptData */
/* ContentData
at_test script test only
EndContentData */
#include "precompiled.h"
bool ATtest(Player *player, AreaTriggerEntry *at)
{
player->Say("Hi!",LANG_UNIVERSAL);
return true;
}
void AddSC_areatrigger_scripts()
{
Script *newscript;
newscript = new Script;
newscript->Name="at_test";
newscript->pAreaTrigger = ATtest;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,156 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Emeriss
SD%Complete: 90
SDComment: Teleport function & Mark of Nature missing
SDCategory: Bosses
EndScriptData */
#include "precompiled.h"
#define SPELL_SLEEP 24777
#define SPELL_NOXIOUSBREATH 24818
#define SPELL_TAILSWEEP 15847
//#define SPELL_MARKOFNATURE 25040 // Not working
#define SPELL_VOLATILEINFECTION 24928
#define SPELL_CORRUPTIONOFEARTH 24910
struct MANGOS_DLL_DECL boss_emerissAI : public ScriptedAI
{
boss_emerissAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 Sleep_Timer;
uint32 NoxiousBreath_Timer;
uint32 TailSweep_Timer;
//uint32 MarkOfNature_Timer;
uint32 VolatileInfection_Timer;
uint32 CorruptionofEarth1_Timer;
uint32 CorruptionofEarth2_Timer;
uint32 CorruptionofEarth3_Timer;
void Reset()
{
Sleep_Timer = 15000 + rand()%5000;
NoxiousBreath_Timer = 8000;
TailSweep_Timer = 4000;
//MarkOfNature_Timer = 45000;
VolatileInfection_Timer = 12000;
CorruptionofEarth1_Timer = 0;
CorruptionofEarth2_Timer = 0;
CorruptionofEarth3_Timer = 0;
}
void Aggro(Unit *who) {}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
//Sleep_Timer
if (Sleep_Timer < diff)
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_SLEEP);
Sleep_Timer = 8000 + rand()%8000;
}else Sleep_Timer -= diff;
//NoxiousBreath_Timer
if (NoxiousBreath_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_NOXIOUSBREATH);
NoxiousBreath_Timer = 14000 + rand()%6000;
}else NoxiousBreath_Timer -= diff;
//Tailsweep every 2 seconds
if (TailSweep_Timer < diff)
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_TAILSWEEP);
TailSweep_Timer = 2000;
}else TailSweep_Timer -= diff;
//MarkOfNature_Timer
//if (MarkOfNature_Timer < diff)
//{
// DoCast(m_creature->getVictim(),SPELL_MARKOFNATURE);
// MarkOfNature_Timer = 45000;
//}else MarkOfNature_Timer -= diff;
//VolatileInfection_Timer
if (VolatileInfection_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_VOLATILEINFECTION);
VolatileInfection_Timer = 7000 + rand()%5000;
}else VolatileInfection_Timer -= diff;
//CorruptionofEarth_Timer
if ( (int) (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() +0.5) == 75)
{
if (CorruptionofEarth1_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_CORRUPTIONOFEARTH);
//1 minutes for next one. Means not again with this health value
CorruptionofEarth1_Timer = 60000;
} else CorruptionofEarth1_Timer -= diff;
}
//CorruptionofEarth_Timer
if ( (int) (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() +0.5) == 50)
{
if (CorruptionofEarth2_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_CORRUPTIONOFEARTH);
//1 minutes for next one. Means not again with this health value
CorruptionofEarth2_Timer = 60000;
} else CorruptionofEarth2_Timer -= diff;
}
//CorruptionofEarth_Timer
if ( (int) (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() +0.5) == 25)
{
if (CorruptionofEarth3_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_CORRUPTIONOFEARTH);
//1 minutes for next one. Means not again with this health value
CorruptionofEarth3_Timer = 60000;
} else CorruptionofEarth3_Timer -= diff;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_emeriss(Creature *_Creature)
{
return new boss_emerissAI (_Creature);
}
void AddSC_boss_emeriss()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_emeriss";
newscript->GetAI = GetAI_boss_emeriss;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,24 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Lethon
SD%Complete: 0
SDComment: Place Holder
SDCategory: Bosses
EndScriptData */
#include "precompiled.h"
@@ -0,0 +1,306 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Taerar
SD%Complete: 90
SDComment: Mark of Nature & Teleport NYI
SDCategory: Bosses
EndScriptData */
#include "precompiled.h"
//Spells of Taerar
#define SPELL_SLEEP 24777
#define SPELL_NOXIOUSBREATH 24818
#define SPELL_TAILSWEEP 15847
//#define SPELL_MARKOFNATURE 25040 // Not working
#define SPELL_ARCANEBLAST 24857
#define SPELL_BELLOWINGROAR 22686
#define SPELL_SUMMONSHADE 24843
//Spells of Shades of Taerar
#define SPELL_POSIONCLOUD 24840
#define SPELL_POSIONBREATH 20667
struct MANGOS_DLL_DECL boss_taerarAI : public ScriptedAI
{
boss_taerarAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 Sleep_Timer;
uint32 NoxiousBreath_Timer;
uint32 TailSweep_Timer;
//uint32 MarkOfNature_Timer;
uint32 ArcaneBlast_Timer;
uint32 BellowingRoar_Timer;
uint32 Shades_Timer;
uint32 Summon1_Timer;
uint32 Summon2_Timer;
uint32 Summon3_Timer;
int Rand;
int RandX;
int RandY;
Creature* Summoned;
bool Shades;
void Reset()
{
Sleep_Timer = 15000 + rand()%5000;
NoxiousBreath_Timer = 8000;
TailSweep_Timer = 4000;
//MarkOfNature_Timer = 45000;
ArcaneBlast_Timer = 12000;
BellowingRoar_Timer = 30000;
Summon1_Timer = 0;
Summon2_Timer = 0;
Summon3_Timer = 0;
Shades_Timer = 60000; //The time that Taerar is banished
Shades = false;
}
void Aggro(Unit *who)
{
}
void SummonShades(Unit* victim)
{
Rand = rand()%15;
switch (rand()%2)
{
case 0: RandX = 0 - Rand; break;
case 1: RandX = 0 + Rand; break;
}
Rand = 0;
Rand = rand()%15;
switch (rand()%2)
{
case 0: RandY = 0 - Rand; break;
case 1: RandY = 0 + Rand; break;
}
Rand = 0;
Summoned = DoSpawnCreature(15302, RandX, RandY, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
if(Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(victim);
}
void UpdateAI(const uint32 diff)
{
if (Shades && Shades_Timer < diff)
{
//Become unbanished again
m_creature->setFaction(14);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
//m_creature->m_canMove = true;
Shades = false;
} else if (Shades)
{
Shades_Timer -= diff;
//Do nothing while banished
return;
}
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
//Sleep_Timer
if (Sleep_Timer < diff)
{
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,0);
if (target) DoCast(target,SPELL_SLEEP);
Sleep_Timer = 8000 + rand()%7000;
}else Sleep_Timer -= diff;
//NoxiousBreath_Timer
if (NoxiousBreath_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_NOXIOUSBREATH);
NoxiousBreath_Timer = 14000 + rand()%6000;
} else NoxiousBreath_Timer -= diff;
//Tailsweep every 2 seconds
if (TailSweep_Timer < diff)
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_TAILSWEEP);
TailSweep_Timer = 2000;
}else TailSweep_Timer -= diff;
//MarkOfNature_Timer
//if (MarkOfNature_Timer < diff)
//{
// DoCast(m_creature->getVictim(),SPELL_MARKOFNATURE);
// MarkOfNature_Timer = 45000;
//}else MarkOfNature_Timer -= diff;
//ArcaneBlast_Timer
if (ArcaneBlast_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_ARCANEBLAST);
ArcaneBlast_Timer = 7000 + rand()%5000;
}else ArcaneBlast_Timer -= diff;
//BellowingRoar_Timer
if (BellowingRoar_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_BELLOWINGROAR);
BellowingRoar_Timer = 20000 + rand()%10000;
} else BellowingRoar_Timer -= diff;
//Summon 3 Shades
if ( !Shades && (int) (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() +0.5) == 75)
{
if (Summon1_Timer < diff)
{
//Inturrupt any spell casting
m_creature->InterruptNonMeleeSpells(false);
m_creature->setFaction(35);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
//m_creature->m_canMove = false;
//Cast
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,0);
SummonShades(target);
SummonShades(target);
SummonShades(target);
Summon1_Timer = 120000;
Shades = true;
Shades_Timer = 60000;
} else Summon1_Timer -= diff;
}
//Summon 3 Shades
if ( !Shades && (int) (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() +0.5) == 50)
{
if (Summon2_Timer < diff)
{
//Inturrupt any spell casting
m_creature->InterruptNonMeleeSpells(false);
m_creature->setFaction(35);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
//m_creature->m_canMove = false;
//Cast
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,0);
SummonShades(target);
SummonShades(target);
SummonShades(target);
Summon2_Timer = 120000;
Shades = true;
Shades_Timer = 60000;
} else Summon2_Timer -= diff;
}
//Summon 3 Shades
if ( !Shades && (int) (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() +0.5) == 25)
{
if (Summon3_Timer < diff)
{
//Inturrupt any spell casting
m_creature->InterruptNonMeleeSpells(false);
m_creature->setFaction(35);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
//m_creature->m_canMove = false;
//Cast
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,0);
SummonShades(target);
SummonShades(target);
SummonShades(target);
Summon3_Timer = 120000;
Shades = true;
Shades_Timer = 60000;
} else Summon3_Timer -= diff;
}
DoMeleeAttackIfReady();
}
};
// Shades of Taerar Script
struct MANGOS_DLL_DECL boss_shadeoftaerarAI : public ScriptedAI
{
boss_shadeoftaerarAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 PoisonCloud_Timer;
uint32 PosionBreath_Timer;
void Reset()
{
PoisonCloud_Timer = 8000;
PosionBreath_Timer = 12000;
}
void Aggro(Unit *who)
{
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
//PoisonCloud_Timer
if (PoisonCloud_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_POSIONCLOUD);
PoisonCloud_Timer = 30000;
}else PoisonCloud_Timer -= diff;
//PosionBreath_Timer
if (PosionBreath_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_POSIONBREATH);
PosionBreath_Timer = 12000;
}else PosionBreath_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_taerar(Creature *_Creature)
{
return new boss_taerarAI (_Creature);
}
CreatureAI* GetAI_boss_shadeoftaerar(Creature *_Creature)
{
return new boss_shadeoftaerarAI (_Creature);
}
void AddSC_boss_taerar()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_taerar";
newscript->GetAI = GetAI_boss_taerar;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="boss_shade_of_taerar";
newscript->GetAI = GetAI_boss_shadeoftaerar;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,246 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Ysondre
SD%Complete: 90
SDComment: Mark of Nature & Teleport missing
SDCategory: Bosses
EndScriptData */
#include "precompiled.h"
#define SPELL_SLEEP 24777
#define SPELL_NOXIOUSBREATH 24818
#define SPELL_TAILSWEEP 15847
//#define SPELL_MARKOFNATURE 25040 // Not working
#define SPELL_LIGHTNINGWAVE 24819
#define SPELL_SUMMONDRUIDS 24795
//druid spells
#define SPELL_MOONFIRE 21669
// Ysondre script
struct MANGOS_DLL_DECL boss_ysondreAI : public ScriptedAI
{
boss_ysondreAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 Sleep_Timer;
uint32 NoxiousBreath_Timer;
uint32 TailSweep_Timer;
//uint32 MarkOfNature_Timer;
uint32 LightningWave_Timer;
uint32 SummonDruids1_Timer;
uint32 SummonDruids2_Timer;
uint32 SummonDruids3_Timer;
int Rand;
int RandX;
int RandY;
Creature* Summoned;
void Reset()
{
Sleep_Timer = 15000 + rand()%5000;
NoxiousBreath_Timer = 8000;
TailSweep_Timer = 4000;
//MarkOfNature_Timer = 45000;
LightningWave_Timer = 12000;
SummonDruids1_Timer = 0;
SummonDruids2_Timer = 0;
SummonDruids3_Timer = 0;
}
void Aggro(Unit *who)
{
}
void SummonDruids(Unit* victim)
{
Rand = rand()%10;
switch (rand()%2)
{
case 0: RandX = 0 - Rand; break;
case 1: RandX = 0 + Rand; break;
}
Rand = 0;
Rand = rand()%10;
switch (rand()%2)
{
case 0: RandY = 0 - Rand; break;
case 1: RandY = 0 + Rand; break;
}
Rand = 0;
Summoned = DoSpawnCreature(15260, RandX, RandY, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000);
if(Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(victim);
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
//Sleep_Timer
if (Sleep_Timer < diff)
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_SLEEP);
Sleep_Timer = 8000 + rand()%7000;
}else Sleep_Timer -= diff;
//NoxiousBreath_Timer
if (NoxiousBreath_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_NOXIOUSBREATH);
NoxiousBreath_Timer = 14000 + rand()%6000;
}else NoxiousBreath_Timer -= diff;
//Tailsweep every 2 seconds
if (TailSweep_Timer < diff)
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_TAILSWEEP);
TailSweep_Timer = 2000;
}else TailSweep_Timer -= diff;
//MarkOfNature_Timer
//if (MarkOfNature_Timer < diff)
//{
// DoCast(m_creature->getVictim(),SPELL_MARKOFNATURE);
// MarkOfNature_Timer = 45000;
//}else MarkOfNature_Timer -= diff;
//LightningWave_Timer
if (LightningWave_Timer < diff)
{
//Cast LIGHTNINGWAVE on a Random target
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_LIGHTNINGWAVE);
LightningWave_Timer = 7000 + rand()%5000;
}else LightningWave_Timer -= diff;
//Summon Druids
if ( (int) (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() +0.5) == 75)
{
if (SummonDruids1_Timer < diff)
{
// summon 10 druids
Unit* target = NULL;
for(int i = 0; i < 10;i++)
{
target = SelectUnit(SELECT_TARGET_RANDOM,0);
SummonDruids(target);
}
SummonDruids1_Timer = 60000;
} else SummonDruids1_Timer -= diff;
}
//Summon Druids
if ( (int) (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() +0.5) == 50)
{
if (SummonDruids2_Timer < diff)
{
// summon 10 druids
Unit* target = NULL;
for(int i = 0; i < 10;i++)
{
target = SelectUnit(SELECT_TARGET_RANDOM,0);
SummonDruids(target);
}
SummonDruids2_Timer = 60000;
} else SummonDruids2_Timer -= diff;
}
//Summon Druids
if ( (int) (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() +0.5) == 25)
{
if (SummonDruids3_Timer < diff)
{
// summon 10 druids
Unit* target = NULL;
for(int i = 0; i < 10;i++)
{
target = SelectUnit(SELECT_TARGET_RANDOM,0);
SummonDruids(target);
}
SummonDruids3_Timer = 60000;
} else SummonDruids3_Timer -= diff;
}
DoMeleeAttackIfReady();
}
};
// Summoned druid script
struct MANGOS_DLL_DECL mob_dementeddruidsAI : public ScriptedAI
{
mob_dementeddruidsAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 MoonFire_Timer;
void Reset()
{
MoonFire_Timer = 3000;
}
void Aggro(Unit *who)
{
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
//MoonFire_Timer
if (MoonFire_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_MOONFIRE);
MoonFire_Timer = 5000;
}else MoonFire_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_ysondre(Creature *_Creature)
{
return new boss_ysondreAI (_Creature);
}
CreatureAI* GetAI_mob_dementeddruids(Creature *_Creature)
{
return new mob_dementeddruidsAI (_Creature);
}
void AddSC_boss_ysondre()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_ysondre";
newscript->GetAI = GetAI_boss_ysondre;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="mob_dementeddruids";
newscript->GetAI = GetAI_mob_dementeddruids;
m_scripts[nrscripts++] = newscript;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,215 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef SC_EVENTAI_H
#define SC_EVENTAI_H
#define MAX_ACTIONS 3
enum Event_Types
{
EVENT_T_TIMER = 0, //InitialMin, InitialMax, RepeatMin, RepeatMax
EVENT_T_TIMER_OOC = 1, //InitialMin, InitialMax, RepeatMin, RepeatMax
EVENT_T_HP = 2, //HPMax%, HPMin%, RepeatMin, RepeatMax
EVENT_T_MANA = 3, //ManaMax%,ManaMin% RepeatMin, RepeatMax
EVENT_T_AGGRO = 4, //NONE
EVENT_T_KILL = 5, //RepeatMin, RepeatMax
EVENT_T_DEATH = 6, //NONE
EVENT_T_EVADE = 7, //NONE
EVENT_T_SPELLHIT = 8, //SpellID, School, RepeatMin, RepeatMax
EVENT_T_RANGE = 9, //MinDist, MaxDist, RepeatMin, RepeatMax
EVENT_T_OOC_LOS = 10, //NoHostile, NoFriendly, RepeatMin, RepeatMax
EVENT_T_SPAWNED = 11, //NONE
EVENT_T_TARGET_HP = 12, //HPMax%, HPMin%, RepeatMin, RepeatMax
EVENT_T_TARGET_CASTING = 13, //RepeatMin, RepeatMax
EVENT_T_FRIENDLY_HP = 14, //HPDeficit, Radius, RepeatMin, RepeatMax
EVENT_T_FRIENDLY_IS_CC = 15, //DispelType, Radius, RepeatMin, RepeatMax
EVENT_T_FRIENDLY_MISSING_BUFF = 16, //SpellId, Radius, RepeatMin, RepeatMax
EVENT_T_SUMMONED_UNIT = 17, //CreatureId, RepeatMin, RepeatMax
EVENT_T_TARGET_MANA = 18, //ManaMax%, ManaMin%, RepeatMin, RepeatMax
EVENT_T_QUEST_ACCEPT = 19, //QuestID
EVENT_T_QUEST_COMPLETE = 20, //
EVENT_T_END,
};
enum Action_Types
{
ACTION_T_NONE = 0, //No action
ACTION_T_SAY = 1, //TextId
ACTION_T_YELL = 2, //TextId
ACTION_T_TEXTEMOTE = 3, //TextId
ACTION_T_SOUND = 4, //SoundId
ACTION_T_EMOTE = 5, //EmoteId
ACTION_T_RANDOM_SAY = 6, //TextId1, TextId2, TextId3 (-1 in any field means no output if randomed that field)
ACTION_T_RANDOM_YELL = 7, //TextId1, TextId2, TextId3 (-1 in any field means no output if randomed that field)
ACTION_T_RANDOM_TEXTEMOTE = 8, //TextId1, TextId2, TextId3 (-1 in any field means no output if randomed that field)
ACTION_T_RANDOM_SOUND = 9, //SoundId1, SoundId2, SoundId3 (-1 in any field means no output if randomed that field)
ACTION_T_RANDOM_EMOTE = 10, //EmoteId1, EmoteId2, EmoteId3 (-1 in any field means no output if randomed that field)
ACTION_T_CAST = 11, //SpellId, Target, CastFlags
ACTION_T_SUMMON = 12, //CreatureID, Target, Duration in ms
ACTION_T_THREAT_SINGLE_PCT = 13, //Threat%, Target
ACTION_T_THREAT_ALL_PCT = 14, //Threat%
ACTION_T_QUEST_EVENT = 15, //QuestID, Target
ACTION_T_CASTCREATUREGO = 16, //QuestID, SpellId, Target
ACTION_T_SET_UNIT_FIELD = 17, //Field_Number, Value, Target
ACTION_T_SET_UNIT_FLAG = 18, //Flags (may be more than one field OR'd together), Target
ACTION_T_REMOVE_UNIT_FLAG = 19, //Flags (may be more than one field OR'd together), Target
ACTION_T_AUTO_ATTACK = 20, //AllowAttackState (0 = stop attack, anything else means continue attacking)
ACTION_T_COMBAT_MOVEMENT = 21, //AllowCombatMovement (0 = stop combat based movement, anything else continue attacking)
ACTION_T_SET_PHASE = 22, //Phase
ACTION_T_INC_PHASE = 23, //Value (may be negative to decrement phase, should not be 0)
ACTION_T_EVADE = 24, //No Params
ACTION_T_FLEE = 25, //No Params
ACTION_T_QUEST_EVENT_ALL = 26, //QuestID
ACTION_T_CASTCREATUREGO_ALL = 27, //QuestId, SpellId
ACTION_T_REMOVEAURASFROMSPELL = 28, //Target, Spellid
ACTION_T_RANGED_MOVEMENT = 29, //Distance, Angle
ACTION_T_RANDOM_PHASE = 30, //PhaseId1, PhaseId2, PhaseId3
ACTION_T_RANDOM_PHASE_RANGE = 31, //PhaseMin, PhaseMax
ACTION_T_SUMMON_ID = 32, //CreatureId, Target, SpawnId
ACTION_T_KILLED_MONSTER = 33, //CreatureId, Target
ACTION_T_SET_INST_DATA = 34, //Field, Data
ACTION_T_SET_INST_DATA64 = 35, //Field, Target
ACTION_T_UPDATE_TEMPLATE = 36, //Entry, Team
ACTION_T_DIE = 37, //No Params
ACTION_T_ZONE_COMBAT_PULSE = 38, //No Params
ACTION_T_END,
};
enum Target
{
//Self (m_creature)
TARGET_T_SELF = 0, //Self cast
//Hostile targets (if pet then returns pet owner)
TARGET_T_HOSTILE, //Our current target (ie: highest aggro)
TARGET_T_HOSTILE_SECOND_AGGRO, //Second highest aggro (generaly used for cleaves and some special attacks)
TARGET_T_HOSTILE_LAST_AGGRO, //Dead last on aggro (no idea what this could be used for)
TARGET_T_HOSTILE_RANDOM, //Just any random target on our threat list
TARGET_T_HOSTILE_RANDOM_NOT_TOP, //Any random target except top threat
//Invoker targets (if pet then returns pet owner)
TARGET_T_ACTION_INVOKER, //Unit who caused this Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP, EVENT_T_FRIENDLY_IS_CC, EVENT_T_FRIENDLY_MISSING_BUFF)
//Hostile targets (including pets)
TARGET_T_HOSTILE_WPET, //Current target (can be a pet)
TARGET_T_HOSTILE_WPET_SECOND_AGGRO, //Second highest aggro (generaly used for cleaves and some special attacks)
TARGET_T_HOSTILE_WPET_LAST_AGGRO, //Dead last on aggro (no idea what this could be used for)
TARGET_T_HOSTILE_WPET_RANDOM, //Just any random target on our threat list
TARGET_T_HOSTILE_WPET_RANDOM_NOT_TOP, //Any random target except top threat
TARGET_T_ACTION_INVOKER_WPET,
TARGET_T_END
};
enum CastFlags
{
CAST_INTURRUPT_PREVIOUS = 0x01, //Interrupt any spell casting
CAST_TRIGGERED = 0x02, //Triggered (this makes spell cost zero mana and have no cast time)
CAST_FORCE_CAST = 0x04, //Forces cast even if creature is out of mana or out of range
CAST_NO_MELEE_IF_OOM = 0x08, //Prevents creature from entering melee if out of mana or out of range
CAST_FORCE_TARGET_SELF = 0x10, //Forces the target to cast this spell on itself
};
enum EventFlags
{
EFLAG_REPEATABLE = 0x01, //Event repeats
EFLAG_NORMAL = 0x02, //Event only occurs in Normal instance difficulty
EFLAG_HEROIC = 0x04, //Event only occurs in Heroic instance difficulty
EFLAG_RESERVED_3 = 0x08,
EFLAG_RESERVED_4 = 0x10,
EFLAG_RESERVED_5 = 0x20,
EFLAG_RESERVED_6 = 0x40,
EFLAG_DEBUG_ONLY = 0x80, //Event only occurs in debug build of SD2 only
};
struct EventAI_Event
{
uint32 event_id;
uint32 creature_id;
uint16 event_type;
uint32 event_inverse_phase_mask;
uint8 event_chance;
uint8 event_flags;
union
{
uint32 event_param1;
int32 event_param1_s;
};
union
{
uint32 event_param2;
int32 event_param2_s;
};
union
{
uint32 event_param3;
int32 event_param3_s;
};
union
{
uint32 event_param4;
int32 event_param4_s;
};
struct _action
{
uint16 type;
union
{
uint32 param1;
int32 param1_s;
};
union
{
uint32 param2;
int32 param2_s;
};
union
{
uint32 param3;
int32 param3_s;
};
}action[MAX_ACTIONS];
};
//Event_Map
extern std::list<EventAI_Event> EventAI_Event_List;
struct EventAI_Summon
{
uint32 id;
float position_x;
float position_y;
float position_z;
float orientation;
uint32 SpawnTimeSecs;
};
//EventSummon_Map
extern HM_NAMESPACE::hash_map<uint32, EventAI_Summon> EventAI_Summon_Map;
//EventAI Error handling
extern uint32 EAI_ErrorLevel;
/*
struct EventAI_CreatureError
{
bool ListEmpty;
bool NoInstance;
};
//Error prevention list
extern HM_NAMESPACE::hash_map<uint32, EventAI_CreatureError> EventAI_CreatureErrorPreventionList;
//Defines
#define EVENTAI_EMPTY_EVENTLIST "SD2: Eventlist for Creature %i is empty but creature is using Mob_EventAI. Preventing EventAI on this creature."
*/
#endif
@@ -0,0 +1,172 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Generic_Creature
SD%Complete: 80
SDComment: Should be replaced with core based AI
SDCategory: Creatures
EndScriptData */
#include "precompiled.h"
#define GENERIC_CREATURE_COOLDOWN 5000
struct MANGOS_DLL_DECL generic_creatureAI : public ScriptedAI
{
generic_creatureAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 GlobalCooldown; //This variable acts like the global cooldown that players have (1.5 seconds)
uint32 BuffTimer; //This variable keeps track of buffs
bool IsSelfRooted;
void Reset()
{
GlobalCooldown = 0;
BuffTimer = 0; //Rebuff as soon as we can
IsSelfRooted = false;
}
void Aggro(Unit *who)
{
if (!m_creature->IsWithinDistInMap(who, ATTACK_DISTANCE))
{
IsSelfRooted = true;
}
}
void UpdateAI(const uint32 diff)
{
//Always decrease our global cooldown first
if (GlobalCooldown > diff)
GlobalCooldown -= diff;
else GlobalCooldown = 0;
//Buff timer (only buff when we are alive and not in combat
if (!InCombat && m_creature->isAlive())
if (BuffTimer < diff )
{
//Find a spell that targets friendly and applies an aura (these are generally buffs)
SpellEntry const *info = SelectSpell(m_creature, -1, -1, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_AURA);
if (info && !GlobalCooldown)
{
//Cast the buff spell
DoCastSpell(m_creature, info);
//Set our global cooldown
GlobalCooldown = GENERIC_CREATURE_COOLDOWN;
//Set our timer to 10 minutes before rebuff
BuffTimer = 600000;
}//Try agian in 30 seconds
else BuffTimer = 30000;
}else BuffTimer -= diff;
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
//If we are within range melee the target
if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
{
//Make sure our attack is ready and we arn't currently casting
if( m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false))
{
bool Healing = false;
SpellEntry const *info = NULL;
//Select a healing spell if less than 30% hp
if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 30)
info = SelectSpell(m_creature, -1, -1, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_HEALING);
//No healing spell available, select a hostile spell
if (info) Healing = true;
else info = SelectSpell(m_creature->getVictim(), -1, -1, SELECT_TARGET_ANY_ENEMY, 0, 0, 0, 0, SELECT_EFFECT_DONTCARE);
//50% chance if elite or higher, 20% chance if not, to replace our white hit with a spell
if (info && (rand() % (m_creature->GetCreatureInfo()->rank > 1 ? 2 : 5) == 0) && !GlobalCooldown)
{
//Cast the spell
if (Healing)DoCastSpell(m_creature, info);
else DoCastSpell(m_creature->getVictim(), info);
//Set our global cooldown
GlobalCooldown = GENERIC_CREATURE_COOLDOWN;
}
else m_creature->AttackerStateUpdate(m_creature->getVictim());
m_creature->resetAttackTimer();
}
}
else
{
//Only run this code if we arn't already casting
if (!m_creature->IsNonMeleeSpellCasted(false))
{
bool Healing = false;
SpellEntry const *info = NULL;
//Select a healing spell if less than 30% hp ONLY 33% of the time
if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 30 && rand() % 3 == 0)
info = SelectSpell(m_creature, -1, -1, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_HEALING);
//No healing spell available, See if we can cast a ranged spell (Range must be greater than ATTACK_DISTANCE)
if (info) Healing = true;
else info = SelectSpell(m_creature->getVictim(), -1, -1, SELECT_TARGET_ANY_ENEMY, 0, 0, ATTACK_DISTANCE, 0, SELECT_EFFECT_DONTCARE);
//Found a spell, check if we arn't on cooldown
if (info && !GlobalCooldown)
{
//If we are currently moving stop us and set the movement generator
if (!IsSelfRooted)
{
IsSelfRooted = true;
}
//Cast spell
if (Healing) DoCastSpell(m_creature,info);
else DoCastSpell(m_creature->getVictim(),info);
//Set our global cooldown
GlobalCooldown = GENERIC_CREATURE_COOLDOWN;
}//If no spells available and we arn't moving run to target
else if (IsSelfRooted)
{
//Cancel our current spell and then allow movement agian
m_creature->InterruptNonMeleeSpells(false);
IsSelfRooted = false;
}
}
}
}
};
CreatureAI* GetAI_generic_creature(Creature *_Creature)
{
return new generic_creatureAI (_Creature);
}
void AddSC_generic_creature()
{
Script *newscript;
newscript = new Script;
newscript->Name="generic_creature";
newscript->GetAI = GetAI_generic_creature;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,294 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: SimpleAI
SD%Complete: 100
SDComment: Base Class for SimpleAI creatures
SDCategory: Creatures
EndScriptData */
#include "precompiled.h"
#include "simple_ai.h"
SimpleAI::SimpleAI(Creature *c) : ScriptedAI(c)
{
//Clear all data
Aggro_Text[0] = NULL;
Aggro_Text[1] = NULL;
Aggro_Text[2] = NULL;
Aggro_Say[0] = false;
Aggro_Say[1] = false;
Aggro_Say[2] = false;
Aggro_Sound[0] = 0;
Aggro_Sound[1] = 0;
Aggro_Sound[2] = 0;
Death_Text[0] = NULL;
Death_Text[1] = NULL;
Death_Text[2] = NULL;
Death_Say[0] = false;
Death_Say[1] = false;
Death_Say[2] = false;
Death_Sound[0] = 0;
Death_Sound[1] = 0;
Death_Sound[2] = 0;
Death_Spell = 0;
Death_Target_Type = 0;
Kill_Text[0] = NULL;
Kill_Text[1] = NULL;
Kill_Text[2] = NULL;
Kill_Say[0] = false;
Kill_Say[1] = false;
Kill_Say[2] = false;
Kill_Sound[0] = 0;
Kill_Sound[1] = 0;
Kill_Sound[2] = 0;
Kill_Spell = 0;
Kill_Target_Type = 0;
memset(Spell,0,sizeof(Spell));
EnterEvadeMode();
}
void SimpleAI::Reset()
{
}
void SimpleAI::Aggro(Unit *who)
{
//Reset cast timers
if (Spell[0].First_Cast >= 0)
Spell_Timer[0] = Spell[0].First_Cast;
else Spell_Timer[0] = 1000;
if (Spell[1].First_Cast >= 0)
Spell_Timer[1] = Spell[1].First_Cast;
else Spell_Timer[1] = 1000;
if (Spell[2].First_Cast >= 0)
Spell_Timer[2] = Spell[2].First_Cast;
else Spell_Timer[2] = 1000;
if (Spell[3].First_Cast >= 0)
Spell_Timer[3] = Spell[3].First_Cast;
else Spell_Timer[3] = 1000;
if (Spell[4].First_Cast >= 0)
Spell_Timer[4] = Spell[4].First_Cast;
else Spell_Timer[4] = 1000;
if (Spell[5].First_Cast >= 0)
Spell_Timer[5] = Spell[5].First_Cast;
else Spell_Timer[5] = 1000;
if (Spell[6].First_Cast >= 0)
Spell_Timer[6] = Spell[6].First_Cast;
else Spell_Timer[6] = 1000;
if (Spell[7].First_Cast >= 0)
Spell_Timer[7] = Spell[7].First_Cast;
else Spell_Timer[7] = 1000;
if (Spell[8].First_Cast >= 0)
Spell_Timer[8] = Spell[8].First_Cast;
else Spell_Timer[8] = 1000;
if (Spell[9].First_Cast >= 0)
Spell_Timer[9] = Spell[9].First_Cast;
else Spell_Timer[9] = 1000;
uint32 random_text = rand()%3;
//Random yell
if (Aggro_Text[random_text])
if (Aggro_Say[random_text])
DoSay(Aggro_Text[random_text], LANG_UNIVERSAL, who);
else DoYell(Aggro_Text[random_text], LANG_UNIVERSAL, who);
//Random sound
if (Aggro_Sound[random_text])
DoPlaySoundToSet(m_creature, Aggro_Sound[random_text]);
}
void SimpleAI::KilledUnit(Unit *victim)
{
uint32 random_text = rand()%3;
//Random yell
if (Kill_Text[random_text])
if (Kill_Say[random_text])
DoSay(Kill_Text[random_text], LANG_UNIVERSAL, victim);
else DoYell(Kill_Text[random_text], LANG_UNIVERSAL, victim);
//Random sound
if (Kill_Sound[random_text])
DoPlaySoundToSet(m_creature, Kill_Sound[random_text]);
if (!Kill_Spell)
return;
Unit* target = NULL;
switch (Kill_Target_Type)
{
case CAST_SELF:
target = m_creature;
break;
case CAST_HOSTILE_TARGET:
target = m_creature->getVictim();
break;
case CAST_HOSTILE_SECOND_AGGRO:
target = SelectUnit(SELECT_TARGET_TOPAGGRO,1);
break;
case CAST_HOSTILE_LAST_AGGRO:
target = SelectUnit(SELECT_TARGET_BOTTOMAGGRO,0);
break;
case CAST_HOSTILE_RANDOM:
target = SelectUnit(SELECT_TARGET_RANDOM,0);
break;
case CAST_KILLEDUNIT_VICTIM:
target = victim;
break;
}
//Target is ok, cast a spell on it
if (target)
DoCast(target, Kill_Spell);
}
void SimpleAI::DamageTaken(Unit *killer, uint32 &damage)
{
//Return if damage taken won't kill us
if (m_creature->GetHealth() > damage)
return;
uint32 random_text = rand()%3;
//Random yell
if (Death_Text[random_text])
if (Death_Say[random_text])
DoSay(Death_Text[random_text], LANG_UNIVERSAL, killer);
else DoYell(Death_Text[random_text], LANG_UNIVERSAL, killer);
//Random sound
if (Death_Sound[random_text])
DoPlaySoundToSet(m_creature, Death_Sound[random_text]);
if (!Death_Spell)
return;
Unit* target = NULL;
switch (Death_Target_Type)
{
case CAST_SELF:
target = m_creature;
break;
case CAST_HOSTILE_TARGET:
target = m_creature->getVictim();
break;
case CAST_HOSTILE_SECOND_AGGRO:
target = SelectUnit(SELECT_TARGET_TOPAGGRO,1);
break;
case CAST_HOSTILE_LAST_AGGRO:
target = SelectUnit(SELECT_TARGET_BOTTOMAGGRO,0);
break;
case CAST_HOSTILE_RANDOM:
target = SelectUnit(SELECT_TARGET_RANDOM,0);
break;
case CAST_JUSTDIED_KILLER:
target = killer;
break;
}
//Target is ok, cast a spell on it
if (target)
DoCast(target, Death_Spell);
}
void SimpleAI::UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
//Spells
for (uint32 i = 0; i < 10; ++i)
{
//Spell not valid
if (!Spell[i].Enabled || !Spell[i].Spell_Id)
continue;
if (Spell_Timer[i] < diff)
{
//Check if this is a percentage based
if (Spell[i].First_Cast < 0 && Spell[i].First_Cast > -100 && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() > -Spell[i].First_Cast)
continue;
//Check Current spell
if (!(Spell[i].InterruptPreviousCast && m_creature->IsNonMeleeSpellCasted(false)))
{
Unit* target = NULL;
switch (Spell[i].Cast_Target_Type)
{
case CAST_SELF:
target = m_creature;
break;
case CAST_HOSTILE_TARGET:
target = m_creature->getVictim();
break;
case CAST_HOSTILE_SECOND_AGGRO:
target = SelectUnit(SELECT_TARGET_TOPAGGRO,1);
break;
case CAST_HOSTILE_LAST_AGGRO:
target = SelectUnit(SELECT_TARGET_BOTTOMAGGRO,0);
break;
case CAST_HOSTILE_RANDOM:
target = SelectUnit(SELECT_TARGET_RANDOM,0);
break;
}
//Target is ok, cast a spell on it and then do our random yell
if (target)
{
if (m_creature->IsNonMeleeSpellCasted(false))
m_creature->InterruptNonMeleeSpells(false);
DoCast(target, Spell[i].Spell_Id);
//Yell and sound use the same number so that you can make
//the creature yell with the correct sound effect attached
uint32 random_text = rand()%3;
//Random yell
if (Spell[i].Text[random_text])
if (Spell[i].Say[random_text])
DoSay(Spell[i].Text[random_text], LANG_UNIVERSAL, target);
else DoYell(Spell[i].Text[random_text], LANG_UNIVERSAL, target);
//Random sound
if (Spell[i].Text_Sound[random_text])
DoPlaySoundToSet(m_creature, Spell[i].Text_Sound[random_text]);
}
}
//Spell will cast agian when the cooldown is up
if (Spell[i].CooldownRandomAddition)
Spell_Timer[i] = Spell[i].Cooldown + (rand() % Spell[i].CooldownRandomAddition);
else Spell_Timer[i] = Spell[i].Cooldown;
}else Spell_Timer[i] -= diff;
}
DoMeleeAttackIfReady();
}
@@ -0,0 +1,74 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef SC_SIMPLEAI_H
#define SC_SIMPLEAI_H
enum CastTarget
{
CAST_SELF = 0, //Self cast
CAST_HOSTILE_TARGET, //Our current target (ie: highest aggro)
CAST_HOSTILE_SECOND_AGGRO, //Second highest aggro (generaly used for cleaves and some special attacks)
CAST_HOSTILE_LAST_AGGRO, //Dead last on aggro (no idea what this could be used for)
CAST_HOSTILE_RANDOM, //Just any random target on our threat list
CAST_FRIENDLY_RANDOM, //NOT YET IMPLEMENTED
//Special cases
CAST_KILLEDUNIT_VICTIM, //Only works within KilledUnit function
CAST_JUSTDIED_KILLER, //Only works within JustDied function
};
struct MANGOS_DLL_DECL SimpleAI : public ScriptedAI
{
SimpleAI(Creature *c);// : ScriptedAI(c);
void Reset();
void Aggro(Unit *who);
void KilledUnit(Unit *victim);
void DamageTaken(Unit *killer, uint32 &damage);
void UpdateAI(const uint32 diff);
public:
char* Aggro_Text[3];
bool Aggro_Say[3];
uint32 Aggro_Sound[3];
char* Death_Text[3];
bool Death_Say[3];
uint32 Death_Sound[3];
uint32 Death_Spell;
uint32 Death_Target_Type;
char* Kill_Text[3];
bool Kill_Say[3];
uint32 Kill_Sound[3];
uint32 Kill_Spell;
uint32 Kill_Target_Type;
struct SimpleAI_Spell
{
uint32 Spell_Id; //Spell ID to cast
int32 First_Cast; //Delay for first cast
uint32 Cooldown; //Cooldown between casts
uint32 CooldownRandomAddition; //Random addition to cooldown (in range from 0 - CooldownRandomAddition)
uint32 Cast_Target_Type; //Target type (note that certain spells may ignore this)
bool InterruptPreviousCast; //Interrupt a previous cast if this spell needs to be cast
bool Enabled; //Spell enabled or disabled (default: false)
//3 texts to many?
char* Text[3];
bool Say[3];
uint32 Text_Sound[3];
}Spell[10];
protected:
uint32 Spell_Timer[10];
};
#endif
@@ -0,0 +1,277 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Custom_Example
SD%Complete: 100
SDComment: Short custom scripting example
SDCategory: Script Examples
EndScriptData */
#include "precompiled.h"
// **** This script is designed as an example for others to build on ****
// **** Please modify whatever you'd like to as this script is only for developement ****
// **** Script Info ****
// This script is written in a way that it can be used for both friendly and hostile monsters
// Its primary purpose is to show just how much you can really do with scripts
// I recommend trying it out on both an agressive NPC and on friendly npc
// **** Quick Info ****
// Functions with Handled Function marked above them are functions that are called automatically by the core
// Functions that are marked Custom Function are functions I've created to simplify code
#define SPELL_BUFF 25661
#define SPELL_ONE 12555
#define SPELL_ONE_ALT 24099
#define SPELL_TWO 10017
#define SPELL_THREE 26027
#define SPELL_ENRAGE 23537
#define SPELL_BESERK 32309
#define SAY_AGGRO "Let the games begin."
#define SAY_RANDOM_0 "I see endless suffering. I see torment. I see rage. I see everything."
#define SAY_RANDOM_1 "Muahahahaha"
#define SAY_RANDOM_2 "These mortal infedels my lord, they have invaded your sanctum and seek to steal your secrets."
#define SAY_RANDOM_3 "You are already dead."
#define SAY_RANDOM_4 "Where to go? What to do? So many choices that all end in pain, end in death."
#define SAY_BESERK "$N, I sentance you to death!"
#define SAY_PHASE "The suffering has just begun!"
#define GOSSIP_ITEM "I'm looking for a fight"
#define SAY_DANCE "I always thought I was a good dancer"
#define SAY_SALUTE "Move out Soldier!"
struct MANGOS_DLL_DECL custom_exampleAI : public ScriptedAI
{
//*** HANDLED FUNCTION ***
//This is the constructor, called only once when the creature is first created
custom_exampleAI(Creature *c) : ScriptedAI(c) {Reset();}
//*** CUSTOM VARIABLES ****
//These variables are for use only by this individual script.
//Nothing else will ever call them but us.
uint32 Say_Timer; //Timer for random chat
uint32 Rebuff_Timer; //Timer for rebuffing
uint32 Spell_1_Timer; //Timer for spell 1 when in combat
uint32 Spell_2_Timer; //Timer for spell 1 when in combat
uint32 Spell_3_Timer; //Timer for spell 1 when in combat
uint32 Beserk_Timer; //Timer until we go into Beserk (enraged) mode
uint32 Phase; //The current battle phase we are in
uint32 Phase_Timer; //Timer until phase transition
//*** HANDLED FUNCTION ***
//This is called whenever the core decides we need to evade
void Reset()
{
Phase = 1; //Start in phase 1
Phase_Timer = 60000; //60 seconds
Spell_1_Timer = 5000; //5 seconds
Spell_2_Timer = 37000; //37 seconds
Spell_3_Timer = 19000; //19 seconds
Beserk_Timer = 120000; //2 minutes
}
//*** HANDLED FUNCTION ***
//Attack Start is called whenever someone hits us.
void Aggro(Unit *who)
{
//Say some stuff
DoSay(SAY_AGGRO,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature,8280);
}
//*** HANDLED FUNCTION ***
//Update AI is called Every single map update (roughly once every 100ms if a player is within the grid)
void UpdateAI(const uint32 diff)
{
//Out of combat timers
if (!m_creature->getVictim())
{
//Random Say timer
if (Say_Timer < diff)
{
//Random switch between 5 outcomes
switch (rand()%5)
{
case 0:
DoYell(SAY_RANDOM_0,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature,8831); //8831 is the index of the sound we are playing. You find these numbers in SoundEntries.dbc
break;
case 1:
DoYell(SAY_RANDOM_1,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature,8818);
break;
case 2:
DoYell(SAY_RANDOM_2,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature,8041);
break;
case 3:
DoYell(SAY_RANDOM_3,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature,8581);
break;
case 4:
DoYell(SAY_RANDOM_4,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature,8791);
break;
}
Say_Timer = 45000; //Say something agian in 45 seconds
}else Say_Timer -= diff;
//Rebuff timer
if (Rebuff_Timer < diff)
{
DoCast(m_creature,SPELL_BUFF);
Rebuff_Timer = 900000; //Rebuff agian in 15 minutes
}else Rebuff_Timer -= diff;
}
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
//Spell 1 timer
if (Spell_1_Timer < diff)
{
//Cast spell one on our current target.
if (rand()%50 > 10)
DoCast(m_creature->getVictim(),SPELL_ONE_ALT);
else if (m_creature->GetDistance(m_creature->getVictim()) < 25)
DoCast(m_creature->getVictim(),SPELL_ONE);
Spell_1_Timer = 5000;
}else Spell_1_Timer -= diff;
//Spell 2 timer
if (Spell_2_Timer < diff)
{
//Cast spell one on our current target.
DoCast(m_creature->getVictim(),SPELL_TWO);
Spell_2_Timer = 37000;
}else Spell_2_Timer -= diff;
//Spell 3 timer
if (Phase > 1)
if (Spell_3_Timer < diff)
{
//Cast spell one on our current target.
DoCast(m_creature->getVictim(),SPELL_THREE);
Spell_3_Timer = 19000;
}else Spell_3_Timer -= diff;
//Beserk timer
if (Phase > 1)
if (Beserk_Timer < diff)
{
//Say our line then cast uber death spell
DoPlaySoundToSet(m_creature,8588);
DoYell(SAY_BESERK,LANG_UNIVERSAL,m_creature->getVictim());
DoCast(m_creature->getVictim(),SPELL_BESERK);
//Cast our beserk spell agian in 12 seconds if we didn't kill everyone
Beserk_Timer = 12000;
}else Beserk_Timer -= diff;
//Phase timer
if (Phase == 1)
if (Phase_Timer < diff)
{
//Go to next phase
Phase++;
DoYell(SAY_PHASE,LANG_UNIVERSAL,NULL);
DoCast(m_creature,SPELL_ENRAGE);
}else Phase_Timer -= diff;
DoMeleeAttackIfReady();
}
};
//This is the GetAI method used by all scripts that involve AI
//It is called every time a new creature using this script is created
CreatureAI* GetAI_custom_example(Creature *_Creature)
{
return new custom_exampleAI (_Creature);
}
//This function is called when the player clicks an option on the gossip menu
void SendDefaultMenu_custom_example(Player *player, Creature *_Creature, uint32 action)
{
if (action == GOSSIP_ACTION_INFO_DEF + 1) //Fight time
{
//Set our faction to hostile twoards all
_Creature->setFaction(24);
_Creature->Attack(player, true);
player->PlayerTalkClass->CloseGossip();
}
}
//This function is called when the player clicks an option on the gossip menu
bool GossipSelect_custom_example(Player *player, Creature *_Creature, uint32 sender, uint32 action )
{
if (sender == GOSSIP_SENDER_MAIN)
SendDefaultMenu_custom_example(player, _Creature, action);
return true;
}
//This function is called when the player opens the gossip menu
bool GossipHello_custom_example(Player *player, Creature *_Creature)
{
player->ADD_GOSSIP_ITEM( 0, GOSSIP_ITEM , GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
player->PlayerTalkClass->SendGossipMenu(907,_Creature->GetGUID());
return true;
}
//Our Recive emote function
bool ReceiveEmote_custom_example(Player *player, Creature *_Creature, uint32 emote)
{
_Creature->HandleEmoteCommand(emote);
if (emote == TEXTEMOTE_DANCE)
((custom_exampleAI*)_Creature->AI())->DoSay(SAY_DANCE,LANG_UNIVERSAL,NULL);
if (emote == TEXTEMOTE_SALUTE)
((custom_exampleAI*)_Creature->AI())->DoSay(SAY_SALUTE,LANG_UNIVERSAL,NULL);
return true;
}
//This is the actual function called only once durring InitScripts()
//It must define all handled functions that are to be run in this script
//For example if you want this Script to handle Emotes you must include
//newscript->ReciveEmote = My_Emote_Function;
void AddSC_custom_example()
{
Script *newscript;
newscript = new Script;
newscript->Name="custom_example";
newscript->GetAI = GetAI_custom_example;
newscript->pGossipHello = &GossipHello_custom_example;
newscript->pGossipSelect = &GossipSelect_custom_example;
newscript->pReceiveEmote = &ReceiveEmote_custom_example;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,81 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Custom_Gossip_Codebox
SD%Complete: 100
SDComment: Show a codebox in gossip option
SDCategory: Script Examples
EndScriptData */
#include "precompiled.h"
#include <cstring>
//This function is called when the player opens the gossip menubool
bool GossipHello_custom_gossip_codebox(Player *player, Creature *_Creature)
{
player->PlayerTalkClass->GetGossipMenu()->AddMenuItem(0, "A quiz: what's your name?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1, "", 0, true);
player->ADD_GOSSIP_ITEM(0, "I'm not interested", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
player->PlayerTalkClass->SendGossipMenu(907,_Creature->GetGUID());
return true;
}
//This function is called when the player clicks an option on the gossip menubool
bool GossipSelect_custom_gossip_codebox(Player *player, Creature *_Creature, uint32 sender, uint32 action )
{
if(action == GOSSIP_ACTION_INFO_DEF+2)
{
_Creature->Say("Normal select, guess you're not interested.", LANG_UNIVERSAL, 0);
player->CLOSE_GOSSIP_MENU();
}
return true;
}
bool GossipSelectWithCode_custom_gossip_codebox( Player *player, Creature *_Creature, uint32 sender, uint32 action, const char* sCode )
{
if(sender == GOSSIP_SENDER_MAIN)
{
if(action == GOSSIP_ACTION_INFO_DEF+1)
{
if(std::strcmp(sCode, player->GetName())!=0)
{
_Creature->Say("Wrong!", LANG_UNIVERSAL, 0);
_Creature->CastSpell(player, 12826, true);
}
else
{
_Creature->Say("You're right, you are allowed to see my inner secrets.", LANG_UNIVERSAL, 0);
_Creature->CastSpell(player, 26990, true);
}
player->CLOSE_GOSSIP_MENU();
return true;
}
}
return false;
}
void AddSC_custom_gossip_codebox()
{
Script *newscript;
newscript = new Script;
newscript->Name="custom_gossip_codebox";
newscript->pGossipHello = &GossipHello_custom_gossip_codebox;
newscript->pGossipSelect = &GossipSelect_custom_gossip_codebox;
newscript->pGossipSelectWithCode = &GossipSelectWithCode_custom_gossip_codebox;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,202 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Test
SD%Complete: 100
SDComment: Script used for testing escortAI
SDCategory: Script Examples
EndScriptData */
#include "precompiled.h"
#include "../npc/npc_escortAI.h"
struct MANGOS_DLL_DECL npc_testAI : public npc_escortAI
{
public:
// CreatureAI functions
npc_testAI(Creature *c) : npc_escortAI(c) {Reset();}
uint32 DeathCoilTimer;
uint32 ChatTimer;
// Pure Virtual Functions
void WaypointReached(uint32 i)
{
switch (i)
{
case 1:
m_creature->Say("Hmm a nice day for a walk alright", LANG_UNIVERSAL, 0);
break;
case 3:
{
m_creature->Say("Wild Felboar attack!", LANG_UNIVERSAL, 0);
Creature* temp = m_creature->SummonCreature(21878, m_creature->GetPositionX()+5, m_creature->GetPositionY()+7, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 3000);
temp->AI()->AttackStart(m_creature);
}
break;
case 4:
{
m_creature->Say("Time for me to go! See ya around $N!", LANG_UNIVERSAL, PlayerGUID);
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_WAVE);
Unit* temp = Unit::GetUnit(*m_creature, PlayerGUID);
if (temp)
{
temp->MonsterSay("Bye Bye!", LANG_UNIVERSAL, 0);
temp->HandleEmoteCommand(EMOTE_ONESHOT_WAVE);
}
}
break;
}
}
void Aggro(Unit*)
{
if (IsBeingEscorted)
m_creature->Say("Help $N! I'm under attack!", LANG_UNIVERSAL, PlayerGUID);
else m_creature->Say("Die scum!", LANG_UNIVERSAL, 0);
}
void Reset()
{
DeathCoilTimer = 4000;
ChatTimer = 4000;
}
void JustDied(Unit* killer)
{
if (IsBeingEscorted)
{
//killer = m_creature when player got to far from creature
if (killer == m_creature)
{
Unit *pTemp = Unit::GetUnit(*m_creature,PlayerGUID);
if( pTemp )
DoWhisper("How dare you leave me like that! I hate you! =*(", pTemp);
}
else m_creature->Say("...no...how could you let me die $N", LANG_UNIVERSAL, PlayerGUID);
}
else m_creature->Say("ugh...", LANG_UNIVERSAL, 0);
}
void UpdateAI(const uint32 diff)
{
//Must update npc_escortAI
npc_escortAI::UpdateAI(diff);
//Combat check
if (InCombat && m_creature->getVictim())
{
if (DeathCoilTimer < diff)
{
m_creature->Say("Taste death!", LANG_UNIVERSAL, 0);
m_creature->CastSpell(m_creature->getVictim(), 33130, false);
DeathCoilTimer = 4000;
}else DeathCoilTimer -= diff;
}else
{
//Out of combat but being escorted
if (IsBeingEscorted)
if (ChatTimer < diff)
{
if (m_creature->HasAura(3593, 0))
{
m_creature->Say("Fireworks!", LANG_UNIVERSAL, 0);
m_creature->CastSpell(m_creature, 11540, false);
}else
{
m_creature->Say("Hmm, I think I could use a buff", LANG_UNIVERSAL, 0);
m_creature->CastSpell(m_creature, 3593, false);
}
ChatTimer = 12000;
}else ChatTimer -= diff;
}
}
};
CreatureAI* GetAI_test(Creature *_Creature)
{
npc_testAI* testAI = new npc_testAI(_Creature);
testAI->AddWaypoint(0, 1231, -4419, 23);
testAI->AddWaypoint(1, 1198, -4440, 23, 0);
testAI->AddWaypoint(2, 1208, -4392, 23);
testAI->AddWaypoint(3, 1231, -4419, 23, 5000);
testAI->AddWaypoint(4, 1208, -4392, 23, 5000);
return (CreatureAI*)testAI;
}
bool GossipHello_npc_test(Player *player, Creature *_Creature)
{
player->TalkedToCreature(_Creature->GetEntry(),_Creature->GetGUID());
_Creature->prepareGossipMenu(player,0);
player->PlayerTalkClass->GetGossipMenu()->AddMenuItem(0, "Click to Test Escort(Attack, Defend, Run)", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1,"",0);
player->PlayerTalkClass->GetGossipMenu()->AddMenuItem(0, "Click to Test Escort(NoAttack, NoDefend, Walk)", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2,"",0);
player->PlayerTalkClass->GetGossipMenu()->AddMenuItem(0, "Click to Test Escort(NoAttack, Defend, Walk)", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3,"",0);
_Creature->sendPreparedGossip( player );
return true;
}
bool GossipSelect_npc_test(Player *player, Creature *_Creature, uint32 sender, uint32 action )
{
if (action == GOSSIP_ACTION_INFO_DEF+1)
{
player->CLOSE_GOSSIP_MENU();
((npc_escortAI*)(_Creature->AI()))->Start(true, true, true, player->GetGUID());
return true; // prevent mangos core handling
}
if (action == GOSSIP_ACTION_INFO_DEF+2)
{
player->CLOSE_GOSSIP_MENU();
((npc_escortAI*)(_Creature->AI()))->Start(false, false, false, player->GetGUID());
return true; // prevent mangos core handling
}
if (action == GOSSIP_ACTION_INFO_DEF+3)
{
player->CLOSE_GOSSIP_MENU();
((npc_escortAI*)(_Creature->AI()))->Start(false, true, false, player->GetGUID());
return true; // prevent mangos core handling
}
return false;
}
void AddSC_test()
{
Script *newscript;
newscript = new Script;
newscript->Name="test";
newscript->GetAI = GetAI_test;
newscript->pGossipHello = &GossipHello_npc_test;
newscript->pGossipSelect = &GossipSelect_npc_test;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,209 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: GO_Scripts
SD%Complete: 100
SDComment: Quest support: 4285,4287,4288(crystal pylons), 4296. Field_Repair_Bot->Teaches spell 22704. Barov_journal->Teaches spell 26089
SDCategory: Game Objects
EndScriptData */
/* ContentData
go_northern_crystal_pylon
go_eastern_crystal_pylon
go_western_crystal_pylon
go_barov_journal
go_field_repair_bot_74A
go_orb_of_command
go_tablet_of_madness
go_tablet_of_the_seven
go_teleporter
EndContentData */
#include "precompiled.h"
/*######
## go_crystal_pylons (3x)
######*/
bool GOHello_go_northern_crystal_pylon(Player *player, GameObject* _GO)
{
if (_GO->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER)
{
player->PrepareQuestMenu(_GO->GetGUID());
player->SendPreparedQuest(_GO->GetGUID());
}
if (player->GetQuestStatus(4285) == QUEST_STATUS_INCOMPLETE)
player->AreaExploredOrEventHappens(4285);
return true;
}
bool GOHello_go_eastern_crystal_pylon(Player *player, GameObject* _GO)
{
if (_GO->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER)
{
player->PrepareQuestMenu(_GO->GetGUID());
player->SendPreparedQuest(_GO->GetGUID());
}
if (player->GetQuestStatus(4287) == QUEST_STATUS_INCOMPLETE)
player->AreaExploredOrEventHappens(4287);
return true;
}
bool GOHello_go_western_crystal_pylon(Player *player, GameObject* _GO)
{
if (_GO->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER)
{
player->PrepareQuestMenu(_GO->GetGUID());
player->SendPreparedQuest(_GO->GetGUID());
}
if (player->GetQuestStatus(4288) == QUEST_STATUS_INCOMPLETE)
player->AreaExploredOrEventHappens(4288);
return true;
}
/*######
## go_barov_journal
######*/
bool GOHello_go_barov_journal(Player *player, GameObject* _GO)
{
if(player->HasSkill(SKILL_TAILORING) && player->GetBaseSkillValue(SKILL_TAILORING) >= 280 && !player->HasSpell(26086))
{
player->CastSpell(player,26095,false);
}
return true;
}
/*######
## go_field_repair_bot_74A
######*/
bool GOHello_go_field_repair_bot_74A(Player *player, GameObject* _GO)
{
if(player->HasSkill(SKILL_ENGINERING) && player->GetBaseSkillValue(SKILL_ENGINERING) >= 300 && !player->HasSpell(22704))
{
player->CastSpell(player,22864,false);
}
return true;
}
/*######
## go_orb_of_command
######*/
bool GOHello_go_orb_of_command(Player *player, GameObject* _GO)
{
if( player->GetQuestRewardStatus(7761) )
player->CastSpell(player,23460,true);
return true;
}
/*######
## go_tablet_of_madness
######*/
bool GOHello_go_tablet_of_madness(Player *player, GameObject* _GO)
{
if (player->HasSkill(SKILL_ALCHEMY) && player->GetSkillValue(SKILL_ALCHEMY) >= 300 && !player->HasSpell(24266))
{
player->CastSpell(player,24267,false);
}
return true;
}
/*######
## go_tablet_of_the_seven
######*/
//TODO: use gossip option ("Transcript the Tablet") instead, if Mangos adds support.
bool GOHello_go_tablet_of_the_seven(Player *player, GameObject* _GO)
{
if (_GO->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER)
return true;
if (player->GetQuestStatus(4296) == QUEST_STATUS_INCOMPLETE)
player->CastSpell(player,15065,false);
return true;
}
/*######
## go_teleporter
######*/
bool GOHello_go_teleporter(Player *player, GameObject* _GO)
{
player->TeleportTo(0, 1807.07f,336.105f,70.3975f,0.0f);
return false;
}
void AddSC_go_scripts()
{
Script *newscript;
newscript = new Script;
newscript->Name="go_northern_crystal_pylon";
newscript->pGOHello = &GOHello_go_northern_crystal_pylon;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="go_eastern_crystal_pylon";
newscript->pGOHello = &GOHello_go_eastern_crystal_pylon;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="go_western_crystal_pylon";
newscript->pGOHello = &GOHello_go_western_crystal_pylon;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="go_barov_journal";
newscript->pGOHello = &GOHello_go_barov_journal;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="go_field_repair_bot_74A";
newscript->pGOHello = &GOHello_go_field_repair_bot_74A;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="go_orb_of_command";
newscript->pGOHello = &GOHello_go_orb_of_command;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="go_tablet_of_madness";
newscript->pGOHello = GOHello_go_tablet_of_madness;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="go_tablet_of_the_seven";
newscript->pGOHello = GOHello_go_tablet_of_the_seven;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="go_teleporter";
newscript->pGOHello = GOHello_go_teleporter;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,160 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Guard_AI
SD%Complete: 90
SDComment:
SDCategory: Guards
EndScriptData */
#include "precompiled.h"
#include "guard_ai.h"
// **** This script is for use within every single guard to save coding time ****
#define GENERIC_CREATURE_COOLDOWN 5000
void guardAI::Reset()
{
GlobalCooldown = 0;
BuffTimer = 0; //Rebuff as soon as we can
}
void guardAI::Aggro(Unit *who)
{
}
void guardAI::JustDied(Unit *Killer)
{
//Send Zone Under Attack message to the LocalDefense and WorldDefense Channels
if( Killer->GetTypeId() == TYPEID_PLAYER )
m_creature->SendZoneUnderAttackMessage((Player*)Killer);
else if( Unit *owner = Killer->GetOwner() )
{
if( owner->GetTypeId() == TYPEID_PLAYER )
m_creature->SendZoneUnderAttackMessage((Player*)owner);
}
}
void guardAI::UpdateAI(const uint32 diff)
{
//Always decrease our global cooldown first
if (GlobalCooldown > diff)
GlobalCooldown -= diff;
else GlobalCooldown = 0;
//Buff timer (only buff when we are alive and not in combat
if (m_creature->isAlive() && !InCombat)
if (BuffTimer < diff )
{
//Find a spell that targets friendly and applies an aura (these are generally buffs)
SpellEntry const *info = SelectSpell(m_creature, -1, -1, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_AURA);
if (info && !GlobalCooldown)
{
//Cast the buff spell
DoCastSpell(m_creature, info);
//Set our global cooldown
GlobalCooldown = GENERIC_CREATURE_COOLDOWN;
//Set our timer to 10 minutes before rebuff
BuffTimer = 600000;
} //Try agian in 30 seconds
else BuffTimer = 30000;
}else BuffTimer -= diff;
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
// Make sure our attack is ready and we arn't currently casting
if( m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false))
{
//If we are within range melee the target
if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
{
bool Healing = false;
SpellEntry const *info = NULL;
//Select a healing spell if less than 30% hp
if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 30)
info = SelectSpell(m_creature, -1, -1, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_HEALING);
//No healing spell available, select a hostile spell
if (info) Healing = true;
else info = SelectSpell(m_creature->getVictim(), -1, -1, SELECT_TARGET_ANY_ENEMY, 0, 0, 0, 0, SELECT_EFFECT_DONTCARE);
//20% chance to replace our white hit with a spell
if (info && rand() % 5 == 0 && !GlobalCooldown)
{
//Cast the spell
if (Healing)DoCastSpell(m_creature, info);
else DoCastSpell(m_creature->getVictim(), info);
//Set our global cooldown
GlobalCooldown = GENERIC_CREATURE_COOLDOWN;
}
else m_creature->AttackerStateUpdate(m_creature->getVictim());
m_creature->resetAttackTimer();
}
}
else
{
//Only run this code if we arn't already casting
if (!m_creature->IsNonMeleeSpellCasted(false))
{
bool Healing = false;
SpellEntry const *info = NULL;
//Select a healing spell if less than 30% hp ONLY 33% of the time
if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 30 && rand() % 3 == 0)
info = SelectSpell(m_creature, -1, -1, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_HEALING);
//No healing spell available, See if we can cast a ranged spell (Range must be greater than ATTACK_DISTANCE)
if (info) Healing = true;
else info = SelectSpell(m_creature->getVictim(), -1, -1, SELECT_TARGET_ANY_ENEMY, 0, 0, ATTACK_DISTANCE, 0, SELECT_EFFECT_DONTCARE);
//Found a spell, check if we arn't on cooldown
if (info && !GlobalCooldown)
{
//If we are currently moving stop us and set the movement generator
if ((*m_creature).GetMotionMaster()->GetCurrentMovementGeneratorType()!=IDLE_MOTION_TYPE)
{
(*m_creature).GetMotionMaster()->Clear(false);
(*m_creature).GetMotionMaster()->MoveIdle();
}
//Cast spell
if (Healing) DoCastSpell(m_creature,info);
else DoCastSpell(m_creature->getVictim(),info);
//Set our global cooldown
GlobalCooldown = GENERIC_CREATURE_COOLDOWN;
} //If no spells available and we arn't moving run to target
else if ((*m_creature).GetMotionMaster()->GetCurrentMovementGeneratorType()!=TARGETED_MOTION_TYPE)
{
//Cancel our current spell and then mutate new movement generator
m_creature->InterruptNonMeleeSpells(false);
(*m_creature).GetMotionMaster()->Clear(false);
(*m_creature).GetMotionMaster()->MoveChase(m_creature->getVictim());
}
}
}
}
@@ -0,0 +1,25 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef SC_GUARDAI_H
#define SC_GUARDAI_H
#define GENERIC_CREATURE_COOLDOWN 5000
struct MANGOS_DLL_DECL guardAI : public ScriptedAI
{
guardAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 GlobalCooldown; //This variable acts like the global cooldown that players have (1.5 seconds)
uint32 BuffTimer; //This variable keeps track of buffs
void Reset();
void Aggro(Unit *who);
void JustDied(Unit *Killer);
void UpdateAI(const uint32 diff);
};
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,529 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Item_Scripts
SD%Complete: 100
SDComment: Items for a range of different items. See content below (in script)
SDCategory: Items
EndScriptData */
/* ContentData
item_area_52_special(i28132) Prevents abuse of this item
item_attuned_crystal_cores(i34368) Prevent abuse(quest 11524 & 11525)
item_blackwhelp_net(i31129) Quest Whelps of the Wyrmcult (q10747). Prevents abuse
item_draenei_fishing_net(i23654) Hacklike implements chance to spawn item or creature
item_disciplinary_rod Prevents abuse
item_nether_wraith_beacon(i31742) Summons creatures for quest Becoming a Spellfire Tailor (q10832)
item_flying_machine(i34060,i34061) Engineering crafted flying machines
item_gor_dreks_ointment(i30175) Protecting Our Own(q10488)
item_muiseks_vessel Cast on creature, they must be dead(q 3123,3124,3125,3126,3127)
item_protovoltaic_magneto_collector Prevents abuse
item_razorthorn_flayer_gland Quest Discovering Your Roots (q11520) and Rediscovering Your Roots (q11521). Prevents abuse
item_tame_beast_rods(many) Prevent cast on any other creature than the intended (for all tame beast quests)
item_soul_cannon(i32825) Prevents abuse of this item
item_sparrowhawk_net(i32321) Quest To Catch A Sparrowhawk (q10987). Prevents abuse
item_voodoo_charm Provide proper error message and target(q2561)
item_vorenthals_presence(i30259) Prevents abuse of this item
item_yehkinyas_bramble(i10699) Allow cast spell on vale screecher only and remove corpse if cast sucessful (q3520)
item_zezzak_shard(i31463) Quest The eyes of Grillok (q10813). Prevents abuse
EndContentData */
#include "precompiled.h"
#include "SpellMgr.h"
#include "Spell.h"
#include "WorldPacket.h"
/*#####
# item_area_52_special
#####*/
bool ItemUse_item_area_52_special(Player *player, Item* _Item, SpellCastTargets const& targets)
{
if ( player->GetAreaId() == 3803 )
{
return false;
}
else
{
player->SendEquipError(EQUIP_ERR_OUT_OF_RANGE,_Item,NULL);
return true;
}
}
/*#####
# item_attuned_crystal_cores
#####*/
bool ItemUse_item_attuned_crystal_cores(Player *player, Item* _Item, SpellCastTargets const& targets)
{
if( targets.getUnitTarget() && targets.getUnitTarget()->GetTypeId()==TYPEID_UNIT &&
targets.getUnitTarget()->GetEntry() == 24972 && targets.getUnitTarget()->isDead() )
return false;
player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW,_Item,NULL);
return true;
}
/*#####
# item_blackwhelp_net
#####*/
bool ItemUse_item_blackwhelp_net(Player *player, Item* _Item, SpellCastTargets const& targets)
{
if( targets.getUnitTarget() && targets.getUnitTarget()->GetTypeId()==TYPEID_UNIT &&
targets.getUnitTarget()->GetEntry() == 21387 )
return false;
player->SendEquipError(EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM,_Item,NULL);
return true;
}
/*#####
# item_draenei_fishing_net
#####*/
//This is just a hack and should be removed from here.
//Creature/Item are in fact created before spell are sucessfully casted, without any checks at all to ensure proper/expected behavior.
bool ItemUse_item_draenei_fishing_net(Player *player, Item* _Item, SpellCastTargets const& targets)
{
//if( targets.getGOTarget() && targets.getGOTarget()->GetTypeId() == TYPEID_GAMEOBJECT &&
//targets.getGOTarget()->GetGOInfo()->type == GAMEOBJECT_TYPE_SPELL_FOCUS && targets.getGOTarget()->GetEntry() == 181616 )
//{
if( player->GetQuestStatus(9452) == QUEST_STATUS_INCOMPLETE )
{
if( rand()%100 < 35 )
{
Creature *Murloc = player->SummonCreature(17102,player->GetPositionX() ,player->GetPositionY()+20, player->GetPositionZ(), 0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
if( Murloc )
Murloc->AI()->AttackStart(player);
}
else
{
ItemPosCountVec dest;
uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 23614, 1);
if( msg == EQUIP_ERR_OK )
{
Item* item = player->StoreNewItem(dest,23614,true);
if( item )
player->SendNewItem(item,1,false,true);
}else
player->SendEquipError(msg,NULL,NULL);
}
}
//}
return false;
}
/*#####
# item_disciplinary_rod
#####*/
bool ItemUse_item_disciplinary_rod(Player *player, Item* _Item, SpellCastTargets const& targets)
{
if( targets.getUnitTarget() && targets.getUnitTarget()->GetTypeId()==TYPEID_UNIT &&
(targets.getUnitTarget()->GetEntry() == 15941 || targets.getUnitTarget()->GetEntry() == 15945) )
return false;
player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW,_Item,NULL);
return true;
}
/*#####
# item_nether_wraith_beacon
#####*/
bool ItemUse_item_nether_wraith_beacon(Player *player, Item* _Item, SpellCastTargets const& targets)
{
if (player->GetQuestStatus(10832) == QUEST_STATUS_INCOMPLETE)
{
Creature *Nether;
Nether = player->SummonCreature(22408,player->GetPositionX() ,player->GetPositionY()+20, player->GetPositionZ(), 0,TEMPSUMMON_TIMED_DESPAWN,180000);
Nether = player->SummonCreature(22408,player->GetPositionX() ,player->GetPositionY()-20, player->GetPositionZ(), 0,TEMPSUMMON_TIMED_DESPAWN,180000);
if (Nether)
((CreatureAI*)Nether->AI())->AttackStart(player);
}
return false;
}
/*#####
# item_flying_machine
#####*/
bool ItemUse_item_flying_machine(Player *player, Item* _Item, SpellCastTargets const& targets)
{
uint32 itemId = _Item->GetEntry();
if( itemId == 34060 )
if( player->GetBaseSkillValue(SKILL_RIDING) >= 225 )
return false;
if( itemId == 34061 )
if( player->GetBaseSkillValue(SKILL_RIDING) == 300 )
return false;
debug_log("SD2: Player attempt to use item %u, but did not meet riding requirement",itemId);
player->SendEquipError(EQUIP_ERR_ERR_CANT_EQUIP_SKILL,_Item,NULL);
return true;
}
/*#####
# item_gor_dreks_ointment
#####*/
bool ItemUse_item_gor_dreks_ointment(Player *player, Item* _Item, SpellCastTargets const& targets)
{
if( targets.getUnitTarget() && targets.getUnitTarget()->GetTypeId()==TYPEID_UNIT &&
targets.getUnitTarget()->GetEntry() == 20748 && !targets.getUnitTarget()->HasAura(32578,0) )
return false;
player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW,_Item,NULL);
return true;
}
/*#####
# item_muiseks_vessel
#####*/
bool ItemUse_item_muiseks_vessel(Player *player, Item* _Item, SpellCastTargets const& targets)
{
Unit* uTarget = targets.getUnitTarget();
uint32 itemSpell = _Item->GetProto()->Spells[0].SpellId;
uint32 cEntry = 0;
uint32 cEntry2 = 0;
uint32 cEntry3 = 0;
uint32 cEntry4 = 0;
if(itemSpell)
{
switch(itemSpell)
{
case 11885: //Wandering Forest Walker
cEntry = 7584;
break;
case 11886: //Owlbeasts
cEntry = 2927;
cEntry2 = 2928;
cEntry3 = 2929;
cEntry4 = 7808;
break;
case 11887: //Freyfeather Hippogryphs
cEntry = 5300;
cEntry2 = 5304;
cEntry3 = 5305;
cEntry4 = 5306;
break;
case 11888: //Sprite Dragon Sprite Darters
cEntry = 5276;
cEntry2 = 5278;
break;
case 11889: //Zapped Land Walker Land Walker Zapped Cliff Giant Cliff Giant
cEntry = 5357;
cEntry2 = 5358;
cEntry3 = 14640;
cEntry4 = 14604;
break;
}
if( uTarget && uTarget->GetTypeId()==TYPEID_UNIT && uTarget->isDead() &&
(uTarget->GetEntry()==cEntry || uTarget->GetEntry()==cEntry2 || uTarget->GetEntry()==cEntry3 || uTarget->GetEntry()==cEntry4) )
{
((Creature*)uTarget)->RemoveCorpse();
return false;
}
}
WorldPacket data(SMSG_CAST_FAILED, (4+2)); // prepare packet error message
data << uint32(_Item->GetEntry()); // itemId
data << uint8(SPELL_FAILED_BAD_TARGETS); // reason
player->GetSession()->SendPacket(&data); // send message: Invalid target
player->SendEquipError(EQUIP_ERR_NONE,_Item,NULL); // break spell
return true;
}
/*#####
# item_razorthorn_flayer_gland
#####*/
bool ItemUse_item_razorthorn_flayer_gland(Player *player, Item* _Item, SpellCastTargets const& targets)
{
if( targets.getUnitTarget() && targets.getUnitTarget()->GetTypeId()==TYPEID_UNIT &&
targets.getUnitTarget()->GetEntry() == 24922 )
return false;
player->SendEquipError(EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM,_Item,NULL);
return true;
}
/*#####
# item_tame_beast_rods
#####*/
bool ItemUse_item_tame_beast_rods(Player *player, Item* _Item, SpellCastTargets const& targets)
{
uint32 itemSpell = _Item->GetProto()->Spells[0].SpellId;
uint32 cEntry = 0;
if(itemSpell)
{
switch(itemSpell)
{
case 19548: cEntry = 1196; break; //Ice Claw Bear
case 19674: cEntry = 1126; break; //Large Crag Boar
case 19687: cEntry = 1201; break; //Snow Leopard
case 19688: cEntry = 2956; break; //Adult Plainstrider
case 19689: cEntry = 2959; break; //Prairie Stalker
case 19692: cEntry = 2970; break; //Swoop
case 19693: cEntry = 1998; break; //Webwood Lurker
case 19694: cEntry = 3099; break; //Dire Mottled Boar
case 19696: cEntry = 3107; break; //Surf Crawler
case 19697: cEntry = 3126; break; //Armored Scorpid
case 19699: cEntry = 2043; break; //Nightsaber Stalker
case 19700: cEntry = 1996; break; //Strigid Screecher
case 30646: cEntry = 17217; break; //Barbed Crawler
case 30653: cEntry = 17374; break; //Greater Timberstrider
case 30654: cEntry = 17203; break; //Nightstalker
case 30099: cEntry = 15650; break; //Crazed Dragonhawk
case 30102: cEntry = 15652; break; //Elder Springpaw
case 30105: cEntry = 16353; break; //Mistbat
}
if( targets.getUnitTarget() && targets.getUnitTarget()->GetTypeId()==TYPEID_UNIT &&
targets.getUnitTarget()->GetEntry() == cEntry )
return false;
}
WorldPacket data(SMSG_CAST_FAILED, (4+2)); // prepare packet error message
data << uint32(_Item->GetEntry()); // itemId
data << uint8(SPELL_FAILED_BAD_TARGETS); // reason
player->GetSession()->SendPacket(&data); // send message: Invalid target
player->SendEquipError(EQUIP_ERR_NONE,_Item,NULL); // break spell
return true;
}
/*#####
# item_protovoltaic_magneto_collector
#####*/
bool ItemUse_item_protovoltaic_magneto_collector(Player *player, Item* _Item, SpellCastTargets const& targets)
{
if( targets.getUnitTarget() && targets.getUnitTarget()->GetTypeId()==TYPEID_UNIT &&
targets.getUnitTarget()->GetEntry() == 21729 )
return false;
player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW,_Item,NULL);
return true;
}
/*#####
# item_soul_cannon
#####*/
bool ItemUse_item_soul_cannon(Player *player, Item* _Item, SpellCastTargets const& targets)
{
// allow use
if( targets.getUnitTarget() && targets.getUnitTarget()->GetTypeId()==TYPEID_UNIT &&
targets.getUnitTarget()->GetEntry() == 22357 )
return false;
// error
player->SendEquipError(EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM,_Item,NULL);
return true;
}
/*#####
# item_sparrowhawk_net
#####*/
bool ItemUse_item_sparrowhawk_net(Player *player, Item* _Item, SpellCastTargets const& targets)
{
if( targets.getUnitTarget() && targets.getUnitTarget()->GetTypeId()==TYPEID_UNIT &&
targets.getUnitTarget()->GetEntry() == 22979 )
return false;
player->SendEquipError(EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM,_Item,NULL);
return true;
}
/*#####
# item_voodoo_charm
#####*/
bool ItemUse_item_voodoo_charm(Player *player, Item* _Item, SpellCastTargets const& targets)
{
if( targets.getUnitTarget() && targets.getUnitTarget()->GetTypeId()==TYPEID_UNIT && targets.getUnitTarget()->isDead() &&
targets.getUnitTarget()->GetEntry()==7318 )
return false;
WorldPacket data(SMSG_CAST_FAILED, (4+2)); // prepare packet error message
data << uint32(_Item->GetEntry()); // itemId
data << uint8(SPELL_FAILED_BAD_TARGETS); // reason
player->GetSession()->SendPacket(&data); // send message: Invalid target
player->SendEquipError(EQUIP_ERR_NONE,_Item,NULL); // break spell
return true;
}
/*#####
# item_vorenthals_presence
#####*/
bool ItemUse_item_vorenthals_presence(Player *player, Item* _Item, SpellCastTargets const& targets)
{
// allow use
if( targets.getUnitTarget() && targets.getUnitTarget()->GetTypeId()==TYPEID_UNIT &&
targets.getUnitTarget()->GetEntry() == 20132 )
return false;
// error
player->SendEquipError(EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM,_Item,NULL);
return true;
}
/*#####
# item_yehkinyas_bramble
#####*/
bool ItemUse_item_yehkinyas_bramble(Player *player, Item* _Item, SpellCastTargets const& targets)
{
if (player->GetQuestStatus(3520) == QUEST_STATUS_INCOMPLETE)
{
Unit * unit_target = targets.getUnitTarget();
if( unit_target &&
unit_target->GetTypeId()==TYPEID_UNIT &&
unit_target->isDead() &&
// cast only on corpse 5307 or 5308
(unit_target->GetEntry()==5307 || unit_target->GetEntry()==5308) )
{
((Creature*)unit_target)->RemoveCorpse(); // remove corpse for cancelling second use
return false; // all ok
}
}
WorldPacket data(SMSG_CAST_FAILED, (4+2)); // prepare packet error message
data << uint32(10699); // itemId
data << uint8(SPELL_FAILED_BAD_TARGETS); // reason
player->GetSession()->SendPacket(&data); // send message: Bad target
player->SendEquipError(EQUIP_ERR_NONE,_Item,NULL); // break spell
return true;
}
/*#####
# item_zezzak_shard
#####*/
bool ItemUse_item_zezzak_shard(Player *player, Item* _Item, SpellCastTargets const& targets)
{
if( targets.getUnitTarget() && targets.getUnitTarget()->GetTypeId()==TYPEID_UNIT &&
targets.getUnitTarget()->GetEntry() == 19440 )
return false;
player->SendEquipError(EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM,_Item,NULL);
return true;
}
void AddSC_item_scripts()
{
Script *newscript;
newscript = new Script;
newscript->Name="item_area_52_special";
newscript->pItemUse = ItemUse_item_area_52_special;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="item_attuned_crystal_cores";
newscript->pItemUse = ItemUse_item_attuned_crystal_cores;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="item_blackwhelp_net";
newscript->pItemUse = ItemUse_item_blackwhelp_net;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="item_disciplinary_rod";
newscript->pItemUse = ItemUse_item_disciplinary_rod;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="item_draenei_fishing_net";
newscript->pItemUse = ItemUse_item_draenei_fishing_net;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="item_nether_wraith_beacon";
newscript->pItemUse = ItemUse_item_nether_wraith_beacon;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="item_flying_machine";
newscript->pItemUse = ItemUse_item_flying_machine;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="item_gor_dreks_ointment";
newscript->pItemUse = ItemUse_item_gor_dreks_ointment;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="item_muiseks_vessel";
newscript->pItemUse = ItemUse_item_muiseks_vessel;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="item_razorthorn_flayer_gland";
newscript->pItemUse = ItemUse_item_razorthorn_flayer_gland;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="item_tame_beast_rods";
newscript->pItemUse = ItemUse_item_tame_beast_rods;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="item_protovoltaic_magneto_collector";
newscript->pItemUse = ItemUse_item_protovoltaic_magneto_collector;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="item_soul_cannon";
newscript->pItemUse = ItemUse_item_soul_cannon;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="item_sparrowhawk_net";
newscript->pItemUse = ItemUse_item_sparrowhawk_net;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="item_voodoo_charm";
newscript->pItemUse = ItemUse_item_voodoo_charm;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="item_vorenthals_presence";
newscript->pItemUse = ItemUse_item_vorenthals_presence;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="item_yehkinyas_bramble";
newscript->pItemUse = ItemUse_item_yehkinyas_bramble;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="item_zezzaks_shard";
newscript->pItemUse = ItemUse_item_zezzak_shard;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,42 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Item_Test
SD%Complete: 100
SDComment: Used for Testing Item Scripts
SDCategory: Items
EndScriptData */
#include "precompiled.h"
extern void LoadDatabase();
bool ItemUse_item_test(Player *player, Item* _Item, SpellCastTargets const& targets)
{
LoadDatabase();
return true;
}
void AddSC_item_test()
{
Script *newscript;
newscript = new Script;
newscript->Name="item_test";
newscript->pItemUse = ItemUse_item_test;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,304 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
/* ScriptData
SDName: Npc_EscortAI
SD%Complete: 100
SDComment:
SDCategory: Npc
EndScriptData */
#include "precompiled.h"
#include "npc_escortAI.h"
#define WP_LAST_POINT -1
#define MAX_PLAYER_DISTANCE 50
bool npc_escortAI::IsVisible(Unit* who) const
{
if (!who)
return false;
return (m_creature->GetDistance(who) < VISIBLE_RANGE) && who->isVisibleForOrDetect(m_creature,true);
}
void npc_escortAI::AttackStart(Unit *who)
{
if (!who)
return;
if (IsBeingEscorted && !Defend)
return;
if (who->isTargetableForAttack())
{
//Begin attack
if ( m_creature->Attack(who, true) )
{
m_creature->GetMotionMaster()->MovementExpired();
m_creature->GetMotionMaster()->MoveChase(who);
m_creature->AddThreat(who, 0.0f);
}
if (!InCombat)
{
InCombat = true;
//Store last position
m_creature->GetPosition(LastPos.x, LastPos.y, LastPos.z);
debug_log("SD2: EscortAI has entered combat via Attack and stored last location");
Aggro(who);
}
}
}
void npc_escortAI::MoveInLineOfSight(Unit *who)
{
if (IsBeingEscorted && !Attack)
return;
if( !m_creature->getVictim() && who->isTargetableForAttack() && ( m_creature->IsHostileTo( who )) && who->isInAccessablePlaceFor(m_creature) )
{
if (m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
return;
float attackRadius = m_creature->GetAttackDistance(who);
if( m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who) )
{
who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
//Begin attack
if ( m_creature->Attack(who, true) )
{
m_creature->GetMotionMaster()->MovementExpired();
m_creature->GetMotionMaster()->MoveChase(who);
m_creature->AddThreat(who, 0.0f);
}
if (!InCombat)
{
InCombat = true;
//Store last position
m_creature->GetPosition(LastPos.x, LastPos.y, LastPos.z);
debug_log("SD2: EscortAI has entered combat via LOS and stored last location");
Aggro(who);
}
}
}
}
void npc_escortAI::JustRespawned()
{
InCombat = false;
IsBeingEscorted = false;
IsOnHold = false;
//Re-Enable gossip
m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
Reset();
}
void npc_escortAI::EnterEvadeMode()
{
InCombat = false;
m_creature->RemoveAllAuras();
m_creature->DeleteThreatList();
m_creature->CombatStop();
m_creature->SetLootRecipient(NULL);
if (IsBeingEscorted)
{
debug_log("SD2: EscortAI has left combat and is now returning to last point");
Returning = true;
m_creature->GetMotionMaster()->MovementExpired();
m_creature->GetMotionMaster()->MovePoint(WP_LAST_POINT, LastPos.x, LastPos.y, LastPos.z);
}else
{
m_creature->GetMotionMaster()->MovementExpired();
m_creature->GetMotionMaster()->MoveTargetedHome();
}
Reset();
}
void npc_escortAI::UpdateAI(const uint32 diff)
{
//Waypoint Updating
if (IsBeingEscorted && !InCombat && WaitTimer && !Returning)
if (WaitTimer <= diff)
{
if (ReconnectWP)
{
//Correct movement speed
if (Run)
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
else m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
//Continue with waypoints
if( !IsOnHold )
{
m_creature->GetMotionMaster()->MovePoint(CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z );
debug_log("SD2: EscortAI Reconnect WP is: %d, %f, %f, %f", CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z);
WaitTimer = 0;
ReconnectWP = false;
return;
}
}
//End of the line, Despawn self then immediatly respawn
if (CurrentWP == WaypointList.end())
{
debug_log("SD2: EscortAI reached end of waypoints");
m_creature->setDeathState(JUST_DIED);
m_creature->SetHealth(0);
m_creature->CombatStop();
m_creature->DeleteThreatList();
m_creature->Respawn();
m_creature->GetMotionMaster()->Clear(true);
//Re-Enable gossip
m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
IsBeingEscorted = false;
WaitTimer = 0;
return;
}
if( !IsOnHold )
{
m_creature->GetMotionMaster()->MovePoint(CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z );
debug_log("SD2: EscortAI Next WP is: %d, %f, %f, %f", CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z);
WaitTimer = 0;
}
}else WaitTimer -= diff;
//Check if player is within range
if (IsBeingEscorted && !InCombat && PlayerGUID)
if (PlayerTimer < diff)
{
Unit* p = Unit::GetUnit(*m_creature, PlayerGUID);
if (!p || m_creature->GetDistance(p) > MAX_PLAYER_DISTANCE)
{
JustDied(m_creature);
IsBeingEscorted = false;
debug_log("SD2: EscortAI Evaded back to spawn point because player was to far away or not found");
m_creature->setDeathState(JUST_DIED);
m_creature->SetHealth(0);
m_creature->CombatStop();
m_creature->DeleteThreatList();
m_creature->Respawn();
m_creature->GetMotionMaster()->Clear(true);
//Re-Enable gossip
m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
}
PlayerTimer = 1000;
}else PlayerTimer -= diff;
//Check if we have a current target
if( m_creature->isAlive() && m_creature->SelectHostilTarget() && m_creature->getVictim())
{
//If we are within range melee the target
if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
{
if( m_creature->isAttackReady() )
{
m_creature->AttackerStateUpdate(m_creature->getVictim());
m_creature->resetAttackTimer();
}
}
}
}
void npc_escortAI::MovementInform(uint32 type, uint32 id)
{
if (type != POINT_MOTION_TYPE || !IsBeingEscorted)
return;
//Original position reached, continue waypoint movement
if (id == WP_LAST_POINT)
{
debug_log("SD2: EscortAI has returned to original position before combat");
ReconnectWP = true;
Returning = false;
WaitTimer = 1;
}else
{
//Make sure that we are still on the right waypoint
if (CurrentWP->id != id)
{
debug_log("SD2 ERROR: EscortAI reached waypoint out of order %d, expected %d", id, CurrentWP->id);
return;
}
debug_log("SD2: EscortAI Waypoint %d reached", CurrentWP->id);
//Call WP function
WaypointReached(CurrentWP->id);
WaitTimer = CurrentWP->WaitTimeMs + 1;
++CurrentWP;
}
}
void npc_escortAI::AddWaypoint(uint32 id, float x, float y, float z, uint32 WaitTimeMs)
{
Escort_Waypoint t(id, x, y, z, WaitTimeMs);
WaypointList.push_back(t);
}
void npc_escortAI::Start(bool bAttack, bool bDefend, bool bRun, uint64 pGUID)
{
if (InCombat)
{
debug_log("SD2 ERROR: EscortAI attempt to Start while in combat");
return;
}
if (WaypointList.empty())
{
debug_log("SD2 ERROR: Call to escortAI::Start with 0 waypoints");
return;
}
Attack = bAttack;
Defend = bDefend;
Run = bRun;
PlayerGUID = pGUID;
debug_log("SD2: EscortAI started with %d waypoints. Attack = %d, Defend = %d, Run = %d, PlayerGUID = %d", WaypointList.size(), Attack, Defend, Run, PlayerGUID);
CurrentWP = WaypointList.begin();
//Set initial speed
if (Run)
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
else m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
//Start WP
m_creature->GetMotionMaster()->MovePoint(CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z );
debug_log("SD2: EscortAI Next WP is: %d, %f, %f, %f", CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z);
IsBeingEscorted = true;
ReconnectWP = false;
Returning = false;
IsOnHold = false;
//Disable gossip
m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
}
@@ -0,0 +1,85 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef SC_ESCORTAI_H
#define SC_ESCORTAI_H
struct Escort_Waypoint
{
Escort_Waypoint(uint32 _id, float _x, float _y, float _z, uint32 _w)
{
id = _id;
x = _x;
y = _y;
z = _z;
WaitTimeMs = _w;
}
uint32 id;
float x;
float y;
float z;
uint32 WaitTimeMs;
};
struct MANGOS_DLL_DECL npc_escortAI : public ScriptedAI
{
public:
// Pure Virtual Functions
virtual void WaypointReached(uint32) = 0;
virtual void Aggro(Unit*) = 0;
virtual void Reset() = 0;
// CreatureAI functions
npc_escortAI(Creature *c) : ScriptedAI(c), IsBeingEscorted(false), PlayerTimer(1000) {m_creature->GetPosition(LastPos.x, LastPos.y, LastPos.z);}
bool IsVisible(Unit*) const;
void AttackStart(Unit*);
void MoveInLineOfSight(Unit*);
void JustRespawned();
void EnterEvadeMode();
void UpdateAI(const uint32);
void MovementInform(uint32, uint32);
// EscortAI functions
void AddWaypoint(uint32 id, float x, float y, float z, uint32 WaitTimeMs = 0);
void Start(bool bAttack, bool bDefend, bool bRun, uint64 pGUID = 0);
// EscortAI variables
protected:
uint64 PlayerGUID;
bool IsBeingEscorted;
bool IsOnHold;
private:
uint32 WaitTimer;
uint32 PlayerTimer;
struct
{
float x;
float y;
float z;
}LastPos;
std::list<Escort_Waypoint> WaypointList;
std::list<Escort_Waypoint>::iterator CurrentWP;
bool Attack;
bool Defend;
bool Returning;
bool ReconnectWP;
bool Run;
};
#endif
@@ -0,0 +1,144 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Npc_Innkeeper
SD%Complete: 50
SDComment: This script are currently not in use. EventSystem cannot be used on Windows build of SD2
SDCategory: NPCs
EndScriptData */
#include "precompiled.h"
#define HALLOWEEN_EVENTID 12
#define SPELL_TRICK_OR_TREATED 24755
#define SPELL_TREAT 24715
#define LOCALE_TRICK_OR_TREAT_0 "Trick or Treat!"
#define LOCALE_TRICK_OR_TREAT_2 "Des bonbons ou des blagues!"
#define LOCALE_TRICK_OR_TREAT_3 "Süßes oder Saures!"
#define LOCALE_TRICK_OR_TREAT_6 "¡Truco o trato!"
bool isEventActive()
{
/*
const GameEvent::ActiveEvents *ActiveEventsList = gameeventmgr.GetActiveEventList();
GameEvent::ActiveEvents::const_iterator itr;
for (itr = ActiveEventsList->begin(); itr != ActiveEventsList->end(); ++itr)
{
if (*itr==HALLOWEEN_EVENTID)
{
return true;
}
}*/
return false;
}
bool GossipHello_npc_innkeeper(Player *player, Creature *_Creature)
{
if (_Creature->isQuestGiver())
player->PrepareQuestMenu( _Creature->GetGUID() );
if (isEventActive()&& !player->GetAura(SPELL_TRICK_OR_TREATED,0))
{
char* localizedEntry;
switch (player->GetSession()->GetSessionDbLocaleIndex())
{
case 0:
localizedEntry=LOCALE_TRICK_OR_TREAT_0;
break;
case 2:
localizedEntry=LOCALE_TRICK_OR_TREAT_2;
break;
case 3:
localizedEntry=LOCALE_TRICK_OR_TREAT_3;
break;
case 6:
localizedEntry=LOCALE_TRICK_OR_TREAT_6;
break;
default:
localizedEntry=LOCALE_TRICK_OR_TREAT_0;
}
player->ADD_GOSSIP_ITEM(0, localizedEntry, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+HALLOWEEN_EVENTID);
}
player->TalkedToCreature(_Creature->GetEntry(),_Creature->GetGUID());
player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
return true;
}
bool GossipSelect_npc_innkeeper(Player *player, Creature *_Creature, uint32 sender, uint32 action )
{
if (action == GOSSIP_ACTION_INFO_DEF+HALLOWEEN_EVENTID && isEventActive() && !player->GetAura(SPELL_TRICK_OR_TREATED,0))
{
player->CLOSE_GOSSIP_MENU();
player->CastSpell(player, SPELL_TRICK_OR_TREATED, true);
// either trick or treat, 50% chance
if(rand()%2)
{
player->CastSpell(player, SPELL_TREAT, true);
}
else
{
int32 trickspell=0;
switch (rand()%9) // note that female characters can get male costumes and vice versa
{
case 0:
trickspell=24753; // cannot cast, random 30sec
break;
case 1:
trickspell=24713; // lepper gnome costume
break;
case 2:
trickspell=24735; // male ghost costume
break;
case 3:
trickspell=24736; // female ghostcostume
break;
case 4:
trickspell=24710; // male ninja costume
break;
case 5:
trickspell=24711; // female ninja costume
break;
case 6:
trickspell=24708; // male pirate costume
break;
case 7:
trickspell=24709; // female pirate costume
break;
case 8:
trickspell=24723; // skeleton costume
break;
}
player->CastSpell(player, trickspell, true);
}
return true; // prevent mangos core handling
}
return false; // the player didn't select "trick or treat" or cheated, normal core handling
}
void AddSC_npc_innkeeper()
{
Script *newscript;
newscript = new Script;
newscript->Name="npc_innkeeper";
newscript->pGossipHello = &GossipHello_npc_innkeeper;
newscript->pGossipSelect = &GossipSelect_npc_innkeeper;
m_scripts[nrscripts++] = newscript;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,878 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Npcs_Special
SD%Complete: 100
SDComment: To be used for special NPCs that are located globally. Support for quest 3861 (Cluck!), 6622 and 6624 (Triage)
SDCategory: NPCs
EndScriptData
*/
/* ContentData
npc_chicken_cluck 100% support for quest 3861 (Cluck!)
npc_dancing_flames 100% midsummer event NPC
npc_guardian 100% guardianAI used to prevent players from accessing off-limits areas. Not in use by SD2
npc_injured_patient 100% patients for triage-quests (6622 and 6624)
npc_doctor 100% Gustaf Vanhowzen and Gregory Victor, quest 6622 and 6624 (Triage)
npc_mount_vendor 100% Regular mount vendors all over the world. Display gossip if player doesn't meet the requirements to buy
npc_rogue_trainer 80% Scripted trainers, so they are able to offer item 17126 for class quest 6681
npc_sayge 100% Darkmoon event fortune teller, buff player based on answers given
EndContentData */
#include "precompiled.h"
/*########
# npc_chicken_cluck
#########*/
#define QUEST_CLUCK 3861
#define EMOTE_A_HELLO "looks up at you quizzically. Maybe you should inspect it?"
#define EMOTE_H_HELLO "looks at you unexpectadly."
#define CLUCK_TEXT2 "starts pecking at the feed."
#define FACTION_FRIENDLY 84
#define FACTION_CHICKEN 31
struct MANGOS_DLL_DECL npc_chicken_cluckAI : public ScriptedAI
{
npc_chicken_cluckAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 ResetFlagTimer;
void Reset()
{
ResetFlagTimer = 120000;
m_creature->setFaction(FACTION_CHICKEN);
m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
}
void Aggro(Unit *who) {}
void UpdateAI(const uint32 diff)
{
// Reset flags after a certain time has passed so that the next player has to start the 'event' again
if(m_creature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER))
{
if(ResetFlagTimer < diff)
EnterEvadeMode();
else ResetFlagTimer -= diff;
}
if(m_creature->SelectHostilTarget() && m_creature->getVictim())
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_npc_chicken_cluck(Creature *_Creature)
{
return new npc_chicken_cluckAI(_Creature);
}
bool ReceiveEmote_npc_chicken_cluck( Player *player, Creature *_Creature, uint32 emote )
{
if( emote == TEXTEMOTE_CHICKEN )
{
if( player->GetTeam() == ALLIANCE )
{
if( rand()%30 == 1 )
{
if( player->GetQuestStatus(QUEST_CLUCK) == QUEST_STATUS_NONE )
{
_Creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
_Creature->setFaction(FACTION_FRIENDLY);
_Creature->MonsterTextEmote(EMOTE_A_HELLO, 0);
}
}
} else
_Creature->MonsterTextEmote(EMOTE_H_HELLO,0);
}
if( emote == TEXTEMOTE_CHEER && player->GetTeam() == ALLIANCE )
if( player->GetQuestStatus(QUEST_CLUCK) == QUEST_STATUS_COMPLETE )
{
_Creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
_Creature->setFaction(FACTION_FRIENDLY);
_Creature->MonsterTextEmote(CLUCK_TEXT2, 0);
}
return true;
}
bool QuestAccept_npc_chicken_cluck(Player *player, Creature *_Creature, const Quest *_Quest )
{
if(_Quest->GetQuestId() == QUEST_CLUCK)
((npc_chicken_cluckAI*)_Creature->AI())->Reset();
return true;
}
bool QuestComplete_npc_chicken_cluck(Player *player, Creature *_Creature, const Quest *_Quest)
{
if(_Quest->GetQuestId() == QUEST_CLUCK)
((npc_chicken_cluckAI*)_Creature->AI())->Reset();
return true;
}
/*######
## npc_dancing_flames
######*/
bool ReceiveEmote_npc_dancing_flames( Player *player, Creature *_Creature, uint32 emote )
{
if( emote == TEXTEMOTE_DANCE )
_Creature->CastSpell(player,47057,false);
return true;
}
/*######
## Triage quest
######*/
#define SAY_DOC1 "I'm saved! Thank you, doctor!"
#define SAY_DOC2 "HOORAY! I AM SAVED!"
#define SAY_DOC3 "Sweet, sweet embrace... take me..."
struct Location
{
float x, y, z, o;
};
#define DOCTOR_ALLIANCE 12939
static Location AllianceCoords[]=
{
{ // Top-far-right bunk as seen from entrance
-3757.38, -4533.05, 14.16, 3.62
},
{ // Top-far-left bunk
-3754.36, -4539.13, 14.16, 5.13
},
{ // Far-right bunk
-3749.54, -4540.25, 14.28, 3.34
},
{ // Right bunk near entrance
-3742.10, -4536.85, 14.28, 3.64
},
{ // Far-left bunk
-3755.89, -4529.07, 14.05, 0.57
},
{ // Mid-left bunk
-3749.51, -4527.08, 14.07, 5.26
},
{ // Left bunk near entrance
-3746.37, -4525.35, 14.16, 5.22
},
};
#define ALLIANCE_COORDS 7
//alliance run to where
#define A_RUNTOX -3742.96
#define A_RUNTOY -4531.52
#define A_RUNTOZ 11.91
#define DOCTOR_HORDE 12920
static Location HordeCoords[]=
{
{ // Left, Behind
-1013.75, -3492.59, 62.62, 4.34
},
{ // Right, Behind
-1017.72, -3490.92, 62.62, 4.34
},
{ // Left, Mid
-1015.77, -3497.15, 62.82, 4.34
},
{ // Right, Mid
-1019.51, -3495.49, 62.82, 4.34
},
{ // Left, front
-1017.25, -3500.85, 62.98, 4.34
},
{ // Right, Front
-1020.95, -3499.21, 62.98, 4.34
}
};
#define HORDE_COORDS 6
//horde run to where
#define H_RUNTOX -1016.44
#define H_RUNTOY -3508.48
#define H_RUNTOZ 62.96
const uint32 AllianceSoldierId[3] =
{
12938, // 12938 Injured Alliance Soldier
12936, // 12936 Badly injured Alliance Soldier
12937 // 12937 Critically injured Alliance Soldier
};
const uint32 HordeSoldierId[3] =
{
12923, //12923 Injured Soldier
12924, //12924 Badly injured Soldier
12925 //12925 Critically injured Soldier
};
/*######
## npc_doctor (handles both Gustaf Vanhowzen and Gregory Victor)
######*/
struct MANGOS_DLL_DECL npc_doctorAI : public ScriptedAI
{
uint64 Playerguid;
uint32 SummonPatient_Timer;
uint32 SummonPatientCount;
uint32 PatientDiedCount;
uint32 PatientSavedCount;
bool Event;
std::list<uint64> Patients;
std::vector<Location*> Coordinates;
npc_doctorAI(Creature *c) : ScriptedAI(c) {Reset();}
void Reset(){}
void BeginEvent(Player* player);
void PatientDied(Location* Point);
void PatientSaved(Creature* soldier, Player* player, Location* Point);
void UpdateAI(const uint32 diff);
void Aggro(Unit* who){}
};
/*#####
## npc_injured_patient (handles all the patients, no matter Horde or Alliance)
#####*/
struct MANGOS_DLL_DECL npc_injured_patientAI : public ScriptedAI
{
npc_injured_patientAI(Creature *c) : ScriptedAI(c) {Reset();}
uint64 Doctorguid;
Location* Coord;
void Reset()
{
Doctorguid = 0;
Coord = NULL;
//no select
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
//no regen health
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
//to make them lay with face down
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_DEAD);
uint32 mobId = m_creature->GetEntry();
switch (mobId)
{ //lower max health
case 12923:
case 12938: //Injured Soldier
m_creature->SetHealth(uint32(m_creature->GetMaxHealth()*.75));
break;
case 12924:
case 12936: //Badly injured Soldier
m_creature->SetHealth(uint32(m_creature->GetMaxHealth()*.50));
break;
case 12925:
case 12937: //Critically injured Soldier
m_creature->SetHealth(uint32(m_creature->GetMaxHealth()*.25));
break;
}
}
void Aggro(Unit* who){}
void SpellHit(Unit *caster, const SpellEntry *spell)
{
if (caster->GetTypeId() == TYPEID_PLAYER && m_creature->isAlive() && spell->Id == 20804)
{
if( (((Player*)caster)->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE) || (((Player*)caster)->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE))
{
if(Doctorguid)
{
Creature* Doctor = ((Creature*)Unit::GetUnit((*m_creature), Doctorguid));
if(Doctor)
((npc_doctorAI*)Doctor->AI())->PatientSaved(m_creature, ((Player*)caster), Coord);
}
}
//make not selectable
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
//regen health
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
//stand up
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_NONE);
DoSay(SAY_DOC1,LANG_UNIVERSAL,NULL);
uint32 mobId = m_creature->GetEntry();
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
switch (mobId)
{
case 12923:
case 12924:
case 12925:
m_creature->GetMotionMaster()->MovePoint(0, H_RUNTOX, H_RUNTOY, H_RUNTOZ);
break;
case 12936:
case 12937:
case 12938:
m_creature->GetMotionMaster()->MovePoint(0, A_RUNTOX, A_RUNTOY, A_RUNTOZ);
break;
}
}
return;
}
void UpdateAI(const uint32 diff)
{
if (m_creature->isAlive() && m_creature->GetHealth() > 6)
{ //lower HP on every world tick makes it a useful counter, not officlone though
m_creature->SetHealth(uint32(m_creature->GetHealth()-5) );
}
if (m_creature->isAlive() && m_creature->GetHealth() <= 6)
{
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
m_creature->setDeathState(JUST_DIED);
m_creature->SetFlag(UNIT_DYNAMIC_FLAGS, 32);
if(Doctorguid)
{
Creature* Doctor = ((Creature*)Unit::GetUnit((*m_creature), Doctorguid));
if(Doctor)
((npc_doctorAI*)Doctor->AI())->PatientDied(Coord);
}
}
}
};
CreatureAI* GetAI_npc_injured_patient(Creature *_Creature)
{
return new npc_injured_patientAI (_Creature);
}
/*
npc_doctor (continue)
*/
void npc_doctorAI::BeginEvent(Player* player)
{
Playerguid = player->GetGUID();
SummonPatient_Timer = 10000;
SummonPatientCount = 0;
PatientDiedCount = 0;
PatientSavedCount = 0;
switch(m_creature->GetEntry())
{
case DOCTOR_ALLIANCE:
for(uint8 i = 0; i < ALLIANCE_COORDS; ++i)
Coordinates.push_back(&AllianceCoords[i]);
break;
case DOCTOR_HORDE:
for(uint8 i = 0; i < HORDE_COORDS; ++i)
Coordinates.push_back(&HordeCoords[i]);
break;
}
Event = true;
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
void npc_doctorAI::PatientDied(Location* Point)
{
Player* player = ((Player*)Unit::GetUnit((*m_creature), Playerguid));
if(player && ((player->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE) || (player->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE)))
{
PatientDiedCount++;
if (PatientDiedCount > 5 && Event)
{
if(player->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE)
player->FailQuest(6624);
else if(player->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE)
player->FailQuest(6622);
Event = false;
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
Coordinates.push_back(Point);
}
}
void npc_doctorAI::PatientSaved(Creature* soldier, Player* player, Location* Point)
{
if(player && Playerguid == player->GetGUID())
{
if((player->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE) || (player->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE))
{
PatientSavedCount++;
if(PatientSavedCount == 15)
{
if(!Patients.empty())
{
std::list<uint64>::iterator itr;
for(itr = Patients.begin(); itr != Patients.end(); ++itr)
{
Creature* Patient = ((Creature*)Unit::GetUnit((*m_creature), *itr));
if( Patient )
Patient->setDeathState(JUST_DIED);
}
}
if(player->GetQuestStatus(6624) == QUEST_STATUS_INCOMPLETE)
player->AreaExploredOrEventHappens(6624);
else if(player->GetQuestStatus(6622) == QUEST_STATUS_INCOMPLETE)
player->AreaExploredOrEventHappens(6622);
Event = false;
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
Coordinates.push_back(Point);
}
}
}
void npc_doctorAI::UpdateAI(const uint32 diff)
{
if(Event && SummonPatientCount >= 20)
{
Event = false;
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
if(Event)
if(SummonPatient_Timer < diff)
{
Creature* Patient = NULL;
Location* Point = NULL;
if(Coordinates.empty())
return;
std::vector<Location*>::iterator itr = Coordinates.begin()+rand()%Coordinates.size();
uint32 patientEntry = 0;
switch(m_creature->GetEntry())
{
case DOCTOR_ALLIANCE: patientEntry = AllianceSoldierId[rand()%3]; break;
case DOCTOR_HORDE: patientEntry = HordeSoldierId[rand()%3]; break;
default:
error_log("SD2: Invalid entry for Triage doctor. Please check your database");
return;
}
Point = *itr;
Patient = m_creature->SummonCreature(patientEntry, Point->x, Point->y, Point->z, Point->o, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
if(Patient)
{
Patients.push_back(Patient->GetGUID());
((npc_injured_patientAI*)Patient->AI())->Doctorguid = m_creature->GetGUID();
if(Point)
((npc_injured_patientAI*)Patient->AI())->Coord = Point;
Coordinates.erase(itr);
}
SummonPatient_Timer = 10000;
SummonPatientCount++;
}else SummonPatient_Timer -= diff;
}
bool QuestAccept_npc_doctor(Player *player, Creature *creature, Quest const *quest )
{
if((quest->GetQuestId() == 6624) || (quest->GetQuestId() == 6622))
((npc_doctorAI*)creature->AI())->BeginEvent(player);
return true;
}
CreatureAI* GetAI_npc_doctor(Creature *_Creature)
{
return new npc_doctorAI (_Creature);
}
/*######
## npc_guardian
######*/
#define SPELL_DEATHTOUCH 5
#define SAY_AGGRO "This area is closed!"
struct MANGOS_DLL_DECL npc_guardianAI : public ScriptedAI
{
npc_guardianAI(Creature *c) : ScriptedAI(c) {Reset();}
void Reset()
{
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
}
void Aggro(Unit *who)
{
DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL);
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if (m_creature->isAttackReady())
{
m_creature->CastSpell(m_creature->getVictim(),SPELL_DEATHTOUCH, true);
m_creature->resetAttackTimer();
}
}
};
CreatureAI* GetAI_npc_guardian(Creature *_Creature)
{
return new npc_guardianAI (_Creature);
}
/*######
## npc_mount_vendor
######*/
bool GossipHello_npc_mount_vendor(Player *player, Creature *_Creature)
{
if (_Creature->isQuestGiver())
player->PrepareQuestMenu( _Creature->GetGUID() );
bool canBuy;
canBuy = false;
uint32 vendor = _Creature->GetEntry();
uint8 race = player->getRace();
switch (vendor)
{
case 384: //Katie Hunter
case 1460: //Unger Statforth
case 2357: //Merideth Carlson
case 4885: //Gregor MacVince
if (player->GetReputationRank(72) != REP_EXALTED && race != RACE_HUMAN)
player->SEND_GOSSIP_MENU(5855, _Creature->GetGUID());
else canBuy = true;
break;
case 1261: //Veron Amberstill
if (player->GetReputationRank(47) != REP_EXALTED && race != RACE_DWARF)
player->SEND_GOSSIP_MENU(5856, _Creature->GetGUID());
else canBuy = true;
break;
case 3362: //Ogunaro Wolfrunner
if (player->GetReputationRank(76) != REP_EXALTED && race != RACE_ORC)
player->SEND_GOSSIP_MENU(5841, _Creature->GetGUID());
else canBuy = true;
break;
case 3685: //Harb Clawhoof
if (player->GetReputationRank(81) != REP_EXALTED && race != RACE_TAUREN)
player->SEND_GOSSIP_MENU(5843, _Creature->GetGUID());
else canBuy = true;
break;
case 4730: //Lelanai
if (player->GetReputationRank(69) != REP_EXALTED && race != RACE_NIGHTELF)
player->SEND_GOSSIP_MENU(5844, _Creature->GetGUID());
else canBuy = true;
break;
case 4731: //Zachariah Post
if (player->GetReputationRank(68) != REP_EXALTED && race != RACE_UNDEAD_PLAYER)
player->SEND_GOSSIP_MENU(5840, _Creature->GetGUID());
else canBuy = true;
break;
case 7952: //Zjolnir
if (player->GetReputationRank(530) != REP_EXALTED && race != RACE_TROLL)
player->SEND_GOSSIP_MENU(5842, _Creature->GetGUID());
else canBuy = true;
break;
case 7955: //Milli Featherwhistle
if (player->GetReputationRank(54) != REP_EXALTED && race != RACE_GNOME)
player->SEND_GOSSIP_MENU(5857, _Creature->GetGUID());
else canBuy = true;
break;
case 16264: //Winaestra
if (player->GetReputationRank(911) != REP_EXALTED && race != RACE_BLOODELF)
player->SEND_GOSSIP_MENU(10305, _Creature->GetGUID());
else canBuy = true;
break;
case 17584: //Torallius the Pack Handler
if (player->GetReputationRank(930) != REP_EXALTED && race != RACE_DRAENEI)
player->SEND_GOSSIP_MENU(10239, _Creature->GetGUID());
else canBuy = true;
break;
}
if (canBuy)
{
if (_Creature->isVendor())
player->ADD_GOSSIP_ITEM( 1, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
}
return true;
}
bool GossipSelect_npc_mount_vendor(Player *player, Creature *_Creature, uint32 sender, uint32 action)
{
if (action == GOSSIP_ACTION_TRADE)
player->SEND_VENDORLIST( _Creature->GetGUID() );
return true;
}
/*######
## npc_rogue_trainer
######*/
bool GossipHello_npc_rogue_trainer(Player *player, Creature *_Creature)
{
if( _Creature->isQuestGiver() )
player->PrepareQuestMenu( _Creature->GetGUID() );
if( _Creature->isTrainer() )
player->ADD_GOSSIP_ITEM(2, GOSSIP_TEXT_TRAIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRAIN);
if( _Creature->isCanTrainingAndResetTalentsOf(player) )
player->ADD_GOSSIP_ITEM(2, "I wish to unlearn my talents", GOSSIP_SENDER_MAIN, GOSSIP_OPTION_UNLEARNTALENTS);
if( player->getClass() == CLASS_ROGUE && player->getLevel() >= 24 && !player->HasItemCount(17126,1) && !player->GetQuestRewardStatus(6681) )
{
player->ADD_GOSSIP_ITEM(0, "<Take the letter>", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
player->SEND_GOSSIP_MENU(5996, _Creature->GetGUID());
} else
player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
return true;
}
bool GossipSelect_npc_rogue_trainer(Player *player, Creature *_Creature, uint32 sender, uint32 action)
{
switch( action )
{
case GOSSIP_ACTION_INFO_DEF+1:
player->CLOSE_GOSSIP_MENU();
player->CastSpell(player,21100,false);
break;
case GOSSIP_ACTION_TRAIN:
player->SEND_TRAINERLIST( _Creature->GetGUID() );
break;
case GOSSIP_OPTION_UNLEARNTALENTS:
player->CLOSE_GOSSIP_MENU();
player->SendTalentWipeConfirm( _Creature->GetGUID() );
break;
}
return true;
}
/*######
## npc_sayge
######*/
#define SPELL_DMG 23768 //dmg
#define SPELL_RES 23769 //res
#define SPELL_ARM 23767 //arm
#define SPELL_SPI 23738 //spi
#define SPELL_INT 23766 //int
#define SPELL_STM 23737 //stm
#define SPELL_STR 23735 //str
#define SPELL_AGI 23736 //agi
#define SPELL_FORTUNE 23765 //faire fortune
bool GossipHello_npc_sayge(Player *player, Creature *_Creature)
{
if(_Creature->isQuestGiver())
player->PrepareQuestMenu( _Creature->GetGUID() );
if( player->HasSpellCooldown(SPELL_INT) ||
player->HasSpellCooldown(SPELL_ARM) ||
player->HasSpellCooldown(SPELL_DMG) ||
player->HasSpellCooldown(SPELL_RES) ||
player->HasSpellCooldown(SPELL_STR) ||
player->HasSpellCooldown(SPELL_AGI) ||
player->HasSpellCooldown(SPELL_STM) ||
player->HasSpellCooldown(SPELL_SPI) )
player->SEND_GOSSIP_MENU(7393, _Creature->GetGUID());
else
{
player->ADD_GOSSIP_ITEM(0, "Yes", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
player->SEND_GOSSIP_MENU(7339, _Creature->GetGUID());
}
return true;
}
void SendAction_npc_sayge(Player *player, Creature *_Creature, uint32 action)
{
switch(action)
{
case GOSSIP_ACTION_INFO_DEF+1:
player->ADD_GOSSIP_ITEM(0, "Slay the Man", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
player->ADD_GOSSIP_ITEM(0, "Turn him over to liege", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
player->ADD_GOSSIP_ITEM(0, "Confiscate the corn", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
player->ADD_GOSSIP_ITEM(0, "Let him go and have the corn", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5);
player->SEND_GOSSIP_MENU(7340, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+2:
player->ADD_GOSSIP_ITEM(0, "Execute your friend painfully", GOSSIP_SENDER_MAIN+1, GOSSIP_ACTION_INFO_DEF);
player->ADD_GOSSIP_ITEM(0, "Execute your friend painlessly", GOSSIP_SENDER_MAIN+2, GOSSIP_ACTION_INFO_DEF);
player->ADD_GOSSIP_ITEM(0, "Let your friend go", GOSSIP_SENDER_MAIN+3, GOSSIP_ACTION_INFO_DEF);
player->SEND_GOSSIP_MENU(7341, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+3:
player->ADD_GOSSIP_ITEM(0, "Confront the diplomat", GOSSIP_SENDER_MAIN+4, GOSSIP_ACTION_INFO_DEF);
player->ADD_GOSSIP_ITEM(0, "Show not so quiet defiance", GOSSIP_SENDER_MAIN+5, GOSSIP_ACTION_INFO_DEF);
player->ADD_GOSSIP_ITEM(0, "Remain quiet", GOSSIP_SENDER_MAIN+2, GOSSIP_ACTION_INFO_DEF);
player->SEND_GOSSIP_MENU(7361, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+4:
player->ADD_GOSSIP_ITEM(0, "Speak against your brother openly", GOSSIP_SENDER_MAIN+6, GOSSIP_ACTION_INFO_DEF);
player->ADD_GOSSIP_ITEM(0, "Help your brother in", GOSSIP_SENDER_MAIN+7, GOSSIP_ACTION_INFO_DEF);
player->ADD_GOSSIP_ITEM(0, "Keep your brother out without letting him know", GOSSIP_SENDER_MAIN+8, GOSSIP_ACTION_INFO_DEF);
player->SEND_GOSSIP_MENU(7362, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+5:
player->ADD_GOSSIP_ITEM(0, "Take credit, keep gold", GOSSIP_SENDER_MAIN+5, GOSSIP_ACTION_INFO_DEF);
player->ADD_GOSSIP_ITEM(0, "Take credit, share the gold", GOSSIP_SENDER_MAIN+4, GOSSIP_ACTION_INFO_DEF);
player->ADD_GOSSIP_ITEM(0, "Let the knight take credit", GOSSIP_SENDER_MAIN+3, GOSSIP_ACTION_INFO_DEF);
player->SEND_GOSSIP_MENU(7363, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF:
player->ADD_GOSSIP_ITEM(0, "Thanks", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6);
player->SEND_GOSSIP_MENU(7364, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+6:
_Creature->CastSpell(player, SPELL_FORTUNE, false);
player->SEND_GOSSIP_MENU(7365, _Creature->GetGUID());
break;
}
}
bool GossipSelect_npc_sayge(Player *player, Creature *_Creature, uint32 sender, uint32 action )
{
switch(sender)
{
case GOSSIP_SENDER_MAIN:
SendAction_npc_sayge(player, _Creature, action);
break;
case GOSSIP_SENDER_MAIN+1:
_Creature->CastSpell(player, SPELL_DMG, false);
player->AddSpellCooldown(SPELL_DMG,0,time(NULL) + 7200);
SendAction_npc_sayge(player, _Creature, action);
break;
case GOSSIP_SENDER_MAIN+2:
_Creature->CastSpell(player, SPELL_RES, false);
player->AddSpellCooldown(SPELL_RES,0,time(NULL) + 7200);
SendAction_npc_sayge(player, _Creature, action);
break;
case GOSSIP_SENDER_MAIN+3:
_Creature->CastSpell(player, SPELL_ARM, false);
player->AddSpellCooldown(SPELL_ARM,0,time(NULL) + 7200);
SendAction_npc_sayge(player, _Creature, action);
break;
case GOSSIP_SENDER_MAIN+4:
_Creature->CastSpell(player, SPELL_SPI, false);
player->AddSpellCooldown(SPELL_SPI,0,time(NULL) + 7200);
SendAction_npc_sayge(player, _Creature, action);
break;
case GOSSIP_SENDER_MAIN+5:
_Creature->CastSpell(player, SPELL_INT, false);
player->AddSpellCooldown(SPELL_INT,0,time(NULL) + 7200);
SendAction_npc_sayge(player, _Creature, action);
break;
case GOSSIP_SENDER_MAIN+6:
_Creature->CastSpell(player, SPELL_STM, false);
player->AddSpellCooldown(SPELL_STM,0,time(NULL) + 7200);
SendAction_npc_sayge(player, _Creature, action);
break;
case GOSSIP_SENDER_MAIN+7:
_Creature->CastSpell(player, SPELL_STR, false);
player->AddSpellCooldown(SPELL_STR,0,time(NULL) + 7200);
SendAction_npc_sayge(player, _Creature, action);
break;
case GOSSIP_SENDER_MAIN+8:
_Creature->CastSpell(player, SPELL_AGI, false);
player->AddSpellCooldown(SPELL_AGI,0,time(NULL) + 7200);
SendAction_npc_sayge(player, _Creature, action);
break;
}
return true;
}
void AddSC_npcs_special()
{
Script *newscript;
newscript = new Script;
newscript->Name="npc_chicken_cluck";
newscript->GetAI = GetAI_npc_chicken_cluck;
newscript->pReceiveEmote = &ReceiveEmote_npc_chicken_cluck;
newscript->pQuestAccept = &QuestAccept_npc_chicken_cluck;
newscript->pQuestComplete = &QuestComplete_npc_chicken_cluck;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="npc_dancing_flames";
newscript->pReceiveEmote = &ReceiveEmote_npc_dancing_flames;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="npc_injured_patient";
newscript->GetAI = GetAI_npc_injured_patient;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="npc_doctor";
newscript->GetAI = GetAI_npc_doctor;
newscript->pQuestAccept = &QuestAccept_npc_doctor;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="npc_guardian";
newscript->GetAI = GetAI_npc_guardian;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="npc_mount_vendor";
newscript->pGossipHello = &GossipHello_npc_mount_vendor;
newscript->pGossipSelect = &GossipSelect_npc_mount_vendor;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="npc_rogue_trainer";
newscript->pGossipHello = &GossipHello_npc_rogue_trainer;
newscript->pGossipSelect = &GossipSelect_npc_rogue_trainer;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="npc_sayge";
newscript->pGossipHello = &GossipHello_npc_sayge;
newscript->pGossipSelect = &GossipSelect_npc_sayge;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,62 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Alterac_Mountains
SD%Complete: 100
SDComment: Quest support: 6681
SDCategory: Alterac Mountains
EndScriptData */
/* ContentData
npc_ravenholdt
EndContentData */
#include "precompiled.h"
/*######
## npc_ravenholdt
######*/
struct MANGOS_DLL_DECL npc_ravenholdtAI : public ScriptedAI
{
npc_ravenholdtAI(Creature *c) : ScriptedAI(c) { Reset(); }
void Reset() { }
void MoveInLineOfSight(Unit *who)
{
if( who->GetTypeId() == TYPEID_PLAYER )
if( ((Player*)who)->GetQuestStatus(6681) == QUEST_STATUS_INCOMPLETE )
((Player*)who)->KilledMonster(m_creature->GetEntry(),m_creature->GetGUID() );
}
void Aggro(Unit* who) { }
};
CreatureAI* GetAI_npc_ravenholdt(Creature *_Creature)
{
return new npc_ravenholdtAI (_Creature);
}
void AddSC_alterac_mountains()
{
Script *newscript;
newscript = new Script;
newscript->Name="npc_ravenholdt";
newscript->GetAI = GetAI_npc_ravenholdt;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,405 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Exarch_Maladaar
SD%Complete: 95
SDComment: Most of event implemented, some adjustments to timers remain and possibly make some better code for switching his dark side in to better "images" of player.
SDCategory: Auchindoun, Auchenai Crypts
EndScriptData */
/* ContentData
mob_stolen_soul
boss_exarch_maladaar
mob_avatar_of_martyred
EndContentData */
#include "precompiled.h"
#define SPELL_MOONFIRE 37328
#define SPELL_FIREBALL 37329
#define SPELL_MIND_FLAY 37330
#define SPELL_HEMORRHAGE 37331
#define SPELL_FROSTSHOCK 37332
#define SPELL_CURSE_OF_AGONY 37334
#define SPELL_MORTAL_STRIKE 37335
#define SPELL_FREEZING_TRAP 37368
#define SPELL_HAMMER_OF_JUSTICE 37369
struct MANGOS_DLL_DECL mob_stolen_soulAI : public ScriptedAI
{
mob_stolen_soulAI(Creature *c) : ScriptedAI(c) {Reset();}
uint8 myClass;
uint32 Class_Timer;
void Reset()
{
Class_Timer = 1000;
}
void Aggro(Unit *who)
{ }
void SetMyClass(uint8 myclass)
{
myClass = myclass;
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if( Class_Timer < diff )
{
switch( myClass )
{
case CLASS_WARRIOR:
DoCast(m_creature->getVictim(), SPELL_MORTAL_STRIKE);
Class_Timer = 6000;
break;
case CLASS_PALADIN:
DoCast(m_creature->getVictim(), SPELL_HAMMER_OF_JUSTICE);
Class_Timer = 6000;
break;
case CLASS_HUNTER:
DoCast(m_creature->getVictim(), SPELL_FREEZING_TRAP);
Class_Timer = 20000;
break;
case CLASS_ROGUE:
DoCast(m_creature->getVictim(), SPELL_HEMORRHAGE);
Class_Timer = 10000;
break;
case CLASS_PRIEST:
DoCast(m_creature->getVictim(), SPELL_MIND_FLAY);
Class_Timer = 5000;
break;
case CLASS_SHAMAN:
DoCast(m_creature->getVictim(), SPELL_FROSTSHOCK);
Class_Timer = 8000;
break;
case CLASS_MAGE:
DoCast(m_creature->getVictim(), SPELL_FIREBALL);
Class_Timer = 5000;
break;
case CLASS_WARLOCK:
DoCast(m_creature->getVictim(), SPELL_CURSE_OF_AGONY);
Class_Timer = 20000;
break;
case CLASS_DRUID:
DoCast(m_creature->getVictim(), SPELL_MOONFIRE);
Class_Timer = 10000;
break;
default:
break;
}
}else Class_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_stolen_soul(Creature *_Creature)
{
return new mob_stolen_soulAI (_Creature);
}
#define SAY_INTRO "You have defiled the resting place of our ancestors. For this offense, there can be but one punishment. It is fitting that you have come to a place of the dead... for you will soon be joining them."
#define SOUND_INTRO 10509
#define SAY_SUMMON "Rise my fallen brothers. Take form and fight!"
#define SOUND_SUMMON 10512
#define SAY_AGGRO_1 "You will pay with your life!"
#define SOUND_AGGRO_1 10513
#define SAY_AGGRO_2 "There's no turning back now!"
#define SOUND_AGGRO_2 10514
#define SAY_AGGRO_3 "Serve your penitence!"
#define SOUND_AGGRO_3 10515
#define SAY_ROAR "Let your mind be clouded."
#define SOUND_ROAR 10510
#define SAY_SOUL_CLEAVE "Stare into the darkness of your soul."
#define SOUND_SOUL_CLEAVE 10511
#define SAY_SLAY_1 "These walls will be your doom."
#define SOUND_SLAY_1 10516
#define SAY_SLAY_2 "<laugh> Now, you'll stay for eternity!"
#define SOUND_SLAY_2 10517
#define SAY_DEATH "This is... where.. I belong..."
#define SOUND_DEATH 10518
#define SPELL_RIBBON_OF_SOULS 32422
#define SPELL_SOUL_SCREAM 32421
#define SPELL_STOLEN_SOUL 32346
#define SPELL_STOLEN_SOUL_VISUAL 32395
#define SPELL_SUMMON_AVATAR 32424
#define ENTRY_STOLEN_SOUL 18441
struct MANGOS_DLL_DECL boss_exarch_maladaarAI : public ScriptedAI
{
boss_exarch_maladaarAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 soulmodel;
uint64 soulholder;
uint8 soulclass;
uint32 Fear_timer;
uint32 Ribbon_of_Souls_timer;
uint32 StolenSoul_Timer;
bool HasTaunted;
bool Avatar_summoned;
void Reset()
{
soulmodel = 0;
soulholder = 0;
soulclass = 0;
Fear_timer = 20000;
Ribbon_of_Souls_timer = 5000;
StolenSoul_Timer = 30000;
HasTaunted = false;
Avatar_summoned = false;
}
void MoveInLineOfSight(Unit *who)
{
if( !m_creature->getVictim() && who->isTargetableForAttack() && ( m_creature->IsHostileTo( who )) && who->isInAccessablePlaceFor(m_creature) )
{
if( !HasTaunted && m_creature->IsWithinDistInMap(who, 150.0) )
{
DoYell(SAY_INTRO, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_INTRO);
HasTaunted = true;
}
if (m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
return;
float attackRadius = m_creature->GetAttackDistance(who);
if( m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who) )
{
DoStartAttackAndMovement(who);
who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
if (!InCombat)
{
Aggro(who);
InCombat = true;
}
}
}
}
void Aggro(Unit *who)
{
switch(rand()%3)
{
case 0:
DoYell(SAY_AGGRO_1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_AGGRO_1);
break;
case 1:
DoYell(SAY_AGGRO_2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_AGGRO_2);
break;
case 2:
DoYell(SAY_AGGRO_3, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_AGGRO_3);
break;
}
}
void JustSummoned(Creature *summoned)
{
if( summoned->GetEntry() == ENTRY_STOLEN_SOUL )
{
//SPELL_STOLEN_SOUL_VISUAL has shapeshift effect, but not implemented feature in mangos for this spell.
summoned->SetDisplayId(soulmodel);
summoned->CastSpell(summoned,SPELL_STOLEN_SOUL_VISUAL,false);
if( Unit *target = Unit::GetUnit(*m_creature,soulholder) )
summoned->AI()->AttackStart(target);
((mob_stolen_soulAI*)summoned->AI())->SetMyClass(soulclass);
}
}
void KilledUnit(Unit* victim)
{
if (rand()%2)
return;
switch(rand()%2)
{
case 0:
DoYell(SAY_SLAY_1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_SLAY_1);
break;
case 1:
DoYell(SAY_SLAY_2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_SLAY_2);
break;
}
}
void JustDied(Unit* Killer)
{
DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_DEATH);
//When Exarch Maladar is defeated D'ore appear.
DoSpawnCreature(19412,0,0,0,0, TEMPSUMMON_TIMED_DESPAWN, 600000);
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if( !Avatar_summoned && ((m_creature->GetHealth()*100) / m_creature->GetMaxHealth() < 25) )
{
if( m_creature->IsNonMeleeSpellCasted(false) )
m_creature->InterruptNonMeleeSpells(true);
DoYell(SAY_SUMMON, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_SUMMON);
DoCast(m_creature, SPELL_SUMMON_AVATAR);
Avatar_summoned = true;
StolenSoul_Timer = 45000;
}
if( StolenSoul_Timer < diff )
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
{
if( target->GetTypeId() == TYPEID_PLAYER )
{
if( m_creature->IsNonMeleeSpellCasted(false) )
m_creature->InterruptNonMeleeSpells(true);
uint32 i = urand(1,2);
if( i == 1 )
{
DoYell(SAY_ROAR, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_ROAR);
}
else
{
DoYell(SAY_SOUL_CLEAVE, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_SOUL_CLEAVE);
}
soulmodel = target->GetDisplayId();
soulholder = target->GetGUID();
soulclass = target->getClass();
DoCast(target,SPELL_STOLEN_SOUL);
DoSpawnCreature(ENTRY_STOLEN_SOUL,0,0,0,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,10000);
StolenSoul_Timer = 45000;
} else StolenSoul_Timer = 1000;
}
}else StolenSoul_Timer -= diff;
if( Ribbon_of_Souls_timer < diff )
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_RIBBON_OF_SOULS);
Ribbon_of_Souls_timer = 5000 + (rand()%20 * 1000);
}else Ribbon_of_Souls_timer -= diff;
if( Fear_timer < diff )
{
DoCast(m_creature,SPELL_SOUL_SCREAM);
Fear_timer = 25000 + rand()% 10000;
}else Fear_timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_exarch_maladaar(Creature *_Creature)
{
return new boss_exarch_maladaarAI (_Creature);
}
#define SPELL_MORTAL_STRIKE 16856
#define SPELL_SUNDER_ARMOR 16145
struct MANGOS_DLL_DECL mob_avatar_of_martyredAI : public ScriptedAI
{
mob_avatar_of_martyredAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 Mortal_Strike_timer;
void Reset()
{
Mortal_Strike_timer = 10000;
}
void Aggro(Unit *who)
{
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if(Mortal_Strike_timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_MORTAL_STRIKE);
Mortal_Strike_timer = 10000 + rand()%20 * 1000;
}else Mortal_Strike_timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_avatar_of_martyred(Creature *_Creature)
{
return new mob_avatar_of_martyredAI (_Creature);
}
void AddSC_boss_exarch_maladaar()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_exarch_maladaar";
newscript->GetAI = GetAI_boss_exarch_maladaar;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="mob_avatar_of_martyred";
newscript->GetAI = GetAI_mob_avatar_of_martyred;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="mob_stolen_soul";
newscript->GetAI = GetAI_mob_stolen_soul;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,313 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_NexusPrince_Shaffar
SD%Complete: 80
SDComment: Need more tuning of spell timers, it should not be as linear fight as current. Also should possibly find a better way to deal with his three initial beacons to make sure all aggro.
SDCategory: Auchindoun, Mana Tombs
EndScriptData */
/* ContentData
boss_nexusprince_shaffar
mob_ethereal_beacon
EndContentData */
#include "precompiled.h"
#define SAY_INTRO "What is this? You must forgive me, but I was not expecting company. As you can see, we are somewhat preoccupied right now. But no matter. As I am a gracious host, I will tend to you... personally."
#define SOUND_INTRO 10539
#define SAY_AGGRO_1 "We have not yet been properly introduced."
#define SOUND_AGGRO_1 10541
#define SAY_AGGRO_2 "An epic battle. How exciting!"
#define SOUND_AGGRO_2 10542
#define SAY_AGGRO_3 "I have longed for a good adventure."
#define SOUND_AGGRO_3 10543
#define SAY_SLAY_1 "It has been... entertaining."
#define SOUND_SLAY_1 10544
#define SAY_SLAY_2 "And now we part company."
#define SOUND_SLAY_2 10545
#define SAY_SUMMON "I have such fascinating things to show you."
#define SOUND_SUMMON 10540
#define SAY_DEAD "I must bid you... farewell."
#define SOUND_DEAD 10546
#define SPELL_BLINK 34605
#define SPELL_FROSTBOLT 32364
#define SPELL_FIREBALL 32363
#define SPELL_FROSTNOVA 32365
#define SPELL_ETHEREAL_BEACON 32371 // Summon 18431
#define SPELL_ETHEREAL_BEACON_VISUAL 32368
#define ENTRY_BEACON 18431
struct MANGOS_DLL_DECL boss_nexusprince_shaffarAI : public ScriptedAI
{
boss_nexusprince_shaffarAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 Blink_Timer;
uint32 Beacon_Timer;
uint32 FireBall_Timer;
uint32 Frostbolt_Timer;
uint32 FrostNova_Timer;
bool HasTaunted;
bool CanBlink;
void Reset()
{
Blink_Timer = 1500;
Beacon_Timer = 10000;
FireBall_Timer = 8000;
Frostbolt_Timer = 4000;
FrostNova_Timer = 15000;
HasTaunted = false;
CanBlink = false;
}
void MoveInLineOfSight(Unit *who)
{
if( !m_creature->getVictim() && who->isTargetableForAttack() && ( m_creature->IsHostileTo( who )) && who->isInAccessablePlaceFor(m_creature) )
{
if( !HasTaunted && m_creature->IsWithinDistInMap(who, 100.0) )
{
DoYell(SAY_INTRO, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_INTRO);
HasTaunted = true;
}
if (m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
return;
float attackRadius = m_creature->GetAttackDistance(who);
if( m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who) )
{
DoStartAttackAndMovement(who);
who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
if (!InCombat)
{
Aggro(who);
InCombat = true;
}
}
}
}
void Aggro(Unit *who)
{
switch(rand()%3)
{
case 0:
DoYell(SAY_AGGRO_1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_AGGRO_1);
break;
case 1:
DoYell(SAY_AGGRO_2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_AGGRO_2);
break;
case 2:
DoYell(SAY_AGGRO_3, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_AGGRO_3);
break;
}
}
void JustSummoned(Creature *summoned)
{
if( summoned->GetEntry() == ENTRY_BEACON )
{
summoned->CastSpell(summoned,SPELL_ETHEREAL_BEACON_VISUAL,false);
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
summoned->AI()->AttackStart(target);
}
}
void KilledUnit(Unit* victim)
{
switch(rand()%2)
{
case 0:
DoYell(SAY_SLAY_1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_SLAY_1);
break;
case 1:
DoYell(SAY_SLAY_2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_SLAY_2);
break;
}
}
void JustDied(Unit* Killer)
{
DoYell(SAY_DEAD, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_DEAD);
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if( FrostNova_Timer < diff )
{
if( m_creature->IsNonMeleeSpellCasted(false) )
m_creature->InterruptNonMeleeSpells(true);
DoCast(m_creature,SPELL_FROSTNOVA);
FrostNova_Timer = 17500 + rand()%7500;
CanBlink = true;
}else FrostNova_Timer -= diff;
if( Frostbolt_Timer < diff )
{
DoCast(m_creature->getVictim(),SPELL_FROSTBOLT);
Frostbolt_Timer = 4500 + rand()%1500;
}else Frostbolt_Timer -= diff;
if( FireBall_Timer < diff )
{
DoCast(m_creature->getVictim(),SPELL_FIREBALL);
FireBall_Timer = 4500 + rand()%1500;
}else FireBall_Timer -= diff;
if( CanBlink )
{
if( Blink_Timer < diff )
{
if( m_creature->IsNonMeleeSpellCasted(false) )
m_creature->InterruptNonMeleeSpells(true);
DoCast(m_creature,SPELL_BLINK);
Blink_Timer = 1000 + rand()%1500;
CanBlink = false;
}else Blink_Timer -= diff;
}
if( Beacon_Timer < diff)
{
if( m_creature->IsNonMeleeSpellCasted(false) )
m_creature->InterruptNonMeleeSpells(true);
if( !urand(0,3) )
{
DoYell(SAY_SUMMON, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_SUMMON);
}
DoCast(m_creature,SPELL_ETHEREAL_BEACON);
Beacon_Timer = 10000;
}else Beacon_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_nexusprince_shaffar(Creature *_Creature)
{
return new boss_nexusprince_shaffarAI (_Creature);
}
#define SPELL_ARCANE_BOLT 15254
#define SPELL_ETHEREAL_APPRENTICE 32372 // Summon 18430
struct MANGOS_DLL_DECL mob_ethereal_beaconAI : public ScriptedAI
{
mob_ethereal_beaconAI(Creature *c) : ScriptedAI(c)
{
HeroicMode = m_creature->GetMap()->IsHeroic();
Reset();
}
bool HeroicMode;
bool CanEvade;
uint32 Apprentice_Timer;
uint32 ArcaneBolt_Timer;
void Reset()
{
if( CanEvade )
m_creature->SetVisibility(VISIBILITY_OFF);
CanEvade = false;
Apprentice_Timer = (HeroicMode ? 10000 : 20000);
ArcaneBolt_Timer = 1000;
}
void Aggro(Unit *who)
{
}
void JustSummoned(Creature *summoned)
{
summoned->AI()->AttackStart(m_creature->getVictim());
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if( ArcaneBolt_Timer < diff )
{
DoCast(m_creature->getVictim(),SPELL_ARCANE_BOLT);
ArcaneBolt_Timer = 2000 + rand()%2500;
}else ArcaneBolt_Timer -= diff;
if( Apprentice_Timer < diff )
{
if( m_creature->IsNonMeleeSpellCasted(false) )
m_creature->InterruptNonMeleeSpells(true);
m_creature->CastSpell(m_creature,SPELL_ETHEREAL_APPRENTICE,true);
if( m_creature->GetOwner() )
((Pet*)m_creature)->SetDuration(0);
CanEvade = true;
}else Apprentice_Timer -= diff;
if( CanEvade )
EnterEvadeMode();
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_ethereal_beacon(Creature *_Creature)
{
return new mob_ethereal_beaconAI (_Creature);
}
void AddSC_boss_nexusprince_shaffar()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_nexusprince_shaffar";
newscript->GetAI = GetAI_boss_nexusprince_shaffar;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="mob_ethereal_beacon";
newscript->GetAI = GetAI_mob_ethereal_beacon;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,159 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Pandemonius
SD%Complete: 75
SDComment: Not known how void blast is done (amount of rapid cast seems to be related to players in party). All mobs remaining in surrounding area should aggro when engaged.
SDCategory: Auchindoun, Mana Tombs
EndScriptData */
#include "precompiled.h"
#define SAY_AGGRO_1 "I will feed on your soul."
#define SOUND_AGGRO_1 10561
#define SAY_AGGRO_2 "So... full of life!"
#define SOUND_AGGRO_2 10562
#define SAY_AGGRO_3 "Do not... resist."
#define SOUND_AGGRO_3 10563
#define SAY_KILL_1 "Yes! I am... empowered!"
#define SOUND_KILL_1 10564
#define SAY_KILL_2 "More... I must have more!"
#define SOUND_KILL_2 10565
#define SAY_DEATH "To the void... once... more.."
#define SOUND_DEATH 10566
#define EMOTE_DARK_SHELL "shifts into the void..."
#define SPELL_VOID_BLAST 32325
#define H_SPELL_VOID_BLAST 38760
#define SPELL_DARK_SHELL 32358
#define H_SPELL_DARK_SHELL 38759
struct MANGOS_DLL_DECL boss_pandemoniusAI : public ScriptedAI
{
boss_pandemoniusAI(Creature *c) : ScriptedAI(c)
{
HeroicMode = m_creature->GetMap()->IsHeroic();
Reset();
}
bool HeroicMode;
uint32 VoidBlast_Timer;
uint32 DarkShell_Timer;
uint32 VoidBlast_Counter;
void Reset()
{
VoidBlast_Timer = 30000;
DarkShell_Timer = 20000;
VoidBlast_Counter = 0;
}
void JustDied(Unit* Killer)
{
DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_DEATH);
}
void KilledUnit(Unit* victim)
{
switch(rand()%2)
{
case 0:
DoYell(SAY_KILL_1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_KILL_1);
break;
case 1:
DoYell(SAY_KILL_2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_KILL_2);
break;
}
}
void Aggro(Unit *who)
{
switch(rand()%3)
{
case 0:
DoYell(SAY_AGGRO_1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_AGGRO_1);
break;
case 1:
DoYell(SAY_AGGRO_2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_AGGRO_2);
break;
case 2:
DoYell(SAY_AGGRO_3, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_AGGRO_3);
break;
}
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if( VoidBlast_Timer < diff )
{
if( Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0) )
{
DoCast(target,HeroicMode ? H_SPELL_VOID_BLAST : SPELL_VOID_BLAST);
VoidBlast_Timer = 500;
++VoidBlast_Counter;
}
if( VoidBlast_Counter == 5 )
{
VoidBlast_Timer = 25000+rand()%10000;
VoidBlast_Counter = 0;
}
}else VoidBlast_Timer -= diff;
if( !VoidBlast_Counter )
{
if( DarkShell_Timer < diff )
{
if( m_creature->IsNonMeleeSpellCasted(false) )
m_creature->InterruptNonMeleeSpells(true);
DoTextEmote(EMOTE_DARK_SHELL,NULL,true);
DoCast(m_creature,HeroicMode ? H_SPELL_DARK_SHELL : SPELL_DARK_SHELL);
DarkShell_Timer = 20000;
}else DarkShell_Timer -= diff;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_pandemonius(Creature *_Creature)
{
return new boss_pandemoniusAI (_Creature);
}
void AddSC_boss_pandemonius()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_pandemonius";
newscript->GetAI = GetAI_boss_pandemonius;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,441 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Darkweaver_Syth
SD%Complete: 85
SDComment: Shock spells/times need more work. Heroic not implemented.
SDCategory: Auchindoun, Sethekk Halls
EndScriptData */
#include "precompiled.h"
#define SAY_SUMMON "I have pets..<squawk>..of my own!"
#define SOUND_SUMMON 10502
#define SAY_AGGRO_1 "Hrrmm.. Time to.. hrrm.. make my move."
#define SOUND_AGGRO_1 10503
#define SAY_AGGRO_2 "Nice pets..hrm.. Yes! <squawking>"
#define SOUND_AGGRO_2 10504
#define SAY_AGGRO_3 "Nice pets have.. weapons. No so..<squawk>..nice."
#define SOUND_AGGRO_3 10505
#define SAY_SLAY_1 "Death.. meeting life is.. <squawking>"
#define SOUND_SLAY_1 10506
#define SAY_SLAY_2 "Uhn.. Be free..<squawk>"
#define SOUND_SLAY_2 10507
#define SAY_DEATH "No more life..hrm. No more pain. <squawks weakly>"
#define SOUND_DEATH 10508
#define SPELL_FROST_SHOCK 37865
#define SPELL_FLAME_SHOCK 34354
#define SPELL_SHADOW_SHOCK 30138
#define SPELL_ARCANE_SHOCK 37132
#define SPELL_CHAIN_LIGHTNING 39945
#define SPELL_SUMMON_SYTH_FIRE 33537 // Spawns 19203
#define SPELL_SUMMON_SYTH_ARCANE 33538 // Spawns 19205
#define SPELL_SUMMON_SYTH_FROST 33539 // Spawns 19204
#define SPELL_SUMMON_SYTH_SHADOW 33540 // Spawns 19206
#define SPELL_FLAME_BUFFET 33526
#define H_SPELL_FLAME_BUFFET 38141
#define SPELL_ARCANE_BUFFET 33527
#define H_SPELL_ARCANE_BUFFET 38138
#define SPELL_FROST_BUFFET 33528
#define H_SPELL_FROST_BUFFET 38142
#define SPELL_SHADOW_BUFFET 33529
#define H_SPELL_SHADOW_BUFFET 38143
struct MANGOS_DLL_DECL boss_darkweaver_sythAI : public ScriptedAI
{
boss_darkweaver_sythAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 flameshock_timer;
uint32 arcaneshock_timer;
uint32 frostshock_timer;
uint32 shadowshock_timer;
uint32 chainlightning_timer;
bool summon90;
bool summon50;
bool summon10;
void Reset()
{
flameshock_timer = 2000;
arcaneshock_timer = 4000;
frostshock_timer = 6000;
shadowshock_timer = 8000;
chainlightning_timer = 15000;
summon90 = false;
summon50 = false;
summon10 = false;
}
void Aggro(Unit *who)
{
switch(rand()%3)
{
case 0:
DoYell(SAY_AGGRO_1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_AGGRO_1);
break;
case 1:
DoYell(SAY_AGGRO_2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_AGGRO_2);
break;
case 2:
DoYell(SAY_AGGRO_3, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_AGGRO_3);
break;
}
}
void JustDied(Unit* Killer)
{
DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_DEATH);
}
void KilledUnit(Unit* victim)
{
if (rand()%2)
return;
switch(rand()%2)
{
case 0:
DoYell(SAY_SLAY_1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_SLAY_1);
break;
case 1:
DoYell(SAY_SLAY_2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_SLAY_2);
break;
}
}
void JustSummoned(Creature *summoned)
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
summoned->AI()->AttackStart(target);
}
void SythSummoning()
{
DoYell(SAY_SUMMON, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_SUMMON);
if( m_creature->IsNonMeleeSpellCasted(false) )
m_creature->InterruptNonMeleeSpells(false);
DoCast(m_creature,SPELL_SUMMON_SYTH_ARCANE,true); //front
DoCast(m_creature,SPELL_SUMMON_SYTH_FIRE,true); //back
DoCast(m_creature,SPELL_SUMMON_SYTH_FROST,true); //left
DoCast(m_creature,SPELL_SUMMON_SYTH_SHADOW,true); //right
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if( ((m_creature->GetHealth()*100) / m_creature->GetMaxHealth() < 90) && !summon90)
{
SythSummoning();
summon90 = true;
}
if( ((m_creature->GetHealth()*100) / m_creature->GetMaxHealth() < 50) && !summon50)
{
SythSummoning();
summon50 = true;
}
if( ((m_creature->GetHealth()*100) / m_creature->GetMaxHealth() < 10) && !summon10)
{
SythSummoning();
summon10 = true;
}
if( flameshock_timer < diff )
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_FLAME_SHOCK);
flameshock_timer = 10000 + rand()%5000;
}else flameshock_timer -= diff;
if( arcaneshock_timer < diff )
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_ARCANE_SHOCK);
arcaneshock_timer = 10000 + rand()%5000;
}else arcaneshock_timer -= diff;
if( frostshock_timer < diff )
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_FROST_SHOCK);
frostshock_timer = 10000 + rand()%5000;
}else frostshock_timer -= diff;
if( shadowshock_timer < diff )
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_SHADOW_SHOCK);
shadowshock_timer = 10000 + rand()%5000;
}else shadowshock_timer -= diff;
if( chainlightning_timer < diff )
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_CHAIN_LIGHTNING);
chainlightning_timer = 25000;
}else chainlightning_timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_darkweaver_syth(Creature *_Creature)
{
return new boss_darkweaver_sythAI (_Creature);
}
/* ELEMENTALS */
struct MANGOS_DLL_DECL mob_syth_fireAI : public ScriptedAI
{
mob_syth_fireAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 flameshock_timer;
uint32 flamebuffet_timer;
void Reset()
{
m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true);
flameshock_timer = 2500;
flamebuffet_timer = 5000;
}
void Aggro(Unit *who) { }
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if(flameshock_timer < diff)
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_FLAME_SHOCK);
flameshock_timer = 5000;
}else flameshock_timer -= diff;
if(flamebuffet_timer < diff)
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_FLAME_BUFFET);
flamebuffet_timer = 5000;
}else flamebuffet_timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_syth_fire(Creature *_Creature)
{
return new mob_syth_fireAI (_Creature);
}
struct MANGOS_DLL_DECL mob_syth_arcaneAI : public ScriptedAI
{
mob_syth_arcaneAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 arcaneshock_timer;
uint32 arcanebuffet_timer;
void Reset()
{
m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_ARCANE, true);
arcaneshock_timer = 2500;
arcanebuffet_timer = 5000;
}
void Aggro(Unit *who) { }
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if(arcaneshock_timer < diff)
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_ARCANE_SHOCK);
arcaneshock_timer = 5000;
}else arcaneshock_timer -= diff;
if(arcanebuffet_timer < diff)
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_ARCANE_BUFFET);
arcanebuffet_timer = 5000;
}else arcanebuffet_timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_syth_arcane(Creature *_Creature)
{
return new mob_syth_arcaneAI (_Creature);
}
struct MANGOS_DLL_DECL mob_syth_frostAI : public ScriptedAI
{
mob_syth_frostAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 frostshock_timer;
uint32 frostbuffet_timer;
void Reset()
{
m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true);
frostshock_timer = 2500;
frostbuffet_timer = 5000;
}
void Aggro(Unit *who) { }
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if(frostshock_timer < diff)
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_FROST_SHOCK);
frostshock_timer = 5000;
}else frostshock_timer -= diff;
if(frostbuffet_timer < diff)
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_FROST_BUFFET);
frostbuffet_timer = 5000;
}else frostbuffet_timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_syth_frost(Creature *_Creature)
{
return new mob_syth_frostAI (_Creature);
}
struct MANGOS_DLL_DECL mob_syth_shadowAI : public ScriptedAI
{
mob_syth_shadowAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 shadowshock_timer;
uint32 shadowbuffet_timer;
void Reset()
{
m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_SHADOW, true);
shadowshock_timer = 2500;
shadowbuffet_timer = 5000;
}
void Aggro(Unit *who) { }
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if(shadowshock_timer < diff)
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_SHADOW_SHOCK);
shadowshock_timer = 5000;
}else shadowshock_timer -= diff;
if(shadowbuffet_timer < diff)
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
DoCast(target,SPELL_SHADOW_BUFFET);
shadowbuffet_timer = 5000;
}else shadowbuffet_timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_syth_shadow(Creature *_Creature)
{
return new mob_syth_shadowAI (_Creature);
}
void AddSC_boss_darkweaver_syth()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_darkweaver_syth";
newscript->GetAI = GetAI_boss_darkweaver_syth;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="mob_syth_fire";
newscript->GetAI = GetAI_mob_syth_arcane;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="mob_syth_arcane";
newscript->GetAI = GetAI_mob_syth_arcane;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="mob_syth_frost";
newscript->GetAI = GetAI_mob_syth_frost;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="mob_syth_shadow";
newscript->GetAI = GetAI_mob_syth_shadow;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,256 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Talon_King_Ikiss
SD%Complete: 80
SDComment: Heroic supported. Some details missing, but most are spell related.
SDCategory: Auchindoun, Sethekk Halls
EndScriptData */
#include "precompiled.h"
#include "def_sethekk_halls.h"
#define SAY_INTRO "<squawk>..Trinkets yes pretty Trinkets..<squawk>..power, great power.<squawk>..power in Trinkets..<squawk>"
#define SOUND_INTRO 10557
#define SAY_AGGRO_1 "You make war on Ikiss?..<squawk>"
#define SOUND_AGGRO_1 10554
#define SAY_AGGRO_2 "Ikiss cut you pretty..<squawk>..slice you. Yes!"
#define SOUND_AGGRO_2 10555
#define SAY_AGGRO_3 "No escape for..<squawk>..for you"
#define SOUND_AGGRO_3 10556
#define SAY_SLAY_1 "You die..<squawk>..stay away from Trinkets"
#define SOUND_SLAY_1 10558
#define SAY_SLAY_2 "<squawk>"
#define SOUND_SLAY_2 10559
#define SAY_DEATH "Ikiss will not..<squawk>..die"
#define SOUND_DEATH 10560
#define EMOTE_ARCANE_EXP "begins to channel arcane energy..."
#define SPELL_BLINK 38194
#define SPELL_BLINK_TELEPORT 38203
#define SPELL_MANA_SHIELD 38151
#define SPELL_ARCANE_BUBBLE 9438
#define H_SPELL_SLOW 35032
#define SPELL_POLYMORPH 38245
#define H_SPELL_POLYMORPH 43309
#define SPELL_ARCANE_VOLLEY 35059
#define H_SPELL_ARCANE_VOLLEY 40424
#define SPELL_ARCANE_EXPLOSION 38197
#define H_SPELL_ARCANE_EXPLOSION 40425
struct MANGOS_DLL_DECL boss_talon_king_ikissAI : public ScriptedAI
{
boss_talon_king_ikissAI(Creature *c) : ScriptedAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
Reset();
}
ScriptedInstance* pInstance;
bool HeroicMode;
uint32 ArcaneVolley_Timer;
uint32 Sheep_Timer;
uint32 Blink_Timer;
uint32 Slow_Timer;
bool ManaShield;
bool Blink;
bool Intro;
void Reset()
{
HeroicMode = m_creature->GetMap()->IsHeroic();
ArcaneVolley_Timer = 5000;
Sheep_Timer = 8000;
Blink_Timer = 35000;
Slow_Timer = 15000+rand()%15000;
Blink = false;
Intro = false;
ManaShield = false;
}
void MoveInLineOfSight(Unit *who)
{
if( !m_creature->getVictim() && who->isTargetableForAttack() && ( m_creature->IsHostileTo( who )) && who->isInAccessablePlaceFor(m_creature) )
{
if(!Intro && m_creature->IsWithinDistInMap(who, 100))
{
Intro = true;
DoYell(SAY_INTRO, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_INTRO);
}
if (m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
return;
float attackRadius = m_creature->GetAttackDistance(who);
if( m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who) )
{
DoStartAttackAndMovement(who);
who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
if (!InCombat)
{
Aggro(who);
InCombat = true;
}
}
}
}
void Aggro(Unit *who)
{
switch(rand()%3)
{
case 0:
DoYell(SAY_AGGRO_1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_AGGRO_1);
break;
case 1:
DoYell(SAY_AGGRO_2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_AGGRO_2);
break;
case 2:
DoYell(SAY_AGGRO_3, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_AGGRO_3);
break;
}
}
void JustDied(Unit* Killer)
{
DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_DEATH);
if( pInstance )
pInstance->SetData(DATA_IKISSDOOREVENT, DONE);
}
void KilledUnit(Unit* victim)
{
switch(rand()%2)
{
case 0:
DoYell(SAY_SLAY_1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_SLAY_1);
break;
case 1:
DoYell(SAY_SLAY_2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_SLAY_2);
break;
}
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if( Blink )
{
DoCast(m_creature,HeroicMode ? H_SPELL_ARCANE_EXPLOSION : SPELL_ARCANE_EXPLOSION);
m_creature->CastSpell(m_creature,SPELL_ARCANE_BUBBLE,true);
Blink = false;
}
if( ArcaneVolley_Timer < diff )
{
DoCast(m_creature,HeroicMode ? H_SPELL_ARCANE_VOLLEY : SPELL_ARCANE_VOLLEY);
ArcaneVolley_Timer = 10000+rand()%5000;
}else ArcaneVolley_Timer -= diff;
if( Sheep_Timer < diff )
{
//second top aggro target in normal, random target in heroic correct?
Unit *target = NULL;
if( HeroicMode ? target = SelectUnit(SELECT_TARGET_RANDOM,0) : target = SelectUnit(SELECT_TARGET_TOPAGGRO,1) )
DoCast(target,HeroicMode ? H_SPELL_POLYMORPH : SPELL_POLYMORPH);
Sheep_Timer = 15000+rand()%2500;
}else Sheep_Timer -= diff;
//may not be correct time to cast
if( !ManaShield && ((m_creature->GetHealth()*100) / m_creature->GetMaxHealth() < 20) )
{
DoCast(m_creature,SPELL_MANA_SHIELD);
ManaShield = true;
}
if( HeroicMode )
{
if( Slow_Timer < diff )
{
DoCast(m_creature,H_SPELL_SLOW);
Slow_Timer = 15000+rand()%25000;
}else Slow_Timer -= diff;
}
if( Blink_Timer < diff )
{
DoTextEmote(EMOTE_ARCANE_EXP,NULL,true);
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM,0) )
{
if( m_creature->IsNonMeleeSpellCasted(false) )
m_creature->InterruptNonMeleeSpells(false);
//Spell doesn't work, but we use for visual effect at least
DoCast(target,SPELL_BLINK);
float X = target->GetPositionX();
float Y = target->GetPositionY();
float Z = target->GetPositionZ();
m_creature->Relocate(X,Y,Z);
m_creature->SendMonsterMove(X, Y, Z, 0, 0, 0);
DoCast(target,SPELL_BLINK_TELEPORT);
Blink = true;
}
Blink_Timer = 35000+rand()%5000;
}else Blink_Timer -= diff;
if( !Blink )
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_talon_king_ikiss(Creature *_Creature)
{
return new boss_talon_king_ikissAI (_Creature);
}
void AddSC_boss_talon_king_ikiss()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_talon_king_ikiss";
newscript->GetAI = GetAI_boss_talon_king_ikiss;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,9 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef DEF_SETHEKK_HALLS_H
#define DEF_SETHEKK_HALLS_H
#define DATA_IKISSDOOREVENT 1
#endif
@@ -0,0 +1,74 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Instance - Sethekk Halls
SD%Complete: 50
SDComment: Instance Data for Sethekk Halls instance
SDCategory: Auchindoun, Sethekk Halls
EndScriptData */
#include "precompiled.h"
#include "def_sethekk_halls.h"
#define IKISS_DOOR 177203
struct MANGOS_DLL_DECL instance_sethekk_halls : public ScriptedInstance
{
instance_sethekk_halls(Map *Map) : ScriptedInstance(Map) {Initialize();};
GameObject *IkissDoor;
void Initialize()
{
IkissDoor = NULL;
}
void OnObjectCreate(GameObject *go)
{
switch(go->GetEntry())
{
case IKISS_DOOR:
IkissDoor = go;
break;
}
}
void SetData(uint32 type, uint32 data)
{
switch(type)
{
case DATA_IKISSDOOREVENT:
if( IkissDoor )
IkissDoor->SetGoState(0);
break;
}
}
};
InstanceData* GetInstanceData_instance_sethekk_halls(Map* map)
{
return new instance_sethekk_halls(map);
}
void AddSC_instance_sethekk_halls()
{
Script *newscript;
newscript = new Script;
newscript->Name = "instance_sethekk_halls";
newscript->GetInstanceData = GetInstanceData_instance_sethekk_halls;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,223 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Ambassador_Hellmaw
SD%Complete: 75
SDComment: Waypoints after Intro not implemented. Enrage spell missing/not known
SDCategory: Auchindoun, Shadow Labyrinth
EndScriptData */
#include "precompiled.h"
#include "def_shadow_labyrinth.h"
#define SAY_INTRO "Infidels have invaded the sanctuary! Sniveling pests...You have yet to learn the true meaning of agony!"
#define SOUND_INTRO 10473
#define SAY_AGGRO1 "Pathetic mortals! You will pay dearly!"
#define SOUND_AGGRO1 10475
#define SAY_AGGRO2 "I will break you!"
#define SOUND_AGGRO2 10476
#define SAY_AGGRO3 "Finally! Something to relieve the tedium!"
#define SOUND_AGGRO3 10477
#define SAY_HELP "Aid me, you fools, before it's too late!"
#define SOUND_HELP 10474
#define SAY_SLAY1 "Do you fear death?"
#define SOUND_SLAY1 10478
#define SAY_SLAY2 "This is the part I enjoy most."
#define SOUND_SLAY2 10479
#define SAY_DEATH "Do not...grow...overconfident, mortal."
#define SOUND_DEATH 10480
#define SPELL_BANISH 30231
#define SPELL_CORROSIVE_ACID 23313
#define SPELL_FEAR 33547
#define SPELL_ENRAGE 0 //need to find proper spell
struct MANGOS_DLL_DECL boss_ambassador_hellmawAI : public ScriptedAI
{
boss_ambassador_hellmawAI(Creature *c) : ScriptedAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
Reset();
}
ScriptedInstance* pInstance;
bool HeroicMode;
uint32 EventCheck_Timer;
uint32 CorrosiveAcid_Timer;
uint32 Fear_Timer;
uint32 Enrage_Timer;
bool Intro;
bool IsBanished;
void Reset()
{
HeroicMode = m_creature->GetMap()->IsHeroic();
EventCheck_Timer = 5000;
CorrosiveAcid_Timer = 25000;
Fear_Timer = 40000;
Enrage_Timer = 180000;
Intro = false;
IsBanished = false;
if( pInstance )
{
if( pInstance->GetData(TYPE_HELLMAW) == NOT_STARTED )
{
DoCast(m_creature,SPELL_BANISH);
IsBanished = true;
}
else pInstance->SetData(TYPE_HELLMAW,FAIL);
if( pInstance->GetData(TYPE_OVERSEER) == DONE )
{
if( m_creature->HasAura(SPELL_BANISH,0) )
m_creature->RemoveAurasDueToSpell(SPELL_BANISH);
Intro = true;
}
}
}
void MovementInform(uint32 type, uint32 id)
{
if( type != POINT_MOTION_TYPE )
return;
}
void DoIntro()
{
DoYell(SAY_INTRO, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_INTRO);
if( m_creature->HasAura(SPELL_BANISH,0) )
m_creature->RemoveAurasDueToSpell(SPELL_BANISH);
IsBanished = false;
Intro = true;
if( pInstance )
pInstance->SetData(TYPE_HELLMAW, IN_PROGRESS);
}
void Aggro(Unit *who)
{
switch(rand()%3)
{
case 0:
DoYell(SAY_AGGRO1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_AGGRO1);
break;
case 1:
DoYell(SAY_AGGRO2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_AGGRO2);
break;
case 2:
DoYell(SAY_AGGRO3, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_AGGRO3);
break;
}
}
void KilledUnit(Unit *victim)
{
switch(rand()%2)
{
case 0:
DoYell(SAY_SLAY1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_SLAY1);
break;
case 1:
DoYell(SAY_SLAY2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_SLAY2);
break;
}
}
void JustDied(Unit *victim)
{
DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_DEATH);
if( pInstance )
pInstance->SetData(TYPE_HELLMAW, DONE);
}
void UpdateAI(const uint32 diff)
{
if( !Intro )
{
if( EventCheck_Timer < diff )
{
if( pInstance )
{
if( pInstance->GetData(TYPE_OVERSEER) == DONE )
DoIntro();
}
EventCheck_Timer = 5000;
}else EventCheck_Timer -= diff;
}
if( !InCombat && !IsBanished )
{
//this is where we add MovePoint()
//DoWhine("I haz no mount!", LANG_UNIVERSAL, NULL);
}
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
if( CorrosiveAcid_Timer < diff )
{
DoCast(m_creature,SPELL_CORROSIVE_ACID);
CorrosiveAcid_Timer = 25000;
}else CorrosiveAcid_Timer -= diff;
if( Fear_Timer < diff )
{
DoCast(m_creature,SPELL_FEAR);
Fear_Timer = 35000;
}else Fear_Timer -= diff;
/*if( HeroicMode )
{
if( Enrage_Timer < diff )
{
DoCast(m_creature,SPELL_ENRAGE);
}else Enrage_Timer -= diff;
}*/
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_ambassador_hellmaw(Creature *_Creature)
{
return new boss_ambassador_hellmawAI (_Creature);
}
void AddSC_boss_ambassador_hellmaw()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_ambassador_hellmaw";
newscript->GetAI = GetAI_boss_ambassador_hellmaw;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,191 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Blackheart_the_Inciter
SD%Complete: 75
SDComment: Incite Chaos not functional since core lacks Mind Control support
SDCategory: Auchindoun, Shadow Labyrinth
EndScriptData */
#include "precompiled.h"
#include "def_shadow_labyrinth.h"
#define SPELL_INCITE_CHAOS 33676
#define SPELL_INCITE_CHAOS_B 33684 //debuff applied to each member of party
#define SPELL_CHARGE 33709
#define SPELL_WAR_STOMP 33707
#define SAY_AGGRO1 "You be dead people!"
#define SAY_AGGRO2 "Time to kill!"
#define SAY_AGGRO3 "I see dead people!"
#define SAY_SLAY1 "No coming back for you!"
#define SAY_SLAY2 "Nice try!"
#define SAY_SLAY3 "Now you gone for good!"
#define SAY_DEATH "This...no...good.."
#define SOUND_AGGRO1 10498
#define SOUND_AGGRO2 10497
#define SOUND_AGGRO3 10488
#define SOUND_SLAY1 10489
#define SOUND_SLAY2 10490
#define SOUND_SLAY3 10499
#define SOUND_DEATH 10491
struct MANGOS_DLL_DECL boss_blackheart_the_inciterAI : public ScriptedAI
{
boss_blackheart_the_inciterAI(Creature *c) : ScriptedAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
Reset();
}
ScriptedInstance *pInstance;
bool InciteChaos;
uint32 InciteChaos_Timer;
uint32 InciteChaosWait_Timer;
uint32 Charge_Timer;
uint32 Knockback_Timer;
void Reset()
{
InciteChaos = false;
InciteChaos_Timer = 20000;
InciteChaosWait_Timer = 15000;
Charge_Timer = 5000;
Knockback_Timer = 15000;
if( pInstance )
pInstance->SetData(DATA_BLACKHEARTTHEINCITEREVENT, NOT_STARTED);
}
void KilledUnit(Unit *victim)
{
switch(rand()%3)
{
case 0:
DoYell(SAY_SLAY1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_SLAY1);
break;
case 1:
DoYell(SAY_SLAY2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_SLAY2);
break;
case 2:
DoYell(SAY_SLAY3, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_SLAY3);
break;
}
}
void JustDied(Unit *victim)
{
DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_DEATH);
if( pInstance )
pInstance->SetData(DATA_BLACKHEARTTHEINCITEREVENT, DONE);
}
void Aggro(Unit *who)
{
switch(rand()%3)
{
case 0:
DoYell(SAY_AGGRO1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_AGGRO1);
break;
case 1:
DoYell(SAY_AGGRO2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_AGGRO2);
break;
case 2:
DoYell(SAY_AGGRO3, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_AGGRO3);
break;
}
if( pInstance )
pInstance->SetData(DATA_BLACKHEARTTHEINCITEREVENT, IN_PROGRESS);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
if( InciteChaos )
{
if( InciteChaosWait_Timer < diff )
{
InciteChaos = false;
InciteChaosWait_Timer = 15000;
}else InciteChaosWait_Timer -= diff;
return;
}
if( InciteChaos_Timer < diff )
{
DoCast(m_creature, SPELL_INCITE_CHAOS);
std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList();
for( std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr )
{
Unit* target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
if( target && target->GetTypeId() == TYPEID_PLAYER )
target->CastSpell(target,SPELL_INCITE_CHAOS_B,true);
}
DoResetThreat();
InciteChaos = true;
InciteChaos_Timer = 40000;
return;
}else InciteChaos_Timer -= diff;
//Charge_Timer
if( Charge_Timer < diff )
{
if( Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0) )
DoCast(target, SPELL_CHARGE);
Charge_Timer = 25000;
}else Charge_Timer -= diff;
//Knockback_Timer
if( Knockback_Timer < diff )
{
DoCast(m_creature, SPELL_WAR_STOMP);
Knockback_Timer = 20000;
}else Knockback_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_blackheart_the_inciter(Creature *_Creature)
{
return new boss_blackheart_the_inciterAI (_Creature);
}
void AddSC_boss_blackheart_the_inciter()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_blackheart_the_inciter";
newscript->GetAI = GetAI_boss_blackheart_the_inciter;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,294 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Grandmaster_Vorpil
SD%Complete: 75
SDComment: Despawn all summoned on death not implemented. Void Traveler effects not implemented.
SDCategory: Auchindoun, Shadow Labyrinth
EndScriptData */
#include "precompiled.h"
#include "def_shadow_labyrinth.h"
#define SPELL_DRAW_SHADOWS 33563
#define SPELL_VOID_PORTAL_A 33566 //spell only summon one unit, but we use it for the visual effect and summon the 4 other portals manual way(only one spell exist)
#define SPELL_VOID_PORTAL_VISUAL 33569
#define SPELL_SHADOW_BOLT_VOLLEY 32963
#define SPELL_SUMMON_VOIDWALKER_A 33582
#define SPELL_SUMMON_VOIDWALKER_B 33583
#define SPELL_SUMMON_VOIDWALKER_C 33584
#define SPELL_SUMMON_VOIDWALKER_D 33585
#define SPELL_SUMMON_VOIDWALKER_E 33586
#define SPELL_RAIN_OF_FIRE 33617
#define H_SPELL_RAIN_OF_FIRE 39363
#define H_SPELL_BANISH 38791
#define SAY_INTRO "Keep your minds focused for the days of reckoning are close at hand. Soon, the destroyer of worlds will return to make good on his promise. Soon the destruction of all that is will begin!"
#define SAY_AGGRO1 "I'll make an offering of your blood!"
#define SAY_AGGRO2 "You'll be a fine example, for the others."
#define SAY_AGGRO3 "Good, a worthy sacrifice."
#define SAY_HELP "Come to my aid, heed your master now!"
#define SAY_SLAY1 "I serve with pride."
#define SAY_SLAY2 "Your death is for the greater cause!"
#define SAY_DEATH "I give my life... Gladly."
#define SOUND_INTRO 10522
#define SOUND_AGGRO1 10524
#define SOUND_AGGRO2 10525
#define SOUND_AGGRO3 10526
#define SOUND_HELP 10523
#define SOUND_SLAY1 10527
#define SOUND_SLAY2 10528
#define SOUND_DEATH 10529
#define ENTRY_VOID_PORTAL 19224
#define ENTRY_VOID_TRAVELER 19226
#define LOCX -253.06f
#define LOCY -264.02f
#define LOCZ 17.08
struct MANGOS_DLL_DECL boss_grandmaster_vorpilAI : public ScriptedAI
{
boss_grandmaster_vorpilAI(Creature *c) : ScriptedAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
Reset();
}
ScriptedInstance* pInstance;
bool HeroicMode;
uint32 ShadowBoltVolley_Timer;
uint32 DrawShadows_Timer;
uint32 Teleport_Timer;
uint32 VoidTraveler_Timer;
uint32 Banish_Timer;
bool Intro;
bool Teleport;
void Reset()
{
HeroicMode = m_creature->GetMap()->IsHeroic();
ShadowBoltVolley_Timer = 15000;
DrawShadows_Timer = 40000;
Teleport_Timer = 1000;
VoidTraveler_Timer = 20000;
Banish_Timer = 25000;
Intro = false;
Teleport = false;
if( pInstance )
pInstance->SetData(DATA_GRANDMASTERVORPILEVENT, NOT_STARTED);
}
void MoveInLineOfSight(Unit *who)
{
if( !m_creature->getVictim() && who->isTargetableForAttack() && ( m_creature->IsHostileTo( who )) && who->isInAccessablePlaceFor(m_creature) )
{
//not sure about right radius
if(!Intro && m_creature->IsWithinDistInMap(who, 50))
{
DoYell(SAY_INTRO, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_INTRO);
DoCast(m_creature, SPELL_VOID_PORTAL_A,true);
m_creature->SummonCreature(ENTRY_VOID_PORTAL,-262.40,-229.57,17.08,0,TEMPSUMMON_CORPSE_DESPAWN,0);
m_creature->SummonCreature(ENTRY_VOID_PORTAL,-260.35,-297.56,17.08,0,TEMPSUMMON_CORPSE_DESPAWN,0);
m_creature->SummonCreature(ENTRY_VOID_PORTAL,-292.05,-270.37,12.68,0,TEMPSUMMON_CORPSE_DESPAWN,0);
m_creature->SummonCreature(ENTRY_VOID_PORTAL,-301.64,-255.97,12.68,0,TEMPSUMMON_CORPSE_DESPAWN,0);
Intro = true;
}
if (m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
return;
float attackRadius = m_creature->GetAttackDistance(who);
if( m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who) )
{
DoStartAttackAndMovement(who);
who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
if (!InCombat)
{
Aggro(who);
InCombat = true;
}
}
}
}
void Aggro(Unit *who)
{
switch(rand()%3)
{
case 0:
DoYell(SAY_AGGRO1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_AGGRO1);
break;
case 1:
DoYell(SAY_AGGRO2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_AGGRO2);
break;
case 2:
DoYell(SAY_AGGRO3, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_AGGRO3);
break;
}
if( pInstance )
pInstance->SetData(DATA_GRANDMASTERVORPILEVENT, IN_PROGRESS);
}
void KilledUnit(Unit *victim)
{
switch(rand()%2)
{
case 0:
DoYell(SAY_SLAY1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_SLAY1);
break;
case 1:
DoYell(SAY_SLAY2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_SLAY2);
break;
}
}
void JustSummoned(Creature *summoned)
{
if( summoned->GetEntry() == ENTRY_VOID_TRAVELER )
{
summoned->GetMotionMaster()->MoveChase(m_creature);
summoned->SetSpeed(MOVE_WALK,0.8,true);
}
if( summoned->GetEntry() == ENTRY_VOID_PORTAL )
summoned->CastSpell(summoned,SPELL_VOID_PORTAL_VISUAL,true);
}
void JustDied(Unit *victim)
{
DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_DEATH);
if( pInstance )
pInstance->SetData(DATA_GRANDMASTERVORPILEVENT, DONE);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
if( Teleport )
{
if( Teleport_Timer <= diff )
{
m_creature->Relocate(LOCX,LOCY,LOCZ);
m_creature->SendMonsterMove(LOCX,LOCY,LOCZ,0,true,0);
float ranX = LOCX;
float ranY = LOCY;
float ranZ = LOCZ;
std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList();
for( std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr )
{
Unit* target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
if( target && target->GetTypeId() == TYPEID_PLAYER )
{
target->GetRandomPoint(LOCX,LOCY,LOCZ,3.0,ranX,ranY,ranZ);
DoTeleportPlayer(target,ranX,ranY,ranZ,m_creature->GetAngle(m_creature->GetPositionX(),m_creature->GetPositionY()));
}
}
Teleport = false;
if( HeroicMode ) DoCast(m_creature->getVictim(), H_SPELL_RAIN_OF_FIRE);
else DoCast(m_creature->getVictim(), SPELL_RAIN_OF_FIRE);
Teleport_Timer = 1000;
}else Teleport_Timer -= diff;
}
if( ShadowBoltVolley_Timer < diff )
{
DoCast(m_creature->getVictim(), SPELL_SHADOW_BOLT_VOLLEY);
ShadowBoltVolley_Timer = 30000;
}else ShadowBoltVolley_Timer -= diff;
if( DrawShadows_Timer < diff )
{
DoCast(m_creature,SPELL_DRAW_SHADOWS);
DrawShadows_Timer = 35000;
Teleport = true;
}else DrawShadows_Timer -= diff;
if( VoidTraveler_Timer < diff )
{
DoYell(SAY_HELP, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_HELP);
switch(rand()%5)
{
case 0:
DoCast(m_creature,SPELL_SUMMON_VOIDWALKER_A,true);
break;
case 1:
DoCast(m_creature,SPELL_SUMMON_VOIDWALKER_B,true);
break;
case 2:
DoCast(m_creature,SPELL_SUMMON_VOIDWALKER_C,true);
break;
case 3:
DoCast(m_creature,SPELL_SUMMON_VOIDWALKER_D,true);
break;
case 4:
DoCast(m_creature,SPELL_SUMMON_VOIDWALKER_E,true);
break;
}
//faster rate when below (X) health?
VoidTraveler_Timer = 35000;
}else VoidTraveler_Timer -= diff;
if( HeroicMode )
{
if( Banish_Timer < diff )
{
if( Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1) )
DoCast(target,H_SPELL_BANISH);
Banish_Timer = 35000;
}else Banish_Timer -= diff;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_grandmaster_vorpil(Creature *_Creature)
{
return new boss_grandmaster_vorpilAI (_Creature);
}
void AddSC_boss_grandmaster_vorpil()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_grandmaster_vorpil";
newscript->GetAI = GetAI_boss_grandmaster_vorpil;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,192 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Murmur
SD%Complete: 75
SDComment: Database should have `RegenHealth`=0 to prevent regen. Also, his shockwave triggered after magnetic pull may be incorrect. Murmur's Touch does not work properly.
SDCategory: Auchindoun, Shadow Labyrinth
EndScriptData */
#include "precompiled.h"
#define EMOTE_SONIC_BOOM "draws energy from the air."
#define SPELL_MAGNETIC_PULL 33689
#define SPELL_SONIC_BOOM_PRE 33923
#define SPELL_SONIC_BOOM_CAST 38795
#define SPELL_MURMURS_TOUCH 33711
#define SPELL_RESONANCE 33657
#define SPELL_SHOCKWAVE 33686
struct MANGOS_DLL_DECL boss_murmurAI : public ScriptedAI
{
boss_murmurAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 SonicBoom_Timer;
uint32 MurmursTouch_Timer;
uint32 Resonance_Timer;
uint32 MagneticPull_Timer;
bool CanSonicBoom;
bool CanShockWave;
uint64 pTarget;
void Reset()
{
SonicBoom_Timer = 30000;
MurmursTouch_Timer = 20000;
Resonance_Timer = 10000;
MagneticPull_Timer = 45000;
CanSonicBoom = false;
CanShockWave = false;
pTarget = 0;
//database should have `RegenHealth`=0 to prevent regen
uint32 hp = m_creature->GetMaxHealth()*0.4;
if( hp )
m_creature->SetHealth(hp);
}
void Aggro(Unit *who) { }
void AttackStart(Unit* who)
{
if (!who)
return;
if (who->isTargetableForAttack())
{
//Begin attack
DoStartAttackNoMovement(who);
if (!InCombat)
{
Aggro(who);
InCombat = true;
}
}
}
void MoveInLineOfSight(Unit* who)
{
if( !m_creature->getVictim() && who->isTargetableForAttack() && ( m_creature->IsHostileTo( who )) && who->isInAccessablePlaceFor(m_creature) )
{
if (m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
return;
float attackRadius = m_creature->GetAttackDistance(who);
if(m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who))
{
DoStartAttackNoMovement(who);
who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
if (!InCombat)
{
Aggro(who);
InCombat = true;
}
}
}
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
//SonicBoom_Timer
if(SonicBoom_Timer < diff)
{
if(CanSonicBoom)
{
DoCast(m_creature, SPELL_SONIC_BOOM_CAST,true);
CanSonicBoom = false;
SonicBoom_Timer = 30000;
}
else
{
DoTextEmote(EMOTE_SONIC_BOOM,NULL);
DoCast(m_creature,SPELL_SONIC_BOOM_PRE);
CanSonicBoom = true;
SonicBoom_Timer = 5000;
}
}else SonicBoom_Timer -= diff;
//MurmursTouch_Timer
if(MurmursTouch_Timer < diff)
{
/*Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,0);
if(target)
DoCast(target, SPELL_MURMURS_TOUCH);*/
DoCast(m_creature, SPELL_MURMURS_TOUCH);
MurmursTouch_Timer = 30000;
}else MurmursTouch_Timer -= diff;
//Resonance_Timer
if(Resonance_Timer < diff)
{
if( !m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE) )
DoCast(m_creature->getVictim(), SPELL_RESONANCE);
Resonance_Timer = 5000;
}else Resonance_Timer -= diff;
//MagneticPull_Timer
if(MagneticPull_Timer < diff)
{
if( !CanShockWave )
{
if( Unit* temp = SelectUnit(SELECT_TARGET_RANDOM,0) )
{
if( temp->GetTypeId() == TYPEID_PLAYER )
{
DoCast(temp, SPELL_MAGNETIC_PULL);
pTarget = temp->GetGUID();
CanShockWave = true;
}
MagneticPull_Timer = 2500;
}
}
else
{
if( Unit* target = Unit::GetUnit(*m_creature,pTarget) )
target->CastSpell(target,SPELL_SHOCKWAVE,true);
MagneticPull_Timer = 35000;
CanShockWave = false;
pTarget = 0;
}
}else MagneticPull_Timer -= diff;
//no meele if preparing for sonic boom
if(!CanSonicBoom)
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_murmur(Creature *_Creature)
{
return new boss_murmurAI (_Creature);
}
void AddSC_boss_murmur()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_murmur";
newscript->GetAI = GetAI_boss_murmur;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,13 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef DEF_SHADOW_LABYRINTH_H
#define DEF_SHADOW_LABYRINTH_H
#define TYPE_HELLMAW 1
#define TYPE_OVERSEER 2
#define DATA_BLACKHEARTTHEINCITEREVENT 3
#define DATA_GRANDMASTERVORPILEVENT 4
#define DATA_MURMUREVENT 5
#endif
@@ -0,0 +1,168 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Instance_Shadow_Labyrinth
SD%Complete: 85
SDComment: Some cleanup left along with save
SDCategory: Auchindoun, Shadow Labyrinth
EndScriptData */
#include "precompiled.h"
#include "def_shadow_labyrinth.h"
#define ENCOUNTERS 5
#define REFECTORY_DOOR 183296 //door opened when blackheart the inciter dies
#define SCREAMING_HALL_DOOR 183295 //door opened when grandmaster vorpil dies
/* Shadow Labyrinth encounters:
1 - Ambassador Hellmaw event
2 - Blackheart the Inciter event
3 - Grandmaster Vorpil event
4 - Murmur event
*/
struct MANGOS_DLL_DECL instance_shadow_labyrinth : public ScriptedInstance
{
instance_shadow_labyrinth(Map *Map) : ScriptedInstance(Map) {Initialize();};
uint32 Encounter[ENCOUNTERS];
GameObject *RefectoryDoor;
GameObject *ScreamingHallDoor;
uint64 GrandmasterVorpil;
uint32 FelOverseerCount;
void Initialize()
{
RefectoryDoor = NULL;
ScreamingHallDoor = NULL;
GrandmasterVorpil = 0;
FelOverseerCount = 0;
for(uint8 i = 0; i < ENCOUNTERS; i++)
Encounter[i] = false;
}
bool IsEncounterInProgress() const
{
for(uint8 i = 0; i < ENCOUNTERS; i++)
if(Encounter[i]) return true;
return false;
}
void OnObjectCreate(GameObject *go)
{
switch(go->GetEntry())
{
case REFECTORY_DOOR:
RefectoryDoor = go;
break;
case SCREAMING_HALL_DOOR:
ScreamingHallDoor = go;
break;
}
}
void OnCreatureCreate(Creature *creature, uint32 creature_entry)
{
switch(creature_entry)
{
case 18732:
GrandmasterVorpil = creature->GetGUID();
break;
case 18796:
++FelOverseerCount;
debug_log("SD2: Shadow Labyrinth: counting %u Fel Overseers.",FelOverseerCount);
break;
}
}
void SetData(uint32 type, uint32 data)
{
switch(type)
{
case TYPE_HELLMAW:
Encounter[0] = data;
break;
case TYPE_OVERSEER:
if( data != DONE )
error_log("SD2: Shadow Labyrinth: TYPE_OVERSEER did not expect other data than DONE");
if( FelOverseerCount )
{
--FelOverseerCount;
debug_log("SD2: Shadow Labyrinth: %u Fel Overseers left to kill.",FelOverseerCount);
}
if( FelOverseerCount == 0 )
{
Encounter[1] = DONE;
debug_log("SD2: Shadow Labyrinth: TYPE_OVERSEER == DONE");
}
break;
case DATA_BLACKHEARTTHEINCITEREVENT:
if( data == DONE )
{
if( RefectoryDoor )
RefectoryDoor->UseDoorOrButton();
}
Encounter[2] = data;
break;
case DATA_GRANDMASTERVORPILEVENT:
if( data == DONE )
{
if( ScreamingHallDoor )
ScreamingHallDoor->UseDoorOrButton();
}
Encounter[3] = data;
break;
case DATA_MURMUREVENT:
Encounter[4] = data;
break;
}
}
uint32 GetData(uint32 type)
{
switch( type )
{
case TYPE_HELLMAW:
return Encounter[0];
case TYPE_OVERSEER:
return Encounter[1];
}
return false;
}
};
InstanceData* GetInstanceData_instance_shadow_labyrinth(Map* map)
{
return new instance_shadow_labyrinth(map);
}
void AddSC_instance_shadow_labyrinth()
{
Script *newscript;
newscript = new Script;
newscript->Name = "instance_shadow_labyrinth";
newscript->GetInstanceData = GetInstanceData_instance_shadow_labyrinth;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,164 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Azshara
SD%Complete: 90
SDComment: Quest support: 2744, 3141, 9364
SDCategory: Azshara
EndScriptData */
/* ContentData
mobs_spitelashes
npc_loramus_thalipedes
EndContentData */
#include "precompiled.h"
/*######
## mobs_spitelashes
######*/
struct MANGOS_DLL_DECL mobs_spitelashesAI : public ScriptedAI
{
mobs_spitelashesAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 morphtimer;
bool spellhit;
void Reset()
{
morphtimer = 0;
spellhit = false;
}
void Aggro(Unit *who) { }
void SpellHit(Unit *Hitter, const SpellEntry *Spellkind)
{
if( !spellhit &&
Hitter->GetTypeId() == TYPEID_PLAYER &&
((Player*)Hitter)->GetQuestStatus(9364) == QUEST_STATUS_INCOMPLETE &&
(Spellkind->Id==118 || Spellkind->Id== 12824 || Spellkind->Id== 12825 || Spellkind->Id== 12826) )
{
spellhit=true;
DoCast(m_creature,29124); //become a sheep
}
}
void UpdateAI(const uint32 diff)
{
// we mustn't remove the creature in the same round in which we cast the summon spell, otherwise there will be no summons
if( spellhit && morphtimer>=5000 )
{
m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
m_creature->RemoveCorpse(); //you don't see any corpse on off.
EnterEvadeMode(); //spellhit will be set to false
}
// walk 5 seconds before summoning
if( spellhit && morphtimer<5000 )
{
morphtimer+=diff;
if( morphtimer>=5000 )
{
DoCast(m_creature,28406); //summon copies
DoCast(m_creature,6924); //visual explosion
}
}
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
//TODO: add abilities for the different creatures
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mobs_spitelashes(Creature *_Creature)
{
return new mobs_spitelashesAI (_Creature);
}
/*######
## npc_loramus_thalipedes
######*/
bool GossipHello_npc_loramus_thalipedes(Player *player, Creature *_Creature)
{
if (_Creature->isQuestGiver())
player->PrepareQuestMenu( _Creature->GetGUID() );
if (player->GetQuestStatus(2744) == QUEST_STATUS_INCOMPLETE)
player->ADD_GOSSIP_ITEM( 0, "Can you help me?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
if (player->GetQuestStatus(3141) == QUEST_STATUS_INCOMPLETE)
player->ADD_GOSSIP_ITEM( 0, "Tell me your story", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
return true;
}
bool GossipSelect_npc_loramus_thalipedes(Player *player, Creature *_Creature, uint32 sender, uint32 action)
{
switch (action)
{
case GOSSIP_ACTION_INFO_DEF+1:
player->CLOSE_GOSSIP_MENU();
player->AreaExploredOrEventHappens(2744);
break;
case GOSSIP_ACTION_INFO_DEF+2:
player->ADD_GOSSIP_ITEM( 0, "Please continue", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 21);
player->SEND_GOSSIP_MENU(1813, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+21:
player->ADD_GOSSIP_ITEM( 0, "I do not understand", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 22);
player->SEND_GOSSIP_MENU(1814, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+22:
player->ADD_GOSSIP_ITEM( 0, "Indeed", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 23);
player->SEND_GOSSIP_MENU(1815, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+23:
player->ADD_GOSSIP_ITEM( 0, "I will do this with or your help, Loramus", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 24);
player->SEND_GOSSIP_MENU(1816, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+24:
player->ADD_GOSSIP_ITEM( 0, "Yes", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 25);
player->SEND_GOSSIP_MENU(1817, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+25:
player->CLOSE_GOSSIP_MENU();
player->AreaExploredOrEventHappens(3141);
break;
}
return true;
}
void AddSC_azshara()
{
Script *newscript;
newscript = new Script;
newscript->Name="mobs_spitelashes";
newscript->GetAI = GetAI_mobs_spitelashes;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="npc_loramus_thalipedes";
newscript->pGossipHello = &GossipHello_npc_loramus_thalipedes;
newscript->pGossipSelect = &GossipSelect_npc_loramus_thalipedes;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,153 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Azuregos
SD%Complete: 90
SDComment: Teleport not included, spell reflect not effecting dots (Core problem)
SDCategory: Azshara
EndScriptData */
#include "precompiled.h"
#define SPELL_MARKOFFROST 23182
#define SPELL_MANASTORM 21097
#define SPELL_CHILL 21098
#define SPELL_FROSTBREATH 21099
#define SPELL_REFLECT 22067 //Old one was 30969
#define SPELL_CLEAVE 8255 //Perhaps not right ID
#define SPELL_ENRAGE 23537
struct MANGOS_DLL_DECL boss_azuregosAI : public ScriptedAI
{
boss_azuregosAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 MarkOfFrost_Timer;
uint32 ManaStorm_Timer;
uint32 Chill_Timer;
uint32 Breath_Timer;
uint32 Teleport_Timer;
uint32 Reflect_Timer;
uint32 Cleave_Timer;
uint32 Enrage_Timer;
bool Enraged;
void Reset()
{
MarkOfFrost_Timer = 35000;
ManaStorm_Timer = 5000 + rand()%12000;
Chill_Timer = 10000 + rand()%20000;
Breath_Timer = 2000 + rand()%6000;
Teleport_Timer = 30000;
Reflect_Timer = 15000 + rand()%15000;
Cleave_Timer = 7000;
Enrage_Timer = 0;
Enraged = false;
}
void Aggro(Unit *who) {}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
if(Teleport_Timer < diff)
{
std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
std::list<HostilReference*>::iterator i = m_threatlist.begin();
for (i = m_threatlist.begin(); i!= m_threatlist.end();++i)
{
Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());
if(pUnit && (pUnit->GetTypeId() == TYPEID_PLAYER))
{
DoTeleportPlayer(pUnit, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()+3, pUnit->GetOrientation());
}
}
DoResetThreat();
Teleport_Timer = 30000;
}else Teleport_Timer -= diff;
// //MarkOfFrost_Timer
// if (MarkOfFrost_Timer < diff)
// {
// DoCast(m_creature->getVictim(),SPELL_MARKOFFROST);
// MarkOfFrost_Timer = 25000;
// }else MarkOfFrost_Timer -= diff;
//Chill_Timer
if (Chill_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_CHILL);
Chill_Timer = 13000 + rand()%12000;
}else Chill_Timer -= diff;
//Breath_Timer
if (Breath_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_FROSTBREATH);
Breath_Timer = 10000 + rand()%5000;
}else Breath_Timer -= diff;
//ManaStorm_Timer
if (ManaStorm_Timer < diff)
{
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,0);
if (target)
DoCast(target,SPELL_MANASTORM);
ManaStorm_Timer = 7500 + rand()%5000;
}else ManaStorm_Timer -= diff;
//Reflect_Timer
if (Reflect_Timer < diff)
{
DoCast(m_creature,SPELL_REFLECT);
Reflect_Timer = 20000 + rand()%15000;
}else Reflect_Timer -= diff;
//Cleave_Timer
if (Cleave_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_CLEAVE);
Cleave_Timer = 7000;
}else Cleave_Timer -= diff;
//Enrage_Timer
if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 26 && !Enraged)
{
DoCast(m_creature, SPELL_ENRAGE);
Enraged = true;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_azuregos(Creature *_Creature)
{
return new boss_azuregosAI (_Creature);
}
void AddSC_boss_azuregos()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_azuregos";
newscript->GetAI = GetAI_boss_azuregos;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,372 @@
/* Copyright (C) 2006,2007 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Azuremyst_Isle
SD%Complete: 75
SDComment: Quest support: 9283, 9537, 9554(special flight path, proper model for mount missing). Injured Draenei cosmetic only
SDCategory: Azuremyst Isle
EndScriptData */
/* ContentData
npc_draenei_survivor
npc_engineer_spark_overgrind
npc_injured_draenei
npc_susurrus
EndContentData */
#include "precompiled.h"
#include <cmath>
/*######
## npc_draenei_survivor
######*/
#define HEAL1 "The last thing I remember is the ship falling and us getting into the pods. I'll go see how I can help. Thank you!"
#define HEAL2 "$C, Where am I? Who are you? Oh no! What happened to the ship?."
#define HEAL3 "$C You saved me! I owe you a debt that I can never repay. I'll go see if I can help the others."
#define HEAL4 "Ugh... what is this place? Is that all that's left of the ship over there?"
#define HELP1 "Oh, the pain..."
#define HELP2 "Everything hurts, Please make it stop..."
#define HELP3 "Ughhh... I hurt. Can you help me?"
#define HELP4 "I don't know if I can make it, please help me..."
struct MANGOS_DLL_DECL npc_draenei_survivorAI : public ScriptedAI
{
npc_draenei_survivorAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 UnSpawnTimer;
uint32 ResetlifeTimer;
uint32 SayingTimer;
uint32 HealSayTimer;
bool UnSpawn;
bool say;
bool HealSay;
bool isRun;
bool isMove;
void Reset()
{
UnSpawnTimer = 2500;
ResetlifeTimer= 60000;
SayingTimer = 5000;
HealSayTimer = 6000;
say = false;
isRun = false;
isMove = false;
UnSpawn = false;
HealSay = false;
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
//cast red shining
m_creature->CastSpell(m_creature, 29152, false, NULL);
//set creature health
m_creature->SetHealth(int(m_creature->GetMaxHealth()*.1));
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 3);
}
void Aggro(Unit *who) {}
void MoveInLineOfSight(Unit *who) //MoveInLineOfSight is called if creature could see you, updated all 100 ms
{
if (!who)
return;
if(who->GetTypeId() == TYPEID_PLAYER && m_creature->IsFriendlyTo(who) && m_creature->IsWithinDistInMap(who, 15) && say && !isRun)
{
switch (rand()%4) //Random switch between 4 texts
{
case 0:
DoSay(HELP1, LANG_UNIVERSAL, NULL);
SayingTimer = 15000;
say = false;
break;
case 1:
DoSay(HELP2, LANG_UNIVERSAL, NULL);
SayingTimer = 15000;
say = false;
break;
case 2:
DoSay(HELP3, LANG_UNIVERSAL, NULL);
SayingTimer = 15000;
say = false;
break;
case 3:
DoSay(HELP4, LANG_UNIVERSAL, NULL);
SayingTimer = 15000;
say = false;
break;
}
}
else
{
isRun = false;
}
}
void UpdateAI(const uint32 diff) //Is also called each ms for Creature AI Updates...
{
if (m_creature->GetHealth() > 50)
{
if(ResetlifeTimer < diff)
{
ResetlifeTimer = 60000;
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
//set creature health
m_creature->SetHealth(int(m_creature->GetMaxHealth()*.1));
// ley down
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,3);
}
else ResetlifeTimer -= diff;
}
if(HealSay)
{
if (HealSayTimer < diff)
{
UnSpawn = true;
isRun = true;
isMove = true;
}else HealSayTimer -= diff;
}
if(UnSpawn)
{
if(isMove)
{
m_creature->GetMotionMaster()->Clear();
m_creature->GetMotionMaster()->MovePoint(0, -4115.053711f, -13754.831055f, 73.508949f);
isMove = false;
}
if (UnSpawnTimer < diff)
{
m_creature->StopMoving();
EnterEvadeMode();
//set creature health
m_creature->SetHealth(int(m_creature->GetMaxHealth()*.1));
}else UnSpawnTimer -= diff;
}
if(SayingTimer < diff)
{
say = true;
}else SayingTimer -= diff;
}
void SpellHit(Unit *Hitter, const SpellEntry *Spellkind)//Called if you cast a spell and do some things if Specified spell is true!
{
if (Hitter && Spellkind->Id == 28880)
{
m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
m_creature->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED);
m_creature->HandleEmoteCommand(ANIM_RISE);
switch (rand()%4) //This switch doesn't work at all, creature say nothing!
{
case 0: DoSay(HEAL1, LANG_UNIVERSAL, Hitter); break;
case 1: DoSay(HEAL2, LANG_UNIVERSAL, Hitter); break;
case 2: DoSay(HEAL3, LANG_UNIVERSAL, Hitter); break;
case 3: DoSay(HEAL4, LANG_UNIVERSAL, Hitter); break;
}
HealSay = true;
}
}
};
CreatureAI* GetAI_npc_draenei_survivor(Creature *_Creature)
{
return new npc_draenei_survivorAI (_Creature);
}
/*######
## npc_engineer_spark_overgrind
######*/
#define SAY_TEXT "Yes Master, all goes along as planned."
#define SAY_EMOTE "puts the shell to his ear."
#define GOSSIP_FIGHT "Traitor! You will be brought to justice!"
#define ATTACK_YELL "Now I cut you!"
#define SPELL_DYNAMITE 7978
struct MANGOS_DLL_DECL npc_engineer_spark_overgrindAI : public ScriptedAI
{
npc_engineer_spark_overgrindAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 Dynamite_Timer;
uint32 Emote_Timer;
void Reset()
{
Dynamite_Timer = 8000;
Emote_Timer = 120000 + rand()%30000;
m_creature->setFaction(875);
}
void Aggro(Unit *who) { }
void UpdateAI(const uint32 diff)
{
if( !InCombat )
{
if (Emote_Timer < diff)
{
DoSay(SAY_TEXT,LANG_UNIVERSAL,NULL);
DoTextEmote(SAY_EMOTE,NULL);
Emote_Timer = 120000 + rand()%30000;
}else Emote_Timer -= diff;
}
if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if (Dynamite_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_DYNAMITE);
Dynamite_Timer = 8000;
} else Dynamite_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_npc_engineer_spark_overgrind(Creature *_Creature)
{
return new npc_engineer_spark_overgrindAI (_Creature);
}
bool GossipHello_npc_engineer_spark_overgrind(Player *player, Creature *_Creature)
{
if( player->GetQuestStatus(9537) == QUEST_STATUS_INCOMPLETE )
player->ADD_GOSSIP_ITEM(0, GOSSIP_FIGHT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
return true;
}
bool GossipSelect_npc_engineer_spark_overgrind(Player *player, Creature *_Creature, uint32 sender, uint32 action )
{
if( action == GOSSIP_ACTION_INFO_DEF )
{
player->CLOSE_GOSSIP_MENU();
_Creature->setFaction(14);
_Creature->Yell(ATTACK_YELL, LANG_UNIVERSAL, player->GetGUID());
((npc_engineer_spark_overgrindAI*)_Creature->AI())->AttackStart(player);
}
return true;
}
/*######
## npc_injured_draenei
######*/
struct MANGOS_DLL_DECL npc_injured_draeneiAI : public ScriptedAI
{
npc_injured_draeneiAI(Creature *c) : ScriptedAI(c) {Reset();}
void Reset()
{
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT);
m_creature->SetHealth(int(m_creature->GetMaxHealth()*.15));
switch (rand()%2)
{
case 0: m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 1); break;
case 1: m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 3); break;
}
}
void Aggro(Unit *who) {}
void MoveInLineOfSight(Unit *who)
{
return; //ignore everyone around them (won't aggro anything)
}
void UpdateAI(const uint32 diff)
{
return;
}
};
CreatureAI* GetAI_npc_injured_draenei(Creature *_Creature)
{
return new npc_injured_draeneiAI (_Creature);
}
/*######
## npc_susurrus
######*/
bool GossipHello_npc_susurrus(Player *player, Creature *_Creature)
{
if (_Creature->isQuestGiver())
player->PrepareQuestMenu( _Creature->GetGUID() );
if (player->HasItemCount(23843,1,true))
player->ADD_GOSSIP_ITEM(0, "I am ready.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
return true;
}
bool GossipSelect_npc_susurrus(Player *player, Creature *_Creature, uint32 sender, uint32 action )
{
if (action == GOSSIP_ACTION_INFO_DEF)
{
player->CLOSE_GOSSIP_MENU();
player->CastSpell(player,32474,true); //apparently correct spell, possible not correct place to cast, or correct caster
std::vector<uint32> nodes;
nodes.resize(2);
nodes[0] = 92; //from susurrus
nodes[1] = 91; //end at exodar
player->ActivateTaxiPathTo(nodes,11686); //TaxiPath 506. Using invisible model, possible mangos must allow 0(from dbc) for cases like this.
}
return true;
}
/*######
##
######*/
void AddSC_azuremyst_isle()
{
Script *newscript;
newscript = new Script;
newscript->Name="npc_draenei_survivor";
newscript->GetAI = GetAI_npc_draenei_survivor;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="npc_engineer_spark_overgrind";
newscript->GetAI = GetAI_npc_engineer_spark_overgrind;
newscript->pGossipHello = &GossipHello_npc_engineer_spark_overgrind;
newscript->pGossipSelect = &GossipSelect_npc_engineer_spark_overgrind;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="npc_injured_draenei";
newscript->GetAI = GetAI_npc_injured_draenei;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="npc_susurrus";
newscript->pGossipHello = &GossipHello_npc_susurrus;
newscript->pGossipSelect = &GossipSelect_npc_susurrus;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,189 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: The_Barrens
SD%Complete: 90
SDComment: Quest support: 2458, 4921, 6981
SDCategory: Barrens
EndScriptData */
/* ContentData
npc_beaten_corpse
npc_sputtervalve
npc_taskmaster_fizzule remove hack when mangos implement feature/detect spell kind to not aggro
EndContentData */
#include "precompiled.h"
/*######
## npc_beaten_corpse
######*/
bool GossipHello_npc_beaten_corpse(Player *player, Creature *_Creature)
{
if( player->GetQuestStatus(4921) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(4921) == QUEST_STATUS_COMPLETE)
player->ADD_GOSSIP_ITEM(0,"Examine corpse in detail...",GOSSIP_SENDER_MAIN,GOSSIP_ACTION_INFO_DEF+1);
player->SEND_GOSSIP_MENU(3557,_Creature->GetGUID());
return true;
}
bool GossipSelect_npc_beaten_corpse(Player *player, Creature *_Creature, uint32 sender, uint32 action )
{
if(action == GOSSIP_ACTION_INFO_DEF +1)
{
player->SEND_GOSSIP_MENU(3558,_Creature->GetGUID());
player->KilledMonster( 10668,_Creature->GetGUID() );
}
return true;
}
/*######
## npc_sputtervalve
######*/
bool GossipHello_npc_sputtervalve(Player *player, Creature *_Creature)
{
if (_Creature->isQuestGiver())
player->PrepareQuestMenu( _Creature->GetGUID() );
if( player->GetQuestStatus(6981) == QUEST_STATUS_INCOMPLETE)
player->ADD_GOSSIP_ITEM(0,"Can you tell me about this shard?",GOSSIP_SENDER_MAIN,GOSSIP_ACTION_INFO_DEF);
player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(),_Creature->GetGUID());
return true;
}
bool GossipSelect_npc_sputtervalve(Player *player, Creature *_Creature, uint32 sender, uint32 action )
{
if(action == GOSSIP_ACTION_INFO_DEF)
{
player->SEND_GOSSIP_MENU(2013,_Creature->GetGUID());
player->AreaExploredOrEventHappens(6981);
}
return true;
}
/*######
## npc_taskmaster_fizzule
######*/
//#define FACTION_HOSTILE_F 430
#define FACTION_HOSTILE_F 16
#define FACTION_FRIENDLY_F 35
#define SPELL_FLARE 10113
#define SPELL_FOLLY 10137
struct MANGOS_DLL_DECL npc_taskmaster_fizzuleAI : public ScriptedAI
{
npc_taskmaster_fizzuleAI(Creature* c) : ScriptedAI(c) { Reset(); }
bool IsFriend;
uint32 Reset_Timer;
uint32 FlareCount;
void Reset()
{
IsFriend = false;
Reset_Timer = 120000;
FlareCount = 0;
m_creature->setFaction(FACTION_HOSTILE_F);
m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
}
//This is a hack. Spellcast will make creature aggro but that is not
//supposed to happen (mangos not implemented/not found way to detect this spell kind)
void DoUglyHack()
{
m_creature->RemoveAllAuras();
m_creature->DeleteThreatList();
m_creature->CombatStop();
}
void SpellHit(Unit *caster, const SpellEntry *spell)
{
if( spell->Id == SPELL_FLARE || spell->Id == SPELL_FOLLY )
{
DoUglyHack();
++FlareCount;
if( FlareCount >= 2 )
{
m_creature->setFaction(FACTION_FRIENDLY_F);
IsFriend = true;
}
}
}
void Aggro(Unit* who) { }
void UpdateAI(const uint32 diff)
{
if( IsFriend )
{
if( Reset_Timer < diff )
{
EnterEvadeMode();
} else Reset_Timer -= diff;
}
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_npc_taskmaster_fizzule(Creature *_Creature)
{
return new npc_taskmaster_fizzuleAI (_Creature);
}
bool ReciveEmote_npc_taskmaster_fizzule(Player *player, Creature *_Creature, uint32 emote)
{
if( emote == TEXTEMOTE_SALUTE )
{
if( ((npc_taskmaster_fizzuleAI*)_Creature->AI())->FlareCount >= 2 )
{
_Creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
_Creature->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
}
}
return true;
}
void AddSC_the_barrens()
{
Script *newscript;
newscript = new Script;
newscript->Name="npc_beaten_corpse";
newscript->pGossipHello = &GossipHello_npc_beaten_corpse;
newscript->pGossipSelect = &GossipSelect_npc_beaten_corpse;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="npc_sputtervalve";
newscript->pGossipHello = &GossipHello_npc_sputtervalve;
newscript->pGossipSelect = &GossipSelect_npc_sputtervalve;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="npc_taskmaster_fizzule";
newscript->GetAI = GetAI_npc_taskmaster_fizzule;
newscript->pReceiveEmote = &ReciveEmote_npc_taskmaster_fizzule;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,68 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Black_Temple
SD%Complete: 95
SDComment: Spirit of Olum: Player Teleporter to Seer Kanai Teleport after defeating Naj'entus and Supremus. TODO: Find proper gossip.
SDCategory: Black Temple
EndScriptData */
/* ContentData
npc_spirit_of_olum
EndContentData */
#include "precompiled.h"
#include "def_black_temple.h"
/*###
# npc_spirit_of_olum
####*/
#define SPELL_TELEPORT 41566 // s41566 - Teleport to Ashtongue NPC's
#define GOSSIP_OLUM1 "Teleport me to the other Ashtongue Deathsworn"
bool GossipHello_npc_spirit_of_olum(Player* player, Creature* _Creature)
{
ScriptedInstance* pInstance = ((ScriptedInstance*)_Creature->GetInstanceData());
if(pInstance && (pInstance->GetData(DATA_SUPREMUSEVENT) >= DONE) && (pInstance->GetData(DATA_HIGHWARLORDNAJENTUSEVENT) >= DONE))
player->ADD_GOSSIP_ITEM(0, GOSSIP_OLUM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
return true;
}
bool GossipSelect_npc_spirit_of_olum(Player* player, Creature* _Creature, uint32 sender, uint32 action)
{
if(action == GOSSIP_ACTION_INFO_DEF + 1)
player->CLOSE_GOSSIP_MENU();
player->InterruptNonMeleeSpells(false);
player->CastSpell(player, SPELL_TELEPORT, false);
return true;
}
void AddSC_black_temple()
{
Script *newscript;
newscript = new Script;
newscript->Name = "npc_spirit_of_olum";
newscript->pGossipHello = GossipHello_npc_spirit_of_olum;
newscript->pGossipSelect = GossipSelect_npc_spirit_of_olum;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,365 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Bloodboil
SD%Complete: 80
SDComment: Bloodboil not working correctly, missing enrage
SDCategory: Black Temple
EndScriptData */
#include "precompiled.h"
#include "def_black_temple.h"
//Spells
#define SPELL_ACID_GEYSER 40630
#define SPELL_ACIDIC_WOUND 40481
#define SPELL_ARCING_SMASH 40599
#define SPELL_BLOODBOIL 42005 // This spell is AoE whereas it shouldn't be
#define SPELL_FEL_ACID 40508
#define SPELL_FEL_RAGE_SELF 40594
#define SPELL_FEL_RAGE_TARGET 40604
#define SPELL_FEL_RAGE_2 40616
#define SPELL_FEL_RAGE_3 41625
#define SPELL_BEWILDERING_STRIKE 40491
#define SPELL_EJECT1 40486 // 1000 Physical damage + knockback + script effect (should handle threat reduction I think)
#define SPELL_EJECT2 40597 // 1000 Physical damage + Stun (used in phase 2?)
#define SPELL_TAUNT_GURTOGG 40603
#define SPELL_INSIGNIFIGANCE 40618
#define SPELL_BERSERK 45078
//Speech'n'Sound
#define SAY_AGGRO "Horde will crush you!"
#define SOUND_AGGRO 11432
#define SAY_SLAY1 "Time to feast!"
#define SOUND_SLAY1 11433
#define SAY_SLAY2 "More! I want more!"
#define SOUND_SLAY2 11434
#define SAY_SPECIAL1 "Drink your blood! Eat your flesh!"
#define SOUND_SPECIAL1 11435
#define SAY_SPECIAL2 "I hunger!"
#define SOUND_SPECIAL2 11436
#define SAY_ENRAGE "I'll rip the meat from your bones!"
#define SOUND_ENRAGE 11437
#define SOUND_DEATH 11439
//This is used to sort the players by distance in preparation for the Bloodboil cast.
struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool>
{
const Unit* MainTarget;
TargetDistanceOrder(const Unit* Target) : MainTarget(Target) {};
// functor for operator ">"
bool operator()(const Unit* _Left, const Unit* _Right) const
{
return (MainTarget->GetDistance(_Left) > MainTarget->GetDistance(_Right));
}
};
struct MANGOS_DLL_DECL boss_gurtogg_bloodboilAI : public ScriptedAI
{
boss_gurtogg_bloodboilAI(Creature *c) : ScriptedAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
Reset();
}
ScriptedInstance* pInstance;
uint64 TargetGUID;
float TargetThreat;
uint32 BloodboilTimer;
uint32 BloodboilCount;
uint32 AcidGeyserTimer;
uint32 AcidicWoundTimer;
uint32 ArcingSmashTimer;
uint32 EnrageTimer;
uint32 FelAcidTimer;
uint32 EjectTimer;
uint32 BewilderingStrikeTimer;
uint32 PhaseChangeTimer;
bool Phase1;
void Reset()
{
if(pInstance)
pInstance->SetData(DATA_GURTOGGBLOODBOILEVENT, NOT_STARTED);
TargetGUID = 0;
TargetThreat = 0;
BloodboilTimer = 10000;
BloodboilCount = 0;
AcidGeyserTimer = 1000;
AcidicWoundTimer = 6000;
ArcingSmashTimer = 19000;
EnrageTimer = 600000;
FelAcidTimer = 25000;
EjectTimer = 10000;
BewilderingStrikeTimer = 15000;
PhaseChangeTimer = 60000;
Phase1 = true;
}
void Aggro(Unit *who)
{
DoZoneInCombat();
DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_AGGRO);
if(pInstance)
pInstance->SetData(DATA_GURTOGGBLOODBOILEVENT, IN_PROGRESS);
}
void KilledUnit(Unit *victim)
{
switch(rand()%2)
{
case 0:
DoYell(SAY_SLAY1,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_SLAY1);
break;
case 1:
DoYell(SAY_SLAY2,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_SLAY2);
break;
}
}
void JustDied(Unit *victim)
{
if(pInstance)
pInstance->SetData(DATA_GURTOGGBLOODBOILEVENT, DONE);
DoPlaySoundToSet(m_creature,SOUND_DEATH);
}
// Note: This seems like a very complicated fix. The fix needs to be handled by the core, as implementation of limited-target AoE spells are still not limited.
void CastBloodboil()
{
// Get the Threat List
std::list<HostilReference *> m_threatlist = m_creature->getThreatManager().getThreatList();
if(!m_threatlist.size()) return; // He doesn't have anyone in his threatlist, useless to continue
std::list<Unit *> targets;
std::list<HostilReference *>::iterator itr = m_threatlist.begin();
for( ; itr!= m_threatlist.end(); ++itr) //store the threat list in a different container
{
Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
//only on alive players
if(target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER )
targets.push_back( target);
}
//Sort the list of players
targets.sort(TargetDistanceOrder(m_creature));
//Resize so we only get top 5
targets.resize(5);
//Aura each player in the targets list with Bloodboil. Aura code copied+pasted from Aura command in Level3.cpp
/*SpellEntry const *spellInfo = GetSpellStore()->LookupEntry( SPELL_BLOODBOIL );
if(spellInfo)
{
for(std::list<Unit *>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
{
Unit* target = *itr;
if(!target) return;
for(uint32 i = 0;i<3;i++)
{
uint8 eff = spellInfo->Effect[i];
if (eff>=TOTAL_SPELL_EFFECTS)
continue;
Aura *Aur = new Aura(spellInfo, i, NULL, target);
target->AddAura(Aur);
}
}
}*/
}
void RevertThreatOnTarget(uint64 guid)
{
Unit* pUnit = NULL;
pUnit = Unit::GetUnit((*m_creature), guid);
if(pUnit)
{
if(m_creature->getThreatManager().getThreat(pUnit))
m_creature->getThreatManager().modifyThreatPercent(pUnit, -100);
if(TargetThreat)
m_creature->AddThreat(pUnit, TargetThreat);
}
}
void UpdateAI(const uint32 diff)
{
if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if(ArcingSmashTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_ARCING_SMASH);
ArcingSmashTimer = 10000;
}else ArcingSmashTimer -= diff;
if(FelAcidTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_FEL_ACID);
FelAcidTimer = 25000;
}else FelAcidTimer -= diff;
if(!m_creature->HasAura(SPELL_BERSERK, 0))
if(EnrageTimer < diff)
{
DoCast(m_creature, SPELL_BERSERK);
DoYell(SAY_ENRAGE,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_ENRAGE);
}else EnrageTimer -= diff;
if(Phase1)
{
if(BewilderingStrikeTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_BEWILDERING_STRIKE);
float mt_threat = m_creature->getThreatManager().getThreat(m_creature->getVictim());
Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 1);
m_creature->AddThreat(target, mt_threat);
BewilderingStrikeTimer = 20000;
}else BewilderingStrikeTimer -= diff;
if(EjectTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_EJECT1);
m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(), -40);
EjectTimer = 15000;
}else EjectTimer -= diff;
if(AcidicWoundTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_ACIDIC_WOUND);
AcidicWoundTimer = 10000;
}else AcidicWoundTimer -= diff;
if(BloodboilTimer < diff)
{
if(BloodboilCount < 5) // Only cast it five times.
{
//CastBloodboil(); // Causes issues on windows, so is commented out.
DoCast(m_creature->getVictim(), SPELL_BLOODBOIL);
++BloodboilCount;
BloodboilTimer = 10000*BloodboilCount;
}
}else BloodboilTimer -= diff;
}
if(!Phase1)
{
if(AcidGeyserTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_ACID_GEYSER);
AcidGeyserTimer = 30000;
}else AcidGeyserTimer -= diff;
if(EjectTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_EJECT2);
EjectTimer = 15000;
}else EjectTimer -= diff;
}
if(PhaseChangeTimer < diff)
{
if(Phase1)
{
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);
if(target && target->isAlive())
{
Phase1 = false;
TargetThreat = m_creature->getThreatManager().getThreat(target);
TargetGUID = target->GetGUID();
target->CastSpell(m_creature, SPELL_TAUNT_GURTOGG, true);
if(m_creature->getThreatManager().getThreat(target))
m_creature->getThreatManager().modifyThreatPercent(target, -100);
m_creature->AddThreat(target, 50000000.0f);
// If VMaps are disabled, this spell can call the whole instance
DoCast(m_creature, SPELL_INSIGNIFIGANCE, true);
DoCast(target, SPELL_FEL_RAGE_TARGET, true);
DoCast(target,SPELL_FEL_RAGE_2, true);
/* These spells do not work, comment them out for now.
DoCast(target, SPELL_FEL_RAGE_2, true);
DoCast(target, SPELL_FEL_RAGE_3, true);*/
//Cast this without triggered so that it appears in combat logs and shows visual.
DoCast(m_creature, SPELL_FEL_RAGE_SELF);
switch(rand()%2)
{
case 0:
DoYell(SAY_SPECIAL1,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_SPECIAL1);
break;
case 1:
DoYell(SAY_SPECIAL2,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_SPECIAL2);
break;
}
AcidGeyserTimer = 1000;
PhaseChangeTimer = 30000;
}
}else // Encounter is a loop pretty much. Phase 1 -> Phase 2 -> Phase 1 -> Phase 2 till death or enrage
{
if(TargetGUID)
RevertThreatOnTarget(TargetGUID);
TargetGUID = 0;
Phase1 = true;
BloodboilTimer = 10000;
BloodboilCount = 0;
AcidicWoundTimer += 2000;
ArcingSmashTimer += 2000;
FelAcidTimer += 2000;
EjectTimer += 2000;
PhaseChangeTimer = 60000;
}
}else PhaseChangeTimer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_gurtogg_bloodboil(Creature *_Creature)
{
return new boss_gurtogg_bloodboilAI (_Creature);
}
void AddSC_boss_gurtogg_bloodboil()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_gurtogg_bloodboil";
newscript->GetAI = GetAI_boss_gurtogg_bloodboil;
m_scripts[nrscripts++] = newscript;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,353 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Mother_Shahraz
SD%Complete: 80
SDComment: Saber Lash missing, Fatal Attraction slightly incorrect; need to damage only if affected players are within range of each other
SDCategory: Black Temple
EndScriptData */
#include "precompiled.h"
#include "def_black_temple.h"
//Spells
#define SPELL_BEAM_SINISTER 40859
#define SPELL_BEAM_VILE 40860
#define SPELL_BEAM_WICKED 40861
#define SPELL_BEAM_SINFUL 40827
#define SPELL_ATTRACTION 40871
#define SPELL_SILENCING_SHRIEK 40823
#define SPELL_ENRAGE 23537
#define SPELL_SABER_LASH 43267
#define SPELL_SABER_LASH_IMM 43690
#define SPELL_TELEPORT_VISUAL 40869
#define SPELL_BERSERK 45078
uint32 PrismaticAuras[]=
{
40880, // Shadow
40882, // Fire
40883, // Nature
40891, // Arcane
40896, // Frost
40897, // Holy
};
//Speech'n'Sounds
#define SAY_TAUNT1 "You play, you pay."
#define SOUND_TAUNT1 11501
#define SAY_TAUNT2 "I'm not impressed."
#define SOUND_TAUNT2 11502
#define SAY_TAUNT3 "Enjoying yourselves?"
#define SOUND_TAUNT3 11503
#define SAY_AGGRO "So, business... Or pleasure?"
#define SOUND_AGGRO 11504
#define SAY_SPELL1 "You seem a little tense."
#define SOUND_SPELL1 11505
#define SAY_SPELL2 "Don't be shy."
#define SOUND_SPELL2 11506
#define SAY_SPELL3 "I'm all... yours."
#define SOUND_SPELL3 11507
#define SAY_SLAY1 "Easy come, easy go."
#define SOUND_SLAY1 11508
#define SAY_SLAY2 "So much for a happy ending."
#define SOUND_SLAY2 11509
#define SAY_ENRAGE "Stop toying with my emotions!"
#define SOUND_ENRAGE 11510
#define SAY_DEATH "I wasn't... finished."
#define SOUND_DEATH 11511
struct Locations
{
float x,y,z;
};
static Locations TeleportPoint[]=
{
{959.996, 212.576, 193.843},
{932.537, 231.813, 193.838},
{958.675, 254.767, 193.822},
{946.955, 201.316, 192.535},
{944.294, 149.676, 197.551},
{930.548, 284.888, 193.367},
{965.997, 278.398, 195.777}
};
struct MANGOS_DLL_DECL boss_shahrazAI : public ScriptedAI
{
boss_shahrazAI(Creature *c) : ScriptedAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
Reset();
}
ScriptedInstance* pInstance;
uint64 TargetGUID[3];
uint32 BeamTimer;
uint32 BeamCount;
uint32 CurrentBeam;
uint32 PrismaticShieldTimer;
uint32 FatalAttractionTimer;
uint32 FatalAttractionExplodeTimer;
uint32 ShriekTimer;
uint32 RandomYellTimer;
uint32 EnrageTimer;
uint32 ExplosionCount;
bool Enraged;
void Reset()
{
if(pInstance)
pInstance->SetData(DATA_MOTHERSHAHRAZEVENT, NOT_STARTED);
for(uint8 i = 0; i<3; i++)
TargetGUID[i] = 0;
BeamTimer = 60000; // Timers may be incorrect
BeamCount = 0;
CurrentBeam = 0; // 0 - Sinister, 1 - Vile, 2 - Wicked, 3 - Sinful
PrismaticShieldTimer = 0;
FatalAttractionTimer = 60000;
FatalAttractionExplodeTimer = 70000;
ShriekTimer = 30000;
RandomYellTimer = 70000 + rand()%41 * 1000;
EnrageTimer = 600000;
ExplosionCount = 0;
Enraged = false;
}
void Aggro(Unit *who)
{
if(pInstance)
pInstance->SetData(DATA_MOTHERSHAHRAZEVENT, IN_PROGRESS);
DoZoneInCombat();
DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_AGGRO);
}
void KilledUnit(Unit *victim)
{
switch(rand()%2)
{
case 0:
DoYell(SAY_SLAY1,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_SLAY1);
break;
case 1:
DoYell(SAY_SLAY2,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_SLAY2);
break;
}
}
void JustDied(Unit *victim)
{
if(pInstance)
pInstance->SetData(DATA_MOTHERSHAHRAZEVENT, DONE);
DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_DEATH);
}
void TeleportPlayers()
{
uint32 random = rand()%7;
float X = TeleportPoint[random].x;
float Y = TeleportPoint[random].y;
float Z = TeleportPoint[random].z;
for(uint8 i = 0; i < 3; i++)
{
Unit* pUnit = SelectUnit(SELECT_TARGET_RANDOM, 1);
if(pUnit && pUnit->isAlive() && (pUnit->GetTypeId() == TYPEID_PLAYER))
{
TargetGUID[i] = pUnit->GetGUID();
pUnit->CastSpell(pUnit, SPELL_TELEPORT_VISUAL, true);
DoTeleportPlayer(pUnit, X, Y, Z, pUnit->GetOrientation());
}
}
}
void UpdateAI(const uint32 diff)
{
if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 10) && !Enraged)
{
Enraged = true;
DoCast(m_creature, SPELL_ENRAGE, true);
DoYell(SAY_ENRAGE, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_ENRAGE);
}
//Randomly cast one beam.
if(BeamTimer < diff)
{
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);
if(!target || !target->isAlive())
return;
BeamTimer = 9000;
switch(CurrentBeam)
{
case 0:
DoCast(target, SPELL_BEAM_SINISTER);
break;
case 1:
DoCast(target, SPELL_BEAM_VILE);
break;
case 2:
DoCast(target, SPELL_BEAM_WICKED);
break;
case 3:
DoCast(target, SPELL_BEAM_SINFUL);
break;
}
BeamCount++;
uint32 Beam = CurrentBeam;
if(BeamCount > 3)
while(CurrentBeam == Beam)
CurrentBeam = rand()%3;
}else BeamTimer -= diff;
// Random Prismatic Shield every 15 seconds.
if(PrismaticShieldTimer < diff)
{
uint32 random = rand()%6;
if(PrismaticAuras[random])
DoCast(m_creature, PrismaticAuras[random]);
PrismaticShieldTimer = 15000;
}else PrismaticShieldTimer -= diff;
// Select 3 random targets (can select same target more than once), teleport to a random location then make them cast explosions until they get away from each other.
if(FatalAttractionTimer < diff)
{
ExplosionCount = 0;
TeleportPlayers();
switch(rand()%2)
{
case 0:
DoYell(SAY_SPELL2,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_SPELL2);
break;
case 1:
DoYell(SAY_SPELL3,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_SPELL3);
break;
}
FatalAttractionExplodeTimer = 2000;
FatalAttractionTimer = 40000 + rand()%31 * 1000;
}else FatalAttractionTimer -= diff;
if(FatalAttractionExplodeTimer < diff)
{
// Just make them explode three times... they're supposed to keep exploding while they are in range, but it'll take too much code. I'll try to think of an efficient way for it later.
if(ExplosionCount < 3)
{
for(uint8 i = 0; i < 4; i++)
{
Unit* pUnit = NULL;
if(TargetGUID[i])
{
pUnit = Unit::GetUnit((*m_creature), TargetGUID[i]);
if(pUnit)
pUnit->CastSpell(pUnit, SPELL_ATTRACTION, true);
TargetGUID[i] = 0;
}
}
ExplosionCount++;
FatalAttractionExplodeTimer = 1000;
}
else
{
FatalAttractionExplodeTimer = FatalAttractionTimer + 2000;
ExplosionCount = 0;
}
}else FatalAttractionExplodeTimer -= diff;
if(ShriekTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_SILENCING_SHRIEK);
ShriekTimer = 30000;
}else ShriekTimer -= diff;
//Enrage
if(!m_creature->HasAura(SPELL_BERSERK, 0))
if(EnrageTimer < diff)
{
DoCast(m_creature, SPELL_BERSERK);
DoYell(SAY_ENRAGE,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_ENRAGE);
}else EnrageTimer -= diff;
//Random taunts
if(RandomYellTimer < diff)
{
switch(rand()%3)
{
case 0:
DoYell(SAY_TAUNT1,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_TAUNT1);
break;
case 1:
DoYell(SAY_TAUNT2,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_TAUNT2);
break;
case 2:
DoYell(SAY_TAUNT3,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_TAUNT3);
break;
}
RandomYellTimer = 60000 + rand()%91 * 1000;
}else RandomYellTimer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_shahraz(Creature *_Creature)
{
return new boss_shahrazAI (_Creature);
}
void AddSC_boss_mother_shahraz()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_mother_shahraz";
newscript->GetAI = GetAI_boss_shahraz;
m_scripts[nrscripts++] = newscript;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,813 @@
/* Copyright (C) 2006,2007 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Shade_of_Akama
SD%Complete: 99
SDComment: Seems to be complete.
SDCategory: Black Temple
EndScriptData */
#include "precompiled.h"
#include "def_black_temple.h"
#include "sc_grid_searchers.h"
struct Location
{
float x, y, o, z;
};
static Location ChannelerLocations[]=
{
{463.161285, 401.219757, 3.141592},
{457.377625, 391.227661, 2.106461},
{446.012421, 391.227661, 1.071904},
{439.533783, 401.219757, 0.000000},
{446.012421, 411.211853, 5.210546},
{457.377625, 411.211853, 4.177494}
};
static Location SpawnLocations[]=
{
{498.652740, 461.728119, 0},
{498.505003, 339.619324, 0}
};
static Location AkamaWP[]=
{
{482.352448, 401.162720, 0, 112.783928},
{469.597443, 402.264404, 0, 118.537910}
};
static Location BrokenCoords[]=
{
{541.375916, 401.439575, M_PI, 112.783997}, // The place where Akama channels
{534.130005, 352.394531, 2.164150, 112.783737}, // Behind a 'pillar' which is behind the east alcove
{499.621185, 341.534729, 1.652856, 112.783730}, // East Alcove
{499.151093, 461.036438, 4.770888, 112.78370}, // West Alcove
};
static Location BrokenWP[]=
{
{492.491638, 400.744690, 3.122336, 112.783737},
{494.335724, 382.221771, 2.676230, 112.783737},
{489.555939, 373.507202, 2.416263, 112.783737},
{491.136353, 427.868774, 3.519748, 112.783737},
};
// Locations
#define Z1 118.543144
#define Z2 120.783768
#define Z_SPAWN 113.537949
#define AGGRO_X 482.793182
#define AGGRO_Y 401.270172
#define AGGRO_Z 112.783928
#define AKAMA_X 514.583984
#define AKAMA_Y 400.601013
#define AKAMA_Z 112.783997
// Texts
#define SOUND_DEATH 11386
#define SAY_DEATH "No! Not yet..."
#define SOUND_LOW_HEALTH 11385
#define SAY_LOW_HEALTH "I will not last much longer..."
// Ending cinematic text
#define SAY_FREE "Come out from the shadows! I've returned to lead you against our true enemy! Shed your chains and raise your weapons against your Illidari masters!"
#define SAY_BROKEN_FREE_01 "Hail our leader! Hail Akama!"
#define SAY_BROKEN_FREE_02 "Hail Akama!"
// Gossips
#define GOSSIP_ITEM "We are ready to fight alongside you, Akama"
// Spells
#define SPELL_VERTEX_SHADE_BLACK 39833
#define SPELL_SHADE_SOUL_CHANNEL 40401
#define SPELL_DESTRUCTIVE_POISON 40874
#define SPELL_LIGHTNING_BOLT 42024
#define SPELL_AKAMA_SOUL_CHANNEL 40447
#define SPELL_AKAMA_SOUL_RETRIEVE 40902
#define AKAMA_SOUL_EXPEL 40855
#define SPELL_SHADE_SOUL_CHANNEL_2 40520
// Channeler entry
#define CREATURE_CHANNELER 23421
#define CREATURE_SORCERER 23215
#define CREATURE_DEFENDER 23216
#define CREATURE_BROKEN 23319
const uint32 spawnEntries[4]= { 23523, 23318, 23524 };
struct MANGOS_DLL_DECL mob_ashtongue_channelerAI : public ScriptedAI
{
mob_ashtongue_channelerAI(Creature* c) : ScriptedAI(c) { Reset(); }
uint64 ShadeGUID;
void Reset() { ShadeGUID = 0; }
void JustDied(Unit* killer);
void Aggro(Unit* who) {}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff) {}
};
struct MANGOS_DLL_DECL mob_ashtongue_sorcererAI : public ScriptedAI
{
mob_ashtongue_sorcererAI(Creature* c) : ScriptedAI(c) { Reset(); }
uint64 ShadeGUID;
uint32 CheckTimer;
bool StartBanishing;
void Reset()
{
StartBanishing = false;
CheckTimer = 5000;
ShadeGUID = 0;
}
void JustDied(Unit* killer);
void Aggro(Unit* who) {}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff)
{
if(StartBanishing)
return;
if(CheckTimer < diff)
{
Unit* Shade = Unit::GetUnit((*m_creature), ShadeGUID);
if(Shade && Shade->isAlive() && m_creature->isAlive())
{
if(m_creature->GetDistance2d(Shade) < 20)
{
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveIdle();
DoCast(Shade, SPELL_SHADE_SOUL_CHANNEL, true);
DoCast(Shade, SPELL_SHADE_SOUL_CHANNEL_2, true);
StartBanishing = true;
}
}
CheckTimer = 2000;
}else CheckTimer -= diff;
}
};
struct MANGOS_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
{
boss_shade_of_akamaAI(Creature* c) : ScriptedAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
AkamaGUID = pInstance ? pInstance->GetData64(DATA_AKAMA_SHADE) : 0;
Reset();
}
ScriptedInstance* pInstance;
std::list<uint64> Channelers;
std::list<uint64> Sorcerers;
uint64 AkamaGUID;
uint32 SorcererCount;
uint32 DeathCount;
uint32 ReduceHealthTimer;
uint32 SummonTimer;
uint32 ResetTimer;
uint32 DefenderTimer; // They are on a flat 15 second timer, independant of the other summon creature timer.
bool IsBanished;
bool HasKilledAkama;
void Reset()
{
FindChannelers();
if(!Channelers.empty())
for(std::list<uint64>::iterator itr = Channelers.begin(); itr != Channelers.end(); ++itr)
{
Creature* Channeler = NULL;
Channeler = ((Creature*)Unit::GetUnit(*m_creature, *itr));
if(Channeler)
{
if(Channeler->isDead())
{
Channeler->RemoveCorpse();
Channeler->Respawn();
}
Channeler->CastSpell(m_creature, SPELL_SHADE_SOUL_CHANNEL, true);
Channeler->CastSpell(m_creature, SPELL_SHADE_SOUL_CHANNEL_2, true);
Channeler->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
}
else error_log("SD2 ERROR: No Channelers are stored in the list. This encounter will not work properly");
if(!Sorcerers.empty())
for(std::list<uint64>::iterator itr = Sorcerers.begin(); itr != Sorcerers.end(); ++itr)
if(Creature* Sorcerer = ((Creature*)Unit::GetUnit(*m_creature, *itr)))
if(Sorcerer->isAlive())
{
Sorcerer->SetVisibility(VISIBILITY_OFF);
Sorcerer->DealDamage(Sorcerer, Sorcerer->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
}
Sorcerers.clear();
if(Unit* Akama = Unit::GetUnit(*m_creature, AkamaGUID))
Akama->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
SorcererCount = 0;
DeathCount = 0;
SummonTimer = 10000;
ReduceHealthTimer = 0;
ResetTimer = 60000;
DefenderTimer = 15000;
IsBanished = true;
HasKilledAkama = false;
m_creature->SetVisibility(VISIBILITY_ON);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
m_creature->GetMotionMaster()->Clear();
m_creature->GetMotionMaster()->MoveIdle();
m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_STUN);
if(pInstance && m_creature->isAlive())
pInstance->SetData(DATA_SHADEOFAKAMAEVENT, NOT_STARTED);
}
void Aggro(Unit* who) { }
void AttackStart(Unit* who)
{
if(!who || IsBanished) return;
if(who->isTargetableForAttack() && who != m_creature)
DoStartAttackAndMovement(who);
}
void MoveInLineOfSight(Unit* who)
{
if(IsBanished) return;
ScriptedAI::MoveInLineOfSight(who);
}
void IncrementDeathCount(uint64 guid = 0) // If guid is set, will remove it from list of sorcerer
{
debug_log("SD2: Increasing Death Count for Shade of Akama encounter");
++DeathCount;
m_creature->RemoveSingleAuraFromStack(SPELL_SHADE_SOUL_CHANNEL_2, 0);
if(guid)
{
if(Sorcerers.empty())
error_log("SD2 ERROR: Shade of Akama - attempt to remove guid %u from Sorcerers list but list is already empty", guid);
else Sorcerers.remove(guid);
}
}
void SummonCreature()
{
uint32 random = rand()%2;
float X = SpawnLocations[random].x;
float Y = SpawnLocations[random].y;
// max of 6 sorcerers can be summoned
if((rand()%3 == 0) && (DeathCount > 0) && (SorcererCount < 7))
{
Creature* Sorcerer = m_creature->SummonCreature(CREATURE_SORCERER, X, Y, Z_SPAWN, 0, TEMPSUMMON_DEAD_DESPAWN, 0);
if(Sorcerer)
{
((mob_ashtongue_sorcererAI*)Sorcerer->AI())->ShadeGUID = m_creature->GetGUID();
Sorcerer->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
Sorcerer->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ());
Sorcerer->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
Sorcerers.push_back(Sorcerer->GetGUID());
--DeathCount;
++SorcererCount;
}
}
else
{
for(uint8 i = 0; i < 3; ++i)
{
Creature* Spawn = m_creature->SummonCreature(spawnEntries[i], X, Y, Z_SPAWN, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 25000);
if(Spawn)
{
Spawn->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
Spawn->GetMotionMaster()->MovePoint(0, AGGRO_X, AGGRO_Y, AGGRO_Z);
}
}
}
}
void FindChannelers()
{
CellPair pair(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
Cell cell(pair);
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
std::list<Creature*> ChannelerList;
AllCreaturesOfEntryInRange check(m_creature, CREATURE_CHANNELER, 50);
MaNGOS::CreatureListSearcher<AllCreaturesOfEntryInRange> searcher(ChannelerList, check);
TypeContainerVisitor<MaNGOS::CreatureListSearcher<AllCreaturesOfEntryInRange>, GridTypeMapContainer> visitor(searcher);
CellLock<GridReadGuard> cell_lock(cell, pair);
cell_lock->Visit(cell_lock, visitor, *(m_creature->GetMap()));
if(!ChannelerList.empty())
{
Channelers.clear();
for(std::list<Creature*>::iterator itr = ChannelerList.begin(); itr != ChannelerList.end(); ++itr)
{
((mob_ashtongue_channelerAI*)(*itr)->AI())->ShadeGUID = m_creature->GetGUID();
Channelers.push_back((*itr)->GetGUID());
debug_log("SD2: Shade of Akama Grid Search found channeler %u. Adding to list", (*itr)->GetGUID());
}
}
else error_log("SD2 ERROR: Grid Search was unable to find any channelers. Shade of Akama encounter will be buggy");
}
void SetSelectableChannelers()
{
if(Channelers.empty())
{
error_log("SD2 ERROR: Channeler List is empty, Shade of Akama encounter will be buggy");
return;
}
for(std::list<uint64>::iterator itr = Channelers.begin(); itr != Channelers.end(); ++itr)
if(Creature* Channeler = ((Creature*)Unit::GetUnit(*m_creature, *itr)))
Channeler->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
void SetAkamaGUID(uint64 guid) { AkamaGUID = guid; }
void UpdateAI(const uint32 diff)
{
if(!InCombat)
return;
if(IsBanished)
{
// Akama is set in the threatlist so when we reset, we make sure that he is not included in our check
if(m_creature->getThreatManager().getThreatList().size() < 2)
EnterEvadeMode();
if(DefenderTimer < diff)
{
uint32 ran = rand()%2;
Creature* Defender = m_creature->SummonCreature(CREATURE_DEFENDER, SpawnLocations[ran].x, SpawnLocations[ran].y, Z_SPAWN, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 25000);
if(Defender)
{
Defender->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
bool move = true;
if(AkamaGUID)
{
if(Unit* Akama = Unit::GetUnit(*m_creature, AkamaGUID))
{
float x, y, z;
Akama->GetPosition(x,y,z);
// They move towards AKama
Defender->GetMotionMaster()->MovePoint(0, x, y, z);
}else move = false;
}else move = false;
if(!move)
Defender->GetMotionMaster()->MovePoint(0, AKAMA_X, AKAMA_Y, AKAMA_Z);
}
DefenderTimer = 15000;
}else DefenderTimer -= diff;
if(SummonTimer < diff)
{
SummonCreature();
SummonTimer = 35000;
}else SummonTimer -= diff;
if(DeathCount >= 6)
{
if(AkamaGUID)
{
Unit* Akama = Unit::GetUnit((*m_creature), AkamaGUID);
if(Akama && Akama->isAlive())
{
IsBanished = false;
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveChase(Akama);
Akama->GetMotionMaster()->Clear();
// Shade should move to Akama, not the other way around
Akama->GetMotionMaster()->MoveIdle();
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
// Crazy amount of threat
m_creature->AddThreat(Akama, 10000000.0f);
Akama->AddThreat(m_creature, 10000000.0f);
m_creature->Attack(Akama, true);
Akama->Attack(m_creature, true);
}
}
}
}
else // No longer banished, let's fight Akama now
{
if(ReduceHealthTimer < diff)
{
if(AkamaGUID)
{
Unit* Akama = Unit::GetUnit((*m_creature), AkamaGUID);
if(Akama && Akama->isAlive())
{
//10 % less health every few seconds.
m_creature->DealDamage(Akama, Akama->GetMaxHealth()/10, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
ReduceHealthTimer = 12000;
}
else
{
HasKilledAkama = true; // Akama is dead or missing, we stop fighting and disappear
m_creature->SetVisibility(VISIBILITY_OFF);
m_creature->SetHealth(m_creature->GetMaxHealth());
m_creature->RemoveAllAuras();
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
}
}else ReduceHealthTimer -= diff;
if(HasKilledAkama)
{
if(ResetTimer < diff)
{
InCombat = false;
EnterEvadeMode(); // Reset a little while after killing Akama
}
else ResetTimer -= diff;
}
DoMeleeAttackIfReady();
}
}
};
void mob_ashtongue_channelerAI::JustDied(Unit* killer)
{
Creature* Shade = ((Creature*)Unit::GetUnit((*m_creature), ShadeGUID));
if(Shade && Shade->isAlive())
((boss_shade_of_akamaAI*)Shade->AI())->IncrementDeathCount();
else error_log("SD2 ERROR: Channeler dead but unable to increment DeathCount for Shade of Akama.");
}
void mob_ashtongue_sorcererAI::JustDied(Unit* killer)
{
Creature* Shade = ((Creature*)Unit::GetUnit((*m_creature), ShadeGUID));
if(Shade && Shade->isAlive())
((boss_shade_of_akamaAI*)Shade->AI())->IncrementDeathCount(m_creature->GetGUID());
else error_log("SD2 ERROR: Sorcerer dead but unable to increment DeathCount for Shade of Akama.");
}
struct MANGOS_DLL_DECL npc_akamaAI : public ScriptedAI
{
npc_akamaAI(Creature* c) : ScriptedAI(c)
{
ShadeHasDied = false;
StartCombat = false;
pInstance = ((ScriptedInstance*)c->GetInstanceData());
ShadeGUID = pInstance ? pInstance->GetData64(DATA_SHADEOFAKAMA) : 0;
Reset();
}
ScriptedInstance* pInstance;
uint64 ShadeGUID;
uint32 DestructivePoisonTimer;
uint32 LightningBoltTimer;
uint32 CheckTimer;
uint32 CastSoulRetrieveTimer;
uint32 SoulRetrieveTimer;
uint32 SummonBrokenTimer;
uint32 EndingTalkCount;
uint32 WayPointId;
uint32 BrokenSummonIndex;
std::list<uint64> BrokenList;
bool EventBegun;
bool ShadeHasDied;
bool StartCombat;
bool HasYelledOnce;
void Reset()
{
DestructivePoisonTimer = 15000;
LightningBoltTimer = 10000;
CheckTimer = 2000;
CastSoulRetrieveTimer = 0;
SoulRetrieveTimer = 0;
SummonBrokenTimer = 0;
EndingTalkCount = 0;
WayPointId = 0;
BrokenSummonIndex = 0;
BrokenList.clear();
EventBegun = false;
HasYelledOnce = false;
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 0); // Database sometimes has very very strange values
m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
}
void Aggro(Unit* who) {}
void BeginEvent(Player* pl)
{
if(!pInstance)
return;
ShadeGUID = pInstance->GetData64(DATA_SHADEOFAKAMA);
if(!ShadeGUID)
return;
Creature* Shade = ((Creature*)Unit::GetUnit((*m_creature), ShadeGUID));
if(Shade)
{
pInstance->SetData(DATA_SHADEOFAKAMAEVENT, IN_PROGRESS);
// Prevent players from trying to restart event
m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
((boss_shade_of_akamaAI*)Shade->AI())->SetAkamaGUID(m_creature->GetGUID());
((boss_shade_of_akamaAI*)Shade->AI())->SetSelectableChannelers();
((boss_shade_of_akamaAI*)Shade->AI())->InCombat = true;
Shade->AddThreat(m_creature, 1000000.0f);
Shade->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
Shade->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
if(pl) Shade->AddThreat(pl, 1.0f);
DoZoneInCombat(Shade);
EventBegun = true;
}
}
void MovementInform(uint32 type, uint32 id)
{
if(type != POINT_MOTION_TYPE)
return;
switch(id)
{
case 0: ++WayPointId; break;
case 1:
if(Unit* Shade = Unit::GetUnit(*m_creature, ShadeGUID))
{
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, ShadeGUID);
DoCast(Shade, SPELL_AKAMA_SOUL_RETRIEVE);
EndingTalkCount = 0;
SoulRetrieveTimer = 16000;
}
break;
}
}
void JustDied(Unit* killer)
{
DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_DEATH);
}
void UpdateAI(const uint32 diff)
{
if(!EventBegun)
return;
if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 15 && !HasYelledOnce)
{
DoYell(SAY_LOW_HEALTH, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_LOW_HEALTH);
HasYelledOnce = true;
}
if(ShadeGUID && !StartCombat)
{
Creature* Shade = ((Creature*)Unit::GetUnit((*m_creature), ShadeGUID));
if(Shade && Shade->isAlive())
{
if(((boss_shade_of_akamaAI*)Shade->AI())->IsBanished)
{
if(CastSoulRetrieveTimer < diff)
{
DoCast(Shade, SPELL_AKAMA_SOUL_CHANNEL);
CastSoulRetrieveTimer = 500;
}else CastSoulRetrieveTimer -= diff;
}
else
{
m_creature->InterruptNonMeleeSpells(false);
StartCombat = true;
}
}
}
if(ShadeHasDied && (WayPointId == 1))
{
if(pInstance) pInstance->SetData(DATA_SHADEOFAKAMAEVENT, DONE);
m_creature->GetMotionMaster()->MovePoint(WayPointId, AkamaWP[1].x, AkamaWP[1].y, AkamaWP[1].z);
++WayPointId;
}
if(!ShadeHasDied && StartCombat)
{
if(CheckTimer < diff)
{
if(ShadeGUID)
{
Unit* Shade = Unit::GetUnit((*m_creature), ShadeGUID);
if(Shade && !Shade->isAlive())
{
ShadeHasDied = true;
WayPointId = 0;
m_creature->SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
m_creature->GetMotionMaster()->MovePoint(WayPointId, AkamaWP[0].x, AkamaWP[0].y, AkamaWP[0].z);
}
}
CheckTimer = 5000;
}else CheckTimer -= diff;
}
if(SummonBrokenTimer && BrokenSummonIndex < 4)
if(SummonBrokenTimer <= diff)
{
for(uint8 i = 0; i < 4; ++i)
{
float x = BrokenCoords[BrokenSummonIndex].x + (i*5);
float y = BrokenCoords[BrokenSummonIndex].y + (1*5);
float z = BrokenCoords[BrokenSummonIndex].z;
float o = BrokenCoords[BrokenSummonIndex].o;
Creature* Broken = m_creature->SummonCreature(CREATURE_BROKEN, x, y, z, o, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000);
if(Broken)
{
float wx = BrokenWP[BrokenSummonIndex].x + (i*5);
float wy = BrokenWP[BrokenSummonIndex].y + (i*5);
float wz = BrokenWP[BrokenSummonIndex].z;
Broken->GetMotionMaster()->MovePoint(0, wx, wy, wz);
Broken->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
BrokenList.push_back(Broken->GetGUID());
}
}
++BrokenSummonIndex;
SummonBrokenTimer = 1000;
}else SummonBrokenTimer -= diff;
if(SoulRetrieveTimer)
if(SoulRetrieveTimer <= diff)
{
switch(EndingTalkCount)
{
case 0:
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
++EndingTalkCount;
SoulRetrieveTimer = 2000;
SummonBrokenTimer = 1;
case 1:
DoYell(SAY_FREE, LANG_UNIVERSAL, NULL);
++EndingTalkCount;
SoulRetrieveTimer = 25000;
break;
case 2:
if(!BrokenList.empty())
{
bool Yelled = false;
for(std::list<uint64>::iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr)
if(Unit* pUnit = Unit::GetUnit(*m_creature, *itr))
{
if(!Yelled)
{
pUnit->MonsterYell(SAY_BROKEN_FREE_01, LANG_UNIVERSAL, 0);
Yelled = true;
}
pUnit->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL);
}
}
++EndingTalkCount;
SoulRetrieveTimer = 1500;
break;
case 3:
if(!BrokenList.empty())
for(std::list<uint64>::iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr)
if(Unit* pUnit = Unit::GetUnit(*m_creature, *itr))
// This is the incorrect spell, but can't seem to find the right one.
pUnit->CastSpell(pUnit, 39656, true);
++EndingTalkCount;
SoulRetrieveTimer = 5000;
case 4:
if(!BrokenList.empty())
for(std::list<uint64>::iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr)
if(Unit* pUnit = Unit::GetUnit((*m_creature), *itr))
pUnit->MonsterYell(SAY_BROKEN_FREE_02, LANG_UNIVERSAL, 0);
SoulRetrieveTimer = 0;
break;
}
}else SoulRetrieveTimer -= diff;
if(!m_creature->getVictim() || !m_creature->SelectHostilTarget())
return;
if(DestructivePoisonTimer < diff)
{
// SPELL_DESTRUCTIVE_POISON is self-cast only for some reason so we make our target cast it on itself
m_creature->getVictim()->CastSpell(m_creature->getVictim(), SPELL_DESTRUCTIVE_POISON, true);
DestructivePoisonTimer = 15000;
}else DestructivePoisonTimer -= diff;
if(LightningBoltTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_LIGHTNING_BOLT);
LightningBoltTimer = 10000;
}else LightningBoltTimer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_shade_of_akama(Creature *_Creature)
{
return new boss_shade_of_akamaAI (_Creature);
}
CreatureAI* GetAI_mob_ashtongue_channeler(Creature *_Creature)
{
return new mob_ashtongue_channelerAI (_Creature);
}
CreatureAI* GetAI_mob_ashtongue_sorcerer(Creature *_Creature)
{
return new mob_ashtongue_sorcererAI (_Creature);
}
CreatureAI* GetAI_npc_akama_shade(Creature *_Creature)
{
return new npc_akamaAI (_Creature);
}
bool GossipSelect_npc_akama(Player *player, Creature *_Creature, uint32 sender, uint32 action )
{
if (action == GOSSIP_ACTION_INFO_DEF + 1) //Fight time
{
player->CLOSE_GOSSIP_MENU();
((npc_akamaAI*)_Creature->AI())->BeginEvent(player);
}
return true;
}
bool GossipHello_npc_akama(Player *player, Creature *_Creature)
{
if(player->isAlive())
{
player->ADD_GOSSIP_ITEM( 0, GOSSIP_ITEM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
player->SEND_GOSSIP_MENU(907, _Creature->GetGUID());
}
return true;
}
void AddSC_boss_shade_of_akama()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_shade_of_akama";
newscript->GetAI = GetAI_boss_shade_of_akama;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="mob_ashtongue_channeler";
newscript->GetAI = GetAI_mob_ashtongue_channeler;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="mob_ashtongue_sorcerer";
newscript->GetAI = GetAI_mob_ashtongue_sorcerer;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="npc_akama_shade";
newscript->GetAI = GetAI_npc_akama_shade;
newscript->pGossipHello = &GossipHello_npc_akama;
newscript->pGossipSelect = &GossipSelect_npc_akama;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,406 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/ >
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Supremus
SD%Complete: 95
SDComment: Need to implement doors.
SDCategory: Black Temple
EndScriptData */
#include "precompiled.h"
#include "def_black_temple.h"
//Spells
#define SPELL_HURTFUL_STRIKE 41926
#define SPELL_DEMON_FIRE 40029
#define SPELL_MOLTEN_FLAME 40253
#define SPELL_VOLCANIC_ERUPTION 40276
#define SPELL_VOLCANIC_FIREBALL 40118
#define SPELL_VOLCANIC_GEYSER 42055
#define SPELL_MOLTEN_PUNCH 40126
#define SPELL_BERSERK 45078
#define CREATURE_VOLCANO 23085
#define CREATURE_STALKER 23095
struct MANGOS_DLL_DECL molten_flameAI : public ScriptedAI
{
molten_flameAI(Creature *c) : ScriptedAI(c)
{
Reset();
}
uint64 SupremusGUID;
bool TargetLocked;
uint32 CheckTimer;
void Reset()
{
SupremusGUID = 0;
TargetLocked = false;
CheckTimer = 1000;
}
void Aggro(Unit *who) {}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit *who)
{
if(TargetLocked)
return; // stop it from aggroing players who move in LOS if we have a target.
if(who && (who != m_creature) && (m_creature->IsWithinDistInMap(who, 10)))
StalkTarget(who);
}
void SetSupremusGUID(uint64 GUID) { SupremusGUID = GUID; }
void StalkTarget(Unit* target)
{
if(!target) return;
m_creature->AddThreat(target, 50000000.0f);
m_creature->GetMotionMaster()->MoveChase(target);
DoCast(m_creature, SPELL_DEMON_FIRE, true);
// DoCast(m_creature, SPELL_MOLTEN_FLAME, true); // This spell damages self, so disabled for now
TargetLocked = true;
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget())
return;
if(m_creature->getVictim() && m_creature->isAlive())
{
if(CheckTimer < diff)
{
if(SupremusGUID)
{
Unit* Supremus = NULL;
Supremus = Unit::GetUnit((*m_creature), SupremusGUID);
if(Supremus && (!Supremus->isAlive()))
m_creature->DealDamage(m_creature, m_creature->GetHealth(), 0, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
}
CheckTimer = 2000;
}else CheckTimer -= diff;
}
}
};
struct MANGOS_DLL_DECL npc_volcanoAI : public ScriptedAI
{
npc_volcanoAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 CheckTimer;
uint64 SupremusGUID;
uint32 FireballTimer;
uint32 GeyserTimer;
void Reset()
{
CheckTimer = 1000;
SupremusGUID = 0;
FireballTimer = 500;
GeyserTimer = 0;
}
void Aggro(Unit *who) {}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void SetSupremusGUID(uint64 guid) { SupremusGUID = guid; }
void UpdateAI(const uint32 diff)
{
if(CheckTimer < diff)
{
if(SupremusGUID)
{
Unit* Supremus = NULL;
Supremus = Unit::GetUnit((*m_creature), SupremusGUID);
if(Supremus && (!Supremus->isAlive()))
m_creature->DealDamage(m_creature, m_creature->GetHealth(), 0, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
}
CheckTimer = 2000;
}else CheckTimer -= diff;
if(GeyserTimer < diff)
{
DoCast(m_creature, SPELL_VOLCANIC_GEYSER);
GeyserTimer = 18000;
}else GeyserTimer -= diff;
}
};
struct MANGOS_DLL_DECL boss_supremusAI : public ScriptedAI
{
boss_supremusAI(Creature *c) : ScriptedAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
Reset();
}
ScriptedInstance* pInstance;
uint32 SummonFlameTimer;
uint32 SwitchTargetTimer;
uint32 PhaseSwitchTimer;
uint32 SummonVolcanoTimer;
uint32 HurtfulStrikeTimer;
uint32 BerserkTimer;
bool Phase1;
void Reset()
{
if(pInstance)
{
if(m_creature->isAlive())
{
pInstance->SetData(DATA_SUPREMUSEVENT, NOT_STARTED);
ToggleDoors(true);
}
else ToggleDoors(false);
}
HurtfulStrikeTimer = 5000;
SummonFlameTimer = 20000;
SwitchTargetTimer = 90000;
PhaseSwitchTimer = 60000;
SummonVolcanoTimer = 5000;
BerserkTimer = 900000; // 15 minute enrage
Phase1 = true;
}
void Aggro(Unit *who)
{
DoZoneInCombat();
if(pInstance)
pInstance->SetData(DATA_SUPREMUSEVENT, IN_PROGRESS);
}
void ToggleDoors(bool close)
{
if(GameObject* Doors = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_GAMEOBJECT_SUPREMUS_DOORS)))
{
if(close) Doors->SetGoState(1); // Closed
else Doors->SetGoState(0); // Open
}
}
void JustDied(Unit *killer)
{
if(pInstance)
{
pInstance->SetData(DATA_SUPREMUSEVENT, DONE);
ToggleDoors(false);
}
}
float CalculateRandomCoord(float initial)
{
float coord = 0;
switch(rand()%2)
{
case 0: coord = initial + 20 + rand()%20; break;
case 1: coord = initial - 20 - rand()%20; break;
}
return coord;
}
Creature* SummonCreature(uint32 entry, Unit* target)
{
if(target && entry)
{
Creature* Summon = m_creature->SummonCreature(entry, CalculateRandomCoord(target->GetPositionX()), CalculateRandomCoord(target->GetPositionY()), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 20000);
if(Summon)
{
Summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
Summon->setFaction(m_creature->getFaction());
return Summon;
}
}
return NULL;
}
Unit* CalculateHurtfulStrikeTarget()
{
uint32 health = 0;
Unit* target = NULL;
std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
std::list<HostilReference*>::iterator i = m_threatlist.begin();
for (i = m_threatlist.begin(); i!= m_threatlist.end();++i)
{
Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());
if(pUnit && m_creature->IsWithinDistInMap(pUnit, ATTACK_DISTANCE))
{
if(pUnit->GetHealth() > health)
{
health = pUnit->GetHealth();
target = pUnit;
}
}
}
return target;
}
void UpdateAI(const uint32 diff)
{
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if(!m_creature->HasAura(SPELL_BERSERK, 0))
if(BerserkTimer < diff)
DoCast(m_creature, SPELL_BERSERK);
else BerserkTimer -= diff;
if(SummonFlameTimer < diff)
{
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM, 1);
if(!target) // someone is trying to solo, set target as current victim.
target = m_creature->getVictim();
if(target)
{
Creature* MoltenFlame = SummonCreature(CREATURE_STALKER, target);
if(MoltenFlame)
{
// Invisible model
MoltenFlame->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686);
((molten_flameAI*)MoltenFlame->AI())->SetSupremusGUID(m_creature->GetGUID());
((molten_flameAI*)MoltenFlame->AI())->StalkTarget(target);
SummonFlameTimer = 20000;
}
}
}else SummonFlameTimer -= diff;
if(Phase1)
{
if(HurtfulStrikeTimer < diff)
{
Unit* target = CalculateHurtfulStrikeTarget();
if(target)
{
DoCast(target, SPELL_HURTFUL_STRIKE);
HurtfulStrikeTimer = 5000;
}
}else HurtfulStrikeTimer -= diff;
}
if(!Phase1)
{
if(SwitchTargetTimer < diff)
{
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);
if(target)
{
DoResetThreat();
m_creature->AddThreat(target, 5000000.0f);
DoTextEmote("acquires a new target!", NULL);
SwitchTargetTimer = 10000;
}
}else SwitchTargetTimer -= diff;
if(SummonVolcanoTimer < diff)
{
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
if(!target)
target = m_creature->getVictim();
if(target)
{
Creature* Volcano = NULL;
Volcano = SummonCreature(CREATURE_VOLCANO, target);
if(Volcano)
{
DoCast(target, SPELL_VOLCANIC_ERUPTION);
((npc_volcanoAI*)Volcano->AI())->SetSupremusGUID(m_creature->GetGUID());
}
DoTextEmote("roars and the ground begins to crack open!", NULL);
SummonVolcanoTimer = 10000;
}
}else SummonVolcanoTimer -= diff;
}
if(PhaseSwitchTimer < diff)
{
if(!Phase1)
{
Phase1 = true;
DoResetThreat();
PhaseSwitchTimer = 60000;
m_creature->SetSpeed(MOVE_RUN, 1.0f);
}
else
{
Phase1 = false;
DoResetThreat();
SwitchTargetTimer = 10000;
SummonVolcanoTimer = 2000;
PhaseSwitchTimer = 60000;
m_creature->SetSpeed(MOVE_RUN, 0.9f);
}
}else PhaseSwitchTimer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_supremus(Creature *_Creature)
{
return new boss_supremusAI (_Creature);
}
CreatureAI* GetAI_molten_flame(Creature *_Creature)
{
return new molten_flameAI (_Creature);
}
CreatureAI* GetAI_npc_volcano(Creature *_Creature)
{
return new npc_volcanoAI (_Creature);
}
void AddSC_boss_supremus()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_supremus";
newscript->GetAI = GetAI_boss_supremus;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="molten_flame";
newscript->GetAI = GetAI_molten_flame;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="npc_volcano";
newscript->GetAI = GetAI_npc_volcano;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,589 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Teron_Gorefiend
SD%Complete: 60
SDComment: Requires Mind Control support for Ghosts.
SDCategory: Black Temple
EndScriptData */
#include "precompiled.h"
#include "def_black_temple.h"
//Spells
#define SPELL_INCINERATE 40239
#define SPELL_CRUSHING_SHADOWS 40243
#define SPELL_SHADOWBOLT 40185
#define SPELL_PASSIVE_SHADOWFORM 40326
#define SPELL_SHADOW_OF_DEATH 40251
#define SPELL_BERSERK 45078
#define SPELL_ATROPHY 40327 // Shadowy Constructs use this when they get within melee range of a player
//Speech'n'sound
#define SAY_INTRO "I was the first, you know. For me, the wheel of death has spun many times. So much time has passed. I have a lot of catching up to do..."
#define SOUND_INTRO 11512
#define SAY_AGGRO "Vengeance is mine!"
#define SOUND_AGGRO 11513
#define SAY_SLAY1 "I have use for you!"
#define SOUND_SLAY1 11514
#define SAY_SLAY2 "It gets worse..."
#define SOUND_SLAY2 11515
#define SAY_SPELL1 "What are you afraid of?"
#define SOUND_SPELL1 11517
#define SAY_SPELL2 "Death... really isn't so bad."
#define SOUND_SPELL2 11516
#define SAY_SPECIAL1 "Give in!"
#define SOUND_SPECIAL1 11518
#define SAY_SPECIAL2 "I have something for you..."
#define SOUND_SPECIAL2 11519
#define SAY_ENRAGE "YOU WILL SHOW THE PROPER RESPECT!"
#define SOUND_ENRAGE 11520
#define SAY_DEATH "The wheel...spins...again...."
#define SOUND_DEATH 11521
#define CREATURE_DOOM_BLOSSOM 23123
#define CREATURE_SHADOWY_CONSTRUCT 23111
struct MANGOS_DLL_DECL mob_doom_blossomAI : public ScriptedAI
{
mob_doom_blossomAI(Creature *c) : ScriptedAI(c)
{
Reset();
}
uint32 CheckTeronTimer;
uint32 ShadowBoltTimer;
uint64 TeronGUID;
void Reset()
{
CheckTeronTimer = 5000;
ShadowBoltTimer = 12000;
TeronGUID = 0;
}
void Aggro(Unit *who) { }
void AttackStart(Unit* who) { }
void MoveInLineOfSight(Unit* who) { }
void UpdateAI(const uint32 diff)
{
if(CheckTeronTimer < diff)
{
if(TeronGUID)
{
DoZoneInCombat();
Creature* Teron = ((Creature*)Unit::GetUnit((*m_creature), TeronGUID));
if((Teron) && (!Teron->isAlive() || Teron->IsInEvadeMode()))
m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
}
else
m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
CheckTeronTimer = 5000;
}else CheckTeronTimer -= diff;
if(!m_creature->getVictim() || !m_creature->SelectHostilTarget())
return;
if(ShadowBoltTimer < diff)
{
DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_SHADOWBOLT);
ShadowBoltTimer = 10000;
}else ShadowBoltTimer -= diff;
}
void SetTeronGUID(uint64 guid){ TeronGUID = guid; }
};
//This is used to sort the players by distance for Constructs to see who to cast Atrophy on
struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool>
{
const Unit* MainTarget;
TargetDistanceOrder(const Unit* Target) : MainTarget(Target) {};
// functor for operator "<"
bool operator()(const Unit* _Left, const Unit* _Right) const
{
return (MainTarget->GetDistance(_Left) < MainTarget->GetDistance(_Right));
}
};
struct MANGOS_DLL_DECL mob_shadowy_constructAI : public ScriptedAI
{
mob_shadowy_constructAI(Creature* c) : ScriptedAI(c)
{
Reset();
}
uint64 GhostGUID;
uint64 TeronGUID;
uint32 CheckPlayerTimer;
uint32 CheckTeronTimer;
void Reset()
{
GhostGUID = 0;
TeronGUID = 0;
CheckPlayerTimer = 2000;
CheckTeronTimer = 5000;
}
void Aggro(Unit* who) { }
void MoveInLineOfSight(Unit *who)
{
if(!who || (!who->isAlive()) || (who->GetGUID() == GhostGUID))
return;
if(who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))
{
float attackRadius = m_creature->GetAttackDistance(who);
if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))
{
if(who->HasStealthAura())
who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
m_creature->AddThreat(who, 1.0f);
}
}
}
/* Comment it out for now. NOTE TO FUTURE DEV: UNCOMMENT THIS OUT ONLY AFTER MIND CONTROL IS IMPLEMENTED
void DamageTaken(Unit* done_by, uint32 &damage)
{
if(done_by->GetGUID() != GhostGUID)
damage = 0; // Only the ghost can deal damage.
}
*/
void CheckPlayers()
{
std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
if(m_threatlist.empty())
return; // No threat list. Don't continue.
std::list<HostilReference*>::iterator itr = m_threatlist.begin();
std::list<Unit*> targets;
for( ; itr != m_threatlist.end(); ++itr)
{
Unit* pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid());
if(pUnit && pUnit->isAlive())
targets.push_back(pUnit);
}
targets.sort(TargetDistanceOrder(m_creature));
Unit* target = targets.front();
if(target && m_creature->IsWithinDistInMap(target, m_creature->GetAttackDistance(target)))
{
DoCast(target, SPELL_ATROPHY);
m_creature->AI()->AttackStart(target);
}
}
void UpdateAI(const uint32 diff)
{
if(CheckPlayerTimer < diff)
{
CheckPlayers();
CheckPlayerTimer = 3000;
}else CheckPlayerTimer -= diff;
if(CheckTeronTimer < diff)
{
Creature* Teron = ((Creature*)Unit::GetUnit((*m_creature), TeronGUID));
if(!Teron || !Teron->isAlive() || Teron->IsInEvadeMode())
m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
CheckTeronTimer = 5000;
}else CheckTeronTimer -= diff;
}
};
struct MANGOS_DLL_DECL boss_teron_gorefiendAI : public ScriptedAI
{
boss_teron_gorefiendAI(Creature *c) : ScriptedAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
Reset();
}
ScriptedInstance* pInstance;
uint32 IncinerateTimer;
uint32 SummonDoomBlossomTimer;
uint32 EnrageTimer;
uint32 CrushingShadowsTimer;
uint32 ShadowOfDeathTimer;
uint32 SummonShadowsTimer;
uint32 RandomYellTimer;
uint32 AggroTimer;
uint64 AggroTargetGUID;
uint64 GhostGUID; // Player that gets killed by Shadow of Death and gets turned into a ghost
bool Intro;
void Reset()
{
if(pInstance)
pInstance->SetData(DATA_TERONGOREFIENDEVENT, NOT_STARTED);
IncinerateTimer = 20000 + rand()%11000;
SummonDoomBlossomTimer = 12000;
EnrageTimer = 600000;
CrushingShadowsTimer = 22000;
SummonShadowsTimer = 60000;
RandomYellTimer = 50000;
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
// Start off unattackable so that the intro is done properly
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
AggroTimer = 20000;
AggroTargetGUID = 0;
Intro = false;
}
void Aggro(Unit *who) {}
void MoveInLineOfSight(Unit *who)
{
if(!who || (!who->isAlive())) return;
if(who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))
{
float attackRadius = m_creature->GetAttackDistance(who);
if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))
{
if(who->HasStealthAura())
who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
m_creature->AddThreat(who, 1.0f);
}
if(!InCombat && !Intro && m_creature->IsWithinDistInMap(who, 200.0f) && (who->GetTypeId() == TYPEID_PLAYER))
{
if(pInstance)
pInstance->SetData(DATA_TERONGOREFIENDEVENT, IN_PROGRESS);
m_creature->GetMotionMaster()->Clear(false);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
DoYell(SAY_INTRO,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_INTRO);
m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_TALK);
AggroTargetGUID = who->GetGUID();
Intro = true;
}
}
}
void KilledUnit(Unit *victim)
{
switch(rand()%2)
{
case 0:
DoYell(SAY_SLAY1,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_SLAY1);
break;
case 1:
DoYell(SAY_SLAY2,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_SLAY2);
break;
}
}
void JustDied(Unit *victim)
{
if(pInstance)
pInstance->SetData(DATA_TERONGOREFIENDEVENT, DONE);
DoYell(SAY_DEATH,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature,SOUND_DEATH);
}
float CalculateRandomLocation(float Loc, uint32 radius)
{
float coord = Loc;
switch(rand()%2)
{
case 0:
coord += rand()%radius;
break;
case 1:
coord -= rand()%radius;
break;
}
return coord;
}
void SetThreatList(Creature* Blossom)
{
if(!Blossom) return;
std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
std::list<HostilReference*>::iterator i = m_threatlist.begin();
for(i = m_threatlist.begin(); i != m_threatlist.end(); i++)
{
Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());
if(pUnit && pUnit->isAlive())
{
float threat = m_creature->getThreatManager().getThreat(pUnit);
Blossom->AddThreat(pUnit, threat);
}
}
}
void MindControlGhost()
{
/************************************************************************/
/** NOTE FOR FUTURE DEVELOPER: PROPERLY IMPLEMENT THE GHOST PORTION *****/
/** ONLY AFTER MaNGOS FULLY IMPLEMENTS MIND CONTROL ABILITIES *****/
/** THE CURRENT CODE IN THIS FUNCTION IS ONLY THE BEGINNING OF *****/
/** WHAT IS FULLY NECESSARY FOR GOREFIEND TO BE 100% COMPLETE *****/
/************************************************************************/
Unit* Ghost = NULL;
if(GhostGUID)
Ghost = Unit::GetUnit((*m_creature), GhostGUID);
if(Ghost && Ghost->isAlive() && Ghost->HasAura(SPELL_SHADOW_OF_DEATH, 0))
{
/*float x,y,z;
Ghost->GetPosition(x,y,z);
Creature* control = m_creature->SummonCreature(CREATURE_GHOST, x, y, z, 0, TEMPSUMMON_TIMED_DESAWN, 30000);
if(control)
{
((Player*)Ghost)->Possess(control);
Ghost->DealDamage(Ghost, Ghost->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL,
false);
}*/
for(uint8 i = 0; i < 4; ++i)
{
Creature* Construct = NULL;
float X = CalculateRandomLocation(Ghost->GetPositionX(), 10);
float Y = CalculateRandomLocation(Ghost->GetPositionY(), 10);
Construct = m_creature->SummonCreature(CREATURE_SHADOWY_CONSTRUCT, X, Y, Ghost->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000);
if(Construct)
{
Construct->CastSpell(Construct, SPELL_PASSIVE_SHADOWFORM, true);
SetThreatList(Construct); // Use same function as Doom Blossom to set Threat List.
((mob_shadowy_constructAI*)Construct->AI())->GhostGUID = GhostGUID;
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
if(!target) // someone's trying to solo.
target = m_creature->getVictim();
if(target)
Construct->GetMotionMaster()->MoveChase(target);
}
}
}
}
void UpdateAI(const uint32 diff)
{
if(Intro)
{
if(AggroTimer < diff)
{
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
DoYell(SAY_AGGRO, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_AGGRO);
m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
Intro = false;
if(AggroTargetGUID)
{
Unit* pUnit = Unit::GetUnit((*m_creature), AggroTargetGUID);
if(pUnit)
{
m_creature->GetMotionMaster()->MoveChase(pUnit);
AttackStart(pUnit);
}
DoZoneInCombat();
}else EnterEvadeMode();
}else AggroTimer -= diff;
}
if(!m_creature->SelectHostilTarget() || !m_creature->getVictim() || Intro)
return;
if(SummonShadowsTimer < diff)
{
//MindControlGhost();
for(uint8 i = 0; i < 2; ++i)
{
Creature* Shadow = NULL;
float X = CalculateRandomLocation(m_creature->GetPositionX(), 10);
Shadow = m_creature->SummonCreature(CREATURE_SHADOWY_CONSTRUCT, X, m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 0);
if(Shadow)
{
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
if(!target)
target = m_creature->getVictim();
if(target)
Shadow->AI()->AttackStart(target);
}
}
SummonShadowsTimer = 60000;
}else SummonShadowsTimer -= diff;
if(SummonDoomBlossomTimer < diff)
{
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);
if(target)
{
float X = CalculateRandomLocation(target->GetPositionX(), 20);
float Y = CalculateRandomLocation(target->GetPositionY(), 20);
Creature* DoomBlossom = m_creature->SummonCreature(CREATURE_DOOM_BLOSSOM, X, Y, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000);
if(DoomBlossom)
{
DoomBlossom->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
DoomBlossom->setFaction(m_creature->getFaction());
DoomBlossom->AddThreat(target, 1.0f);
((mob_doom_blossomAI*)DoomBlossom->AI())->SetTeronGUID(m_creature->GetGUID());
((mob_doom_blossomAI*)DoomBlossom->AI())->InCombat = true;
SetThreatList(DoomBlossom);
SummonDoomBlossomTimer = 35000;
}
}
}else SummonDoomBlossomTimer -= diff;
if(IncinerateTimer < diff)
{
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
if(!target)
target = m_creature->getVictim();
if(target)
{
switch(rand()%2)
{
case 0:
DoYell(SAY_SPECIAL1,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_SPECIAL1);
break;
case 1:
DoYell(SAY_SPECIAL2,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_SPECIAL2);
break;
}
DoCast(target, SPELL_INCINERATE);
IncinerateTimer = 20000 + rand()%31 * 1000;
}
}else IncinerateTimer -= diff;
if(CrushingShadowsTimer < diff)
{
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);
if(target && target->isAlive())
DoCast(target, SPELL_CRUSHING_SHADOWS);
CrushingShadowsTimer = 10000 + rand()%16 * 1000;
}else CrushingShadowsTimer -= diff;
/*** NOTE FOR FUTURE DEV: UNCOMMENT BELOW ONLY IF MIND CONTROL IS FULLY IMPLEMENTED **/
/*if(ShadowOfDeathTimer < diff)
{
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
if(!target)
target = m_creature->getVictim();
if(target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER)
{
DoCast(target, SPELL_SHADOW_OF_DEATH);
GhostGUID = target->GetGUID();
ShadowOfDeathTimer = 30000;
SummonShadowsTimer = 53000; // Make it VERY close but slightly less so that we can check if the aura is still on the player
}
}else ShadowOfDeathTimer -= diff;*/
if(RandomYellTimer < diff)
{
switch(rand()%2)
{
case 0:
DoYell(SAY_SPELL1,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_SPELL1);
break;
case 1:
DoYell(SAY_SPELL2,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_SPELL2);
break;
}
RandomYellTimer = 50000 + rand()%51 * 1000;
}else RandomYellTimer -= diff;
if(!m_creature->HasAura(SPELL_BERSERK, 0))
if(EnrageTimer < diff)
{
DoCast(m_creature, SPELL_BERSERK);
DoYell(SAY_ENRAGE,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_ENRAGE);
}else EnrageTimer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_doom_blossom(Creature *_Creature)
{
return new mob_doom_blossomAI(_Creature);
}
CreatureAI* GetAI_mob_shadowy_construct(Creature *_Creature)
{
return new mob_shadowy_constructAI(_Creature);
}
CreatureAI* GetAI_boss_teron_gorefiend(Creature *_Creature)
{
return new boss_teron_gorefiendAI (_Creature);
}
void AddSC_boss_teron_gorefiend()
{
Script *newscript;
newscript = new Script;
newscript->Name = "mob_doom_blossom";
newscript->GetAI = GetAI_mob_doom_blossom;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name = "mob_shadowy_construct";
newscript->GetAI = GetAI_mob_shadowy_construct;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="boss_teron_gorefiend";
newscript->GetAI = GetAI_boss_teron_gorefiend;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,435 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Warlord_Najentus
SD%Complete: 90
SDComment: Using a creature workaround instead of a GO for Impaling Spine.
SDCategory: Black Temple
EndScriptData */
#include "precompiled.h"
#include "def_black_temple.h"
//Aggro
#define SAY_AGGRO "You will die, in the name of Lady Vashj!"
#define SOUND_AGGRO 11450
//Needle (Random)
#define SAY_NEEDLE1 "Stick around!"
#define SOUND_NEEDLE1 11451
#define SAY_NEEDLE2 "I'll deal with you later!"
#define SOUND_NEEDLE2 11452
//Slay
#define SAY_SLAY1 "Your success was short lived!"
#define SOUND_SLAY1 11455
#define SAY_SLAY2 "Time for you to go!"
#define SOUND_SLAY2 11456
//Special
#define SAY_SPECIAL1 "Bel'anen dal'lorei!"
#define SOUND_SPECIAL1 11453
#define SAY_SPECIAL2 "Blood will flow!"
#define SOUND_SPECIAL2 11454
//Enrage
#define SAY_ENRAGE "My patience has ran out! Die, DIE!"
#define SOUND_ENRAGE 11458
//Death
#define SAY_DEATH "Lord Illidan will... crush you."
#define SOUND_DEATH 11459
//Spells
#define SPELL_CRASHINGWAVE 40100
#define SPELL_NEEDLE_SPINE 39835
#define SPELL_NEEDLE_AOE 39968
#define SPELL_TIDAL_BURST 39878
#define SPELL_TIDAL_SHIELD 39872 // Not going to use this since Hurl Spine doesn't dispel it.
#define SPELL_IMPALING_SPINE 39837
#define SPELL_CREATE_NAJENTUS_SPINE 39956
#define SPELL_HURL_SPINE 39948
#define SPELL_SHIELD_VISUAL 37136
#define SPELL_BERSERK 45078
#define DISPLAYID_SPINE 7362
struct MANGOS_DLL_DECL mob_najentus_spineAI : public ScriptedAI
{
mob_najentus_spineAI(Creature *c) : ScriptedAI(c)
{
Reset();
}
uint64 SpineVictimGUID;
void Reset() { SpineVictimGUID = 0; }
void SetSpineVictimGUID(uint64 guid){ SpineVictimGUID = guid; }
void JustDied(Unit *killer)
{
// Make the killer have the Najentus Spine item to pierce Tidal Shield
if(killer)
killer->CastSpell(killer, SPELL_CREATE_NAJENTUS_SPINE, true);
}
void DamageTaken(Unit *done_by, uint32 &damage)
{
if(damage < m_creature->GetHealth()) return;
// Remove the Impaling Spine DoT from whoever was affected
if(SpineVictimGUID)
{
Unit* victim = Unit::GetUnit((*m_creature), SpineVictimGUID);
if(victim && ((victim->HasAura(SPELL_IMPALING_SPINE, 0)) || (victim->HasAura(SPELL_IMPALING_SPINE, 1)) || (victim->HasAura(SPELL_IMPALING_SPINE, 2))))
victim->RemoveAurasDueToSpell(SPELL_IMPALING_SPINE);
}
}
void Aggro(Unit* who) {}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff) {}
};
struct MANGOS_DLL_DECL boss_najentusAI : public ScriptedAI
{
boss_najentusAI(Creature *c) : ScriptedAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
Reset();
}
ScriptedInstance* pInstance;
uint32 CrashingWaveTimer;
uint32 NeedleSpineTimer;
uint32 EnrageTimer;
uint32 SpecialYellTimer;
uint32 TidalShieldTimer;
uint32 ImpalingSpineTimer;
uint32 CheckTimer; // This timer checks if Najentus is Tidal Shielded and if so, regens health. If not, sets IsShielded to false
uint32 DispelShieldTimer; // This shield is only supposed to last 30 seconds, but the SPELL_SHIELD_VISUAL lasts forever
uint64 SpineTargetGUID;
uint64 SpineGUID;
bool IsShielded;
void Reset()
{
IsShielded = false;
CrashingWaveTimer = 28000;
NeedleSpineTimer = 10000;
EnrageTimer = 480000;
SpecialYellTimer = 45000 + (rand()%76)*1000;
TidalShieldTimer = 60000;
ImpalingSpineTimer = 45000;
CheckTimer = 2000;
DispelShieldTimer = 30000;
SpineTargetGUID = 0;
SpineGUID = 0;
if(pInstance)
{
if(m_creature->isAlive())
{
pInstance->SetData(DATA_HIGHWARLORDNAJENTUSEVENT, NOT_STARTED);
ToggleGate(true);
}
else ToggleGate(false);
}
}
void KilledUnit(Unit *victim)
{
switch(rand()%2)
{
case 0:
DoYell(SAY_SLAY1,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_SLAY1);
break;
case 1:
DoYell(SAY_SLAY2,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_SLAY2);
break;
}
}
void JustDied(Unit *victim)
{
if(pInstance)
{
pInstance->SetData(DATA_HIGHWARLORDNAJENTUSEVENT, DONE);
ToggleGate(false);
}
DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_DEATH);
}
void ToggleGate(bool close)
{
if(GameObject* Gate = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_GAMEOBJECT_NAJENTUS_GATE)))
if(close) Gate->SetGoState(0); // Closed
else Gate->SetGoState(2); // Opened
}
void SpellHit(Unit *caster, const SpellEntry *spell)
{
if(IsShielded)
{
if(spell->Id == SPELL_HURL_SPINE)
{
if(m_creature->HasAura(SPELL_SHIELD_VISUAL, 0))
m_creature->RemoveAurasDueToSpell(SPELL_SHIELD_VISUAL);
if(m_creature->HasAura(SPELL_TIDAL_SHIELD, 0))
m_creature->RemoveAurasDueToSpell(SPELL_TIDAL_SHIELD);
DoCast(m_creature->getVictim(), SPELL_TIDAL_BURST);
IsShielded = false;
}
}
}
void DamageTaken(Unit *done_by, uint32 &damage)
{
if(IsShielded)
damage = 0;
}
void Aggro(Unit *who)
{
if(pInstance)
pInstance->SetData(DATA_HIGHWARLORDNAJENTUSEVENT, IN_PROGRESS);
DoYell(SAY_AGGRO, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_AGGRO);
DoZoneInCombat();
}
// This is a workaround since we cannot summon GameObjects at will.
// Instead, we create a custom creature on top of the player.
// When someone kills the creature, the killer gets the "Naj'entus Spine" item.
// This item is the only item that should be able to pierce Tidal Shield
void DoImpalingSpineWorkaround(Unit* target)
{
Creature* Spine = NULL;
Spine = m_creature->SummonCreature(500000, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_DEAD_DESPAWN, 10000);
if(Spine)
{
Spine->setFaction(m_creature->getFaction());
((mob_najentus_spineAI*)Spine->AI())->SetSpineVictimGUID(target->GetGUID());
SpineTargetGUID = target->GetGUID();
}
}
bool RemoveImpalingSpine(uint64 guid)
{
if(!IsShielded || guid == SpineTargetGUID) return false;
if(SpineTargetGUID)
{
Unit* target = Unit::GetUnit((*m_creature), SpineTargetGUID);
if(target && target->HasAura(SPELL_IMPALING_SPINE, 0))
{
target->RemoveAurasDueToSpell(SPELL_IMPALING_SPINE);
return true;
}
}
return false;
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if(CheckTimer < diff)
{
// if(m_creature->HasAura(SPELL_TIDAL_SHIELD, 0))
if(m_creature->HasAura(SPELL_SHIELD_VISUAL, 0))
m_creature->SetHealth(m_creature->GetHealth() + (m_creature->GetMaxHealth()/100));
else
IsShielded = false;
CheckTimer = 2000;
}else CheckTimer -= diff;
if(IsShielded)
{
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveIdle();
if(!m_creature->HasAura(SPELL_SHIELD_VISUAL, 0))
DoCast(m_creature, SPELL_SHIELD_VISUAL);
if(DispelShieldTimer < diff)
{
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
if(m_creature->HasAura(SPELL_SHIELD_VISUAL, 0))
m_creature->RemoveAurasDueToSpell(SPELL_SHIELD_VISUAL);
IsShielded = false;
}else DispelShieldTimer -= diff;
return; // Don't cast or do anything while Shielded
}
// Crashing Wave
if(CrashingWaveTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_CRASHINGWAVE);
CrashingWaveTimer = 28500;
}else CrashingWaveTimer -= diff;
if(!m_creature->HasAura(SPELL_BERSERK, 0))
if(EnrageTimer < diff)
{
DoYell(SAY_ENRAGE, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_ENRAGE);
DoCast(m_creature, SPELL_BERSERK);
}else EnrageTimer -= diff;
// Needle
if(NeedleSpineTimer < diff)
{
for(uint8 i = 0; i < 3; ++i)
{
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
if(!target)
target = m_creature->getVictim();
DoCast(target, SPELL_NEEDLE_AOE, true);
DoCast(target, SPELL_NEEDLE_SPINE);
}
NeedleSpineTimer = 60000;
}else NeedleSpineTimer -= diff;
if(SpecialYellTimer < diff)
{
switch(rand()%2)
{
case 0:
DoPlaySoundToSet(m_creature, SOUND_SPECIAL1);
break;
case 1:
DoYell(SAY_SPECIAL2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_SPECIAL2);
break;
}
SpecialYellTimer = 25000 + (rand()%76)*1000;
}else SpecialYellTimer -= diff;
if(ImpalingSpineTimer < diff)
{
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
if(!target)
target = m_creature->getVictim();
if(target && (target->GetTypeId() == TYPEID_PLAYER))
{
DoCast(target, SPELL_IMPALING_SPINE);
//DoImpalingSpineWorkaround(target);
SpineTargetGUID = target->GetGUID();
ImpalingSpineTimer = 45000;
switch(rand()%2)
{
case 0:
DoYell(SAY_NEEDLE1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_NEEDLE1);
break;
case 1:
DoYell(SAY_NEEDLE2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_NEEDLE2);
break;
}
}
}else ImpalingSpineTimer -= diff;
if(TidalShieldTimer < diff)
{
m_creature->InterruptNonMeleeSpells(false);
DoCast(m_creature, SPELL_SHIELD_VISUAL, true);
// DoCast(m_creature, SPELL_TIDAL_SHIELD);
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveIdle();
IsShielded = true;
TidalShieldTimer = 60000;
CheckTimer = 2000;
DispelShieldTimer = 30000;
}else TidalShieldTimer -= diff;
DoMeleeAttackIfReady();
}
};
bool GOHello_go_najentus_spine(Player *player, GameObject* _GO)
{
ScriptedInstance* pInstance = ((ScriptedInstance*)_GO->GetInstanceData());
if(pInstance)
{
uint64 NajentusGUID = pInstance->GetData64(DATA_HIGHWARLORDNAJENTUS);
if(NajentusGUID)
{
Creature* Najentus = ((Creature*)Unit::GetUnit((*_GO), NajentusGUID));
if(Najentus)
{
if(((boss_najentusAI*)Najentus->AI())->RemoveImpalingSpine(player->GetGUID()))
return true;
}else error_log("ERROR: Na'entus Spine GameObject unable to find Naj'entus");
}else error_log("ERROR: Invalid GUID acquired for Naj'entus by Naj'entus Spine GameObject");
}
else error_log("ERROR: Naj'entus Spine spawned in invalid instance or location");
return true;
}
CreatureAI* GetAI_mob_najentus_spine(Creature *_Creature)
{
return new mob_najentus_spineAI (_Creature);
}
CreatureAI* GetAI_boss_najentus(Creature *_Creature)
{
return new boss_najentusAI (_Creature);
}
void AddSC_boss_najentus()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_najentus";
newscript->GetAI = GetAI_boss_najentus;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name = "mob_najentus_spine";
newscript->GetAI = GetAI_mob_najentus_spine;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name = "go_najentus_spine";
newscript->pGOHello = &GOHello_go_najentus_spine;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,34 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef DEF_BLACK_TEMPLE_H
#define DEF_BLACK_TEMPLE_H
#define DATA_AKAMA 1
#define DATA_AKAMA_SHADE 2
#define DATA_GURTOGGBLOODBOILEVENT 3
#define DATA_HIGHWARLORDNAJENTUS 4
#define DATA_HIGHWARLORDNAJENTUSEVENT 5
#define DATA_ILLIDANSTORMRAGE 6
#define DATA_ILLIDANSTORMRAGEEVENT 7
#define DATA_ILLIDARICOUNCILEVENT 8
#define DATA_ILLIDARICOUNCIL 9
#define DATA_LADYMALANDE 10
#define DATA_HIGHNETHERMANCERZEREVOR 11
#define DATA_GATHIOSTHESHATTERER 12
#define DATA_VERASDARKSHADOW 13
#define DATA_MOTHERSHAHRAZEVENT 14
#define DATA_RELIQUARYOFSOULSEVENT 15
#define DATA_SHADEOFAKAMA 16
#define DATA_SHADEOFAKAMAEVENT 17
#define DATA_SUPREMUS 18
#define DATA_SUPREMUSEVENT 19
#define DATA_TERONGOREFIENDEVENT 20
#define DATA_GAMEOBJECT_NAJENTUS_GATE 21
#define DATA_GAMEOBJECT_ILLIDAN_GATE 22
#define DATA_GAMEOBJECT_ILLIDAN_DOOR_R 23
#define DATA_GAMEOBJECT_ILLIDAN_DOOR_L 24
#define DATA_GAMEOBJECT_SUPREMUS_DOORS 25
#define DATA_BLOOD_ELF_COUNCIL_VOICE 26
#endif
@@ -0,0 +1,885 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Illidari_Council
SD%Complete: 95
SDComment: Circle of Healing not working properly.
SDCategory: Black Temple
EndScriptData */
#include "precompiled.h"
#include "def_black_temple.h"
// High Nethermancer Zerevor's spells
#define SPELL_FLAMESTRIKE 41481
#define SPELL_BLIZZARD 41482
#define SPELL_ARCANE_BOLT 41483
#define SPELL_ARCANE_EXPLOSION 41524
#define SPELL_DAMPEN_MAGIC 41478
// Lady Malande's spells
#define SPELL_EMPOWERED_SMITE 41471
#define SPELL_CIRCLE_OF_HEALING 41455
#define SPELL_REFLECTIVE_SHIELD 41475
#define SPELL_DIVINE_WRATH 41472
#define SPELL_HEAL_VISUAL 24171
// Gathios the Shatterer's spells
#define SPELL_BLESS_PROTECTION 41450
#define SPELL_BLESS_SPELLWARD 41451
#define SPELL_CONSECRATION 41541
#define SPELL_HAMMER_OF_JUSTICE 41468
#define SPELL_SEAL_OF_COMMAND 41469
#define SPELL_SEAL_OF_BLOOD 41459
#define SPELL_CHROMATIC_AURA 41453
#define SPELL_DEVOTION_AURA 41452
// Veras Darkshadow's spells
#define SPELL_DEADLY_POISON 41485
#define SPELL_ENVENOM 41487
#define SPELL_VANISH 41479
#define SPELL_BERSERK 45078
//Speech'n'Sounds
#define SAY_GATH_AGGRO "I have better things to do!"
#define SOUND_GATH_AGGRO 11422
#define SAY_GATH_SLAY "Selama am'oronor!"
#define SOUND_GATH_SLAY 11423
#define SAY_GATH_COMNT "Well done!"
#define SOUND_GATH_COMNT 11424
#define SAY_GATH_DEATH "Lord Illidan... I..."
#define SOUND_GATH_DEATH 11425
#define SAY_GATH_SPECIAL1 "Enjoy your final moments!"
#define SOUND_GATH_SPECIAL1 11426
#define SAY_GATH_SPECIAL2 "You are mine!"
#define SOUND_GATH_SPECIAL2 11427
#define SAY_MALA_AGGRO "Flee, or die!"
#define SOUND_MALA_AGGRO 11482
#define SAY_MALA_SLAY "My work is done."
#define SOUND_MALA_SLAY 11483
#define SAY_MALA_COMNT "As it should be!"
#define SOUND_MALA_COMNT 11484
#define SAY_MALA_DEATH "Destiny... awaits."
#define SOUND_MALA_DEATH 11485
#define SAY_MALA_SPECIAL1 "No second chances!"
#define SOUND_MALA_SPECIAL1 11486
#define SAY_MALA_SPECIAL2 "I'm full of surprises!"
#define SOUND_MALA_SPECIAL2 11487
#define SAY_ZERE_AGGRO "Common... such a crude language. Bandal!"
#define SOUND_ZERE_AGGRO 11440
#define SAY_ZERE_SLAY "Shorel'aran."
#define SOUND_ZERE_SLAY 11441
#define SAY_ZERE_COMNT "Belesa menoor!"
#define SOUND_ZERE_COMNT 11442
#define SAY_ZERE_DEATH "Diel ma'ahn... oreindel'o"
#define SOUND_ZERE_DEATH 11443
#define SAY_ZERE_SPECIAL1 "Diel fin'al"
#define SOUND_ZERE_SPECIAL1 11444
#define SAY_ZERE_SPECIAL2 "Sha'amoor ara mashal?"
#define SOUND_ZERE_SPECIAL2 11445
#define SAY_VERA_AGGRO "You wish to test me?"
#define SOUND_VERA_AGGRO 11524
#define SAY_VERA_SLAY "Valiant effort!"
#define SOUND_VERA_SLAY 11525
#define SAY_VERA_COMNT "A glorious kill!"
#define SOUND_VERA_COMNT 11526
#define SAY_VERA_DEATH "You got lucky!"
#define SOUND_VERA_DEATH 11527
#define SAY_VERA_SPECIAL1 "You're not caught up for this!"
#define SOUND_VERA_SPECIAL1 11528
#define SAY_VERA_SPECIAL2 "Anar'alah belore!"
#define SOUND_VERA_SPECIAL2 11529
#define ERROR_INST_DATA "SD2 ERROR: Instance Data for Black Temple not set properly; Illidari Council event will not function properly."
struct CouncilYells
{
char* text;
uint32 soundId, timer;
};
static CouncilYells CouncilAggro[]=
{
{"I have better things to do!", 11422, 5000}, // Gathios
{"You wish to test me?", 11524, 5500}, // Veras
{"Flee, or die!", 11482, 5000}, // Malande
{"Common... such a crude language. Bandal!", 11440, 0}, // Zerevor
};
// Need to get proper timers for this later
static CouncilYells CouncilEnrage[]=
{
{"Enough games!", 11428, 2000}, // Gathios
{"You wish to kill me? Hahaha, you first!", 11530, 6000},//Veras
{"For Quel'Thalas! For the Sunwell!", 11488, 5000}, // Malande
{"Sha'amoor sine menoor!", 11446, 0}, // Zerevor
};
struct MANGOS_DLL_DECL mob_blood_elf_council_voice_triggerAI : public ScriptedAI
{
mob_blood_elf_council_voice_triggerAI(Creature* c) : ScriptedAI(c)
{
for(uint8 i = 0; i < 4; ++i)
Council[i] = 0;
Reset();
}
uint64 Council[4];
uint32 EnrageTimer;
uint32 AggroYellTimer;
uint8 YellCounter; // Serves as the counter for both the aggro and enrage yells
bool EventStarted;
void Reset()
{
EnrageTimer = 900000; // 15 minutes
AggroYellTimer = 500;
YellCounter = 0;
EventStarted = false;
}
// finds and stores the GUIDs for each Council member using instance data system.
void LoadCouncilGUIDs()
{
if(ScriptedInstance* pInstance = ((ScriptedInstance*)m_creature->GetInstanceData()))
{
Council[0] = pInstance->GetData64(DATA_GATHIOSTHESHATTERER);
Council[1] = pInstance->GetData64(DATA_VERASDARKSHADOW);
Council[2] = pInstance->GetData64(DATA_LADYMALANDE);
Council[3] = pInstance->GetData64(DATA_HIGHNETHERMANCERZEREVOR);
}
else error_log(ERROR_INST_DATA);
}
void Aggro(Unit* who) {}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void UpdateAI(const uint32 diff)
{
if(!EventStarted)
return;
if(YellCounter > 3)
return;
if(AggroYellTimer)
if(AggroYellTimer <= diff)
{
if(Unit* pMember = Unit::GetUnit(*m_creature, Council[YellCounter]))
{
pMember->MonsterYell(CouncilAggro[YellCounter].text, LANG_UNIVERSAL, 0);
DoPlaySoundToSet(pMember, CouncilAggro[YellCounter].soundId);
AggroYellTimer = CouncilAggro[YellCounter].timer;
}
++YellCounter;
if(YellCounter > 3)
YellCounter = 0; // Reuse for Enrage Yells
}else AggroYellTimer -= diff;
if(EnrageTimer)
if(EnrageTimer <= diff)
{
if(Unit* pMember = Unit::GetUnit(*m_creature, Council[YellCounter]))
{
pMember->CastSpell(pMember, SPELL_BERSERK, true);
pMember->MonsterYell(CouncilEnrage[YellCounter].text, LANG_UNIVERSAL, 0);
DoPlaySoundToSet(pMember, CouncilEnrage[YellCounter].soundId);
EnrageTimer = CouncilEnrage[YellCounter].timer;
}
++YellCounter;
}else EnrageTimer -= diff;
}
};
struct MANGOS_DLL_DECL mob_illidari_councilAI : public ScriptedAI
{
mob_illidari_councilAI(Creature *c) : ScriptedAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
for(uint8 i = 0; i < 4; ++i)
Council[i] = 0;
Reset();
}
ScriptedInstance* pInstance;
uint64 Council[4];
uint32 CheckTimer;
uint32 EndEventTimer;
uint8 DeathCount;
bool EventBegun;
void Reset()
{
CheckTimer = 2000;
EndEventTimer = 0;
DeathCount = 0;
Creature* pMember = NULL;
for(uint8 i = 0; i < 4; ++i)
{
if(pMember = ((Creature*)Unit::GetUnit((*m_creature), Council[i])))
{
if(!pMember->isAlive())
{
pMember->RemoveCorpse();
pMember->Respawn();
}
pMember->AI()->EnterEvadeMode();
}
}
if(pInstance)
{
pInstance->SetData(DATA_ILLIDARICOUNCILEVENT, NOT_STARTED);
if(Creature* VoiceTrigger = ((Creature*)Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_BLOOD_ELF_COUNCIL_VOICE))))
VoiceTrigger->AI()->EnterEvadeMode();
}
EventBegun = false;
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686);
}
void Aggro(Unit *who) {}
void AttackStart(Unit* who) {}
void MoveInLineOfSight(Unit* who) {}
void StartEvent(Unit *target)
{
if(!pInstance) return;
if(target && target->isAlive())
{
Council[0] = pInstance->GetData64(DATA_GATHIOSTHESHATTERER);
Council[1] = pInstance->GetData64(DATA_HIGHNETHERMANCERZEREVOR);
Council[2] = pInstance->GetData64(DATA_LADYMALANDE);
Council[3] = pInstance->GetData64(DATA_VERASDARKSHADOW);
// Start the event for the Voice Trigger
if(Creature* VoiceTrigger = ((Creature*)Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_BLOOD_ELF_COUNCIL_VOICE))))
{
((mob_blood_elf_council_voice_triggerAI*)VoiceTrigger->AI())->LoadCouncilGUIDs();
((mob_blood_elf_council_voice_triggerAI*)VoiceTrigger->AI())->EventStarted = true;
}
for(uint8 i = 0; i < 4; ++i)
{
Unit* Member = NULL;
if(Council[i])
{
Member = Unit::GetUnit((*m_creature), Council[i]);
if(Member && Member->isAlive())
Member->AddThreat(target, 1.0f);
}
}
pInstance->SetData(DATA_ILLIDARICOUNCILEVENT, IN_PROGRESS);
EventBegun = true;
}
}
void UpdateAI(const uint32 diff)
{
if(!EventBegun) return;
if(EndEventTimer)
if(EndEventTimer <= diff)
{
if(DeathCount > 3)
{
if(pInstance)
{
if(Creature* VoiceTrigger = ((Creature*)Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_BLOOD_ELF_COUNCIL_VOICE))))
VoiceTrigger->DealDamage(VoiceTrigger, VoiceTrigger->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
pInstance->SetData(DATA_ILLIDARICOUNCILEVENT, DONE);
}
m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
return;
}
Creature* pMember = ((Creature*)Unit::GetUnit(*m_creature, Council[DeathCount]));
if(pMember && pMember->isAlive())
pMember->DealDamage(pMember, pMember->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
++DeathCount;
EndEventTimer = 1500;
}else EndEventTimer -= diff;
if(CheckTimer)
if(CheckTimer <= diff)
{
uint8 EvadeCheck = 0;
for(uint8 i = 0; i < 4; ++i)
{
if(Council[i])
{
if(Creature* Member = ((Creature*)Unit::GetUnit((*m_creature), Council[i])))
{
// This is the evade/death check.
if(Member->isAlive() && !Member->SelectHostilTarget())
++EvadeCheck; //If all members evade, we reset so that players can properly reset the event
else if(!Member->isAlive()) // If even one member dies, kill the rest, set instance data, and kill self.
{
EndEventTimer = 1000;
CheckTimer = 0;
return;
}
}
}
}
if(EvadeCheck > 3)
Reset();
CheckTimer = 2000;
}else CheckTimer -= diff;
}
};
struct MANGOS_DLL_DECL boss_illidari_councilAI : public ScriptedAI
{
boss_illidari_councilAI(Creature* c) : ScriptedAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
for(uint8 i = 0; i < 4; ++i)
Council[i] = 0;
LoadedGUIDs = false;
}
uint64 Council[4];
ScriptedInstance* pInstance;
bool LoadedGUIDs;
void Aggro(Unit* who)
{
if(pInstance)
{
Creature* Controller = ((Creature*)Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_ILLIDARICOUNCIL)));
if(Controller)
((mob_illidari_councilAI*)Controller->AI())->StartEvent(who);
}
else
{
error_log(ERROR_INST_DATA);
EnterEvadeMode();
}
DoZoneInCombat();
// Load GUIDs on first aggro because the creature guids are only set as the creatures are created in world-
// this means that for each creature, it will attempt to LoadGUIDs even though some of the other creatures are
// not in world, and thus have no GUID set in the instance data system. Putting it in aggro ensures that all the creatures
// have been loaded and have their GUIDs set in the instance data system.
if(!LoadedGUIDs)
LoadGUIDs();
}
void DamageTaken(Unit* done_by, uint32 &damage)
{
if(done_by == m_creature)
return;
damage /= 4;
for(uint8 i = 0; i < 4; ++i)
{
if(Unit* pUnit = Unit::GetUnit(*m_creature, Council[i]))
if(pUnit != m_creature && damage < pUnit->GetHealth())
pUnit->SetHealth(pUnit->GetHealth() - damage);
}
}
void LoadGUIDs()
{
if(!pInstance)
{
error_log(ERROR_INST_DATA);
return;
}
Council[0] = pInstance->GetData64(DATA_LADYMALANDE);
Council[1] = pInstance->GetData64(DATA_HIGHNETHERMANCERZEREVOR);
Council[2] = pInstance->GetData64(DATA_GATHIOSTHESHATTERER);
Council[3] = pInstance->GetData64(DATA_VERASDARKSHADOW);
LoadedGUIDs = true;
}
};
struct MANGOS_DLL_DECL boss_gathios_the_shattererAI : public boss_illidari_councilAI
{
boss_gathios_the_shattererAI(Creature *c) : boss_illidari_councilAI(c) { Reset(); }
uint32 ConsecrationTimer;
uint32 HammerOfJusticeTimer;
uint32 SealTimer;
uint32 AuraTimer;
uint32 BlessingTimer;
void Reset()
{
ConsecrationTimer = 40000;
HammerOfJusticeTimer = 10000;
SealTimer = 40000;
AuraTimer = 90000;
BlessingTimer = 60000;
}
void KilledUnit(Unit *victim)
{
DoYell(SAY_GATH_SLAY,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_GATH_SLAY);
}
void JustDied(Unit *victim)
{
DoYell(SAY_GATH_DEATH, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_GATH_DEATH);
}
Unit* SelectCouncilMember()
{
Unit* pUnit = m_creature;
uint32 member = 0; // He chooses Lady Malande most often
if(rand()%10 == 0) // But there is a chance he picks someone else.
member = urand(1, 3);
if(member != 2) // No need to create another pointer to us using Unit::GetUnit
pUnit = Unit::GetUnit((*m_creature), Council[member]);
return pUnit;
}
void CastAuraOnCouncil()
{
uint32 spellid = 0;
switch(rand()%2)
{
case 0: spellid = SPELL_DEVOTION_AURA; break;
case 1: spellid = SPELL_CHROMATIC_AURA; break;
}
for(uint8 i = 0; i < 4; ++i)
{
Unit* pUnit = Unit::GetUnit((*m_creature), Council[i]);
if(pUnit)
pUnit->CastSpell(pUnit, spellid, true, 0, 0, m_creature->GetGUID());
}
}
void UpdateAI(const uint32 diff)
{
if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if(BlessingTimer < diff)
{
if(Unit* pUnit = SelectCouncilMember())
{
switch(rand()%2)
{
case 0: DoCast(pUnit, SPELL_BLESS_SPELLWARD); break;
case 1: DoCast(pUnit, SPELL_BLESS_PROTECTION); break;
}
}
BlessingTimer = 60000;
}else BlessingTimer -= diff;
if(ConsecrationTimer < diff)
{
DoCast(m_creature, SPELL_CONSECRATION);
ConsecrationTimer = 40000;
}else ConsecrationTimer -= diff;
if(HammerOfJusticeTimer < diff)
{
if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
{
// is in ~10-40 yd range
if(m_creature->GetDistance2d(target) > 10 && m_creature->GetDistance2d(target) < 40)
{
DoCast(target, SPELL_HAMMER_OF_JUSTICE);
HammerOfJusticeTimer = 20000;
}
}
}else HammerOfJusticeTimer -= diff;
if(SealTimer < diff)
{
switch(rand()%2)
{
case 0: DoCast(m_creature, SPELL_SEAL_OF_COMMAND); break;
case 1: DoCast(m_creature, SPELL_SEAL_OF_BLOOD); break;
}
SealTimer = 40000;
}else SealTimer -= diff;
if(AuraTimer < diff)
{
CastAuraOnCouncil();
AuraTimer = 90000;
}else AuraTimer -= diff;
DoMeleeAttackIfReady();
}
};
struct MANGOS_DLL_DECL boss_high_nethermancer_zerevorAI : public boss_illidari_councilAI
{
boss_high_nethermancer_zerevorAI(Creature *c) : boss_illidari_councilAI(c) { Reset(); }
uint32 BlizzardTimer;
uint32 FlamestrikeTimer;
uint32 ArcaneBoltTimer;
uint32 DampenMagicTimer;
uint32 Cooldown;
uint32 ArcaneExplosionTimer;
void Reset()
{
BlizzardTimer = 30000 + rand()%61 * 1000;
FlamestrikeTimer = 30000 + rand()%61 * 1000;
ArcaneBoltTimer = 10000;
DampenMagicTimer = 2000;
ArcaneExplosionTimer = 14000;
Cooldown = 0;
}
void KilledUnit(Unit *victim)
{
DoYell(SAY_ZERE_SLAY,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_ZERE_SLAY);
}
void JustDied(Unit *victim)
{
DoYell(SAY_ZERE_DEATH, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_ZERE_DEATH);
}
void UpdateAI(const uint32 diff)
{
if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if(Cooldown)
{
if(Cooldown < diff) Cooldown = 0;
else
{
Cooldown -= diff;
return; // Don't cast any other spells if global cooldown is still ticking
}
}
if(DampenMagicTimer < diff)
{
DoCast(m_creature, SPELL_DAMPEN_MAGIC);
Cooldown = 1000;
DampenMagicTimer = 110000; // almost 2 minutes
ArcaneBoltTimer += 1000; // Give the Mage some time to spellsteal Dampen.
}else DampenMagicTimer -= diff;
if(ArcaneExplosionTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_ARCANE_EXPLOSION);
Cooldown = 1000;
ArcaneExplosionTimer = 14000;
}else ArcaneExplosionTimer -= diff;
if(ArcaneBoltTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_ARCANE_BOLT);
ArcaneBoltTimer = 3000;
Cooldown = 2000;
}else ArcaneBoltTimer -= diff;
if(BlizzardTimer < diff)
{
if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
{
DoCast(target, SPELL_BLIZZARD);
BlizzardTimer = 45000 + rand()%46 * 1000;
FlamestrikeTimer += 10000;
Cooldown = 1000;
}
}else BlizzardTimer -= diff;
if(FlamestrikeTimer < diff)
{
if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
{
DoCast(target, SPELL_FLAMESTRIKE);
FlamestrikeTimer = 55000 + rand()%46 * 1000;
BlizzardTimer += 10000;
Cooldown = 2000;
}
}else FlamestrikeTimer -= diff;
}
};
struct MANGOS_DLL_DECL boss_lady_malandeAI : public boss_illidari_councilAI
{
boss_lady_malandeAI(Creature *c) : boss_illidari_councilAI(c) { Reset(); }
uint32 EmpoweredSmiteTimer;
uint32 CircleOfHealingTimer;
uint32 DivineWrathTimer;
uint32 ReflectiveShieldTimer;
void Reset()
{
EmpoweredSmiteTimer = 38000;
CircleOfHealingTimer = 20000;
DivineWrathTimer = 40000;
ReflectiveShieldTimer = 0;
}
void KilledUnit(Unit *victim)
{
DoYell(SAY_MALA_SLAY,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_MALA_SLAY);
}
void JustDied(Unit *victim)
{
DoYell(SAY_MALA_DEATH, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_MALA_DEATH);
}
void UpdateAI(const uint32 diff)
{
if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if(EmpoweredSmiteTimer < diff)
{
if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
{
DoCast(target, SPELL_EMPOWERED_SMITE);
EmpoweredSmiteTimer = 38000;
}
}else EmpoweredSmiteTimer -= diff;
if(CircleOfHealingTimer < diff)
{
//Currently bugged and puts Malande on the threatlist of the other council members. It also heals players.
//DoCast(m_creature, SPELL_CIRCLE_OF_HEALING);
CircleOfHealingTimer = 60000;
}else CircleOfHealingTimer -= diff;
if(DivineWrathTimer < diff)
{
if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
{
DoCast(target, SPELL_DIVINE_WRATH);
DivineWrathTimer = 40000 + rand()%41 * 1000;
}
}else DivineWrathTimer -= diff;
if(ReflectiveShieldTimer < diff)
{
DoCast(m_creature, SPELL_REFLECTIVE_SHIELD);
ReflectiveShieldTimer = 65000;
}else ReflectiveShieldTimer -= diff;
DoMeleeAttackIfReady();
}
};
struct MANGOS_DLL_DECL boss_veras_darkshadowAI : public boss_illidari_councilAI
{
boss_veras_darkshadowAI(Creature *c) : boss_illidari_councilAI(c) { Reset(); }
uint64 EnvenomTargetGUID;
uint32 DeadlyPoisonTimer;
uint32 VanishTimer;
uint32 AppearEnvenomTimer;
bool HasVanished;
void Reset()
{
EnvenomTargetGUID = 0;
DeadlyPoisonTimer = 20000;
VanishTimer = 60000 + rand()%61 * 1000;
AppearEnvenomTimer = 150000;
HasVanished = false;
m_creature->SetVisibility(VISIBILITY_ON);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
void KilledUnit(Unit *victim)
{
DoYell(SAY_VERA_SLAY,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature, SOUND_VERA_SLAY);
}
void JustDied(Unit *victim)
{
DoYell(SAY_VERA_DEATH, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature,SOUND_VERA_DEATH);
}
void UpdateAI(const uint32 diff)
{
if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())
return;
if(!HasVanished)
{
if(DeadlyPoisonTimer < diff)
{
DoCast(m_creature->getVictim(), SPELL_DEADLY_POISON);
DeadlyPoisonTimer = 15000 + rand()%31 * 1000;
}else DeadlyPoisonTimer -= diff;
if(AppearEnvenomTimer < diff) // Cast Envenom. This is cast 4 seconds after Vanish is over
{
DoCast(m_creature->getVictim(), SPELL_ENVENOM);
AppearEnvenomTimer = 90000;
}else AppearEnvenomTimer -= diff;
if(VanishTimer < diff) // Disappear and stop attacking, but follow a random unit
{
if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
{
VanishTimer = 30000;
AppearEnvenomTimer= 28000;
HasVanished = true;
m_creature->SetVisibility(VISIBILITY_OFF);
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
DoResetThreat();
// Chase a unit. Check before DoMeleeAttackIfReady prevents from attacking
m_creature->AddThreat(target, 500000.0f);
m_creature->GetMotionMaster()->MoveChase(target);
}
}else VanishTimer -= diff;
DoMeleeAttackIfReady();
}
else
{
if(VanishTimer < diff) // Become attackable and poison current target
{
Unit* target = m_creature->getVictim();
DoCast(target, SPELL_DEADLY_POISON);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
DoResetThreat();
m_creature->AddThreat(target, 3000.0f); // Make Veras attack his target for a while, he will cast Envenom 4 seconds after.
DeadlyPoisonTimer += 6000;
VanishTimer = 90000;
AppearEnvenomTimer = 4000;
HasVanished = false;
}else VanishTimer -= diff;
if(AppearEnvenomTimer < diff) // Appear 2 seconds before becoming attackable (Shifting out of vanish)
{
m_creature->GetMotionMaster()->Clear();
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
m_creature->SetVisibility(VISIBILITY_ON);
AppearEnvenomTimer = 6000;
}else AppearEnvenomTimer -= diff;
}
}
};
CreatureAI* GetAI_mob_blood_elf_council_voice_trigger(Creature* c)
{
return new mob_blood_elf_council_voice_triggerAI(c);
}
CreatureAI* GetAI_mob_illidari_council(Creature *_Creature)
{
return new mob_illidari_councilAI (_Creature);
}
CreatureAI* GetAI_boss_gathios_the_shatterer(Creature *_Creature)
{
return new boss_gathios_the_shattererAI (_Creature);
}
CreatureAI* GetAI_boss_lady_malande(Creature *_Creature)
{
return new boss_lady_malandeAI (_Creature);
}
CreatureAI* GetAI_boss_veras_darkshadow(Creature *_Creature)
{
return new boss_veras_darkshadowAI (_Creature);
}
CreatureAI* GetAI_boss_high_nethermancer_zerevor(Creature *_Creature)
{
return new boss_high_nethermancer_zerevorAI (_Creature);
}
void AddSC_boss_illidari_council()
{
Script *newscript;
newscript = new Script;
newscript->Name="mob_illidari_council";
newscript->GetAI = GetAI_mob_illidari_council;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name = "mob_blood_elf_council_voice_trigger";
newscript->GetAI = GetAI_mob_blood_elf_council_voice_trigger;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="boss_gathios_the_shatterer";
newscript->GetAI = GetAI_boss_gathios_the_shatterer;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="boss_lady_malande";
newscript->GetAI = GetAI_boss_lady_malande;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="boss_veras_darkshadow";
newscript->GetAI = GetAI_boss_veras_darkshadow;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="boss_high_nethermancer_zerevor";
newscript->GetAI = GetAI_boss_high_nethermancer_zerevor;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,252 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Instance_Black_Temple
SD%Complete: 100
SDComment: Instance Data Scripts and functions to acquire mobs and set encounter status for use in various Black Temple Scripts
SDCategory: Black Temple
EndScriptData */
#include "precompiled.h"
#include "def_black_temple.h"
#define ENCOUNTERS 9
/* Black Temple encounters:
0 - High Warlord Naj'entus event
1 - Supremus Event
2 - Shade of Akama Event
3 - Teron Gorefiend Event
4 - Gurtogg Bloodboil Event
5 - Reliquary Of Souls Event
6 - Mother Shahraz Event
7 - Illidari Council Event
8 - Illidan Stormrage Event
*/
struct MANGOS_DLL_DECL instance_black_temple : public ScriptedInstance
{
instance_black_temple(Map *Map) : ScriptedInstance(Map) {Initialize();};
uint64 Najentus;
uint64 Akama; // This is the Akama that starts the Illidan encounter.
uint64 Akama_Shade; // This is the Akama that starts the Shade of Akama encounter.
uint64 ShadeOfAkama;
uint64 Supremus;
uint64 LadyMalande;
uint64 GathiosTheShatterer;
uint64 HighNethermancerZerevor;
uint64 VerasDarkshadow;
uint64 IllidariCouncil;
uint64 BloodElfCouncilVoice;
uint64 IllidanStormrage;
uint64 NajentusGate;
uint64 MainTempleDoors;
uint64 IllidanGate;
uint64 IllidanDoor[2];
uint32 Encounters[ENCOUNTERS];
void Initialize()
{
Najentus = 0;
Akama = 0;
Akama_Shade = 0;
ShadeOfAkama = 0;
Supremus = 0;
LadyMalande = 0;
GathiosTheShatterer = 0;
HighNethermancerZerevor = 0;
VerasDarkshadow = 0;
IllidariCouncil = 0;
BloodElfCouncilVoice = 0;
IllidanStormrage = 0;
NajentusGate = 0;
MainTempleDoors = 0;
IllidanGate = 0;
IllidanDoor[0] = 0;
IllidanDoor[1] = 0;
for(uint8 i = 0; i < ENCOUNTERS; i++)
Encounters[i] = NOT_STARTED;
}
bool IsEncounterInProgress() const
{
for(uint8 i = 0; i < ENCOUNTERS; i++)
if(Encounters[i] == IN_PROGRESS) return true;
return false;
}
void OnCreatureCreate(Creature *creature, uint32 creature_entry)
{
switch(creature_entry)
{
case 22887: Najentus = creature->GetGUID(); break;
case 23089: Akama = creature->GetGUID(); break;
case 22990: Akama_Shade = creature->GetGUID(); break;
case 22841: ShadeOfAkama = creature->GetGUID(); break;
case 22898: Supremus = creature->GetGUID(); break;
case 22917: IllidanStormrage = creature->GetGUID(); break;
case 22949: GathiosTheShatterer = creature->GetGUID(); break;
case 22950: HighNethermancerZerevor = creature->GetGUID(); break;
case 22951: LadyMalande = creature->GetGUID(); break;
case 22952: VerasDarkshadow = creature->GetGUID(); break;
case 23426: IllidariCouncil = creature->GetGUID(); break;
case 23499: BloodElfCouncilVoice = creature->GetGUID(); break;
}
}
void OnObjectCreate(GameObject* go)
{
switch(go->GetEntry())
{
case 185483: // Gate past Naj'entus (at the entrance to Supermoose's courtyards)
NajentusGate = go->GetGUID();
break;
case 185882: // Main Temple Doors - right past Supermoose (Supremus)
MainTempleDoors = go->GetGUID();
break;
case 185905: // Gate leading to Temple Summit
IllidanGate = go->GetGUID();
break;
case 186261: // Right door at Temple Summit
IllidanDoor[0] = go->GetGUID();
break;
case 186262: // Left door at Temple Summit
IllidanDoor[1] = go->GetGUID();
break;
}
}
uint64 GetData64(uint32 identifier)
{
switch(identifier)
{
case DATA_HIGHWARLORDNAJENTUS: return Najentus;
case DATA_AKAMA: return Akama;
case DATA_AKAMA_SHADE: return Akama_Shade;
case DATA_SHADEOFAKAMA: return ShadeOfAkama;
case DATA_SUPREMUS: return Supremus;
case DATA_ILLIDANSTORMRAGE: return IllidanStormrage;
case DATA_GATHIOSTHESHATTERER: return GathiosTheShatterer;
case DATA_HIGHNETHERMANCERZEREVOR: return HighNethermancerZerevor;
case DATA_LADYMALANDE: return LadyMalande;
case DATA_VERASDARKSHADOW: return VerasDarkshadow;
case DATA_ILLIDARICOUNCIL: return IllidariCouncil;
case DATA_GAMEOBJECT_NAJENTUS_GATE: return NajentusGate;
case DATA_GAMEOBJECT_ILLIDAN_GATE: return IllidanGate;
case DATA_GAMEOBJECT_ILLIDAN_DOOR_R: return IllidanDoor[0];
case DATA_GAMEOBJECT_ILLIDAN_DOOR_L: return IllidanDoor[1];
case DATA_GAMEOBJECT_SUPREMUS_DOORS: return MainTempleDoors;
case DATA_BLOOD_ELF_COUNCIL_VOICE: return BloodElfCouncilVoice;
}
return 0;
}
void SetData(uint32 type, uint32 data)
{
switch(type)
{
case DATA_HIGHWARLORDNAJENTUSEVENT: Encounters[0] = data; break;
case DATA_SUPREMUSEVENT: Encounters[1] = data; break;
case DATA_SHADEOFAKAMAEVENT: Encounters[2] = data; break;
case DATA_TERONGOREFIENDEVENT: Encounters[3] = data; break;
case DATA_GURTOGGBLOODBOILEVENT: Encounters[4] = data; break;
case DATA_RELIQUARYOFSOULSEVENT: Encounters[5] = data; break;
case DATA_MOTHERSHAHRAZEVENT: Encounters[6] = data; break;
case DATA_ILLIDARICOUNCILEVENT: Encounters[7] = data; break;
case DATA_ILLIDANSTORMRAGEEVENT: Encounters[8] = data; break;
}
if(data == DONE)
SaveToDB();
}
uint32 GetData(uint32 type)
{
switch(type)
{
case DATA_HIGHWARLORDNAJENTUSEVENT: return Encounters[0];
case DATA_SUPREMUSEVENT: return Encounters[1];
case DATA_SHADEOFAKAMAEVENT: return Encounters[2];
case DATA_TERONGOREFIENDEVENT: return Encounters[3];
case DATA_GURTOGGBLOODBOILEVENT: return Encounters[4];
case DATA_RELIQUARYOFSOULSEVENT: return Encounters[5];
case DATA_MOTHERSHAHRAZEVENT: return Encounters[6];
case DATA_ILLIDARICOUNCILEVENT: return Encounters[7];
case DATA_ILLIDANSTORMRAGEEVENT: return Encounters[8];
}
return 0;
}
const char* Save()
{
OUT_SAVE_INST_DATA;
std::ostringstream stream;
stream << Encounters[0] << " " << Encounters[1] << " " << Encounters[2] << " "
<< Encounters[3] << " " << Encounters[4] << " " << Encounters[5] << " "
<< Encounters[6] << " " << Encounters[7] << " " << Encounters[8];
char* out = new char[stream.str().length() + 1];
strcpy(out, stream.str().c_str());
if(out)
{
OUT_SAVE_INST_DATA_COMPLETE;
return out;
}
return NULL;
}
void Load(const char* in)
{
if(!in)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
OUT_LOAD_INST_DATA(in);
std::istringstream stream(in);
stream >> Encounters[0] >> Encounters[1] >> Encounters[2] >> Encounters[3]
>> Encounters[4] >> Encounters[5] >> Encounters[6] >> Encounters[7]
>> Encounters[8];
for(uint8 i = 0; i < ENCOUNTERS; ++i)
if(Encounters[i] == IN_PROGRESS) // Do not load an encounter as "In Progress" - reset it instead.
Encounters[i] = NOT_STARTED;
OUT_LOAD_INST_DATA_COMPLETE;
}
};
InstanceData* GetInstanceData_instance_black_temple(Map* map)
{
return new instance_black_temple(map);
}
void AddSC_instance_black_temple()
{
Script *newscript;
newscript = new Script;
newscript->Name = "instance_black_temple";
newscript->GetInstanceData = GetInstanceData_instance_black_temple;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,237 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Blackrock_Depths
SD%Complete: 95
SDComment: Quest support: 4001, 4342, 7604. Vendor Lokhtos Darkbargainer.
SDCategory: Blackrock Depths
EndScriptData */
/* ContentData
mob_phalanx
npc_kharan_mighthammer
npc_lokhtos_darkbargainer
EndContentData */
#include "precompiled.h"
/*######
## mob_phalanx
######*/
#define SPELL_THUNDERCLAP 8732
#define SPELL_FIREBALLVOLLEY 22425
#define SPELL_MIGHTYBLOW 14099
struct MANGOS_DLL_DECL mob_phalanxAI : public ScriptedAI
{
mob_phalanxAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 ThunderClap_Timer;
uint32 FireballVolley_Timer;
uint32 MightyBlow_Timer;
void Reset()
{
ThunderClap_Timer = 12000;
FireballVolley_Timer =0;
MightyBlow_Timer = 15000;
}
void Aggro(Unit *who)
{
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if(!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
//ThunderClap_Timer
if( ThunderClap_Timer < diff )
{
DoCast(m_creature->getVictim(),SPELL_THUNDERCLAP);
ThunderClap_Timer = 10000;
}else ThunderClap_Timer -= diff;
//FireballVolley_Timer
if( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 51 )
{
if (FireballVolley_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_FIREBALLVOLLEY);
FireballVolley_Timer = 15000;
}else FireballVolley_Timer -= diff;
}
//MightyBlow_Timer
if( MightyBlow_Timer < diff )
{
DoCast(m_creature->getVictim(),SPELL_MIGHTYBLOW);
MightyBlow_Timer = 10000;
}else MightyBlow_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_phalanx(Creature *_Creature)
{
return new mob_phalanxAI (_Creature);
}
/*######
## npc_kharan_mighthammer
######*/
#define QUEST_4001 4001
#define QUEST_4342 4342
bool GossipHello_npc_kharan_mighthammer(Player *player, Creature *_Creature)
{
if( _Creature->isQuestGiver() )
player->PrepareQuestMenu( _Creature->GetGUID() );
if( player->GetQuestStatus(QUEST_4001) == QUEST_STATUS_INCOMPLETE )
player->ADD_GOSSIP_ITEM( 0, "I need to know where the princess are, Kharan!", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
if( player->GetQuestStatus(4342) == QUEST_STATUS_INCOMPLETE )
player->ADD_GOSSIP_ITEM( 0, "All is not lost, Kharan!", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
if( player->GetTeam() == HORDE ) player->SEND_GOSSIP_MENU(2473, _Creature->GetGUID());
if( player->GetTeam() == ALLIANCE ) player->SEND_GOSSIP_MENU(2474, _Creature->GetGUID());
return true;
}
bool GossipSelect_npc_kharan_mighthammer(Player *player, Creature *_Creature, uint32 sender, uint32 action)
{
switch (action)
{
case GOSSIP_ACTION_INFO_DEF+1:
player->ADD_GOSSIP_ITEM(0, "Gor'shak is my friend, you can trust me.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
player->SEND_GOSSIP_MENU(2475, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+2:
player->ADD_GOSSIP_ITEM(0, "Not enough, you need to tell me more.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
player->SEND_GOSSIP_MENU(2476, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+3:
player->ADD_GOSSIP_ITEM(0, "So what happened?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
player->SEND_GOSSIP_MENU(2477, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+4:
player->ADD_GOSSIP_ITEM(0, "Continue...", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5);
player->SEND_GOSSIP_MENU(2478, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+5:
player->ADD_GOSSIP_ITEM(0, "So you suspect that someone on the inside was involved? That they were tipped off?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6);
player->SEND_GOSSIP_MENU(2479, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+6:
player->ADD_GOSSIP_ITEM(0, "Continue with your story please.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7);
player->SEND_GOSSIP_MENU(2480, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+7:
player->ADD_GOSSIP_ITEM(0, "Indeed.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+8);
player->SEND_GOSSIP_MENU(2481, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+8:
player->ADD_GOSSIP_ITEM(0, "The door is open, Kharan. You are a free man.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+9);
player->SEND_GOSSIP_MENU(2482, _Creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+9:
player->CLOSE_GOSSIP_MENU();
if( player->GetTeam() == HORDE ) player->AreaExploredOrEventHappens(QUEST_4001);
if( player->GetTeam() == ALLIANCE ) player->AreaExploredOrEventHappens(QUEST_4342);
break;
}
return true;
}
/*######
## npc_lokhtos_darkbargainer
######*/
#define ITEM_THRORIUM_BROTHERHOOD_CONTRACT 18628
#define ITEM_SULFURON_INGOT 17203
#define QUEST_A_BINDING_CONTRACT 7604
#define SPELL_CREATE_THORIUM_BROTHERHOOD_CONTRACT_DND 23059
bool GossipHello_npc_lokhtos_darkbargainer(Player *player, Creature *_Creature)
{
if (_Creature->isQuestGiver())
player->PrepareQuestMenu( _Creature->GetGUID() );
if (_Creature->isVendor() && player->GetReputationRank(59) >= REP_FRIENDLY)
player->ADD_GOSSIP_ITEM( 1, "Show me what I have access to, Lothos.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
if (player->GetQuestRewardStatus(QUEST_A_BINDING_CONTRACT) != 1 &&
!player->HasItemCount(ITEM_THRORIUM_BROTHERHOOD_CONTRACT, 1, true) &&
player->HasItemCount(ITEM_SULFURON_INGOT, 1))
{
player->ADD_GOSSIP_ITEM(0, "Get Thorium Brotherhood Contract", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
}
if (player->GetReputationRank(59) < REP_FRIENDLY)
player->SEND_GOSSIP_MENU(3673, _Creature->GetGUID());
else
player->SEND_GOSSIP_MENU(3677, _Creature->GetGUID());
return true;
}
bool GossipSelect_npc_lokhtos_darkbargainer(Player *player, Creature *_Creature, uint32 sender, uint32 action )
{
if (action == GOSSIP_ACTION_INFO_DEF + 1)
{
player->CLOSE_GOSSIP_MENU();
player->CastSpell(player, SPELL_CREATE_THORIUM_BROTHERHOOD_CONTRACT_DND, false);
}
if (action == GOSSIP_ACTION_TRADE)
{
player->SEND_VENDORLIST( _Creature->GetGUID() );
}
return true;
}
/*######
##
######*/
void AddSC_blackrock_depths()
{
Script *newscript;
newscript = new Script;
newscript->Name="phalanx";
newscript->GetAI = GetAI_mob_phalanx;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="npc_kharan_mighthammer";
newscript->pGossipHello = &GossipHello_npc_kharan_mighthammer;
newscript->pGossipSelect = &GossipSelect_npc_kharan_mighthammer;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="npc_lokhtos_darkbargainer";
newscript->pGossipHello = &GossipHello_npc_lokhtos_darkbargainer;
newscript->pGossipSelect = &GossipSelect_npc_lokhtos_darkbargainer;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,106 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Ambassador_Flamelash
SD%Complete: 100
SDComment:
SDCategory: Blackrock Depths
EndScriptData */
#include "precompiled.h"
#define SPELL_FIREBLAST 15573
struct MANGOS_DLL_DECL boss_ambassador_flamelashAI : public ScriptedAI
{
boss_ambassador_flamelashAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 FireBlast_Timer;
uint32 Spirit_Timer;
int Rand;
int RandX;
int RandY;
Creature* Summoned;
void Reset()
{
FireBlast_Timer = 2000;
Spirit_Timer = 24000;
}
void Aggro(Unit *who) {}
void SummonSpirits(Unit* victim)
{
Rand = rand()%10;
switch (rand()%2)
{
case 0: RandX -= Rand; break;
case 1: RandX += Rand; break;
}
Rand = 0;
Rand = rand()%10;
switch (rand()%2)
{
case 0: RandY -= Rand; break;
case 1: RandY += Rand; break;
}
Summoned = DoSpawnCreature(9178, RandX, RandY, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
if(Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(victim);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
//FireBlast_Timer
if (FireBlast_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_FIREBLAST);
FireBlast_Timer = 7000;
}else FireBlast_Timer -= diff;
//Spirit_Timer
if (Spirit_Timer < diff)
{
SummonSpirits(m_creature->getVictim());
SummonSpirits(m_creature->getVictim());
SummonSpirits(m_creature->getVictim());
SummonSpirits(m_creature->getVictim());
Spirit_Timer = 30000;
}else Spirit_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_ambassador_flamelash(Creature *_Creature)
{
return new boss_ambassador_flamelashAI (_Creature);
}
void AddSC_boss_ambassador_flamelash()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_ambassador_flamelash";
newscript->GetAI = GetAI_boss_ambassador_flamelash;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,91 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Angerrel
SD%Complete: 100
SDComment:
SDCategory: Blackrock Depths
EndScriptData */
#include "precompiled.h"
#define SPELL_SUNDERARMOR 24317
#define SPELL_SHIELDBLOCK 12169
#define SPELL_STRIKE 15580
struct MANGOS_DLL_DECL boss_angerrelAI : public ScriptedAI
{
boss_angerrelAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 SunderArmor_Timer;
uint32 ShieldBlock_Timer;
uint32 Strike_Timer;
void Reset()
{
SunderArmor_Timer = 8000;
ShieldBlock_Timer = 15000;
Strike_Timer = 12000;
}
void Aggro(Unit *who)
{
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
//SunderArmor_Timer
if (SunderArmor_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_SUNDERARMOR);
SunderArmor_Timer = 28000;
}else SunderArmor_Timer -= diff;
//ShieldBlock_Timer
if (ShieldBlock_Timer < diff)
{
DoCast(m_creature,SPELL_SHIELDBLOCK);
ShieldBlock_Timer = 25000;
}else ShieldBlock_Timer -= diff;
//Strike_Timer
if (Strike_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_STRIKE);
Strike_Timer = 10000;
}else Strike_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_angerrel(Creature *_Creature)
{
return new boss_angerrelAI (_Creature);
}
void AddSC_boss_angerrel()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_angerrel";
newscript->GetAI = GetAI_boss_angerrel;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,115 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Anubshiah
SD%Complete: 100
SDComment:
SDCategory: Blackrock Depths
EndScriptData */
#include "precompiled.h"
#define SPELL_SHADOWBOLT 17228
#define SPELL_CURSEOFTONGUES 15470
#define SPELL_CURSEOFWEAKNESS 17227
#define SPELL_DEMONARMOR 11735
#define SPELL_ENVELOPINGWEB 15471
struct MANGOS_DLL_DECL boss_anubshiahAI : public ScriptedAI
{
boss_anubshiahAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 ShadowBolt_Timer;
uint32 CurseOfTongues_Timer;
uint32 CurseOfWeakness_Timer;
uint32 DemonArmor_Timer;
uint32 EnvelopingWeb_Timer;
void Reset()
{
ShadowBolt_Timer = 7000;
CurseOfTongues_Timer = 24000;
CurseOfWeakness_Timer = 12000;
DemonArmor_Timer = 3000;
EnvelopingWeb_Timer = 16000;
}
void Aggro(Unit *who)
{
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
//ShadowBolt_Timer
if (ShadowBolt_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_SHADOWBOLT);
ShadowBolt_Timer = 7000;
}else ShadowBolt_Timer -= diff;
//CurseOfTongues_Timer
if (CurseOfTongues_Timer < diff)
{
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,0);
if (target) DoCast(target,SPELL_CURSEOFTONGUES);
CurseOfTongues_Timer = 18000;
}else CurseOfTongues_Timer -= diff;
//CurseOfWeakness_Timer
if (CurseOfWeakness_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_CURSEOFWEAKNESS);
CurseOfWeakness_Timer = 45000;
}else CurseOfWeakness_Timer -= diff;
//DemonArmor_Timer
if (DemonArmor_Timer < diff)
{
DoCast(m_creature,SPELL_DEMONARMOR);
DemonArmor_Timer = 300000;
}else DemonArmor_Timer -= diff;
//EnvelopingWeb_Timer
if (EnvelopingWeb_Timer < diff)
{
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,0);
if (target) DoCast(target,SPELL_ENVELOPINGWEB);
EnvelopingWeb_Timer = 12000;
}else EnvelopingWeb_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_anubshiah(Creature *_Creature)
{
return new boss_anubshiahAI (_Creature);
}
void AddSC_boss_anubshiah()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_anubshiah";
newscript->GetAI = GetAI_boss_anubshiah;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,139 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Doomrel
SD%Complete: 100
SDComment:
SDCategory: Blackrock Depths
EndScriptData */
#include "precompiled.h"
#define SPELL_SHADOWBOLTVOLLEY 17228
#define SPELL_IMMOLATE 15505
#define SPELL_CURSEOFWEAKNESS 17227
#define SPELL_DEMONARMOR 11735
struct MANGOS_DLL_DECL boss_doomrelAI : public ScriptedAI
{
boss_doomrelAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 ShadowVolley_Timer;
uint32 Immolate_Timer;
uint32 CurseOfWeakness_Timer;
uint32 DemonArmor_Timer;
bool Voidwalkers;
int Rand;
int RandX;
int RandY;
Creature* Summoned;
void Reset()
{
ShadowVolley_Timer = 10000;
Immolate_Timer = 18000;
CurseOfWeakness_Timer = 5000;
DemonArmor_Timer = 16000;
Voidwalkers = false;
}
void Aggro(Unit *who)
{
}
void SummonVoidwalkers(Unit* victim)
{
Rand = rand()%5;
switch (rand()%2)
{
case 0: RandX = 0 - Rand; break;
case 1: RandX = 0 + Rand; break;
}
Rand = 0;
Rand = rand()%5;
switch (rand()%2)
{
case 0: RandY = 0 - Rand; break;
case 1: RandY = 0 + Rand; break;
}
Rand = 0;
Summoned = DoSpawnCreature(16119, RandX, RandY, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 120000);
if(Summoned)
((CreatureAI*)Summoned->AI())->AttackStart(victim);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
//ShadowVolley_Timer
if (ShadowVolley_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_SHADOWBOLTVOLLEY);
ShadowVolley_Timer = 12000;
}else ShadowVolley_Timer -= diff;
//Immolate_Timer
if (Immolate_Timer < diff)
{
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,0);
if (target)DoCast(target,SPELL_IMMOLATE);
Immolate_Timer = 25000;
}else Immolate_Timer -= diff;
//CurseOfWeakness_Timer
if (CurseOfWeakness_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_CURSEOFWEAKNESS);
CurseOfWeakness_Timer = 45000;
}else CurseOfWeakness_Timer -= diff;
//DemonArmor_Timer
if (DemonArmor_Timer < diff)
{
DoCast(m_creature,SPELL_DEMONARMOR);
DemonArmor_Timer = 300000;
}else DemonArmor_Timer -= diff;
//Summon Voidwalkers
if (!Voidwalkers && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 51 )
{
SummonVoidwalkers(m_creature->getVictim());
SummonVoidwalkers(m_creature->getVictim());
SummonVoidwalkers(m_creature->getVictim());
Voidwalkers = true;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_doomrel(Creature *_Creature)
{
return new boss_doomrelAI (_Creature);
}
void AddSC_boss_doomrel()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_doomrel";
newscript->GetAI = GetAI_boss_doomrel;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,91 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Doperel
SD%Complete: 100
SDComment:
SDCategory: Blackrock Depths
EndScriptData */
#include "precompiled.h"
#define SPELL_SINISTERSTRIKE 15581
#define SPELL_BACKSTAB 15582
#define SPELL_GOUGE 13579
struct MANGOS_DLL_DECL boss_doperelAI : public ScriptedAI
{
boss_doperelAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 SinisterStrike_Timer;
uint32 BackStab_Timer;
uint32 Gouge_Timer;
void Reset()
{
SinisterStrike_Timer = 8000;
BackStab_Timer = 12000;
Gouge_Timer = 6000;
}
void Aggro(Unit *who)
{
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
//SinisterStrike_Timer
if (SinisterStrike_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_SINISTERSTRIKE);
SinisterStrike_Timer = 7000;
}else SinisterStrike_Timer -= diff;
//BackStab_Timer
if (BackStab_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_BACKSTAB);
BackStab_Timer = 6000;
}else BackStab_Timer -= diff;
//Gouge_Timer
if (Gouge_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_GOUGE);
Gouge_Timer = 8000;
}else Gouge_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_doperel(Creature *_Creature)
{
return new boss_doperelAI (_Creature);
}
void AddSC_boss_doperel()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_doperel";
newscript->GetAI = GetAI_boss_doperel;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,104 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Emperor_Dagran_Thaurissan
SD%Complete: 99
SDComment:
SDCategory: Blackrock Depths
EndScriptData */
#include "precompiled.h"
#define SPELL_HANDOFTHAURISSAN 17492
#define SPELL_AVATAROFFLAME 15636
#define SAY_AGGRO "Come to aid the Throne!"
#define SAY_SLAY "Hail to the king, baby!"
struct MANGOS_DLL_DECL boss_draganthaurissanAI : public ScriptedAI
{
boss_draganthaurissanAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 HandOfThaurissan_Timer;
uint32 AvatarOfFlame_Timer;
//uint32 Counter;
void Reset()
{
HandOfThaurissan_Timer = 4000;
AvatarOfFlame_Timer = 25000;
//Counter= 0;
}
void Aggro(Unit *who)
{
DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL);
}
void KilledUnit(Unit* victim)
{
DoYell(SAY_SLAY, LANG_UNIVERSAL, NULL);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
if (HandOfThaurissan_Timer < diff)
{
Unit* target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM,0);
if (target) DoCast(target,SPELL_HANDOFTHAURISSAN);
//3 Hands of Thaurissan will be casted
//if (Counter < 3)
//{
// HandOfThaurissan_Timer = 1000;
// Counter++;
//}
//else
//{
HandOfThaurissan_Timer = 5000;
//Counter=0;
//}
}else HandOfThaurissan_Timer -= diff;
//AvatarOfFlame_Timer
if (AvatarOfFlame_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_AVATAROFFLAME);
AvatarOfFlame_Timer = 18000;
}else AvatarOfFlame_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_draganthaurissan(Creature *_Creature)
{
return new boss_draganthaurissanAI (_Creature);
}
void AddSC_boss_draganthaurissan()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_emperor_dagran_thaurissan";
newscript->GetAI = GetAI_boss_draganthaurissan;
m_scripts[nrscripts++] = newscript;
}
@@ -0,0 +1,167 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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 Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_General_Angerforge
SD%Complete: 100
SDComment:
SDCategory: Blackrock Depths
EndScriptData */
#include "precompiled.h"
#define SPELL_MIGHTYBLOW 14099
#define SPELL_HAMSTRING 9080
#define SPELL_CLEAVE 20691
struct MANGOS_DLL_DECL boss_general_angerforgeAI : public ScriptedAI
{
boss_general_angerforgeAI(Creature *c) : ScriptedAI(c) {Reset();}
uint32 MightyBlow_Timer;
uint32 HamString_Timer;
uint32 Cleave_Timer;
uint32 Adds_Timer;
bool Medics;
int Rand1;
int Rand1X;
int Rand1Y;
int Rand2;
int Rand2X;
int Rand2Y;
Creature* SummonedAdds;
Creature* SummonedMedics;
void Reset()
{
MightyBlow_Timer = 8000;
HamString_Timer = 12000;
Cleave_Timer = 16000;
Adds_Timer = 0;
Medics = false;
}
void Aggro(Unit *who)
{
}
void SummonAdds(Unit* victim)
{
Rand1 = rand()%15;
switch (rand()%2)
{
case 0: Rand1X = 0 - Rand1; break;
case 1: Rand1X = 0 + Rand1; break;
}
Rand1 = 0;
Rand1 = rand()%15;
switch (rand()%2)
{
case 0: Rand1Y = 0 - Rand1; break;
case 1: Rand1Y = 0 + Rand1; break;
}
Rand1 = 0;
SummonedAdds = DoSpawnCreature(8901, Rand1X, Rand1Y, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 120000);
if(SummonedAdds)
((CreatureAI*)SummonedAdds->AI())->AttackStart(victim);
}
void SummonMedics(Unit* victim)
{
Rand2 = rand()%10;
switch (rand()%2)
{
case 0: Rand2X = 0 - Rand2; break;
case 1: Rand2X = 0 + Rand2; break;
}
Rand2 = 0;
Rand2 = rand()%10;
switch (rand()%2)
{
case 0: Rand2Y = 0 - Rand2; break;
case 1: Rand2Y = 0 + Rand2; break;
}
Rand2 = 0;
SummonedMedics = DoSpawnCreature(8894, Rand2X, Rand2Y, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 120000);
if(SummonedMedics)
((CreatureAI*)SummonedMedics->AI())->AttackStart(victim);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
//MightyBlow_Timer
if (MightyBlow_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_MIGHTYBLOW);
MightyBlow_Timer = 18000;
}else MightyBlow_Timer -= diff;
//HamString_Timer
if (HamString_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_HAMSTRING);
HamString_Timer = 15000;
}else HamString_Timer -= diff;
//Cleave_Timer
if (Cleave_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_CLEAVE);
Cleave_Timer = 9000;
}else Cleave_Timer -= diff;
//Adds_Timer
if ( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 21 )
{
if (Adds_Timer < diff)
{
// summon 3 Adds every 25s
SummonAdds(m_creature->getVictim());
SummonAdds(m_creature->getVictim());
SummonAdds(m_creature->getVictim());
Adds_Timer = 25000;
} else Adds_Timer -= diff;
}
//Summon Medics
if ( !Medics && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 21 )
{
SummonMedics(m_creature->getVictim());
SummonMedics(m_creature->getVictim());
Medics = true;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_general_angerforge(Creature *_Creature)
{
return new boss_general_angerforgeAI (_Creature);
}
void AddSC_boss_general_angerforge()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_general_angerforge";
newscript->GetAI = GetAI_boss_general_angerforge;
m_scripts[nrscripts++] = newscript;
}

Some files were not shown because too many files have changed in this diff Show More