aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNay <dnpd.dd@gmail.com>2012-12-27 17:53:34 +0000
committerNay <dnpd.dd@gmail.com>2012-12-27 17:53:34 +0000
commit7e196e8e58800c3e0cde80a07f20c4ecccd1a842 (patch)
treed77aa80f8e6bd417eb2d8b368006fd3d7fc8fa19 /src
parent79b1895223bbf16bfd6484e34e067beea457e4cc (diff)
parent7fe2d7309ae3b850f3a7c75fc9bb6ec18bea00a1 (diff)
Merge remote-tracking branch 'origin/master' into mmaps
Diffstat (limited to 'src')
-rw-r--r--src/server/collision/PrecompiledHeaders/collisionPCH.h3
-rw-r--r--src/server/game/Battlegrounds/Battleground.cpp6
-rw-r--r--src/server/game/Battlegrounds/Battleground.h2
-rw-r--r--src/server/game/DataStores/DBCEnums.h18
-rw-r--r--src/server/game/Entities/Object/Object.cpp14
-rw-r--r--src/server/game/Entities/Player/Player.cpp62
-rw-r--r--src/server/game/Entities/Player/Player.h9
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp22
-rw-r--r--src/server/game/Entities/Unit/Unit.h2
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp24
-rw-r--r--src/server/game/Globals/ObjectMgr.h5
-rw-r--r--src/server/game/Handlers/ChatHandler.cpp51
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp12
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h7
-rw-r--r--src/server/game/Quests/QuestDef.cpp25
-rw-r--r--src/server/game/Quests/QuestDef.h7
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h2
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp3
-rw-r--r--src/server/game/Spells/Spell.cpp5
-rw-r--r--src/server/game/Spells/SpellEffects.cpp1
-rw-r--r--src/server/game/Spells/SpellInfo.cpp2
-rw-r--r--src/server/game/Spells/SpellMgr.cpp64
-rw-r--r--src/server/game/Texts/CreatureTextMgr.cpp4
-rw-r--r--src/server/game/World/World.cpp1
-rw-r--r--src/server/scripts/Commands/cs_reload.cpp22
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp4
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp6
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp2
-rw-r--r--src/server/scripts/Northrend/dragonblight.cpp93
-rw-r--r--src/server/scripts/Outland/TempestKeep/botanica/boss_high_botanist_freywinn.cpp4
-rw-r--r--src/server/scripts/Spells/spell_quest.cpp32
32 files changed, 293 insertions, 223 deletions
diff --git a/src/server/collision/PrecompiledHeaders/collisionPCH.h b/src/server/collision/PrecompiledHeaders/collisionPCH.h
index 636eaa1bef8..ece2ef1b8ef 100644
--- a/src/server/collision/PrecompiledHeaders/collisionPCH.h
+++ b/src/server/collision/PrecompiledHeaders/collisionPCH.h
@@ -4,3 +4,6 @@
#include "WorldModel.h"
#include "ModelInstance.h"
#include "BoundingIntervalHierarchy.h"
+#include "RegularGrid.h"
+#include "BoundingIntervalHierarchyWrapper.h"
+#include "GameObjectModel.h"
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index 22f960ceaef..1c426be3b4e 100644
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -1183,10 +1183,6 @@ void Battleground::AddPlayer(Player* player)
player->CastSpell(player, SPELL_ARENA_PREPARATION, true);
player->ResetAllPowers();
}
-
- WorldPacket data(SMSG_ARENA_OPPONENT_UPDATE, 8);
- data << uint64(player->GetGUID());
- SendPacketToTeam(team, &data, player, false);
}
else
{
@@ -1884,7 +1880,7 @@ int32 Battleground::GetObjectType(uint64 guid)
return -1;
}
-void Battleground::HandleKillUnit(Creature* /*creature*/, Player* /*killer*/)
+void Battleground::HandleKillUnit(Creature* /*victim*/, Player* /*killer*/)
{
}
diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
index 0a837f9f3c3..b58f321fe55 100644
--- a/src/server/game/Battlegrounds/Battleground.h
+++ b/src/server/game/Battlegrounds/Battleground.h
@@ -108,7 +108,7 @@ enum BattlegroundTimeIntervals
RESURRECTION_INTERVAL = 30000, // ms
//REMIND_INTERVAL = 10000, // ms
INVITATION_REMIND_TIME = 20000, // ms
- INVITE_ACCEPT_WAIT_TIME = 40000, // ms
+ INVITE_ACCEPT_WAIT_TIME = 60000, // ms
TIME_TO_AUTOREMOVE = 120000, // ms
MAX_OFFLINE_TIME = 300, // secs
RESPAWN_ONE_DAY = 86400, // secs
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index fa6b5f0695f..cdc1c790844 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -365,24 +365,6 @@ enum SummonPropGroup
SUMMON_PROP_GROUP_UNKNOWN3 = 4 // 86 spells in 3.0.3, taxi/mounts
};
-// SummonProperties.dbc, col 3
-enum SummonPropType
-{
- SUMMON_PROP_TYPE_UNKNOWN = 0, // different summons, 1330 spells in 3.0.3
- SUMMON_PROP_TYPE_SUMMON = 1, // generic summons, 49 spells in 3.0.3
- SUMMON_PROP_TYPE_GUARDIAN = 2, // summon guardian, 393 spells in 3.0.3
- SUMMON_PROP_TYPE_ARMY = 3, // summon army, 5 spells in 3.0.3
- SUMMON_PROP_TYPE_TOTEM = 4, // summon totem, 169 spells in 3.0.3
- SUMMON_PROP_TYPE_CRITTER = 5, // critter/minipet, 195 spells in 3.0.3
- SUMMON_PROP_TYPE_DK = 6, // summon DRW/Ghoul, 2 spells in 3.0.3
- SUMMON_PROP_TYPE_BOMB = 7, // summon bot/bomb, 4 spells in 3.0.3
- SUMMON_PROP_TYPE_PHASING = 8, // something todo with DK prequest line, 2 spells in 3.0.3
- SUMMON_PROP_TYPE_SIEGE_VEH = 9, // summon different vehicles, 14 spells in 3.0.3
- SUMMON_PROP_TYPE_DRAKE_VEH = 10, // summon drake (vehicle), 3 spells
- SUMMON_PROP_TYPE_LIGHTWELL = 11, // summon lightwell, 6 spells in 3.0.3
- SUMMON_PROP_TYPE_JEEVES = 12 // summon Jeeves, 1 spell in 3.3.5a
-};
-
// SummonProperties.dbc, col 5
enum SummonPropFlags
{
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 6f16618491e..5c6f287b726 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -302,6 +302,19 @@ void Object::DestroyForPlayer(Player* target, bool onDeath) const
{
ASSERT(target);
+ if (isType(TYPEMASK_UNIT) || isType(TYPEMASK_PLAYER))
+ {
+ if (Battleground* bg = target->GetBattleground())
+ {
+ if (bg->isArena())
+ {
+ WorldPacket data(SMSG_ARENA_UNIT_DESTROYED, 8);
+ data << uint64(GetGUID());
+ target->GetSession()->SendPacket(&data);
+ }
+ }
+ }
+
WorldPacket data(SMSG_DESTROY_OBJECT, 8 + 1);
data << uint64(GetGUID());
//! If the following bool is true, the client will call "void CGUnit_C::OnDeath()" for this object.
@@ -2254,6 +2267,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
mask = UNIT_MASK_GUARDIAN;
break;
case SUMMON_TYPE_TOTEM:
+ case SUMMON_TYPE_LIGHTWELL:
mask = UNIT_MASK_TOTEM;
break;
case SUMMON_TYPE_VEHICLE:
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index bca94517ef4..3607e8a9ec3 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -2031,24 +2031,18 @@ bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data)
return true;
}
-bool Player::ToggleAFK()
+void Player::ToggleAFK()
{
ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK);
- bool state = HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK);
-
// afk player not allowed in battleground
- if (state && InBattleground() && !InArena())
+ if (isAFK() && InBattleground() && !InArena())
LeaveBattleground();
-
- return state;
}
-bool Player::ToggleDND()
+void Player::ToggleDND()
{
ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_DND);
-
- return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_DND);
}
uint8 Player::GetChatTag() const
@@ -15232,7 +15226,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
_SaveQuestStatus(trans);
if (announce)
- SendQuestReward(quest, XP, questGiver);
+ SendQuestReward(quest, XP);
// cast spells after mark quest complete (some spells have quest completed state requirements in spell_area data)
if (quest->GetRewSpellCast() > 0)
@@ -16042,7 +16036,7 @@ void Player::KilledMonsterCredit(uint32 entry, uint64 guid)
continue;
// just if !ingroup || !noraidgroup || raidgroup
QuestStatusData& q_status = m_QuestStatus[questid];
- if (q_status.Status == QUEST_STATUS_INCOMPLETE && (!GetGroup() || !GetGroup()->isRaidGroup() || qInfo->IsAllowedInRaid()))
+ if (q_status.Status == QUEST_STATUS_INCOMPLETE && (!GetGroup() || !GetGroup()->isRaidGroup() || qInfo->IsAllowedInRaid(GetMap()->GetDifficulty())))
{
if (qInfo->HasFlag(QUEST_TRINITY_FLAGS_KILL_OR_CAST))
{
@@ -16097,7 +16091,7 @@ void Player::KilledPlayerCredit()
continue;
// just if !ingroup || !noraidgroup || raidgroup
QuestStatusData& q_status = m_QuestStatus[questid];
- if (q_status.Status == QUEST_STATUS_INCOMPLETE && (!GetGroup() || !GetGroup()->isRaidGroup() || qInfo->IsAllowedInRaid()))
+ if (q_status.Status == QUEST_STATUS_INCOMPLETE && (!GetGroup() || !GetGroup()->isRaidGroup() || qInfo->IsAllowedInRaid(GetMap()->GetDifficulty())))
{
if (qInfo->HasFlag(QUEST_TRINITY_FLAGS_PLAYER_KILL))
{
@@ -16365,7 +16359,7 @@ bool Player::HasQuestForItem(uint32 itemid) const
continue;
// hide quest if player is in raid-group and quest is no raid quest
- if (GetGroup() && GetGroup()->isRaidGroup() && !qinfo->IsAllowedInRaid())
+ if (GetGroup() && GetGroup()->isRaidGroup() && !qinfo->IsAllowedInRaid(GetMap()->GetDifficulty()))
if (!InBattleground()) //there are two ways.. we can make every bg-quest a raidquest, or add this code here.. i don't know if this can be exploited by other quests, but i think all other quests depend on a specific area.. but keep this in mind, if something strange happens later
continue;
@@ -16413,7 +16407,7 @@ void Player::SendQuestComplete(uint32 quest_id)
}
}
-void Player::SendQuestReward(Quest const* quest, uint32 XP, Object* questGiver)
+void Player::SendQuestReward(Quest const* quest, uint32 XP)
{
uint32 questid = quest->GetQuestId();
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = %u", questid);
@@ -16436,9 +16430,6 @@ void Player::SendQuestReward(Quest const* quest, uint32 XP, Object* questGiver)
data << uint32(quest->GetBonusTalents()); // bonus talents
data << uint32(quest->GetRewArenaPoints());
GetSession()->SendPacket(&data);
-
- if (quest->GetQuestCompleteScript() != 0)
- GetMap()->ScriptsStart(sQuestEndScripts, quest->GetQuestCompleteScript(), questGiver, this);
}
void Player::SendQuestFailed(uint32 questId, InventoryResult reason)
@@ -20089,42 +20080,29 @@ void Player::Whisper(const std::string& text, uint32 language, uint64 receiver)
std::string _text(text);
sScriptMgr->OnPlayerChat(this, CHAT_MSG_WHISPER, language, _text, rPlayer);
- // when player you are whispering to is dnd, he cannot receive your message, unless you are in gm mode
- if (!rPlayer->isDND() || isGameMaster())
- {
- WorldPacket data(SMSG_MESSAGECHAT, 200);
- BuildPlayerChat(&data, CHAT_MSG_WHISPER, _text, language);
- rPlayer->GetSession()->SendPacket(&data);
-
- // not send confirmation for addon messages
- if (!isAddonMessage)
- {
- data.Initialize(SMSG_MESSAGECHAT, 200);
- rPlayer->BuildPlayerChat(&data, CHAT_MSG_WHISPER_INFORM, _text, language);
- GetSession()->SendPacket(&data);
- }
- }
- else if (!isAddonMessage)
- // announce to player that player he is whispering to is dnd and cannot receive his message
- ChatHandler(GetSession()).PSendSysMessage(LANG_PLAYER_DND, rPlayer->GetName().c_str(), rPlayer->dndMsg.c_str());
+ WorldPacket data(SMSG_MESSAGECHAT, 200);
+ BuildPlayerChat(&data, CHAT_MSG_WHISPER, _text, language);
+ rPlayer->GetSession()->SendPacket(&data);
// rest stuff shouldn't happen in case of addon message
if (isAddonMessage)
return;
+ data.Initialize(SMSG_MESSAGECHAT, 200);
+ rPlayer->BuildPlayerChat(&data, CHAT_MSG_WHISPER_INFORM, _text, language);
+ GetSession()->SendPacket(&data);
+
if (!isAcceptWhispers() && !isGameMaster() && !rPlayer->isGameMaster())
{
SetAcceptWhispers(true);
ChatHandler(GetSession()).SendSysMessage(LANG_COMMAND_WHISPERON);
}
- // announce to player that player he is whispering to is afk
+ // announce afk or dnd message
if (rPlayer->isAFK())
- ChatHandler(GetSession()).PSendSysMessage(LANG_PLAYER_AFK, rPlayer->GetName().c_str(), rPlayer->afkMsg.c_str());
-
- // if player whisper someone, auto turn of dnd to be able to receive an answer
- if (isDND() && !rPlayer->isGameMaster())
- ToggleDND();
+ ChatHandler(GetSession()).PSendSysMessage(LANG_PLAYER_AFK, rPlayer->GetName().c_str(), rPlayer->autoReplyMsg.c_str());
+ else if (rPlayer->isDND())
+ ChatHandler(GetSession()).PSendSysMessage(LANG_PLAYER_DND, rPlayer->GetName().c_str(), rPlayer->autoReplyMsg.c_str());
}
void Player::PetSpellInitialize()
@@ -22786,7 +22764,7 @@ bool Player::HasQuestForGO(int32 GOId) const
if (!qinfo)
continue;
- if (GetGroup() && GetGroup()->isRaidGroup() && !qinfo->IsAllowedInRaid())
+ if (GetGroup() && GetGroup()->isRaidGroup() && !qinfo->IsAllowedInRaid(GetMap()->GetDifficulty()))
continue;
for (uint8 j = 0; j < QUEST_OBJECTIVES_COUNT; ++j)
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 1e8b6aedb3e..522fe529b41 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1108,13 +1108,12 @@ class Player : public Unit, public GridObject<Player>
Creature* GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask);
GameObject* GetGameObjectIfCanInteractWith(uint64 guid, GameobjectTypes type) const;
- bool ToggleAFK();
- bool ToggleDND();
+ void ToggleAFK();
+ void ToggleDND();
bool isAFK() const { return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK); }
bool isDND() const { return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_DND); }
uint8 GetChatTag() const;
- std::string afkMsg;
- std::string dndMsg;
+ std::string autoReplyMsg;
uint32 GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair, BarberShopStyleEntry const* newSkin=NULL);
@@ -1480,7 +1479,7 @@ class Player : public Unit, public GridObject<Player>
bool CanShareQuest(uint32 quest_id) const;
void SendQuestComplete(uint32 quest_id);
- void SendQuestReward(Quest const* quest, uint32 XP, Object* questGiver);
+ void SendQuestReward(Quest const* quest, uint32 XP);
void SendQuestFailed(uint32 questId, InventoryResult reason = EQUIP_ERR_OK);
void SendQuestTimerFailed(uint32 quest_id);
void SendCanTakeQuestResponse(uint32 msg) const;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index dee977de054..4148e3177fe 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -17064,7 +17064,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
}
if (IsInMap(caster))
- caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId+1, target, GetVehicleKit() ? TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE : TRIGGERED_NONE, NULL, NULL, origCasterGUID);
+ caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId, target, GetVehicleKit() ? TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE : TRIGGERED_NONE, NULL, NULL, origCasterGUID);
else // This can happen during Player::_LoadAuras
{
int32 bp0 = seatId;
@@ -17094,7 +17094,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
void Unit::EnterVehicle(Unit* base, int8 seatId)
{
- CastCustomSpell(VEHICLE_SPELL_RIDE_HARDCODED, SPELLVALUE_BASE_POINT0, seatId+1, base, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE);
+ CastCustomSpell(VEHICLE_SPELL_RIDE_HARDCODED, SPELLVALUE_BASE_POINT0, seatId, base, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE);
}
void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* aurApp)
@@ -17324,23 +17324,27 @@ void Unit::NearTeleportTo(float x, float y, float z, float orientation, bool cas
ToPlayer()->TeleportTo(GetMapId(), x, y, z, orientation, TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (casting ? TELE_TO_SPELL : 0));
else
{
- UpdatePosition(x, y, z, orientation, true);
- Position pos; // dummy, not used for creatures.
+ Position pos = {x, y, z, orientation};
SendTeleportPacket(pos);
+ UpdatePosition(x, y, z, orientation, true);
UpdateObjectVisibility();
}
}
-void Unit::SendTeleportPacket(Position& oldPos)
+void Unit::SendTeleportPacket(Position& pos)
{
+ Position oldPos = { GetPositionX(), GetPositionY(), GetPositionZMinusOffset(), GetOrientation() };
+ if (GetTypeId() == TYPEID_UNIT)
+ Relocate(&pos);
+
WorldPacket data2(MSG_MOVE_TELEPORT, 38);
data2.append(GetPackGUID());
BuildMovementPacket(&data2);
-
- if (GetTypeId() == TYPEID_PLAYER)
+ if (GetTypeId() == TYPEID_UNIT)
Relocate(&oldPos);
-
- SendMessageToSet(&data2, false);
+ if (GetTypeId() == TYPEID_PLAYER)
+ Relocate(&pos);
+ SendMessageToSet(&data2, true);
}
bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool teleport)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 5dbf800dc31..c79cbca469f 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1593,7 +1593,7 @@ class Unit : public WorldObject
void SendSpellDamageImmune(Unit* target, uint32 spellId);
void NearTeleportTo(float x, float y, float z, float orientation, bool casting = false);
- void SendTeleportPacket(Position& oldPos);
+ void SendTeleportPacket(Position& pos);
virtual bool UpdatePosition(float x, float y, float z, float ang, bool teleport = false);
// returns true if unit's position really changed
bool UpdatePosition(const Position &pos, bool teleport = false) { return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); }
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 70ac4aec4aa..be365202cdc 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -49,7 +49,6 @@
#include "WaypointManager.h"
#include "World.h"
-ScriptMapMap sQuestEndScripts;
ScriptMapMap sSpellScripts;
ScriptMapMap sGameObjectScripts;
ScriptMapMap sEventScripts;
@@ -60,7 +59,6 @@ std::string GetScriptsTableNameByType(ScriptsType type)
std::string res = "";
switch (type)
{
- case SCRIPTS_QUEST_END: res = "quest_end_scripts"; break;
case SCRIPTS_SPELL: res = "spell_scripts"; break;
case SCRIPTS_GAMEOBJECT: res = "gameobject_scripts"; break;
case SCRIPTS_EVENT: res = "event_scripts"; break;
@@ -75,7 +73,6 @@ ScriptMapMap* GetScriptsMapByType(ScriptsType type)
ScriptMapMap* res = NULL;
switch (type)
{
- case SCRIPTS_QUEST_END: res = &sQuestEndScripts; break;
case SCRIPTS_SPELL: res = &sSpellScripts; break;
case SCRIPTS_GAMEOBJECT: res = &sGameObjectScripts; break;
case SCRIPTS_EVENT: res = &sEventScripts; break;
@@ -3658,13 +3655,12 @@ void ObjectMgr::LoadQuests()
"DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4, DetailsEmoteDelay1, DetailsEmoteDelay2, DetailsEmoteDelay3, DetailsEmoteDelay4, EmoteOnIncomplete, EmoteOnComplete, "
// 136 137 138 139 140 141 142 143
"OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4, OfferRewardEmoteDelay1, OfferRewardEmoteDelay2, OfferRewardEmoteDelay3, OfferRewardEmoteDelay4, "
- // 144 145
- "CompleteScript, WDBVerified"
+ // 144
+ "WDBVerified"
" FROM quest_template");
if (!result)
{
sLog->outError(LOG_FILTER_SQL, ">> Loaded 0 quests definitions. DB table `quest_template` is empty.");
-
return;
}
@@ -4310,7 +4306,7 @@ void ObjectMgr::LoadQuestLocales()
_questLocaleStore.clear(); // need for reload case
- QueryResult result = WorldDatabase.Query("SELECT entry, "
+ QueryResult result = WorldDatabase.Query("SELECT Id, "
"Title_loc1, Details_loc1, Objectives_loc1, OfferRewardText_loc1, RequestItemsText_loc1, EndText_loc1, CompletedText_loc1, ObjectiveText1_loc1, ObjectiveText2_loc1, ObjectiveText3_loc1, ObjectiveText4_loc1, "
"Title_loc2, Details_loc2, Objectives_loc2, OfferRewardText_loc2, RequestItemsText_loc2, EndText_loc2, CompletedText_loc2, ObjectiveText1_loc2, ObjectiveText2_loc2, ObjectiveText3_loc2, ObjectiveText4_loc2, "
"Title_loc3, Details_loc3, Objectives_loc3, OfferRewardText_loc3, RequestItemsText_loc3, EndText_loc3, CompletedText_loc3, ObjectiveText1_loc3, ObjectiveText2_loc3, ObjectiveText3_loc3, ObjectiveText4_loc3, "
@@ -4683,18 +4679,6 @@ void ObjectMgr::LoadGameObjectScripts()
}
}
-void ObjectMgr::LoadQuestEndScripts()
-{
- LoadScripts(SCRIPTS_QUEST_END);
-
- // check ids
- for (ScriptMapMap::const_iterator itr = sQuestEndScripts.begin(); itr != sQuestEndScripts.end(); ++itr)
- {
- if (!GetQuestTemplate(itr->first))
- sLog->outError(LOG_FILTER_SQL, "Table `quest_end_scripts` has not existing quest (Id: %u) as script id", itr->first);
- }
-}
-
void ObjectMgr::LoadSpellScripts()
{
LoadScripts(SCRIPTS_SPELL);
@@ -5177,7 +5161,7 @@ void ObjectMgr::LoadNpcTextLocales()
_npcTextLocaleStore.clear(); // need for reload case
- QueryResult result = WorldDatabase.Query("SELECT entry, "
+ QueryResult result = WorldDatabase.Query("SELECT ID, "
"Text0_0_loc1, Text0_1_loc1, Text1_0_loc1, Text1_1_loc1, Text2_0_loc1, Text2_1_loc1, Text3_0_loc1, Text3_1_loc1, Text4_0_loc1, Text4_1_loc1, Text5_0_loc1, Text5_1_loc1, Text6_0_loc1, Text6_1_loc1, Text7_0_loc1, Text7_1_loc1, "
"Text0_0_loc2, Text0_1_loc2, Text1_0_loc2, Text1_1_loc2, Text2_0_loc2, Text2_1_loc2, Text3_0_loc2, Text3_1_loc1, Text4_0_loc2, Text4_1_loc2, Text5_0_loc2, Text5_1_loc2, Text6_0_loc2, Text6_1_loc2, Text7_0_loc2, Text7_1_loc2, "
"Text0_0_loc3, Text0_1_loc3, Text1_0_loc3, Text1_1_loc3, Text2_0_loc3, Text2_1_loc3, Text3_0_loc3, Text3_1_loc1, Text4_0_loc3, Text4_1_loc3, Text5_0_loc3, Text5_1_loc3, Text6_0_loc3, Text6_1_loc3, Text7_0_loc3, Text7_1_loc3, "
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index e1df03b97b0..84597d37722 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -127,8 +127,7 @@ enum ScriptsType
{
SCRIPTS_FIRST = 1,
- SCRIPTS_QUEST_END = SCRIPTS_FIRST,
- SCRIPTS_SPELL,
+ SCRIPTS_SPELL = SCRIPTS_FIRST,
SCRIPTS_GAMEOBJECT,
SCRIPTS_EVENT,
SCRIPTS_WAYPOINT,
@@ -361,7 +360,6 @@ typedef std::multimap<uint32, ScriptInfo> ScriptMap;
typedef std::map<uint32, ScriptMap > ScriptMapMap;
typedef std::multimap<uint32, uint32> SpellScriptsContainer;
typedef std::pair<SpellScriptsContainer::iterator, SpellScriptsContainer::iterator> SpellScriptsBounds;
-extern ScriptMapMap sQuestEndScripts;
extern ScriptMapMap sSpellScripts;
extern ScriptMapMap sGameObjectScripts;
extern ScriptMapMap sEventScripts;
@@ -864,7 +862,6 @@ class ObjectMgr
}
void LoadGameObjectScripts();
- void LoadQuestEndScripts();
void LoadEventScripts();
void LoadSpellScripts();
void LoadWaypointScripts();
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index e4989816998..560cc904974 100644
--- a/src/server/game/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
@@ -440,40 +440,51 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
} break;
case CHAT_MSG_AFK:
{
- if ((msg.empty() || !_player->isAFK()) && !_player->isInCombat())
+ if (!_player->isInCombat())
{
- if (!_player->isAFK())
+ if (_player->isAFK()) // Already AFK
{
if (msg.empty())
- msg = GetTrinityString(LANG_PLAYER_AFK_DEFAULT);
- _player->afkMsg = msg;
+ _player->ToggleAFK(); // Remove AFK
+ else
+ _player->autoReplyMsg = msg; // Update message
}
+ else // New AFK mode
+ {
+ _player->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_AFK_DEFAULT) : msg;
- sScriptMgr->OnPlayerChat(_player, type, lang, msg);
+ if (_player->isDND())
+ _player->ToggleDND();
+
+ _player->ToggleAFK();
+ }
- _player->ToggleAFK();
- if (_player->isAFK() && _player->isDND())
- _player->ToggleDND();
+ sScriptMgr->OnPlayerChat(_player, type, lang, msg);
}
- } break;
+ break;
+ }
case CHAT_MSG_DND:
{
- if (msg.empty() || !_player->isDND())
+ if (_player->isDND()) // Already DND
{
- if (!_player->isDND())
- {
- if (msg.empty())
- msg = GetTrinityString(LANG_PLAYER_DND_DEFAULT);
- _player->dndMsg = msg;
- }
+ if (msg.empty())
+ _player->ToggleDND(); // Remove DND
+ else
+ _player->autoReplyMsg = msg; // Update message
+ }
+ else // New DND mode
+ {
+ _player->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : msg;
- sScriptMgr->OnPlayerChat(_player, type, lang, msg);
+ if (_player->isAFK())
+ _player->ToggleAFK();
_player->ToggleDND();
- if (_player->isDND() && _player->isAFK())
- _player->ToggleAFK();
}
- } break;
+
+ sScriptMgr->OnPlayerChat(_player, type, lang, msg);
+ break;
+ }
default:
sLog->outError(LOG_FILTER_NETWORKIO, "CHAT: unknown message type %u, lang: %u", type, lang);
break;
diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp
index 8b230ae05c9..8181bdd6b6e 100644
--- a/src/server/game/Handlers/QuestHandler.cpp
+++ b/src/server/game/Handlers/QuestHandler.cpp
@@ -461,16 +461,8 @@ void WorldSession::HandleQuestConfirmAccept(WorldPacket& recvData)
if (!pOriginalPlayer)
return;
- if (quest->IsRaidQuest())
- {
- if (!_player->IsInSameRaidWith(pOriginalPlayer))
- return;
- }
- else
- {
- if (!_player->IsInSameGroupWith(pOriginalPlayer))
- return;
- }
+ if (!_player->IsInSameRaidWith(pOriginalPlayer))
+ return;
if (_player->CanAddQuest(quest, true))
_player->AddQuest(quest, NULL); // NULL, this prevent DB script from duplicate running
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index 283025c7e0d..6a38fe4e63b 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -3147,10 +3147,11 @@ enum SummonType
SUMMON_TYPE_MINIPET = 5,
SUMMON_TYPE_GUARDIAN2 = 6,
SUMMON_TYPE_WILD2 = 7,
- SUMMON_TYPE_WILD3 = 8,
+ SUMMON_TYPE_WILD3 = 8, // Related to phases and DK prequest line (3.3.5a)
SUMMON_TYPE_VEHICLE = 9,
- SUMMON_TYPE_VEHICLE2 = 10,
- SUMMON_TYPE_OBJECT = 11
+ SUMMON_TYPE_VEHICLE2 = 10, // Oculus and Argent Tournament vehicles (3.3.5a)
+ SUMMON_TYPE_LIGHTWELL = 11,
+ SUMMON_TYPE_JEEVES = 12
};
enum EventId
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index 1238afe2ee1..9e9bcffd871 100644
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -140,9 +140,7 @@ Quest::Quest(Field* questRecord)
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
OfferRewardEmoteDelay[i] = questRecord[140+i].GetInt32();
- CompleteScript = questRecord[144].GetUInt32();
-
- // int32 WDBVerified = questRecord[145].GetInt32();
+ //int32 WDBVerified = questRecord[144].GetInt32();
Flags |= SpecialFlags << 20;
if (Flags & QUEST_TRINITY_FLAGS_AUTO_ACCEPT)
@@ -219,9 +217,26 @@ bool Quest::IsAutoComplete() const
return sWorld->getBoolConfig(CONFIG_QUEST_IGNORE_AUTO_COMPLETE) ? false : (Method == 0 || HasFlag(QUEST_FLAGS_AUTOCOMPLETE));
}
-bool Quest::IsAllowedInRaid() const
+bool Quest::IsRaidQuest(Difficulty difficulty) const
+{
+ switch (Type)
+ {
+ case QUEST_TYPE_RAID:
+ return true;
+ case QUEST_TYPE_RAID_10:
+ return !(difficulty & RAID_DIFFICULTY_MASK_25MAN);
+ case QUEST_TYPE_RAID_25:
+ return difficulty & RAID_DIFFICULTY_MASK_25MAN;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool Quest::IsAllowedInRaid(Difficulty difficulty) const
{
- if (IsRaidQuest())
+ if (IsRaidQuest(difficulty))
return true;
return sWorld->getBoolConfig(CONFIG_QUEST_IGNORE_RAID);
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index 61b3de5f327..d02e4c511b1 100644
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -22,6 +22,7 @@
#include "Define.h"
#include "DatabaseEnv.h"
#include "SharedDefines.h"
+#include "DBCEnums.h"
#include <string>
#include <vector>
@@ -244,7 +245,6 @@ class Quest
uint32 GetPointOpt() const { return PointOption; }
uint32 GetIncompleteEmote() const { return EmoteOnIncomplete; }
uint32 GetCompleteEmote() const { return EmoteOnComplete; }
- uint32 GetQuestCompleteScript() const { return CompleteScript; }
bool IsRepeatable() const { return Flags & QUEST_TRINITY_FLAGS_REPEATABLE; }
bool IsAutoAccept() const;
bool IsAutoComplete() const;
@@ -254,8 +254,8 @@ class Quest
bool IsMonthly() const { return Flags & QUEST_TRINITY_FLAGS_MONTHLY; }
bool IsSeasonal() const { return (ZoneOrSort == -QUEST_SORT_SEASONAL || ZoneOrSort == -QUEST_SORT_SPECIAL || ZoneOrSort == -QUEST_SORT_LUNAR_FESTIVAL || ZoneOrSort == -QUEST_SORT_MIDSUMMER || ZoneOrSort == -QUEST_SORT_BREWFEST || ZoneOrSort == -QUEST_SORT_LOVE_IS_IN_THE_AIR || ZoneOrSort == -QUEST_SORT_NOBLEGARDEN) && !IsRepeatable(); }
bool IsDailyOrWeekly() const { return Flags & (QUEST_FLAGS_DAILY | QUEST_FLAGS_WEEKLY); }
- bool IsRaidQuest() const { return Type == QUEST_TYPE_RAID || Type == QUEST_TYPE_RAID_10 || Type == QUEST_TYPE_RAID_25; }
- bool IsAllowedInRaid() const;
+ bool IsRaidQuest(Difficulty difficulty) const;
+ bool IsAllowedInRaid(Difficulty difficulty) const;
bool IsDFQuest() const { return Flags & QUEST_TRINITY_FLAGS_DF_QUEST; }
uint32 CalculateHonorGain(uint8 level) const;
@@ -354,7 +354,6 @@ class Quest
uint32 PointOption;
uint32 EmoteOnIncomplete;
uint32 EmoteOnComplete;
- uint32 CompleteScript;
};
struct QuestStatusData
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 0821be2abb9..6492f3ee1f8 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -1249,7 +1249,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x4C4*/ { "CMSG_GM_GRANT_ACHIEVEMENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
/*0x4C5*/ { "CMSG_GM_REMOVE_ACHIEVEMENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
/*0x4C6*/ { "CMSG_GM_SET_CRITERIA_FOR_PLAYER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4C7*/ { "SMSG_ARENA_OPPONENT_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
+ /*0x4C7*/ { "SMSG_ARENA_UNIT_DESTROYED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
/*0x4C8*/ { "SMSG_ARENA_TEAM_CHANGE_FAILED_QUEUED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
/*0x4C9*/ { "CMSG_PROFILEDATA_REQUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
/*0x4CA*/ { "SMSG_PROFILEDATA_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index 625ee88a853..f7a73a20d6e 100644
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -1257,7 +1257,7 @@ enum Opcodes
CMSG_GM_GRANT_ACHIEVEMENT = 0x4C4,
CMSG_GM_REMOVE_ACHIEVEMENT = 0x4C5,
CMSG_GM_SET_CRITERIA_FOR_PLAYER = 0x4C6,
- SMSG_ARENA_OPPONENT_UPDATE = 0x4C7, // uint64
+ SMSG_ARENA_UNIT_DESTROYED = 0x4C7,
SMSG_ARENA_TEAM_CHANGE_FAILED_QUEUED = 0x4C8, // uint32 "Can't modify arena team while queued or in a match."
CMSG_PROFILEDATA_REQUEST = 0x4C9,
SMSG_PROFILEDATA_RESPONSE = 0x4CA,
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 260091c9ed7..745a7baab8f 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -3199,7 +3199,8 @@ void AuraEffect::HandleAuraControlVehicle(AuraApplication const* aurApp, uint8 m
if (apply)
{
- caster->_EnterVehicle(target->GetVehicleKit(), m_amount - 1, aurApp);
+ // correct amount is already calculated adding one more -1 meant calculated amount - 1
+ caster->_EnterVehicle(target->GetVehicleKit(), m_amount, aurApp);
}
else
{
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index aa0104da57e..8f09dd0c103 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -4854,9 +4854,10 @@ SpellCastResult Spell::CheckCast(bool strict)
if (!checkMask)
checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
+ // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(m_caster);
if (!(m_spellInfo->AttributesEx6 & SPELL_ATTR6_CASTABLE_WHILE_ON_VEHICLE) && !(m_spellInfo->Attributes & SPELL_ATTR0_CASTABLE_WHILE_MOUNTED)
- && (vehicleSeat->m_flags & checkMask) != checkMask)
+ && (vehicleSeat->m_flags & checkMask) != checkMask && m_caster->GetTypeId() == TYPEID_PLAYER)
return SPELL_FAILED_DONT_REPORT;
}
@@ -5634,7 +5635,7 @@ SpellCastResult Spell::CheckCasterAuras() const
Unit::AuraEffectList const& stunAuras = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_STUN);
for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
{
- if (!((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & (1<<MECHANIC_STUN)))
+ if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & (1<<MECHANIC_STUN)))
{
foundNotStun = true;
break;
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 8bf164767e8..926264f899b 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -2355,6 +2355,7 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
case SUMMON_TYPE_VEHICLE2:
summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id);
break;
+ case SUMMON_TYPE_LIGHTWELL:
case SUMMON_TYPE_TOTEM:
{
summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id);
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 61b92ce6f81..dd367212f67 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -1546,7 +1546,7 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta
if (unitTarget->HasUnitState(UNIT_STATE_IN_FLIGHT))
return SPELL_FAILED_BAD_TARGETS;
- /* TARGET_UNIT_MASTER gets blocked here for passengers, because the whole idea of this check is to
+ /* TARGET_UNIT_MASTER gets blocked here for passengers, because the whole idea of this check is to
not allow passengers to be implicitly hit by spells, however this target type should be an exception,
if this is left it kills spells that award kill credit from vehicle to master (few spells),
the use of these 2 covers passenger target check, logically, if vehicle cast this to master it should always hit
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index d166c6f9ebf..9714e2bc09b 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -1836,14 +1836,14 @@ void SpellMgr::LoadSpellProcs()
int32 spellId = fields[0].GetInt32();
bool allRanks = false;
- if (spellId <=0)
+ if (spellId < 0)
{
allRanks = true;
spellId = -spellId;
}
- SpellInfo const* spellEntry = GetSpellInfo(spellId);
- if (!spellEntry)
+ SpellInfo const* spellInfo = GetSpellInfo(spellId);
+ if (!spellInfo)
{
sLog->outError(LOG_FILTER_SQL, "Spell %u listed in `spell_proc` does not exist", spellId);
continue;
@@ -1851,9 +1851,9 @@ void SpellMgr::LoadSpellProcs()
if (allRanks)
{
- if (GetFirstSpellInChain(spellId) != uint32(spellId))
+ if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId))
{
- sLog->outError(LOG_FILTER_SQL, "Spell %u listed in `spell_proc` is not first rank of spell.", fields[0].GetInt32());
+ sLog->outError(LOG_FILTER_SQL, "Spell %u listed in `spell_proc` is not first rank of spell.", spellId);
continue;
}
}
@@ -1876,79 +1876,77 @@ void SpellMgr::LoadSpellProcs()
baseProcEntry.cooldown = uint32(cooldown);
baseProcEntry.charges = fields[14].GetUInt32();
- while (true)
+ while (spellInfo)
{
- if (mSpellProcMap.find(spellId) != mSpellProcMap.end())
+ if (mSpellProcMap.find(spellInfo->Id) != mSpellProcMap.end())
{
- sLog->outError(LOG_FILTER_SQL, "Spell %u listed in `spell_proc` has duplicate entry in the table", spellId);
+ sLog->outError(LOG_FILTER_SQL, "Spell %u listed in `spell_proc` has duplicate entry in the table", spellInfo->Id);
break;
}
SpellProcEntry procEntry = SpellProcEntry(baseProcEntry);
// take defaults from dbcs
if (!procEntry.typeMask)
- procEntry.typeMask = spellEntry->ProcFlags;
+ procEntry.typeMask = spellInfo->ProcFlags;
if (!procEntry.charges)
- procEntry.charges = spellEntry->ProcCharges;
+ procEntry.charges = spellInfo->ProcCharges;
if (!procEntry.chance && !procEntry.ratePerMinute)
- procEntry.chance = float(spellEntry->ProcChance);
+ procEntry.chance = float(spellInfo->ProcChance);
// validate data
if (procEntry.schoolMask & ~SPELL_SCHOOL_MASK_ALL)
- sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has wrong `schoolMask` set: %u", spellId, procEntry.schoolMask);
+ sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has wrong `schoolMask` set: %u", spellInfo->Id, procEntry.schoolMask);
if (procEntry.spellFamilyName && (procEntry.spellFamilyName < 3 || procEntry.spellFamilyName > 17 || procEntry.spellFamilyName == 14 || procEntry.spellFamilyName == 16))
- sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has wrong `spellFamilyName` set: %u", spellId, procEntry.spellFamilyName);
+ sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has wrong `spellFamilyName` set: %u", spellInfo->Id, procEntry.spellFamilyName);
if (procEntry.chance < 0)
{
- sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has negative value in `chance` field", spellId);
+ sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has negative value in `chance` field", spellInfo->Id);
procEntry.chance = 0;
}
if (procEntry.ratePerMinute < 0)
{
- sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has negative value in `ratePerMinute` field", spellId);
+ sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has negative value in `ratePerMinute` field", spellInfo->Id);
procEntry.ratePerMinute = 0;
}
if (cooldown < 0)
{
- sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has negative value in `cooldown` field", spellId);
+ sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has negative value in `cooldown` field", spellInfo->Id);
procEntry.cooldown = 0;
}
if (procEntry.chance == 0 && procEntry.ratePerMinute == 0)
- sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u doesn't have `chance` and `ratePerMinute` values defined, proc will not be triggered", spellId);
+ sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u doesn't have `chance` and `ratePerMinute` values defined, proc will not be triggered", spellInfo->Id);
if (procEntry.charges > 99)
{
- sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has too big value in `charges` field", spellId);
+ sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has too big value in `charges` field", spellInfo->Id);
procEntry.charges = 99;
}
if (!procEntry.typeMask)
- sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u doesn't have `typeMask` value defined, proc will not be triggered", spellId);
- if (procEntry.spellTypeMask & ~PROC_SPELL_PHASE_MASK_ALL)
- sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has wrong `spellTypeMask` set: %u", spellId, procEntry.spellTypeMask);
+ sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u doesn't have `typeMask` value defined, proc will not be triggered", spellInfo->Id);
+ if (procEntry.spellTypeMask & ~PROC_SPELL_TYPE_MASK_ALL)
+ sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has wrong `spellTypeMask` set: %u", spellInfo->Id, procEntry.spellTypeMask);
if (procEntry.spellTypeMask && !(procEntry.typeMask & (SPELL_PROC_FLAG_MASK | PERIODIC_PROC_FLAG_MASK)))
- sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has `spellTypeMask` value defined, but it won't be used for defined `typeMask` value", spellId);
+ sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has `spellTypeMask` value defined, but it won't be used for defined `typeMask` value", spellInfo->Id);
if (!procEntry.spellPhaseMask && procEntry.typeMask & REQ_SPELL_PHASE_PROC_FLAG_MASK)
- sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u doesn't have `spellPhaseMask` value defined, but it's required for defined `typeMask` value, proc will not be triggered", spellId);
+ sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u doesn't have `spellPhaseMask` value defined, but it's required for defined `typeMask` value, proc will not be triggered", spellInfo->Id);
if (procEntry.spellPhaseMask & ~PROC_SPELL_PHASE_MASK_ALL)
- sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has wrong `spellPhaseMask` set: %u", spellId, procEntry.spellPhaseMask);
+ sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has wrong `spellPhaseMask` set: %u", spellInfo->Id, procEntry.spellPhaseMask);
if (procEntry.spellPhaseMask && !(procEntry.typeMask & REQ_SPELL_PHASE_PROC_FLAG_MASK))
- sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has `spellPhaseMask` value defined, but it won't be used for defined `typeMask` value", spellId);
+ sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has `spellPhaseMask` value defined, but it won't be used for defined `typeMask` value", spellInfo->Id);
if (procEntry.hitMask & ~PROC_HIT_MASK_ALL)
- sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has wrong `hitMask` set: %u", spellId, procEntry.hitMask);
+ sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has wrong `hitMask` set: %u", spellInfo->Id, procEntry.hitMask);
if (procEntry.hitMask && !(procEntry.typeMask & TAKEN_HIT_PROC_FLAG_MASK || (procEntry.typeMask & DONE_HIT_PROC_FLAG_MASK && (!procEntry.spellPhaseMask || procEntry.spellPhaseMask & (PROC_SPELL_PHASE_HIT | PROC_SPELL_PHASE_FINISH)))))
- sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has `hitMask` value defined, but it won't be used for defined `typeMask` and `spellPhaseMask` values", spellId);
+ sLog->outError(LOG_FILTER_SQL, "`spell_proc` table entry for spellId %u has `hitMask` value defined, but it won't be used for defined `typeMask` and `spellPhaseMask` values", spellInfo->Id);
- mSpellProcMap[spellId] = procEntry;
+ mSpellProcMap[spellInfo->Id] = procEntry;
if (allRanks)
- {
- spellId = GetNextSpellInChain(spellId);
- spellEntry = GetSpellInfo(spellId);
- }
+ spellInfo = spellInfo->GetNextRankSpell();
else
break;
}
++count;
- } while (result->NextRow());
+ }
+ while (result->NextRow());
sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u spell proc conditions and data in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp
index 89b75fd1695..fac64455b9d 100644
--- a/src/server/game/Texts/CreatureTextMgr.cpp
+++ b/src/server/game/Texts/CreatureTextMgr.cpp
@@ -187,7 +187,7 @@ void CreatureTextMgr::LoadCreatureTextLocales()
mLocaleTextMap.clear(); // for reload case
- QueryResult result = WorldDatabase.Query("SELECT entry, textGroup, id, text_loc1, text_loc2, text_loc3, text_loc4, text_loc5, text_loc6, text_loc7, text_loc8 FROM locales_creature_text");
+ QueryResult result = WorldDatabase.Query("SELECT entry, groupid, id, text_loc1, text_loc2, text_loc3, text_loc4, text_loc5, text_loc6, text_loc7, text_loc8 FROM locales_creature_text");
if (!result)
return;
@@ -197,7 +197,7 @@ void CreatureTextMgr::LoadCreatureTextLocales()
do
{
Field* fields = result->Fetch();
- CreatureTextLocale& loc = mLocaleTextMap[CreatureTextId(fields[0].GetUInt32(), uint32(fields[1].GetUInt8()), fields[2].GetUInt32())];
+ CreatureTextLocale& loc = mLocaleTextMap[CreatureTextId(fields[0].GetUInt32(), uint32(fields[1].GetUInt8()), uint32(fields[2].GetUInt8()))];
for (uint8 i = 1; i < TOTAL_LOCALES; ++i)
{
LocaleConstant locale = LocaleConstant(i);
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 67693f22267..81261138957 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1655,7 +1655,6 @@ void World::SetInitialWorldSettings()
LoadAutobroadcasts();
///- Load and initialize scripts
- sObjectMgr->LoadQuestEndScripts(); // must be after load Creature/Gameobject(Template/Data) and QuestTemplate
sObjectMgr->LoadSpellScripts(); // must be after load Creature/Gameobject(Template/Data)
sObjectMgr->LoadGameObjectScripts(); // must be after load Creature/Gameobject(Template/Data)
sObjectMgr->LoadEventScripts(); // must be after load Creature/Gameobject(Template/Data)
diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp
index 5b5608f9a26..f62a6f059b7 100644
--- a/src/server/scripts/Commands/cs_reload.cpp
+++ b/src/server/scripts/Commands/cs_reload.cpp
@@ -126,7 +126,6 @@ public:
{ "pickpocketing_loot_template", SEC_ADMINISTRATOR, true, &HandleReloadLootTemplatesPickpocketingCommand, "", NULL},
{ "points_of_interest", SEC_ADMINISTRATOR, true, &HandleReloadPointsOfInterestCommand, "", NULL },
{ "prospecting_loot_template", SEC_ADMINISTRATOR, true, &HandleReloadLootTemplatesProspectingCommand, "", NULL },
- { "quest_end_scripts", SEC_ADMINISTRATOR, true, &HandleReloadQuestEndScriptsCommand, "", NULL },
{ "quest_poi", SEC_ADMINISTRATOR, true, &HandleReloadQuestPOICommand, "", NULL },
{ "quest_template", SEC_ADMINISTRATOR, true, &HandleReloadQuestTemplateCommand, "", NULL },
{ "reference_loot_template", SEC_ADMINISTRATOR, true, &HandleReloadLootTemplatesReferenceCommand, "", NULL },
@@ -263,7 +262,6 @@ public:
sLog->outInfo(LOG_FILTER_GENERAL, "Re-Loading Scripts...");
HandleReloadGameObjectScriptsCommand(handler, "a");
HandleReloadEventScriptsCommand(handler, "a");
- HandleReloadQuestEndScriptsCommand(handler, "a");
HandleReloadSpellScriptsCommand(handler, "a");
handler->SendGlobalGMSysMessage("DB tables `*_scripts` reloaded.");
HandleReloadDbScriptStringCommand(handler, "a");
@@ -1043,26 +1041,6 @@ public:
return true;
}
- static bool HandleReloadQuestEndScriptsCommand(ChatHandler* handler, const char* args)
- {
- if (sScriptMgr->IsScriptScheduled())
- {
- handler->SendSysMessage("DB scripts used currently, please attempt reload later.");
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- if (*args != 'a')
- sLog->outInfo(LOG_FILTER_GENERAL, "Re-Loading Scripts from `quest_end_scripts`...");
-
- sObjectMgr->LoadQuestEndScripts();
-
- if (*args != 'a')
- handler->SendGlobalGMSysMessage("DB table `quest_end_scripts` reloaded.");
-
- return true;
- }
-
static bool HandleReloadSpellScriptsCommand(ChatHandler* handler, const char* args)
{
if (sScriptMgr->IsScriptScheduled())
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
index 2d09feef089..b0edbf214e8 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
@@ -1006,7 +1006,7 @@ class boss_icehowl : public CreatureScript
events.ScheduleEvent(EVENT_WHIRL, urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS));
return;
case EVENT_MASSIVE_CRASH:
- me->GetMotionMaster()->MoveJump(ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 20.0f, 20.0f); // 1: Middle of the room
+ me->GetMotionMaster()->MoveJump(ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 20.0f, 20.0f, 0); // 1: Middle of the room
SetCombatMovement(false);
me->AttackStop();
_stage = 7; //Invalid (Do nothing more than move)
@@ -1059,7 +1059,7 @@ class boss_icehowl : public CreatureScript
_trampleTargetY = target->GetPositionY();
_trampleTargetZ = target->GetPositionZ();
// 2: Hop Backwards
- me->GetMotionMaster()->MoveJump(2*me->GetPositionX() - _trampleTargetX, 2*me->GetPositionY() - _trampleTargetY, me->GetPositionZ(), 30.0f, 20.0f);
+ me->GetMotionMaster()->MoveJump(2*me->GetPositionX() - _trampleTargetX, 2*me->GetPositionY() - _trampleTargetY, me->GetPositionZ(), 30.0f, 20.0f, 0);
_stage = 7; //Invalid (Do nothing more than move)
}
else
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp
index ed196d2cd0c..f94b028bfaf 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_krickandick.cpp
@@ -226,13 +226,13 @@ class boss_ick : public CreatureScript
case EVENT_TOXIC_WASTE:
if (Creature* krick = GetKrick())
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- krick->CastSpell(target, SPELL_TOXIC_WASTE, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE);
+ krick->CastSpell(target, SPELL_TOXIC_WASTE);
events.ScheduleEvent(EVENT_TOXIC_WASTE, urand(7000, 10000));
break;
case EVENT_SHADOW_BOLT:
if (Creature* krick = GetKrick())
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
- krick->CastSpell(target, SPELL_SHADOW_BOLT, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE);
+ krick->CastSpell(target, SPELL_SHADOW_BOLT);
events.ScheduleEvent(EVENT_SHADOW_BOLT, 15000);
return;
case EVENT_MIGHTY_KICK:
@@ -322,7 +322,7 @@ class boss_krick : public CreatureScript
void KilledUnit(Unit* victim)
{
- if (victim == me)
+ if (victim->GetTypeId() != TYPEID_PLAYER)
return;
Talk(SAY_KRICK_SLAY);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
index 8bdef30a711..ee915fb6ee8 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
@@ -232,7 +232,7 @@ class boss_sindragosa : public CreatureScript
}
}
- void JustDied(Unit* killer)
+ void JustDied(Unit* /* killer */)
{
_JustDied();
Talk(SAY_DEATH);
diff --git a/src/server/scripts/Northrend/dragonblight.cpp b/src/server/scripts/Northrend/dragonblight.cpp
index 13a8370690e..695a942721d 100644
--- a/src/server/scripts/Northrend/dragonblight.cpp
+++ b/src/server/scripts/Northrend/dragonblight.cpp
@@ -33,6 +33,8 @@ EndContentData */
#include "SpellScript.h"
#include "SpellAuraEffects.h"
#include "ScriptedEscortAI.h"
+#include "Vehicle.h"
+#include "CombatAI.h"
#include "Player.h"
enum eEnums
@@ -172,15 +174,27 @@ public:
};
/*######
-## wyrmrest_defender
+## Quest: Defending Wyrmrest Temple ID: 12372
######*/
enum WyrmDefenderEnum
{
- QUEST_DEFENDING_WYRMREST_TEMPLE = 12372,
- GOSSIP_TEXTID_DEF1 = 12899,
- GOSSIP_TEXTID_DEF2 = 12900,
- SPELL_CHARACTER_SCRIPT = 49213
+ // Quest data
+ QUEST_DEFENDING_WYRMREST_TEMPLE = 12372,
+ GOSSIP_TEXTID_DEF1 = 12899,
+
+ // Gossip data
+ GOSSIP_TEXTID_DEF2 = 12900,
+
+ // Spells data
+ SPELL_CHARACTER_SCRIPT = 49213,
+ SPELL_DEFENDER_ON_LOW_HEALTH_EMOTE = 52421, // ID - 52421 Wyrmrest Defender: On Low Health Boss Emote to Controller - Random /self/
+ SPELL_RENEW = 49263, // casted to heal drakes
+ SPELL_WYRMREST_DEFENDER_MOUNT = 49256,
+
+ // Texts data
+ WHISPER_MOUNTED = 0,
+ BOSS_EMOTE_ON_LOW_HEALTH = 2
};
#define GOSSIP_ITEM_1 "We need to get into the fight. Are you ready?"
@@ -211,10 +225,79 @@ class npc_wyrmrest_defender : public CreatureScript
player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_DEF2, creature->GetGUID());
// Makes player cast trigger spell for 49207 on self
player->CastSpell(player, SPELL_CHARACTER_SCRIPT, true);
+ // The gossip should not auto close
}
return true;
}
+
+ struct npc_wyrmrest_defenderAI : public VehicleAI
+ {
+ npc_wyrmrest_defenderAI(Creature* creature) : VehicleAI(creature) { }
+
+ bool hpWarningReady;
+ bool renewRecoveryCanCheck;
+
+ uint32 RenewRecoveryChecker;
+
+ void Reset()
+ {
+ hpWarningReady = true;
+ renewRecoveryCanCheck = false;
+
+ RenewRecoveryChecker = 0;
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ // Check system for Health Warning should happen first time whenever get under 30%,
+ // after it should be able to happen only after recovery of last renew is fully done (20 sec),
+ // next one used won't interfere
+ if (hpWarningReady && me->GetHealthPct() <= 30.0f)
+ {
+ me->CastSpell(me, SPELL_DEFENDER_ON_LOW_HEALTH_EMOTE);
+ hpWarningReady = false;
+ }
+
+ if (renewRecoveryCanCheck)
+ {
+ if (RenewRecoveryChecker <= diff)
+ {
+ renewRecoveryCanCheck = false;
+ hpWarningReady = true;
+ }
+ else RenewRecoveryChecker -= diff;
+ }
+ }
+
+ void SpellHit(Unit* /*caster*/, SpellInfo const* spell)
+ {
+ switch (spell->Id)
+ {
+ case SPELL_WYRMREST_DEFENDER_MOUNT:
+ Talk(WHISPER_MOUNTED, me->GetCharmerOrOwnerGUID());
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+ break;
+ // Both below are for checking low hp warning
+ case SPELL_DEFENDER_ON_LOW_HEALTH_EMOTE:
+ Talk(BOSS_EMOTE_ON_LOW_HEALTH, me->GetCharmerOrOwnerGUID());
+ break;
+ case SPELL_RENEW:
+ if (!hpWarningReady && RenewRecoveryChecker <= 100)
+ {
+ RenewRecoveryChecker = 20000;
+ }
+ renewRecoveryCanCheck = true;
+ break;
+ }
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_wyrmrest_defenderAI(creature);
+ }
};
void AddSC_dragonblight()
diff --git a/src/server/scripts/Outland/TempestKeep/botanica/boss_high_botanist_freywinn.cpp b/src/server/scripts/Outland/TempestKeep/botanica/boss_high_botanist_freywinn.cpp
index 4288061860e..53277afdc54 100644
--- a/src/server/scripts/Outland/TempestKeep/botanica/boss_high_botanist_freywinn.cpp
+++ b/src/server/scripts/Outland/TempestKeep/botanica/boss_high_botanist_freywinn.cpp
@@ -31,7 +31,9 @@ enum eSays
SAY_AGGRO = 0,
SAY_KILL = 1,
SAY_TREE = 2,
- SAY_DEATH = 3
+ SAY_SUMMON = 3,
+ SAY_DEATH = 4,
+ SAY_OOC_RANDOM = 5,
};
enum eSpells
diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp
index 58b6fca8a81..b6497c048c8 100644
--- a/src/server/scripts/Spells/spell_quest.cpp
+++ b/src/server/scripts/Spells/spell_quest.cpp
@@ -1284,7 +1284,10 @@ class spell_q12372_cast_from_gossip_trigger : public SpellScriptLoader
// 49370 - Wyrmrest Defender: Destabilize Azure Dragonshrine Effect
enum Quest12372Data
{
+ // NPCs
NPC_WYRMREST_TEMPLE_CREDIT = 27698,
+ // Spells
+ WHISPER_ON_HIT_BY_FORCE_WHISPER = 1
};
class spell_q12372_destabilize_azure_dragonshrine_dummy : public SpellScriptLoader
@@ -1318,6 +1321,34 @@ class spell_q12372_destabilize_azure_dragonshrine_dummy : public SpellScriptLoad
}
};
+// ID - 50287 Azure Dragon: On Death Force Cast Wyrmrest Defender to Whisper to Controller - Random (casted from Azure Dragons and Azure Drakes on death)
+class spell_q12372_azure_on_death_force_whisper : public SpellScriptLoader
+{
+ public:
+ spell_q12372_azure_on_death_force_whisper() : SpellScriptLoader("spell_q12372_azure_on_death_force_whisper") { }
+
+ class spell_q12372_azure_on_death_force_whisper_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q12372_azure_on_death_force_whisper_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Creature* defender = GetHitCreature())
+ defender->AI()->Talk(WHISPER_ON_HIT_BY_FORCE_WHISPER, defender->GetCharmerOrOwnerGUID());
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_q12372_azure_on_death_force_whisper_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_q12372_azure_on_death_force_whisper_SpellScript();
+ }
+};
+
// "Bombing Run" and "Bomb Them Again!"
enum Quest11010_11102_11023Data
{
@@ -1522,4 +1553,5 @@ void AddSC_quest_spell_scripts()
new spell_q11010_q11102_q11023_aggro_burst();
new spell_q11010_q11102_q11023_choose_loc();
new spell_q11010_q11102_q11023_q11008_check_fly_mount();
+ new spell_q12372_azure_on_death_force_whisper();
}