aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/CoreAI/GameObjectAI.h3
-rwxr-xr-xsrc/server/game/AI/CoreAI/PetAI.cpp16
-rwxr-xr-xsrc/server/game/AI/CoreAI/PetAI.h1
-rwxr-xr-xsrc/server/game/AI/EventAI/CreatureEventAIMgr.cpp21
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp5
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.h51
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp37
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp3
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h14
-rwxr-xr-xsrc/server/game/Battlegrounds/Battleground.cpp8
-rwxr-xr-xsrc/server/game/Chat/Commands/Level3.cpp34
-rwxr-xr-xsrc/server/game/DataStores/DBCEnums.h14
-rwxr-xr-xsrc/server/game/DungeonFinding/LFGMgr.cpp49
-rwxr-xr-xsrc/server/game/DungeonFinding/LFGMgr.h1
-rw-r--r--src/server/game/DungeonFinding/LFGScripts.cpp7
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.cpp10
-rwxr-xr-xsrc/server/game/Entities/Creature/TemporarySummon.h1
-rwxr-xr-xsrc/server/game/Entities/GameObject/GameObject.cpp20
-rwxr-xr-xsrc/server/game/Entities/Object/Object.h8
-rwxr-xr-xsrc/server/game/Entities/Pet/Pet.h1
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp157
-rwxr-xr-xsrc/server/game/Entities/Player/Player.h1
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp92
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h15
-rwxr-xr-xsrc/server/game/Entities/Vehicle/Vehicle.cpp13
-rwxr-xr-xsrc/server/game/Globals/ObjectMgr.cpp178
-rwxr-xr-xsrc/server/game/Globals/ObjectMgr.h38
-rwxr-xr-xsrc/server/game/Groups/Group.cpp76
-rwxr-xr-xsrc/server/game/Groups/Group.h14
-rwxr-xr-xsrc/server/game/Groups/GroupRefManager.h3
-rwxr-xr-xsrc/server/game/Groups/GroupReference.h1
-rwxr-xr-xsrc/server/game/Handlers/AuthHandler.cpp2
-rwxr-xr-xsrc/server/game/Handlers/GroupHandler.cpp22
-rwxr-xr-xsrc/server/game/Handlers/LootHandler.cpp8
-rwxr-xr-xsrc/server/game/Handlers/MiscHandler.cpp38
-rwxr-xr-xsrc/server/game/Handlers/MovementHandler.cpp40
-rwxr-xr-xsrc/server/game/Handlers/PetHandler.cpp6
-rwxr-xr-xsrc/server/game/Handlers/QueryHandler.cpp10
-rwxr-xr-xsrc/server/game/Handlers/QuestHandler.cpp4
-rwxr-xr-xsrc/server/game/Handlers/SpellHandler.cpp23
-rwxr-xr-xsrc/server/game/Instances/InstanceSaveMgr.cpp5
-rwxr-xr-xsrc/server/game/Loot/LootMgr.cpp23
-rwxr-xr-xsrc/server/game/Maps/Map.cpp133
-rwxr-xr-xsrc/server/game/Maps/Map.h36
-rwxr-xr-xsrc/server/game/Maps/MapInstanced.cpp2
-rwxr-xr-xsrc/server/game/Maps/MapManager.cpp1
-rwxr-xr-xsrc/server/game/Maps/MapManager.h2
-rw-r--r--src/server/game/Movement/Spline/MoveSplineFlag.h76
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.cpp29
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.h31
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInitArgs.h4
-rwxr-xr-xsrc/server/game/OutdoorPvP/OutdoorPvP.cpp4
-rw-r--r--src/server/game/Server/Protocol/PacketLog.cpp62
-rw-r--r--[-rwxr-xr-x]src/server/game/Server/Protocol/PacketLog.h (renamed from src/server/game/Server/Protocol/WorldLog.h)45
-rwxr-xr-xsrc/server/game/Server/Protocol/WorldLog.cpp114
-rwxr-xr-xsrc/server/game/Server/WorldSession.cpp6
-rwxr-xr-xsrc/server/game/Server/WorldSocket.cpp54
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuraEffects.cpp259
-rwxr-xr-xsrc/server/game/Spells/Spell.cpp27
-rwxr-xr-xsrc/server/game/Spells/SpellEffects.cpp8
-rw-r--r--src/server/game/Spells/SpellInfo.cpp1
-rwxr-xr-xsrc/server/game/Spells/SpellMgr.cpp8
-rw-r--r--src/server/game/Warden/Warden.cpp6
-rwxr-xr-xsrc/server/game/World/World.cpp6
-rw-r--r--src/server/scripts/Kalimdor/winterspring.cpp113
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp22
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp187
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp61
-rw-r--r--src/server/scripts/Northrend/dragonblight.cpp99
-rw-r--r--src/server/scripts/Outland/netherstorm.cpp8
-rw-r--r--src/server/scripts/Spells/CMakeLists.txt1
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp17
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp18
-rw-r--r--src/server/scripts/Spells/spell_pet.cpp1752
-rw-r--r--src/server/scripts/World/go_scripts.cpp31
-rw-r--r--src/server/scripts/World/npcs_special.cpp11
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.cpp17
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.h1
-rw-r--r--src/server/worldserver/worldserver.conf.dist23
-rw-r--r--src/tools/map_extractor/System.cpp12
80 files changed, 3189 insertions, 1171 deletions
diff --git a/src/server/game/AI/CoreAI/GameObjectAI.h b/src/server/game/AI/CoreAI/GameObjectAI.h
index f4555649210..fbc8675cc47 100644
--- a/src/server/game/AI/CoreAI/GameObjectAI.h
+++ b/src/server/game/AI/CoreAI/GameObjectAI.h
@@ -53,7 +53,8 @@ class GameObjectAI
virtual uint64 GetData64(uint32 /*id*/) { return 0; }
virtual void SetData(uint32 /*id*/, uint32 /*value*/) {}
virtual void OnGameEvent(bool /*start*/, uint16 /*eventId*/) {}
- virtual void OnStateChanged(uint32 /*state*/, Unit* /*unit*/) { }
+ virtual void OnStateChanged(uint32 /*state*/, Unit* /*unit*/) {}
+ virtual void EventInform(uint32 /*eventId*/) {}
};
class NullGameObjectAI : public GameObjectAI
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp
index 160b406a6ea..97ae0581a18 100755
--- a/src/server/game/AI/CoreAI/PetAI.cpp
+++ b/src/server/game/AI/CoreAI/PetAI.cpp
@@ -532,3 +532,19 @@ bool PetAI::CanAttack(Unit* target)
// default, though we shouldn't ever get here
return false;
}
+
+void PetAI::ReceiveEmote(Player* player, uint32 emote)
+{
+ if (me->GetOwnerGUID() && me->GetOwnerGUID() == player->GetGUID())
+ switch (emote)
+ {
+ case TEXT_EMOTE_COWER:
+ if (me->isPet() && me->ToPet()->IsPetGhoul())
+ me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
+ break;
+ case TEXT_EMOTE_ANGRY:
+ if (me->isPet() && me->ToPet()->IsPetGhoul())
+ me->HandleEmoteCommand(EMOTE_ONESHOT_COWER);
+ break;
+ }
+}
diff --git a/src/server/game/AI/CoreAI/PetAI.h b/src/server/game/AI/CoreAI/PetAI.h
index ed3e2305556..8e5311fa000 100755
--- a/src/server/game/AI/CoreAI/PetAI.h
+++ b/src/server/game/AI/CoreAI/PetAI.h
@@ -42,6 +42,7 @@ class PetAI : public CreatureAI
void MovementInform(uint32 moveType, uint32 data);
void OwnerDamagedBy(Unit* attacker);
void OwnerAttacked(Unit* target);
+ void ReceiveEmote(Player* player, uint32 textEmote);
private:
bool _isVisible(Unit*) const;
diff --git a/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp b/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp
index 517e55af457..a863f2f89cf 100755
--- a/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp
+++ b/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp
@@ -204,12 +204,17 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
temp.raw.param3 = fields[8].GetInt32();
temp.raw.param4 = fields[9].GetInt32();
+ CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id);
//Creature does not exist in database
- if (!sObjectMgr->GetCreatureTemplate(temp.creature_id))
+ if (!cInfo)
{
- sLog->outErrorDb("CreatureEventAI: Event %u has script for non-existing creature entry (%u), skipping.", i, temp.creature_id);
+ sLog->outErrorDb("CreatureEventAI: Event %u has script for non-existing creature entry (%u), skipping.", i, creature_id);
continue;
}
+
+ // Only on the first script
+ if (cInfo->AIName != "EventAI" && m_CreatureEventAI_Event_Map[creature_id].empty())
+ sLog->outErrorDb("Creature entry %u has EventAI scripts, but its AIName is not 'EventAI' - possible AI-mismatch?", temp.creature_id);
//No chance of this event occuring
if (temp.event_chance == 0)
@@ -735,18 +740,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
}
while (result->NextRow());
- for (CreatureEventAI_Event_Map::const_iterator itr = m_CreatureEventAI_Event_Map.begin(); itr != m_CreatureEventAI_Event_Map.end(); ++itr)
- {
- if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(itr->first))
- {
- if (cInfo->AIName != "EventAI")
- {
- sLog->outErrorDb("Creature entry %u has EventAI scripts, but its AIName is not 'EventAI', changing to EventAI", itr->first);
- const_cast<CreatureTemplate*>(cInfo)->AIName = "EventAI";
- }
- }
- }
-
sLog->outString(">> Loaded %u CreatureEventAI scripts in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
sLog->outString();
}
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index 08f1b18ffad..98b5c0a6ba3 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -937,6 +937,11 @@ void SmartGameObjectAI::OnStateChanged(uint32 state, Unit* unit)
GetScript()->ProcessEventsFor(SMART_EVENT_GO_STATE_CHANGED, unit, state);
}
+void SmartGameObjectAI::EventInform(uint32 eventId)
+{
+ GetScript()->ProcessEventsFor(SMART_EVENT_GO_EVENT_INFORM, NULL, eventId);
+}
+
class SmartTrigger : public AreaTriggerScript
{
public:
diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h
index 435aa176d4d..3a3a7dc9510 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.h
+++ b/src/server/game/AI/SmartScripts/SmartAI.h
@@ -235,30 +235,31 @@ class SmartAI : public CreatureAI
class SmartGameObjectAI : public GameObjectAI
{
-public:
- SmartGameObjectAI(GameObject* g) : GameObjectAI(g), go(g) {}
- ~SmartGameObjectAI() {}
-
- void UpdateAI(uint32 diff);
- void InitializeAI();
- void Reset();
- SmartScript* GetScript() { return &mScript; }
- static int Permissible(const GameObject* g);
-
- bool GossipHello(Player* player);
- bool GossipSelect(Player* player, uint32 sender, uint32 action);
- bool GossipSelectCode(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/);
- bool QuestAccept(Player* player, Quest const* quest);
- bool QuestReward(Player* player, Quest const* quest, uint32 opt);
- uint32 GetDialogStatus(Player* /*player*/);
- void Destroyed(Player* player, uint32 eventId);
- void SetData(uint32 id, uint32 value);
- void SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker);
- void OnGameEvent(bool start, uint16 eventId);
- void OnStateChanged(uint32 state, Unit* unit);
-
-protected:
- GameObject* const go;
- SmartScript mScript;
+ public:
+ SmartGameObjectAI(GameObject* g) : GameObjectAI(g), go(g) {}
+ ~SmartGameObjectAI() {}
+
+ void UpdateAI(uint32 diff);
+ void InitializeAI();
+ void Reset();
+ SmartScript* GetScript() { return &mScript; }
+ static int Permissible(const GameObject* g);
+
+ bool GossipHello(Player* player);
+ bool GossipSelect(Player* player, uint32 sender, uint32 action);
+ bool GossipSelectCode(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/);
+ bool QuestAccept(Player* player, Quest const* quest);
+ bool QuestReward(Player* player, Quest const* quest, uint32 opt);
+ uint32 GetDialogStatus(Player* /*player*/);
+ void Destroyed(Player* player, uint32 eventId);
+ void SetData(uint32 id, uint32 value);
+ void SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker);
+ void OnGameEvent(bool start, uint16 eventId);
+ void OnStateChanged(uint32 state, Unit* unit);
+ void EventInform(uint32 eventId);
+
+ protected:
+ GameObject* const go;
+ SmartScript mScript;
};
#endif
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 01a9b777358..1b414029366 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -160,9 +160,6 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
case SMART_ACTION_TALK:
{
- if (!me)
- break;
-
ObjectList* targets = GetTargets(e, unit);
Creature* talker = me;
Player* targetPlayer = NULL;
@@ -185,6 +182,9 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
delete targets;
}
+ if (!talker)
+ break;
+
mTalkerEntry = talker->GetEntry();
mLastTextID = e.action.talk.textGroupID;
mTextTimer = e.action.talk.duration;
@@ -789,7 +789,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!IsUnit((*itr)))
continue;
- (*itr)->ToUnit()->RemoveAurasDueToSpell(e.action.removeAura.spell);
+ if (e.action.removeAura.spell == 0)
+ (*itr)->ToUnit()->RemoveAllAuras();
+ else
+ (*itr)->ToUnit()->RemoveAurasDueToSpell(e.action.removeAura.spell);
+
sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_REMOVEAURASFROMSPELL: Unit %u, spell %u",
(*itr)->GetGUIDLow(), e.action.removeAura.spell);
}
@@ -2016,16 +2020,16 @@ void SmartScript::InstallTemplate(SmartScriptHolder const& e)
if (!go)
return;
//store hostage as id1
- AddEvent(SMART_EVENT_GOSSIP_HELLO, 0, 0, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 1, 0, 0, 0, 0, 0, SMART_TARGET_CLOSEST_CREATURE, e.action.installTtemplate.param1, 10, 0, 0);
+ AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 1, 0, 0, 0, 0, 0, SMART_TARGET_CLOSEST_CREATURE, e.action.installTtemplate.param1, 10, 0, 0);
//store invoker as id2
- AddEvent(SMART_EVENT_GOSSIP_HELLO, 0, 0, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 2, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0);
+ AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 2, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0);
//signal hostage
- AddEvent(SMART_EVENT_GOSSIP_HELLO, 0, 0, 0, 0, 0, SMART_ACTION_SET_DATA, 0, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 1, 0, 0, 0);
+ AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_SET_DATA, 0, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 1, 0, 0, 0);
//when hostage raeched end point, give credit to invoker
if (e.action.installTtemplate.param2)
AddEvent(SMART_EVENT_DATA_SET, 0, 0, 0, 0, 0, SMART_ACTION_CALL_KILLEDMONSTER, e.action.installTtemplate.param1, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 2, 0, 0, 0);
else
- AddEvent(SMART_EVENT_GOSSIP_HELLO, 0, 0, 0, 0, 0, SMART_ACTION_CALL_KILLEDMONSTER, e.action.installTtemplate.param1, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 2, 0, 0, 0);
+ AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_CALL_KILLEDMONSTER, e.action.installTtemplate.param1, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 2, 0, 0, 0);
break;
}
case SMARTAI_TEMPLATE_BASIC:
@@ -2119,12 +2123,20 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
case SMART_TARGET_INVOKER_PARTY:
if (trigger)
{
- l->push_back(trigger);
if (Player* player = trigger->ToPlayer())
+ {
if (Group* group = player->GetGroup())
+ {
for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
if (Player* member = groupRef->getSource())
l->push_back(member);
+ }
+ // We still add the player to the list if there is no group. If we do
+ // this even if there is a group (thus the else-check), it will add the
+ // same player to the list twice. We don't want that to happen.
+ else
+ l->push_back(trigger);
+ }
}
break;
case SMART_TARGET_CREATURE_RANGE:
@@ -2759,6 +2771,13 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
ProcessAction(e, unit, var0, var1);
break;
}
+ case SMART_EVENT_GO_EVENT_INFORM:
+ {
+ if (e.event.eventInform.eventId != var0)
+ return;
+ ProcessAction(e, NULL, var0);
+ break;
+ }
default:
sLog->outErrorDb("SmartScript::ProcessEvent: Unhandled Event type %u", e.GetEventType());
break;
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index a7149f37480..bf84f39747a 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -533,6 +533,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
break;
}
case SMART_EVENT_GO_STATE_CHANGED:
+ case SMART_EVENT_GO_EVENT_INFORM:
case SMART_EVENT_TIMED_EVENT_TRIGGERED:
case SMART_EVENT_INSTANCE_PLAYER_ENTER:
case SMART_EVENT_TRANSPORT_RELOCATE:
@@ -709,7 +710,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
return false;
break;
case SMART_ACTION_REMOVEAURASFROMSPELL:
- if (!IsSpellValid(e, e.action.removeAura.spell))
+ if (e.action.removeAura.spell != 0 && !IsSpellValid(e, e.action.removeAura.spell))
return false;
break;
case SMART_ACTION_RANDOM_PHASE:
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index c23e288f66d..b82d0724f53 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -153,9 +153,10 @@ enum SMART_EVENT
SMART_EVENT_IS_BEHIND_TARGET = 67, //1 // cooldownMin, CooldownMax
SMART_EVENT_GAME_EVENT_START = 68, //1 // game_event.Entry
SMART_EVENT_GAME_EVENT_END = 69, //1 // game_event.Entry
- SMART_EVENT_GO_STATE_CHANGED = 70, // go state
+ SMART_EVENT_GO_STATE_CHANGED = 70, //1 // go state
+ SMART_EVENT_GO_EVENT_INFORM = 71, //1 // eventId
- SMART_EVENT_END = 71,
+ SMART_EVENT_END = 72,
};
struct SmartEvent
@@ -352,6 +353,11 @@ struct SmartEvent
struct
{
+ uint32 eventId;
+ } eventInform;
+
+ struct
+ {
uint32 param1;
uint32 param2;
uint32 param3;
@@ -398,7 +404,7 @@ enum SMART_ACTION
SMART_ACTION_FLEE_FOR_ASSIST = 25, // With Emote
SMART_ACTION_CALL_GROUPEVENTHAPPENS = 26, // QuestID
SMART_ACTION_CALL_CASTEDCREATUREORGO = 27, // CreatureId, SpellId
- SMART_ACTION_REMOVEAURASFROMSPELL = 28, // Spellid
+ SMART_ACTION_REMOVEAURASFROMSPELL = 28, // Spellid, 0 removes all auras
SMART_ACTION_FOLLOW = 29, // Distance (0 = default), Angle (0 = default), EndCreatureEntry, credit, creditType (0monsterkill, 1event)
SMART_ACTION_RANDOM_PHASE = 30, // PhaseId1, PhaseId2, PhaseId3...
SMART_ACTION_RANDOM_PHASE_RANGE = 31, // PhaseMin, PhaseMax
@@ -1166,7 +1172,7 @@ const uint32 SmartAIEventMask[SMART_EVENT_END][2] =
{SMART_EVENT_GAME_EVENT_START, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },
{SMART_EVENT_GAME_EVENT_END, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },
{SMART_EVENT_GO_STATE_CHANGED, SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },
-
+ {SMART_EVENT_GO_EVENT_INFORM, SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },
};
enum SmartEventFlags
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index c589edcee7a..85bbd2f3b89 100755
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -850,12 +850,8 @@ void Battleground::EndBattleground(uint32 winner)
if (team == winner)
{
// update achievement BEFORE personal rating update
- if (ArenaTeamMember* member = winner_arena_team->GetMember(player->GetGUID()))
- {
- uint32 rating = player->GetArenaPersonalRating(winner_arena_team->GetSlot());
- player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA,
- rating ? rating : 1);
- }
+ uint32 rating = player->GetArenaPersonalRating(winner_arena_team->GetSlot());
+ player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1);
winner_arena_team->MemberWon(player, loser_matchmaker_rating, winner_matchmaker_change);
}
diff --git a/src/server/game/Chat/Commands/Level3.cpp b/src/server/game/Chat/Commands/Level3.cpp
index 30562bb9662..4b2f1c5e7bb 100755
--- a/src/server/game/Chat/Commands/Level3.cpp
+++ b/src/server/game/Chat/Commands/Level3.cpp
@@ -1144,15 +1144,20 @@ bool ChatHandler::HandleLookupQuestCommand(const char *args)
{
QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
- if (status == QUEST_STATUS_COMPLETE)
+ switch (status)
{
- if (target->GetQuestRewardStatus(qinfo->GetQuestId()))
- statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED);
- else
+ case QUEST_STATUS_COMPLETE:
statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE);
+ break;
+ case QUEST_STATUS_INCOMPLETE:
+ statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);
+ break;
+ case QUEST_STATUS_REWARDED:
+ statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED);
+ break;
+ default:
+ break;
}
- else if (status == QUEST_STATUS_INCOMPLETE)
- statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);
}
if (m_session)
@@ -1187,15 +1192,20 @@ bool ChatHandler::HandleLookupQuestCommand(const char *args)
{
QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
- if (status == QUEST_STATUS_COMPLETE)
+ switch (status)
{
- if (target->GetQuestRewardStatus(qinfo->GetQuestId()))
- statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED);
- else
+ case QUEST_STATUS_COMPLETE:
statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE);
+ break;
+ case QUEST_STATUS_INCOMPLETE:
+ statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);
+ break;
+ case QUEST_STATUS_REWARDED:
+ statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED);
+ break;
+ default:
+ break;
}
- else if (status == QUEST_STATUS_INCOMPLETE)
- statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);
}
if (m_session)
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index 23578a55816..e73480cb4de 100755
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -416,16 +416,27 @@ enum SummonPropFlags
enum VehicleSeatFlags
{
+ VEHICLE_SEAT_FLAG_HAS_LOWER_ANIM_FOR_ENTER = 0x00000001,
+ VEHICLE_SEAT_FLAG_HAS_LOWER_ANIM_FOR_RIDE = 0x00000002,
+ VEHICLE_SEAT_FLAG_SHOULD_USE_VEH_SEAT_EXIT_ANIM_ON_VOLUNTARY_EXIT = 0x00000008,
VEHICLE_SEAT_FLAG_HIDE_PASSENGER = 0x00000200, // Passenger is hidden
- VEHICLE_SEAT_FLAG_UNK1 = 0x00000400, // needed for CGCamera__SyncFreeLookFacing
+ VEHICLE_SEAT_FLAG_ALLOW_TURNING = 0x00000400, // needed for CGCamera__SyncFreeLookFacing
VEHICLE_SEAT_FLAG_CAN_CONTROL = 0x00000800, // Lua_UnitInVehicleControlSeat
VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL = 0x00001000, // Can cast spells with SPELL_AURA_MOUNTED from seat (possibly 4.x only, 0 seats on 3.3.5a)
VEHICLE_SEAT_FLAG_UNCONTROLLED = 0x00002000, // can override !& VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT
VEHICLE_SEAT_FLAG_CAN_ATTACK = 0x00004000, // Can attack, cast spells and use items from vehicle
+ VEHICLE_SEAT_FLAG_SHOULD_USE_VEH_SEAT_EXIT_ANIMN_ON_FORCED_EXIT = 0x00008000,
+ VEHICLE_SEAT_FLAG_HAS_VEH_EXIT_ANIM_VOLUNTARY_EXIT = 0x00040000,
+ VEHICLE_SEAT_FLAG_HAS_VEH_EXIT_ANIM_FORCED_EXIT = 0x00080000,
+ VEHICLE_SEAT_FLAG_REC_HAS_VEHICLE_ENTER_ANIM = 0x00400000,
+ VEHICLE_SEAT_FLAG_ENABLE_VEHICLE_ZOOM = 0x01000000,
VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT = 0x02000000, // Lua_CanExitVehicle - can enter and exit at free will
VEHICLE_SEAT_FLAG_CAN_SWITCH = 0x04000000, // Lua_CanSwitchVehicleSeats
+ VEHICLE_SEAT_FLAG_HAS_START_WARITING_FOR_VEH_TRANSITION_ANIM_ENTER = 0x08000000,
+ VEHICLE_SEAT_FLAG_HAS_START_WARITING_FOR_VEH_TRANSITION_ANIM_EXIT = 0x10000000,
VEHICLE_SEAT_FLAG_CAN_CAST = 0x20000000, // Lua_UnitHasVehicleUI
VEHICLE_SEAT_FLAG_UNK2 = 0x40000000, // checked in conjunction with 0x800 in CastSpell2
+ VEHICLE_SEAT_FLAG_ALLOWS_INTERACTION = 0x80000000,
};
enum VehicleSeatFlagsB
@@ -437,6 +448,7 @@ enum VehicleSeatFlagsB
VEHICLE_SEAT_FLAG_B_USABLE_FORCED_2 = 0x00000040,
VEHICLE_SEAT_FLAG_B_USABLE_FORCED_3 = 0x00000100,
VEHICLE_SEAT_FLAG_B_USABLE_FORCED_4 = 0x02000000,
+ VEHICLE_SEAT_FLAG_B_CAN_SWITCH = 0x04000000,
VEHICLE_SEAT_FLAG_B_VEHICLE_PLAYERFRAME_UI = 0x80000000, // Lua_UnitHasVehiclePlayerFrameUI - actually checked for flagsb &~ 0x80000000
};
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp
index 47c298d7467..a5ff89136b8 100755
--- a/src/server/game/DungeonFinding/LFGMgr.cpp
+++ b/src/server/game/DungeonFinding/LFGMgr.cpp
@@ -1417,6 +1417,10 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept)
waitTimesMap[(*it)->GetGUID()] = int32(joinTime - itQueue->second->joinTime);
}
+ // Set the dungeon difficulty
+ LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(pProposal->dungeonId);
+ ASSERT(dungeon);
+
// Create a new group (if needed)
LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_GROUP_FOUND);
Group* grp = pProposal->groupLowGuid ? sGroupMgr->GetGroupByGUID(pProposal->groupLowGuid) : NULL;
@@ -1427,6 +1431,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept)
Group* group = player->GetGroup();
if (sendUpdate)
player->GetSession()->SendLfgUpdateProposal(proposalId, pProposal);
+
if (group)
{
player->GetSession()->SendLfgUpdateParty(updateData);
@@ -1478,14 +1483,16 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept)
break;
}
}
+
m_teleport.push_back(pguid);
grp->SetLfgRoles(pguid, pProposal->players[pguid]->role);
SetState(pguid, LFG_STATE_DUNGEON);
+
+ // Add the cooldown spell if queued for a random dungeon
+ if (dungeon->type == LFG_TYPE_RANDOM)
+ player->CastSpell(player, LFG_SPELL_DUNGEON_COOLDOWN, false);
}
- // Set the dungeon difficulty
- LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(pProposal->dungeonId);
- ASSERT(dungeon);
grp->SetDungeonDifficulty(Difficulty(dungeon->difficulty));
uint64 gguid = grp->GetGUID();
SetDungeon(gguid, dungeon->Entry());
@@ -1626,6 +1633,7 @@ void LFGMgr::InitBoot(Group* grp, uint64 kicker, uint64 victim, std::string reas
{
if (!grp)
return;
+
uint64 gguid = grp->GetGUID();
SetState(gguid, LFG_STATE_BOOT);
@@ -1635,7 +1643,6 @@ void LFGMgr::InitBoot(Group* grp, uint64 kicker, uint64 victim, std::string reas
pBoot->reason = reason;
pBoot->victim = victim;
pBoot->votedNeeded = GetVotesNeeded(gguid);
- PlayerSet players;
// Set votes
for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
@@ -1651,15 +1658,11 @@ void LFGMgr::InitBoot(Group* grp, uint64 kicker, uint64 victim, std::string reas
else
{
pBoot->votes[guid] = LFG_ANSWER_PENDING; // Other members need to vote
- players.insert(plrg);
+ plrg->GetSession()->SendLfgBootPlayer(pBoot);
}
}
}
- // Notify players
- for (PlayerSet::const_iterator it = players.begin(); it != players.end(); ++it)
- (*it)->GetSession()->SendLfgBootPlayer(pBoot);
-
m_Boots[grp->GetLowGUID()] = pBoot;
}
@@ -1748,14 +1751,7 @@ void LFGMgr::UpdateBoot(Player* player, bool accept)
void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*/)
{
sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::TeleportPlayer: [" UI64FMTD "] is being teleported %s", player->GetGUID(), out ? "out" : "in");
- if (out)
- {
- player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW);
- player->TeleportToBGEntryPoint();
- return;
- }
- // TODO Add support for LFG_TELEPORTERROR_FATIGUE
LfgTeleportError error = LFG_TELEPORTERROR_OK;
Group* grp = player->GetGroup();
@@ -1765,10 +1761,25 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*
error = LFG_TELEPORTERROR_PLAYER_DEAD;
else if (player->IsFalling() || player->HasUnitState(UNIT_STATE_JUMPING))
error = LFG_TELEPORTERROR_FALLING;
+ else if (player->IsMirrorTimerActive(FATIGUE_TIMER))
+ error = LFG_TELEPORTERROR_FATIGUE;
else
{
- uint64 gguid = grp->GetGUID();
- LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(GetDungeon(gguid));
+ LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(GetDungeon(grp->GetGUID()));
+
+ if (out)
+ {
+ // Player needs to be inside the LFG dungeon to be able to teleport out
+ if (dungeon && player->GetMapId() == uint32(dungeon->map))
+ {
+ player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW);
+ player->TeleportToBGEntryPoint();
+ }
+ else
+ player->GetSession()->SendLfgTeleportError(LFG_TELEPORTERROR_DONT_REPORT); // Not sure which error message to send
+
+ return;
+ }
if (!dungeon)
error = LFG_TELEPORTERROR_INVALID_LOCATION;
@@ -1817,7 +1828,7 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*
if (error == LFG_TELEPORTERROR_OK)
{
- if (!player->GetMap()->IsDungeon() && !player->GetMap()->IsRaid())
+ if (!player->GetMap()->IsDungeon())
player->SetBattlegroundEntryPoint();
if (player->isInFlight())
diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h
index d10902b9553..f21818deb64 100755
--- a/src/server/game/DungeonFinding/LFGMgr.h
+++ b/src/server/game/DungeonFinding/LFGMgr.h
@@ -68,6 +68,7 @@ enum LfgTeleportError
LFG_TELEPORTERROR_OK = 0, // Internal use
LFG_TELEPORTERROR_PLAYER_DEAD = 1,
LFG_TELEPORTERROR_FALLING = 2,
+ LFG_TELEPORTERROR_DONT_REPORT = 3,
LFG_TELEPORTERROR_FATIGUE = 4,
LFG_TELEPORTERROR_INVALID_LOCATION = 6
};
diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp
index 6175addfae2..1fa7fe0ca9f 100644
--- a/src/server/game/DungeonFinding/LFGScripts.cpp
+++ b/src/server/game/DungeonFinding/LFGScripts.cpp
@@ -117,13 +117,14 @@ void LFGGroupScript::OnRemoveMember(Group* group, uint64 guid, RemoveMethod meth
return;
}
+ uint32 state = sLFGMgr->GetState(gguid);
sLFGMgr->ClearState(guid);
sLFGMgr->SetState(guid, LFG_STATE_NONE);
if (Player* player = ObjectAccessor::FindPlayer(guid))
{
+ if (method == GROUP_REMOVEMETHOD_LEAVE && state != LFG_STATE_FINISHED_DUNGEON && player->HasAura(LFG_SPELL_DUNGEON_COOLDOWN))
+ player->CastSpell(player, LFG_SPELL_DUNGEON_DESERTER, false);
/*
- if (method == GROUP_REMOVEMETHOD_LEAVE)
- // Add deserter flag
else if (group->isLfgKickActive())
// Update internal kick cooldown of kicked
*/
@@ -134,7 +135,7 @@ void LFGGroupScript::OnRemoveMember(Group* group, uint64 guid, RemoveMethod meth
sLFGMgr->TeleportPlayer(player, true);
}
- if (sLFGMgr->GetState(gguid) != LFG_STATE_FINISHED_DUNGEON)// Need more players to finish the dungeon
+ if (state != LFG_STATE_FINISHED_DUNGEON)// Need more players to finish the dungeon
sLFGMgr->OfferContinue(group);
}
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index e8ec686daf5..07e8e37e82a 100755
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -486,7 +486,7 @@ void Creature::Update(uint32 diff)
break;
uint64 dbtableHighGuid = MAKE_NEW_GUID(m_DBTableGuid, GetEntry(), HIGHGUID_UNIT);
- time_t linkedRespawntime = sObjectMgr->GetLinkedRespawnTime(dbtableHighGuid, GetMap()->GetInstanceId());
+ time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid);
if (!linkedRespawntime) // Can respawn
Respawn();
else // the master is dead
@@ -1303,7 +1303,7 @@ bool Creature::LoadCreatureFromDB(uint32 guid, Map* map, bool addToMap)
m_respawnDelay = data->spawntimesecs;
m_deathState = ALIVE;
- m_respawnTime = sObjectMgr->GetCreatureRespawnTime(m_DBTableGuid, GetInstanceId());
+ m_respawnTime = GetMap()->GetCreatureRespawnTime(m_DBTableGuid);
if (m_respawnTime) // respawn on Update
{
m_deathState = DEAD;
@@ -1398,7 +1398,7 @@ void Creature::DeleteFromDB()
return;
}
- sObjectMgr->RemoveCreatureRespawnTime(m_DBTableGuid, GetInstanceId());
+ GetMap()->RemoveCreatureRespawnTime(m_DBTableGuid);
sObjectMgr->DeleteCreatureData(m_DBTableGuid);
SQLTransaction trans = WorldDatabase.BeginTransaction();
@@ -1598,7 +1598,7 @@ void Creature::Respawn(bool force)
if (getDeathState() == DEAD)
{
if (m_DBTableGuid)
- sObjectMgr->RemoveCreatureRespawnTime(m_DBTableGuid, GetInstanceId());
+ GetMap()->RemoveCreatureRespawnTime(m_DBTableGuid);
sLog->outStaticDebug("Respawning creature %s (GuidLow: %u, Full GUID: " UI64FMTD " Entry: %u)", GetName(), GetGUIDLow(), GetGUID(), GetEntry());
m_respawnTime = 0;
@@ -2013,7 +2013,7 @@ void Creature::SaveRespawnTime()
if (isSummon() || !m_DBTableGuid || (m_creatureData && !m_creatureData->dbData))
return;
- sObjectMgr->SaveCreatureRespawnTime(m_DBTableGuid, GetInstanceId(), m_respawnTime);
+ GetMap()->SaveCreatureRespawnTime(m_DBTableGuid, m_respawnTime);
}
// this should not be called by petAI or
diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h
index 829eb73bf80..537bbd9c099 100755
--- a/src/server/game/Entities/Creature/TemporarySummon.h
+++ b/src/server/game/Entities/Creature/TemporarySummon.h
@@ -36,6 +36,7 @@ class TempSummon : public Creature
Unit* GetSummoner() const;
uint64 GetSummonerGUID() { return m_summonerGUID; }
TempSummonType const& GetSummonType() { return m_type; }
+ uint32 GetTimer() { return m_timer; }
const SummonPropertiesEntry* const m_Properties;
private:
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 5101d01899d..1d9958a6524 100755
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -338,7 +338,7 @@ void GameObject::Update(uint32 diff)
if (m_respawnTime <= now) // timer expired
{
uint64 dbtableHighGuid = MAKE_NEW_GUID(m_DBTableGuid, GetEntry(), HIGHGUID_GAMEOBJECT);
- time_t linkedRespawntime = sObjectMgr->GetLinkedRespawnTime(dbtableHighGuid, GetMap()->GetInstanceId());
+ time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid);
if (linkedRespawntime) // Can't respawn, the master is dead
{
uint64 targetGuid = sObjectMgr->GetLinkedRespawnGuid(dbtableHighGuid);
@@ -761,13 +761,13 @@ bool GameObject::LoadGameObjectFromDB(uint32 guid, Map* map, bool addToMap)
else
{
m_respawnDelayTime = data->spawntimesecs;
- m_respawnTime = sObjectMgr->GetGORespawnTime(m_DBTableGuid, map->GetInstanceId());
+ m_respawnTime = GetMap()->GetGORespawnTime(m_DBTableGuid);
// ready to respawn
if (m_respawnTime && m_respawnTime <= time(NULL))
{
m_respawnTime = 0;
- sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId());
+ GetMap()->RemoveGORespawnTime(m_DBTableGuid);
}
}
}
@@ -788,7 +788,7 @@ bool GameObject::LoadGameObjectFromDB(uint32 guid, Map* map, bool addToMap)
void GameObject::DeleteFromDB()
{
- sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId());
+ GetMap()->RemoveGORespawnTime(m_DBTableGuid);
sObjectMgr->DeleteGOData(m_DBTableGuid);
PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAMEOBJECT);
@@ -863,7 +863,7 @@ Unit* GameObject::GetOwner() const
void GameObject::SaveRespawnTime()
{
if (m_goData && m_goData->dbData && m_respawnTime > time(NULL) && m_spawnedByDefault)
- sObjectMgr->SaveGORespawnTime(m_DBTableGuid, GetInstanceId(), m_respawnTime);
+ GetMap()->SaveGORespawnTime(m_DBTableGuid, m_respawnTime);
}
bool GameObject::IsAlwaysVisibleFor(WorldObject const* seer) const
@@ -908,7 +908,7 @@ void GameObject::Respawn()
if (m_spawnedByDefault && m_respawnTime > 0)
{
m_respawnTime = time(NULL);
- sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId());
+ GetMap()->RemoveGORespawnTime(m_DBTableGuid);
}
}
@@ -1711,7 +1711,13 @@ bool GameObject::IsInRange(float x, float y, float z, float radius) const
void GameObject::EventInform(uint32 eventId)
{
- if (eventId && m_zoneScript)
+ if (!eventId)
+ return;
+
+ if (AI())
+ AI()->EventInform(eventId);
+
+ if (m_zoneScript)
m_zoneScript->ProcessEvent(this, eventId);
}
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 64b780bb6c3..5a6a5799fee 100755
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -34,11 +34,11 @@
#define CONTACT_DISTANCE 0.5f
#define INTERACTION_DISTANCE 5.0f
#define ATTACK_DISTANCE 5.0f
-#define MAX_VISIBILITY_DISTANCE 500.0f // max distance for visible objects
+#define MAX_VISIBILITY_DISTANCE SIZE_OF_GRIDS // max distance for visible objects
#define SIGHT_RANGE_UNIT 50.0f
-#define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents
-#define DEFAULT_VISIBILITY_INSTANCE 120.0f // default visible distance in instances, 120 yards
-#define DEFAULT_VISIBILITY_BGARENAS 180.0f // default visible distance in BG/Arenas, 180 yards
+#define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents
+#define DEFAULT_VISIBILITY_INSTANCE 170.0f // default visible distance in instances, 170 yards
+#define DEFAULT_VISIBILITY_BGARENAS 533.0f // default visible distance in BG/Arenas, roughly 533 yards
#define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
#define DEFAULT_COMBAT_REACH 1.5f
diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h
index 1b1a6c0f62d..3475817816d 100755
--- a/src/server/game/Entities/Pet/Pet.h
+++ b/src/server/game/Entities/Pet/Pet.h
@@ -164,6 +164,7 @@ class Pet : public Guardian
bool HaveInDiet(ItemTemplate const* item) const;
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel);
void SetDuration(int32 dur) { m_duration = dur; }
+ int32 GetDuration() { return m_duration; }
/*
bool UpdateStats(Stats stat);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 4cf6d4ad979..42d342cbcf9 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -3322,7 +3322,7 @@ void Player::SendInitialSpells()
uint16 spellCooldowns = m_spellCooldowns.size();
data << uint16(spellCooldowns);
- for (SpellCooldowns::const_iterator itr=m_spellCooldowns.begin(); itr != m_spellCooldowns.end(); ++itr)
+ for (SpellCooldowns::const_iterator itr = m_spellCooldowns.begin(); itr != m_spellCooldowns.end(); ++itr)
{
SpellInfo const* sEntry = sSpellMgr->GetSpellInfo(itr->first);
if (!sEntry)
@@ -9103,7 +9103,6 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
loot->loot_type = loot_type;
WorldPacket data(SMSG_LOOT_RESPONSE, (9+50)); // we guess size
-
data << uint64(guid);
data << uint8(loot_type);
data << LootView(*loot, this, permission);
@@ -13555,9 +13554,9 @@ void Player::SendEquipError(InventoryResult msg, Item* pItem, Item* pItem2, uint
}
case EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM: // no idea about this one...
{
- data << uint64(0);
- data << uint32(0);
- data << uint64(0);
+ data << uint64(0); // item guid
+ data << uint32(0); // slot
+ data << uint64(0); // container
break;
}
case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED:
@@ -14242,7 +14241,7 @@ void Player::SendNewItem(Item* item, uint32 count, bool received, bool created,
data << uint64(GetGUID()); // player GUID
data << uint32(received); // 0=looted, 1=from npc
data << uint32(created); // 0=received, 1=created
- data << uint32(1); // always 0x01 (probably meant to be count of listed items)
+ data << uint32(1); // bool print error to chat
data << uint8(item->GetBagSlot()); // bagslot
// item slot, but when added to stack: 0xFFFFFFFF
data << uint32((item->GetCount() == count) ? item->GetSlot() : -1);
@@ -20121,8 +20120,10 @@ void Player::PetSpellInitialize()
WorldPacket data(SMSG_PET_SPELLS, 8+2+4+4+4*MAX_UNIT_ACTION_BAR_INDEX+1+1);
data << uint64(pet->GetGUID());
data << uint16(pet->GetCreatureTemplate()->family); // creature family (required for pet talents)
- data << uint32(0);
- data << uint8(pet->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0);
+ data << uint32(pet->GetDuration());
+ data << uint8(pet->GetReactState());
+ data << uint8(charmInfo->GetCommandState());
+ data << uint16(0); // Flags, mostly unknown
// action bar loop
charmInfo->BuildActionBar(&data);
@@ -20155,22 +20156,33 @@ void Player::PetSpellInitialize()
for (CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureSpellCooldowns.begin(); itr != pet->m_CreatureSpellCooldowns.end(); ++itr)
{
- time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILLISECONDS : 0;
-
- data << uint32(itr->first); // spellid
- data << uint16(0); // spell category?
- data << uint32(cooldown); // cooldown
- data << uint32(0); // category cooldown
- }
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
+ if (!spellInfo)
+ {
+ data << uint32(0);
+ data << uint16(0);
+ data << uint32(0);
+ data << uint32(0);
+ continue;
+ }
- for (CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureCategoryCooldowns.begin(); itr != pet->m_CreatureCategoryCooldowns.end(); ++itr)
- {
time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILLISECONDS : 0;
+ data << uint32(itr->first); // spell ID
- data << uint32(itr->first); // spellid
- data << uint16(0); // spell category?
- data << uint32(0); // cooldown
- data << uint32(cooldown); // category cooldown
+ CreatureSpellCooldowns::const_iterator categoryitr = pet->m_CreatureCategoryCooldowns.find(spellInfo->Category);
+ if (categoryitr != pet->m_CreatureCategoryCooldowns.end())
+ {
+ time_t categoryCooldown = (categoryitr->second > curTime) ? (categoryitr->second - curTime) * IN_MILLISECONDS : 0;
+ data << uint16(spellInfo->Category); // spell category
+ data << uint32(cooldown); // spell cooldown
+ data << uint32(categoryCooldown); // category cooldown
+ }
+ else
+ {
+ data << uint16(0);
+ data << uint32(cooldown);
+ data << uint32(0);
+ }
}
GetSession()->SendPacket(&data);
@@ -20206,24 +20218,24 @@ void Player::PossessSpellInitialize()
void Player::VehicleSpellInitialize()
{
- Creature* veh = GetVehicleCreatureBase();
- if (!veh)
+ Creature* vehicle = GetVehicleCreatureBase();
+ if (!vehicle)
return;
- uint8 cooldownCount = veh->m_CreatureSpellCooldowns.size() + veh->m_CreatureCategoryCooldowns.size();
+ uint8 cooldownCount = vehicle->m_CreatureSpellCooldowns.size();
WorldPacket data(SMSG_PET_SPELLS, 8 + 2 + 4 + 4 + 4 * 10 + 1 + 1 + cooldownCount * (4 + 2 + 4 + 4));
- data << uint64(veh->GetGUID());
- data << uint16(veh->GetCreatureTemplate()->family);
- data << uint32(0);
- // The following three segments are read as one uint32
- data << uint8(veh->GetReactState());
- data << uint8(0); // CommandState?
- data << uint16(0); // unk
+ data << uint64(vehicle->GetGUID()); // Guid
+ data << uint16(0); // Pet Family (0 for all vehicles)
+ data << uint32(vehicle->isSummon() ? vehicle->ToTempSummon()->GetTimer() : 0); // Duration
+ // The following three segments are read by the client as one uint32
+ data << uint8(vehicle->GetReactState()); // React State
+ data << uint8(0); // Command State
+ data << uint16(0x800); // DisableActions (set for all vehicles)
for (uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
{
- uint32 spellId = veh->m_spells[i];
+ uint32 spellId = vehicle->m_spells[i];
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
{
@@ -20231,54 +20243,59 @@ void Player::VehicleSpellInitialize()
continue;
}
- ConditionList conditions = sConditionMgr->GetConditionsForVehicleSpell(veh->GetEntry(), spellId);
- if (!sConditionMgr->IsObjectMeetToConditions(this, veh, conditions))
+ ConditionList conditions = sConditionMgr->GetConditionsForVehicleSpell(vehicle->GetEntry(), spellId);
+ if (!sConditionMgr->IsObjectMeetToConditions(this, vehicle, conditions))
{
- sLog->outDebug(LOG_FILTER_CONDITIONSYS, "VehicleSpellInitialize: conditions not met for Vehicle entry %u spell %u", veh->ToCreature()->GetEntry(), spellId);
+ sLog->outDebug(LOG_FILTER_CONDITIONSYS, "VehicleSpellInitialize: conditions not met for Vehicle entry %u spell %u", vehicle->ToCreature()->GetEntry(), spellId);
data << uint16(0) << uint8(0) << uint8(i+8);
continue;
}
if (spellInfo->IsPassive())
- {
- veh->CastSpell(veh, spellId, true);
- data << uint16(0) << uint8(0) << uint8(i+8);
- }
- else
- data << uint32(MAKE_UNIT_ACTION_BUTTON(spellId, i+8));
+ vehicle->CastSpell(vehicle, spellId, true);
+
+ data << uint32(MAKE_UNIT_ACTION_BUTTON(spellId, i+8));
}
for (uint32 i = CREATURE_MAX_SPELLS; i < MAX_SPELL_CONTROL_BAR; ++i)
- data << uint16(0) << uint8(0) << uint8(i+8);
+ data << uint32(0);
- data << uint8(0);
- /*if (v23 > 0)
- {
- for (uint32 i = 0; i < v23; ++i)
- data << uint32(v16); // Some spellid?
- }*/
+ data << uint8(0); // Auras?
// Cooldowns
- data << cooldownCount;
+ data << uint8(cooldownCount);
time_t now = sWorld->GetGameTime();
- CreatureSpellCooldowns::const_iterator itr;
- for (itr = veh->m_CreatureSpellCooldowns.begin(); itr != veh->m_CreatureSpellCooldowns.end(); ++itr)
- {
- time_t cooldown = (itr->second > now) ? (itr->second - now) * IN_MILLISECONDS : 0;
- data << uint32(itr->first); // SpellId
- data << uint16(0); // unk
- data << uint32(cooldown); // spell cooldown
- data << uint32(0); // category cooldown
- }
- for (itr = veh->m_CreatureCategoryCooldowns.begin(); itr != veh->m_CreatureCategoryCooldowns.end(); ++itr)
+ for (CreatureSpellCooldowns::const_iterator itr = vehicle->m_CreatureSpellCooldowns.begin(); itr != vehicle->m_CreatureSpellCooldowns.end(); ++itr)
{
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
+ if (!spellInfo)
+ {
+ data << uint32(0);
+ data << uint16(0);
+ data << uint32(0);
+ data << uint32(0);
+ continue;
+ }
+
time_t cooldown = (itr->second > now) ? (itr->second - now) * IN_MILLISECONDS : 0;
- data << uint32(itr->first); // SpellId
- data << uint16(0); // unk
- data << uint32(0); // spell cooldown
- data << uint32(cooldown); // category cooldown
+ data << uint32(itr->first); // spell ID
+
+ CreatureSpellCooldowns::const_iterator categoryitr = vehicle->m_CreatureCategoryCooldowns.find(spellInfo->Category);
+ if (categoryitr != vehicle->m_CreatureCategoryCooldowns.end())
+ {
+ time_t categoryCooldown = (categoryitr->second > now) ? (categoryitr->second - now) * IN_MILLISECONDS : 0;
+ data << uint16(spellInfo->Category); // spell category
+ data << uint32(cooldown); // spell cooldown
+ data << uint32(categoryCooldown); // category cooldown
+ }
+ else
+ {
+ data << uint16(0);
+ data << uint32(cooldown);
+ data << uint32(0);
+ }
}
GetSession()->SendPacket(&data);
@@ -20317,7 +20334,7 @@ void Player::CharmSpellInitialize()
if (charm->GetTypeId() != TYPEID_PLAYER)
data << uint8(charm->ToCreature()->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0);
else
- data << uint8(0) << uint8(0) << uint16(0);
+ data << uint32(0);
charmInfo->BuildActionBar(&data);
@@ -22299,8 +22316,8 @@ void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint3
data << uint32(time);
if (type == RAID_INSTANCE_WELCOME)
{
- data << uint8(0); // is your (1)
- data << uint8(0); // is extended (1), ignored if prev field is 0
+ data << uint8(0); // is locked
+ data << uint8(0); // is extended, ignored if prev field is 0
}
GetSession()->SendPacket(&data);
}
@@ -23345,7 +23362,7 @@ Player* Player::GetNextRandomRaidMember(float radius)
PartyResult Player::CanUninviteFromGroup() const
{
- const Group* grp = GetGroup();
+ Group const* grp = GetGroup();
if (!grp)
return ERR_NOT_IN_GROUP;
@@ -23368,8 +23385,12 @@ PartyResult Player::CanUninviteFromGroup() const
if (grp->isRollLootActive())
return ERR_PARTY_LFG_BOOT_LOOT_ROLLS;
+ // TODO: Should also be sent when anyone has recently left combat, with an aprox ~5 seconds timer.
+ for (GroupReference const* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
+ if (itr->getSource() && itr->getSource()->isInCombat())
+ return ERR_PARTY_LFG_BOOT_IN_COMBAT;
+
/* Missing support for these types
- return ERR_PARTY_LFG_BOOT_IN_COMBAT; // also have a cooldown (some secs after combat finish
return ERR_PARTY_LFG_BOOT_COOLDOWN_S;
return ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S;
*/
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index ed887994bca..b0cbb5c7927 100755
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1970,6 +1970,7 @@ class Player : public Unit, public GridObject<Player>
StopMirrorTimer(BREATH_TIMER);
StopMirrorTimer(FIRE_TIMER);
}
+ bool IsMirrorTimerActive(MirrorTimerType type) { return m_MirrorTimer[type] == getMaxTimer(type); }
void SetMovement(PlayerMovementType pType);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index c90b86f2349..daa8c1e05de 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -424,50 +424,6 @@ void Unit::DisableSpline()
movespline->_Interrupt();
}
-void Unit::SendMonsterMoveExitVehicle(Position const* newPos)
-{
- WorldPacket data(SMSG_MONSTER_MOVE, 1+12+4+1+4+4+4+12+GetPackGUID().size());
- data.append(GetPackGUID());
-
- data << uint8(GetTypeId() == TYPEID_PLAYER ? 1 : 0); // sets/unsets MOVEMENTFLAG2_UNK7 (0x40)
- data << GetPositionX() << GetPositionY() << GetPositionZ();
- data << getMSTime();
-
- data << uint8(SPLINETYPE_FACING_ANGLE);
- data << float(GetOrientation()); // guess
- data << uint32(SPLINEFLAG_EXIT_VEHICLE);
- data << uint32(0); // Time in between points
- data << uint32(1); // 1 single waypoint
- data << newPos->GetPositionX();
- data << newPos->GetPositionY();
- data << newPos->GetPositionZ();
-
- SendMessageToSet(&data, true);
-}
-
-void Unit::SendMonsterMoveTransport(Unit* vehicleOwner)
-{
- // TODO: Turn into BuildMonsterMoveTransport packet and allow certain variables (for npc movement aboard vehicles)
- WorldPacket data(SMSG_MONSTER_MOVE_TRANSPORT, GetPackGUID().size()+vehicleOwner->GetPackGUID().size() + 47);
- data.append(GetPackGUID());
- data.append(vehicleOwner->GetPackGUID());
- data << int8(GetTransSeat());
- data << uint8(0); // sets/unsets MOVEMENTFLAG2_UNK7 (0x40)
- data << GetPositionX() - vehicleOwner->GetPositionX();
- data << GetPositionY() - vehicleOwner->GetPositionY();
- data << GetPositionZ() - vehicleOwner->GetPositionZ();
- data << uint32(getMSTime()); // should be an increasing constant that indicates movement packet count
- data << uint8(SPLINETYPE_FACING_ANGLE);
- data << GetTransOffsetO(); // facing angle?
- data << uint32(SPLINEFLAG_TRANSPORT);
- data << uint32(GetTransTime()); // move time
- data << uint32(1); // amount of waypoints
- data << uint32(0); // waypoint X
- data << uint32(0); // waypoint Y
- data << uint32(0); // waypoint Z
- SendMessageToSet(&data, true);
-}
-
void Unit::resetAttackTimer(WeaponAttackType type)
{
m_attackTimer[type] = uint32(GetAttackTime(type) * m_modAttackSpeedPct[type]);
@@ -2509,12 +2465,12 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spell)
// Chance resist debuff
if (!spell->IsPositive())
{
- bool bNegativeAura = false;
+ bool bNegativeAura = true;
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- if (spell->Effects[i].ApplyAuraName != 0)
+ if (spell->Effects[i].ApplyAuraName == 0)
{
- bNegativeAura = true;
+ bNegativeAura = false;
break;
}
}
@@ -2937,9 +2893,11 @@ void Unit::SetCurrentCastedSpell(Spell* pSpell)
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
m_AutoRepeatFirstCast = true;
}
- AddUnitState(UNIT_STATE_CASTING);
- } break;
+ if (pSpell->m_spellInfo->CalcCastTime(this) > 0)
+ AddUnitState(UNIT_STATE_CASTING);
+ break;
+ }
case CURRENT_CHANNELED_SPELL:
{
// channel spells always break generic non-delayed and any channeled spells
@@ -2951,8 +2909,9 @@ void Unit::SetCurrentCastedSpell(Spell* pSpell)
m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != 75)
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
AddUnitState(UNIT_STATE_CASTING);
- } break;
+ break;
+ }
case CURRENT_AUTOREPEAT_SPELL:
{
// only Auto Shoot does not break anything
@@ -2964,12 +2923,11 @@ void Unit::SetCurrentCastedSpell(Spell* pSpell)
}
// special action: set first cast flag
m_AutoRepeatFirstCast = true;
- } break;
+ break;
+ }
default:
- {
- // other spell types don't break anything now
- } break;
+ break; // other spell types don't break anything now
}
// current spell (if it is still here) may be safely deleted now
@@ -14567,6 +14525,11 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
if (procSpell && (triggeredByAura->GetMiscValue() & procSpell->SchoolMask)) // School check
takeCharges = true;
break;
+ case SPELL_AURA_SPELL_MAGNET:
+ // Skip Melee hits and targets with magnet aura
+ if (procSpell && (triggeredByAura->GetBase()->GetUnitOwner()->ToUnit() == ToUnit())) // Magnet
+ takeCharges = true;
+ break;
case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT:
case SPELL_AURA_MOD_POWER_COST_SCHOOL:
// Skip melee hits and spells ws wrong school or zero cost
@@ -16308,7 +16271,7 @@ Creature* Unit::GetVehicleCreatureBase() const
uint64 Unit::GetTransGUID() const
{
if (GetVehicle())
- return GetVehicle()->GetBase()->GetGUID();
+ return GetVehicleBase()->GetGUID();
if (GetTransport())
return GetTransport()->GetGUID();
@@ -17171,11 +17134,12 @@ void Unit::_ExitVehicle(Position const* exitPosition)
Vehicle* vehicle = m_vehicle;
m_vehicle = NULL;
- SetControlled(false, UNIT_STATE_ROOT); // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT
+ SetControlled(false, UNIT_STATE_ROOT); // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT
Position pos;
- if (!exitPosition) // Exit position not specified
- vehicle->GetBase()->GetPosition(&pos);
+ if (!exitPosition) // Exit position not specified
+ vehicle->GetBase()->GetPosition(&pos); // This should use passenger's current position, leaving it as it is now
+ // because we calculate positions incorrect (sometimes under map)
else
pos = *exitPosition;
@@ -17190,14 +17154,17 @@ void Unit::_ExitVehicle(Position const* exitPosition)
SendMessageToSet(&data, false);
}
- SendMonsterMoveExitVehicle(&pos);
- Relocate(&pos);
+ Movement::MoveSplineInit init(*this);
+ init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
+ init.SetFacing(GetOrientation());
+ init.SetTransportExit();
+ init.Launch();
+
+ //GetMotionMaster()->MoveFall(); // Enable this once passenger positions are calculater properly (see above)
if (Player* player = ToPlayer())
player->ResummonPetTemporaryUnSummonedIfAny();
- SendMovementFlagUpdate();
-
if (vehicle->GetBase()->HasUnitTypeMask(UNIT_MASK_MINION))
if (((Minion*)vehicle->GetBase())->GetOwner() == this)
vehicle->Dismiss();
@@ -17593,6 +17560,7 @@ void Unit::SetInFront(Unit const* target)
void Unit::SetFacingTo(float ori)
{
Movement::MoveSplineInit init(*this);
+ init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset());
init.SetFacing(ori);
init.Launch();
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index f246f595dec..9b63de0cdb8 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -735,19 +735,6 @@ enum MovementFlags2
MOVEMENTFLAG2_UNK16 = 0x00008000,
};
-enum SplineFlags
-{
- SPLINEFLAG_WALKMODE = 0x00001000,
- SPLINEFLAG_FLYING = 0x00002000,
- SPLINEFLAG_TRANSPORT = 0x00800000,
- SPLINEFLAG_EXIT_VEHICLE = 0x01000000,
-};
-
-enum SplineType
-{
- SPLINETYPE_FACING_ANGLE = 4,
-};
-
enum UnitTypeMask
{
UNIT_MASK_NONE = 0x00000000,
@@ -1629,9 +1616,7 @@ class Unit : public WorldObject
void MonsterMoveWithSpeed(float x, float y, float z, float speed);
//void SetFacing(float ori, WorldObject* obj = NULL);
- void SendMonsterMoveExitVehicle(Position const* newPos);
//void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL);
- void SendMonsterMoveTransport(Unit* vehicleOwner);
void SendMovementFlagUpdate();
/*! These methods send the same packet to the client in apply and unapply case.
diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp
index c297ce1e792..710821f2f24 100755
--- a/src/server/game/Entities/Vehicle/Vehicle.cpp
+++ b/src/server/game/Entities/Vehicle/Vehicle.cpp
@@ -28,6 +28,7 @@
#include "ZoneScript.h"
#include "SpellMgr.h"
#include "SpellInfo.h"
+#include "MoveSplineInit.h"
Vehicle::Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry) : _me(unit), _vehicleInfo(vehInfo), _usableSeatNum(0), _creatureEntry(creatureEntry)
{
@@ -338,7 +339,7 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
}
}
- if (seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_UNK1))
+ if (seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_ALLOW_TURNING))
unit->AddUnitState(UNIT_STATE_ONVEHICLE);
unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
@@ -364,7 +365,12 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
unit->SendClearTarget(); // SMSG_BREAK_TARGET
unit->SetControlled(true, UNIT_STATE_ROOT); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures)
// also adds MOVEMENTFLAG_ROOT
- unit->SendMonsterMoveTransport(_me); // SMSG_MONSTER_MOVE_TRANSPORT
+ Movement::MoveSplineInit init(*unit);
+ init.DisableTransportPathTransformations();
+ init.MoveTo(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ);
+ init.SetFacing(0.0f);
+ init.SetTransportEnter();
+ init.Launch();
if (_me->GetTypeId() == TYPEID_UNIT)
{
@@ -372,7 +378,8 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
_me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, true);
// update all passenger's positions
- RelocatePassengers(_me->GetPositionX(), _me->GetPositionY(), _me->GetPositionZ(), _me->GetOrientation());
+ //Passenger's spline OR vehicle movement will update positions
+ //RelocatePassengers(_me->GetPositionX(), _me->GetPositionY(), _me->GetPositionZ(), _me->GetOrientation());
}
}
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index df6018faf39..65f2ccff476 100755
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -1872,71 +1872,6 @@ void ObjectMgr::RemoveGameobjectFromGrid(uint32 guid, GameObjectData const* data
}
}
-void ObjectMgr::LoadCreatureRespawnTimes()
-{
- uint32 oldMSTime = getMSTime();
-
- uint32 count = 0;
-
- PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_CREATURE_RESPAWNS));
- if (!result)
- {
- sLog->outString(">> Loaded 0 creature respawn time.");
- sLog->outString();
- return;
- }
-
- do
- {
- Field* fields = result->Fetch();
-
- uint32 loguid = fields[0].GetUInt32();
- uint32 respawn_time = fields[1].GetUInt32();
- uint32 instance = fields[2].GetUInt32();
-
- _creatureRespawnTimes[MAKE_PAIR64(loguid, instance)] = time_t(respawn_time);
-
- ++count;
- } while (result->NextRow());
-
- sLog->outString(">> Loaded %lu creature respawn times in %u ms", (unsigned long)_creatureRespawnTimes.size(), GetMSTimeDiffToNow(oldMSTime));
- sLog->outString();
-}
-
-void ObjectMgr::LoadGameobjectRespawnTimes()
-{
- uint32 oldMSTime = getMSTime();
-
- // Remove outdated data
- CharacterDatabase.DirectExecute("DELETE FROM gameobject_respawn WHERE respawnTime <= UNIX_TIMESTAMP(NOW())");
-
- uint32 count = 0;
-
- PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_GO_RESPAWNS));
- if (!result)
- {
- sLog->outString(">> Loaded 0 gameobject respawn times. DB table `gameobject_respawn` is empty!");
- sLog->outString();
- return;
- }
-
- do
- {
- Field* fields = result->Fetch();
-
- uint32 loguid = fields[0].GetUInt32();
- uint32 respawn_time = fields[1].GetUInt32();
- uint32 instance = fields[2].GetUInt32();
-
- _goRespawnTimes[MAKE_PAIR64(loguid, instance)] = time_t(respawn_time);
-
- ++count;
- } while (result->NextRow());
-
- sLog->outString();
- sLog->outString(">> Loaded %lu gameobject respawn times in %u ms", (unsigned long)_goRespawnTimes.size(), GetMSTimeDiffToNow(oldMSTime));
-}
-
Player* ObjectMgr::GetPlayerByLowGUID(uint32 lowguid) const
{
uint64 guid = MAKE_NEW_GUID(lowguid, 0, HIGHGUID_PLAYER);
@@ -7172,44 +7107,6 @@ void ObjectMgr::LoadNPCSpellClickSpells()
sLog->outString();
}
-void ObjectMgr::SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t)
-{
- if (!t)
- {
- // Delete only
- RemoveCreatureRespawnTime(loguid, instance);
- return;
- }
-
- // This function can be called from various map threads concurrently
- {
- _creatureRespawnTimesMutex.acquire();
- _creatureRespawnTimes[MAKE_PAIR64(loguid, instance)] = t;
- _creatureRespawnTimesMutex.release();
- }
-
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CREATURE_RESPAWN);
- stmt->setUInt32(0, loguid);
- stmt->setUInt32(1, uint32(t));
- stmt->setUInt32(2, instance);
- CharacterDatabase.Execute(stmt);
-}
-
-void ObjectMgr::RemoveCreatureRespawnTime(uint32 loguid, uint32 instance)
-{
- // This function can be called from various map threads concurrently
- {
- _creatureRespawnTimesMutex.acquire();
- _creatureRespawnTimes[MAKE_PAIR64(loguid, instance)] = 0;
- _creatureRespawnTimesMutex.release();
- }
-
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN);
- stmt->setUInt32(0, loguid);
- stmt->setUInt32(1, instance);
- CharacterDatabase.Execute(stmt);
-}
-
void ObjectMgr::DeleteCreatureData(uint32 guid)
{
// remove mapid*cellid -> guid_set map
@@ -7220,81 +7117,6 @@ void ObjectMgr::DeleteCreatureData(uint32 guid)
_creatureDataStore.erase(guid);
}
-void ObjectMgr::SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t)
-{
- if (!t)
- {
- // Delete only
- RemoveGORespawnTime(loguid, instance);
- return;
- }
-
- // This function can be called from different map threads concurrently
- {
- _goRespawnTimesMutex.acquire();
- _goRespawnTimes[MAKE_PAIR64(loguid, instance)] = t;
- _goRespawnTimesMutex.release();
- }
-
- PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GO_RESPAWN);
- stmt->setUInt32(0, loguid);
- stmt->setUInt64(1, uint64(t));
- stmt->setUInt32(2, instance);
- CharacterDatabase.Execute(stmt);
-}
-
-void ObjectMgr::RemoveGORespawnTime(uint32 loguid, uint32 instance)
-{
- // This function can be called from different map threads concurrently
- {
- _goRespawnTimesMutex.acquire();
- _goRespawnTimes[MAKE_PAIR64(loguid, instance)] = 0;
- _goRespawnTimesMutex.release();
- }
-
- PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GO_RESPAWN);
- stmt->setUInt32(0, loguid);
- stmt->setUInt32(1, instance);
- CharacterDatabase.Execute(stmt);
-}
-
-void ObjectMgr::DeleteRespawnTimeForInstance(uint32 instance)
-{
- // This function can be called from different map threads concurrently
- RespawnTimes::iterator next;
-
- {
- _goRespawnTimesMutex.acquire();
- for (RespawnTimes::iterator itr = _goRespawnTimes.begin(); itr != _goRespawnTimes.end(); itr = next)
- {
- next = itr;
- ++next;
-
- if (GUID_HIPART(itr->first) == instance)
- _goRespawnTimes.erase(itr);
- }
- _goRespawnTimesMutex.release();
- }
- {
- _creatureRespawnTimesMutex.acquire();
- for (RespawnTimes::iterator itr = _creatureRespawnTimes.begin(); itr != _creatureRespawnTimes.end(); itr = next)
- {
- next = itr;
- ++next;
-
- if (GUID_HIPART(itr->first) == instance)
- _creatureRespawnTimes.erase(itr);
- }
- _creatureRespawnTimesMutex.release();
- }
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE);
- stmt->setUInt32(0, instance);
- CharacterDatabase.Execute(stmt);
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GO_RESPAWN_BY_INSTANCE);
- stmt->setUInt32(0, instance);
- CharacterDatabase.Execute(stmt);
-}
-
void ObjectMgr::DeleteGOData(uint32 guid)
{
// remove mapid*cellid -> guid_set map
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index f81e7f1f074..97c2f0234ba 100755
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -367,8 +367,6 @@ struct CellObjectGuids
typedef UNORDERED_MAP<uint32/*cell_id*/, CellObjectGuids> CellObjectGuidsMap;
typedef UNORDERED_MAP<uint32/*(mapid, spawnMode) pair*/, CellObjectGuidsMap> MapObjectGuids;
-typedef UNORDERED_MAP<uint64/*(instance, guid) pair*/, time_t> RespawnTimes;
-
// Trinity string ranges
#define MIN_TRINITY_STRING_ID 1 // 'trinity_string'
#define MAX_TRINITY_STRING_ID 2000000000
@@ -854,13 +852,11 @@ class ObjectMgr
void LoadCreatures();
void LoadLinkedRespawn();
bool SetCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid);
- void LoadCreatureRespawnTimes();
void LoadCreatureAddons();
void LoadCreatureModelInfo();
void LoadEquipmentTemplates();
void LoadGameObjectLocales();
void LoadGameobjects();
- void LoadGameobjectRespawnTimes();
void LoadItemTemplates();
void LoadItemLocales();
void LoadItemSetNames();
@@ -1048,36 +1044,6 @@ class ObjectMgr
void AddCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid, uint32 instance);
void DeleteCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid);
- time_t GetLinkedRespawnTime(uint64 guid, uint32 instance)
- {
- uint64 linkedGuid = GetLinkedRespawnGuid(guid);
- switch (GUID_HIPART(linkedGuid))
- {
- case HIGHGUID_UNIT:
- return GetCreatureRespawnTime(GUID_LOPART(linkedGuid), instance);
- case HIGHGUID_GAMEOBJECT:
- return GetGORespawnTime(GUID_LOPART(linkedGuid), instance);
- default:
- return 0;
- }
- }
-
- time_t GetCreatureRespawnTime(uint32 loguid, uint32 instance)
- {
- TRINITY_GUARD(ACE_Thread_Mutex, _creatureRespawnTimesMutex);
- return _creatureRespawnTimes[MAKE_PAIR64(loguid, instance)];
- }
- void SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t);
- void RemoveCreatureRespawnTime(uint32 loguid, uint32 instance);
- time_t GetGORespawnTime(uint32 loguid, uint32 instance)
- {
- TRINITY_GUARD(ACE_Thread_Mutex, _goRespawnTimesMutex);
- return _goRespawnTimes[MAKE_PAIR64(loguid, instance)];
- }
- void SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t);
- void RemoveGORespawnTime(uint32 loguid, uint32 instance);
- void DeleteRespawnTimeForInstance(uint32 instance);
-
// grid objects
void AddCreatureToGrid(uint32 guid, CreatureData const* data);
void RemoveCreatureFromGrid(uint32 guid, CreatureData const* data);
@@ -1307,10 +1273,6 @@ class ObjectMgr
TrinityStringLocaleContainer _trinityStringLocaleStore;
GossipMenuItemsLocaleContainer _gossipMenuItemsLocaleStore;
PointOfInterestLocaleContainer _pointOfInterestLocaleStore;
- RespawnTimes _creatureRespawnTimes;
- ACE_Thread_Mutex _creatureRespawnTimesMutex;
- RespawnTimes _goRespawnTimes;
- ACE_Thread_Mutex _goRespawnTimesMutex;
CacheVendorItemContainer _cacheVendorItemStore;
CacheTrainerSpellContainer _cacheTrainerSpellStore;
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index c7648bf1ccc..3a6390cd83a 100755
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -525,7 +525,7 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOV
roll->playerVote.erase(itr2);
- CountRollVote(guid, roll->itemGUID, GetMembersCount()-1, MAX_ROLL_TYPE);
+ CountRollVote(guid, roll->itemGUID, MAX_ROLL_TYPE);
}
// Update subgroups
@@ -732,7 +732,7 @@ void Group::SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll &r)
WorldPacket data(SMSG_LOOT_START_ROLL, (8+4+4+4+4+4+4+1));
data << uint64(r.itemGUID); // guid of rolled item
data << uint32(mapid); // 3.3.3 mapid
- data << uint32(r.totalPlayersRolling); // maybe the number of players rolling for it???
+ data << uint32(r.itemSlot); // itemslot
data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for
data << uint32(r.itemRandomSuffix); // randomSuffix
data << uint32(r.itemRandomPropId); // item random property ID
@@ -759,7 +759,7 @@ void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p,
WorldPacket data(SMSG_LOOT_START_ROLL, (8 + 4 + 4 + 4 + 4 + 4 + 4 + 1));
data << uint64(r.itemGUID); // guid of rolled item
data << uint32(mapId); // 3.3.3 mapid
- data << uint32(r.totalPlayersRolling); // maybe the number of players rolling for it???
+ data << uint32(r.itemSlot); // itemslot
data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for
data << uint32(r.itemRandomSuffix); // randomSuffix
data << uint32(r.itemRandomPropId); // item random property ID
@@ -773,20 +773,20 @@ void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p,
p->GetSession()->SendPacket(&data);
}
-void Group::SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r)
+void Group::SendLootRoll(uint64 sourceGuid, uint64 targetGuid, uint8 rollNumber, uint8 rollType, Roll const& roll)
{
WorldPacket data(SMSG_LOOT_ROLL, (8+4+8+4+4+4+1+1+1));
- data << uint64(SourceGuid); // guid of the item rolled
- data << uint32(0); // unknown, maybe amount of players
- data << uint64(TargetGuid);
- data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for
- data << uint32(r.itemRandomSuffix); // randomSuffix
- data << uint32(r.itemRandomPropId); // Item random property ID
- data << uint8(RollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number
- data << uint8(RollType); // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll
- data << uint8(0); // auto pass on NeedBeforeGreed loot because player cannot use the object
+ data << uint64(sourceGuid); // guid of the item rolled
+ data << uint32(roll.itemSlot); // slot
+ data << uint64(targetGuid);
+ data << uint32(roll.itemid); // the itemEntryId for the item that shall be rolled for
+ data << uint32(roll.itemRandomSuffix); // randomSuffix
+ data << uint32(roll.itemRandomPropId); // Item random property ID
+ data << uint8(rollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number
+ data << uint8(rollType); // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll
+ data << uint8(0); // 1: "You automatically passed on: %s because you cannot loot that item." - Possibly used in need befor greed
- for (Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr != r.playerVote.end(); ++itr)
+ for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
{
Player* p = ObjectAccessor::FindPlayer(itr->first);
if (!p || !p->GetSession())
@@ -797,19 +797,19 @@ void Group::SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber,
}
}
-void Group::SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r)
+void Group::SendLootRollWon(uint64 sourceGuid, uint64 targetGuid, uint8 rollNumber, uint8 rollType, Roll const& roll)
{
WorldPacket data(SMSG_LOOT_ROLL_WON, (8+4+4+4+4+8+1+1));
- data << uint64(SourceGuid); // guid of the item rolled
- data << uint32(0); // unknown, maybe amount of players
- data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for
- data << uint32(r.itemRandomSuffix); // randomSuffix
- data << uint32(r.itemRandomPropId); // Item random property
- data << uint64(TargetGuid); // guid of the player who won.
- data << uint8(RollNumber); // rollnumber realted to SMSG_LOOT_ROLL
- data << uint8(RollType); // Rolltype related to SMSG_LOOT_ROLL
+ data << uint64(sourceGuid); // guid of the item rolled
+ data << uint32(roll.itemSlot); // slot
+ data << uint32(roll.itemid); // the itemEntryId for the item that shall be rolled for
+ data << uint32(roll.itemRandomSuffix); // randomSuffix
+ data << uint32(roll.itemRandomPropId); // Item random property
+ data << uint64(targetGuid); // guid of the player who won.
+ data << uint8(rollNumber); // rollnumber realted to SMSG_LOOT_ROLL
+ data << uint8(rollType); // rollType related to SMSG_LOOT_ROLL
- for (Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr != r.playerVote.end(); ++itr)
+ for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
{
Player* p = ObjectAccessor::FindPlayer(itr->first);
if (!p || !p->GetSession())
@@ -820,11 +820,11 @@ void Group::SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumb
}
}
-void Group::SendLootAllPassed(uint32 numberOfPlayers, Roll const& roll)
+void Group::SendLootAllPassed(Roll const& roll)
{
WorldPacket data(SMSG_LOOT_ALL_PASSED, (8+4+4+4+4));
data << uint64(roll.itemGUID); // Guid of the item rolled
- data << uint32(numberOfPlayers); // The number of players rolling for it
+ data << uint32(roll.itemSlot); // Item loot slot
data << uint32(roll.itemid); // The itemEntryId for the item that shall be rolled for
data << uint32(roll.itemRandomPropId); // Item random property ID
data << uint32(roll.itemRandomSuffix); // Item random suffix ID
@@ -1067,7 +1067,7 @@ void Group::MasterLoot(Loot* /*loot*/, WorldObject* pLootedObject)
}
}
-void Group::CountRollVote(uint64 playerGUID, uint64 Guid, uint32 NumberOfPlayers, uint8 Choice)
+void Group::CountRollVote(uint64 playerGUID, uint64 Guid, uint8 Choice)
{
Rolls::iterator rollI = GetRoll(Guid);
if (rollI == RollId.end())
@@ -1108,7 +1108,7 @@ void Group::CountRollVote(uint64 playerGUID, uint64 Guid, uint32 NumberOfPlayers
}
if (roll->totalPass + roll->totalNeed + roll->totalGreed >= roll->totalPlayersRolling)
- CountTheRoll(rollI, NumberOfPlayers);
+ CountTheRoll(rollI);
}
//called when roll timer expires
@@ -1117,7 +1117,7 @@ void Group::EndRoll(Loot* pLoot)
for (Rolls::iterator itr = RollId.begin(); itr != RollId.end();)
{
if ((*itr)->getLoot() == pLoot) {
- CountTheRoll(itr, GetMembersCount()); //i don't have to edit player votes, who didn't vote ... he will pass
+ CountTheRoll(itr); //i don't have to edit player votes, who didn't vote ... he will pass
itr = RollId.begin();
}
else
@@ -1125,7 +1125,7 @@ void Group::EndRoll(Loot* pLoot)
}
}
-void Group::CountTheRoll(Rolls::iterator rollI, uint32 NumberOfPlayers)
+void Group::CountTheRoll(Rolls::iterator rollI)
{
Roll* roll = *rollI;
if (!roll->isValid()) // is loot already deleted ?
@@ -1248,7 +1248,7 @@ void Group::CountTheRoll(Rolls::iterator rollI, uint32 NumberOfPlayers)
}
else
{
- SendLootAllPassed(NumberOfPlayers, *roll);
+ SendLootAllPassed(*roll);
// remove is_blocked so that the item is lootable by all players
LootItem* item = &(roll->getLoot()->items[roll->itemSlot]);
@@ -2076,20 +2076,6 @@ bool Group::HasFreeSlotSubGroup(uint8 subgroup) const
return (m_subGroupsCounts && m_subGroupsCounts[subgroup] < MAXGROUPSIZE);
}
-Group::MemberSlotList const& Group::GetMemberSlots() const
-{
- return m_memberSlots;
-}
-
-GroupReference* Group::GetFirstMember()
-{
- return m_memberMgr.getFirst();
-}
-
-uint32 Group::GetMembersCount() const
-{
- return m_memberSlots.size();
-}
uint8 Group::GetMemberGroup(uint64 guid) const
{
diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h
index 03f946cd3b6..e5f174c4230 100755
--- a/src/server/game/Groups/Group.h
+++ b/src/server/game/Groups/Group.h
@@ -230,9 +230,11 @@ class Group
bool SameSubGroup(Player const* member1, Player const* member2) const;
bool HasFreeSlotSubGroup(uint8 subgroup) const;
- MemberSlotList const& GetMemberSlots() const;
- GroupReference* GetFirstMember();
- uint32 GetMembersCount() const;
+ MemberSlotList const& GetMemberSlots() const { return m_memberSlots; }
+ GroupReference* GetFirstMember() { return m_memberMgr.getFirst(); }
+ GroupReference const* GetFirstMember() const { return m_memberMgr.getFirst(); }
+ uint32 GetMembersCount() const { return m_memberSlots.size(); }
+
uint8 GetMemberGroup(uint64 guid) const;
void ConvertToLFG();
@@ -276,14 +278,14 @@ class Group
void SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, bool canNeed, Roll const& r);
void SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r);
void SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r);
- void SendLootAllPassed(uint32 NumberOfPlayers, const Roll &r);
+ void SendLootAllPassed(Roll const& roll);
void SendLooter(Creature* creature, Player* pLooter);
void GroupLoot(Loot* loot, WorldObject* pLootedObject);
void NeedBeforeGreed(Loot* loot, WorldObject* pLootedObject);
void MasterLoot(Loot* loot, WorldObject* pLootedObject);
Rolls::iterator GetRoll(uint64 Guid);
- void CountTheRoll(Rolls::iterator roll, uint32 NumberOfPlayers);
- void CountRollVote(uint64 playerGUID, uint64 Guid, uint32 NumberOfPlayers, uint8 Choise);
+ void CountTheRoll(Rolls::iterator roll);
+ void CountRollVote(uint64 playerGUID, uint64 Guid, uint8 Choise);
void EndRoll(Loot* loot);
// related to disenchant rolls
diff --git a/src/server/game/Groups/GroupRefManager.h b/src/server/game/Groups/GroupRefManager.h
index 9bcc05f8724..d9fef8611de 100755
--- a/src/server/game/Groups/GroupRefManager.h
+++ b/src/server/game/Groups/GroupRefManager.h
@@ -28,7 +28,8 @@ class GroupReference;
class GroupRefManager : public RefManager<Group, Player>
{
public:
- GroupReference* getFirst() { return ((GroupReference*) RefManager<Group, Player>::getFirst()); }
+ GroupReference* getFirst() { return ((GroupReference*)RefManager<Group, Player>::getFirst()); }
+ GroupReference const* getFirst() const { return ((GroupReference const*)RefManager<Group, Player>::getFirst()); }
};
#endif
diff --git a/src/server/game/Groups/GroupReference.h b/src/server/game/Groups/GroupReference.h
index 2048fd9cb0d..7960dd21035 100755
--- a/src/server/game/Groups/GroupReference.h
+++ b/src/server/game/Groups/GroupReference.h
@@ -35,6 +35,7 @@ class GroupReference : public Reference<Group, Player>
GroupReference() : Reference<Group, Player>(), iSubGroup(0) {}
~GroupReference() { unlink(); }
GroupReference* next() { return (GroupReference*)Reference<Group, Player>::next(); }
+ GroupReference const* next() const { return (GroupReference const*)Reference<Group, Player>::next(); }
uint8 getSubGroup() const { return iSubGroup; }
void setSubGroup(uint8 pSubGroup) { iSubGroup = pSubGroup; }
};
diff --git a/src/server/game/Handlers/AuthHandler.cpp b/src/server/game/Handlers/AuthHandler.cpp
index 9a3e756dda3..49027bdf497 100755
--- a/src/server/game/Handlers/AuthHandler.cpp
+++ b/src/server/game/Handlers/AuthHandler.cpp
@@ -31,7 +31,7 @@ void WorldSession::SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos)
if (!shortForm)
{
packet << uint32(queuePos); // Queue position
- packet << uint8(0); // Unk 3.3.0
+ packet << uint8(0); // Realm has a free character migration - bool
}
SendPacket(&packet);
diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp
index de8dc2b90f6..18435263b2e 100755
--- a/src/server/game/Handlers/GroupHandler.cpp
+++ b/src/server/game/Handlers/GroupHandler.cpp
@@ -429,24 +429,20 @@ void WorldSession::HandleLootMethodOpcode(WorldPacket & recv_data)
group->SendUpdate();
}
-void WorldSession::HandleLootRoll(WorldPacket &recv_data)
+void WorldSession::HandleLootRoll(WorldPacket& recvData)
{
+ uint64 guid;
+ uint32 itemSlot;
+ uint8 rollType;
+ recvData >> guid; // guid of the item rolled
+ recvData >> itemSlot;
+ recvData >> rollType; // 0: pass, 1: need, 2: greed
+
Group* group = GetPlayer()->GetGroup();
if (!group)
- {
- recv_data.rfinish();
return;
- }
- uint64 Guid;
- uint32 NumberOfPlayers;
- uint8 rollType;
- recv_data >> Guid; //guid of the item rolled
- recv_data >> NumberOfPlayers;
- recv_data >> rollType; //0: pass, 1: need, 2: greed
-
- // everything's fine, do it
- group->CountRollVote(GetPlayer()->GetGUID(), Guid, NumberOfPlayers, rollType);
+ group->CountRollVote(GetPlayer()->GetGUID(), guid, rollType);
switch (rollType)
{
diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp
index 8e4b41a9be4..339c7a44d9f 100755
--- a/src/server/game/Handlers/LootHandler.cpp
+++ b/src/server/game/Handlers/LootHandler.cpp
@@ -220,16 +220,18 @@ void WorldSession::HandleLootOpcode(WorldPacket & recv_data)
GetPlayer()->InterruptNonMeleeSpells(false);
}
-void WorldSession::HandleLootReleaseOpcode(WorldPacket & recv_data)
+void WorldSession::HandleLootReleaseOpcode(WorldPacket& recvData)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_LOOT_RELEASE");
// cheaters can modify lguid to prevent correct apply loot release code and re-loot
// use internal stored guid
- recv_data.read_skip<uint64>(); // guid;
+ uint64 guid;
+ recvData >> guid;
if (uint64 lguid = GetPlayer()->GetLootGUID())
- DoLootRelease(lguid);
+ if (lguid == guid)
+ DoLootRelease(lguid);
}
void WorldSession::DoLootRelease(uint64 lguid)
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 8484ac52d27..11f0857ca2b 100755
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -494,7 +494,7 @@ void WorldSession::HandleZoneUpdateOpcode(WorldPacket & recv_data)
uint32 newZone;
recv_data >> newZone;
- sLog->outDetail("WORLD: Recvd ZONE_UPDATE: %u", newZone);
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd ZONE_UPDATE: %u", newZone);
// use server size data
uint32 newzone, newarea;
@@ -730,7 +730,7 @@ void WorldSession::HandleBugOpcode(WorldPacket & recv_data)
void WorldSession::HandleReclaimCorpseOpcode(WorldPacket &recv_data)
{
- sLog->outDetail("WORLD: Received CMSG_RECLAIM_CORPSE");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_RECLAIM_CORPSE");
uint64 guid;
recv_data >> guid;
@@ -767,7 +767,7 @@ void WorldSession::HandleReclaimCorpseOpcode(WorldPacket &recv_data)
void WorldSession::HandleResurrectResponseOpcode(WorldPacket & recv_data)
{
- sLog->outDetail("WORLD: Received CMSG_RESURRECT_RESPONSE");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_RESURRECT_RESPONSE");
uint64 guid;
uint8 status;
@@ -938,7 +938,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recv_data)
void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data)
{
- sLog->outDetail("WORLD: Received CMSG_UPDATE_ACCOUNT_DATA");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_UPDATE_ACCOUNT_DATA");
uint32 type, timestamp, decompressedSize;
recv_data >> type >> timestamp >> decompressedSize;
@@ -993,7 +993,7 @@ void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data)
void WorldSession::HandleRequestAccountData(WorldPacket& recv_data)
{
- sLog->outDetail("WORLD: Received CMSG_REQUEST_ACCOUNT_DATA");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_ACCOUNT_DATA");
uint32 type;
recv_data >> type;
@@ -1072,18 +1072,18 @@ void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data)
void WorldSession::HandleCompleteCinematic(WorldPacket & /*recv_data*/)
{
- sLog->outStaticDebug("WORLD: Player is watching cinema");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_COMPLETE_CINEMATIC");
}
void WorldSession::HandleNextCinematicCamera(WorldPacket & /*recv_data*/)
{
- sLog->outStaticDebug("WORLD: Which movie to play");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_NEXT_CINEMATIC_CAMERA");
}
void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket & recv_data)
{
/* WorldSession::Update(getMSTime());*/
- sLog->outStaticDebug("WORLD: Time Lag/Synchronization Resent/Update");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_MOVE_TIME_SKIPPED");
uint64 guid;
recv_data.readPackGUID(guid);
@@ -1105,7 +1105,7 @@ void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket & recv_data)
void WorldSession::HandleFeatherFallAck(WorldPacket &recv_data)
{
- sLog->outStaticDebug("WORLD: CMSG_MOVE_FEATHER_FALL_ACK");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_MOVE_FEATHER_FALL_ACK");
// no used
recv_data.rfinish(); // prevent warnings spam
@@ -1193,13 +1193,17 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recv_data)
{
uint64 guid;
recv_data >> guid;
- sLog->outStaticDebug("Inspected guid is " UI64FMTD, guid);
+
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_INSPECT");
_player->SetSelection(guid);
Player* player = ObjectAccessor::FindPlayer(guid);
- if (!player) // wrong player
+ if (!player)
+ {
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_INSPECT: No player found from GUID: " UI64FMTD, guid);
return;
+ }
uint32 talent_points = 0x47;
uint32 guid_size = player->GetPackGUID().wpos();
@@ -1230,7 +1234,7 @@ void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recv_data)
if (!player)
{
- sLog->outError("InspectHonorStats: WTF, player not found...");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_INSPECT_HONOR_STATS: No player found from GUID: " UI64FMTD, guid);
return;
}
@@ -1246,10 +1250,6 @@ void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recv_data)
void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recv_data)
{
- // write in client console: worldport 469 452 6454 2536 180 or /console worldport 469 452 6454 2536 180
- // Received opcode CMSG_WORLD_TELEPORT
- // Time is ***, map=469, x=452.000000, y=6454.000000, z=2536.000000, orient=3.141593
-
uint32 time;
uint32 mapid;
float PositionX;
@@ -1264,20 +1264,20 @@ void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recv_data)
recv_data >> PositionZ;
recv_data >> Orientation; // o (3.141593 = 180 degrees)
- //sLog->outDebug("Received opcode CMSG_WORLD_TELEPORT");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_WORLD_TELEPORT");
+
if (GetPlayer()->isInFlight())
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "Player '%s' (GUID: %u) in flight, ignore worldport command.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
return;
}
- sLog->outStaticDebug("Time %u sec, map=%u, x=%f, y=%f, z=%f, orient=%f", time/1000, mapid, PositionX, PositionY, PositionZ, Orientation);
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_WORLD_TELEPORT: Player = %s, Time = %u, map = %u, x = %f, y = %f, z = %f, o = %f", GetPlayer()->GetName(), time, mapid, PositionX, PositionY, PositionZ, Orientation);
if (AccountMgr::IsAdminAccount(GetSecurity()))
GetPlayer()->TeleportTo(mapid, PositionX, PositionY, PositionZ, Orientation);
else
SendNotification(LANG_YOU_NOT_HAVE_PERMISSION);
- sLog->outDebug(LOG_FILTER_NETWORKIO, "Received worldport command from player %s", GetPlayer()->GetName());
}
void WorldSession::HandleWhoisOpcode(WorldPacket& recv_data)
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index c271a43462a..ff9030f04d5 100755
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -295,16 +295,42 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recvData)
}
// if we boarded a transport, add us to it
- if (plrMover && !plrMover->GetTransport())
+ if (plrMover)
{
- // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just dismount if the guid can be found in the transport list
- for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
+ if (!plrMover->GetTransport())
{
- if ((*iter)->GetGUID() == movementInfo.t_guid)
+ // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just dismount if the guid can be found in the transport list
+ for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
{
- plrMover->m_transport = (*iter);
- (*iter)->AddPassenger(plrMover);
- break;
+ if ((*iter)->GetGUID() == movementInfo.t_guid)
+ {
+ plrMover->m_transport = *iter;
+ (*iter)->AddPassenger(plrMover);
+ break;
+ }
+ }
+ }
+ else if (plrMover->GetTransport()->GetGUID() != movementInfo.t_guid)
+ {
+ bool foundNewTransport = false;
+ plrMover->m_transport->RemovePassenger(plrMover);
+ for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
+ {
+ if ((*iter)->GetGUID() == movementInfo.t_guid)
+ {
+ foundNewTransport = true;
+ plrMover->m_transport = *iter;
+ (*iter)->AddPassenger(plrMover);
+ break;
+ }
+ }
+
+ if (!foundNewTransport)
+ {
+ plrMover->m_transport = NULL;
+ movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
+ movementInfo.t_time = 0;
+ movementInfo.t_seat = -1;
}
}
}
diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp
index e54bee96b8b..321c0ada247 100755
--- a/src/server/game/Handlers/PetHandler.cpp
+++ b/src/server/game/Handlers/PetHandler.cpp
@@ -339,9 +339,11 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint16 spellid
if (unit_target2->GetTypeId() == TYPEID_PLAYER)
pet->SendUpdateToPlayer((Player*)unit_target2);
}
+
if (Unit* powner = pet->GetCharmerOrOwner())
if (powner->GetTypeId() == TYPEID_PLAYER)
- pet->SendUpdateToPlayer(powner->ToPlayer());
+ pet->SendUpdateToPlayer(powner->ToPlayer());
+
result = SPELL_CAST_OK;
}
@@ -741,7 +743,7 @@ void WorldSession::HandlePetSpellAutocastOpcode(WorldPacket& recvPacket)
void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
{
- sLog->outDetail("WORLD: CMSG_PET_CAST_SPELL");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_PET_CAST_SPELL");
uint64 guid;
uint8 castCount;
diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp
index 628cdbbdd5e..4fb90bed10b 100755
--- a/src/server/game/Handlers/QueryHandler.cpp
+++ b/src/server/game/Handlers/QueryHandler.cpp
@@ -113,7 +113,7 @@ void WorldSession::HandleCreatureQueryOpcode(WorldPacket & recv_data)
ObjectMgr::GetLocaleString(cl->SubName, loc_idx, SubName);
}
}
- sLog->outDetail("WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name.c_str(), entry);
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name.c_str(), entry);
// guess size
WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 100);
data << uint32(entry); // creature entry
@@ -179,7 +179,7 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPacket & recv_data)
ObjectMgr::GetLocaleString(gl->CastBarCaption, loc_idx, CastBarCaption);
}
}
- sLog->outDetail("WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name.c_str(), entry);
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name.c_str(), entry);
WorldPacket data (SMSG_GAMEOBJECT_QUERY_RESPONSE, 150);
data << uint32(entry);
data << uint32(info->type);
@@ -209,7 +209,7 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPacket & recv_data)
void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recv_data*/)
{
- sLog->outDetail("WORLD: Received MSG_CORPSE_QUERY");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received MSG_CORPSE_QUERY");
Corpse* corpse = GetPlayer()->GetCorpse();
@@ -264,7 +264,7 @@ void WorldSession::HandleNpcTextQueryOpcode(WorldPacket & recv_data)
uint64 guid;
recv_data >> textID;
- sLog->outDetail("WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID);
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID);
recv_data >> guid;
GetPlayer()->SetSelection(guid);
@@ -344,7 +344,7 @@ void WorldSession::HandleNpcTextQueryOpcode(WorldPacket & recv_data)
/// Only _static_ data is sent in this packet !!!
void WorldSession::HandlePageTextQueryOpcode(WorldPacket & recv_data)
{
- sLog->outDetail("WORLD: Received CMSG_PAGE_TEXT_QUERY");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_PAGE_TEXT_QUERY");
uint32 pageID;
recv_data >> pageID;
diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp
index 34fed5e9a97..d13c2fb0956 100755
--- a/src/server/game/Handlers/QuestHandler.cpp
+++ b/src/server/game/Handlers/QuestHandler.cpp
@@ -324,7 +324,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data)
// Send next quest
if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
{
- if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(quest, true))
+ if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true))
{
_player->AddQuest(nextQuest, object);
if (_player->CanCompleteQuest(nextQuest->GetQuestId()))
@@ -343,7 +343,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data)
// Send next quest
if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
{
- if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(quest, true))
+ if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true))
{
_player->AddQuest(nextQuest, object);
if (_player->CanCompleteQuest(nextQuest->GetQuestId()))
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp
index 1affdf0aff7..c02bb43a353 100755
--- a/src/server/game/Handlers/SpellHandler.cpp
+++ b/src/server/game/Handlers/SpellHandler.cpp
@@ -99,7 +99,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
return;
}
- sLog->outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, castCount: %u, spellId: %u, Item: %u, glyphIndex: %u, data length = %i", bagIndex, slot, castCount, spellId, pItem->GetEntry(), glyphIndex, (uint32)recvPacket.size());
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, castCount: %u, spellId: %u, Item: %u, glyphIndex: %u, data length = %i", bagIndex, slot, castCount, spellId, pItem->GetEntry(), glyphIndex, (uint32)recvPacket.size());
ItemTemplate const* proto = pItem->GetTemplate();
if (!proto)
@@ -175,7 +175,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
{
- sLog->outDetail("WORLD: CMSG_OPEN_ITEM packet, data length = %i", (uint32)recvPacket.size());
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_OPEN_ITEM packet, data length = %i", (uint32)recvPacket.size());
Player* pUser = _player;
@@ -658,13 +658,16 @@ void WorldSession::HandleUpdateProjectilePosition(WorldPacket& recvPacket)
recvPacket >> z;
Unit* caster = ObjectAccessor::GetUnit(*_player, casterGuid);
- Spell* spell = caster ? caster->FindCurrentSpellBySpellId(spellId) : NULL;
- if (spell && spell->m_targets.HasDst())
- {
- Position pos = *spell->m_targets.GetDstPos();
- pos.Relocate(x, y, z);
- spell->m_targets.ModDst(pos);
- }
+ if (!caster)
+ return;
+
+ Spell* spell = caster->FindCurrentSpellBySpellId(spellId);
+ if (!spell || !spell->m_targets.HasDst())
+ return;
+
+ Position pos = *spell->m_targets.GetDstPos();
+ pos.Relocate(x, y, z);
+ spell->m_targets.ModDst(pos);
WorldPacket data(SMSG_SET_PROJECTILE_POSITION, 21);
data << uint64(casterGuid);
@@ -672,5 +675,5 @@ void WorldSession::HandleUpdateProjectilePosition(WorldPacket& recvPacket)
data << float(x);
data << float(y);
data << float(z);
- SendPacket(&data);
+ caster->SendMessageToSet(&data, true);
}
diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp
index 8078a91d082..59bb86cb68e 100755
--- a/src/server/game/Instances/InstanceSaveMgr.cpp
+++ b/src/server/game/Instances/InstanceSaveMgr.cpp
@@ -543,7 +543,10 @@ void InstanceSaveManager::_ResetInstance(uint32 mapid, uint32 instanceId)
if (iMap && iMap->IsDungeon())
((InstanceMap*)iMap)->Reset(INSTANCE_RESET_RESPAWN_DELAY);
- sObjectMgr->DeleteRespawnTimeForInstance(instanceId); // even if map is not loaded
+ if (iMap)
+ iMap->DeleteRespawnTimes();
+ else
+ Map::DeleteRespawnTimesInDB(mapid, instanceId);
// Free up the instance id and allow it to be reused
sMapMgr->FreeInstanceId(instanceId);
diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp
index a5ad46c9ec4..53b560e0b77 100755
--- a/src/server/game/Loot/LootMgr.cpp
+++ b/src/server/game/Loot/LootMgr.cpp
@@ -358,7 +358,12 @@ bool LootItem::AllowedForPlayer(Player const* player) const
// check quest requirements
if (!(pProto->FlagsCu & ITEM_FLAGS_CU_IGNORE_QUEST_STATUS) && ((needs_quest || (pProto->StartQuest && player->GetQuestStatus(pProto->StartQuest) != QUEST_STATUS_NONE)) && !player->HasQuestForItem(itemid)))
- return false;
+ if (Group const* group = player->GetGroup())
+ {
+ if (pProto->Flags & ITEM_PROTO_FLAG_PARTY_LOOT || ((pProto->Flags & ITEM_PROTO_FLAG_PARTY_LOOT) == 0 && (group->GetLootMethod() != MASTER_LOOT || group->GetLooterGuid() != player->GetGUID())))
+ return false;
+ }
+ else return false;
return true;
}
@@ -889,6 +894,7 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
}
LootSlotType slotType = lv.permission == OWNER_PERMISSION ? LOOT_SLOT_TYPE_OWNER : LOOT_SLOT_TYPE_ALLOW_LOOT;
+ LootSlotType partySlotType = lv.permission == MASTER_PERMISSION ? LOOT_SLOT_TYPE_MASTER : (lv.permission == GROUP_PERMISSION ? LOOT_SLOT_TYPE_ROLL_ONGOING : slotType);
QuestItemMap const& lootPlayerQuestItems = l.GetPlayerQuestItems();
QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(lv.viewer->GetGUIDLow());
if (q_itr != lootPlayerQuestItems.end())
@@ -901,7 +907,10 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
{
b << uint8(l.items.size() + (qi - q_list->begin()));
b << item;
- b << uint8(slotType);
+ if (!item.freeforall)
+ b << uint8(partySlotType);
+ else
+ b << uint8(slotType);
++itemsShown;
}
}
@@ -919,7 +928,10 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
{
b << uint8(fi->index);
b << item;
- b << uint8(slotType);
+ if (!item.freeforall)
+ b << uint8(partySlotType);
+ else
+ b << uint8(slotType);
++itemsShown;
}
}
@@ -937,7 +949,10 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
{
b << uint8(ci->index);
b << item;
- b << uint8(slotType);
+ if (!item.freeforall)
+ b << uint8(partySlotType);
+ else
+ b << uint8(slotType);
++itemsShown;
}
}
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 162dd12d121..82659e32016 100755
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -2632,7 +2632,7 @@ void InstanceMap::UnloadAll()
ASSERT(!HavePlayers());
if (m_resetAfterUnload == true)
- sObjectMgr->DeleteRespawnTimeForInstance(GetInstanceId());
+ DeleteRespawnTimes();
Map::UnloadAll();
}
@@ -2781,3 +2781,134 @@ void Map::UpdateIteratorBack(Player* player)
if (m_mapRefIter == player->GetMapRef())
m_mapRefIter = m_mapRefIter->nocheck_prev();
}
+
+void Map::SaveCreatureRespawnTime(uint32 dbGuid, time_t respawnTime)
+{
+ if (!respawnTime)
+ {
+ // Delete only
+ RemoveCreatureRespawnTime(dbGuid);
+ return;
+ }
+
+ _creatureRespawnTimes[dbGuid] = respawnTime;
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CREATURE_RESPAWN);
+ stmt->setUInt32(0, dbGuid);
+ stmt->setUInt32(1, uint32(respawnTime));
+ stmt->setUInt16(2, GetId());
+ stmt->setUInt32(3, GetInstanceId());
+ CharacterDatabase.Execute(stmt);
+}
+
+void Map::RemoveCreatureRespawnTime(uint32 dbGuid)
+{
+ _creatureRespawnTimes.erase(dbGuid);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN);
+ stmt->setUInt32(0, dbGuid);
+ stmt->setUInt16(1, GetId());
+ stmt->setUInt32(2, GetInstanceId());
+ CharacterDatabase.Execute(stmt);
+}
+
+void Map::SaveGORespawnTime(uint32 dbGuid, time_t respawnTime)
+{
+ if (!respawnTime)
+ {
+ // Delete only
+ RemoveGORespawnTime(dbGuid);
+ return;
+ }
+
+ _goRespawnTimes[dbGuid] = respawnTime;
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GO_RESPAWN);
+ stmt->setUInt32(0, dbGuid);
+ stmt->setUInt32(1, uint32(respawnTime));
+ stmt->setUInt16(2, GetId());
+ stmt->setUInt32(3, GetInstanceId());
+ CharacterDatabase.Execute(stmt);
+}
+
+void Map::RemoveGORespawnTime(uint32 dbGuid)
+{
+ _goRespawnTimes.erase(dbGuid);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GO_RESPAWN);
+ stmt->setUInt32(0, dbGuid);
+ stmt->setUInt16(1, GetId());
+ stmt->setUInt32(2, GetInstanceId());
+ CharacterDatabase.Execute(stmt);
+}
+
+void Map::LoadRespawnTimes()
+{
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CREATURE_RESPAWNS);
+ stmt->setUInt16(0, GetId());
+ stmt->setUInt32(1, GetInstanceId());
+ if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 loguid = fields[0].GetUInt32();
+ uint32 respawnTime = fields[1].GetUInt32();
+
+ _creatureRespawnTimes[loguid] = time_t(respawnTime);
+ } while (result->NextRow());
+ }
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GO_RESPAWNS);
+ stmt->setUInt16(0, GetId());
+ stmt->setUInt32(1, GetInstanceId());
+ if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 loguid = fields[0].GetUInt32();
+ uint32 respawnTime = fields[1].GetUInt32();
+
+ _goRespawnTimes[loguid] = time_t(respawnTime);
+ } while (result->NextRow());
+ }
+}
+
+void Map::DeleteRespawnTimes()
+{
+ _creatureRespawnTimes.clear();
+ _goRespawnTimes.clear();
+
+ DeleteRespawnTimesInDB(GetId(), GetInstanceId());
+}
+
+void Map::DeleteRespawnTimesInDB(uint16 mapId, uint32 instanceId)
+{
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE);
+ stmt->setUInt16(0, mapId);
+ stmt->setUInt32(1, instanceId);
+ CharacterDatabase.Execute(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GO_RESPAWN_BY_INSTANCE);
+ stmt->setUInt16(0, mapId);
+ stmt->setUInt32(1, instanceId);
+ CharacterDatabase.Execute(stmt);
+}
+
+time_t Map::GetLinkedRespawnTime(uint64 guid) const
+{
+ uint64 linkedGuid = sObjectMgr->GetLinkedRespawnGuid(guid);
+ switch (GUID_HIPART(linkedGuid))
+ {
+ case HIGHGUID_UNIT:
+ return GetCreatureRespawnTime(GUID_LOPART(linkedGuid));
+ case HIGHGUID_GAMEOBJECT:
+ return GetGORespawnTime(GUID_LOPART(linkedGuid));
+ default:
+ break;
+ }
+
+ return time_t(0);
+}
+
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 6ba08646f25..214f50e6d3c 100755
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -443,6 +443,38 @@ class Map : public GridRefManager<NGridType>
void Insert(const GameObjectModel& mdl) { _dynamicTree.insert(mdl); }
bool Contains(const GameObjectModel& mdl) const { return _dynamicTree.contains(mdl);}
bool getObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist);
+
+ /*
+ RESPAWN TIMES
+ */
+ time_t GetLinkedRespawnTime(uint64 guid) const;
+ time_t GetCreatureRespawnTime(uint32 dbGuid) const
+ {
+ UNORDERED_MAP<uint32 /*dbGUID*/, time_t>::const_iterator itr = _creatureRespawnTimes.find(dbGuid);
+ if (itr != _creatureRespawnTimes.end())
+ return itr->second;
+
+ return time_t(0);
+ }
+
+ time_t GetGORespawnTime(uint32 dbGuid) const
+ {
+ UNORDERED_MAP<uint32 /*dbGUID*/, time_t>::const_iterator itr = _goRespawnTimes.find(dbGuid);
+ if (itr != _goRespawnTimes.end())
+ return itr->second;
+
+ return time_t(0);
+ }
+
+ void SaveCreatureRespawnTime(uint32 dbGuid, time_t respawnTime);
+ void RemoveCreatureRespawnTime(uint32 dbGuid);
+ void SaveGORespawnTime(uint32 dbGuid, time_t respawnTime);
+ void RemoveGORespawnTime(uint32 dbGuid);
+ void LoadRespawnTimes();
+ void DeleteRespawnTimes();
+
+ static void DeleteRespawnTimesInDB(uint16 mapId, uint32 instanceId);
+
private:
void LoadMapAndVMap(int gx, int gy);
void LoadVMap(int gx, int gy);
@@ -488,6 +520,7 @@ class Map : public GridRefManager<NGridType>
void ScriptsProcess();
void UpdateActiveCells(const float &x, const float &y, const uint32 t_diff);
+
protected:
void SetUnloadReferenceLock(const GridCoord &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); }
@@ -570,6 +603,9 @@ class Map : public GridRefManager<NGridType>
else
m_activeNonPlayers.erase(obj);
}
+
+ UNORDERED_MAP<uint32 /*dbGUID*/, time_t> _creatureRespawnTimes;
+ UNORDERED_MAP<uint32 /*dbGUID*/, time_t> _goRespawnTimes;
};
enum InstanceResetMethod
diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp
index 5543251e115..2c1bdb00834 100755
--- a/src/server/game/Maps/MapInstanced.cpp
+++ b/src/server/game/Maps/MapInstanced.cpp
@@ -211,6 +211,8 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave* save,
InstanceMap* map = new InstanceMap(GetId(), GetGridExpiry(), InstanceId, difficulty, this);
ASSERT(map->IsDungeon());
+ map->LoadRespawnTimes();
+
bool load_data = save != NULL;
map->CreateInstanceData(load_data);
diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp
index eb09538721d..e9de3ae001f 100755
--- a/src/server/game/Maps/MapManager.cpp
+++ b/src/server/game/Maps/MapManager.cpp
@@ -110,6 +110,7 @@ Map* MapManager::CreateBaseMap(uint32 id)
else
{
map = new Map(id, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY);
+ map->LoadRespawnTimes();
}
i_maps[id] = map;
}
diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h
index 1049325237a..106c2189c65 100755
--- a/src/server/game/Maps/MapManager.h
+++ b/src/server/game/Maps/MapManager.h
@@ -71,7 +71,7 @@ class MapManager
void SetMapUpdateInterval(uint32 t)
{
- if (t > MIN_MAP_UPDATE_DELAY)
+ if (t < MIN_MAP_UPDATE_DELAY)
t = MIN_MAP_UPDATE_DELAY;
i_timer.SetInterval(t);
diff --git a/src/server/game/Movement/Spline/MoveSplineFlag.h b/src/server/game/Movement/Spline/MoveSplineFlag.h
index 33973064e09..cfc2fdee450 100644
--- a/src/server/game/Movement/Spline/MoveSplineFlag.h
+++ b/src/server/game/Movement/Spline/MoveSplineFlag.h
@@ -34,43 +34,43 @@ namespace Movement
{
public:
enum eFlags{
- None = 0x00000000,
- // x00-xFF(first byte) used as animation Ids storage in pair with Animation flag
- Done = 0x00000100,
- Falling = 0x00000200, // Affects elevation computation, can't be combined with Parabolic flag
- No_Spline = 0x00000400,
- Parabolic = 0x00000800, // Affects elevation computation, can't be combined with Falling flag
- Walkmode = 0x00001000,
- Flying = 0x00002000, // Smooth movement(Catmullrom interpolation mode), flying animation
- OrientationFixed = 0x00004000, // Model orientation fixed
- Final_Point = 0x00008000,
- Final_Target = 0x00010000,
- Final_Angle = 0x00020000,
- Catmullrom = 0x00040000, // Used Catmullrom interpolation mode
- Cyclic = 0x00080000, // Movement by cycled spline
- Enter_Cycle = 0x00100000, // Everytimes appears with cyclic flag in monster move packet, erases first spline vertex after first cycle done
- Animation = 0x00200000, // Plays animation after some time passed
- Frozen = 0x00400000, // Will never arrive
- Unknown5 = 0x00800000,
- Unknown6 = 0x01000000,
- Unknown7 = 0x02000000,
- Unknown8 = 0x04000000,
+ None = 0x00000000,
+ // x00-xFF(first byte) used as animation Ids storage in pair with Animation flag
+ Done = 0x00000100,
+ Falling = 0x00000200, // Affects elevation computation, can't be combined with Parabolic flag
+ No_Spline = 0x00000400,
+ Parabolic = 0x00000800, // Affects elevation computation, can't be combined with Falling flag
+ Walkmode = 0x00001000,
+ Flying = 0x00002000, // Smooth movement(Catmullrom interpolation mode), flying animation
+ OrientationFixed = 0x00004000, // Model orientation fixed
+ Final_Point = 0x00008000,
+ Final_Target = 0x00010000,
+ Final_Angle = 0x00020000,
+ Catmullrom = 0x00040000, // Used Catmullrom interpolation mode
+ Cyclic = 0x00080000, // Movement by cycled spline
+ Enter_Cycle = 0x00100000, // Everytimes appears with cyclic flag in monster move packet, erases first spline vertex after first cycle done
+ Animation = 0x00200000, // Plays animation after some time passed
+ Frozen = 0x00400000, // Will never arrive
+ TransportEnter = 0x00800000,
+ TransportExit = 0x01000000,
+ Unknown7 = 0x02000000,
+ Unknown8 = 0x04000000,
OrientationInversed = 0x08000000,
- Unknown10 = 0x10000000,
- Unknown11 = 0x20000000,
- Unknown12 = 0x40000000,
- Unknown13 = 0x80000000,
+ Unknown10 = 0x10000000,
+ Unknown11 = 0x20000000,
+ Unknown12 = 0x40000000,
+ Unknown13 = 0x80000000,
// Masks
- Mask_Final_Facing = Final_Point | Final_Target | Final_Angle,
+ Mask_Final_Facing = Final_Point | Final_Target | Final_Angle,
// animation ids stored here, see AnimType enum, used with Animation flag
- Mask_Animations = 0xFF,
+ Mask_Animations = 0xFF,
// flags that shouldn't be appended into SMSG_MONSTER_MOVE\SMSG_MONSTER_MOVE_TRANSPORT packet, should be more probably
Mask_No_Monster_Move = Mask_Final_Facing | Mask_Animations | Done,
// CatmullRom interpolation mode used
- Mask_CatmullRom = Flying | Catmullrom,
+ Mask_CatmullRom = Flying | Catmullrom,
// Unused, not suported flags
- Mask_Unused = No_Spline|Enter_Cycle|Frozen|Unknown5|Unknown6|Unknown7|Unknown8|Unknown10|Unknown11|Unknown12|Unknown13,
+ Mask_Unused = No_Spline|Enter_Cycle|Frozen|Unknown7|Unknown8|Unknown10|Unknown11|Unknown12|Unknown13,
};
inline uint32& raw() { return (uint32&)*this;}
@@ -98,14 +98,16 @@ namespace Movement
void operator &= (uint32 f) { raw() &= f;}
void operator |= (uint32 f) { raw() |= f;}
- void EnableAnimation(uint8 anim) { raw() = (raw() & ~(Mask_Animations|Falling|Parabolic)) | Animation|anim;}
- void EnableParabolic() { raw() = (raw() & ~(Mask_Animations|Falling|Animation)) | Parabolic;}
- void EnableFalling() { raw() = (raw() & ~(Mask_Animations|Parabolic|Animation)) | Falling;}
+ void EnableAnimation(uint8 anim) { raw() = (raw() & ~(Mask_Animations | Falling | Parabolic)) | Animation | anim; }
+ void EnableParabolic() { raw() = (raw() & ~(Mask_Animations | Falling | Animation)) | Parabolic; }
+ void EnableFalling() { raw() = (raw() & ~(Mask_Animations | Parabolic | Animation)) | Falling; }
void EnableFlying() { raw() = (raw() & ~Catmullrom) | Flying; }
void EnableCatmullRom() { raw() = (raw() & ~Flying) | Catmullrom; }
- void EnableFacingPoint() { raw() = (raw() & ~Mask_Final_Facing) | Final_Point;}
- void EnableFacingAngle() { raw() = (raw() & ~Mask_Final_Facing) | Final_Angle;}
- void EnableFacingTarget() { raw() = (raw() & ~Mask_Final_Facing) | Final_Target;}
+ void EnableFacingPoint() { raw() = (raw() & ~Mask_Final_Facing) | Final_Point; }
+ void EnableFacingAngle() { raw() = (raw() & ~Mask_Final_Facing) | Final_Angle; }
+ void EnableFacingTarget() { raw() = (raw() & ~Mask_Final_Facing) | Final_Target; }
+ void EnableTransportEnter() { raw() = (raw() & ~TransportExit) | TransportEnter; }
+ void EnableTransportExit() { raw() = (raw() & ~TransportEnter) | TransportExit; }
uint8 animId : 8;
bool done : 1;
@@ -123,8 +125,8 @@ namespace Movement
bool enter_cycle : 1;
bool animation : 1;
bool frozen : 1;
- bool unknown5 : 1;
- bool unknown6 : 1;
+ bool transportEnter: 1;
+ bool transportExit : 1;
bool unknown7 : 1;
bool unknown8 : 1;
bool orientationInversed : 1;
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp
index b8440e06076..c539dd3cc39 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.cpp
+++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp
@@ -62,7 +62,8 @@ namespace Movement
bool transport = false;
Location real_position(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZMinusOffset(), unit.GetOrientation());
- if (unit.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes
+ if (unit.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit.GetTransGUID())
{
transport = true;
real_position.x = unit.GetTransOffsetX();
@@ -108,13 +109,7 @@ namespace Movement
data.append(unit.GetPackGUID());
if (transport)
{
- if (unit.GetVehicle())
- data.appendPackGUID(unit.GetVehicleBase()->GetGUID());
- else if (unit.GetTransport())
- data.appendPackGUID(unit.GetTransGUID());
- else
- data << uint8(0);
-
+ data.appendPackGUID(unit.GetTransGUID());
data << int8(unit.GetTransSeat());
}
@@ -124,6 +119,8 @@ namespace Movement
MoveSplineInit::MoveSplineInit(Unit& m) : unit(m)
{
+ // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes
+ args.TransformForTransport = unit.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit.GetTransGUID();
// mix existing state into new
args.flags.walkmode = unit.m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING);
args.flags.flying = unit.m_movementInfo.HasMovementFlag((MovementFlags)(MOVEMENTFLAG_CAN_FLY|MOVEMENTFLAG_DISABLE_GRAVITY));
@@ -132,12 +129,19 @@ namespace Movement
void MoveSplineInit::SetFacing(const Unit * target)
{
args.flags.EnableFacingTarget();
- //args.facing.target = target->GetObjectGuid().GetRawValue();
- args.facing.target = target->GetUInt64Value(OBJECT_FIELD_GUID);
+ args.facing.target = target->GetGUID();
}
void MoveSplineInit::SetFacing(float angle)
{
+ if (args.TransformForTransport)
+ {
+ if (Unit* vehicle = unit.GetVehicleBase())
+ angle -= vehicle->GetOrientation();
+ else if (Transport* transport = unit.GetTransport())
+ angle -= transport->GetOrientation();
+ }
+
args.facing.angle = G3D::wrap(angle, 0.f, (float)G3D::twoPi());
args.flags.EnableFacingAngle();
}
@@ -146,13 +150,13 @@ namespace Movement
{
args.path_Idx_offset = 0;
args.path.resize(2);
- TransportPathTransform transform(unit);
+ TransportPathTransform transform(unit, args.TransformForTransport);
args.path[1] = transform(dest);
}
Vector3 TransportPathTransform::operator()(Vector3 input)
{
- if (_owner.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ if (_transformForTransport)
{
if (Unit* vehicle = _owner.GetVehicleBase())
{
@@ -169,5 +173,4 @@ namespace Movement
return input;
}
-
}
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h
index b1b08d97cfa..ef847809ac8 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.h
+++ b/src/server/game/Movement/Spline/MoveSplineInit.h
@@ -37,11 +37,13 @@ namespace Movement
class TransportPathTransform
{
public:
- TransportPathTransform(Unit& owner) : _owner(owner) { }
+ TransportPathTransform(Unit& owner, bool transformForTransport)
+ : _owner(owner), _transformForTransport(transformForTransport) { }
Vector3 operator()(Vector3 input);
private:
Unit& _owner;
+ bool _transformForTransport;
};
/* Initializes and launches spline movement
@@ -107,6 +109,12 @@ namespace Movement
/* Enables falling mode. Disabled by default
*/
void SetFall();
+ /* Enters transport. Disabled by default
+ */
+ void SetTransportEnter();
+ /* Exits transport. Disabled by default
+ */
+ void SetTransportExit();
/* Inverses unit model orientation. Disabled by default
*/
void SetOrientationInversed();
@@ -123,31 +131,36 @@ namespace Movement
PointsArray& Path() { return args.path; }
+ /* Disables transport coordinate transformations for cases where raw offsets are available
+ */
+ void DisableTransportPathTransformations();
protected:
MoveSplineInitArgs args;
Unit& unit;
};
- inline void MoveSplineInit::SetFly() { args.flags.EnableFlying();}
+ inline void MoveSplineInit::SetFly() { args.flags.EnableFlying(); }
inline void MoveSplineInit::SetWalk(bool enable) { args.flags.walkmode = enable;}
inline void MoveSplineInit::SetSmooth() { args.flags.EnableCatmullRom();}
inline void MoveSplineInit::SetCyclic() { args.flags.cyclic = true;}
inline void MoveSplineInit::SetFall() { args.flags.EnableFalling();}
inline void MoveSplineInit::SetVelocity(float vel) { args.velocity = vel; args.HasVelocity = true; }
inline void MoveSplineInit::SetOrientationInversed() { args.flags.orientationInversed = true;}
+ inline void MoveSplineInit::SetTransportEnter() { args.flags.EnableTransportEnter(); }
+ inline void MoveSplineInit::SetTransportExit() { args.flags.EnableTransportExit(); }
inline void MoveSplineInit::SetOrientationFixed(bool enable) { args.flags.orientationFixed = enable;}
inline void MoveSplineInit::MovebyPath(const PointsArray& controls, int32 path_offset)
{
args.path_Idx_offset = path_offset;
args.path.resize(controls.size());
- std::transform(controls.begin(), controls.end(), args.path.begin(), TransportPathTransform(unit));
+ std::transform(controls.begin(), controls.end(), args.path.begin(), TransportPathTransform(unit, args.TransformForTransport));
}
inline void MoveSplineInit::MoveTo(float x, float y, float z)
{
- Vector3 v(x,y,z);
+ Vector3 v(x, y, z);
MoveTo(v);
}
@@ -166,10 +179,14 @@ namespace Movement
inline void MoveSplineInit::SetFacing(Vector3 const& spot)
{
- args.facing.f.x = spot.x;
- args.facing.f.y = spot.y;
- args.facing.f.z = spot.z;
+ TransportPathTransform transform(unit, args.TransformForTransport);
+ Vector3 finalSpot = transform(spot);
+ args.facing.f.x = finalSpot.x;
+ args.facing.f.y = finalSpot.y;
+ args.facing.f.z = finalSpot.z;
args.flags.EnableFacingPoint();
}
+
+ inline void MoveSplineInit::DisableTransportPathTransformations() { args.TransformForTransport = false; }
}
#endif // TRINITYSERVER_MOVESPLINEINIT_H
diff --git a/src/server/game/Movement/Spline/MoveSplineInitArgs.h b/src/server/game/Movement/Spline/MoveSplineInitArgs.h
index 74409c9562b..de02b35d0a0 100644
--- a/src/server/game/Movement/Spline/MoveSplineInitArgs.h
+++ b/src/server/game/Movement/Spline/MoveSplineInitArgs.h
@@ -42,7 +42,8 @@ namespace Movement
struct MoveSplineInitArgs
{
MoveSplineInitArgs(size_t path_capacity = 16) : path_Idx_offset(0),
- velocity(0.f), parabolic_amplitude(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f), HasVelocity(false)
+ velocity(0.f), parabolic_amplitude(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f),
+ HasVelocity(false), TransformForTransport(true)
{
path.reserve(path_capacity);
}
@@ -57,6 +58,7 @@ namespace Movement
uint32 splineId;
float initialOrientation;
bool HasVelocity;
+ bool TransformForTransport;
/** Returns true to show that the arguments were configured correctly and MoveSpline initialization will succeed. */
bool Validate() const;
diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.cpp b/src/server/game/OutdoorPvP/OutdoorPvP.cpp
index 465fca75030..dfdd4fc4ffc 100755
--- a/src/server/game/OutdoorPvP/OutdoorPvP.cpp
+++ b/src/server/game/OutdoorPvP/OutdoorPvP.cpp
@@ -166,8 +166,10 @@ bool OPvPCapturePoint::DelCreature(uint32 type)
//if (Map* map = sMapMgr->FindMap(cr->GetMapId()))
// map->Remove(cr, false);
// delete respawn time for this creature
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN_BY_GUID);
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN);
stmt->setUInt32(0, guid);
+ stmt->setUInt16(1, cr->GetMapId());
+ stmt->setUInt32(2, 0); // instance id, always 0 for world maps
CharacterDatabase.Execute(stmt);
cr->AddObjectToRemoveList();
diff --git a/src/server/game/Server/Protocol/PacketLog.cpp b/src/server/game/Server/Protocol/PacketLog.cpp
new file mode 100644
index 00000000000..cb6dcdbdb9e
--- /dev/null
+++ b/src/server/game/Server/Protocol/PacketLog.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "PacketLog.h"
+#include "Config.h"
+#include "ByteBuffer.h"
+#include "WorldPacket.h"
+
+PacketLog::PacketLog() : _file(NULL)
+{
+ Initialize();
+}
+
+PacketLog::~PacketLog()
+{
+ if (_file)
+ fclose(_file);
+
+ _file = NULL;
+}
+
+void PacketLog::Initialize()
+{
+ std::string logsDir = ConfigMgr::GetStringDefault("LogsDir", "");
+
+ if (!logsDir.empty())
+ if ((logsDir.at(logsDir.length()-1) != '/') && (logsDir.at(logsDir.length()-1) != '\\'))
+ logsDir.push_back('/');
+
+ std::string logname = ConfigMgr::GetStringDefault("PacketLogFile", "");
+ if (!logname.empty())
+ _file = fopen((logsDir + logname).c_str(), "wb");
+}
+
+void PacketLog::LogPacket(WorldPacket const& packet, Direction direction)
+{
+ ByteBuffer data(4+4+4+1+packet.size());
+ data << int32(packet.GetOpcode());
+ data << int32(packet.size());
+ data << uint32(time(NULL));
+ data << uint8(direction);
+
+ for (uint32 i = 0; i < packet.size(); i++)
+ data << const_cast<WorldPacket&>(packet)[i];
+
+ fwrite(data.contents(), 1, data.size(), _file);
+ fflush(_file);
+}
diff --git a/src/server/game/Server/Protocol/WorldLog.h b/src/server/game/Server/Protocol/PacketLog.h
index fb344f195de..b899daae198 100755..100644
--- a/src/server/game/Server/Protocol/WorldLog.h
+++ b/src/server/game/Server/Protocol/PacketLog.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* 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,46 +15,36 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/// \addtogroup u2w
-/// @{
-/// \file
-
-#ifndef TRINITY_WORLDLOG_H
-#define TRINITY_WORLDLOG_H
+#ifndef TRINITY_PACKETLOG_H
+#define TRINITY_PACKETLOG_H
#include "Common.h"
#include <ace/Singleton.h>
-#include "Errors.h"
-#include <stdarg.h>
+enum Direction
+{
+ CLIENT_TO_SERVER,
+ SERVER_TO_CLIENT
+};
+
+class WorldPacket;
-/// %Log packets to a file
-class WorldLog
+class PacketLog
{
- friend class ACE_Singleton<WorldLog, ACE_Thread_Mutex>;
+ friend class ACE_Singleton<PacketLog, ACE_Thread_Mutex>;
private:
- WorldLog();
- ~WorldLog();
- WorldLog(const WorldLog &);
- WorldLog& operator=(const WorldLog &);
- ACE_Thread_Mutex Lock;
+ PacketLog();
+ ~PacketLog();
public:
void Initialize();
- /// Is the world logger active?
- bool LogWorld(void) const { return (i_file != NULL); }
- /// %Log to the file
- void outLog(char const* fmt, ...);
- void outTimestampLog(char const* fmt, ...);
+ bool CanLogPacket() const { return (_file != NULL); }
+ void LogPacket(WorldPacket const& packet, Direction direction);
private:
- FILE* i_file;
-
- bool m_dbWorld;
+ FILE* _file;
};
-#define sWorldLog ACE_Singleton<WorldLog, ACE_Thread_Mutex>::instance()
+#define sPacketLog ACE_Singleton<PacketLog, ACE_Thread_Mutex>::instance()
#endif
-/// @}
-
diff --git a/src/server/game/Server/Protocol/WorldLog.cpp b/src/server/game/Server/Protocol/WorldLog.cpp
deleted file mode 100755
index 38b13dff095..00000000000
--- a/src/server/game/Server/Protocol/WorldLog.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/** \file
- \ingroup u2w
-*/
-
-#include "WorldLog.h"
-#include "Config.h"
-#include "Log.h"
-#include "DatabaseWorkerPool.h"
-
-WorldLog::WorldLog() : i_file(NULL)
-{
- Initialize();
-}
-
-WorldLog::~WorldLog()
-{
- if (i_file != NULL)
- fclose(i_file);
-
- i_file = NULL;
-}
-
-/// Open the log file (if specified so in the configuration file)
-void WorldLog::Initialize()
-{
- std::string logsDir = ConfigMgr::GetStringDefault("LogsDir", "");
-
- if (!logsDir.empty())
- {
- if ((logsDir.at(logsDir.length()-1) != '/') && (logsDir.at(logsDir.length()-1) != '\\'))
- logsDir.push_back('/');
- }
-
- std::string logname = ConfigMgr::GetStringDefault("WorldLogFile", "");
- if (!logname.empty())
- {
- i_file = fopen((logsDir+logname).c_str(), "w");
- }
-
- m_dbWorld = ConfigMgr::GetBoolDefault("LogDB.World", false); // can be VERY heavy if enabled
-}
-
-void WorldLog::outTimestampLog(char const* fmt, ...)
-{
- if (LogWorld())
- {
- TRINITY_GUARD(ACE_Thread_Mutex, Lock);
- ASSERT(i_file);
-
- Log::outTimestamp(i_file);
- va_list args;
- va_start(args, fmt);
- vfprintf(i_file, fmt, args);
- //fprintf(i_file, "\n");
- va_end(args);
-
- fflush(i_file);
- }
-
- if (sLog->GetLogDB() && m_dbWorld)
- {
- va_list ap2;
- va_start(ap2, fmt);
- char nnew_str[MAX_QUERY_LEN];
- vsnprintf(nnew_str, MAX_QUERY_LEN, fmt, ap2);
- sLog->outDB(LOG_TYPE_WORLD, nnew_str);
- va_end(ap2);
- }
-}
-
-void WorldLog::outLog(char const* fmt, ...)
-{
- if (LogWorld())
- {
- TRINITY_GUARD(ACE_Thread_Mutex, Lock);
- ASSERT(i_file);
-
- va_list args;
- va_start(args, fmt);
- vfprintf(i_file, fmt, args);
- //fprintf(i_file, "\n");
- va_end(args);
-
- fflush(i_file);
- }
-
- if (sLog->GetLogDB() && m_dbWorld)
- {
- va_list ap2;
- va_start(ap2, fmt);
- char nnew_str[MAX_QUERY_LEN];
- vsnprintf(nnew_str, MAX_QUERY_LEN, fmt, ap2);
- sLog->outDB(LOG_TYPE_WORLD, nnew_str);
- va_end(ap2);
- }
-}
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 7756e686388..81ec5495421 100755
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -208,7 +208,7 @@ void WorldSession::QueuePacket(WorldPacket* new_packet)
/// Logging helper for unexpected opcodes
void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, const char* status, const char *reason)
{
- sLog->outError("SESSION (account: %u, guidlow: %u, char: %s): received unexpected opcode %s (0x%.4X, status: %s) %s",
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION (account: %u, guidlow: %u, char: %s): received unexpected opcode %s (0x%.4X, status: %s) %s",
GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>",
LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode(), status, reason);
}
@@ -216,7 +216,7 @@ void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, const char* status,
/// Logging helper for unexpected opcodes
void WorldSession::LogUnprocessedTail(WorldPacket* packet)
{
- sLog->outError("SESSION: opcode %s (0x%.4X) have unprocessed tail data (read stop at %u from %u)",
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION: opcode %s (0x%.4X) have unprocessed tail data (read stop at %u from %u)",
LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode(), uint32(packet->rpos()), uint32(packet->wpos()));
packet->print_storage();
}
@@ -334,7 +334,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
LogUnprocessedTail(packet);
break;
case STATUS_NEVER:
- sLog->outError("SESSION (account: %u, guidlow: %u, char: %s): received not allowed opcode %s (0x%.4X)",
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION (account: %u, guidlow: %u, char: %s): received not allowed opcode %s (0x%.4X)",
GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>",
LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode());
break;
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index 64137dfe7c7..74e414a43a9 100755
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -42,7 +42,7 @@
#include "WorldSession.h"
#include "WorldSocketMgr.h"
#include "Log.h"
-#include "WorldLog.h"
+#include "PacketLog.h"
#include "ScriptMgr.h"
#include "AccountMgr.h"
@@ -152,7 +152,7 @@ const std::string& WorldSocket::GetRemoteAddress (void) const
return m_Address;
}
-int WorldSocket::SendPacket(const WorldPacket& pct)
+int WorldSocket::SendPacket(WorldPacket const& pct)
{
ACE_GUARD_RETURN (LockType, Guard, m_OutBufferLock, -1);
@@ -160,24 +160,8 @@ int WorldSocket::SendPacket(const WorldPacket& pct)
return -1;
// Dump outgoing packet.
- if (sWorldLog->LogWorld())
- {
- sWorldLog->outTimestampLog ("SERVER:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
- (uint32) get_handle(),
- pct.size(),
- LookupOpcodeName (pct.GetOpcode()),
- pct.GetOpcode());
-
- uint32 p = 0;
- while (p < pct.size())
- {
- for (uint32 j = 0; j < 16 && p < pct.size(); j++)
- sWorldLog->outLog("%.2X ", const_cast<WorldPacket&>(pct)[p++]);
-
- sWorldLog->outLog("\n");
- }
- sWorldLog->outLog("\n");
- }
+ if (sPacketLog->CanLogPacket())
+ sPacketLog->LogPacket(pct, SERVER_TO_CLIENT);
// Create a copy of the original packet; this is to avoid issues if a hook modifies it.
sScriptMgr->OnPacketSend(this, WorldPacket(pct));
@@ -674,7 +658,7 @@ int WorldSocket::schedule_wakeup_output (GuardType& g)
return 0;
}
-int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
+int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
{
ACE_ASSERT (new_pct);
@@ -687,24 +671,8 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
return -1;
// Dump received packet.
- if (sWorldLog->LogWorld())
- {
- sWorldLog->outTimestampLog ("CLIENT:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
- (uint32) get_handle(),
- new_pct->size(),
- LookupOpcodeName (new_pct->GetOpcode()),
- new_pct->GetOpcode());
-
- uint32 p = 0;
- while (p < new_pct->size())
- {
- for (uint32 j = 0; j < 16 && p < new_pct->size(); j++)
- sWorldLog->outLog ("%.2X ", (*new_pct)[p++]);
-
- sWorldLog->outLog ("\n");
- }
- sWorldLog->outLog ("\n");
- }
+ if (sPacketLog->CanLogPacket())
+ sPacketLog->LogPacket(*new_pct, CLIENT_TO_SERVER);
try
{
@@ -955,6 +923,8 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
sha.UpdateBigNumbers (&k, NULL);
sha.Finalize();
+ std::string address = GetRemoteAddress();
+
if (memcmp (sha.GetDigest(), digest, 20))
{
packet.Initialize (SMSG_AUTH_RESPONSE, 1);
@@ -962,13 +932,11 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
SendPacket(packet);
- sLog->outError("WorldSocket::HandleAuthSession: Sent Auth Response (authentification failed).");
+ sLog->outError("WorldSocket::HandleAuthSession: Authentication failed for account: %u ('%s') address: %s", id, account.c_str(), address.c_str());
return -1;
}
- std::string address = GetRemoteAddress();
-
- sLog->outStaticDebug ("WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.",
+ sLog->outStaticDebug("WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.",
account.c_str(),
address.c_str());
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 05114c8bc07..849a7136ea8 100755
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -3368,41 +3368,244 @@ void AuraEffect::HandleModStateImmunityMask(AuraApplication const* aurApp, uint8
return;
Unit* target = aurApp->GetTarget();
+ std::list <AuraType> aura_immunity_list;
+ uint32 mechanic_immunity_list;
+ int32 miscVal = GetMiscValue();
- std::list <AuraType> immunity_list;
- if (GetMiscValue() & (1<<10))
- immunity_list.push_back(SPELL_AURA_MOD_STUN);
- if (GetMiscValue() & (1<<1))
- immunity_list.push_back(SPELL_AURA_TRANSFORM);
-
- // These flag can be recognized wrong:
- if (GetMiscValue() & (1<<6))
- immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
- if (GetMiscValue() & (1<<0))
- immunity_list.push_back(SPELL_AURA_MOD_ROOT);
- if (GetMiscValue() & (1<<2))
- immunity_list.push_back(SPELL_AURA_MOD_CONFUSE);
- if (GetMiscValue() & (1<<9))
- immunity_list.push_back(SPELL_AURA_MOD_FEAR);
-
- // an exception for Bladestorm
- if ((GetMiscValue() & (1<<7)) && (GetId() != 46924))
- immunity_list.push_back(SPELL_AURA_MOD_DISARM);
-
- // apply immunities
- for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end(); ++iter)
- target->ApplySpellImmune(GetId(), IMMUNITY_STATE, *iter, apply);
+ switch (miscVal)
+ {
+ case 96:
+ case 1615:
+ {
+ if (GetAmount())
+ {
+ mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT)
+ | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN)
+ | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM)
+ | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR)
+ | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED)
+ | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN);
+
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_STUN);
+ aura_immunity_list.push_back(SPELL_AURA_TRANSFORM);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR);
+ }
+ break;
+ }
+ case 679:
+ {
+ if (GetId() == 57742)
+ {
+ mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT)
+ | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN)
+ | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM)
+ | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR)
+ | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED)
+ | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN);
+
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_STUN);
+ aura_immunity_list.push_back(SPELL_AURA_TRANSFORM);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR);
+ }
+ break;
+ }
+ case 1557:
+ {
+ if (GetId() == 64187)
+ {
+ mechanic_immunity_list = (1 << MECHANIC_STUN);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_STUN);
+ }
+ else
+ {
+ mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT)
+ | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN)
+ | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM)
+ | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR)
+ | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED)
+ | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN);
+
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_STUN);
+ aura_immunity_list.push_back(SPELL_AURA_TRANSFORM);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR);
+ }
+ break;
+ }
+ case 1614:
+ case 1694:
+ {
+ target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, apply);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_TAUNT);
+ break;
+ }
+ case 1630:
+ {
+ if (!GetAmount())
+ {
+ target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, apply);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_TAUNT);
+ }
+ else
+ {
+ mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT)
+ | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN)
+ | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM)
+ | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR)
+ | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED)
+ | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN);
+
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_STUN);
+ aura_immunity_list.push_back(SPELL_AURA_TRANSFORM);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR);
+ }
+ break;
+ }
+ case 477:
+ case 1733:
+ {
+ if (!GetAmount())
+ {
+ mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT)
+ | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN)
+ | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM)
+ | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR)
+ | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED)
+ | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN);
+
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, apply);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_STUN);
+ aura_immunity_list.push_back(SPELL_AURA_TRANSFORM);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR);
+ }
+ break;
+ }
+ case 878:
+ {
+ if (GetAmount() == 1)
+ {
+ mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_STUN)
+ | (1 << MECHANIC_DISORIENTED) | (1 << MECHANIC_FREEZE);
+
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_STUN);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
+ }
+ break;
+ }
+ default:
+ break;
+ }
- // Patch 3.0.3 Bladestorm now breaks all snares and roots on the warrior when activated.
- if (apply && GetId() == 46924)
+ if (aura_immunity_list.size() == 0)
{
- target->RemoveAurasByType(SPELL_AURA_MOD_ROOT);
- target->RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED);
+ if (miscVal & (1<<10))
+ aura_immunity_list.push_back(SPELL_AURA_MOD_STUN);
+ if (miscVal & (1<<1))
+ aura_immunity_list.push_back(SPELL_AURA_TRANSFORM);
+
+ // These flag can be recognized wrong:
+ if (miscVal & (1<<6))
+ aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
+ if (miscVal & (1<<0))
+ aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT);
+ if (miscVal & (1<<2))
+ aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE);
+ if (miscVal & (1<<9))
+ aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR);
+ if (miscVal & (1<<7))
+ aura_immunity_list.push_back(SPELL_AURA_MOD_DISARM);
}
+ // apply immunities
+ for (std::list <AuraType>::iterator iter = aura_immunity_list.begin(); iter != aura_immunity_list.end(); ++iter)
+ target->ApplySpellImmune(GetId(), IMMUNITY_STATE, *iter, apply);
+
if (apply && GetSpellInfo()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)
- for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end(); ++iter)
+ {
+ target->RemoveAurasWithMechanic(mechanic_immunity_list, AURA_REMOVE_BY_DEFAULT, GetId());
+ for (std::list <AuraType>::iterator iter = aura_immunity_list.begin(); iter != aura_immunity_list.end(); ++iter)
target->RemoveAurasByType(*iter);
+ }
}
void AuraEffect::HandleModMechanicImmunity(AuraApplication const* aurApp, uint8 mode, bool apply) const
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 58a89f75fd3..b51a3e8ee73 100755
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -2547,12 +2547,31 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
return SPELL_MISS_EVADE;
// For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
+ if (m_spellInfo->Speed && (unit->IsImmunedToDamage(m_spellInfo) || unit->IsImmunedToSpell(m_spellInfo)))
+ return SPELL_MISS_IMMUNE;
+
// disable effects to which unit is immune
+ SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
- if (effectMask & (1 << effectNumber) && unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
- effectMask &= ~(1 << effectNumber);
- if (!effectMask || (m_spellInfo->Speed && (unit->IsImmunedToDamage(m_spellInfo) || unit->IsImmunedToSpell(m_spellInfo))))
- return SPELL_MISS_IMMUNE;
+ {
+ if (effectMask & (1 << effectNumber))
+ if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
+ effectMask &= ~(1 << effectNumber);
+ else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
+ {
+ int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
+ debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
+
+ if (debuff_resist_chance > 0)
+ if (irand(0,10000) <= (debuff_resist_chance * 100))
+ {
+ effectMask &= ~(1 << effectNumber);
+ returnVal = SPELL_MISS_RESIST;
+ }
+ }
+ }
+ if (!effectMask)
+ return returnVal;
PrepareScriptHitHandlers();
CallScriptBeforeHitHandlers();
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 17e79501d16..0d5dac8f8e0 100755
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -3317,6 +3317,14 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
fixed_bonus += (aur->GetStackAmount() - 1) * CalculateDamage(2, unitTarget);
}
}
+ if (m_spellInfo->SpellFamilyFlags[0] & 0x8000000) // Mocking Blow
+ {
+ if (unitTarget->IsImmunedToSpellEffect(m_spellInfo,EFFECT_1) || unitTarget->GetTypeId() == TYPEID_PLAYER)
+ {
+ m_damage = 0;
+ return;
+ }
+ }
break;
}
case SPELLFAMILY_ROGUE:
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index a931f759163..7995087f2c1 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -450,6 +450,7 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const
if (!basePointsPerLevel && (_spellInfo->Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION && _spellInfo->SpellLevel) &&
Effect != SPELL_EFFECT_WEAPON_PERCENT_DAMAGE &&
Effect != SPELL_EFFECT_KNOCK_BACK &&
+ Effect != SPELL_EFFECT_ADD_EXTRA_ATTACKS &&
ApplyAuraName != SPELL_AURA_MOD_SPEED_ALWAYS &&
ApplyAuraName != SPELL_AURA_MOD_SPEED_NOT_STACK &&
ApplyAuraName != SPELL_AURA_MOD_INCREASE_SPEED &&
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 06e4978eb58..d9459b11ba1 100755
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -3045,6 +3045,9 @@ void SpellMgr::LoadDbcDataCorrections()
case 48246: // Ball of Flame
spellInfo->MaxAffectedTargets = 1;
break;
+ case 36384: // Skartax Purple Beam
+ spellInfo->MaxAffectedTargets = 2;
+ break;
case 41376: // Spite
case 39992: // Needle Spine
case 29576: // Multi-Shot
@@ -3084,7 +3087,7 @@ void SpellMgr::LoadDbcDataCorrections()
case 50312: // Unholy Frenzy
spellInfo->MaxAffectedTargets = 15;
break;
- case 33711: //Murmur's Touch
+ case 33711: // Murmur's Touch
case 38794:
spellInfo->MaxAffectedTargets = 1;
spellInfo->EffectTriggerSpell[0] = 33760;
@@ -3238,6 +3241,9 @@ void SpellMgr::LoadDbcDataCorrections()
spellInfo->EffectDieSides[0] = 0; // was 1, that should probably mean seat 0, but instead it's treated as spell 1
spellInfo->EffectBasePoints[0] = 52391; // Ride Vehicle (forces seat 0)
break;
+ case 45602: // Ride Carpet
+ spellInfo->EffectBasePoints[EFFECT_0] = 0; // force seat 0, vehicle doesn't have the required seat flags for "no seat specified (-1)"
+ break;
case 64745: // Item - Death Knight T8 Tank 4P Bonus
case 64936: // Item - Warrior T8 Protection 4P Bonus
spellInfo->EffectBasePoints[0] = 100; // 100% chance of procc'ing, not -10% (chance calculated in PrepareTriggersExecutedOnHit)
diff --git a/src/server/game/Warden/Warden.cpp b/src/server/game/Warden/Warden.cpp
index 0734e0a0f63..cc1c2ff50c6 100644
--- a/src/server/game/Warden/Warden.cpp
+++ b/src/server/game/Warden/Warden.cpp
@@ -188,7 +188,11 @@ std::string Warden::Penalty(WardenCheck* check /*= NULL*/)
std::string accountName;
AccountMgr::GetName(_session->GetAccountId(), accountName);
std::stringstream banReason;
- banReason << "Warden Anticheat Violation: " << check->Comment << " (CheckId: " << check->CheckId << ")";
+ banReason << "Warden Anticheat Violation";
+ // Check can be NULL, for example if the client sent a wrong signature in the warden packet (CHECKSUM FAIL)
+ if (check)
+ banReason << ": " << check->Comment << " (CheckId: " << check->CheckId << ")";
+
sWorld->BanAccount(BAN_ACCOUNT, accountName, duration.str(), banReason.str(),"Server");
return "Ban";
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index fa4943ce625..3aee1dc429e 100755
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1411,15 +1411,9 @@ void World::SetInitialWorldSettings()
sLog->outString("Loading Creature Addon Data...");
sObjectMgr->LoadCreatureAddons(); // must be after LoadCreatureTemplates() and LoadCreatures()
- sLog->outString("Loading Creature Respawn Data..."); // must be after PackInstances()
- sObjectMgr->LoadCreatureRespawnTimes();
-
sLog->outString("Loading Gameobject Data...");
sObjectMgr->LoadGameobjects();
- sLog->outString("Loading Gameobject Respawn Data..."); // must be after PackInstances()
- sObjectMgr->LoadGameobjectRespawnTimes();
-
sLog->outString("Loading Creature Linked Respawn...");
sObjectMgr->LoadLinkedRespawn(); // must be after LoadCreatures(), LoadGameObjects()
diff --git a/src/server/scripts/Kalimdor/winterspring.cpp b/src/server/scripts/Kalimdor/winterspring.cpp
index a02156ee110..2c4da0fdf7c 100644
--- a/src/server/scripts/Kalimdor/winterspring.cpp
+++ b/src/server/scripts/Kalimdor/winterspring.cpp
@@ -18,15 +18,13 @@
/* ScriptData
SDName: Winterspring
-SD%Complete: 90
-SDComment: Quest support: 5126 (Loraxs' tale missing proper gossip items text). Vendor Rivern Frostwind. Obtain Cache of Mau'ari
+SD%Complete: Almost Completely Emptied
+SDComment: Vendor Rivern Frostwind.
SDCategory: Winterspring
EndScriptData */
/* ContentData
-npc_lorax
npc_rivern_frostwind
-npc_witch_doctor_mauari
EndContentData */
#include "ScriptMgr.h"
@@ -34,71 +32,6 @@ EndContentData */
#include "ScriptedGossip.h"
/*######
-## npc_lorax
-######*/
-
-#define GOSSIP_HL "Talk to me"
-
-#define GOSSIP_SL1 "What do you do here?"
-#define GOSSIP_SL2 "I can help you"
-#define GOSSIP_SL3 "What deal?"
-#define GOSSIP_SL4 "Then what happened?"
-#define GOSSIP_SL5 "He is not safe, i'll make sure of that."
-
-class npc_lorax : public CreatureScript
-{
-public:
- npc_lorax() : CreatureScript("npc_lorax") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
- player->SEND_GOSSIP_MENU(3759, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->SEND_GOSSIP_MENU(3760, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(3761, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+3:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
- player->SEND_GOSSIP_MENU(3762, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+4:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
- player->SEND_GOSSIP_MENU(3763, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+5:
- player->CLOSE_GOSSIP_MENU();
- player->AreaExploredOrEventHappens(5126);
- break;
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature)
- {
- if (creature->isQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(5126) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
-
- return true;
- }
-
-};
-
-/*######
## npc_rivern_frostwind
######*/
@@ -131,49 +64,7 @@ public:
};
-/*######
-## npc_witch_doctor_mauari
-######*/
-
-#define GOSSIP_HWDM "I'd like you to make me a new Cache of Mau'ari please."
-
-class npc_witch_doctor_mauari : public CreatureScript
-{
-public:
- npc_witch_doctor_mauari() : CreatureScript("npc_witch_doctor_mauari") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
- {
- player->PlayerTalkClass->ClearMenus();
- if (action == GOSSIP_ACTION_INFO_DEF+1)
- {
- player->CLOSE_GOSSIP_MENU();
- creature->CastSpell(player, 16351, false);
- }
-
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature)
- {
- if (creature->isQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestRewardStatus(975))
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HWDM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- player->SEND_GOSSIP_MENU(3377, creature->GetGUID());
- }
- else
- player->SEND_GOSSIP_MENU(3375, creature->GetGUID());
-
- return true;
- }
-};
-
void AddSC_winterspring()
{
- new npc_lorax();
new npc_rivern_frostwind();
- new npc_witch_doctor_mauari();
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
index 734639a8b51..9baf6ba7a00 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
@@ -651,7 +651,7 @@ class npc_spinestalker : public CreatureScript
// Increase add count
if (!me->isDead())
{
- _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1); // this cannot be in Reset because reset also happens on evade
+ _instance->SetData64(DATA_SINDRAGOSA_FROSTWYRMS, me->GetGUID()); // this cannot be in Reset because reset also happens on evade
Reset();
}
}
@@ -674,13 +674,12 @@ class npc_spinestalker : public CreatureScript
void JustRespawned()
{
ScriptedAI::JustRespawned();
- _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1); // this cannot be in Reset because reset also happens on evade
+ _instance->SetData64(DATA_SINDRAGOSA_FROSTWYRMS, me->GetGUID()); // this cannot be in Reset because reset also happens on evade
}
void JustDied(Unit* /*killer*/)
{
_events.Reset();
- _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 0);
}
void DoAction(int32 const action)
@@ -778,7 +777,7 @@ class npc_rimefang : public CreatureScript
// Increase add count
if (!me->isDead())
{
- _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1); // this cannot be in Reset because reset also happens on evade
+ _instance->SetData64(DATA_SINDRAGOSA_FROSTWYRMS, me->GetGUID()); // this cannot be in Reset because reset also happens on evade
Reset();
}
}
@@ -801,13 +800,12 @@ class npc_rimefang : public CreatureScript
void JustRespawned()
{
ScriptedAI::JustRespawned();
- _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1); // this cannot be in Reset because reset also happens on evade
+ _instance->SetData64(DATA_SINDRAGOSA_FROSTWYRMS, me->GetGUID()); // this cannot be in Reset because reset also happens on evade
}
void JustDied(Unit* /*killer*/)
{
_events.Reset();
- _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 0);
}
void DoAction(int32 const action)
@@ -934,7 +932,8 @@ class npc_sindragosa_trash : public CreatureScript
// Increase add count
if (!me->isDead())
{
- _instance->SetData(_frostwyrmId, 1); // this cannot be in Reset because reset also happens on evade
+ if (me->GetEntry() == NPC_FROSTWING_WHELP)
+ _instance->SetData64(_frostwyrmId, me->GetGUID()); // this cannot be in Reset because reset also happens on evade
Reset();
}
}
@@ -956,13 +955,8 @@ class npc_sindragosa_trash : public CreatureScript
ScriptedAI::JustRespawned();
// Increase add count
- _instance->SetData(_frostwyrmId, 1); // this cannot be in Reset because reset also happens on evade
- }
-
- void JustDied(Unit* /*killer*/)
- {
- // Decrease add count
- _instance->SetData(_frostwyrmId, 0);
+ if (me->GetEntry() == NPC_FROSTWING_WHELP)
+ _instance->SetData64(_frostwyrmId, me->GetGUID()); // this cannot be in Reset because reset also happens on evade
}
void SetData(uint32 type, uint32 data)
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
index cb83efc748f..288fde28c38 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
@@ -89,6 +89,13 @@ WeeklyQuest const WeeklyQuestData[WeeklyNPCs] =
{NPC_VALITHRIA_DREAMWALKER_QUEST, {QUEST_RESPITE_FOR_A_TORNMENTED_SOUL_10, QUEST_RESPITE_FOR_A_TORNMENTED_SOUL_25}}, // Respite for a Tormented Soul
};
+enum FrostwyrmFlags
+{
+ FLAG_SPINESTALKER_SUMMONED = 0x01,
+ FLAG_RIMEFANG_SUMMONED = 0x02,
+ FLAG_SINDRAGOSA_SUMMONED = 0x04,
+};
+
class instance_icecrown_citadel : public InstanceMapScript
{
public:
@@ -138,9 +145,6 @@ class instance_icecrown_citadel : public InstanceMapScript
FrozenThroneEdgeGUID = 0;
FrozenThroneWindGUID = 0;
FrozenThroneWarningGUID = 0;
- FrostwyrmCount = 0;
- SpinestalkerTrashCount = 0;
- RimefangTrashCount = 0;
IsBonedEligible = true;
IsOozeDanceEligible = true;
IsNauseaEligible = true;
@@ -148,6 +152,7 @@ class instance_icecrown_citadel : public InstanceMapScript
ColdflameJetsState = NOT_STARTED;
BloodQuickeningState = NOT_STARTED;
BloodQuickeningMinutes = 0;
+ FrostwyrmFlags = 0;
}
void FillInitialWorldStates(WorldPacket& data)
@@ -279,9 +284,13 @@ class instance_icecrown_citadel : public InstanceMapScript
break;
case NPC_SPINESTALKER:
SpinestalkerGUID = creature->GetGUID();
+ if (!creature->isAlive())
+ FrostwyrmFlags |= FLAG_SPINESTALKER_SUMMONED;
break;
case NPC_RIMEFANG:
RimefangGUID = creature->GetGUID();
+ if (!creature->isAlive())
+ FrostwyrmFlags |= FLAG_RIMEFANG_SUMMONED;
break;
case NPC_THE_LICH_KING:
TheLichKingGUID = creature->GetGUID();
@@ -347,6 +356,56 @@ class instance_icecrown_citadel : public InstanceMapScript
if (Creature* crok = instance->GetCreature(CrokScourgebaneGUID))
crok->AI()->SetGUID(creature->GetGUID(), ACTION_VRYKUL_DEATH);
break;
+ case NPC_FROSTWING_WHELP:
+ if (creature->AI()->GetData(1/*DATA_FROSTWYRM_OWNER*/) == DATA_SPINESTALKER)
+ {
+ if (FrostwyrmFlags & FLAG_SPINESTALKER_SUMMONED)
+ return;
+
+ SpinestalkerTrash.erase(creature->GetGUID());
+ if (SpinestalkerTrash.empty())
+ {
+ FrostwyrmFlags |= FLAG_SPINESTALKER_SUMMONED;
+ if (Creature* spinestalk = instance->GetCreature(SpinestalkerGUID))
+ spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM);
+ }
+ }
+ else
+ {
+ if (FrostwyrmFlags & FLAG_RIMEFANG_SUMMONED)
+ return;
+
+ RimefangTrash.erase(creature->GetGUID());
+ if (RimefangTrash.empty())
+ {
+ FrostwyrmFlags |= FLAG_RIMEFANG_SUMMONED;
+ if (Creature* spinestalk = instance->GetCreature(RimefangGUID))
+ spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM);
+ }
+ }
+ break;
+ case NPC_RIMEFANG:
+ case NPC_SPINESTALKER:
+ {
+ if (FrostwyrmFlags & FLAG_SINDRAGOSA_SUMMONED)
+ return;
+
+ if (instance->IsHeroic() && !HeroicAttempts)
+ return;
+
+ if (GetBossState(DATA_SINDRAGOSA) == DONE)
+ return;
+
+ FrostwyrmGUIDs.erase(creature->GetGUID());
+ if (FrostwyrmGUIDs.empty())
+ {
+ FrostwyrmFlags |= FLAG_SINDRAGOSA_SUMMONED;
+ instance->LoadGrid(SindragosaSpawnPos.GetPositionX(), SindragosaSpawnPos.GetPositionY());
+ if (Creature* boss = instance->SummonCreature(NPC_SINDRAGOSA, SindragosaSpawnPos))
+ boss->AI()->DoAction(ACTION_START_FROSTWYRM);
+ }
+ break;
+ }
default:
break;
}
@@ -538,11 +597,17 @@ class instance_icecrown_citadel : public InstanceMapScript
switch (type)
{
case DATA_SINDRAGOSA_FROSTWYRMS:
- return FrostwyrmCount;
+ if (FrostwyrmFlags & FLAG_SINDRAGOSA_SUMMONED)
+ return 255;
+ return FrostwyrmGUIDs.size();
case DATA_SPINESTALKER:
- return SpinestalkerTrashCount;
+ if (FrostwyrmFlags & FLAG_SPINESTALKER_SUMMONED)
+ return 255;
+ return SpinestalkerTrash.size();
case DATA_RIMEFANG:
- return RimefangTrashCount;
+ if (FrostwyrmFlags & FLAG_RIMEFANG_SUMMONED)
+ return 255;
+ return RimefangTrash.size();
case DATA_COLDFLAME_JETS:
return ColdflameJetsState;
case DATA_TEAM_IN_INSTANCE:
@@ -741,6 +806,9 @@ class instance_icecrown_citadel : public InstanceMapScript
sindra->DespawnOrUnsummon();
}
}
+ // Reached when loading from DB
+ if (state == DONE)
+ FrostwyrmFlags |= FLAG_SINDRAGOSA_SUMMONED;
break;
case DATA_THE_LICH_KING:
{
@@ -798,89 +866,17 @@ class instance_icecrown_citadel : public InstanceMapScript
IsOrbWhispererEligible = data ? true : false;
break;
case DATA_SINDRAGOSA_FROSTWYRMS:
- {
- if (FrostwyrmCount == 255)
- return;
-
- if (instance->IsHeroic() && !HeroicAttempts)
- return;
-
- if (GetBossState(DATA_SINDRAGOSA) == DONE)
- return;
-
- switch (data)
- {
- case 0:
- if (FrostwyrmCount)
- {
- --FrostwyrmCount;
- if (!FrostwyrmCount)
- {
- instance->LoadGrid(SindragosaSpawnPos.GetPositionX(), SindragosaSpawnPos.GetPositionY());
- if (Creature* boss = instance->SummonCreature(NPC_SINDRAGOSA, SindragosaSpawnPos))
- boss->AI()->DoAction(ACTION_START_FROSTWYRM);
- }
- }
- break;
- case 1:
- ++FrostwyrmCount;
- break;
- default:
- FrostwyrmCount = data;
- break;
- }
+ if (data == 255)
+ FrostwyrmFlags |= FLAG_SINDRAGOSA_SUMMONED;
break;
- }
case DATA_SPINESTALKER:
- {
- if (SpinestalkerTrashCount == 255)
- return;
-
- switch (data)
- {
- case 0:
- if (SpinestalkerTrashCount)
- {
- --SpinestalkerTrashCount;
- if (!SpinestalkerTrashCount)
- if (Creature* spinestalk = instance->GetCreature(SpinestalkerGUID))
- spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM);
- }
- break;
- case 1:
- ++SpinestalkerTrashCount;
- break;
- default:
- SpinestalkerTrashCount = data;
- break;
- }
+ if (data == 255)
+ FrostwyrmFlags |= FLAG_SPINESTALKER_SUMMONED;
break;
- }
case DATA_RIMEFANG:
- {
- if (RimefangTrashCount == 255)
- return;
-
- switch (data)
- {
- case 0:
- if (RimefangTrashCount)
- {
- --RimefangTrashCount;
- if (!RimefangTrashCount)
- if (Creature* rime = instance->GetCreature(RimefangGUID))
- rime->AI()->DoAction(ACTION_START_FROSTWYRM);
- }
- break;
- case 1:
- ++RimefangTrashCount;
- break;
- default:
- RimefangTrashCount = data;
- break;
- }
+ if (data == 255)
+ FrostwyrmFlags |= FLAG_RIMEFANG_SUMMONED;
break;
- }
case DATA_COLDFLAME_JETS:
ColdflameJetsState = data;
if (ColdflameJetsState == DONE)
@@ -922,6 +918,22 @@ class instance_icecrown_citadel : public InstanceMapScript
}
}
+ void SetData64(uint32 id, uint64 data)
+ {
+ switch (id)
+ {
+ case DATA_SINDRAGOSA_FROSTWYRMS:
+ FrostwyrmGUIDs.insert(data);
+ break;
+ case DATA_SPINESTALKER:
+ SpinestalkerTrash.insert(data);
+ break;
+ case DATA_RIMEFANG:
+ RimefangTrash.insert(data);
+ break;
+ }
+ }
+
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/, uint32 /*miscvalue1*/)
{
switch (criteria_id)
@@ -1289,12 +1301,13 @@ class instance_icecrown_citadel : public InstanceMapScript
uint64 PillarsUnchainedGUID;
uint32 TeamInInstance;
uint32 ColdflameJetsState;
- uint32 FrostwyrmCount;
- uint32 SpinestalkerTrashCount;
- uint32 RimefangTrashCount;
+ std::set<uint64> FrostwyrmGUIDs;
+ std::set<uint64> SpinestalkerTrash;
+ std::set<uint64> RimefangTrash;
uint32 BloodQuickeningState;
uint32 HeroicAttempts;
uint16 BloodQuickeningMinutes;
+ uint16 FrostwyrmFlags;
bool IsBonedEligible;
bool IsOozeDanceEligible;
bool IsNauseaEligible;
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
index c7091b42c5a..a2044854672 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
@@ -170,7 +170,11 @@ enum AchievementCredits
ACHIEV_MUST_DECONSTRUCT_FASTER = 21027,
};
-#define HEART_VEHICLE_SEAT 0
+enum VehicleSeats
+{
+ HEART_VEHICLE_SEAT_NORMAL = 0,
+ HEART_VEHICLE_SEAT_EXPOSED = 1,
+};
/*-------------------------------------------------------
*
@@ -198,6 +202,8 @@ class boss_xt002 : public CreatureScript
_Reset();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ DoCast(me, SPELL_STAND);
_healthRecovered = false;
_gravityBombCasualty = false;
@@ -356,15 +362,16 @@ class boss_xt002 : public CreatureScript
me->AttackStop();
me->SetReactState(REACT_PASSIVE);
- Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT) : NULL;
+ Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT_NORMAL) : NULL;
if (heart)
{
heart->CastSpell(heart, SPELL_HEART_OVERLOAD, false);
heart->CastSpell(me, SPELL_HEART_LIGHTNING_TETHER, false);
heart->CastSpell(heart, SPELL_HEART_HEAL_TO_FULL, true);
heart->CastSpell(heart, SPELL_EXPOSED_HEART, false); // Channeled
-
- heart->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ heart->ChangeSeat(HEART_VEHICLE_SEAT_EXPOSED, true);
+ heart->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ heart->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
}
events.CancelEvent(EVENT_SEARING_LIGHT);
@@ -392,11 +399,13 @@ class boss_xt002 : public CreatureScript
events.RescheduleEvent(EVENT_GRAVITY_BOMB, TIMER_GRAVITY_BOMB);
events.RescheduleEvent(EVENT_TYMPANIC_TANTRUM, urand(TIMER_TYMPANIC_TANTRUM_MIN, TIMER_TYMPANIC_TANTRUM_MAX));
- Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT) : NULL;
+ Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT_EXPOSED) : NULL;
if (!heart)
return;
- heart->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ heart->ChangeSeat(HEART_VEHICLE_SEAT_NORMAL, false);
+ heart->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ heart->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
heart->RemoveAurasDueToSpell(SPELL_EXPOSED_HEART);
if (!_hardMode)
@@ -425,43 +434,39 @@ class boss_xt002 : public CreatureScript
* XT-002 HEART
*
*///----------------------------------------------------
+
class mob_xt002_heart : public CreatureScript
{
public:
mob_xt002_heart() : CreatureScript("mob_xt002_heart") { }
- CreatureAI* GetAI(Creature* creature) const
+ struct mob_xt002_heartAI : public Scripted_NoMovementAI
{
- return new mob_xt002_heartAI(creature);
- }
-
- struct mob_xt002_heartAI : public ScriptedAI
- {
- mob_xt002_heartAI(Creature* creature) : ScriptedAI(creature)
+ mob_xt002_heartAI(Creature* creature) : Scripted_NoMovementAI(creature),
+ _instance(creature->GetInstanceScript())
{
- _instance = creature->GetInstanceScript();
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_STUNNED | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- me->SetReactState(REACT_PASSIVE);
}
- void DamageTaken(Unit* /*pDone*/, uint32 &damage)
+ void UpdateAI(uint32 const /*diff*/) { }
+
+ void JustDied(Unit* /*killer*/)
{
- Creature* xt002 = me->GetCreature(*me, _instance->GetData64(BOSS_XT002));
+ Creature* xt002 = _instance ? me->GetCreature(*me, _instance->GetData64(BOSS_XT002)) : NULL;
if (!xt002 || !xt002->AI())
return;
- if (damage >= me->GetHealth())
- {
- xt002->AI()->SetData(DATA_TRANSFERED_HEALTH, me->GetMaxHealth());
- xt002->AI()->DoAction(ACTION_ENTER_HARD_MODE);
- damage = 0;
- }
+ xt002->AI()->SetData(DATA_TRANSFERED_HEALTH, me->GetHealth());
+ xt002->AI()->DoAction(ACTION_ENTER_HARD_MODE);
}
- private:
- InstanceScript* _instance;
- uint32 _damageTaken;
+ private:
+ InstanceScript* _instance;
};
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_xt002_heartAI(creature);
+ }
};
/*-------------------------------------------------------
@@ -915,7 +920,7 @@ class spell_xt002_heart_overload_periodic : public SpellScriptLoader
{
uint8 a = urand(0, 4);
uint32 spellId = spells[a];
- toyPile->CastSpell(toyPile, spellId, true);
+ toyPile->CastSpell(toyPile, spellId, true, NULL, NULL, instance->GetData64(BOSS_XT002));
}
}
}
diff --git a/src/server/scripts/Northrend/dragonblight.cpp b/src/server/scripts/Northrend/dragonblight.cpp
index 4cbe280a9f2..1b339b24549 100644
--- a/src/server/scripts/Northrend/dragonblight.cpp
+++ b/src/server/scripts/Northrend/dragonblight.cpp
@@ -69,7 +69,106 @@ public:
}
};
+/*######
+## Quest Strengthen the Ancients (12096|12092)
+######*/
+
+enum StrengthenAncientsMisc
+{
+ SAY_WALKER_FRIENDLY = 0,
+ SAY_WALKER_ENEMY = 1,
+ SAY_LOTHALOR = 0,
+
+ SPELL_CREATE_ITEM_BARK = 47550,
+ SPELL_CONFUSED = 47044,
+
+ NPC_LOTHALOR = 26321,
+
+ FACTION_WALKER_ENEMY = 14,
+};
+
+class spell_q12096_q12092_dummy : public SpellScriptLoader // Strengthen the Ancients: On Interact Dummy to Woodlands Walker
+{
+public:
+ spell_q12096_q12092_dummy() : SpellScriptLoader("spell_q12096_q12092_dummy") { }
+
+ class spell_q12096_q12092_dummy_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q12096_q12092_dummy_SpellScript);
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ uint32 roll = rand() % 2;
+
+ Creature* tree = GetHitCreature();
+ Player* player = GetCaster()->ToPlayer();
+
+ if (!tree || !player)
+ return;
+
+ tree->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+
+ if (roll == 1) // friendly version
+ {
+ tree->CastSpell(player, SPELL_CREATE_ITEM_BARK);
+ tree->AI()->Talk(SAY_WALKER_FRIENDLY, player->GetGUID());
+ tree->DespawnOrUnsummon(1000);
+ }
+ else if (roll == 0) // enemy version
+ {
+ tree->AI()->Talk(SAY_WALKER_ENEMY, player->GetGUID());
+ tree->setFaction(FACTION_WALKER_ENEMY);
+ tree->Attack(player, true);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_q12096_q12092_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_q12096_q12092_dummy_SpellScript();
+ }
+};
+
+class spell_q12096_q12092_bark : public SpellScriptLoader // Bark of the Walkers
+{
+public:
+ spell_q12096_q12092_bark() : SpellScriptLoader("spell_q12096_q12092_bark") { }
+
+ class spell_q12096_q12092_bark_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q12096_q12092_bark_SpellScript);
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ Creature* lothalor = GetHitCreature();
+ if (!lothalor || lothalor->GetEntry() != NPC_LOTHALOR)
+ return;
+
+ lothalor->AI()->Talk(SAY_LOTHALOR);
+ lothalor->RemoveAura(SPELL_CONFUSED);
+ lothalor->DespawnOrUnsummon(4000);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_q12096_q12092_bark_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_q12096_q12092_bark_SpellScript();
+ }
+};
+
void AddSC_dragonblight()
{
new npc_alexstrasza_wr_gate;
+ new spell_q12096_q12092_dummy;
+ new spell_q12096_q12092_bark;
}
diff --git a/src/server/scripts/Outland/netherstorm.cpp b/src/server/scripts/Outland/netherstorm.cpp
index afc18c71b92..16dac13d1a9 100644
--- a/src/server/scripts/Outland/netherstorm.cpp
+++ b/src/server/scripts/Outland/netherstorm.cpp
@@ -777,10 +777,10 @@ public:
PlayerGUID = who->GetGUID();
}
- void SpellHit(Unit* /*caster*/, const SpellInfo* /*spell*/)
- {
- DoCast(me, SPELL_DE_MATERIALIZE);
- }
+ //void SpellHit(Unit* /*caster*/, const SpellInfo* /*spell*/)
+ //{
+ // DoCast(me, SPELL_DE_MATERIALIZE);
+ //}
void UpdateAI(const uint32 diff)
{
diff --git a/src/server/scripts/Spells/CMakeLists.txt b/src/server/scripts/Spells/CMakeLists.txt
index 04dcee9287c..2bb695bd8a9 100644
--- a/src/server/scripts/Spells/CMakeLists.txt
+++ b/src/server/scripts/Spells/CMakeLists.txt
@@ -24,6 +24,7 @@ set(scripts_STAT_SRCS
Spells/spell_paladin.cpp
Spells/spell_item.cpp
Spells/spell_holiday.cpp
+ Spells/spell_pet.cpp
)
message(" -> Prepared: Spells")
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index 36dcb53ad00..c33ca548d73 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -381,6 +381,13 @@ class spell_dk_scourge_strike : public SpellScriptLoader
class spell_dk_scourge_strike_SpellScript : public SpellScript
{
PrepareSpellScript(spell_dk_scourge_strike_SpellScript);
+ float multiplier;
+
+ bool Load()
+ {
+ multiplier = 1.0f;
+ return true;
+ }
bool Validate(SpellInfo const* /*spellEntry*/)
{
@@ -393,8 +400,15 @@ class spell_dk_scourge_strike : public SpellScriptLoader
{
Unit* caster = GetCaster();
if (Unit* unitTarget = GetHitUnit())
+ multiplier = (GetEffectValue() * unitTarget->GetDiseasesByCaster(caster->GetGUID()) / 100.f);
+ }
+
+ void HandleAfterHit()
+ {
+ Unit* caster = GetCaster();
+ if (Unit* unitTarget = GetHitUnit())
{
- int32 bp = CalculatePctN(GetHitDamage(), GetEffectValue() * unitTarget->GetDiseasesByCaster(caster->GetGUID()));
+ int32 bp = GetHitDamage() * multiplier;
caster->CastCustomSpell(unitTarget, DK_SPELL_SCOURGE_STRIKE_TRIGGERED, &bp, NULL, NULL, true);
}
}
@@ -402,6 +416,7 @@ class spell_dk_scourge_strike : public SpellScriptLoader
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_dk_scourge_strike_SpellScript::HandleDummy, EFFECT_2, SPELL_EFFECT_DUMMY);
+ AfterHit += SpellHitFn(spell_dk_scourge_strike_SpellScript::HandleAfterHit);
}
};
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index e23e21cf2cd..5b65d0ca763 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -660,22 +660,16 @@ class spell_pvp_trinket_wotf_shared_cd : public SpellScriptLoader
return true;
}
- void HandleScript(SpellEffIndex /*effIndex*/)
+ void HandleScript()
{
- Player* caster = GetCaster()->ToPlayer();
- SpellInfo const* spellInfo = GetSpellInfo();
- caster->AddSpellCooldown(spellInfo->Id, 0, time(NULL) + sSpellMgr->GetSpellInfo(SPELL_WILL_OF_THE_FORSAKEN_COOLDOWN_TRIGGER)->GetRecoveryTime() / IN_MILLISECONDS);
- WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+4);
- data << uint64(caster->GetGUID());
- data << uint8(0);
- data << uint32(spellInfo->Id);
- data << uint32(0);
- caster->GetSession()->SendPacket(&data);
+ // This is only needed because spells cast from spell_linked_spell are triggered by default
+ // Spell::SendSpellCooldown() skips all spells with TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
+ GetCaster()->ToPlayer()->AddSpellAndCategoryCooldowns(GetSpellInfo(), GetCastItem() ? GetCastItem()->GetEntry() : 0, GetSpell());
}
void Register()
{
- OnEffectHit += SpellEffectFn(spell_pvp_trinket_wotf_shared_cd_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ AfterCast += SpellCastFn(spell_pvp_trinket_wotf_shared_cd_SpellScript::HandleScript);
}
};
@@ -2697,7 +2691,7 @@ public:
{
PrepareSpellScript(spell_gen_touch_the_nightmare_SpellScript);
- void HandleDamageCalc(SpellEffIndex effIndex)
+ void HandleDamageCalc(SpellEffIndex /*effIndex*/)
{
uint32 bp = GetCaster()->GetMaxHealth() * 0.3f;
SetHitDamage(bp);
diff --git a/src/server/scripts/Spells/spell_pet.cpp b/src/server/scripts/Spells/spell_pet.cpp
new file mode 100644
index 00000000000..6ed0f18c785
--- /dev/null
+++ b/src/server/scripts/Spells/spell_pet.cpp
@@ -0,0 +1,1752 @@
+/*
+ * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Scripts for spells with SPELLFAMILY_DEATHKNIGHT and SPELLFAMILY_GENERIC spells used by deathknight players.
+ * Ordered alphabetically using scriptname.
+ * Scriptnames of files in this file should be prefixed with "spell_dk_".
+ */
+
+#include "ScriptMgr.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
+#include "Unit.h"
+#include "Player.h"
+#include "Pet.h"
+
+enum HunterPetCalculate
+{
+ SPELL_TAMED_PET_PASSIVE_06 = 19591,
+ SPELL_TAMED_PET_PASSIVE_07 = 20784,
+ SPELL_TAMED_PET_PASSIVE_08 = 34666,
+ SPELL_TAMED_PET_PASSIVE_09 = 34667,
+ SPELL_TAMED_PET_PASSIVE_10 = 34675,
+ SPELL_HUNTER_PET_SCALING_01 = 34902,
+ SPELL_HUNTER_PET_SCALING_02 = 34903,
+ SPELL_HUNTER_PET_SCALING_03 = 34904,
+ SPELL_HUNTER_PET_SCALING_04 = 61017,
+ SPELL_HUNTER_ANIMAL_HANDLER = 34453,
+};
+
+enum WarlockPetCalculate
+{
+ SPELL_PET_PASSIVE_CRIT = 35695,
+ SPELL_PET_PASSIVE_DAMAGE_TAKEN = 35697,
+ SPELL_WARLOCK_PET_SCALING_01 = 34947,
+ SPELL_WARLOCK_PET_SCALING_02 = 34956,
+ SPELL_WARLOCK_PET_SCALING_03 = 34957,
+ SPELL_WARLOCK_PET_SCALING_04 = 34958,
+ SPELL_WARLOCK_PET_SCALING_05 = 61013,
+ ENTRY_FELGUARD = 17252,
+ ENTRY_VOIDWALKER = 1860,
+ ENTRY_FELHUNTER = 417,
+ ENTRY_SUCCUBUS = 1863,
+ ENTRY_IMP = 416,
+ SPELL_WARLOCK_GLYPH_OF_VOIDWALKER = 56247,
+};
+
+enum DKPetCalculate
+{
+ SPELL_DEATH_KNIGHT_RUNE_WEAPON_02 = 51906,
+ SPELL_DEATH_KNIGHT_PET_SCALING_01 = 54566,
+ SPELL_DEATH_KNIGHT_PET_SCALING_02 = 51996,
+ SPELL_DEATH_KNIGHT_PET_SCALING_03 = 61697,
+ SPELL_NIGHT_OF_THE_DEAD = 55620,
+ ENTRY_ARMY_OF_THE_DEAD_GHOUL = 24207,
+ SPELL_DEATH_KNIGHT_GLYPH_OF_GHOUL = 58686,
+};
+
+enum ShamanPetCalculate
+{
+ SPELL_FERAL_SPIRIT_PET_UNK_01 = 35674,
+ SPELL_FERAL_SPIRIT_PET_UNK_02 = 35675,
+ SPELL_FERAL_SPIRIT_PET_UNK_03 = 35676,
+ SPELL_FERAL_SPIRIT_PET_SCALING_04 = 61783,
+};
+
+enum MiscPetCalculate
+{
+ SPELL_MAGE_PET_PASSIVE_ELEMENTAL = 44559,
+ SPELL_PET_HEALTH_SCALING = 61679,
+ SPELL_PET_UNK_01 = 67561,
+ SPELL_PET_UNK_02 = 67557,
+};
+
+class spell_gen_pet_calculate : public SpellScriptLoader
+{
+ public:
+ spell_gen_pet_calculate() : SpellScriptLoader("spell_gen_pet_calculate") { }
+
+ class spell_gen_pet_calculate_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gen_pet_calculate_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountCritSpell(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float CritSpell = 0.0f;
+ // Crit from Intellect
+ CritSpell += owner->GetSpellCritFromIntellect();
+ // Increase crit from SPELL_AURA_MOD_SPELL_CRIT_CHANCE
+ CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_CRIT_CHANCE);
+ // Increase crit from SPELL_AURA_MOD_CRIT_PCT
+ CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT);
+ // Increase crit spell from spell crit ratings
+ CritSpell += owner->GetRatingBonusValue(CR_CRIT_SPELL);
+
+ amount += int32(CritSpell);
+ }
+ }
+
+ void CalculateAmountCritMelee(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float CritMelee = 0.0f;
+ // Crit from Agility
+ CritMelee += owner->GetMeleeCritFromAgility();
+ // Increase crit from SPELL_AURA_MOD_WEAPON_CRIT_PERCENT
+ CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT);
+ // Increase crit from SPELL_AURA_MOD_CRIT_PCT
+ CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT);
+ // Increase crit melee from melee crit ratings
+ CritMelee += owner->GetRatingBonusValue(CR_CRIT_MELEE);
+
+ amount += int32(CritMelee);
+ }
+ }
+
+ void CalculateAmountMeleeHit(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitMelee = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_HIT_CHANCE
+ HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
+ // Increase hit melee from meele hit ratings
+ HitMelee += owner->GetRatingBonusValue(CR_HIT_MELEE);
+
+ amount += int32(HitMelee);
+ }
+ }
+
+ void CalculateAmountSpellHit(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitSpell = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE
+ HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ // Increase hit spell from spell hit ratings
+ HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL);
+
+ amount += int32(HitSpell);
+ }
+ }
+
+ void CalculateAmountExpertise(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float Expertise = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_EXPERTISE
+ Expertise += owner->GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE);
+ // Increase Expertise from Expertise ratings
+ Expertise += owner->GetRatingBonusValue(CR_EXPERTISE);
+
+ amount += int32(Expertise);
+ }
+ }
+
+ void Register()
+ {
+ switch (m_scriptSpellId)
+ {
+ case SPELL_TAMED_PET_PASSIVE_06:
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountCritMelee, EFFECT_0, SPELL_AURA_MOD_WEAPON_CRIT_PERCENT);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountCritSpell, EFFECT_1, SPELL_AURA_MOD_SPELL_CRIT_CHANCE);
+ break;
+ case SPELL_PET_PASSIVE_CRIT:
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountCritSpell, EFFECT_0, SPELL_AURA_MOD_SPELL_CRIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountCritMelee, EFFECT_1, SPELL_AURA_MOD_WEAPON_CRIT_PERCENT);
+ break;
+ case SPELL_WARLOCK_PET_SCALING_05:
+ case SPELL_HUNTER_PET_SCALING_04:
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountExpertise, EFFECT_2, SPELL_AURA_MOD_EXPERTISE);
+ break;
+ case SPELL_DEATH_KNIGHT_PET_SCALING_03:
+// case SPELL_SHAMAN_PET_HIT:
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ break;
+ default:
+ break;
+ }
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_gen_pet_calculate_AuraScript();
+ }
+};
+
+class spell_warl_pet_scaling_01 : public SpellScriptLoader
+{
+public:
+ spell_warl_pet_scaling_01() : SpellScriptLoader("spell_warl_pet_scaling_01") { }
+
+ class spell_warl_pet_scaling_01_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_pet_scaling_01_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ _tempBonus = 0;
+ return true;
+ }
+
+ void CalculateStaminaAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ float ownerBonus = CalculatePctN(owner->GetStat(STAT_STAMINA), 75);
+
+ amount += ownerBonus;
+ }
+ }
+
+ void ApplyEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (_tempBonus)
+ {
+ PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(pet->GetEntry(), pet->getLevel());
+ uint32 healthMod = 0;
+ uint32 baseHealth = pInfo->health;
+ switch (pet->GetEntry())
+ {
+ case ENTRY_IMP:
+ healthMod = uint32(_tempBonus * 8.4f);
+ break;
+ case ENTRY_FELGUARD:
+ case ENTRY_VOIDWALKER:
+ healthMod = _tempBonus * 11;
+ break;
+ case ENTRY_SUCCUBUS:
+ healthMod = uint32(_tempBonus * 9.1f);
+ break;
+ case ENTRY_FELHUNTER:
+ healthMod = uint32(_tempBonus * 9.5f);
+ break;
+ default:
+ healthMod = 0;
+ break;
+ }
+ if (healthMod)
+ pet->ToPet()->SetCreateHealth(baseHealth + healthMod);
+ }
+ }
+
+ void RemoveEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ {
+ PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(pet->GetEntry(), pet->getLevel());
+ pet->ToPet()->SetCreateHealth(pInfo->health);
+ }
+ }
+
+ void CalculateAttackPowerAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ int32 fire = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE);
+ int32 shadow = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_SHADOW);
+ int32 maximum = (fire > shadow) ? fire : shadow;
+ if (maximum < 0)
+ maximum = 0;
+ float bonusAP = maximum * 0.57f;
+
+ amount += bonusAP;
+
+ // Glyph of felguard
+ if (pet->GetEntry() == ENTRY_FELGUARD)
+ {
+ if (AuraEffect* aurEffect = owner->GetAuraEffect(56246, EFFECT_0))
+ {
+ float base_attPower = pet->GetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE) * pet->GetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_PCT);
+ amount += CalculatePctN(amount+base_attPower, aurEffect->GetAmount());
+ }
+ }
+ }
+ }
+
+ void CalculateDamageDoneAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ //the damage bonus used for pets is either fire or shadow damage, whatever is higher
+ int32 fire = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE);
+ int32 shadow = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_SHADOW);
+ int32 maximum = (fire > shadow) ? fire : shadow;
+ float bonusDamage = 0.0f;
+
+ if (maximum > 0)
+ bonusDamage = maximum * 0.15f;
+
+ amount += bonusDamage;
+ }
+ }
+
+ void Register()
+ {
+ OnEffectRemove += AuraEffectRemoveFn(spell_warl_pet_scaling_01_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ AfterEffectApply += AuraEffectApplyFn(spell_warl_pet_scaling_01_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_01_AuraScript::CalculateStaminaAmount, EFFECT_0, SPELL_AURA_MOD_STAT);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_01_AuraScript::CalculateAttackPowerAmount, EFFECT_1, SPELL_AURA_MOD_ATTACK_POWER);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_01_AuraScript::CalculateDamageDoneAmount, EFFECT_2, SPELL_AURA_MOD_DAMAGE_DONE);
+ }
+
+ private:
+ uint32 _tempBonus;
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_warl_pet_scaling_01_AuraScript();
+ }
+};
+
+class spell_warl_pet_scaling_02 : public SpellScriptLoader
+{
+public:
+ spell_warl_pet_scaling_02() : SpellScriptLoader("spell_warl_pet_scaling_02") { }
+
+ class spell_warl_pet_scaling_02_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_pet_scaling_02_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ _tempBonus = 0;
+ return true;
+ }
+
+ void CalculateIntellectAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ float ownerBonus = 0.0f;
+
+ ownerBonus = CalculatePctN(owner->GetStat(STAT_INTELLECT), 30);
+
+ amount += ownerBonus;
+ _tempBonus = ownerBonus;
+ }
+ }
+
+ void ApplyEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (_tempBonus)
+ {
+ PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(pet->GetEntry(), pet->getLevel());
+ uint32 manaMod = 0;
+ uint32 baseMana = pInfo->mana;
+ switch (pet->GetEntry())
+ {
+ case ENTRY_IMP:
+ manaMod = uint32(_tempBonus * 4.9f);
+ break;
+ case ENTRY_VOIDWALKER:
+ case ENTRY_SUCCUBUS:
+ case ENTRY_FELHUNTER:
+ case ENTRY_FELGUARD:
+ manaMod = uint32(_tempBonus * 11.5f);
+ break;
+ default:
+ manaMod = 0;
+ break;
+ }
+ if (manaMod)
+ pet->ToPet()->SetCreateMana(baseMana + manaMod);
+ }
+ }
+
+ void RemoveEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ {
+ PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(pet->GetEntry(), pet->getLevel());
+ pet->ToPet()->SetCreateMana(pInfo->mana);
+ }
+ }
+
+ void CalculateArmorAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ float ownerBonus = 0.0f;
+ ownerBonus = CalculatePctN(owner->GetArmor(), 35);
+ amount += ownerBonus;
+ }
+ }
+
+ void CalculateFireResistanceAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ float ownerBonus = 0.0f;
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_FIRE), 40);
+ amount += ownerBonus;
+ }
+ }
+
+ void Register()
+ {
+ OnEffectRemove += AuraEffectRemoveFn(spell_warl_pet_scaling_02_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ AfterEffectApply += AuraEffectApplyFn(spell_warl_pet_scaling_02_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_02_AuraScript::CalculateIntellectAmount, EFFECT_0, SPELL_AURA_MOD_STAT);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_02_AuraScript::CalculateArmorAmount, EFFECT_1, SPELL_AURA_MOD_RESISTANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_02_AuraScript::CalculateFireResistanceAmount, EFFECT_2, SPELL_AURA_MOD_RESISTANCE);
+ }
+
+ private:
+ uint32 _tempBonus;
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_warl_pet_scaling_02_AuraScript();
+ }
+};
+
+class spell_warl_pet_scaling_03 : public SpellScriptLoader
+{
+public:
+ spell_warl_pet_scaling_03() : SpellScriptLoader("spell_warl_pet_scaling_03") { }
+
+ class spell_warl_pet_scaling_03_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_pet_scaling_03_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateFrostResistanceAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ float ownerBonus = 0.0f;
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_FROST), 40);
+ amount += ownerBonus;
+ }
+ }
+
+ void CalculateArcaneResistanceAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ float ownerBonus = 0.0f;
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_ARCANE), 40);
+ amount += ownerBonus;
+ }
+ }
+
+ void CalculateNatureResistanceAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ float ownerBonus = 0.0f;
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_NATURE), 40);
+ amount += ownerBonus;
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_03_AuraScript::CalculateFrostResistanceAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_03_AuraScript::CalculateArcaneResistanceAmount, EFFECT_1, SPELL_AURA_MOD_RESISTANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_03_AuraScript::CalculateNatureResistanceAmount, EFFECT_2, SPELL_AURA_MOD_RESISTANCE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_warl_pet_scaling_03_AuraScript();
+ }
+};
+
+
+class spell_warl_pet_scaling_04 : public SpellScriptLoader
+{
+public:
+ spell_warl_pet_scaling_04() : SpellScriptLoader("spell_warl_pet_scaling_04") { }
+
+ class spell_warl_pet_scaling_04_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_pet_scaling_04_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateShadowResistanceAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ float ownerBonus = 0.0f;
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_SHADOW), 40);
+ amount += ownerBonus;
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_04_AuraScript::CalculateShadowResistanceAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_warl_pet_scaling_04_AuraScript();
+ }
+};
+
+class spell_warl_pet_scaling_05 : public SpellScriptLoader
+{
+public:
+ spell_warl_pet_scaling_05() : SpellScriptLoader("spell_warl_pet_scaling_05") { }
+
+ class spell_warl_pet_scaling_05_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_pet_scaling_05_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountMeleeHit(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitMelee = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE
+ HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ // Increase hit spell from spell hit ratings
+ HitMelee += owner->GetRatingBonusValue(CR_HIT_SPELL);
+
+ amount += int32(HitMelee);
+ }
+ }
+
+ void CalculateAmountSpellHit(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitSpell = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE
+ HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ // Increase hit spell from spell hit ratings
+ HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL);
+
+ amount += int32(HitSpell);
+ }
+ }
+
+ void CalculateAmountExpertise(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float Expertise = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE
+ Expertise += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ // Increase hit spell from spell hit ratings
+ Expertise += owner->GetRatingBonusValue(CR_HIT_SPELL);
+
+ amount += int32(Expertise);
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_05_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_05_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_05_AuraScript::CalculateAmountExpertise, EFFECT_2, SPELL_AURA_MOD_EXPERTISE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_warl_pet_scaling_05_AuraScript();
+ }
+};
+
+class spell_warl_pet_passive : public SpellScriptLoader
+{
+public:
+ spell_warl_pet_passive() : SpellScriptLoader("spell_warl_pet_passive") { }
+
+ class spell_warl_pet_passive_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_pet_passive_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountCritSpell(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float CritSpell = 0.0f;
+ // Crit from Intellect
+ CritSpell += owner->GetSpellCritFromIntellect();
+ // Increase crit from SPELL_AURA_MOD_SPELL_CRIT_CHANCE
+ CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_CRIT_CHANCE);
+ // Increase crit from SPELL_AURA_MOD_CRIT_PCT
+ CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT);
+ // Increase crit spell from spell crit ratings
+ CritSpell += owner->GetRatingBonusValue(CR_CRIT_SPELL);
+
+ if (AuraApplication* improvedDemonicTacticsApp = owner->GetAuraApplicationOfRankedSpell(54347))
+ if (Aura* improvedDemonicTactics = improvedDemonicTacticsApp->GetBase())
+ if (AuraEffect* improvedDemonicTacticsEffect = improvedDemonicTactics->GetEffect(EFFECT_0))
+ amount += CalculatePctN(CritSpell, improvedDemonicTacticsEffect->GetAmount());
+ }
+ }
+
+ void CalculateAmountCritMelee(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float CritMelee = 0.0f;
+ // Crit from Agility
+ CritMelee += owner->GetMeleeCritFromAgility();
+ // Increase crit from SPELL_AURA_MOD_WEAPON_CRIT_PERCENT
+ CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT);
+ // Increase crit from SPELL_AURA_MOD_CRIT_PCT
+ CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT);
+ // Increase crit melee from melee crit ratings
+ CritMelee += owner->GetRatingBonusValue(CR_CRIT_MELEE);
+
+ if (AuraApplication* improvedDemonicTacticsApp = owner->GetAuraApplicationOfRankedSpell(54347))
+ if (Aura* improvedDemonicTactics = improvedDemonicTacticsApp->GetBase())
+ if (AuraEffect* improvedDemonicTacticsEffect = improvedDemonicTactics->GetEffect(EFFECT_0))
+ amount += CalculatePctN(CritMelee, improvedDemonicTacticsEffect->GetAmount());
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_AuraScript::CalculateAmountCritSpell, EFFECT_0, SPELL_AURA_MOD_SPELL_CRIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_AuraScript::CalculateAmountCritMelee, EFFECT_1, SPELL_AURA_MOD_WEAPON_CRIT_PERCENT);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_warl_pet_passive_AuraScript();
+ }
+};
+// this doesnt actually fit in here
+class spell_warl_pet_passive_damage_done : public SpellScriptLoader
+{
+public:
+ spell_warl_pet_passive_damage_done() : SpellScriptLoader("spell_warl_pet_passive_damage_done") { }
+
+ class spell_warl_pet_passive_damage_done_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_pet_passive_damage_done_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountDamageDone(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ switch (GetCaster()->GetEntry())
+ {
+ case ENTRY_VOIDWALKER:
+ amount += -16;
+ break;
+ case ENTRY_FELHUNTER:
+ amount += -20;
+ break;
+ case ENTRY_SUCCUBUS:
+ case ENTRY_FELGUARD:
+ amount += 5;
+ break;
+ }
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_damage_done_AuraScript::CalculateAmountDamageDone, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_damage_done_AuraScript::CalculateAmountDamageDone, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_warl_pet_passive_damage_done_AuraScript();
+ }
+};
+
+class spell_warl_pet_passive_voidwalker : public SpellScriptLoader
+{
+public:
+ spell_warl_pet_passive_voidwalker() : SpellScriptLoader("spell_warl_pet_passive_voidwalker") { }
+
+ class spell_warl_pet_passive_voidwalker_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_pet_passive_voidwalker_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ if (AuraEffect* aurEffect = owner->GetAuraEffect(SPELL_WARLOCK_GLYPH_OF_VOIDWALKER, EFFECT_0))
+ amount += aurEffect->GetAmount();
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_voidwalker_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_warl_pet_passive_voidwalker_AuraScript();
+ }
+};
+
+
+class spell_sha_pet_scaling_04 : public SpellScriptLoader
+{
+public:
+ spell_sha_pet_scaling_04() : SpellScriptLoader("spell_sha_pet_scaling_04") { }
+
+ class spell_sha_pet_scaling_04_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_sha_pet_scaling_04_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountMeleeHit(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitMelee = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_HIT_CHANCE
+ HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
+ // Increase hit melee from meele hit ratings
+ HitMelee += owner->GetRatingBonusValue(CR_HIT_MELEE);
+
+ amount += int32(HitMelee);
+ }
+ }
+
+ void CalculateAmountSpellHit(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitSpell = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE
+ HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ // Increase hit spell from spell hit ratings
+ HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL);
+
+ amount += int32(HitSpell);
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_sha_pet_scaling_04_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_sha_pet_scaling_04_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_sha_pet_scaling_04_AuraScript();
+ }
+};
+
+class spell_hun_pet_scaling_01 : public SpellScriptLoader
+{
+public:
+ spell_hun_pet_scaling_01() : SpellScriptLoader("spell_hun_pet_scaling_01") { }
+
+ class spell_hun_pet_scaling_01_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_pet_scaling_01_AuraScript);
+
+ void CalculateStaminaAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isPet())
+ return;
+
+ Unit* owner = pet->ToPet()->GetOwner();
+ if (!owner)
+ return;
+
+ float mod = 0.45f;
+ float ownerBonus = 0.0f;
+
+ PetSpellMap::const_iterator itr = (pet->ToPet()->m_spells.find(62758)); // Wild Hunt rank 1
+ if (itr == pet->ToPet()->m_spells.end())
+ itr = pet->ToPet()->m_spells.find(62762); // Wild Hunt rank 2
+
+ if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt
+ {
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
+ AddPctN(mod, spellInfo->Effects[EFFECT_0].CalcValue());
+ }
+
+ ownerBonus = owner->GetStat(STAT_STAMINA)*mod;
+
+ amount += ownerBonus;
+ }
+ }
+
+ void ApplyEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (_tempHealth)
+ pet->SetHealth(_tempHealth);
+ }
+
+ void RemoveEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ _tempHealth = pet->GetHealth();
+ }
+
+ void CalculateAttackPowerAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isPet())
+ return;
+
+ Unit* owner = pet->ToPet()->GetOwner();
+ if (!owner)
+ return;
+
+ float mod = 1.0f; //Hunter contribution modifier
+ float bonusAP = 0.0f;
+
+ PetSpellMap::const_iterator itr = (pet->ToPet()->m_spells.find(62758)); // Wild Hunt rank 1
+ if (itr == pet->ToPet()->m_spells.end())
+ itr = pet->ToPet()->m_spells.find(62762); // Wild Hunt rank 2
+
+ if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt
+ {
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
+ mod += CalculatePctN(1.0f, spellInfo->Effects[EFFECT_1].CalcValue());
+ }
+
+ bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f * mod;
+
+ amount += bonusAP;
+ }
+ }
+
+ void CalculateDamageDoneAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isPet())
+ return;
+
+ Unit* owner = pet->ToPet()->GetOwner();
+ if (!owner)
+ return;
+
+ float mod = 1.0f; //Hunter contribution modifier
+ float bonusDamage = 0.0f;
+
+ PetSpellMap::const_iterator itr = (pet->ToPet()->m_spells.find(62758)); // Wild Hunt rank 1
+ if (itr == pet->ToPet()->m_spells.end())
+ itr = pet->ToPet()->m_spells.find(62762); // Wild Hunt rank 2
+
+ if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt
+ {
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
+ mod += CalculatePctN(1.0f, spellInfo->Effects[EFFECT_1].CalcValue());
+ }
+
+ bonusDamage = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1287f * mod;
+
+ amount += bonusDamage;
+ }
+ }
+
+ void Register()
+ {
+ OnEffectRemove += AuraEffectRemoveFn(spell_hun_pet_scaling_01_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ AfterEffectApply += AuraEffectApplyFn(spell_hun_pet_scaling_01_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_01_AuraScript::CalculateStaminaAmount, EFFECT_0, SPELL_AURA_MOD_STAT);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_01_AuraScript::CalculateAttackPowerAmount, EFFECT_1, SPELL_AURA_MOD_ATTACK_POWER);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_01_AuraScript::CalculateDamageDoneAmount, EFFECT_2, SPELL_AURA_MOD_DAMAGE_DONE);
+ }
+
+ private:
+ uint32 _tempHealth;
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_hun_pet_scaling_01_AuraScript();
+ }
+};
+
+class spell_hun_pet_scaling_02 : public SpellScriptLoader
+{
+public:
+ spell_hun_pet_scaling_02() : SpellScriptLoader("spell_hun_pet_scaling_02") { }
+
+ class spell_hun_pet_scaling_02_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_pet_scaling_02_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateFrostResistanceAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isPet())
+ return;
+
+ Unit* owner = pet->ToPet()->GetOwner();
+ if (!owner)
+ return;
+
+ float ownerBonus = 0.0f;
+
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_FROST), 40);
+
+ amount += ownerBonus;
+ }
+ }
+
+ void CalculateFireResistanceAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isPet())
+ return;
+
+ Unit* owner = pet->ToPet()->GetOwner();
+ if (!owner)
+ return;
+
+ float ownerBonus = 0.0f;
+
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_FIRE), 40);
+
+ amount += ownerBonus;
+ }
+ }
+
+ void CalculateNatureResistanceAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isPet())
+ return;
+
+ Unit* owner = pet->ToPet()->GetOwner();
+ if (!owner)
+ return;
+
+ float ownerBonus = 0.0f;
+
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_NATURE), 40);
+
+ amount += ownerBonus;
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_02_AuraScript::CalculateFrostResistanceAmount, EFFECT_1, SPELL_AURA_MOD_RESISTANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_02_AuraScript::CalculateFireResistanceAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_02_AuraScript::CalculateNatureResistanceAmount, EFFECT_2, SPELL_AURA_MOD_RESISTANCE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_hun_pet_scaling_02_AuraScript();
+ }
+};
+
+class spell_hun_pet_scaling_03 : public SpellScriptLoader
+{
+public:
+ spell_hun_pet_scaling_03() : SpellScriptLoader("spell_hun_pet_scaling_03") { }
+
+ class spell_hun_pet_scaling_03_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_pet_scaling_03_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateShadowResistanceAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isPet())
+ return;
+
+ Unit* owner = pet->ToPet()->GetOwner();
+ if (!owner)
+ return;
+
+ float ownerBonus = 0.0f;
+
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_SHADOW), 40);
+
+ amount += ownerBonus;
+ }
+ }
+
+ void CalculateArcaneResistanceAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isPet())
+ return;
+
+ Unit* owner = pet->ToPet()->GetOwner();
+ if (!owner)
+ return;
+
+ float ownerBonus = 0.0f;
+
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_ARCANE), 40);
+
+ amount += ownerBonus;
+ }
+ }
+
+ void CalculateArmorAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isPet())
+ return;
+
+ Unit* owner = pet->ToPet()->GetOwner();
+ if (!owner)
+ return;
+
+ float ownerBonus = 0.0f;
+
+ ownerBonus = CalculatePctN(owner->GetArmor(), 35);
+
+ amount += ownerBonus;
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_03_AuraScript::CalculateShadowResistanceAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_03_AuraScript::CalculateArcaneResistanceAmount, EFFECT_1, SPELL_AURA_MOD_RESISTANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_03_AuraScript::CalculateArmorAmount, EFFECT_2, SPELL_AURA_MOD_RESISTANCE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_hun_pet_scaling_03_AuraScript();
+ }
+};
+
+class spell_hun_pet_scaling_04 : public SpellScriptLoader
+{
+public:
+ spell_hun_pet_scaling_04() : SpellScriptLoader("spell_hun_pet_scaling_04") { }
+
+ class spell_hun_pet_scaling_04_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_pet_scaling_04_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountMeleeHit(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitMelee = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_HIT_CHANCE
+ HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
+ // Increase hit melee from meele hit ratings
+ HitMelee += owner->GetRatingBonusValue(CR_HIT_MELEE);
+
+ amount += int32(HitMelee);
+ }
+ }
+
+ void CalculateAmountSpellHit(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitSpell = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE
+ HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ // Increase hit spell from spell hit ratings
+ HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL);
+
+ amount += int32(HitSpell);
+ }
+ }
+
+ void CalculateAmountExpertise(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float Expertise = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_EXPERTISE
+ Expertise += owner->GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE);
+ // Increase Expertise from Expertise ratings
+ Expertise += owner->GetRatingBonusValue(CR_EXPERTISE);
+
+ amount += int32(Expertise);
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_04_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_04_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_04_AuraScript::CalculateAmountExpertise, EFFECT_2, SPELL_AURA_MOD_EXPERTISE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_hun_pet_scaling_04_AuraScript();
+ }
+};
+
+class spell_hun_pet_passive_crit : public SpellScriptLoader
+{
+public:
+ spell_hun_pet_passive_crit() : SpellScriptLoader("spell_hun_pet_passive_crit") { }
+
+ class spell_hun_pet_passive_crit_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_pet_passive_crit_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountCritSpell(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float CritSpell = 0.0f;
+ // Crit from Intellect
+ // CritSpell += owner->GetSpellCritFromIntellect();
+ // Increase crit from SPELL_AURA_MOD_SPELL_CRIT_CHANCE
+ // CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_CRIT_CHANCE);
+ // Increase crit from SPELL_AURA_MOD_CRIT_PCT
+ // CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT);
+ // Increase crit spell from spell crit ratings
+ // CritSpell += owner->GetRatingBonusValue(CR_CRIT_SPELL);
+
+ amount += (CritSpell*0.8f);
+ }
+ }
+
+ void CalculateAmountCritMelee(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float CritMelee = 0.0f;
+ // Crit from Agility
+ // CritMelee += owner->GetMeleeCritFromAgility();
+ // Increase crit from SPELL_AURA_MOD_WEAPON_CRIT_PERCENT
+ // CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT);
+ // Increase crit from SPELL_AURA_MOD_CRIT_PCT
+ // CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT);
+ // Increase crit melee from melee crit ratings
+ // CritMelee += owner->GetRatingBonusValue(CR_CRIT_MELEE);
+
+ amount += (CritMelee*0.8f);
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_passive_crit_AuraScript::CalculateAmountCritSpell, EFFECT_1, SPELL_AURA_MOD_SPELL_CRIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_passive_crit_AuraScript::CalculateAmountCritMelee, EFFECT_0, SPELL_AURA_MOD_WEAPON_CRIT_PERCENT);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_hun_pet_passive_crit_AuraScript();
+ }
+};
+
+class spell_hun_pet_passive_damage_done : public SpellScriptLoader
+{
+public:
+ spell_hun_pet_passive_damage_done() : SpellScriptLoader("spell_hun_pet_passive_damage_done") { }
+
+ class spell_hun_pet_passive_damage_done_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_pet_passive_damage_done_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountDamageDone(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // Pet's base damage changes depending on happiness
+ if (GetCaster()->isPet() && GetCaster()->ToPet()->isHunterPet())
+ {
+ switch (GetCaster()->ToPet()->GetHappinessState())
+ {
+ case HAPPY:
+ // 125% of normal damage
+ amount += 25.0f;
+ break;
+ case CONTENT:
+ // 100% of normal damage, nothing to modify
+ break;
+ case UNHAPPY:
+ // 75% of normal damage
+ amount += -25.0f;
+ break;
+ }
+ }
+ // Cobra Reflexes
+ if (AuraEffect* cobraReflexes = GetCaster()->GetAuraEffectOfRankedSpell(61682, EFFECT_0))
+ amount -= cobraReflexes->GetAmount();
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_passive_damage_done_AuraScript::CalculateAmountDamageDone, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_hun_pet_passive_damage_done_AuraScript();
+ }
+};
+
+class spell_hun_animal_handler : public SpellScriptLoader
+{
+public:
+ spell_hun_animal_handler() : SpellScriptLoader("spell_hun_animal_handler") { }
+
+ class spell_hun_animal_handler_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_animal_handler_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountDamageDone(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ if (AuraEffect* aurEffect = owner->GetAuraEffectOfRankedSpell(SPELL_HUNTER_ANIMAL_HANDLER, EFFECT_1))
+ amount = aurEffect->GetAmount();
+ else
+ amount = 0;
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_animal_handler_AuraScript::CalculateAmountDamageDone, EFFECT_0, SPELL_AURA_MOD_ATTACK_POWER_PCT);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_hun_animal_handler_AuraScript();
+ }
+};
+
+
+class spell_dk_avoidance_passive : public SpellScriptLoader
+{
+public:
+ spell_dk_avoidance_passive() : SpellScriptLoader("spell_dk_avoidance_passive") { }
+
+ class spell_dk_avoidance_passive_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dk_avoidance_passive_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAvoidanceAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (Unit* owner = pet->GetOwner())
+
+ // Army of the dead ghoul
+ if (pet->GetEntry() == ENTRY_ARMY_OF_THE_DEAD_GHOUL)
+ amount = -90;
+ // Night of the dead
+ else if ( Aura * aur = owner->GetAuraOfRankedSpell(SPELL_NIGHT_OF_THE_DEAD))
+ amount = aur->GetSpellInfo()->Effects[EFFECT_2].CalcValue();
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_avoidance_passive_AuraScript::CalculateAvoidanceAmount, EFFECT_0, SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_dk_avoidance_passive_AuraScript();
+ }
+};
+
+class spell_dk_pet_scaling_01 : public SpellScriptLoader
+{
+public:
+ spell_dk_pet_scaling_01() : SpellScriptLoader("spell_dk_pet_scaling_01") { }
+
+ class spell_dk_pet_scaling_01_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dk_pet_scaling_01_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ _tempHealth = 0;
+ return true;
+ }
+
+ void CalculateStaminaAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (pet->isGuardian())
+ {
+ if (Unit* owner = pet->GetOwner())
+ {
+ float mod = 0.3f;
+
+ // 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;
+
+ float ownerBonus = float(owner->GetStat(STAT_STAMINA)) * mod;
+ amount += ownerBonus;
+ }
+ }
+ }
+ }
+
+ void ApplyEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (_tempHealth)
+ pet->SetHealth(_tempHealth);
+ }
+
+ void RemoveEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ _tempHealth = pet->GetHealth();
+ }
+
+ void CalculateStrengthAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isGuardian())
+ return;
+
+ Unit* owner = pet->GetOwner();
+ if (!owner)
+ return;
+
+ float mod = 0.7f;
+
+ // Ravenous Dead
+ AuraEffect const* aurEff = NULL;
+ // Check just if owner has Ravenous Dead since it's effect is not an aura
+ aurEff = owner->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DEATHKNIGHT, 3010, 0);
+ if (aurEff)
+ {
+ mod += CalculatePctN(mod, aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()); // Ravenous Dead edits the original scale
+ }
+ // Glyph of the Ghoul
+ aurEff = owner->GetAuraEffect(58686, 0);
+ if (aurEff)
+ mod += CalculatePctN(1.0f, aurEff->GetAmount()); // Glyph of the Ghoul adds a flat value to the scale mod
+ float ownerBonus = float(owner->GetStat(STAT_STRENGTH)) * mod;
+ amount += ownerBonus;
+ }
+ }
+
+ void Register()
+ {
+ OnEffectRemove += AuraEffectRemoveFn(spell_dk_pet_scaling_01_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ AfterEffectApply += AuraEffectApplyFn(spell_dk_pet_scaling_01_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_01_AuraScript::CalculateStaminaAmount, EFFECT_0, SPELL_AURA_MOD_STAT);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_01_AuraScript::CalculateStrengthAmount, EFFECT_1, SPELL_AURA_MOD_STAT);
+ }
+
+ private:
+ uint32 _tempHealth;
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_dk_pet_scaling_01_AuraScript();
+ }
+};
+
+class spell_dk_pet_scaling_02 : public SpellScriptLoader
+{
+public:
+ spell_dk_pet_scaling_02() : SpellScriptLoader("spell_dk_pet_scaling_02") { }
+
+ class spell_dk_pet_scaling_02_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dk_pet_scaling_02_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountMeleeHaste(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HasteMelee = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_HIT_CHANCE
+ HasteMelee += (1-owner->m_modAttackSpeedPct[BASE_ATTACK])*100;
+
+ amount += int32(HasteMelee);
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_02_AuraScript::CalculateAmountMeleeHaste, EFFECT_1, SPELL_AURA_MELEE_SLOW);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_dk_pet_scaling_02_AuraScript();
+ }
+};
+
+class spell_dk_pet_scaling_03 : public SpellScriptLoader
+{
+public:
+ spell_dk_pet_scaling_03() : SpellScriptLoader("spell_dk_pet_scaling_03") { }
+
+ class spell_dk_pet_scaling_03_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dk_pet_scaling_03_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountMeleeHit(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitMelee = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_HIT_CHANCE
+ HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
+ // Increase hit melee from meele hit ratings
+ HitMelee += owner->GetRatingBonusValue(CR_HIT_MELEE);
+
+ amount += int32(HitMelee);
+ }
+ }
+
+ void CalculateAmountSpellHit(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitSpell = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE
+ HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ // Increase hit spell from spell hit ratings
+ HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL);
+
+ amount += int32(HitSpell);
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_03_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_03_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_dk_pet_scaling_03_AuraScript();
+ }
+};
+
+class spell_dk_rune_weapon_scaling_02 : public SpellScriptLoader
+{
+public:
+ spell_dk_rune_weapon_scaling_02() : SpellScriptLoader("spell_dk_rune_weapon_scaling_02") { }
+
+ class spell_dk_rune_weapon_scaling_02_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dk_rune_weapon_scaling_02_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateDamageDoneAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ Unit* owner = pet->GetOwner();
+ if (!owner)
+ return;
+
+ if (pet->isGuardian())
+ ((Guardian*)pet)->SetBonusDamage(owner->GetTotalAttackPowerValue(BASE_ATTACK));
+
+ amount += owner->CalculateDamage(BASE_ATTACK, true, true);;
+ }
+ }
+
+ void CalculateAmountMeleeHaste(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HasteMelee = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_HIT_CHANCE
+ HasteMelee += (1-owner->m_modAttackSpeedPct[BASE_ATTACK])*100;
+
+ amount += int32(HasteMelee);
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_rune_weapon_scaling_02_AuraScript::CalculateDamageDoneAmount, EFFECT_0, SPELL_AURA_MOD_DAMAGE_DONE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_rune_weapon_scaling_02_AuraScript::CalculateAmountMeleeHaste, EFFECT_1, SPELL_AURA_MELEE_SLOW);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_dk_rune_weapon_scaling_02_AuraScript();
+ }
+};
+
+void AddSC_pet_spell_scripts()
+{
+ new spell_gen_pet_calculate();
+}
diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp
index 790a9d0f814..308c7f9afa3 100644
--- a/src/server/scripts/World/go_scripts.cpp
+++ b/src/server/scripts/World/go_scripts.cpp
@@ -1245,6 +1245,36 @@ class go_veil_skith_cage : public GameObjectScript
}
};
+/*######
+## go_frostblade_shrine
+######*/
+
+enum TheCleansing
+{
+ QUEST_THE_CLEANSING_HORDE = 11317,
+ QUEST_THE_CLEANSING_ALLIANCE = 11322,
+ SPELL_CLEANSING_SOUL = 43351,
+ SPELL_RECENT_MEDITATION = 61720,
+};
+
+class go_frostblade_shrine : public GameObjectScript
+{
+public:
+ go_frostblade_shrine() : GameObjectScript("go_frostblade_shrine") { }
+
+ bool OnGossipHello(Player* player, GameObject* go)
+ {
+ if (!player->HasAura(SPELL_RECENT_MEDITATION))
+ if (player->GetQuestStatus(QUEST_THE_CLEANSING_HORDE) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(QUEST_THE_CLEANSING_ALLIANCE) == QUEST_STATUS_INCOMPLETE)
+ {
+ go->UseDoorOrButton(10);
+ player->CastSpell(player, SPELL_CLEANSING_SOUL);
+ player->SetStandState(UNIT_STAND_STATE_SIT);
+ }
+ return true;
+ }
+};
+
void AddSC_go_scripts()
{
new go_cat_figurine;
@@ -1285,4 +1315,5 @@ void AddSC_go_scripts()
new go_gjalerbron_cage;
new go_large_gjalerbron_cage;
new go_veil_skith_cage;
+ new go_frostblade_shrine;
}
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index c9aeea07382..57a65423b6f 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -47,6 +47,7 @@ EndContentData */
#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "World.h"
+#include "PetAI.h"
/*########
# npc_air_force_bots
@@ -2100,16 +2101,18 @@ class npc_shadowfiend : public CreatureScript
public:
npc_shadowfiend() : CreatureScript("npc_shadowfiend") { }
- struct npc_shadowfiendAI : public ScriptedAI
+ struct npc_shadowfiendAI : public PetAI
{
- npc_shadowfiendAI(Creature* creature) : ScriptedAI(creature) {}
+ npc_shadowfiendAI(Creature* creature) : PetAI(creature) {}
- void DamageTaken(Unit* /*killer*/, uint32& damage)
+ void JustDied(Unit* killer)
{
if (me->isSummon())
if (Unit* owner = me->ToTempSummon()->GetSummoner())
- if (owner->HasAura(GLYPH_OF_SHADOWFIEND) && damage >= me->GetHealth())
+ if (owner->HasAura(GLYPH_OF_SHADOWFIEND))
owner->CastSpell(owner, GLYPH_OF_SHADOWFIEND_MANA, true);
+
+ PetAI::JustDied(killer);
}
};
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index d315c6417ea..89cc6ab25e5 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -314,18 +314,17 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PREPARE_STATEMENT(CHAR_DEL_OLD_CORPSES, "DELETE FROM corpse WHERE corpseType = 0 OR time < (UNIX_TIMESTAMP(NOW()) - ?)", CONNECTION_ASYNC)
// Creature respawn
- PREPARE_STATEMENT(CHAR_SEL_CREATURE_RESPAWNS, "SELECT guid, respawnTime, instanceId FROM creature_respawn", CONNECTION_SYNCH)
- PREPARE_STATEMENT(CHAR_REP_CREATURE_RESPAWN, "REPLACE INTO creature_respawn (guid, respawnTime, instanceId) VALUES (?, ?, ?)", CONNECTION_ASYNC)
- PREPARE_STATEMENT(CHAR_DEL_CREATURE_RESPAWN, "DELETE FROM creature_respawn WHERE guid = ? AND instanceId = ?", CONNECTION_ASYNC)
- PREPARE_STATEMENT(CHAR_DEL_CREATURE_RESPAWN_BY_GUID, "DELETE FROM creature_respawn WHERE guid = ?", CONNECTION_ASYNC)
- PREPARE_STATEMENT(CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE, "DELETE FROM creature_respawn WHERE instanceId = ?", CONNECTION_ASYNC)
+ PREPARE_STATEMENT(CHAR_SEL_CREATURE_RESPAWNS, "SELECT guid, respawnTime FROM creature_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_SYNCH)
+ PREPARE_STATEMENT(CHAR_REP_CREATURE_RESPAWN, "REPLACE INTO creature_respawn (guid, respawnTime, mapId, instanceId) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC)
+ PREPARE_STATEMENT(CHAR_DEL_CREATURE_RESPAWN, "DELETE FROM creature_respawn WHERE guid = ? AND mapId = ? AND instanceId = ?", CONNECTION_ASYNC)
+ PREPARE_STATEMENT(CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE, "DELETE FROM creature_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_SEL_MAX_CREATURE_RESPAWNS, "SELECT MAX(respawnTime), instanceId FROM creature_respawn WHERE instanceId > 0 GROUP BY instanceId", CONNECTION_SYNCH)
// Gameobject respawn
- PREPARE_STATEMENT(CHAR_SEL_GO_RESPAWNS, "SELECT guid, respawnTime, instanceId FROM gameobject_respawn", CONNECTION_SYNCH)
- PREPARE_STATEMENT(CHAR_REP_GO_RESPAWN, "REPLACE INTO gameobject_respawn (guid, respawnTime, instanceId) VALUES (?, ?, ?)", CONNECTION_ASYNC)
- PREPARE_STATEMENT(CHAR_DEL_GO_RESPAWN, "DELETE FROM gameobject_respawn WHERE guid = ? AND instanceId = ?", CONNECTION_ASYNC)
- PREPARE_STATEMENT(CHAR_DEL_GO_RESPAWN_BY_INSTANCE, "DELETE FROM gameobject_respawn WHERE instanceId = ?", CONNECTION_ASYNC)
+ PREPARE_STATEMENT(CHAR_SEL_GO_RESPAWNS, "SELECT guid, respawnTime FROM gameobject_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_SYNCH)
+ PREPARE_STATEMENT(CHAR_REP_GO_RESPAWN, "REPLACE INTO gameobject_respawn (guid, respawnTime, mapId, instanceId) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC)
+ PREPARE_STATEMENT(CHAR_DEL_GO_RESPAWN, "DELETE FROM gameobject_respawn WHERE guid = ? AND mapId = ? AND instanceId = ?", CONNECTION_ASYNC)
+ PREPARE_STATEMENT(CHAR_DEL_GO_RESPAWN_BY_INSTANCE, "DELETE FROM gameobject_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_ASYNC)
// GM Tickets
PREPARE_STATEMENT(CHAR_SEL_GM_TICKETS, "SELECT ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, completed, escalated, viewed FROM gm_tickets", CONNECTION_SYNCH)
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index cf6bbd7bdfa..e1530f36e44 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -296,7 +296,6 @@ enum CharacterDatabaseStatements
CHAR_SEL_CREATURE_RESPAWNS,
CHAR_REP_CREATURE_RESPAWN,
CHAR_DEL_CREATURE_RESPAWN,
- CHAR_DEL_CREATURE_RESPAWN_BY_GUID,
CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE,
CHAR_SEL_MAX_CREATURE_RESPAWNS,
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index db167fb86fb..cc4c4a555c2 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -483,12 +483,13 @@ LogFileLevel = 0
DebugLogMask = 0
#
-# WorldLogFile
-# Description: Packet logging file for the world server.
-# Example: "World.log" - (Enabled)
+# PacketLogFile
+# Description: Binary packet logging file for the world server.
+# Filename extension must be .bin to be parsable with WowPacketParser.
+# Example: "World.bin" - (Enabled)
# Default: "" - (Disabled)
-WorldLogFile = ""
+PacketLogFile = ""
#
# DBErrorLogFile
@@ -2024,17 +2025,17 @@ Visibility.GroupMode = 1
# Visibility.Distance.Instances
# Visibility.Distance.BGArenas
# Description: Visibility distance to see other players or gameobjects.
-# Visibility on continents on retail ~90 yards. In BG/Arenas ~180.
-# For instances default ~120.
-# Max limited by active player zone: ~ 333
+# Visibility on continents on retail ~90 yards. In BG/Arenas ~533.
+# For instances default ~170.
+# Max limited by grid size: 533.33333
# Min limit is max aggro radius (45) * Rate.Creature.Aggro
# Default: 90 - (Visibility.Distance.Continents)
-# 120 - (Visibility.Distance.Instances)
-# 180 - (Visibility.Distance.BGArenas)
+# 170 - (Visibility.Distance.Instances)
+# 533 - (Visibility.Distance.BGArenas)
Visibility.Distance.Continents = 90
-Visibility.Distance.Instances = 120
-Visibility.Distance.BGArenas = 180
+Visibility.Distance.Instances = 170
+Visibility.Distance.BGArenas = 533
#
# Visibility.Notify.Period.OnContinents
diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp
index 1505f2c2cee..d64276c6363 100644
--- a/src/tools/map_extractor/System.cpp
+++ b/src/tools/map_extractor/System.cpp
@@ -48,9 +48,9 @@ char output_path[128] = ".";
char input_path[128] = ".";
uint32 maxAreaId = 0;
-//**************************************************
+// **************************************************
// Extractor options
-//**************************************************
+// **************************************************
enum Extract
{
EXTRACT_MAP = 1,
@@ -221,7 +221,7 @@ uint32 ReadMapDBC()
map_ids[x].id = dbc.getRecord(x).getUInt(0);
strcpy(map_ids[x].name, dbc.getRecord(x).getString(1));
}
- printf("Done! (%u maps loaded)\n", map_count);
+ printf("Done! (%zu maps loaded)\n", map_count);
return map_count;
}
@@ -246,7 +246,7 @@ void ReadAreaTableDBC()
maxAreaId = dbc.getMaxId();
- printf("Done! (%u areas loaded)\n", area_count);
+ printf("Done! (%zu areas loaded)\n", area_count);
}
void ReadLiquidTypeTableDBC()
@@ -267,7 +267,7 @@ void ReadLiquidTypeTableDBC()
for(uint32 x = 0; x < liqTypeCount; ++x)
LiqType[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3);
- printf("Done! (%u LiqTypes loaded)\n", liqTypeCount);
+ printf("Done! (%zu LiqTypes loaded)\n", liqTypeCount);
}
//
@@ -572,7 +572,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/,
// Try store as packed in uint16 or uint8 values
if (!(heightHeader.flags & MAP_HEIGHT_NO_HEIGHT))
{
- float step;
+ float step = 0;
// Try Store as uint values
if (CONF_allow_float_to_int)
{