Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.x

This commit is contained in:
Shauren committed 2012-07-04 22:20:21 +02:00
commit ed6f3e2def
360 files changed
+19813 -7203

No files matched your search

+6 -6
View File
@@ -12,30 +12,30 @@ set(scripts_STAT_SRCS
${scripts_STAT_SRCS}
Commands/cs_account.cpp
Commands/cs_achievement.cpp
Commands/cs_cast.cpp
Commands/cs_character.cpp
Commands/cs_debug.cpp
Commands/cs_event.cpp
Commands/cs_gm.cpp
Commands/cs_go.cpp
Commands/cs_gobject.cpp
Commands/cs_honor.cpp
Commands/cs_instance.cpp
Commands/cs_learn.cpp
Commands/cs_list.cpp
Commands/cs_misc.cpp
Commands/cs_modify.cpp
Commands/cs_npc.cpp
Commands/cs_quest.cpp
Commands/cs_reload.cpp
Commands/cs_reset.cpp
Commands/cs_tele.cpp
Commands/cs_server.cpp
Commands/cs_titles.cpp
Commands/cs_wp.cpp
# Commands/cs_character.cpp
# Commands/cs_list.cpp
# Commands/cs_lookup.cpp
# Commands/cs_pdump.cpp
# Commands/cs_guild.cpp
# Commands/cs_cast.cpp
# Commands/cs_reset.cpp
# Commands/cs_instance.cpp
# Commands/cs_server.cpp
# Commands/cs_channel.cpp
# Commands/cs_pet.cpp
# Commands/cs_ticket.cpp
+310
View File
@@ -0,0 +1,310 @@
/*
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.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, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
Name: cast_commandscript
%Complete: 100
Comment: All cast related commands
Category: commandscripts
EndScriptData */
#include "ScriptMgr.h"
#include "Chat.h"
class cast_commandscript : public CommandScript
{
public:
cast_commandscript() : CommandScript("cast_commandscript") { }
ChatCommand* GetCommands() const
{
static ChatCommand castCommandTable[] =
{
{ "back", SEC_ADMINISTRATOR, false, &HandleCastBackCommand, "", NULL },
{ "dist", SEC_ADMINISTRATOR, false, &HandleCastDistCommand, "", NULL },
{ "self", SEC_ADMINISTRATOR, false, &HandleCastSelfCommand, "", NULL },
{ "target", SEC_ADMINISTRATOR, false, &HandleCastTargetCommad, "", NULL },
{ "dest", SEC_ADMINISTRATOR, false, &HandleCastDestCommand, "", NULL },
{ "", SEC_ADMINISTRATOR, false, &HandleCastCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand commandTable[] =
{
{ "cast", SEC_ADMINISTRATOR, false, NULL, "", castCommandTable },
{ NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
static bool HandleCastCommand(ChatHandler* handler, char const* args)
{
if (!*args)
return false;
Unit* target = handler->getSelectedUnit();
if (!target)
{
handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
handler->SetSentErrorMessage(true);
return false;
}
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
uint32 spellId = handler->extractSpellIdFromLink((char*)args);
if (!spellId)
return false;
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
{
handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
handler->SetSentErrorMessage(true);
return false;
}
if (!SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer()))
{
handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId);
handler->SetSentErrorMessage(true);
return false;
}
char* triggeredStr = strtok(NULL, " ");
if (triggeredStr)
{
int l = strlen(triggeredStr);
if (strncmp(triggeredStr, "triggered", l) != 0)
return false;
}
bool triggered = (triggeredStr != NULL);
handler->GetSession()->GetPlayer()->CastSpell(target, spellId, triggered);
return true;
}
static bool HandleCastBackCommand(ChatHandler* handler, char const* args)
{
Creature* caster = handler->getSelectedCreature();
if (!caster)
{
handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
handler->SetSentErrorMessage(true);
return false;
}
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
uint32 spellId = handler->extractSpellIdFromLink((char*)args);
if (!spellId || !sSpellMgr->GetSpellInfo(spellId))
{
handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
handler->SetSentErrorMessage(true);
return false;
}
char* triggeredStr = strtok(NULL, " ");
if (triggeredStr)
{
int l = strlen(triggeredStr);
if (strncmp(triggeredStr, "triggered", l) != 0)
return false;
}
bool triggered = (triggeredStr != NULL);
caster->CastSpell(handler->GetSession()->GetPlayer(), spellId, triggered);
return true;
}
static bool HandleCastDistCommand(ChatHandler* handler, char const* args)
{
if (!*args)
return false;
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
uint32 spellId = handler->extractSpellIdFromLink((char*)args);
if (!spellId)
return false;
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
{
handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
handler->SetSentErrorMessage(true);
return false;
}
if (!SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer()))
{
handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId);
handler->SetSentErrorMessage(true);
return false;
}
char* distStr = strtok(NULL, " ");
float dist = 0;
if (distStr)
sscanf(distStr, "%f", &dist);
char* triggeredStr = strtok(NULL, " ");
if (triggeredStr)
{
int l = strlen(triggeredStr);
if (strncmp(triggeredStr, "triggered", l) != 0)
return false;
}
bool triggered = (triggeredStr != NULL);
float x, y, z;
handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, dist);
handler->GetSession()->GetPlayer()->CastSpell(x, y, z, spellId, triggered);
return true;
}
static bool HandleCastSelfCommand(ChatHandler* handler, char const* args)
{
if (!*args)
return false;
Unit* target = handler->getSelectedUnit();
if (!target)
{
handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
handler->SetSentErrorMessage(true);
return false;
}
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
uint32 spellId = handler->extractSpellIdFromLink((char*)args);
if (!spellId)
return false;
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
return false;
if (!SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer()))
{
handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId);
handler->SetSentErrorMessage(true);
return false;
}
target->CastSpell(target, spellId, false);
return true;
}
static bool HandleCastTargetCommad(ChatHandler* handler, char const* args)
{
Creature* caster = handler->getSelectedCreature();
if (!caster)
{
handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
handler->SetSentErrorMessage(true);
return false;
}
if (!caster->getVictim())
{
handler->SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
handler->SetSentErrorMessage(true);
return false;
}
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
uint32 spellId = handler->extractSpellIdFromLink((char*)args);
if (!spellId || !sSpellMgr->GetSpellInfo(spellId))
{
handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
handler->SetSentErrorMessage(true);
return false;
}
char* triggeredStr = strtok(NULL, " ");
if (triggeredStr)
{
int l = strlen(triggeredStr);
if (strncmp(triggeredStr, "triggered", l) != 0)
return false;
}
bool triggered = (triggeredStr != NULL);
caster->CastSpell(caster->getVictim(), spellId, triggered);
return true;
}
static bool HandleCastDestCommand(ChatHandler* handler, char const* args)
{
Unit* caster = handler->getSelectedUnit();
if (!caster)
{
handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
handler->SetSentErrorMessage(true);
return false;
}
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
uint32 spellId = handler->extractSpellIdFromLink((char*)args);
if (!spellId || !sSpellMgr->GetSpellInfo(spellId))
{
handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
handler->SetSentErrorMessage(true);
return false;
}
char* posX = strtok(NULL, " ");
char* posY = strtok(NULL, " ");
char* posZ = strtok(NULL, " ");
if (!posX || !posY || !posZ)
return false;
float x = float(atof(posX));
float y = float(atof(posY));
float z = float(atof(posZ));
char* triggeredStr = strtok(NULL, " ");
if (triggeredStr)
{
int l = strlen(triggeredStr);
if (strncmp(triggeredStr, "triggered", l) != 0)
return false;
}
bool triggered = (triggeredStr != NULL);
caster->CastSpell(x, y, z, spellId, triggered);
return true;
}
};
void AddSC_cast_commandscript()
{
new cast_commandscript();
}
@@ -0,0 +1,679 @@
/*
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.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, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
Name: character_commandscript
%Complete: 100
Comment: All character related commands
Category: commandscripts
EndScriptData */
#include "ScriptMgr.h"
#include "Chat.h"
#include "AccountMgr.h"
#include "ObjectMgr.h"
class character_commandscript : public CommandScript
{
public:
character_commandscript() : CommandScript("character_commandscript") { }
ChatCommand* GetCommands() const
{
static ChatCommand characterDeletedCommandTable[] =
{
{ "delete", SEC_CONSOLE, true, &HandleCharacterDeletedDeleteCommand, "", NULL },
{ "list", SEC_ADMINISTRATOR, true, &HandleCharacterDeletedListCommand, "", NULL },
{ "restore", SEC_ADMINISTRATOR, true, &HandleCharacterDeletedRestoreCommand, "", NULL },
{ "old", SEC_CONSOLE, true, &HandleCharacterDeletedOldCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand characterCommandTable[] =
{
{ "customize", SEC_GAMEMASTER, true, &HandleCharacterCustomizeCommand, "", NULL },
{ "changefaction", SEC_GAMEMASTER, true, &HandleCharacterChangeFactionCommand, "", NULL },
{ "changerace", SEC_GAMEMASTER, true, &HandleCharacterChangeRaceCommand, "", NULL },
{ "deleted", SEC_GAMEMASTER, true, NULL, "", characterDeletedCommandTable},
{ "erase", SEC_CONSOLE, true, &HandleCharacterEraseCommand, "", NULL },
{ "level", SEC_ADMINISTRATOR, true, &HandleCharacterLevelCommand, "", NULL },
{ "rename", SEC_GAMEMASTER, true, &HandleCharacterRenameCommand, "", NULL },
{ "reputation", SEC_GAMEMASTER, true, &HandleCharacterReputationCommand, "", NULL },
{ "titles", SEC_GAMEMASTER, true, &HandleCharacterTitlesCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand commandTable[] =
{
{ "character", SEC_GAMEMASTER, true, NULL, "", characterCommandTable},
{ NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
// Stores informations about a deleted character
struct DeletedInfo
{
uint32 lowGuid; ///< the low GUID from the character
std::string name; ///< the character name
uint32 accountId; ///< the account id
std::string accountName; ///< the account name
time_t deleteDate; ///< the date at which the character has been deleted
};
typedef std::list<DeletedInfo> DeletedInfoList;
/**
* Collects all GUIDs (and related info) from deleted characters which are still in the database.
*
* @param foundList a reference to an std::list which will be filled with info data
* @param searchString the search string which either contains a player GUID or a part fo the character-name
* @return returns false if there was a problem while selecting the characters (e.g. player name not normalizeable)
*/
static bool GetDeletedCharacterInfoList(DeletedInfoList& foundList, std::string searchString)
{
PreparedQueryResult result;
PreparedStatement* stmt;
if (!searchString.empty())
{
// search by GUID
if (isNumeric(searchString.c_str()))
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO_BY_GUID);
stmt->setUInt32(0, uint32(atoi(searchString.c_str())));
result = CharacterDatabase.Query(stmt);
}
// search by name
else
{
if (!normalizePlayerName(searchString))
return false;
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO_BY_NAME);
stmt->setString(0, searchString);
result = CharacterDatabase.Query(stmt);
}
}
else
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO);
result = CharacterDatabase.Query(stmt);
}
if (result)
{
do
{
Field* fields = result->Fetch();
DeletedInfo info;
info.lowGuid = fields[0].GetUInt32();
info.name = fields[1].GetString();
info.accountId = fields[2].GetUInt32();
// account name will be empty for not existed account
AccountMgr::GetName(info.accountId, info.accountName);
info.deleteDate = time_t(fields[3].GetUInt32());
foundList.push_back(info);
}
while (result->NextRow());
}
return true;
}
/**
* Shows all deleted characters which matches the given search string, expected non empty list
*
* @see HandleCharacterDeletedListCommand
* @see HandleCharacterDeletedRestoreCommand
* @see HandleCharacterDeletedDeleteCommand
* @see DeletedInfoList
*
* @param foundList contains a list with all found deleted characters
*/
static void HandleCharacterDeletedListHelper(DeletedInfoList const& foundList, ChatHandler* handler)
{
if (!handler->GetSession())
{
handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR);
handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_HEADER);
handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR);
}
for (DeletedInfoList::const_iterator itr = foundList.begin(); itr != foundList.end(); ++itr)
{
std::string dateStr = TimeToTimestampStr(itr->deleteDate);
if (!handler->GetSession())
handler->PSendSysMessage(LANG_CHARACTER_DELETED_LIST_LINE_CONSOLE,
itr->lowGuid, itr->name.c_str(), itr->accountName.empty() ? "<Not existed>" : itr->accountName.c_str(),
itr->accountId, dateStr.c_str());
else
handler->PSendSysMessage(LANG_CHARACTER_DELETED_LIST_LINE_CHAT,
itr->lowGuid, itr->name.c_str(), itr->accountName.empty() ? "<Not existed>" : itr->accountName.c_str(),
itr->accountId, dateStr.c_str());
}
if (!handler->GetSession())
handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR);
}
/**
* Restore a previously deleted character
*
* @see HandleCharacterDeletedListHelper
* @see HandleCharacterDeletedRestoreCommand
* @see HandleCharacterDeletedDeleteCommand
* @see DeletedInfoList
*
* @param delInfo the informations about the character which will be restored
*/
static void HandleCharacterDeletedRestoreHelper(DeletedInfo const& delInfo, ChatHandler* handler)
{
if (delInfo.accountName.empty()) // account not exist
{
handler->PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_ACCOUNT, delInfo.name.c_str(), delInfo.lowGuid, delInfo.accountId);
return;
}
// check character count
uint32 charcount = AccountMgr::GetCharactersCount(delInfo.accountId);
if (charcount >= 10)
{
handler->PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_FULL, delInfo.name.c_str(), delInfo.lowGuid, delInfo.accountId);
return;
}
if (sObjectMgr->GetPlayerGUIDByName(delInfo.name))
{
handler->PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_NAME, delInfo.name.c_str(), delInfo.lowGuid, delInfo.accountId);
return;
}
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_RESTORE_DELETE_INFO);
stmt->setString(0, delInfo.name);
stmt->setUInt32(1, delInfo.accountId);
stmt->setUInt32(2, delInfo.lowGuid);
CharacterDatabase.Execute(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_NAME_DATA);
stmt->setUInt32(0, delInfo.lowGuid);
if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
sWorld->AddCharacterNameData(delInfo.lowGuid, delInfo.name, (*result)[2].GetUInt8(), (*result)[0].GetUInt8(), (*result)[1].GetUInt8());
}
static bool HandleCharacterTitlesCommand(ChatHandler* handler, char const* args)
{
if (!*args)
return false;
Player* target;
if (!handler->extractPlayerTarget((char*)args, &target))
return false;
LocaleConstant loc = handler->GetSessionDbcLocale();
char const* targetName = target->GetName();
char const* knownStr = handler->GetTrinityString(LANG_KNOWN);
// Search in CharTitles.dbc
for (uint32 id = 0; id < sCharTitlesStore.GetNumRows(); id++)
{
CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id);
if (titleInfo && target->HasTitle(titleInfo))
{
std::string name = titleInfo->name;
if (name.empty())
continue;
char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->bit_index
? handler->GetTrinityString(LANG_ACTIVE)
: "";
char titleNameStr[80];
snprintf(titleNameStr, 80, name.c_str(), targetName);
// send title in "id (idx:idx) - [namedlink locale]" format
if (handler->GetSession())
handler->PSendSysMessage(LANG_TITLE_LIST_CHAT, id, titleInfo->bit_index, id, titleNameStr, localeNames[loc], knownStr, activeStr);
else
handler->PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->bit_index, name.c_str(), localeNames[loc], knownStr, activeStr);
}
}
return true;
}
//rename characters
static bool HandleCharacterRenameCommand(ChatHandler* handler, char const* args)
{
Player* target;
uint64 targetGuid;
std::string targetName;
if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
return false;
if (target)
{
// check online security
if (handler->HasLowerSecurity(target, 0))
return false;
handler->PSendSysMessage(LANG_RENAME_PLAYER, handler->GetNameLink(target).c_str());
target->SetAtLoginFlag(AT_LOGIN_RENAME);
}
else
{
// check offline security
if (handler->HasLowerSecurity(NULL, targetGuid))
return false;
std::string oldNameLink = handler->playerLink(targetName);
handler->PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
stmt->setUInt16(0, uint16(AT_LOGIN_RENAME));
stmt->setUInt32(1, GUID_LOPART(targetGuid));
CharacterDatabase.Execute(stmt);
}
return true;
}
static bool HandleCharacterLevelCommand(ChatHandler* handler, char const* args)
{
char* nameStr;
char* levelStr;
handler->extractOptFirstArg((char*)args, &nameStr, &levelStr);
if (!levelStr)
return false;
// exception opt second arg: .character level $name
if (isalpha(levelStr[0]))
{
nameStr = levelStr;
levelStr = NULL; // current level will used
}
Player* target;
uint64 targetGuid;
std::string targetName;
if (!handler->extractPlayerTarget(nameStr, &target, &targetGuid, &targetName))
return false;
int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(targetGuid);
int32 newlevel = levelStr ? atoi(levelStr) : oldlevel;
if (newlevel < 1)
return false; // invalid level
if (newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
newlevel = STRONG_MAX_LEVEL;
handler->HandleCharacterLevel(target, targetGuid, oldlevel, newlevel);
if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target) // including player == NULL
{
std::string nameLink = handler->playerLink(targetName);
handler->PSendSysMessage(LANG_YOU_CHANGE_LVL, nameLink.c_str(), newlevel);
}
return true;
}
// customize characters
static bool HandleCharacterCustomizeCommand(ChatHandler* handler, char const* args)
{
Player* target;
uint64 targetGuid;
std::string targetName;
if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
return false;
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
stmt->setUInt16(0, uint16(AT_LOGIN_CUSTOMIZE));
if (target)
{
handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER, handler->GetNameLink(target).c_str());
target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE);
stmt->setUInt32(1, target->GetGUIDLow());
}
else
{
std::string oldNameLink = handler->playerLink(targetName);
stmt->setUInt32(1, GUID_LOPART(targetGuid));
handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
}
CharacterDatabase.Execute(stmt);
return true;
}
static bool HandleCharacterChangeFactionCommand(ChatHandler* handler, char const* args)
{
Player* target;
uint64 targetGuid;
std::string targetName;
if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
return false;
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_FACTION));
if (target)
{
handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER, handler->GetNameLink(target).c_str());
target->SetAtLoginFlag(AT_LOGIN_CHANGE_FACTION);
stmt->setUInt32(1, target->GetGUIDLow());
}
else
{
std::string oldNameLink = handler->playerLink(targetName);
handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
stmt->setUInt32(1, GUID_LOPART(targetGuid));
}
CharacterDatabase.Execute(stmt);
return true;
}
static bool HandleCharacterChangeRaceCommand(ChatHandler* handler, char const* args)
{
Player* target;
uint64 targetGuid;
std::string targetName;
if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
return false;
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_RACE));
if (target)
{
// TODO : add text into database
handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER, handler->GetNameLink(target).c_str());
target->SetAtLoginFlag(AT_LOGIN_CHANGE_RACE);
stmt->setUInt32(1, target->GetGUIDLow());
}
else
{
std::string oldNameLink = handler->playerLink(targetName);
// TODO : add text into database
handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
stmt->setUInt32(1, GUID_LOPART(targetGuid));
}
CharacterDatabase.Execute(stmt);
return true;
}
static bool HandleCharacterReputationCommand(ChatHandler* handler, char const* args)
{
Player* target;
if (!handler->extractPlayerTarget((char*)args, &target))
return false;
LocaleConstant loc = handler->GetSessionDbcLocale();
FactionStateList const& targetFSL = target->GetReputationMgr().GetStateList();
for (FactionStateList::const_iterator itr = targetFSL.begin(); itr != targetFSL.end(); ++itr)
{
FactionState const& faction = itr->second;
FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction.ID);
char const* factionName = factionEntry ? factionEntry->name : "#Not found#";
ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry);
std::string rankName = handler->GetTrinityString(ReputationRankStrIndex[rank]);
std::ostringstream ss;
if (handler->GetSession())
ss << faction.ID << " - |cffffffff|Hfaction:" << faction.ID << "|h[" << factionName << ' ' << localeNames[loc] << "]|h|r";
else
ss << faction.ID << " - " << factionName << ' ' << localeNames[loc];
ss << ' ' << rankName << " (" << target->GetReputationMgr().GetReputation(factionEntry) << ')';
if (faction.Flags & FACTION_FLAG_VISIBLE)
ss << handler->GetTrinityString(LANG_FACTION_VISIBLE);
if (faction.Flags & FACTION_FLAG_AT_WAR)
ss << handler->GetTrinityString(LANG_FACTION_ATWAR);
if (faction.Flags & FACTION_FLAG_PEACE_FORCED)
ss << handler->GetTrinityString(LANG_FACTION_PEACE_FORCED);
if (faction.Flags & FACTION_FLAG_HIDDEN)
ss << handler->GetTrinityString(LANG_FACTION_HIDDEN);
if (faction.Flags & FACTION_FLAG_INVISIBLE_FORCED)
ss << handler->GetTrinityString(LANG_FACTION_INVISIBLE_FORCED);
if (faction.Flags & FACTION_FLAG_INACTIVE)
ss << handler->GetTrinityString(LANG_FACTION_INACTIVE);
handler->SendSysMessage(ss.str().c_str());
}
return true;
}
/**
* Handles the '.character deleted list' command, which shows all deleted characters which matches the given search string
*
* @see HandleCharacterDeletedListHelper
* @see HandleCharacterDeletedRestoreCommand
* @see HandleCharacterDeletedDeleteCommand
* @see DeletedInfoList
*
* @param args the search string which either contains a player GUID or a part fo the character-name
*/
static bool HandleCharacterDeletedListCommand(ChatHandler* handler, char const* args)
{
DeletedInfoList foundList;
if (!GetDeletedCharacterInfoList(foundList, args))
return false;
// if no characters have been found, output a warning
if (foundList.empty())
{
handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY);
return false;
}
HandleCharacterDeletedListHelper(foundList, handler);
return true;
}
/**
* Handles the '.character deleted restore' command, which restores all deleted characters which matches the given search string
*
* The command automatically calls '.character deleted list' command with the search string to show all restored characters.
*
* @see HandleCharacterDeletedRestoreHelper
* @see HandleCharacterDeletedListCommand
* @see HandleCharacterDeletedDeleteCommand
*
* @param args the search string which either contains a player GUID or a part of the character-name
*/
static bool HandleCharacterDeletedRestoreCommand(ChatHandler* handler, char const* args)
{
// It is required to submit at least one argument
if (!*args)
return false;
std::string searchString;
std::string newCharName;
uint32 newAccount = 0;
// GCC by some strange reason fail build code without temporary variable
std::istringstream params(args);
params >> searchString >> newCharName >> newAccount;
DeletedInfoList foundList;
if (!GetDeletedCharacterInfoList(foundList, searchString))
return false;
if (foundList.empty())
{
handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY);
return false;
}
handler->SendSysMessage(LANG_CHARACTER_DELETED_RESTORE);
HandleCharacterDeletedListHelper(foundList, handler);
if (newCharName.empty())
{
// Drop not existed account cases
for (DeletedInfoList::iterator itr = foundList.begin(); itr != foundList.end(); ++itr)
HandleCharacterDeletedRestoreHelper(*itr, handler);
}
else if (foundList.size() == 1 && normalizePlayerName(newCharName))
{
DeletedInfo delInfo = foundList.front();
// update name
delInfo.name = newCharName;
// if new account provided update deleted info
if (newAccount && newAccount != delInfo.accountId)
{
delInfo.accountId = newAccount;
AccountMgr::GetName(newAccount, delInfo.accountName);
}
HandleCharacterDeletedRestoreHelper(delInfo, handler);
}
else
handler->SendSysMessage(LANG_CHARACTER_DELETED_ERR_RENAME);
return true;
}
/**
* Handles the '.character deleted delete' command, which completely deletes all deleted characters which matches the given search string
*
* @see Player::GetDeletedCharacterGUIDs
* @see Player::DeleteFromDB
* @see HandleCharacterDeletedListCommand
* @see HandleCharacterDeletedRestoreCommand
*
* @param args the search string which either contains a player GUID or a part fo the character-name
*/
static bool HandleCharacterDeletedDeleteCommand(ChatHandler* handler, char const* args)
{
// It is required to submit at least one argument
if (!*args)
return false;
DeletedInfoList foundList;
if (!GetDeletedCharacterInfoList(foundList, args))
return false;
if (foundList.empty())
{
handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY);
return false;
}
handler->SendSysMessage(LANG_CHARACTER_DELETED_DELETE);
HandleCharacterDeletedListHelper(foundList, handler);
// Call the appropriate function to delete them (current account for deleted characters is 0)
for (DeletedInfoList::const_iterator itr = foundList.begin(); itr != foundList.end(); ++itr)
Player::DeleteFromDB(itr->lowGuid, 0, false, true);
return true;
}
/**
* Handles the '.character deleted old' command, which completely deletes all deleted characters deleted with some days ago
*
* @see Player::DeleteOldCharacters
* @see Player::DeleteFromDB
* @see HandleCharacterDeletedDeleteCommand
* @see HandleCharacterDeletedListCommand
* @see HandleCharacterDeletedRestoreCommand
*
* @param args the search string which either contains a player GUID or a part fo the character-name
*/
static bool HandleCharacterDeletedOldCommand(ChatHandler* /*handler*/, char const* args)
{
int32 keepDays = sWorld->getIntConfig(CONFIG_CHARDELETE_KEEP_DAYS);
char* daysStr = strtok((char*)args, " ");
if (daysStr)
{
if (!isNumeric(daysStr))
return false;
keepDays = atoi(daysStr);
if (keepDays < 0)
return false;
}
// config option value 0 -> disabled and can't be used
else if (keepDays <= 0)
return false;
Player::DeleteOldCharacters(uint32(keepDays));
return true;
}
static bool HandleCharacterEraseCommand(ChatHandler* handler, char const* args)
{
if (!*args)
return false;
char* characterName_str = strtok((char*)args, " ");
if (!characterName_str)
return false;
std::string characterName = characterName_str;
if (!normalizePlayerName(characterName))
return false;
uint64 characterGuid;
uint32 accountId;
Player* player = sObjectAccessor->FindPlayerByName(characterName.c_str());
if (player)
{
characterGuid = player->GetGUID();
accountId = player->GetSession()->GetAccountId();
player->GetSession()->KickPlayer();
}
else
{
characterGuid = sObjectMgr->GetPlayerGUIDByName(characterName);
if (!characterGuid)
{
handler->PSendSysMessage(LANG_NO_PLAYER, characterName.c_str());
handler->SetSentErrorMessage(true);
return false;
}
accountId = sObjectMgr->GetPlayerAccountIdByGUID(characterGuid);
}
std::string accountName;
AccountMgr::GetName(accountId, accountName);
Player::DeleteFromDB(characterGuid, accountId, true, true);
handler->PSendSysMessage(LANG_CHARACTER_DELETED, characterName.c_str(), GUID_LOPART(characterGuid), accountName.c_str(), accountId);
return true;
}
};
void AddSC_character_commandscript()
{
new character_commandscript();
}
+193
View File
@@ -0,0 +1,193 @@
/*
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.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, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
Name: instance_commandscript
%Complete: 100
Comment: All instance related commands
Category: commandscripts
EndScriptData */
#include "ScriptMgr.h"
#include "Chat.h"
#include "Group.h"
#include "InstanceSaveMgr.h"
#include "InstanceScript.h"
#include "MapManager.h"
class instance_commandscript : public CommandScript
{
public:
instance_commandscript() : CommandScript("instance_commandscript") { }
ChatCommand* GetCommands() const
{
static ChatCommand instanceCommandTable[] =
{
{ "listbinds", SEC_ADMINISTRATOR, false, &HandleInstanceListBindsCommand, "", NULL },
{ "unbind", SEC_ADMINISTRATOR, false, &HandleInstanceUnbindCommand, "", NULL },
{ "stats", SEC_ADMINISTRATOR, true, &HandleInstanceStatsCommand, "", NULL },
{ "savedata", SEC_ADMINISTRATOR, false, &HandleInstanceSaveDataCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand commandTable[] =
{
{ "instance", SEC_ADMINISTRATOR, true, NULL, "", instanceCommandTable },
{ NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
static std::string GetTimeString(uint64 time)
{
uint64 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
std::ostringstream ss;
if (days)
ss << days << "d ";
if (hours)
ss << hours << "h ";
ss << minute << 'm';
return ss.str();
}
static bool HandleInstanceListBindsCommand(ChatHandler* handler, char const* /*args*/)
{
Player* player = handler->getSelectedPlayer();
if (!player)
player = handler->GetSession()->GetPlayer();
uint32 counter = 0;
for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
{
Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i));
for (Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
{
InstanceSave* save = itr->second.save;
std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
handler->PSendSysMessage("map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
counter++;
}
}
handler->PSendSysMessage("player binds: %d", counter);
counter = 0;
if (Group* group = player->GetGroup())
{
for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
{
Group::BoundInstancesMap &binds = group->GetBoundInstances(Difficulty(i));
for (Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
{
InstanceSave* save = itr->second.save;
std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
handler->PSendSysMessage("map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
counter++;
}
}
}
handler->PSendSysMessage("group binds: %d", counter);
return true;
}
static bool HandleInstanceUnbindCommand(ChatHandler* handler, char const* args)
{
if (!*args)
return false;
Player* player = handler->getSelectedPlayer();
if (!player)
player = handler->GetSession()->GetPlayer();
char* map = strtok((char*)args, " ");
char* pDiff = strtok(NULL, " ");
int8 diff = -1;
if (pDiff)
diff = atoi(pDiff);
uint16 counter = 0;
uint16 MapId = 0;
if (strcmp(map, "all"))
{
MapId = uint16(atoi(map));
if (!MapId)
return false;
}
for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
{
Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i));
for (Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
{
InstanceSave* save = itr->second.save;
if (itr->first != player->GetMapId() && (!MapId || MapId == itr->first) && (diff == -1 || diff == save->GetDifficulty()))
{
std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
handler->PSendSysMessage("unbinding map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
player->UnbindInstance(itr, Difficulty(i));
counter++;
}
else
++itr;
}
}
handler->PSendSysMessage("instances unbound: %d", counter);
return true;
}
static bool HandleInstanceStatsCommand(ChatHandler* handler, char const* /*args*/)
{
handler->PSendSysMessage("instances loaded: %d", sMapMgr->GetNumInstances());
handler->PSendSysMessage("players in instances: %d", sMapMgr->GetNumPlayersInInstances());
handler->PSendSysMessage("instance saves: %d", sInstanceSaveMgr->GetNumInstanceSaves());
handler->PSendSysMessage("players bound: %d", sInstanceSaveMgr->GetNumBoundPlayersTotal());
handler->PSendSysMessage("groups bound: %d", sInstanceSaveMgr->GetNumBoundGroupsTotal());
return true;
}
static bool HandleInstanceSaveDataCommand(ChatHandler* handler, char const* /*args*/)
{
Player* player = handler->GetSession()->GetPlayer();
Map* map = player->GetMap();
if (!map->IsDungeon())
{
handler->PSendSysMessage("Map is not a dungeon.");
handler->SetSentErrorMessage(true);
return false;
}
if (!((InstanceMap*)map)->GetInstanceScript())
{
handler->PSendSysMessage("Map has no instance data.");
handler->SetSentErrorMessage(true);
return false;
}
((InstanceMap*)map)->GetInstanceScript()->SaveToDB();
return true;
}
};
void AddSC_instance_commandscript()
{
new instance_commandscript();
}
+469
View File
@@ -0,0 +1,469 @@
/*
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.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, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
Name: list_commandscript
%Complete: 100
Comment: All list related commands
Category: commandscripts
EndScriptData */
#include "ScriptMgr.h"
#include "Chat.h"
#include "SpellAuraEffects.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
class list_commandscript : public CommandScript
{
public:
list_commandscript() : CommandScript("list_commandscript") { }
ChatCommand* GetCommands() const
{
static ChatCommand listCommandTable[] =
{
{ "creature", SEC_ADMINISTRATOR, true, &HandleListCreatureCommand, "", NULL },
{ "item", SEC_ADMINISTRATOR, true, &HandleListItemCommand, "", NULL },
{ "object", SEC_ADMINISTRATOR, true, &HandleListObjectCommand, "", NULL },
{ "auras", SEC_ADMINISTRATOR, false, &HandleListAurasCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand commandTable[] =
{
{ "list", SEC_ADMINISTRATOR, true, NULL, "", listCommandTable },
{ NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
static bool HandleListCreatureCommand(ChatHandler* handler, char const* args)
{
if (!*args)
return false;
// number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
char* id = handler->extractKeyFromLink((char*)args, "Hcreature_entry");
if (!id)
return false;
uint32 creatureId = atol(id);
if (!creatureId)
{
handler->PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, creatureId);
handler->SetSentErrorMessage(true);
return false;
}
CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creatureId);
if (!cInfo)
{
handler->PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, creatureId);
handler->SetSentErrorMessage(true);
return false;
}
char* countStr = strtok(NULL, " ");
uint32 count = countStr ? atol(countStr) : 10;
if (count < 0)
return false;
QueryResult result;
uint32 creatureCount = 0;
result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'", creatureId);
if (result)
creatureCount = (*result)[0].GetUInt64();
if (handler->GetSession())
{
Player* player = handler->GetSession()->GetPlayer();
result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM creature WHERE id = '%u' ORDER BY order_ ASC LIMIT %u",
player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), creatureId, count);
}
else
result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
creatureId, count);
if (result)
{
do
{
Field* fields = result->Fetch();
uint32 guid = fields[0].GetUInt32();
float x = fields[1].GetFloat();
float y = fields[2].GetFloat();
float z = fields[3].GetFloat();
uint16 mapId = fields[4].GetUInt16();
if (handler->GetSession())
handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name.c_str(), x, y, z, mapId);
else
handler->PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name.c_str(), x, y, z, mapId);
}
while (result->NextRow());
}
handler->PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE, creatureId, creatureCount);
return true;
}
static bool HandleListItemCommand(ChatHandler* handler, char const* args)
{
if (!*args)
return false;
char* id = handler->extractKeyFromLink((char*)args, "Hitem");
if (!id)
return false;
uint32 itemId = atol(id);
if (!itemId)
{
handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
handler->SetSentErrorMessage(true);
return false;
}
ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId);
if (!itemTemplate)
{
handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
handler->SetSentErrorMessage(true);
return false;
}
char* countStr = strtok(NULL, " ");
uint32 count = countStr ? atol(countStr) : 10;
if (count < 0)
return false;
PreparedQueryResult result;
// inventory case
uint32 inventoryCount = 0;
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM);
stmt->setUInt32(0, itemId);
result = CharacterDatabase.Query(stmt);
if (result)
inventoryCount = (*result)[0].GetUInt64();
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_INVENTORY_ITEM_BY_ENTRY);
stmt->setUInt32(0, itemId);
stmt->setUInt32(1, count);
result = CharacterDatabase.Query(stmt);
if (result)
{
do
{
Field* fields = result->Fetch();
uint32 itemGuid = fields[0].GetUInt32();
uint32 itemBag = fields[1].GetUInt32();
uint8 itemSlot = fields[2].GetUInt8();
uint32 ownerGuid = fields[3].GetUInt32();
uint32 ownerAccountId = fields[4].GetUInt32();
std::string ownerName = fields[5].GetString();
char const* itemPos = 0;
if (Player::IsEquipmentPos(itemBag, itemSlot))
itemPos = "[equipped]";
else if (Player::IsInventoryPos(itemBag, itemSlot))
itemPos = "[in inventory]";
else if (Player::IsBankPos(itemBag, itemSlot))
itemPos = "[in bank]";
else
itemPos = "";
handler->PSendSysMessage(LANG_ITEMLIST_SLOT, itemGuid, ownerName.c_str(), ownerGuid, ownerAccountId, itemPos);
}
while (result->NextRow());
uint32 resultCount = uint32(result->GetRowCount());
if (count > resultCount)
count -= resultCount;
else if (count)
count = 0;
}
// mail case
uint32 mailCount = 0;
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT_ITEM);
stmt->setUInt32(0, itemId);
result = CharacterDatabase.Query(stmt);
if (result)
mailCount = (*result)[0].GetUInt64();
if (count > 0)
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_ITEMS_BY_ENTRY);
stmt->setUInt32(0, itemId);
stmt->setUInt32(1, count);
result = CharacterDatabase.Query(stmt);
}
else
result = PreparedQueryResult(NULL);
if (result)
{
do
{
Field* fields = result->Fetch();
uint32 itemGuid = fields[0].GetUInt32();
uint32 itemSender = fields[1].GetUInt32();
uint32 itemReceiver = fields[2].GetUInt32();
uint32 itemSenderAccountId = fields[3].GetUInt32();
std::string itemSenderName = fields[4].GetString();
uint32 itemReceiverAccount = fields[5].GetUInt32();
std::string itemReceiverName = fields[6].GetString();
char const* itemPos = "[in mail]";
handler->PSendSysMessage(LANG_ITEMLIST_MAIL, itemGuid, itemSenderName.c_str(), itemSender, itemSenderAccountId, itemReceiverName.c_str(), itemReceiver, itemReceiverAccount, itemPos);
}
while (result->NextRow());
uint32 resultCount = uint32(result->GetRowCount());
if (count > resultCount)
count -= resultCount;
else if (count)
count = 0;
}
// auction case
uint32 auctionCount = 0;
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONHOUSE_COUNT_ITEM);
stmt->setUInt32(0, itemId);
result = CharacterDatabase.Query(stmt);
if (result)
auctionCount = (*result)[0].GetUInt64();
if (count > 0)
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONHOUSE_ITEM_BY_ENTRY);
stmt->setUInt32(0, itemId);
stmt->setUInt32(1, count);
result = CharacterDatabase.Query(stmt);
}
else
result = PreparedQueryResult(NULL);
if (result)
{
do
{
Field* fields = result->Fetch();
uint32 itemGuid = fields[0].GetUInt32();
uint32 owner = fields[1].GetUInt32();
uint32 ownerAccountId = fields[2].GetUInt32();
std::string ownerName = fields[3].GetString();
char const* itemPos = "[in auction]";
handler->PSendSysMessage(LANG_ITEMLIST_AUCTION, itemGuid, ownerName.c_str(), owner, ownerAccountId, itemPos);
}
while (result->NextRow());
}
// guild bank case
uint32 guildCount = 0;
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_COUNT_ITEM);
stmt->setUInt32(0, itemId);
result = CharacterDatabase.Query(stmt);
if (result)
guildCount = (*result)[0].GetUInt64();
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_ITEM_BY_ENTRY);
stmt->setUInt32(0, itemId);
stmt->setUInt32(1, count);
result = CharacterDatabase.Query(stmt);
if (result)
{
do
{
Field* fields = result->Fetch();
uint32 itemGuid = fields[0].GetUInt32();
uint32 guildGuid = fields[1].GetUInt32();
std::string guildName = fields[2].GetString();
char const* itemPos = "[in guild bank]";
handler->PSendSysMessage(LANG_ITEMLIST_GUILD, itemGuid, guildName.c_str(), guildGuid, itemPos);
}
while (result->NextRow());
uint32 resultCount = uint32(result->GetRowCount());
if (count > resultCount)
count -= resultCount;
else if (count)
count = 0;
}
if (inventoryCount + mailCount + auctionCount + guildCount == 0)
{
handler->SendSysMessage(LANG_COMMAND_NOITEMFOUND);
handler->SetSentErrorMessage(true);
return false;
}
handler->PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE, itemId, inventoryCount + mailCount + auctionCount + guildCount, inventoryCount, mailCount, auctionCount, guildCount);
return true;
}
static bool HandleListObjectCommand(ChatHandler* handler, char const* args)
{
if (!*args)
return false;
// number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
char* id = handler->extractKeyFromLink((char*)args, "Hgameobject_entry");
if (!id)
return false;
uint32 gameObjectId = atol(id);
if (!gameObjectId)
{
handler->PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, gameObjectId);
handler->SetSentErrorMessage(true);
return false;
}
GameObjectTemplate const* gInfo = sObjectMgr->GetGameObjectTemplate(gameObjectId);
if (!gInfo)
{
handler->PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, gameObjectId);
handler->SetSentErrorMessage(true);
return false;
}
char* countStr = strtok(NULL, " ");
uint32 count = countStr ? atol(countStr) : 10;
if (count < 0)
return false;
QueryResult result;
uint32 objectCount = 0;
result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'", gameObjectId);
if (result)
objectCount = (*result)[0].GetUInt64();
if (handler->GetSession())
{
Player* player = handler->GetSession()->GetPlayer();
result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, id, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE id = '%u' ORDER BY order_ ASC LIMIT %u",
player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), gameObjectId, count);
}
else
result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, id FROM gameobject WHERE id = '%u' LIMIT %u",
gameObjectId, count);
if (result)
{
do
{
Field* fields = result->Fetch();
uint32 guid = fields[0].GetUInt32();
float x = fields[1].GetFloat();
float y = fields[2].GetFloat();
float z = fields[3].GetFloat();
uint16 mapId = fields[4].GetUInt16();
uint32 entry = fields[5].GetUInt32();
if (handler->GetSession())
handler->PSendSysMessage(LANG_GO_LIST_CHAT, guid, entry, guid, gInfo->name.c_str(), x, y, z, mapId);
else
handler->PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name.c_str(), x, y, z, mapId);
}
while (result->NextRow());
}
handler->PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE, gameObjectId, objectCount);
return true;
}
static bool HandleListAurasCommand(ChatHandler* handler, char const* /*args*/)
{
Unit* unit = handler->getSelectedUnit();
if (!unit)
{
handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
handler->SetSentErrorMessage(true);
return false;
}
char const* talentStr = handler->GetTrinityString(LANG_TALENT);
char const* passiveStr = handler->GetTrinityString(LANG_PASSIVE);
Unit::AuraApplicationMap const& auras = unit->GetAppliedAuras();
handler->PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, auras.size());
for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
{
bool talent = GetTalentSpellCost(itr->second->GetBase()->GetId()) > 0;
AuraApplication const* aurApp = itr->second;
Aura const* aura = aurApp->GetBase();
char const* name = aura->GetSpellInfo()->SpellName;
std::ostringstream ss_name;
ss_name << "|cffffffff|Hspell:" << aura->GetId() << "|h[" << name << "]|h|r";
handler->PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, aura->GetId(), (handler->GetSession() ? ss_name.str().c_str() : name),
aurApp->GetEffectMask(), aura->GetCharges(), aura->GetStackAmount(), aurApp->GetSlot(),
aura->GetDuration(), aura->GetMaxDuration(), (aura->IsPassive() ? passiveStr : ""),
(talent ? talentStr : ""), IS_PLAYER_GUID(aura->GetCasterGUID()) ? "player" : "creature",
GUID_LOPART(aura->GetCasterGUID()));
}
for (uint16 i = 0; i < TOTAL_AURAS; ++i)
{
Unit::AuraEffectList const& auraList = unit->GetAuraEffectsByType(AuraType(i));
if (auraList.empty())
continue;
handler->PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, auraList.size(), i);
for (Unit::AuraEffectList::const_iterator itr = auraList.begin(); itr != auraList.end(); ++itr)
handler->PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(), (*itr)->GetAmount());
}
return true;
}
};
void AddSC_list_commandscript()
{
new list_commandscript();
}
+4 -5
View File
@@ -135,15 +135,14 @@ public:
else
handler->PSendSysMessage("no VMAP available for area info");
/*handler->PSendSysMessage(LANG_MAP_POSITION,
object->GetMapId(), (mapEntry ? mapEntry->name[handler->GetSessionDbcLocale()] : "<unknown>"),
zoneId, (zoneEntry ? zoneEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"),
areaId, (areaEntry ? areaEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"),
handler->PSendSysMessage(LANG_MAP_POSITION,
object->GetMapId(), (mapEntry ? mapEntry->name : "<unknown>"),
zoneId, (zoneEntry ? zoneEntry->area_name : "<unknown>"),
areaId, (areaEntry ? areaEntry->area_name : "<unknown>"),
object->GetPhaseMask(),
object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation(),
cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(),
zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap);
*/
LiquidData liquidStatus;
ZLiquidStatus status = map->getLiquidStatus(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus);
+3 -86
View File
@@ -64,15 +64,14 @@ public:
{ "standstate", SEC_GAMEMASTER, false, &HandleModifyStandStateCommand, "", NULL },
{ "phase", SEC_ADMINISTRATOR, false, &HandleModifyPhaseCommand, "", NULL },
{ "gender", SEC_GAMEMASTER, false, &HandleModifyGenderCommand, "", NULL },
{ "collision", SEC_GAMEMASTER, false, &HandleModifyCollisionCommand, "", NULL },
{ "speed", SEC_MODERATOR, false, NULL, "", modifyspeedCommandTable },
{ "speed", SEC_MODERATOR, false, NULL, "", modifyspeedCommandTable },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand commandTable[] =
{
{ "morph", SEC_GAMEMASTER, false, &HandleModifyMorphCommand, "", NULL },
{ "demorph", SEC_GAMEMASTER, false, &HandleDeMorphCommand, "", NULL },
{ "modify", SEC_MODERATOR, false, NULL, "", modifyCommandTable },
{ "modify", SEC_MODERATOR, false, NULL, "", modifyCommandTable },
{ NULL, 0, false, NULL, "", NULL }
};
return commandTable;
@@ -1391,7 +1390,7 @@ public:
if (!target)
target = handler->GetSession()->GetPlayer();
// check online security
// check online security
else if (target->GetTypeId() == TYPEID_PLAYER && handler->HasLowerSecurity(target->ToPlayer(), 0))
return false;
@@ -1399,88 +1398,6 @@ public:
return true;
}
static bool HandleModifyCollisionCommand(ChatHandler* handler, const char* args)
{
if (!*args)
return false;
Player* target = handler->getSelectedPlayer();
if (!target)
{
handler->PSendSysMessage(LANG_PLAYER_NOT_FOUND);
handler->SetSentErrorMessage(true);
return false;
}
std::string param = (char*)args;
if (param == "on")
{
// enable collision
WorldPacket data;
uint64 guid = target->GetGUID();
uint8* bytes = (uint8*)&guid;
data.Initialize(SMSG_MOVE_SPLINE_ENABLE_COLLISION, 1 + 8);
data.WriteByteMask(bytes[7]);
data.WriteByteMask(bytes[5]);
data.WriteByteMask(bytes[4]);
data.WriteByteMask(bytes[0]);
data.WriteByteMask(bytes[1]);
data.WriteByteMask(bytes[6]);
data.WriteByteMask(bytes[2]);
data.WriteByteMask(bytes[3]);
data.WriteByteSeq(bytes[6]);
data.WriteByteSeq(bytes[3]);
data.WriteByteSeq(bytes[2]);
data.WriteByteSeq(bytes[7]);
data.WriteByteSeq(bytes[4]);
data.WriteByteSeq(bytes[1]);
data.WriteByteSeq(bytes[5]);
data.WriteByteSeq(bytes[0]);
target->SendMessageToSet(&data, true);
handler->SendSysMessage("Enabled Collision");
return true;
}
if (param == "off")
{
// disable collision
WorldPacket data;
uint64 guid = target->GetGUID();
uint8* bytes = (uint8*)&guid;
data.Initialize(SMSG_MOVE_SPLINE_DISABLE_COLLISION, 1 + 8);
data.WriteByteMask(bytes[4]);
data.WriteByteMask(bytes[7]);
data.WriteByteMask(bytes[5]);
data.WriteByteMask(bytes[3]);
data.WriteByteMask(bytes[2]);
data.WriteByteMask(bytes[1]);
data.WriteByteMask(bytes[6]);
data.WriteByteMask(bytes[0]);
data.WriteByteSeq(bytes[6]);
data.WriteByteSeq(bytes[0]);
data.WriteByteSeq(bytes[5]);
data.WriteByteSeq(bytes[4]);
data.WriteByteSeq(bytes[7]);
data.WriteByteSeq(bytes[3]);
data.WriteByteSeq(bytes[1]);
data.WriteByteSeq(bytes[2]);
target->SendMessageToSet(&data, true);
handler->SendSysMessage("Disabled Collision");
return true;
}
return false;
}
};
void AddSC_modify_commandscript()
+310
View File
@@ -0,0 +1,310 @@
/*
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.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, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
Name: reset_commandscript
%Complete: 100
Comment: All reset related commands
Category: commandscripts
EndScriptData */
#include "ScriptMgr.h"
#include "Chat.h"
#include "ObjectAccessor.h"
class reset_commandscript : public CommandScript
{
public:
reset_commandscript() : CommandScript("reset_commandscript") { }
ChatCommand* GetCommands() const
{
static ChatCommand resetCommandTable[] =
{
{ "achievements", SEC_ADMINISTRATOR, true, &HandleResetAchievementsCommand, "", NULL },
{ "honor", SEC_ADMINISTRATOR, true, &HandleResetHonorCommand, "", NULL },
{ "level", SEC_ADMINISTRATOR, true, &HandleResetLevelCommand, "", NULL },
{ "spells", SEC_ADMINISTRATOR, true, &HandleResetSpellsCommand, "", NULL },
{ "stats", SEC_ADMINISTRATOR, true, &HandleResetStatsCommand, "", NULL },
{ "talents", SEC_ADMINISTRATOR, true, &HandleResetTalentsCommand, "", NULL },
{ "all", SEC_ADMINISTRATOR, true, &HandleResetAllCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand commandTable[] =
{
{ "reset", SEC_ADMINISTRATOR, true, NULL, "", resetCommandTable },
{ NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
static bool HandleResetAchievementsCommand(ChatHandler* handler, char const* args)
{
Player* target;
uint64 targetGuid;
if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid))
return false;
if (target)
target->GetAchievementMgr().Reset();
else
AchievementMgr::DeleteFromDB(GUID_LOPART(targetGuid));
return true;
}
static bool HandleResetHonorCommand(ChatHandler* handler, char const* args)
{
Player* target;
if (!handler->extractPlayerTarget((char*)args, &target))
return false;
target->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 0);
target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
return true;
}
static bool HandleResetStatsOrLevelHelper(Player* player)
{
ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(player->getClass());
if (!classEntry)
{
sLog->outError("Class %u not found in DBC (Wrong DBC files?)", player->getClass());
return false;
}
uint8 powerType = classEntry->powerType;
// reset m_form if no aura
if (!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
player->SetShapeshiftForm(FORM_NONE);
player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE);
player->SetFloatValue(UNIT_FIELD_COMBATREACH, DEFAULT_COMBAT_REACH);
player->setFactionForRace(player->getRace());
player->SetUInt32Value(UNIT_FIELD_BYTES_0, ((player->getRace()) | (player->getClass() << 8) | (player->getGender() << 16) | (powerType << 24)));
// reset only if player not in some form;
if (player->GetShapeshiftForm() == FORM_NONE)
player->InitDisplayIds();
player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP);
player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
//-1 is default value
player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
//player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000);
return true;
}
static bool HandleResetLevelCommand(ChatHandler* handler, char const* args)
{
Player* target;
if (!handler->extractPlayerTarget((char*)args, &target))
return false;
if (!HandleResetStatsOrLevelHelper(target))
return false;
uint8 oldLevel = target->getLevel();
// set starting level
uint32 startLevel = target->getClass() != CLASS_DEATH_KNIGHT
? sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL)
: sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
target->_ApplyAllLevelScaleItemMods(false);
target->SetLevel(startLevel);
target->InitRunes();
target->InitStatsForLevel(true);
target->InitTaxiNodesForLevel();
target->InitGlyphsForLevel();
target->InitTalentForLevel();
target->SetUInt32Value(PLAYER_XP, 0);
target->_ApplyAllLevelScaleItemMods(true);
// reset level for pet
if (Pet* pet = target->GetPet())
pet->SynchronizeLevelWithOwner();
sScriptMgr->OnPlayerLevelChanged(target, oldLevel);
return true;
}
static bool HandleResetSpellsCommand(ChatHandler* handler, char const* args)
{
Player* target;
uint64 targetGuid;
std::string targetName;
if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
return false;
if (target)
{
target->resetSpells(/* bool myClassOnly */);
ChatHandler(target).SendSysMessage(LANG_RESET_SPELLS);
if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target)
handler->PSendSysMessage(LANG_RESET_SPELLS_ONLINE, handler->GetNameLink(target).c_str());
}
else
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
stmt->setUInt16(0, uint16(AT_LOGIN_RESET_SPELLS));
stmt->setUInt32(1, GUID_LOPART(targetGuid));
CharacterDatabase.Execute(stmt);
handler->PSendSysMessage(LANG_RESET_SPELLS_OFFLINE, targetName.c_str());
}
return true;
}
static bool HandleResetStatsCommand(ChatHandler* handler, char const* args)
{
Player* target;
if (!handler->extractPlayerTarget((char*)args, &target))
return false;
if (!HandleResetStatsOrLevelHelper(target))
return false;
target->InitRunes();
target->InitStatsForLevel(true);
target->InitTaxiNodesForLevel();
target->InitGlyphsForLevel();
target->InitTalentForLevel();
return true;
}
static bool HandleResetTalentsCommand(ChatHandler* handler, char const* args)
{
Player* target;
uint64 targetGuid;
std::string targetName;
if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
{
// Try reset talents as Hunter Pet
Creature* creature = handler->getSelectedCreature();
if (!*args && creature && creature->isPet())
{
Unit* owner = creature->GetOwner();
if (owner && owner->GetTypeId() == TYPEID_PLAYER && creature->ToPet()->IsPermanentPetFor(owner->ToPlayer()))
{
creature->ToPet()->resetTalents();
owner->ToPlayer()->SendTalentsInfoData(true);
ChatHandler(owner->ToPlayer()).SendSysMessage(LANG_RESET_PET_TALENTS);
if (!handler->GetSession() || handler->GetSession()->GetPlayer() != owner->ToPlayer())
handler->PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE, handler->GetNameLink(owner->ToPlayer()).c_str());
}
return true;
}
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
handler->SetSentErrorMessage(true);
return false;
}
if (target)
{
target->ResetTalents(true);
target->SendTalentsInfoData(false);
ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS);
if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target)
handler->PSendSysMessage(LANG_RESET_TALENTS_ONLINE, handler->GetNameLink(target).c_str());
Pet* pet = target->GetPet();
Pet::resetTalentsForAllPetsOf(target, pet);
if (pet)
target->SendTalentsInfoData(true);
return true;
}
else if (targetGuid)
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
stmt->setUInt16(0, uint16(AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS));
stmt->setUInt32(1, GUID_LOPART(targetGuid));
CharacterDatabase.Execute(stmt);
std::string nameLink = handler->playerLink(targetName);
handler->PSendSysMessage(LANG_RESET_TALENTS_OFFLINE, nameLink.c_str());
return true;
}
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
handler->SetSentErrorMessage(true);
return false;
}
static bool HandleResetAllCommand(ChatHandler* handler, char const* args)
{
if (!*args)
return false;
std::string caseName = args;
AtLoginFlags atLogin;
// Command specially created as single command to prevent using short case names
if (caseName == "spells")
{
atLogin = AT_LOGIN_RESET_SPELLS;
sWorld->SendWorldText(LANG_RESETALL_SPELLS);
if (!handler->GetSession())
handler->SendSysMessage(LANG_RESETALL_SPELLS);
}
else if (caseName == "talents")
{
atLogin = AtLoginFlags(AT_LOGIN_RESET_TALENTS | AT_LOGIN_RESET_PET_TALENTS);
sWorld->SendWorldText(LANG_RESETALL_TALENTS);
if (!handler->GetSession())
handler->SendSysMessage(LANG_RESETALL_TALENTS);
}
else
{
handler->PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE, args);
handler->SetSentErrorMessage(true);
return false;
}
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ALL_AT_LOGIN_FLAGS);
stmt->setUInt16(0, uint16(atLogin));
CharacterDatabase.Execute(stmt);
TRINITY_READ_GUARD(HashMapHolder<Player>::LockType, *HashMapHolder<Player>::GetLock());
HashMapHolder<Player>::MapType const& plist = sObjectAccessor->GetPlayers();
for (HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
itr->second->SetAtLoginFlag(atLogin);
return true;
}
};
void AddSC_reset_commandscript()
{
new reset_commandscript();
}
+445
View File
@@ -0,0 +1,445 @@
/*
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.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, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
Name: server_commandscript
%Complete: 100
Comment: All server related commands
Category: commandscripts
EndScriptData */
#include "ScriptMgr.h"
#include "Chat.h"
#include "SystemConfig.h"
#include "Config.h"
#include "ObjectAccessor.h"
class server_commandscript : public CommandScript
{
public:
server_commandscript() : CommandScript("server_commandscript") { }
ChatCommand* GetCommands() const
{
static ChatCommand serverIdleRestartCommandTable[] =
{
{ "cancel", SEC_ADMINISTRATOR, true, &HandleServerShutDownCancelCommand, "", NULL },
{ "" , SEC_ADMINISTRATOR, true, &HandleServerIdleRestartCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand serverIdleShutdownCommandTable[] =
{
{ "cancel", SEC_ADMINISTRATOR, true, &HandleServerShutDownCancelCommand, "", NULL },
{ "" , SEC_ADMINISTRATOR, true, &HandleServerIdleShutDownCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand serverRestartCommandTable[] =
{
{ "cancel", SEC_ADMINISTRATOR, true, &HandleServerShutDownCancelCommand, "", NULL },
{ "" , SEC_ADMINISTRATOR, true, &HandleServerRestartCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand serverShutdownCommandTable[] =
{
{ "cancel", SEC_ADMINISTRATOR, true, &HandleServerShutDownCancelCommand, "", NULL },
{ "" , SEC_ADMINISTRATOR, true, &HandleServerShutDownCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand serverSetCommandTable[] =
{
{ "difftime", SEC_CONSOLE, true, &HandleServerSetDiffTimeCommand, "", NULL },
{ "loglevel", SEC_CONSOLE, true, &HandleServerSetLogLevelCommand, "", NULL },
{ "logfilelevel", SEC_CONSOLE, true, &HandleServerSetLogFileLevelCommand, "", NULL },
{ "motd", SEC_ADMINISTRATOR, true, &HandleServerSetMotdCommand, "", NULL },
{ "closed", SEC_ADMINISTRATOR, true, &HandleServerSetClosedCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand serverCommandTable[] =
{
{ "corpses", SEC_GAMEMASTER, true, &HandleServerCorpsesCommand, "", NULL },
{ "exit", SEC_CONSOLE, true, &HandleServerExitCommand, "", NULL },
{ "idlerestart", SEC_ADMINISTRATOR, true, NULL, "", serverIdleRestartCommandTable },
{ "idleshutdown", SEC_ADMINISTRATOR, true, NULL, "", serverIdleShutdownCommandTable },
{ "info", SEC_PLAYER, true, &HandleServerInfoCommand, "", NULL },
{ "motd", SEC_PLAYER, true, &HandleServerMotdCommand, "", NULL },
{ "plimit", SEC_ADMINISTRATOR, true, &HandleServerPLimitCommand, "", NULL },
{ "restart", SEC_ADMINISTRATOR, true, NULL, "", serverRestartCommandTable },
{ "shutdown", SEC_ADMINISTRATOR, true, NULL, "", serverShutdownCommandTable },
{ "set", SEC_ADMINISTRATOR, true, NULL, "", serverSetCommandTable },
{ "togglequerylog", SEC_CONSOLE, true, &HandleServerToggleQueryLogging, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand commandTable[] =
{
{ "server", SEC_ADMINISTRATOR, true, NULL, "", serverCommandTable },
{ NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
// Triggering corpses expire check in world
static bool HandleServerCorpsesCommand(ChatHandler* /*handler*/, char const* /*args*/)
{
sObjectAccessor->RemoveOldCorpses();
return true;
}
static bool HandleServerInfoCommand(ChatHandler* handler, char const* /*args*/)
{
uint32 playersNum = sWorld->GetPlayerCount();
uint32 maxPlayersNum = sWorld->GetMaxPlayerCount();
uint32 activeClientsNum = sWorld->GetActiveSessionCount();
uint32 queuedClientsNum = sWorld->GetQueuedSessionCount();
uint32 maxActiveClientsNum = sWorld->GetMaxActiveSessionCount();
uint32 maxQueuedClientsNum = sWorld->GetMaxQueuedSessionCount();
std::string uptime = secsToTimeString(sWorld->GetUptime());
uint32 updateTime = sWorld->GetUpdateTime();
handler->SendSysMessage(_FULLVERSION);
handler->PSendSysMessage(LANG_CONNECTED_PLAYERS, playersNum, maxPlayersNum);
handler->PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum);
handler->PSendSysMessage(LANG_UPTIME, uptime.c_str());
handler->PSendSysMessage(LANG_UPDATE_DIFF, updateTime);
// Can't use sWorld->ShutdownMsg here in case of console command
if (sWorld->IsShuttingDown())
handler->PSendSysMessage(LANG_SHUTDOWN_TIMELEFT, secsToTimeString(sWorld->GetShutDownTimeLeft()).c_str());
return true;
}
// Display the 'Message of the day' for the realm
static bool HandleServerMotdCommand(ChatHandler* handler, char const* /*args*/)
{
handler->PSendSysMessage(LANG_MOTD_CURRENT, sWorld->GetMotd());
return true;
}
static bool HandleServerPLimitCommand(ChatHandler* handler, char const* args)
{
if (*args)
{
char* paramStr = strtok((char*)args, " ");
if (!paramStr)
return false;
int32 limit = strlen(paramStr);
if (strncmp(paramStr, "player", limit) == 0)
sWorld->SetPlayerSecurityLimit(SEC_PLAYER);
else if (strncmp(paramStr, "moderator", limit) == 0)
sWorld->SetPlayerSecurityLimit(SEC_MODERATOR);
else if (strncmp(paramStr, "gamemaster", limit) == 0)
sWorld->SetPlayerSecurityLimit(SEC_GAMEMASTER);
else if (strncmp(paramStr, "administrator", limit) == 0)
sWorld->SetPlayerSecurityLimit(SEC_ADMINISTRATOR);
else if (strncmp(paramStr, "reset", limit) == 0)
{
sWorld->SetPlayerAmountLimit(ConfigMgr::GetIntDefault("PlayerLimit", 100));
sWorld->LoadDBAllowedSecurityLevel();
}
else
{
int32 value = atoi(paramStr);
if (value < 0)
sWorld->SetPlayerSecurityLimit(AccountTypes(-value));
else
sWorld->SetPlayerAmountLimit(uint32(value));
}
}
uint32 playerAmountLimit = sWorld->GetPlayerAmountLimit();
AccountTypes allowedAccountType = sWorld->GetPlayerSecurityLimit();
char const* secName = "";
switch (allowedAccountType)
{
case SEC_PLAYER:
secName = "Player";
break;
case SEC_MODERATOR:
secName = "Moderator";
break;
case SEC_GAMEMASTER:
secName = "Gamemaster";
break;
case SEC_ADMINISTRATOR:
secName = "Administrator";
break;
default:
secName = "<unknown>";
break;
}
handler->PSendSysMessage("Player limits: amount %u, min. security level %s.", playerAmountLimit, secName);
return true;
}
static bool HandleServerShutDownCancelCommand(ChatHandler* /*handler*/, char const* /*args*/)
{
sWorld->ShutdownCancel();
return true;
}
static bool HandleServerShutDownCommand(ChatHandler* /*handler*/, char const* args)
{
if (!*args)
return false;
char* timeStr = strtok((char*) args, " ");
char* exitCodeStr = strtok(NULL, "");
int32 time = atoi(timeStr);
// Prevent interpret wrong arg value as 0 secs shutdown time
if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0)
return false;
if (exitCodeStr)
{
int32 exitCode = atoi(exitCodeStr);
// Handle atoi() errors
if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[1] != '\0'))
return false;
// Exit code should be in range of 0-125, 126-255 is used
// in many shells for their own return codes and code > 255
// is not supported in many others
if (exitCode < 0 || exitCode > 125)
return false;
sWorld->ShutdownServ(time, 0, exitCode);
}
else
sWorld->ShutdownServ(time, 0, SHUTDOWN_EXIT_CODE);
return true;
}
static bool HandleServerRestartCommand(ChatHandler* /*handler*/, char const* args)
{
if (!*args)
return false;
char* timeStr = strtok((char*) args, " ");
char* exitCodeStr = strtok(NULL, "");
int32 time = atoi(timeStr);
// Prevent interpret wrong arg value as 0 secs shutdown time
if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0)
return false;
if (exitCodeStr)
{
int32 exitCode = atoi(exitCodeStr);
// Handle atoi() errors
if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[1] != '\0'))
return false;
// Exit code should be in range of 0-125, 126-255 is used
// in many shells for their own return codes and code > 255
// is not supported in many others
if (exitCode < 0 || exitCode > 125)
return false;
sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART, exitCode);
}
else
sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
return true;
}
static bool HandleServerIdleRestartCommand(ChatHandler* /*handler*/, char const* args)
{
if (!*args)
return false;
char* timeStr = strtok((char*) args, " ");
char* exitCodeStr = strtok(NULL, "");
int32 time = atoi(timeStr);
// Prevent interpret wrong arg value as 0 secs shutdown time
if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0)
return false;
if (exitCodeStr)
{
int32 exitCode = atoi(exitCodeStr);
// Handle atoi() errors
if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[1] != '\0'))
return false;
// Exit code should be in range of 0-125, 126-255 is used
// in many shells for their own return codes and code > 255
// is not supported in many others
if (exitCode < 0 || exitCode > 125)
return false;
sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART | SHUTDOWN_MASK_IDLE, exitCode);
}
else
sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART | SHUTDOWN_MASK_IDLE, RESTART_EXIT_CODE);
return true;
}
static bool HandleServerIdleShutDownCommand(ChatHandler* /*handler*/, char const* args)
{
if (!*args)
return false;
char* timeStr = strtok((char*) args, " ");
char* exitCodeStr = strtok(NULL, "");
int32 time = atoi(timeStr);
// Prevent interpret wrong arg value as 0 secs shutdown time
if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0)
return false;
if (exitCodeStr)
{
int32 exitCode = atoi(exitCodeStr);
// Handle atoi() errors
if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[1] != '\0'))
return false;
// Exit code should be in range of 0-125, 126-255 is used
// in many shells for their own return codes and code > 255
// is not supported in many others
if (exitCode < 0 || exitCode > 125)
return false;
sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, exitCode);
}
else
sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, SHUTDOWN_EXIT_CODE);
return true;
}
// Exit the realm
static bool HandleServerExitCommand(ChatHandler* handler, char const* /*args*/)
{
handler->SendSysMessage(LANG_COMMAND_EXIT);
World::StopNow(SHUTDOWN_EXIT_CODE);
return true;
}
// Define the 'Message of the day' for the realm
static bool HandleServerSetMotdCommand(ChatHandler* handler, char const* args)
{
sWorld->SetMotd(args);
handler->PSendSysMessage(LANG_MOTD_NEW, args);
return true;
}
// Set whether we accept new clients
static bool HandleServerSetClosedCommand(ChatHandler* handler, char const* args)
{
if (strncmp(args, "on", 3) == 0)
{
handler->SendSysMessage(LANG_WORLD_CLOSED);
sWorld->SetClosed(true);
return true;
}
else if (strncmp(args, "off", 4) == 0)
{
handler->SendSysMessage(LANG_WORLD_OPENED);
sWorld->SetClosed(false);
return true;
}
handler->SendSysMessage(LANG_USE_BOL);
handler->SetSentErrorMessage(true);
return false;
}
// Set the level of logging
static bool HandleServerSetLogFileLevelCommand(ChatHandler* /*handler*/, char const* args)
{
if (!*args)
return false;
char* newLevel = strtok((char*)args, " ");
if (!newLevel)
return false;
sLog->SetLogFileLevel(newLevel);
return true;
}
// Set the level of logging
static bool HandleServerSetLogLevelCommand(ChatHandler* /*handler*/, char const* args)
{
if (!*args)
return false;
char* newLevel = strtok((char*)args, " ");
if (!newLevel)
return false;
sLog->SetLogLevel(newLevel);
return true;
}
// set diff time record interval
static bool HandleServerSetDiffTimeCommand(ChatHandler* /*handler*/, char const* args)
{
if (!*args)
return false;
char* newTimeStr = strtok((char*)args, " ");
if (!newTimeStr)
return false;
int32 newTime = atoi(newTimeStr);
if (newTime < 0)
return false;
sWorld->SetRecordDiffInterval(newTime);
printf("Record diff every %u ms\n", newTime);
return true;
}
// toggle sql driver query logging
static bool HandleServerToggleQueryLogging(ChatHandler* handler, char const* /*args*/)
{
sLog->SetSQLDriverQueryLogging(!sLog->GetSQLDriverQueryLogging());
if (sLog->GetSQLDriverQueryLogging())
handler->PSendSysMessage(LANG_SQLDRIVER_QUERY_LOGGING_ENABLED);
else
handler->PSendSysMessage(LANG_SQLDRIVER_QUERY_LOGGING_DISABLED);
return true;
}
};
void AddSC_server_commandscript()
{
new server_commandscript();
}
+5 -4
View File
@@ -97,15 +97,16 @@ public:
if (!*args)
return false;
std::string name = args;
if (!sObjectMgr->DeleteGameTele(name))
// id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r
GameTele const* tele = handler->extractGameTeleFromLink((char*)args);
if (!tele)
{
handler->SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
handler->SetSentErrorMessage(true);
return false;
}
std::string name = tele->name;
sObjectMgr->DeleteGameTele(name);
handler->SendSysMessage(LANG_COMMAND_TP_DELETED);
return true;
}
@@ -64,7 +64,7 @@ public:
void Reset()
{
if(instance->GetBossState(DATA_PYROGAURD_EMBERSEER) == IN_PROGRESS)
if (instance->GetBossState(DATA_PYROGAURD_EMBERSEER) == IN_PROGRESS)
OpenDoors(false);
instance->SetBossState(DATA_PYROGAURD_EMBERSEER,NOT_STARTED);
// respawn any dead Blackhand Incarcerators
@@ -27,7 +27,11 @@ EndScriptData */
npc_shadowfang_prisoner
EndContentData */
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
#include "ScriptedEscortAI.h"
#include "shadowfang_keep.h"
@@ -193,8 +197,48 @@ public:
};
class spell_shadowfang_keep_haunting_spirits : public SpellScriptLoader
{
public:
spell_shadowfang_keep_haunting_spirits() : SpellScriptLoader("spell_shadowfang_keep_haunting_spirits") { }
class spell_shadowfang_keep_haunting_spirits_AuraScript : public AuraScript
{
PrepareAuraScript(spell_shadowfang_keep_haunting_spirits_AuraScript);
void CalcPeriodic(AuraEffect const* /*aurEff*/, bool& isPeriodic, int32& amplitude)
{
isPeriodic = true;
amplitude = (irand(0, 60) + 30) * IN_MILLISECONDS;
}
void HandleDummyTick(AuraEffect const* aurEff)
{
GetTarget()->CastSpell((Unit*)NULL, aurEff->GetAmount(), true);
}
void HandleUpdatePeriodic(AuraEffect* aurEff)
{
aurEff->CalculatePeriodic(GetCaster());
}
void Register()
{
DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_shadowfang_keep_haunting_spirits_AuraScript::CalcPeriodic, EFFECT_0, SPELL_AURA_DUMMY);
OnEffectPeriodic += AuraEffectPeriodicFn(spell_shadowfang_keep_haunting_spirits_AuraScript::HandleDummyTick, EFFECT_0, SPELL_AURA_DUMMY);
OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_shadowfang_keep_haunting_spirits_AuraScript::HandleUpdatePeriodic, EFFECT_0, SPELL_AURA_DUMMY);
}
};
AuraScript* GetAuraScript() const
{
return new spell_shadowfang_keep_haunting_spirits_AuraScript();
}
};
void AddSC_shadowfang_keep()
{
new npc_shadowfang_prisoner();
new npc_arugal_voidwalker();
new spell_shadowfang_keep_haunting_spirits();
}
@@ -23,7 +23,10 @@ SDComment:
SDCategory: Zul'Aman
EndScriptData */
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
#include "zulaman.h"
#define YELL_AGGRO "Da shadow gonna fall on you... "
@@ -47,54 +50,58 @@ EndScriptData */
//Defines for various powers he uses after using soul drain
//Druid
#define SPELL_DR_LIFEBLOOM 43421
#define SPELL_DR_THORNS 43420
#define SPELL_DR_MOONFIRE 43545
enum Spells
{
// Druid
SPELL_DR_THORNS = 43420,
SPELL_DR_LIFEBLOOM = 43421,
SPELL_DR_MOONFIRE = 43545,
//Hunter
#define SPELL_HU_EXPLOSIVE_TRAP 43444
#define SPELL_HU_FREEZING_TRAP 43447
#define SPELL_HU_SNAKE_TRAP 43449
// Hunter
SPELL_HU_EXPLOSIVE_TRAP = 43444,
SPELL_HU_FREEZING_TRAP = 43447,
SPELL_HU_SNAKE_TRAP = 43449,
//Mage
#define SPELL_MG_FIREBALL 41383
#define SPELL_MG_FROSTBOLT 43428
#define SPELL_MG_FROST_NOVA 43426
#define SPELL_MG_ICE_LANCE 43427
// Mage
SPELL_MG_FIREBALL = 41383,
SPELL_MG_FROST_NOVA = 43426,
SPELL_MG_ICE_LANCE = 43427,
SPELL_MG_FROSTBOLT = 43428,
//Paladin
#define SPELL_PA_CONSECRATION 43429
#define SPELL_PA_HOLY_LIGHT 43451
#define SPELL_PA_AVENGING_WRATH 43430
// Paladin
SPELL_PA_CONSECRATION = 43429,
SPELL_PA_AVENGING_WRATH = 43430,
SPELL_PA_HOLY_LIGHT = 43451,
//Priest
#define SPELL_PR_HEAL 41372
#define SPELL_PR_MIND_CONTROL 43550
#define SPELL_PR_MIND_BLAST 41374
#define SPELL_PR_SW_DEATH 41375
#define SPELL_PR_PSYCHIC_SCREAM 43432
#define SPELL_PR_PAIN_SUPP 44416
// Priest
SPELL_PR_HEAL = 41372,
SPELL_PR_MIND_BLAST = 41374,
SPELL_PR_SW_DEATH = 41375,
SPELL_PR_PSYCHIC_SCREAM = 43432,
SPELL_PR_MIND_CONTROL = 43550,
SPELL_PR_PAIN_SUPP = 44416,
//Rogue
#define SPELL_RO_BLIND 43433
#define SPELL_RO_SLICE_DICE 43457
#define SPELL_RO_WOUND_POISON 39665
// Rogue
SPELL_RO_BLIND = 43433,
SPELL_RO_SLICE_DICE = 43457,
SPELL_RO_WOUND_POISON = 43461,
//Shaman
#define SPELL_SH_FIRE_NOVA 43436
#define SPELL_SH_HEALING_WAVE 43548
#define SPELL_SH_CHAIN_LIGHT 43435
// Shaman
SPELL_SH_CHAIN_LIGHT = 43435,
SPELL_SH_FIRE_NOVA = 43436,
SPELL_SH_HEALING_WAVE = 43548,
//Warlock
#define SPELL_WL_CURSE_OF_DOOM 43439
#define SPELL_WL_RAIN_OF_FIRE 43440
#define SPELL_WL_UNSTABLE_AFFL 35183
// Warlock
SPELL_WL_CURSE_OF_DOOM = 43439,
SPELL_WL_RAIN_OF_FIRE = 43440,
SPELL_WL_UNSTABLE_AFFL = 43522,
SPELL_WL_UNSTABLE_AFFL_DISPEL = 43523,
//Warrior
#define SPELL_WR_SPELL_REFLECT 43443
#define SPELL_WR_WHIRLWIND 43442
#define SPELL_WR_MORTAL_STRIKE 43441
// Warrior
SPELL_WR_MORTAL_STRIKE = 43441,
SPELL_WR_WHIRLWIND = 43442,
SPELL_WR_SPELL_REFLECT = 43443
};
#define ORIENT 1.5696f
#define POS_Y 921.2795f
@@ -936,6 +943,40 @@ class boss_koragg : public CreatureScript
}
};
class spell_hexlord_unstable_affliction : public SpellScriptLoader
{
public:
spell_hexlord_unstable_affliction() : SpellScriptLoader("spell_hexlord_unstable_affliction") { }
class spell_hexlord_unstable_affliction_AuraScript : public AuraScript
{
PrepareAuraScript(spell_hexlord_unstable_affliction_AuraScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_WL_UNSTABLE_AFFL_DISPEL))
return false;
return true;
}
void HandleDispel(DispelInfo* dispelInfo)
{
if (Unit* caster = GetCaster())
caster->CastSpell(dispelInfo->GetDispeller(), SPELL_WL_UNSTABLE_AFFL_DISPEL, true, NULL, GetEffect(EFFECT_0));
}
void Register()
{
AfterDispel += AuraDispelFn(spell_hexlord_unstable_affliction_AuraScript::HandleDispel);
}
};
AuraScript* GetAuraScript() const
{
return new spell_hexlord_unstable_affliction_AuraScript();
}
};
void AddSC_boss_hex_lord_malacrass()
{
new boss_hexlord_malacrass();
@@ -947,5 +988,6 @@ void AddSC_boss_hex_lord_malacrass()
new boss_fenstalker();
new boss_koragg();
new boss_alyson_antille();
new spell_hexlord_unstable_affliction();
}
@@ -15,11 +15,13 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "blackfathom_deeps.h"
#include "ScriptedEscortAI.h"
enum eSpells
enum Spells
{
SPELL_BLESSING_OF_BLACKFATHOM = 8733,
SPELL_RAVAGE = 8391,
@@ -94,11 +96,11 @@ public:
uint32 frostNovaTimer;
uint32 frostBoltVolleyTimer;
bool bFlee;
bool Flee;
void Reset()
{
bFlee = false;
Flee = false;
ravageTimer = urand(5000, 8000);
frostNovaTimer = urand(9000, 12000);
@@ -140,7 +142,7 @@ public:
{
if (ravageTimer <= diff)
{
DoCast(me->getVictim(), SPELL_RAVAGE);
DoCastVictim(SPELL_RAVAGE);
ravageTimer = urand(9000, 14000);
} else ravageTimer -= diff;
break;
@@ -148,9 +150,9 @@ public:
case NPC_MURKSHALLOW_SOFTSHELL:
case NPC_BARBED_CRUSTACEAN:
{
if (!bFlee && HealthBelowPct(15))
if (!Flee && HealthBelowPct(15))
{
bFlee = true;
Flee = true;
me->DoFleeToGetAssistance();
}
break;
@@ -160,10 +162,7 @@ public:
if (frostBoltVolleyTimer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
{
if (target)
DoCast(target, SPELL_FROST_BOLT_VOLLEY);
}
DoCast(target, SPELL_FROST_BOLT_VOLLEY);
frostBoltVolleyTimer = urand(5000, 8000);
}
else frostBoltVolleyTimer -= diff;
@@ -190,7 +189,7 @@ public:
};
};
enum eMorridune
enum Morridune
{
SAY_MORRIDUNE_1 = -1048003,
SAY_MORRIDUNE_2 = -1048004
@@ -15,7 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "blackfathom_deeps.h"
enum Spells
@@ -42,14 +43,14 @@ public:
}
uint32 poisonCloudTimer;
bool bIsEnraged;
bool IsEnraged;
InstanceScript* instance;
void Reset()
{
poisonCloudTimer = urand(5000, 9000);
bIsEnraged = false;
IsEnraged = false;
if (instance)
instance->SetData(TYPE_AKU_MAI, NOT_STARTED);
}
@@ -77,10 +78,10 @@ public:
poisonCloudTimer = urand(25000, 50000);
} else poisonCloudTimer -= diff;
if (!bIsEnraged && HealthBelowPct(30))
if (!IsEnraged && HealthBelowPct(30))
{
DoCast(me, SPELL_FRENZIED_RAGE);
bIsEnraged = true;
IsEnraged = true;
}
DoMeleeAttackIfReady();
@@ -15,7 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "blackfathom_deeps.h"
enum Spells
@@ -15,7 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "blackfathom_deeps.h"
enum Spells
@@ -23,7 +23,8 @@ SDComment:
SDCategory: Blackfathom Deeps
EndScriptData */
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "blackfathom_deeps.h"
#define MAX_ENCOUNTER 4
@@ -15,42 +15,30 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "hyjal.h"
#include "hyjal_trash.h"
#define SPELL_CARRION_SWARM 31306
#define SPELL_SLEEP 31298
#define SPELL_VAMPIRIC_AURA 38196
#define SPELL_INFERNO 31299
enum Spells
{
SPELL_CARRION_SWARM = 31306,
SPELL_SLEEP = 31298,
SPELL_VAMPIRIC_AURA = 38196,
SPELL_INFERNO = 31299,
SPELL_IMMOLATION = 31303,
SPELL_INFERNO_EFFECT = 31302,
};
#define SAY_ONDEATH "The clock... is still... ticking."
#define SOUND_ONDEATH 10982
#define SAY_ONSLAY1 "Your hopes are lost!"
#define SAY_ONSLAY2 "Scream for me!"
#define SAY_ONSLAY3 "Pity, no time for a slow death!"
#define SOUND_ONSLAY1 10981
#define SOUND_ONSLAY2 11038
#define SOUND_ONSLAY3 11039
#define SAY_SWARM1 "The swarm is eager to feed!"
#define SAY_SWARM2 "Pestilence upon you!"
#define SOUND_SWARM1 10979
#define SOUND_SWARM2 11037
#define SAY_SLEEP1 "You look tired..."
#define SAY_SLEEP2 "Sweet dreams..."
#define SOUND_SLEEP1 10978
#define SOUND_SLEEP2 11545
#define SAY_INFERNO1 "Let fire rain from above!"
#define SAY_INFERNO2 "Earth and sky shall burn!"
#define SOUND_INFERNO1 10980
#define SOUND_INFERNO2 11036
#define SAY_ONAGGRO "You are defenders of a doomed world! Flee here, and perhaps you will prolong your pathetic lives!"
#define SOUND_ONAGGRO 10977
enum Texts
{
SAY_ONDEATH = 0,
SAY_ONSLAY = 1,
SAY_SWARM = 2,
SAY_SLEEP = 3,
SAY_INFERNO = 4,
SAY_ONAGGRO = 5,
};
class boss_anetheron : public CreatureScript
{
@@ -92,27 +80,12 @@ public:
{
if (instance && IsEvent)
instance->SetData(DATA_ANETHERONEVENT, IN_PROGRESS);
DoPlaySoundToSet(me, SOUND_ONAGGRO);
me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, 0);
Talk(SAY_ONAGGRO);
}
void KilledUnit(Unit* /*victim*/)
{
switch (urand(0, 2))
{
case 0:
DoPlaySoundToSet(me, SOUND_ONSLAY1);
me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, 0);
break;
case 1:
DoPlaySoundToSet(me, SOUND_ONSLAY2);
me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, 0);
break;
case 2:
DoPlaySoundToSet(me, SOUND_ONSLAY3);
me->MonsterYell(SAY_ONSLAY3, LANG_UNIVERSAL, 0);
break;
}
Talk(SAY_ONSLAY);
}
void WaypointReached(uint32 waypointId)
@@ -130,8 +103,7 @@ public:
hyjal_trashAI::JustDied(killer);
if (instance && IsEvent)
instance->SetData(DATA_ANETHERONEVENT, DONE);
DoPlaySoundToSet(me, SOUND_ONDEATH);
me->MonsterYell(SAY_ONDEATH, LANG_UNIVERSAL, 0);
Talk(SAY_ONDEATH);
}
void UpdateAI(const uint32 diff)
@@ -169,17 +141,7 @@ public:
DoCast(target, SPELL_CARRION_SWARM);
SwarmTimer = urand(45000, 60000);
switch (urand(0, 1))
{
case 0:
DoPlaySoundToSet(me, SOUND_SWARM1);
me->MonsterYell(SAY_SWARM1, LANG_UNIVERSAL, 0);
break;
case 1:
DoPlaySoundToSet(me, SOUND_SWARM2);
me->MonsterYell(SAY_SWARM2, LANG_UNIVERSAL, 0);
break;
}
Talk(SAY_SWARM);
} else SwarmTimer -= diff;
if (SleepTimer <= diff)
@@ -190,17 +152,7 @@ public:
target->CastSpell(target, SPELL_SLEEP, true);
}
SleepTimer = 60000;
switch (urand(0, 1))
{
case 0:
DoPlaySoundToSet(me, SOUND_SLEEP1);
me->MonsterYell(SAY_SLEEP1, LANG_UNIVERSAL, 0);
break;
case 1:
DoPlaySoundToSet(me, SOUND_SLEEP2);
me->MonsterYell(SAY_SLEEP2, LANG_UNIVERSAL, 0);
break;
}
Talk(SAY_SLEEP);
} else SleepTimer -= diff;
if (AuraTimer <= diff)
{
@@ -211,17 +163,7 @@ public:
{
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_INFERNO);
InfernoTimer = 45000;
switch (urand(0, 1))
{
case 0:
DoPlaySoundToSet(me, SOUND_INFERNO1);
me->MonsterYell(SAY_INFERNO1, LANG_UNIVERSAL, 0);
break;
case 1:
DoPlaySoundToSet(me, SOUND_INFERNO2);
me->MonsterYell(SAY_INFERNO2, LANG_UNIVERSAL, 0);
break;
}
Talk(SAY_INFERNO);
} else InfernoTimer -= diff;
DoMeleeAttackIfReady();
@@ -230,9 +172,6 @@ public:
};
#define SPELL_IMMOLATION 31303
#define SPELL_INFERNO_EFFECT 31302
class mob_towering_infernal : public CreatureScript
{
public:
@@ -23,56 +23,57 @@ SDComment: Doomfires not completely offlike due to core limitations for random m
SDCategory: Caverns of Time, Mount Hyjal
EndScriptData */
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "hyjal.h"
#include "SpellAuras.h"
#include "hyjal_trash.h"
//text id -1534018 are the text used when previous events complete. Not part of this script.
#define SAY_AGGRO -1534019
#define SAY_DOOMFIRE1 -1534020
#define SAY_DOOMFIRE2 -1534021
#define SAY_AIR_BURST1 -1534022
#define SAY_AIR_BURST2 -1534023
#define SAY_SLAY1 -1534024
#define SAY_SLAY2 -1534025
#define SAY_SLAY3 -1534026
#define SAY_ENRAGE -1534027
#define SAY_DEATH -1534028
#define SAY_SOUL_CHARGE1 -1534029
#define SAY_SOUL_CHARGE2 -1534030
enum Texts
{
SAY_AGGRO = 1,
SAY_DOOMFIRE = 2,
SAY_AIR_BURST = 3,
SAY_SLAY = 4,
SAY_ENRAGE = 5,
SAY_DEATH = 6,
SAY_SOUL_CHARGE = 7,
};
#define SPELL_DENOUEMENT_WISP 32124
#define SPELL_ANCIENT_SPARK 39349
#define SPELL_PROTECTION_OF_ELUNE 38528
enum Spells
{
SPELL_DENOUEMENT_WISP = 32124,
SPELL_ANCIENT_SPARK = 39349,
SPELL_PROTECTION_OF_ELUNE = 38528,
#define SPELL_DRAIN_WORLD_TREE 39140
#define SPELL_DRAIN_WORLD_TREE_2 39141
SPELL_DRAIN_WORLD_TREE = 39140,
SPELL_DRAIN_WORLD_TREE_2 = 39141,
#define SPELL_FINGER_OF_DEATH 31984
#define SPELL_HAND_OF_DEATH 35354
#define SPELL_AIR_BURST 32014
#define SPELL_GRIP_OF_THE_LEGION 31972
#define SPELL_DOOMFIRE_STRIKE 31903 //summons two creatures
#define SPELL_DOOMFIRE_SPAWN 32074
#define SPELL_DOOMFIRE 31945
#define SPELL_SOUL_CHARGE_YELLOW 32045
#define SPELL_SOUL_CHARGE_GREEN 32051
#define SPELL_SOUL_CHARGE_RED 32052
#define SPELL_UNLEASH_SOUL_YELLOW 32054
#define SPELL_UNLEASH_SOUL_GREEN 32057
#define SPELL_UNLEASH_SOUL_RED 32053
#define SPELL_FEAR 31970
SPELL_FINGER_OF_DEATH = 31984,
SPELL_HAND_OF_DEATH = 35354,
SPELL_AIR_BURST = 32014,
SPELL_GRIP_OF_THE_LEGION = 31972,
SPELL_DOOMFIRE_STRIKE = 31903, //summons two creatures
SPELL_DOOMFIRE_SPAWN = 32074,
SPELL_DOOMFIRE = 31945,
SPELL_SOUL_CHARGE_YELLOW = 32045,
SPELL_SOUL_CHARGE_GREEN = 32051,
SPELL_SOUL_CHARGE_RED = 32052,
SPELL_UNLEASH_SOUL_YELLOW = 32054,
SPELL_UNLEASH_SOUL_GREEN = 32057,
SPELL_UNLEASH_SOUL_RED = 32053,
SPELL_FEAR = 31970,
};
#define CREATURE_ARCHIMONDE 17968
#define CREATURE_DOOMFIRE 18095
#define CREATURE_DOOMFIRE_SPIRIT 18104
#define CREATURE_ANCIENT_WISP 17946
#define CREATURE_CHANNEL_TARGET 22418
enum Summons
{
CREATURE_DOOMFIRE = 18095,
CREATURE_DOOMFIRE_SPIRIT = 18104,
CREATURE_ANCIENT_WISP = 17946,
CREATURE_CHANNEL_TARGET = 22418,
};
#define NORDRASSIL_X 5503.713f
#define NORDRASSIL_Y -3523.436f
#define NORDRASSIL_Z 1608.781f
Position const NordrassilLoc = {5503.713f, -3523.436f, 1608.781f, 0.0f};
class mob_ancient_wisp : public CreatureScript
{
@@ -258,11 +259,11 @@ public:
uint32 GripOfTheLegionTimer;
uint32 DoomfireTimer;
uint32 SoulChargeTimer;
uint32 SoulChargeCount;
uint8 SoulChargeCount;
uint32 MeleeRangeCheckTimer;
uint32 HandOfDeathTimer;
uint32 SummonWispTimer;
uint32 WispCount;
uint8 WispCount;
uint32 EnrageTimer;
uint32 CheckDistanceTimer;
@@ -303,7 +304,7 @@ public:
void EnterCombat(Unit* /*who*/)
{
me->InterruptSpell(CURRENT_CHANNELED_SPELL);
DoScriptText(SAY_AGGRO, me);
Talk(SAY_AGGRO);
DoZoneInCombat();
if (instance)
@@ -312,7 +313,7 @@ public:
void KilledUnit(Unit* victim)
{
DoScriptText(RAND(SAY_SLAY1, SAY_SLAY2, SAY_SLAY3), me);
Talk(SAY_SLAY);
if (victim && (victim->GetTypeId() == TYPEID_PLAYER))
GainSoulCharge(CAST_PLR(victim));
@@ -346,7 +347,7 @@ public:
void JustDied(Unit* killer)
{
hyjal_trashAI::JustDied(killer);
DoScriptText(SAY_DEATH, me);
Talk(SAY_DEATH);
if (instance)
instance->SetData(DATA_ARCHIMONDEEVENT, DONE);
@@ -488,7 +489,7 @@ public:
{
if (!IsChanneling)
{
Creature* temp = me->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 1200000);
Creature* temp = me->SummonCreature(CREATURE_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 1200000);
if (temp)
WorldTreeGUID = temp->GetGUID();
@@ -525,14 +526,14 @@ public:
me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MoveIdle();
Enraged = true;
DoScriptText(SAY_ENRAGE, me);
Talk(SAY_ENRAGE);
}
} else EnrageTimer -= diff;
if (CheckDistanceTimer <= diff)
{
// To simplify the check, we simply summon a Creature in the location and then check how far we are from the creature
Creature* Check = me->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 2000);
Creature* Check = me->SummonCreature(CREATURE_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 2000);
if (Check)
{
Check->SetVisible(false);
@@ -542,7 +543,7 @@ public:
me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MoveIdle();
Enraged = true;
DoScriptText(SAY_ENRAGE, me);
Talk(SAY_ENRAGE);
}
}
CheckDistanceTimer = 5000;
@@ -598,11 +599,7 @@ public:
if (AirBurstTimer <= diff)
{
if (urand(0, 1))
DoScriptText(SAY_AIR_BURST1, me);
else
DoScriptText(SAY_AIR_BURST2, me);
Talk(SAY_AIR_BURST);
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 1), SPELL_AIR_BURST);//not on tank
AirBurstTimer = urand(25000, 40000);
} else AirBurstTimer -= diff;
@@ -615,11 +612,7 @@ public:
if (DoomfireTimer <= diff)
{
if (urand(0, 1))
DoScriptText(SAY_DOOMFIRE1, me);
else
DoScriptText(SAY_DOOMFIRE2, me);
Talk(SAY_DOOMFIRE);
Unit* temp = SelectTarget(SELECT_TARGET_RANDOM, 1);
if (!temp)
temp = me->getVictim();
@@ -15,33 +15,31 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "hyjal.h"
#include "hyjal_trash.h"
#define SPELL_RAIN_OF_FIRE 31340
#define SPELL_DOOM 31347
#define SPELL_HOWL_OF_AZGALOR 31344
#define SPELL_CLEAVE 31345
#define SPELL_BERSERK 26662
enum Spells
{
SPELL_RAIN_OF_FIRE = 31340,
SPELL_DOOM = 31347,
SPELL_HOWL_OF_AZGALOR = 31344,
SPELL_CLEAVE = 31345,
SPELL_BERSERK = 26662,
#define SAY_ONDEATH "Your time is almost... up"
#define SOUND_ONDEATH 11002
SPELL_THRASH = 12787,
SPELL_CRIPPLE = 31406,
SPELL_WARSTOMP = 31408,
};
#define SAY_ONSLAY1 "Reesh, hokta!"
#define SAY_ONSLAY2 "Don't fight it"
#define SAY_ONSLAY3 "No one is going to save you"
#define SOUND_ONSLAY1 11001
#define SOUND_ONSLAY2 11048
#define SOUND_ONSLAY3 11047
#define SAY_DOOM1 "Just a taste... of what awaits you"
#define SAY_DOOM2 "Suffer you despicable insect!"
#define SOUND_DOOM1 11046
#define SOUND_DOOM2 11000
#define SAY_ONAGGRO "Abandon all hope! The legion has returned to finish what was begun so many years ago. This time there will be no escape!"
#define SOUND_ONAGGRO 10999
enum Texts
{
SAY_ONDEATH = 0,
SAY_ONSLAY = 1,
SAY_DOOM = 2, // Not used?
SAY_ONAGGRO = 3,
};
class boss_azgalor : public CreatureScript
{
@@ -88,27 +86,12 @@ public:
{
if (instance && IsEvent)
instance->SetData(DATA_AZGALOREVENT, IN_PROGRESS);
DoPlaySoundToSet(me, SOUND_ONAGGRO);
me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, 0);
Talk(SAY_ONAGGRO);
}
void KilledUnit(Unit* /*victim*/)
{
switch (urand(0, 2))
{
case 0:
DoPlaySoundToSet(me, SOUND_ONSLAY1);
me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, 0);
break;
case 1:
DoPlaySoundToSet(me, SOUND_ONSLAY2);
me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, 0);
break;
case 2:
DoPlaySoundToSet(me, SOUND_ONSLAY3);
me->MonsterYell(SAY_ONSLAY3, LANG_UNIVERSAL, 0);
break;
}
Talk(SAY_ONSLAY);
}
void WaypointReached(uint32 waypointId)
@@ -126,7 +109,7 @@ public:
hyjal_trashAI::JustDied(killer);
if (instance && IsEvent)
instance->SetData(DATA_AZGALOREVENT, DONE);
DoPlaySoundToSet(me, SOUND_ONDEATH);
Talk(SAY_ONDEATH);
}
void UpdateAI(const uint32 diff)
@@ -196,10 +179,6 @@ public:
};
#define SPELL_THRASH 12787
#define SPELL_CRIPPLE 31406
#define SPELL_WARSTOMP 31408
class mob_lesser_doomguard : public CreatureScript
{
public:
@@ -15,30 +15,32 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellAuraEffects.h"
#include "SpellScript.h"
#include "hyjal.h"
#include "hyjal_trash.h"
#define SPELL_CLEAVE 31436
#define SPELL_WARSTOMP 31480
#define SPELL_MARK 31447
enum Spells
{
SPELL_CLEAVE = 31436,
SPELL_WARSTOMP = 31480,
SPELL_MARK = 31447,
SPELL_MARK_DAMAGE = 31463
};
#define SOUND_ONDEATH 11018
enum Texts
{
SAY_ONSLAY = 0,
SAY_MARK = 1,
SAY_ONAGGRO = 2,
};
#define SAY_ONSLAY1 "Shaza-Kiel!"
#define SAY_ONSLAY2 "You... are nothing!"
#define SAY_ONSLAY3 "Miserable nuisance!"
#define SOUND_ONSLAY1 11017
#define SOUND_ONSLAY2 11053
#define SOUND_ONSLAY3 11054
#define SAY_MARK1 "Your death will be a painful one."
#define SAY_MARK2 "You... are marked."
#define SOUND_MARK1 11016
#define SOUND_MARK2 11052
#define SAY_ONAGGRO "Cry for mercy! Your meaningless lives will soon be forfeit."
#define SOUND_ONAGGRO 11015
enum Sounds
{
SOUND_ONDEATH = 11018,
};
class boss_kazrogal : public CreatureScript
{
@@ -80,27 +82,12 @@ public:
{
if (instance && IsEvent)
instance->SetData(DATA_KAZROGALEVENT, IN_PROGRESS);
DoPlaySoundToSet(me, SOUND_ONAGGRO);
me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, 0);
Talk(SAY_ONAGGRO);
}
void KilledUnit(Unit* /*victim*/)
{
switch (urand(0, 2))
{
case 0:
DoPlaySoundToSet(me, SOUND_ONSLAY1);
me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, 0);
break;
case 1:
DoPlaySoundToSet(me, SOUND_ONSLAY2);
me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, 0);
break;
case 2:
DoPlaySoundToSet(me, SOUND_ONSLAY3);
me->MonsterYell(SAY_ONSLAY3, LANG_UNIVERSAL, 0);
break;
}
Talk(SAY_ONSLAY);
}
void WaypointReached(uint32 waypointId)
@@ -162,37 +149,15 @@ public:
WarStompTimer = 60000;
} else WarStompTimer -= diff;
if (me->HasAura(SPELL_MARK))
me->RemoveAurasDueToSpell(SPELL_MARK);
if (MarkTimer <= diff)
{
//cast dummy, useful for bos addons
me->CastCustomSpell(me, SPELL_MARK, NULL, NULL, NULL, false, NULL, NULL, me->GetGUID());
DoCastAOE(SPELL_MARK);
std::list<HostileReference*> t_list = me->getThreatManager().getThreatList();
for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
{
Unit* target = Unit::GetUnit(*me, (*itr)->getUnitGuid());
if (target && target->GetTypeId() == TYPEID_PLAYER && target->getPowerType() == POWER_MANA)
{
target->CastSpell(target, SPELL_MARK, true);//only cast on mana users
}
}
MarkTimerBase -= 5000;
if (MarkTimerBase < 5500)
MarkTimerBase = 5500;
MarkTimer = MarkTimerBase;
switch (urand(0, 2))
{
case 0:
DoPlaySoundToSet(me, SOUND_MARK1);
me->MonsterYell(SAY_MARK1, LANG_UNIVERSAL, 0);
break;
case 1:
DoPlaySoundToSet(me, SOUND_MARK2);
me->MonsterYell(SAY_MARK2, LANG_UNIVERSAL, 0);
break;
}
Talk(SAY_MARK);
} else MarkTimer -= diff;
DoMeleeAttackIfReady();
@@ -201,7 +166,79 @@ public:
};
class MarkTargetFilter
{
public:
bool operator()(WorldObject* target) const
{
if (Unit* unit = target->ToUnit())
return unit->getPowerType() != POWER_MANA;
return false;
}
};
class spell_mark_of_kazrogal : public SpellScriptLoader
{
public:
spell_mark_of_kazrogal() : SpellScriptLoader("spell_mark_of_kazrogal") { }
class spell_mark_of_kazrogal_SpellScript : public SpellScript
{
PrepareSpellScript(spell_mark_of_kazrogal_SpellScript);
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(MarkTargetFilter());
}
void Register()
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mark_of_kazrogal_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
class spell_mark_of_kazrogal_AuraScript : public AuraScript
{
PrepareAuraScript(spell_mark_of_kazrogal_AuraScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_MARK_DAMAGE))
return false;
return true;
}
void OnPeriodic(AuraEffect const* aurEff)
{
Unit* target = GetTarget();
if (target->GetPower(POWER_MANA) == 0)
{
target->CastSpell(target, SPELL_MARK_DAMAGE, true, NULL, aurEff);
// Remove aura
SetDuration(0);
}
}
void Register()
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_mark_of_kazrogal_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_MANA_LEECH);
}
};
SpellScript* GetSpellScript() const
{
return new spell_mark_of_kazrogal_SpellScript();
}
AuraScript* GetAuraScript() const
{
return new spell_mark_of_kazrogal_AuraScript();
}
};
void AddSC_boss_kazrogal()
{
new boss_kazrogal();
new spell_mark_of_kazrogal();
}
@@ -15,36 +15,27 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "hyjal.h"
#include "hyjal_trash.h"
#define SPELL_FROST_ARMOR 31256
#define SPELL_DEATH_AND_DECAY 31258
enum Spells
{
SPELL_FROST_ARMOR = 31256,
SPELL_DEATH_AND_DECAY = 31258,
SPELL_FROST_NOVA = 31250,
SPELL_ICEBOLT = 31249,
};
#define SPELL_FROST_NOVA 31250
#define SPELL_ICEBOLT 31249
#define SAY_ONDEATH "You have won this battle, but not... the... war"
#define SOUND_ONDEATH 11026
#define SAY_ONSLAY1 "All life must perish!"
#define SAY_ONSLAY2 "Victory to the Legion!"
#define SOUND_ONSLAY1 11025
#define SOUND_ONSLAY2 11057
#define SAY_DECAY1 "Crumble and rot!"
#define SAY_DECAY2 "Ashes to ashes, dust to dust"
#define SOUND_DECAY1 11023
#define SOUND_DECAY2 11055
#define SAY_NOVA1 "Succumb to the icy chill... of death!"
#define SAY_NOVA2 "It will be much colder in your grave"
#define SOUND_NOVA1 11024
#define SOUND_NOVA2 11058
#define SAY_ONAGGRO "The Legion's final conquest has begun! Once again the subjugation of this world is within our grasp. Let none survive!"
#define SOUND_ONAGGRO 11022
enum Texts
{
SAY_ONDEATH = 0,
SAY_ONSLAY = 1,
SAY_DECAY = 2,
SAY_NOVA = 3,
SAY_ONAGGRO = 4,
};
class boss_rage_winterchill : public CreatureScript
{
@@ -86,23 +77,12 @@ public:
{
if (instance && IsEvent)
instance->SetData(DATA_RAGEWINTERCHILLEVENT, IN_PROGRESS);
DoPlaySoundToSet(me, SOUND_ONAGGRO);
me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, 0);
Talk(SAY_ONAGGRO);
}
void KilledUnit(Unit* /*victim*/)
{
switch (urand(0, 1))
{
case 0:
DoPlaySoundToSet(me, SOUND_ONSLAY1);
me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, 0);
break;
case 1:
DoPlaySoundToSet(me, SOUND_ONSLAY2);
me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, 0);
break;
}
Talk(SAY_ONSLAY);
}
void WaypointReached(uint32 waypointId)
@@ -120,8 +100,7 @@ public:
hyjal_trashAI::JustDied(killer);
if (instance && IsEvent)
instance->SetData(DATA_RAGEWINTERCHILLEVENT, DONE);
DoPlaySoundToSet(me, SOUND_ONDEATH);
me->MonsterYell(SAY_ONDEATH, LANG_UNIVERSAL, 0);
Talk(SAY_ONDEATH);
}
void UpdateAI(const uint32 diff)
@@ -162,33 +141,13 @@ public:
{
DoCast(me->getVictim(), SPELL_DEATH_AND_DECAY);
DecayTimer = 60000+rand()%20000;
switch (urand(0, 1))
{
case 0:
DoPlaySoundToSet(me, SOUND_DECAY1);
me->MonsterYell(SAY_DECAY1, LANG_UNIVERSAL, 0);
break;
case 1:
DoPlaySoundToSet(me, SOUND_DECAY2);
me->MonsterYell(SAY_DECAY2, LANG_UNIVERSAL, 0);
break;
}
Talk(SAY_DECAY);
} else DecayTimer -= diff;
if (NovaTimer <= diff)
{
DoCast(me->getVictim(), SPELL_FROST_NOVA);
NovaTimer = 30000+rand()%15000;
switch (urand(0, 1))
{
case 0:
DoPlaySoundToSet(me, SOUND_NOVA1);
me->MonsterYell(SAY_NOVA1, LANG_UNIVERSAL, 0);
break;
case 1:
DoPlaySoundToSet(me, SOUND_NOVA2);
me->MonsterYell(SAY_NOVA2, LANG_UNIVERSAL, 0);
break;
}
Talk(SAY_NOVA);
} else NovaTimer -= diff;
if (IceboltTimer <= diff)
{
@@ -29,7 +29,9 @@ npc_thrall
npc_tyrande_whisperwind
EndContentData */
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "hyjalAI.h"
#define GOSSIP_ITEM_BEGIN_ALLY "My companions and I are with you, Lady Proudmoore."
@@ -21,7 +21,7 @@
#define ERROR_INST_DATA "TSCR: Instance data not set properly for Mount Hyjal. Encounters will be buggy."
enum eTypes
enum Types
{
WORLD_STATE_WAVES = 2842,
WORLD_STATE_ENEMY = 2453,
@@ -23,17 +23,22 @@ SDComment:
SDCategory: Caverns of Time, Mount Hyjal
EndScriptData */
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedEscortAI.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "Cell.h"
#include "CellImpl.h"
#include "hyjalAI.h"
#include "hyjal_trash.h"
#include "MapManager.h"
#include "Language.h"
#include "Chat.h"
#include "Object.h"
#define SPAWN_GARG_GATE 0
#define SPAWN_WYRM_GATE 1
#define SPAWN_NEAR_TOWER 2
enum Spawns
{
SPAWN_GARG_GATE = 0,
SPAWN_WYRM_GATE = 1,
SPAWN_NEAR_TOWER = 2,
};
#define YELL_HURRY "Hurry, we don't have much time"
@@ -24,43 +24,49 @@
#define HYJAL_AI_MAX_SPELLS 3
// Trash Mobs summoned in waves
#define NECROMANCER 17899//done
#define ABOMINATION 17898//done
#define GHOUL 17895//done
#define BANSHEE 17905//done
#define CRYPT_FIEND 17897//done
#define GARGOYLE 17906//done
#define FROST_WYRM 17907//done
#define GIANT_INFERNAL 17908//done
#define FEL_STALKER 17916//done
enum CreaturesIds
{
// Trash Mobs summoned in waves
NECROMANCER = 17899,
ABOMINATION = 17898,
GHOUL = 17895,
BANSHEE = 17905,
CRYPT_FIEND = 17897,
GARGOYLE = 17906,
FROST_WYRM = 17907,
GIANT_INFERNAL = 17908,
FEL_STALKER = 17916,
#define JAINA 17772
#define THRALL 17852
#define TYRANDE 17948
JAINA = 17772,
THRALL = 17852,
TYRANDE = 17948,
#define ANCIENT_VEIN 185557
#define FLAMEOBJECT 182592
ANCIENT_VEIN = 185557,
FLAMEOBJECT = 182592,
// Bosses summoned after every 8 waves
#define RAGE_WINTERCHILL 17767
#define ANETHERON 17808
#define KAZROGAL 17888
#define AZGALOR 17842
#define ARCHIMONDE 17968
// Bosses summoned after every 8 waves
RAGE_WINTERCHILL = 17767,
ANETHERON = 17808,
KAZROGAL = 17888,
AZGALOR = 17842,
ARCHIMONDE = 17968,
};
#define SPELL_TELEPORT_VISUAL 41232
#define SPELL_MASS_TELEPORT 16807
enum SpellIds
{
SPELL_TELEPORT_VISUAL = 41232,
SPELL_MASS_TELEPORT = 16807,
//Spells for Jaina
#define SPELL_BRILLIANCE_AURA 31260 // The database must handle this spell via creature_addon(it should, but is removed in evade..)
#define SPELL_BLIZZARD 31266
#define SPELL_PYROBLAST 31263
#define SPELL_SUMMON_ELEMENTALS 31264
//Spells for Jaina
SPELL_BRILLIANCE_AURA = 31260, // The database must handle this spell via creature_addon(it should, but is removed in evade..)
SPELL_BLIZZARD = 31266,
SPELL_PYROBLAST = 31263,
SPELL_SUMMON_ELEMENTALS = 31264,
//Thrall spells
#define SPELL_CHAIN_LIGHTNING 31330
#define SPELL_SUMMON_DIRE_WOLF 31331
//Thrall spells
SPELL_CHAIN_LIGHTNING = 31330,
SPELL_SUMMON_DIRE_WOLF = 31331,
};
struct Wave
{
@@ -15,16 +15,35 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "hyjal.h"
#include "hyjal_trash.h"
#include "hyjalAI.h"
#define SPELL_METEOR 33814 //infernal visual
#define SPELL_IMMOLATION 37059
#define SPELL_FLAME_BUFFET 31724
#define NPC_TRIGGER 21987 //World Trigger (Tiny)
#define MODEL_INVIS 11686 //invisible model
enum Spells
{
SPELL_METEOR = 33814, //infernal visual
SPELL_IMMOLATION = 37059,
SPELL_FLAME_BUFFET = 31724,
NPC_TRIGGER = 21987, //World Trigger (Tiny)
MODEL_INVIS = 11686, //invisible model
SPELL_DISEASE_CLOUD = 31607,
SPELL_KNOCKDOWN = 31610,
SPELL_FRENZY = 31540,
SPELL_RAISE_DEAD_1 = 31617,
SPELL_RAISE_DEAD_2 = 31624,
SPELL_RAISE_DEAD_3 = 31625,
SPELL_SHADOW_BOLT = 31627,
SPELL_BANSHEE_CURSE = 31651,
SPELL_BANSHEE_WAIL = 38183,
SPELL_ANTI_MAGIC_SHELL = 31662,
SPELL_WEB = 28991,
SPELL_MANA_BURN = 31729,
SPELL_FROST_BREATH = 31688,
SPELL_GARGOYLE_STRIKE = 31664,
SPELL_EXPLODING_SHOT = 7896,
};
float HordeWPs[8][3]=//basic waypoints from spawn to leader
{
@@ -522,9 +541,6 @@ public:
}
};
#define SPELL_DISEASE_CLOUD 31607
#define SPELL_KNOCKDOWN 31610
class mob_abomination : public CreatureScript
{
public:
@@ -623,8 +639,6 @@ public:
};
#define SPELL_FRENZY 31540
class mob_ghoul : public CreatureScript
{
public:
@@ -727,11 +741,6 @@ public:
};
#define SPELL_RAISE_DEAD_1 31617
#define SPELL_RAISE_DEAD_2 31624
#define SPELL_RAISE_DEAD_3 31625
#define SPELL_SHADOW_BOLT 31627
class mob_necromancer : public CreatureScript
{
public:
@@ -859,10 +868,6 @@ public:
};
#define SPELL_BANSHEE_CURSE 31651
#define SPELL_BANSHEE_WAIL 38183
#define SPELL_ANTI_MAGIC_SHELL 31662
class mob_banshee : public CreatureScript
{
public:
@@ -966,8 +971,6 @@ public:
};
#define SPELL_WEB 28991
class mob_crypt_fiend : public CreatureScript
{
public:
@@ -1058,8 +1061,6 @@ public:
};
#define SPELL_MANA_BURN 31729
class mob_fel_stalker : public CreatureScript
{
public:
@@ -1150,8 +1151,6 @@ public:
};
#define SPELL_FROST_BREATH 31688
class mob_frost_wyrm : public CreatureScript
{
public:
@@ -1264,8 +1263,6 @@ public:
};
#define SPELL_GARGOYLE_STRIKE 31664
class mob_gargoyle : public CreatureScript
{
public:
@@ -1402,8 +1399,6 @@ public:
};
#define SPELL_EXPLODING_SHOT 7896
class alliance_rifleman : public CreatureScript
{
public:
@@ -23,15 +23,16 @@ SDComment: Instance Data Scripts and functions to acquire mobs and set encounter
SDCategory: Caverns of Time, Mount Hyjal
EndScriptData */
#include "ScriptPCH.h"
#include "hyjal.h"
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "ScriptedCreature.h"
#include "hyjal_trash.h"
enum eEnums
enum Misc
{
MAX_ENCOUNTER = 5,
GO_ANCIENT_GEM = 185557
GO_ANCIENT_GEM = 185557,
};
/* Battle of Mount Hyjal encounters:
0 - Rage Winterchill event
@@ -23,7 +23,8 @@ SDComment:
SDCategory: Maraudon
EndScriptData */
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
enum Spells
{
@@ -46,15 +47,15 @@ public:
{
celebras_the_cursedAI(Creature* creature) : ScriptedAI(creature) {}
uint32 Wrath_Timer;
uint32 EntanglingRoots_Timer;
uint32 CorruptForces_Timer;
uint32 WrathTimer;
uint32 EntanglingRootsTimer;
uint32 CorruptForcesTimer;
void Reset()
{
Wrath_Timer = 8000;
EntanglingRoots_Timer = 2000;
CorruptForces_Timer = 30000;
WrathTimer = 8000;
EntanglingRootsTimer = 2000;
CorruptForcesTimer = 30000;
}
void EnterCombat(Unit* /*who*/) { }
@@ -70,32 +71,30 @@ public:
return;
//Wrath
if (Wrath_Timer <= diff)
if (WrathTimer <= diff)
{
Unit* target = NULL;
target = SelectTarget(SELECT_TARGET_RANDOM, 0);
if (target)
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
DoCast(target, SPELL_WRATH);
Wrath_Timer = 8000;
WrathTimer = 8000;
}
else Wrath_Timer -= diff;
else WrathTimer -= diff;
//EntanglingRoots
if (EntanglingRoots_Timer <= diff)
if (EntanglingRootsTimer <= diff)
{
DoCast(me->getVictim(), SPELL_ENTANGLINGROOTS);
EntanglingRoots_Timer = 20000;
DoCastVictim(SPELL_ENTANGLINGROOTS);
EntanglingRootsTimer = 20000;
}
else EntanglingRoots_Timer -= diff;
else EntanglingRootsTimer -= diff;
//CorruptForces
if (CorruptForces_Timer <= diff)
if (CorruptForcesTimer <= diff)
{
me->InterruptNonMeleeSpells(false);
DoCast(me, SPELL_CORRUPT_FORCES);
CorruptForces_Timer = 20000;
CorruptForcesTimer = 20000;
}
else CorruptForces_Timer -= diff;
else CorruptForcesTimer -= diff;
DoMeleeAttackIfReady();
}
@@ -23,7 +23,8 @@ SDComment:
SDCategory: Maraudon
EndScriptData */
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
enum Spells
{
@@ -46,15 +47,15 @@ public:
{
boss_landslideAI(Creature* creature) : ScriptedAI(creature) {}
uint32 KnockAway_Timer;
uint32 Trample_Timer;
uint32 Landslide_Timer;
uint32 KnockAwayTimer;
uint32 TrampleTimer;
uint32 LandslideTimer;
void Reset()
{
KnockAway_Timer = 8000;
Trample_Timer = 2000;
Landslide_Timer = 0;
KnockAwayTimer = 8000;
TrampleTimer = 2000;
LandslideTimer = 0;
}
void EnterCombat(Unit* /*who*/)
@@ -66,32 +67,32 @@ public:
if (!UpdateVictim())
return;
//KnockAway_Timer
if (KnockAway_Timer <= diff)
//KnockAwayTimer
if (KnockAwayTimer <= diff)
{
DoCast(me->getVictim(), SPELL_KNOCKAWAY);
KnockAway_Timer = 15000;
DoCastVictim(SPELL_KNOCKAWAY);
KnockAwayTimer = 15000;
}
else KnockAway_Timer -= diff;
else KnockAwayTimer -= diff;
//Trample_Timer
if (Trample_Timer <= diff)
//TrampleTimer
if (TrampleTimer <= diff)
{
DoCast(me, SPELL_TRAMPLE);
Trample_Timer = 8000;
TrampleTimer = 8000;
}
else Trample_Timer -= diff;
else TrampleTimer -= diff;
//Landslide
if (HealthBelowPct(50))
{
if (Landslide_Timer <= diff)
if (LandslideTimer <= diff)
{
me->InterruptNonMeleeSpells(false);
DoCast(me, SPELL_LANDSLIDE);
Landslide_Timer = 60000;
LandslideTimer = 60000;
}
else Landslide_Timer -= diff;
else LandslideTimer -= diff;
}
DoMeleeAttackIfReady();
@@ -23,7 +23,9 @@ SDComment:
SDCategory: Maraudon
EndScriptData */
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
enum Spells
{
SPELL_TOXICVOLLEY = 21687,
@@ -44,24 +46,22 @@ public:
{
boss_noxxionAI(Creature* creature) : ScriptedAI(creature) {}
uint32 ToxicVolley_Timer;
uint32 Uppercut_Timer;
uint32 Adds_Timer;
uint32 Invisible_Timer;
uint32 ToxicVolleyTimer;
uint32 UppercutTimer;
uint32 AddsTimer;
uint32 InvisibleTimer;
bool Invisible;
void Reset()
{
ToxicVolley_Timer = 7000;
Uppercut_Timer = 16000;
Adds_Timer = 19000;
Invisible_Timer = 15000; //Too much too low?
ToxicVolleyTimer = 7000;
UppercutTimer = 16000;
AddsTimer = 19000;
InvisibleTimer = 15000; //Too much too low?
Invisible = false;
}
void EnterCombat(Unit* /*who*/)
{
}
void EnterCombat(Unit* /*who*/) {}
void SummonAdds(Unit* victim)
{
@@ -71,7 +71,7 @@ public:
void UpdateAI(const uint32 diff)
{
if (Invisible && Invisible_Timer <= diff)
if (Invisible && InvisibleTimer <= diff)
{
//Become visible again
me->setFaction(14);
@@ -83,7 +83,7 @@ public:
}
else if (Invisible)
{
Invisible_Timer -= diff;
InvisibleTimer -= diff;
//Do nothing while invisible
return;
}
@@ -92,24 +92,24 @@ public:
if (!UpdateVictim())
return;
//ToxicVolley_Timer
if (ToxicVolley_Timer <= diff)
//ToxicVolleyTimer
if (ToxicVolleyTimer <= diff)
{
DoCast(me->getVictim(), SPELL_TOXICVOLLEY);
ToxicVolley_Timer = 9000;
DoCastVictim(SPELL_TOXICVOLLEY);
ToxicVolleyTimer = 9000;
}
else ToxicVolley_Timer -= diff;
else ToxicVolleyTimer -= diff;
//Uppercut_Timer
if (Uppercut_Timer <= diff)
//UppercutTimer
if (UppercutTimer <= diff)
{
DoCast(me->getVictim(), SPELL_UPPERCUT);
Uppercut_Timer = 12000;
DoCastVictim(SPELL_UPPERCUT);
UppercutTimer = 12000;
}
else Uppercut_Timer -= diff;
else UppercutTimer -= diff;
//Adds_Timer
if (!Invisible && Adds_Timer <= diff)
//AddsTimer
if (!Invisible && AddsTimer <= diff)
{
//Interrupt any spell casting
//me->m_canMove = true;
@@ -124,11 +124,11 @@ public:
SummonAdds(me->getVictim());
SummonAdds(me->getVictim());
Invisible = true;
Invisible_Timer = 15000;
InvisibleTimer = 15000;
Adds_Timer = 40000;
AddsTimer = 40000;
}
else Adds_Timer -= diff;
else AddsTimer -= diff;
DoMeleeAttackIfReady();
}
@@ -23,7 +23,8 @@ SDComment:
SDCategory: Maraudon
EndScriptData */
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
enum Spells
{
@@ -47,17 +48,17 @@ public:
{
boss_ptheradrasAI(Creature* creature) : ScriptedAI(creature) {}
uint32 Dustfield_Timer;
uint32 Boulder_Timer;
uint32 Thrash_Timer;
uint32 RepulsiveGaze_Timer;
uint32 DustfieldTimer;
uint32 BoulderTimer;
uint32 ThrashTimer;
uint32 RepulsiveGazeTimer;
void Reset()
{
Dustfield_Timer = 8000;
Boulder_Timer = 2000;
Thrash_Timer = 5000;
RepulsiveGaze_Timer = 23000;
DustfieldTimer = 8000;
BoulderTimer = 2000;
ThrashTimer = 5000;
RepulsiveGazeTimer = 23000;
}
void EnterCombat(Unit* /*who*/) {}
@@ -72,40 +73,38 @@ public:
if (!UpdateVictim())
return;
//Dustfield_Timer
if (Dustfield_Timer <= diff)
//DustfieldTimer
if (DustfieldTimer <= diff)
{
DoCast(me, SPELL_DUSTFIELD);
Dustfield_Timer = 14000;
DustfieldTimer = 14000;
}
else Dustfield_Timer -= diff;
else DustfieldTimer -= diff;
//Boulder_Timer
if (Boulder_Timer <= diff)
//BoulderTimer
if (BoulderTimer <= diff)
{
Unit* target = NULL;
target = SelectTarget(SELECT_TARGET_RANDOM, 0);
if (target)
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
DoCast(target, SPELL_BOULDER);
Boulder_Timer = 10000;
BoulderTimer = 10000;
}
else Boulder_Timer -= diff;
else BoulderTimer -= diff;
//RepulsiveGaze_Timer
if (RepulsiveGaze_Timer <= diff)
//RepulsiveGazeTimer
if (RepulsiveGazeTimer <= diff)
{
DoCast(me->getVictim(), SPELL_REPULSIVEGAZE);
RepulsiveGaze_Timer = 20000;
DoCastVictim(SPELL_REPULSIVEGAZE);
RepulsiveGazeTimer = 20000;
}
else RepulsiveGaze_Timer -= diff;
else RepulsiveGazeTimer -= diff;
//Thrash_Timer
if (Thrash_Timer <= diff)
//ThrashTimer
if (ThrashTimer <= diff)
{
DoCast(me, SPELL_THRASH);
Thrash_Timer = 18000;
ThrashTimer = 18000;
}
else Thrash_Timer -= diff;
else ThrashTimer -= diff;
DoMeleeAttackIfReady();
}
@@ -25,10 +25,15 @@ SDComment: <Known bugs>
SDCategory: Onyxia's Lair
EndScriptData */
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "Cell.h"
#include "CellImpl.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "onyxias_lair.h"
enum eYells
enum Yells
{
SAY_AGGRO = -1249000,
SAY_KILL = -1249001,
@@ -37,7 +42,7 @@ enum eYells
EMOTE_BREATH = -1249004,
};
enum eSpells
enum Spells
{
// Phase 1 spells
SPELL_WING_BUFFET = 18500,
@@ -67,15 +72,15 @@ enum eSpells
SPELL_BELLOWING_ROAR = 18431,
};
struct sOnyxMove
struct OnyxMove
{
uint32 uiLocId;
uint32 uiLocIdEnd;
uint32 uiSpellId;
uint8 LocId;
uint8 LocIdEnd;
uint32 SpellId;
float fX, fY, fZ;
};
static sOnyxMove aMoveData[]=
static OnyxMove MoveData[8]=
{
{0, 1, SPELL_BREATH_WEST_TO_EAST, -33.5561f, -182.682f, -56.9457f}, //west
{1, 0, SPELL_BREATH_EAST_TO_WEST, -31.4963f, -250.123f, -55.1278f}, //east
@@ -87,11 +92,11 @@ static sOnyxMove aMoveData[]=
{7, 6, SPELL_BREATH_NORTH_TO_SOUTH, 22.8763f, -217.152f, -55.0548f}, //north
};
const Position MiddleRoomLocation = {-23.6155f, -215.357f, -55.7344f, 0.0f};
Position const MiddleRoomLocation = {-23.6155f, -215.357f, -55.7344f, 0.0f};
const Position Phase2Location = {-80.924f, -214.299f, -82.942f, 0.0f};
Position const Phase2Location = {-80.924f, -214.299f, -82.942f, 0.0f};
static Position aSpawnLocations[3]=
Position const SpawnLocations[3]=
{
//Whelps
{-30.127f, -254.463f, -89.440f, 0.0f},
@@ -121,58 +126,58 @@ public:
InstanceScript* instance;
SummonList Summons;
uint32 m_uiPhase;
uint32 Phase;
uint32 m_uiFlameBreathTimer;
uint32 m_uiCleaveTimer;
uint32 m_uiTailSweepTimer;
uint32 m_uiWingBuffetTimer;
uint32 FlameBreathTimer;
uint32 CleaveTimer;
uint32 TailSweepTimer;
uint32 WingBuffetTimer;
uint32 m_uiMovePoint;
uint32 m_uiMovementTimer;
sOnyxMove* m_pPointData;
uint8 MovePoint;
uint32 MovementTimer;
OnyxMove* PointData;
uint32 m_uiFireballTimer;
uint32 m_uiWhelpTimer;
uint32 m_uiLairGuardTimer;
uint32 m_uiDeepBreathTimer;
uint32 FireballTimer;
uint32 WhelpTimer;
uint32 LairGuardTimer;
uint32 DeepBreathTimer;
uint32 m_uiBellowingRoarTimer;
uint32 BellowingRoarTimer;
uint8 m_uiSummonWhelpCount;
bool m_bIsMoving;
uint8 SummonWhelpCount;
bool IsMoving;
void Reset()
{
if (!IsCombatMovementAllowed())
SetCombatMovement(true);
m_uiPhase = PHASE_START;
Phase = PHASE_START;
m_uiFlameBreathTimer = urand(10000, 20000);
m_uiTailSweepTimer = urand(15000, 20000);
m_uiCleaveTimer = urand(2000, 5000);
m_uiWingBuffetTimer = urand(10000, 20000);
FlameBreathTimer = urand(10000, 20000);
TailSweepTimer = urand(15000, 20000);
CleaveTimer = urand(2000, 5000);
WingBuffetTimer = urand(10000, 20000);
m_uiMovePoint = urand(0, 5);
m_uiMovementTimer = 14000;
m_pPointData = GetMoveData();
MovePoint = urand(0, 5);
MovementTimer = 14000;
PointData = GetMoveData();
m_uiFireballTimer = 15000;
m_uiWhelpTimer = 60000;
m_uiLairGuardTimer = 60000;
m_uiDeepBreathTimer = 85000;
FireballTimer = 15000;
WhelpTimer = 60000;
LairGuardTimer = 60000;
DeepBreathTimer = 85000;
m_uiBellowingRoarTimer = 30000;
BellowingRoarTimer = 30000;
Summons.DespawnAll();
m_uiSummonWhelpCount = 0;
m_bIsMoving = false;
SummonWhelpCount = 0;
IsMoving = false;
if (instance)
{
instance->SetData(DATA_ONYXIA, NOT_STARTED);
instance->SetData(DATA_ONYXIA_PHASE, m_uiPhase);
instance->SetData(DATA_ONYXIA_PHASE, Phase);
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
}
}
@@ -206,7 +211,7 @@ public:
switch (summoned->GetEntry())
{
case NPC_WHELP:
++m_uiSummonWhelpCount;
++SummonWhelpCount;
break;
case NPC_LAIRGUARD:
summoned->setActive(true);
@@ -225,17 +230,17 @@ public:
DoScriptText(SAY_KILL, me);
}
void SpellHit(Unit* /*pCaster*/, const SpellInfo* pSpell)
void SpellHit(Unit* /*pCaster*/, const SpellInfo* Spell)
{
if (pSpell->Id == SPELL_BREATH_EAST_TO_WEST ||
pSpell->Id == SPELL_BREATH_WEST_TO_EAST ||
pSpell->Id == SPELL_BREATH_SE_TO_NW ||
pSpell->Id == SPELL_BREATH_NW_TO_SE ||
pSpell->Id == SPELL_BREATH_SW_TO_NE ||
pSpell->Id == SPELL_BREATH_NE_TO_SW)
if (Spell->Id == SPELL_BREATH_EAST_TO_WEST ||
Spell->Id == SPELL_BREATH_WEST_TO_EAST ||
Spell->Id == SPELL_BREATH_SE_TO_NW ||
Spell->Id == SPELL_BREATH_NW_TO_SE ||
Spell->Id == SPELL_BREATH_SW_TO_NE ||
Spell->Id == SPELL_BREATH_NE_TO_SW)
{
m_pPointData = GetMoveData();
m_uiMovePoint = m_pPointData->uiLocIdEnd;
PointData = GetMoveData();
MovePoint = PointData->LocIdEnd;
me->SetSpeed(MOVE_FLIGHT, 1.5f);
me->GetMotionMaster()->MovePoint(8, MiddleRoomLocation);
@@ -249,16 +254,16 @@ public:
switch (id)
{
case 8:
m_pPointData = GetMoveData();
if (m_pPointData)
PointData = GetMoveData();
if (PointData)
{
me->SetSpeed(MOVE_FLIGHT, 1.0f);
me->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ);
me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ);
}
break;
case 9:
me->GetMotionMaster()->MoveChase(me->getVictim());
m_uiBellowingRoarTimer = 1000;
BellowingRoarTimer = 1000;
break;
case 10:
me->SetCanFly(true);
@@ -266,39 +271,39 @@ public:
me->SetSpeed(MOVE_FLIGHT, 1.0f);
DoScriptText(SAY_PHASE_2_TRANS, me);
if (instance)
instance->SetData(DATA_ONYXIA_PHASE, m_uiPhase);
m_uiWhelpTimer = 5000;
m_uiLairGuardTimer = 15000;
instance->SetData(DATA_ONYXIA_PHASE, Phase);
WhelpTimer = 5000;
LairGuardTimer = 15000;
break;
case 11:
if (m_pPointData)
me->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ);
if (PointData)
me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ);
me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MoveIdle();
break;
default:
m_bIsMoving = false;
IsMoving = false;
break;
}
}
}
void SpellHitTarget(Unit* target, const SpellInfo* pSpell)
void SpellHitTarget(Unit* target, const SpellInfo* Spell)
{
//Workaround - Couldn't find a way to group this spells (All Eruption)
if (((pSpell->Id >= 17086 && pSpell->Id <= 17095) ||
(pSpell->Id == 17097) ||
(pSpell->Id >= 18351 && pSpell->Id <= 18361) ||
(pSpell->Id >= 18564 && pSpell->Id <= 18576) ||
(pSpell->Id >= 18578 && pSpell->Id <= 18607) ||
(pSpell->Id == 18609) ||
(pSpell->Id >= 18611 && pSpell->Id <= 18628) ||
(pSpell->Id >= 21132 && pSpell->Id <= 21133) ||
(pSpell->Id >= 21135 && pSpell->Id <= 21139) ||
(pSpell->Id >= 22191 && pSpell->Id <= 22202) ||
(pSpell->Id >= 22267 && pSpell->Id <= 22268)) &&
if (((Spell->Id >= 17086 && Spell->Id <= 17095) ||
(Spell->Id == 17097) ||
(Spell->Id >= 18351 && Spell->Id <= 18361) ||
(Spell->Id >= 18564 && Spell->Id <= 18576) ||
(Spell->Id >= 18578 && Spell->Id <= 18607) ||
(Spell->Id == 18609) ||
(Spell->Id >= 18611 && Spell->Id <= 18628) ||
(Spell->Id >= 21132 && Spell->Id <= 21133) ||
(Spell->Id >= 21135 && Spell->Id <= 21139) ||
(Spell->Id >= 22191 && Spell->Id <= 22202) ||
(Spell->Id >= 22267 && Spell->Id <= 22268)) &&
(target->GetTypeId() == TYPEID_PLAYER))
{
if (instance)
@@ -308,14 +313,14 @@ public:
}
}
sOnyxMove* GetMoveData()
OnyxMove* GetMoveData()
{
uint32 uiMaxCount = sizeof(aMoveData)/sizeof(sOnyxMove);
uint8 MaxCount = sizeof(MoveData)/sizeof(OnyxMove);
for (uint32 i = 0; i < uiMaxCount; ++i)
for (uint8 i = 0; i < MaxCount; ++i)
{
if (aMoveData[i].uiLocId == m_uiMovePoint)
return &aMoveData[i];
if (MoveData[i].LocId == MovePoint)
return &MoveData[i];
}
return NULL;
@@ -323,84 +328,84 @@ public:
void SetNextRandomPoint()
{
uint32 uiMaxCount = sizeof(aMoveData)/sizeof(sOnyxMove);
uint8 MaxCount = sizeof(MoveData)/sizeof(OnyxMove);
uint32 iTemp = rand()%(uiMaxCount-1);
uint8 iTemp = urand(0, MaxCount-1);
if (iTemp >= m_uiMovePoint)
if (iTemp >= MovePoint)
++iTemp;
m_uiMovePoint = iTemp;
MovePoint = iTemp;
}
void UpdateAI(const uint32 uiDiff)
void UpdateAI(const uint32 Diff)
{
if (!UpdateVictim())
return;
//Common to PHASE_START && PHASE_END
if (m_uiPhase == PHASE_START || m_uiPhase == PHASE_END)
if (Phase == PHASE_START || Phase == PHASE_END)
{
//Specific to PHASE_START || PHASE_END
if (m_uiPhase == PHASE_START)
if (Phase == PHASE_START)
{
if (HealthBelowPct(60))
{
SetCombatMovement(false);
m_uiPhase = PHASE_BREATH;
Phase = PHASE_BREATH;
me->GetMotionMaster()->MovePoint(10, Phase2Location);
return;
}
}
else
{
if (m_uiBellowingRoarTimer <= uiDiff)
if (BellowingRoarTimer <= Diff)
{
DoCastVictim(SPELL_BELLOWING_ROAR);
// Eruption
GameObject* pFloor = NULL;
GameObject* Floor = NULL;
Trinity::GameObjectInRangeCheck check(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 15);
Trinity::GameObjectLastSearcher<Trinity::GameObjectInRangeCheck> searcher(me, pFloor, check);
Trinity::GameObjectLastSearcher<Trinity::GameObjectInRangeCheck> searcher(me, Floor, check);
me->VisitNearbyGridObject(30, searcher);
if (instance && pFloor)
instance->SetData64(DATA_FLOOR_ERUPTION_GUID, pFloor->GetGUID());
m_uiBellowingRoarTimer = 30000;
if (instance && Floor)
instance->SetData64(DATA_FLOOR_ERUPTION_GUID, Floor->GetGUID());
BellowingRoarTimer = 30000;
}
else
m_uiBellowingRoarTimer -= uiDiff;
BellowingRoarTimer -= Diff;
}
if (m_uiFlameBreathTimer <= uiDiff)
if (FlameBreathTimer <= Diff)
{
DoCastVictim(SPELL_FLAME_BREATH);
m_uiFlameBreathTimer = urand(10000, 20000);
FlameBreathTimer = urand(10000, 20000);
}
else
m_uiFlameBreathTimer -= uiDiff;
FlameBreathTimer -= Diff;
if (m_uiTailSweepTimer <= uiDiff)
if (TailSweepTimer <= Diff)
{
DoCastAOE(SPELL_TAIL_SWEEP);
m_uiTailSweepTimer = urand(15000, 20000);
TailSweepTimer = urand(15000, 20000);
}
else
m_uiTailSweepTimer -= uiDiff;
TailSweepTimer -= Diff;
if (m_uiCleaveTimer <= uiDiff)
if (CleaveTimer <= Diff)
{
DoCastVictim(SPELL_CLEAVE);
m_uiCleaveTimer = urand(2000, 5000);
CleaveTimer = urand(2000, 5000);
}
else
m_uiCleaveTimer -= uiDiff;
CleaveTimer -= Diff;
if (m_uiWingBuffetTimer <= uiDiff)
if (WingBuffetTimer <= Diff)
{
DoCastVictim(SPELL_WING_BUFFET);
m_uiWingBuffetTimer = urand(15000, 30000);
WingBuffetTimer = urand(15000, 30000);
}
else
m_uiWingBuffetTimer -= uiDiff;
WingBuffetTimer -= Diff;
DoMeleeAttackIfReady();
}
@@ -408,86 +413,86 @@ public:
{
if (HealthBelowPct(40))
{
m_uiPhase = PHASE_END;
Phase = PHASE_END;
if (instance)
instance->SetData(DATA_ONYXIA_PHASE, m_uiPhase);
instance->SetData(DATA_ONYXIA_PHASE, Phase);
DoScriptText(SAY_PHASE_3_TRANS, me);
SetCombatMovement(true);
me->SetCanFly(false);
m_bIsMoving = false;
IsMoving = false;
me->GetMotionMaster()->MovePoint(9, me->GetHomePosition());
return;
}
if (m_uiDeepBreathTimer <= uiDiff)
if (DeepBreathTimer <= Diff)
{
if (!m_bIsMoving)
if (!IsMoving)
{
if (me->IsNonMeleeSpellCasted(false))
me->InterruptNonMeleeSpells(false);
DoScriptText(EMOTE_BREATH, me);
DoCast(me, m_pPointData->uiSpellId);
m_uiDeepBreathTimer = 70000;
DoCast(me, PointData->SpellId);
DeepBreathTimer = 70000;
}
}
else
m_uiDeepBreathTimer -= uiDiff;
DeepBreathTimer -= Diff;
if (m_uiMovementTimer <= uiDiff)
if (MovementTimer <= Diff)
{
if (!m_bIsMoving)
if (!IsMoving)
{
SetNextRandomPoint();
m_pPointData = GetMoveData();
PointData = GetMoveData();
if (!m_pPointData)
if (!PointData)
return;
me->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ);
m_bIsMoving = true;
m_uiMovementTimer = 25000;
me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ);
IsMoving = true;
MovementTimer = 25000;
}
}
else
m_uiMovementTimer -= uiDiff;
MovementTimer -= Diff;
if (m_uiFireballTimer <= uiDiff)
if (FireballTimer <= Diff)
{
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
DoCast(target, SPELL_FIREBALL);
m_uiFireballTimer = 8000;
FireballTimer = 8000;
}
}
else
m_uiFireballTimer -= uiDiff;
FireballTimer -= Diff;
if (m_uiLairGuardTimer <= uiDiff)
if (LairGuardTimer <= Diff)
{
me->SummonCreature(NPC_LAIRGUARD, aSpawnLocations[2].GetPositionX(), aSpawnLocations[2].GetPositionY(), aSpawnLocations[2].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN);
m_uiLairGuardTimer = 30000;
me->SummonCreature(NPC_LAIRGUARD, SpawnLocations[2], TEMPSUMMON_CORPSE_DESPAWN);
LairGuardTimer = 30000;
}
else
m_uiLairGuardTimer -= uiDiff;
LairGuardTimer -= Diff;
if (m_uiWhelpTimer <= uiDiff)
if (WhelpTimer <= Diff)
{
me->SummonCreature(NPC_WHELP, aSpawnLocations[0].GetPositionX(), aSpawnLocations[0].GetPositionY(), aSpawnLocations[0].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN);
me->SummonCreature(NPC_WHELP, aSpawnLocations[1].GetPositionX(), aSpawnLocations[1].GetPositionY(), aSpawnLocations[1].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN);
if (m_uiSummonWhelpCount >= RAID_MODE(20, 40))
me->SummonCreature(NPC_WHELP, SpawnLocations[0], TEMPSUMMON_CORPSE_DESPAWN);
me->SummonCreature(NPC_WHELP, SpawnLocations[1], TEMPSUMMON_CORPSE_DESPAWN);
if (SummonWhelpCount >= RAID_MODE(20, 40))
{
m_uiSummonWhelpCount = 0;
m_uiWhelpTimer = 90000;
SummonWhelpCount = 0;
WhelpTimer = 90000;
}
else
m_uiWhelpTimer = 500;
WhelpTimer = 500;
}
else
m_uiWhelpTimer -= uiDiff;
WhelpTimer -= Diff;
}
}
};
@@ -22,7 +22,12 @@ SDComment:
SDCategory: Onyxia's Lair
EndScriptData */
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "Cell.h"
#include "CellImpl.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "onyxias_lair.h"
class instance_onyxias_lair : public InstanceMapScript
@@ -44,27 +49,27 @@ public:
std::map<uint64, uint32> FloorEruptionGUID[2];
std::queue<uint64> FloorEruptionGUIDQueue;
uint64 m_uiOnyxiasGUID;
uint32 m_uiOnyxiaLiftoffTimer;
uint32 m_uiManyWhelpsCounter;
uint32 m_uiEruptTimer;
uint64 OnyxiasGUID;
uint32 OnyxiaLiftoffTimer;
uint32 ManyWhelpsCounter;
uint32 EruptTimer;
uint8 m_auiEncounter[MAX_ENCOUNTER];
uint8 Encounter[MAX_ENCOUNTER];
bool m_bAchievManyWhelpsHandleIt;
bool m_bAchievSheDeepBreathMore;
bool AchievManyWhelpsHandleIt;
bool AchievSheDeepBreathMore;
void Initialize()
{
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
memset(&Encounter, 0, sizeof(Encounter));
m_uiOnyxiasGUID = 0;
m_uiOnyxiaLiftoffTimer = 0;
m_uiManyWhelpsCounter = 0;
m_bAchievManyWhelpsHandleIt = false;
m_bAchievSheDeepBreathMore = true;
OnyxiasGUID = 0;
OnyxiaLiftoffTimer = 0;
ManyWhelpsCounter = 0;
AchievManyWhelpsHandleIt = false;
AchievSheDeepBreathMore = true;
m_uiEruptTimer = 0;
EruptTimer = 0;
}
void OnCreatureCreate(Creature* creature)
@@ -72,7 +77,7 @@ public:
switch (creature->GetEntry())
{
case NPC_ONYXIA:
m_uiOnyxiasGUID = creature->GetGUID();
OnyxiasGUID = creature->GetGUID();
break;
}
}
@@ -93,7 +98,7 @@ public:
if (Creature* temp = go->SummonCreature(NPC_WHELP, goPos, TEMPSUMMON_CORPSE_DESPAWN))
{
temp->SetInCombatWithZone();
++m_uiManyWhelpsCounter;
++ManyWhelpsCounter;
}
break;
}
@@ -139,88 +144,88 @@ public:
FloorEruptionGUID[1].erase(floorEruptedGUID);
}
void SetData(uint32 uiType, uint32 uiData)
void SetData(uint32 Type, uint32 Data)
{
switch (uiType)
switch (Type)
{
case DATA_ONYXIA:
m_auiEncounter[0] = uiData;
if (uiData == IN_PROGRESS)
Encounter[0] = Data;
if (Data == IN_PROGRESS)
SetData(DATA_SHE_DEEP_BREATH_MORE, IN_PROGRESS);
break;
case DATA_ONYXIA_PHASE:
if (uiData == PHASE_BREATH) //Used to mark the liftoff phase
if (Data == PHASE_BREATH) //Used to mark the liftoff phase
{
m_bAchievManyWhelpsHandleIt = false;
m_uiManyWhelpsCounter = 0;
m_uiOnyxiaLiftoffTimer = 10*IN_MILLISECONDS;
AchievManyWhelpsHandleIt = false;
ManyWhelpsCounter = 0;
OnyxiaLiftoffTimer = 10*IN_MILLISECONDS;
}
break;
case DATA_SHE_DEEP_BREATH_MORE:
if (uiData == IN_PROGRESS)
if (Data == IN_PROGRESS)
{
m_bAchievSheDeepBreathMore = true;
AchievSheDeepBreathMore = true;
}
else if (uiData == FAIL)
else if (Data == FAIL)
{
m_bAchievSheDeepBreathMore = false;
AchievSheDeepBreathMore = false;
}
break;
}
if (uiType < MAX_ENCOUNTER && uiData == DONE)
if (Type < MAX_ENCOUNTER && Data == DONE)
SaveToDB();
}
void SetData64(uint32 uiType, uint64 uiData)
void SetData64(uint32 Type, uint64 Data)
{
switch (uiType)
switch (Type)
{
case DATA_FLOOR_ERUPTION_GUID:
FloorEruptionGUID[1] = FloorEruptionGUID[0];
FloorEruptionGUIDQueue.push(uiData);
m_uiEruptTimer = 2500;
FloorEruptionGUIDQueue.push(Data);
EruptTimer = 2500;
break;
}
}
uint32 GetData(uint32 uiType)
uint32 GetData(uint32 Type)
{
switch (uiType)
switch (Type)
{
case DATA_ONYXIA:
return m_auiEncounter[0];
return Encounter[0];
}
return 0;
}
uint64 GetData64(uint32 uiData)
uint64 GetData64(uint32 Data)
{
switch (uiData)
switch (Data)
{
case DATA_ONYXIA_GUID:
return m_uiOnyxiasGUID;
return OnyxiasGUID;
}
return 0;
}
void Update(uint32 uiDiff)
void Update(uint32 Diff)
{
if (GetData(DATA_ONYXIA) == IN_PROGRESS)
{
if (m_uiOnyxiaLiftoffTimer && m_uiOnyxiaLiftoffTimer <= uiDiff)
if (OnyxiaLiftoffTimer && OnyxiaLiftoffTimer <= Diff)
{
m_uiOnyxiaLiftoffTimer = 0;
if (m_uiManyWhelpsCounter >= 50)
m_bAchievManyWhelpsHandleIt = true;
} else m_uiOnyxiaLiftoffTimer -= uiDiff;
OnyxiaLiftoffTimer = 0;
if (ManyWhelpsCounter >= 50)
AchievManyWhelpsHandleIt = true;
} else OnyxiaLiftoffTimer -= Diff;
}
if (!FloorEruptionGUIDQueue.empty())
{
if (m_uiEruptTimer <= uiDiff)
if (EruptTimer <= Diff)
{
uint32 treeHeight = 0;
do
@@ -229,10 +234,10 @@ public:
FloorEruption(FloorEruptionGUIDQueue.front());
FloorEruptionGUIDQueue.pop();
} while (!FloorEruptionGUIDQueue.empty() && (*FloorEruptionGUID[1].find(FloorEruptionGUIDQueue.front())).second == treeHeight);
m_uiEruptTimer = 1000;
EruptTimer = 1000;
}
else
m_uiEruptTimer -= uiDiff;
EruptTimer -= Diff;
}
}
@@ -242,10 +247,10 @@ public:
{
case ACHIEV_CRITERIA_MANY_WHELPS_10_PLAYER: // Criteria for achievement 4403: Many Whelps! Handle It! (10 player) Hatch 50 eggs in 10s
case ACHIEV_CRITERIA_MANY_WHELPS_25_PLAYER: // Criteria for achievement 4406: Many Whelps! Handle It! (25 player) Hatch 50 eggs in 10s
return m_bAchievManyWhelpsHandleIt;
return AchievManyWhelpsHandleIt;
case ACHIEV_CRITERIA_DEEP_BREATH_10_PLAYER: // Criteria for achievement 4404: She Deep Breaths More (10 player) Everybody evade Deep Breath
case ACHIEV_CRITERIA_DEEP_BREATH_25_PLAYER: // Criteria for achievement 4407: She Deep Breaths More (25 player) Everybody evade Deep Breath
return m_bAchievSheDeepBreathMore;
return AchievSheDeepBreathMore;
}
return false;
}
@@ -18,13 +18,13 @@
#ifndef DEF_ONYXIAS_LAIR_H
#define DEF_ONYXIAS_LAIR_H
enum eData64
enum Data64
{
DATA_ONYXIA_GUID,
DATA_FLOOR_ERUPTION_GUID
};
enum eInstanceData
enum InstanceData
{
DATA_ONYXIA,
MAX_ENCOUNTER,
@@ -34,7 +34,7 @@ enum eInstanceData
DATA_MANY_WHELPS_COUNT
};
enum eCreatures
enum Creatures
{
NPC_WHELP = 11262,
NPC_LAIRGUARD = 36561,
@@ -42,20 +42,20 @@ enum eCreatures
NPC_ONYXIA = 10184
};
enum eOnyxiaPhases
enum OnyxiaPhases
{
PHASE_START = 1,
PHASE_BREATH = 2,
PHASE_END = 3
};
enum eGameObjects
enum GameObjects
{
GO_WHELP_SPAWNER = 176510,
GO_WHELP_EGG = 176511
};
enum eAchievementData
enum AchievementData
{
ACHIEV_CRITERIA_MANY_WHELPS_10_PLAYER = 12565, // Criteria for achievement 4403: Many Whelps! Handle It! (10 player) Hatch 50 eggs in 10s
ACHIEV_CRITERIA_MANY_WHELPS_25_PLAYER = 12568, // Criteria for achievement 4406: Many Whelps! Handle It! (25 player) Hatch 50 eggs in 10s
+3 -3
View File
@@ -169,15 +169,15 @@ class npc_torek : public CreatureScript
# npc_ruul_snowhoof
####*/
enum RuulSnowhoof
{
enum RuulSnowhoof
{
NPC_THISTLEFUR_URSA = 3921,
NPC_THISTLEFUR_TOTEMIC = 3922,
NPC_THISTLEFUR_PATHFINDER = 3926,
QUEST_FREEDOM_TO_RUUL = 6482,
GO_CAGE = 178147
GO_CAGE = 178147
};
Position const RuulSnowhoofSummonsCoord[6] =
@@ -25,7 +25,6 @@ EndScriptData */
/* ContentData
mobs_risen_husk_spirit
npc_deserter_agitator
npc_lady_jaina_proudmoore
npc_nat_pagle
npc_private_hendel
@@ -132,93 +131,7 @@ class mobs_risen_husk_spirit : public CreatureScript
};
/*######
## npc_deserter_agitator
######*/
enum Deserter
{
QUEST_TRAITORS_AMONG_US = 11126,
NPC_THERAMORE_DESERTER = 23602,
};
const Position DeserterDisappearPos = {-3609.03f, -4332.91f, 9.39354f, 3.73862f};
#define GOSSIP_ITEM_DESERTER "Your propaganda wont`t work on me. Spout your treasonous filth elsewhere traitor!"
class npc_deserter_agitator : public CreatureScript
{
public:
npc_deserter_agitator() : CreatureScript("npc_deserter_agitator") { }
bool OnGossipHello(Player* player, Creature* creature)
{
if (player->GetQuestStatus(QUEST_TRAITORS_AMONG_US) == QUEST_STATUS_INCOMPLETE)
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_DESERTER, GOSSIP_SENDER_MAIN, GOSSIP_SENDER_INFO);
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
return true;
}
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
{
player->PlayerTalkClass->ClearMenus();
if (action == GOSSIP_SENDER_INFO)
{
player->CLOSE_GOSSIP_MENU();
switch (urand(0, 1))
{
case 0:
creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
creature->setFaction(14);
creature->AI()->AttackStart(player);
break;
case 1:
player->KilledMonsterCredit(NPC_THERAMORE_DESERTER, 0);
creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
creature->SetSpeed(MOVE_RUN, creature->GetSpeedRate(MOVE_RUN), true);
creature->setFaction(35);
creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
creature->SetReactState(REACT_PASSIVE);
creature->GetMotionMaster()->MovePoint(1, DeserterDisappearPos);
break;
}
}
return true;
}
CreatureAI* GetAI(Creature* creature) const
{
return new npc_deserter_agitatorAI(creature);
}
struct npc_deserter_agitatorAI : public ScriptedAI
{
npc_deserter_agitatorAI(Creature* creature) : ScriptedAI(creature) { }
void Reset()
{
me->RestoreFaction();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
me->SetReactState(REACT_AGGRESSIVE);
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
}
void MovementInform(uint32 Type, uint32 Id)
{
if (Type != POINT_MOTION_TYPE)
return;
if (Id == 1)
me->DisappearAndDie();
}
};
};
/*######
## npc_deserter_agitator
## npc_theramor_guard
######*/
enum TheramoreGuard
@@ -794,16 +707,16 @@ class spell_energize_aoe : public SpellScriptLoader
return true;
}
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& targets)
{
for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end();)
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end();)
{
if ((*itr)->GetTypeId() == TYPEID_PLAYER && (*itr)->ToPlayer()->GetQuestStatus(GetSpellInfo()->Effects[EFFECT_1].CalcValue()) == QUEST_STATUS_INCOMPLETE)
++itr;
else
unitList.erase(itr++);
targets.erase(itr++);
}
unitList.push_back(GetCaster());
targets.push_back(GetCaster());
}
void HandleScript(SpellEffIndex effIndex)
@@ -815,8 +728,8 @@ class spell_energize_aoe : public SpellScriptLoader
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_energize_aoe_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
OnUnitTargetSelect += SpellUnitTargetFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENTRY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENTRY);
}
};
@@ -865,7 +778,6 @@ void AddSC_dustwallow_marsh()
new npc_zelfrax();
new npc_stinky();
new npc_theramore_guard();
new npc_deserter_agitator();
new spell_ooze_zap();
new spell_ooze_zap_channel_end();
new spell_energize_aoe();
+2 -111
View File
@@ -18,86 +18,19 @@
/* ScriptData
SDName: Winterspring
SD%Complete: 90
SDComment: Quest support: 5126 (Loraxs' tale missing proper gossip items text). Vendor Rivern Frostwind. Obtain Cache of Mau'ari
SD%Complete: Almost Completely Emptied
SDComment: Vendor Rivern Frostwind.
SDCategory: Winterspring
EndScriptData */
/* ContentData
npc_lorax
npc_rivern_frostwind
npc_witch_doctor_mauari
EndContentData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
/*######
## npc_lorax
######*/
#define GOSSIP_HL "Talk to me"
#define GOSSIP_SL1 "What do you do here?"
#define GOSSIP_SL2 "I can help you"
#define GOSSIP_SL3 "What deal?"
#define GOSSIP_SL4 "Then what happened?"
#define GOSSIP_SL5 "He is not safe, i'll make sure of that."
class npc_lorax : public CreatureScript
{
public:
npc_lorax() : CreatureScript("npc_lorax") { }
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
{
player->PlayerTalkClass->ClearMenus();
switch (action)
{
case GOSSIP_ACTION_INFO_DEF:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
player->SEND_GOSSIP_MENU(3759, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+1:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
player->SEND_GOSSIP_MENU(3760, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+2:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
player->SEND_GOSSIP_MENU(3761, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+3:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
player->SEND_GOSSIP_MENU(3762, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+4:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
player->SEND_GOSSIP_MENU(3763, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+5:
player->CLOSE_GOSSIP_MENU();
player->AreaExploredOrEventHappens(5126);
break;
}
return true;
}
bool OnGossipHello(Player* player, Creature* creature)
{
if (creature->isQuestGiver())
player->PrepareQuestMenu(creature->GetGUID());
if (player->GetQuestStatus(5126) == QUEST_STATUS_INCOMPLETE)
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
return true;
}
};
/*######
## npc_rivern_frostwind
######*/
@@ -131,49 +64,7 @@ public:
};
/*######
## npc_witch_doctor_mauari
######*/
#define GOSSIP_HWDM "I'd like you to make me a new Cache of Mau'ari please."
class npc_witch_doctor_mauari : public CreatureScript
{
public:
npc_witch_doctor_mauari() : CreatureScript("npc_witch_doctor_mauari") { }
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
{
player->PlayerTalkClass->ClearMenus();
if (action == GOSSIP_ACTION_INFO_DEF+1)
{
player->CLOSE_GOSSIP_MENU();
creature->CastSpell(player, 16351, false);
}
return true;
}
bool OnGossipHello(Player* player, Creature* creature)
{
if (creature->isQuestGiver())
player->PrepareQuestMenu(creature->GetGUID());
if (player->GetQuestRewardStatus(975))
{
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HWDM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
player->SEND_GOSSIP_MENU(3377, creature->GetGUID());
}
else
player->SEND_GOSSIP_MENU(3375, creature->GetGUID());
return true;
}
};
void AddSC_winterspring()
{
new npc_lorax();
new npc_rivern_frostwind();
new npc_witch_doctor_mauari();
}
@@ -186,7 +186,7 @@ class ConflagrationTargetSelector
public:
ConflagrationTargetSelector() { }
bool operator()(Unit* unit)
bool operator()(WorldObject* unit) const
{
return unit->GetTypeId() != TYPEID_PLAYER;
}
@@ -201,12 +201,12 @@ class spell_saviana_conflagration_init : public SpellScriptLoader
{
PrepareSpellScript(spell_saviana_conflagration_init_SpellScript);
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& targets)
{
unitList.remove_if (ConflagrationTargetSelector());
targets.remove_if(ConflagrationTargetSelector());
uint8 maxSize = uint8(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 6 : 3);
if (unitList.size() > maxSize)
Trinity::Containers::RandomResizeList(unitList, maxSize);
if (targets.size() > maxSize)
Trinity::Containers::RandomResizeList(targets, maxSize);
}
void HandleDummy(SpellEffIndex effIndex)
@@ -218,7 +218,7 @@ class spell_saviana_conflagration_init : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_saviana_conflagration_init_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_saviana_conflagration_init_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_saviana_conflagration_init_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
@@ -60,9 +60,9 @@ class OrientationCheck : public std::unary_function<Unit*, bool>
{
public:
explicit OrientationCheck(Unit* _caster) : caster(_caster) { }
bool operator() (Unit* unit)
bool operator()(WorldObject* object)
{
return !unit->isInFront(caster, 2.5f) || !unit->IsWithinDist(caster, 40.0f);
return !object->isInFront(caster, 2.5f) || !object->IsWithinDist(caster, 40.0f);
}
private:
@@ -76,15 +76,16 @@ class spell_eadric_radiance : public SpellScriptLoader
class spell_eadric_radiance_SpellScript : public SpellScript
{
PrepareSpellScript(spell_eadric_radiance_SpellScript);
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& unitList)
{
unitList.remove_if (OrientationCheck(GetCaster()));
unitList.remove_if(OrientationCheck(GetCaster()));
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_eadric_radiance_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_eadric_radiance_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_eadric_radiance_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_eadric_radiance_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
@@ -27,7 +27,10 @@ EndScriptData */
// All - untested
// Pets aren't being summoned by their masters
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
#include "trial_of_the_crusader.h"
enum eYell
@@ -945,18 +948,18 @@ public:
};
enum eWarlockSpells
enum WarlockSpells
{
SPELL_HELLFIRE = 65816,
SPELL_CORRUPTION = 65810,
SPELL_CURSE_OF_AGONY = 65814,
SPELL_CURSE_OF_EXHAUSTION = 65815,
SPELL_FEAR = 65809, //8s
SPELL_SEARING_PAIN = 65819,
SPELL_SHADOW_BOLT = 65821,
SPELL_UNSTABLE_AFFLICTION = 65812,
SPELL_SUMMON_FELHUNTER = 67514,
H_SPELL_UNSTABLE_AFFLICTION = 68155, //15s
SPELL_HELLFIRE = 65816,
SPELL_CORRUPTION = 65810,
SPELL_CURSE_OF_AGONY = 65814,
SPELL_CURSE_OF_EXHAUSTION = 65815,
SPELL_FEAR = 65809, // 8s
SPELL_SEARING_PAIN = 65819,
SPELL_SHADOW_BOLT = 65821,
SPELL_UNSTABLE_AFFLICTION = 65812, // 15s
SPELL_UNSTABLE_AFFLICTION_DISPEL = 65813,
SPELL_SUMMON_FELHUNTER = 67514,
};
class mob_toc_warlock : public CreatureScript
@@ -2030,6 +2033,40 @@ public:
};
};
class spell_faction_champion_warl_unstable_affliction : public SpellScriptLoader
{
public:
spell_faction_champion_warl_unstable_affliction() : SpellScriptLoader("spell_faction_champion_warl_unstable_affliction") { }
class spell_faction_champion_warl_unstable_affliction_AuraScript : public AuraScript
{
PrepareAuraScript(spell_faction_champion_warl_unstable_affliction_AuraScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_UNSTABLE_AFFLICTION_DISPEL))
return false;
return true;
}
void HandleDispel(DispelInfo* dispelInfo)
{
if (Unit* caster = GetCaster())
caster->CastSpell(dispelInfo->GetDispeller(), SPELL_UNSTABLE_AFFLICTION_DISPEL, true, NULL, GetEffect(EFFECT_0));
}
void Register()
{
AfterDispel += AuraDispelFn(spell_faction_champion_warl_unstable_affliction_AuraScript::HandleDispel);
}
};
AuraScript* GetAuraScript() const
{
return new spell_faction_champion_warl_unstable_affliction_AuraScript();
}
};
void AddSC_boss_faction_champions()
{
new boss_toc_champion_controller();
@@ -2049,4 +2086,5 @@ void AddSC_boss_faction_champions()
new mob_toc_retro_paladin();
new mob_toc_pet_warlock();
new mob_toc_pet_hunter();
new spell_faction_champion_warl_unstable_affliction();
}
@@ -359,7 +359,7 @@ class DistanceCheck
public:
explicit DistanceCheck(Unit* _caster) : caster(_caster) { }
bool operator() (Unit* unit)
bool operator() (WorldObject* unit) const
{
if (caster->GetExactDist2d(unit) <= 10.0f)
return true;
@@ -378,25 +378,25 @@ class spell_bronjahm_soulstorm_targeting : public SpellScriptLoader
{
PrepareSpellScript(spell_bronjahm_soulstorm_targeting_SpellScript);
void FilterTargetsInitial(std::list<Unit*>& unitList)
void FilterTargetsInitial(std::list<WorldObject*>& targets)
{
unitList.remove_if (DistanceCheck(GetCaster()));
sharedUnitList = unitList;
targets.remove_if(DistanceCheck(GetCaster()));
sharedTargets = targets;
}
// use the same target for first and second effect
void FilterTargetsSubsequent(std::list<Unit*>& unitList)
void FilterTargetsSubsequent(std::list<WorldObject*>& targets)
{
unitList = sharedUnitList;
targets = sharedTargets;
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargetsInitial, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargetsSubsequent, EFFECT_2, TARGET_UNIT_DEST_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargetsInitial, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargetsSubsequent, EFFECT_2, TARGET_UNIT_DEST_AREA_ENEMY);
}
std::list<Unit*> sharedUnitList;
std::list<WorldObject*> sharedTargets;
};
SpellScript* GetSpellScript() const
@@ -631,9 +631,9 @@ class BloodboltHitCheck
public:
explicit BloodboltHitCheck(LanaThelAI* ai) : _ai(ai) {}
bool operator()(Unit* unit)
bool operator()(WorldObject* object) const
{
return _ai->WasBloodbolted(unit->GetGUID());
return _ai->WasBloodbolted(object->GetGUID());
}
private:
@@ -661,13 +661,13 @@ class spell_blood_queen_bloodbolt : public SpellScriptLoader
return GetCaster()->GetEntry() == NPC_BLOOD_QUEEN_LANA_THEL;
}
void FilterTargets(std::list<Unit*>& targets)
void FilterTargets(std::list<WorldObject*>& targets)
{
uint32 targetCount = (targets.size() + 2) / 3;
targets.remove_if (BloodboltHitCheck(static_cast<LanaThelAI*>(GetCaster()->GetAI())));
targets.remove_if(BloodboltHitCheck(static_cast<LanaThelAI*>(GetCaster()->GetAI())));
Trinity::Containers::RandomResizeList(targets, targetCount);
// mark targets now, effect hook has missile travel time delay (might cast next in that time)
for (std::list<Unit*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr)
for (std::list<WorldObject*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr)
GetCaster()->GetAI()->SetGUID((*itr)->GetGUID(), GUID_BLOODBOLT);
}
@@ -679,7 +679,7 @@ class spell_blood_queen_bloodbolt : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_blood_queen_bloodbolt_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blood_queen_bloodbolt_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_blood_queen_bloodbolt_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
@@ -699,19 +699,19 @@ class spell_blood_queen_pact_of_the_darkfallen : public SpellScriptLoader
{
PrepareSpellScript(spell_blood_queen_pact_of_the_darkfallen_SpellScript);
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& targets)
{
unitList.remove_if (Trinity::UnitAuraCheck(false, SPELL_PACT_OF_THE_DARKFALLEN));
targets.remove_if(Trinity::UnitAuraCheck(false, SPELL_PACT_OF_THE_DARKFALLEN));
bool remove = true;
std::list<Unit*>::const_iterator itrEnd = unitList.end(), itr, itr2;
std::list<WorldObject*>::const_iterator itrEnd = targets.end(), itr, itr2;
// we can do this, unitList is MAX 4 in size
for (itr = unitList.begin(); itr != itrEnd && remove; ++itr)
for (itr = targets.begin(); itr != itrEnd && remove; ++itr)
{
if (!GetCaster()->IsWithinDist(*itr, 5.0f, false))
remove = false;
for (itr2 = unitList.begin(); itr2 != itrEnd && remove; ++itr2)
for (itr2 = targets.begin(); itr2 != itrEnd && remove; ++itr2)
if (itr != itr2 && !(*itr2)->IsWithinDist(*itr, 5.0f, false))
remove = false;
}
@@ -721,14 +721,14 @@ class spell_blood_queen_pact_of_the_darkfallen : public SpellScriptLoader
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
{
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_PACT_OF_THE_DARKFALLEN);
unitList.clear();
targets.clear();
}
}
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_blood_queen_pact_of_the_darkfallen_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blood_queen_pact_of_the_darkfallen_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
@@ -785,15 +785,15 @@ class spell_blood_queen_pact_of_the_darkfallen_dmg_target : public SpellScriptLo
{
PrepareSpellScript(spell_blood_queen_pact_of_the_darkfallen_dmg_SpellScript);
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& unitList)
{
unitList.remove_if (Trinity::UnitAuraCheck(true, SPELL_PACT_OF_THE_DARKFALLEN));
unitList.remove_if(Trinity::UnitAuraCheck(true, SPELL_PACT_OF_THE_DARKFALLEN));
unitList.push_back(GetCaster());
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_blood_queen_pact_of_the_darkfallen_dmg_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blood_queen_pact_of_the_darkfallen_dmg_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
@@ -1198,34 +1198,34 @@ class spell_deathbringer_blood_nova_targeting : public SpellScriptLoader
return true;
}
void FilterTargetsInitial(std::list<Unit*>& unitList)
void FilterTargetsInitial(std::list<WorldObject*>& targets)
{
if (unitList.empty())
if (targets.empty())
return;
// select one random target, with preference of ranged targets
uint32 targetsAtRange = 0;
uint32 const minTargets = uint32(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 10 : 4);
unitList.sort(Trinity::ObjectDistanceOrderPred(GetCaster(), false));
targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster(), false));
// get target count at range
for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr, ++targetsAtRange)
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr, ++targetsAtRange)
if ((*itr)->GetDistance(GetCaster()) < 12.0f)
break;
// set the upper cap
if (targetsAtRange < minTargets)
targetsAtRange = std::min<uint32>(unitList.size() - 1, minTargets);
targetsAtRange = std::min<uint32>(targets.size() - 1, minTargets);
std::list<Unit*>::const_iterator itr = unitList.begin();
std::list<WorldObject*>::const_iterator itr = targets.begin();
std::advance(itr, urand(0, targetsAtRange));
target = *itr;
unitList.clear();
unitList.push_back(target);
targets.clear();
targets.push_back(target);
}
// use the same target for first and second effect
void FilterTargetsSubsequent(std::list<Unit*>& unitList)
void FilterTargetsSubsequent(std::list<WorldObject*>& unitList)
{
if (!target)
return;
@@ -1241,12 +1241,13 @@ class spell_deathbringer_blood_nova_targeting : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_deathbringer_blood_nova_targeting_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_deathbringer_blood_nova_targeting_SpellScript::FilterTargetsSubsequent, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_deathbringer_blood_nova_targeting_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_deathbringer_blood_nova_targeting_SpellScript::FilterTargetsSubsequent, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_deathbringer_blood_nova_targeting_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST);
OnEffectHitTarget += SpellEffectFn(spell_deathbringer_blood_nova_targeting_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST);
}
Unit* target;
WorldObject* target;
};
SpellScript* GetSpellScript() const
@@ -1269,20 +1270,20 @@ class spell_deathbringer_boiling_blood : public SpellScriptLoader
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& targets)
{
unitList.remove(GetCaster()->getVictim());
if (unitList.empty())
targets.remove(GetCaster()->getVictim());
if (targets.empty())
return;
Unit* target = Trinity::Containers::SelectRandomContainerElement(unitList);
unitList.clear();
unitList.push_back(target);
WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
targets.clear();
targets.push_back(target);
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_deathbringer_boiling_blood_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_deathbringer_boiling_blood_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
@@ -416,7 +416,7 @@ class spell_marrowgar_coldflame : public SpellScriptLoader
{
PrepareSpellScript(spell_marrowgar_coldflame_SpellScript);
void SelectTarget(std::list<Unit*>& targets)
void SelectTarget(std::list<WorldObject*>& targets)
{
targets.clear();
// select any unit but not the tank (by owners threatlist)
@@ -438,7 +438,7 @@ class spell_marrowgar_coldflame : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_marrowgar_coldflame_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_marrowgar_coldflame_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_marrowgar_coldflame_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
@@ -296,6 +296,7 @@ class boss_professor_putricide : public CreatureScript
summon->ModifyAuraState(AURA_STATE_UNKNOWN22, true);
summon->CastSpell(summon, SPELL_GASEOUS_BLOAT_PROC, true);
summon->CastCustomSpell(SPELL_GASEOUS_BLOAT, SPELLVALUE_AURA_STACK, 10, summon, false);
summon->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
summon->SetReactState(REACT_PASSIVE);
return;
case NPC_VOLATILE_OOZE:
@@ -303,6 +304,7 @@ class boss_professor_putricide : public CreatureScript
summon->ModifyAuraState(AURA_STATE_UNKNOWN19, true);
summon->CastSpell(summon, SPELL_OOZE_ERUPTION_SEARCH_PERIODIC, true);
summon->CastSpell(summon, SPELL_VOLATILE_OOZE_ADHESIVE, false);
summon->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
summon->SetReactState(REACT_PASSIVE);
return;
case NPC_CHOKING_GAS_BOMB:
@@ -868,26 +870,26 @@ class spell_putricide_ooze_channel : public SpellScriptLoader
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
void SelectTarget(std::list<Unit*>& targetList)
void SelectTarget(std::list<WorldObject*>& targets)
{
if (targetList.empty())
if (targets.empty())
{
FinishCast(SPELL_FAILED_NO_VALID_TARGETS);
GetCaster()->ToCreature()->DespawnOrUnsummon(1); // despawn next update
return;
}
Unit* target = Trinity::Containers::SelectRandomContainerElement(targetList);
targetList.clear();
targetList.push_back(target);
WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
targets.clear();
targets.push_back(target);
_target = target;
}
void SetTarget(std::list<Unit*>& targetList)
void SetTarget(std::list<WorldObject*>& targets)
{
targetList.clear();
targets.clear();
if (_target)
targetList.push_back(_target);
targets.push_back(_target);
}
void StartAttack()
@@ -910,14 +912,14 @@ class spell_putricide_ooze_channel : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_ooze_channel_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_ooze_channel_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY);
AfterHit += SpellHitFn(spell_putricide_ooze_channel_SpellScript::StartAttack);
OnCast += SpellCastFn(spell_putricide_ooze_channel_SpellScript::CheckTarget);
}
Unit* _target;
WorldObject* _target;
};
SpellScript* GetSpellScript() const
@@ -931,7 +933,7 @@ class ExactDistanceCheck
public:
ExactDistanceCheck(Unit* source, float dist) : _source(source), _dist(dist) {}
bool operator()(Unit* unit)
bool operator()(WorldObject* unit) const
{
return _source->GetExactDist2d(unit) > _dist;
}
@@ -950,15 +952,15 @@ class spell_putricide_slime_puddle : public SpellScriptLoader
{
PrepareSpellScript(spell_putricide_slime_puddle_SpellScript);
void ScaleRange(std::list<Unit*>& targets)
void ScaleRange(std::list<WorldObject*>& targets)
{
targets.remove_if(ExactDistanceCheck(GetCaster(), 2.5f * GetCaster()->GetFloatValue(OBJECT_FIELD_SCALE_X)));
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_slime_puddle_SpellScript::ScaleRange, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_slime_puddle_SpellScript::ScaleRange, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_slime_puddle_SpellScript::ScaleRange, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_slime_puddle_SpellScript::ScaleRange, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY);
}
};
@@ -1176,13 +1178,13 @@ class spell_putricide_eat_ooze : public SpellScriptLoader
{
PrepareSpellScript(spell_putricide_eat_ooze_SpellScript);
void SelectTarget(std::list<Unit*>& targets)
void SelectTarget(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster()));
Unit* target = targets.front();
WorldObject* target = targets.front();
targets.clear();
targets.push_back(target);
}
@@ -1209,7 +1211,7 @@ class spell_putricide_eat_ooze : public SpellScriptLoader
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_putricide_eat_ooze_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_eat_ooze_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_eat_ooze_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY);
}
};
@@ -1456,15 +1458,15 @@ class spell_putricide_mutated_transformation_dmg : public SpellScriptLoader
{
PrepareSpellScript(spell_putricide_mutated_transformation_dmg_SpellScript);
void FilterTargetsInitial(std::list<Unit*>& unitList)
void FilterTargetsInitial(std::list<WorldObject*>& targets)
{
if (Unit* owner = ObjectAccessor::GetUnit(*GetCaster(), GetCaster()->GetCreatorGUID()))
unitList.remove(owner);
targets.remove(owner);
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_mutated_transformation_dmg_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_mutated_transformation_dmg_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
@@ -449,23 +449,23 @@ class spell_rotface_ooze_flood : public SpellScriptLoader
GetHitUnit()->CastSpell(triggers.back(), uint32(GetEffectValue()), false, NULL, NULL, GetOriginalCaster() ? GetOriginalCaster()->GetGUID() : 0);
}
void FilterTargets(std::list<Unit*>& targetList)
void FilterTargets(std::list<WorldObject*>& targets)
{
// get 2 targets except 2 nearest
targetList.sort(Trinity::ObjectDistanceOrderPred(GetCaster()));
targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster()));
// .resize() runs pop_back();
if (targetList.size() > 4)
targetList.resize(4);
if (targets.size() > 4)
targets.resize(4);
while (targetList.size() > 2)
targetList.pop_front();
while (targets.size() > 2)
targets.pop_front();
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_rotface_ooze_flood_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
OnUnitTargetSelect += SpellUnitTargetFn(spell_rotface_ooze_flood_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_ooze_flood_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
}
};
@@ -490,21 +490,21 @@ class spell_rotface_mutated_infection : public SpellScriptLoader
return true;
}
void FilterTargets(std::list<Unit*>& targets)
void FilterTargets(std::list<WorldObject*>& targets)
{
// remove targets with this aura already
// tank is not on this list
targets.remove_if (Trinity::UnitAuraCheck(true, GetSpellInfo()->Id));
targets.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Id));
if (targets.empty())
return;
Unit* target = Trinity::Containers::SelectRandomContainerElement(targets);
WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
targets.clear();
targets.push_back(target);
_target = target;
}
void ReplaceTargets(std::list<Unit*>& targets)
void ReplaceTargets(std::list<WorldObject*>& targets)
{
targets.clear();
if (_target)
@@ -520,13 +520,13 @@ class spell_rotface_mutated_infection : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_rotface_mutated_infection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_rotface_mutated_infection_SpellScript::ReplaceTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_rotface_mutated_infection_SpellScript::ReplaceTargets, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_mutated_infection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_mutated_infection_SpellScript::ReplaceTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_mutated_infection_SpellScript::ReplaceTargets, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY);
AfterHit += SpellHitFn(spell_rotface_mutated_infection_SpellScript::NotifyTargets);
}
Unit* _target;
WorldObject* _target;
};
SpellScript* GetSpellScript() const
@@ -19,6 +19,7 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellAuraEffects.h"
#include "GridNotifiers.h"
#include "icecrown_citadel.h"
enum Texts
@@ -167,7 +168,7 @@ class FrostwyrmLandEvent : public BasicEvent
bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/)
{
_owner.GetMotionMaster()->MoveLand(POINT_FROSTWYRM_LAND, _dest, 8.247422f);
_owner.GetMotionMaster()->MoveLand(POINT_FROSTWYRM_LAND, _dest);
return true;
}
@@ -183,7 +184,7 @@ class FrostBombExplosion : public BasicEvent
bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/)
{
_owner->CastSpell((Unit*)NULL, SPELL_FROST_BOMB, true, NULL, NULL, _sindragosaGUID);
_owner->CastSpell((Unit*)NULL, SPELL_FROST_BOMB, false, NULL, NULL, _sindragosaGUID);
_owner->RemoveAurasDueToSpell(SPELL_FROST_BOMB_VISUAL);
return true;
}
@@ -200,7 +201,7 @@ class boss_sindragosa : public CreatureScript
struct boss_sindragosaAI : public BossAI
{
boss_sindragosaAI(Creature* creature) : BossAI(creature, DATA_SINDRAGOSA)
boss_sindragosaAI(Creature* creature) : BossAI(creature, DATA_SINDRAGOSA), _summoned(false)
{
}
@@ -220,7 +221,7 @@ class boss_sindragosa : public CreatureScript
_isInAirPhase = false;
_isThirdPhase = false;
if (instance->GetData(DATA_SINDRAGOSA_FROSTWYRMS) != 255)
if (!_summoned)
{
me->SetCanFly(true);
me->SetDisableGravity(true);
@@ -266,10 +267,13 @@ class boss_sindragosa : public CreatureScript
{
if (action == ACTION_START_FROSTWYRM)
{
if (_summoned)
return;
_summoned = true;
if (TempSummon* summon = me->ToTempSummon())
summon->SetTempSummonType(TEMPSUMMON_DEAD_DESPAWN);
instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 255);
if (me->isDead())
return;
@@ -481,7 +485,7 @@ class boss_sindragosa : public CreatureScript
Position pos;
pos.Relocate(me);
pos.m_positionZ += 17.0f;
me->GetMotionMaster()->MoveTakeoff(POINT_TAKEOFF, pos, 8.30078125f);
me->GetMotionMaster()->MoveTakeoff(POINT_TAKEOFF, pos);
events.CancelEventGroup(EVENT_GROUP_LAND_PHASE);
events.ScheduleEvent(EVENT_AIR_PHASE, 110000);
break;
@@ -523,7 +527,7 @@ class boss_sindragosa : public CreatureScript
events.ScheduleEvent(EVENT_FROST_BREATH, urand(10000, 15000), EVENT_GROUP_LAND_PHASE);
events.ScheduleEvent(EVENT_UNCHAINED_MAGIC, urand(12000, 17000), EVENT_GROUP_LAND_PHASE);
events.ScheduleEvent(EVENT_ICY_GRIP, urand(35000, 40000), EVENT_GROUP_LAND_PHASE);
me->GetMotionMaster()->MoveLand(POINT_LAND_GROUND, SindragosaLandPos, 0.0f);
me->GetMotionMaster()->MoveLand(POINT_LAND_GROUND, SindragosaLandPos);
break;
case EVENT_THIRD_PHASE_CHECK:
{
@@ -550,6 +554,7 @@ class boss_sindragosa : public CreatureScript
uint8 _mysticBuffetStack;
bool _isInAirPhase;
bool _isThirdPhase;
bool _summoned;
};
CreatureAI* GetAI(Creature* creature) const
@@ -642,7 +647,7 @@ class npc_spinestalker : public CreatureScript
struct npc_spinestalkerAI : public ScriptedAI
{
npc_spinestalkerAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
npc_spinestalkerAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _summoned(false)
{
}
@@ -651,7 +656,7 @@ class npc_spinestalker : public CreatureScript
// Increase add count
if (!me->isDead())
{
_instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1); // this cannot be in Reset because reset also happens on evade
_instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, me->GetDBTableGUIDLow()); // this cannot be in Reset because reset also happens on evade
Reset();
}
}
@@ -664,7 +669,7 @@ class npc_spinestalker : public CreatureScript
_events.ScheduleEvent(EVENT_TAIL_SWEEP, urand(8000, 12000));
me->SetReactState(REACT_DEFENSIVE);
if (_instance->GetData(DATA_SPINESTALKER) != 255)
if (!_summoned)
{
me->SetCanFly(true);
me->SetDisableGravity(true);
@@ -674,20 +679,22 @@ class npc_spinestalker : public CreatureScript
void JustRespawned()
{
ScriptedAI::JustRespawned();
_instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1); // this cannot be in Reset because reset also happens on evade
_instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, me->GetDBTableGUIDLow()); // this cannot be in Reset because reset also happens on evade
}
void JustDied(Unit* /*killer*/)
{
_events.Reset();
_instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 0);
}
void DoAction(int32 const action)
{
if (action == ACTION_START_FROSTWYRM)
{
_instance->SetData(DATA_SPINESTALKER, 255);
if (_summoned)
return;
_summoned = true;
if (me->isDead())
return;
@@ -754,6 +761,7 @@ class npc_spinestalker : public CreatureScript
private:
EventMap _events;
InstanceScript* _instance;
bool _summoned;
};
CreatureAI* GetAI(Creature* creature) const
@@ -769,7 +777,7 @@ class npc_rimefang : public CreatureScript
struct npc_rimefangAI : public ScriptedAI
{
npc_rimefangAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
npc_rimefangAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _summoned(false)
{
}
@@ -778,7 +786,7 @@ class npc_rimefang : public CreatureScript
// Increase add count
if (!me->isDead())
{
_instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1); // this cannot be in Reset because reset also happens on evade
_instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, me->GetDBTableGUIDLow()); // this cannot be in Reset because reset also happens on evade
Reset();
}
}
@@ -791,7 +799,7 @@ class npc_rimefang : public CreatureScript
me->SetReactState(REACT_DEFENSIVE);
_icyBlastCounter = 0;
if (_instance->GetData(DATA_RIMEFANG) != 255)
if (!_summoned)
{
me->SetCanFly(true);
me->SetDisableGravity(true);
@@ -801,20 +809,22 @@ class npc_rimefang : public CreatureScript
void JustRespawned()
{
ScriptedAI::JustRespawned();
_instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1); // this cannot be in Reset because reset also happens on evade
_instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, me->GetDBTableGUIDLow()); // this cannot be in Reset because reset also happens on evade
}
void JustDied(Unit* /*killer*/)
{
_events.Reset();
_instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 0);
}
void DoAction(int32 const action)
{
if (action == ACTION_START_FROSTWYRM)
{
_instance->SetData(DATA_RIMEFANG, 255);
if (_summoned)
return;
_summoned = true;
if (me->isDead())
return;
@@ -908,6 +918,7 @@ class npc_rimefang : public CreatureScript
EventMap _events;
InstanceScript* _instance;
uint8 _icyBlastCounter;
bool _summoned;
};
CreatureAI* GetAI(Creature* creature) const
@@ -934,7 +945,8 @@ class npc_sindragosa_trash : public CreatureScript
// Increase add count
if (!me->isDead())
{
_instance->SetData(_frostwyrmId, 1); // this cannot be in Reset because reset also happens on evade
if (me->GetEntry() == NPC_FROSTWING_WHELP)
_instance->SetData(_frostwyrmId, me->GetDBTableGUIDLow()); // this cannot be in Reset because reset also happens on evade
Reset();
}
}
@@ -956,13 +968,8 @@ class npc_sindragosa_trash : public CreatureScript
ScriptedAI::JustRespawned();
// Increase add count
_instance->SetData(_frostwyrmId, 1); // this cannot be in Reset because reset also happens on evade
}
void JustDied(Unit* /*killer*/)
{
// Decrease add count
_instance->SetData(_frostwyrmId, 0);
if (me->GetEntry() == NPC_FROSTWING_WHELP)
_instance->SetData(_frostwyrmId, me->GetDBTableGUIDLow()); // this cannot be in Reset because reset also happens on evade
}
void SetData(uint32 type, uint32 data)
@@ -1035,12 +1042,31 @@ class spell_sindragosa_s_fury : public SpellScriptLoader
bool Load()
{
_targetCount = 0;
return true;
// This script should execute only in Icecrown Citadel
if (InstanceMap* instance = GetCaster()->GetMap()->ToInstanceMap())
if (instance->GetInstanceScript())
if (instance->GetScriptId() == sObjectMgr->GetScriptId(ICCScriptName))
return true;
return false;
}
void CountTargets(std::list<Unit*>& unitList)
void SelectDest()
{
_targetCount = unitList.size();
if (Position* dest = const_cast<WorldLocation*>(GetExplTargetDest()))
{
float destX = float(rand_norm()) * 75.0f + 4350.0f;
float destY = float(rand_norm()) * 75.0f + 2450.0f;
float destZ = 205.0f; // random number close to ground, get exact in next call
GetCaster()->UpdateGroundPositionZ(destX, destY, destZ);
dest->Relocate(destX, destY, destZ);
}
}
void CountTargets(std::list<WorldObject*>& targets)
{
_targetCount = targets.size();
}
void HandleDummy(SpellEffIndex effIndex)
@@ -1051,10 +1077,10 @@ class spell_sindragosa_s_fury : public SpellScriptLoader
return;
float resistance = float(GetHitUnit()->GetResistance(SpellSchoolMask(GetSpellInfo()->SchoolMask)));
uint32 minResistFactor = uint32((resistance / (resistance + 510.0f))* 10.0f) * 2;
uint32 randomResist = urand(0, (9 - minResistFactor) * 100)/100 + minResistFactor;
uint32 minResistFactor = uint32((resistance / (resistance + 510.0f)) * 10.0f) * 2;
uint32 randomResist = urand(0, (9 - minResistFactor) * 100) / 100 + minResistFactor;
uint32 damage = (uint32(GetEffectValue()/_targetCount) * randomResist) / 10;
uint32 damage = (uint32(GetEffectValue() / _targetCount) * randomResist) / 10;
SpellNonMeleeDamage damageInfo(GetCaster(), GetHitUnit(), GetSpellInfo()->Id, GetSpellInfo()->SchoolMask);
damageInfo.damage = damage;
@@ -1064,8 +1090,9 @@ class spell_sindragosa_s_fury : public SpellScriptLoader
void Register()
{
BeforeCast += SpellCastFn(spell_sindragosa_s_fury_SpellScript::SelectDest);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sindragosa_s_fury_SpellScript::CountTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY);
OnEffectHitTarget += SpellEffectFn(spell_sindragosa_s_fury_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_sindragosa_s_fury_SpellScript::CountTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY);
}
uint32 _targetCount;
@@ -1082,9 +1109,11 @@ class UnchainedMagicTargetSelector
public:
UnchainedMagicTargetSelector() { }
bool operator()(Unit* unit)
bool operator()(WorldObject* object) const
{
return unit->getPowerType() != POWER_MANA;
if (Unit* unit = object->ToUnit())
return unit->getPowerType() != POWER_MANA;
return true;
}
};
@@ -1097,7 +1126,7 @@ class spell_sindragosa_unchained_magic : public SpellScriptLoader
{
PrepareSpellScript(spell_sindragosa_unchained_magic_SpellScript);
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& unitList)
{
unitList.remove_if(UnchainedMagicTargetSelector());
uint32 maxSize = uint32(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 6 : 2);
@@ -1107,7 +1136,7 @@ class spell_sindragosa_unchained_magic : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_sindragosa_unchained_magic_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sindragosa_unchained_magic_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
@@ -1290,7 +1319,7 @@ class MysticBuffetTargetFilter
public:
explicit MysticBuffetTargetFilter(Unit* caster) : _caster(caster) { }
bool operator()(Unit* unit)
bool operator()(WorldObject* unit) const
{
return !unit->IsWithinLOSInMap(_caster);
}
@@ -1308,14 +1337,14 @@ class spell_sindragosa_mystic_buffet : public SpellScriptLoader
{
PrepareSpellScript(spell_sindragosa_mystic_buffet_SpellScript);
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& targets)
{
unitList.remove_if(MysticBuffetTargetFilter(GetCaster()));
targets.remove_if(MysticBuffetTargetFilter(GetCaster()));
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_sindragosa_mystic_buffet_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sindragosa_mystic_buffet_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
@@ -1393,22 +1422,15 @@ class spell_frostwarden_handler_order_whelp : public SpellScriptLoader
return true;
}
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& targets)
{
for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end();)
{
if ((*itr)->GetTypeId() != TYPEID_PLAYER)
unitList.erase(itr++);
else
++itr;
}
if (unitList.empty())
targets.remove_if(Trinity::ObjectTypeIdCheck(TYPEID_PLAYER, false));
if (targets.empty())
return;
Unit* target = Trinity::Containers::SelectRandomContainerElement(unitList);
unitList.clear();
unitList.push_back(target);
WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
targets.clear();
targets.push_back(target);
}
void HandleForcedCast(SpellEffIndex effIndex)
@@ -1429,7 +1451,7 @@ class spell_frostwarden_handler_order_whelp : public SpellScriptLoader
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_frostwarden_handler_order_whelp_SpellScript::HandleForcedCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST);
OnUnitTargetSelect += SpellUnitTargetFn(spell_frostwarden_handler_order_whelp_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_frostwarden_handler_order_whelp_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
@@ -1509,7 +1531,7 @@ class at_sindragosa_lair : public AreaTriggerScript
if (Creature* rimefang = ObjectAccessor::GetCreature(*player, instance->GetData64(DATA_RIMEFANG)))
rimefang->AI()->DoAction(ACTION_START_FROSTWYRM);
if (!instance->GetData(DATA_SINDRAGOSA_FROSTWYRMS) && instance->GetBossState(DATA_SINDRAGOSA) != DONE)
if (!instance->GetData(DATA_SINDRAGOSA_FROSTWYRMS) && !instance->GetData64(DATA_SINDRAGOSA) && instance->GetBossState(DATA_SINDRAGOSA) != DONE)
{
if (player->GetMap()->IsHeroic() && !instance->GetData(DATA_HEROIC_ATTEMPTS))
return true;
@@ -138,7 +138,7 @@ enum Spells
SPELL_IN_FROSTMOURNE_ROOM = 74276,
SPELL_KILL_FROSTMOURNE_PLAYERS = 75127,
SPELL_HARVESTED_SOUL = 72679,
SPELL_TRIGGER_VILE_SPIRIT_HEROIC = 73582,
SPELL_TRIGGER_VILE_SPIRIT_HEROIC = 73582, // TODO: Cast every 3 seconds during Frostmourne phase, targets a Wicked Spirit amd activates it
// Frostmourne
SPELL_LIGHTS_FAVOR = 69382,
@@ -152,6 +152,7 @@ enum Spells
SPELL_SUMMON_SPIRIT_BOMB_1 = 73581, // (Heroic)
SPELL_SUMMON_SPIRIT_BOMB_2 = 74299, // (Heroic)
SPELL_EXPLOSION = 73576, // Spirit Bomb (Heroic)
SPELL_HARVEST_SOUL_DAMAGE_AURA = 73655,
// Outro
SPELL_FURY_OF_FROSTMOURNE = 72350,
@@ -221,7 +222,7 @@ enum Events
EVENT_QUAKE_2 = 27,
EVENT_VILE_SPIRITS = 28,
EVENT_HARVEST_SOULS = 29, // heroic only
EVENT_WICKED_SPIRITS = 30,
EVENT_BERSERK = 30,
EVENT_SOUL_RIP = 31,
EVENT_DESTROY_SOUL = 32,
EVENT_FROSTMOURNE_TALK_1 = 33,
@@ -249,19 +250,18 @@ enum Events
EVENT_OUTRO_TERENAS_TALK_2 = 55,
EVENT_OUTRO_TALK_7 = 56,
EVENT_OUTRO_TALK_8 = 57,
EVENT_BERSERK = 58,
// Shambling Horror
EVENT_SHOCKWAVE = 59,
EVENT_ENRAGE = 60,
EVENT_SHOCKWAVE = 58,
EVENT_ENRAGE = 59,
// Raging Spirit
EVENT_SOUL_SHRIEK = 61,
EVENT_SOUL_SHRIEK = 60,
// Strangulate Vehicle (Harvest Soul)
EVENT_TELEPORT = 62,
EVENT_MOVE_TO_LICH_KING = 63,
EVENT_DESPAWN_SELF = 64,
EVENT_TELEPORT = 61,
EVENT_MOVE_TO_LICH_KING = 62,
EVENT_DESPAWN_SELF = 63,
};
enum EventGroups
@@ -391,7 +391,7 @@ class HeightDifferenceCheck
{
}
bool operator()(Unit* unit) const
bool operator()(WorldObject* unit) const
{
return (unit->GetPositionZ() - _baseObject->GetPositionZ() > _difference) != _reverse;
}
@@ -475,6 +475,32 @@ class VileSpiritActivateEvent : public BasicEvent
Creature* _owner;
};
class TriggerWickedSpirit : public BasicEvent
{
public:
explicit TriggerWickedSpirit(Creature* owner)
: _owner(owner), _counter(13)
{
}
bool Execute(uint64 /*time*/, uint32 /*diff*/)
{
_owner->CastCustomSpell(SPELL_TRIGGER_VILE_SPIRIT_HEROIC, SPELLVALUE_MAX_TARGETS, 1, NULL, true);
if (--_counter)
{
_owner->m_Events.AddEvent(this, _owner->m_Events.CalculateTime(3000));
return false;
}
return true;
}
private:
Creature* _owner;
uint32 _counter;
};
class boss_the_lich_king : public CreatureScript
{
public:
@@ -503,6 +529,8 @@ class boss_the_lich_king : public CreatureScript
me->SetDisableGravity(false);
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
me->GetMotionMaster()->MoveFall();
if (Creature* frostmourne = me->FindNearestCreature(NPC_FROSTMOURNE_TRIGGER, 50.0f))
frostmourne->DespawnOrUnsummon();
}
void EnterCombat(Unit* target)
@@ -601,8 +629,6 @@ class boss_the_lich_king : public CreatureScript
summons.DoAction(ACTION_TELEPORT_BACK, pred);
if (!IsHeroic())
Talk(SAY_LK_FROSTMOURNE_ESCAPE);
else
DoCastAOE(SPELL_TRIGGER_VILE_SPIRIT_HEROIC);
break;
}
default:
@@ -645,6 +671,8 @@ class boss_the_lich_king : public CreatureScript
if (events.GetPhaseMask() & PHASE_MASK_ONE && !HealthAbovePct(70))
{
events.SetPhase(PHASE_TRANSITION);
me->SetReactState(REACT_PASSIVE);
me->AttackStop();
me->GetMotionMaster()->MovePoint(POINT_CENTER_1, CenterPosition);
return;
}
@@ -652,6 +680,8 @@ class boss_the_lich_king : public CreatureScript
if (events.GetPhaseMask() & PHASE_MASK_TWO && !HealthAbovePct(40))
{
events.SetPhase(PHASE_TRANSITION);
me->SetReactState(REACT_PASSIVE);
me->AttackStop();
me->GetMotionMaster()->MovePoint(POINT_CENTER_2, CenterPosition);
return;
}
@@ -664,7 +694,8 @@ class boss_the_lich_king : public CreatureScript
events.SetPhase(PHASE_OUTRO);
summons.DespawnAll();
SendMusicToPlayers(MUSIC_FURY_OF_FROSTMOURNE);
DoCastAOE(SPELL_FURY_OF_FROSTMOURNE);
me->InterruptNonMeleeSpells(true);
me->CastSpell((Unit*)NULL, SPELL_FURY_OF_FROSTMOURNE, TRIGGERED_NONE);
me->SetWalk(true);
events.ScheduleEvent(EVENT_OUTRO_TALK_1, 2600, 0, PHASE_OUTRO);
events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 6600, 0, PHASE_OUTRO);
@@ -712,7 +743,6 @@ class boss_the_lich_king : public CreatureScript
break;
case NPC_FROSTMOURNE_TRIGGER:
{
summons.Summon(summon);
summon->CastSpell((Unit*)NULL, SPELL_BROKEN_FROSTMOURNE, true);
SendLightOverride(LIGHT_SOULSTORM, 10000);
@@ -724,16 +754,11 @@ class boss_the_lich_king : public CreatureScript
case NPC_VILE_SPIRIT:
{
summons.Summon(summon);
if (events.GetPhaseMask() & PHASE_MASK_FROSTMOURNE)
{
TeleportSpirit(summon);
return;
}
summon->SetReactState(REACT_PASSIVE);
summon->SetSpeed(MOVE_FLIGHT, 0.5f);
summon->GetMotionMaster()->MoveRandom(10.0f);
summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(15000));
if (!(events.GetPhaseMask() & PHASE_MASK_FROSTMOURNE))
summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(15000));
return;
}
case NPC_STRANGULATE_VEHICLE:
@@ -756,7 +781,6 @@ class boss_the_lich_king : public CreatureScript
case NPC_VALKYR_SHADOWGUARD:
case NPC_RAGING_SPIRIT:
case NPC_VILE_SPIRIT:
case NPC_WICKED_SPIRIT:
summon->ToTempSummon()->SetTempSummonType(TEMPSUMMON_CORPSE_DESPAWN);
break;
default:
@@ -802,8 +826,6 @@ class boss_the_lich_king : public CreatureScript
me->SetFacingTo(0.0f);
Talk(SAY_LK_REMORSELESS_WINTER);
SendMusicToPlayers(MUSIC_SPECIAL);
me->SetReactState(REACT_PASSIVE);
me->AttackStop();
DoCast(me, SPELL_REMORSELESS_WINTER_1);
events.DelayEvents(62500, EVENT_GROUP_BERSERK); // delay berserk timer, its not ticking during phase transitions
events.ScheduleEvent(EVENT_QUAKE, 62500, 0, PHASE_TRANSITION);
@@ -819,8 +841,6 @@ class boss_the_lich_king : public CreatureScript
me->SetFacingTo(0.0f);
Talk(SAY_LK_REMORSELESS_WINTER);
SendMusicToPlayers(MUSIC_SPECIAL);
me->SetReactState(REACT_PASSIVE);
me->AttackStop();
DoCast(me, SPELL_REMORSELESS_WINTER_2);
summons.DespawnEntry(NPC_VALKYR_SHADOWGUARD);
events.DelayEvents(62500, EVENT_GROUP_BERSERK); // delay berserk timer, its not ticking during phase transitions
@@ -992,10 +1012,6 @@ class boss_the_lich_king : public CreatureScript
DoCastAOE(SPELL_VILE_SPIRITS);
events.ScheduleEvent(EVENT_VILE_SPIRITS, urand(35000, 40000), EVENT_GROUP_VILE_SPIRITS, PHASE_THREE);
break;
case EVENT_WICKED_SPIRITS:
DoCastAOE(SPELL_VILE_SPIRITS);
events.ScheduleEvent(EVENT_WICKED_SPIRITS, urand(35000, 40000), 0, PHASE_FROSTMOURNE);
break;
case EVENT_HARVEST_SOULS:
Talk(SAY_LK_HARVEST_SOUL);
DoCastAOE(SPELL_HARVEST_SOULS);
@@ -1003,7 +1019,6 @@ class boss_the_lich_king : public CreatureScript
events.SetPhase(PHASE_FROSTMOURNE); // will stop running UpdateVictim (no evading)
me->SetReactState(REACT_PASSIVE);
me->AttackStop();
events.ScheduleEvent(EVENT_WICKED_SPIRITS, events.GetNextEventTime(EVENT_VILE_SPIRITS) - events.GetTimer(), 0, PHASE_FROSTMOURNE);
events.DelayEvents(50000, EVENT_GROUP_VILE_SPIRITS);
events.RescheduleEvent(EVENT_DEFILE, 50000, 0, PHASE_THREE);
events.RescheduleEvent(EVENT_SOUL_REAPER, urand(57000, 62000), 0, PHASE_THREE);
@@ -1019,16 +1034,22 @@ class boss_the_lich_king : public CreatureScript
if (!triggers.empty())
{
triggers.sort(Trinity::ObjectDistanceOrderPred(terenas, true));
Unit* spawner = triggers.front();
Creature* spawner = triggers.front();
spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_1, true); // summons bombs randomly
spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_2, true); // summons bombs on players
spawner->m_Events.AddEvent(new TriggerWickedSpirit(spawner), spawner->m_Events.CalculateTime(3000));
}
for (SummonList::iterator i = summons.begin(); i != summons.end(); ++i)
{
Creature* summon = ObjectAccessor::GetCreature(*me, *i);
if (summon && summon->GetEntry() == NPC_VILE_SPIRIT)
TeleportSpirit(summon);
{
summon->m_Events.KillAllEvents(true);
summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(50000));
summon->GetMotionMaster()->MoveRandom(10.0f);
summon->SetReactState(REACT_PASSIVE);
}
}
}
break;
@@ -1099,22 +1120,6 @@ class boss_the_lich_king : public CreatureScript
}
private:
void TeleportSpirit(Creature* summon)
{
float dist = me->GetObjectSize() + (15.0f - me->GetObjectSize()) * float(rand_norm());
float angle = float(rand_norm()) * float(2.0f * M_PI);
Position dest = TerenasSpawnHeroic;
me->MovePosition(dest, dist, angle);
dest.m_positionZ += 15.0f;
summon->UpdateEntry(NPC_WICKED_SPIRIT);
summon->SetReactState(REACT_PASSIVE);
summon->NearTeleportTo(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), dest.GetOrientation());
summon->SetSpeed(MOVE_FLIGHT, 0.5f);
summon->m_Events.KillAllEvents(true);
summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(1000));
}
void SendMusicToPlayers(uint32 musicId) const
{
WorldPacket data(SMSG_PLAY_MUSIC, 4);
@@ -1635,8 +1640,13 @@ class npc_strangulate_vehicle : public CreatureScript
return;
if (TempSummon* summ = me->ToTempSummon())
{
if (Unit* summoner = summ->GetSummoner())
{
DoCast(summoner, SPELL_HARVEST_SOUL_TELEPORT_BACK);
summoner->RemoveAurasDueToSpell(SPELL_HARVEST_SOUL_DAMAGE_AURA);
}
}
if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))
lichKing->AI()->SummonedCreatureDespawn(me);
@@ -1993,6 +2003,10 @@ class npc_broken_frostmourne : public CreatureScript
_events.ScheduleEvent(EVENT_OUTRO_SUMMON_TERENAS, 6000, 0, PHASE_OUTRO);
}
void EnterEvadeMode()
{
}
void UpdateAI(uint32 const diff)
{
UpdateVictim();
@@ -2274,7 +2288,7 @@ class spell_the_lich_king_shadow_trap_periodic : public SpellScriptLoader
{
PrepareSpellScript(spell_the_lich_king_shadow_trap_periodic_SpellScript);
void CheckTargetCount(std::list<Unit*>& targets)
void CheckTargetCount(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
@@ -2284,7 +2298,7 @@ class spell_the_lich_king_shadow_trap_periodic : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_shadow_trap_periodic_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_shadow_trap_periodic_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
@@ -2308,10 +2322,10 @@ class spell_the_lich_king_quake : public SpellScriptLoader
return GetCaster()->GetInstanceScript() != NULL;
}
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& targets)
{
if (GameObject* platform = ObjectAccessor::GetGameObject(*GetCaster(), GetCaster()->GetInstanceScript()->GetData64(DATA_ARTHAS_PLATFORM)))
unitList.remove_if(HeightDifferenceCheck(platform, 5.0f, false));
targets.remove_if(HeightDifferenceCheck(platform, 5.0f, false));
}
void HandleSendEvent(SpellEffIndex /*effIndex*/)
@@ -2322,7 +2336,7 @@ class spell_the_lich_king_quake : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_quake_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_quake_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
OnEffectHit += SpellEffectFn(spell_the_lich_king_quake_SpellScript::HandleSendEvent, EFFECT_1, SPELL_EFFECT_SEND_EVENT);
}
};
@@ -2349,7 +2363,7 @@ class spell_the_lich_king_ice_burst_target_search : public SpellScriptLoader
return true;
}
void CheckTargetCount(std::list<Unit*>& unitList)
void CheckTargetCount(std::list<WorldObject*>& unitList)
{
if (unitList.empty())
return;
@@ -2357,12 +2371,16 @@ class spell_the_lich_king_ice_burst_target_search : public SpellScriptLoader
// if there is at least one affected target cast the explosion
GetCaster()->CastSpell(GetCaster(), SPELL_ICE_BURST, true);
if (GetCaster()->GetTypeId() == TYPEID_UNIT)
{
GetCaster()->ToCreature()->SetReactState(REACT_PASSIVE);
GetCaster()->AttackStop();
GetCaster()->ToCreature()->DespawnOrUnsummon(500);
}
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_ice_burst_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_ice_burst_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
@@ -2411,7 +2429,7 @@ class ExactDistanceCheck
public:
ExactDistanceCheck(Unit* source, float dist) : _source(source), _dist(dist) {}
bool operator()(Unit* unit)
bool operator()(WorldObject* unit)
{
return _source->GetExactDist2d(unit) > _dist;
}
@@ -2430,7 +2448,7 @@ class spell_the_lich_king_defile : public SpellScriptLoader
{
PrepareSpellScript(spell_the_lich_king_defile_SpellScript);
void CorrectRange(std::list<Unit*>& targets)
void CorrectRange(std::list<WorldObject*>& targets)
{
targets.remove_if(ExactDistanceCheck(GetCaster(), 10.0f * GetCaster()->GetFloatValue(OBJECT_FIELD_SCALE_X)));
}
@@ -2446,8 +2464,8 @@ class spell_the_lich_king_defile : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_defile_SpellScript::CorrectRange, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_defile_SpellScript::CorrectRange, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_defile_SpellScript::CorrectRange, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_defile_SpellScript::CorrectRange, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnHit += SpellHitFn(spell_the_lich_king_defile_SpellScript::ChangeDamageAndGrow);
}
};
@@ -2472,14 +2490,18 @@ class spell_the_lich_king_summon_into_air : public SpellScriptLoader
static Position const offset = {0.0f, 0.0f, 15.0f, 0.0f};
WorldLocation* dest = const_cast<WorldLocation*>(GetExplTargetDest());
dest->RelocateOffset(offset);
GetHitDest()->RelocateOffset(offset);
// spirit bombs get higher
if (GetSpellInfo()->Effects[effIndex].MiscValue == NPC_SPIRIT_BOMB)
{
dest->RelocateOffset(offset);
GetHitDest()->RelocateOffset(offset);
}
}
void Register()
{
OnEffectLaunch += SpellEffectFn(spell_the_lich_king_summon_into_air_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON);
OnEffectHit += SpellEffectFn(spell_the_lich_king_summon_into_air_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON);
}
};
@@ -2545,26 +2567,26 @@ class spell_the_lich_king_valkyr_target_search : public SpellScriptLoader
return true;
}
void SelectTarget(std::list<Unit*>& unitList)
void SelectTarget(std::list<WorldObject*>& targets)
{
if (unitList.empty())
if (targets.empty())
return;
unitList.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Id));
if (unitList.empty())
targets.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Id));
if (targets.empty())
return;
_target = Trinity::Containers::SelectRandomContainerElement(unitList);
unitList.clear();
unitList.push_back(_target);
_target = Trinity::Containers::SelectRandomContainerElement(targets);
targets.clear();
targets.push_back(_target);
GetCaster()->GetAI()->SetGUID(_target->GetGUID());
}
void ReplaceTarget(std::list<Unit*>& unitList)
void ReplaceTarget(std::list<WorldObject*>& targets)
{
unitList.clear();
targets.clear();
if (_target)
unitList.push_back(_target);
targets.push_back(_target);
}
void HandleScript(SpellEffIndex effIndex)
@@ -2575,12 +2597,12 @@ class spell_the_lich_king_valkyr_target_search : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_valkyr_target_search_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_valkyr_target_search_SpellScript::ReplaceTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_valkyr_target_search_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_valkyr_target_search_SpellScript::ReplaceTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_valkyr_target_search_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
Unit* _target;
WorldObject* _target;
};
SpellScript* GetSpellScript() const
@@ -2757,7 +2779,7 @@ class spell_the_lich_king_vile_spirit_move_target_search : public SpellScriptLoa
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
void SelectTarget(std::list<Unit*>& targets)
void SelectTarget(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
@@ -2778,11 +2800,11 @@ class spell_the_lich_king_vile_spirit_move_target_search : public SpellScriptLoa
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_vile_spirit_move_target_search_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_vile_spirit_move_target_search_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_vile_spirit_move_target_search_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
Unit* _target;
WorldObject* _target;
};
SpellScript* GetSpellScript() const
@@ -2805,7 +2827,7 @@ class spell_the_lich_king_vile_spirit_damage_target_search : public SpellScriptL
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
void CheckTargetCount(std::list<Unit*>& targets)
void CheckTargetCount(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
@@ -2822,7 +2844,7 @@ class spell_the_lich_king_vile_spirit_damage_target_search : public SpellScriptL
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_vile_spirit_damage_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_vile_spirit_damage_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
Unit* _target;
@@ -2954,6 +2976,15 @@ class spell_the_lich_king_restore_soul : public SpellScriptLoader
lichKing->AI()->DoAction(ACTION_TELEPORT_BACK);
if (Creature* spawner = GetCaster()->FindNearestCreature(NPC_WORLD_TRIGGER_INFINITE_AOI, 50.0f))
spawner->RemoveAllAuras();
std::list<Creature*> spirits;
GetCaster()->GetCreatureListWithEntryInGrid(spirits, NPC_WICKED_SPIRIT, 200.0f);
for (std::list<Creature*>::iterator itr = spirits.begin(); itr != spirits.end(); ++itr)
{
(*itr)->m_Events.KillAllEvents(true);
(*itr)->SetReactState(REACT_PASSIVE);
(*itr)->AI()->EnterEvadeMode();
}
}
void RemoveAura()
@@ -3046,23 +3077,18 @@ class spell_the_lich_king_trigger_vile_spirit : public SpellScriptLoader
{
PrepareSpellScript(spell_the_lich_king_trigger_vile_spirit_SpellScript);
void TeleportOutside()
void ActivateSpirit()
{
Creature* target = GetHitCreature();
if (!target)
return;
Position dest;
Position offset;
TerenasSpawnHeroic.GetPositionOffsetTo(*target, offset);
GetCaster()->GetPosition(&dest);
dest.RelocateOffset(offset);
target->NearTeleportTo(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), dest.GetOrientation());
VileSpiritActivateEvent(target).Execute(0, 0);
}
void Register()
{
OnHit += SpellHitFn(spell_the_lich_king_trigger_vile_spirit_SpellScript::TeleportOutside);
OnHit += SpellHitFn(spell_the_lich_king_trigger_vile_spirit_SpellScript::ActivateSpirit);
}
};
@@ -1013,11 +1013,8 @@ class npc_dream_portal : public CreatureScript
{
}
void DoAction(int32 const action)
void OnSpellClick(Unit* /*clicker*/)
{
if (action != EVENT_SPELLCLICK)
return;
_used = true;
me->DespawnOrUnsummon();
}
@@ -1190,13 +1187,13 @@ class spell_dreamwalker_summoner : public SpellScriptLoader
return true;
}
void FilterTargets(std::list<Unit*>& targets)
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if (Trinity::UnitAuraCheck(true, SPELL_RECENTLY_SPAWNED));
targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_RECENTLY_SPAWNED));
if (targets.empty())
return;
Unit* target = Trinity::Containers::SelectRandomContainerElement(targets);
WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
targets.clear();
targets.push_back(target);
}
@@ -1212,7 +1209,7 @@ class spell_dreamwalker_summoner : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_dreamwalker_summoner_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dreamwalker_summoner_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
OnEffectHitTarget += SpellEffectFn(spell_dreamwalker_summoner_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST);
}
};
@@ -1241,7 +1238,7 @@ class spell_dreamwalker_summon_suppresser : public SpellScriptLoader
std::list<Creature*> summoners;
GetCreatureListWithEntryInGrid(summoners, caster, NPC_WORLD_TRIGGER, 100.0f);
summoners.remove_if (Trinity::UnitAuraCheck(true, SPELL_RECENTLY_SPAWNED));
summoners.remove_if(Trinity::UnitAuraCheck(true, SPELL_RECENTLY_SPAWNED));
Trinity::Containers::RandomResizeList(summoners, 2);
if (summoners.empty())
return;
@@ -19,6 +19,7 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedEscortAI.h"
#include "PassiveAI.h"
#include "Cell.h"
#include "CellImpl.h"
#include "GridNotifiers.h"
@@ -158,6 +159,9 @@ enum Spells
SPELL_FEL_IRON_BOMB_UNDEAD = 71787,
SPELL_MACHINE_GUN_UNDEAD = 71788,
SPELL_ROCKET_LAUNCH_UNDEAD = 71786,
// Invisible Stalker (Float, Uninteractible, LargeAOI)
SPELL_SOUL_MISSILE = 72585,
};
// Helper defines
@@ -248,6 +252,9 @@ enum EventTypes
EVENT_RUPERT_FEL_IRON_BOMB = 52,
EVENT_RUPERT_MACHINE_GUN = 53,
EVENT_RUPERT_ROCKET_LAUNCH = 54,
// Invisible Stalker (Float, Uninteractible, LargeAOI)
EVENT_SOUL_MISSILE = 55,
};
enum DataTypesICC
@@ -1668,6 +1675,56 @@ class npc_impaling_spear : public CreatureScript
}
};
class npc_arthas_teleport_visual : public CreatureScript
{
public:
npc_arthas_teleport_visual() : CreatureScript("npc_arthas_teleport_visual") { }
struct npc_arthas_teleport_visualAI : public NullCreatureAI
{
npc_arthas_teleport_visualAI(Creature* creature) : NullCreatureAI(creature), _instance(creature->GetInstanceScript())
{
}
void Reset()
{
_events.Reset();
if (_instance->GetBossState(DATA_PROFESSOR_PUTRICIDE) == DONE &&
_instance->GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) == DONE &&
_instance->GetBossState(DATA_SINDRAGOSA) == DONE)
_events.ScheduleEvent(EVENT_SOUL_MISSILE, urand(1000, 6000));
}
void UpdateAI(uint32 const diff)
{
if (_events.Empty())
return;
_events.Update(diff);
if (_events.ExecuteEvent() == EVENT_SOUL_MISSILE)
{
DoCastAOE(SPELL_SOUL_MISSILE);
_events.ScheduleEvent(EVENT_SOUL_MISSILE, urand(5000, 7000));
}
}
private:
InstanceScript* _instance;
EventMap _events;
};
CreatureAI* GetAI(Creature* creature) const
{
// Distance from the center of the spire
if (creature->GetExactDist2d(4357.052f, 2769.421f) < 100.0f && creature->GetHomePosition().GetPositionZ() < 315.0f)
return GetIcecrownCitadelAI<npc_arthas_teleport_visualAI>(creature);
// Default to no script
return NULL;
}
};
class spell_icc_stoneform : public SpellScriptLoader
{
public:
@@ -1777,15 +1834,15 @@ class DeathPlagueTargetSelector
public:
explicit DeathPlagueTargetSelector(Unit* caster) : _caster(caster) {}
bool operator()(Unit* unit)
bool operator()(WorldObject* object) const
{
if (unit == _caster)
if (object == _caster)
return true;
if (unit->GetTypeId() != TYPEID_PLAYER)
if (object->GetTypeId() != TYPEID_PLAYER)
return true;
if (unit->HasAura(SPELL_RECENTLY_INFECTED) || unit->HasAura(SPELL_DEATH_PLAGUE_AURA))
if (object->ToUnit()->HasAura(SPELL_RECENTLY_INFECTED) || object->ToUnit()->HasAura(SPELL_DEATH_PLAGUE_AURA))
return true;
return false;
@@ -1811,25 +1868,25 @@ class spell_frost_giant_death_plague : public SpellScriptLoader
}
// First effect
void CountTargets(std::list<Unit*>& unitList)
void CountTargets(std::list<WorldObject*>& targets)
{
unitList.remove(GetCaster());
_failed = unitList.empty();
targets.remove(GetCaster());
_failed = targets.empty();
}
// Second effect
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& targets)
{
// Select valid targets for jump
unitList.remove_if (DeathPlagueTargetSelector(GetCaster()));
if (!unitList.empty())
targets.remove_if(DeathPlagueTargetSelector(GetCaster()));
if (!targets.empty())
{
Unit* target = Trinity::Containers::SelectRandomContainerElement(unitList);
unitList.clear();
unitList.push_back(target);
WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
targets.clear();
targets.push_back(target);
}
unitList.push_back(GetCaster());
targets.push_back(GetCaster());
}
void HandleScript(SpellEffIndex effIndex)
@@ -1843,8 +1900,8 @@ class spell_frost_giant_death_plague : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_frost_giant_death_plague_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_frost_giant_death_plague_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ALLY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_frost_giant_death_plague_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_frost_giant_death_plague_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ALLY);
OnEffectHitTarget += SpellEffectFn(spell_frost_giant_death_plague_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
@@ -1893,9 +1950,11 @@ class spell_icc_harvest_blight_specimen : public SpellScriptLoader
class AliveCheck
{
public:
bool operator()(Unit* unit)
bool operator()(WorldObject* object) const
{
return unit->isAlive();
if (Unit* unit = object->ToUnit())
return unit->isAlive();
return true;
}
};
@@ -1908,10 +1967,10 @@ class spell_svalna_revive_champion : public SpellScriptLoader
{
PrepareSpellScript(spell_svalna_revive_champion_SpellScript);
void RemoveAliveTarget(std::list<Unit*>& unitList)
void RemoveAliveTarget(std::list<WorldObject*>& targets)
{
unitList.remove_if(AliveCheck());
Trinity::Containers::RandomResizeList(unitList, 2);
targets.remove_if(AliveCheck());
Trinity::Containers::RandomResizeList(targets, 2);
}
void Land(SpellEffIndex /*effIndex*/)
@@ -1926,12 +1985,12 @@ class spell_svalna_revive_champion : public SpellScriptLoader
//pos.m_positionZ = caster->GetBaseMap()->GetHeight(caster->GetPhaseMask(), pos.GetPositionX(), pos.GetPositionY(), caster->GetPositionZ(), true, 50.0f);
//pos.m_positionZ += 0.05f;
caster->SetHomePosition(pos);
caster->GetMotionMaster()->MoveLand(POINT_LAND, pos, caster->GetSpeed(MOVE_FLIGHT));
caster->GetMotionMaster()->MoveLand(POINT_LAND, pos);
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_svalna_revive_champion_SpellScript::RemoveAliveTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_svalna_revive_champion_SpellScript::RemoveAliveTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY);
OnEffectHit += SpellEffectFn(spell_svalna_revive_champion_SpellScript::Land, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
@@ -1974,6 +2033,33 @@ class spell_svalna_remove_spear : public SpellScriptLoader
}
};
class spell_icc_soul_missile : public SpellScriptLoader
{
public:
spell_icc_soul_missile() : SpellScriptLoader("spell_icc_soul_missile") { }
class spell_icc_soul_missile_SpellScript : public SpellScript
{
PrepareSpellScript(spell_icc_soul_missile_SpellScript);
void RelocateDest()
{
static Position const offset = {0.0f, 0.0f, 200.0f, 0.0f};
const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset);
}
void Register()
{
OnCast += SpellCastFn(spell_icc_soul_missile_SpellScript::RelocateDest);
}
};
SpellScript* GetSpellScript() const
{
return new spell_icc_soul_missile_SpellScript();
}
};
class at_icc_saurfang_portal : public AreaTriggerScript
{
public:
@@ -2063,6 +2149,7 @@ void AddSC_icecrown_citadel()
new npc_captain_rupert();
new npc_frostwing_vrykul();
new npc_impaling_spear();
new npc_arthas_teleport_visual();
new spell_icc_stoneform();
new spell_icc_sprit_alarm();
new spell_frost_giant_death_plague();
@@ -2070,6 +2157,7 @@ void AddSC_icecrown_citadel()
new spell_trigger_spell_from_caster("spell_svalna_caress_of_death", SPELL_IMPALING_SPEAR_KILL);
new spell_svalna_revive_champion();
new spell_svalna_remove_spear();
new spell_icc_soul_missile();
new at_icc_saurfang_portal();
new at_icc_shutdown_traps();
new at_icc_start_blood_quickening();
@@ -51,6 +51,7 @@ enum SharedSpells
SPELL_GREEN_BLIGHT_RESIDUE = 72145,
// The Lich King
SPELL_ARTHAS_TELEPORTER_CEREMONY = 72915,
SPELL_FROSTMOURNE_TELEPORT_VISUAL = 73078,
};
@@ -275,6 +276,9 @@ enum CreaturesIds
NPC_WORLD_TRIGGER_INFINITE_AOI = 36171,
NPC_SPIRIT_BOMB = 39189,
NPC_FROSTMOURNE_TRIGGER = 38584,
// Generic
NPC_INVISIBLE_STALKER = 30298,
};
enum GameObjectsIds
@@ -345,6 +349,7 @@ enum GameObjectsIds
GO_SIGIL_OF_THE_FROSTWING = 202181,
// The Lich King
GO_SCOURGE_TRANSPORTER_LK = 202223,
GO_ARTHAS_PLATFORM = 202161,
GO_ARTHAS_PRECIPICE = 202078,
GO_DOODAD_ICECROWN_THRONEFROSTYWIND01 = 202188,
@@ -130,6 +130,7 @@ class instance_icecrown_citadel : public InstanceMapScript
SindragosaGUID = 0;
SpinestalkerGUID = 0;
RimefangGUID = 0;
TheLichKingTeleportGUID = 0;
TheLichKingGUID = 0;
HighlordTirionFordringGUID = 0;
TerenasMenethilGUID = 0;
@@ -138,9 +139,6 @@ class instance_icecrown_citadel : public InstanceMapScript
FrozenThroneEdgeGUID = 0;
FrozenThroneWindGUID = 0;
FrozenThroneWarningGUID = 0;
FrostwyrmCount = 0;
SpinestalkerTrashCount = 0;
RimefangTrashCount = 0;
IsBonedEligible = true;
IsOozeDanceEligible = true;
IsNauseaEligible = true;
@@ -283,6 +281,11 @@ class instance_icecrown_citadel : public InstanceMapScript
case NPC_RIMEFANG:
RimefangGUID = creature->GetGUID();
break;
case NPC_INVISIBLE_STALKER:
// Teleporter visual at center
if (creature->GetExactDist2d(4357.052f, 2769.421f) < 10.0f)
creature->CastSpell(creature, SPELL_ARTHAS_TELEPORTER_CEREMONY, false);
break;
case NPC_THE_LICH_KING:
TheLichKingGUID = creature->GetGUID();
break;
@@ -293,11 +296,22 @@ class instance_icecrown_citadel : public InstanceMapScript
case NPC_TERENAS_MENETHIL_FROSTMOURNE_H:
TerenasMenethilGUID = creature->GetGUID();
break;
case NPC_WICKED_SPIRIT:
// Remove corpse as soon as it dies (and respawn 10 seconds later)
creature->SetCorpseDelay(0);
creature->SetReactState(REACT_PASSIVE);
break;
default:
break;
}
}
void OnCreatureRemove(Creature* creature)
{
if (creature->GetEntry() == NPC_SINDRAGOSA)
SindragosaGUID = 0;
}
// Weekly quest spawn prevention
uint32 GetCreatureEntry(uint32 /*guidLow*/, CreatureData const* data)
{
@@ -347,6 +361,43 @@ class instance_icecrown_citadel : public InstanceMapScript
if (Creature* crok = instance->GetCreature(CrokScourgebaneGUID))
crok->AI()->SetGUID(creature->GetGUID(), ACTION_VRYKUL_DEATH);
break;
case NPC_FROSTWING_WHELP:
if (FrostwyrmGUIDs.empty())
return;
if (creature->AI()->GetData(1/*DATA_FROSTWYRM_OWNER*/) == DATA_SPINESTALKER)
{
SpinestalkerTrash.erase(creature->GetDBTableGUIDLow());
if (SpinestalkerTrash.empty())
if (Creature* spinestalk = instance->GetCreature(SpinestalkerGUID))
spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM);
}
else
{
RimefangTrash.erase(creature->GetDBTableGUIDLow());
if (RimefangTrash.empty())
if (Creature* spinestalk = instance->GetCreature(RimefangGUID))
spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM);
}
break;
case NPC_RIMEFANG:
case NPC_SPINESTALKER:
{
if (instance->IsHeroic() && !HeroicAttempts)
return;
if (GetBossState(DATA_SINDRAGOSA) == DONE)
return;
FrostwyrmGUIDs.erase(creature->GetDBTableGUIDLow());
if (FrostwyrmGUIDs.empty())
{
instance->LoadGrid(SindragosaSpawnPos.GetPositionX(), SindragosaSpawnPos.GetPositionY());
if (Creature* boss = instance->SummonCreature(NPC_SINDRAGOSA, SindragosaSpawnPos))
boss->AI()->DoAction(ACTION_START_FROSTWYRM);
}
break;
}
default:
break;
}
@@ -460,6 +511,11 @@ class instance_icecrown_citadel : public InstanceMapScript
go->SetLootRecipient(valithria->GetLootRecipient());
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE | GO_FLAG_NODESPAWN);
break;
case GO_SCOURGE_TRANSPORTER_LK:
TheLichKingTeleportGUID = go->GetGUID();
if (GetBossState(DATA_PROFESSOR_PUTRICIDE) == DONE && GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) == DONE && GetBossState(DATA_SINDRAGOSA) == DONE)
go->SetGoState(GO_STATE_ACTIVE);
break;
case GO_ARTHAS_PLATFORM:
// this enables movement at The Frozen Throne, when printed this value is 0.000000f
// however, when represented as integer client will accept only this value
@@ -538,11 +594,11 @@ class instance_icecrown_citadel : public InstanceMapScript
switch (type)
{
case DATA_SINDRAGOSA_FROSTWYRMS:
return FrostwyrmCount;
return FrostwyrmGUIDs.size();
case DATA_SPINESTALKER:
return SpinestalkerTrashCount;
return SpinestalkerTrash.size();
case DATA_RIMEFANG:
return RimefangTrashCount;
return RimefangTrash.size();
case DATA_COLDFLAME_JETS:
return ColdflameJetsState;
case DATA_TEAM_IN_INSTANCE:
@@ -698,6 +754,8 @@ class instance_icecrown_citadel : public InstanceMapScript
break;
case DATA_PROFESSOR_PUTRICIDE:
HandleGameObject(PlagueSigilGUID, state != DONE);
if (state == DONE)
CheckLichKingAvailability();
if (instance->IsHeroic())
{
if (state == FAIL && HeroicAttempts)
@@ -712,6 +770,8 @@ class instance_icecrown_citadel : public InstanceMapScript
break;
case DATA_BLOOD_QUEEN_LANA_THEL:
HandleGameObject(BloodwingSigilGUID, state != DONE);
if (state == DONE)
CheckLichKingAvailability();
if (instance->IsHeroic())
{
if (state == FAIL && HeroicAttempts)
@@ -730,6 +790,8 @@ class instance_icecrown_citadel : public InstanceMapScript
break;
case DATA_SINDRAGOSA:
HandleGameObject(FrostwingSigilGUID, state != DONE);
if (state == DONE)
CheckLichKingAvailability();
if (instance->IsHeroic())
{
if (state == FAIL && HeroicAttempts)
@@ -798,89 +860,14 @@ class instance_icecrown_citadel : public InstanceMapScript
IsOrbWhispererEligible = data ? true : false;
break;
case DATA_SINDRAGOSA_FROSTWYRMS:
{
if (FrostwyrmCount == 255)
return;
if (instance->IsHeroic() && !HeroicAttempts)
return;
if (GetBossState(DATA_SINDRAGOSA) == DONE)
return;
switch (data)
{
case 0:
if (FrostwyrmCount)
{
--FrostwyrmCount;
if (!FrostwyrmCount)
{
instance->LoadGrid(SindragosaSpawnPos.GetPositionX(), SindragosaSpawnPos.GetPositionY());
if (Creature* boss = instance->SummonCreature(NPC_SINDRAGOSA, SindragosaSpawnPos))
boss->AI()->DoAction(ACTION_START_FROSTWYRM);
}
}
break;
case 1:
++FrostwyrmCount;
break;
default:
FrostwyrmCount = data;
break;
}
FrostwyrmGUIDs.insert(data);
break;
}
case DATA_SPINESTALKER:
{
if (SpinestalkerTrashCount == 255)
return;
switch (data)
{
case 0:
if (SpinestalkerTrashCount)
{
--SpinestalkerTrashCount;
if (!SpinestalkerTrashCount)
if (Creature* spinestalk = instance->GetCreature(SpinestalkerGUID))
spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM);
}
break;
case 1:
++SpinestalkerTrashCount;
break;
default:
SpinestalkerTrashCount = data;
break;
}
SpinestalkerTrash.insert(data);
break;
}
case DATA_RIMEFANG:
{
if (RimefangTrashCount == 255)
return;
switch (data)
{
case 0:
if (RimefangTrashCount)
{
--RimefangTrashCount;
if (!RimefangTrashCount)
if (Creature* rime = instance->GetCreature(RimefangGUID))
rime->AI()->DoAction(ACTION_START_FROSTWYRM);
}
break;
case 1:
++RimefangTrashCount;
break;
default:
RimefangTrashCount = data;
break;
}
RimefangTrash.insert(data);
break;
}
case DATA_COLDFLAME_JETS:
ColdflameJetsState = data;
if (ColdflameJetsState == DONE)
@@ -1095,6 +1082,28 @@ class instance_icecrown_citadel : public InstanceMapScript
return true;
}
void CheckLichKingAvailability()
{
if (GetBossState(DATA_PROFESSOR_PUTRICIDE) == DONE && GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) == DONE && GetBossState(DATA_SINDRAGOSA) == DONE)
{
if (GameObject* teleporter = instance->GetGameObject(TheLichKingTeleportGUID))
{
teleporter->SetGoState(GO_STATE_ACTIVE);
std::list<Creature*> stalkers;
GetCreatureListWithEntryInGrid(stalkers, teleporter, NPC_INVISIBLE_STALKER, 100.0f);
if (stalkers.empty())
return;
stalkers.sort(Trinity::ObjectDistanceOrderPred(teleporter));
stalkers.front()->CastSpell((Unit*)NULL, SPELL_ARTHAS_TELEPORTER_CEREMONY, false);
stalkers.pop_front();
for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr)
(*itr)->AI()->Reset();
}
}
}
std::string GetSaveData()
{
OUT_SAVE_INST_DATA;
@@ -1276,6 +1285,7 @@ class instance_icecrown_citadel : public InstanceMapScript
uint64 SindragosaGUID;
uint64 SpinestalkerGUID;
uint64 RimefangGUID;
uint64 TheLichKingTeleportGUID;
uint64 TheLichKingGUID;
uint64 HighlordTirionFordringGUID;
uint64 TerenasMenethilGUID;
@@ -1289,9 +1299,9 @@ class instance_icecrown_citadel : public InstanceMapScript
uint64 PillarsUnchainedGUID;
uint32 TeamInInstance;
uint32 ColdflameJetsState;
uint32 FrostwyrmCount;
uint32 SpinestalkerTrashCount;
uint32 RimefangTrashCount;
std::set<uint32> FrostwyrmGUIDs;
std::set<uint32> SpinestalkerTrash;
std::set<uint32> RimefangTrash;
uint32 BloodQuickeningState;
uint32 HeroicAttempts;
uint16 BloodQuickeningMinutes;
@@ -15,7 +15,10 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
#include "naxxramas.h"
enum Horsemen
@@ -26,6 +29,11 @@ enum Horsemen
HORSEMEN_SIR,
};
enum Spells
{
SPELL_MARK_DAMAGE = 28836
};
enum Events
{
EVENT_NONE,
@@ -395,7 +403,63 @@ public:
};
class spell_four_horsemen_mark : public SpellScriptLoader
{
public:
spell_four_horsemen_mark() : SpellScriptLoader("spell_four_horsemen_mark") { }
class spell_four_horsemen_mark_AuraScript : public AuraScript
{
PrepareAuraScript(spell_four_horsemen_mark_AuraScript);
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetCaster())
{
int32 damage;
switch (GetStackAmount())
{
case 1:
damage = 0;
break;
case 2:
damage = 500;
break;
case 3:
damage = 1000;
break;
case 4:
damage = 1500;
break;
case 5:
damage = 4000;
break;
case 6:
damage = 12000;
break;
default:
damage = 20000 + 1000 * (GetStackAmount() - 7);
break;
}
if (damage)
caster->CastCustomSpell(SPELL_MARK_DAMAGE, SPELLVALUE_BASE_POINT0, damage, GetTarget());
}
}
void Register()
{
AfterEffectApply += AuraEffectApplyFn(spell_four_horsemen_mark_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
AuraScript* GetAuraScript() const
{
return new spell_four_horsemen_mark_AuraScript();
}
};
void AddSC_boss_four_horsemen()
{
new boss_four_horsemen();
new spell_four_horsemen_mark();
}
@@ -15,7 +15,11 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "GridNotifiers.h"
#include "CombatAI.h"
#include "naxxramas.h"
enum Yells
@@ -25,6 +29,7 @@ enum Yells
SAY_DEATH = -1533042,
SAY_TELEPORT = -1533043
};
//Gothik
enum Spells
{
@@ -36,8 +41,11 @@ enum Spells
SPELL_INFORM_LIVE_RIDER = 27935,
SPELL_INFORM_DEAD_TRAINEE = 27915,
SPELL_INFORM_DEAD_KNIGHT = 27931,
SPELL_INFORM_DEAD_RIDER = 27937
SPELL_INFORM_DEAD_RIDER = 27937,
SPELL_SHADOW_MARK = 27825
};
enum Creatures
{
MOB_LIVE_TRAINEE = 16124,
@@ -585,8 +593,35 @@ class mob_gothik_minion : public CreatureScript
}
};
class spell_gothik_shadow_bolt_volley : public SpellScriptLoader
{
public:
spell_gothik_shadow_bolt_volley() : SpellScriptLoader("spell_gothik_shadow_bolt_volley") { }
class spell_gothik_shadow_bolt_volley_SpellScript : public SpellScript
{
PrepareSpellScript(spell_gothik_shadow_bolt_volley_SpellScript);
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(Trinity::UnitAuraCheck(false, SPELL_SHADOW_MARK));
}
void Register()
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gothik_shadow_bolt_volley_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
SpellScript* GetSpellScript() const
{
return new spell_gothik_shadow_bolt_volley_SpellScript();
}
};
void AddSC_boss_gothik()
{
new boss_gothik();
new mob_gothik_minion();
new spell_gothik_shadow_bolt_volley();
}
@@ -86,6 +86,7 @@ enum Spells
SPELL_SHADOW_FISURE = 27810,
SPELL_VOID_BLAST = 27812,
SPELL_MANA_DETONATION = 27819,
SPELL_MANA_DETONATION_DAMAGE = 27820,
SPELL_FROST_BLAST = 27808,
SPELL_CHAINS_OF_KELTHUZAD = 28410, //28408 script effect
SPELL_KELTHUZAD_CHANNEL = 29423,
@@ -773,6 +774,46 @@ class npc_kelthuzad_abomination : public CreatureScript
}
};
class spell_kelthuzad_detonate_mana : public SpellScriptLoader
{
public:
spell_kelthuzad_detonate_mana() : SpellScriptLoader("spell_kelthuzad_detonate_mana") { }
class spell_kelthuzad_detonate_mana_AuraScript : public AuraScript
{
PrepareAuraScript(spell_kelthuzad_detonate_mana_AuraScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_MANA_DETONATION_DAMAGE))
return false;
return true;
}
void HandleScript(AuraEffect const* aurEff)
{
PreventDefaultAction();
Unit* target = GetTarget();
if (int32 mana = int32(target->GetMaxPower(POWER_MANA) / 10))
{
mana = target->ModifyPower(POWER_MANA, -mana);
target->CastCustomSpell(SPELL_MANA_DETONATION_DAMAGE, SPELLVALUE_BASE_POINT0, -mana * 10, target, true, NULL, aurEff);
}
}
void Register()
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_kelthuzad_detonate_mana_AuraScript::HandleScript, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const
{
return new spell_kelthuzad_detonate_mana_AuraScript();
}
};
class achievement_just_cant_get_enough : public AchievementCriteriaScript
{
public:
@@ -796,5 +837,6 @@ void AddSC_boss_kelthuzad()
new boss_kelthuzad();
new at_kelthuzad_center();
new npc_kelthuzad_abomination();
new spell_kelthuzad_detonate_mana();
new achievement_just_cant_get_enough();
}
@@ -456,10 +456,10 @@ class spell_thaddius_pos_neg_charge : public SpellScriptLoader
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
void HandleTargets(std::list<Unit*>& targetList)
void HandleTargets(std::list<WorldObject*>& targets)
{
uint8 count = 0;
for (std::list<Unit*>::iterator ihit = targetList.begin(); ihit != targetList.end(); ++ihit)
for (std::list<WorldObject*>::iterator ihit = targets.begin(); ihit != targets.end(); ++ihit)
if ((*ihit)->GetGUID() != GetCaster()->GetGUID())
if (Player* target = (*ihit)->ToPlayer())
if (target->HasAura(GetTriggeringSpell()->Id))
@@ -498,7 +498,7 @@ class spell_thaddius_pos_neg_charge : public SpellScriptLoader
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_thaddius_pos_neg_charge_SpellScript::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
OnUnitTargetSelect += SpellUnitTargetFn(spell_thaddius_pos_neg_charge_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thaddius_pos_neg_charge_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
@@ -297,7 +297,7 @@ class spell_varos_energize_core_area_enemy : public SpellScriptLoader
{
PrepareSpellScript(spell_varos_energize_core_area_enemySpellScript)
void FilterTargets(std::list<Unit*>& targetList)
void FilterTargets(std::list<WorldObject*>& targets)
{
Creature* varos = GetCaster()->ToCreature();
if (!varos)
@@ -308,7 +308,7 @@ class spell_varos_energize_core_area_enemy : public SpellScriptLoader
float orientation = CAST_AI(boss_varos::boss_varosAI, varos->AI())->GetCoreEnergizeOrientation();
for (std::list<Unit*>::iterator itr = targetList.begin(); itr != targetList.end();)
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end();)
{
Position pos;
(*itr)->GetPosition(&pos);
@@ -317,7 +317,7 @@ class spell_varos_energize_core_area_enemy : public SpellScriptLoader
float diff = fabs(orientation - angle);
if (diff > 1.0f)
itr = targetList.erase(itr);
itr = targets.erase(itr);
else
++itr;
}
@@ -325,7 +325,7 @@ class spell_varos_energize_core_area_enemy : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_varos_energize_core_area_enemySpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_varos_energize_core_area_enemySpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
@@ -344,7 +344,7 @@ class spell_varos_energize_core_area_entry : public SpellScriptLoader
{
PrepareSpellScript(spell_varos_energize_core_area_entrySpellScript)
void FilterTargets(std::list<Unit*>& targetList)
void FilterTargets(std::list<WorldObject*>& targets)
{
Creature* varos = GetCaster()->ToCreature();
if (!varos)
@@ -355,7 +355,7 @@ class spell_varos_energize_core_area_entry : public SpellScriptLoader
float orientation = CAST_AI(boss_varos::boss_varosAI, varos->AI())->GetCoreEnergizeOrientation();
for (std::list<Unit*>::iterator itr = targetList.begin(); itr != targetList.end();)
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end();)
{
Position pos;
(*itr)->GetPosition(&pos);
@@ -364,7 +364,7 @@ class spell_varos_energize_core_area_entry : public SpellScriptLoader
float diff = fabs(orientation - angle);
if (diff > 1.0f)
itr = targetList.erase(itr);
itr = targets.erase(itr);
else
++itr;
}
@@ -372,7 +372,7 @@ class spell_varos_energize_core_area_entry : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_varos_energize_core_area_entrySpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_varos_energize_core_area_entrySpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
}
};
@@ -47,7 +47,9 @@ enum Drakes
NPC_VERDISA = 27657,
NPC_BELGARISTRASZ = 27658,
NPC_ETERNOS = 27659
NPC_ETERNOS = 27659,
SPELL_SHOCK_CHARGE = 49836,
};
enum Says
@@ -210,8 +212,40 @@ public:
}
};
class spell_gen_stop_time : public SpellScriptLoader
{
public:
spell_gen_stop_time() : SpellScriptLoader("spell_gen_stop_time") { }
class spell_gen_stop_time_AuraScript : public AuraScript
{
PrepareAuraScript(spell_gen_stop_time_AuraScript);
void Apply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* caster = GetCaster();
if (!caster)
return;
Unit* target = GetTarget();
for (uint32 i = 0; i < 5; ++i)
caster->CastSpell(target, SPELL_SHOCK_CHARGE, false);
}
void Register()
{
AfterEffectApply += AuraEffectApplyFn(spell_gen_stop_time_AuraScript::Apply, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const
{
return new spell_gen_stop_time_AuraScript();
}
};
void AddSC_oculus()
{
new npc_oculus_drake();
new npc_image_belgaristrasz();
new spell_gen_stop_time();
}
@@ -19,11 +19,13 @@
/* ScriptData
SDName: Boss Loken
SD%Complete: 60%
SDComment: Missing intro. Remove hack of Pulsing Shockwave when core supports. Aura is not working (59414)
SDComment: Missing intro.
SDCategory: Halls of Lightning
EndScriptData */
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "halls_of_lightning.h"
enum eEnums
@@ -73,23 +75,17 @@ public:
InstanceScript* instance;
bool m_bIsAura;
uint32 m_uiArcLightning_Timer;
uint32 m_uiLightningNova_Timer;
uint32 m_uiPulsingShockwave_Timer;
uint32 m_uiResumePulsingShockwave_Timer;
uint32 m_uiHealthAmountModifier;
void Reset()
{
m_bIsAura = false;
m_uiArcLightning_Timer = 15000;
m_uiLightningNova_Timer = 20000;
m_uiPulsingShockwave_Timer = 2000;
m_uiResumePulsingShockwave_Timer = 15000;
m_uiResumePulsingShockwave_Timer = 1000;
m_uiHealthAmountModifier = 1;
@@ -116,7 +112,10 @@ public:
Talk(SAY_DEATH);
if (instance)
{
instance->SetData(TYPE_LOKEN, DONE);
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_PULSING_SHOCKWAVE_AURA);
}
}
void KilledUnit(Unit* /*victim*/)
@@ -130,44 +129,13 @@ public:
if (!UpdateVictim())
return;
if (m_bIsAura)
{
// workaround for PULSING_SHOCKWAVE
if (m_uiPulsingShockwave_Timer <= uiDiff)
{
Map* map = me->GetMap();
if (map->IsDungeon())
{
Map::PlayerList const &PlayerList = map->GetPlayers();
if (PlayerList.isEmpty())
return;
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
if (i->getSource() && i->getSource()->isAlive() && i->getSource()->isTargetableForAttack())
{
int32 dmg;
float m_fDist = me->GetExactDist(i->getSource()->GetPositionX(), i->getSource()->GetPositionY(), i->getSource()->GetPositionZ());
dmg = DUNGEON_MODE(100, 150); // need to correct damage
if (m_fDist > 1.0f) // Further from 1 yard
dmg = int32(dmg*m_fDist);
me->CastCustomSpell(i->getSource(), DUNGEON_MODE(52942, 59837), &dmg, 0, 0, false);
}
}
m_uiPulsingShockwave_Timer = 2000;
} else m_uiPulsingShockwave_Timer -= uiDiff;
}
else
if (m_uiResumePulsingShockwave_Timer)
{
if (m_uiResumePulsingShockwave_Timer <= uiDiff)
{
//breaks at movement, can we assume when it's time, this spell is casted and also must stop movement?
DoCast(me, SPELL_PULSING_SHOCKWAVE_AURA, true);
DoCast(me, SPELL_PULSING_SHOCKWAVE_N); // need core support
m_bIsAura = true;
DoCast(me, SPELL_PULSING_SHOCKWAVE_N, true);
m_uiResumePulsingShockwave_Timer = 0;
}
else
@@ -190,7 +158,7 @@ public:
Talk(EMOTE_NOVA);
DoCast(me, SPELL_LIGHTNING_NOVA_N);
m_bIsAura = false;
me->RemoveAurasDueToSpell(DUNGEON_MODE<uint32>(SPELL_PULSING_SHOCKWAVE_N, SPELL_PULSING_SHOCKWAVE_H));
m_uiResumePulsingShockwave_Timer = DUNGEON_MODE(5000, 4000); // Pause Pulsing Shockwave aura
m_uiLightningNova_Timer = urand(20000, 21000);
}
@@ -216,7 +184,39 @@ public:
};
class spell_loken_pulsing_shockwave : public SpellScriptLoader
{
public:
spell_loken_pulsing_shockwave() : SpellScriptLoader("spell_loken_pulsing_shockwave") { }
class spell_loken_pulsing_shockwave_SpellScript : public SpellScript
{
PrepareSpellScript(spell_loken_pulsing_shockwave_SpellScript);
void CalculateDamage(SpellEffIndex /*effIndex*/)
{
if (!GetHitUnit())
return;
float distance = GetCaster()->GetDistance2d(GetHitUnit());
if (distance > 1.0f)
SetHitDamage(int32(GetHitDamage() * distance));
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_loken_pulsing_shockwave_SpellScript::CalculateDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
}
};
SpellScript* GetSpellScript() const
{
return new spell_loken_pulsing_shockwave_SpellScript();
}
};
void AddSC_boss_loken()
{
new boss_loken();
new spell_loken_pulsing_shockwave();
}
@@ -23,7 +23,9 @@ SDComment:
SDCategory:
Script Data End */
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "halls_of_stone.h"
enum Spells
@@ -157,17 +159,12 @@ public:
DoScriptText(SAY_KILL, me);
}
void SpellHitTarget(Unit* target, const SpellInfo* pSpell)
void SpellHitTarget(Unit* /*target*/, const SpellInfo* pSpell)
{
//this part should be in the core
if (pSpell->Id == SPELL_SHATTER || pSpell->Id == H_SPELL_SHATTER)
{
//this spell must have custom handling in the core, dealing damage based on distance
target->CastSpell(target, DUNGEON_MODE(SPELL_SHATTER_EFFECT, H_SPELL_SHATTER_EFFECT), true);
if (target->HasAura(SPELL_STONED))
target->RemoveAurasDueToSpell(SPELL_STONED);
// todo: we need eventmap to kill this stuff
//clear this, if we are still performing
if (bIsSlam)
{
@@ -186,7 +183,74 @@ public:
};
class spell_krystallus_shatter : public SpellScriptLoader
{
public:
spell_krystallus_shatter() : SpellScriptLoader("spell_krystallus_shatter") { }
class spell_krystallus_shatter_SpellScript : public SpellScript
{
PrepareSpellScript(spell_krystallus_shatter_SpellScript);
void HandleScript(SpellEffIndex /*effIndex*/)
{
if (Unit* target = GetHitUnit())
{
target->RemoveAurasDueToSpell(SPELL_STONED);
target->CastSpell((Unit*)NULL, SPELL_SHATTER_EFFECT, true);
}
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_krystallus_shatter_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const
{
return new spell_krystallus_shatter_SpellScript();
}
};
class spell_krystallus_shatter_effect : public SpellScriptLoader
{
public:
spell_krystallus_shatter_effect() : SpellScriptLoader("spell_krystallus_shatter_effect") { }
class spell_krystallus_shatter_effect_SpellScript : public SpellScript
{
PrepareSpellScript(spell_krystallus_shatter_effect_SpellScript);
void CalculateDamage()
{
if (!GetHitUnit())
return;
float radius = GetSpellInfo()->Effects[EFFECT_0].CalcRadius(GetCaster());
if (!radius)
return;
float distance = GetCaster()->GetDistance2d(GetHitUnit());
if (distance > 1.0f)
SetHitDamage(int32(GetHitDamage() * ((radius - distance) / radius)));
}
void Register()
{
OnHit += SpellHitFn(spell_krystallus_shatter_effect_SpellScript::CalculateDamage);
}
};
SpellScript* GetSpellScript() const
{
return new spell_krystallus_shatter_effect_SpellScript();
}
};
void AddSC_boss_krystallus()
{
new boss_krystallus();
new spell_krystallus_shatter();
new spell_krystallus_shatter_effect();
}
@@ -1080,7 +1080,7 @@ class NotVictimFilter
{
}
bool operator()(Unit* target)
bool operator()(WorldObject* target)
{
return target != _victim;
}
@@ -1098,14 +1098,14 @@ class spell_algalon_arcane_barrage : public SpellScriptLoader
{
PrepareSpellScript(spell_algalon_arcane_barrage_SpellScript);
void SelectTarget(std::list<Unit*>& targets)
void SelectTarget(std::list<WorldObject*>& targets)
{
targets.remove_if(NotVictimFilter(GetCaster()));
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_algalon_arcane_barrage_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_algalon_arcane_barrage_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
@@ -1118,9 +1118,9 @@ class spell_algalon_arcane_barrage : public SpellScriptLoader
class ActiveConstellationFilter
{
public:
bool operator()(Unit* target) const
bool operator()(WorldObject* target) const
{
return target->GetAI()->GetData(0);
return target->ToUnit() && target->ToUnit()->GetAI() && target->ToUnit()->GetAI()->GetData(0);
}
};
@@ -1133,7 +1133,7 @@ class spell_algalon_trigger_3_adds : public SpellScriptLoader
{
PrepareSpellScript(spell_algalon_trigger_3_adds_SpellScript);
void SelectTarget(std::list<Unit*>& targets)
void SelectTarget(std::list<WorldObject*>& targets)
{
targets.remove_if(ActiveConstellationFilter());
}
@@ -1150,7 +1150,7 @@ class spell_algalon_trigger_3_adds : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_algalon_trigger_3_adds_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_algalon_trigger_3_adds_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
}
};
@@ -1202,7 +1202,7 @@ class spell_algalon_big_bang : public SpellScriptLoader
return true;
}
void CountTargets(std::list<Unit*>& targets)
void CountTargets(std::list<WorldObject*>& targets)
{
_targetCount = targets.size();
}
@@ -1215,7 +1215,7 @@ class spell_algalon_big_bang : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_algalon_big_bang_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_algalon_big_bang_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
AfterCast += SpellCastFn(spell_algalon_big_bang_SpellScript::CheckTargets);
}
@@ -472,9 +472,9 @@ class npc_feral_defender : public CreatureScript
class SanctumSentryCheck
{
public:
bool operator() (Unit* unit)
bool operator()(WorldObject* object) const
{
if (unit->GetEntry() == NPC_SANCTUM_SENTRY)
if (object->GetEntry() == NPC_SANCTUM_SENTRY)
return false;
return true;
@@ -490,14 +490,14 @@ class spell_auriaya_strenght_of_the_pack : public SpellScriptLoader
{
PrepareSpellScript(spell_auriaya_strenght_of_the_pack_SpellScript);
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& unitList)
{
unitList.remove_if (SanctumSentryCheck());
unitList.remove_if(SanctumSentryCheck());
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_auriaya_strenght_of_the_pack_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_strenght_of_the_pack_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
@@ -516,15 +516,15 @@ class spell_auriaya_sentinel_blast : public SpellScriptLoader
{
PrepareSpellScript(spell_auriaya_sentinel_blast_SpellScript);
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& unitList)
{
unitList.remove_if (PlayerOrPetCheck());
unitList.remove_if(PlayerOrPetCheck());
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
@@ -720,20 +720,18 @@ class boss_flame_leviathan_overload_device : public CreatureScript
{
}
void DoAction(const int32 param)
void OnSpellClick(Unit* /*clicker*/)
{
if (param == EVENT_SPELLCLICK)
if (me->GetVehicle())
{
if (me->GetVehicle())
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
if (Unit* player = me->GetVehicle()->GetPassenger(SEAT_PLAYER))
{
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
if (Unit* player = me->GetVehicle()->GetPassenger(SEAT_PLAYER))
{
me->GetVehicleBase()->CastSpell(player, SPELL_SMOKE_TRAIL, true);
player->GetMotionMaster()->MoveKnockbackFrom(me->GetVehicleBase()->GetPositionX(), me->GetVehicleBase()->GetPositionY(), 30, 30);
player->ExitVehicle();
}
me->GetVehicleBase()->CastSpell(player, SPELL_SMOKE_TRAIL, true);
player->GetMotionMaster()->MoveKnockbackFrom(me->GetVehicleBase()->GetPositionX(), me->GetVehicleBase()->GetPositionY(), 30, 30);
player->ExitVehicle();
}
}
}
@@ -1232,7 +1230,7 @@ public:
//bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action)
//{
// player->PlayerTalkClass->ClearMenus();
// switch(action)
// switch (action)
// {
// case GOSSIP_ACTION_INFO_DEF+1:
// if (player)
@@ -1619,7 +1617,7 @@ class FlameLeviathanPursuedTargetSelector
public:
explicit FlameLeviathanPursuedTargetSelector(Unit* unit) : _me(unit) {};
bool operator()(Unit* target) const
bool operator()(WorldObject* target) const
{
//! No players, only vehicles (todo: check if blizzlike)
Creature* creatureTarget = target->ToCreature();
@@ -1667,7 +1665,7 @@ class spell_pursue : public SpellScriptLoader
return true;
}
void FilterTargets(std::list<Unit*>& targets)
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(FlameLeviathanPursuedTargetSelector(GetCaster()));
if (targets.empty())
@@ -1683,7 +1681,7 @@ class spell_pursue : public SpellScriptLoader
}
}
void FilterTargetsSubsequently(std::list<Unit*>& targets)
void FilterTargetsSubsequently(std::list<WorldObject*>& targets)
{
targets.clear();
if (_target)
@@ -1710,12 +1708,12 @@ class spell_pursue : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_pursue_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_pursue_SpellScript::FilterTargetsSubsequently, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pursue_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pursue_SpellScript::FilterTargetsSubsequently, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_pursue_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
}
Unit* _target;
WorldObject* _target;
};
SpellScript* GetSpellScript() const
@@ -51,6 +51,8 @@ enum VezaxSpells
SPELL_SHADOW_CRASH_HIT = 62659,
SPELL_SURGE_OF_DARKNESS = 62662,
SPELL_SARONITE_VAPORS = 63323,
SPELL_SARONITE_VAPORS_ENERGIZE = 63337,
SPELL_SARONITE_VAPORS_DAMAGE = 63338,
SPELL_SUMMON_SARONITE_VAPORS = 63081,
SPELL_BERSERK = 26662,
@@ -463,6 +465,45 @@ class spell_mark_of_the_faceless : public SpellScriptLoader
}
};
class spell_general_vezax_saronite_vapors : public SpellScriptLoader
{
public:
spell_general_vezax_saronite_vapors() : SpellScriptLoader("spell_general_vezax_saronite_vapors") { }
class spell_general_vezax_saronite_vapors_AuraScript : public AuraScript
{
PrepareAuraScript(spell_general_vezax_saronite_vapors_AuraScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_SARONITE_VAPORS_ENERGIZE) || !sSpellMgr->GetSpellInfo(SPELL_SARONITE_VAPORS_DAMAGE))
return false;
return true;
}
void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetCaster())
{
int32 mana = int32(aurEff->GetAmount() * pow(2.0f, GetStackAmount())); // mana restore - bp * 2^stackamount
int32 damage = mana * 2;
caster->CastCustomSpell(GetTarget(), SPELL_SARONITE_VAPORS_ENERGIZE, &mana, NULL, NULL, true);
caster->CastCustomSpell(GetTarget(), SPELL_SARONITE_VAPORS_DAMAGE, &damage, NULL, NULL, true);
}
}
void Register()
{
AfterEffectApply += AuraEffectApplyFn(spell_general_vezax_saronite_vapors_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
AuraScript* GetAuraScript() const
{
return new spell_general_vezax_saronite_vapors_AuraScript();
}
};
class achievement_shadowdodger : public AchievementCriteriaScript
{
public:
@@ -509,6 +550,7 @@ void AddSC_boss_general_vezax()
new boss_saronite_animus();
new npc_saronite_vapors();
new spell_mark_of_the_faceless();
new spell_general_vezax_saronite_vapors();
new achievement_shadowdodger();
new achievement_smell_saronite();
}
@@ -354,7 +354,7 @@ class StoneGripTargetSelector : public std::unary_function<Unit*, bool>
public:
StoneGripTargetSelector(Creature* me, Unit const* victim) : _me(me), _victim(victim) {}
bool operator() (Unit* target)
bool operator()(WorldObject* target)
{
if (target == _victim && _me->getThreatManager().getThreatList().size() > 1)
return true;
@@ -385,10 +385,10 @@ class spell_ulduar_stone_grip_cast_target : public SpellScriptLoader
return true;
}
void FilterTargetsInitial(std::list<Unit*>& unitList)
void FilterTargetsInitial(std::list<WorldObject*>& unitList)
{
// Remove "main tank" and non-player targets
unitList.remove_if (StoneGripTargetSelector(GetCaster()->ToCreature(), GetCaster()->getVictim()));
unitList.remove_if(StoneGripTargetSelector(GetCaster()->ToCreature(), GetCaster()->getVictim()));
// Maximum affected targets per difficulty mode
uint32 maxTargets = 1;
if (GetSpellInfo()->Id == 63981)
@@ -397,7 +397,7 @@ class spell_ulduar_stone_grip_cast_target : public SpellScriptLoader
// Return a random amount of targets based on maxTargets
while (maxTargets < unitList.size())
{
std::list<Unit*>::iterator itr = unitList.begin();
std::list<WorldObject*>::iterator itr = unitList.begin();
advance(itr, urand(0, unitList.size()-1));
unitList.erase(itr);
}
@@ -406,20 +406,20 @@ class spell_ulduar_stone_grip_cast_target : public SpellScriptLoader
m_unitList = unitList;
}
void FillTargetsSubsequential(std::list<Unit*>& unitList)
void FillTargetsSubsequential(std::list<WorldObject*>& unitList)
{
unitList = m_unitList;
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_ulduar_stone_grip_cast_target_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_ulduar_stone_grip_cast_target_SpellScript::FillTargetsSubsequential, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_ulduar_stone_grip_cast_target_SpellScript::FillTargetsSubsequential, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ulduar_stone_grip_cast_target_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ulduar_stone_grip_cast_target_SpellScript::FillTargetsSubsequential, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ulduar_stone_grip_cast_target_SpellScript::FillTargetsSubsequential, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY);
}
// Shared between effects
std::list<Unit*> m_unitList;
std::list<WorldObject*> m_unitList;
};
SpellScript* GetSpellScript() const
@@ -598,14 +598,14 @@ class spell_kologarn_stone_shout : public SpellScriptLoader
{
PrepareSpellScript(spell_kologarn_stone_shout_SpellScript);
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& unitList)
{
unitList.remove_if (PlayerOrPetCheck());
unitList.remove_if(PlayerOrPetCheck());
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_kologarn_stone_shout_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kologarn_stone_shout_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
@@ -170,7 +170,11 @@ enum AchievementCredits
ACHIEV_MUST_DECONSTRUCT_FASTER = 21027,
};
#define HEART_VEHICLE_SEAT 0
enum VehicleSeats
{
HEART_VEHICLE_SEAT_NORMAL = 0,
HEART_VEHICLE_SEAT_EXPOSED = 1,
};
/*-------------------------------------------------------
*
@@ -198,6 +202,8 @@ class boss_xt002 : public CreatureScript
_Reset();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetReactState(REACT_AGGRESSIVE);
DoCast(me, SPELL_STAND);
_healthRecovered = false;
_gravityBombCasualty = false;
@@ -356,15 +362,16 @@ class boss_xt002 : public CreatureScript
me->AttackStop();
me->SetReactState(REACT_PASSIVE);
Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT) : NULL;
Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT_NORMAL) : NULL;
if (heart)
{
heart->CastSpell(heart, SPELL_HEART_OVERLOAD, false);
heart->CastSpell(me, SPELL_HEART_LIGHTNING_TETHER, false);
heart->CastSpell(heart, SPELL_HEART_HEAL_TO_FULL, true);
heart->CastSpell(heart, SPELL_EXPOSED_HEART, false); // Channeled
heart->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
heart->ChangeSeat(HEART_VEHICLE_SEAT_EXPOSED, true);
heart->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
heart->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
}
events.CancelEvent(EVENT_SEARING_LIGHT);
@@ -392,11 +399,13 @@ class boss_xt002 : public CreatureScript
events.RescheduleEvent(EVENT_GRAVITY_BOMB, TIMER_GRAVITY_BOMB);
events.RescheduleEvent(EVENT_TYMPANIC_TANTRUM, urand(TIMER_TYMPANIC_TANTRUM_MIN, TIMER_TYMPANIC_TANTRUM_MAX));
Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT) : NULL;
Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT_EXPOSED) : NULL;
if (!heart)
return;
heart->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
heart->ChangeSeat(HEART_VEHICLE_SEAT_NORMAL, false);
heart->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
heart->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
heart->RemoveAurasDueToSpell(SPELL_EXPOSED_HEART);
if (!_hardMode)
@@ -425,43 +434,39 @@ class boss_xt002 : public CreatureScript
* XT-002 HEART
*
*///----------------------------------------------------
class mob_xt002_heart : public CreatureScript
{
public:
mob_xt002_heart() : CreatureScript("mob_xt002_heart") { }
struct mob_xt002_heartAI : public Scripted_NoMovementAI
{
mob_xt002_heartAI(Creature* creature) : Scripted_NoMovementAI(creature),
_instance(creature->GetInstanceScript())
{
}
void UpdateAI(uint32 const /*diff*/) { }
void JustDied(Unit* /*killer*/)
{
Creature* xt002 = _instance ? me->GetCreature(*me, _instance->GetData64(BOSS_XT002)) : NULL;
if (!xt002 || !xt002->AI())
return;
xt002->AI()->SetData(DATA_TRANSFERED_HEALTH, me->GetHealth());
xt002->AI()->DoAction(ACTION_ENTER_HARD_MODE);
}
private:
InstanceScript* _instance;
};
CreatureAI* GetAI(Creature* creature) const
{
return new mob_xt002_heartAI(creature);
}
struct mob_xt002_heartAI : public ScriptedAI
{
mob_xt002_heartAI(Creature* creature) : ScriptedAI(creature)
{
_instance = creature->GetInstanceScript();
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_STUNNED | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
me->SetReactState(REACT_PASSIVE);
}
void DamageTaken(Unit* /*pDone*/, uint32 &damage)
{
Creature* xt002 = me->GetCreature(*me, _instance->GetData64(BOSS_XT002));
if (!xt002 || !xt002->AI())
return;
if (damage >= me->GetHealth())
{
xt002->AI()->SetData(DATA_TRANSFERED_HEALTH, me->GetMaxHealth());
xt002->AI()->DoAction(ACTION_ENTER_HARD_MODE);
damage = 0;
}
}
private:
InstanceScript* _instance;
uint32 _damageTaken;
};
};
/*-------------------------------------------------------
@@ -915,7 +920,7 @@ class spell_xt002_heart_overload_periodic : public SpellScriptLoader
{
uint8 a = urand(0, 4);
uint32 spellId = spells[a];
toyPile->CastSpell(toyPile, spellId, true);
toyPile->CastSpell(toyPile, spellId, true, NULL, NULL, instance->GetData64(BOSS_XT002));
}
}
}
@@ -945,9 +950,9 @@ class spell_xt002_tympanic_tantrum : public SpellScriptLoader
{
PrepareSpellScript(spell_xt002_tympanic_tantrum_SpellScript);
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& targets)
{
unitList.remove_if(PlayerOrPetCheck());
targets.remove_if(PlayerOrPetCheck());
}
void RecalculateDamage()
@@ -957,8 +962,9 @@ class spell_xt002_tympanic_tantrum : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnHit += SpellHitFn(spell_xt002_tympanic_tantrum_SpellScript::RecalculateDamage);
OnHit += SpellHitFn(spell_xt002_tympanic_tantrum_SpellScript::RecalculateDamage);
}
};
@@ -268,10 +268,10 @@ GameObjectAI* GetUlduarAI(GameObject* go)
class PlayerOrPetCheck
{
public:
bool operator() (Unit* unit)
bool operator()(WorldObject* object) const
{
if (unit->GetTypeId() != TYPEID_PLAYER)
if (!unit->ToCreature()->isPet())
if (object->GetTypeId() != TYPEID_PLAYER)
if (!object->ToCreature()->isPet())
return true;
return false;
@@ -276,7 +276,7 @@ public:
arthas->CastSpell(me, SPELL_TRANSFORMING_CHANNEL, false);
pos.Relocate(me);
pos.m_positionZ += 8.0f;
me->GetMotionMaster()->MoveTakeoff(0, pos, 3.30078125f);
me->GetMotionMaster()->MoveTakeoff(0, pos);
// spectators flee event
if (instance)
{
@@ -333,7 +333,9 @@ public:
pos.m_positionX = me->GetHomePosition().GetPositionX();
pos.m_positionY = me->GetHomePosition().GetPositionY();
pos.m_positionZ = 90.6065f;
me->GetMotionMaster()->MoveLand(0, pos, 6.247422f);
me->GetMotionMaster()->MoveLand(0, pos);
me->SetDisableGravity(false, true);
me->SetHover(true);
me->SetDisableGravity(false, true);
me->SetHover(true);
++introPhase;
@@ -522,12 +524,12 @@ public:
};
};
class checkRitualTarget
class RitualTargetCheck
{
public:
explicit checkRitualTarget(Unit* _caster) : caster(_caster) { }
explicit RitualTargetCheck(Unit* _caster) : caster(_caster) { }
bool operator() (Unit* unit)
bool operator() (WorldObject* unit) const
{
if (InstanceScript* instance = caster->GetInstanceScript())
if (instance->GetData64(DATA_SACRIFICED_PLAYER) == unit->GetGUID())
@@ -549,14 +551,14 @@ class spell_paralyze_pinnacle : public SpellScriptLoader
{
PrepareSpellScript(spell_paralyze_pinnacle_SpellScript);
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& unitList)
{
unitList.remove_if(checkRitualTarget(GetCaster()));
unitList.remove_if(RitualTargetCheck(GetCaster()));
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_paralyze_pinnacle_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_paralyze_pinnacle_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
@@ -69,7 +69,106 @@ public:
}
};
/*######
## Quest Strengthen the Ancients (12096|12092)
######*/
enum StrengthenAncientsMisc
{
SAY_WALKER_FRIENDLY = 0,
SAY_WALKER_ENEMY = 1,
SAY_LOTHALOR = 0,
SPELL_CREATE_ITEM_BARK = 47550,
SPELL_CONFUSED = 47044,
NPC_LOTHALOR = 26321,
FACTION_WALKER_ENEMY = 14,
};
class spell_q12096_q12092_dummy : public SpellScriptLoader // Strengthen the Ancients: On Interact Dummy to Woodlands Walker
{
public:
spell_q12096_q12092_dummy() : SpellScriptLoader("spell_q12096_q12092_dummy") { }
class spell_q12096_q12092_dummy_SpellScript : public SpellScript
{
PrepareSpellScript(spell_q12096_q12092_dummy_SpellScript);
void HandleDummy(SpellEffIndex /*effIndex*/)
{
uint32 roll = rand() % 2;
Creature* tree = GetHitCreature();
Player* player = GetCaster()->ToPlayer();
if (!tree || !player)
return;
tree->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
if (roll == 1) // friendly version
{
tree->CastSpell(player, SPELL_CREATE_ITEM_BARK);
tree->AI()->Talk(SAY_WALKER_FRIENDLY, player->GetGUID());
tree->DespawnOrUnsummon(1000);
}
else if (roll == 0) // enemy version
{
tree->AI()->Talk(SAY_WALKER_ENEMY, player->GetGUID());
tree->setFaction(FACTION_WALKER_ENEMY);
tree->Attack(player, true);
}
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_q12096_q12092_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const
{
return new spell_q12096_q12092_dummy_SpellScript();
}
};
class spell_q12096_q12092_bark : public SpellScriptLoader // Bark of the Walkers
{
public:
spell_q12096_q12092_bark() : SpellScriptLoader("spell_q12096_q12092_bark") { }
class spell_q12096_q12092_bark_SpellScript : public SpellScript
{
PrepareSpellScript(spell_q12096_q12092_bark_SpellScript);
void HandleDummy(SpellEffIndex /*effIndex*/)
{
Creature* lothalor = GetHitCreature();
if (!lothalor || lothalor->GetEntry() != NPC_LOTHALOR)
return;
lothalor->AI()->Talk(SAY_LOTHALOR);
lothalor->RemoveAura(SPELL_CONFUSED);
lothalor->DespawnOrUnsummon(4000);
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_q12096_q12092_bark_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const
{
return new spell_q12096_q12092_bark_SpellScript();
}
};
void AddSC_dragonblight()
{
new npc_alexstrasza_wr_gate;
new spell_q12096_q12092_dummy;
new spell_q12096_q12092_bark;
}
@@ -746,6 +746,130 @@ public:
}
};
/*######
## Quest Kick, What Kick? (12589)
######*/
enum KickWhatKick
{
NPC_LUCKY_WILHELM = 28054,
NPC_APPLE = 28053,
NPC_DROSTAN = 28328,
NPC_CRUNCHY = 28346,
NPC_THICKBIRD = 28093,
SPELL_HIT_APPLE = 51331,
SPELL_MISS_APPLE = 51332,
SPELL_MISS_BIRD_APPLE = 51366,
SPELL_APPLE_FALL = 51371,
SPELL_BIRD_FALL = 51369,
EVENT_MISS = 0,
EVENT_HIT = 1,
EVENT_MISS_BIRD = 2,
SAY_WILHELM_MISS = 0,
SAY_WILHELM_HIT = 1,
SAY_DROSTAN_REPLY_MISS = 0,
};
class spell_q12589_shoot_rjr : public SpellScriptLoader
{
public:
spell_q12589_shoot_rjr() : SpellScriptLoader("spell_q12589_shoot_rjr") { }
class spell_q12589_shoot_rjr_SpellScript : public SpellScript
{
PrepareSpellScript(spell_q12589_shoot_rjr_SpellScript);
SpellCastResult CheckCast()
{
if (Unit* target = GetExplTargetUnit())
if (target->GetEntry() == NPC_LUCKY_WILHELM)
return SPELL_CAST_OK;
SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_TARGET_WILHELM);
return SPELL_FAILED_CUSTOM_ERROR;
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
uint32 roll = urand(1, 100);
uint8 ev;
if (roll <= 50)
ev = EVENT_MISS;
else if (roll <= 83)
ev = EVENT_HIT;
else
ev = EVENT_MISS_BIRD;
Unit* shooter = GetCaster();
Creature* wilhelm = GetHitUnit()->ToCreature();
Creature* apple = shooter->FindNearestCreature(NPC_APPLE, 30);
Creature* drostan = shooter->FindNearestCreature(NPC_DROSTAN, 30);
if (!wilhelm || !apple || !drostan)
return;
switch (ev)
{
case EVENT_MISS_BIRD:
{
Creature* crunchy = shooter->FindNearestCreature(NPC_CRUNCHY, 30);
Creature* bird = shooter->FindNearestCreature(NPC_THICKBIRD, 30);
if (!bird || !crunchy)
; // fall to EVENT_MISS
else
{
shooter->CastSpell(bird, SPELL_MISS_BIRD_APPLE);
bird->CastSpell(bird, SPELL_BIRD_FALL);
wilhelm->AI()->Talk(SAY_WILHELM_MISS);
drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS);
bird->Kill(bird);
crunchy->GetMotionMaster()->MovePoint(0, bird->GetPositionX(), bird->GetPositionY(),
bird->GetMap()->GetWaterOrGroundLevel(bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ()));
// TODO: Make crunchy perform emote eat when he reaches the bird
break;
}
}
case EVENT_MISS:
{
shooter->CastSpell(wilhelm, SPELL_MISS_APPLE);
wilhelm->AI()->Talk(SAY_WILHELM_MISS);
drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS);
break;
}
case EVENT_HIT:
{
shooter->CastSpell(apple, SPELL_HIT_APPLE);
apple->CastSpell(apple, SPELL_APPLE_FALL);
wilhelm->AI()->Talk(SAY_WILHELM_HIT);
if (Player* player = shooter->ToPlayer())
player->KilledMonsterCredit(NPC_APPLE, 0);
apple->DespawnOrUnsummon();
break;
}
}
}
void Register()
{
OnCheckCast += SpellCheckCastFn(spell_q12589_shoot_rjr_SpellScript::CheckCast);
OnEffectHitTarget += SpellEffectFn(spell_q12589_shoot_rjr_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const
{
return new spell_q12589_shoot_rjr_SpellScript();
}
};
void AddSC_sholazar_basin()
{
new npc_injured_rainspeaker_oracle();
@@ -756,4 +880,5 @@ void AddSC_sholazar_basin()
new npc_adventurous_dwarf();
new npc_jungle_punch_target();
new spell_q12620_the_lifewarden_wrath();
new spell_q12589_shoot_rjr();
}
@@ -19,11 +19,13 @@
/* ScriptData
SDName: Boss_Gruul
SD%Complete: 60
SDComment: Ground Slam need further development (knock back effect and shatter effect must be added to the core)
SDComment: Ground Slam need further development (knock back effect must be added to the core)
SDCategory: Gruul's Lair
EndScriptData */
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "gruuls_lair.h"
enum eEnums
@@ -144,12 +146,7 @@ public:
//this part should be in the core
if (pSpell->Id == SPELL_SHATTER)
{
//this spell must have custom handling in the core, dealing damage based on distance
target->CastSpell(target, SPELL_SHATTER_EFFECT, true);
if (target->HasAura(SPELL_STONED))
target->RemoveAurasDueToSpell(SPELL_STONED);
// todo: use eventmap to kill this stuff
//clear this, if we are still performing
if (m_bPerformingGroundSlam)
{
@@ -258,7 +255,83 @@ public:
};
class spell_gruul_shatter : public SpellScriptLoader
{
public:
spell_gruul_shatter() : SpellScriptLoader("spell_gruul_shatter") { }
class spell_gruul_shatter_SpellScript : public SpellScript
{
PrepareSpellScript(spell_gruul_shatter_SpellScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_STONED))
return false;
if (!sSpellMgr->GetSpellInfo(SPELL_SHATTER_EFFECT))
return false;
return true;
}
void HandleScript(SpellEffIndex /*effIndex*/)
{
if (Unit* target = GetHitUnit())
{
target->RemoveAurasDueToSpell(SPELL_STONED);
target->CastSpell((Unit*)NULL, SPELL_SHATTER_EFFECT, true);
}
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_gruul_shatter_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const
{
return new spell_gruul_shatter_SpellScript();
}
};
class spell_gruul_shatter_effect : public SpellScriptLoader
{
public:
spell_gruul_shatter_effect() : SpellScriptLoader("spell_gruul_shatter_effect") { }
class spell_gruul_shatter_effect_SpellScript : public SpellScript
{
PrepareSpellScript(spell_gruul_shatter_effect_SpellScript);
void CalculateDamage()
{
if (!GetHitUnit())
return;
float radius = GetSpellInfo()->Effects[EFFECT_0].CalcRadius(GetCaster());
if (!radius)
return;
float distance = GetCaster()->GetDistance2d(GetHitUnit());
if (distance > 1.0f)
SetHitDamage(int32(GetHitDamage() * ((radius - distance) / radius)));
}
void Register()
{
OnHit += SpellHitFn(spell_gruul_shatter_effect_SpellScript::CalculateDamage);
}
};
SpellScript* GetSpellScript() const
{
return new spell_gruul_shatter_effect_SpellScript();
}
};
void AddSC_boss_gruul()
{
new boss_gruul();
new spell_gruul_shatter();
new spell_gruul_shatter_effect();
}
@@ -518,7 +518,7 @@ class spell_astromancer_wrath_of_the_astromancer : public SpellScriptLoader
return true;
}
void CountTargets(std::list<Unit*>& targetList)
void CountTargets(std::list<WorldObject*>& targetList)
{
_targetCount = targetList.size();
}
@@ -549,7 +549,7 @@ class spell_astromancer_wrath_of_the_astromancer : public SpellScriptLoader
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_astromancer_wrath_of_the_astromancer_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_astromancer_wrath_of_the_astromancer_SpellScript::CountTargets, EFFECT_0, TARGET_DEST_CASTER_RADIUS);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_astromancer_wrath_of_the_astromancer_SpellScript::CountTargets, EFFECT_0, TARGET_DEST_CASTER_RADIUS);
}
};
@@ -52,10 +52,10 @@ class spell_capacitus_polarity_charge : public SpellScriptLoader
return true;
}
void HandleTargets(std::list<Unit*>& targetList)
void HandleTargets(std::list<WorldObject*>& targetList)
{
uint8 count = 0;
for (std::list<Unit*>::iterator ihit = targetList.begin(); ihit != targetList.end(); ++ihit)
for (std::list<WorldObject*>::iterator ihit = targetList.begin(); ihit != targetList.end(); ++ihit)
if ((*ihit)->GetGUID() != GetCaster()->GetGUID())
if (Player* target = (*ihit)->ToPlayer())
if (target->HasAura(GetTriggeringSpell()->Id))
@@ -88,7 +88,7 @@ class spell_capacitus_polarity_charge : public SpellScriptLoader
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_capacitus_polarity_charge_SpellScript::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
OnUnitTargetSelect += SpellUnitTargetFn(spell_capacitus_polarity_charge_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_capacitus_polarity_charge_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
@@ -651,7 +651,7 @@ class npc_simon_bunny : public CreatureScript
{
_events.Update(diff);
switch(_events.ExecuteEvent())
switch (_events.ExecuteEvent())
{
case EVENT_SIMON_PERIODIC_PLAYER_CHECK:
if (!CheckPlayer())
@@ -16,7 +16,10 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptPCH.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellAuraEffects.h"
#include "SpellScript.h"
enum Texts
{
@@ -36,6 +39,7 @@ enum Spells
SPELL_THUNDERCLAP = 36706,
SPELL_VOID_BOLT = 39329,
SPELL_MARK_OF_KAZZAK = 32960,
SPELL_MARK_OF_KAZZAK_DAMAGE = 32961,
SPELL_ENRAGE = 32964,
SPELL_CAPTURE_SOUL = 32966,
SPELL_TWISTED_REFLECTION = 21063,
@@ -171,7 +175,55 @@ class boss_doomlord_kazzak : public CreatureScript
}
};
class spell_mark_of_kazzak : public SpellScriptLoader
{
public:
spell_mark_of_kazzak() : SpellScriptLoader("spell_mark_of_kazzak") { }
class spell_mark_of_kazzak_AuraScript : public AuraScript
{
PrepareAuraScript(spell_mark_of_kazzak_AuraScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_MARK_OF_KAZZAK_DAMAGE))
return false;
return true;
}
void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
{
if (Unit* owner = GetUnitOwner())
amount = CalculatePctU(owner->GetPower(POWER_MANA), 5);
}
void OnPeriodic(AuraEffect const* aurEff)
{
Unit* target = GetTarget();
if (target->GetPower(POWER_MANA) == 0)
{
target->CastSpell(target, SPELL_MARK_OF_KAZZAK_DAMAGE, true, NULL, aurEff);
// Remove aura
SetDuration(0);
}
}
void Register()
{
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mark_of_kazzak_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_MANA_LEECH);
OnEffectPeriodic += AuraEffectPeriodicFn(spell_mark_of_kazzak_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_MANA_LEECH);
}
};
AuraScript* GetAuraScript() const
{
return new spell_mark_of_kazzak_AuraScript();
}
};
void AddSC_boss_doomlordkazzak()
{
new boss_doomlord_kazzak();
new spell_mark_of_kazzak();
}
+4 -4
View File
@@ -777,10 +777,10 @@ public:
PlayerGUID = who->GetGUID();
}
void SpellHit(Unit* /*caster*/, const SpellInfo* /*spell*/)
{
DoCast(me, SPELL_DE_MATERIALIZE);
}
//void SpellHit(Unit* /*caster*/, const SpellInfo* /*spell*/)
//{
// DoCast(me, SPELL_DE_MATERIALIZE);
//}
void UpdateAI(const uint32 diff)
{
+1
View File
@@ -24,6 +24,7 @@ set(scripts_STAT_SRCS
Spells/spell_paladin.cpp
Spells/spell_item.cpp
Spells/spell_holiday.cpp
Spells/spell_pet.cpp
)
message(" -> Prepared: Spells")
+53 -20
View File
@@ -40,6 +40,8 @@ enum DeathKnightSpells
DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED = 63611,
DK_SPELL_UNHOLY_PRESENCE = 48265,
DK_SPELL_IMPROVED_UNHOLY_PRESENCE_TRIGGERED = 63622,
SPELL_DK_ITEM_T8_MALEE_4P_BONUS = 64736,
DK_SPELL_BLACK_ICE_R1 = 49140,
};
// 50462 - Anti-Magic Shell (on raid member)
@@ -111,8 +113,7 @@ class spell_dk_anti_magic_shell_self : public SpellScriptLoader
void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/)
{
// Set absorbtion amount to unlimited
amount = -1;
amount = GetCaster()->CountPctFromMaxHealth(hpPct);
}
void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount)
@@ -334,16 +335,30 @@ class spell_dk_death_pact : public SpellScriptLoader
{
PrepareSpellScript(spell_dk_death_pact_SpellScript);
void FilterTargets(std::list<Unit*>& unitList)
SpellCastResult CheckCast()
{
// Check if we have valid targets, otherwise skip spell casting here
if (Player* player = GetCaster()->ToPlayer())
for (Unit::ControlList::const_iterator itr = player->m_Controlled.begin(); itr != player->m_Controlled.end(); ++itr)
if (Creature* undeadPet = (*itr)->ToCreature())
if (undeadPet->isAlive() &&
undeadPet->GetOwnerGUID() == player->GetGUID() &&
undeadPet->GetCreatureType() == CREATURE_TYPE_UNDEAD &&
undeadPet->IsWithinDist(player, 100.0f, false))
return SPELL_CAST_OK;
return SPELL_FAILED_NO_PET;
}
void FilterTargets(std::list<WorldObject*>& unitList)
{
Unit* unit_to_add = NULL;
for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
for (std::list<WorldObject*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
{
if ((*itr)->GetTypeId() == TYPEID_UNIT
&& (*itr)->GetOwnerGUID() == GetCaster()->GetGUID()
&& (*itr)->ToCreature()->GetCreatureTemplate()->type == CREATURE_TYPE_UNDEAD)
if (Unit* unit = (*itr)->ToUnit())
if (unit->GetOwnerGUID() == GetCaster()->GetGUID() && unit->GetCreatureType() == CREATURE_TYPE_UNDEAD)
{
unit_to_add = (*itr);
unit_to_add = unit;
break;
}
}
@@ -351,18 +366,12 @@ class spell_dk_death_pact : public SpellScriptLoader
unitList.clear();
if (unit_to_add)
unitList.push_back(unit_to_add);
else
{
// Pet not found - remove cooldown
if (Player* modOwner = GetCaster()->GetSpellModOwner())
modOwner->RemoveSpellCooldown(GetSpellInfo()->Id, true);
FinishCast(SPELL_FAILED_NO_PET);
}
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_dk_death_pact_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ALLY);
OnCheckCast += SpellCheckCastFn(spell_dk_death_pact_SpellScript::CheckCast);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dk_death_pact_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ALLY);
}
};
@@ -381,6 +390,13 @@ class spell_dk_scourge_strike : public SpellScriptLoader
class spell_dk_scourge_strike_SpellScript : public SpellScript
{
PrepareSpellScript(spell_dk_scourge_strike_SpellScript);
float multiplier;
bool Load()
{
multiplier = 1.0f;
return true;
}
bool Validate(SpellInfo const* /*spellEntry*/)
{
@@ -394,7 +410,23 @@ class spell_dk_scourge_strike : public SpellScriptLoader
Unit* caster = GetCaster();
if (Unit* unitTarget = GetHitUnit())
{
int32 bp = CalculatePctN(GetHitDamage(), GetEffectValue() * unitTarget->GetDiseasesByCaster(caster->GetGUID()));
multiplier = (GetEffectValue() * unitTarget->GetDiseasesByCaster(caster->GetGUID()) / 100.f);
// Death Knight T8 Melee 4P Bonus
if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_DK_ITEM_T8_MALEE_4P_BONUS, EFFECT_0))
AddPctF(multiplier, aurEff->GetAmount());
}
}
void HandleAfterHit()
{
Unit* caster = GetCaster();
if (Unit* unitTarget = GetHitUnit())
{
int32 bp = GetHitDamage() * multiplier;
if (AuraEffect* aurEff = caster->GetAuraEffectOfRankedSpell(DK_SPELL_BLACK_ICE_R1, EFFECT_0))
AddPctN(bp, aurEff->GetAmount());
caster->CastCustomSpell(unitTarget, DK_SPELL_SCOURGE_STRIKE_TRIGGERED, &bp, NULL, NULL, true);
}
}
@@ -402,6 +434,7 @@ class spell_dk_scourge_strike : public SpellScriptLoader
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_dk_scourge_strike_SpellScript::HandleDummy, EFFECT_2, SPELL_EFFECT_DUMMY);
AfterHit += SpellHitFn(spell_dk_scourge_strike_SpellScript::HandleAfterHit);
}
};
@@ -588,7 +621,7 @@ public:
if (!target->HasAura(DK_SPELL_BLOOD_PRESENCE) && !target->HasAura(DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED))
{
int32 basePoints1 = aurEff->GetAmount();
target->CastCustomSpell(target, 63611, NULL, &basePoints1, NULL, true, 0, aurEff);
target->CastCustomSpell(target, DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED, NULL, &basePoints1, NULL, true, 0, aurEff);
}
}
@@ -723,14 +756,14 @@ class spell_dk_death_coil : public SpellScriptLoader
{
PrepareSpellScript(spell_dk_death_coil_SpellScript);
bool Validate(SpellInfo const* /*SpellEntry*/)
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_DEATH_COIL_DAMAGE) || !sSpellMgr->GetSpellInfo(SPELL_DEATH_COIL_HEAL))
return false;
return true;
}
void HandleDummy(SpellEffIndex /* effIndex */)
void HandleDummy(SpellEffIndex /*effIndex*/)
{
int32 damage = GetEffectValue();
Unit* caster = GetCaster();
+271 -19
View File
@@ -28,7 +28,11 @@
enum DruidSpells
{
DRUID_INCREASED_MOONFIRE_DURATION = 38414,
DRUID_NATURES_SPLENDOR = 57865
DRUID_NATURES_SPLENDOR = 57865,
DRUID_LIFEBLOOM_FINAL_HEAL = 33778,
DRUID_LIFEBLOOM_ENERGIZE = 64372,
DRUID_SURVIVAL_INSTINCTS = 50322,
DRUID_SAVAGE_ROAR = 62071
};
// 54846 Glyph of Starfire
@@ -154,7 +158,7 @@ class spell_dru_primal_tenacity : public SpellScriptLoader
void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount)
{
// reduces all damage taken while Stunned in Cat Form
if (GetTarget()->GetShapeshiftForm() == FORM_CAT && GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_STUNNED) && GetTarget()->HasAuraWithMechanic(1<<MECHANIC_STUN))
if (GetTarget()->GetShapeshiftForm() == FORM_CAT && GetTarget()->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED) && GetTarget()->HasAuraWithMechanic(1<<MECHANIC_STUN))
absorbAmount = CalculatePctN(dmgInfo.GetDamage(), absorbPct);
}
@@ -228,37 +232,37 @@ class spell_dru_t10_restoration_4p_bonus : public SpellScriptLoader
return GetCaster()->GetTypeId() == TYPEID_PLAYER;
}
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& targets)
{
if (!GetCaster()->ToPlayer()->GetGroup())
{
unitList.clear();
unitList.push_back(GetCaster());
targets.clear();
targets.push_back(GetCaster());
}
else
{
unitList.remove(GetExplTargetUnit());
targets.remove(GetExplTargetUnit());
std::list<Unit*> tempTargets;
for (std::list<Unit*>::const_iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
if ((*itr)->GetTypeId() == TYPEID_PLAYER && GetCaster()->IsInRaidWith(*itr))
tempTargets.push_back(*itr);
for (std::list<WorldObject*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr)
if ((*itr)->GetTypeId() == TYPEID_PLAYER && GetCaster()->IsInRaidWith((*itr)->ToUnit()))
tempTargets.push_back((*itr)->ToUnit());
if (tempTargets.empty())
{
unitList.clear();
targets.clear();
FinishCast(SPELL_FAILED_DONT_REPORT);
return;
}
Unit* target = Trinity::Containers::SelectRandomContainerElement(tempTargets);
unitList.clear();
unitList.push_back(target);
targets.clear();
targets.push_back(target);
}
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_dru_t10_restoration_4p_bonus_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_t10_restoration_4p_bonus_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY);
}
};
@@ -277,14 +281,14 @@ class spell_dru_starfall_aoe : public SpellScriptLoader
{
PrepareSpellScript(spell_dru_starfall_aoe_SpellScript);
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& targets)
{
unitList.remove(GetExplTargetUnit());
targets.remove(GetExplTargetUnit());
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_dru_starfall_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_starfall_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
@@ -337,7 +341,12 @@ class spell_dru_starfall_dummy : public SpellScriptLoader
{
PrepareSpellScript(spell_dru_starfall_dummy_SpellScript);
void HandleDummy(SpellEffIndex /* effIndex */)
void FilterTargets(std::list<WorldObject*>& targets)
{
Trinity::Containers::RandomResizeList(targets, 2);
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
// Shapeshifting into an animal form or mounting cancels the effect
@@ -348,15 +357,16 @@ class spell_dru_starfall_dummy : public SpellScriptLoader
return;
}
//Any effect which causes you to lose control of your character will supress the starfall effect.
// Any effect which causes you to lose control of your character will supress the starfall effect.
if (caster->HasUnitState(UNIT_STATE_CONTROLLED))
return;
caster->CastSpell(GetHitUnit(), GetEffectValue(), true);
caster->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true);
}
void Register()
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_starfall_dummy_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_dru_starfall_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
@@ -367,6 +377,244 @@ class spell_dru_starfall_dummy : public SpellScriptLoader
}
};
class spell_dru_lifebloom : public SpellScriptLoader
{
public:
spell_dru_lifebloom() : SpellScriptLoader("spell_dru_lifebloom") { }
class spell_dru_lifebloom_AuraScript : public AuraScript
{
PrepareAuraScript(spell_dru_lifebloom_AuraScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(DRUID_LIFEBLOOM_FINAL_HEAL))
return false;
if (!sSpellMgr->GetSpellInfo(DRUID_LIFEBLOOM_ENERGIZE))
return false;
return true;
}
void AfterRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
// Final heal only on duration end
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
return;
// final heal
int32 stack = GetStackAmount();
int32 healAmount = aurEff->GetAmount();
if (Unit* caster = GetCaster())
{
healAmount = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), healAmount, HEAL, stack);
healAmount = GetTarget()->SpellHealingBonusTaken(caster, GetSpellInfo(), healAmount, HEAL, stack);
GetTarget()->CastCustomSpell(GetTarget(), DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, aurEff, GetCasterGUID());
// restore mana
int32 returnMana = CalculatePctU(caster->GetCreateMana(), GetSpellInfo()->ManaCostPercentage) * stack / 2;
caster->CastCustomSpell(caster, DRUID_LIFEBLOOM_ENERGIZE, &returnMana, NULL, NULL, true, NULL, aurEff, GetCasterGUID());
return;
}
GetTarget()->CastCustomSpell(GetTarget(), DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, aurEff, GetCasterGUID());
}
void HandleDispel(DispelInfo* dispelInfo)
{
if (Unit* target = GetUnitOwner())
{
if (AuraEffect const* aurEff = GetEffect(EFFECT_1))
{
// final heal
int32 healAmount = aurEff->GetAmount();
if (Unit* caster = GetCaster())
{
healAmount = caster->SpellHealingBonusDone(target, GetSpellInfo(), healAmount, HEAL, dispelInfo->GetRemovedCharges());
healAmount = target->SpellHealingBonusTaken(caster, GetSpellInfo(), healAmount, HEAL, dispelInfo->GetRemovedCharges());
target->CastCustomSpell(target, DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, NULL, GetCasterGUID());
// restore mana
int32 returnMana = CalculatePctU(caster->GetCreateMana(), GetSpellInfo()->ManaCostPercentage) * dispelInfo->GetRemovedCharges() / 2;
caster->CastCustomSpell(caster, DRUID_LIFEBLOOM_ENERGIZE, &returnMana, NULL, NULL, true, NULL, NULL, GetCasterGUID());
return;
}
target->CastCustomSpell(target, DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, NULL, GetCasterGUID());
}
}
}
void Register()
{
AfterEffectRemove += AuraEffectRemoveFn(spell_dru_lifebloom_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
AfterDispel += AuraDispelFn(spell_dru_lifebloom_AuraScript::HandleDispel);
}
};
AuraScript* GetAuraScript() const
{
return new spell_dru_lifebloom_AuraScript();
}
};
class spell_dru_predatory_strikes : public SpellScriptLoader
{
public:
spell_dru_predatory_strikes() : SpellScriptLoader("spell_dru_predatory_strikes") { }
class spell_dru_predatory_strikes_AuraScript : public AuraScript
{
PrepareAuraScript(spell_dru_predatory_strikes_AuraScript);
void UpdateAmount(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Player* target = GetTarget()->ToPlayer())
target->UpdateAttackPowerAndDamage();
}
void Register()
{
AfterEffectApply += AuraEffectApplyFn(spell_dru_predatory_strikes_AuraScript::UpdateAmount, EFFECT_ALL, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
AfterEffectRemove += AuraEffectRemoveFn(spell_dru_predatory_strikes_AuraScript::UpdateAmount, EFFECT_ALL, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
}
};
AuraScript* GetAuraScript() const
{
return new spell_dru_predatory_strikes_AuraScript();
}
};
class spell_dru_savage_roar : public SpellScriptLoader
{
public:
spell_dru_savage_roar() : SpellScriptLoader("spell_dru_savage_roar") { }
class spell_dru_savage_roar_SpellScript : public SpellScript
{
PrepareSpellScript(spell_dru_savage_roar_SpellScript);
SpellCastResult CheckCast()
{
Unit* caster = GetCaster();
if (caster->GetShapeshiftForm() != FORM_CAT)
return SPELL_FAILED_ONLY_SHAPESHIFT;
return SPELL_CAST_OK;
}
void Register()
{
OnCheckCast += SpellCheckCastFn(spell_dru_savage_roar_SpellScript::CheckCast);
}
};
class spell_dru_savage_roar_AuraScript : public AuraScript
{
PrepareAuraScript(spell_dru_savage_roar_AuraScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(DRUID_SAVAGE_ROAR))
return false;
return true;
}
void AfterApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
target->CastSpell(target, DRUID_SAVAGE_ROAR, true, NULL, aurEff, GetCasterGUID());
}
void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
GetTarget()->RemoveAurasDueToSpell(DRUID_SAVAGE_ROAR);
}
void Register()
{
AfterEffectApply += AuraEffectApplyFn(spell_dru_savage_roar_AuraScript::AfterApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
AfterEffectRemove += AuraEffectRemoveFn(spell_dru_savage_roar_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
SpellScript* GetSpellScript() const
{
return new spell_dru_savage_roar_SpellScript();
}
AuraScript* GetAuraScript() const
{
return new spell_dru_savage_roar_AuraScript();
}
};
class spell_dru_survival_instincts : public SpellScriptLoader
{
public:
spell_dru_survival_instincts() : SpellScriptLoader("spell_dru_survival_instincts") { }
class spell_dru_survival_instincts_SpellScript : public SpellScript
{
PrepareSpellScript(spell_dru_survival_instincts_SpellScript);
SpellCastResult CheckCast()
{
Unit* caster = GetCaster();
if (!caster->IsInFeralForm())
return SPELL_FAILED_ONLY_SHAPESHIFT;
return SPELL_CAST_OK;
}
void Register()
{
OnCheckCast += SpellCheckCastFn(spell_dru_survival_instincts_SpellScript::CheckCast);
}
};
class spell_dru_survival_instincts_AuraScript : public AuraScript
{
PrepareAuraScript(spell_dru_survival_instincts_AuraScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(DRUID_SURVIVAL_INSTINCTS))
return false;
return true;
}
void AfterApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
int32 bp0 = target->CountPctFromMaxHealth(aurEff->GetAmount());
target->CastCustomSpell(target, DRUID_SURVIVAL_INSTINCTS, &bp0, NULL, NULL, true);
}
void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
GetTarget()->RemoveAurasDueToSpell(DRUID_SURVIVAL_INSTINCTS);
}
void Register()
{
AfterEffectApply += AuraEffectApplyFn(spell_dru_survival_instincts_AuraScript::AfterApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
AfterEffectRemove += AuraEffectRemoveFn(spell_dru_survival_instincts_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
}
};
SpellScript* GetSpellScript() const
{
return new spell_dru_survival_instincts_SpellScript();
}
AuraScript* GetAuraScript() const
{
return new spell_dru_survival_instincts_AuraScript();
}
};
void AddSC_druid_spell_scripts()
{
new spell_dru_glyph_of_starfire();
@@ -377,4 +625,8 @@ void AddSC_druid_spell_scripts()
new spell_dru_starfall_aoe();
new spell_dru_swift_flight_passive();
new spell_dru_starfall_dummy();
new spell_dru_lifebloom();
new spell_dru_predatory_strikes();
new spell_dru_savage_roar();
new spell_dru_survival_instincts();
}
+436 -29
View File
@@ -239,7 +239,7 @@ class spell_gen_parachute : public SpellScriptLoader
{
PrepareAuraScript(spell_gen_parachute_AuraScript);
bool Validate(SpellInfo const* /*spellEntry*/)
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_PARACHUTE) || !sSpellMgr->GetSpellInfo(SPELL_PARACHUTE_BUFF))
return false;
@@ -660,22 +660,16 @@ class spell_pvp_trinket_wotf_shared_cd : public SpellScriptLoader
return true;
}
void HandleScript(SpellEffIndex /*effIndex*/)
void HandleScript()
{
Player* caster = GetCaster()->ToPlayer();
SpellInfo const* spellInfo = GetSpellInfo();
caster->AddSpellCooldown(spellInfo->Id, 0, time(NULL) + sSpellMgr->GetSpellInfo(SPELL_WILL_OF_THE_FORSAKEN_COOLDOWN_TRIGGER)->GetRecoveryTime() / IN_MILLISECONDS);
WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+4);
data << uint64(caster->GetGUID());
data << uint8(0);
data << uint32(spellInfo->Id);
data << uint32(0);
caster->GetSession()->SendPacket(&data);
// This is only needed because spells cast from spell_linked_spell are triggered by default
// Spell::SendSpellCooldown() skips all spells with TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
GetCaster()->ToPlayer()->AddSpellAndCategoryCooldowns(GetSpellInfo(), GetCastItem() ? GetCastItem()->GetEntry() : 0, GetSpell());
}
void Register()
{
OnEffectHit += SpellEffectFn(spell_pvp_trinket_wotf_shared_cd_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
AfterCast += SpellCastFn(spell_pvp_trinket_wotf_shared_cd_SpellScript::HandleScript);
}
};
@@ -2052,9 +2046,9 @@ class spell_gen_defend : public SpellScriptLoader
public:
spell_gen_defend() : SpellScriptLoader("spell_gen_defend") { }
class spell_gen_defendAuraScript : public AuraScript
class spell_gen_defend_AuraScript : public AuraScript
{
PrepareAuraScript(spell_gen_defendAuraScript);
PrepareAuraScript(spell_gen_defend_AuraScript);
bool Validate(SpellInfo const* /*spellEntry*/)
{
@@ -2103,26 +2097,26 @@ class spell_gen_defend : public SpellScriptLoader
// Defend spells casted by NPCs (add visuals)
if (spell->Effects[EFFECT_0].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)
{
AfterEffectApply += AuraEffectApplyFn(spell_gen_defendAuraScript::RefreshVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
OnEffectRemove += AuraEffectRemoveFn(spell_gen_defendAuraScript::RemoveVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
AfterEffectApply += AuraEffectApplyFn(spell_gen_defend_AuraScript::RefreshVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
}
// Remove Defend spell from player when he dismounts
if (spell->Effects[EFFECT_2].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)
OnEffectRemove += AuraEffectRemoveFn(spell_gen_defendAuraScript::RemoveDummyFromDriver, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveDummyFromDriver, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
// Defend spells casted by players (add/remove visuals)
if (spell->Effects[EFFECT_1].ApplyAuraName == SPELL_AURA_DUMMY)
{
AfterEffectApply += AuraEffectApplyFn(spell_gen_defendAuraScript::RefreshVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
OnEffectRemove += AuraEffectRemoveFn(spell_gen_defendAuraScript::RemoveVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
AfterEffectApply += AuraEffectApplyFn(spell_gen_defend_AuraScript::RefreshVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
}
}
};
AuraScript* GetAuraScript() const
{
return new spell_gen_defendAuraScript();
return new spell_gen_defend_AuraScript();
}
};
@@ -2326,9 +2320,9 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader
public:
spell_gen_on_tournament_mount() : SpellScriptLoader("spell_gen_on_tournament_mount") { }
class spell_gen_on_tournament_mountAuraScript : public AuraScript
class spell_gen_on_tournament_mount_AuraScript : public AuraScript
{
PrepareAuraScript(spell_gen_on_tournament_mountAuraScript);
PrepareAuraScript(spell_gen_on_tournament_mount_AuraScript);
uint32 _pennantSpellId;
@@ -2468,14 +2462,14 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader
void Register()
{
AfterEffectApply += AuraEffectApplyFn(spell_gen_on_tournament_mountAuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
OnEffectRemove += AuraEffectRemoveFn(spell_gen_on_tournament_mountAuraScript::HandleRemoveEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
AfterEffectApply += AuraEffectApplyFn(spell_gen_on_tournament_mount_AuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
OnEffectRemove += AuraEffectRemoveFn(spell_gen_on_tournament_mount_AuraScript::HandleRemoveEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
AuraScript* GetAuraScript() const
{
return new spell_gen_on_tournament_mountAuraScript();
return new spell_gen_on_tournament_mount_AuraScript();
}
};
@@ -2484,9 +2478,9 @@ class spell_gen_tournament_pennant : public SpellScriptLoader
public:
spell_gen_tournament_pennant() : SpellScriptLoader("spell_gen_tournament_pennant") { }
class spell_gen_tournament_pennantAuraScript : public AuraScript
class spell_gen_tournament_pennant_AuraScript : public AuraScript
{
PrepareAuraScript(spell_gen_tournament_pennantAuraScript);
PrepareAuraScript(spell_gen_tournament_pennant_AuraScript);
bool Load()
{
@@ -2502,13 +2496,13 @@ class spell_gen_tournament_pennant : public SpellScriptLoader
void Register()
{
OnEffectApply += AuraEffectApplyFn(spell_gen_tournament_pennantAuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
OnEffectApply += AuraEffectApplyFn(spell_gen_tournament_pennant_AuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
AuraScript* GetAuraScript() const
{
return new spell_gen_tournament_pennantAuraScript();
return new spell_gen_tournament_pennant_AuraScript();
}
};
@@ -2688,6 +2682,401 @@ public:
}
};
class spell_gen_touch_the_nightmare : public SpellScriptLoader
{
public:
spell_gen_touch_the_nightmare() : SpellScriptLoader("spell_gen_touch_the_nightmare") { }
class spell_gen_touch_the_nightmare_SpellScript : public SpellScript
{
PrepareSpellScript(spell_gen_touch_the_nightmare_SpellScript);
void HandleDamageCalc(SpellEffIndex /*effIndex*/)
{
uint32 bp = GetCaster()->GetMaxHealth() * 0.3f;
SetHitDamage(bp);
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_gen_touch_the_nightmare_SpellScript::HandleDamageCalc, EFFECT_2, SPELL_EFFECT_SCHOOL_DAMAGE);
}
};
SpellScript* GetSpellScript() const
{
return new spell_gen_touch_the_nightmare_SpellScript();
}
};
class spell_gen_dream_funnel: public SpellScriptLoader
{
public:
spell_gen_dream_funnel() : SpellScriptLoader("spell_gen_dream_funnel") { }
class spell_gen_dream_funnel_AuraScript : public AuraScript
{
PrepareAuraScript(spell_gen_dream_funnel_AuraScript);
void HandleEffectCalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated)
{
if (GetCaster())
amount = GetCaster()->GetMaxHealth() * 0.05f;
canBeRecalculated = false;
}
void Register()
{
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_dream_funnel_AuraScript::HandleEffectCalcAmount, EFFECT_0, SPELL_AURA_PERIODIC_HEAL);
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_dream_funnel_AuraScript::HandleEffectCalcAmount, EFFECT_2, SPELL_AURA_PERIODIC_DAMAGE);
}
};
AuraScript* GetAuraScript() const
{
return new spell_gen_dream_funnel_AuraScript();
}
};
enum GenericBandage
{
SPELL_RECENTLY_BANDAGED = 11196,
};
class spell_gen_bandage : public SpellScriptLoader
{
public:
spell_gen_bandage() : SpellScriptLoader("spell_gen_bandage") { }
class spell_gen_bandage_SpellScript : public SpellScript
{
PrepareSpellScript(spell_gen_bandage_SpellScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_RECENTLY_BANDAGED))
return false;
return true;
}
SpellCastResult CheckCast()
{
if (Unit* target = GetExplTargetUnit())
{
if (target->HasAura(SPELL_RECENTLY_BANDAGED))
return SPELL_FAILED_TARGET_AURASTATE;
}
return SPELL_CAST_OK;
}
void HandleScript()
{
if (Unit* target = GetHitUnit())
GetCaster()->CastSpell(target, SPELL_RECENTLY_BANDAGED, true);
}
void Register()
{
OnCheckCast += SpellCheckCastFn(spell_gen_bandage_SpellScript::CheckCast);
AfterHit += SpellHitFn(spell_gen_bandage_SpellScript::HandleScript);
}
};
SpellScript* GetSpellScript() const
{
return new spell_gen_bandage_SpellScript();
}
};
enum GenericLifebloom
{
SPELL_HEXLORD_MALACRASS_LIFEBLOOM_FINAL_HEAL = 43422,
SPELL_TUR_RAGEPAW_LIFEBLOOM_FINAL_HEAL = 52552,
SPELL_CENARION_SCOUT_LIFEBLOOM_FINAL_HEAL = 53692,
SPELL_TWISTED_VISAGE_LIFEBLOOM_FINAL_HEAL = 57763,
SPELL_FACTION_CHAMPIONS_DRU_LIFEBLOOM_FINAL_HEAL = 66094,
};
class spell_gen_lifebloom : public SpellScriptLoader
{
public:
spell_gen_lifebloom(const char* name, uint32 spellId) : SpellScriptLoader(name), _spellId(spellId) { }
class spell_gen_lifebloom_AuraScript : public AuraScript
{
PrepareAuraScript(spell_gen_lifebloom_AuraScript);
public:
spell_gen_lifebloom_AuraScript(uint32 spellId) : AuraScript(), _spellId(spellId) { }
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(_spellId))
return false;
return true;
}
void AfterRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
// Final heal only on duration end
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE && GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL)
return;
// final heal
GetTarget()->CastSpell(GetTarget(), _spellId, true, NULL, aurEff, GetCasterGUID());
}
void Register()
{
AfterEffectRemove += AuraEffectRemoveFn(spell_gen_lifebloom_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL);
}
private:
uint32 _spellId;
};
AuraScript* GetAuraScript() const
{
return new spell_gen_lifebloom_AuraScript(_spellId);
}
private:
uint32 _spellId;
};
enum SummonElemental
{
SPELL_SUMMON_FIRE_ELEMENTAL = 8985,
SPELL_SUMMON_EARTH_ELEMENTAL = 19704
};
class spell_gen_summon_elemental : public SpellScriptLoader
{
public:
spell_gen_summon_elemental(const char* name, uint32 spellId) : SpellScriptLoader(name), _spellId(spellId) { }
class spell_gen_summon_elemental_AuraScript : public AuraScript
{
PrepareAuraScript(spell_gen_summon_elemental_AuraScript);
public:
spell_gen_summon_elemental_AuraScript(uint32 spellId) : AuraScript(), _spellId(spellId) { }
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(_spellId))
return false;
return true;
}
void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetCaster())
if (Unit* owner = GetCaster()->GetOwner())
owner->CastSpell(owner, _spellId, true);
}
void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetCaster())
if (Unit* owner = GetCaster()->GetOwner())
if (owner->GetTypeId() == TYPEID_PLAYER) // todo: this check is maybe wrong
owner->ToPlayer()->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
}
void Register()
{
AfterEffectApply += AuraEffectApplyFn(spell_gen_summon_elemental_AuraScript::AfterApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
AfterEffectRemove += AuraEffectRemoveFn(spell_gen_summon_elemental_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
private:
uint32 _spellId;
};
AuraScript* GetAuraScript() const
{
return new spell_gen_summon_elemental_AuraScript(_spellId);
}
private:
uint32 _spellId;
};
enum Mounts
{
SPELL_COLD_WEATHER_FLYING = 54197,
// Magic Broom
SPELL_MAGIC_BROOM_60 = 42680,
SPELL_MAGIC_BROOM_100 = 42683,
SPELL_MAGIC_BROOM_150 = 42667,
SPELL_MAGIC_BROOM_280 = 42668,
// Headless Horseman's Mount
SPELL_HEADLESS_HORSEMAN_MOUNT_60 = 51621,
SPELL_HEADLESS_HORSEMAN_MOUNT_100 = 48024,
SPELL_HEADLESS_HORSEMAN_MOUNT_150 = 51617,
SPELL_HEADLESS_HORSEMAN_MOUNT_280 = 48023,
// Winged Steed of the Ebon Blade
SPELL_WINGED_STEED_150 = 54726,
SPELL_WINGED_STEED_280 = 54727,
// Big Love Rocket
SPELL_BIG_LOVE_ROCKET_0 = 71343,
SPELL_BIG_LOVE_ROCKET_60 = 71344,
SPELL_BIG_LOVE_ROCKET_100 = 71345,
SPELL_BIG_LOVE_ROCKET_150 = 71346,
SPELL_BIG_LOVE_ROCKET_310 = 71347,
// Invincible
SPELL_INVINCIBLE_60 = 72281,
SPELL_INVINCIBLE_100 = 72282,
SPELL_INVINCIBLE_150 = 72283,
SPELL_INVINCIBLE_310 = 72284,
// Blazing Hippogryph
SPELL_BLAZING_HIPPOGRYPH_150 = 74854,
SPELL_BLAZING_HIPPOGRYPH_280 = 74855,
// Celestial Steed
SPELL_CELESTIAL_STEED_60 = 75619,
SPELL_CELESTIAL_STEED_100 = 75620,
SPELL_CELESTIAL_STEED_150 = 75617,
SPELL_CELESTIAL_STEED_280 = 75618,
SPELL_CELESTIAL_STEED_310 = 76153,
// X-53 Touring Rocket
SPELL_X53_TOURING_ROCKET_150 = 75957,
SPELL_X53_TOURING_ROCKET_280 = 75972,
SPELL_X53_TOURING_ROCKET_310 = 76154,
};
class spell_gen_mount : public SpellScriptLoader
{
public:
spell_gen_mount(const char* name, uint32 mount0 = 0, uint32 mount60 = 0, uint32 mount100 = 0, uint32 mount150 = 0, uint32 mount280 = 0, uint32 mount310 = 0) : SpellScriptLoader(name),
_mount0(mount0), _mount60(mount60), _mount100(mount100), _mount150(mount150), _mount280(mount280), _mount310(mount310) { }
class spell_gen_mount_SpellScript : public SpellScript
{
PrepareSpellScript(spell_gen_mount_SpellScript);
public:
spell_gen_mount_SpellScript(uint32 mount0, uint32 mount60, uint32 mount100, uint32 mount150, uint32 mount280, uint32 mount310) : SpellScript(),
_mount0(mount0), _mount60(mount60), _mount100(mount100), _mount150(mount150), _mount280(mount280), _mount310(mount310) { }
bool Validate(SpellInfo const* /*spell*/)
{
if (_mount0 && !sSpellMgr->GetSpellInfo(_mount0))
return false;
if (_mount60 && !sSpellMgr->GetSpellInfo(_mount60))
return false;
if (_mount100 && !sSpellMgr->GetSpellInfo(_mount100))
return false;
if (_mount150 && !sSpellMgr->GetSpellInfo(_mount150))
return false;
if (_mount280 && !sSpellMgr->GetSpellInfo(_mount280))
return false;
if (_mount310 && !sSpellMgr->GetSpellInfo(_mount310))
return false;
return true;
}
void HandleMount(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
if (Player* target = GetHitPlayer())
{
// Prevent stacking of mounts and client crashes upon dismounting
target->RemoveAurasByType(SPELL_AURA_MOUNTED, 0, GetHitAura());
// Triggered spell id dependent on riding skill and zone
bool canFly = false;
uint32 map = GetVirtualMapForMapAndZone(target->GetMapId(), target->GetZoneId());
if (map == 530 || (map == 571 && target->HasSpell(SPELL_COLD_WEATHER_FLYING)))
canFly = true;
float x, y, z;
target->GetPosition(x, y, z);
uint32 areaFlag = target->GetBaseMap()->GetAreaFlag(x, y, z);
AreaTableEntry const* area = sAreaStore.LookupEntry(areaFlag);
if (!area || (canFly && (area->flags & AREA_FLAG_NO_FLY_ZONE)))
canFly = false;
uint32 mount = 0;
switch (target->GetBaseSkillValue(SKILL_RIDING))
{
case 0:
mount = _mount0;
break;
case 75:
mount = _mount60;
break;
case 150:
mount = _mount100;
break;
case 225:
if (canFly)
mount = _mount150;
else
mount = _mount100;
break;
case 300:
if (canFly)
mount = _mount280;
else
mount = _mount100;
break;
case 375:
if (canFly)
mount = _mount310;
else
mount = _mount100;
break;
default:
break;
}
if (mount)
{
PreventHitAura();
target->CastSpell(target, mount, true);
}
}
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_gen_mount_SpellScript::HandleMount, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
}
private:
uint32 _mount0;
uint32 _mount60;
uint32 _mount100;
uint32 _mount150;
uint32 _mount280;
uint32 _mount310;
};
SpellScript* GetSpellScript() const
{
return new spell_gen_mount_SpellScript(_mount0, _mount60, _mount100, _mount150, _mount280, _mount310);
}
private:
uint32 _mount0;
uint32 _mount60;
uint32 _mount100;
uint32 _mount150;
uint32 _mount280;
uint32 _mount310;
};
void AddSC_generic_spell_scripts()
{
new spell_gen_absorb0_hitlimit1();
@@ -2742,4 +3131,22 @@ void AddSC_generic_spell_scripts()
new spell_gen_count_pct_from_max_hp("spell_gen_default_count_pct_from_max_hp");
new spell_gen_count_pct_from_max_hp("spell_gen_50pct_count_pct_from_max_hp", 50);
new spell_gen_despawn_self();
new spell_gen_touch_the_nightmare();
new spell_gen_dream_funnel();
new spell_gen_bandage();
new spell_gen_lifebloom("spell_hexlord_lifebloom", SPELL_HEXLORD_MALACRASS_LIFEBLOOM_FINAL_HEAL);
new spell_gen_lifebloom("spell_tur_ragepaw_lifebloom", SPELL_TUR_RAGEPAW_LIFEBLOOM_FINAL_HEAL);
new spell_gen_lifebloom("spell_cenarion_scout_lifebloom", SPELL_CENARION_SCOUT_LIFEBLOOM_FINAL_HEAL);
new spell_gen_lifebloom("spell_twisted_visage_lifebloom", SPELL_TWISTED_VISAGE_LIFEBLOOM_FINAL_HEAL);
new spell_gen_lifebloom("spell_faction_champion_dru_lifebloom", SPELL_FACTION_CHAMPIONS_DRU_LIFEBLOOM_FINAL_HEAL);
new spell_gen_summon_elemental("spell_gen_summon_fire_elemental", SPELL_SUMMON_FIRE_ELEMENTAL);
new spell_gen_summon_elemental("spell_gen_summon_earth_elemental", SPELL_SUMMON_EARTH_ELEMENTAL);
new spell_gen_mount("spell_magic_broom", 0, SPELL_MAGIC_BROOM_60, SPELL_MAGIC_BROOM_100, SPELL_MAGIC_BROOM_150, SPELL_MAGIC_BROOM_280);
new spell_gen_mount("spell_headless_horseman_mount", 0, SPELL_HEADLESS_HORSEMAN_MOUNT_60, SPELL_HEADLESS_HORSEMAN_MOUNT_100, SPELL_HEADLESS_HORSEMAN_MOUNT_150, SPELL_HEADLESS_HORSEMAN_MOUNT_280);
new spell_gen_mount("spell_winged_steed_of_the_ebon_blade", 0, 0, 0, SPELL_WINGED_STEED_150, SPELL_WINGED_STEED_280);
new spell_gen_mount("spell_big_love_rocket", SPELL_BIG_LOVE_ROCKET_0, SPELL_BIG_LOVE_ROCKET_60, SPELL_BIG_LOVE_ROCKET_100, SPELL_BIG_LOVE_ROCKET_150, SPELL_BIG_LOVE_ROCKET_310);
new spell_gen_mount("spell_invincible", 0, SPELL_INVINCIBLE_60, SPELL_INVINCIBLE_100, SPELL_INVINCIBLE_150, SPELL_INVINCIBLE_310);
new spell_gen_mount("spell_blazing_hippogryph", 0, 0, 0, SPELL_BLAZING_HIPPOGRYPH_150, SPELL_BLAZING_HIPPOGRYPH_280);
new spell_gen_mount("spell_celestial_steed", 0, SPELL_CELESTIAL_STEED_60, SPELL_CELESTIAL_STEED_100, SPELL_CELESTIAL_STEED_150, SPELL_CELESTIAL_STEED_280, SPELL_CELESTIAL_STEED_310);
new spell_gen_mount("spell_x53_touring_rocket", 0, 0, 0, SPELL_X53_TOURING_ROCKET_150, SPELL_X53_TOURING_ROCKET_280, SPELL_X53_TOURING_ROCKET_310);
}
@@ -618,6 +618,86 @@ class spell_hun_misdirection_proc : public SpellScriptLoader
}
};
class spell_hun_disengage : public SpellScriptLoader
{
public:
spell_hun_disengage() : SpellScriptLoader("spell_hun_disengage") { }
class spell_hun_disengage_SpellScript : public SpellScript
{
PrepareSpellScript(spell_hun_disengage_SpellScript);
SpellCastResult CheckCast()
{
Unit* caster = GetCaster();
if (caster->GetTypeId() == TYPEID_PLAYER && !caster->isInCombat())
return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
return SPELL_CAST_OK;
}
void Register()
{
OnCheckCast += SpellCheckCastFn(spell_hun_disengage_SpellScript::CheckCast);
}
};
SpellScript* GetSpellScript() const
{
return new spell_hun_disengage_SpellScript();
}
};
class spell_hun_tame_beast : public SpellScriptLoader
{
public:
spell_hun_tame_beast() : SpellScriptLoader("spell_hun_tame_beast") { }
class spell_hun_tame_beast_SpellScript : public SpellScript
{
PrepareSpellScript(spell_hun_tame_beast_SpellScript);
SpellCastResult CheckCast()
{
Unit* caster = GetCaster();
if (caster->GetTypeId() != TYPEID_PLAYER)
return SPELL_FAILED_DONT_REPORT;
if (!GetExplTargetUnit())
return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
if (Creature* target = GetExplTargetUnit()->ToCreature())
{
if (target->getLevel() > caster->getLevel())
return SPELL_FAILED_HIGHLEVEL;
// use SMSG_PET_TAME_FAILURE?
if (!target->GetCreatureTemplate()->isTameable(caster->ToPlayer()->CanTameExoticPets()))
return SPELL_FAILED_BAD_TARGETS;
if (caster->GetPetGUID())
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
if (caster->GetCharmGUID())
return SPELL_FAILED_ALREADY_HAVE_CHARM;
}
else
return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
return SPELL_CAST_OK;
}
void Register()
{
OnCheckCast += SpellCheckCastFn(spell_hun_tame_beast_SpellScript::CheckCast);
}
};
SpellScript* GetSpellScript() const
{
return new spell_hun_tame_beast_SpellScript();
}
};
void AddSC_hunter_spell_scripts()
{
@@ -633,4 +713,6 @@ void AddSC_hunter_spell_scripts()
new spell_hun_pet_carrion_feeder();
new spell_hun_misdirection();
new spell_hun_misdirection_proc();
new spell_hun_disengage();
new spell_hun_tame_beast();
}
-55
View File
@@ -1848,60 +1848,6 @@ class spell_item_unusual_compass : public SpellScriptLoader
}
};
enum UDED
{
NPC_IRONWOOL_MAMMOTH = 53806,
SPELL_MAMMOTH_CARCASS = 57444,
SPELL_MAMMOTH_MEAT = 54625,
};
class spell_item_uded : public SpellScriptLoader
{
public:
spell_item_uded() : SpellScriptLoader("spell_item_uded") { }
class spell_item_uded_SpellScript : public SpellScript
{
PrepareSpellScript(spell_item_uded_SpellScript);
bool Load()
{
if (GetHitCreature() && GetHitCreature()->GetEntry() == NPC_IRONWOOL_MAMMOTH)
return true;
return false;
}
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_MAMMOTH_CARCASS) || !sSpellMgr->GetSpellInfo(SPELL_MAMMOTH_MEAT))
return false;
return true;
}
void HandleDummy(SpellEffIndex /* effIndex */)
{
Unit* caster = GetCaster();
Creature* creature = GetHitCreature();
caster->CastSpell(caster,SPELL_MAMMOTH_CARCASS,true);
for (uint8 i = 0; i < 4; ++i)
caster->CastSpell(caster,SPELL_MAMMOTH_MEAT,true);
creature->Kill(creature);
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_item_uded_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const
{
return new spell_item_uded_SpellScript();
}
};
enum ChickenCover
{
SPELL_CHICKEN_NET = 51959,
@@ -2109,7 +2055,6 @@ void AddSC_item_spell_scripts()
new spell_item_rocket_boots();
new spell_item_pygmy_oil();
new spell_item_unusual_compass();
new spell_item_uded();
new spell_item_chicken_cover();
new spell_item_muisek_vessel();
new spell_item_greatmothers_soulcatcher();
+43 -4
View File
@@ -342,13 +342,52 @@ public:
}
};
class spell_mage_living_bomb : public SpellScriptLoader
{
public:
spell_mage_living_bomb() : SpellScriptLoader("spell_mage_living_bomb") { }
class spell_mage_living_bomb_AuraScript : public AuraScript
{
PrepareAuraScript(spell_mage_living_bomb_AuraScript);
bool Validate(SpellInfo const* spell)
{
if (!sSpellMgr->GetSpellInfo(uint32(spell->Effects[EFFECT_1].CalcValue())))
return false;
return true;
}
void AfterRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
AuraRemoveMode removeMode = GetTargetApplication()->GetRemoveMode();
if (removeMode != AURA_REMOVE_BY_ENEMY_SPELL && removeMode != AURA_REMOVE_BY_EXPIRE)
return;
if (Unit* caster = GetCaster())
caster->CastSpell(GetTarget(), uint32(aurEff->GetAmount()), true, NULL, aurEff);
}
void Register()
{
AfterEffectRemove += AuraEffectRemoveFn(spell_mage_living_bomb_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const
{
return new spell_mage_living_bomb_AuraScript();
}
};
void AddSC_mage_spell_scripts()
{
new spell_mage_blast_wave;
new spell_mage_cold_snap;
new spell_mage_blast_wave();
new spell_mage_cold_snap();
new spell_mage_frost_warding_trigger();
new spell_mage_incanters_absorbtion_absorb();
new spell_mage_incanters_absorbtion_manashield();
new spell_mage_polymorph_cast_visual;
new spell_mage_summon_water_elemental;
new spell_mage_polymorph_cast_visual();
new spell_mage_summon_water_elemental();
new spell_mage_living_bomb();
}
+107 -7
View File
@@ -43,6 +43,10 @@ enum PaladinSpells
SPELL_DIVINE_STORM = 53385,
SPELL_DIVINE_STORM_DUMMY = 54171,
SPELL_DIVINE_STORM_HEAL = 54172,
SPELL_FORBEARANCE = 25771,
SPELL_AVENGING_WRATH_MARKER = 61987,
SPELL_IMMUNE_SHIELD_MARKER = 61988,
};
// 31850 - Ardent Defender
@@ -255,17 +259,18 @@ class spell_pal_holy_shock : public SpellScriptLoader
class spell_pal_holy_shock_SpellScript : public SpellScript
{
PrepareSpellScript(spell_pal_holy_shock_SpellScript)
bool Validate(SpellInfo const* spellEntry)
PrepareSpellScript(spell_pal_holy_shock_SpellScript);
bool Validate(SpellInfo const* spell)
{
if (!sSpellMgr->GetSpellInfo(PALADIN_SPELL_HOLY_SHOCK_R1))
return false;
// can't use other spell than holy shock due to spell_ranks dependency
if (sSpellMgr->GetFirstSpellInChain(PALADIN_SPELL_HOLY_SHOCK_R1) != sSpellMgr->GetFirstSpellInChain(spellEntry->Id))
if (sSpellMgr->GetFirstSpellInChain(PALADIN_SPELL_HOLY_SHOCK_R1) != sSpellMgr->GetFirstSpellInChain(spell->Id))
return false;
uint8 rank = sSpellMgr->GetSpellRank(spellEntry->Id);
uint8 rank = sSpellMgr->GetSpellRank(spell->Id);
if (!sSpellMgr->GetSpellWithRank(PALADIN_SPELL_HOLY_SHOCK_R1_DAMAGE, rank, true) || !sSpellMgr->GetSpellWithRank(PALADIN_SPELL_HOLY_SHOCK_R1_HEALING, rank, true))
return false;
@@ -287,7 +292,7 @@ class spell_pal_holy_shock : public SpellScriptLoader
SpellCastResult CheckCast()
{
Player* caster = GetCaster()->ToPlayer();
Unit* caster = GetCaster();
if (Unit* target = GetExplTargetUnit())
{
if (!caster->IsFriendlyTo(target))
@@ -404,7 +409,7 @@ class spell_pal_divine_storm_dummy : public SpellScriptLoader
return true;
}
void CountTargets(std::list<Unit*>& targetList)
void CountTargets(std::list<WorldObject*>& targetList)
{
_targetCount = targetList.size();
}
@@ -423,7 +428,7 @@ class spell_pal_divine_storm_dummy : public SpellScriptLoader
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_pal_divine_storm_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
OnUnitTargetSelect += SpellUnitTargetFn(spell_pal_divine_storm_dummy_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pal_divine_storm_dummy_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID);
}
};
@@ -433,6 +438,99 @@ class spell_pal_divine_storm_dummy : public SpellScriptLoader
}
};
class spell_pal_lay_on_hands : public SpellScriptLoader
{
public:
spell_pal_lay_on_hands() : SpellScriptLoader("spell_pal_lay_on_hands") { }
class spell_pal_lay_on_hands_SpellScript : public SpellScript
{
PrepareSpellScript(spell_pal_lay_on_hands_SpellScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_FORBEARANCE))
return false;
if (!sSpellMgr->GetSpellInfo(SPELL_AVENGING_WRATH_MARKER))
return false;
if (!sSpellMgr->GetSpellInfo(SPELL_IMMUNE_SHIELD_MARKER))
return false;
return true;
}
SpellCastResult CheckCast()
{
Unit* caster = GetCaster();
if (Unit* target = GetExplTargetUnit())
if (caster == target)
if (target->HasAura(SPELL_FORBEARANCE) || target->HasAura(SPELL_AVENGING_WRATH_MARKER) || target->HasAura(SPELL_IMMUNE_SHIELD_MARKER))
return SPELL_FAILED_TARGET_AURASTATE;
return SPELL_CAST_OK;
}
void HandleScript()
{
Unit* caster = GetCaster();
if (caster == GetHitUnit())
{
caster->CastSpell(caster, SPELL_FORBEARANCE, true);
caster->CastSpell(caster, SPELL_AVENGING_WRATH_MARKER, true);
caster->CastSpell(caster, SPELL_IMMUNE_SHIELD_MARKER, true);
}
}
void Register()
{
OnCheckCast += SpellCheckCastFn(spell_pal_lay_on_hands_SpellScript::CheckCast);
AfterHit += SpellHitFn(spell_pal_lay_on_hands_SpellScript::HandleScript);
}
};
SpellScript* GetSpellScript() const
{
return new spell_pal_lay_on_hands_SpellScript();
}
};
class spell_pal_righteous_defense : public SpellScriptLoader
{
public:
spell_pal_righteous_defense() : SpellScriptLoader("spell_pal_righteous_defense") { }
class spell_pal_righteous_defense_SpellScript : public SpellScript
{
PrepareSpellScript(spell_pal_righteous_defense_SpellScript);
SpellCastResult CheckCast()
{
Unit* caster = GetCaster();
if (caster->GetTypeId() != TYPEID_PLAYER)
return SPELL_FAILED_DONT_REPORT;
if (Unit* target = GetExplTargetUnit())
{
if (!target->IsFriendlyTo(caster) || target->getAttackers().empty())
return SPELL_FAILED_BAD_TARGETS;
}
else
return SPELL_FAILED_BAD_TARGETS;
return SPELL_CAST_OK;
}
void Register()
{
OnCheckCast += SpellCheckCastFn(spell_pal_righteous_defense_SpellScript::CheckCast);
}
};
SpellScript* GetSpellScript() const
{
return new spell_pal_righteous_defense_SpellScript();
}
};
void AddSC_paladin_spell_scripts()
{
new spell_pal_ardent_defender();
@@ -443,4 +541,6 @@ void AddSC_paladin_spell_scripts()
new spell_pal_judgement_of_command();
new spell_pal_divine_storm();
new spell_pal_divine_storm_dummy();
new spell_pal_lay_on_hands();
new spell_pal_righteous_defense();
}
File diff suppressed because it is too large. Load diff
+90 -3
View File
@@ -34,6 +34,9 @@ enum PriestSpells
PRIEST_SPELL_PENANCE_R1_HEAL = 47757,
PRIEST_SPELL_REFLECTIVE_SHIELD_TRIGGERED = 33619,
PRIEST_SPELL_REFLECTIVE_SHIELD_R1 = 33201,
PRIEST_SPELL_VAMPIRIC_TOUCH_DISPEL = 64085,
PRIEST_SPELL_EMPOWERED_RENEW = 63544,
PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT = 3021,
};
// Guardian Spirit
@@ -129,14 +132,14 @@ class spell_pri_mind_sear : public SpellScriptLoader
{
PrepareSpellScript(spell_pri_mind_sear_SpellScript);
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& unitList)
{
unitList.remove_if (Trinity::ObjectGUIDCheck(GetCaster()->GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT)));
unitList.remove_if(Trinity::ObjectGUIDCheck(GetCaster()->GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT)));
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_pri_mind_sear_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pri_mind_sear_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
@@ -330,6 +333,88 @@ public:
}
};
class spell_pri_vampiric_touch : public SpellScriptLoader
{
public:
spell_pri_vampiric_touch() : SpellScriptLoader("spell_pri_vampiric_touch") { }
class spell_pri_vampiric_touch_AuraScript : public AuraScript
{
PrepareAuraScript(spell_pri_vampiric_touch_AuraScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(PRIEST_SPELL_VAMPIRIC_TOUCH_DISPEL))
return false;
return true;
}
void HandleDispel(DispelInfo* /*dispelInfo*/)
{
if (Unit* caster = GetCaster())
if (Unit* target = GetUnitOwner())
if (AuraEffect const* aurEff = GetEffect(EFFECT_1))
{
int32 damage = aurEff->GetAmount() * 8;
// backfire damage
caster->CastCustomSpell(target, PRIEST_SPELL_VAMPIRIC_TOUCH_DISPEL, &damage, NULL, NULL, true, NULL, aurEff);
}
}
void Register()
{
AfterDispel += AuraDispelFn(spell_pri_vampiric_touch_AuraScript::HandleDispel);
}
};
AuraScript* GetAuraScript() const
{
return new spell_pri_vampiric_touch_AuraScript();
}
};
class spell_priest_renew : public SpellScriptLoader
{
public:
spell_priest_renew() : SpellScriptLoader("spell_priest_renew") { }
class spell_priest_renew_AuraScript : public AuraScript
{
PrepareAuraScript(spell_priest_renew_AuraScript);
bool Load()
{
return GetCaster() && GetCaster()->GetTypeId() == TYPEID_PLAYER;
}
void HandleApplyEffect(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetCaster())
{
// Empowered Renew
if (AuraEffect const* empoweredRenewAurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT, EFFECT_1))
{
uint32 heal = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), GetEffect(EFFECT_0)->GetAmount(), DOT);
heal = GetTarget()->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT);
int32 basepoints0 = empoweredRenewAurEff->GetAmount() * GetEffect(EFFECT_0)->GetTotalTicks() * int32(heal) / 100;
caster->CastCustomSpell(GetTarget(), PRIEST_SPELL_EMPOWERED_RENEW, &basepoints0, NULL, NULL, true, NULL, aurEff);
}
}
}
void Register()
{
OnEffectApply += AuraEffectApplyFn(spell_priest_renew_AuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
AuraScript* GetAuraScript() const
{
return new spell_priest_renew_AuraScript();
}
};
void AddSC_priest_spell_scripts()
{
new spell_pri_guardian_spirit();
@@ -339,4 +424,6 @@ void AddSC_priest_spell_scripts()
new spell_pri_reflective_shield_trigger();
new spell_pri_mind_sear();
new spell_pri_prayer_of_mending_heal();
new spell_pri_vampiric_touch();
new spell_priest_renew();
}
+81 -1
View File
@@ -639,7 +639,7 @@ class spell_q12851_going_bearback : public SpellScriptLoader
// Already in fire
if (target->HasAura(SPELL_ABLAZE))
return;
if (Player* player = caster->GetCharmerOrOwnerPlayerOrPlayerItself())
{
switch (target->GetEntry())
@@ -1162,6 +1162,84 @@ class spell_q12277_wintergarde_mine_explosion : public SpellScriptLoader
}
};
enum FocusOnTheBeach
{
SPELL_BUNNY_CREDIT_BEAM = 47390,
};
class spell_q12066_bunny_kill_credit : public SpellScriptLoader
{
public:
spell_q12066_bunny_kill_credit() : SpellScriptLoader("spell_q12066_bunny_kill_credit") { }
class spell_q12066_bunny_kill_credit_SpellScript : public SpellScript
{
PrepareSpellScript(spell_q12066_bunny_kill_credit_SpellScript);
void HandleDummy(SpellEffIndex /*effIndex*/)
{
if (Creature* target = GetHitCreature())
target->CastSpell(GetCaster(), SPELL_BUNNY_CREDIT_BEAM, false);
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_q12066_bunny_kill_credit_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const
{
return new spell_q12066_bunny_kill_credit_SpellScript();
}
};
enum ACleansingSong
{
SPELL_SUMMON_SPIRIT_ATAH = 52954,
SPELL_SUMMON_SPIRIT_HAKHALAN = 52958,
SPELL_SUMMON_SPIRIT_KOOSU = 52959,
AREA_BITTERTIDELAKE = 4385,
AREA_RIVERSHEART = 4290,
AREA_WINTERGRASPRIVER = 4388,
};
class spell_q12735_song_of_cleansing : public SpellScriptLoader
{
public:
spell_q12735_song_of_cleansing() : SpellScriptLoader("spell_q12735_song_of_cleansing") { }
class spell_q12735_song_of_cleansing_SpellScript : public SpellScript
{
PrepareSpellScript(spell_q12735_song_of_cleansing_SpellScript);
void HandleScript(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
if (caster && caster->GetAreaId() == AREA_BITTERTIDELAKE)
caster->CastSpell(caster, SPELL_SUMMON_SPIRIT_ATAH);
else if (caster && caster->GetAreaId() == AREA_RIVERSHEART)
caster->CastSpell(caster, SPELL_SUMMON_SPIRIT_HAKHALAN);
else if (caster && caster->GetAreaId() == AREA_WINTERGRASPRIVER)
caster->CastSpell(caster, SPELL_SUMMON_SPIRIT_KOOSU);
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_q12735_song_of_cleansing_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const
{
return new spell_q12735_song_of_cleansing_SpellScript();
}
};
void AddSC_quest_spell_scripts()
{
new spell_q55_sacred_cleansing();
@@ -1189,4 +1267,6 @@ void AddSC_quest_spell_scripts()
new spell_q9452_cast_net();
new spell_q12987_read_pronouncement();
new spell_q12277_wintergarde_mine_explosion();
new spell_q12066_bunny_kill_credit();
new spell_q12735_song_of_cleansing();
}
+114 -15
View File
@@ -35,13 +35,19 @@ enum ShamanSpells
SHAMAN_SPELL_FIRE_NOVA_TRIGGERED_R1 = 8349,
SHAMAN_SPELL_SATED = 57724,
SHAMAN_SPELL_EXHAUSTION = 57723,
SHAMAN_SPELL_STORM_EARTH_AND_FIRE = 51483,
EARTHBIND_TOTEM_SPELL_EARTHGRAB = 64695,
// For Earthen Power
SHAMAN_TOTEM_SPELL_EARTHBIND_TOTEM = 6474,
SHAMAN_TOTEM_SPELL_EARTHEN_POWER = 59566,
SHAMAN_BIND_SIGHT = 6277,
ICON_ID_SHAMAN_LAVA_FLOW = 3087,
SHAMAN_LAVA_FLOWS_R1 = 51480,
SHAMAN_LAVA_FLOWS_TRIGGERED_R1 = 64694,
};
// 51474 - Astral shift
@@ -255,10 +261,13 @@ class EarthenPowerTargetSelector
{
public:
EarthenPowerTargetSelector() { }
bool operator() (Unit* target)
bool operator() (WorldObject* target)
{
if (!target->HasAuraWithMechanic(1 << MECHANIC_SNARE))
if (!target->ToUnit())
return true;
if (!target->ToUnit()->HasAuraWithMechanic(1 << MECHANIC_SNARE))
return true;
return false;
@@ -274,14 +283,14 @@ class spell_sha_earthen_power : public SpellScriptLoader
{
PrepareSpellScript(spell_sha_earthen_power_SpellScript);
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& unitList)
{
unitList.remove_if(EarthenPowerTargetSelector());
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_earthen_power_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_earthen_power_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
@@ -307,7 +316,7 @@ class spell_sha_bloodlust : public SpellScriptLoader
return true;
}
void RemoveInvalidTargets(std::list<Unit*>& targets)
void RemoveInvalidTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(Trinity::UnitAuraCheck(true, SHAMAN_SPELL_SATED));
}
@@ -320,9 +329,9 @@ class spell_sha_bloodlust : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID);
OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID);
OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID);
AfterHit += SpellHitFn(spell_sha_bloodlust_SpellScript::ApplyDebuff);
}
};
@@ -349,9 +358,9 @@ class spell_sha_heroism : public SpellScriptLoader
return true;
}
void RemoveInvalidTargets(std::list<Unit*>& targets)
void RemoveInvalidTargets(std::list<WorldObject*>& targets)
{
targets.remove_if (Trinity::UnitAuraCheck(true, SHAMAN_SPELL_EXHAUSTION));
targets.remove_if(Trinity::UnitAuraCheck(true, SHAMAN_SPELL_EXHAUSTION));
}
void ApplyDebuff()
@@ -362,9 +371,9 @@ class spell_sha_heroism : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID);
OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID);
OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID);
AfterHit += SpellHitFn(spell_sha_heroism_SpellScript::ApplyDebuff);
}
};
@@ -652,6 +661,94 @@ class spell_sha_chain_heal : public SpellScriptLoader
}
};
class spell_sha_flame_shock : public SpellScriptLoader
{
public:
spell_sha_flame_shock() : SpellScriptLoader("spell_sha_flame_shock") { }
class spell_sha_flame_shock_AuraScript : public AuraScript
{
PrepareAuraScript(spell_sha_flame_shock_AuraScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SHAMAN_LAVA_FLOWS_R1))
return false;
if (!sSpellMgr->GetSpellInfo(SHAMAN_LAVA_FLOWS_TRIGGERED_R1))
return false;
return true;
}
void HandleDispel(DispelInfo* /*dispelInfo*/)
{
if (Unit* caster = GetCaster())
// Lava Flows
if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, ICON_ID_SHAMAN_LAVA_FLOW, EFFECT_0))
{
if (sSpellMgr->GetFirstSpellInChain(SHAMAN_LAVA_FLOWS_R1) != sSpellMgr->GetFirstSpellInChain(aurEff->GetId()))
return;
uint8 rank = sSpellMgr->GetSpellRank(aurEff->GetId());
caster->CastSpell(caster, sSpellMgr->GetSpellWithRank(SHAMAN_LAVA_FLOWS_TRIGGERED_R1, rank), true);
}
}
void Register()
{
AfterDispel += AuraDispelFn(spell_sha_flame_shock_AuraScript::HandleDispel);
}
};
AuraScript* GetAuraScript() const
{
return new spell_sha_flame_shock_AuraScript();
}
};
class spell_sha_sentry_totem : public SpellScriptLoader
{
public:
spell_sha_sentry_totem() : SpellScriptLoader("spell_sha_sentry_totem") { }
class spell_sha_sentry_totem_AuraScript : public AuraScript
{
PrepareAuraScript(spell_sha_sentry_totem_AuraScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SHAMAN_BIND_SIGHT))
return false;
return true;
}
void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetCaster())
if (Creature* totem = caster->GetMap()->GetCreature(caster->m_SummonSlot[4]))
if (totem->isTotem())
caster->CastSpell(totem, SHAMAN_BIND_SIGHT, true);
}
void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetCaster())
if (caster->GetTypeId() == TYPEID_PLAYER)
caster->ToPlayer()->StopCastingBindSight();
}
void Register()
{
AfterEffectApply += AuraEffectApplyFn(spell_sha_sentry_totem_AuraScript::AfterApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
AfterEffectRemove += AuraEffectRemoveFn(spell_sha_sentry_totem_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const
{
return new spell_sha_sentry_totem_AuraScript();
}
};
void AddSC_shaman_spell_scripts()
{
new spell_sha_astral_shift();
@@ -667,4 +764,6 @@ void AddSC_shaman_spell_scripts()
new spell_sha_mana_spring_totem();
new spell_sha_lava_lash();
new spell_sha_chain_heal();
new spell_sha_flame_shock();
new spell_sha_sentry_totem();
}
+109 -3
View File
@@ -37,6 +37,9 @@ enum WarlockSpells
WARLOCK_DEMONIC_CIRCLE_SUMMON = 48018,
WARLOCK_DEMONIC_CIRCLE_TELEPORT = 48020,
WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST = 62388,
WARLOCK_HAUNT = 48181,
WARLOCK_HAUNT_HEAL = 48210,
WARLOCK_UNSTABLE_AFFLICTION_DISPEL = 31117,
};
class spell_warl_banish : public SpellScriptLoader
@@ -299,15 +302,15 @@ class spell_warl_seed_of_corruption : public SpellScriptLoader
{
PrepareSpellScript(spell_warl_seed_of_corruption_SpellScript);
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& targets)
{
if (GetExplTargetUnit())
unitList.remove(GetExplTargetUnit());
targets.remove(GetExplTargetUnit());
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_warl_seed_of_corruption_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warl_seed_of_corruption_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
@@ -523,6 +526,107 @@ class spell_warl_demonic_circle_teleport : public SpellScriptLoader
}
};
class spell_warl_haunt : public SpellScriptLoader
{
public:
spell_warl_haunt() : SpellScriptLoader("spell_warl_haunt") { }
class spell_warl_haunt_SpellScript : public SpellScript
{
PrepareSpellScript(spell_warl_haunt_SpellScript);
void HandleOnHit()
{
if (Aura* aura = GetHitAura())
if (AuraEffect* aurEff = aura->GetEffect(EFFECT_1))
aurEff->SetAmount(CalculatePctN(aurEff->GetAmount(), GetHitDamage()));
}
void Register()
{
OnHit += SpellHitFn(spell_warl_haunt_SpellScript::HandleOnHit);
}
};
class spell_warl_haunt_AuraScript : public AuraScript
{
PrepareAuraScript(spell_warl_haunt_AuraScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(WARLOCK_HAUNT_HEAL))
return false;
return true;
}
void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL && GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
return;
if (Unit* caster = GetCaster())
{
int32 amount = aurEff->GetAmount();
GetTarget()->CastCustomSpell(caster, WARLOCK_HAUNT_HEAL, &amount, NULL, NULL, true, NULL, aurEff, GetCasterGUID());
}
}
void Register()
{
OnEffectRemove += AuraEffectApplyFn(spell_warl_haunt_AuraScript::HandleRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
SpellScript* GetSpellScript() const
{
return new spell_warl_haunt_SpellScript();
}
AuraScript* GetAuraScript() const
{
return new spell_warl_haunt_AuraScript();
}
};
class spell_warl_unstable_affliction : public SpellScriptLoader
{
public:
spell_warl_unstable_affliction() : SpellScriptLoader("spell_warl_unstable_affliction") { }
class spell_warl_unstable_affliction_AuraScript : public AuraScript
{
PrepareAuraScript(spell_warl_unstable_affliction_AuraScript);
bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(WARLOCK_UNSTABLE_AFFLICTION_DISPEL))
return false;
return true;
}
void HandleDispel(DispelInfo* dispelInfo)
{
if (Unit* caster = GetCaster())
if (AuraEffect const* aurEff = GetEffect(EFFECT_0))
{
int32 damage = aurEff->GetAmount() * 9;
// backfire damage and silence
caster->CastCustomSpell(dispelInfo->GetDispeller(), WARLOCK_UNSTABLE_AFFLICTION_DISPEL, &damage, NULL, NULL, true, NULL, aurEff);
}
}
void Register()
{
AfterDispel += AuraDispelFn(spell_warl_unstable_affliction_AuraScript::HandleDispel);
}
};
AuraScript* GetAuraScript() const
{
return new spell_warl_unstable_affliction_AuraScript();
}
};
void AddSC_warlock_spell_scripts()
{
new spell_warl_banish();
@@ -535,4 +639,6 @@ void AddSC_warlock_spell_scripts()
new spell_warl_life_tap();
new spell_warl_demonic_circle_summon();
new spell_warl_demonic_circle_teleport();
new spell_warl_haunt();
new spell_warl_unstable_affliction();
}
+53 -6
View File
@@ -77,7 +77,7 @@ class spell_warr_improved_spell_reflection : public SpellScriptLoader
{
PrepareSpellScript(spell_warr_improved_spell_reflection_SpellScript);
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& unitList)
{
if (GetCaster())
unitList.remove(GetCaster());
@@ -85,7 +85,7 @@ class spell_warr_improved_spell_reflection : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_warr_improved_spell_reflection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_PARTY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warr_improved_spell_reflection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_PARTY);
}
};
@@ -184,9 +184,9 @@ class spell_warr_deep_wounds : public SpellScriptLoader
damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE);
ApplyPctN(damage, 16 * sSpellMgr->GetSpellRank(GetSpellInfo()->Id));
damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE);
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_DEEP_WOUNDS_RANK_PERIODIC);
uint32 ticks = spellInfo->GetDuration() / spellInfo->Effects[EFFECT_0].Amplitude;
@@ -397,7 +397,20 @@ class spell_warr_bloodthirst : public SpellScriptLoader
{
PrepareSpellScript(spell_warr_bloodthirst_SpellScript);
void HandleDummy(SpellEffIndex /* effIndex */)
void HandleDamage(SpellEffIndex /*effIndex*/)
{
int32 damage = GetEffectValue();
ApplyPctF(damage, GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK));
if (Unit* target = GetHitUnit())
{
damage = GetCaster()->SpellDamageBonusDone(target, GetSpellInfo(), uint32(damage), SPELL_DIRECT_DAMAGE);
damage = target->SpellDamageBonusTaken(GetCaster(), GetSpellInfo(), uint32(damage), SPELL_DIRECT_DAMAGE);
}
SetHitDamage(damage);
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
int32 damage = GetEffectValue();
GetCaster()->CastCustomSpell(GetCaster(), SPELL_BLOODTHIRST, &damage, NULL, NULL, true, NULL);
@@ -405,7 +418,8 @@ class spell_warr_bloodthirst : public SpellScriptLoader
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_warr_bloodthirst_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY);
OnEffectHitTarget += SpellEffectFn(spell_warr_bloodthirst_SpellScript::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
OnEffectHit += SpellEffectFn(spell_warr_bloodthirst_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY);
}
};
@@ -415,6 +429,38 @@ class spell_warr_bloodthirst : public SpellScriptLoader
}
};
enum BloodthirstHeal
{
SPELL_BLOODTHIRST_DAMAGE = 23881,
};
class spell_warr_bloodthirst_heal : public SpellScriptLoader
{
public:
spell_warr_bloodthirst_heal() : SpellScriptLoader("spell_warr_bloodthirst_heal") { }
class spell_warr_bloodthirst_heal_SpellScript : public SpellScript
{
PrepareSpellScript(spell_warr_bloodthirst_heal_SpellScript);
void HandleHeal(SpellEffIndex /*effIndex*/)
{
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_BLOODTHIRST_DAMAGE))
SetHitHeal(GetCaster()->CountPctFromMaxHealth(spellInfo->Effects[EFFECT_1].CalcValue(GetCaster())));
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_warr_bloodthirst_heal_SpellScript::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL);
}
};
SpellScript* GetSpellScript() const
{
return new spell_warr_bloodthirst_heal_SpellScript();
}
};
enum Overpower
{
SPELL_UNRELENTING_ASSAULT_RANK_1 = 46859,
@@ -471,5 +517,6 @@ void AddSC_warrior_spell_scripts()
new spell_warr_execute();
new spell_warr_concussion_blow();
new spell_warr_bloodthirst();
new spell_warr_bloodthirst_heal();
new spell_warr_overpower();
}
@@ -313,6 +313,27 @@ class achievement_tilted : public AchievementCriteriaScript
}
};
class achievement_not_even_a_scratch : public AchievementCriteriaScript
{
public:
achievement_not_even_a_scratch() : AchievementCriteriaScript("achievement_not_even_a_scratch") { }
bool OnCheck(Player* source, Unit* /*target*/)
{
if (!source)
return false;
Battleground* battleground = source->GetBattleground();
if (!battleground)
return false;
if (static_cast<BattlegroundSA*>(battleground)->notEvenAScratch(source->GetTeam()))
return true;
return false;
}
};
void AddSC_achievement_scripts()
{
new achievement_resilient_victory();
@@ -331,4 +352,5 @@ void AddSC_achievement_scripts()
new achievement_arena_kills("achievement_arena_5v5_kills", ARENA_TYPE_5v5);
new achievement_bg_sa_defense_of_ancients();
new achievement_tilted();
new achievement_not_even_a_scratch();
}
@@ -224,9 +224,9 @@ class DreamFogTargetSelector
public:
DreamFogTargetSelector() { }
bool operator()(Unit* unit)
bool operator()(WorldObject* object) const
{
return unit->HasAura(SPELL_SLEEP);
return object->ToUnit() && object->ToUnit()->HasAura(SPELL_SLEEP);
}
};
@@ -239,14 +239,14 @@ class spell_dream_fog_sleep : public SpellScriptLoader
{
PrepareSpellScript(spell_dream_fog_sleep_SpellScript);
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& unitList)
{
unitList.remove_if (DreamFogTargetSelector());
unitList.remove_if(DreamFogTargetSelector());
}
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_dream_fog_sleep_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dream_fog_sleep_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
@@ -265,10 +265,12 @@ class MarkOfNatureTargetSelector
public:
MarkOfNatureTargetSelector() { }
bool operator()(Unit* unit)
bool operator()(WorldObject* object) const
{
// return anyone that isn't tagged or already under the influence of Aura of Nature
return !(unit->HasAura(SPELL_MARK_OF_NATURE) && !unit->HasAura(SPELL_AURA_OF_NATURE));
if (Unit* unit = object->ToUnit())
// return anyone that isn't tagged or already under the influence of Aura of Nature
return !(unit->HasAura(SPELL_MARK_OF_NATURE) && !unit->HasAura(SPELL_AURA_OF_NATURE));
return true;
}
};
@@ -290,9 +292,9 @@ class spell_mark_of_nature : public SpellScriptLoader
return true;
}
void FilterTargets(std::list<Unit*>& unitList)
void FilterTargets(std::list<WorldObject*>& targets)
{
unitList.remove_if (MarkOfNatureTargetSelector());
targets.remove_if(MarkOfNatureTargetSelector());
}
void HandleEffect(SpellEffIndex effIndex)
@@ -305,7 +307,7 @@ class spell_mark_of_nature : public SpellScriptLoader
void Register()
{
OnUnitTargetSelect += SpellUnitTargetFn(spell_mark_of_nature_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mark_of_nature_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_mark_of_nature_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
}
};
+54
View File
@@ -1245,6 +1245,58 @@ class go_veil_skith_cage : public GameObjectScript
}
};
/*######
## go_frostblade_shrine
######*/
enum TheCleansing
{
QUEST_THE_CLEANSING_HORDE = 11317,
QUEST_THE_CLEANSING_ALLIANCE = 11322,
SPELL_CLEANSING_SOUL = 43351,
SPELL_RECENT_MEDITATION = 61720,
};
class go_frostblade_shrine : public GameObjectScript
{
public:
go_frostblade_shrine() : GameObjectScript("go_frostblade_shrine") { }
bool OnGossipHello(Player* player, GameObject* go)
{
if (!player->HasAura(SPELL_RECENT_MEDITATION))
if (player->GetQuestStatus(QUEST_THE_CLEANSING_HORDE) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(QUEST_THE_CLEANSING_ALLIANCE) == QUEST_STATUS_INCOMPLETE)
{
go->UseDoorOrButton(10);
player->CastSpell(player, SPELL_CLEANSING_SOUL);
player->SetStandState(UNIT_STAND_STATE_SIT);
}
return true;
}
};
/*######
## go_midsummer_bonfire
######*/
enum eMidsummerBonfire
{
STAMP_OUT_BONFIRE_QUEST_COMPLETE = 45458,
};
class go_midsummer_bonfire : public GameObjectScript
{
public:
go_midsummer_bonfire() : GameObjectScript("go_midsummer_bonfire") { }
bool OnGossipSelect(Player* player, GameObject* /*go*/, uint32 /*sender*/, uint32 /*action*/)
{
player->CastSpell(player, STAMP_OUT_BONFIRE_QUEST_COMPLETE, true);
player->CLOSE_GOSSIP_MENU();
return false;
}
};
void AddSC_go_scripts()
{
new go_cat_figurine;
@@ -1285,4 +1337,6 @@ void AddSC_go_scripts()
new go_gjalerbron_cage;
new go_large_gjalerbron_cage;
new go_veil_skith_cage;
new go_frostblade_shrine;
new go_midsummer_bonfire;
}
+33 -4
View File
@@ -47,6 +47,7 @@ EndContentData */
#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "World.h"
#include "PetAI.h"
/*########
# npc_air_force_bots
@@ -2100,16 +2101,18 @@ class npc_shadowfiend : public CreatureScript
public:
npc_shadowfiend() : CreatureScript("npc_shadowfiend") { }
struct npc_shadowfiendAI : public ScriptedAI
struct npc_shadowfiendAI : public PetAI
{
npc_shadowfiendAI(Creature* creature) : ScriptedAI(creature) {}
npc_shadowfiendAI(Creature* creature) : PetAI(creature) {}
void DamageTaken(Unit* /*killer*/, uint32& damage)
void JustDied(Unit* killer)
{
if (me->isSummon())
if (Unit* owner = me->ToTempSummon()->GetSummoner())
if (owner->HasAura(GLYPH_OF_SHADOWFIEND) && damage >= me->GetHealth())
if (owner->HasAura(GLYPH_OF_SHADOWFIEND))
owner->CastSpell(owner, GLYPH_OF_SHADOWFIEND_MANA, true);
PetAI::JustDied(killer);
}
};
@@ -2988,6 +2991,31 @@ public:
};
};
/*######
## npc_generic_harpoon_cannon
######*/
class npc_generic_harpoon_cannon : public CreatureScript
{
public:
npc_generic_harpoon_cannon() : CreatureScript("npc_generic_harpoon_cannon") { }
struct npc_generic_harpoon_cannonAI : public ScriptedAI
{
npc_generic_harpoon_cannonAI(Creature* creature) : ScriptedAI(creature) {}
void Reset()
{
me->SetUnitMovementFlags(MOVEMENTFLAG_ROOT);
}
};
CreatureAI* GetAI(Creature* creature) const
{
return new npc_generic_harpoon_cannonAI(creature);
}
};
void AddSC_npcs_special()
{
new npc_air_force_bots();
@@ -3020,4 +3048,5 @@ void AddSC_npcs_special()
new npc_earth_elemental();
new npc_firework();
new npc_spring_rabbit();
new npc_generic_harpoon_cannon();
}