aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/authserver/Main.cpp57
-rw-r--r--src/server/authserver/Server/AuthSocket.cpp20
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp12
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h5
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp8
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h17
-rw-r--r--src/server/game/Accounts/RBAC.h3
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp109
-rw-r--r--src/server/game/Achievements/AchievementMgr.h20
-rw-r--r--src/server/game/Calendar/CalendarMgr.cpp3
-rw-r--r--src/server/game/DataStores/DBCEnums.h8
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.cpp5
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp31
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h2
-rw-r--r--src/server/game/Entities/Pet/Pet.cpp37
-rw-r--r--src/server/game/Entities/Player/Player.cpp364
-rw-r--r--src/server/game/Entities/Player/Player.h18
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp95
-rw-r--r--src/server/game/Entities/Unit/Unit.h39
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp28
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.h20
-rw-r--r--src/server/game/Groups/Group.cpp5
-rw-r--r--src/server/game/Handlers/CalendarHandler.cpp20
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp10
-rw-r--r--src/server/game/Handlers/ChatHandler.cpp75
-rw-r--r--src/server/game/Handlers/LootHandler.cpp2
-rw-r--r--src/server/game/Handlers/MailHandler.cpp42
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp17
-rw-r--r--src/server/game/Handlers/NPCHandler.cpp9
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp206
-rw-r--r--src/server/game/Handlers/SkillHandler.cpp3
-rw-r--r--src/server/game/Handlers/SpellHandler.cpp10
-rw-r--r--src/server/game/Handlers/TaxiHandler.cpp17
-rw-r--r--src/server/game/Handlers/TicketHandler.cpp24
-rw-r--r--src/server/game/Movement/MotionMaster.cpp5
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2
-rw-r--r--src/server/game/Server/WorldSession.h3
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp42
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp7
-rw-r--r--src/server/game/Spells/Spell.cpp494
-rw-r--r--src/server/game/Spells/Spell.h10
-rw-r--r--src/server/game/Spells/SpellEffects.cpp124
-rw-r--r--src/server/game/Spells/SpellMgr.cpp194
-rw-r--r--src/server/game/Spells/SpellScript.cpp42
-rw-r--r--src/server/game/Spells/SpellScript.h30
-rw-r--r--src/server/game/Tickets/TicketMgr.cpp37
-rw-r--r--src/server/game/Tickets/TicketMgr.h6
-rw-r--r--src/server/game/Warden/Warden.cpp3
-rw-r--r--src/server/game/Weather/Weather.cpp16
-rw-r--r--src/server/game/Weather/WeatherMgr.cpp1
-rw-r--r--src/server/game/World/World.cpp12
-rw-r--r--src/server/game/World/World.h3
-rw-r--r--src/server/scripts/Commands/cs_ban.cpp2
-rw-r--r--src/server/scripts/Commands/cs_gm.cpp34
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp43
-rw-r--r--src/server/scripts/Commands/cs_quest.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_chromaggus.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_ebonroc.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_firemaw.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_flamegor.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp6
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp11
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/boss_netherspite.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp5
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp12
-rw-r--r--src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/Stratholme/boss_baron_rivendare.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp5
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp14
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp280
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h8
-rw-r--r--src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp5
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp11
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp9
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp6
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp6
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp6
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp42
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp4
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp15
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp8
-rw-r--r--src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp2
-rw-r--r--src/server/scripts/Kalimdor/RazorfenDowns/boss_glutton.cpp5
-rw-r--r--src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp3
-rw-r--r--src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.h8
-rw-r--r--src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp2
-rw-r--r--src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp2
-rw-r--r--src/server/scripts/Kalimdor/zone_ashenvale.cpp2
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp6
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp389
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp2
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp12
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp8
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp22
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp30
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp2
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp4
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp12
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp45
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp13
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp29
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h6
-rw-r--r--src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp4
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp12
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp9
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp13
-rw-r--r--src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp56
-rw-r--r--src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp2
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp19
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp21
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp10
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp5
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp12
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp14
-rw-r--r--src/server/scripts/Northrend/VaultOfArchavon/boss_emalon.cpp4
-rw-r--r--src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp4
-rw-r--r--src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp2
-rw-r--r--src/server/scripts/Northrend/VioletHold/boss_erekem.cpp26
-rw-r--r--src/server/scripts/Northrend/VioletHold/violet_hold.cpp6
-rw-r--r--src/server/scripts/Northrend/zone_borean_tundra.cpp5
-rw-r--r--src/server/scripts/Northrend/zone_dragonblight.cpp10
-rw-r--r--src/server/scripts/Northrend/zone_grizzly_hills.cpp2
-rw-r--r--src/server/scripts/Northrend/zone_storm_peaks.cpp10
-rw-r--r--src/server/scripts/Northrend/zone_wintergrasp.cpp5
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_illidan.cpp2
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp54
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp2
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp6
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp3
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp6
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp4
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp18
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp2
-rw-r--r--src/server/scripts/Outland/zone_blades_edge_mountains.cpp6
-rw-r--r--src/server/scripts/Outland/zone_nagrand.cpp65
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp280
-rw-r--r--src/server/scripts/Spells/spell_druid.cpp71
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp57
-rw-r--r--src/server/scripts/Spells/spell_holiday.cpp62
-rw-r--r--src/server/scripts/Spells/spell_item.cpp35
-rw-r--r--src/server/scripts/Spells/spell_paladin.cpp104
-rw-r--r--src/server/scripts/Spells/spell_pet.cpp3
-rw-r--r--src/server/scripts/Spells/spell_priest.cpp151
-rw-r--r--src/server/scripts/Spells/spell_quest.cpp88
-rw-r--r--src/server/scripts/Spells/spell_rogue.cpp120
-rw-r--r--src/server/scripts/Spells/spell_shaman.cpp13
-rw-r--r--src/server/scripts/Spells/spell_warrior.cpp98
-rw-r--r--src/server/scripts/World/npc_taxi.cpp1
-rw-r--r--src/server/shared/CompilerDefs.h2
-rw-r--r--src/server/shared/Cryptography/OpenSSLCrypto.cpp5
-rw-r--r--src/server/shared/Debugging/WheatyExceptionReport.cpp233
-rw-r--r--src/server/shared/Debugging/WheatyExceptionReport.h31
-rw-r--r--src/server/shared/Logging/AppenderFile.cpp16
-rw-r--r--src/server/shared/Utilities/ByteConverter.h4
-rw-r--r--src/server/shared/Utilities/Util.cpp3
-rw-r--r--src/server/worldserver/Master.cpp57
-rw-r--r--src/server/worldserver/worldserver.conf.dist9
-rw-r--r--src/tools/mmaps_generator/MapBuilder.cpp2
-rw-r--r--src/tools/vmap4_extractor/vmapexport.cpp2
171 files changed, 3227 insertions, 2193 deletions
diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp
index 28e9f324c19..d1b2b614037 100644
--- a/src/server/authserver/Main.cpp
+++ b/src/server/authserver/Main.cpp
@@ -178,42 +178,44 @@ extern int main(int argc, char** argv)
Handler.register_handler(SIGINT, &SignalINT);
Handler.register_handler(SIGTERM, &SignalTERM);
+#if defined(_WIN32) || defined(__linux__)
+
///- Handle affinity for multiple processors and process priority
uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0);
bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false);
#ifdef _WIN32 // Windows
+
+ HANDLE hProcess = GetCurrentProcess();
+ if (affinity > 0)
{
- HANDLE hProcess = GetCurrentProcess();
-
- if (affinity > 0)
- {
- ULONG_PTR appAff;
- ULONG_PTR sysAff;
-
- if (GetProcessAffinityMask(hProcess, &appAff, &sysAff))
- {
- ULONG_PTR currentAffinity = affinity & appAff; // remove non accessible processors
-
- if (!currentAffinity)
- TC_LOG_ERROR("server.authserver", "Processors marked in UseProcessors bitmask (hex) %x are not accessible for the authserver. Accessible processors bitmask (hex): %x", affinity, appAff);
- else if (SetProcessAffinityMask(hProcess, currentAffinity))
- TC_LOG_INFO("server.authserver", "Using processors (bitmask, hex): %x", currentAffinity);
- else
- TC_LOG_ERROR("server.authserver", "Can't set used processors (hex): %x", currentAffinity);
- }
- }
-
- if (highPriority)
+ ULONG_PTR appAff;
+ ULONG_PTR sysAff;
+
+ if (GetProcessAffinityMask(hProcess, &appAff, &sysAff))
{
- if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS))
- TC_LOG_INFO("server.authserver", "authserver process priority class set to HIGH");
+ // remove non accessible processors
+ ULONG_PTR currentAffinity = affinity & appAff;
+
+ if (!currentAffinity)
+ TC_LOG_ERROR("server.authserver", "Processors marked in UseProcessors bitmask (hex) %x are not accessible for the authserver. Accessible processors bitmask (hex): %x", affinity, appAff);
+ else if (SetProcessAffinityMask(hProcess, currentAffinity))
+ TC_LOG_INFO("server.authserver", "Using processors (bitmask, hex): %x", currentAffinity);
else
- TC_LOG_ERROR("server.authserver", "Can't set authserver process priority class.");
+ TC_LOG_ERROR("server.authserver", "Can't set used processors (hex): %x", currentAffinity);
}
}
-#elif __linux__ // Linux
-
+
+ if (highPriority)
+ {
+ if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS))
+ TC_LOG_INFO("server.authserver", "authserver process priority class set to HIGH");
+ else
+ TC_LOG_ERROR("server.authserver", "Can't set authserver process priority class.");
+ }
+
+#else // Linux
+
if (affinity > 0)
{
cpu_set_t mask;
@@ -240,7 +242,8 @@ extern int main(int argc, char** argv)
else
TC_LOG_INFO("server.authserver", "authserver process priority class set to %i", getpriority(PRIO_PROCESS, 0));
}
-
+
+#endif
#endif
// maximum counter for next ping
diff --git a/src/server/authserver/Server/AuthSocket.cpp b/src/server/authserver/Server/AuthSocket.cpp
index 67d3975815f..c7bb600024a 100644
--- a/src/server/authserver/Server/AuthSocket.cpp
+++ b/src/server/authserver/Server/AuthSocket.cpp
@@ -321,9 +321,7 @@ bool AuthSocket::_HandleLogonChallenge()
socket().recv((char *)&buf[0], 4);
-#if TRINITY_ENDIAN == TRINITY_BIGENDIAN
- EndianConvert(*((uint16*)(buf[0])));
-#endif
+ EndianConvertPtr<uint16>(&buf[0]);
uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size;
TC_LOG_DEBUG("server.authserver", "[AuthChallenge] got header, body is %#04x bytes", remaining);
@@ -343,15 +341,13 @@ bool AuthSocket::_HandleLogonChallenge()
// BigEndian code, nop in little endian case
// size already converted
-#if TRINITY_ENDIAN == TRINITY_BIGENDIAN
- EndianConvert(*((uint32*)(&ch->gamename[0])));
+ EndianConvertPtr<uint32>(&ch->gamename[0]);
EndianConvert(ch->build);
- EndianConvert(*((uint32*)(&ch->platform[0])));
- EndianConvert(*((uint32*)(&ch->os[0])));
- EndianConvert(*((uint32*)(&ch->country[0])));
+ EndianConvertPtr<uint32>(&ch->platform[0]);
+ EndianConvertPtr<uint32>(&ch->os[0]);
+ EndianConvertPtr<uint32>(&ch->country[0]);
EndianConvert(ch->timezone_bias);
EndianConvert(ch->ip);
-#endif
ByteBuffer pkt;
@@ -397,7 +393,7 @@ bool AuthSocket::_HandleLogonChallenge()
bool locked = false;
if (fields[2].GetUInt8() == 1) // if ip is locked
{
- TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), fields[3].GetCString());
+ TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), fields[4].GetCString());
TC_LOG_DEBUG("server.authserver", "[AuthChallenge] Player address is '%s'", ip_address.c_str());
if (strcmp(fields[4].GetCString(), ip_address.c_str()) != 0)
@@ -783,9 +779,7 @@ bool AuthSocket::_HandleReconnectChallenge()
socket().recv((char *)&buf[0], 4);
-#if TRINITY_ENDIAN == TRINITY_BIGENDIAN
- EndianConvert(*((uint16*)(buf[0])));
-#endif
+ EndianConvertPtr<uint16>(&buf[0]);
uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size;
TC_LOG_DEBUG("server.authserver", "[ReconnectChallenge] got header, body is %#04x bytes", remaining);
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index bd51fe0a85b..49beb0ae86f 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -76,6 +76,7 @@ SmartScript::SmartScript()
goOrigGUID = 0;
mLastInvoker = 0;
mScriptType = SMART_SCRIPT_TYPE_CREATURE;
+ isProcessingTimedActionList = false;
}
SmartScript::~SmartScript()
@@ -3253,6 +3254,7 @@ void SmartScript::OnUpdate(uint32 const diff)
bool needCleanup = true;
if (!mTimedActionList.empty())
{
+ isProcessingTimedActionList = true;
for (SmartAIEventList::iterator i = mTimedActionList.begin(); i != mTimedActionList.end(); ++i)
{
if ((*i).enableTimed)
@@ -3261,6 +3263,8 @@ void SmartScript::OnUpdate(uint32 const diff)
needCleanup = false;
}
}
+
+ isProcessingTimedActionList = false;
}
if (needCleanup)
mTimedActionList.clear();
@@ -3502,6 +3506,14 @@ Unit* SmartScript::DoFindClosestFriendlyInRange(float range, bool playerOnly)
void SmartScript::SetScript9(SmartScriptHolder& e, uint32 entry)
{
+ //do NOT clear mTimedActionList if it's being iterated because it will invalidate the iterator and delete
+ // any SmartScriptHolder contained like the "e" parameter passed to this function
+ if (isProcessingTimedActionList)
+ {
+ TC_LOG_ERROR("scripts.ai", "Entry %d SourceType %u Event %u Action %u is trying to overwrite timed action list from a timed action, this is not allowed!.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType());
+ return;
+ }
+
mTimedActionList.clear();
mTimedActionList = sSmartScriptMgr->GetScript(entry, SMART_SCRIPT_TYPE_TIMED_ACTIONLIST);
if (mTimedActionList.empty())
diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h
index 2e1068d1bff..244728a3037 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.h
+++ b/src/server/game/AI/SmartScripts/SmartScript.h
@@ -118,7 +118,7 @@ class SmartScript
smart = false;
if (!smart)
- TC_LOG_ERROR("sql.sql", "SmartScript: Action target Creature (GUID: %u Entry: %u) is not using SmartAI, action skipped to prevent crash.", c ? c->GetDBTableGUIDLow() : (me ? me->GetDBTableGUIDLow() : 0), c ? c->GetEntry() : (me ? me->GetEntry() : 0));
+ TC_LOG_ERROR("sql.sql", "SmartScript: Action target Creature (GUID: %u Entry: %u) is not using SmartAI, action called by Creature (GUID: %u Entry: %u) skipped to prevent crash.", c ? c->GetDBTableGUIDLow() : 0, c ? c->GetEntry() : 0, me ? me->GetDBTableGUIDLow() : 0, me ? me->GetEntry() : 0);
return smart;
}
@@ -132,7 +132,7 @@ class SmartScript
if (!go || go->GetAIName() != "SmartGameObjectAI")
smart = false;
if (!smart)
- TC_LOG_ERROR("sql.sql", "SmartScript: Action target GameObject (GUID: %u Entry: %u) is not using SmartGameObjectAI, action skipped to prevent crash.", g ? g->GetDBTableGUIDLow() : (go ? go->GetDBTableGUIDLow() : 0), g ? g->GetEntry() : (go ? go->GetEntry() : 0));
+ TC_LOG_ERROR("sql.sql", "SmartScript: Action target GameObject (GUID: %u Entry: %u) is not using SmartGameObjectAI, action called by GameObject (GUID: %u Entry: %u) skipped to prevent crash.", g ? g->GetDBTableGUIDLow() : 0, g ? g->GetEntry() : 0, go ? go->GetDBTableGUIDLow() : 0, go ? go->GetEntry() : 0);
return smart;
}
@@ -222,6 +222,7 @@ class SmartScript
SmartAIEventList mEvents;
SmartAIEventList mInstallEvents;
SmartAIEventList mTimedActionList;
+ bool isProcessingTimedActionList;
Creature* me;
uint64 meOrigGUID;
GameObject* go;
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index 543cb9235d3..c6b73a468d2 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -766,6 +766,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u attempts to set invalid phase, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
return false;
}
+
if (!IsMinMaxValid(e, e.action.randomPhaseRange.phaseMin, e.action.randomPhaseRange.phaseMax))
return false;
break;
@@ -886,6 +887,12 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
return false;
break;
}
+ case SMART_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST:
+ {
+ if (!IsMinMaxValid(e, e.action.randTimedActionList.entry1, e.action.randTimedActionList.entry2))
+ return false;
+ break;
+ }
case SMART_ACTION_SET_POWER:
case SMART_ACTION_ADD_POWER:
case SMART_ACTION_REMOVE_POWER:
@@ -985,7 +992,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
case SMART_ACTION_SIMPLE_TALK:
case SMART_ACTION_CROSS_CAST:
case SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST:
- case SMART_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST:
case SMART_ACTION_RANDOM_MOVE:
case SMART_ACTION_SET_UNIT_FIELD_BYTES_1:
case SMART_ACTION_REMOVE_UNIT_FIELD_BYTES_1:
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index 9ba5ccc578e..265df8e2ac4 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -52,9 +52,12 @@ enum SMART_EVENT_PHASE
SMART_EVENT_PHASE_4 = 4,
SMART_EVENT_PHASE_5 = 5,
SMART_EVENT_PHASE_6 = 6,
- SMART_EVENT_PHASE_MAX = 7,
+ SMART_EVENT_PHASE_7 = 7,
+ SMART_EVENT_PHASE_8 = 8,
+ SMART_EVENT_PHASE_9 = 9,
+ SMART_EVENT_PHASE_MAX = 10,
- SMART_EVENT_PHASE_COUNT = 6
+ SMART_EVENT_PHASE_COUNT = 9
};
enum SMART_EVENT_PHASE_BITS
@@ -66,7 +69,10 @@ enum SMART_EVENT_PHASE_BITS
SMART_EVENT_PHASE_4_BIT = 8,
SMART_EVENT_PHASE_5_BIT = 16,
SMART_EVENT_PHASE_6_BIT = 32,
- SMART_EVENT_PHASE_ALL = SMART_EVENT_PHASE_1_BIT + SMART_EVENT_PHASE_2_BIT + SMART_EVENT_PHASE_3_BIT + SMART_EVENT_PHASE_4_BIT + SMART_EVENT_PHASE_5_BIT + SMART_EVENT_PHASE_6_BIT
+ SMART_EVENT_PHASE_7_BIT = 64,
+ SMART_EVENT_PHASE_8_BIT = 128,
+ SMART_EVENT_PHASE_9_BIT = 256,
+ SMART_EVENT_PHASE_ALL = SMART_EVENT_PHASE_1_BIT + SMART_EVENT_PHASE_2_BIT + SMART_EVENT_PHASE_3_BIT + SMART_EVENT_PHASE_4_BIT + SMART_EVENT_PHASE_5_BIT + SMART_EVENT_PHASE_6_BIT + SMART_EVENT_PHASE_7_BIT + SMART_EVENT_PHASE_8_BIT + SMART_EVENT_PHASE_9_BIT
};
const uint32 SmartPhaseMask[SMART_EVENT_PHASE_COUNT][2] =
@@ -76,7 +82,10 @@ const uint32 SmartPhaseMask[SMART_EVENT_PHASE_COUNT][2] =
{SMART_EVENT_PHASE_3, SMART_EVENT_PHASE_3_BIT },
{SMART_EVENT_PHASE_4, SMART_EVENT_PHASE_4_BIT },
{SMART_EVENT_PHASE_5, SMART_EVENT_PHASE_5_BIT },
- {SMART_EVENT_PHASE_6, SMART_EVENT_PHASE_6_BIT }
+ {SMART_EVENT_PHASE_6, SMART_EVENT_PHASE_6_BIT },
+ {SMART_EVENT_PHASE_7, SMART_EVENT_PHASE_7_BIT },
+ {SMART_EVENT_PHASE_8, SMART_EVENT_PHASE_8_BIT },
+ {SMART_EVENT_PHASE_9, SMART_EVENT_PHASE_9_BIT }
};
enum SMART_EVENT
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h
index 2a10da29c20..dc5a2768668 100644
--- a/src/server/game/Accounts/RBAC.h
+++ b/src/server/game/Accounts/RBAC.h
@@ -678,6 +678,9 @@ enum RBACPermissions
RBAC_PERM_COMMAND_WP_UNLOAD = 772,
RBAC_PERM_COMMAND_WP_RELOAD = 773,
RBAC_PERM_COMMAND_WP_SHOW = 774,
+ RBAC_PERM_COMMAND_MODIFY_CURRENCY = 775, // only 4.3.4
+ RBAC_PERM_COMMAND_DEBUG_PHASE = 776, // only 4.3.4
+ RBAC_PERM_COMMAND_MAILBOX = 777,
// custom permissions 1000+
RBAC_PERM_MAX
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 7d53f481fe8..b98ff3e4f01 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -97,6 +97,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: // only Children's Week achievements
case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
+ case ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN:
break;
default:
if (dataType != ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT)
@@ -110,7 +111,8 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
switch (dataType)
{
case ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE:
- case ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT:
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT:
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_NTH_BIRTHDAY:
return true;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE:
if (!creature.id || !sObjectMgr->GetCreatureTemplate(creature.id))
@@ -259,7 +261,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM:
if (equipped_item.item_quality >= MAX_ITEM_QUALITY)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_requirement` (Entry: %u Type: %u) for requirement ACHIEVEMENT_CRITERIA_REQUIRE_S_EQUIPED_ITEM (%u) has unknown quality state in value1 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM (%u) has unknown quality state in value1 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, equipped_item.item_quality);
return false;
}
@@ -267,7 +269,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID:
if (!sMapStore.LookupEntry(map_id.mapId))
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_requirement` (Entry: %u Type: %u) for requirement ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID (%u) has unknown map id in value1 (%u), ignored.",
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID (%u) has unknown map id in value1 (%u), ignored.",
criteria->ID, criteria->requiredType, dataType, map_id.mapId);
return false;
}
@@ -292,6 +294,14 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
return false;
}
return true;
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE:
+ if (!sCharTitlesStore.LookupEntry(known_title.title_id))
+ {
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_requirement` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE (%u) have unknown title_id in value1 (%u), ignore.",
+ criteria->ID, criteria->requiredType, dataType, known_title.title_id);
+ return false;
+ }
+ return true;
default:
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) has data for non-supported data type (%u), ignored.", criteria->ID, criteria->requiredType, dataType);
return false;
@@ -317,7 +327,7 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
return false;
return true;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE:
- if (!source || source->GetTypeId() != TYPEID_PLAYER)
+ if (source->GetTypeId() != TYPEID_PLAYER)
return false;
if (classRace.class_id && classRace.class_id != source->ToPlayer()->getClass())
return false;
@@ -381,22 +391,22 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
uint32 score = bg->GetTeamScore(source->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
return score >= bg_loss_team_score.min_score && score <= bg_loss_team_score.max_score;
}
- case ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT:
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT:
{
if (!source->IsInWorld())
return false;
Map* map = source->GetMap();
if (!map->IsDungeon())
{
- TC_LOG_ERROR("achievement", "Achievement system call ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT (%u) for achievement criteria %u for non-dungeon/non-raid map %u",
- ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT, criteria_id, map->GetId());
+ TC_LOG_ERROR("achievement", "Achievement system call ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT (%u) for achievement criteria %u for non-dungeon/non-raid map %u",
+ dataType, criteria_id, map->GetId());
return false;
}
- InstanceScript* instance = ((InstanceMap*)map)->GetInstanceScript();
+ InstanceScript* instance = map->ToInstanceMap()->GetInstanceScript();
if (!instance)
{
- TC_LOG_ERROR("achievement", "Achievement system call ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT (%u) for achievement criteria %u for map %u but map does not have a instance script",
- ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT, criteria_id, map->GetId());
+ TC_LOG_ERROR("achievement", "Achievement system call ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT (%u) for achievement criteria %u for map %u but map does not have a instance script",
+ dataType, criteria_id, map->GetId());
return false;
}
return instance->CheckAchievementCriteriaMeet(criteria_id, source, target, miscvalue1);
@@ -410,6 +420,25 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
}
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID:
return source->GetMapId() == map_id.mapId;
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_NTH_BIRTHDAY:
+ {
+ time_t birthday_start = time_t(sWorld->getIntConfig(CONFIG_BIRTHDAY_TIME));
+ tm birthday_tm;
+ ACE_OS::localtime_r(&birthday_start, &birthday_tm);
+
+ // exactly N birthday
+ birthday_tm.tm_year += birthday_login.nth_birthday;
+
+ time_t birthday = mktime(&birthday_tm);
+ time_t now = sWorld->GetGameTime();
+ return now <= birthday + DAY && now >= birthday;
+ }
+ case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE:
+ {
+ if (CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(known_title.title_id))
+ return source->HasTitle(titleInfo->bit_index);
+ return false;
+ }
default:
break;
}
@@ -1562,6 +1591,20 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
break;
}
+ case ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN:
+ {
+ // This criteria is only called directly after login - with expected miscvalue1 == 1
+ if (!miscValue1)
+ continue;
+
+ // They have no proper requirements in dbc
+ AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
+ if (!data || !data->Meets(GetPlayer(), unit))
+ continue;
+
+ SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ break;
+ }
// std case: not exist in DBC, not triggered in code as result
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER:
@@ -1574,7 +1617,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID:
case ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA:
case ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK:
- case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE:
break; // Not implemented yet :(
}
@@ -1717,6 +1759,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
return progress->counter >= achievementCriteria->get_killing_blow.killCount;
case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA:
return achievementCriteria->win_arena.count && progress->counter >= achievementCriteria->win_arena.count;
+ case ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN:
+ return true;
// handle all statistic-only criteria here
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
@@ -2287,11 +2331,24 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
switch (criteria->requiredType)
{
- case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: // any cases
- break;
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
+ case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING:
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET:
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:
+ case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE:
+ case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL:
+ case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM:
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
+ case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2:
+ case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL:
+ case ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN:
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE:
- break; // any cases
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
+ // achievement requires db data
+ break;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
{
AchievementEntry const* achievement = sAchievementMgr->GetAchievement(criteria->referredAchievement);
@@ -2304,44 +2361,22 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
continue;
}
- case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING:
- break; // any cases
- case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: // any cases
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL: // any cases
- break;
case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA: // need skip generic cases
if (criteria->additionalRequirements[0].additionalRequirement_type != ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE)
continue;
break;
- case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM: // any cases
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
- break; // any cases
- case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
- break; // any cases
case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE: // need skip generic cases
if (criteria->do_emote.count == 0)
continue;
break;
- case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2:
- break; // any cases
case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL: // skip statistics
if (criteria->win_duel.duelCount == 0)
continue;
break;
- case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: // any cases
- break;
case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: // need skip generic cases
if (criteria->loot_type.lootTypeCount != 1)
continue;
break;
- case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE:
- break; // any cases
- case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL:
- break; // any cases
- case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL: // any cases
- break;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST:
case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: // only Children's Week achievements
{
@@ -2352,8 +2387,6 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
continue;
break;
}
- case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
- break;
default: // type not use DB data, ignore
continue;
}
diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h
index 1a6777d1055..c4216b2ee74 100644
--- a/src/server/game/Achievements/AchievementMgr.h
+++ b/src/server/game/Achievements/AchievementMgr.h
@@ -65,13 +65,15 @@ enum AchievementCriteriaDataType
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK = 15, // drunken_state 0 (enum DrunkenState) of player
ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY = 16, // holiday_id 0 event in holiday time
ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE = 17, // min_score max_score player's team win bg and opposition team have team score in range
- ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT = 18, // 0 0 maker instance script call for check current criteria requirements fit
+ ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT = 18, // 0 0 maker instance script call for check current criteria requirements fit
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM = 19, // item_level item_quality for equipped item in slot to check item level and quality
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID = 20, // map_id 0 player must be on map with id in map_id
- ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE = 21 // class_id race_id
+ ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE = 21, // class_id race_id
+ ACHIEVEMENT_CRITERIA_DATA_TYPE_NTH_BIRTHDAY = 22, // N login on day of N-th Birthday
+ ACHIEVEMENT_CRITERIA_DATA_TYPE_S_KNOWN_TITLE = 23 // title_id known (pvp) title, values from dbc
};
-#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 22 // maximum value in AchievementCriteriaDataType enum
+#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 24 // maximum value in AchievementCriteriaDataType enum
struct AchievementCriteriaData
{
@@ -161,7 +163,7 @@ struct AchievementCriteriaData
uint32 min_score;
uint32 max_score;
} bg_loss_team_score;
- // ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT = 18 (no data)
+ // ACHIEVEMENT_CRITERIA_DATA_TYPE_INSTANCE_SCRIPT = 18 (no data)
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM = 19
struct
{
@@ -173,6 +175,16 @@ struct AchievementCriteriaData
{
uint32 mapId;
} map_id;
+ // ACHIEVEMENT_CRITERIA_DATA_TYPE_NTH_BIRTHDAY = 21
+ struct
+ {
+ uint32 nth_birthday;
+ } birthday_login;
+ // ACHIEVEMENT_CRITERIA_DATA_TYPE_KNOWN_TITLE = 22
+ struct
+ {
+ uint32 title_id;
+ } known_title;
// ...
struct
{
diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp
index f7a6864fb95..52ed50f3948 100644
--- a/src/server/game/Calendar/CalendarMgr.cpp
+++ b/src/server/game/Calendar/CalendarMgr.cpp
@@ -340,7 +340,8 @@ CalendarEventStore CalendarMgr::GetPlayerEvents(uint64 guid)
for (CalendarEventInviteStore::const_iterator itr = _invites.begin(); itr != _invites.end(); ++itr)
for (CalendarInviteStore::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2)
if ((*itr2)->GetInviteeGUID() == guid)
- events.insert(GetEvent(itr->first));
+ if (CalendarEvent* event = GetEvent(itr->first)) // NULL check added as attempt to fix #11512
+ events.insert(event);
if (Player* player = ObjectAccessor::FindPlayer(guid))
for (CalendarEventStore::const_iterator itr = _events.begin(); itr != _events.end(); ++itr)
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index 87397c6685b..8d8b7c89a5c 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -91,9 +91,9 @@ enum AchievementCriteriaFlags
{
ACHIEVEMENT_CRITERIA_FLAG_SHOW_PROGRESS_BAR = 0x00000001, // Show progress as bar
ACHIEVEMENT_CRITERIA_FLAG_HIDDEN = 0x00000002, // Not show criteria in client
- ACHIEVEMENT_CRITERIA_FLAG_UNK3 = 0x00000004, // BG related??
- ACHIEVEMENT_CRITERIA_FLAG_UNK4 = 0x00000008, //
- ACHIEVEMENT_CRITERIA_FLAG_UNK5 = 0x00000010, // not used
+ ACHIEVEMENT_CRITERIA_FLAG_FAIL_ACHIEVEMENT = 0x00000004, // BG related??
+ ACHIEVEMENT_CRITERIA_FLAG_RESET_ON_START = 0x00000008, //
+ ACHIEVEMENT_CRITERIA_FLAG_IS_DATE = 0x00000010, // not used
ACHIEVEMENT_CRITERIA_FLAG_MONEY_COUNTER = 0x00000020 // Displays counter as money
};
@@ -174,7 +174,7 @@ enum AchievementCriteriaTypes
ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL = 70,
ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT = 72,
/// @todo 73: Achievements 1515, 1241, 1103 (Name: Mal'Ganis)
- ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE = 74, /// @todo title id is not mentioned in dbc
+ ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN = 74,
ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS = 75,
ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL = 76,
ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL = 77,
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp
index 2dcba7b6a76..1665eae0fcc 100644
--- a/src/server/game/DungeonFinding/LFGMgr.cpp
+++ b/src/server/game/DungeonFinding/LFGMgr.cpp
@@ -405,7 +405,9 @@ void LFGMgr::InitializeLockedDungeons(Player* player, uint8 level /* = 0 */)
lockData = LFG_LOCKSTATUS_NOT_IN_SEASON;
else if (AccessRequirement const* ar = sObjectMgr->GetAccessRequirement(dungeon->map, Difficulty(dungeon->difficulty)))
{
- if (ar->achievement && !player->HasAchieved(ar->achievement))
+ if (player->GetAverageItemLevel() < ar->item_level)
+ lockData = LFG_LOCKSTATUS_TOO_LOW_GEAR_SCORE;
+ else if (ar->achievement && !player->HasAchieved(ar->achievement))
lockData = LFG_LOCKSTATUS_MISSING_ACHIEVEMENT;
else if (player->GetTeam() == ALLIANCE && ar->quest_A && !player->GetQuestRewardStatus(ar->quest_A))
lockData = LFG_LOCKSTATUS_QUEST_NOT_COMPLETED;
@@ -422,7 +424,6 @@ void LFGMgr::InitializeLockedDungeons(Player* player, uint8 level /* = 0 */)
}
/* @todo VoA closed if WG is not under team control (LFG_LOCKSTATUS_RAID_LOCKED)
- lockData = LFG_LOCKSTATUS_TOO_LOW_GEAR_SCORE;
lockData = LFG_LOCKSTATUS_TOO_HIGH_GEAR_SCORE;
lockData = LFG_LOCKSTATUS_ATTUNEMENT_TOO_LOW_LEVEL;
lockData = LFG_LOCKSTATUS_ATTUNEMENT_TOO_HIGH_LEVEL;
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 21d5ba0d21a..e3c8c9c8136 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -986,9 +986,17 @@ bool GameObject::ActivateToQuest(Player* target) const
switch (GetGoType())
{
- // scan GO chest with loot including quest items
+ case GAMEOBJECT_TYPE_QUESTGIVER:
+ {
+ GameObject* go = const_cast<GameObject*>(this);
+ QuestGiverStatus questStatus = target->GetQuestDialogStatus(go);
+ if (questStatus > DIALOG_STATUS_UNAVAILABLE)
+ return true;
+ break;
+ }
case GAMEOBJECT_TYPE_CHEST:
{
+ // scan GO chest with loot including quest items
if (LootTemplates_Gameobject.HaveQuestLootForPlayer(GetGOInfo()->GetLootId(), target))
{
if (Battleground const* bg = target->GetBattleground())
@@ -2148,6 +2156,10 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t
int16 pathProgress = -1;
switch (GetGoType())
{
+ case GAMEOBJECT_TYPE_QUESTGIVER:
+ if (ActivateToQuest(target))
+ dynFlags |= GO_DYNFLAG_LO_ACTIVATE;
+ break;
case GAMEOBJECT_TYPE_CHEST:
case GAMEOBJECT_TYPE_GOOBER:
if (ActivateToQuest(target))
@@ -2209,3 +2221,20 @@ void GameObject::GetRespawnPosition(float &x, float &y, float &z, float* ori /*
if (ori)
*ori = GetOrientation();
}
+
+float GameObject::GetInteractionDistance()
+{
+ switch (GetGoType())
+ {
+ /// @todo find out how the client calculates the maximal usage distance to spellless working
+ // gameobjects like guildbanks and mailboxes - 10.0 is a just an abitrary choosen number
+ case GAMEOBJECT_TYPE_GUILD_BANK:
+ case GAMEOBJECT_TYPE_MAILBOX:
+ return 10.0f;
+ case GAMEOBJECT_TYPE_FISHINGHOLE:
+ case GAMEOBJECT_TYPE_FISHINGNODE:
+ return 20.0f + CONTACT_DISTANCE; // max spell range
+ default:
+ return INTERACTION_DISTANCE;
+ }
+}
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index 0ef03723cb4..84abc391bc6 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -830,6 +830,8 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map
float GetStationaryZ() const { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetPositionZ(); return GetPositionZ(); }
float GetStationaryO() const { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetOrientation(); return GetOrientation(); }
+ float GetInteractionDistance();
+
protected:
bool AIM_Initialize();
void UpdateModel(); // updates model in case displayId were changed
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index c218c3c645f..a887e85e77e 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -1122,9 +1122,8 @@ void Pet::_LoadSpellCooldowns()
{
time_t curTime = time(NULL);
- WorldPacket data(SMSG_SPELL_COOLDOWN, size_t(8+1+result->GetRowCount()*8));
- data << GetGUID();
- data << uint8(0x0); // flags (0x1, 0x2)
+ PacketCooldowns cooldowns;
+ WorldPacket data;
do
{
@@ -1143,8 +1142,7 @@ void Pet::_LoadSpellCooldowns()
if (db_time <= curTime)
continue;
- data << uint32(spell_id);
- data << uint32(uint32(db_time-curTime)*IN_MILLISECONDS);
+ cooldowns[spell_id] = uint32(db_time - curTime)*IN_MILLISECONDS;
_AddCreatureSpellCooldown(spell_id, db_time);
@@ -1152,8 +1150,11 @@ void Pet::_LoadSpellCooldowns()
}
while (result->NextRow());
- if (!m_CreatureSpellCooldowns.empty() && GetOwner())
+ if (!cooldowns.empty() && GetOwner())
+ {
+ BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, cooldowns);
GetOwner()->GetSession()->SendPacket(&data);
+ }
}
}
@@ -2050,21 +2051,17 @@ void Pet::SynchronizeLevelWithOwner()
void Pet::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs)
{
- WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+m_spells.size()*8);
- data << uint64(GetGUID());
- data << uint8(0x0); // flags (0x1, 0x2)
+ PacketCooldowns cooldowns;
+ WorldPacket data;
time_t curTime = time(NULL);
for (PetSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
{
if (itr->second.state == PETSPELL_REMOVED)
continue;
+
uint32 unSpellId = itr->first;
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(unSpellId);
- if (!spellInfo)
- {
- ASSERT(spellInfo);
- continue;
- }
+ ASSERT(spellInfo);
// Not send cooldown for this spells
if (spellInfo->IsCooldownStartedOnEvent())
@@ -2075,14 +2072,18 @@ void Pet::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs)
if ((idSchoolMask & spellInfo->GetSchoolMask()) && GetCreatureSpellCooldownDelay(unSpellId) < unTimeMs)
{
- data << uint32(unSpellId);
- data << uint32(unTimeMs); // in m.secs
+ cooldowns[unSpellId] = unTimeMs;
_AddCreatureSpellCooldown(unSpellId, curTime + unTimeMs/IN_MILLISECONDS);
}
}
- if (Player* owner = GetOwner())
- owner->GetSession()->SendPacket(&data);
+ if (!cooldowns.empty())
+ {
+ BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, cooldowns);
+
+ if (Player* owner = GetOwner())
+ owner->GetSession()->SendPacket(&data);
+ }
}
Player* Pet::GetOwner() const
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 4dab652d732..09a0d033c68 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -687,7 +687,7 @@ Player::Player(WorldSession* session): Unit(true)
m_regenTimerCount = 0;
m_weaponChangeTimer = 0;
- m_zoneUpdateId = 0;
+ m_zoneUpdateId = uint32(-1);
m_zoneUpdateTimer = 0;
m_areaUpdateId = 0;
@@ -2634,38 +2634,38 @@ void Player::RegenerateHealth()
if (getLevel() < 15)
HealthIncreaseRate = sWorld->getRate(RATE_HEALTH) * (2.066f - (getLevel() * 0.066f));
- float addvalue = 0.0f;
+ float addValue = 0.0f;
// polymorphed case
if (IsPolymorphed())
- addvalue = (float)GetMaxHealth()/3;
+ addValue = float(GetMaxHealth()) / 3.0f;
// normal regen case (maybe partly in combat case)
else if (!IsInCombat() || HasAuraType(SPELL_AURA_MOD_REGEN_DURING_COMBAT))
{
- addvalue = OCTRegenHPPerSpirit() * HealthIncreaseRate;
+ addValue = OCTRegenHPPerSpirit() * HealthIncreaseRate;
if (!IsInCombat())
{
AuraEffectList const& mModHealthRegenPct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALTH_REGEN_PERCENT);
for (AuraEffectList::const_iterator i = mModHealthRegenPct.begin(); i != mModHealthRegenPct.end(); ++i)
- AddPct(addvalue, (*i)->GetAmount());
+ AddPct(addValue, (*i)->GetAmount());
- addvalue += GetTotalAuraModifier(SPELL_AURA_MOD_REGEN) * 2 * IN_MILLISECONDS / (5 * IN_MILLISECONDS);
+ addValue += GetTotalAuraModifier(SPELL_AURA_MOD_REGEN) * 0.4f;
}
else if (HasAuraType(SPELL_AURA_MOD_REGEN_DURING_COMBAT))
- ApplyPct(addvalue, GetTotalAuraModifier(SPELL_AURA_MOD_REGEN_DURING_COMBAT));
+ ApplyPct(addValue, GetTotalAuraModifier(SPELL_AURA_MOD_REGEN_DURING_COMBAT));
if (!IsStandState())
- addvalue *= 1.5f;
+ addValue *= 1.5f;
}
// always regeneration bonus (including combat)
- addvalue += GetTotalAuraModifier(SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT);
- addvalue += m_baseHealthRegen / 2.5f;
+ addValue += GetTotalAuraModifier(SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT);
+ addValue += m_baseHealthRegen / 2.5f;
- if (addvalue < 0)
- addvalue = 0;
+ if (addValue < 0.0f)
+ addValue = 0.0f;
- ModifyHealth(int32(addvalue));
+ ModifyHealth(int32(addValue));
}
void Player::ResetAllPowers()
@@ -2765,30 +2765,14 @@ GameObject* Player::GetGameObjectIfCanInteractWith(uint64 guid, GameobjectTypes
{
if (go->GetGoType() == type)
{
- float maxdist;
- switch (type)
- {
- /// @todo find out how the client calculates the maximal usage distance to spellless working
- // gameobjects like guildbanks and mailboxes - 10.0 is a just an abitrary choosen number
- case GAMEOBJECT_TYPE_GUILD_BANK:
- case GAMEOBJECT_TYPE_MAILBOX:
- maxdist = 10.0f;
- break;
- case GAMEOBJECT_TYPE_FISHINGHOLE:
- maxdist = 20.0f+CONTACT_DISTANCE; // max spell range
- break;
- default:
- maxdist = INTERACTION_DISTANCE;
- break;
- }
-
- if (go->IsWithinDistInMap(this, maxdist))
+ if (go->IsWithinDistInMap(this, go->GetInteractionDistance()))
return go;
- TC_LOG_DEBUG("maps", "IsGameObjectOfTypeInRange: GameObject '%s' [GUID: %u] is too far away from player %s [GUID: %u] to be used by him (distance=%f, maximal 10 is allowed)", go->GetGOInfo()->name.c_str(),
+ TC_LOG_DEBUG("maps", "GetGameObjectIfCanInteractWith: GameObject '%s' [GUID: %u] is too far away from player %s [GUID: %u] to be used by him (distance=%f, maximal 10 is allowed)", go->GetGOInfo()->name.c_str(),
go->GetGUIDLow(), GetName().c_str(), GetGUIDLow(), go->GetDistance(this));
}
}
+
return NULL;
}
@@ -5127,7 +5111,10 @@ void Player::BuildPlayerRepop()
// BG - remove insignia related
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
-// SendCorpseReclaimDelay();
+ int32 corpseReclaimDelay = CalculateCorpseReclaimDelay();
+
+ if (corpseReclaimDelay >= 0)
+ SendCorpseReclaimDelay(corpseReclaimDelay);
// to prevent cheating
corpse->ResetGhostTime();
@@ -5235,7 +5222,11 @@ void Player::KillPlayer()
m_deathTimer = 6 * MINUTE * IN_MILLISECONDS;
UpdateCorpseReclaimDelay(); // dependent at use SetDeathPvP() call before kill
- SendCorpseReclaimDelay();
+
+ int32 corpseReclaimDelay = CalculateCorpseReclaimDelay();
+
+ if (corpseReclaimDelay >= 0)
+ SendCorpseReclaimDelay(corpseReclaimDelay);
// don't create corpse at this moment, player might be falling
@@ -7517,14 +7508,9 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
{
if (Weather* weather = WeatherMgr::FindWeather(zone->ID))
weather->SendWeatherUpdateToPlayer(this);
- else
- {
- if (!WeatherMgr::AddWeather(zone->ID))
- {
- // send fine weather packet to remove old zone's weather
- WeatherMgr::SendFineWeatherUpdateToPlayer(this);
- }
- }
+ else if (!WeatherMgr::AddWeather(zone->ID))
+ // send fine weather packet to remove old zone's weather
+ WeatherMgr::SendFineWeatherUpdateToPlayer(this);
}
sScriptMgr->OnPlayerUpdateZone(this, newZone, newArea);
@@ -12364,11 +12350,8 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update)
GetGlobalCooldownMgr().AddGlobalCooldown(spellProto, m_weaponChangeTimer);
- WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+4);
- data << uint64(GetGUID());
- data << uint8(1);
- data << uint32(cooldownSpell);
- data << uint32(0);
+ WorldPacket data;
+ BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_INCLUDE_GCD, cooldownSpell, 0);
GetSession()->SendPacket(&data);
}
}
@@ -15051,7 +15034,7 @@ void Player::AddQuestAndCheckCompletion(Quest const* quest, Object* questGiver)
switch (questGiver->GetTypeId())
{
case TYPEID_UNIT:
- sScriptMgr->OnQuestAccept(this, (questGiver->ToCreature()), quest);
+ sScriptMgr->OnQuestAccept(this, questGiver->ToCreature(), quest);
questGiver->ToCreature()->AI()->sQuestAccept(this, quest);
break;
case TYPEID_ITEM:
@@ -15194,7 +15177,7 @@ void Player::AddQuest(Quest const* quest, Object* questGiver)
StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_QUEST, quest_id);
- UpdateForQuestWorldObjects();
+ SendQuestUpdate(quest_id);
}
void Player::CompleteQuest(uint32 quest_id)
@@ -15360,7 +15343,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
else if (quest->IsSeasonal())
SetSeasonalQuestStatus(quest_id);
- RemoveActiveQuest(quest_id);
+ RemoveActiveQuest(quest_id, false);
m_RewardedQuests.insert(quest_id);
m_RewardedQuestsSave[quest_id] = true;
@@ -15408,6 +15391,8 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
UpdatePvPState();
}
+ SendQuestUpdate(quest_id);
+
//lets remove flag for delayed teleports
SetCanDelayTeleport(false);
}
@@ -16001,17 +15986,49 @@ bool Player::CanShareQuest(uint32 quest_id) const
return false;
}
-void Player::SetQuestStatus(uint32 quest_id, QuestStatus status)
+void Player::SetQuestStatus(uint32 questId, QuestStatus status, bool update /*= true*/)
{
- if (sObjectMgr->GetQuestTemplate(quest_id))
+ if (sObjectMgr->GetQuestTemplate(questId))
+ {
+ m_QuestStatus[questId].Status = status;
+ m_QuestStatusSave[questId] = true;
+ }
+
+ if (update)
+ SendQuestUpdate(questId);
+}
+
+void Player::RemoveActiveQuest(uint32 questId, bool update /*= true*/)
+{
+ QuestStatusMap::iterator itr = m_QuestStatus.find(questId);
+ if (itr != m_QuestStatus.end())
{
- m_QuestStatus[quest_id].Status = status;
- m_QuestStatusSave[quest_id] = true;
+ m_QuestStatus.erase(itr);
+ m_QuestStatusSave[questId] = false;
}
+ if (update)
+ SendQuestUpdate(questId);
+}
+
+void Player::RemoveRewardedQuest(uint32 questId, bool update /*= true*/)
+{
+ RewardedQuestSet::iterator rewItr = m_RewardedQuests.find(questId);
+ if (rewItr != m_RewardedQuests.end())
+ {
+ m_RewardedQuests.erase(rewItr);
+ m_RewardedQuestsSave[questId] = false;
+ }
+
+ if (update)
+ SendQuestUpdate(questId);
+}
+
+void Player::SendQuestUpdate(uint32 questId)
+{
uint32 zone = 0, area = 0;
- SpellAreaForQuestMapBounds saBounds = sSpellMgr->GetSpellAreaForQuestMapBounds(quest_id);
+ SpellAreaForQuestMapBounds saBounds = sSpellMgr->GetSpellAreaForQuestMapBounds(questId);
if (saBounds.first != saBounds.second)
{
GetZoneAndAreaId(zone, area);
@@ -16022,7 +16039,7 @@ void Player::SetQuestStatus(uint32 quest_id, QuestStatus status)
CastSpell(this, itr->second->spellId, true);
}
- saBounds = sSpellMgr->GetSpellAreaForQuestEndMapBounds(quest_id);
+ saBounds = sSpellMgr->GetSpellAreaForQuestEndMapBounds(questId);
if (saBounds.first != saBounds.second)
{
if (!zone || !area)
@@ -16036,25 +16053,108 @@ void Player::SetQuestStatus(uint32 quest_id, QuestStatus status)
UpdateForQuestWorldObjects();
}
-void Player::RemoveActiveQuest(uint32 quest_id)
+QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver)
{
- QuestStatusMap::iterator itr = m_QuestStatus.find(quest_id);
- if (itr != m_QuestStatus.end())
+ QuestRelationBounds qr;
+ QuestRelationBounds qir;
+
+ switch (questgiver->GetTypeId())
{
- m_QuestStatus.erase(itr);
- m_QuestStatusSave[quest_id] = false;
- return;
+ case TYPEID_GAMEOBJECT:
+ {
+ QuestGiverStatus questStatus = QuestGiverStatus(sScriptMgr->GetDialogStatus(this, questgiver->ToGameObject()));
+ if (questStatus != DIALOG_STATUS_SCRIPTED_NO_STATUS)
+ return questStatus;
+ qr = sObjectMgr->GetGOQuestRelationBounds(questgiver->GetEntry());
+ qir = sObjectMgr->GetGOQuestInvolvedRelationBounds(questgiver->GetEntry());
+ break;
+ }
+ case TYPEID_UNIT:
+ {
+ QuestGiverStatus questStatus = QuestGiverStatus(sScriptMgr->GetDialogStatus(this, questgiver->ToCreature()));
+ if (questStatus != DIALOG_STATUS_SCRIPTED_NO_STATUS)
+ return questStatus;
+ qr = sObjectMgr->GetCreatureQuestRelationBounds(questgiver->GetEntry());
+ qir = sObjectMgr->GetCreatureQuestInvolvedRelationBounds(questgiver->GetEntry());
+ break;
+ }
+ default:
+ // it's impossible, but check
+ TC_LOG_ERROR("entities.player.quest", "GetQuestDialogStatus called for unexpected type %u", questgiver->GetTypeId());
+ return DIALOG_STATUS_NONE;
}
-}
-void Player::RemoveRewardedQuest(uint32 quest_id)
-{
- RewardedQuestSet::iterator rewItr = m_RewardedQuests.find(quest_id);
- if (rewItr != m_RewardedQuests.end())
+ QuestGiverStatus result = DIALOG_STATUS_NONE;
+
+ for (QuestRelations::const_iterator i = qir.first; i != qir.second; ++i)
{
- m_RewardedQuests.erase(rewItr);
- m_RewardedQuestsSave[quest_id] = false;
+ QuestGiverStatus result2 = DIALOG_STATUS_NONE;
+ uint32 questId = i->second;
+ Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
+ if (!quest)
+ continue;
+
+ ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK, quest->GetQuestId());
+ if (!sConditionMgr->IsObjectMeetToConditions(this, conditions))
+ continue;
+
+ QuestStatus status = GetQuestStatus(questId);
+ if ((status == QUEST_STATUS_COMPLETE && !GetQuestRewardStatus(questId)) ||
+ (quest->IsAutoComplete() && CanTakeQuest(quest, false)))
+ {
+ if (quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly())
+ result2 = DIALOG_STATUS_REWARD_REP;
+ else
+ result2 = DIALOG_STATUS_REWARD;
+ }
+ else if (status == QUEST_STATUS_INCOMPLETE)
+ result2 = DIALOG_STATUS_INCOMPLETE;
+
+ if (result2 > result)
+ result = result2;
+ }
+
+ for (QuestRelations::const_iterator i = qr.first; i != qr.second; ++i)
+ {
+ QuestGiverStatus result2 = DIALOG_STATUS_NONE;
+ uint32 questId = i->second;
+ Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
+ if (!quest)
+ continue;
+
+ ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK, quest->GetQuestId());
+ if (!sConditionMgr->IsObjectMeetToConditions(this, conditions))
+ continue;
+
+ QuestStatus status = GetQuestStatus(questId);
+ if (status == QUEST_STATUS_NONE)
+ {
+ if (CanSeeStartQuest(quest))
+ {
+ if (SatisfyQuestLevel(quest, false))
+ {
+ if (quest->IsAutoComplete())
+ result2 = DIALOG_STATUS_REWARD_REP;
+ else if (getLevel() <= (GetQuestLevel(quest) + sWorld->getIntConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF)))
+ {
+ if (quest->IsDaily())
+ result2 = DIALOG_STATUS_AVAILABLE_REP;
+ else
+ result2 = DIALOG_STATUS_AVAILABLE;
+ }
+ else
+ result2 = DIALOG_STATUS_LOW_LEVEL_AVAILABLE;
+ }
+ else
+ result2 = DIALOG_STATUS_UNAVAILABLE;
+ }
+ }
+
+ if (result2 > result)
+ result = result2;
}
+
+ return result;
}
// not used in Trinity, but used in scripting code
@@ -17452,8 +17552,9 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
UpdateHonorFields();
m_deathExpireTime = time_t(fields[36].GetUInt32());
- if (m_deathExpireTime > now+MAX_DEATH_COUNT*DEATH_EXPIRE_STEP)
- m_deathExpireTime = now+MAX_DEATH_COUNT*DEATH_EXPIRE_STEP-1;
+
+ if (m_deathExpireTime > now + MAX_DEATH_COUNT * DEATH_EXPIRE_STEP)
+ m_deathExpireTime = now + MAX_DEATH_COUNT * DEATH_EXPIRE_STEP - 1;
// clear channel spell data (if saved at channel spell casting)
SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, 0);
@@ -18507,6 +18608,9 @@ void Player::_LoadGroup(PreparedQueryResult result)
{
if (Group* group = sGroupMgr->GetGroupByDbStoreId((*result)[0].GetUInt32()))
{
+ if (group->IsLeader(GetGUID()))
+ SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GROUP_LEADER);
+
uint8 subgroup = group->GetMemberGroup(GetGUID());
SetGroup(group, subgroup);
if (getLevel() >= LEVELREQUIREMENT_HEROIC)
@@ -18517,6 +18621,9 @@ void Player::_LoadGroup(PreparedQueryResult result)
}
}
}
+
+ if (!GetGroup() || !GetGroup()->IsLeader(GetGUID()))
+ RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GROUP_LEADER);
}
void Player::_LoadBoundInstances(PreparedQueryResult result)
@@ -21298,10 +21405,8 @@ void Player::ContinueTaxiFlight()
void Player::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs)
{
- // last check 2.0.10
- WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+m_spells.size()*8);
- data << uint64(GetGUID());
- data << uint8(0x0); // flags (0x1, 0x2)
+ PacketCooldowns cooldowns;
+ WorldPacket data;
time_t curTime = time(NULL);
for (PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
{
@@ -21324,12 +21429,16 @@ void Player::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs)
if ((idSchoolMask & spellInfo->GetSchoolMask()) && GetSpellCooldownDelay(unSpellId) < unTimeMs)
{
- data << uint32(unSpellId);
- data << uint32(unTimeMs); // in m.secs
+ cooldowns[unSpellId] = unTimeMs;
AddSpellCooldown(unSpellId, 0, curTime + unTimeMs/IN_MILLISECONDS);
}
}
- GetSession()->SendPacket(&data);
+
+ if (!cooldowns.empty())
+ {
+ BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, cooldowns);
+ GetSession()->SendPacket(&data);
+ }
}
void Player::InitDataForForm(bool reapplyMods)
@@ -21487,6 +21596,15 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32
return false;
}
+ if (!(pProto->AllowableClass & getClassMask()) && pProto->Bonding == BIND_WHEN_PICKED_UP && !IsGameMaster())
+ {
+ SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, item, 0);
+ return false;
+ }
+
+ if (!IsGameMaster() && ((pProto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && GetTeam() == ALLIANCE) || (pProto->Flags2 == ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && GetTeam() == HORDE)))
+ return false;
+
Creature* creature = GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR);
if (!creature)
{
@@ -21495,6 +21613,14 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32
return false;
}
+ ConditionList conditions = sConditionMgr->GetConditionsForNpcVendorEvent(creature->GetEntry(), item);
+ if (!sConditionMgr->IsObjectMeetToConditions(this, creature, conditions))
+ {
+ TC_LOG_DEBUG("condition", "BuyItemFromVendor: conditions not met for creature entry %u item %u", creature->GetEntry(), item);
+ SendBuyError(BUY_ERR_CANT_FIND_ITEM, creature, item, 0);
+ return false;
+ }
+
VendorItemData const* vItems = creature->GetVendorItems();
if (!vItems || vItems->Empty())
{
@@ -21789,6 +21915,8 @@ void Player::AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 ite
time_t catrecTime;
time_t recTime;
+ bool needsCooldownPacket = false;
+
// overwrite time for selected category
if (infinityCooldown)
{
@@ -21811,6 +21939,16 @@ void Player::AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 ite
if (catrec > 0 && !(spellInfo->AttributesEx6 & SPELL_ATTR6_IGNORE_CATEGORY_COOLDOWN_MODS))
ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, catrec, spell);
+ if (int32 cooldownMod = GetTotalAuraModifier(SPELL_AURA_MOD_COOLDOWN))
+ {
+ // Apply SPELL_AURA_MOD_COOLDOWN only to own spells
+ if (HasSpell(spellInfo->Id))
+ {
+ needsCooldownPacket = true;
+ rec += cooldownMod * IN_MILLISECONDS; // SPELL_AURA_MOD_COOLDOWN does not affect category cooldows, verified with shaman shocks
+ }
+ }
+
// replace negative cooldowns by 0
if (rec < 0) rec = 0;
if (catrec < 0) catrec = 0;
@@ -21825,8 +21963,17 @@ void Player::AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 ite
// self spell cooldown
if (recTime > 0)
+ {
AddSpellCooldown(spellInfo->Id, itemId, recTime);
+ if (needsCooldownPacket)
+ {
+ WorldPacket data;
+ BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, spellInfo->Id, rec);
+ SendDirectMessage(&data);
+ }
+ }
+
// category spells
if (cat && catrec > 0)
{
@@ -23326,7 +23473,7 @@ void Player::UpdateForQuestWorldObjects()
UpdateData udata;
WorldPacket packet;
- for (ClientGUIDs::iterator itr=m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr)
+ for (ClientGUIDs::iterator itr = m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr)
{
if (IS_GAMEOBJECT_GUID(*itr))
{
@@ -23605,7 +23752,7 @@ uint32 Player::GetResurrectionSpellId()
}
// Used in triggers for check "Only to targets that grant experience or honor" req
-bool Player::isHonorOrXPTarget(Unit* victim)
+bool Player::isHonorOrXPTarget(Unit* victim) const
{
uint8 v_level = victim->getLevel();
uint8 k_grey = Trinity::XP::GetGrayLevel(getLevel());
@@ -23844,7 +23991,7 @@ uint32 Player::GetCorpseReclaimDelay(bool pvp) const
time_t now = time(NULL);
// 0..2 full period
// should be ceil(x)-1 but not floor(x)
- uint64 count = (now < m_deathExpireTime - 1) ? (m_deathExpireTime - 1 - now)/DEATH_EXPIRE_STEP : 0;
+ uint64 count = (now < m_deathExpireTime - 1) ? (m_deathExpireTime - 1 - now) / DEATH_EXPIRE_STEP : 0;
return copseReclaimDelay[count];
}
@@ -23857,65 +24004,66 @@ void Player::UpdateCorpseReclaimDelay()
return;
time_t now = time(NULL);
+
if (now < m_deathExpireTime)
{
// full and partly periods 1..3
- uint64 count = (m_deathExpireTime - now)/DEATH_EXPIRE_STEP +1;
+ uint64 count = (m_deathExpireTime - now) / DEATH_EXPIRE_STEP + 1;
+
if (count < MAX_DEATH_COUNT)
- m_deathExpireTime = now+(count+1)*DEATH_EXPIRE_STEP;
+ m_deathExpireTime = now+(count + 1) * DEATH_EXPIRE_STEP;
else
- m_deathExpireTime = now+MAX_DEATH_COUNT*DEATH_EXPIRE_STEP;
+ m_deathExpireTime = now + MAX_DEATH_COUNT*DEATH_EXPIRE_STEP;
}
else
- m_deathExpireTime = now+DEATH_EXPIRE_STEP;
+ m_deathExpireTime = now + DEATH_EXPIRE_STEP;
}
-void Player::SendCorpseReclaimDelay(bool load)
+int32 Player::CalculateCorpseReclaimDelay(bool load)
{
Corpse* corpse = GetCorpse();
+
if (load && !corpse)
- return;
+ return -1;
- bool pvp;
- if (corpse)
- pvp = (corpse->GetType() == CORPSE_RESURRECTABLE_PVP);
- else
- pvp = (m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH);
+ bool pvp = corpse ? corpse->GetType() == CORPSE_RESURRECTABLE_PVP : m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH;
+
+ uint32 delay;
- time_t delay;
if (load)
{
if (corpse->GetGhostTime() > m_deathExpireTime)
- return;
+ return -1;
+
+ uint64 count = 0;
- uint64 count;
if ((pvp && sWorld->getBoolConfig(CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVP)) ||
(!pvp && sWorld->getBoolConfig(CONFIG_DEATH_CORPSE_RECLAIM_DELAY_PVE)))
{
- count = (m_deathExpireTime-corpse->GetGhostTime())/DEATH_EXPIRE_STEP;
+ count = (m_deathExpireTime - corpse->GetGhostTime()) / DEATH_EXPIRE_STEP;
+
if (count >= MAX_DEATH_COUNT)
- count = MAX_DEATH_COUNT-1;
+ count = MAX_DEATH_COUNT - 1;
}
- else
- count=0;
-
- time_t expected_time = corpse->GetGhostTime()+copseReclaimDelay[count];
+ time_t expected_time = corpse->GetGhostTime() + copseReclaimDelay[count];
time_t now = time(NULL);
+
if (now >= expected_time)
- return;
+ return -1;
- delay = expected_time-now;
+ delay = expected_time - now;
}
else
delay = GetCorpseReclaimDelay(pvp);
- if (!delay)
- return;
+ return delay * IN_MILLISECONDS;
+}
- //! corpse reclaim delay 30 * 1000ms or longer at often deaths
+void Player::SendCorpseReclaimDelay(uint32 delay)
+{
WorldPacket data(SMSG_CORPSE_RECLAIM_DELAY, 4);
- data << uint32(delay*IN_MILLISECONDS);
+ data << uint32(delay);
GetSession()->SendPacket(&data);
}
@@ -24309,7 +24457,7 @@ bool Player::isTotalImmune()
return false;
}
-bool Player::HasTitle(uint32 bitIndex)
+bool Player::HasTitle(uint32 bitIndex) const
{
if (bitIndex > MAX_TITLE_INDEX)
return false;
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index cd73f38823e..2eb740f0a82 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -840,6 +840,7 @@ struct AccessRequirement
{
uint8 levelMin;
uint8 levelMax;
+ uint16 item_level;
uint32 item;
uint32 item2;
uint32 quest_A;
@@ -1382,9 +1383,11 @@ class Player : public Unit, public GridObject<Player>
bool TakeQuestSourceItem(uint32 questId, bool msg);
bool GetQuestRewardStatus(uint32 quest_id) const;
QuestStatus GetQuestStatus(uint32 quest_id) const;
- void SetQuestStatus(uint32 quest_id, QuestStatus status);
- void RemoveActiveQuest(uint32 quest_id);
- void RemoveRewardedQuest(uint32 quest_id);
+ void SetQuestStatus(uint32 questId, QuestStatus status, bool update = true);
+ void RemoveActiveQuest(uint32 questId, bool update = true);
+ void RemoveRewardedQuest(uint32 questId, bool update = true);
+ void SendQuestUpdate(uint32 questId);
+ QuestGiverStatus GetQuestDialogStatus(Object* questGiver);
void SetDailyQuestStatus(uint32 quest_id);
void SetWeeklyQuestStatus(uint32 quest_id);
@@ -1894,7 +1897,7 @@ class Player : public Unit, public GridObject<Player>
bool IsAtRecruitAFriendDistance(WorldObject const* pOther) const;
void RewardPlayerAndGroupAtKill(Unit* victim, bool isBattleGround);
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject* pRewardSource);
- bool isHonorOrXPTarget(Unit* victim);
+ bool isHonorOrXPTarget(Unit* victim) const;
bool GetsRecruitAFriendBonus(bool forXP);
uint8 GetGrantableLevels() { return m_grantableLevels; }
@@ -1936,7 +1939,8 @@ class Player : public Unit, public GridObject<Player>
uint32 GetDeathTimer() const { return m_deathTimer; }
uint32 GetCorpseReclaimDelay(bool pvp) const;
void UpdateCorpseReclaimDelay();
- void SendCorpseReclaimDelay(bool load = false);
+ int32 CalculateCorpseReclaimDelay(bool load = false);
+ void SendCorpseReclaimDelay(uint32 delay);
uint32 GetShieldBlockValue() const; // overwrite Unit version (virtual)
bool CanParry() const { return m_canParry; }
@@ -2262,8 +2266,8 @@ class Player : public Unit, public GridObject<Player>
void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry);
void CompletedAchievement(AchievementEntry const* entry);
- bool HasTitle(uint32 bitIndex);
- bool HasTitle(CharTitlesEntry const* title) { return HasTitle(title->bit_index); }
+ bool HasTitle(uint32 bitIndex) const;
+ bool HasTitle(CharTitlesEntry const* title) const { return HasTitle(title->bit_index); }
void SetTitle(CharTitlesEntry const* title, bool lost = false);
//bool isActiveObject() const { return true; }
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 3de062148e9..52565a2eaa5 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -4484,10 +4484,13 @@ uint32 Unit::GetDoTsByCaster(uint64 casterGUID) const
int32 Unit::GetTotalAuraModifier(AuraType auratype) const
{
+ AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
+ if (mTotalAuraList.empty())
+ return 0;
+
std::map<SpellGroup, int32> SameEffectSpellGroup;
int32 modifier = 0;
- AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup))
modifier += (*i)->GetAmount();
@@ -5668,17 +5671,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
break;
}
}
-
- // Retaliation
- if (dummySpell->SpellFamilyFlags[1] & 0x8)
- {
- // check attack comes not from behind
- if (!HasInArc(M_PI, victim))
- return false;
-
- triggered_spell_id = 22858;
- break;
- }
// Second Wind
if (dummySpell->SpellIconID == 1697)
{
@@ -5708,19 +5700,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
triggered_spell_id = 58374;
break;
}
- // Glyph of Sunder Armor
- if (dummySpell->Id == 58387)
- {
- if (!victim || !victim->IsAlive() || !procSpell)
- return false;
-
- target = SelectNearbyTarget(victim);
- if (!target)
- return false;
-
- triggered_spell_id = 58567;
- break;
- }
break;
}
case SPELLFAMILY_WARLOCK:
@@ -8740,13 +8719,28 @@ ReputationRank Unit::GetReactionTo(Unit const* target) const
if (GetCharmerOrOwnerOrSelf() == target->GetCharmerOrOwnerOrSelf())
return REP_FRIENDLY;
+ Player const* selfPlayerOwner = GetAffectingPlayer();
+ Player const* targetPlayerOwner = target->GetAffectingPlayer();
+
+ // check forced reputation to support SPELL_AURA_FORCE_REACTION
+ if (selfPlayerOwner)
+ {
+ if (FactionTemplateEntry const* targetFactionTemplateEntry = target->GetFactionTemplateEntry())
+ if (ReputationRank const* repRank = selfPlayerOwner->GetReputationMgr().GetForcedRankIfAny(targetFactionTemplateEntry))
+ return *repRank;
+ }
+ else if (targetPlayerOwner)
+ {
+ if (FactionTemplateEntry const* selfFactionTemplateEntry = GetFactionTemplateEntry())
+ if (ReputationRank const* repRank = targetPlayerOwner->GetReputationMgr().GetForcedRankIfAny(selfFactionTemplateEntry))
+ return *repRank;
+ }
+
+
if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE))
{
if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE))
{
- Player const* selfPlayerOwner = GetAffectingPlayer();
- Player const* targetPlayerOwner = target->GetAffectingPlayer();
-
if (selfPlayerOwner && targetPlayerOwner)
{
// always friendly to other unit controlled by player, or to the player himself
@@ -9365,9 +9359,7 @@ void Unit::SetMinion(Minion *minion, bool apply)
}
if (minion->m_Properties && minion->m_Properties->Type == SUMMON_TYPE_MINIPET)
- {
SetCritterGUID(minion->GetGUID());
- }
// PvP, FFAPvP
minion->SetByteValue(UNIT_FIELD_BYTES_2, 1, GetByteValue(UNIT_FIELD_BYTES_2, 1));
@@ -13274,12 +13266,14 @@ void Unit::SetLevel(uint8 lvl)
{
SetUInt32Value(UNIT_FIELD_LEVEL, lvl);
- // group update
- if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->GetGroup())
- ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_LEVEL);
+ if (Player* player = ToPlayer())
+ {
+ // group update
+ if (player->GetGroup())
+ player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_LEVEL);
- if (GetTypeId() == TYPEID_PLAYER)
- sWorld->UpdateCharacterNameDataLevel(ToPlayer()->GetGUIDLow(), lvl);
+ sWorld->UpdateCharacterNameDataLevel(GetGUIDLow(), lvl);
+ }
}
void Unit::SetHealth(uint32 val)
@@ -17469,19 +17463,21 @@ bool Unit::SetHover(bool enable, bool /*packetOnly = false*/)
if (enable == HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
return false;
+ float hoverHeight = GetFloatValue(UNIT_FIELD_HOVERHEIGHT);
+
if (enable)
{
//! No need to check height on ascent
AddUnitMovementFlag(MOVEMENTFLAG_HOVER);
- if (float hh = GetFloatValue(UNIT_FIELD_HOVERHEIGHT))
- UpdateHeight(GetPositionZ() + hh);
+ if (hoverHeight)
+ UpdateHeight(GetPositionZ() + hoverHeight);
}
else
{
RemoveUnitMovementFlag(MOVEMENTFLAG_HOVER);
- if (float hh = GetFloatValue(UNIT_FIELD_HOVERHEIGHT))
+ if (hoverHeight)
{
- float newZ = GetPositionZ() - hh;
+ float newZ = GetPositionZ() - hoverHeight;
UpdateAllowedPositionZ(GetPositionX(), GetPositionY(), newZ);
UpdateHeight(newZ);
}
@@ -17663,3 +17659,24 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target)
updateMask.AppendToPacket(data);
data->append(fieldBuffer);
}
+
+void Unit::BuildCooldownPacket(WorldPacket& data, uint8 flags, uint32 spellId, uint32 cooldown)
+{
+ data.Initialize(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
+ data << uint64(GetGUID());
+ data << uint8(flags);
+ data << uint32(spellId);
+ data << uint32(cooldown);
+}
+
+void Unit::BuildCooldownPacket(WorldPacket& data, uint8 flags, PacketCooldowns const& cooldowns)
+{
+ data.Initialize(SMSG_SPELL_COOLDOWN, 8 + 1 + (4 + 4) * cooldowns.size());
+ data << uint64(GetGUID());
+ data << uint8(flags);
+ for (UNORDERED_MAP<uint32, uint32>::const_iterator itr = cooldowns.begin(); itr != cooldowns.end(); ++itr)
+ {
+ data << uint32(itr->first);
+ data << uint32(itr->second);
+ }
+}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 151f20d09f9..751bfcb8126 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -683,7 +683,8 @@ enum NPCFlags
UNIT_NPC_FLAG_STABLEMASTER = 0x00400000, // 100%
UNIT_NPC_FLAG_GUILD_BANKER = 0x00800000, // cause client to send 997 opcode
UNIT_NPC_FLAG_SPELLCLICK = 0x01000000, // cause client to send 1015 opcode (spell click)
- UNIT_NPC_FLAG_PLAYER_VEHICLE = 0x02000000 // players with mounts that have vehicle data should have it set
+ UNIT_NPC_FLAG_PLAYER_VEHICLE = 0x02000000, // players with mounts that have vehicle data should have it set
+ UNIT_NPC_FLAG_MAILBOX = 0x04000000 //
};
enum MovementFlags
@@ -1232,6 +1233,16 @@ enum PlayerTotemType
SUMMON_TYPE_TOTEM_AIR = 83
};
+/// Spell cooldown flags sent in SMSG_SPELL_COOLDOWN
+enum SpellCooldownFlags
+{
+ SPELL_COOLDOWN_FLAG_NONE = 0x0,
+ SPELL_COOLDOWN_FLAG_INCLUDE_GCD = 0x1, ///< Starts GCD in addition to normal cooldown specified in the packet
+ SPELL_COOLDOWN_FLAG_INCLUDE_EVENT_COOLDOWNS = 0x2 ///< Starts GCD for spells that should start their cooldown on events, requires SPELL_COOLDOWN_FLAG_INCLUDE_GCD set
+};
+
+typedef UNORDERED_MAP<uint32, uint32> PacketCooldowns;
+
// delay time next attack to prevent client attack animation problems
#define ATTACK_DISPLAY_DELAY 200
#define MAX_PLAYER_STEALTH_DETECT_RANGE 30.0f // max distance for detection targets by player
@@ -1564,6 +1575,8 @@ class Unit : public WorldObject
void SetAuraStack(uint32 spellId, Unit* target, uint32 stack);
void SendPlaySpellVisual(uint32 id);
void SendPlaySpellImpact(uint64 guid, uint32 id);
+ void BuildCooldownPacket(WorldPacket& data, uint8 flags, uint32 spellId, uint32 cooldown);
+ void BuildCooldownPacket(WorldPacket& data, uint8 flags, PacketCooldowns const& cooldowns);
void DeMorph();
@@ -2260,12 +2273,23 @@ namespace Trinity
{
public:
PowerPctOrderPred(Powers power, bool ascending = true) : _power(power), _ascending(ascending) { }
- bool operator() (Unit const* a, Unit const* b) const
+
+ bool operator()(WorldObject const* objA, WorldObject const* objB) const
+ {
+ Unit const* a = objA->ToUnit();
+ Unit const* b = objB->ToUnit();
+ float rA = (a && a->GetMaxPower(_power)) ? float(a->GetPower(_power)) / float(a->GetMaxPower(_power)) : 0.0f;
+ float rB = (b && b->GetMaxPower(_power)) ? float(b->GetPower(_power)) / float(b->GetMaxPower(_power)) : 0.0f;
+ return _ascending ? rA < rB : rA > rB;
+ }
+
+ bool operator()(Unit const* a, Unit const* b) const
{
float rA = a->GetMaxPower(_power) ? float(a->GetPower(_power)) / float(a->GetMaxPower(_power)) : 0.0f;
float rB = b->GetMaxPower(_power) ? float(b->GetPower(_power)) / float(b->GetMaxPower(_power)) : 0.0f;
return _ascending ? rA < rB : rA > rB;
}
+
private:
Powers const _power;
bool const _ascending;
@@ -2276,12 +2300,23 @@ namespace Trinity
{
public:
HealthPctOrderPred(bool ascending = true) : _ascending(ascending) { }
+
+ bool operator()(WorldObject const* objA, WorldObject const* objB) const
+ {
+ Unit const* a = objA->ToUnit();
+ Unit const* b = objB->ToUnit();
+ float rA = (a && a->GetMaxHealth()) ? float(a->GetHealth()) / float(a->GetMaxHealth()) : 0.0f;
+ float rB = (b && b->GetMaxHealth()) ? float(b->GetHealth()) / float(b->GetMaxHealth()) : 0.0f;
+ return _ascending ? rA < rB : rA > rB;
+ }
+
bool operator() (Unit const* a, Unit const* b) const
{
float rA = a->GetMaxHealth() ? float(a->GetHealth()) / float(a->GetMaxHealth()) : 0.0f;
float rB = b->GetMaxHealth() ? float(b->GetHealth()) / float(b->GetMaxHealth()) : 0.0f;
return _ascending ? rA < rB : rA > rB;
}
+
private:
bool const _ascending;
};
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 04f3395653d..c5c97e74777 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -705,12 +705,6 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo)
cInfo->Entry, cInfo->type, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->type);
}
- if (cInfo->type_flags != difficultyInfo->type_flags)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, type_flags %u) has different `type_flags` in difficulty %u mode (Entry: %u, type_flags %u).",
- cInfo->Entry, cInfo->type_flags, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->type_flags);
- }
-
if (!cInfo->VehicleId && difficultyInfo->VehicleId)
{
TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, VehicleId %u) has different `VehicleId` in difficulty %u mode (Entry: %u, VehicleId %u).",
@@ -6012,8 +6006,9 @@ void ObjectMgr::LoadAccessRequirements()
_accessRequirementStore.clear(); // need for reload case
}
- // 0 1 2 3 4 5 6 7 8 9
- QueryResult result = WorldDatabase.Query("SELECT mapid, difficulty, level_min, level_max, item, item2, quest_done_A, quest_done_H, completed_achievement, quest_failed_text FROM access_requirement");
+ // 0 1 2 3 4 5 6 7 8 9 10
+ QueryResult result = WorldDatabase.Query("SELECT mapid, difficulty, level_min, level_max, item_level, item, item2, quest_done_A, quest_done_H, completed_achievement, quest_failed_text FROM access_requirement");
+
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 access requirement definitions. DB table `access_requirement` is empty.");
@@ -6036,12 +6031,13 @@ void ObjectMgr::LoadAccessRequirements()
ar->levelMin = fields[2].GetUInt8();
ar->levelMax = fields[3].GetUInt8();
- ar->item = fields[4].GetUInt32();
- ar->item2 = fields[5].GetUInt32();
- ar->quest_A = fields[6].GetUInt32();
- ar->quest_H = fields[7].GetUInt32();
- ar->achievement = fields[8].GetUInt32();
- ar->questFailedText = fields[9].GetString();
+ ar->item_level = fields[4].GetUInt16();
+ ar->item = fields[5].GetUInt32();
+ ar->item2 = fields[6].GetUInt32();
+ ar->quest_A = fields[7].GetUInt32();
+ ar->quest_H = fields[8].GetUInt32();
+ ar->achievement = fields[9].GetUInt32();
+ ar->questFailedText = fields[10].GetString();
if (ar->item)
{
@@ -7510,6 +7506,10 @@ void ObjectMgr::LoadGameObjectForQuests()
{
switch (itr->second.type)
{
+ case GAMEOBJECT_TYPE_QUESTGIVER:
+ _gameObjectForQuestStore.insert(itr->second.entry);
+ ++count;
+ break;
case GAMEOBJECT_TYPE_CHEST:
{
// scan GO chest with loot including quest items
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index f5138845012..319b7b589b9 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -835,26 +835,6 @@ namespace Trinity
float i_range;
};
- class AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck
- {
- public:
- AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck(Unit const* funit, float range)
- : i_funit(funit), i_range(range) { }
-
- bool operator()(const Unit* u)
- {
- return u->IsAlive()
- && i_funit->IsWithinDistInMap(u, i_range)
- && !i_funit->IsFriendlyTo(u)
- && i_funit->IsValidAttackTarget(u)
- && u->GetCreatureType() != CREATURE_TYPE_CRITTER
- && i_funit->CanSeeOrDetect(u);
- }
- private:
- Unit const* i_funit;
- float i_range;
- };
-
class CreatureWithDbGUIDCheck
{
public:
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 354f00a9e91..a3fee2d52aa 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -99,6 +99,7 @@ bool Group::Create(Player* leader)
m_guid = MAKE_NEW_GUID(lowguid, 0, HIGHGUID_GROUP);
m_leaderGuid = leaderGuid;
m_leaderName = leader->GetName();
+ leader->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GROUP_LEADER);
if (isBGGroup() || isBFGroup())
m_groupType = GROUPTYPE_BGRAID;
@@ -666,6 +667,10 @@ void Group::ChangeLeader(uint64 newLeaderGuid)
CharacterDatabase.CommitTransaction(trans);
}
+ if (Player* oldLeader = ObjectAccessor::FindPlayer(m_leaderGuid))
+ oldLeader->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GROUP_LEADER);
+
+ newLeader->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GROUP_LEADER);
m_leaderGuid = newLeader->GetGUID();
m_leaderName = newLeader->GetName();
ToggleGroupMemberFlag(slot, MEMBER_FLAG_ASSISTANT, false);
diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp
index fba575ee84e..45d4d221d06 100644
--- a/src/server/game/Handlers/CalendarHandler.cpp
+++ b/src/server/game/Handlers/CalendarHandler.cpp
@@ -235,18 +235,20 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData)
recvData.ReadPackedTime(unkPackedTime);
recvData >> flags;
- CalendarEvent* calendarEvent = new CalendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId,
+ CalendarEvent calendarEvent(sCalendarMgr->GetFreeEventId(), guid, 0, CalendarEventType(type), dungeonId,
time_t(eventPackedTime), flags, time_t(unkPackedTime), title, description);
- if (calendarEvent->IsGuildEvent() || calendarEvent->IsGuildAnnouncement())
+ if (calendarEvent.IsGuildEvent() || calendarEvent.IsGuildAnnouncement())
if (Player* creator = ObjectAccessor::FindPlayer(guid))
- calendarEvent->SetGuildId(creator->GetGuildId());
+ calendarEvent.SetGuildId(creator->GetGuildId());
- if (calendarEvent->IsGuildAnnouncement())
+ if (calendarEvent.IsGuildAnnouncement())
{
// 946684800 is 01/01/2000 00:00:00 - default response time
- CalendarInvite* invite = new CalendarInvite(0, calendarEvent->GetEventId(), 0, guid, 946684800, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, "");
- sCalendarMgr->AddInvite(calendarEvent, invite);
+ CalendarInvite invite(0, calendarEvent.GetEventId(), 0, guid, 946684800, CALENDAR_STATUS_NOT_SIGNED_UP, CALENDAR_RANK_PLAYER, "");
+ // WARNING: By passing pointer to a local variable, the underlying method(s) must NOT perform any kind
+ // of storage of the pointer as it will lead to memory corruption
+ sCalendarMgr->AddInvite(&calendarEvent, &invite);
}
else
{
@@ -262,12 +264,12 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData)
recvData >> status >> rank;
// 946684800 is 01/01/2000 00:00:00 - default response time
- CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent->GetEventId(), invitee, guid, 946684800, CalendarInviteStatus(status), CalendarModerationRank(rank), "");
- sCalendarMgr->AddInvite(calendarEvent, invite);
+ CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), calendarEvent.GetEventId(), invitee, guid, 946684800, CalendarInviteStatus(status), CalendarModerationRank(rank), "");
+ sCalendarMgr->AddInvite(&calendarEvent, invite);
}
}
- sCalendarMgr->AddEvent(calendarEvent, CALENDAR_SENDTYPE_ADD);
+ sCalendarMgr->AddEvent(new CalendarEvent(calendarEvent, calendarEvent.GetEventId()), CALENDAR_SENDTYPE_ADD);
}
void WorldSession::HandleCalendarUpdateEvent(WorldPacket& recvData)
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 94e9306b29f..333d4d893cd 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -1027,6 +1027,9 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
m_playerLoading = false;
+ // Handle Login-Achievements (should be handled after loading)
+ _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN, 1);
+
sScriptMgr->OnPlayerLogin(pCurrChar);
delete holder;
}
@@ -1590,9 +1593,6 @@ void WorldSession::HandleEquipmentSetDelete(WorldPacket &recvData)
void WorldSession::HandleEquipmentSetUse(WorldPacket &recvData)
{
- if (_player->IsInCombat())
- return;
-
TC_LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_USE");
for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
@@ -1609,6 +1609,10 @@ void WorldSession::HandleEquipmentSetUse(WorldPacket &recvData)
if (itemGuid == 1)
continue;
+ // Only equip weapons in combat
+ if (_player->IsInCombat() && i != EQUIPMENT_SLOT_MAINHAND && i != EQUIPMENT_SLOT_OFFHAND && i != EQUIPMENT_SLOT_RANGED)
+ continue;
+
Item* item = _player->GetItemByGuid(itemGuid);
uint16 dstpos = i | (INVENTORY_SLOT_BAG_0 << 8);
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index b45840ab190..fbc78564ea5 100644
--- a/src/server/game/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
@@ -55,6 +55,14 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
return;
}
+ if (lang == LANG_UNIVERSAL && type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
+ {
+ TC_LOG_ERROR("network", "CMSG_MESSAGECHAT: Possible hacking-attempt: %s tried to send a message in universal language", GetPlayerInfo().c_str());
+ SendNotification(LANG_UNKNOWN_LANGUAGE);
+ recvData.rfinish();
+ return;
+ }
+
Player* sender = GetPlayer();
//TC_LOG_DEBUG("CHAT: packet received. type %u, lang %u", type, lang);
@@ -67,6 +75,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
recvData.rfinish();
return;
}
+
if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id))
{
// also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language)
@@ -242,6 +251,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
case CHAT_MSG_EMOTE:
case CHAT_MSG_YELL:
{
+ // Prevent cheating
+ if (!sender->IsAlive())
+ return;
+
if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ))
{
SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ));
@@ -302,18 +315,18 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
Group* group = GetPlayer()->GetOriginalGroup();
if (!group)
{
- group = _player->GetGroup();
+ group = sender->GetGroup();
if (!group || group->isBGGroup())
return;
}
- if (type == CHAT_MSG_PARTY_LEADER && !group->IsLeader(_player->GetGUID()))
+ if (type == CHAT_MSG_PARTY_LEADER && !group->IsLeader(sender->GetGUID()))
return;
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
WorldPacket data;
- ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), _player, NULL, msg);
+ ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, NULL, msg);
group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID()));
} break;
case CHAT_MSG_GUILD:
@@ -354,7 +367,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
WorldPacket data;
- ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), _player, NULL, msg);
+ ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), sender, NULL, msg);
group->BroadcastPacket(&data, false);
} break;
case CHAT_MSG_RAID_LEADER:
@@ -364,14 +377,14 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
if (!group)
{
group = GetPlayer()->GetGroup();
- if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(_player->GetGUID()))
+ if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(sender->GetGUID()))
return;
}
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
WorldPacket data;
- ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), _player, NULL, msg);
+ ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, NULL, msg);
group->BroadcastPacket(&data, false);
} break;
case CHAT_MSG_RAID_WARNING:
@@ -384,7 +397,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
WorldPacket data;
//in battleground, raid warning is sent only to players in battleground - code is ok
- ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, Language(lang), _player, NULL, msg);
+ ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg);
group->BroadcastPacket(&data, false);
} break;
case CHAT_MSG_BATTLEGROUND:
@@ -397,7 +410,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
WorldPacket data;
- ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), _player, NULL, msg);
+ ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, NULL, msg);
group->BroadcastPacket(&data, false);
} break;
case CHAT_MSG_BATTLEGROUND_LEADER:
@@ -410,74 +423,74 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
WorldPacket data;
- ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), _player, NULL, msg);;
+ ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), sender, NULL, msg);;
group->BroadcastPacket(&data, false);
} break;
case CHAT_MSG_CHANNEL:
{
if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ))
{
- if (_player->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ))
+ if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ))
{
SendNotification(GetTrinityString(LANG_CHANNEL_REQ), sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ));
return;
}
}
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(_player->GetTeam()))
+ if (ChannelMgr* cMgr = ChannelMgr::forTeam(sender->GetTeam()))
{
- if (Channel* chn = cMgr->GetChannel(channel, _player))
+ if (Channel* chn = cMgr->GetChannel(channel, sender))
{
- sScriptMgr->OnPlayerChat(_player, type, lang, msg, chn);
- chn->Say(_player->GetGUID(), msg.c_str(), lang);
+ sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn);
+ chn->Say(sender->GetGUID(), msg.c_str(), lang);
}
}
} break;
case CHAT_MSG_AFK:
{
- if (!_player->IsInCombat())
+ if (!sender->IsInCombat())
{
- if (_player->isAFK()) // Already AFK
+ if (sender->isAFK()) // Already AFK
{
if (msg.empty())
- _player->ToggleAFK(); // Remove AFK
+ sender->ToggleAFK(); // Remove AFK
else
- _player->autoReplyMsg = msg; // Update message
+ sender->autoReplyMsg = msg; // Update message
}
else // New AFK mode
{
- _player->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_AFK_DEFAULT) : msg;
+ sender->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_AFK_DEFAULT) : msg;
- if (_player->isDND())
- _player->ToggleDND();
+ if (sender->isDND())
+ sender->ToggleDND();
- _player->ToggleAFK();
+ sender->ToggleAFK();
}
- sScriptMgr->OnPlayerChat(_player, type, lang, msg);
+ sScriptMgr->OnPlayerChat(sender, type, lang, msg);
}
break;
}
case CHAT_MSG_DND:
{
- if (_player->isDND()) // Already DND
+ if (sender->isDND()) // Already DND
{
if (msg.empty())
- _player->ToggleDND(); // Remove DND
+ sender->ToggleDND(); // Remove DND
else
- _player->autoReplyMsg = msg; // Update message
+ sender->autoReplyMsg = msg; // Update message
}
else // New DND mode
{
- _player->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : msg;
+ sender->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : msg;
- if (_player->isAFK())
- _player->ToggleAFK();
+ if (sender->isAFK())
+ sender->ToggleAFK();
- _player->ToggleDND();
+ sender->ToggleDND();
}
- sScriptMgr->OnPlayerChat(_player, type, lang, msg);
+ sScriptMgr->OnPlayerChat(sender, type, lang, msg);
break;
}
default:
diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp
index 4fd912298ec..f3a1803dfca 100644
--- a/src/server/game/Handlers/LootHandler.cpp
+++ b/src/server/game/Handlers/LootHandler.cpp
@@ -223,7 +223,7 @@ void WorldSession::HandleLootOpcode(WorldPacket& recvData)
recvData >> guid;
// Check possible cheat
- if (!_player->IsAlive())
+ if (!GetPlayer()->IsAlive() || !IS_CRE_OR_VEH_GUID(guid))
return;
GetPlayer()->SendLoot(guid, LOOT_CORPSE);
diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp
index 5ab24f44a22..10ef7810d1d 100644
--- a/src/server/game/Handlers/MailHandler.cpp
+++ b/src/server/game/Handlers/MailHandler.cpp
@@ -29,6 +29,32 @@
#include "Item.h"
#include "AccountMgr.h"
+bool WorldSession::CanOpenMailBox(uint64 guid)
+{
+ if (guid == _player->GetGUID())
+ {
+ if (!HasPermission(rbac::RBAC_PERM_COMMAND_MAILBOX))
+ {
+ TC_LOG_WARN("cheat", "%s attempt open mailbox in cheating way.", _player->GetName().c_str());
+ return false;
+ }
+ }
+ else if (IS_GAMEOBJECT_GUID(guid))
+ {
+ if (!_player->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_MAILBOX))
+ return false;
+ }
+ else if (IS_CRE_OR_VEH_OR_PET_GUID(guid))
+ {
+ if (!_player->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_MAILBOX))
+ return false;
+ }
+ else
+ return false;
+
+ return true;
+}
+
void WorldSession::HandleSendMail(WorldPacket& recvData)
{
uint64 mailbox, unk3;
@@ -62,7 +88,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
// packet read complete, now do check
- if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ if (!CanOpenMailBox(mailbox))
return;
if (receiverName.empty())
@@ -307,7 +333,7 @@ void WorldSession::HandleMailMarkAsRead(WorldPacket& recvData)
recvData >> mailbox;
recvData >> mailId;
- if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ if (!CanOpenMailBox(mailbox))
return;
Player* player = _player;
@@ -331,7 +357,7 @@ void WorldSession::HandleMailDelete(WorldPacket& recvData)
recvData >> mailId;
recvData.read_skip<uint32>(); // mailTemplateId
- if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ if (!CanOpenMailBox(mailbox))
return;
Mail* m = _player->GetMail(mailId);
@@ -359,7 +385,7 @@ void WorldSession::HandleMailReturnToSender(WorldPacket& recvData)
recvData >> mailId;
recvData.read_skip<uint64>(); // original sender GUID for return to, not used
- if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ if (!CanOpenMailBox(mailbox))
return;
Player* player = _player;
@@ -424,7 +450,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData)
recvData >> mailId;
recvData >> itemId; // item guid low
- if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ if (!CanOpenMailBox(mailbox))
return;
Player* player = _player;
@@ -518,7 +544,7 @@ void WorldSession::HandleMailTakeMoney(WorldPacket& recvData)
recvData >> mailbox;
recvData >> mailId;
- if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ if (!CanOpenMailBox(mailbox))
return;
Player* player = _player;
@@ -555,7 +581,7 @@ void WorldSession::HandleGetMailList(WorldPacket& recvData)
uint64 mailbox;
recvData >> mailbox;
- if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ if (!CanOpenMailBox(mailbox))
return;
Player* player = _player;
@@ -678,7 +704,7 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket& recvData)
recvData >> mailbox;
recvData >> mailId;
- if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
+ if (!CanOpenMailBox(mailbox))
return;
Player* player = _player;
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 8b92706bd06..60f4fb09c28 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -734,34 +734,34 @@ void WorldSession::HandleReclaimCorpseOpcode(WorldPacket& recvData)
uint64 guid;
recvData >> guid;
- if (GetPlayer()->IsAlive())
+ if (_player->IsAlive())
return;
// do not allow corpse reclaim in arena
- if (GetPlayer()->InArena())
+ if (_player->InArena())
return;
// body not released yet
- if (!GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
+ if (!_player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
return;
- Corpse* corpse = GetPlayer()->GetCorpse();
+ Corpse* corpse = _player->GetCorpse();
if (!corpse)
return;
// prevent resurrect before 30-sec delay after body release not finished
- if (time_t(corpse->GetGhostTime() + GetPlayer()->GetCorpseReclaimDelay(corpse->GetType() == CORPSE_RESURRECTABLE_PVP)) > time_t(time(NULL)))
+ if (time_t(corpse->GetGhostTime() + _player->GetCorpseReclaimDelay(corpse->GetType() == CORPSE_RESURRECTABLE_PVP)) > time_t(time(NULL)))
return;
- if (!corpse->IsWithinDistInMap(GetPlayer(), CORPSE_RECLAIM_RADIUS, true))
+ if (!corpse->IsWithinDistInMap(_player, CORPSE_RECLAIM_RADIUS, true))
return;
// resurrect
- GetPlayer()->ResurrectPlayer(GetPlayer()->InBattleground() ? 1.0f : 0.5f);
+ _player->ResurrectPlayer(_player->InBattleground() ? 1.0f : 0.5f);
// spawn bones
- GetPlayer()->SpawnCorpseBones();
+ _player->SpawnCorpseBones();
}
void WorldSession::HandleResurrectResponseOpcode(WorldPacket& recvData)
@@ -1135,7 +1135,6 @@ void WorldSession::HandleMoveRootAck(WorldPacket& recvData)
void WorldSession::HandleSetActionBarToggles(WorldPacket& recvData)
{
uint8 actionBar;
-
recvData >> actionBar;
if (!GetPlayer()) // ignore until not logged (check needed because STATUS_AUTHED)
diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp
index df6703980d1..fc14797ea94 100644
--- a/src/server/game/Handlers/NPCHandler.cpp
+++ b/src/server/game/Handlers/NPCHandler.cpp
@@ -103,6 +103,13 @@ void WorldSession::SendShowBank(uint64 guid)
SendPacket(&data);
}
+void WorldSession::SendShowMailBox(uint64 guid)
+{
+ WorldPacket data(SMSG_SHOW_MAILBOX, 8);
+ data << guid;
+ SendPacket(&data);
+}
+
void WorldSession::HandleTrainerListOpcode(WorldPacket& recvData)
{
uint64 guid;
@@ -383,7 +390,6 @@ void WorldSession::HandleSpiritHealerActivateOpcode(WorldPacket& recvData)
TC_LOG_DEBUG("network", "WORLD: CMSG_SPIRIT_HEALER_ACTIVATE");
uint64 guid;
-
recvData >> guid;
Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_SPIRITHEALER);
@@ -403,7 +409,6 @@ void WorldSession::HandleSpiritHealerActivateOpcode(WorldPacket& recvData)
void WorldSession::SendSpiritResurrect()
{
_player->ResurrectPlayer(0.5f, true);
-
_player->DurabilityLossAll(0.25f, true);
// get corpse nearest graveyard
diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp
index e8d43b55fd8..d4dc7a9ab0d 100644
--- a/src/server/game/Handlers/QuestHandler.cpp
+++ b/src/server/game/Handlers/QuestHandler.cpp
@@ -38,42 +38,34 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recvData)
recvData >> guid;
uint32 questStatus = DIALOG_STATUS_NONE;
- Object* questgiver = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
- if (!questgiver)
+ Object* questGiver = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT);
+ if (!questGiver)
{
TC_LOG_INFO("network", "Error in CMSG_QUESTGIVER_STATUS_QUERY, called for non-existing questgiver (Typeid: %u GUID: %u)", GuidHigh2TypeId(GUID_HIPART(guid)), GUID_LOPART(guid));
return;
}
- switch (questgiver->GetTypeId())
+ switch (questGiver->GetTypeId())
{
case TYPEID_UNIT:
{
- TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for npc, guid = %u", questgiver->GetGUIDLow());
- Creature* cr_questgiver = questgiver->ToCreature();
- if (!cr_questgiver->IsHostileTo(_player)) // do not show quest status to enemies
- {
- questStatus = sScriptMgr->GetDialogStatus(_player, cr_questgiver);
- if (questStatus == DIALOG_STATUS_SCRIPTED_NO_STATUS)
- questStatus = getDialogStatus(_player, cr_questgiver);
- }
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for npc, guid = %u", questGiver->GetGUIDLow());
+ if (!questGiver->ToCreature()->IsHostileTo(_player)) // do not show quest status to enemies
+ questStatus = _player->GetQuestDialogStatus(questGiver);
break;
}
case TYPEID_GAMEOBJECT:
{
- TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject guid = %u", questgiver->GetGUIDLow());
- GameObject* go_questgiver = questgiver->ToGameObject();
- questStatus = sScriptMgr->GetDialogStatus(_player, go_questgiver);
- if (questStatus == DIALOG_STATUS_SCRIPTED_NO_STATUS)
- questStatus = getDialogStatus(_player, go_questgiver);
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject guid = %u", questGiver->GetGUIDLow());
+ questStatus = _player->GetQuestDialogStatus(questGiver);
break;
}
default:
- TC_LOG_ERROR("network", "QuestGiver called for unexpected type %u", questgiver->GetTypeId());
+ TC_LOG_ERROR("network", "QuestGiver called for unexpected type %u", questGiver->GetTypeId());
break;
}
- //inform client about status of quest
+ // inform client about status of quest
_player->PlayerTalkClass->SendQuestGiverStatus(uint8(questStatus), guid);
}
@@ -174,7 +166,7 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData)
if (_player->CanAddQuest(quest, true))
{
- _player->AddQuest(quest, object);
+ _player->AddQuestAndCheckCompletion(quest, object);
if (quest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT))
{
@@ -191,7 +183,7 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData)
{
player->SetDivider(_player->GetGUID());
- //need confirmation that any gossip window will close
+ // need confirmation that any gossip window will close
player->PlayerTalkClass->SendCloseGossip();
_player->SendQuestConfirmAccept(quest, player);
@@ -200,45 +192,6 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData)
}
}
- if (_player->CanCompleteQuest(questId))
- _player->CompleteQuest(questId);
-
- switch (object->GetTypeId())
- {
- case TYPEID_UNIT:
- sScriptMgr->OnQuestAccept(_player, (object->ToCreature()), quest);
- object->ToCreature()->AI()->sQuestAccept(_player, quest);
- break;
- case TYPEID_ITEM:
- case TYPEID_CONTAINER:
- {
- Item* item = (Item*)object;
- sScriptMgr->OnQuestAccept(_player, item, quest);
-
- // destroy not required for quest finish quest starting item
- bool destroyItem = true;
- for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
- {
- if (quest->RequiredItemId[i] == item->GetEntry() && item->GetTemplate()->MaxCount > 0)
- {
- destroyItem = false;
- break;
- }
- }
-
- if (destroyItem)
- _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
-
- break;
- }
- case TYPEID_GAMEOBJECT:
- sScriptMgr->OnQuestAccept(_player, object->ToGameObject(), quest);
- object->ToGameObject()->AI()->QuestAccept(_player, quest);
- break;
- default:
- break;
- }
-
_player->PlayerTalkClass->SendCloseGossip();
if (quest->GetSrcSpell() > 0)
@@ -314,7 +267,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData)
TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u", uint32(GUID_LOPART(guid)), questId, reward);
- Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
+ Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT);
if (!object || !object->hasInvolvedQuest(questId))
return;
@@ -338,7 +291,9 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData)
switch (object->GetTypeId())
{
case TYPEID_UNIT:
- if (!(sScriptMgr->OnQuestReward(_player, (object->ToCreature()), quest, reward)))
+ {
+ Creature* questgiver = object->ToCreature();
+ if (!sScriptMgr->OnQuestReward(_player, questgiver, quest, reward))
{
// Send next quest
if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
@@ -349,11 +304,14 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData)
_player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
}
- (object->ToCreature())->AI()->sQuestReward(_player, quest, reward);
+ questgiver->AI()->sQuestReward(_player, quest, reward);
}
break;
+ }
case TYPEID_GAMEOBJECT:
- if (!sScriptMgr->OnQuestReward(_player, ((GameObject*)object), quest, reward))
+ {
+ GameObject* questGiver = object->ToGameObject();
+ if (!sScriptMgr->OnQuestReward(_player, questGiver, quest, reward))
{
// Send next quest
if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
@@ -364,9 +322,10 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData)
_player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
}
- object->ToGameObject()->AI()->QuestReward(_player, quest, reward);
+ questGiver->AI()->QuestReward(_player, quest, reward);
}
break;
+ }
default:
break;
}
@@ -384,7 +343,7 @@ void WorldSession::HandleQuestgiverRequestRewardOpcode(WorldPacket& recvData)
TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_REQUEST_REWARD npc = %u, quest = %u", uint32(GUID_LOPART(guid)), questId);
- Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
+ Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT);
if (!object || !object->hasInvolvedQuest(questId))
return;
@@ -468,17 +427,16 @@ void WorldSession::HandleQuestConfirmAccept(WorldPacket& recvData)
TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = %u", questId);
- if (const Quest* quest = sObjectMgr->GetQuestTemplate(questId))
+ if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
{
if (!quest->HasFlag(QUEST_FLAGS_PARTY_ACCEPT))
return;
- Player* pOriginalPlayer = ObjectAccessor::FindPlayer(_player->GetDivider());
-
- if (!pOriginalPlayer)
+ Player* originalPlayer = ObjectAccessor::FindPlayer(_player->GetDivider());
+ if (!originalPlayer)
return;
- if (!_player->IsInSameRaidWith(pOriginalPlayer))
+ if (!_player->IsInSameRaidWith(originalPlayer))
return;
if (_player->CanAddQuest(quest, true))
@@ -501,7 +459,7 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recvData)
if (!quest)
return;
- Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
+ Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT);
if (!object || !object->hasInvolvedQuest(questId))
return;
@@ -638,104 +596,6 @@ void WorldSession::HandleQuestPushResult(WorldPacket& recvPacket)
}
}
-uint32 WorldSession::getDialogStatus(Player* player, Object* questgiver)
-{
- uint32 result = DIALOG_STATUS_NONE;
-
- QuestRelationBounds qr;
- QuestRelationBounds qir;
-
- switch (questgiver->GetTypeId())
- {
- case TYPEID_GAMEOBJECT:
- {
- qr = sObjectMgr->GetGOQuestRelationBounds(questgiver->GetEntry());
- qir = sObjectMgr->GetGOQuestInvolvedRelationBounds(questgiver->GetEntry());
- break;
- }
- case TYPEID_UNIT:
- {
- qr = sObjectMgr->GetCreatureQuestRelationBounds(questgiver->GetEntry());
- qir = sObjectMgr->GetCreatureQuestInvolvedRelationBounds(questgiver->GetEntry());
- break;
- }
- default:
- //its imposible, but check ^)
- TC_LOG_ERROR("network", "Warning: GetDialogStatus called for unexpected type %u", questgiver->GetTypeId());
- return DIALOG_STATUS_NONE;
- }
-
- for (QuestRelations::const_iterator i = qir.first; i != qir.second; ++i)
- {
- uint32 result2 = 0;
- uint32 quest_id = i->second;
- Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
- if (!quest)
- continue;
-
- ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK, quest->GetQuestId());
- if (!sConditionMgr->IsObjectMeetToConditions(player, conditions))
- continue;
-
- QuestStatus status = player->GetQuestStatus(quest_id);
- if ((status == QUEST_STATUS_COMPLETE && !player->GetQuestRewardStatus(quest_id)) ||
- (quest->IsAutoComplete() && player->CanTakeQuest(quest, false)))
- {
- if (quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly())
- result2 = DIALOG_STATUS_REWARD_REP;
- else
- result2 = DIALOG_STATUS_REWARD;
- }
- else if (status == QUEST_STATUS_INCOMPLETE)
- result2 = DIALOG_STATUS_INCOMPLETE;
-
- if (result2 > result)
- result = result2;
- }
-
- for (QuestRelations::const_iterator i = qr.first; i != qr.second; ++i)
- {
- uint32 result2 = 0;
- uint32 quest_id = i->second;
- Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
- if (!quest)
- continue;
-
- ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK, quest->GetQuestId());
- if (!sConditionMgr->IsObjectMeetToConditions(player, conditions))
- continue;
-
- QuestStatus status = player->GetQuestStatus(quest_id);
- if (status == QUEST_STATUS_NONE)
- {
- if (player->CanSeeStartQuest(quest))
- {
- if (player->SatisfyQuestLevel(quest, false))
- {
- if (quest->IsAutoComplete())
- result2 = DIALOG_STATUS_REWARD_REP;
- else if (player->getLevel() <= ((player->GetQuestLevel(quest) == -1) ? player->getLevel() : player->GetQuestLevel(quest) + sWorld->getIntConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF)))
- {
- if (quest->IsDaily())
- result2 = DIALOG_STATUS_AVAILABLE_REP;
- else
- result2 = DIALOG_STATUS_AVAILABLE;
- }
- else
- result2 = DIALOG_STATUS_LOW_LEVEL_AVAILABLE;
- }
- else
- result2 = DIALOG_STATUS_UNAVAILABLE;
- }
- }
-
- if (result2 > result)
- result = result2;
- }
-
- return result;
-}
-
void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket*/)
{
TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY");
@@ -758,9 +618,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
if (!questgiver->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER))
continue;
- questStatus = sScriptMgr->GetDialogStatus(_player, questgiver);
- if (questStatus == DIALOG_STATUS_SCRIPTED_NO_STATUS)
- questStatus = getDialogStatus(_player, questgiver);
+ questStatus = _player->GetQuestDialogStatus(questgiver);
data << uint64(questgiver->GetGUID());
data << uint8(questStatus);
@@ -772,9 +630,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
if (!questgiver || questgiver->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER)
continue;
- questStatus = sScriptMgr->GetDialogStatus(_player, questgiver);
- if (questStatus == DIALOG_STATUS_SCRIPTED_NO_STATUS)
- questStatus = getDialogStatus(_player, questgiver);
+ questStatus = _player->GetQuestDialogStatus(questgiver);
data << uint64(questgiver->GetGUID());
data << uint8(questStatus);
diff --git a/src/server/game/Handlers/SkillHandler.cpp b/src/server/game/Handlers/SkillHandler.cpp
index bbbe1a4987f..fe893314b87 100644
--- a/src/server/game/Handlers/SkillHandler.cpp
+++ b/src/server/game/Handlers/SkillHandler.cpp
@@ -68,6 +68,9 @@ void WorldSession::HandleTalentWipeConfirmOpcode(WorldPacket& recvData)
return;
}
+ if (!unit->isCanTrainingAndResetTalentsOf(_player))
+ return;
+
// remove fake death
if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp
index 75a98247186..ba30803e8c2 100644
--- a/src/server/game/Handlers/SpellHandler.cpp
+++ b/src/server/game/Handlers/SpellHandler.cpp
@@ -266,19 +266,21 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
void WorldSession::HandleGameObjectUseOpcode(WorldPacket& recvData)
{
uint64 guid;
-
recvData >> guid;
TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_GAMEOBJ_USE Message [guid=%u]", GUID_LOPART(guid));
if (GameObject* obj = GetPlayer()->GetMap()->GetGameObject(guid))
{
+ if (!obj->IsWithinDistInMap(GetPlayer(), obj->GetInteractionDistance()))
+ return;
+
// ignore for remote control state
- if (_player->m_mover != _player)
- if (!(_player->IsOnVehicle(_player->m_mover) || _player->IsMounted()) && !obj->GetGOInfo()->IsUsableMounted())
+ if (GetPlayer()->m_mover != GetPlayer())
+ if (!(GetPlayer()->IsOnVehicle(GetPlayer()->m_mover) || GetPlayer()->IsMounted()) && !obj->GetGOInfo()->IsUsableMounted())
return;
- obj->Use(_player);
+ obj->Use(GetPlayer());
}
}
diff --git a/src/server/game/Handlers/TaxiHandler.cpp b/src/server/game/Handlers/TaxiHandler.cpp
index 4487ae7b15f..34899fc23df 100644
--- a/src/server/game/Handlers/TaxiHandler.cpp
+++ b/src/server/game/Handlers/TaxiHandler.cpp
@@ -184,6 +184,14 @@ void WorldSession::HandleActivateTaxiExpressOpcode (WorldPacket& recvData)
{
uint32 node;
recvData >> node;
+
+ if (!GetPlayer()->m_taxi.IsTaximaskNodeKnown(node) && !GetPlayer()->isTaxiCheater())
+ {
+ SendActivateTaxiReply(ERR_TAXINOTVISITED);
+ recvData.rfinish();
+ return;
+ }
+
nodes.push_back(node);
}
@@ -290,6 +298,15 @@ void WorldSession::HandleActivateTaxiOpcode(WorldPacket& recvData)
return;
}
+ if (!GetPlayer()->isTaxiCheater())
+ {
+ if (!GetPlayer()->m_taxi.IsTaximaskNodeKnown(nodes[0]) || !GetPlayer()->m_taxi.IsTaximaskNodeKnown(nodes[1]))
+ {
+ SendActivateTaxiReply(ERR_TAXINOTVISITED);
+ return;
+ }
+ }
+
GetPlayer()->ActivateTaxiPathTo(nodes, npc);
}
diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp
index b9949ac631d..688d7e58b6c 100644
--- a/src/server/game/Handlers/TicketHandler.cpp
+++ b/src/server/game/Handlers/TicketHandler.cpp
@@ -49,13 +49,23 @@ void WorldSession::HandleGMTicketCreateOpcode(WorldPacket& recvData)
// Player must not have ticket
if (!ticket || ticket->IsClosed())
{
- ticket = new GmTicket(GetPlayer(), recvData);
-
+ uint32 mapId;
+ float x, y, z;
+ std::string message;
+ uint32 needResponse;
+ bool needMoreHelp;
uint32 count;
std::list<uint32> times;
uint32 decompressedSize;
std::string chatLog;
+ recvData >> mapId;
+ recvData >> x >> y >> z;
+ recvData >> message;
+
+ recvData >> needResponse;
+ recvData >> needMoreHelp;
+
recvData >> count;
for (uint32 i = 0; i < count; i++)
@@ -77,19 +87,25 @@ void WorldSession::HandleGMTicketCreateOpcode(WorldPacket& recvData)
if (uncompress(dest.contents(), &realSize, recvData.contents() + pos, recvData.size() - pos) == Z_OK)
{
dest >> chatLog;
- ticket->SetChatLog(times, chatLog);
}
else
{
TC_LOG_ERROR("network", "CMSG_GMTICKET_CREATE possibly corrupt. Uncompression failed.");
recvData.rfinish();
- delete ticket;
return;
}
recvData.rfinish(); // Will still have compressed data in buffer.
}
+ ticket = new GmTicket(GetPlayer());
+ ticket->SetPosition(mapId, x, y, z);
+ ticket->SetMessage(message);
+ ticket->SetGmAction(needResponse, needMoreHelp);
+
+ if (!chatLog.empty())
+ ticket->SetChatLog(times, chatLog);
+
sTicketMgr->AddTicket(ticket);
sTicketMgr->UpdateLastChange();
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index d224c21efe8..55f745d993b 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -337,6 +337,9 @@ void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, floa
if (_owner->GetTypeId() == TYPEID_PLAYER)
return;
+ if (speedXY <= 0.1f)
+ return;
+
float x, y, z;
float moveTimeHalf = speedZ / Movement::gravity;
float dist = 2 * moveTimeHalf * speedXY;
@@ -370,6 +373,8 @@ void MotionMaster::MoveJumpTo(float angle, float speedXY, float speedZ)
void MotionMaster::MoveJump(float x, float y, float z, float speedXY, float speedZ, uint32 id)
{
TC_LOG_DEBUG("misc", "Unit (GUID: %u) jump to point (X: %f Y: %f Z: %f)", _owner->GetGUIDLow(), x, y, z);
+ if (speedXY <= 0.1f)
+ return;
float moveTimeHalf = speedZ / Movement::gravity;
float max_height = -Movement::computeFallElevation(moveTimeHalf, false, -speedZ);
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 97e81de7ecf..ea02b83f2e8 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -931,7 +931,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x386*/ { "SMSG_SPLINE_SET_FLIGHT_BACK_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
/*0x387*/ { "CMSG_MAELSTROM_INVALIDATE_CACHE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
/*0x388*/ { "SMSG_FLIGHT_SPLINE_SYNC", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x389*/ { "CMSG_SET_TAXI_BENCHMARK_MODE", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTaxiBenchmarkOpcode },
+ /*0x389*/ { "CMSG_SET_TAXI_BENCHMARK_MODE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTaxiBenchmarkOpcode },
/*0x38A*/ { "SMSG_JOINED_BATTLEGROUND_QUEUE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
/*0x38B*/ { "SMSG_REALM_SPLIT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
/*0x38C*/ { "CMSG_REALM_SPLIT", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleRealmSplitOpcode },
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 8b00cb9432e..0af6069a0e5 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -275,6 +275,8 @@ class WorldSession
void SendTrainerList(uint64 guid, std::string const& strTitle);
void SendListInventory(uint64 guid);
void SendShowBank(uint64 guid);
+ bool CanOpenMailBox(uint64 guid);
+ void SendShowMailBox(uint64 guid);
void SendTabardVendorActivate(uint64 guid);
void SendSpiritResurrect();
void SendBindPoint(Creature* npc);
@@ -357,7 +359,6 @@ class WorldSession
uint32 GetLatency() const { return m_latency; }
void SetLatency(uint32 latency) { m_latency = latency; }
void ResetClientTimeDelay() { m_clientTimeDelay = 0; }
- uint32 getDialogStatus(Player* player, Object* questgiver);
ACE_Atomic_Op<ACE_Thread_Mutex, time_t> m_timeOutTime;
void UpdateTimeOutTime(uint32 diff)
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 5cb86244aa1..b7aabcc7589 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -5351,37 +5351,6 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const
if (!target->HasAuraType(SPELL_AURA_MOD_STEALTH))
target->RemoveAurasDueToSpell(31665);
break;
- // Killing Spree
- case 51690:
- {
- /// @todo this should use effect[1] of 51690
- UnitList targets;
- {
- // eff_radius == 0
- float radius = GetSpellInfo()->GetMaxRange(false);
-
- CellCoord p(Trinity::ComputeCellCoord(target->GetPositionX(), target->GetPositionY()));
- Cell cell(p);
-
- Trinity::AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck u_check(target, radius);
- Trinity::UnitListSearcher<Trinity::AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck> checker(target, targets, u_check);
-
- TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
- TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
-
- cell.Visit(p, grid_object_checker, *GetBase()->GetOwner()->GetMap(), *target, radius);
- cell.Visit(p, world_object_checker, *GetBase()->GetOwner()->GetMap(), *target, radius);
- }
-
- if (targets.empty())
- return;
-
- Unit* spellTarget = Trinity::Containers::SelectRandomContainerElement(targets);
-
- target->CastSpell(spellTarget, 57840, true);
- target->CastSpell(spellTarget, 57841, true);
- break;
- }
// Overkill
case 58428:
if (!target->HasAuraType(SPELL_AURA_MOD_STEALTH))
@@ -5874,6 +5843,13 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
else
damage = uint32(target->CountPctFromMaxHealth(damage));
+ if (m_spellInfo->Effects[m_effIndex].IsTargetingArea() || m_spellInfo->Effects[m_effIndex].IsAreaAuraEffect() || m_spellInfo->Effects[m_effIndex].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
+ {
+ damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
+ if (caster->GetTypeId() != TYPEID_PLAYER)
+ damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
+ }
+
bool crit = IsPeriodicTickCrit(target, caster);
if (crit)
damage = caster->SpellCriticalDamageBonus(m_spellInfo, damage, target);
@@ -6106,8 +6082,10 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
if (target != caster && GetSpellInfo()->AttributesEx2 & SPELL_ATTR2_HEALTH_FUNNEL)
{
uint32 funnelDamage = GetSpellInfo()->ManaPerSecond; // damage is not affected by spell power
- if ((int32)funnelDamage > gain)
+
+ if ((int32)funnelDamage > gain && gain > 0)
funnelDamage = gain;
+
uint32 funnelAbsorb = 0;
caster->DealDamageMods(caster, funnelDamage, &funnelAbsorb);
caster->SendSpellNonMeleeDamageLog(caster, GetId(), funnelDamage, GetSpellInfo()->GetSchoolMask(), funnelAbsorb, 0, false, 0, false);
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 9c7fff612b7..8e7edfc5355 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -1525,11 +1525,8 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
player->RemoveSpellCooldown(GetSpellInfo()->Id, true);
player->AddSpellCooldown(GetSpellInfo()->Id, 0, uint32(time(NULL) + aurEff->GetAmount()));
- WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+4+4);
- data << uint64(player->GetGUID());
- data << uint8(0x0); // flags (0x1, 0x2)
- data << uint32(GetSpellInfo()->Id);
- data << uint32(aurEff->GetAmount()*IN_MILLISECONDS);
+ WorldPacket data;
+ player->BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, GetSpellInfo()->Id, aurEff->GetAmount()*IN_MILLISECONDS);
player->SendDirectMessage(&data);
}
break;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 49eed70f57d..bf6f95d8c92 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -85,9 +85,26 @@ SpellDestination::SpellDestination(WorldObject const& wObj)
_transportGUID = wObj.GetTransGUID();
_transportOffset.Relocate(wObj.GetTransOffsetX(), wObj.GetTransOffsetY(), wObj.GetTransOffsetZ(), wObj.GetTransOffsetO());
_position.Relocate(wObj);
- _position.SetOrientation(wObj.GetOrientation());
}
+void SpellDestination::Relocate(Position const& pos)
+{
+ if (_transportGUID)
+ {
+ Position offset;
+ _position.GetPositionOffsetTo(pos, offset);
+ _transportOffset.RelocateOffset(offset);
+ }
+ _position.Relocate(pos);
+}
+
+void SpellDestination::RelocateOffset(Position const& offset)
+{
+ if (_transportGUID)
+ _transportOffset.RelocateOffset(offset);
+
+ _position.RelocateOffset(offset);
+}
SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0), m_strTarget()
{
@@ -350,14 +367,7 @@ void SpellCastTargets::SetSrc(WorldObject const& wObj)
void SpellCastTargets::ModSrc(Position const& pos)
{
ASSERT(m_targetMask & TARGET_FLAG_SOURCE_LOCATION);
-
- if (m_src._transportGUID)
- {
- Position offset;
- m_src._position.GetPositionOffsetTo(pos, offset);
- m_src._transportOffset.RelocateOffset(offset);
- }
- m_src._position.Relocate(pos);
+ m_src.Relocate(pos);
}
void SpellCastTargets::RemoveSrc()
@@ -393,6 +403,12 @@ void SpellCastTargets::SetDst(WorldObject const& wObj)
m_targetMask |= TARGET_FLAG_DEST_LOCATION;
}
+void SpellCastTargets::SetDst(SpellDestination const& spellDest)
+{
+ m_dst = spellDest;
+ m_targetMask |= TARGET_FLAG_DEST_LOCATION;
+}
+
void SpellCastTargets::SetDst(SpellCastTargets const& spellTargets)
{
m_dst = spellTargets.m_dst;
@@ -402,14 +418,13 @@ void SpellCastTargets::SetDst(SpellCastTargets const& spellTargets)
void SpellCastTargets::ModDst(Position const& pos)
{
ASSERT(m_targetMask & TARGET_FLAG_DEST_LOCATION);
+ m_dst.Relocate(pos);
+}
- if (m_dst._transportGUID)
- {
- Position offset;
- m_dst._position.GetPositionOffsetTo(pos, offset);
- m_dst._transportOffset.RelocateOffset(offset);
- }
- m_dst._position.Relocate(pos);
+void SpellCastTargets::ModDst(SpellDestination const& spellDest)
+{
+ ASSERT(m_targetMask & TARGET_FLAG_DEST_LOCATION);
+ m_dst = spellDest;
}
void SpellCastTargets::RemoveDst()
@@ -1090,24 +1105,13 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge
Trinity::Containers::RandomResizeList(targets, maxTargets);
}
- // for compability with older code - add only unit and go targets
- /// @todo remove this
- std::list<Unit*> unitTargets;
- std::list<GameObject*> gObjTargets;
-
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
{
if (Unit* unitTarget = (*itr)->ToUnit())
- unitTargets.push_back(unitTarget);
+ AddUnitTarget(unitTarget, effMask, false);
else if (GameObject* gObjTarget = (*itr)->ToGameObject())
- gObjTargets.push_back(gObjTarget);
+ AddGOTarget(gObjTarget, effMask);
}
-
- for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr)
- AddUnitTarget(*itr, effMask, false);
-
- for (std::list<GameObject*>::iterator itr = gObjTargets.begin(); itr != gObjTargets.end(); ++itr)
- AddGOTarget(*itr, effMask);
}
}
}
@@ -1167,200 +1171,10 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
- // Custom entries
- /// @todo remove those
- switch (m_spellInfo->Id)
- {
- case 46584: // Raise Dead
- {
- if (Player* playerCaster = m_caster->ToPlayer())
- {
- for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
- {
- switch ((*itr)->GetTypeId())
- {
- case TYPEID_UNIT:
- case TYPEID_PLAYER:
- {
- Unit* unitTarget = (*itr)->ToUnit();
- if (unitTarget->IsAlive() || !playerCaster->isHonorOrXPTarget(unitTarget)
- || ((unitTarget->GetCreatureTypeMask() & (1 << (CREATURE_TYPE_HUMANOID-1))) == 0)
- || (unitTarget->GetDisplayId() != unitTarget->GetNativeDisplayId()))
- break;
- AddUnitTarget(unitTarget, effMask, false);
- // no break;
- }
- case TYPEID_CORPSE: // wont work until corpses are allowed in target lists, but at least will send dest in packet
- m_targets.SetDst(*(*itr));
- return; // nothing more to do here
- default:
- break;
- }
- }
- }
- return; // don't add targets to target map
- }
- // Corpse Explosion
- case 49158:
- case 51325:
- case 51326:
- case 51327:
- case 51328:
- // check if our target is not valid (spell can target ghoul or dead unit)
- if (!(m_targets.GetUnitTarget() && m_targets.GetUnitTarget()->GetDisplayId() == m_targets.GetUnitTarget()->GetNativeDisplayId() &&
- ((m_targets.GetUnitTarget()->GetEntry() == 26125 && m_targets.GetUnitTarget()->GetOwnerGUID() == m_caster->GetGUID())
- || m_targets.GetUnitTarget()->isDead())))
- {
- // remove existing targets
- CleanupTargetList();
-
- for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
- {
- switch ((*itr)->GetTypeId())
- {
- case TYPEID_UNIT:
- case TYPEID_PLAYER:
- if (!(*itr)->ToUnit()->isDead())
- break;
- AddUnitTarget((*itr)->ToUnit(), 1 << effIndex, false);
- return;
- default:
- break;
- }
- }
- if (m_caster->GetTypeId() == TYPEID_PLAYER)
- m_caster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true);
- SendCastResult(SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW);
- finish(false);
- }
- return;
- default:
- break;
- }
-
CallScriptObjectAreaTargetSelectHandlers(targets, effIndex);
- std::list<Unit*> unitTargets;
- std::list<GameObject*> gObjTargets;
- // for compability with older code - add only unit and go targets
- /// @todo remove this
- for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
+ if (!targets.empty())
{
- if (Unit* unitTarget = (*itr)->ToUnit())
- unitTargets.push_back(unitTarget);
- else if (GameObject* gObjTarget = (*itr)->ToGameObject())
- gObjTargets.push_back(gObjTarget);
- }
-
- if (!unitTargets.empty())
- {
- // Special target selection for smart heals and energizes
- uint32 maxSize = 0;
- int32 power = -1;
- switch (m_spellInfo->SpellFamilyName)
- {
- case SPELLFAMILY_GENERIC:
- switch (m_spellInfo->Id)
- {
- case 52759: // Ancestral Awakening
- case 71610: // Echoes of Light (Althor's Abacus normal version)
- case 71641: // Echoes of Light (Althor's Abacus heroic version)
- maxSize = 1;
- power = POWER_HEALTH;
- break;
- case 54968: // Glyph of Holy Light
- maxSize = m_spellInfo->MaxAffectedTargets;
- power = POWER_HEALTH;
- break;
- case 57669: // Replenishment
- // In arenas Replenishment may only affect the caster
- if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->InArena())
- {
- unitTargets.clear();
- unitTargets.push_back(m_caster);
- break;
- }
- maxSize = 10;
- power = POWER_MANA;
- break;
- default:
- break;
- }
- break;
- case SPELLFAMILY_PRIEST:
- if (m_spellInfo->SpellFamilyFlags[0] == 0x10000000) // Circle of Healing
- {
- maxSize = m_caster->HasAura(55675) ? 6 : 5; // Glyph of Circle of Healing
- power = POWER_HEALTH;
- }
- else if (m_spellInfo->Id == 64844) // Divine Hymn
- {
- maxSize = 3;
- power = POWER_HEALTH;
- }
- else if (m_spellInfo->Id == 64904) // Hymn of Hope
- {
- maxSize = 3;
- power = POWER_MANA;
- }
- else
- break;
-
- // Remove targets outside caster's raid
- for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end();)
- {
- if (!(*itr)->IsInRaidWith(m_caster))
- itr = unitTargets.erase(itr);
- else
- ++itr;
- }
- break;
- case SPELLFAMILY_DRUID:
- if (m_spellInfo->SpellFamilyFlags[1] == 0x04000000) // Wild Growth
- {
- maxSize = m_caster->HasAura(62970) ? 6 : 5; // Glyph of Wild Growth
- power = POWER_HEALTH;
- }
- else
- break;
-
- // Remove targets outside caster's raid
- for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end();)
- if (!(*itr)->IsInRaidWith(m_caster))
- itr = unitTargets.erase(itr);
- else
- ++itr;
- break;
- default:
- break;
- }
-
- if (maxSize && power != -1)
- {
- if (Powers(power) == POWER_HEALTH)
- {
- if (unitTargets.size() > maxSize)
- {
- unitTargets.sort(Trinity::HealthPctOrderPred());
- unitTargets.resize(maxSize);
- }
- }
- else
- {
- for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end();)
- if ((*itr)->getPowerType() != (Powers)power)
- itr = unitTargets.erase(itr);
- else
- ++itr;
-
- if (unitTargets.size() > maxSize)
- {
- unitTargets.sort(Trinity::PowerPctOrderPred((Powers)power));
- unitTargets.resize(maxSize);
- }
- }
- }
-
// Other special target selection goes here
if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
{
@@ -1369,138 +1183,138 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
if ((*j)->IsAffectedOnSpell(m_spellInfo))
maxTargets += (*j)->GetAmount();
- Trinity::Containers::RandomResizeList(unitTargets, maxTargets);
+ Trinity::Containers::RandomResizeList(targets, maxTargets);
}
- for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr)
- AddUnitTarget(*itr, effMask, false);
- }
-
- if (!gObjTargets.empty())
- {
- if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
+ for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
{
- Unit::AuraEffectList const& Auras = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS);
- for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
- if ((*j)->IsAffectedOnSpell(m_spellInfo))
- maxTargets += (*j)->GetAmount();
-
- Trinity::Containers::RandomResizeList(gObjTargets, maxTargets);
+ if (Unit* unitTarget = (*itr)->ToUnit())
+ AddUnitTarget(unitTarget, effMask, false);
+ else if (GameObject* gObjTarget = (*itr)->ToGameObject())
+ AddGOTarget(gObjTarget, effMask);
}
-
- for (std::list<GameObject*>::iterator itr = gObjTargets.begin(); itr != gObjTargets.end(); ++itr)
- AddGOTarget(*itr, effMask);
}
}
void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
{
+ SpellDestination dest(*m_caster);
+
switch (targetType.GetTarget())
{
case TARGET_DEST_CASTER:
- m_targets.SetDst(*m_caster);
- return;
+ break;
case TARGET_DEST_HOME:
if (Player* playerCaster = m_caster->ToPlayer())
- m_targets.SetDst(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
- return;
+ dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
+ break;
case TARGET_DEST_DB:
if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
{
/// @todo fix this check
if (m_spellInfo->HasEffect(SPELL_EFFECT_TELEPORT_UNITS) || m_spellInfo->HasEffect(SPELL_EFFECT_BIND))
- m_targets.SetDst(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
+ dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
else if (st->target_mapId == m_caster->GetMapId())
- m_targets.SetDst(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
+ dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
}
else
{
TC_LOG_DEBUG("spells", "SPELL: unknown target coordinates for spell ID %u", m_spellInfo->Id);
- WorldObject* target = m_targets.GetObjectTarget();
- m_targets.SetDst(target ? *target : *m_caster);
+ if (WorldObject* target = m_targets.GetObjectTarget())
+ dest = SpellDestination(*target);
}
- return;
+ break;
case TARGET_DEST_CASTER_FISHING:
{
- float min_dis = m_spellInfo->GetMinRange(true);
- float max_dis = m_spellInfo->GetMaxRange(true);
- float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
- float x, y, z, angle;
- angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
- m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle);
-
- float ground = z;
- float liquidLevel = m_caster->GetMap()->GetWaterOrGroundLevel(x, y, z, &ground);
- if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
- {
- SendCastResult(SPELL_FAILED_NOT_HERE);
- SendChannelUpdate(0);
- finish(false);
- return;
- }
-
- if (ground + 0.75 > liquidLevel)
- {
- SendCastResult(SPELL_FAILED_TOO_SHALLOW);
- SendChannelUpdate(0);
- finish(false);
- return;
- }
-
- m_targets.SetDst(x, y, liquidLevel, m_caster->GetOrientation());
- return;
+ float minDist = m_spellInfo->GetMinRange(true);
+ float maxDist = m_spellInfo->GetMaxRange(true);
+ float dist = frand(minDist, maxDist);
+ float x, y, z;
+ float angle = float(rand_norm()) * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
+ m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dist, angle);
+
+ float ground = z;
+ float liquidLevel = m_caster->GetMap()->GetWaterOrGroundLevel(x, y, z, &ground);
+ if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
+ {
+ SendCastResult(SPELL_FAILED_NOT_HERE);
+ SendChannelUpdate(0);
+ finish(false);
+ return;
+ }
+
+ if (ground + 0.75 > liquidLevel)
+ {
+ SendCastResult(SPELL_FAILED_TOO_SHALLOW);
+ SendChannelUpdate(0);
+ finish(false);
+ return;
+ }
+
+ dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation());
+ break;
}
default:
- break;
- }
+ {
+ float dist;
+ float angle = targetType.CalcDirectionAngle();
+ float objSize = m_caster->GetObjectSize();
+ if (targetType.GetTarget() == TARGET_DEST_CASTER_SUMMON)
+ dist = PET_FOLLOW_DIST;
+ else
+ dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
- float dist;
- float angle = targetType.CalcDirectionAngle();
- float objSize = m_caster->GetObjectSize();
- if (targetType.GetTarget() == TARGET_DEST_CASTER_SUMMON)
- dist = PET_FOLLOW_DIST;
- else
- dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
+ if (dist < objSize)
+ dist = objSize;
+ else if (targetType.GetTarget() == TARGET_DEST_CASTER_RANDOM)
+ dist = objSize + (dist - objSize) * float(rand_norm());
- if (dist < objSize)
- dist = objSize;
- else if (targetType.GetTarget() == TARGET_DEST_CASTER_RANDOM)
- dist = objSize + (dist - objSize) * (float)rand_norm();
+ Position pos = dest._position;
+ if (targetType.GetTarget() == TARGET_DEST_CASTER_FRONT_LEAP)
+ m_caster->MovePositionToFirstCollision(pos, dist, angle);
+ else
+ m_caster->MovePosition(pos, dist, angle);
- Position pos;
- if (targetType.GetTarget() == TARGET_DEST_CASTER_FRONT_LEAP)
- m_caster->GetFirstCollisionPosition(pos, dist, angle);
- else
- m_caster->GetNearPosition(pos, dist, angle);
- m_targets.SetDst(*m_caster);
- m_targets.ModDst(pos);
+ dest.Relocate(pos);
+ break;
+ }
+ }
+
+ CallScriptDestinationTargetSelectHandlers(dest, effIndex);
+ m_targets.SetDst(dest);
}
void Spell::SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
{
WorldObject* target = m_targets.GetObjectTarget();
+
+ SpellDestination dest(*target);
+
switch (targetType.GetTarget())
{
case TARGET_DEST_TARGET_ENEMY:
case TARGET_DEST_TARGET_ANY:
- m_targets.SetDst(*target);
- return;
+ break;
default:
+ {
+ float angle = targetType.CalcDirectionAngle();
+ float objSize = target->GetObjectSize();
+ float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
+ if (dist < objSize)
+ dist = objSize;
+ else if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
+ dist = objSize + (dist - objSize) * float(rand_norm());
+
+ Position pos = dest._position;
+ target->MovePosition(pos, dist, angle);
+
+ dest.Relocate(pos);
break;
+ }
}
- float angle = targetType.CalcDirectionAngle();
- float objSize = target->GetObjectSize();
- float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
- if (dist < objSize)
- dist = objSize;
- else if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
- dist = objSize + (dist - objSize) * (float)rand_norm();
-
- Position pos;
- target->GetNearPosition(pos, dist, angle);
- m_targets.SetDst(*target);
- m_targets.ModDst(pos);
+ CallScriptDestinationTargetSelectHandlers(dest, effIndex);
+ m_targets.SetDst(dest);
}
void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
@@ -1509,8 +1323,9 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT
// can only happen if previous destination target could not be set for some reason
// (not found nearby target, or channel target for example
// maybe we should abort the spell in such case?
- if (!m_targets.HasDst())
- m_targets.SetDst(*m_caster);
+ CheckDst();
+
+ SpellDestination dest(*m_targets.GetDst());
switch (targetType.GetTarget())
{
@@ -1520,20 +1335,25 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT
case TARGET_DEST_DEST:
return;
case TARGET_DEST_TRAJ:
- SelectImplicitTrajTargets();
+ SelectImplicitTrajTargets(effIndex);
return;
default:
+ {
+ float angle = targetType.CalcDirectionAngle();
+ float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
+ if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
+ dist *= float(rand_norm());
+
+ Position pos = dest._position;
+ m_caster->MovePosition(pos, dist, angle);
+
+ dest.Relocate(pos);
break;
+ }
}
- float angle = targetType.CalcDirectionAngle();
- float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
- if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
- dist *= (float)rand_norm();
-
- Position pos = *m_targets.GetDstPos();
- m_caster->MovePosition(pos, dist, angle);
- m_targets.ModDst(pos);
+ CallScriptDestinationTargetSelectHandlers(dest, effIndex);
+ m_targets.ModDst(dest);
}
void Spell::SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
@@ -1624,14 +1444,9 @@ void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTarg
// Chain primary target is added earlier
CallScriptObjectAreaTargetSelectHandlers(targets, effIndex);
- // for backward compability
- std::list<Unit*> unitTargets;
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
if (Unit* unitTarget = (*itr)->ToUnit())
- unitTargets.push_back(unitTarget);
-
- for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr)
- AddUnitTarget(*itr, effMask, false);
+ AddUnitTarget(unitTarget, effMask, false);
}
}
@@ -1649,7 +1464,7 @@ float tangent(float x)
#define DEBUG_TRAJ(a) //a
-void Spell::SelectImplicitTrajTargets()
+void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex)
{
if (!m_targets.HasTraj())
return;
@@ -1778,7 +1593,11 @@ void Spell::SelectImplicitTrajTargets()
Position trajDst;
trajDst.Relocate(x, y, z, m_caster->GetOrientation());
- m_targets.ModDst(trajDst);
+ SpellDestination dest(*m_targets.GetDst());
+ dest.Relocate(trajDst);
+
+ CallScriptDestinationTargetSelectHandlers(dest, effIndex);
+ m_targets.ModDst(dest);
}
}
@@ -3201,7 +3020,7 @@ void Spell::cast(bool skipCheck)
if (this->GetSpellInfo()->DmgClass != SPELL_DAMAGE_CLASS_NONE)
if (Pet* playerPet = playerCaster->GetPet())
if (playerPet->IsAlive() && playerPet->isControlled() && (m_targets.GetTargetMask() & TARGET_FLAG_UNIT))
- playerPet->AI()->OwnerAttacked(m_targets.GetObjectTarget()->ToUnit());
+ playerPet->AI()->OwnerAttacked(m_targets.GetUnitTarget());
}
SetExecutedCurrently(true);
@@ -4976,8 +4795,7 @@ SpellCastResult Spell::CheckCast(bool strict)
uint32 zone, area;
m_caster->GetZoneAndAreaId(zone, area);
- SpellCastResult locRes= m_spellInfo->CheckLocation(m_caster->GetMapId(), zone, area,
- m_caster->GetTypeId() == TYPEID_PLAYER ? m_caster->ToPlayer() : NULL);
+ SpellCastResult locRes = m_spellInfo->CheckLocation(m_caster->GetMapId(), zone, area, m_caster->ToPlayer());
if (locRes != SPELL_CAST_OK)
return locRes;
}
@@ -6832,10 +6650,10 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier)
if (m_damage > 0)
{
- if (m_spellInfo->Effects[i].IsTargetingArea())
+ if (m_spellInfo->Effects[i].IsTargetingArea() || m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
{
m_damage = int32(float(m_damage) * unit->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
- if (m_caster->GetTypeId() == TYPEID_UNIT)
+ if (m_caster->GetTypeId() != TYPEID_PLAYER)
m_damage = int32(float(m_damage) * unit->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
if (m_caster->GetTypeId() == TYPEID_PLAYER)
@@ -7177,6 +6995,20 @@ void Spell::CallScriptObjectTargetSelectHandlers(WorldObject*& target, SpellEffI
}
}
+void Spell::CallScriptDestinationTargetSelectHandlers(SpellDestination& target, SpellEffIndex effIndex)
+{
+ for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
+ {
+ (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
+ std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
+ for (; hookItr != hookItrEnd; ++hookItr)
+ if (hookItr->IsEffectAffected(m_spellInfo, effIndex))
+ hookItr->Call(*scritr, target);
+
+ (*scritr)->_FinishScriptCall();
+ }
+}
+
bool Spell::CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
{
// Skip if there are not any script
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 72bc195aec7..031311f2749 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -87,6 +87,9 @@ struct SpellDestination
SpellDestination(Position const& pos);
SpellDestination(WorldObject const& wObj);
+ void Relocate(Position const& pos);
+ void RelocateOffset(Position const& offset);
+
WorldLocation _position;
uint64 _transportGUID;
Position _transportOffset;
@@ -141,8 +144,10 @@ class SpellCastTargets
void SetDst(float x, float y, float z, float orientation, uint32 mapId = MAPID_INVALID);
void SetDst(Position const& pos);
void SetDst(WorldObject const& wObj);
+ void SetDst(SpellDestination const& spellDest);
void SetDst(SpellCastTargets const& spellTargets);
void ModDst(Position const& pos);
+ void ModDst(SpellDestination const& spellDest);
void RemoveDst();
bool HasSrc() const { return GetTargetMask() & TARGET_FLAG_SOURCE_LOCATION; }
@@ -359,7 +364,7 @@ class Spell
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType);
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask);
- void SelectImplicitTrajTargets();
+ void SelectImplicitTrajTargets(SpellEffIndex effIndex);
void SelectEffectTypeImplicitTargets(uint8 effIndex);
@@ -552,7 +557,7 @@ class Spell
GameObject* focusObject;
// Damage and healing in effects need just calculate
- int32 m_damage; // Damge in effects count here
+ int32 m_damage; // Damage in effects count here
int32 m_healing; // Healing in effects count here
// ******************************************
@@ -636,6 +641,7 @@ class Spell
void CallScriptAfterHitHandlers();
void CallScriptObjectAreaTargetSelectHandlers(std::list<WorldObject*>& targets, SpellEffIndex effIndex);
void CallScriptObjectTargetSelectHandlers(WorldObject*& target, SpellEffIndex effIndex);
+ void CallScriptDestinationTargetSelectHandlers(SpellDestination& target, SpellEffIndex effIndex);
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck);
std::list<SpellScript*> m_loadedScripts;
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 4e57c538c4d..73d3c39148a 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -682,11 +682,6 @@ void Spell::EffectDummy(SpellEffIndex effIndex)
if (!unitTarget && !gameObjTarget && !itemTarget)
return;
- uint32 spell_id = 0;
- int32 bp = 0;
- bool triggered = true;
- SpellCastTargets targets;
-
// selection by spell family
switch (m_spellInfo->SpellFamilyName)
{
@@ -723,60 +718,10 @@ void Spell::EffectDummy(SpellEffIndex effIndex)
}
}
break;
- case SPELLFAMILY_DEATHKNIGHT:
- switch (m_spellInfo->Id)
- {
- case 46584: // Raise Dead
- if (m_caster->GetTypeId() != TYPEID_PLAYER)
- return;
-
- // Do we have talent Master of Ghouls?
- if (m_caster->HasAura(52143))
- // summon as pet
- bp = 52150;
- else
- // or guardian
- bp = 46585;
-
- if (m_targets.HasDst())
- targets.SetDst(*m_targets.GetDstPos());
- else
- {
- targets.SetDst(*m_caster);
- // Corpse not found - take reagents (only not triggered cast can take them)
- triggered = false;
- }
- // Remove cooldown - summon spellls have category
- m_caster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true);
- spell_id = 48289;
- break;
- // Raise dead - take reagents and trigger summon spells
- case 48289:
- if (m_targets.HasDst())
- targets.SetDst(*m_targets.GetDstPos());
- spell_id = CalculateDamage(0, NULL);
- break;
- }
+ default:
break;
}
- //spells triggered by dummy effect should not miss
- if (spell_id)
- {
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
-
- if (!spellInfo)
- {
- TC_LOG_ERROR("spells", "EffectDummy of spell %u: triggering unknown spell id %i\n", m_spellInfo->Id, spell_id);
- return;
- }
-
- targets.SetUnitTarget(unitTarget);
- Spell* spell = new Spell(m_caster, spellInfo, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, m_originalCasterGUID, true);
- if (bp) spell->SetSpellValue(SPELLVALUE_BASE_POINT0, bp);
- spell->prepare(&targets);
- }
-
// pet auras
if (PetAura const* petSpell = sSpellMgr->GetPetAura(m_spellInfo->Id, effIndex))
{
@@ -910,7 +855,7 @@ void Spell::EffectTriggerSpell(SpellEffIndex effIndex)
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
if (!spellInfo)
{
- TC_LOG_DEBUG("spells", "Spell::EffectTriggerSpell spell %u tried to trigger unknown spell %u", m_spellInfo->Id, triggered_spell_id);
+ TC_LOG_ERROR("spells", "Spell::EffectTriggerSpell spell %u tried to trigger unknown spell %u", m_spellInfo->Id, triggered_spell_id);
return;
}
@@ -962,7 +907,7 @@ void Spell::EffectTriggerMissileSpell(SpellEffIndex effIndex)
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
if (!spellInfo)
{
- TC_LOG_DEBUG("spells", "Spell::EffectTriggerMissileSpell spell %u tried to trigger unknown spell %u", m_spellInfo->Id, triggered_spell_id);
+ TC_LOG_ERROR("spells", "Spell::EffectTriggerMissileSpell spell %u tried to trigger unknown spell %u", m_spellInfo->Id, triggered_spell_id);
return;
}
@@ -4101,65 +4046,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
}
break;
}
- case SPELLFAMILY_PALADIN:
- {
- // Judgement (seal trigger)
- if (m_spellInfo->GetCategory() == SPELLCATEGORY_JUDGEMENT)
- {
- if (!unitTarget || !unitTarget->IsAlive())
- return;
- uint32 spellId1 = 0;
- uint32 spellId2 = 0;
-
- // Judgement self add switch
- switch (m_spellInfo->Id)
- {
- case 53407: spellId1 = 20184; break; // Judgement of Justice
- case 20271: // Judgement of Light
- case 57774: spellId1 = 20185; break; // Judgement of Light
- case 53408: spellId1 = 20186; break; // Judgement of Wisdom
- default:
- TC_LOG_ERROR("spells", "Unsupported Judgement (seal trigger) spell (Id: %u) in Spell::EffectScriptEffect", m_spellInfo->Id);
- return;
- }
- // all seals have aura dummy in 2 effect
- Unit::AuraApplicationMap & sealAuras = m_caster->GetAppliedAuras();
- for (Unit::AuraApplicationMap::iterator iter = sealAuras.begin(); iter != sealAuras.end();)
- {
- Aura* aura = iter->second->GetBase();
- if (aura->GetSpellInfo()->GetSpellSpecific() == SPELL_SPECIFIC_SEAL)
- {
- if (AuraEffect* aureff = aura->GetEffect(2))
- if (aureff->GetAuraType() == SPELL_AURA_DUMMY)
- {
- if (sSpellMgr->GetSpellInfo(aureff->GetAmount()))
- spellId2 = aureff->GetAmount();
- break;
- }
- if (!spellId2)
- {
- switch (iter->first)
- {
- // Seal of light, Seal of wisdom, Seal of justice
- case 20165:
- case 20166:
- case 20164:
- spellId2 = 54158;
- }
- }
- break;
- }
- else
- ++iter;
- }
- if (spellId1)
- m_caster->CastSpell(unitTarget, spellId1, true);
- if (spellId2)
- m_caster->CastSpell(unitTarget, spellId2, true);
- return;
- }
- break;
- }
case SPELLFAMILY_DEATHKNIGHT:
{
// Pestilence
@@ -4978,7 +4864,7 @@ void Spell::EffectQuestClear(SpellEffIndex effIndex)
}
}
- player->RemoveActiveQuest(quest_id);
+ player->RemoveActiveQuest(quest_id, false);
player->RemoveRewardedQuest(quest_id);
}
@@ -5072,6 +4958,7 @@ void Spell::EffectResurrectPet(SpellEffIndex /*effIndex*/)
hadPet = false;
}
+ // TODO: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends
Pet* pet = player->GetPet(); // Attempt to get current pet
if (!pet || pet->IsAlive())
return;
@@ -5799,6 +5686,7 @@ void Spell::SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const*
TempSummon* summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id);
if (!summon)
return;
+
if (summon->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
((Guardian*)summon)->InitStatsForLevel(level);
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index d51be9b04b5..93f264d2d61 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -814,7 +814,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr
{
if (EventProcFlag & PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS)
{
- if (!(procExtra & PROC_EX_INTERNAL_DOT))
+ if (!(procExtra & PROC_EX_INTERNAL_HOT))
return false;
}
else if (procExtra & PROC_EX_INTERNAL_HOT)
@@ -2714,8 +2714,39 @@ void SpellMgr::UnloadSpellInfoImplicitTargetConditionLists()
void SpellMgr::LoadSpellInfoCustomAttributes()
{
uint32 oldMSTime = getMSTime();
-
+ uint32 oldMSTime2 = oldMSTime;
SpellInfo* spellInfo = NULL;
+
+ QueryResult result = WorldDatabase.Query("SELECT entry, attributes FROM spell_custom_attr");
+
+ if (!result)
+ TC_LOG_INFO("server.loading", ">> Loaded 0 spell custom attributes from DB. DB table `spell_custom_attr` is empty.");
+ else
+ {
+ uint32 count = 0;
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 spellId = fields[0].GetUInt32();
+ uint32 attributes = fields[1].GetUInt32();
+
+ spellInfo = _GetSpellInfo(spellId);
+ if (!spellInfo)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `spell_custom_attr` has wrong spell (entry: %u), ignored.", spellId);
+ continue;
+ }
+
+ // TODO: validate attributes
+
+ spellInfo->AttributesCu |= attributes;
+ ++count;
+ } while (result->NextRow());
+
+ TC_LOG_INFO("server.loading", ">> Loaded %u spell custom attributes from DB in %u ms", count, GetMSTimeDiffToNow(oldMSTime2));
+ }
+
for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
{
spellInfo = mSpellInfoMap[i];
@@ -2826,165 +2857,6 @@ void SpellMgr::LoadSpellInfoCustomAttributes()
if (spellInfo->SpellVisual[0] == 3879)
spellInfo->AttributesCu |= SPELL_ATTR0_CU_CONE_BACK;
- switch (spellInfo->Id)
- {
- case 1776: // Gouge
- case 1777:
- case 8629:
- case 11285:
- case 11286:
- case 12540:
- case 13579:
- case 24698:
- case 28456:
- case 29425:
- case 34940:
- case 36862:
- case 38764:
- case 38863:
- case 52743: // Head Smack
- spellInfo->AttributesCu |= SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER;
- break;
- case 53: // Backstab
- case 2589:
- case 2590:
- case 2591:
- case 8721:
- case 11279:
- case 11280:
- case 11281:
- case 25300:
- case 26863:
- case 48656:
- case 48657:
- case 703: // Garrote
- case 8631:
- case 8632:
- case 8633:
- case 11289:
- case 11290:
- case 26839:
- case 26884:
- case 48675:
- case 48676:
- case 5221: // Shred
- case 6800:
- case 8992:
- case 9829:
- case 9830:
- case 27001:
- case 27002:
- case 48571:
- case 48572:
- case 8676: // Ambush
- case 8724:
- case 8725:
- case 11267:
- case 11268:
- case 11269:
- case 27441:
- case 48689:
- case 48690:
- case 48691:
- case 6785: // Ravage
- case 6787:
- case 9866:
- case 9867:
- case 27005:
- case 48578:
- case 48579:
- case 21987: // Lash of Pain
- case 23959: // Test Stab R50
- case 24825: // Test Backstab
- case 58563: // Assassinate Restless Lookout
- spellInfo->AttributesCu |= SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET;
- break;
- case 26029: // Dark Glare
- case 37433: // Spout
- case 43140: // Flame Breath
- case 43215: // Flame Breath
- case 70461: // Coldflame Trap
- case 72133: // Pain and Suffering
- case 73788: // Pain and Suffering
- case 73789: // Pain and Suffering
- case 73790: // Pain and Suffering
- spellInfo->AttributesCu |= SPELL_ATTR0_CU_CONE_LINE;
- break;
- case 24340: // Meteor
- case 26558: // Meteor
- case 28884: // Meteor
- case 36837: // Meteor
- case 38903: // Meteor
- case 41276: // Meteor
- case 57467: // Meteor
- case 26789: // Shard of the Fallen Star
- case 31436: // Malevolent Cleave
- case 35181: // Dive Bomb
- case 40810: // Saber Lash
- case 43267: // Saber Lash
- case 43268: // Saber Lash
- case 42384: // Brutal Swipe
- case 45150: // Meteor Slash
- case 64688: // Sonic Screech
- case 72373: // Shared Suffering
- case 71904: // Chaos Bane
- case 70492: // Ooze Eruption
- case 72505: // Ooze Eruption
- case 72624: // Ooze Eruption
- case 72625: // Ooze Eruption
- // ONLY SPELLS WITH SPELLFAMILY_GENERIC and EFFECT_SCHOOL_DAMAGE
- spellInfo->AttributesCu |= SPELL_ATTR0_CU_SHARE_DAMAGE;
- break;
- case 18500: // Wing Buffet
- case 33086: // Wild Bite
- case 49749: // Piercing Blow
- case 52890: // Penetrating Strike
- case 53454: // Impale
- case 59446: // Impale
- case 62383: // Shatter
- case 64777: // Machine Gun
- case 65239: // Machine Gun
- case 65919: // Impale
- case 67858: // Impale
- case 67859: // Impale
- case 67860: // Impale
- case 69293: // Wing Buffet
- case 74439: // Machine Gun
- case 63278: // Mark of the Faceless (General Vezax)
- case 62544: // Thrust (Argent Tournament)
- case 64588: // Thrust (Argent Tournament)
- case 66479: // Thrust (Argent Tournament)
- case 68505: // Thrust (Argent Tournament)
- case 62709: // Counterattack! (Argent Tournament)
- case 62626: // Break-Shield (Argent Tournament, Player)
- case 64590: // Break-Shield (Argent Tournament, Player)
- case 64342: // Break-Shield (Argent Tournament, NPC)
- case 64686: // Break-Shield (Argent Tournament, NPC)
- case 65147: // Break-Shield (Argent Tournament, NPC)
- case 68504: // Break-Shield (Argent Tournament, NPC)
- case 62874: // Charge (Argent Tournament, Player)
- case 68498: // Charge (Argent Tournament, Player)
- case 64591: // Charge (Argent Tournament, Player)
- case 63003: // Charge (Argent Tournament, NPC)
- case 63010: // Charge (Argent Tournament, NPC)
- case 68321: // Charge (Argent Tournament, NPC)
- case 72255: // Mark of the Fallen Champion (Deathbringer Saurfang)
- case 72444: // Mark of the Fallen Champion (Deathbringer Saurfang)
- case 72445: // Mark of the Fallen Champion (Deathbringer Saurfang)
- case 72446: // Mark of the Fallen Champion (Deathbringer Saurfang)
- spellInfo->AttributesCu |= SPELL_ATTR0_CU_IGNORE_ARMOR;
- break;
- case 64422: // Sonic Screech (Auriaya)
- spellInfo->AttributesCu |= SPELL_ATTR0_CU_SHARE_DAMAGE;
- spellInfo->AttributesCu |= SPELL_ATTR0_CU_IGNORE_ARMOR;
- break;
- case 72293: // Mark of the Fallen Champion (Deathbringer Saurfang)
- spellInfo->AttributesCu |= SPELL_ATTR0_CU_NEGATIVE_EFF0;
- break;
- default:
- break;
- }
-
switch (spellInfo->SpellFamilyName)
{
case SPELLFAMILY_WARRIOR:
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index 7301e693978..c0bcd477e5b 100644
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -203,8 +203,8 @@ void SpellScript::HitHandler::Call(SpellScript* spellScript)
(spellScript->*pHitHandlerScript)();
}
-SpellScript::TargetHook::TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area)
- : _SpellScript::EffectHook(_effectIndex), targetType(_targetType), area(_area) { }
+SpellScript::TargetHook::TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area, bool _dest)
+ : _SpellScript::EffectHook(_effectIndex), targetType(_targetType), area(_area), dest(_dest) { }
std::string SpellScript::TargetHook::ToString()
{
@@ -236,8 +236,9 @@ bool SpellScript::TargetHook::CheckEffect(SpellInfo const* spellEntry, uint8 eff
switch (targetInfo.GetObjectType())
{
case TARGET_OBJECT_TYPE_SRC: // EMPTY
- case TARGET_OBJECT_TYPE_DEST: // EMPTY
return false;
+ case TARGET_OBJECT_TYPE_DEST: // DEST
+ return dest;
default:
switch (targetInfo.GetReferenceType())
{
@@ -259,7 +260,7 @@ bool SpellScript::TargetHook::CheckEffect(SpellInfo const* spellEntry, uint8 eff
}
SpellScript::ObjectAreaTargetSelectHandler::ObjectAreaTargetSelectHandler(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType)
- : TargetHook(_effIndex, _targetType, true)
+ : TargetHook(_effIndex, _targetType, true, false)
{
pObjectAreaTargetSelectHandlerScript = _pObjectAreaTargetSelectHandlerScript;
}
@@ -270,7 +271,7 @@ void SpellScript::ObjectAreaTargetSelectHandler::Call(SpellScript* spellScript,
}
SpellScript::ObjectTargetSelectHandler::ObjectTargetSelectHandler(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType)
- : TargetHook(_effIndex, _targetType, false)
+ : TargetHook(_effIndex, _targetType, false, false)
{
pObjectTargetSelectHandlerScript = _pObjectTargetSelectHandlerScript;
}
@@ -280,6 +281,17 @@ void SpellScript::ObjectTargetSelectHandler::Call(SpellScript* spellScript, Worl
(spellScript->*pObjectTargetSelectHandlerScript)(target);
}
+SpellScript::DestinationTargetSelectHandler::DestinationTargetSelectHandler(SpellDestinationTargetSelectFnType _DestinationTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType)
+ : TargetHook(_effIndex, _targetType, false, true)
+{
+ DestinationTargetSelectHandlerScript = _DestinationTargetSelectHandlerScript;
+}
+
+void SpellScript::DestinationTargetSelectHandler::Call(SpellScript* spellScript, SpellDestination& target)
+{
+ (spellScript->*DestinationTargetSelectHandlerScript)(target);
+}
+
bool SpellScript::_Validate(SpellInfo const* entry)
{
for (std::list<EffectHandler>::iterator itr = OnEffectLaunch.begin(); itr != OnEffectLaunch.end(); ++itr)
@@ -306,6 +318,10 @@ bool SpellScript::_Validate(SpellInfo const* entry)
if (!(*itr).GetAffectedEffectsMask(entry))
TC_LOG_ERROR("scripts", "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnObjectTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
+ for (std::list<DestinationTargetSelectHandler>::iterator itr = OnDestinationTargetSelect.begin(); itr != OnDestinationTargetSelect.end(); ++itr)
+ if (!(*itr).GetAffectedEffectsMask(entry))
+ TC_LOG_ERROR("scripts", "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnDestinationTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
+
return _SpellScript::_Validate(entry);
}
@@ -560,16 +576,28 @@ void SpellScript::PreventHitDefaultEffect(SpellEffIndex effIndex)
m_hitPreventDefaultEffectMask |= 1 << effIndex;
}
-int32 SpellScript::GetEffectValue()
+int32 SpellScript::GetEffectValue() const
{
if (!IsInEffectHook())
{
- TC_LOG_ERROR("scripts", "Script: `%s` Spell: `%u`: function SpellScript::PreventHitDefaultEffect was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId);
+ TC_LOG_ERROR("scripts", "Script: `%s` Spell: `%u`: function SpellScript::GetEffectValue was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId);
return 0;
}
+
return m_spell->damage;
}
+void SpellScript::SetEffectValue(int32 value)
+{
+ if (!IsInEffectHook())
+ {
+ TC_LOG_ERROR("scripts", "Script: `%s` Spell: `%u`: function SpellScript::SetEffectValue was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId);
+ return;
+ }
+
+ m_spell->damage = value;
+}
+
Item* SpellScript::GetCastItem()
{
return m_spell->m_CastItem;
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index 75cf63b495b..6378a8bed9b 100644
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -135,6 +135,7 @@ enum SpellScriptHookType
SPELL_SCRIPT_HOOK_AFTER_HIT,
SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT,
SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT,
+ SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT,
SPELL_SCRIPT_HOOK_CHECK_CAST,
SPELL_SCRIPT_HOOK_BEFORE_CAST,
SPELL_SCRIPT_HOOK_ON_CAST,
@@ -158,7 +159,8 @@ class SpellScript : public _SpellScript
typedef void(CLASSNAME::*SpellHitFnType)(); \
typedef void(CLASSNAME::*SpellCastFnType)(); \
typedef void(CLASSNAME::*SpellObjectAreaTargetSelectFnType)(std::list<WorldObject*>&); \
- typedef void(CLASSNAME::*SpellObjectTargetSelectFnType)(WorldObject*&);
+ typedef void(CLASSNAME::*SpellObjectTargetSelectFnType)(WorldObject*&); \
+ typedef void(CLASSNAME::*SpellDestinationTargetSelectFnType)(SpellDestination&);
SPELLSCRIPT_FUNCTION_TYPE_DEFINES(SpellScript)
@@ -203,12 +205,13 @@ class SpellScript : public _SpellScript
class TargetHook : public _SpellScript::EffectHook
{
public:
- TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area);
+ TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area, bool _dest);
bool CheckEffect(SpellInfo const* spellInfo, uint8 effIndex);
std::string ToString();
protected:
uint16 targetType;
bool area;
+ bool dest;
};
class ObjectAreaTargetSelectHandler : public TargetHook
@@ -224,18 +227,28 @@ class SpellScript : public _SpellScript
{
public:
ObjectTargetSelectHandler(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType);
- void Call(SpellScript* spellScript, WorldObject*& targets);
+ void Call(SpellScript* spellScript, WorldObject*& target);
private:
SpellObjectTargetSelectFnType pObjectTargetSelectHandlerScript;
};
+ class DestinationTargetSelectHandler : public TargetHook
+ {
+ public:
+ DestinationTargetSelectHandler(SpellDestinationTargetSelectFnType _DestinationTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType);
+ void Call(SpellScript* spellScript, SpellDestination& target);
+ private:
+ SpellDestinationTargetSelectFnType DestinationTargetSelectHandlerScript;
+ };
+
#define SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \
class CastHandlerFunction : public SpellScript::CastHandler { public: CastHandlerFunction(SpellCastFnType _pCastHandlerScript) : SpellScript::CastHandler((SpellScript::SpellCastFnType)_pCastHandlerScript) { } }; \
class CheckCastHandlerFunction : public SpellScript::CheckCastHandler { public: CheckCastHandlerFunction(SpellCheckCastFnType _checkCastHandlerScript) : SpellScript::CheckCastHandler((SpellScript::SpellCheckCastFnType)_checkCastHandlerScript) { } }; \
class EffectHandlerFunction : public SpellScript::EffectHandler { public: EffectHandlerFunction(SpellEffectFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : SpellScript::EffectHandler((SpellScript::SpellEffectFnType)_pEffectHandlerScript, _effIndex, _effName) { } }; \
class HitHandlerFunction : public SpellScript::HitHandler { public: HitHandlerFunction(SpellHitFnType _pHitHandlerScript) : SpellScript::HitHandler((SpellScript::SpellHitFnType)_pHitHandlerScript) { } }; \
class ObjectAreaTargetSelectHandlerFunction : public SpellScript::ObjectAreaTargetSelectHandler { public: ObjectAreaTargetSelectHandlerFunction(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectAreaTargetSelectHandler((SpellScript::SpellObjectAreaTargetSelectFnType)_pObjectAreaTargetSelectHandlerScript, _effIndex, _targetType) { } }; \
- class ObjectTargetSelectHandlerFunction : public SpellScript::ObjectTargetSelectHandler { public: ObjectTargetSelectHandlerFunction(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectTargetSelectHandler((SpellScript::SpellObjectTargetSelectFnType)_pObjectTargetSelectHandlerScript, _effIndex, _targetType) { } };
+ class ObjectTargetSelectHandlerFunction : public SpellScript::ObjectTargetSelectHandler { public: ObjectTargetSelectHandlerFunction(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectTargetSelectHandler((SpellScript::SpellObjectTargetSelectFnType)_pObjectTargetSelectHandlerScript, _effIndex, _targetType) { } }; \
+ class DestinationTargetSelectHandlerFunction : public SpellScript::DestinationTargetSelectHandler { public: DestinationTargetSelectHandlerFunction(SpellDestinationTargetSelectFnType _DestinationTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::DestinationTargetSelectHandler((SpellScript::SpellDestinationTargetSelectFnType)_DestinationTargetSelectHandlerScript, _effIndex, _targetType) { } };
#define PrepareSpellScript(CLASSNAME) SPELLSCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME)
public:
@@ -299,11 +312,17 @@ class SpellScript : public _SpellScript
HookList<ObjectTargetSelectHandler> OnObjectTargetSelect;
#define SpellObjectTargetSelectFn(F, I, N) ObjectTargetSelectHandlerFunction(&F, I, N)
+ // example: OnDestinationTargetSelect += SpellDestinationTargetSelectFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier);
+ // where function is void function(SpellDestination& target)
+ HookList<DestinationTargetSelectHandler> OnDestinationTargetSelect;
+ #define SpellDestinationTargetSelectFn(F, I, N) DestinationTargetSelectHandlerFunction(&F, I, N)
+
// hooks are executed in following order, at specified event of spell:
// 1. BeforeCast - executed when spell preparation is finished (when cast bar becomes full) before cast is handled
// 2. OnCheckCast - allows to override result of CheckCast function
// 3a. OnObjectAreaTargetSelect - executed just before adding selected targets to final target list (for area targets)
// 3b. OnObjectTargetSelect - executed just before adding selected target to final target list (for single unit targets)
+ // 3c. OnDestinationTargetSelect - executed just before adding selected target to final target list (for destination targets)
// 4. OnCast - executed just before spell is launched (creates missile) or executed
// 5. AfterCast - executed after spell missile is launched and immediate spell actions are done
// 6. OnEffectLaunch - executed just before specified effect handler call - when spell missile is launched
@@ -392,7 +411,8 @@ class SpellScript : public _SpellScript
void PreventHitDefaultEffect(SpellEffIndex effIndex);
// method avalible only in EffectHandler method
- int32 GetEffectValue();
+ int32 GetEffectValue() const;
+ void SetEffectValue(int32 value);
// returns: cast item if present.
Item* GetCastItem();
diff --git a/src/server/game/Tickets/TicketMgr.cpp b/src/server/game/Tickets/TicketMgr.cpp
index 83c049363d4..43c9ba80e24 100644
--- a/src/server/game/Tickets/TicketMgr.cpp
+++ b/src/server/game/Tickets/TicketMgr.cpp
@@ -34,26 +34,13 @@ inline float GetAge(uint64 t) { return float(time(NULL) - t) / DAY; }
// GM ticket
GmTicket::GmTicket() : _id(0), _playerGuid(0), _posX(0), _posY(0), _posZ(0), _mapId(0), _createTime(0), _lastModifiedTime(0),
_closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _viewed(false),
- _needResponse(false), _haveTicket(false) { }
+ _needResponse(false), _needMoreHelp(false) { }
-GmTicket::GmTicket(Player* player, WorldPacket& recvData) : _createTime(time(NULL)), _lastModifiedTime(time(NULL)), _closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _viewed(false), _haveTicket(false)
+GmTicket::GmTicket(Player* player) : _createTime(time(NULL)), _lastModifiedTime(time(NULL)), _closedBy(0), _assignedTo(0), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _viewed(false), _needResponse(false), _needMoreHelp(false)
{
_id = sTicketMgr->GenerateTicketId();
_playerName = player->GetName();
_playerGuid = player->GetGUID();
-
- uint32 mapId;
- recvData >> mapId; // Map is sent as UInt32!
- _mapId = mapId;
-
- recvData >> _posX;
- recvData >> _posY;
- recvData >> _posZ;
- recvData >> _message;
- uint32 needResponse;
- recvData >> needResponse;
- _needResponse = (needResponse == 17); // Requires GM response. 17 = true, 1 = false (17 is default)
- recvData >> _haveTicket; // Requests further GM interaction on a ticket to which a GM has already responded. Basically means "has a new ticket"
}
GmTicket::~GmTicket() { }
@@ -80,7 +67,7 @@ bool GmTicket::LoadFromDB(Field* fields)
_completed = fields[++index].GetBool();
_escalatedStatus = GMTicketEscalationStatus(fields[++index].GetUInt8());
_viewed = fields[++index].GetBool();
- _haveTicket = fields[++index].GetBool();
+ _needMoreHelp = fields[++index].GetBool();
return true;
}
@@ -107,7 +94,7 @@ void GmTicket::SaveToDB(SQLTransaction& trans) const
stmt->setBool (++index, _completed);
stmt->setUInt8 (++index, uint8(_escalatedStatus));
stmt->setBool (++index, _viewed);
- stmt->setBool (++index, _haveTicket);
+ stmt->setBool (++index, _needMoreHelp);
CharacterDatabase.ExecuteOrAppend(trans, stmt);
}
@@ -124,7 +111,7 @@ void GmTicket::WritePacket(WorldPacket& data) const
data << uint32(GMTICKET_STATUS_HASTEXT);
data << uint32(_id);
data << _message;
- data << uint8(_haveTicket);
+ data << uint8(_needMoreHelp);
data << GetAge(_lastModifiedTime);
if (GmTicket* ticket = sTicketMgr->GetOldestOpenTicket())
data << GetAge(ticket->GetLastModifiedTime());
@@ -220,6 +207,20 @@ void GmTicket::SetUnassigned()
}
}
+void GmTicket::SetPosition(uint32 mapId, float x, float y, float z)
+{
+ _mapId = mapId;
+ _posX = x;
+ _posY = y;
+ _posZ = z;
+}
+
+void GmTicket::SetGmAction(uint32 needResponse, bool needMoreHelp)
+{
+ _needResponse = (needResponse == 17); // Requires GM response. 17 = true, 1 = false (17 is default)
+ _needMoreHelp = needMoreHelp; // Requests further GM interaction on a ticket to which a GM has already responded. Basically means "has a new ticket"
+}
+
void GmTicket::TeleportTo(Player* player) const
{
player->TeleportTo(_mapId, _posX, _posY, _posZ, 0.0f, 0);
diff --git a/src/server/game/Tickets/TicketMgr.h b/src/server/game/Tickets/TicketMgr.h
index 3dd048189d7..5bfe78abbba 100644
--- a/src/server/game/Tickets/TicketMgr.h
+++ b/src/server/game/Tickets/TicketMgr.h
@@ -82,7 +82,7 @@ class GmTicket
{
public:
GmTicket();
- GmTicket(Player* player, WorldPacket& recvData);
+ GmTicket(Player* player);
~GmTicket();
bool IsClosed() const { return _closedBy; }
@@ -129,6 +129,8 @@ public:
void SetComment(std::string const& comment) { _comment = comment; }
void SetViewed() { _viewed = true; }
void SetUnassigned();
+ void SetPosition(uint32 mapId, float x, float y, float z);
+ void SetGmAction(uint32 needResponse, bool needMoreHelp);
void AppendResponse(std::string const& response) { _response += response; }
@@ -164,7 +166,7 @@ private:
GMTicketEscalationStatus _escalatedStatus;
bool _viewed;
bool _needResponse; /// @todo find out the use of this, and then store it in DB
- bool _haveTicket;
+ bool _needMoreHelp;
std::string _response;
std::string _chatLog; // No need to store in db, will be refreshed every session client side
};
diff --git a/src/server/game/Warden/Warden.cpp b/src/server/game/Warden/Warden.cpp
index 4611a4da884..42872bba22e 100644
--- a/src/server/game/Warden/Warden.cpp
+++ b/src/server/game/Warden/Warden.cpp
@@ -223,6 +223,9 @@ std::string Warden::Penalty(WardenCheck* check /*= NULL*/)
void WorldSession::HandleWardenDataOpcode(WorldPacket& recvData)
{
+ if (!_warden)
+ return;
+
_warden->DecryptData(recvData.contents(), recvData.size());
uint8 opcode;
recvData >> opcode;
diff --git a/src/server/game/Weather/Weather.cpp b/src/server/game/Weather/Weather.cpp
index b9133c9d0b1..cb332df9a41 100644
--- a/src/server/game/Weather/Weather.cpp
+++ b/src/server/game/Weather/Weather.cpp
@@ -194,7 +194,6 @@ bool Weather::ReGenerate()
void Weather::SendWeatherUpdateToPlayer(Player* player)
{
WorldPacket data(SMSG_WEATHER, (4+4+4));
-
data << uint32(GetWeatherState()) << (float)m_grade << uint8(0);
player->GetSession()->SendPacket(&data);
}
@@ -202,10 +201,6 @@ void Weather::SendWeatherUpdateToPlayer(Player* player)
/// Send the new weather to all players in the zone
bool Weather::UpdateWeather()
{
- Player* player = sWorld->FindPlayerInZone(m_zone);
- if (!player)
- return false;
-
///- Send the weather packet to all players in this zone
if (m_grade >= 1)
m_grade = 0.9999f;
@@ -215,8 +210,13 @@ bool Weather::UpdateWeather()
WeatherState state = GetWeatherState();
WorldPacket data(SMSG_WEATHER, (4+4+4));
- data << uint32(state) << (float)m_grade << uint8(0);
- player->SendMessageToSet(&data, true);
+ data << uint32(state);
+ data << (float)m_grade;
+ data << uint8(0);
+
+ //- Returns false if there were no players found to update
+ if (!sWorld->SendZoneMessage(m_zone, &data))
+ return false;
///- Log the event
char const* wthstr;
@@ -263,8 +263,8 @@ bool Weather::UpdateWeather()
wthstr = "fine";
break;
}
- TC_LOG_INFO("misc", "Change the weather of zone %u to %s.", m_zone, wthstr);
+ TC_LOG_INFO("misc", "Change the weather of zone %u to %s.", m_zone, wthstr);
sScriptMgr->OnWeatherChange(this, state, m_grade);
return true;
}
diff --git a/src/server/game/Weather/WeatherMgr.cpp b/src/server/game/Weather/WeatherMgr.cpp
index e327836fa4a..886a910becc 100644
--- a/src/server/game/Weather/WeatherMgr.cpp
+++ b/src/server/game/Weather/WeatherMgr.cpp
@@ -145,7 +145,6 @@ void LoadWeatherData()
void SendFineWeatherUpdateToPlayer(Player* player)
{
WorldPacket data(SMSG_WEATHER, (4+4+4));
-
data << (uint32)WEATHER_STATE_FINE << (float)0.0f << uint8(0);
player->GetSession()->SendPacket(&data);
}
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index d5bd0974922..af2fb90ea1b 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -169,10 +169,7 @@ Player* World::FindPlayerInZone(uint32 zone)
continue;
if (player->IsInWorld() && player->GetZoneId() == zone)
- {
- // Used by the weather system. We return the player to broadcast the change weather message to him and all players in the zone.
return player;
- }
}
return NULL;
}
@@ -1265,6 +1262,8 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_PACKET_SPOOF_BANDURATION] = sConfigMgr->GetIntDefault("PacketSpoof.BanDuration", 86400);
+ m_int_configs[CONFIG_BIRTHDAY_TIME] = sConfigMgr->GetIntDefault("BirthdayTime", 1222964635);
+
// call ScriptMgr if we're reloading the configuration
if (reload)
sScriptMgr->OnConfigLoad(reload);
@@ -2278,9 +2277,11 @@ void World::SendGlobalText(const char* text, WorldSession* self)
}
/// Send a packet to all players (or players selected team) in the zone (except self if mentioned)
-void World::SendZoneMessage(uint32 zone, WorldPacket* packet, WorldSession* self, uint32 team)
+bool World::SendZoneMessage(uint32 zone, WorldPacket* packet, WorldSession* self, uint32 team)
{
+ bool foundPlayerToSend = false;
SessionMap::const_iterator itr;
+
for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
{
if (itr->second &&
@@ -2291,8 +2292,11 @@ void World::SendZoneMessage(uint32 zone, WorldPacket* packet, WorldSession* self
(team == 0 || itr->second->GetPlayer()->GetTeam() == team))
{
itr->second->SendPacket(packet);
+ foundPlayerToSend = true;
}
}
+
+ return foundPlayerToSend;
}
/// Send a System Message to all players in the zone (except self if mentioned)
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 8c8aebf97d9..4c43507d038 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -339,6 +339,7 @@ enum WorldIntConfigs
CONFIG_BG_REWARD_WINNER_ARENA_LAST,
CONFIG_BG_REWARD_LOSER_HONOR_FIRST,
CONFIG_BG_REWARD_LOSER_HONOR_LAST,
+ CONFIG_BIRTHDAY_TIME,
INT_CONFIG_VALUE_COUNT
};
@@ -628,7 +629,7 @@ class World
void SendGMText(int32 string_id, ...);
void SendGlobalMessage(WorldPacket* packet, WorldSession* self = 0, uint32 team = 0);
void SendGlobalGMMessage(WorldPacket* packet, WorldSession* self = 0, uint32 team = 0);
- void SendZoneMessage(uint32 zone, WorldPacket* packet, WorldSession* self = 0, uint32 team = 0);
+ bool SendZoneMessage(uint32 zone, WorldPacket* packet, WorldSession* self = 0, uint32 team = 0);
void SendZoneText(uint32 zone, const char *text, WorldSession* self = 0, uint32 team = 0);
void SendServerMessage(ServerMessageType type, const char *text = "", Player* player = NULL);
diff --git a/src/server/scripts/Commands/cs_ban.cpp b/src/server/scripts/Commands/cs_ban.cpp
index b1a3dd4bca5..aa90c21c995 100644
--- a/src/server/scripts/Commands/cs_ban.cpp
+++ b/src/server/scripts/Commands/cs_ban.cpp
@@ -205,7 +205,7 @@ public:
else
handler->PSendSysMessage(LANG_BAN_YOUBANNED, nameOrIP.c_str(), secsToTimeString(TimeStringToSecs(durationStr), true).c_str(), reasonStr);
}
- else
+ else
{
if (sWorld->getBoolConfig(CONFIG_SHOW_BAN_IN_WORLD))
sWorld->SendWorldText(LANG_BAN_ACCOUNT_YOUPERMBANNEDMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), nameOrIP.c_str(), reasonStr);
diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp
index 55e22a8c99a..498ee68ba11 100644
--- a/src/server/scripts/Commands/cs_gm.cpp
+++ b/src/server/scripts/Commands/cs_gm.cpp
@@ -198,33 +198,34 @@ public:
//Enable\Disable Invisible mode
static bool HandleGMVisibleCommand(ChatHandler* handler, char const* args)
{
+ Player* _player = handler->GetSession()->GetPlayer();
+
if (!*args)
{
- handler->PSendSysMessage(LANG_YOU_ARE, handler->GetSession()->GetPlayer()->isGMVisible() ? handler->GetTrinityString(LANG_VISIBLE) : handler->GetTrinityString(LANG_INVISIBLE));
+ handler->PSendSysMessage(LANG_YOU_ARE, _player->isGMVisible() ? handler->GetTrinityString(LANG_VISIBLE) : handler->GetTrinityString(LANG_INVISIBLE));
return true;
}
const uint32 VISUAL_AURA = 37800;
std::string param = (char*)args;
- Player* player = handler->GetSession()->GetPlayer();
if (param == "on")
{
- if (player->HasAura(VISUAL_AURA, 0))
- player->RemoveAurasDueToSpell(VISUAL_AURA);
+ if (_player->HasAura(VISUAL_AURA, 0))
+ _player->RemoveAurasDueToSpell(VISUAL_AURA);
- player->SetGMVisible(true);
+ _player->SetGMVisible(true);
+ _player->UpdateObjectVisibility();
handler->GetSession()->SendNotification(LANG_INVISIBLE_VISIBLE);
return true;
}
if (param == "off")
{
+ _player->AddAura(VISUAL_AURA, _player);
+ _player->SetGMVisible(false);
+ _player->UpdateObjectVisibility();
handler->GetSession()->SendNotification(LANG_INVISIBLE_INVISIBLE);
- player->SetGMVisible(false);
-
- player->AddAura(VISUAL_AURA, player);
-
return true;
}
@@ -236,12 +237,11 @@ public:
//Enable\Disable GM Mode
static bool HandleGMCommand(ChatHandler* handler, char const* args)
{
+ Player* _player = handler->GetSession()->GetPlayer();
+
if (!*args)
{
- if (handler->GetSession()->GetPlayer()->IsGameMaster())
- handler->GetSession()->SendNotification(LANG_GM_ON);
- else
- handler->GetSession()->SendNotification(LANG_GM_OFF);
+ handler->GetSession()->SendNotification(_player->IsGameMaster() ? LANG_GM_ON : LANG_GM_OFF);
return true;
}
@@ -249,9 +249,9 @@ public:
if (param == "on")
{
- handler->GetSession()->GetPlayer()->SetGameMaster(true);
+ _player->SetGameMaster(true);
handler->GetSession()->SendNotification(LANG_GM_ON);
- handler->GetSession()->GetPlayer()->UpdateTriggerVisibility();
+ _player->UpdateTriggerVisibility();
#ifdef _DEBUG_VMAPS
VMAP::IVMapManager* vMapManager = VMAP::VMapFactory::createOrGetVMapManager();
vMapManager->processCommand("stoplog");
@@ -261,9 +261,9 @@ public:
if (param == "off")
{
- handler->GetSession()->GetPlayer()->SetGameMaster(false);
+ _player->SetGameMaster(false);
handler->GetSession()->SendNotification(LANG_GM_OFF);
- handler->GetSession()->GetPlayer()->UpdateTriggerVisibility();
+ _player->UpdateTriggerVisibility();
#ifdef _DEBUG_VMAPS
VMAP::IVMapManager* vMapManager = VMAP::VMapFactory::createOrGetVMapManager();
vMapManager->processCommand("startlog");
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 1b8f50b5eab..6de8a155d01 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -94,6 +94,7 @@ public:
{ "unpossess", rbac::RBAC_PERM_COMMAND_UNPOSSESS, false, &HandleUnPossessCommand, "", NULL },
{ "unstuck", rbac::RBAC_PERM_COMMAND_UNSTUCK, true, &HandleUnstuckCommand, "", NULL },
{ "wchange", rbac::RBAC_PERM_COMMAND_WCHANGE, false, &HandleChangeWeather, "", NULL },
+ { "mailbox", rbac::RBAC_PERM_COMMAND_MAILBOX, false, &HandleMailBoxCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
return commandTable;
@@ -813,11 +814,12 @@ public:
if (kickReason != NULL)
kickReasonStr = kickReason;
- if (sWorld->getBoolConfig(CONFIG_SHOW_KICK_IN_WORLD))
- sWorld->SendWorldText(LANG_COMMAND_KICKMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), playerName.c_str(), kickReasonStr.c_str());
- else
- handler->PSendSysMessage(LANG_COMMAND_KICKMESSAGE, playerName.c_str());
- target->GetSession()->KickPlayer();
+ if (sWorld->getBoolConfig(CONFIG_SHOW_KICK_IN_WORLD))
+ sWorld->SendWorldText(LANG_COMMAND_KICKMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), playerName.c_str(), kickReasonStr.c_str());
+ else
+ handler->PSendSysMessage(LANG_COMMAND_KICKMESSAGE, playerName.c_str());
+
+ target->GetSession()->KickPlayer();
return true;
}
@@ -1337,23 +1339,20 @@ public:
return false;
}
- std::string tNameLink = handler->GetNameLink(target);
-
- if (!target->GetSkillValue(skill))
- {
- handler->PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, skillLine->name[handler->GetSessionDbcLocale()]);
- handler->SetSentErrorMessage(true);
- return false;
- }
+ bool targetHasSkill = target->GetSkillValue(skill);
- uint16 max = maxPureSkill ? atol (maxPureSkill) : target->GetPureMaxSkillValue(skill);
+ // If our target does not yet have the skill they are trying to add to them, the chosen level also becomes
+ // the max level of the new profession.
+ uint16 max = maxPureSkill ? atol (maxPureSkill) : targetHasSkill ? target->GetPureMaxSkillValue(skill) : uint16(level);
if (level <= 0 || level > max || max <= 0)
return false;
- target->SetSkill(skill, target->GetSkillStep(skill), level, max);
- handler->PSendSysMessage(LANG_SET_SKILL, skill, skillLine->name[handler->GetSessionDbcLocale()], tNameLink.c_str(), level, max);
-
+ // If the player has the skill, we get the current skill step. If they don't have the skill, we
+ // add the skill to the player's book with step 1 (which is the first rank, in most cases something
+ // like 'Apprentice <skill>'.
+ target->SetSkill(skill, targetHasSkill ? target->GetSkillStep(skill) : 1, level, max);
+ handler->PSendSysMessage(LANG_SET_SKILL, skill, skillLine->name[handler->GetSessionDbcLocale()], handler->GetNameLink(target).c_str(), level, max);
return true;
}
@@ -1840,7 +1839,7 @@ public:
target->GetSession()->m_muteTime = muteTime;
stmt->setInt64(0, muteTime);
std::string nameLink = handler->playerLink(targetName);
-
+
if (sWorld->getBoolConfig(CONFIG_SHOW_MUTE_IN_WORLD))
{
sWorld->SendWorldText(LANG_COMMAND_MUTEMESSAGE_WORLD, (handler->GetSession() ? handler->GetSession()->GetPlayerName().c_str() : "Server"), nameLink.c_str(), notSpeakTime, muteReasonStr.c_str());
@@ -2480,6 +2479,14 @@ public:
player->StopCastingBindSight();
return true;
}
+
+ static bool HandleMailBoxCommand(ChatHandler* handler, char const* /*args*/)
+ {
+ Player* player = handler->GetSession()->GetPlayer();
+
+ handler->GetSession()->SendShowMailBox(player->GetGUID());
+ return true;
+ }
};
void AddSC_misc_commandscript()
diff --git a/src/server/scripts/Commands/cs_quest.cpp b/src/server/scripts/Commands/cs_quest.cpp
index 01e28b0910d..369a8e87289 100644
--- a/src/server/scripts/Commands/cs_quest.cpp
+++ b/src/server/scripts/Commands/cs_quest.cpp
@@ -147,7 +147,7 @@ public:
}
}
- player->RemoveActiveQuest(entry);
+ player->RemoveActiveQuest(entry, false);
player->RemoveRewardedQuest(entry);
handler->SendSysMessage(LANG_COMMAND_QUEST_REMOVED);
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp
index 845db0cac1c..1edb1100289 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp
@@ -74,7 +74,7 @@ public:
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (Creature* Moira = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_MOIRA) : 0))
+ if (Creature* Moira = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_MOIRA)))
{
Moira->AI()->EnterEvadeMode();
Moira->setFaction(35);
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp
index fe38377341b..8989a8065dc 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockSpire/boss_rend_blackhand.cpp
@@ -191,7 +191,7 @@ public:
void SetData(uint32 type, uint32 data) OVERRIDE
{
- if (instance && type == AREATRIGGER && data == AREATRIGGER_BLACKROCK_STADIUM)
+ if (type == AREATRIGGER && data == AREATRIGGER_BLACKROCK_STADIUM)
{
if (!gythEvent)
{
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_chromaggus.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_chromaggus.cpp
index d292e5f7701..3930656f0e1 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_chromaggus.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_chromaggus.cpp
@@ -183,7 +183,7 @@ public:
void EnterCombat(Unit* /*who*/) OVERRIDE
{
- if (instance && instance->GetBossState(BOSS_FLAMEGOR) != DONE)
+ if (instance->GetBossState(BOSS_FLAMEGOR) != DONE)
{
EnterEvadeMode();
return;
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_ebonroc.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_ebonroc.cpp
index b8a3c157c52..8d25fe117fe 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_ebonroc.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_ebonroc.cpp
@@ -45,7 +45,7 @@ public:
void EnterCombat(Unit* /*who*/) OVERRIDE
{
- if (instance && instance->GetBossState(BOSS_BROODLORD) != DONE)
+ if (instance->GetBossState(BOSS_BROODLORD) != DONE)
{
EnterEvadeMode();
return;
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_firemaw.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_firemaw.cpp
index 706f376e882..cbd625e852a 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_firemaw.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_firemaw.cpp
@@ -45,7 +45,7 @@ public:
void EnterCombat(Unit* /*who*/) OVERRIDE
{
- if (instance && instance->GetBossState(BOSS_BROODLORD) != DONE)
+ if (instance->GetBossState(BOSS_BROODLORD) != DONE)
{
EnterEvadeMode();
return;
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_flamegor.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_flamegor.cpp
index e262cba1978..390bcaa3c9d 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_flamegor.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_flamegor.cpp
@@ -50,7 +50,7 @@ public:
void EnterCombat(Unit* /*who*/) OVERRIDE
{
- if (instance && instance->GetBossState(BOSS_BROODLORD) != DONE)
+ if (instance->GetBossState(BOSS_BROODLORD) != DONE)
{
EnterEvadeMode();
return;
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp
index 945d8b40d32..02662cd235c 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp
@@ -223,16 +223,14 @@ public:
void SetData(uint32 type, uint32 data) OVERRIDE
{
- if (instance && type == 1 && data == 1)
+ if ( type == 1 && data == 1)
{
me->StopMoving();
events.ScheduleEvent(EVENT_PATH_2, 9000);
}
- if (instance && type == 1 && data == 2)
- {
+ if (type == 1 && data == 2)
events.ScheduleEvent(EVENT_SUCCESS_1, 5000);
- }
}
void UpdateAI(uint32 diff) OVERRIDE
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp
index 294b662aea7..d2bd82447dc 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_majordomo_executus.cpp
@@ -96,7 +96,7 @@ class boss_majordomo : public CreatureScript
void UpdateAI(uint32 diff) OVERRIDE
{
- if (instance && instance->GetBossState(BOSS_MAJORDOMO_EXECUTUS) != DONE)
+ if (instance->GetBossState(BOSS_MAJORDOMO_EXECUTUS) != DONE)
{
if (!UpdateVictim())
return;
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp
index 4e135ad513a..4d22ba6abb3 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp
@@ -233,7 +233,7 @@ class boss_ragnaros : public CreatureScript
break;
case EVENT_SUBMERGE:
{
- if (instance && !_isBanished)
+ if (!_isBanished)
{
//Creature spawning and ragnaros becomming unattackable
//is not very well supported in the core //no it really isnt
diff --git a/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp b/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp
index d26458be82e..2b50c525f78 100644
--- a/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp
+++ b/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp
@@ -193,15 +193,10 @@ public:
instance->HandleGameObject(0, false, go);
}
- void SetInFace(bool bBool)
+ void SetInFace(bool isRight)
{
- if (bBool)
- {
- if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(DATA_GO_CAVE_IN_RIGHT)))
- me->SetFacingToObject(go);
- }else
- if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(DATA_GO_CAVE_IN_LEFT)))
- me->SetFacingToObject(go);
+ if (GameObject* go = GameObject::GetGameObject(*me, instance->GetData64(isRight ? DATA_GO_CAVE_IN_RIGHT : DATA_GO_CAVE_IN_LEFT)))
+ me->SetFacingToObject(go);
}
void RestoreAll()
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp
index 36bb2e32cb6..2dff776c35a 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_moroes.cpp
@@ -252,7 +252,7 @@ public:
if (!UpdateVictim())
return;
- if (instance && !instance->GetData(TYPE_MOROES))
+ if (!instance->GetData(TYPE_MOROES))
{
EnterEvadeMode();
return;
@@ -371,7 +371,7 @@ struct boss_moroes_guestAI : public ScriptedAI
void UpdateAI(uint32 /*diff*/) OVERRIDE
{
- if (instance && !instance->GetData(TYPE_MOROES))
+ if (!instance->GetData(TYPE_MOROES))
EnterEvadeMode();
DoMeleeAttackIfReady();
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_netherspite.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_netherspite.cpp
index 1b9ef055b8c..ebd8762e9be 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/boss_netherspite.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_netherspite.cpp
@@ -247,13 +247,13 @@ public:
PortalPhase = false;
Talk(EMOTE_PHASE_BANISH);
- for (int i=0; i<3; ++i)
+ for (uint8 i = 0; i < 3; ++i)
me->RemoveAurasDueToSpell(NetherBuff[i]);
}
void HandleDoors(bool open) // Massive Door switcher
{
- if (GameObject* Door = GameObject::GetGameObject(*me, instance ? instance->GetData64(DATA_GO_MASSIVE_DOOR) : 0))
+ if (GameObject* Door = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_GO_MASSIVE_DOOR) ))
Door->SetGoState(open ? GO_STATE_ACTIVE : GO_STATE_READY);
}
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp
index f667394f29c..241ac85faa2 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/karazhan.cpp
@@ -496,12 +496,13 @@ public:
EventStarted = false;
YellTimer = 0;
- if (instance && instance->GetData64(DATA_IMAGE_OF_MEDIVH) == 0)
+ if (instance->GetData64(DATA_IMAGE_OF_MEDIVH) == 0)
{
instance->SetData64(DATA_IMAGE_OF_MEDIVH, me->GetGUID());
(*me).GetMotionMaster()->MovePoint(1, MedivPos[0], MedivPos[1], MedivPos[2]);
Step = 0;
- }else
+ }
+ else
{
me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
me->RemoveCorpse();
diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp
index 6c15fdc77fa..0601c69e96d 100644
--- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp
+++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp
@@ -515,7 +515,7 @@ public:
return;
}
//Don't really die in all phases of Kael'Thas
- if (instance && instance->GetData(DATA_KAELTHAS_EVENT) == 0)
+ if (instance->GetData(DATA_KAELTHAS_EVENT) == 0)
{
//prevent death
damage = 0;
diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp
index 8592120f94a..4bc0ee68cc3 100644
--- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp
+++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp
@@ -376,7 +376,7 @@ struct boss_priestess_lackey_commonAI : public ScriptedAI
ResetThreatTimer = urand(5000, 20000);
// in case she is not alive and Reset was for some reason called, respawn her (most likely party wipe after killing her)
- if (Creature* pDelrissa = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_DELRISSA) : 0))
+ if (Creature* pDelrissa = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_DELRISSA)))
{
if (!pDelrissa->IsAlive())
pDelrissa->Respawn();
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp
index 0d62d47a5d6..a78dce47784 100644
--- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp
@@ -172,7 +172,7 @@ public:
if (!UpdateVictim())
return;
- if (_bHasDied && !_bHeal && instance && instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) == SPECIAL)
+ if (_bHasDied && !_bHeal && instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) == SPECIAL)
{
//On ressurection, stop fake death and heal whitemane and resume fight
if (Unit* Whitemane = Unit::GetUnit(*me, instance->GetData64(DATA_WHITEMANE)))
@@ -259,7 +259,7 @@ public:
void AttackStart(Unit* who) OVERRIDE
{
- if (instance && instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) == NOT_STARTED)
+ if (instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) == NOT_STARTED)
return;
ScriptedAI::AttackStart(who);
@@ -289,11 +289,11 @@ public:
if (_bCanResurrect)
{
//When casting resuruction make sure to delay so on rez when reinstate battle deepsleep runs out
- if (instance && Wait_Timer <= diff)
+ if (Wait_Timer <= diff)
{
- if (Unit* Mograine = Unit::GetUnit(*me, instance->GetData64(DATA_MOGRAINE)))
+ if (Creature* mograine = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_MOGRAINE)))
{
- DoCast(Mograine, SPELL_SCARLETRESURRECTION);
+ DoCast(mograine, SPELL_SCARLETRESURRECTION);
Talk(SAY_WH_RESSURECT);
_bCanResurrect = false;
}
@@ -325,7 +325,7 @@ public:
if (!HealthAbovePct(75))
target = me;
- if (Creature* mograine = Unit::GetCreature((*me), instance->GetData64(DATA_MOGRAINE)))
+ if (Creature* mograine = Unit::GetCreature(*me, instance->GetData64(DATA_MOGRAINE)))
{
// checking _bCanResurrectCheck prevents her healing Mograine while he is "faking death"
if (_bCanResurrectCheck && mograine->IsAlive() && !mograine->HealthAbovePct(75))
diff --git a/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp b/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp
index eb7295f72d0..76ae6b06058 100644
--- a/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp
+++ b/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp
@@ -93,7 +93,7 @@ public:
InstanceScript* instance = creature->GetInstanceScript();
if (instance && instance->GetData(TYPE_FREE_NPC) != DONE && instance->GetData(TYPE_RETHILGORE) == DONE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_DOOR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_DOOR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
diff --git a/src/server/scripts/EasternKingdoms/Stratholme/boss_baron_rivendare.cpp b/src/server/scripts/EasternKingdoms/Stratholme/boss_baron_rivendare.cpp
index fe0e3a050c8..f4663c0f8ec 100644
--- a/src/server/scripts/EasternKingdoms/Stratholme/boss_baron_rivendare.cpp
+++ b/src/server/scripts/EasternKingdoms/Stratholme/boss_baron_rivendare.cpp
@@ -93,7 +93,7 @@ public:
MortalStrike_Timer = 12000;
// RaiseDead_Timer = 30000;
SummonSkeletons_Timer = 34000;
- if (instance && instance->GetData(TYPE_RAMSTEIN) == DONE)
+ if (instance->GetData(TYPE_RAMSTEIN) == DONE)
instance->SetData(TYPE_BARON, NOT_STARTED);
}
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp
index a52ddcea3b0..9dcbed211bb 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_brutallus.cpp
@@ -176,7 +176,7 @@ public:
void DoIntro()
{
- Creature* Madrigosa = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_MADRIGOSA) : 0);
+ Creature* Madrigosa = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_MADRIGOSA));
if (!Madrigosa)
return;
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
index 9d073cd7ef8..e8b112aa1cd 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
@@ -454,7 +454,7 @@ public:
{
if (uiRandomSayTimer < diff)
{
- if (instance && instance->GetBossState(DATA_MURU) != DONE && instance->GetBossState(DATA_KILJAEDEN) == NOT_STARTED)
+ if (instance->GetBossState(DATA_MURU) != DONE && instance->GetBossState(DATA_KILJAEDEN) == NOT_STARTED)
Talk(SAY_KJ_OFFCOMBAT);
uiRandomSayTimer = 30000;
} else uiRandomSayTimer -= diff;
@@ -1206,7 +1206,7 @@ public:
if (uiTimer <= diff)
{
- if (Unit* random = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_PLAYER_GUID) : 0))
+ if (Unit* random = ObjectAccessor::GetPlayer(*me, instance->GetData64(DATA_PLAYER_GUID)))
DoCast(random, SPELL_SHADOW_BOLT, false);
uiTimer = urand(500, 1000);
} else uiTimer -= diff;
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp
index 426771e6db6..6980dbfb9c2 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp
@@ -433,10 +433,11 @@ public:
{
if (!SummonSentinel)
{
- if (InAction && instance && instance->GetBossState(DATA_MURU) == NOT_STARTED)
+ if (InAction && instance->GetBossState(DATA_MURU) == NOT_STARTED)
Reset();
return;
}
+
if (SummonTimer <= diff)
{
DoCastAOE(SPELL_SUMMON_VOID_SENTINEL, false);
@@ -602,7 +603,7 @@ public:
{
if (SpellTimer <= diff)
{
- Unit* Victim = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_PLAYER_GUID) : 0);
+ Unit* Victim = Unit::GetUnit(*me, instance->GetData64(DATA_PLAYER_GUID));
switch (NeedForAHack)
{
case 0:
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp
index 04e3d9f3450..d6657ac0986 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp
@@ -231,7 +231,7 @@ struct boss_hexlord_addAI : public ScriptedAI
void UpdateAI(uint32 /*diff*/) OVERRIDE
{
- if (instance && instance->GetData(DATA_HEXLORDEVENT) != IN_PROGRESS)
+ if (instance->GetData(DATA_HEXLORDEVENT) != IN_PROGRESS)
{
EnterEvadeMode();
return;
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp
index 5b943fd57f2..e542b3c4895 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp
@@ -344,9 +344,8 @@ class npc_zulian_prowler : public CreatureScript
DoCast(me, SPELL_SNEAK_RANK_1_1);
DoCast(me, SPELL_SNEAK_RANK_1_2);
- if (_instance)
- if (Unit* arlokk = me->GetUnit(*me, _instance->GetData64(NPC_ARLOKK)))
- me->GetMotionMaster()->MovePoint(0, arlokk->GetPositionX(), arlokk->GetPositionY(), arlokk->GetPositionZ());
+ if (Unit* arlokk = me->GetUnit(*me, _instance->GetData64(NPC_ARLOKK)))
+ me->GetMotionMaster()->MovePoint(0, arlokk->GetPositionX(), arlokk->GetPositionY(), arlokk->GetPositionZ());
_events.ScheduleEvent(EVENT_ATTACK, 6000);
}
@@ -365,13 +364,10 @@ class npc_zulian_prowler : public CreatureScript
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (_instance)
+ if (Unit* arlokk = me->GetUnit(*me, _instance->GetData64(NPC_ARLOKK)))
{
- if (Unit* arlokk = me->GetUnit(*me, _instance->GetData64(NPC_ARLOKK)))
- {
- if (arlokk->IsAlive())
- arlokk->GetAI()->SetData(_sideData, 0);
- }
+ if (arlokk->IsAlive())
+ arlokk->GetAI()->SetData(_sideData, 0);
}
me->DespawnOrUnsummon(4000);
}
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp
index e6ef90d1638..336599f2cc5 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -16,13 +15,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Boss_Jeklik
-SD%Complete: 85
-SDComment: Problem in finding the right flying batriders for spawning and making them fly.
-SDCategory: Zul'Gurub
-EndScriptData */
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "zulgurub.h"
@@ -44,11 +36,47 @@ enum Spells
SPELL_CHAIN_MIND_FLAY = 26044, // Right ID unknown. So disabled
SPELL_GREATERHEAL = 23954,
SPELL_BAT_FORM = 23966,
+
// Batriders Spell
SPELL_BOMB = 40332 // Wrong ID but Magmadars bomb is not working...
};
-class boss_jeklik : public CreatureScript //jeklik
+enum BatIds
+{
+ NPC_BLOODSEEKER_BAT = 11368,
+ NPC_FRENZIED_BAT = 14965
+};
+
+enum Events
+{
+ EVENT_CHARGE_JEKLIK = 1,
+ EVENT_SONIC_BURST,
+ EVENT_SCREECH,
+ EVENT_SPAWN_BATS,
+ EVENT_SHADOW_WORD_PAIN,
+ EVENT_MIND_FLAY,
+ EVENT_CHAIN_MIND_FLAY,
+ EVENT_GREATER_HEAL,
+ EVENT_SPAWN_FLYING_BATS
+};
+
+enum Phase
+{
+ PHASE_ONE = 1,
+ PHASE_TWO = 2
+};
+
+Position const SpawnBat[6] =
+{
+ { -12291.6220f, -1380.2640f, 144.8304f, 5.483f },
+ { -12289.6220f, -1380.2640f, 144.8304f, 5.483f },
+ { -12293.6220f, -1380.2640f, 144.8304f, 5.483f },
+ { -12291.6220f, -1380.2640f, 144.8304f, 5.483f },
+ { -12289.6220f, -1380.2640f, 144.8304f, 5.483f },
+ { -12293.6220f, -1380.2640f, 144.8304f, 5.483f }
+};
+
+class boss_jeklik : public CreatureScript
{
public: boss_jeklik() : CreatureScript("boss_jeklik") { }
@@ -56,32 +84,9 @@ class boss_jeklik : public CreatureScript //jeklik
{
boss_jeklikAI(Creature* creature) : BossAI(creature, DATA_JEKLIK) { }
- uint32 Charge_Timer;
- uint32 SonicBurst_Timer;
- uint32 Screech_Timer;
- uint32 SpawnBats_Timer;
- uint32 ShadowWordPain_Timer;
- uint32 MindFlay_Timer;
- uint32 ChainMindFlay_Timer;
- uint32 GreaterHeal_Timer;
- uint32 SpawnFlyingBats_Timer;
-
- bool PhaseTwo;
-
void Reset() OVERRIDE
{
_Reset();
- Charge_Timer = 20000;
- SonicBurst_Timer = 8000;
- Screech_Timer = 13000;
- SpawnBats_Timer = 60000;
- ShadowWordPain_Timer = 6000;
- MindFlay_Timer = 11000;
- ChainMindFlay_Timer = 26000;
- GreaterHeal_Timer = 50000;
- SpawnFlyingBats_Timer = 10000;
-
- PhaseTwo = false;
}
void JustDied(Unit* /*killer*/) OVERRIDE
@@ -94,156 +99,124 @@ class boss_jeklik : public CreatureScript //jeklik
{
_EnterCombat();
Talk(SAY_AGGRO);
+ events.SetPhase(PHASE_ONE);
+
+ events.ScheduleEvent(EVENT_CHARGE_JEKLIK, 20000, 0, PHASE_ONE);
+ events.ScheduleEvent(EVENT_SONIC_BURST, 8000, 0, PHASE_ONE);
+ events.ScheduleEvent(EVENT_SCREECH, 13000, 0, PHASE_ONE);
+ events.ScheduleEvent(EVENT_SPAWN_BATS, 60000, 0, PHASE_ONE);
+
+ me->SetCanFly(true);
DoCast(me, SPELL_BAT_FORM);
}
+ void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) OVERRIDE
+ {
+ if (events.IsInPhase(PHASE_ONE) && !HealthAbovePct(50))
+ {
+ me->RemoveAurasDueToSpell(SPELL_BAT_FORM);
+ me->SetCanFly(false);
+ DoResetThreat();
+ events.SetPhase(PHASE_TWO);
+ events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 6000, 0, PHASE_TWO);
+ events.ScheduleEvent(EVENT_MIND_FLAY, 11000, 0, PHASE_TWO);
+ events.ScheduleEvent(EVENT_CHAIN_MIND_FLAY, 26000, 0, PHASE_TWO);
+ events.ScheduleEvent(EVENT_GREATER_HEAL, 50000, 0, PHASE_TWO);
+ events.ScheduleEvent(EVENT_SPAWN_FLYING_BATS, 10000, 0, PHASE_TWO);
+ return;
+ }
+ }
+
void UpdateAI(uint32 diff) OVERRIDE
{
if (!UpdateVictim())
return;
- if (me->GetVictim() && me->IsAlive())
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
{
- if (HealthAbovePct(50))
+ switch (eventId)
{
- if (Charge_Timer <= diff)
- {
+ case EVENT_CHARGE_JEKLIK:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
{
DoCast(target, SPELL_CHARGE);
AttackStart(target);
}
-
- Charge_Timer = urand(15000, 30000);
- } else Charge_Timer -= diff;
-
- if (SonicBurst_Timer <= diff)
- {
+ events.ScheduleEvent(EVENT_CHARGE_JEKLIK, urand(15000, 30000), 0, PHASE_ONE);
+ break;
+ case EVENT_SONIC_BURST:
DoCastVictim(SPELL_SONICBURST);
- SonicBurst_Timer = urand(8000, 13000);
- } else SonicBurst_Timer -= diff;
-
- if (Screech_Timer <= diff)
- {
+ events.ScheduleEvent(EVENT_SONIC_BURST, urand(8000, 13000), 0, PHASE_ONE);
+ case EVENT_SCREECH:
DoCastVictim(SPELL_SCREECH);
- Screech_Timer = urand(18000, 26000);
- } else Screech_Timer -= diff;
-
- if (SpawnBats_Timer <= diff)
- {
- Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0);
-
- Creature* Bat = NULL;
- Bat = me->SummonCreature(11368, -12291.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (target && Bat) Bat ->AI()->AttackStart(target);
-
- Bat = me->SummonCreature(11368, -12289.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (target && Bat) Bat ->AI()->AttackStart(target);
-
- Bat = me->SummonCreature(11368, -12293.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (target && Bat) Bat ->AI()->AttackStart(target);
-
- Bat = me->SummonCreature(11368, -12291.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (target && Bat) Bat ->AI()->AttackStart(target);
-
- Bat = me->SummonCreature(11368, -12289.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (target && Bat) Bat ->AI()->AttackStart(target);
- Bat = me->SummonCreature(11368, -12293.6220f, -1380.2640f, 144.8304f, 5.483f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (target && Bat) Bat ->AI()->AttackStart(target);
-
- SpawnBats_Timer = 60000;
- } else SpawnBats_Timer -= diff;
- }
- else
- {
- if (PhaseTwo)
- {
- if (ShadowWordPain_Timer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- DoCast(target, SPELL_SHADOW_WORD_PAIN);
- ShadowWordPain_Timer = urand(12000, 18000);
- }
- }ShadowWordPain_Timer -=diff;
-
- if (MindFlay_Timer <= diff)
- {
- DoCastVictim(SPELL_MIND_FLAY);
- MindFlay_Timer = 16000;
- }MindFlay_Timer -=diff;
-
- if (ChainMindFlay_Timer <= diff)
- {
- me->InterruptNonMeleeSpells(false);
- DoCastVictim(SPELL_CHAIN_MIND_FLAY);
- ChainMindFlay_Timer = urand(15000, 30000);
- }ChainMindFlay_Timer -=diff;
-
- if (GreaterHeal_Timer <= diff)
- {
- me->InterruptNonMeleeSpells(false);
- DoCast(me, SPELL_GREATERHEAL);
- GreaterHeal_Timer = urand(25000, 35000);
- }GreaterHeal_Timer -=diff;
-
- if (SpawnFlyingBats_Timer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- if (Creature* FlyingBat = me->SummonCreature(14965, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()+15, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
- FlyingBat->AI()->AttackStart(target);
- }
-
- SpawnFlyingBats_Timer = urand(10000, 15000);
- } else SpawnFlyingBats_Timer -=diff;
- }
- else
- {
- me->SetDisplayId(15219);
- DoResetThreat();
- PhaseTwo = true;
- }
+ events.ScheduleEvent(EVENT_SCREECH, urand(18000, 26000), 0, PHASE_ONE);
+ case EVENT_SPAWN_BATS:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ for (uint8 i = 0; i < 6; ++i)
+ if (Creature* bat = me->SummonCreature(NPC_BLOODSEEKER_BAT, SpawnBat[i], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
+ bat->AI()->AttackStart(target);
+ events.ScheduleEvent(EVENT_SPAWN_BATS, 60000, 0, PHASE_ONE);
+ break;
+ case EVENT_SHADOW_WORD_PAIN:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_SHADOW_WORD_PAIN);
+ events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(12000, 18000), 0, PHASE_TWO);
+ break;
+ case EVENT_MIND_FLAY:
+ DoCastVictim(SPELL_MIND_FLAY);
+ events.ScheduleEvent(EVENT_MIND_FLAY, 16000, 0, PHASE_TWO);
+ break;
+ case EVENT_CHAIN_MIND_FLAY:
+ me->InterruptNonMeleeSpells(false);
+ DoCastVictim(SPELL_CHAIN_MIND_FLAY);
+ events.ScheduleEvent(EVENT_CHAIN_MIND_FLAY, urand(15000, 30000), 0, PHASE_TWO);
+ break;
+ case EVENT_GREATER_HEAL:
+ me->InterruptNonMeleeSpells(false);
+ DoCast(me, SPELL_GREATERHEAL);
+ events.ScheduleEvent(EVENT_GREATER_HEAL, urand(25000, 35000), 0, PHASE_TWO);
+ break;
+ case EVENT_SPAWN_FLYING_BATS:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ if (Creature* flyingBat = me->SummonCreature(NPC_FRENZIED_BAT, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + 15.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
+ flyingBat->AI()->AttackStart(target);
+ events.ScheduleEvent(EVENT_SPAWN_FLYING_BATS, urand(10000, 15000), 0, PHASE_TWO);
+ break;
+ default:
+ break;
}
-
- DoMeleeAttackIfReady();
}
+
+ DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- return new boss_jeklikAI(creature);
+ return GetZulGurubAI<boss_jeklikAI>(creature);
}
};
-//Flying Bat
+// Flying Bat
class npc_batrider : public CreatureScript
{
public:
-
- npc_batrider()
- : CreatureScript("npc_batrider")
- {
- }
+ npc_batrider() : CreatureScript("npc_batrider") { }
struct npc_batriderAI : public ScriptedAI
{
- npc_batriderAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
-
- InstanceScript* instance;
+ npc_batriderAI(Creature* creature) : ScriptedAI(creature) { }
uint32 Bomb_Timer;
- uint32 Check_Timer;
void Reset() OVERRIDE
{
Bomb_Timer = 2000;
- Check_Timer = 1000;
-
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
@@ -254,7 +227,6 @@ class npc_batrider : public CreatureScript
if (!UpdateVictim())
return;
- //Bomb_Timer
if (Bomb_Timer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
@@ -262,20 +234,9 @@ class npc_batrider : public CreatureScript
DoCast(target, SPELL_BOMB);
Bomb_Timer = 5000;
}
- } else Bomb_Timer -= diff;
-
- //Check_Timer
- if (Check_Timer <= diff)
- {
- if (instance->GetBossState(DATA_JEKLIK) == DONE)
- {
- me->setDeathState(JUST_DIED);
- me->RemoveCorpse();
- return;
- }
-
- Check_Timer = 1000;
- } else Check_Timer -= diff;
+ }
+ else
+ Bomb_Timer -= diff;
DoMeleeAttackIfReady();
}
@@ -283,7 +244,7 @@ class npc_batrider : public CreatureScript
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- return GetInstanceAI<npc_batriderAI>(creature);
+ return new npc_batriderAI(creature);
}
};
@@ -292,4 +253,3 @@ void AddSC_boss_jeklik()
new boss_jeklik();
new npc_batrider();
}
-
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h
index c92e8b8724d..a9386ff1782 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h
@@ -66,13 +66,9 @@ enum GameobjectIds
};
template<class AI>
-CreatureAI* GetZulGurubAI(Creature* creature)
+AI* GetZulGurubAI(Creature* creature)
{
- if (InstanceMap* instance = creature->GetMap()->ToInstanceMap())
- if (instance->GetInstanceScript())
- if (instance->GetScriptId() == sObjectMgr->GetScriptId(ZGScriptName))
- return new AI(creature);
- return NULL;
+ return GetInstanceAI<AI>(creature, ZGScriptName);
}
#endif
diff --git a/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp b/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp
index 4bfbff50dd5..0cd1403d48a 100644
--- a/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp
@@ -233,10 +233,7 @@ public:
struct npc_lord_gregor_lescovarAI : public npc_escortAI
{
- npc_lord_gregor_lescovarAI(Creature* creature) : npc_escortAI(creature)
- {
- creature->RestoreFaction();
- }
+ npc_lord_gregor_lescovarAI(Creature* creature) : npc_escortAI(creature) { }
uint32 uiTimer;
uint32 uiPhase;
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp
index a4f9a364684..c7803f23e1b 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp
@@ -72,14 +72,15 @@ public:
AuraTimer = 5000;
InfernoTimer = 45000;
- if (instance && IsEvent)
+ if (IsEvent)
instance->SetData(DATA_ANETHERONEVENT, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
- if (instance && IsEvent)
+ if (IsEvent)
instance->SetData(DATA_ANETHERONEVENT, IN_PROGRESS);
+
Talk(SAY_ONAGGRO);
}
@@ -91,7 +92,7 @@ public:
void WaypointReached(uint32 waypointId) OVERRIDE
{
- if (waypointId == 7 && instance)
+ if (waypointId == 7)
{
Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_JAINAPROUDMOORE));
if (target && target->IsAlive())
@@ -102,7 +103,7 @@ public:
void JustDied(Unit* killer) OVERRIDE
{
hyjal_trashAI::JustDied(killer);
- if (instance && IsEvent)
+ if (IsEvent)
instance->SetData(DATA_ANETHERONEVENT, DONE);
Talk(SAY_ONDEATH);
}
@@ -225,7 +226,7 @@ public:
{
if (AnetheronGUID)
{
- Creature* boss = Unit::GetCreature((*me), AnetheronGUID);
+ Creature* boss = ObjectAccessor::GetCreature(*me, AnetheronGUID);
if (!boss || (boss && boss->isDead()))
{
me->setDeathState(JUST_DIED);
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp
index 6d296945659..4decce7482f 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp
@@ -78,14 +78,15 @@ public:
EnrageTimer = 600000;
enraged = false;
- if (instance && IsEvent)
+ if (IsEvent)
instance->SetData(DATA_AZGALOREVENT, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
- if (instance && IsEvent)
+ if (IsEvent)
instance->SetData(DATA_AZGALOREVENT, IN_PROGRESS);
+
Talk(SAY_ONAGGRO);
}
@@ -107,7 +108,7 @@ public:
void JustDied(Unit* killer) OVERRIDE
{
hyjal_trashAI::JustDied(killer);
- if (instance && IsEvent)
+ if (IsEvent)
instance->SetData(DATA_AZGALOREVENT, DONE);
Talk(SAY_ONDEATH);
}
@@ -237,7 +238,7 @@ public:
{
if (AzgalorGUID)
{
- Creature* boss = Unit::GetCreature((*me), AzgalorGUID);
+ Creature* boss = ObjectAccessor::GetCreature(*me, AzgalorGUID);
if (!boss || (boss && boss->isDead()))
{
me->setDeathState(JUST_DIED);
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp
index 7a5870809f7..af7b0c1d899 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp
@@ -74,13 +74,13 @@ public:
MarkTimer = 45000;
MarkTimerBase = 45000;
- if (instance && IsEvent)
+ if (IsEvent)
instance->SetData(DATA_KAZROGALEVENT, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
- if (instance && IsEvent)
+ if (IsEvent)
instance->SetData(DATA_KAZROGALEVENT, IN_PROGRESS);
Talk(SAY_ONAGGRO);
}
@@ -103,7 +103,7 @@ public:
void JustDied(Unit* killer) OVERRIDE
{
hyjal_trashAI::JustDied(killer);
- if (instance && IsEvent)
+ if (IsEvent)
instance->SetData(DATA_KAZROGALEVENT, DONE);
DoPlaySoundToSet(me, SOUND_ONDEATH);
}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp
index 4d6a94b6e73..691207a4682 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp
@@ -69,13 +69,13 @@ public:
NovaTimer = 15000;
IceboltTimer = 10000;
- if (instance && IsEvent)
+ if (IsEvent)
instance->SetData(DATA_RAGEWINTERCHILLEVENT, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
- if (instance && IsEvent)
+ if (IsEvent)
instance->SetData(DATA_RAGEWINTERCHILLEVENT, IN_PROGRESS);
Talk(SAY_ONAGGRO);
}
@@ -98,7 +98,7 @@ public:
void JustDied(Unit* killer) OVERRIDE
{
hyjal_trashAI::JustDied(killer);
- if (instance && IsEvent)
+ if (IsEvent)
instance->SetData(DATA_RAGEWINTERCHILLEVENT, DONE);
Talk(SAY_ONDEATH);
}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp
index 3b3cacf7d3f..c8006158ef1 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp
@@ -705,7 +705,7 @@ void hyjalAI::UpdateAI(uint32 diff)
switch (me->GetEntry())
{
case JAINA:
- if (instance && instance->GetData(DATA_ALLIANCE_RETREAT))
+ if (instance->GetData(DATA_ALLIANCE_RETREAT))
{
me->SetVisible(false);
HideNearPos(me->GetPositionX(), me->GetPositionY());
@@ -717,7 +717,7 @@ void hyjalAI::UpdateAI(uint32 diff)
else me->SetVisible(true);
break;
case THRALL: //thrall
- if (instance && instance->GetData(DATA_HORDE_RETREAT))
+ if (instance->GetData(DATA_HORDE_RETREAT))
{
me->SetVisible(false);
HideNearPos(me->GetPositionX(), me->GetPositionY());
@@ -781,7 +781,7 @@ void hyjalAI::UpdateAI(uint32 diff)
if (Summon)
{
- if (instance && EnemyCount)
+ if (EnemyCount)
{
EnemyCount = instance->GetData(DATA_TRASH);
if (!EnemyCount)
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
index 2688fbbdaff..cbace6df028 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
@@ -443,7 +443,7 @@ public:
void WaypointReached(uint32 waypointId) OVERRIDE
{
- if (waypointId == 0 && instance && !IsOverrun)
+ if (waypointId == 0 && !IsOverrun)
{
if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall
{
@@ -559,7 +559,7 @@ public:
void WaypointReached(uint32 waypointId) OVERRIDE
{
- if (waypointId == 7 && instance && !IsOverrun)
+ if (waypointId == 7 && !IsOverrun)
{
if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall
{
@@ -658,7 +658,7 @@ public:
void WaypointReached(uint32 waypointId) OVERRIDE
{
- if (waypointId == 7 && instance && !IsOverrun)
+ if (waypointId == 7 && !IsOverrun)
{
if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall
{
@@ -769,7 +769,7 @@ public:
void WaypointReached(uint32 waypointId) OVERRIDE
{
- if (waypointId == 7 && instance && !IsOverrun)
+ if (waypointId == 7 && !IsOverrun)
{
if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall
{
@@ -882,7 +882,7 @@ public:
void WaypointReached(uint32 waypointId) OVERRIDE
{
- if (waypointId == 7 && instance && !IsOverrun)
+ if (waypointId == 7 && !IsOverrun)
{
if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall
{
@@ -978,7 +978,7 @@ public:
void WaypointReached(uint32 waypointId) OVERRIDE
{
- if (waypointId == 7 && instance && !IsOverrun)
+ if (waypointId == 7 && !IsOverrun)
{
if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall
{
@@ -1064,7 +1064,7 @@ public:
void WaypointReached(uint32 waypointId) OVERRIDE
{
- if (waypointId == 7 && instance && !IsOverrun)
+ if (waypointId == 7 && !IsOverrun)
{
if (instance->GetData(DATA_ALLIANCE_RETREAT))//2.alliance boss down, attack thrall
{
@@ -1153,7 +1153,7 @@ public:
void WaypointReached(uint32 waypointId) OVERRIDE
{
- if (waypointId == 2 && instance && !IsOverrun)
+ if (waypointId == 2 && !IsOverrun)
{
Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_THRALL));
if (target && target->IsAlive())
@@ -1166,7 +1166,7 @@ public:
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (instance && IsEvent)
+ if (IsEvent)
instance->SetData(DATA_TRASH, 0);//signal trash is dead
float x, y, z;
@@ -1181,11 +1181,13 @@ public:
void UpdateAI(uint32 diff) OVERRIDE
{
hyjal_trashAI::UpdateAI(diff);
+
if (IsEvent || IsOverrun)
{
CAST_AI(hyjal_trashAI, me->AI())->SetCanAttack(false);
npc_escortAI::UpdateAI(diff);
}
+
if (IsEvent)
{
if (!go)
@@ -1197,7 +1199,9 @@ public:
AddWaypoint(i, FrostWyrmWPs[i][0], FrostWyrmWPs[i][1], FrostWyrmWPs[i][2]);
Start(false, true);
SetDespawnAtEnd(false);
- }else{//fly path FlyPathWPs
+ }
+ else
+ {//fly path FlyPathWPs
for (uint8 i = 0; i < 3; ++i)
AddWaypoint(i, FlyPathWPs[i][0]+irand(-10, 10), FlyPathWPs[i][1]+irand(-10, 10), FlyPathWPs[i][2]);
Start(false, true);
@@ -1205,9 +1209,12 @@ public:
}
}
}
+
if (!UpdateVictim())
return;
- if (!me->IsWithinDist(me->GetVictim(), 25)){
+
+ if (!me->IsWithinDist(me->GetVictim(), 25))
+ {
if (MoveTimer <= diff)
{
me->GetMotionMaster()->MoveChase(me->GetVictim());
@@ -1227,7 +1234,6 @@ public:
} else FrostBreathTimer -= diff;
}
};
-
};
class npc_gargoyle : public CreatureScript
@@ -1246,7 +1252,8 @@ public:
{
instance = creature->GetInstanceScript();
go = false;
- DummyTarget[0] = 0;DummyTarget[1] = 0;DummyTarget[2] = 0;
+ for (uint8 i = 0; i < 3; ++i)
+ DummyTarget[i] = 0;
Reset();
}
@@ -1267,7 +1274,7 @@ public:
void WaypointReached(uint32 waypointId) OVERRIDE
{
- if (waypointId == 2 && instance && !IsOverrun)
+ if (waypointId == 2 && !IsOverrun)
{
Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_THRALL));
if (target && target->IsAlive())
@@ -1291,11 +1298,13 @@ public:
void UpdateAI(uint32 diff) OVERRIDE
{
hyjal_trashAI::UpdateAI(diff);
+
if (IsEvent || IsOverrun)
{
CAST_AI(hyjal_trashAI, me->AI())->SetCanAttack(false);
npc_escortAI::UpdateAI(diff);
}
+
if (IsEvent)
{
if (!go)
@@ -1315,6 +1324,7 @@ public:
}
}
}
+
if (IsOverrun && !UpdateVictim())
{
if (faction == 0)//alliance
@@ -1326,8 +1336,10 @@ public:
} else StrikeTimer -= diff;
}
}
+
if (!UpdateVictim())
return;
+
if (!me->IsWithinDist(me->GetVictim(), 20) || forcemove)
{
forcemove = false;
@@ -1347,6 +1359,7 @@ public:
MoveTimer = 2000;
} else MoveTimer-=diff;
}
+
if (StrikeTimer <= diff)
{
if (me->IsWithinDist(me->GetVictim(), 20))
@@ -1359,7 +1372,6 @@ public:
} else StrikeTimer -= diff;
}
};
-
};
class alliance_rifleman : public CreatureScript
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp
index e4f1324d19c..7c0169cda95 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp
@@ -147,7 +147,7 @@ public:
return;
}
- if (Creature* pArthas = me->GetCreature(*me, instance ? instance->GetData64(DATA_ARTHAS) : 0))
+ if (Creature* pArthas = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ARTHAS)))
if (pArthas->isDead())
{
EnterEvadeMode();
@@ -196,7 +196,7 @@ public:
uiOutroTimer = 8000;
break;
case 2:
- me->SetTarget(instance ? instance->GetData64(DATA_ARTHAS) : 0);
+ me->SetTarget(instance->GetData64(DATA_ARTHAS));
me->HandleEmoteCommand(29);
Talk(SAY_ESCAPE_SPEECH_2);
++uiOutroStep;
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp
index 061c7fdfc62..5b1db051a56 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_captain_skarloc.cpp
@@ -99,7 +99,7 @@ public:
{
Talk(SAY_DEATH);
- if (instance && instance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS)
+ if (instance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS)
instance->SetData(TYPE_THRALL_PART1, DONE);
}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp
index cb25d96acf3..4d75bc0545c 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp
@@ -91,7 +91,7 @@ public:
{
Talk(SAY_DEATH);
- if (instance && instance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS)
+ if (instance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS)
instance->SetData(TYPE_THRALL_PART4, DONE);
}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp
index 6e4ef814dbe..bf902ba403c 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp
@@ -82,7 +82,7 @@ public:
player->PrepareQuestMenu(creature->GetGUID());
InstanceScript* instance = creature->GetInstanceScript();
- if (instance && instance->GetData(TYPE_BARREL_DIVERSION) != DONE && !player->HasItemCount(ITEM_ENTRY_BOMBS))
+ if (instance->GetData(TYPE_BARREL_DIVERSION) != DONE && !player->HasItemCount(ITEM_ENTRY_BOMBS))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_EROZION1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
if (player->GetQuestStatus(QUEST_ENTRY_RETURN) == QUEST_STATUS_COMPLETE)
@@ -92,7 +92,6 @@ public:
return true;
}
-
};
/*######
@@ -585,18 +584,14 @@ public:
{
player->CLOSE_GOSSIP_MENU();
- if (instance && instance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS)
+ if (instance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS)
{
instance->SetData(TYPE_THRALL_PART4, IN_PROGRESS);
if (instance->GetData64(DATA_EPOCH) == 0)
creature->SummonCreature(ENTRY_EPOCH, 2639.13f, 698.55f, 65.43f, 4.59f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000);
- if (uint64 ThrallGUID = instance->GetData64(DATA_THRALL))
- {
- Creature* Thrall = (Unit::GetCreature((*creature), ThrallGUID));
- if (Thrall)
- CAST_AI(npc_thrall_old_hillsbrad::npc_thrall_old_hillsbradAI, Thrall->AI())->StartWP();
- }
+ if (Creature* thrall = (Unit::GetCreature(*creature, instance->GetData64(DATA_THRALL))))
+ CAST_AI(npc_thrall_old_hillsbrad::npc_thrall_old_hillsbradAI, thrall->AI())->StartWP();
}
}
return true;
@@ -605,7 +600,7 @@ public:
bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
{
InstanceScript* instance = creature->GetInstanceScript();
- if (instance && instance->GetData(TYPE_THRALL_PART3) == DONE && instance->GetData(TYPE_THRALL_PART4) == NOT_STARTED)
+ if (instance->GetData(TYPE_THRALL_PART3) == DONE && instance->GetData(TYPE_THRALL_PART4) == NOT_STARTED)
{
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_EPOCH1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
player->SEND_GOSSIP_MENU(GOSSIP_ID_EPOCH1, creature->GetGUID());
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp
index f1406a5a008..58bda23fb36 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp
@@ -138,8 +138,8 @@ public:
void AttackStart(Unit* /*who*/) OVERRIDE
{
- //if (instance && instance->GetData(TYPE_MEDIVH) == IN_PROGRESS)
- //return;
+ //if (instance->GetData(TYPE_MEDIVH) == IN_PROGRESS)
+ // return;
//ScriptedAI::AttackStart(who);
}
@@ -297,7 +297,7 @@ public:
if (!creature_entry)
return;
- if (instance && instance->GetData(TYPE_MEDIVH) != IN_PROGRESS)
+ if (instance->GetData(TYPE_MEDIVH) != IN_PROGRESS)
{
me->InterruptNonMeleeSpells(true);
me->RemoveAllAuras();
@@ -311,7 +311,7 @@ public:
pos.m_positionZ = std::max(me->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY));
if (Unit* Summon = DoSummon(creature_entry, pos, 30000, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT))
- if (Unit* temp = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_MEDIVH) : 0))
+ if (Unit* temp = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_MEDIVH)))
Summon->AddThreat(temp, 0.0f);
}
diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp b/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp
index 7381594a1ce..29e08699a0f 100644
--- a/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp
+++ b/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp
@@ -340,7 +340,7 @@ public:
Trinity::GameObjectInRangeCheck check(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 15);
Trinity::GameObjectLastSearcher<Trinity::GameObjectInRangeCheck> searcher(me, Floor, check);
me->VisitNearbyGridObject(30, searcher);
- if (instance && Floor)
+ if (Floor)
instance->SetData64(DATA_FLOOR_ERUPTION_GUID, Floor->GetGUID());
events.ScheduleEvent(EVENT_BELLOWING_ROAR, 30000);
break;
diff --git a/src/server/scripts/Kalimdor/RazorfenDowns/boss_glutton.cpp b/src/server/scripts/Kalimdor/RazorfenDowns/boss_glutton.cpp
index d29831b8cde..830c3fed382 100644
--- a/src/server/scripts/Kalimdor/RazorfenDowns/boss_glutton.cpp
+++ b/src/server/scripts/Kalimdor/RazorfenDowns/boss_glutton.cpp
@@ -40,7 +40,10 @@ public:
struct boss_gluttonAI : public BossAI
{
- boss_gluttonAI(Creature* creature) : BossAI(creature, DATA_GLUTTON) { }
+ boss_gluttonAI(Creature* creature) : BossAI(creature, DATA_GLUTTON)
+ {
+ hp15 = false;
+ }
void Reset() OVERRIDE
{
diff --git a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp
index 3b4defeca56..b9605794074 100644
--- a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp
+++ b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp
@@ -158,6 +158,7 @@ public:
{
instance = creature->GetInstanceScript();
eventInProgress = false;
+ spawnerCount = 0;
}
void Reset() OVERRIDE
@@ -177,9 +178,7 @@ public:
void EnterCombat(Unit* who) OVERRIDE
{
if (channeling)
- {
Talk(SAY_WATCH_OUT, who);
- }
else
{
events.ScheduleEvent(EVENT_FIREBALL, 1000);
diff --git a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.h b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.h
index 4778677e067..a9a5a82f127 100644
--- a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.h
+++ b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.h
@@ -61,13 +61,9 @@ enum GameObjectIds
};
template<class AI>
-CreatureAI* GetRazorfenDownsAI(Creature* creature)
+AI* GetRazorfenDownsAI(Creature* creature)
{
- if (InstanceMap* instance = creature->GetMap()->ToInstanceMap())
- if (instance->GetInstanceScript())
- if (instance->GetScriptId() == sObjectMgr->GetScriptId(RFDScriptName))
- return new AI(creature);
- return NULL;
+ return GetInstanceAI<AI>(creature, RFDScriptName);
}
#endif
diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp
index c1897ff48ad..433193bd703 100644
--- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp
+++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_bug_trio.cpp
@@ -119,7 +119,7 @@ public:
//Checking if Vem is dead. If yes we will enrage.
if (Check_Timer <= diff)
{
- if (instance && instance->GetData(DATA_VEMISDEAD))
+ if (instance->GetData(DATA_VEMISDEAD))
{
DoCast(me, SPELL_ENRAGE);
VemDead = true;
diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp
index 81171eef580..d84279f1e8b 100644
--- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp
+++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_twinemperors.cpp
@@ -502,8 +502,6 @@ public:
//Added. Can be removed if its included in DB.
me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true);
- me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, 0);
- me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, 0);
}
void CastSpellOnBug(Creature* target)
diff --git a/src/server/scripts/Kalimdor/zone_ashenvale.cpp b/src/server/scripts/Kalimdor/zone_ashenvale.cpp
index 41c0441bca5..ec28ee42625 100644
--- a/src/server/scripts/Kalimdor/zone_ashenvale.cpp
+++ b/src/server/scripts/Kalimdor/zone_ashenvale.cpp
@@ -198,7 +198,7 @@ public:
void sQuestAccept(Player* player, Quest const* quest)
{
- if (quest->GetQuestId() == QUEST_TOREK_ASSULT)
+ if (quest->GetQuestId() == QUEST_FREEDOM_TO_RUUL)
{
me->setFaction(FACTION_QUEST);
npc_escortAI::Start(true, false, player->GetGUID());
diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp
index 1890dfb4ff8..f599e6e7c27 100644
--- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp
+++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_jedoga_shadowseeker.cpp
@@ -394,7 +394,7 @@ public:
void AttackStart(Unit* victim) OVERRIDE
{
- if ((instance && instance->GetBossState(DATA_JEDOGA_SHADOWSEEKER) == IN_PROGRESS) || !victim)
+ if ((instance->GetBossState(DATA_JEDOGA_SHADOWSEEKER) == IN_PROGRESS) || !victim)
return;
ScriptedAI::AttackStart(victim);
@@ -403,7 +403,7 @@ public:
void MoveInLineOfSight(Unit* who) OVERRIDE
{
- if ((instance && instance->GetBossState(DATA_JEDOGA_SHADOWSEEKER) == IN_PROGRESS) || !who)
+ if ((instance->GetBossState(DATA_JEDOGA_SHADOWSEEKER) == IN_PROGRESS) || !who)
return;
ScriptedAI::MoveInLineOfSight(who);
@@ -432,7 +432,7 @@ public:
void UpdateAI(uint32 diff) OVERRIDE
{
- if (instance && bCheckTimer <= diff)
+ if (bCheckTimer <= diff)
{
if (me->GetGUID() == instance->GetData64(DATA_ADD_JEDOGA_OPFER) && !bWalking)
{
diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp
index 77d3ce21d0c..efe439de440 100644
--- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp
+++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp
@@ -17,76 +17,75 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
+#include "SpellScript.h"
#include "Player.h"
#include "ahnkahet.h"
enum Spells
{
- SPELL_BLOODTHIRST = 55968, // Trigger Spell + add aura
- SPELL_CONJURE_FLAME_SPHERE = 55931,
- SPELL_FLAME_SPHERE_SUMMON_1 = 55895, // 1x 30106
- H_SPELL_FLAME_SPHERE_SUMMON_1 = 59511, // 1x 31686
- H_SPELL_FLAME_SPHERE_SUMMON_2 = 59512, // 1x 31687
- SPELL_FLAME_SPHERE_SPAWN_EFFECT = 55891,
- SPELL_FLAME_SPHERE_VISUAL = 55928,
- SPELL_FLAME_SPHERE_PERIODIC = 55926,
- SPELL_FLAME_SPHERE_DEATH_EFFECT = 55947,
- SPELL_BEAM_VISUAL = 60342,
- SPELL_EMBRACE_OF_THE_VAMPYR = 55959,
- SPELL_VANISH = 55964,
- CREATURE_FLAME_SPHERE = 30106,
- H_CREATURE_FLAME_SPHERE_1 = 31686,
- H_CREATURE_FLAME_SPHERE_2 = 31687,
- SPELL_HOVER_FALL = 60425
+ SPELL_BLOODTHIRST = 55968, // Trigger Spell + add aura
+ SPELL_CONJURE_FLAME_SPHERE = 55931,
+ SPELL_FLAME_SPHERE_SUMMON_1 = 55895, // 1x 30106
+ SPELL_FLAME_SPHERE_SUMMON_2 = 59511, // 1x 31686
+ SPELL_FLAME_SPHERE_SUMMON_3 = 59512, // 1x 31687
+ SPELL_FLAME_SPHERE_SPAWN_EFFECT = 55891,
+ SPELL_FLAME_SPHERE_VISUAL = 55928,
+ SPELL_FLAME_SPHERE_PERIODIC = 55926,
+ SPELL_FLAME_SPHERE_DEATH_EFFECT = 55947,
+ SPELL_EMBRACE_OF_THE_VAMPYR = 55959,
+ SPELL_VANISH = 55964,
+
+ NPC_FLAME_SPHERE_1 = 30106,
+ NPC_FLAME_SPHERE_2 = 31686,
+ NPC_FLAME_SPHERE_3 = 31687,
+
+ SPELL_BEAM_VISUAL = 60342,
+ SPELL_HOVER_FALL = 60425
};
enum Misc
{
- DATA_EMBRACE_DMG = 20000,
- H_DATA_EMBRACE_DMG = 40000,
- DATA_SPHERE_DISTANCE = 15
+ DATA_EMBRACE_DMG = 20000,
+ H_DATA_EMBRACE_DMG = 40000
};
-#define DATA_SPHERE_ANGLE_OFFSET 0.7f
-#define DATA_GROUND_POSITION_Z 11.30809f
+#define DATA_SPHERE_DISTANCE 25.0f
+#define DATA_SPHERE_ANGLE_OFFSET M_PI / 2
+#define DATA_GROUND_POSITION_Z 11.30809f
enum Yells
{
- SAY_1 = 0,
- SAY_WARNING = 1,
- SAY_AGGRO = 2,
- SAY_SLAY = 3,
- SAY_DEATH = 4,
- SAY_FEED = 5,
- SAY_VANISH = 6
+ SAY_1 = 0,
+ SAY_WARNING = 1,
+ SAY_AGGRO = 2,
+ SAY_SLAY = 3,
+ SAY_DEATH = 4,
+ SAY_FEED = 5,
+ SAY_VANISH = 6
};
enum Events
{
- EVENT_CASTING_FLAME_SPHERES = 1,
+ EVENT_CONJURE_FLAME_SPHERES = 1,
+ EVENT_BLOODTHIRST,
+ EVENT_VANISH,
EVENT_JUST_VANISHED,
EVENT_VANISHED,
EVENT_FEEDING,
- EVENT_BLOODTHIRST,
- EVENT_FLAME_SPHERE,
- EVENT_VANISH
-};
-
-enum Phase
-{
- PHASE_NORMAL = 1,
- PHASE_SPECIAL = 2
+ // Flame Sphere
+ EVENT_START_MOVE,
+ EVENT_DESPAWN
};
-class boss_taldaram : public CreatureScript
+class boss_prince_taldaram : public CreatureScript
{
public:
- boss_taldaram() : CreatureScript("boss_taldaram") { }
+ boss_prince_taldaram() : CreatureScript("boss_prince_taldaram") { }
- struct boss_taldaramAI : public BossAI
+ struct boss_prince_taldaramAI : public BossAI
{
- boss_taldaramAI(Creature* creature) : BossAI(creature, DATA_PRINCE_TALDARAM)
+ boss_prince_taldaramAI(Creature* creature) : BossAI(creature, DATA_PRINCE_TALDARAM)
{
me->SetDisableGravity(true);
}
@@ -94,6 +93,7 @@ class boss_taldaram : public CreatureScript
void Reset() OVERRIDE
{
_Reset();
+ _flameSphereTargetGUID = 0;
_embraceTargetGUID = 0;
_embraceTakenDamage = 0;
}
@@ -102,10 +102,24 @@ class boss_taldaram : public CreatureScript
{
_EnterCombat();
Talk(SAY_AGGRO);
- events.SetPhase(PHASE_NORMAL);
events.ScheduleEvent(EVENT_BLOODTHIRST, 10000);
events.ScheduleEvent(EVENT_VANISH, urand(25000, 35000));
- events.ScheduleEvent(EVENT_FLAME_SPHERE, 5000);
+ events.ScheduleEvent(EVENT_CONJURE_FLAME_SPHERES, 5000);
+ }
+
+ void JustSummoned(Creature* summon)
+ {
+ BossAI::JustSummoned(summon);
+
+ switch (summon->GetEntry())
+ {
+ case NPC_FLAME_SPHERE_1:
+ case NPC_FLAME_SPHERE_2:
+ case NPC_FLAME_SPHERE_3:
+ summon->AI()->SetGUID(_flameSphereTargetGUID);
+ default:
+ return;
+ }
}
void UpdateAI(uint32 diff) OVERRIDE
@@ -122,80 +136,40 @@ class boss_taldaram : public CreatureScript
{
switch (eventId)
{
- if (events.IsInPhase(PHASE_NORMAL))
- {
- case EVENT_BLOODTHIRST:
- DoCast(me, SPELL_BLOODTHIRST);
- events.ScheduleEvent(EVENT_BLOODTHIRST, 10000);
- break;
- case EVENT_FLAME_SPHERE:
- DoCastVictim(SPELL_CONJURE_FLAME_SPHERE);
- events.SetPhase(PHASE_SPECIAL);
- events.ScheduleEvent(EVENT_CASTING_FLAME_SPHERES, 3000);
- events.ScheduleEvent(EVENT_FLAME_SPHERE, 15000);
- break;
- case EVENT_VANISH:
+ case EVENT_BLOODTHIRST:
+ DoCast(me, SPELL_BLOODTHIRST);
+ events.ScheduleEvent(EVENT_BLOODTHIRST, 10000);
+ break;
+ case EVENT_CONJURE_FLAME_SPHERES:
+ // random target?
+ if (Unit* victim = me->GetVictim())
{
- Map::PlayerList const& players = me->GetMap()->GetPlayers();
- uint32 targets = 0;
- for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
- {
- Player* player = i->GetSource();
- if (player && player->IsAlive())
- ++targets;
- }
-
- if (targets > 2)
- {
- Talk(SAY_VANISH);
- DoCast(me, SPELL_VANISH);
- events.SetPhase(PHASE_SPECIAL);
- events.ScheduleEvent(EVENT_JUST_VANISHED, 500);
- if (Unit* embraceTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- _embraceTargetGUID = embraceTarget->GetGUID();
- }
- events.ScheduleEvent(EVENT_VANISH, urand(25000, 35000));
- break;
+ _flameSphereTargetGUID = victim->GetGUID();
+ DoCast(victim, SPELL_CONJURE_FLAME_SPHERE);
}
- }
- case EVENT_CASTING_FLAME_SPHERES:
+ events.ScheduleEvent(EVENT_CONJURE_FLAME_SPHERES, 15000);
+ break;
+ case EVENT_VANISH:
{
- events.SetPhase(PHASE_NORMAL);
- Unit* sphereTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
- if (!sphereTarget)
- break;
-
- float angle, x, y;
-
- //DoCast(me, SPELL_FLAME_SPHERE_SUMMON_1);
- if (Creature* sphere = DoSpawnCreature(CREATURE_FLAME_SPHERE, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10 * IN_MILLISECONDS))
+ Map::PlayerList const& players = me->GetMap()->GetPlayers();
+ uint32 targets = 0;
+ for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
{
- angle = sphere->GetAngle(sphereTarget);
- x = sphere->GetPositionX() + DATA_SPHERE_DISTANCE * std::cos(angle);
- y = sphere->GetPositionY() + DATA_SPHERE_DISTANCE * std::sin(angle);
- sphere->GetMotionMaster()->MovePoint(0, x, y, sphere->GetPositionZ());
+ Player* player = i->GetSource();
+ if (player && player->IsAlive())
+ ++targets;
}
- if (IsHeroic())
+ if (targets > 2)
{
- //DoCast(me, H_SPELL_FLAME_SPHERE_SUMMON_1);
- if (Creature* sphere = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_1, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10 * IN_MILLISECONDS))
- {
- angle = sphere->GetAngle(sphereTarget) + DATA_SPHERE_ANGLE_OFFSET;
- x = sphere->GetPositionX() + DATA_SPHERE_DISTANCE/2 * std::cos(angle);
- y = sphere->GetPositionY() + DATA_SPHERE_DISTANCE/2 * std::sin(angle);
- sphere->GetMotionMaster()->MovePoint(0, x, y, sphere->GetPositionZ());
- }
-
- //DoCast(me, H_SPELL_FLAME_SPHERE_SUMMON_2);
- if (Creature* sphere = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_2, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10 * IN_MILLISECONDS))
- {
- angle = sphere->GetAngle(sphereTarget) - DATA_SPHERE_ANGLE_OFFSET;
- x = sphere->GetPositionX() + DATA_SPHERE_DISTANCE/2 * std::cos(angle);
- y = sphere->GetPositionY() + DATA_SPHERE_DISTANCE/2 * std::sin(angle);
- sphere->GetMotionMaster()->MovePoint(0, x, y, sphere->GetPositionZ());
- }
+ Talk(SAY_VANISH);
+ DoCast(me, SPELL_VANISH);
+ events.DelayEvents(500);
+ events.ScheduleEvent(EVENT_JUST_VANISHED, 500);
+ if (Unit* embraceTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ _embraceTargetGUID = embraceTarget->GetGUID();
}
+ events.ScheduleEvent(EVENT_VANISH, urand(25000, 35000));
break;
}
case EVENT_JUST_VANISHED:
@@ -218,7 +192,6 @@ class boss_taldaram : public CreatureScript
break;
case EVENT_FEEDING:
_embraceTargetGUID = 0;
- events.SetPhase(PHASE_NORMAL);
break;
default:
break;
@@ -232,13 +205,12 @@ class boss_taldaram : public CreatureScript
{
Unit* embraceTarget = GetEmbraceTarget();
- if (events.IsInPhase(PHASE_SPECIAL) && embraceTarget && embraceTarget->IsAlive())
+ if (embraceTarget && embraceTarget->IsAlive())
{
_embraceTakenDamage += damage;
if (_embraceTakenDamage > DUNGEON_MODE<uint32>(DATA_EMBRACE_DMG, H_DATA_EMBRACE_DMG))
{
_embraceTargetGUID = 0;
- events.SetPhase(PHASE_NORMAL);
me->CastStop();
}
}
@@ -255,12 +227,9 @@ class boss_taldaram : public CreatureScript
if (victim->GetTypeId() != TYPEID_PLAYER)
return;
- Unit* embraceTarget = GetEmbraceTarget();
- if (events.IsInPhase(PHASE_SPECIAL) && embraceTarget && victim == embraceTarget)
- {
+ if (victim->GetGUID() == _embraceTargetGUID)
_embraceTargetGUID = 0;
- events.SetPhase(PHASE_NORMAL);
- }
+
Talk(SAY_SLAY);
}
@@ -289,76 +258,120 @@ class boss_taldaram : public CreatureScript
me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), DATA_GROUND_POSITION_Z, me->GetOrientation());
DoCast(SPELL_HOVER_FALL);
me->SetDisableGravity(false);
- me->GetMotionMaster()->MovePoint(0, me->GetHomePosition());
+ me->GetMotionMaster()->MoveLand(0, me->GetHomePosition());
Talk(SAY_WARNING);
instance->HandleGameObject(instance->GetData64(DATA_PRINCE_TALDARAM_PLATFORM), true);
}
private:
+ uint64 _flameSphereTargetGUID;
uint64 _embraceTargetGUID;
uint32 _embraceTakenDamage;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- return GetAhnKahetAI<boss_taldaramAI>(creature);
+ return GetAhnKahetAI<boss_prince_taldaramAI>(creature);
}
};
-class npc_taldaram_flamesphere : public CreatureScript
+// 30106, 31686, 31687 - Flame Sphere
+class npc_prince_taldaram_flame_sphere : public CreatureScript
{
public:
- npc_taldaram_flamesphere() : CreatureScript("npc_taldaram_flamesphere") { }
+ npc_prince_taldaram_flame_sphere() : CreatureScript("npc_prince_taldaram_flame_sphere") { }
- struct npc_taldaram_flamesphereAI : public ScriptedAI
+ struct npc_prince_taldaram_flame_sphereAI : public ScriptedAI
{
- npc_taldaram_flamesphereAI(Creature* creature) : ScriptedAI(creature)
+ npc_prince_taldaram_flame_sphereAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset() OVERRIDE
{
+ DoCast(me, SPELL_FLAME_SPHERE_SPAWN_EFFECT, true);
+ DoCast(me, SPELL_FLAME_SPHERE_VISUAL, true);
+
+ _flameSphereTargetGUID = 0;
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_START_MOVE, 3 * IN_MILLISECONDS);
+ _events.ScheduleEvent(EVENT_DESPAWN, 13 * IN_MILLISECONDS);
}
- void Reset() OVERRIDE
+ void SetGUID(uint64 guid, int32 /*id = 0*/) OVERRIDE
{
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- //! HACK: Creature's can't have MOVEMENTFLAG_FLYING
- me->AddUnitMovementFlag(MOVEMENTFLAG_FLYING);
- me->setFaction(16);
- me->SetObjectScale(1.0f);
- DoCast(me, SPELL_FLAME_SPHERE_VISUAL);
- DoCast(me, SPELL_FLAME_SPHERE_SPAWN_EFFECT);
- DoCast(me, SPELL_FLAME_SPHERE_PERIODIC);
- _despawnTimer = 10 * IN_MILLISECONDS;
+ _flameSphereTargetGUID = guid;
}
void EnterCombat(Unit* /*who*/) OVERRIDE { }
void MoveInLineOfSight(Unit* /*who*/) OVERRIDE { }
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- DoCast(me, SPELL_FLAME_SPHERE_DEATH_EFFECT);
- }
-
void UpdateAI(uint32 diff) OVERRIDE
{
- if (_despawnTimer <= diff)
- me->DisappearAndDie();
- else
- _despawnTimer -= diff;
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_START_MOVE:
+ {
+ DoCast(me, SPELL_FLAME_SPHERE_PERIODIC, true);
+
+ /// @todo: find correct values
+ float angleOffset = 0.0f;
+ float distOffset = DATA_SPHERE_DISTANCE;
+
+ switch (me->GetEntry())
+ {
+ case NPC_FLAME_SPHERE_1:
+ break;
+ case NPC_FLAME_SPHERE_2:
+ angleOffset = DATA_SPHERE_ANGLE_OFFSET;
+ break;
+ case NPC_FLAME_SPHERE_3:
+ angleOffset = -DATA_SPHERE_ANGLE_OFFSET;
+ break;
+ default:
+ return;
+ }
+
+ Unit* sphereTarget = ObjectAccessor::GetUnit(*me, _flameSphereTargetGUID);
+ if (!sphereTarget)
+ return;
+
+ float angle = me->GetAngle(sphereTarget) + angleOffset;
+ float x = me->GetPositionX() + distOffset * std::cos(angle);
+ float y = me->GetPositionY() + distOffset * std::sin(angle);
+
+ /// @todo: correct speed
+ me->GetMotionMaster()->MovePoint(0, x, y, me->GetPositionZ());
+ break;
+ }
+ case EVENT_DESPAWN:
+ DoCast(me, SPELL_FLAME_SPHERE_DEATH_EFFECT, true);
+ me->DespawnOrUnsummon(1000);
+ break;
+ default:
+ break;
+ }
+ }
}
private:
- uint32 _despawnTimer;
+ EventMap _events;
+ uint64 _flameSphereTargetGUID;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- return new npc_taldaram_flamesphereAI(creature);
+ return new npc_prince_taldaram_flame_sphereAI(creature);
}
};
-class prince_taldaram_sphere : public GameObjectScript
+// 193093, 193094 - Ancient Nerubian Device
+class go_prince_taldaram_sphere : public GameObjectScript
{
public:
- prince_taldaram_sphere() : GameObjectScript("prince_taldaram_sphere") { }
+ go_prince_taldaram_sphere() : GameObjectScript("go_prince_taldaram_sphere") { }
bool OnGossipHello(Player* /*player*/, GameObject* go) OVERRIDE
{
@@ -369,7 +382,6 @@ class prince_taldaram_sphere : public GameObjectScript
Creature* PrinceTaldaram = ObjectAccessor::GetCreature(*go, instance->GetData64(DATA_PRINCE_TALDARAM));
if (PrinceTaldaram && PrinceTaldaram->IsAlive())
{
- // maybe these are hacks :(
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
go->SetGoState(GO_STATE_ACTIVE);
@@ -385,15 +397,88 @@ class prince_taldaram_sphere : public GameObjectScript
break;
}
- CAST_AI(boss_taldaram::boss_taldaramAI, PrinceTaldaram->AI())->CheckSpheres();
+ CAST_AI(boss_prince_taldaram::boss_prince_taldaramAI, PrinceTaldaram->AI())->CheckSpheres();
}
return true;
}
};
+// 55931 - Conjure Flame Sphere
+class spell_prince_taldaram_conjure_flame_sphere : public SpellScriptLoader
+{
+ public:
+ spell_prince_taldaram_conjure_flame_sphere() : SpellScriptLoader("spell_prince_taldaram_conjure_flame_sphere") { }
+
+ class spell_prince_taldaram_conjure_flame_sphere_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_prince_taldaram_conjure_flame_sphere_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_FLAME_SPHERE_SUMMON_1)
+ || !sSpellMgr->GetSpellInfo(SPELL_FLAME_SPHERE_SUMMON_2)
+ || !sSpellMgr->GetSpellInfo(SPELL_FLAME_SPHERE_SUMMON_3))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ caster->CastSpell(caster, SPELL_FLAME_SPHERE_SUMMON_1, true);
+
+ if (caster->GetMap()->IsHeroic())
+ {
+ caster->CastSpell(caster, SPELL_FLAME_SPHERE_SUMMON_2, true);
+ caster->CastSpell(caster, SPELL_FLAME_SPHERE_SUMMON_3, true);
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_prince_taldaram_conjure_flame_sphere_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_prince_taldaram_conjure_flame_sphere_SpellScript();
+ }
+};
+
+// 55895, 59511, 59512 - Flame Sphere Summon
+class spell_prince_taldaram_flame_sphere_summon : public SpellScriptLoader
+{
+ public:
+ spell_prince_taldaram_flame_sphere_summon() : SpellScriptLoader("spell_prince_taldaram_flame_sphere_summon") { }
+
+ class spell_prince_taldaram_flame_sphere_summon_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_prince_taldaram_flame_sphere_summon_SpellScript);
+
+ void SetDest(SpellDestination& dest)
+ {
+ Position offset = { 0.0f, 0.0f, 5.5f, 0.0f };
+ dest.RelocateOffset(offset);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_prince_taldaram_flame_sphere_summon_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_prince_taldaram_flame_sphere_summon_SpellScript();
+ }
+};
+
void AddSC_boss_taldaram()
{
- new boss_taldaram();
- new npc_taldaram_flamesphere();
- new prince_taldaram_sphere();
+ new boss_prince_taldaram();
+ new npc_prince_taldaram_flame_sphere();
+ new go_prince_taldaram_sphere();
+ new spell_prince_taldaram_conjure_flame_sphere();
+ new spell_prince_taldaram_flame_sphere_summon();
}
diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp
index 7534e747ee0..a7ad7dbfb4b 100644
--- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp
+++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_hadronox.cpp
@@ -84,7 +84,7 @@ public:
uiDoorsTimer = urand(20*IN_MILLISECONDS, 30*IN_MILLISECONDS);
uiCheckDistanceTimer = 2*IN_MILLISECONDS;
- if (instance && (instance->GetBossState(DATA_HADRONOX) != DONE && !bFirstTime))
+ if (instance->GetBossState(DATA_HADRONOX) != DONE && !bFirstTime)
instance->SetBossState(DATA_HADRONOX, FAIL);
bFirstTime = false;
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp
index dd699911786..9ae6f811e19 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/obsidian_sanctum.cpp
@@ -253,7 +253,7 @@ struct dummy_dragonAI : public ScriptedAI
{
case NPC_TENEBRON:
{
- if (instance && !instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS)
+ if (!instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS)
{
for (uint32 i = 0; i < 6; ++i)
me->SummonCreature(NPC_TWILIGHT_EGG, TwilightEggs[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
@@ -267,7 +267,7 @@ struct dummy_dragonAI : public ScriptedAI
}
case NPC_SHADRON:
{
- if (instance && !instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS)
+ if (!instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS)
me->SummonCreature(NPC_ACOLYTE_OF_SHADRON, AcolyteofShadron, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 28000);
else
me->SummonCreature(NPC_ACOLYTE_OF_SHADRON, AcolyteofShadron2, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 28000);
@@ -276,7 +276,7 @@ struct dummy_dragonAI : public ScriptedAI
}
case NPC_VESPERON:
{
- if (instance && !instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS)
+ if (!instance->GetBossState(DATA_SARTHARION) == IN_PROGRESS)
{
if (Creature* acolyte = me->SummonCreature(NPC_ACOLYTE_OF_VESPERON, AcolyteofVesperon, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000))
{
@@ -328,19 +328,19 @@ struct dummy_dragonAI : public ScriptedAI
{
case NPC_TENEBRON:
spellId = SPELL_POWER_OF_TENEBRON;
- if (instance && instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS)
+ if (instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS)
instance->SetBossState(DATA_TENEBRON, DONE);
break;
case NPC_SHADRON:
spellId = SPELL_POWER_OF_SHADRON;
- if (instance && instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS)
+ if (instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS)
instance->SetBossState(DATA_SHADRON, DONE);
if (Creature* acolyte = me->FindNearestCreature(NPC_ACOLYTE_OF_SHADRON, 100.0f))
acolyte->Kill(acolyte);
break;
case NPC_VESPERON:
spellId = SPELL_POWER_OF_VESPERON;
- if (instance && instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS)
+ if (instance->GetBossState(DATA_SARTHARION) != IN_PROGRESS)
instance->SetBossState(DATA_VESPERON, DONE);
if (Creature* acolyte = me->FindNearestCreature(NPC_ACOLYTE_OF_VESPERON, 100.0f))
acolyte->Kill(acolyte);
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp
index 91c1563b494..6c0acc9bba4 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp
@@ -252,9 +252,8 @@ class npc_baltharus_the_warborn_clone : public CreatureScript
void JustDied(Unit* killer) OVERRIDE
{
// This is here because DamageTaken wont trigger if the damage is deadly.
- if (_instance)
- if (Creature* baltharus = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_BALTHARUS_THE_WARBORN)))
- killer->Kill(baltharus);
+ if (Creature* baltharus = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_BALTHARUS_THE_WARBORN)))
+ killer->Kill(baltharus);
}
void UpdateAI(uint32 diff) OVERRIDE
@@ -262,8 +261,7 @@ class npc_baltharus_the_warborn_clone : public CreatureScript
if (!UpdateVictim())
return;
- if (_instance)
- me->SetHealth(_instance->GetData(DATA_BALTHARUS_SHARED_HEALTH));
+ me->SetHealth(_instance->GetData(DATA_BALTHARUS_SHARED_HEALTH));
_events.Update(diff);
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
index 0f583d54a13..c35c9ba2d11 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
@@ -1697,6 +1697,7 @@ class spell_halion_twilight_phasing : public SpellScriptLoader
}
};
+// 74805 - Summon Exit Portals
class spell_halion_summon_exit_portals : public SpellScriptLoader
{
public:
@@ -1706,23 +1707,22 @@ class spell_halion_summon_exit_portals : public SpellScriptLoader
{
PrepareSpellScript(spell_halion_summon_exit_portals_SpellScript);
- void OnSummon(SpellEffIndex effIndex)
+ void SetDest0(SpellDestination& dest)
{
- WorldLocation summonPos = *GetExplTargetDest();
- Position offset = {0.0f, 20.0f, 0.0f, 0.0f};
- if (effIndex == EFFECT_1)
- offset.m_positionY = -20.0f;
-
- summonPos.RelocateOffset(offset);
+ Position const offset = { 0.0f, 20.0f, 0.0f, 0.0f };
+ dest.RelocateOffset(offset);
+ }
- SetExplTargetDest(summonPos);
- GetHitDest()->RelocateOffset(offset);
+ void SetDest1(SpellDestination& dest)
+ {
+ Position const offset = { 0.0f, -20.0f, 0.0f, 0.0f };
+ dest.RelocateOffset(offset);
}
void Register() OVERRIDE
{
- OnEffectLaunch += SpellEffectFn(spell_halion_summon_exit_portals_SpellScript::OnSummon, EFFECT_0, SPELL_EFFECT_SUMMON_OBJECT_WILD);
- OnEffectLaunch += SpellEffectFn(spell_halion_summon_exit_portals_SpellScript::OnSummon, EFFECT_1, SPELL_EFFECT_SUMMON_OBJECT_WILD);
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_halion_summon_exit_portals_SpellScript::SetDest0, EFFECT_0, TARGET_DEST_CASTER);
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_halion_summon_exit_portals_SpellScript::SetDest1, EFFECT_1, TARGET_DEST_CASTER);
}
};
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
index 3b1b5d4fd24..d2f6b8a3420 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
@@ -363,11 +363,11 @@ public:
{
bDone = true;
- if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1))
+ if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1))
me->SetHomePosition(739.678f, 662.541f, 412.393f, 4.49f);
- else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2))
+ else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2))
me->SetHomePosition(746.71f, 661.02f, 411.69f, 4.6f);
- else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3))
+ else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3))
me->SetHomePosition(754.34f, 660.70f, 412.39f, 4.79f);
EnterEvadeMode();
@@ -496,11 +496,11 @@ public:
{
bDone = true;
- if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1))
+ if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1))
me->SetHomePosition(739.678f, 662.541f, 412.393f, 4.49f);
- else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2))
+ else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2))
me->SetHomePosition(746.71f, 661.02f, 411.69f, 4.6f);
- else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3))
+ else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3))
me->SetHomePosition(754.34f, 660.70f, 412.39f, 4.79f);
instance->SetData(BOSS_GRAND_CHAMPIONS, IN_PROGRESS);
@@ -639,11 +639,11 @@ public:
{
bDone = true;
- if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1))
+ if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1))
me->SetHomePosition(739.678f, 662.541f, 412.393f, 4.49f);
- else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2))
+ else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2))
me->SetHomePosition(746.71f, 661.02f, 411.69f, 4.6f);
- else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3))
+ else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3))
me->SetHomePosition(754.34f, 660.70f, 412.39f, 4.79f);
instance->SetData(BOSS_GRAND_CHAMPIONS, IN_PROGRESS);
@@ -783,11 +783,11 @@ public:
{
bDone = true;
- if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1))
+ if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1))
me->SetHomePosition(739.678f, 662.541f, 412.393f, 4.49f);
- else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2))
+ else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2))
me->SetHomePosition(746.71f, 661.02f, 411.69f, 4.6f);
- else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3))
+ else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3))
me->SetHomePosition(754.34f, 660.70f, 412.39f, 4.79f);
instance->SetData(BOSS_GRAND_CHAMPIONS, IN_PROGRESS);
@@ -929,11 +929,11 @@ public:
{
bDone = true;
- if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1))
+ if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_1))
me->SetHomePosition(739.678f, 662.541f, 412.393f, 4.49f);
- else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2))
+ else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_2))
me->SetHomePosition(746.71f, 661.02f, 411.69f, 4.6f);
- else if (instance && me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3))
+ else if (me->GetGUID() == instance->GetData64(DATA_GRAND_CHAMPION_3))
me->SetHomePosition(754.34f, 660.70f, 412.39f, 4.79f);
instance->SetData(BOSS_GRAND_CHAMPIONS, IN_PROGRESS);
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp
index ab21393fce3..a60e69d6479 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/trial_of_the_champion.cpp
@@ -431,7 +431,7 @@ public:
void JustSummoned(Creature* summon) OVERRIDE
{
- if (instance && instance->GetData(BOSS_GRAND_CHAMPIONS) == NOT_STARTED)
+ if (instance->GetData(BOSS_GRAND_CHAMPIONS) == NOT_STARTED)
{
summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
summon->SetReactState(REACT_PASSIVE);
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
index 0b9b9f2543f..93d5c399725 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
@@ -470,7 +470,7 @@ class npc_swarm_scarab : public CreatureScript
void UpdateAI(uint32 diff) OVERRIDE
{
- if (_instance && _instance->GetBossState(BOSS_ANUBARAK) != IN_PROGRESS)
+ if (_instance->GetBossState(BOSS_ANUBARAK) != IN_PROGRESS)
me->DisappearAndDie();
if (!UpdateVictim())
@@ -540,7 +540,7 @@ class npc_nerubian_burrower : public CreatureScript
void UpdateAI(uint32 diff) OVERRIDE
{
- if (_instance && _instance->GetBossState(BOSS_ANUBARAK) != IN_PROGRESS)
+ if (_instance->GetBossState(BOSS_ANUBARAK) != IN_PROGRESS)
me->DisappearAndDie();
if (!UpdateVictim() && !me->HasAura(SPELL_SUBMERGE_EFFECT))
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp
index 99423a4b7ae..cb4b3cfcea3 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp
@@ -239,7 +239,7 @@ class npc_legion_flame : public CreatureScript
void UpdateAI(uint32 /*diff*/) OVERRIDE
{
UpdateVictim();
- if (_instance && _instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS)
+ if (_instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS)
me->DespawnOrUnsummon();
}
private:
@@ -326,7 +326,7 @@ class npc_fel_infernal : public CreatureScript
void UpdateAI(uint32 diff) OVERRIDE
{
- if (_instance && _instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS)
+ if (_instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS)
{
me->DespawnOrUnsummon();
return;
@@ -420,8 +420,7 @@ class npc_mistress_of_pain : public CreatureScript
npc_mistress_of_painAI(Creature* creature) : ScriptedAI(creature)
{
_instance = creature->GetInstanceScript();
- if (_instance)
- _instance->SetData(DATA_MISTRESS_OF_PAIN_COUNT, INCREASE);
+ _instance->SetData(DATA_MISTRESS_OF_PAIN_COUNT, INCREASE);
}
void Reset() OVERRIDE
@@ -435,13 +434,12 @@ class npc_mistress_of_pain : public CreatureScript
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (_instance)
- _instance->SetData(DATA_MISTRESS_OF_PAIN_COUNT, DECREASE);
+ _instance->SetData(DATA_MISTRESS_OF_PAIN_COUNT, DECREASE);
}
void UpdateAI(uint32 diff) OVERRIDE
{
- if (_instance && _instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS)
+ if (_instance->GetBossState(BOSS_JARAXXUS) != IN_PROGRESS)
{
me->DespawnOrUnsummon();
return;
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 a11a74250f5..ea166585bb3 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp
@@ -295,8 +295,7 @@ class npc_snobold_vassal : public CreatureScript
npc_snobold_vassalAI(Creature* creature) : ScriptedAI(creature)
{
_instance = creature->GetInstanceScript();
- if (_instance)
- _instance->SetData(DATA_SNOBOLD_COUNT, INCREASE);
+ _instance->SetData(DATA_SNOBOLD_COUNT, INCREASE);
}
void Reset() OVERRIDE
@@ -350,8 +349,7 @@ class npc_snobold_vassal : public CreatureScript
if (Unit* target = ObjectAccessor::GetPlayer(*me, _targetGUID))
if (target->IsAlive())
target->RemoveAurasDueToSpell(SPELL_SNOBOLLED);
- if (_instance)
- _instance->SetData(DATA_SNOBOLD_COUNT, DECREASE);
+ _instance->SetData(DATA_SNOBOLD_COUNT, DECREASE);
}
void DoAction(int32 action) OVERRIDE
@@ -378,30 +376,27 @@ class npc_snobold_vassal : public CreatureScript
{
if (!target->IsAlive())
{
- if (_instance)
+ Unit* gormok = ObjectAccessor::GetCreature(*me, _instance->GetData64(NPC_GORMOK));
+ if (gormok && gormok->IsAlive())
{
- Unit* gormok = ObjectAccessor::GetCreature(*me, _instance->GetData64(NPC_GORMOK));
- if (gormok && gormok->IsAlive())
- {
- SetCombatMovement(false);
- _targetDied = true;
+ SetCombatMovement(false);
+ _targetDied = true;
- // looping through Gormoks seats
- for (uint8 i = 0; i < MAX_SNOBOLDS; i++)
+ // looping through Gormoks seats
+ for (uint8 i = 0; i < MAX_SNOBOLDS; i++)
+ {
+ if (!gormok->GetVehicleKit()->GetPassenger(i))
{
- if (!gormok->GetVehicleKit()->GetPassenger(i))
- {
- me->EnterVehicle(gormok, i);
- DoAction(ACTION_ENABLE_FIRE_BOMB);
- break;
- }
+ me->EnterVehicle(gormok, i);
+ DoAction(ACTION_ENABLE_FIRE_BOMB);
+ break;
}
}
- else if (Unit* target2 = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
- {
- _targetGUID = target2->GetGUID();
- me->GetMotionMaster()->MoveJump(target2->GetPositionX(), target2->GetPositionY(), target2->GetPositionZ(), 15.0f, 15.0f);
- }
+ }
+ else if (Unit* target2 = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
+ {
+ _targetGUID = target2->GetGUID();
+ me->GetMotionMaster()->MoveJump(target2->GetPositionX(), target2->GetPositionY(), target2->GetPositionZ(), 15.0f, 15.0f);
}
}
}
@@ -528,7 +523,7 @@ struct boss_jormungarAI : public BossAI
void JustReachedHome() OVERRIDE
{
// prevent losing 2 attempts at once on heroics
- if (instance && instance->GetData(TYPE_NORTHREND_BEASTS) != FAIL)
+ if (instance->GetData(TYPE_NORTHREND_BEASTS) != FAIL)
instance->SetData(TYPE_NORTHREND_BEASTS, FAIL);
me->DespawnOrUnsummon();
@@ -552,7 +547,7 @@ struct boss_jormungarAI : public BossAI
if (!UpdateVictim())
return;
- if (!Enraged && instance && instance->GetData(TYPE_NORTHREND_BEASTS) == SNAKES_SPECIAL)
+ if (!Enraged && instance->GetData(TYPE_NORTHREND_BEASTS) == SNAKES_SPECIAL)
{
me->RemoveAurasDueToSpell(SPELL_SUBMERGE_0);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
index cb0ec2acc38..fdefde10b4f 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
@@ -247,8 +247,8 @@ class boss_lich_king_toc : public CreatureScript
summoned->CastSpell(summoned, 51807, false);
summoned->SetDisplayId(summoned->GetCreatureTemplate()->Modelid2);
}
- if (_instance)
- _instance->SetBossState(BOSS_LICH_KING, IN_PROGRESS);
+
+ _instance->SetBossState(BOSS_LICH_KING, IN_PROGRESS);
me->SetWalk(true);
}
@@ -401,12 +401,9 @@ class npc_fizzlebang_toc : public CreatureScript
{
case 1:
me->SetWalk(false);
- if (_instance)
- {
- _instance->DoUseDoorOrButton(_instance->GetData64(GO_MAIN_GATE_DOOR));
- _instance->SetData(TYPE_EVENT, 1120);
- _instance->SetData(TYPE_EVENT_TIMER, 1*IN_MILLISECONDS);
- }
+ _instance->DoUseDoorOrButton(_instance->GetData64(GO_MAIN_GATE_DOOR));
+ _instance->SetData(TYPE_EVENT, 1120);
+ _instance->SetData(TYPE_EVENT_TIMER, 1*IN_MILLISECONDS);
break;
default:
break;
diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
index c9247ce17f3..1f4713415ac 100644
--- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
@@ -664,8 +664,7 @@ class npc_jaina_or_sylvanas_hor : public CreatureScript
_events.ScheduleEvent(EVENT_INTRO_END, 5000);
break;
case EVENT_INTRO_END:
- if (_instance)
- _instance->SetData(DATA_INTRO_EVENT, DONE);
+ _instance->SetData(DATA_INTRO_EVENT, DONE);
// Loralen or Koreln disappearAndDie()
if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID))
{
@@ -1830,7 +1829,7 @@ public:
_emergeTimer = 4000;
_doEmerge = false;
_doJump = false;
- if (_instance && _instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS)
+ if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS)
_instance->SetData(DATA_SUMMONS, 1);
}
@@ -1838,13 +1837,11 @@ public:
void IsSummonedBy(Unit*) OVERRIDE
{
DoCast(me, SPELL_EMERGE_VISUAL);
- DoZoneInCombat(me, 100.00f);
}
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (_instance)
- _instance->SetData(DATA_SUMMONS, 0);
+ _instance->SetData(DATA_SUMMONS, 0);
}
void AttackStart(Unit* who) OVERRIDE
@@ -1932,9 +1929,8 @@ public:
_boltVolleyTimer = 15000;
_curseTimer = 7000;
_doEmerge = false;
- if (_instance)
- if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS)
- _instance->SetData(DATA_SUMMONS, 1);
+ if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS)
+ _instance->SetData(DATA_SUMMONS, 1);
}
void IsSummonedBy(Unit*) OVERRIDE
@@ -1945,9 +1941,7 @@ public:
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (_instance)
- _instance->SetData(DATA_SUMMONS, 0);
-
+ _instance->SetData(DATA_SUMMONS, 0);
}
void AttackStart(Unit* who) OVERRIDE
@@ -2049,9 +2043,8 @@ public:
_doWalk = false;
_vomitTimer = 15000;
_strikeTimer = 6000;
- if (_instance)
- if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS)
- _instance->SetData(DATA_SUMMONS, 1);
+ if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS)
+ _instance->SetData(DATA_SUMMONS, 1);
}
void IsSummonedBy(Unit*) OVERRIDE
@@ -2062,9 +2055,6 @@ public:
void UpdateAI(uint32 diff) OVERRIDE
{
- if (!_instance)
- return;
-
if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS)
{
if (_doWalk != true)
@@ -2103,8 +2093,7 @@ public:
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (_instance)
- _instance->SetData(DATA_SUMMONS, 0);
+ _instance->SetData(DATA_SUMMONS, 0);
}
};
diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h
index ff3192b89d5..c4776c3cfcd 100644
--- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h
+++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h
@@ -147,9 +147,9 @@ struct boss_horAI : ScriptedAI
{
events.Reset();
me->SetVisible(false);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
me->SetReactState(REACT_PASSIVE);
- if (instance && instance->GetData(DATA_WAVE_COUNT) != NOT_STARTED)
+ if (instance->GetData(DATA_WAVE_COUNT) != NOT_STARTED)
instance->ProcessEvent(0, EVENT_DO_WIPE);
}
@@ -158,7 +158,7 @@ struct boss_horAI : ScriptedAI
switch (actionID)
{
case ACTION_ENTER_COMBAT: // called by InstanceScript when boss shall enter in combat.
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
me->SetReactState(REACT_AGGRESSIVE);
if (Unit* unit = me->SelectNearestTarget())
diff --git a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
index 5a16271d378..46912eeb898 100644
--- a/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
+++ b/src/server/scripts/Northrend/Gundrak/boss_drakkari_colossus.cpp
@@ -423,7 +423,7 @@ public:
if (id == 1)
{
- if (Creature* colossus = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0))
+ if (Creature* colossus = Unit::GetCreature(*me, instance->GetData64(DATA_DRAKKARI_COLOSSUS)))
{
colossus->AI()->DoAction(ACTION_UNFREEZE_COLOSSUS);
if (!colossus->AI()->GetData(DATA_INTRO_DONE))
@@ -440,7 +440,7 @@ public:
return;
// we do this checks to see if the creature is one of the creatures that sorround the boss
- if (Creature* colossus = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0))
+ if (Creature* colossus = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_DRAKKARI_COLOSSUS)))
{
Position homePosition;
me->GetHomePosition().GetPosition(&homePosition);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
index 30c11ec556d..b053f0a0258 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
@@ -1492,6 +1492,7 @@ class spell_taldaram_ball_of_inferno_flame : public SpellScriptLoader
}
};
+// 72080 - Kinetic Bomb (Valanar)
class spell_valanar_kinetic_bomb : public SpellScriptLoader
{
public:
@@ -1501,18 +1502,15 @@ class spell_valanar_kinetic_bomb : public SpellScriptLoader
{
PrepareSpellScript(spell_valanar_kinetic_bomb_SpellScript);
- void ChangeSummonPos(SpellEffIndex /*effIndex*/)
+ void SetDest(SpellDestination& dest)
{
- WorldLocation summonPos = *GetExplTargetDest();
- Position offset = {0.0f, 0.0f, 20.0f, 0.0f};
- summonPos.RelocateOffset(offset);
- SetExplTargetDest(summonPos);
- GetHitDest()->RelocateOffset(offset);
+ Position const offset = { 0.0f, 0.0f, 20.0f, 0.0f };
+ dest.RelocateOffset(offset);
}
void Register() OVERRIDE
{
- OnEffectHit += SpellEffectFn(spell_valanar_kinetic_bomb_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON);
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_valanar_kinetic_bomb_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER);
}
};
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
index f3b62cd7b24..ca2c75e502c 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
@@ -2034,6 +2034,7 @@ class spell_svalna_remove_spear : public SpellScriptLoader
}
};
+// 72585 - Soul Missile
class spell_icc_soul_missile : public SpellScriptLoader
{
public:
@@ -2043,15 +2044,15 @@ class spell_icc_soul_missile : public SpellScriptLoader
{
PrepareSpellScript(spell_icc_soul_missile_SpellScript);
- void RelocateDest()
+ void RelocateDest(SpellDestination& dest)
{
- static Position const offset = {0.0f, 0.0f, 200.0f, 0.0f};
- const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset);
+ static Position const offset = { 0.0f, 0.0f, 200.0f, 0.0f };
+ dest.RelocateOffset(offset);
}
void Register() OVERRIDE
{
- OnCast += SpellCastFn(spell_icc_soul_missile_SpellScript::RelocateDest);
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_icc_soul_missile_SpellScript::RelocateDest, EFFECT_0, TARGET_DEST_CASTER);
}
};
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
index 41d1f53b52d..2091b82e20c 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
@@ -374,11 +374,11 @@ public:
void FindGameObjects()
{
- PortalsGUID[0] = instance ? instance->GetData64(DATA_KELTHUZAD_PORTAL01) : 0;
- PortalsGUID[1] = instance ? instance->GetData64(DATA_KELTHUZAD_PORTAL02) : 0;
- PortalsGUID[2] = instance ? instance->GetData64(DATA_KELTHUZAD_PORTAL03) : 0;
- PortalsGUID[3] = instance ? instance->GetData64(DATA_KELTHUZAD_PORTAL04) : 0;
- KTTriggerGUID = instance ? instance->GetData64(DATA_KELTHUZAD_TRIGGER) : 0;
+ PortalsGUID[0] = instance->GetData64(DATA_KELTHUZAD_PORTAL01);
+ PortalsGUID[1] = instance->GetData64(DATA_KELTHUZAD_PORTAL02);
+ PortalsGUID[2] = instance->GetData64(DATA_KELTHUZAD_PORTAL03);
+ PortalsGUID[3] = instance->GetData64(DATA_KELTHUZAD_PORTAL04);
+ KTTriggerGUID = instance->GetData64(DATA_KELTHUZAD_TRIGGER);
}
void UpdateAI(uint32 diff) OVERRIDE
@@ -757,8 +757,7 @@ class npc_kelthuzad_abomination : public CreatureScript
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (_instance)
- _instance->SetData(DATA_ABOMINATION_KILLED, _instance->GetData(DATA_ABOMINATION_KILLED) + 1);
+ _instance->SetData(DATA_ABOMINATION_KILLED, _instance->GetData(DATA_ABOMINATION_KILLED) + 1);
}
private:
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
index 4e386afae17..7ae9ce3faa6 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
@@ -450,7 +450,7 @@ public:
{
case ACTION_LAND_ENCOUNTER_START:
events.CancelEventGroup(1);
- if (Creature* alexstraszaBunny = me->GetMap()->GetCreature(instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID)))
+ if (Creature* alexstraszaBunny = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID)))
{
Position pos;
pos.m_positionZ = alexstraszaBunny->GetPositionZ();
@@ -713,7 +713,8 @@ public:
{
_firstCyclicMovementStarted = true;
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->SetFacingToObject(me->GetMap()->GetCreature(instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID)));
+ if (Creature* alexstraszaBunny = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID)))
+ me->SetFacingToObject(alexstraszaBunny);
events.ScheduleEvent(EVENT_SUMMON_ARCANE_BOMB, 1*IN_MILLISECONDS, 0, PHASE_TWO);
}
_flyingOutOfPlatform = false;
@@ -722,7 +723,8 @@ public:
break;
case POINT_PHASE_ONE_TO_TWO_TRANSITION:
me->SetDisableGravity(true);
- me->SetFacingToObject(me->GetMap()->GetCreature(instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID)));
+ if (Creature* alexstraszaBunny = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID)))
+ me->SetFacingToObject(alexstraszaBunny);
SendLightOverride(LIGHT_ARCANE_RUNES, 5*IN_MILLISECONDS);
events.ScheduleEvent(EVENT_FLY_OUT_OF_PLATFORM, 18*IN_MILLISECONDS, 0, PHASE_TWO);
break;
@@ -780,7 +782,7 @@ public:
me->CastCustomSpell(SPELL_RANDOM_PORTAL, SPELLVALUE_MAX_TARGETS, 1);
break;
case EVENT_LAND_START_ENCOUNTER:
- if (GameObject* iris = me->GetMap()->GetGameObject(instance->GetData64(DATA_FOCUSING_IRIS_GUID)))
+ if (GameObject* iris = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_FOCUSING_IRIS_GUID)))
{
me->SetFacingToObject(iris);
iris->Delete(); // this is not the best way.
@@ -837,7 +839,7 @@ public:
case EVENT_FLY_OUT_OF_PLATFORM:
if (!_performingDestroyPlatform)
{
- if (Creature* alexstraszaBunny = me->GetMap()->GetCreature(instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID)))
+ if (Creature* alexstraszaBunny = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_ALEXSTRASZA_BUNNY_GUID)))
{
Position randomPosOnRadius;
// Hardcodded retail value, reason is Z getters can fail... (TO DO: Change to getter when height calculation works on 100%!)
@@ -908,7 +910,7 @@ public:
if (!_flyingOutOfPlatform)
{
DoCast(me, SPELL_SUMMON_ARCANE_BOMB, true);
- if (Creature* lastArcaneOverloadBunny = me->GetMap()->GetCreature(_arcaneOverloadGUID))
+ if (Creature* lastArcaneOverloadBunny = ObjectAccessor::GetCreature(*me, _arcaneOverloadGUID))
DoCast(lastArcaneOverloadBunny, SPELL_ARCANE_BOMB_TRIGGER, true);
}
events.ScheduleEvent(EVENT_SUMMON_ARCANE_BOMB, urand(15, 16)*IN_MILLISECONDS, 2, PHASE_TWO);
@@ -993,7 +995,7 @@ public:
{
_JustDied();
Talk(SAY_DEATH);
- if (Creature* alexstraszaGiftBoxBunny = me->GetMap()->GetCreature(instance->GetData64(DATA_GIFT_BOX_BUNNY_GUID)))
+ if (Creature* alexstraszaGiftBoxBunny = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_GIFT_BOX_BUNNY_GUID)))
{
if (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)
alexstraszaGiftBoxBunny->SummonGameObject(GO_HEART_OF_MAGIC_10, HeartOfMagicSpawnPos.GetPositionX(), HeartOfMagicSpawnPos.GetPositionY(),
@@ -1087,7 +1089,7 @@ public:
{
if (spell->Id == SPELL_PORTAL_OPENED)
{
- if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS)))
+ if (Creature* malygos = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MALYGOS)))
{
if (malygos->AI()->GetData(DATA_PHASE) == PHASE_ONE)
DoCast(me, SPELL_SUMMON_POWER_PARK, true);
@@ -1101,15 +1103,12 @@ public:
if (!me->HasAura(SPELL_PORTAL_VISUAL_CLOSED) && !me->HasAura(SPELL_PORTAL_OPENED))
DoCast(me, SPELL_PORTAL_VISUAL_CLOSED, true);
- if (_instance)
+ if (Creature* malygos = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MALYGOS)))
{
- if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS)))
+ if (malygos->AI()->GetData(DATA_PHASE) != PHASE_ONE && me->HasAura(SPELL_PORTAL_OPENED))
{
- if (malygos->AI()->GetData(DATA_PHASE) != PHASE_ONE && me->HasAura(SPELL_PORTAL_OPENED))
- {
- me->RemoveAura(SPELL_PORTAL_OPENED);
- DoCast(me, SPELL_PORTAL_VISUAL_CLOSED, true);
- }
+ me->RemoveAura(SPELL_PORTAL_OPENED);
+ DoCast(me, SPELL_PORTAL_VISUAL_CLOSED, true);
}
}
}
@@ -1143,9 +1142,8 @@ public:
{
me->GetMotionMaster()->MoveIdle();
- if (_instance)
- if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS)))
- me->GetMotionMaster()->MoveFollow(malygos, 0.0f, 0.0f);
+ if (Creature* malygos = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MALYGOS)))
+ me->GetMotionMaster()->MoveFollow(malygos, 0.0f, 0.0f);
}
void UpdateAI(uint32 /*diff*/) OVERRIDE
@@ -1153,7 +1151,7 @@ public:
if (!_instance)
return;
- if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS)))
+ if (Creature* malygos = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MALYGOS)))
{
if (malygos->AI()->GetData(DATA_PHASE) != PHASE_ONE || _instance->GetBossState(DATA_MALYGOS_EVENT) == FAIL)
{
@@ -1432,7 +1430,7 @@ class npc_nexus_lord : public CreatureScript
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS)))
+ if (Creature* malygos = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MALYGOS)))
malygos->AI()->SetData(DATA_SUMMON_DEATHS, malygos->AI()->GetData(DATA_SUMMON_DEATHS) + 1);
}
@@ -1499,7 +1497,7 @@ class npc_scion_of_eternity : public CreatureScript
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS)))
+ if (Creature* malygos = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MALYGOS)))
malygos->AI()->SetData(DATA_SUMMON_DEATHS, malygos->AI()->GetData(DATA_SUMMON_DEATHS) + 1);
}
@@ -1542,7 +1540,7 @@ public:
void DoAction(int32 /*action*/) OVERRIDE
{
- if (Creature* malygos = me->GetMap()->GetCreature(_instance->GetData64(DATA_MALYGOS)))
+ if (Creature* malygos = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MALYGOS)))
{
if (malygos->AI()->GetData(DATA_PHASE) == PHASE_TWO)
me->DespawnOrUnsummon(6*IN_MILLISECONDS);
@@ -2047,7 +2045,7 @@ class spell_scion_of_eternity_arcane_barrage : public SpellScriptLoader
Creature* caster = GetCaster()->ToCreature();
InstanceScript* instance = caster->GetInstanceScript();
- Creature* malygos = caster->GetMap()->GetCreature(instance->GetData64(DATA_MALYGOS));
+ Creature* malygos = ObjectAccessor::GetCreature(*caster, instance->GetData64(DATA_MALYGOS));
// If max possible targets are more than 1 then Scions wouldn't select previosly selected target,
// in longer terms this means if spell picks target X then 2nd cast of this spell will pick smth else
@@ -2232,6 +2230,7 @@ class spell_alexstrasza_bunny_destroy_platform_event : public SpellScriptLoader
}
};
+// 56070 - Summon Red Dragon Buddy
class spell_wyrmrest_skytalon_summon_red_dragon_buddy : public SpellScriptLoader
{
public:
@@ -2246,19 +2245,16 @@ class spell_wyrmrest_skytalon_summon_red_dragon_buddy : public SpellScriptLoader
return GetCaster()->GetTypeId() == TYPEID_PLAYER;
}
- void ChangeSummonPos(SpellEffIndex /*effIndex*/)
+ void SetDest(SpellDestination& dest)
{
// Adjust effect summon position to lower Z
- WorldLocation summonPos = *GetExplTargetDest();
- Position offset = { 0.0f, 0.0f, -80.0f, 0.0f };
- summonPos.RelocateOffset(offset);
- SetExplTargetDest(summonPos);
- GetHitDest()->RelocateOffset(offset);
+ Position const offset = { 0.0f, 0.0f, -80.0f, 0.0f };
+ dest.RelocateOffset(offset);
}
void Register() OVERRIDE
{
- OnEffectHit += SpellEffectFn(spell_wyrmrest_skytalon_summon_red_dragon_buddy_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON);
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_wyrmrest_skytalon_summon_red_dragon_buddy_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER_RADIUS);
}
};
diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp
index 2f6a328b728..9943ad7e1b1 100644
--- a/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp
+++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp
@@ -213,7 +213,7 @@ public:
{
InstanceScript* instance = go->GetInstanceScript();
- Creature* pKeristrasza = Unit::GetCreature(*go, instance ? instance->GetData64(DATA_KERISTRASZA) : 0);
+ Creature* pKeristrasza = ObjectAccessor::GetCreature(*go, instance->GetData64(DATA_KERISTRASZA));
if (pKeristrasza && pKeristrasza->IsAlive())
{
// maybe these are hacks :(
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
index 40e526219fa..506e16741fb 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
@@ -375,27 +375,16 @@ class spell_oculus_call_ruby_emerald_amber_drake : public SpellScriptLoader
{
PrepareSpellScript(spell_oculus_call_ruby_emerald_amber_drake_SpellScript);
- void ChangeSummonPos(SpellEffIndex /*effIndex*/)
+ void SetDest(SpellDestination& dest)
{
// Adjust effect summon position
- WorldLocation summonPos = *GetExplTargetDest();
- Position offset = { 0.0f, 0.0f, 12.0f, 0.0f };
- summonPos.RelocateOffset(offset);
- SetExplTargetDest(summonPos);
- GetHitDest()->RelocateOffset(offset);
- }
-
- void ModDestHeight(SpellEffIndex /*effIndex*/)
- {
- // Used to cast visual effect at proper position
- Position offset = { 0.0f, 0.0f, 12.0f, 0.0f };
- const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset);
+ Position const offset = { 0.0f, 0.0f, 12.0f, 0.0f };
+ dest.RelocateOffset(offset);
}
void Register() OVERRIDE
{
- OnEffectHit += SpellEffectFn(spell_oculus_call_ruby_emerald_amber_drake_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON);
- OnEffectLaunch += SpellEffectFn(spell_oculus_call_ruby_emerald_amber_drake_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON);
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_oculus_call_ruby_emerald_amber_drake_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER_FRONT);
}
};
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp
index c666a36741b..1788ecacd35 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp
@@ -168,7 +168,7 @@ public:
for (std::list<uint64>::const_iterator itr = lSparkList.begin(); itr != lSparkList.end(); ++itr)
{
- if (Creature* pSpark = Unit::GetCreature(*me, *itr))
+ if (Creature* pSpark = ObjectAccessor::GetCreature(*me, *itr))
{
if (pSpark->IsAlive())
{
@@ -297,11 +297,6 @@ class npc_spark_of_ionar : public CreatureScript
public:
npc_spark_of_ionar() : CreatureScript("npc_spark_of_ionar") { }
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetInstanceAI<npc_spark_of_ionarAI>(creature);
- }
-
struct npc_spark_of_ionarAI : public ScriptedAI
{
npc_spark_of_ionarAI(Creature* creature) : ScriptedAI(creature)
@@ -336,7 +331,7 @@ public:
void UpdateAI(uint32 uiDiff) OVERRIDE
{
// Despawn if the encounter is not running
- if (instance && instance->GetBossState(DATA_IONAR) != IN_PROGRESS)
+ if (instance->GetBossState(DATA_IONAR) != IN_PROGRESS)
{
me->DespawnOrUnsummon();
return;
@@ -345,13 +340,13 @@ public:
// Prevent them to follow players through the whole instance
if (uiCheckTimer <= uiDiff)
{
- Creature* pIonar = instance->instance->GetCreature(instance->GetData64(DATA_IONAR));
- if (pIonar && pIonar->IsAlive())
+ Creature* ionar = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_IONAR));
+ if (ionar && ionar->IsAlive())
{
- if (me->GetDistance(pIonar) > DATA_MAX_SPARK_DISTANCE)
+ if (me->GetDistance(ionar) > DATA_MAX_SPARK_DISTANCE)
{
Position pos;
- pIonar->GetPosition(&pos);
+ ionar->GetPosition(&pos);
me->SetSpeed(MOVE_RUN, 2.0f);
me->GetMotionMaster()->Clear();
@@ -369,6 +364,10 @@ public:
}
};
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetInstanceAI<npc_spark_of_ionarAI>(creature);
+ }
};
void AddSC_boss_ionar()
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
index a8f933431c3..9599700eccb 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
@@ -1253,6 +1253,7 @@ class spell_algalon_remove_phase : public SpellScriptLoader
}
};
+// 62295 - Cosmic Smash
class spell_algalon_cosmic_smash : public SpellScriptLoader
{
public:
@@ -1262,16 +1263,15 @@ class spell_algalon_cosmic_smash : public SpellScriptLoader
{
PrepareSpellScript(spell_algalon_cosmic_smash_SpellScript);
- void ModDestHeight(SpellEffIndex /*effIndex*/)
+ void ModDestHeight(SpellDestination& dest)
{
- Position offset = {0.0f, 0.0f, 65.0f, 0.0f};
- const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset);
- GetHitDest()->RelocateOffset(offset);
+ Position const offset = { 0.0f, 0.0f, 65.0f, 0.0f };
+ dest.RelocateOffset(offset);
}
void Register() OVERRIDE
{
- OnEffectLaunch += SpellEffectFn(spell_algalon_cosmic_smash_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON);
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_algalon_cosmic_smash_SpellScript::ModDestHeight, EFFECT_0, TARGET_DEST_CASTER_SUMMON);
}
};
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
index 779adf67211..ee1345590f3 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
@@ -1192,7 +1192,7 @@ class npc_lorekeeper : public CreatureScript
bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
{
InstanceScript* instance = creature->GetInstanceScript();
- if (instance && instance->GetData(BOSS_LEVIATHAN) !=DONE && player)
+ if (instance && instance->GetData(BOSS_LEVIATHAN) != DONE && player)
{
player->PrepareGossipMenu(creature);
@@ -1285,8 +1285,7 @@ class go_ulduar_tower : public GameObjectScript
break;
}
- Creature* trigger = go->FindNearestCreature(NPC_ULDUAR_GAUNTLET_GENERATOR, 15.0f, true);
- if (trigger)
+ if (Creature* trigger = go->FindNearestCreature(NPC_ULDUAR_GAUNTLET_GENERATOR, 15.0f, true))
trigger->DisappearAndDie();
}
};
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp
index 480c04c3254..169a7085672 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp
@@ -227,7 +227,7 @@ class npc_flash_freeze : public CreatureScript
// Prevents to have Ice Block on other place than target is
me->NearTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation());
if (target->GetTypeId() == TYPEID_PLAYER)
- if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(BOSS_HODIR) : 0))
+ if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_HODIR)))
Hodir->AI()->DoAction(ACTION_CHEESE_THE_FREEZE);
}
}
@@ -279,7 +279,7 @@ class npc_ice_block : public CreatureScript
{
Helper->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED);
- if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(BOSS_HODIR) : 0))
+ if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_HODIR)))
{
if (!Hodir->IsInCombat())
{
@@ -658,7 +658,7 @@ class npc_hodir_priest : public CreatureScript
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(BOSS_HODIR) : 0))
+ if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_HODIR)))
Hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS);
}
@@ -720,7 +720,7 @@ class npc_hodir_shaman : public CreatureScript
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(BOSS_HODIR) : 0))
+ if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_HODIR)))
Hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS);
}
@@ -781,7 +781,7 @@ class npc_hodir_druid : public CreatureScript
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(BOSS_HODIR) : 0))
+ if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_HODIR)))
Hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS);
}
@@ -861,7 +861,7 @@ class npc_hodir_mage : public CreatureScript
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(BOSS_HODIR) : 0))
+ if (Creature* Hodir = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_HODIR)))
Hodir->AI()->DoAction(ACTION_I_HAVE_THE_COOLEST_FRIENDS);
}
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp
index 862ee2c786b..e96cfaccc56 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp
@@ -312,7 +312,7 @@ class go_razorscale_harpoon : public GameObjectScript
bool OnGossipHello(Player* /*player*/, GameObject* go) OVERRIDE
{
InstanceScript* instance = go->GetInstanceScript();
- if (ObjectAccessor::GetCreature(*go, instance ? instance->GetData64(BOSS_RAZORSCALE) : 0))
+ if (ObjectAccessor::GetCreature(*go, instance->GetData64(BOSS_RAZORSCALE)))
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
return false;
}
@@ -347,14 +347,14 @@ class boss_razorscale : public CreatureScript
me->SetReactState(REACT_PASSIVE);
PermaGround = false;
HarpoonCounter = 0;
- if (Creature* commander = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_EXPEDITION_COMMANDER) : 0))
+ if (Creature* commander = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EXPEDITION_COMMANDER)))
commander->AI()->DoAction(ACTION_COMMANDER_RESET);
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
_EnterCombat();
- if (Creature* controller = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_RAZORSCALE_CONTROL) : 0))
+ if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_RAZORSCALE_CONTROL)))
controller->AI()->DoAction(ACTION_HARPOON_BUILD);
me->SetSpeed(MOVE_FLIGHT, 3.0f, true);
me->SetReactState(REACT_PASSIVE);
@@ -369,7 +369,7 @@ class boss_razorscale : public CreatureScript
void JustDied(Unit* /*killer*/) OVERRIDE
{
_JustDied();
- if (Creature* controller = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_RAZORSCALE_CONTROL) : 0))
+ if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_RAZORSCALE_CONTROL)))
controller->AI()->Reset();
}
@@ -445,7 +445,7 @@ class boss_razorscale : public CreatureScript
me->SetCanFly(false);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED | UNIT_FLAG_PACIFIED);
- if (Creature* commander = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_EXPEDITION_COMMANDER) : 0))
+ if (Creature* commander = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EXPEDITION_COMMANDER)))
commander->AI()->DoAction(ACTION_GROUND_PHASE);
events.ScheduleEvent(EVENT_BREATH, 30000, 0, PHASE_GROUND);
events.ScheduleEvent(EVENT_BUFFET, 33000, 0, PHASE_GROUND);
@@ -461,7 +461,7 @@ class boss_razorscale : public CreatureScript
return;
case EVENT_BUFFET:
DoCastAOE(SPELL_WINGBUFFET);
- if (Creature* controller = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(DATA_RAZORSCALE_CONTROL) : 0))
+ if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_RAZORSCALE_CONTROL)))
controller->CastSpell(controller, SPELL_FLAMED, true);
events.CancelEvent(EVENT_BUFFET);
return;
@@ -689,7 +689,7 @@ class npc_expedition_commander : public CreatureScript
Phase = 5;
break;
case 5:
- if (Creature* Razorscale = ObjectAccessor::GetCreature(*me, instance ? instance->GetData64(BOSS_RAZORSCALE) : 0))
+ if (Creature* Razorscale = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_RAZORSCALE)))
{
Razorscale->AI()->DoAction(ACTION_EVENT_START);
me->SetInCombatWith(Razorscale);
diff --git a/src/server/scripts/Northrend/VaultOfArchavon/boss_emalon.cpp b/src/server/scripts/Northrend/VaultOfArchavon/boss_emalon.cpp
index 4dd3aa9916b..7377029080f 100644
--- a/src/server/scripts/Northrend/VaultOfArchavon/boss_emalon.cpp
+++ b/src/server/scripts/Northrend/VaultOfArchavon/boss_emalon.cpp
@@ -195,7 +195,7 @@ class npc_tempest_minion : public CreatureScript
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (Creature* emalon = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EMALON) : 0))
+ if (Creature* emalon = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EMALON)))
{
if (emalon->IsAlive())
{
@@ -210,7 +210,7 @@ class npc_tempest_minion : public CreatureScript
DoZoneInCombat();
events.ScheduleEvent(EVENT_SHOCK, 20000);
- if (Creature* pEmalon = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EMALON) : 0))
+ if (Creature* pEmalon = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EMALON)))
{
if (!pEmalon->GetVictim() && pEmalon->AI())
pEmalon->AI()->AttackStart(who);
diff --git a/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp b/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp
index ccb1b5ed7d8..bd2128a1b4c 100644
--- a/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp
+++ b/src/server/scripts/Northrend/VaultOfArchavon/boss_toravon.cpp
@@ -241,7 +241,7 @@ class npc_frozen_orb_stalker : public CreatureScript
npc_frozen_orb_stalkerAI(Creature* creature) : ScriptedAI(creature)
{
creature->SetVisible(false);
- creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_DISABLE_MOVE);
+ creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE);
creature->SetReactState(REACT_PASSIVE);
instance = creature->GetInstanceScript();
@@ -256,7 +256,7 @@ class npc_frozen_orb_stalker : public CreatureScript
return;
spawned = true;
- Unit* toravon = me->GetCreature(*me, instance ? instance->GetData64(DATA_TORAVON) : 0);
+ Unit* toravon = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TORAVON));
if (!toravon)
return;
diff --git a/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp b/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp
index ec20489bfc2..e53d046b396 100644
--- a/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp
+++ b/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp
@@ -90,7 +90,7 @@ public:
void UpdateAI(uint32 diff) OVERRIDE
{
- if (instance && instance->GetData(DATA_REMOVE_NPC) == 1)
+ if (instance->GetData(DATA_REMOVE_NPC) == 1)
{
me->DespawnOrUnsummon();
instance->SetData(DATA_REMOVE_NPC, 0);
diff --git a/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp b/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp
index 81edfd65d03..441603dcdc8 100644
--- a/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp
+++ b/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp
@@ -79,12 +79,12 @@ public:
else if (instance->GetData(DATA_WAVE_COUNT) == 12)
instance->SetData(DATA_2ND_BOSS_EVENT, NOT_STARTED);
- if (Creature* pGuard1 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_1) : 0))
+ if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_1)))
{
if (!pGuard1->IsAlive())
pGuard1->Respawn();
}
- if (Creature* pGuard2 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_2) : 0))
+ if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_2)))
{
if (!pGuard2->IsAlive())
pGuard2->Respawn();
@@ -103,15 +103,15 @@ public:
who->SetInCombatWith(me);
DoStartMovement(who);
- if (Creature* pGuard1 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_1) : 0))
+ if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_1)))
{
- pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
+ pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
if (!pGuard1->GetVictim() && pGuard1->AI())
pGuard1->AI()->AttackStart(who);
}
- if (Creature* pGuard2 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_2) : 0))
+ if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_2)))
{
- pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
+ pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
if (!pGuard2->GetVictim() && pGuard2->AI())
pGuard2->AI()->AttackStart(who);
}
@@ -148,9 +148,9 @@ public:
//spam stormstrike in hc mode if spawns are dead
if (IsHeroic())
{
- if (Creature* pGuard1 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_1) : 0))
+ if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_1)))
{
- if (Creature* pGuard2 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_2) : 0))
+ if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_2)))
{
if (!pGuard1->IsAlive() && !pGuard2->IsAlive())
DoCastVictim(SPELL_STORMSTRIKE);
@@ -168,12 +168,12 @@ public:
{
if (uint64 TargetGUID = GetChainHealTargetGUID())
{
- if (Creature* target = Unit::GetCreature(*me, TargetGUID))
+ if (Creature* target = ObjectAccessor::GetCreature(*me, TargetGUID))
DoCast(target, SPELL_CHAIN_HEAL);
//If one of the adds is dead spawn heals faster
- Creature* pGuard1 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_1) : 0);
- Creature* pGuard2 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_2) : 0);
+ Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_1));
+ Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_2));
uiChainHealTimer = ((pGuard1 && !pGuard1->IsAlive()) || (pGuard2 && !pGuard2->IsAlive()) ? 3000 : 8000) + rand()%3000;
}
} else uiChainHealTimer -= diff;
@@ -229,11 +229,11 @@ public:
if (HealthBelowPct(85))
return me->GetGUID();
- Creature* pGuard1 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_1) : 0);
+ Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_1));
if (pGuard1 && pGuard1->IsAlive() && !pGuard1->HealthAbovePct(75))
return pGuard1->GetGUID();
- Creature* pGuard2 = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_EREKEM_GUARD_2) : 0);
+ Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_EREKEM_GUARD_2));
if (pGuard2 && pGuard2->IsAlive() && !pGuard2->HealthAbovePct(75))
return pGuard2->GetGUID();
diff --git a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp
index 79025bb5c0f..5f79e609e01 100644
--- a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp
+++ b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp
@@ -446,7 +446,7 @@ public:
void Reset() OVERRIDE
{
- if (instance && !uiBoss)
+ if (!uiBoss)
uiBoss = instance->GetData(DATA_WAVE_COUNT) == 6 ? instance->GetData(DATA_FIRST_BOSS) : instance->GetData(DATA_SECOND_BOSS);
me->SetReactState(REACT_PASSIVE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
@@ -486,7 +486,7 @@ public:
void UpdateAI(uint32 diff) OVERRIDE
{
- if (instance && instance->GetData(DATA_MAIN_EVENT_PHASE) != IN_PROGRESS)
+ if (instance->GetData(DATA_MAIN_EVENT_PHASE) != IN_PROGRESS)
me->CastStop();
npc_escortAI::UpdateAI(diff);
@@ -723,7 +723,7 @@ struct violet_hold_trashAI : public npc_escortAI
void UpdateAI(uint32) OVERRIDE
{
- if (instance && instance->GetData(DATA_MAIN_EVENT_PHASE) != IN_PROGRESS)
+ if (instance->GetData(DATA_MAIN_EVENT_PHASE) != IN_PROGRESS)
me->CastStop();
if (!bHasGotMovingPoints)
diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp
index 0173454ef28..f840c0562b3 100644
--- a/src/server/scripts/Northrend/zone_borean_tundra.cpp
+++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp
@@ -1359,10 +1359,7 @@ public:
struct npc_counselor_talbotAI : public ScriptedAI
{
- npc_counselor_talbotAI(Creature* creature) : ScriptedAI(creature)
- {
- creature->RestoreFaction();
- }
+ npc_counselor_talbotAI(Creature* creature) : ScriptedAI(creature) { }
uint64 leryssaGUID;
uint64 arlosGUID;
diff --git a/src/server/scripts/Northrend/zone_dragonblight.cpp b/src/server/scripts/Northrend/zone_dragonblight.cpp
index f91f5d8c007..7487c3c8828 100644
--- a/src/server/scripts/Northrend/zone_dragonblight.cpp
+++ b/src/server/scripts/Northrend/zone_dragonblight.cpp
@@ -150,7 +150,10 @@ class npc_commander_eligor_dawnbringer : public CreatureScript
struct npc_commander_eligor_dawnbringerAI : public ScriptedAI
{
- npc_commander_eligor_dawnbringerAI(Creature* creature) : ScriptedAI(creature) { }
+ npc_commander_eligor_dawnbringerAI(Creature* creature) : ScriptedAI(creature)
+ {
+ talkWing = 0;
+ }
void Reset() OVERRIDE
{
@@ -649,7 +652,10 @@ class npc_torturer_lecraft : public CreatureScript
struct npc_torturer_lecraftAI : public ScriptedAI
{
- npc_torturer_lecraftAI(Creature* creature) : ScriptedAI(creature) { }
+ npc_torturer_lecraftAI(Creature* creature) : ScriptedAI(creature)
+ {
+ _playerGUID = 0;
+ }
void Reset() OVERRIDE
{
diff --git a/src/server/scripts/Northrend/zone_grizzly_hills.cpp b/src/server/scripts/Northrend/zone_grizzly_hills.cpp
index bacc6de57f0..112d42441b9 100644
--- a/src/server/scripts/Northrend/zone_grizzly_hills.cpp
+++ b/src/server/scripts/Northrend/zone_grizzly_hills.cpp
@@ -20,8 +20,6 @@
#include "ScriptedCreature.h"
#include "ScriptedEscortAI.h"
#include "Player.h"
-#include "Spell.h"
-#include "SpellInfo.h"
#include "SpellScript.h"
#include "CreatureTextMgr.h"
diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp
index 69e4e65225a..70de4d4758d 100644
--- a/src/server/scripts/Northrend/zone_storm_peaks.cpp
+++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp
@@ -451,7 +451,10 @@ public:
struct npc_brann_bronzebeard_keystoneAI : public ScriptedAI
{
- npc_brann_bronzebeard_keystoneAI(Creature* creature) : ScriptedAI(creature) { }
+ npc_brann_bronzebeard_keystoneAI(Creature* creature) : ScriptedAI(creature)
+ {
+ objectCounter = 0;
+ }
void Reset() OVERRIDE
{
@@ -634,7 +637,10 @@ public:
struct npc_king_jokkum_vehicleAI : public VehicleAI
{
- npc_king_jokkum_vehicleAI(Creature* creature) : VehicleAI(creature) { }
+ npc_king_jokkum_vehicleAI(Creature* creature) : VehicleAI(creature)
+ {
+ pathEnd = false;
+ }
void Reset() OVERRIDE
{
diff --git a/src/server/scripts/Northrend/zone_wintergrasp.cpp b/src/server/scripts/Northrend/zone_wintergrasp.cpp
index 311b18524b2..e218741649d 100644
--- a/src/server/scripts/Northrend/zone_wintergrasp.cpp
+++ b/src/server/scripts/Northrend/zone_wintergrasp.cpp
@@ -249,7 +249,10 @@ class npc_wg_queue : public CreatureScript
struct npc_wg_queueAI : public ScriptedAI
{
- npc_wg_queueAI(Creature* creature) : ScriptedAI(creature) { }
+ npc_wg_queueAI(Creature* creature) : ScriptedAI(creature)
+ {
+ FrostArmor_Timer = 0;
+ }
uint32 FrostArmor_Timer;
diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
index 3bbd41afc89..d74aecb9b25 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
@@ -1672,7 +1672,7 @@ public:
{
if (Check_Timer <= diff)
{
- if (instance && instance->GetBossState(DATA_ILLIDARI_COUNCIL) == DONE)
+ if (instance->GetBossState(DATA_ILLIDARI_COUNCIL) == DONE)
me->SetVisible(true);
Check_Timer = 5000;
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp
index 6d632c81bca..9055bb1862d 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_fathomlord_karathress.cpp
@@ -139,21 +139,20 @@ public:
RAdvisors[0] = instance->GetData64(DATA_SHARKKIS);
RAdvisors[1] = instance->GetData64(DATA_TIDALVESS);
RAdvisors[2] = instance->GetData64(DATA_CARIBDIS);
- //Respawn of the 3 Advisors
- Creature* pAdvisor = NULL;
- for (int i=0; i<MAX_ADVISORS; ++i)
+ // Respawn of the 3 Advisors
+ for (uint8 i = 0; i < MAX_ADVISORS; ++i)
if (RAdvisors[i])
{
- pAdvisor = (Unit::GetCreature((*me), RAdvisors[i]));
- if (pAdvisor && !pAdvisor->IsAlive())
+ Creature* advisor = ObjectAccessor::GetCreature(*me, RAdvisors[i]);
+ if (advisor && !advisor->IsAlive())
{
- pAdvisor->Respawn();
- pAdvisor->AI()->EnterEvadeMode();
- pAdvisor->GetMotionMaster()->MoveTargetedHome();
+ advisor->Respawn();
+ advisor->AI()->EnterEvadeMode();
+ advisor->GetMotionMaster()->MoveTargetedHome();
}
}
- instance->SetData(DATA_KARATHRESSEVENT, NOT_STARTED);
+ instance->SetData(DATA_KARATHRESSEVENT, NOT_STARTED);
}
void EventSharkkisDeath()
@@ -215,7 +214,7 @@ public:
void UpdateAI(uint32 diff) OVERRIDE
{
//Only if not incombat check if the event is started
- if (!me->IsInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT))
+ if (!me->IsInCombat() && instance->GetData(DATA_KARATHRESSEVENT))
{
if (Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER)))
{
@@ -229,7 +228,7 @@ public:
return;
//someone evaded!
- if (instance && !instance->GetData(DATA_KARATHRESSEVENT))
+ if (!instance->GetData(DATA_KARATHRESSEVENT))
{
EnterEvadeMode();
return;
@@ -269,12 +268,11 @@ public:
{
BlessingOfTides = true;
bool continueTriggering = false;
- Creature* Advisor;
for (uint8 i = 0; i < MAX_ADVISORS; ++i)
if (Advisors[i])
{
- Advisor = (Unit::GetCreature(*me, Advisors[i]));
- if (Advisor && Advisor->IsAlive())
+ Creature* advisor = ObjectAccessor::GetCreature(*me, Advisors[i]);
+ if (advisor && advisor->IsAlive())
{
continueTriggering = true;
break;
@@ -333,11 +331,9 @@ public:
pet = false;
- Creature* Pet = Unit::GetCreature(*me, SummonedPet);
+ Creature* Pet = ObjectAccessor::GetCreature(*me, SummonedPet);
if (Pet && Pet->IsAlive())
- {
Pet->DealDamage(Pet, Pet->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- }
SummonedPet = 0;
@@ -346,7 +342,7 @@ public:
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (Creature* Karathress = (Unit::GetCreature((*me), instance->GetData64(DATA_KARATHRESS))))
+ if (Creature* Karathress = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_KARATHRESS)))
CAST_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventSharkkisDeath();
}
@@ -359,7 +355,7 @@ public:
void UpdateAI(uint32 diff) OVERRIDE
{
//Only if not incombat check if the event is started
- if (!me->IsInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT))
+ if (!me->IsInCombat() && instance->GetData(DATA_KARATHRESSEVENT))
{
if (Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER)))
AttackStart(target);
@@ -370,7 +366,7 @@ public:
return;
//someone evaded!
- if (instance && !instance->GetData(DATA_KARATHRESSEVENT))
+ if (!instance->GetData(DATA_KARATHRESSEVENT))
{
EnterEvadeMode();
return;
@@ -394,11 +390,11 @@ public:
if (TheBeastWithin_Timer <= diff)
{
DoCast(me, SPELL_THE_BEAST_WITHIN);
- Creature* Pet = Unit::GetCreature(*me, SummonedPet);
+
+ Creature* Pet = ObjectAccessor::GetCreature(*me, SummonedPet);
if (Pet && Pet->IsAlive())
- {
Pet->CastSpell(Pet, SPELL_PET_ENRAGE, true);
- }
+
TheBeastWithin_Timer = 30000;
} else TheBeastWithin_Timer -= diff;
@@ -472,7 +468,7 @@ public:
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (Creature* Karathress = Unit::GetCreature((*me), instance->GetData64(DATA_KARATHRESS)))
+ if (Creature* Karathress = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_KARATHRESS)))
CAST_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventTidalvessDeath();
}
@@ -486,7 +482,7 @@ public:
void UpdateAI(uint32 diff) OVERRIDE
{
//Only if not incombat check if the event is started
- if (!me->IsInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT))
+ if (!me->IsInCombat() && instance->GetData(DATA_KARATHRESSEVENT))
{
if (Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER)))
AttackStart(target);
@@ -497,7 +493,7 @@ public:
return;
//someone evaded!
- if (instance && !instance->GetData(DATA_KARATHRESSEVENT))
+ if (!instance->GetData(DATA_KARATHRESSEVENT))
{
EnterEvadeMode();
return;
@@ -588,7 +584,7 @@ public:
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (Creature* Karathress = Unit::GetCreature((*me), instance->GetData64(DATA_KARATHRESS)))
+ if (Creature* Karathress = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_KARATHRESS)))
CAST_AI(boss_fathomlord_karathress::boss_fathomlord_karathressAI, Karathress->AI())->EventCaribdisDeath();
}
@@ -601,7 +597,7 @@ public:
void UpdateAI(uint32 diff) OVERRIDE
{
//Only if not incombat check if the event is started
- if (!me->IsInCombat() && instance && instance->GetData(DATA_KARATHRESSEVENT))
+ if (!me->IsInCombat() && instance->GetData(DATA_KARATHRESSEVENT))
{
if (Unit* target = Unit::GetUnit(*me, instance->GetData64(DATA_KARATHRESSEVENT_STARTER)))
AttackStart(target);
@@ -612,7 +608,7 @@ public:
return;
//someone evaded!
- if (instance && !instance->GetData(DATA_KARATHRESSEVENT))
+ if (!instance->GetData(DATA_KARATHRESSEVENT))
{
EnterEvadeMode();
return;
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp
index b421d9c1153..8d6eb064194 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lady_vashj.cpp
@@ -519,7 +519,7 @@ public:
if (CheckTimer <= diff)
{
// Start Phase 3
- if (instance && instance->GetData(DATA_CANSTARTPHASE3))
+ if (instance->GetData(DATA_CANSTARTPHASE3))
{
// set life 50%
me->SetHealth(me->CountPctFromMaxHealth(50));
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp
index a45e4ddb0a9..f9370b44c20 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_leotheras_the_blind.cpp
@@ -317,10 +317,10 @@ public:
// and reseting equipment
me->LoadEquipment();
- if (instance && instance->GetData64(DATA_LEOTHERAS_EVENT_STARTER))
+ if (instance->GetData64(DATA_LEOTHERAS_EVENT_STARTER))
{
Unit* victim = NULL;
- victim = Unit::GetUnit(*me, instance->GetData64(DATA_LEOTHERAS_EVENT_STARTER));
+ victim = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_LEOTHERAS_EVENT_STARTER));
if (victim)
me->getThreatManager().addThreat(victim, 1);
StartEvent();
@@ -750,7 +750,7 @@ public:
return;
}
- if (instance && !instance->GetData64(DATA_LEOTHERAS_EVENT_STARTER))
+ if (!instance->GetData64(DATA_LEOTHERAS_EVENT_STARTER))
{
EnterEvadeMode();
return;
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp
index a6cd426f435..718c32cd8ae 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp
@@ -112,10 +112,11 @@ public:
bool CheckCanStart()//check if players fished
{
- if (instance && instance->GetData(DATA_STRANGE_POOL) == NOT_STARTED)
+ if (instance->GetData(DATA_STRANGE_POOL) == NOT_STARTED)
return false;
return true;
}
+
void Reset() OVERRIDE
{
me->SetSwim(true);
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp
index 42833fead04..3661ebc8cc3 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/boss_mekgineer_steamrigger.cpp
@@ -224,11 +224,11 @@ public:
{
if (Repair_Timer <= diff)
{
- if (instance && instance->GetBossState(DATA_MEKGINEER_STEAMRIGGER) == IN_PROGRESS)
+ if (instance->GetBossState(DATA_MEKGINEER_STEAMRIGGER) == IN_PROGRESS)
{
- if (Unit* pMekgineer = Unit::GetUnit(*me, instance->GetData64(DATA_MEKGINEER_STEAMRIGGER)))
+ if (Creature* mekgineer = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_MEKGINEER_STEAMRIGGER)))
{
- if (me->IsWithinDistInMap(pMekgineer, MAX_REPAIR_RANGE))
+ if (me->IsWithinDistInMap(mekgineer, MAX_REPAIR_RANGE))
{
//are we already channeling? Doesn't work very well, find better check?
if (!me->GetUInt32Value(UNIT_CHANNEL_SPELL))
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
index d802e48f3b0..a961800025d 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
@@ -484,7 +484,7 @@ class npc_ember_of_alar : public CreatureScript
me->setDeathState(JUST_DIED);
}
- void DamageTaken(Unit* killer, uint32 &damage) OVERRIDE
+ void DamageTaken(Unit* killer, uint32& damage) OVERRIDE
{
if (damage >= me->GetHealth() && killer != me && !toDie)
{
@@ -492,7 +492,7 @@ class npc_ember_of_alar : public CreatureScript
DoCast(me, SPELL_EMBER_BLAST, true);
me->SetDisplayId(11686);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- if (instance && instance->GetData(DATA_ALAREVENT) == 2)
+ if (instance->GetData(DATA_ALAREVENT) == 2)
{
if (Unit* Alar = Unit::GetUnit(*me, instance->GetData64(DATA_ALAR)))
{
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp
index 75b1bfe8ad1..077539b6b88 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp
@@ -182,7 +182,7 @@ struct advisorbase_ai : public ScriptedAI
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
//reset encounter
- if (instance && (instance->GetData(DATA_KAELTHASEVENT) == 1 || instance->GetData(DATA_KAELTHASEVENT) == 3))
+ if (instance->GetData(DATA_KAELTHASEVENT) == 1 || instance->GetData(DATA_KAELTHASEVENT) == 3)
if (Creature* Kaelthas = Unit::GetCreature(*me, instance->GetData64(DATA_KAELTHAS)))
Kaelthas->AI()->EnterEvadeMode();
}
@@ -223,14 +223,14 @@ struct advisorbase_ai : public ScriptedAI
return;
//Prevent glitch if in fake death
- if (FakeDeath && instance && instance->GetData(DATA_KAELTHASEVENT) != 0)
+ if (FakeDeath && instance->GetData(DATA_KAELTHASEVENT) != 0)
{
damage = 0;
return;
}
//Don't really die in phase 1 & 3, only die after that
- if (instance && instance->GetData(DATA_KAELTHASEVENT) != 0)
+ if (instance->GetData(DATA_KAELTHASEVENT) != 0)
{
//prevent death
damage = 0;
@@ -417,7 +417,7 @@ class boss_kaelthas : public CreatureScript
}
else if (me->GetMap()->IsDungeon())
{
- if (instance && !instance->GetData(DATA_KAELTHASEVENT) && !Phase)
+ if (!instance->GetData(DATA_KAELTHASEVENT) && !Phase)
StartEvent();
who->SetInCombatWith(me);
@@ -429,7 +429,7 @@ class boss_kaelthas : public CreatureScript
void EnterCombat(Unit* /*who*/) OVERRIDE
{
- if (instance && !instance->GetData(DATA_KAELTHASEVENT) && !Phase)
+ if (!instance->GetData(DATA_KAELTHASEVENT) && !Phase)
StartEvent();
}
@@ -1046,7 +1046,7 @@ class boss_thaladred_the_darkener : public CreatureScript
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (instance && instance->GetData(DATA_KAELTHASEVENT) == 3)
+ if (instance->GetData(DATA_KAELTHASEVENT) == 3)
Talk(SAY_THALADRED_DEATH);
}
@@ -1138,7 +1138,7 @@ class boss_lord_sanguinar : public CreatureScript
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (instance && instance->GetData(DATA_KAELTHASEVENT) == 3)
+ if (instance->GetData(DATA_KAELTHASEVENT) == 3)
Talk(SAY_SANGUINAR_DEATH);
}
@@ -1203,7 +1203,7 @@ class boss_grand_astromancer_capernian : public CreatureScript
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (instance && instance->GetData(DATA_KAELTHASEVENT) == 3)
+ if (instance->GetData(DATA_KAELTHASEVENT) == 3)
Talk(SAY_CAPERNIAN_DEATH);
}
@@ -1342,7 +1342,7 @@ class boss_master_engineer_telonicus : public CreatureScript
void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (instance && instance->GetData(DATA_KAELTHASEVENT) == 3)
+ if (instance->GetData(DATA_KAELTHASEVENT) == 3)
Talk(SAY_TELONICUS_DEATH);
}
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp
index a1917d6201c..1a972f65360 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_void_reaver.cpp
@@ -77,7 +77,7 @@ class boss_void_reaver : public CreatureScript
Enraged = false;
- if (instance && me->IsAlive())
+ if (me->IsAlive())
instance->SetData(DATA_VOIDREAVEREVENT, NOT_STARTED);
}
diff --git a/src/server/scripts/Outland/zone_blades_edge_mountains.cpp b/src/server/scripts/Outland/zone_blades_edge_mountains.cpp
index cc58be26664..3f1579c42b1 100644
--- a/src/server/scripts/Outland/zone_blades_edge_mountains.cpp
+++ b/src/server/scripts/Outland/zone_blades_edge_mountains.cpp
@@ -113,7 +113,10 @@ public:
struct npc_bloodmaul_bruteAI : public ScriptedAI
{
- npc_bloodmaul_bruteAI(Creature* creature) : ScriptedAI(creature) { }
+ npc_bloodmaul_bruteAI(Creature* creature) : ScriptedAI(creature)
+ {
+ hp30 = false;
+ }
void Reset() OVERRIDE
{
@@ -1128,6 +1131,7 @@ public:
npc_oscillating_frequency_scanner_master_bunnyAI(Creature* creature) : ScriptedAI(creature)
{
playerGuid = 0;
+ timer = 500;
}
void Reset() OVERRIDE
diff --git a/src/server/scripts/Outland/zone_nagrand.cpp b/src/server/scripts/Outland/zone_nagrand.cpp
index 8d5c81d1c01..9b7a3f8aa2a 100644
--- a/src/server/scripts/Outland/zone_nagrand.cpp
+++ b/src/server/scripts/Outland/zone_nagrand.cpp
@@ -182,13 +182,11 @@ public:
{
if (quest->GetQuestId() == QUEST_TOTEM_KARDASH_H)
{
- if (npc_maghar_captiveAI* pEscortAI = dynamic_cast<npc_maghar_captiveAI*>(creature->AI()))
+ if (npc_maghar_captiveAI* EscortAI = dynamic_cast<npc_maghar_captiveAI*>(creature->AI()))
{
creature->SetStandState(UNIT_STAND_STATE_STAND);
creature->setFaction(232);
-
- pEscortAI->Start(true, false, player->GetGUID(), quest);
-
+ EscortAI->Start(true, false, player->GetGUID(), quest);
creature->AI()->Talk(SAY_MAG_START);
creature->SummonCreature(NPC_MURK_RAIDER, m_afAmbushA[0]+2.5f, m_afAmbushA[1]-2.5f, m_afAmbushA[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
@@ -208,15 +206,15 @@ public:
{
npc_maghar_captiveAI(Creature* creature) : npc_escortAI(creature) { Reset(); }
- uint32 m_uiChainLightningTimer;
- uint32 m_uiHealTimer;
- uint32 m_uiFrostShockTimer;
+ uint32 ChainLightningTimer;
+ uint32 HealTimer;
+ uint32 FrostShockTimer;
void Reset() OVERRIDE
{
- m_uiChainLightningTimer = 1000;
- m_uiHealTimer = 0;
- m_uiFrostShockTimer = 6000;
+ ChainLightningTimer = 1000;
+ HealTimer = 0;
+ FrostShockTimer = 6000;
}
void EnterCombat(Unit* /*who*/) OVERRIDE
@@ -224,6 +222,18 @@ public:
DoCast(me, SPELL_EARTHBIND_TOTEM, false);
}
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ if (!HasEscortState(STATE_ESCORT_ESCORTING))
+ return;
+
+ if (Player* player = GetPlayerForEscort())
+ {
+ if (player->GetQuestStatus(QUEST_TOTEM_KARDASH_H) != QUEST_STATUS_COMPLETE)
+ player->FailQuest(QUEST_TOTEM_KARDASH_H);
+ }
+ }
+
void WaypointReached(uint32 waypointId) OVERRIDE
{
switch (waypointId)
@@ -263,9 +273,9 @@ public:
}
- void SpellHitTarget(Unit* /*target*/, const SpellInfo* pSpell) OVERRIDE
+ void SpellHitTarget(Unit* /*target*/, const SpellInfo* spell) OVERRIDE
{
- if (pSpell->Id == SPELL_CHAIN_LIGHTNING)
+ if (spell->Id == SPELL_CHAIN_LIGHTNING)
{
if (rand()%10)
return;
@@ -274,38 +284,42 @@ public:
}
}
- void UpdateAI(uint32 uiDiff) OVERRIDE
+ void UpdateAI(uint32 diff) OVERRIDE
{
- npc_escortAI::UpdateAI(uiDiff);
- if (!me->GetVictim())
+ npc_escortAI::UpdateAI(diff);
+
+ if (!UpdateVictim())
+ return;
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
return;
- if (m_uiChainLightningTimer <= uiDiff)
+ if (ChainLightningTimer <= diff)
{
DoCastVictim(SPELL_CHAIN_LIGHTNING);
- m_uiChainLightningTimer = urand(7000, 14000);
+ ChainLightningTimer = urand(7000, 14000);
}
else
- m_uiChainLightningTimer -= uiDiff;
+ ChainLightningTimer -= diff;
if (HealthBelowPct(30))
{
- if (m_uiHealTimer <= uiDiff)
+ if (HealTimer <= diff)
{
DoCast(me, SPELL_HEALING_WAVE);
- m_uiHealTimer = 5000;
+ HealTimer = 5000;
}
else
- m_uiHealTimer -= uiDiff;
+ HealTimer -= diff;
}
- if (m_uiFrostShockTimer <= uiDiff)
+ if (FrostShockTimer <= diff)
{
DoCastVictim(SPELL_FROST_SHOCK);
- m_uiFrostShockTimer = urand(7500, 15000);
+ FrostShockTimer = urand(7500, 15000);
}
else
- m_uiFrostShockTimer -= uiDiff;
+ FrostShockTimer -= diff;
DoMeleeAttackIfReady();
}
@@ -517,6 +531,7 @@ public:
if (npc_kurenai_captiveAI* EscortAI = dynamic_cast<npc_kurenai_captiveAI*>(creature->AI()))
{
creature->SetStandState(UNIT_STAND_STATE_STAND);
+ creature->setFaction(231);
EscortAI->Start(true, false, player->GetGUID(), quest);
creature->AI()->Talk(SAY_KUR_START);
@@ -629,6 +644,8 @@ public:
void UpdateAI(uint32 diff) OVERRIDE
{
+ npc_escortAI::UpdateAI(diff);
+
if (!UpdateVictim())
return;
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index e1ef9ea6862..e8108f03e7d 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -25,6 +25,7 @@
#include "ScriptMgr.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
+#include "Containers.h"
enum DeathKnightSpells
{
@@ -49,6 +50,8 @@ enum DeathKnightSpells
SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED = 63622,
SPELL_DK_ITEM_SIGIL_VENGEFUL_HEART = 64962,
SPELL_DK_ITEM_T8_MELEE_4P_BONUS = 64736,
+ SPELL_DK_MASTER_OF_GHOULS = 52143,
+ SPELL_DK_RAISE_DEAD_USE_REAGENT = 48289,
SPELL_DK_RUNIC_POWER_ENERGIZE = 49088,
SPELL_DK_SCENT_OF_BLOOD = 50422,
SPELL_DK_SCOURGE_STRIKE_TRIGGERED = 70890,
@@ -63,6 +66,11 @@ enum DeathKnightSpellIcons
DK_ICON_ID_IMPROVED_DEATH_STRIKE = 2751
};
+enum Misc
+{
+ NPC_DK_GHOUL = 26125
+};
+
// 50462 - Anti-Magic Shell (on raid member)
class spell_dk_anti_magic_shell_raid : public SpellScriptLoader
{
@@ -140,13 +148,12 @@ class spell_dk_anti_magic_shell_self : public SpellScriptLoader
absorbAmount = std::min(CalculatePct(dmgInfo.GetDamage(), absorbPct), GetTarget()->CountPctFromMaxHealth(hpPct));
}
- void Trigger(AuraEffect* aurEff, DamageInfo & /*dmgInfo*/, uint32 & absorbAmount)
+ void Trigger(AuraEffect* aurEff, DamageInfo& /*dmgInfo*/, uint32& absorbAmount)
{
- Unit* target = GetTarget();
// damage absorbed by Anti-Magic Shell energizes the DK with additional runic power.
// This, if I'm not mistaken, shows that we get back ~20% of the absorbed damage as runic power.
- int32 bp = absorbAmount * 2 / 10;
- target->CastCustomSpell(target, SPELL_DK_RUNIC_POWER_ENERGIZE, &bp, NULL, NULL, true, NULL, aurEff);
+ int32 bp = CalculatePct(absorbAmount, 20);
+ GetTarget()->CastCustomSpell(SPELL_DK_RUNIC_POWER_ENERGIZE, SPELLVALUE_BASE_POINT0, bp, GetTarget(), true, NULL, aurEff);
}
void Register() OVERRIDE
@@ -312,6 +319,28 @@ class spell_dk_blood_gorged : public SpellScriptLoader
}
};
+class CorpseExplosionCheck
+{
+public:
+ explicit CorpseExplosionCheck(uint64 casterGUID) : _casterGUID(casterGUID) { }
+
+ bool operator()(WorldObject* obj) const
+ {
+ if (Unit* target = obj->ToUnit())
+ {
+ if ((target->isDead() || (target->GetEntry() == NPC_DK_GHOUL && target->GetOwnerGUID() == _casterGUID))
+ && !(target->GetCreatureTypeMask() & CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL)
+ && target->GetDisplayId() == target->GetNativeDisplayId())
+ return false;
+ }
+
+ return true;
+ }
+
+private:
+ uint64 _casterGUID;
+};
+
// 49158 - Corpse Explosion (51325, 51326, 51327, 51328)
class spell_dk_corpse_explosion : public SpellScriptLoader
{
@@ -322,41 +351,87 @@ class spell_dk_corpse_explosion : public SpellScriptLoader
{
PrepareSpellScript(spell_dk_corpse_explosion_SpellScript);
- bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ bool Validate(SpellInfo const* spellInfo) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_DK_CORPSE_EXPLOSION_TRIGGERED) || !sSpellMgr->GetSpellInfo(SPELL_DK_GHOUL_EXPLODE))
- return false;
- if (!sSpellMgr->GetSpellInfo(SPELL_DK_CORPSE_EXPLOSION_VISUAL))
+ if (!sSpellMgr->GetSpellInfo(SPELL_DK_CORPSE_EXPLOSION_TRIGGERED)
+ || !sSpellMgr->GetSpellInfo(SPELL_DK_GHOUL_EXPLODE)
+ || !sSpellMgr->GetSpellInfo(SPELL_DK_CORPSE_EXPLOSION_VISUAL)
+ || !sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_1].CalcValue()))
return false;
return true;
}
- void HandleDummy(SpellEffIndex /*effIndex*/)
+ bool Load() OVERRIDE
+ {
+ _target = NULL;
+ return true;
+ }
+
+ void CheckTarget(WorldObject*& target)
+ {
+ if (CorpseExplosionCheck(GetCaster()->GetGUID())(target))
+ target = NULL;
+
+ _target = target;
+ }
+
+ void CheckTargets(std::list<WorldObject*>& targets)
+ {
+ WorldObject* target = _target;
+ if (!target)
+ {
+ targets.remove_if(CorpseExplosionCheck(GetCaster()->GetGUID()));
+ if (targets.empty())
+ {
+ FinishCast(SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW);
+ return;
+ }
+ target = Trinity::Containers::SelectRandomContainerElement(targets);
+ targets.clear();
+ targets.push_back(target);
+ }
+ else
+ targets.clear();
+ }
+
+ void HandleDamage(SpellEffIndex effIndex, Unit* target)
+ {
+ if (effIndex == EFFECT_0)
+ GetCaster()->CastCustomSpell(GetSpellInfo()->Effects[EFFECT_1].CalcValue(), SPELLVALUE_BASE_POINT0, GetEffectValue(), target, true);
+ else if (effIndex == EFFECT_1)
+ GetCaster()->CastCustomSpell(GetEffectValue(), SPELLVALUE_BASE_POINT0, GetSpell()->CalculateDamage(EFFECT_0, NULL), target, true);
+ }
+
+ void HandleCorpseExplosion(SpellEffIndex effIndex)
{
if (Unit* unitTarget = GetHitUnit())
{
- int32 bp = 0;
if (unitTarget->IsAlive()) // Living ghoul as a target
{
- bp = int32(unitTarget->CountPctFromMaxHealth(25));
- unitTarget->CastCustomSpell(unitTarget, SPELL_DK_GHOUL_EXPLODE, &bp, NULL, NULL, false);
+ unitTarget->CastSpell(unitTarget, SPELL_DK_GHOUL_EXPLODE, false);
+ // Corpse Explosion (Suicide) and Set corpse look handled in SpellScript of SPELL_DK_GHOUL_EXPLODE
}
else // Some corpse
{
- bp = GetEffectValue();
- GetCaster()->CastCustomSpell(unitTarget, GetSpellInfo()->Effects[EFFECT_1].CalcValue(), &bp, NULL, NULL, true);
+ HandleDamage(effIndex, unitTarget);
// Corpse Explosion (Suicide)
unitTarget->CastSpell(unitTarget, SPELL_DK_CORPSE_EXPLOSION_TRIGGERED, true);
+ // Set corpse look
+ GetCaster()->CastSpell(unitTarget, SPELL_DK_CORPSE_EXPLOSION_VISUAL, true);
}
- // Set corpse look
- GetCaster()->CastSpell(unitTarget, SPELL_DK_CORPSE_EXPLOSION_VISUAL, true);
}
}
void Register() OVERRIDE
{
- OnEffectHitTarget += SpellEffectFn(spell_dk_corpse_explosion_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_dk_corpse_explosion_SpellScript::CheckTarget, EFFECT_0, TARGET_UNIT_TARGET_ANY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dk_corpse_explosion_SpellScript::CheckTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY);
+ OnEffectHitTarget += SpellEffectFn(spell_dk_corpse_explosion_SpellScript::HandleCorpseExplosion, EFFECT_0, SPELL_EFFECT_DUMMY);
+ OnEffectHitTarget += SpellEffectFn(spell_dk_corpse_explosion_SpellScript::HandleCorpseExplosion, EFFECT_1, SPELL_EFFECT_DUMMY);
}
+
+ private:
+ WorldObject* _target;
};
SpellScript* GetSpellScript() const OVERRIDE
@@ -617,24 +692,34 @@ class spell_dk_ghoul_explode : public SpellScriptLoader
{
PrepareSpellScript(spell_dk_ghoul_explode_SpellScript);
- bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ bool Validate(SpellInfo const* spellInfo) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_DK_CORPSE_EXPLOSION_TRIGGERED))
+ if (!sSpellMgr->GetSpellInfo(SPELL_DK_CORPSE_EXPLOSION_TRIGGERED)
+ || spellInfo->Effects[EFFECT_2].CalcValue() <= 0)
return false;
return true;
}
+ void HandleDamage(SpellEffIndex /*effIndex*/)
+ {
+ int32 value = int32(GetCaster()->CountPctFromMaxHealth(GetSpellInfo()->Effects[EFFECT_2].CalcValue(GetCaster())));
+ SetEffectValue(value);
+ }
+
void Suicide(SpellEffIndex /*effIndex*/)
{
if (Unit* unitTarget = GetHitUnit())
{
// Corpse Explosion (Suicide)
unitTarget->CastSpell(unitTarget, SPELL_DK_CORPSE_EXPLOSION_TRIGGERED, true);
+ // Set corpse look
+ GetCaster()->CastSpell(unitTarget, SPELL_DK_CORPSE_EXPLOSION_VISUAL, true);
}
}
void Register() OVERRIDE
{
+ OnEffectLaunchTarget += SpellEffectFn(spell_dk_ghoul_explode_SpellScript::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
OnEffectHitTarget += SpellEffectFn(spell_dk_ghoul_explode_SpellScript::Suicide, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE);
}
};
@@ -941,6 +1026,162 @@ class spell_dk_presence : public SpellScriptLoader
}
};
+class RaiseDeadCheck
+{
+ public:
+ explicit RaiseDeadCheck(Player const* caster) : _caster(caster) { }
+
+ bool operator()(WorldObject* obj) const
+ {
+ if (Unit* target = obj->ToUnit())
+ {
+ if (!target->IsAlive()
+ && _caster->isHonorOrXPTarget(target)
+ && target->GetCreatureType() == CREATURE_TYPE_HUMANOID
+ && target->GetDisplayId() == target->GetNativeDisplayId())
+ return false;
+ }
+
+ return true;
+ }
+
+ private:
+ Player const* _caster;
+};
+
+// 46584 - Raise Dead
+class spell_dk_raise_dead : public SpellScriptLoader
+{
+ public:
+ spell_dk_raise_dead() : SpellScriptLoader("spell_dk_raise_dead") { }
+
+ class spell_dk_raise_dead_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_dk_raise_dead_SpellScript);
+
+ bool Validate(SpellInfo const* spellInfo) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_1].CalcValue())
+ || !sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_2].CalcValue())
+ || !sSpellMgr->GetSpellInfo(SPELL_DK_RAISE_DEAD_USE_REAGENT)
+ || !sSpellMgr->GetSpellInfo(SPELL_DK_MASTER_OF_GHOULS))
+ return false;
+ return true;
+ }
+
+ bool Load() OVERRIDE
+ {
+ _result = SPELL_CAST_OK;
+ _corpse = false;
+ return GetCaster()->GetTypeId() == TYPEID_PLAYER;
+ }
+
+ SpellCastResult CheckCast()
+ {
+ /// process spell target selection before cast starts
+ /// targets of effect_1 are used to check cast
+ GetSpell()->SelectSpellTargets();
+ /// cleanup spell target map, and fill it again on normal way
+ GetSpell()->CleanupTargetList();
+ /// _result is set in spell target selection
+ return _result;
+ }
+
+ SpellCastResult CheckReagents()
+ {
+ /// @workaround: there is no access to castresult of other spells, check it manually
+ SpellInfo const* reagentSpell = sSpellMgr->GetSpellInfo(SPELL_DK_RAISE_DEAD_USE_REAGENT);
+ Player* player = GetCaster()->ToPlayer();
+ if (!player->CanNoReagentCast(reagentSpell))
+ {
+ for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
+ {
+ if (reagentSpell->Reagent[i] <= 0)
+ continue;
+
+ if (!player->HasItemCount(reagentSpell->Reagent[i], reagentSpell->ReagentCount[i]))
+ {
+ Spell::SendCastResult(player, reagentSpell, 0, SPELL_FAILED_REAGENTS);
+ return SPELL_FAILED_DONT_REPORT;
+ }
+ }
+ }
+ return SPELL_CAST_OK;
+ }
+
+ void CheckTargets(std::list<WorldObject*>& targets)
+ {
+ targets.remove_if(RaiseDeadCheck(GetCaster()->ToPlayer()));
+
+ if (targets.empty())
+ {
+ if (GetSpell()->getState() == SPELL_STATE_PREPARING)
+ _result = CheckReagents();
+
+ return;
+ }
+
+ WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
+ targets.clear();
+ targets.push_back(target);
+ _corpse = true;
+ }
+
+ void CheckTarget(WorldObject*& target)
+ {
+ // Don't add caster to target map, if we found a corpse to raise dead
+ if (_corpse)
+ target = NULL;
+ }
+
+ void ConsumeReagents()
+ {
+ // No corpse found, take reagents
+ if (!_corpse)
+ GetCaster()->CastSpell(GetCaster(), SPELL_DK_RAISE_DEAD_USE_REAGENT, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_POWER_AND_REAGENT_COST));
+ }
+
+ uint32 GetGhoulSpellId()
+ {
+ // Do we have talent Master of Ghouls?
+ if (GetCaster()->HasAura(SPELL_DK_MASTER_OF_GHOULS))
+ // summon as pet
+ return GetSpellInfo()->Effects[EFFECT_2].CalcValue();
+
+ // or guardian
+ return GetSpellInfo()->Effects[EFFECT_1].CalcValue();
+ }
+
+ void HandleRaiseDead(SpellEffIndex /*effIndex*/)
+ {
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(GetGhoulSpellId());
+ SpellCastTargets targets;
+ targets.SetDst(*GetHitUnit());
+
+ GetCaster()->CastSpell(targets, spellInfo, NULL, TRIGGERED_FULL_MASK);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnCheckCast += SpellCheckCastFn(spell_dk_raise_dead_SpellScript::CheckCast);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dk_raise_dead_SpellScript::CheckTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY);
+ OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_dk_raise_dead_SpellScript::CheckTarget, EFFECT_2, TARGET_UNIT_CASTER);
+ OnCast += SpellCastFn(spell_dk_raise_dead_SpellScript::ConsumeReagents);
+ OnEffectHitTarget += SpellEffectFn(spell_dk_raise_dead_SpellScript::HandleRaiseDead, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
+ OnEffectHitTarget += SpellEffectFn(spell_dk_raise_dead_SpellScript::HandleRaiseDead, EFFECT_2, SPELL_EFFECT_DUMMY);
+ }
+
+ private:
+ SpellCastResult _result;
+ bool _corpse;
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_dk_raise_dead_SpellScript();
+ }
+};
+
// 59754 Rune Tap - Party
class spell_dk_rune_tap_party : public SpellScriptLoader
{
@@ -1225,6 +1466,7 @@ void AddSC_deathknight_spell_scripts()
new spell_dk_improved_frost_presence();
new spell_dk_improved_unholy_presence();
new spell_dk_presence();
+ new spell_dk_raise_dead();
new spell_dk_rune_tap_party();
new spell_dk_scent_of_blood();
new spell_dk_scourge_strike();
diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp
index 9fd43807fd5..5e56d4b8d92 100644
--- a/src/server/scripts/Spells/spell_druid.cpp
+++ b/src/server/scripts/Spells/spell_druid.cpp
@@ -993,6 +993,76 @@ class spell_dru_t10_restoration_4p_bonus : public SpellScriptLoader
}
};
+class RaidCheck
+{
+ public:
+ explicit RaidCheck(Unit const* caster) : _caster(caster) { }
+
+ bool operator()(WorldObject* obj) const
+ {
+ if (Unit* target = obj->ToUnit())
+ return !_caster->IsInRaidWith(target);
+
+ return true;
+ }
+
+ private:
+ Unit const* _caster;
+};
+
+// -48438 - Wild Growth
+class spell_dru_wild_growth : public SpellScriptLoader
+{
+ public:
+ spell_dru_wild_growth() : SpellScriptLoader("spell_dru_wild_growth") { }
+
+ class spell_dru_wild_growth_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_dru_wild_growth_SpellScript);
+
+ bool Validate(SpellInfo const* spellInfo) OVERRIDE
+ {
+ if (spellInfo->Effects[EFFECT_2].IsEffect() || spellInfo->Effects[EFFECT_2].CalcValue() <= 0)
+ return false;
+ return true;
+ }
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ targets.remove_if(RaidCheck(GetCaster()));
+
+ uint32 const maxTargets = uint32(GetSpellInfo()->Effects[EFFECT_2].CalcValue(GetCaster()));
+
+ if (targets.size() > maxTargets)
+ {
+ targets.sort(Trinity::HealthPctOrderPred());
+ targets.resize(maxTargets);
+ }
+
+ _targets = targets;
+ }
+
+ void SetTargets(std::list<WorldObject*>& targets)
+ {
+ targets = _targets;
+ }
+
+ void Register() OVERRIDE
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_wild_growth_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_wild_growth_SpellScript::SetTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ALLY);
+ }
+
+ private:
+ std::list<WorldObject*> _targets;
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_dru_wild_growth_SpellScript();
+ }
+};
+
void AddSC_druid_spell_scripts()
{
new spell_dru_dash();
@@ -1018,4 +1088,5 @@ void AddSC_druid_spell_scripts()
new spell_dru_tiger_s_fury();
new spell_dru_typhoon();
new spell_dru_t10_restoration_4p_bonus();
+ new spell_dru_wild_growth();
}
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 3feb9821177..1e9a8713019 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -2963,22 +2963,65 @@ enum Replenishment
SPELL_INFINITE_REPLENISHMENT = 61782
};
+class ReplenishmentCheck
+{
+public:
+ bool operator()(WorldObject* obj) const
+ {
+ if (Unit* target = obj->ToUnit())
+ return target->getPowerType() != POWER_MANA;
+
+ return true;
+ }
+};
+
class spell_gen_replenishment : public SpellScriptLoader
{
public:
spell_gen_replenishment() : SpellScriptLoader("spell_gen_replenishment") { }
- class spell_gen_replenishment_AuraScript : public AuraScript
+ class spell_gen_replenishment_SpellScript : public SpellScript
{
- PrepareAuraScript(spell_gen_replenishment_AuraScript);
+ PrepareSpellScript(spell_gen_replenishment_SpellScript);
- bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ void RemoveInvalidTargets(std::list<WorldObject*>& targets)
{
- if (!sSpellMgr->GetSpellInfo(SPELL_REPLENISHMENT) ||
- !sSpellMgr->GetSpellInfo(SPELL_INFINITE_REPLENISHMENT))
- return false;
- return true;
+ // In arenas Replenishment may only affect the caster
+ if (Player* caster = GetCaster()->ToPlayer())
+ {
+ if (caster->InArena())
+ {
+ targets.clear();
+ targets.push_back(caster);
+ return;
+ }
+ }
+
+ targets.remove_if(ReplenishmentCheck());
+
+ uint8 const maxTargets = 10;
+
+ if (targets.size() > maxTargets)
+ {
+ targets.sort(Trinity::PowerPctOrderPred(POWER_MANA));
+ targets.resize(maxTargets);
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gen_replenishment_SpellScript::RemoveInvalidTargets, EFFECT_ALL, TARGET_UNIT_CASTER_AREA_RAID);
}
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_gen_replenishment_SpellScript();
+ }
+
+ class spell_gen_replenishment_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gen_replenishment_AuraScript);
bool Load() OVERRIDE
{
diff --git a/src/server/scripts/Spells/spell_holiday.cpp b/src/server/scripts/Spells/spell_holiday.cpp
index bb84606dece..07d95aa63f5 100644
--- a/src/server/scripts/Spells/spell_holiday.cpp
+++ b/src/server/scripts/Spells/spell_holiday.cpp
@@ -277,6 +277,62 @@ class spell_hallow_end_tricky_treat : public SpellScriptLoader
}
};
+enum PilgrimsBountyBuffFood
+{
+ // Pilgrims Bounty Buff Food
+ SPELL_WELL_FED_AP_TRIGGER = 65414,
+ SPELL_WELL_FED_ZM_TRIGGER = 65412,
+ SPELL_WELL_FED_HIT_TRIGGER = 65416,
+ SPELL_WELL_FED_HASTE_TRIGGER = 65410,
+ SPELL_WELL_FED_SPIRIT_TRIGGER = 65415
+};
+
+class spell_pilgrims_bounty_buff_food : public SpellScriptLoader
+{
+ private:
+ uint32 const _triggeredSpellId;
+ public:
+ spell_pilgrims_bounty_buff_food(const char* name, uint32 triggeredSpellId) : SpellScriptLoader(name), _triggeredSpellId(triggeredSpellId) { }
+
+ class spell_pilgrims_bounty_buff_food_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_pilgrims_bounty_buff_food_AuraScript)
+ private:
+ uint32 const _triggeredSpellId;
+
+ public:
+ spell_pilgrims_bounty_buff_food_AuraScript(uint32 triggeredSpellId) : AuraScript(), _triggeredSpellId(triggeredSpellId) { }
+
+ bool Load() OVERRIDE
+ {
+ _handled = false;
+ return true;
+ }
+
+ void HandleTriggerSpell(AuraEffect const* /*aurEff*/)
+ {
+ PreventDefaultAction();
+ if (_handled)
+ return;
+
+ _handled = true;
+ GetTarget()->CastSpell(GetTarget(), _triggeredSpellId, true);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_pilgrims_bounty_buff_food_AuraScript::HandleTriggerSpell, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+
+ bool _handled;
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_pilgrims_bounty_buff_food_AuraScript(_triggeredSpellId);
+ }
+};
+
enum Mistletoe
{
SPELL_CREATE_MISTLETOE = 26206,
@@ -396,6 +452,12 @@ void AddSC_holiday_spell_scripts()
new spell_hallow_end_trick();
new spell_hallow_end_trick_or_treat();
new spell_hallow_end_tricky_treat();
+ // Pilgrims Bounty
+ new spell_pilgrims_bounty_buff_food("spell_gen_slow_roasted_turkey", SPELL_WELL_FED_AP_TRIGGER);
+ new spell_pilgrims_bounty_buff_food("spell_gen_cranberry_chutney", SPELL_WELL_FED_ZM_TRIGGER);
+ new spell_pilgrims_bounty_buff_food("spell_gen_spice_bread_stuffing", SPELL_WELL_FED_HIT_TRIGGER);
+ new spell_pilgrims_bounty_buff_food("spell_gen_pumpkin_pie", SPELL_WELL_FED_SPIRIT_TRIGGER);
+ new spell_pilgrims_bounty_buff_food("spell_gen_candied_sweet_potato", SPELL_WELL_FED_HASTE_TRIGGER);
// Winter Veil
new spell_winter_veil_mistletoe();
new spell_winter_veil_px_238_winter_wondervolt();
diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp
index 8b3716f8f7d..837023f3bdd 100644
--- a/src/server/scripts/Spells/spell_item.cpp
+++ b/src/server/scripts/Spells/spell_item.cpp
@@ -349,6 +349,40 @@ class spell_item_deviate_fish : public SpellScriptLoader
}
};
+// 71610, 71641 - Echoes of Light (Althor's Abacus)
+class spell_item_echoes_of_light : public SpellScriptLoader
+{
+ public:
+ spell_item_echoes_of_light() : SpellScriptLoader("spell_item_echoes_of_light") { }
+
+ class spell_item_echoes_of_light_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_item_echoes_of_light_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ if (targets.size() < 2)
+ return;
+
+ targets.sort(Trinity::HealthPctOrderPred());
+
+ WorldObject* target = targets.front();
+ targets.clear();
+ targets.push_back(target);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_item_echoes_of_light_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_item_echoes_of_light_SpellScript();
+ }
+};
+
// http://www.wowhead.com/item=47499 Flask of the North
// 67019 Flask of the North
enum FlaskOfTheNorthSpells
@@ -2571,6 +2605,7 @@ void AddSC_item_spell_scripts()
new spell_item_defibrillate("spell_item_gnomish_army_knife", 33);
new spell_item_desperate_defense();
new spell_item_deviate_fish();
+ new spell_item_echoes_of_light();
new spell_item_flask_of_the_north();
new spell_item_gnomish_death_ray();
new spell_item_make_a_wish();
diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp
index 0b790f01d29..b5265561d85 100644
--- a/src/server/scripts/Spells/spell_paladin.cpp
+++ b/src/server/scripts/Spells/spell_paladin.cpp
@@ -57,6 +57,11 @@ enum PaladinSpells
SPELL_PALADIN_ITEM_HEALING_TRANCE = 37706,
+ SPELL_PALADIN_JUDGEMENT_DAMAGE = 54158,
+ SPELL_PALADIN_JUDGEMENT_OF_JUSTICE = 20184,
+ SPELL_PALADIN_JUDGEMENT_OF_LIGHT = 20185,
+ SPELL_PALADIN_JUDGEMENT_OF_WISDOM = 20186,
+
SPELL_PALADIN_GLYPH_OF_SALVATION = 63225,
SPELL_PALADIN_RIGHTEOUS_DEFENSE_TAUNT = 31790,
@@ -361,7 +366,6 @@ class spell_pal_divine_sacrifice : public SpellScriptLoader
bool Load() OVERRIDE
{
-
if (Unit* caster = GetCaster())
{
if (caster->GetTypeId() == TYPEID_PLAYER)
@@ -564,6 +568,39 @@ class spell_pal_eye_for_an_eye : public SpellScriptLoader
}
};
+// 54968 - Glyph of Holy Light
+class spell_pal_glyph_of_holy_light : public SpellScriptLoader
+{
+ public:
+ spell_pal_glyph_of_holy_light() : SpellScriptLoader("spell_pal_glyph_of_holy_light") { }
+
+ class spell_pal_glyph_of_holy_light_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_pal_glyph_of_holy_light_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ uint32 const maxTargets = GetSpellInfo()->MaxAffectedTargets;
+
+ if (targets.size() > maxTargets)
+ {
+ targets.sort(Trinity::HealthPctOrderPred());
+ targets.resize(maxTargets);
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pal_glyph_of_holy_light_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_pal_glyph_of_holy_light_SpellScript();
+ }
+};
+
// 63521 - Guarded by The Light
class spell_pal_guarded_by_the_light : public SpellScriptLoader
{
@@ -891,6 +928,67 @@ class spell_pal_item_healing_discount : public SpellScriptLoader
}
};
+// 53407 - Judgement of Justice
+// 20271 - Judgement of Light
+// 53408 - Judgement of Wisdom
+class spell_pal_judgement : public SpellScriptLoader
+{
+ public:
+ spell_pal_judgement(char const* scriptName, uint32 spellId) : SpellScriptLoader(scriptName), _spellId(spellId) { }
+
+ class spell_pal_judgement_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_pal_judgement_SpellScript);
+
+ public:
+ spell_pal_judgement_SpellScript(uint32 spellId) : SpellScript(), _spellId(spellId) { }
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_JUDGEMENT_DAMAGE)
+ || !sSpellMgr->GetSpellInfo(_spellId))
+ return false;
+ return true;
+ }
+
+ void HandleScriptEffect(SpellEffIndex /*effIndex*/)
+ {
+ uint32 spellId2 = SPELL_PALADIN_JUDGEMENT_DAMAGE;
+
+ // some seals have SPELL_AURA_DUMMY in EFFECT_2
+ Unit::AuraEffectList const& auras = GetCaster()->GetAuraEffectsByType(SPELL_AURA_DUMMY);
+ for (Unit::AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
+ {
+ if ((*i)->GetSpellInfo()->GetSpellSpecific() == SPELL_SPECIFIC_SEAL && (*i)->GetEffIndex() == EFFECT_2)
+ if (sSpellMgr->GetSpellInfo((*i)->GetAmount()))
+ {
+ spellId2 = (*i)->GetAmount();
+ break;
+ }
+ }
+
+ GetCaster()->CastSpell(GetHitUnit(), _spellId, true);
+ GetCaster()->CastSpell(GetHitUnit(), spellId2, true);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_pal_judgement_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+
+ private:
+ uint32 const _spellId;
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_pal_judgement_SpellScript(_spellId);
+ }
+
+ private:
+ uint32 const _spellId;
+};
+
// 20425 - Judgement of Command
class spell_pal_judgement_of_command : public SpellScriptLoader
{
@@ -1142,6 +1240,7 @@ void AddSC_paladin_spell_scripts()
new spell_pal_divine_storm_dummy();
new spell_pal_exorcism_and_holy_wrath_damage();
new spell_pal_eye_for_an_eye();
+ new spell_pal_glyph_of_holy_light();
new spell_pal_guarded_by_the_light();
new spell_pal_hand_of_sacrifice();
new spell_pal_hand_of_salvation();
@@ -1154,6 +1253,9 @@ void AddSC_paladin_spell_scripts()
new spell_pal_improved_aura_effect("spell_pal_improved_devotion_aura_effect");
new spell_pal_improved_aura_effect("spell_pal_sanctified_retribution_effect");
new spell_pal_item_healing_discount();
+ new spell_pal_judgement("spell_pal_judgement_of_justice", SPELL_PALADIN_JUDGEMENT_OF_JUSTICE);
+ new spell_pal_judgement("spell_pal_judgement_of_light", SPELL_PALADIN_JUDGEMENT_OF_LIGHT);
+ new spell_pal_judgement("spell_pal_judgement_of_wisdom", SPELL_PALADIN_JUDGEMENT_OF_WISDOM);
new spell_pal_judgement_of_command();
new spell_pal_lay_on_hands();
new spell_pal_righteous_defense();
diff --git a/src/server/scripts/Spells/spell_pet.cpp b/src/server/scripts/Spells/spell_pet.cpp
index 3d6853daf2c..a7742630ccd 100644
--- a/src/server/scripts/Spells/spell_pet.cpp
+++ b/src/server/scripts/Spells/spell_pet.cpp
@@ -1498,9 +1498,8 @@ public:
// Ravenous Dead. Check just if owner has Ravenous Dead since it's effect is not an aura
if (AuraEffect const* aurEff = owner->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DEATHKNIGHT, 3010, 0))
- {
mod += aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()/100; // Ravenous Dead edits the original scale
- }
+
// Glyph of the Ghoul
if (AuraEffect const* aurEff = owner->GetAuraEffect(SPELL_DEATH_KNIGHT_GLYPH_OF_GHOUL, 0))
mod += aurEff->GetAmount()/100;
diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp
index 4a702c7559c..71e5dac28ec 100644
--- a/src/server/scripts/Spells/spell_priest.cpp
+++ b/src/server/scripts/Spells/spell_priest.cpp
@@ -31,6 +31,7 @@ enum PriestSpells
{
SPELL_PRIEST_DIVINE_AEGIS = 47753,
SPELL_PRIEST_EMPOWERED_RENEW = 63544,
+ SPELL_PRIEST_GLYPH_OF_CIRCLE_OF_HEALING = 55675,
SPELL_PRIEST_GLYPH_OF_LIGHTWELL = 55673,
SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL = 56161,
SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL = 48153,
@@ -53,6 +54,82 @@ enum PriestSpellIcons
PRIEST_ICON_ID_PAIN_AND_SUFFERING = 2874,
};
+class PowerCheck
+{
+ public:
+ explicit PowerCheck(Powers const power) : _power(power) { }
+
+ bool operator()(WorldObject* obj) const
+ {
+ if (Unit* target = obj->ToUnit())
+ return target->getPowerType() != _power;
+
+ return true;
+ }
+
+ private:
+ Powers const _power;
+};
+
+class RaidCheck
+{
+ public:
+ explicit RaidCheck(Unit const* caster) : _caster(caster) { }
+
+ bool operator()(WorldObject* obj) const
+ {
+ if (Unit* target = obj->ToUnit())
+ return !_caster->IsInRaidWith(target);
+
+ return true;
+ }
+
+ private:
+ Unit const* _caster;
+};
+
+// -34861 - Circle of Healing
+class spell_pri_circle_of_healing : public SpellScriptLoader
+{
+ public:
+ spell_pri_circle_of_healing() : SpellScriptLoader("spell_pri_circle_of_healing") { }
+
+ class spell_pri_circle_of_healing_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_pri_circle_of_healing_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPH_OF_CIRCLE_OF_HEALING))
+ return false;
+ return true;
+ }
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ targets.remove_if(RaidCheck(GetCaster()));
+
+ uint32 const maxTargets = GetCaster()->HasAura(SPELL_PRIEST_GLYPH_OF_CIRCLE_OF_HEALING) ? 6 : 5; // Glyph of Circle of Healing
+
+ if (targets.size() > maxTargets)
+ {
+ targets.sort(Trinity::HealthPctOrderPred());
+ targets.resize(maxTargets);
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pri_circle_of_healing_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_pri_circle_of_healing_SpellScript();
+ }
+};
+
// -47509 - Divine Aegis
class spell_pri_divine_aegis : public SpellScriptLoader
{
@@ -103,6 +180,41 @@ class spell_pri_divine_aegis : public SpellScriptLoader
}
};
+// 64844 - Divine Hymn
+class spell_pri_divine_hymn : public SpellScriptLoader
+{
+ public:
+ spell_pri_divine_hymn() : SpellScriptLoader("spell_pri_divine_hymn") { }
+
+ class spell_pri_divine_hymn_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_pri_divine_hymn_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ targets.remove_if(RaidCheck(GetCaster()));
+
+ uint32 const maxTargets = 3;
+
+ if (targets.size() > maxTargets)
+ {
+ targets.sort(Trinity::HealthPctOrderPred());
+ targets.resize(maxTargets);
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pri_divine_hymn_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_pri_divine_hymn_SpellScript();
+ }
+};
+
// 55680 - Glyph of Prayer of Healing
class spell_pri_glyph_of_prayer_of_healing : public SpellScriptLoader
{
@@ -198,6 +310,42 @@ class spell_pri_guardian_spirit : public SpellScriptLoader
}
};
+// 64904 - Hymn of Hope
+class spell_pri_hymn_of_hope : public SpellScriptLoader
+{
+ public:
+ spell_pri_hymn_of_hope() : SpellScriptLoader("spell_pri_hymn_of_hope") { }
+
+ class spell_pri_hymn_of_hope_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_pri_hymn_of_hope_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ targets.remove_if(PowerCheck(POWER_MANA));
+ targets.remove_if(RaidCheck(GetCaster()));
+
+ uint32 const maxTargets = 3;
+
+ if (targets.size() > maxTargets)
+ {
+ targets.sort(Trinity::PowerPctOrderPred(POWER_MANA));
+ targets.resize(maxTargets);
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pri_hymn_of_hope_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_pri_hymn_of_hope_SpellScript();
+ }
+};
+
// 37594 - Greater Heal Refund
class spell_pri_item_greater_heal_refund : public SpellScriptLoader
{
@@ -703,9 +851,12 @@ class spell_pri_vampiric_touch : public SpellScriptLoader
void AddSC_priest_spell_scripts()
{
+ new spell_pri_circle_of_healing();
new spell_pri_divine_aegis();
+ new spell_pri_divine_hymn();
new spell_pri_glyph_of_prayer_of_healing();
new spell_pri_guardian_spirit();
+ new spell_pri_hymn_of_hope();
new spell_pri_item_greater_heal_refund();
new spell_pri_lightwell_renew();
new spell_pri_mana_burn();
diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp
index 419a289aed4..cdf32bd94d5 100644
--- a/src/server/scripts/Spells/spell_quest.cpp
+++ b/src/server/scripts/Spells/spell_quest.cpp
@@ -1606,6 +1606,7 @@ class spell_q12527_zuldrak_rat : public SpellScriptLoader
}
};
+// 55368 - Summon Stefan
class spell_q12661_q12669_q12676_q12677_q12713_summon_stefan : public SpellScriptLoader
{
public:
@@ -1615,19 +1616,16 @@ class spell_q12661_q12669_q12676_q12677_q12713_summon_stefan : public SpellScrip
{
PrepareSpellScript(spell_q12661_q12669_q12676_q12677_q12713_summon_stefan_SpellScript);
- void ChangeSummonPos(SpellEffIndex /*effIndex*/)
+ void SetDest(SpellDestination& dest)
{
// Adjust effect summon position
- WorldLocation summonPos = *GetExplTargetDest();
- Position offset = { 0.0f, 0.0f, 20.0f, 0.0f };
- summonPos.RelocateOffset(offset);
- SetExplTargetDest(summonPos);
- GetHitDest()->RelocateOffset(offset);
+ Position const offset = { 0.0f, 0.0f, 20.0f, 0.0f };
+ dest.RelocateOffset(offset);
}
void Register() OVERRIDE
{
- OnEffectHit += SpellEffectFn(spell_q12661_q12669_q12676_q12677_q12713_summon_stefan_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON);
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_q12661_q12669_q12676_q12677_q12713_summon_stefan_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER_BACK);
}
};
@@ -1723,6 +1721,7 @@ class spell_q13291_q13292_q13239_q13261_frostbrood_skytalon_grab_decoy : public
}
};
+// 59303 - Summon Frost Wyrm
class spell_q13291_q13292_q13239_q13261_armored_decoy_summon_skytalon : public SpellScriptLoader
{
public:
@@ -1732,19 +1731,16 @@ class spell_q13291_q13292_q13239_q13261_armored_decoy_summon_skytalon : public S
{
PrepareSpellScript(spell_q13291_q13292_q13239_q13261_armored_decoy_summon_skytalon_SpellScript);
- void ChangeSummonPos(SpellEffIndex /*effIndex*/)
+ void SetDest(SpellDestination& dest)
{
// Adjust effect summon position
- WorldLocation summonPos = *GetExplTargetDest();
- Position offset = { 0.0f, 0.0f, 20.0f, 0.0f };
- summonPos.RelocateOffset(offset);
- SetExplTargetDest(summonPos);
- GetHitDest()->RelocateOffset(offset);
+ Position const offset = { 0.0f, 0.0f, 20.0f, 0.0f };
+ dest.RelocateOffset(offset);
}
void Register() OVERRIDE
{
- OnEffectHit += SpellEffectFn(spell_q13291_q13292_q13239_q13261_armored_decoy_summon_skytalon_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON);
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_q13291_q13292_q13239_q13261_armored_decoy_summon_skytalon_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER_BACK);
}
};
@@ -1754,6 +1750,7 @@ class spell_q13291_q13292_q13239_q13261_armored_decoy_summon_skytalon : public S
}
};
+// 12601 - Second Chances: Summon Landgren's Soul Moveto Target Bunny
class spell_q12847_summon_soul_moveto_bunny : public SpellScriptLoader
{
public:
@@ -1763,19 +1760,16 @@ class spell_q12847_summon_soul_moveto_bunny : public SpellScriptLoader
{
PrepareSpellScript(spell_q12847_summon_soul_moveto_bunny_SpellScript);
- void ChangeSummonPos(SpellEffIndex /*effIndex*/)
+ void SetDest(SpellDestination& dest)
{
// Adjust effect summon position
- WorldLocation summonPos = *GetExplTargetDest();
- Position offset = { 0.0f, 0.0f, 2.5f, 0.0f };
- summonPos.RelocateOffset(offset);
- SetExplTargetDest(summonPos);
- GetHitDest()->RelocateOffset(offset);
+ Position const offset = { 0.0f, 0.0f, 2.5f, 0.0f };
+ dest.RelocateOffset(offset);
}
void Register() OVERRIDE
{
- OnEffectHit += SpellEffectFn(spell_q12847_summon_soul_moveto_bunny_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON);
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_q12847_summon_soul_moveto_bunny_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER);
}
};
@@ -2012,19 +2006,19 @@ class spell_q12308_escape_from_silverbrook_summon_worgen : public SpellScriptLoa
{
PrepareSpellScript(spell_q12308_escape_from_silverbrook_summon_worgen_SpellScript);
- void ModDest(SpellEffIndex effIndex)
+ void ModDest(SpellDestination& dest)
{
- float dist = GetSpellInfo()->Effects[effIndex].CalcRadius(GetCaster());
- float angle = (urand(0, 1) ? -1 : 1) * (frand(0.75f, 1.0f) * M_PI);
+ float dist = GetSpellInfo()->Effects[EFFECT_0].CalcRadius(GetCaster());
+ float angle = frand(0.75f, 1.25f) * M_PI;
Position pos;
GetCaster()->GetNearPosition(pos, dist, angle);
- GetHitDest()->Relocate(&pos);
+ dest.Relocate(pos);
}
void Register() OVERRIDE
{
- OnEffectHit += SpellEffectFn(spell_q12308_escape_from_silverbrook_summon_worgen_SpellScript::ModDest, EFFECT_0, SPELL_EFFECT_SUMMON);
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_q12308_escape_from_silverbrook_summon_worgen_SpellScript::ModDest, EFFECT_0, TARGET_DEST_CASTER_SUMMON);
}
};
@@ -2241,6 +2235,47 @@ class spell_q12919_gymers_throw : public SpellScriptLoader
}
};
+enum Quest_The_Hunter_And_The_Prince
+{
+ SPELL_ILLIDAN_KILL_CREDIT = 61748
+};
+
+class spell_q13400_illidan_kill_master : public SpellScriptLoader
+{
+ public:
+ spell_q13400_illidan_kill_master() : SpellScriptLoader("spell_q13400_illidan_kill_master") { }
+
+ class spell_q13400_illidan_kill_master_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q13400_illidan_kill_master_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_ILLIDAN_KILL_CREDIT))
+ return false;
+ return true;
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ if (caster->IsVehicle())
+ if (Unit* passenger = caster->GetVehicleKit()->GetPassenger(0))
+ passenger->CastSpell(passenger, SPELL_ILLIDAN_KILL_CREDIT, true);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_q13400_illidan_kill_master_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_q13400_illidan_kill_master_SpellScript();
+ }
+};
+
void AddSC_quest_spell_scripts()
{
new spell_q55_sacred_cleansing();
@@ -2295,4 +2330,5 @@ void AddSC_quest_spell_scripts()
new spell_q12619_emblazon_runeblade_effect();
new spell_q12919_gymers_grab();
new spell_q12919_gymers_throw();
+ new spell_q13400_illidan_kill_master();
}
diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp
index 4670117f0ea..d1d43684f3e 100644
--- a/src/server/scripts/Spells/spell_rogue.cpp
+++ b/src/server/scripts/Spells/spell_rogue.cpp
@@ -25,16 +25,21 @@
#include "ScriptMgr.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
+#include "Containers.h"
enum RogueSpells
{
- SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK = 22482,
- SPELL_ROGUE_CHEAT_DEATH_COOLDOWN = 31231,
- SPELL_ROGUE_GLYPH_OF_PREPARATION = 56819,
- SPELL_ROGUE_PREY_ON_THE_WEAK = 58670,
- SPELL_ROGUE_SHIV_TRIGGERED = 5940,
- SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST = 57933,
- SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC = 59628,
+ SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK = 22482,
+ SPELL_ROGUE_CHEAT_DEATH_COOLDOWN = 31231,
+ SPELL_ROGUE_GLYPH_OF_PREPARATION = 56819,
+ SPELL_ROGUE_KILLING_SPREE = 51690,
+ SPELL_ROGUE_KILLING_SPREE_TELEPORT = 57840,
+ SPELL_ROGUE_KILLING_SPREE_WEAPON_DMG = 57841,
+ SPELL_ROGUE_KILLING_SPREE_DMG_BUFF = 61851,
+ SPELL_ROGUE_PREY_ON_THE_WEAK = 58670,
+ SPELL_ROGUE_SHIV_TRIGGERED = 5940,
+ SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST = 57933,
+ SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC = 59628,
};
// 13877, 33735, (check 51211, 65956) - Blade Flurry
@@ -249,6 +254,106 @@ class spell_rog_deadly_poison : public SpellScriptLoader
}
};
+// 51690 - Killing Spree
+#define KillingSpreeScriptName "spell_rog_killing_spree"
+class spell_rog_killing_spree : public SpellScriptLoader
+{
+ public:
+ spell_rog_killing_spree() : SpellScriptLoader(KillingSpreeScriptName) { }
+
+ class spell_rog_killing_spree_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_rog_killing_spree_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ if (targets.empty() || GetCaster()->GetVehicleBase())
+ FinishCast(SPELL_FAILED_OUT_OF_RANGE);
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ if (Aura* aura = GetCaster()->GetAura(SPELL_ROGUE_KILLING_SPREE))
+ {
+ if (spell_rog_killing_spree_AuraScript* script = dynamic_cast<spell_rog_killing_spree_AuraScript*>(aura->GetScriptByName(KillingSpreeScriptName)))
+ script->AddTarget(GetHitUnit());
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rog_killing_spree_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY);
+ OnEffectHitTarget += SpellEffectFn(spell_rog_killing_spree_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_rog_killing_spree_SpellScript();
+ }
+
+ class spell_rog_killing_spree_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_rog_killing_spree_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_KILLING_SPREE_TELEPORT)
+ || !sSpellMgr->GetSpellInfo(SPELL_ROGUE_KILLING_SPREE_WEAPON_DMG)
+ || !sSpellMgr->GetSpellInfo(SPELL_ROGUE_KILLING_SPREE_DMG_BUFF))
+ return false;
+ return true;
+ }
+
+ void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->CastSpell(GetTarget(), SPELL_ROGUE_KILLING_SPREE_DMG_BUFF, true);
+ }
+
+ void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
+ {
+ while (!_targets.empty())
+ {
+ uint64 guid = Trinity::Containers::SelectRandomContainerElement(_targets);
+ if (Unit* target = ObjectAccessor::GetUnit(*GetTarget(), guid))
+ {
+ GetTarget()->CastSpell(target, SPELL_ROGUE_KILLING_SPREE_TELEPORT, true);
+ GetTarget()->CastSpell(target, SPELL_ROGUE_KILLING_SPREE_WEAPON_DMG, true);
+ break;
+ }
+ else
+ _targets.remove(guid);
+ }
+ }
+
+ void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->RemoveAurasDueToSpell(SPELL_ROGUE_KILLING_SPREE_DMG_BUFF);
+ }
+
+ void Register() OVERRIDE
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_rog_killing_spree_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_rog_killing_spree_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_rog_killing_spree_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+
+ public:
+ void AddTarget(Unit* target)
+ {
+ _targets.push_back(target->GetGUID());
+ }
+
+ private:
+ std::list<uint64> _targets;
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_rog_killing_spree_AuraScript();
+ }
+};
+
// -31130 - Nerves of Steel
class spell_rog_nerves_of_steel : public SpellScriptLoader
{
@@ -594,6 +699,7 @@ void AddSC_rogue_spell_scripts()
new spell_rog_blade_flurry();
new spell_rog_cheat_death();
new spell_rog_deadly_poison();
+ new spell_rog_killing_spree();
new spell_rog_nerves_of_steel();
new spell_rog_preparation();
new spell_rog_prey_on_the_weak();
diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp
index c8fa5b3f1fe..707c8a0985f 100644
--- a/src/server/scripts/Spells/spell_shaman.cpp
+++ b/src/server/scripts/Spells/spell_shaman.cpp
@@ -79,6 +79,18 @@ class spell_sha_ancestral_awakening_proc : public SpellScriptLoader
return true;
}
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ if (targets.size() < 2)
+ return;
+
+ targets.sort(Trinity::HealthPctOrderPred());
+
+ WorldObject* target = targets.front();
+ targets.clear();
+ targets.push_back(target);
+ }
+
void HandleDummy(SpellEffIndex /*effIndex*/)
{
int32 damage = GetEffectValue();
@@ -88,6 +100,7 @@ class spell_sha_ancestral_awakening_proc : public SpellScriptLoader
void Register() OVERRIDE
{
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_ancestral_awakening_proc_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID);
OnEffectHitTarget += SpellEffectFn(spell_sha_ancestral_awakening_proc_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp
index cafe510cc4f..5a655a92996 100644
--- a/src/server/scripts/Spells/spell_warrior.cpp
+++ b/src/server/scripts/Spells/spell_warrior.cpp
@@ -42,7 +42,9 @@ enum WarriorSpells
SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_BUFF = 65156,
SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_TALENT = 64976,
SPELL_WARRIOR_LAST_STAND_TRIGGERED = 12976,
+ SPELL_WARRIOR_RETALIATION_DAMAGE = 22858,
SPELL_WARRIOR_SLAM = 50783,
+ SPELL_WARRIOR_SUNDER_ARMOR = 58567,
SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK = 26654,
SPELL_WARRIOR_TAUNT = 355,
SPELL_WARRIOR_UNRELENTING_ASSAULT_RANK_1 = 46859,
@@ -53,6 +55,11 @@ enum WarriorSpells
SPELL_WARRIOR_VIGILANCE_REDIRECT_THREAT = 59665
};
+enum WarriorSpellIcons
+{
+ WARRIOR_ICON_ID_SUDDEN_DEATH = 1989
+};
+
enum MiscSpells
{
SPELL_PALADIN_BLESSING_OF_SANCTUARY = 20911,
@@ -61,11 +68,6 @@ enum MiscSpells
SPELL_GEN_DAMAGE_REDUCTION_AURA = 68066,
};
-enum WarriorSpellIcons
-{
- WARRIOR_ICON_ID_SUDDEN_DEATH = 1989
-};
-
// 23881 - Bloodthirst
class spell_warr_bloodthirst : public SpellScriptLoader
{
@@ -313,7 +315,7 @@ class spell_warr_execute : public SpellScriptLoader
return true;
}
- void HandleDummy(SpellEffIndex effIndex)
+ void HandleEffect(SpellEffIndex effIndex)
{
Unit* caster = GetCaster();
if (Unit* target = GetHitUnit())
@@ -342,7 +344,7 @@ class spell_warr_execute : public SpellScriptLoader
void Register() OVERRIDE
{
- OnEffectHitTarget += SpellEffectFn(spell_warr_execute_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ OnEffectHitTarget += SpellEffectFn(spell_warr_execute_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
@@ -352,6 +354,42 @@ class spell_warr_execute : public SpellScriptLoader
}
};
+// 58387 - Glyph of Sunder Armor
+class spell_warr_glyph_of_sunder_armor : public SpellScriptLoader
+{
+ public:
+ spell_warr_glyph_of_sunder_armor() : SpellScriptLoader("spell_warr_glyph_of_sunder_armor") { }
+
+ class spell_warr_glyph_of_sunder_armor_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warr_glyph_of_sunder_armor_AuraScript);
+
+ void HandleEffectCalcSpellMod(AuraEffect const* aurEff, SpellModifier*& spellMod)
+ {
+ if (!spellMod)
+ {
+ spellMod = new SpellModifier(aurEff->GetBase());
+ spellMod->op = SpellModOp(aurEff->GetMiscValue());
+ spellMod->type = SPELLMOD_FLAT;
+ spellMod->spellId = GetId();
+ spellMod->mask = GetSpellInfo()->Effects[aurEff->GetEffIndex()].SpellClassMask;
+ }
+
+ spellMod->value = aurEff->GetAmount();
+ }
+
+ void Register() OVERRIDE
+ {
+ DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_warr_glyph_of_sunder_armor_AuraScript::HandleEffectCalcSpellMod, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_warr_glyph_of_sunder_armor_AuraScript();
+ }
+};
+
// 59725 - Improved Spell Reflection
class spell_warr_improved_spell_reflection : public SpellScriptLoader
{
@@ -528,6 +566,48 @@ class spell_warr_rend : public SpellScriptLoader
}
};
+// 20230 - Retaliation
+class spell_warr_retaliation : public SpellScriptLoader
+{
+ public:
+ spell_warr_retaliation() : SpellScriptLoader("spell_warr_retaliation") { }
+
+ class spell_warr_retaliation_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warr_retaliation_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_RETALIATION_DAMAGE))
+ return false;
+ return true;
+ }
+
+ bool CheckProc(ProcEventInfo& eventInfo)
+ {
+ // check attack comes not from behind and warrior is not stunned
+ return GetTarget()->isInFront(eventInfo.GetActor(), M_PI) && !GetTarget()->HasUnitState(UNIT_STATE_STUNNED);
+ }
+
+ void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_WARRIOR_RETALIATION_DAMAGE, true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
+ {
+ DoCheckProc += AuraCheckProcFn(spell_warr_retaliation_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_warr_retaliation_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_warr_retaliation_AuraScript();
+ }
+};
+
// 64380, 65941 - Shattering Throw
class spell_warr_shattering_throw : public SpellScriptLoader
{
@@ -739,7 +819,7 @@ class spell_warr_vigilance : public SpellScriptLoader
}
};
-// 50725 Vigilance
+// 50725 - Vigilance
class spell_warr_vigilance_trigger : public SpellScriptLoader
{
public:
@@ -779,11 +859,13 @@ void AddSC_warrior_spell_scripts()
new spell_warr_damage_shield();
new spell_warr_deep_wounds();
new spell_warr_execute();
+ new spell_warr_glyph_of_sunder_armor();
new spell_warr_improved_spell_reflection();
new spell_warr_intimidating_shout();
new spell_warr_last_stand();
new spell_warr_overpower();
new spell_warr_rend();
+ new spell_warr_retaliation();
new spell_warr_shattering_throw();
new spell_warr_slam();
new spell_warr_sweeping_strikes();
diff --git a/src/server/scripts/World/npc_taxi.cpp b/src/server/scripts/World/npc_taxi.cpp
index 730523c85f4..31617e0ef71 100644
--- a/src/server/scripts/World/npc_taxi.cpp
+++ b/src/server/scripts/World/npc_taxi.cpp
@@ -162,7 +162,6 @@ public:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CRIMSONWING, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+25);
break;
case 17209:
- player->SetTaxiCheater(true);
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_WILLIAMKEILAR1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 28);
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_WILLIAMKEILAR2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 29);
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_WILLIAMKEILAR3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 30);
diff --git a/src/server/shared/CompilerDefs.h b/src/server/shared/CompilerDefs.h
index 71b20a4d175..8a557328af4 100644
--- a/src/server/shared/CompilerDefs.h
+++ b/src/server/shared/CompilerDefs.h
@@ -57,6 +57,8 @@
#if defined(__cplusplus) && __cplusplus == 201103L
# define COMPILER_HAS_CPP11_SUPPORT 1
+#elif _MSC_VER >= 1700
+# define COMPILER_HAS_CPP11_SUPPORT 1
#else
# define COMPILER_HAS_CPP11_SUPPORT 0
#endif
diff --git a/src/server/shared/Cryptography/OpenSSLCrypto.cpp b/src/server/shared/Cryptography/OpenSSLCrypto.cpp
index 10ea595640a..bd72459e9df 100644
--- a/src/server/shared/Cryptography/OpenSSLCrypto.cpp
+++ b/src/server/shared/Cryptography/OpenSSLCrypto.cpp
@@ -33,7 +33,12 @@ static void lockingCallback(int mode, int type, const char* /*file*/, int /*line
static void threadIdCallback(CRYPTO_THREADID * id)
{
+/// ACE_thread_t turns out to be a struct under Mac OS.
+#ifndef __APPLE__
CRYPTO_THREADID_set_numeric(id, ACE_Thread::self());
+#else
+ CRYPTO_THREADID_set_pointer(id, ACE_Thread::self());
+#endif
}
void OpenSSLCrypto::threadsSetup()
diff --git a/src/server/shared/Debugging/WheatyExceptionReport.cpp b/src/server/shared/Debugging/WheatyExceptionReport.cpp
index f4da4093dfa..e838c42d32d 100644
--- a/src/server/shared/Debugging/WheatyExceptionReport.cpp
+++ b/src/server/shared/Debugging/WheatyExceptionReport.cpp
@@ -51,6 +51,7 @@ LPTOP_LEVEL_EXCEPTION_FILTER WheatyExceptionReport::m_previousFilter;
HANDLE WheatyExceptionReport::m_hReportFile;
HANDLE WheatyExceptionReport::m_hDumpFile;
HANDLE WheatyExceptionReport::m_hProcess;
+SymbolPairs WheatyExceptionReport::symbols;
// Declare global instance of class
WheatyExceptionReport g_WheatyExceptionReport;
@@ -62,6 +63,13 @@ WheatyExceptionReport::WheatyExceptionReport() // Constructor
// Install the unhandled exception filter function
m_previousFilter = SetUnhandledExceptionFilter(WheatyUnhandledExceptionFilter);
m_hProcess = GetCurrentProcess();
+ if (!IsDebuggerPresent())
+ {
+ _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
+ _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
+ _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
+ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
+ }
}
//============
@@ -71,6 +79,7 @@ WheatyExceptionReport::~WheatyExceptionReport()
{
if (m_previousFilter)
SetUnhandledExceptionFilter(m_previousFilter);
+ ClearSymbols();
}
//===========================================================
@@ -348,7 +357,7 @@ void WheatyExceptionReport::PrintSystemInfo()
}
//===========================================================================
-void WheatyExceptionReport::printTracesForAllThreads()
+void WheatyExceptionReport::printTracesForAllThreads(bool bWriteVariables)
{
THREADENTRY32 te32;
@@ -384,7 +393,7 @@ void WheatyExceptionReport::printTracesForAllThreads()
if (threadHandle)
{
if (GetThreadContext(threadHandle, &context))
- WriteStackDetails(&context, false, threadHandle);
+ WriteStackDetails(&context, bWriteVariables, threadHandle);
CloseHandle(threadHandle);
}
}
@@ -480,7 +489,7 @@ PEXCEPTION_POINTERS pExceptionInfo)
CONTEXT trashableContext = *pCtx;
WriteStackDetails(&trashableContext, false, NULL);
- printTracesForAllThreads();
+ printTracesForAllThreads(false);
// #ifdef _M_IX86 // X86 Only!
@@ -489,13 +498,14 @@ PEXCEPTION_POINTERS pExceptionInfo)
trashableContext = *pCtx;
WriteStackDetails(&trashableContext, true, NULL);
+ printTracesForAllThreads(true);
- _tprintf(_T("========================\r\n"));
+ /*_tprintf(_T("========================\r\n"));
_tprintf(_T("Global Variables\r\n"));
SymEnumSymbols(GetCurrentProcess(),
(UINT_PTR)GetModuleHandle(szFaultingModule),
- 0, EnumerateSymbolsCallback, 0);
+ 0, EnumerateSymbolsCallback, 0);*/
// #endif // X86 Only!
SymCleanup(GetCurrentProcess());
@@ -566,6 +576,9 @@ PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD_PTR& offset)
DWORD_PTR hMod = (DWORD_PTR)mbi.AllocationBase;
+ if (!hMod)
+ return FALSE;
+
if (!GetModuleFileName((HMODULE)hMod, szModule, len))
return FALSE;
@@ -708,7 +721,7 @@ bool bWriteVariables, HANDLE pThreadHandle)
}
// Get the source line for this stack frame entry
- IMAGEHLP_LINE64 lineInfo = { sizeof(IMAGEHLP_LINE) };
+ IMAGEHLP_LINE64 lineInfo = { sizeof(IMAGEHLP_LINE64) };
DWORD dwLineDisplacement;
if (SymGetLineFromAddr64(m_hProcess, sf.AddrPC.Offset,
&dwLineDisplacement, &lineInfo))
@@ -746,15 +759,16 @@ ULONG /*SymbolSize*/,
PVOID UserContext)
{
- char szBuffer[2048];
+ char szBuffer[1024 * 64];
__try
{
- if (FormatSymbolValue(pSymInfo, (STACKFRAME*)UserContext,
+ ClearSymbols();
+ if (FormatSymbolValue(pSymInfo, (STACKFRAME64*)UserContext,
szBuffer, sizeof(szBuffer)))
_tprintf(_T("\t%s\r\n"), szBuffer);
}
- __except(1)
+ __except (EXCEPTION_EXECUTE_HANDLER)
{
_tprintf(_T("punting on symbol %s\r\n"), pSymInfo->Name);
}
@@ -769,7 +783,7 @@ PVOID UserContext)
//////////////////////////////////////////////////////////////////////////////
bool WheatyExceptionReport::FormatSymbolValue(
PSYMBOL_INFO pSym,
-STACKFRAME * sf,
+STACKFRAME64 * sf,
char * pszBuffer,
unsigned /*cbBuffer*/)
{
@@ -782,7 +796,7 @@ unsigned /*cbBuffer*/)
pszCurrBuffer += sprintf(pszCurrBuffer, "Local ");
// If it's a function, don't do anything.
- if (pSym->Tag == 5) // SymTagFunction from CVCONST.H from the DIA SDK
+ if (pSym->Tag == SymTagFunction) // SymTagFunction from CVCONST.H from the DIA SDK
return false;
DWORD_PTR pVariable = 0; // Will point to the variable's data in memory
@@ -791,7 +805,11 @@ unsigned /*cbBuffer*/)
{
// if (pSym->Register == 8) // EBP is the value 8 (in DBGHELP 5.1)
{ // This may change!!!
+#ifdef _M_IX86
pVariable = sf->AddrFrame.Offset;
+#elif _M_X64
+ pVariable = sf->AddrStack.Offset;
+#endif
pVariable += (DWORD_PTR)pSym->Address;
}
// else
@@ -810,7 +828,7 @@ unsigned /*cbBuffer*/)
// will return true.
bool bHandled;
pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, pSym->ModBase, pSym->TypeIndex,
- 0, pVariable, bHandled, pSym->Name);
+ 0, pVariable, bHandled, pSym->Name, "");
if (!bHandled)
{
@@ -842,10 +860,18 @@ DWORD dwTypeIndex,
unsigned nestingLevel,
DWORD_PTR offset,
bool & bHandled,
-char* /*Name*/)
+char* Name,
+char* suffix)
{
bHandled = false;
+ if (!StoreSymbol(dwTypeIndex, offset))
+ return pszCurrBuffer;
+
+ DWORD typeTag;
+ if (!SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_SYMTAG, &typeTag))
+ return pszCurrBuffer;
+
// Get the name of the symbol. This will either be a Type name (if a UDT),
// or the structure member name.
WCHAR * pwszTypeName;
@@ -856,10 +882,82 @@ char* /*Name*/)
LocalFree(pwszTypeName);
}
+ if (strlen(suffix) > 0)
+ pszCurrBuffer += sprintf(pszCurrBuffer, "%s", suffix);
+
+ DWORD innerTypeID;
+ switch (typeTag)
+ {
+ case SymTagPointerType:
+ if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_TYPEID, &innerTypeID))
+ {
+#define MAX_NESTING_LEVEL 5
+ if (nestingLevel >= MAX_NESTING_LEVEL)
+ break;
+
+ pszCurrBuffer += sprintf(pszCurrBuffer, " %s", Name);
+ BOOL isReference;
+ SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_IS_REFERENCE, &isReference);
+
+ char addressStr[40];
+ memset(addressStr, 0, sizeof(addressStr));
+
+ if (isReference)
+ addressStr[0] = '&';
+ else
+ addressStr[0] = '*';
+
+ DWORD_PTR address = *(PDWORD_PTR)offset;
+ if (address == NULL)
+ {
+ pwszTypeName;
+ if (SymGetTypeInfo(m_hProcess, modBase, innerTypeID, TI_GET_SYMNAME,
+ &pwszTypeName))
+ {
+ pszCurrBuffer += sprintf(pszCurrBuffer, " %ls", pwszTypeName);
+ LocalFree(pwszTypeName);
+ }
+
+ pszCurrBuffer += sprintf(pszCurrBuffer, "%s = NULL\r\n", addressStr);
+
+ bHandled = true;
+ return pszCurrBuffer;
+ }
+ else
+ {
+ FormatOutputValue(&addressStr[1], btVoid, sizeof(PVOID), (PVOID)offset);
+ pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID, nestingLevel + 1,
+ address, bHandled, "", addressStr);
+ }
+ }
+ break;
+ case SymTagData:
+ if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_TYPEID, &innerTypeID))
+ {
+ DWORD innerTypeTag;
+ if (!SymGetTypeInfo(m_hProcess, modBase, innerTypeID, TI_GET_SYMTAG, &innerTypeTag))
+ break;
+
+ if (innerTypeTag == SymTagPointerType)
+ {
+ pszCurrBuffer += sprintf(pszCurrBuffer, " %s", Name);
+
+ pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID, nestingLevel + 1,
+ offset, bHandled, "", "");
+ }
+ }
+ break;
+ case SymTagBaseType:
+ break;
+ case SymTagEnum:
+ return pszCurrBuffer;
+ default:
+ break;
+ }
+
// Determine how many children this type has.
DWORD dwChildrenCount = 0;
- SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_CHILDRENCOUNT,
- &dwChildrenCount);
+ SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_CHILDRENCOUNT, &dwChildrenCount);
if (!dwChildrenCount) // If no children, we're done
return pszCurrBuffer;
@@ -869,7 +967,7 @@ char* /*Name*/)
// TI_FINDCHILDREN_PARAMS struct has. Use derivation to accomplish this.
struct FINDCHILDREN : TI_FINDCHILDREN_PARAMS
{
- ULONG MoreChildIds[1024];
+ ULONG MoreChildIds[1024*2];
FINDCHILDREN(){Count = sizeof(MoreChildIds) / sizeof(MoreChildIds[0]);}
} children;
@@ -889,6 +987,12 @@ char* /*Name*/)
// Iterate through each of the children
for (unsigned i = 0; i < dwChildrenCount; i++)
{
+ DWORD symTag;
+ SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i], TI_GET_SYMTAG, &symTag);
+
+ if (symTag == SymTagFunction || symTag == SymTagTypedef)
+ continue;
+
// Add appropriate indentation level (since this routine is recursive)
for (unsigned j = 0; j <= nestingLevel+1; j++)
pszCurrBuffer += sprintf(pszCurrBuffer, "\t");
@@ -898,18 +1002,21 @@ char* /*Name*/)
BasicType basicType = GetBasicType(children.ChildId[i], modBase);
pszCurrBuffer += sprintf(pszCurrBuffer, rgBaseType[basicType]);
+ // Get the offset of the child member, relative to its parent
+ DWORD dwMemberOffset;
+ SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i],
+ TI_GET_OFFSET, &dwMemberOffset);
+
+ // Calculate the address of the member
+ DWORD_PTR dwFinalOffset = offset + dwMemberOffset;
+
pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase,
children.ChildId[i], nestingLevel+1,
- offset, bHandled2, ""/*Name */);
+ dwFinalOffset, bHandled2, ""/*Name */, "");
// If the child wasn't a UDT, format it appropriately
if (!bHandled2)
{
- // Get the offset of the child member, relative to its parent
- DWORD dwMemberOffset;
- SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i],
- TI_GET_OFFSET, &dwMemberOffset);
-
// Get the real "TypeId" of the child. We need this for the
// SymGetTypeInfo(TI_GET_TYPEID) call below.
DWORD typeId;
@@ -920,9 +1027,6 @@ char* /*Name*/)
ULONG64 length;
SymGetTypeInfo(m_hProcess, modBase, typeId, TI_GET_LENGTH, &length);
- // Calculate the address of the member
- DWORD_PTR dwFinalOffset = offset + dwMemberOffset;
-
// BasicType basicType = GetBasicType(children.ChildId[i], modBase);
//
// pszCurrBuffer += sprintf(pszCurrBuffer, rgBaseType[basicType]);
@@ -946,41 +1050,60 @@ BasicType basicType,
DWORD64 length,
PVOID pAddress)
{
- // Format appropriately (assuming it's a 1, 2, or 4 bytes (!!!)
- if (length == 1)
- pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PBYTE)pAddress);
- else if (length == 2)
- pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PWORD)pAddress);
- else if (length == 4)
+ __try
{
- if (basicType == btFloat)
+ // Format appropriately (assuming it's a 1, 2, or 4 bytes (!!!)
+ if (length == 1)
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PBYTE)pAddress);
+ else if (length == 2)
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PWORD)pAddress);
+ else if (length == 4)
{
- pszCurrBuffer += sprintf(pszCurrBuffer, " = %f", *(PFLOAT)pAddress);
+ if (basicType == btFloat)
+ {
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = %f", *(PFLOAT)pAddress);
+ }
+ else if (basicType == btChar)
+ {
+ if (!IsBadStringPtr(*(PSTR*)pAddress, 32))
+ {
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = \"%.31s\"",
+ *(PSTR*)pAddress);
+ }
+ else
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = %X",
+ *(PDWORD)pAddress);
+ }
+ else
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PDWORD)pAddress);
}
- else if (basicType == btChar)
+ else if (length == 8)
{
- if (!IsBadStringPtr(*(PSTR*)pAddress, 32))
+ if (basicType == btFloat)
{
- pszCurrBuffer += sprintf(pszCurrBuffer, " = \"%.31s\"",
- *(PSTR*)pAddress);
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = %lf",
+ *(double *)pAddress);
}
else
- pszCurrBuffer += sprintf(pszCurrBuffer, " = %X",
- *(PDWORD)pAddress);
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = %I64X",
+ *(DWORD64*)pAddress);
}
else
- pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PDWORD)pAddress);
- }
- else if (length == 8)
- {
- if (basicType == btFloat)
{
- pszCurrBuffer += sprintf(pszCurrBuffer, " = %lf",
- *(double *)pAddress);
+#if _WIN64
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = %I64X", (DWORD64*)pAddress);
+#else
+ pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", (PDWORD)pAddress);
+#endif
}
- else
- pszCurrBuffer += sprintf(pszCurrBuffer, " = %I64X",
- *(DWORD64*)pAddress);
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {
+#if _WIN64
+ pszCurrBuffer += sprintf(pszCurrBuffer, " <Unable to read memory> = %I64X", (DWORD64*)pAddress);
+#else
+ pszCurrBuffer += sprintf(pszCurrBuffer, " <Unable to read memory> = %X", (PDWORD)pAddress);
+#endif
}
return pszCurrBuffer;
@@ -1017,7 +1140,7 @@ WheatyExceptionReport::GetBasicType(DWORD typeIndex, DWORD64 modBase)
//============================================================================
int __cdecl WheatyExceptionReport::_tprintf(const TCHAR * format, ...)
{
- TCHAR szBuff[1024];
+ TCHAR szBuff[1024 * 64];
int retValue;
DWORD cbWritten;
va_list argptr;
@@ -1031,4 +1154,14 @@ int __cdecl WheatyExceptionReport::_tprintf(const TCHAR * format, ...)
return retValue;
}
+bool WheatyExceptionReport::StoreSymbol(DWORD type, DWORD_PTR offset)
+{
+ return symbols.insert(SymbolPair(type, offset)).second;
+}
+
+void WheatyExceptionReport::ClearSymbols()
+{
+ symbols.clear();
+}
+
#endif // _WIN32
diff --git a/src/server/shared/Debugging/WheatyExceptionReport.h b/src/server/shared/Debugging/WheatyExceptionReport.h
index 582f1f157b8..74330370509 100644
--- a/src/server/shared/Debugging/WheatyExceptionReport.h
+++ b/src/server/shared/Debugging/WheatyExceptionReport.h
@@ -4,7 +4,7 @@
#if PLATFORM == PLATFORM_WINDOWS && !defined(__MINGW32__)
#include <dbghelp.h>
-
+#include <set>
#if _MSC_VER < 1400
# define countof(array) (sizeof(array) / sizeof(array[0]))
#else
@@ -70,6 +70,25 @@ const char* const rgBaseType[] =
" HRESULT " // btHresult = 31
};
+struct SymbolPair
+{
+ SymbolPair(DWORD type, DWORD_PTR offset)
+ {
+ _type = type;
+ _offset = offset;
+ }
+
+ bool operator<(const SymbolPair& other) const
+ {
+ return _offset < other._offset ||
+ (_offset == other._offset && _type < other._type);
+ }
+
+ DWORD _type;
+ DWORD_PTR _offset;
+};
+typedef std::set<SymbolPair> SymbolPairs;
+
class WheatyExceptionReport
{
public:
@@ -81,7 +100,7 @@ class WheatyExceptionReport
static LONG WINAPI WheatyUnhandledExceptionFilter(
PEXCEPTION_POINTERS pExceptionInfo);
- static void printTracesForAllThreads();
+ static void printTracesForAllThreads(bool);
private:
// where report info is extracted and generated
static void GenerateExceptionReport(PEXCEPTION_POINTERS pExceptionInfo);
@@ -98,9 +117,9 @@ class WheatyExceptionReport
static BOOL CALLBACK EnumerateSymbolsCallback(PSYMBOL_INFO, ULONG, PVOID);
- static bool FormatSymbolValue(PSYMBOL_INFO, STACKFRAME *, char * pszBuffer, unsigned cbBuffer);
+ static bool FormatSymbolValue(PSYMBOL_INFO, STACKFRAME64 *, char * pszBuffer, unsigned cbBuffer);
- static char * DumpTypeIndex(char *, DWORD64, DWORD, unsigned, DWORD_PTR, bool &, char*);
+ static char * DumpTypeIndex(char *, DWORD64, DWORD, unsigned, DWORD_PTR, bool &, char*, char*);
static char * FormatOutputValue(char * pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress);
@@ -108,6 +127,9 @@ class WheatyExceptionReport
static int __cdecl _tprintf(const TCHAR * format, ...);
+ static bool StoreSymbol(DWORD type , DWORD_PTR offset);
+ static void ClearSymbols();
+
// Variables used by the class
static TCHAR m_szLogFileName[MAX_PATH];
static TCHAR m_szDumpFileName[MAX_PATH];
@@ -115,6 +137,7 @@ class WheatyExceptionReport
static HANDLE m_hReportFile;
static HANDLE m_hDumpFile;
static HANDLE m_hProcess;
+ static SymbolPairs symbols;
};
extern WheatyExceptionReport g_WheatyExceptionReport; // global instance of class
diff --git a/src/server/shared/Logging/AppenderFile.cpp b/src/server/shared/Logging/AppenderFile.cpp
index b9c2fd7339d..a88188266e2 100644
--- a/src/server/shared/Logging/AppenderFile.cpp
+++ b/src/server/shared/Logging/AppenderFile.cpp
@@ -33,7 +33,8 @@ AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, co
dynamicName = std::string::npos != filename.find("%s");
backup = (_flags & APPENDER_FLAGS_MAKE_FILE_BACKUP) != 0;
- logfile = !dynamicName ? OpenFile(_filename, _mode, mode == "w" && backup) : NULL;
+ if (!dynamicName)
+ logfile = OpenFile(_filename, _mode, mode == "w" && backup);
}
AppenderFile::~AppenderFile()
@@ -49,7 +50,15 @@ void AppenderFile::_write(LogMessage const& message)
{
char namebuf[TRINITY_PATH_MAX];
snprintf(namebuf, TRINITY_PATH_MAX, filename.c_str(), message.param1.c_str());
- logfile = OpenFile(namebuf, mode, backup || exceedMaxSize);
+ // always use "a" with dynamic name otherwise it could delete the log we wrote in last _write() call
+ FILE* file = OpenFile(namebuf, "a", backup || exceedMaxSize);
+ if (!file)
+ return;
+ fprintf(file, "%s%s", message.prefix.c_str(), message.text.c_str());
+ fflush(file);
+ fileSize += uint64(message.Size());
+ fclose(file);
+ return;
}
else if (exceedMaxSize)
logfile = OpenFile(filename, "w", true);
@@ -60,9 +69,6 @@ void AppenderFile::_write(LogMessage const& message)
fprintf(logfile, "%s%s", message.prefix.c_str(), message.text.c_str());
fflush(logfile);
fileSize += uint64(message.Size());
-
- if (dynamicName)
- CloseFile();
}
FILE* AppenderFile::OpenFile(std::string const &filename, std::string const &mode, bool backup)
diff --git a/src/server/shared/Utilities/ByteConverter.h b/src/server/shared/Utilities/ByteConverter.h
index bf1342a10e4..8eebb05bb13 100644
--- a/src/server/shared/Utilities/ByteConverter.h
+++ b/src/server/shared/Utilities/ByteConverter.h
@@ -47,9 +47,13 @@ namespace ByteConverter
#if TRINITY_ENDIAN == TRINITY_BIGENDIAN
template<typename T> inline void EndianConvert(T& val) { ByteConverter::apply<T>(&val); }
template<typename T> inline void EndianConvertReverse(T&) { }
+template<typename T> inline void EndianConvertPtr(void* val) { ByteConverter::apply<T>(val); }
+template<typename T> inline void EndianConvertPtrReverse(void*) { }
#else
template<typename T> inline void EndianConvert(T&) { }
template<typename T> inline void EndianConvertReverse(T& val) { ByteConverter::apply<T>(&val); }
+template<typename T> inline void EndianConvertPtr(void*) { }
+template<typename T> inline void EndianConvertPtrReverse(void* val) { ByteConverter::apply<T>(val); }
#endif
template<typename T> void EndianConvert(T*); // will generate link error
diff --git a/src/server/shared/Utilities/Util.cpp b/src/server/shared/Utilities/Util.cpp
index 499ad0502b7..ffef61557fc 100644
--- a/src/server/shared/Utilities/Util.cpp
+++ b/src/server/shared/Utilities/Util.cpp
@@ -510,6 +510,9 @@ void vutf8printf(FILE* out, const char *str, va_list* ap)
wchar_t wtemp_buf[32*1024];
size_t temp_len = vsnprintf(temp_buf, 32*1024, str, *ap);
+ //vsnprintf returns -1 if the buffer is too small
+ if (temp_len == size_t(-1))
+ temp_len = 32*1024-1;
size_t wtemp_len = 32*1024-1;
Utf8toWStr(temp_buf, temp_len, wtemp_buf, wtemp_len);
diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp
index f4b2b542de6..c3075deb762 100644
--- a/src/server/worldserver/Master.cpp
+++ b/src/server/worldserver/Master.cpp
@@ -200,42 +200,44 @@ int Master::Run()
ACE_Based::Thread rarThread(new RARunnable);
+#if defined(_WIN32) || defined(__linux__)
+
///- Handle affinity for multiple processors and process priority
uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0);
bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false);
#ifdef _WIN32 // Windows
+
+ HANDLE hProcess = GetCurrentProcess();
+
+ if (affinity > 0)
{
- HANDLE hProcess = GetCurrentProcess();
-
- if (affinity > 0)
- {
- ULONG_PTR appAff;
- ULONG_PTR sysAff;
-
- if (GetProcessAffinityMask(hProcess, &appAff, &sysAff))
- {
- ULONG_PTR currentAffinity = affinity & appAff; // remove non accessible processors
-
- if (!currentAffinity)
- TC_LOG_ERROR("server.worldserver", "Processors marked in UseProcessors bitmask (hex) %x are not accessible for the worldserver. Accessible processors bitmask (hex): %x", affinity, appAff);
- else if (SetProcessAffinityMask(hProcess, currentAffinity))
- TC_LOG_INFO("server.worldserver", "Using processors (bitmask, hex): %x", currentAffinity);
- else
- TC_LOG_ERROR("server.worldserver", "Can't set used processors (hex): %x", currentAffinity);
- }
- }
-
- if (highPriority)
+ ULONG_PTR appAff;
+ ULONG_PTR sysAff;
+
+ if (GetProcessAffinityMask(hProcess, &appAff, &sysAff))
{
- if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS))
- TC_LOG_INFO("server.worldserver", "worldserver process priority class set to HIGH");
+ ULONG_PTR currentAffinity = affinity & appAff; // remove non accessible processors
+
+ if (!currentAffinity)
+ TC_LOG_ERROR("server.worldserver", "Processors marked in UseProcessors bitmask (hex) %x are not accessible for the worldserver. Accessible processors bitmask (hex): %x", affinity, appAff);
+ else if (SetProcessAffinityMask(hProcess, currentAffinity))
+ TC_LOG_INFO("server.worldserver", "Using processors (bitmask, hex): %x", currentAffinity);
else
- TC_LOG_ERROR("server.worldserver", "Can't set worldserver process priority class.");
+ TC_LOG_ERROR("server.worldserver", "Can't set used processors (hex): %x", currentAffinity);
}
}
-#elif __linux__ // Linux
-
+
+ if (highPriority)
+ {
+ if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS))
+ TC_LOG_INFO("server.worldserver", "worldserver process priority class set to HIGH");
+ else
+ TC_LOG_ERROR("server.worldserver", "Can't set worldserver process priority class.");
+ }
+
+#else // Linux
+
if (affinity > 0)
{
cpu_set_t mask;
@@ -262,7 +264,8 @@ int Master::Run()
else
TC_LOG_INFO("server.worldserver", "worldserver process priority class set to %i", getpriority(PRIO_PROCESS, 0));
}
-
+
+#endif
#endif
//Start soap serving thread
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 2a47c8f989e..1762859afae 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -1140,6 +1140,15 @@ AccountInstancesPerHour = 5
Account.PasswordChangeSecurity = 0
#
+# BirthdayTime
+# Description: Set to date of project's birth in UNIX time. By default the date when TrinityCore was started (Thu Oct 2, 2008)
+# Default: 1222964635
+#
+#
+
+BirthdayTime = 1222964635
+
+#
###################################################################################################
###################################################################################################
diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp
index 805926defa0..aa02d76fe47 100644
--- a/src/tools/mmaps_generator/MapBuilder.cpp
+++ b/src/tools/mmaps_generator/MapBuilder.cpp
@@ -340,7 +340,9 @@ namespace MMAP
/**************************************************************************/
void MapBuilder::buildMap(uint32 mapID)
{
+#ifndef __APPLE__
printf("[Thread %u] Building map %03u:\n", uint32(ACE_Thread::self()), mapID);
+#endif
std::set<uint32>* tiles = getTileList(mapID);
diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp
index b28ed84e105..d75af79f379 100644
--- a/src/tools/vmap4_extractor/vmapexport.cpp
+++ b/src/tools/vmap4_extractor/vmapexport.cpp
@@ -396,7 +396,7 @@ bool processArgv(int argc, char ** argv, const char *versionString)
{
hasInputPathParam = true;
strcpy(input_path, argv[i+1]);
- if (input_path[strlen(input_path) - 1] != '\\' || input_path[strlen(input_path) - 1] != '/')
+ if (input_path[strlen(input_path) - 1] != '\\' && input_path[strlen(input_path) - 1] != '/')
strcat(input_path, "/");
++i;
}