aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/collision/Management/VMapManager2.cpp3
-rwxr-xr-xsrc/server/collision/Management/VMapManager2.h2
-rw-r--r--src/server/collision/Maps/MapTree.cpp4
-rw-r--r--src/server/collision/Models/WorldModel.cpp3
-rwxr-xr-xsrc/server/collision/Models/WorldModel.h1
-rwxr-xr-xsrc/server/game/AI/CoreAI/PetAI.cpp4
-rwxr-xr-xsrc/server/game/AI/CreatureAI.cpp1
-rwxr-xr-xsrc/server/game/AI/CreatureAI.h2
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.h1
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp52
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h1
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp1
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h8
-rwxr-xr-xsrc/server/game/Battlegrounds/Zones/BattlegroundWS.cpp12
-rw-r--r--src/server/game/Calendar/CalendarMgr.cpp7
-rwxr-xr-xsrc/server/game/Conditions/ConditionMgr.cpp59
-rwxr-xr-xsrc/server/game/Conditions/ConditionMgr.h27
-rwxr-xr-xsrc/server/game/Entities/Corpse/Corpse.cpp2
-rwxr-xr-xsrc/server/game/Entities/DynamicObject/DynamicObject.cpp2
-rwxr-xr-xsrc/server/game/Entities/GameObject/GameObject.cpp2
-rwxr-xr-xsrc/server/game/Entities/Item/Item.cpp2
-rwxr-xr-xsrc/server/game/Entities/Object/Object.cpp91
-rwxr-xr-xsrc/server/game/Entities/Object/Object.h22
-rwxr-xr-xsrc/server/game/Entities/Object/Updates/UpdateData.h22
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp22
-rwxr-xr-xsrc/server/game/Entities/Player/Player.h8
-rwxr-xr-xsrc/server/game/Entities/Transport/Transport.cpp2
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp33
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h1
-rwxr-xr-xsrc/server/game/Entities/Vehicle/Vehicle.cpp3
-rwxr-xr-xsrc/server/game/Globals/ObjectAccessor.cpp12
-rwxr-xr-xsrc/server/game/Globals/ObjectMgr.cpp2
-rwxr-xr-xsrc/server/game/Handlers/AuctionHouseHandler.cpp8
-rwxr-xr-xsrc/server/game/Maps/Map.cpp5
-rwxr-xr-xsrc/server/game/Maps/MapInstanced.cpp24
-rwxr-xr-xsrc/server/game/Miscellaneous/Language.h4
-rwxr-xr-xsrc/server/game/Scripting/ScriptMgr.cpp5
-rwxr-xr-xsrc/server/game/Scripting/ScriptMgr.h4
-rwxr-xr-xsrc/server/game/Server/Protocol/Opcodes.cpp2
-rwxr-xr-xsrc/server/game/Spells/Spell.cpp275
-rwxr-xr-xsrc/server/game/Spells/Spell.h41
-rwxr-xr-xsrc/server/game/Spells/SpellEffects.cpp99
-rw-r--r--src/server/game/Spells/SpellInfo.cpp7
-rw-r--r--src/server/game/Spells/SpellInfo.h1
-rwxr-xr-xsrc/server/game/Spells/SpellScript.cpp17
-rwxr-xr-xsrc/server/game/Spells/SpellScript.h3
-rwxr-xr-xsrc/server/game/Texts/CreatureTextMgr.cpp403
-rwxr-xr-xsrc/server/game/Texts/CreatureTextMgr.h170
-rw-r--r--src/server/game/Warden/WardenCheckMgr.cpp18
-rw-r--r--src/server/game/Warden/WardenCheckMgr.h2
-rw-r--r--src/server/game/Warden/WardenWin.cpp4
-rwxr-xr-xsrc/server/game/World/World.cpp3
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp36
-rw-r--r--src/server/scripts/Commands/cs_wp.cpp27
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp1
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp1
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp38
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp19
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp40
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp32
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp6
-rw-r--r--src/server/scripts/Northrend/zuldrak.cpp4
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp8
-rw-r--r--src/server/scripts/World/areatrigger_scripts.cpp73
-rwxr-xr-xsrc/server/shared/Cryptography/HMACSHA1.cpp12
-rwxr-xr-xsrc/server/shared/Cryptography/HMACSHA1.h2
-rwxr-xr-xsrc/server/shared/Cryptography/SHA1.h1
-rwxr-xr-xsrc/server/shared/Packets/ByteBuffer.h83
-rw-r--r--src/tools/map_extractor/CMakeLists.txt2
-rw-r--r--src/tools/vmap4_extractor/CMakeLists.txt2
70 files changed, 1158 insertions, 738 deletions
diff --git a/src/server/collision/Management/VMapManager2.cpp b/src/server/collision/Management/VMapManager2.cpp
index 81b97f5f352..62abc31831a 100644
--- a/src/server/collision/Management/VMapManager2.cpp
+++ b/src/server/collision/Management/VMapManager2.cpp
@@ -245,7 +245,7 @@ namespace VMAP
return false;
}
- WorldModel* VMapManager2::acquireModelInstance(const std::string& basepath, const std::string& filename, uint32 flags/* Only used when creating the model */)
+ WorldModel* VMapManager2::acquireModelInstance(const std::string& basepath, const std::string& filename)
{
//! Critical section, thread safe access to iLoadedModelFiles
TRINITY_GUARD(ACE_Thread_Mutex, LoadedModelFilesLock);
@@ -261,7 +261,6 @@ namespace VMAP
return NULL;
}
sLog->outDebug(LOG_FILTER_MAPS, "VMapManager2: loading file '%s%s'", basepath.c_str(), filename.c_str());
- worldmodel->Flags = flags;
model = iLoadedModelFiles.insert(std::pair<std::string, ManagedModel>(filename, ManagedModel())).first;
model->second.setModel(worldmodel);
}
diff --git a/src/server/collision/Management/VMapManager2.h b/src/server/collision/Management/VMapManager2.h
index 4b66a2e9fc7..1fba108388a 100755
--- a/src/server/collision/Management/VMapManager2.h
+++ b/src/server/collision/Management/VMapManager2.h
@@ -103,7 +103,7 @@ namespace VMAP
bool getAreaInfo(unsigned int pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const;
bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type) const;
- WorldModel* acquireModelInstance(const std::string& basepath, const std::string& filename, uint32 flags = 0);
+ WorldModel* acquireModelInstance(const std::string& basepath, const std::string& filename);
void releaseModelInstance(const std::string& filename);
// what's the use of this? o.O
diff --git a/src/server/collision/Maps/MapTree.cpp b/src/server/collision/Maps/MapTree.cpp
index f94f9bbf52b..f4a3f1c7b30 100644
--- a/src/server/collision/Maps/MapTree.cpp
+++ b/src/server/collision/Maps/MapTree.cpp
@@ -309,7 +309,7 @@ namespace VMAP
#endif
if (!iIsTiled && ModelSpawn::readFromFile(rf, spawn))
{
- WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name, spawn.flags);
+ WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name);
sLog->outDebug(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : loading %s", spawn.name.c_str());
if (model)
{
@@ -380,7 +380,7 @@ namespace VMAP
if (result)
{
// acquire model instance
- WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name, spawn.flags);
+ WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name);
if (!model)
sLog->outError("StaticMapTree::LoadMapTile() : could not acquire WorldModel pointer [%u, %u]", tileX, tileY);
diff --git a/src/server/collision/Models/WorldModel.cpp b/src/server/collision/Models/WorldModel.cpp
index cda34510058..d4b08dde5dd 100644
--- a/src/server/collision/Models/WorldModel.cpp
+++ b/src/server/collision/Models/WorldModel.cpp
@@ -421,9 +421,6 @@ namespace VMAP
bool WorldModel::IntersectRay(const G3D::Ray &ray, float &distance, bool stopAtFirstHit) const
{
- // M2 models are not taken into account for LoS calculation
- if (Flags & MOD_M2)
- return false;
// small M2 workaround, maybe better make separate class with virtual intersection funcs
// in any case, there's no need to use a bound tree if we only have one submodel
if (groupModels.size() == 1)
diff --git a/src/server/collision/Models/WorldModel.h b/src/server/collision/Models/WorldModel.h
index dbaccb58573..ebf828e4935 100755
--- a/src/server/collision/Models/WorldModel.h
+++ b/src/server/collision/Models/WorldModel.h
@@ -113,7 +113,6 @@ namespace VMAP
bool GetLocationInfo(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, LocationInfo &info) const;
bool writeFile(const std::string &filename);
bool readFile(const std::string &filename);
- uint32 Flags;
protected:
uint32 RootWMOID;
std::vector<GroupModel> groupModels;
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp
index 30ebd06745f..eedba4d8b7e 100755
--- a/src/server/game/AI/CoreAI/PetAI.cpp
+++ b/src/server/game/AI/CoreAI/PetAI.cpp
@@ -174,7 +174,7 @@ void PetAI::UpdateAI(const uint32 diff)
if (spell->CanAutoCast(target))
{
- targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(target, spell));
+ targetSpellStore.push_back(std::make_pair(target, spell));
spellUsed = true;
break;
}
@@ -186,7 +186,7 @@ void PetAI::UpdateAI(const uint32 diff)
{
Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE, 0);
if (spell->CanAutoCast(me->getVictim()))
- targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(me->getVictim(), spell));
+ targetSpellStore.push_back(std::make_pair(me->getVictim(), spell));
else
delete spell;
}
diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp
index c8818f84e5b..9c236cbd039 100755
--- a/src/server/game/AI/CreatureAI.cpp
+++ b/src/server/game/AI/CreatureAI.cpp
@@ -25,6 +25,7 @@
#include "Log.h"
#include "MapReference.h"
#include "Player.h"
+#include "CreatureTextMgr.h"
//Disable CreatureAI when charmed
void CreatureAI::OnCharmed(bool /*apply*/)
diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h
index dafd3e4e137..423b00291e7 100755
--- a/src/server/game/AI/CreatureAI.h
+++ b/src/server/game/AI/CreatureAI.h
@@ -19,9 +19,9 @@
#ifndef TRINITY_CREATUREAI_H
#define TRINITY_CREATUREAI_H
+#include "Creature.h"
#include "UnitAI.h"
#include "Common.h"
-#include "CreatureTextMgr.h"
class WorldObject;
class Unit;
diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h
index e82b35ec87a..c2501199f77 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.h
+++ b/src/server/game/AI/SmartScripts/SmartAI.h
@@ -23,7 +23,6 @@
#include "CreatureAI.h"
#include "Unit.h"
#include "ConditionMgr.h"
-#include "CreatureTextMgr.h"
#include "Spell.h"
#include "SmartScript.h"
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 67d26ea06dd..0523f59da5d 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -33,6 +33,47 @@
#include "Group.h"
#include "Vehicle.h"
#include "ScriptedGossip.h"
+#include "CreatureTextMgr.h"
+
+class TrinityStringTextBuilder
+{
+ public:
+ TrinityStringTextBuilder(WorldObject* obj, ChatMsg msgtype, int32 id, uint32 language, uint64 targetGUID)
+ : _source(obj), _msgType(msgtype), _textId(id), _language(language), _targetGUID(targetGUID)
+ {
+ }
+
+ size_t operator()(WorldPacket* data, LocaleConstant locale) const
+ {
+ std::string text = sObjectMgr->GetTrinityString(_textId, locale);
+ char const* localizedName = _source->GetNameForLocaleIdx(locale);
+
+ *data << uint8(_msgType);
+ *data << uint32(_language);
+ *data << uint64(_source->GetGUID());
+ *data << uint32(1); // 2.1.0
+ *data << uint32(strlen(localizedName)+1);
+ *data << localizedName;
+ size_t whisperGUIDpos = data->wpos();
+ *data << uint64(_targetGUID); // Unit Target
+ if (_targetGUID && !IS_PLAYER_GUID(_targetGUID))
+ {
+ *data << uint32(1); // target name length
+ *data << uint8(0); // target name
+ }
+ *data << uint32(text.length() + 1);
+ *data << text;
+ *data << uint8(0); // ChatTag
+
+ return whisperGUIDpos;
+ }
+
+ WorldObject* _source;
+ ChatMsg _msgType;
+ int32 _textId;
+ uint32 _language;
+ uint64 _targetGUID;
+};
SmartScript::SmartScript()
{
@@ -695,7 +736,10 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
me->DoFleeToGetAssistance();
if (e.action.flee.withEmote)
- sCreatureTextMgr->SendChatString(me, sObjectMgr->GetTrinityStringForDBCLocale(LANG_FLEE), CHAT_MSG_MONSTER_EMOTE);
+ {
+ TrinityStringTextBuilder builder(me, CHAT_MSG_MONSTER_EMOTE, LANG_FLEE, LANG_UNIVERSAL, 0);
+ sCreatureTextMgr->SendChatPacket(me, builder, CHAT_MSG_MONSTER_EMOTE);
+ }
sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_FLEE_FOR_ASSIST: Creature %u DoFleeToGetAssistance", me->GetGUIDLow());
break;
}
@@ -1329,10 +1373,10 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
target = targets->front();
}
- if(!target)
- me->GetMotionMaster()->MovePoint(0, e.target.x, e.target.y, e.target.z);
+ if (!target)
+ me->GetMotionMaster()->MovePoint(e.action.MoveToPos.pointId, e.target.x, e.target.y, e.target.z);
else
- me->GetMotionMaster()->MovePoint(0, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
+ me->GetMotionMaster()->MovePoint(e.action.MoveToPos.pointId, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
break;
}
case SMART_ACTION_RESPAWN_TARGET:
diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h
index f7524582ab7..faba3c05394 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.h
+++ b/src/server/game/AI/SmartScripts/SmartScript.h
@@ -23,7 +23,6 @@
#include "CreatureAI.h"
#include "Unit.h"
#include "ConditionMgr.h"
-#include "CreatureTextMgr.h"
#include "Spell.h"
#include "GridNotifiers.h"
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index 3fc3f233b4b..fe2a89de9aa 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -27,6 +27,7 @@
#include "InstanceScript.h"
#include "ScriptedCreature.h"
#include "GameEventMgr.h"
+#include "CreatureTextMgr.h"
#include "SmartScriptMgr.h"
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index 0d182e1beb3..007b57b52d7 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -23,7 +23,6 @@
#include "CreatureAI.h"
#include "Unit.h"
#include "ConditionMgr.h"
-#include "CreatureTextMgr.h"
#include "Spell.h"
//#include "SmartScript.h"
@@ -442,7 +441,7 @@ enum SMART_ACTION
SMART_ACTION_CREATE_TIMED_EVENT = 67, // id, InitialMin, InitialMax, RepeatMin(only if it repeats), RepeatMax(only if it repeats), chance
SMART_ACTION_PLAYMOVIE = 68, // entry
- SMART_ACTION_MOVE_TO_POS = 69, // xyz
+ SMART_ACTION_MOVE_TO_POS = 69, // PointId, xyz
SMART_ACTION_RESPAWN_TARGET = 70, //
SMART_ACTION_EQUIP = 71, // entry, slotmask slot1, slot2, slot3 , only slots with mask set will be sent to client, bits are 1, 2, 4, leaving mask 0 is defaulted to mask 7 (send all), slots1-3 are only used if no entry is set
SMART_ACTION_CLOSE_GOSSIP = 72, // none
@@ -875,6 +874,11 @@ struct SmartAction
struct
{
+ uint8 pointId;
+ } MoveToPos;
+
+ struct
+ {
uint32 gossipMenuId;
uint32 gossipNpcTextId;
} sendGossipMenu;
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
index 43a29e93c55..034de38fd9c 100755
--- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
@@ -437,8 +437,8 @@ void BattlegroundWS::EventPlayerClickedOnFlag(Player* Source, GameObject* target
ChatMsg type = CHAT_MSG_BG_SYSTEM_NEUTRAL;
//alliance flag picked up from base
- if (Source->GetTeam() == HORDE && this->GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_BASE
- && this->BgObjects[BG_WS_OBJECT_A_FLAG] == target_obj->GetGUID())
+ if (Source->GetTeam() == HORDE && GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_BASE
+ && BgObjects[BG_WS_OBJECT_A_FLAG] == target_obj->GetGUID())
{
message_id = LANG_BG_WS_PICKEDUP_AF;
type = CHAT_MSG_BG_SYSTEM_HORDE;
@@ -456,8 +456,8 @@ void BattlegroundWS::EventPlayerClickedOnFlag(Player* Source, GameObject* target
}
//horde flag picked up from base
- if (Source->GetTeam() == ALLIANCE && this->GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_BASE
- && this->BgObjects[BG_WS_OBJECT_H_FLAG] == target_obj->GetGUID())
+ if (Source->GetTeam() == ALLIANCE && GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_BASE
+ && BgObjects[BG_WS_OBJECT_H_FLAG] == target_obj->GetGUID())
{
message_id = LANG_BG_WS_PICKEDUP_HF;
type = CHAT_MSG_BG_SYSTEM_ALLIANCE;
@@ -475,7 +475,7 @@ void BattlegroundWS::EventPlayerClickedOnFlag(Player* Source, GameObject* target
}
//Alliance flag on ground(not in base) (returned or picked up again from ground!)
- if (GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10))
+ if (GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10) && BgObjects[BG_WS_OBJECT_A_FLAG] == target_obj->GetGUID())
{
if (Source->GetTeam() == ALLIANCE)
{
@@ -509,7 +509,7 @@ void BattlegroundWS::EventPlayerClickedOnFlag(Player* Source, GameObject* target
}
//Horde flag on ground(not in base) (returned or picked up again)
- if (GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10))
+ if (GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10) && BgObjects[BG_WS_OBJECT_H_FLAG] == target_obj->GetGUID())
{
if (Source->GetTeam() == HORDE)
{
diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp
index b286abba81e..761bbb9b496 100644
--- a/src/server/game/Calendar/CalendarMgr.cpp
+++ b/src/server/game/Calendar/CalendarMgr.cpp
@@ -375,7 +375,7 @@ void CalendarMgr::AddAction(CalendarAction const& action)
uint64 eventId = action.Invite.GetEventId();
uint64 inviteId = action.Invite.GetInviteId();
- CalendarEvent* calendarEvent;
+ CalendarEvent* calendarEvent = NULL;
if (action.GetInviteId() != action.Invite.GetInviteId())
calendarEvent = CheckPermisions(eventId, action.GetPlayer(), action.GetInviteId(), CALENDAR_RANK_MODERATOR);
else
@@ -395,7 +395,7 @@ void CalendarMgr::AddAction(CalendarAction const& action)
uint64 eventId = action.Invite.GetEventId();
uint64 inviteId = action.Invite.GetInviteId();
- CalendarEvent* calendarEvent;
+ CalendarEvent* calendarEvent = NULL;
if (action.GetInviteId() != action.Invite.GetInviteId())
calendarEvent = CheckPermisions(eventId, action.GetPlayer(), action.GetInviteId(), CALENDAR_RANK_OWNER);
else
@@ -420,6 +420,9 @@ void CalendarMgr::AddAction(CalendarAction const& action)
// already checked in CheckPermisions
CalendarInvite* invite = GetInvite(inviteId);
+ if (!invite)
+ return;
+
if (calendarEvent->GetCreatorGUID() == invite->GetInvitee())
{
action.GetPlayer()->GetSession()->SendCalendarCommandResult(CALENDAR_ERROR_DELETE_CREATOR_FAILED);
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 7d21f94f372..755b9299352 100755
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -114,7 +114,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
case CONDITION_QUESTREWARDED:
{
if (Player* player = object->ToPlayer())
- condMeets = (player->GetQuestRewardStatus(ConditionValue1) == !ConditionValue2);
+ condMeets = player->GetQuestRewardStatus(ConditionValue1);
break;
}
case CONDITION_QUESTTAKEN:
@@ -122,7 +122,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
if (Player* player = object->ToPlayer())
{
QuestStatus status = player->GetQuestStatus(ConditionValue1);
- condMeets = ((status == QUEST_STATUS_INCOMPLETE) == !ConditionValue2);
+ condMeets = (status == QUEST_STATUS_INCOMPLETE);
}
break;
}
@@ -131,7 +131,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
if (Player* player = object->ToPlayer())
{
QuestStatus status = player->GetQuestStatus(ConditionValue1);
- condMeets = ((status == QUEST_STATUS_COMPLETE && !player->GetQuestRewardStatus(ConditionValue1)) == !ConditionValue2);
+ condMeets = (status == QUEST_STATUS_COMPLETE && !player->GetQuestRewardStatus(ConditionValue1));
}
break;
}
@@ -140,7 +140,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
if (Player* player = object->ToPlayer())
{
QuestStatus status = player->GetQuestStatus(ConditionValue1);
- condMeets = ((status == QUEST_STATUS_NONE) == !ConditionValue2);
+ condMeets = (status == QUEST_STATUS_NONE);
}
break;
}
@@ -515,7 +515,9 @@ bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo,
sLog->outDebug(LOG_FILTER_CONDITIONSYS, "ConditionMgr::IsPlayerMeetToConditionList condType: %u val1: %u", (*i)->ConditionType, (*i)->ConditionValue1);
if ((*i)->isLoaded())
{
+ //! Find ElseGroup in ElseGroupStore
std::map<uint32, bool>::const_iterator itr = ElseGroupStore.find((*i)->ElseGroup);
+ //! If not found, add an entry in the store and set to true (placeholder)
if (itr == ElseGroupStore.end())
ElseGroupStore[(*i)->ElseGroup] = true;
else if (!(*itr).second)
@@ -854,18 +856,6 @@ void ConditionMgr::LoadConditions(bool isReload)
break;
case CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT:
{
- //if no list for npc create one
- if (SpellClickEventConditionStore.find(cond->SourceGroup) == SpellClickEventConditionStore.end())
- {
- ConditionTypeContainer cmap;
- SpellClickEventConditionStore[cond->SourceGroup] = cmap;
- }
- //if no list for spellclick spell create one
- if (SpellClickEventConditionStore[cond->SourceGroup].find(cond->SourceEntry) == SpellClickEventConditionStore[cond->SourceGroup].end())
- {
- ConditionList clist;
- SpellClickEventConditionStore[cond->SourceGroup][cond->SourceEntry] = clist;
- }
SpellClickEventConditionStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
valid = true;
++count;
@@ -877,18 +867,6 @@ void ConditionMgr::LoadConditions(bool isReload)
break;
case CONDITION_SOURCE_TYPE_VEHICLE_SPELL:
{
- //if no list for vehicle create one
- if (VehicleSpellConditionStore.find(cond->SourceGroup) == VehicleSpellConditionStore.end())
- {
- ConditionTypeContainer cmap;
- VehicleSpellConditionStore[cond->SourceGroup] = cmap;
- }
- //if no list for vehicle's spell create one
- if (VehicleSpellConditionStore[cond->SourceGroup].find(cond->SourceEntry) == VehicleSpellConditionStore[cond->SourceGroup].end())
- {
- ConditionList clist;
- VehicleSpellConditionStore[cond->SourceGroup][cond->SourceEntry] = clist;
- }
VehicleSpellConditionStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
valid = true;
++count;
@@ -896,18 +874,8 @@ void ConditionMgr::LoadConditions(bool isReload)
}
case CONDITION_SOURCE_TYPE_SMART_EVENT:
{
- // If the entry does not exist, create a new list
+ //! TODO: PAIR_32 ?
std::pair<int32, uint32> key = std::make_pair(cond->SourceEntry, cond->SourceId);
- if (SmartEventConditionStore.find(key) == SmartEventConditionStore.end())
- {
- ConditionTypeContainer cmap;
- SmartEventConditionStore[key] = cmap;
- }
- if (SmartEventConditionStore[key].find(cond->SourceGroup) == SmartEventConditionStore[key].end())
- {
- ConditionList clist;
- SmartEventConditionStore[key][cond->SourceGroup] = clist;
- }
SmartEventConditionStore[key][cond->SourceGroup].push_back(cond);
valid = true;
++count;
@@ -1929,6 +1897,19 @@ void ConditionMgr::Clean()
SmartEventConditionStore.clear();
+ for (CreatureSpellConditionContainer::iterator itr = SpellClickEventConditionStore.begin(); itr != SpellClickEventConditionStore.end(); ++itr)
+ {
+ for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
+ {
+ for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
+ delete *i;
+ it->second.clear();
+ }
+ itr->second.clear();
+ }
+
+ SpellClickEventConditionStore.clear();
+
// this is a BIG hack, feel free to fix it if you can figure out the ConditionMgr ;)
for (std::list<Condition*>::const_iterator itr = AllocatedMemoryStore.begin(); itr != AllocatedMemoryStore.end(); ++itr)
delete *itr;
diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h
index 5a5e2dd1c2e..ec6d6dd8453 100755
--- a/src/server/game/Conditions/ConditionMgr.h
+++ b/src/server/game/Conditions/ConditionMgr.h
@@ -72,6 +72,33 @@ enum ConditionTypes
CONDITION_MAX = 39 // MAX
};
+/*! Documentation on implementing a new ConditionSourceType:
+ Step 1: Check for the lowest free ID. Look for CONDITION_SOURCE_TYPE_UNUSED_XX in the enum.
+ Then define the new source type.
+
+ Step 2: Determine and map the parameters for the new condition type.
+
+ Step 3: Add a case block to ConditionMgr::isSourceTypeValid with the new condition type
+ and validate the parameters.
+
+ Step 4: If your condition can be grouped (determined in step 2), add a rule for it in
+ ConditionMgr::CanHaveSourceGroupSet, following the example of the existing types.
+
+ Step 5: Define the maximum available condition targets in ConditionMgr::GetMaxAvailableConditionTargets.
+
+ The following steps only apply if your condition can be grouped:
+
+ Step 6: Determine how you are going to store your conditions. You need to add a new storage container
+ for it in ConditionMgr class, along with a function like:
+ ConditionList GetConditionsForXXXYourNewSourceTypeXXX(parameters...)
+
+ The above function should be placed in upper level (practical) code that actually
+ checks the conditions.
+
+ Step 7: Implement loading for your source type in ConditionMgr::LoadConditions.
+
+ Step 8: Implement memory cleaning for your source type in ConditionMgr::Clean.
+*/
enum ConditionSourceType
{
CONDITION_SOURCE_TYPE_NONE = 0,
diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp
index da5975aafbe..5b7c40e5494 100755
--- a/src/server/game/Entities/Corpse/Corpse.cpp
+++ b/src/server/game/Entities/Corpse/Corpse.cpp
@@ -32,7 +32,7 @@ Corpse::Corpse(CorpseType type) : WorldObject(type != CORPSE_BONES)
m_objectType |= TYPEMASK_CORPSE;
m_objectTypeId = TYPEID_CORPSE;
- m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION);
+ m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_POSITION);
m_valuesCount = CORPSE_END;
diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.cpp b/src/server/game/Entities/DynamicObject/DynamicObject.cpp
index fa975e0cd39..0a4e4c73f42 100755
--- a/src/server/game/Entities/DynamicObject/DynamicObject.cpp
+++ b/src/server/game/Entities/DynamicObject/DynamicObject.cpp
@@ -33,7 +33,7 @@ DynamicObject::DynamicObject(bool isWorldObject) : WorldObject(isWorldObject),
m_objectType |= TYPEMASK_DYNAMICOBJECT;
m_objectTypeId = TYPEID_DYNAMICOBJECT;
- m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION);
+ m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_POSITION);
m_valuesCount = DYNAMICOBJECT_END;
}
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index a06cee891e7..c7101e918ba 100755
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -38,7 +38,7 @@ GameObject::GameObject() : WorldObject(false), m_model(NULL), m_goValue(new Game
m_objectType |= TYPEMASK_GAMEOBJECT;
m_objectTypeId = TYPEID_GAMEOBJECT;
- m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION | UPDATEFLAG_ROTATION);
+ m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_POSITION | UPDATEFLAG_ROTATION);
m_valuesCount = GAMEOBJECT_END;
m_respawnTime = 0;
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index 0fc53a65258..90f6f4a217c 100755
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -237,7 +237,7 @@ Item::Item()
m_objectType |= TYPEMASK_ITEM;
m_objectTypeId = TYPEID_ITEM;
- m_updateFlag = UPDATEFLAG_HIGHGUID;
+ m_updateFlag = UPDATEFLAG_LOWGUID;
m_valuesCount = ITEM_END;
m_slot = 0;
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index c1ecc3b74e7..2a2b78f4630 100755
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -209,7 +209,7 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c
if (target == this) // building packet for yourself
flags |= UPDATEFLAG_SELF;
- if (flags & UPDATEFLAG_HAS_POSITION)
+ if (flags & UPDATEFLAG_STATIONARY_POSITION)
{
// UPDATETYPE_CREATE_OBJECT2 dynamic objects, corpses...
if (isType(TYPEMASK_DYNAMICOBJECT) || isType(TYPEMASK_CORPSE) || isType(TYPEMASK_PLAYER))
@@ -293,19 +293,21 @@ void Object::BuildOutOfRangeUpdateBlock(UpdateData* data) const
data->AddOutOfRangeGUID(GetGUID());
}
-void Object::DestroyForPlayer(Player* target, bool anim) const
+void Object::DestroyForPlayer(Player* target, bool onDeath) const
{
ASSERT(target);
WorldPacket data(SMSG_DESTROY_OBJECT, 8 + 1);
data << uint64(GetGUID());
- data << uint8(anim ? 1 : 0); // WotLK (bool), may be despawn animation
+ //! If the following bool is true, the client will call "void CGUnit_C::OnDeath()" for this object.
+ //! OnDeath() does for eg trigger death animation and interrupts certain spells/missiles/auras/sounds...
+ data << uint8(onDeath ? 1 : 0);
target->GetSession()->SendPacket(&data);
}
-void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags) const
+void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
{
- *data << (uint16)flags; // update flags
+ *data << uint16(flags); // update flags
// 0x20
if (flags & UPDATEFLAG_LIVING)
@@ -330,13 +332,29 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags) const
{
if (flags & UPDATEFLAG_POSITION)
{
- *data << uint8(0); // unk PGUID!
- *data << ((WorldObject*)this)->GetPositionX();
- *data << ((WorldObject*)this)->GetPositionY();
- *data << ((WorldObject*)this)->GetPositionZ();
+ Transport* transport = ((WorldObject*)this)->GetTransport();
+ if (transport)
+ data->append(transport->GetPackGUID());
+ else
+ *data << uint8(0);
+
*data << ((WorldObject*)this)->GetPositionX();
*data << ((WorldObject*)this)->GetPositionY();
*data << ((WorldObject*)this)->GetPositionZ();
+
+ if (transport)
+ {
+ *data << ((WorldObject*)this)->GetTransOffsetX();
+ *data << ((WorldObject*)this)->GetTransOffsetY();
+ *data << ((WorldObject*)this)->GetTransOffsetZ();
+ }
+ else
+ {
+ *data << ((WorldObject*)this)->GetPositionX();
+ *data << ((WorldObject*)this)->GetPositionY();
+ *data << ((WorldObject*)this)->GetPositionZ();
+ }
+
*data << ((WorldObject*)this)->GetOrientation();
if (GetTypeId() == TYPEID_CORPSE)
@@ -347,28 +365,23 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags) const
else
{
// 0x40
- if (flags & UPDATEFLAG_HAS_POSITION)
+ if (flags & UPDATEFLAG_STATIONARY_POSITION)
{
- // 0x02
- if (flags & UPDATEFLAG_TRANSPORT && ((GameObject*)this)->GetGoType() == GAMEOBJECT_TYPE_MO_TRANSPORT)
- {
- *data << (float)0;
- *data << (float)0;
- *data << (float)0;
- *data << ((WorldObject*)this)->GetOrientation();
- }
- else
- {
- *data << ((WorldObject*)this)->GetPositionX();
- *data << ((WorldObject*)this)->GetPositionY();
- *data << ((WorldObject*)this)->GetPositionZ();
- *data << ((WorldObject*)this)->GetOrientation();
- }
+ *data << ((WorldObject*)this)->GetPositionX();
+ *data << ((WorldObject*)this)->GetPositionY();
+ *data << ((WorldObject*)this)->GetPositionZ();
+ *data << ((WorldObject*)this)->GetOrientation();
}
}
}
// 0x8
+ if (flags & UPDATEFLAG_UNKNOWN)
+ {
+ *data << uint32(0);
+ }
+
+ // 0x10
if (flags & UPDATEFLAG_LOWGUID)
{
switch (GetTypeId())
@@ -381,14 +394,16 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags) const
case TYPEID_CORPSE:
*data << uint32(GetGUIDLow()); // GetGUIDLow()
break;
+ //! Unit, Player and default here are sending wrong values.
+ //! TODO: Research the proper formula
case TYPEID_UNIT:
- *data << uint32(0x0000000B); // unk, can be 0xB or 0xC
+ *data << uint32(0x0000000B); // unk
break;
case TYPEID_PLAYER:
if (flags & UPDATEFLAG_SELF)
- *data << uint32(0x0000002F); // unk, can be 0x15 or 0x22
+ *data << uint32(0x0000002F); // unk
else
- *data << uint32(0x00000008); // unk, can be 0x7 or 0x8
+ *data << uint32(0x00000008); // unk
break;
default:
*data << uint32(0x00000000); // unk
@@ -396,15 +411,8 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags) const
}
}
- // 0x10
- if (flags & UPDATEFLAG_HIGHGUID)
- {
- // not high guid
- *data << uint32(GetUInt32Value(OBJECT_FIELD_GUID)); // unk
- }
-
// 0x4
- if (flags & UPDATEFLAG_HAS_TARGET) // packed guid (current target guid)
+ if (flags & UPDATEFLAG_HAS_TARGET)
{
if (Unit* victim = ((Unit*)this)->getVictim())
data->append(victim->GetPackGUID());
@@ -415,14 +423,15 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags) const
// 0x2
if (flags & UPDATEFLAG_TRANSPORT)
{
- *data << uint32(getMSTime()); // ms time
+ *data << uint32(getMSTime()); // Unknown - getMSTime is wrong.
}
// 0x80
- if (flags & UPDATEFLAG_VEHICLE) // unused for now
+ if (flags & UPDATEFLAG_VEHICLE)
{
- *data << uint32(((Unit*)this)->GetVehicleKit()->GetVehicleInfo()->m_ID); // vehicle id
- *data << float(((Creature*)this)->GetOrientation()); // facing adjustment
+ // TODO: Allow players to aquire this updateflag.
+ *data << uint32(((Unit*)this)->GetVehicleKit()->GetVehicleInfo()->m_ID);
+ *data << float(((Creature*)this)->GetOrientation());
}
// 0x200
@@ -581,7 +590,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask*
{
uint32 dynamicFlags = m_uint32Values[index];
- if (const Creature* creature = ToCreature())
+ if (Creature const* creature = ToCreature())
{
if (creature->hasLootRecipient())
{
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 7b3fcc4a337..c243527570b 100755
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -147,7 +147,7 @@ class Object
void BuildOutOfRangeUpdateBlock(UpdateData* data) const;
void BuildMovementUpdateBlock(UpdateData* data, uint32 flags = 0) const;
- virtual void DestroyForPlayer(Player* target, bool anim = false) const;
+ virtual void DestroyForPlayer(Player* target, bool onDeath = false) const;
int32 GetInt32Value(uint16 index) const
{
@@ -299,18 +299,18 @@ class Object
// FG: some hacky helpers
void ForceValuesUpdateAtIndex(uint32);
- Player* ToPlayer(){ if (GetTypeId() == TYPEID_PLAYER) return reinterpret_cast<Player*>(this); else return NULL; }
- const Player* ToPlayer() const { if (GetTypeId() == TYPEID_PLAYER) return (const Player*)((Player*)this); else return NULL; }
- Creature* ToCreature(){ if (GetTypeId() == TYPEID_UNIT) return reinterpret_cast<Creature*>(this); else return NULL; }
- const Creature* ToCreature() const {if (GetTypeId() == TYPEID_UNIT) return (const Creature*)((Creature*)this); else return NULL; }
+ Player* ToPlayer() { if (GetTypeId() == TYPEID_PLAYER) return reinterpret_cast<Player*>(this); else return NULL; }
+ Player const* ToPlayer() const { if (GetTypeId() == TYPEID_PLAYER) return (Player const*)((Player*)this); else return NULL; }
+ Creature* ToCreature() { if (GetTypeId() == TYPEID_UNIT) return reinterpret_cast<Creature*>(this); else return NULL; }
+ Creature const* ToCreature() const { if (GetTypeId() == TYPEID_UNIT) return (Creature const*)((Creature*)this); else return NULL; }
- Unit* ToUnit(){ if (GetTypeId() == TYPEID_UNIT || GetTypeId() == TYPEID_PLAYER) return reinterpret_cast<Unit*>(this); else return NULL; }
- const Unit* ToUnit() const {if (GetTypeId() == TYPEID_UNIT || GetTypeId() == TYPEID_PLAYER) return (const Unit*)((Unit*)this); else return NULL; }
- GameObject* ToGameObject(){ if (GetTypeId() == TYPEID_GAMEOBJECT) return reinterpret_cast<GameObject*>(this); else return NULL; }
- const GameObject* ToGameObject() const {if (GetTypeId() == TYPEID_GAMEOBJECT) return (const GameObject*)((GameObject*)this); else return NULL; }
+ Unit* ToUnit() { if (GetTypeId() == TYPEID_UNIT || GetTypeId() == TYPEID_PLAYER) return reinterpret_cast<Unit*>(this); else return NULL; }
+ Unit const* ToUnit() const { if (GetTypeId() == TYPEID_UNIT || GetTypeId() == TYPEID_PLAYER) return (const Unit*)((Unit*)this); else return NULL; }
+ GameObject* ToGameObject() { if (GetTypeId() == TYPEID_GAMEOBJECT) return reinterpret_cast<GameObject*>(this); else return NULL; }
+ GameObject const* ToGameObject() const { if (GetTypeId() == TYPEID_GAMEOBJECT) return (const GameObject*)((GameObject*)this); else return NULL; }
- Corpse* ToCorpse(){ if (GetTypeId() == TYPEID_CORPSE) return reinterpret_cast<Corpse*>(this); else return NULL; }
- const Corpse* ToCorpse() const {if (GetTypeId() == TYPEID_CORPSE) return (const Corpse*)((Corpse*)this); else return NULL; }
+ Corpse* ToCorpse() { if (GetTypeId() == TYPEID_CORPSE) return reinterpret_cast<Corpse*>(this); else return NULL; }
+ Corpse const* ToCorpse() const { if (GetTypeId() == TYPEID_CORPSE) return (const Corpse*)((Corpse*)this); else return NULL; }
protected:
Object ();
diff --git a/src/server/game/Entities/Object/Updates/UpdateData.h b/src/server/game/Entities/Object/Updates/UpdateData.h
index e4caaec3117..ff649b7cb2f 100755
--- a/src/server/game/Entities/Object/Updates/UpdateData.h
+++ b/src/server/game/Entities/Object/Updates/UpdateData.h
@@ -34,17 +34,17 @@ enum OBJECT_UPDATE_TYPE
enum OBJECT_UPDATE_FLAGS
{
- UPDATEFLAG_NONE = 0x0000,
- UPDATEFLAG_SELF = 0x0001,
- UPDATEFLAG_TRANSPORT = 0x0002,
- UPDATEFLAG_HAS_TARGET = 0x0004,
- UPDATEFLAG_LOWGUID = 0x0008,
- UPDATEFLAG_HIGHGUID = 0x0010,
- UPDATEFLAG_LIVING = 0x0020,
- UPDATEFLAG_HAS_POSITION = 0x0040,
- UPDATEFLAG_VEHICLE = 0x0080,
- UPDATEFLAG_POSITION = 0x0100,
- UPDATEFLAG_ROTATION = 0x0200
+ UPDATEFLAG_NONE = 0x0000,
+ UPDATEFLAG_SELF = 0x0001,
+ UPDATEFLAG_TRANSPORT = 0x0002,
+ UPDATEFLAG_HAS_TARGET = 0x0004,
+ UPDATEFLAG_UNKNOWN = 0x0008,
+ UPDATEFLAG_LOWGUID = 0x0010,
+ UPDATEFLAG_LIVING = 0x0020,
+ UPDATEFLAG_STATIONARY_POSITION = 0x0040,
+ UPDATEFLAG_VEHICLE = 0x0080,
+ UPDATEFLAG_POSITION = 0x0100,
+ UPDATEFLAG_ROTATION = 0x0200
};
class UpdateData
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 857ae4d845b..870b6f683b8 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -143,8 +143,9 @@ static uint32 copseReclaimDelay[MAX_DEATH_COUNT] = { 30, 60, 120 };
// == PlayerTaxi ================================================
PlayerTaxi::PlayerTaxi()
- : m_taximask()
-{ }
+{
+ memset(m_taximask, 0, sizeof(m_taximask));
+}
void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint8 level)
{
@@ -4623,9 +4624,9 @@ void Player::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c
Unit::BuildCreateUpdateBlockForPlayer(data, target);
}
-void Player::DestroyForPlayer(Player* target, bool anim) const
+void Player::DestroyForPlayer(Player* target, bool onDeath) const
{
- Unit::DestroyForPlayer(target, anim);
+ Unit::DestroyForPlayer(target, onDeath);
for (uint8 i = 0; i < INVENTORY_SLOT_BAG_END; ++i)
{
@@ -7420,6 +7421,8 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
}
}
+ sScriptMgr->OnPlayerUpdateZone(this, newZone, newArea);
+
// in PvP, any not controlled zone (except zone->team == 6, default case)
// in PvE, only opposition team capital
switch (zone->team)
@@ -17780,12 +17783,19 @@ void Player::_LoadQuestStatus(PreparedQueryResult result)
QuestStatusData& questStatusData = m_QuestStatus[quest_id];
uint8 qstatus = fields[1].GetUInt8();
- if (qstatus < MAX_QUEST_STATUS)
+ if (qstatus < MAX_QUEST_STATUS && qstatus > QUEST_STATUS_NONE)
questStatusData.Status = QuestStatus(qstatus);
+ else if (qstatus == QUEST_STATUS_NONE)
+ {
+ sLog->outError("Player %s (GUID: %u) has QUEST_STATUS_NONE for quest %u and should be removed from character_queststatus.",
+ GetName(), GetGUIDLow(), quest_id);
+ continue;
+ }
else
{
questStatusData.Status = QUEST_STATUS_INCOMPLETE;
- sLog->outError("Player %s have invalid quest %d status (%u), replaced by QUEST_STATUS_INCOMPLETE(3).", GetName(), quest_id, qstatus);
+ sLog->outError("Player %s (GUID: %u) has invalid quest %d status (%u), replaced by QUEST_STATUS_INCOMPLETE(3).",
+ GetName(), GetGUIDLow(), quest_id, qstatus);
}
questStatusData.Explored = (fields[2].GetUInt8() > 0);
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index db055088808..3d510148aa4 100755
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -687,9 +687,9 @@ enum TransferAbortReason
TRANSFER_ABORT_UNIQUE_MESSAGE = 0x09, // Until you've escaped TLK's grasp, you cannot leave this place!
TRANSFER_ABORT_TOO_MANY_REALM_INSTANCES = 0x0A, // Additional instances cannot be launched, please try again later.
TRANSFER_ABORT_NEED_GROUP = 0x0B, // 3.1
- TRANSFER_ABORT_NOT_FOUND2 = 0x0C, // 3.1
- TRANSFER_ABORT_NOT_FOUND3 = 0x0D, // 3.1
- TRANSFER_ABORT_NOT_FOUND4 = 0x0E, // 3.2
+ TRANSFER_ABORT_NOT_FOUND1 = 0x0C, // 3.1
+ TRANSFER_ABORT_NOT_FOUND2 = 0x0D, // 3.1
+ TRANSFER_ABORT_NOT_FOUND3 = 0x0E, // 3.2
TRANSFER_ABORT_REALM_ONLY = 0x0F, // All players on party must be from the same realm.
TRANSFER_ABORT_MAP_NOT_ALLOWED = 0x10, // Map can't be entered at this time.
};
@@ -1915,7 +1915,7 @@ class Player : public Unit, public GridObject<Player>
WorldSession* GetSession() const { return m_session; }
void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const;
- void DestroyForPlayer(Player* target, bool anim = false) const;
+ void DestroyForPlayer(Player* target, bool onDeath = false) const;
void SendLogXPGain(uint32 GivenXP, Unit* victim, uint32 BonusXP, bool recruitAFriend = false, float group_rate=1.0f);
// notifiers
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index a425640e36d..24fe75605d2 100755
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -173,7 +173,7 @@ void MapManager::LoadTransportNPCs()
Transport::Transport(uint32 period, uint32 script) : GameObject(), m_pathTime(0), m_timer(0),
currenttguid(0), m_period(period), ScriptId(script), m_nextNodeTime(0)
{
- m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_ROTATION);
+ m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_ROTATION);
}
Transport::~Transport()
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 3af6d388ba9..3411d285b1e 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -158,7 +158,7 @@ m_HostileRefManager(this)
m_objectType |= TYPEMASK_UNIT;
m_objectTypeId = TYPEID_UNIT;
- m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION);
+ m_updateFlag = (UPDATEFLAG_LIVING | UPDATEFLAG_STATIONARY_POSITION);
m_attackTimer[BASE_ATTACK] = 0;
m_attackTimer[OFF_ATTACK] = 0;
@@ -430,7 +430,7 @@ void Unit::SendMonsterMoveTransport(Unit* vehicleOwner)
data.append(GetPackGUID());
data.append(vehicleOwner->GetPackGUID());
data << int8(GetTransSeat());
- data << uint8(GetTypeId() == TYPEID_PLAYER ? 1 : 0); // boolean
+ data << uint8(0);
data << GetPositionX() - vehicleOwner->GetPositionX();
data << GetPositionY() - vehicleOwner->GetPositionY();
data << GetPositionZ() - vehicleOwner->GetPositionZ();
@@ -784,20 +784,9 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
// last damage from duel opponent
if (duel_hasEnded)
{
- Player* he;
+ Player* he = duel_wasMounted ? victim->GetCharmer()->ToPlayer() : victim->ToPlayer();
- if (duel_wasMounted)
- {
- ASSERT(victim->GetCharmer()->GetTypeId() == TYPEID_PLAYER);
- he = victim->GetCharmer()->ToPlayer();
- }
- else
- {
- ASSERT(victim->GetTypeId() == TYPEID_PLAYER);
- he = victim->ToPlayer();
- }
-
- ASSERT(he->duel);
+ ASSERT(he && he->duel);
if (duel_wasMounted) // In this case victim==mount
victim->SetHealth(1);
@@ -16991,7 +16980,7 @@ void Unit::ChangeSeat(int8 seatId, bool next)
ASSERT(false);
}
-void Unit::ExitVehicle(Position const* exitPosition)
+void Unit::ExitVehicle(Position const* /*exitPosition*/)
{
//! This function can be called at upper level code to initialize an exit from the passenger's side.
if (!m_vehicle)
@@ -17171,14 +17160,18 @@ bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool tel
GetMap()->CreatureRelocation(ToCreature(), x, y, z, orientation);
}
else if (turn)
- SetOrientation(orientation);
-
- if ((relocated || turn) && IsVehicle())
- GetVehicleKit()->RelocatePassengers(x, y, z, orientation);
+ UpdateOrientation(orientation);
return (relocated || turn);
}
+void Unit::UpdateOrientation(float orientation)
+{
+ SetOrientation(orientation);
+ if (IsVehicle())
+ GetVehicleKit()->RelocatePassengers(GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
+}
+
void Unit::SendThreatListUpdate()
{
if (!getThreatManager().isThreatListEmpty())
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 0fe5f3d8ca3..b07f2ae1c16 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1614,6 +1614,7 @@ class Unit : public WorldObject
virtual bool UpdatePosition(float x, float y, float z, float ang, bool teleport = false);
// returns true if unit's position really changed
bool UpdatePosition(const Position &pos, bool teleport = false) { return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); }
+ void UpdateOrientation(float orientation);
void KnockbackFrom(float x, float y, float speedXY, float speedZ);
void JumpTo(float speedXY, float speedZ, bool forward = true);
diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp
index 6693af5c91f..2f552eddb9f 100755
--- a/src/server/game/Entities/Vehicle/Vehicle.cpp
+++ b/src/server/game/Entities/Vehicle/Vehicle.cpp
@@ -431,6 +431,7 @@ void Vehicle::RemovePassenger(Unit* unit)
sScriptMgr->OnRemovePassenger(this, unit);
}
+//! Must be called after m_base::Relocate
void Vehicle::RelocatePassengers(float x, float y, float z, float ang)
{
ASSERT(_me->GetMap());
@@ -440,8 +441,6 @@ void Vehicle::RelocatePassengers(float x, float y, float z, float ang)
if (Unit* passenger = ObjectAccessor::GetUnit(*GetBase(), itr->second.Passenger))
{
ASSERT(passenger->IsInWorld());
- ASSERT(passenger->IsOnVehicle(GetBase()));
- ASSERT(GetSeatForPassenger(passenger));
float px = x + passenger->m_movementInfo.t_pos.m_positionX;
float py = y + passenger->m_movementInfo.t_pos.m_positionY;
diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp
index 1a069a27825..9a99a28c7aa 100755
--- a/src/server/game/Globals/ObjectAccessor.cpp
+++ b/src/server/game/Globals/ObjectAccessor.cpp
@@ -166,10 +166,18 @@ Unit* ObjectAccessor::FindUnit(uint64 guid)
Player* ObjectAccessor::FindPlayerByName(const char* name)
{
TRINITY_READ_GUARD(HashMapHolder<Player>::LockType, *HashMapHolder<Player>::GetLock());
+ std::string nameStr = name;
+ std::transform(nameStr.begin(), nameStr.end(), nameStr.begin(), ::tolower);
HashMapHolder<Player>::MapType const& m = GetPlayers();
for (HashMapHolder<Player>::MapType::const_iterator iter = m.begin(); iter != m.end(); ++iter)
- if (iter->second->IsInWorld() && strcmp(name, iter->second->GetName()) == 0)
+ {
+ if (!iter->second->IsInWorld())
+ continue;
+ std::string currentName = iter->second->GetName();
+ std::transform(currentName.begin(), currentName.end(), currentName.begin(), ::tolower);
+ if (nameStr.compare(currentName) == 0)
return iter->second;
+ }
return NULL;
}
@@ -400,4 +408,4 @@ template Pet* ObjectAccessor::GetObjectInWorld<Pet>(uint32 mapid, float x, float
template Creature* ObjectAccessor::GetObjectInWorld<Creature>(uint32 mapid, float x, float y, uint64 guid, Creature* /*fake*/);
template Corpse* ObjectAccessor::GetObjectInWorld<Corpse>(uint32 mapid, float x, float y, uint64 guid, Corpse* /*fake*/);
template GameObject* ObjectAccessor::GetObjectInWorld<GameObject>(uint32 mapid, float x, float y, uint64 guid, GameObject* /*fake*/);
-template DynamicObject* ObjectAccessor::GetObjectInWorld<DynamicObject>(uint32 mapid, float x, float y, uint64 guid, DynamicObject* /*fake*/); \ No newline at end of file
+template DynamicObject* ObjectAccessor::GetObjectInWorld<DynamicObject>(uint32 mapid, float x, float y, uint64 guid, DynamicObject* /*fake*/);
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 7834a1cc4a3..11977280177 100755
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -7079,7 +7079,7 @@ void ObjectMgr::LoadNPCSpellClickSpells()
uint32 oldMSTime = getMSTime();
_spellClickInfoStore.clear();
- // 0 1 2 3
+ // 0 1 2 3
QueryResult result = WorldDatabase.Query("SELECT npc_entry, spell_id, cast_flags, user_type FROM npc_spellclick_spells");
if (!result)
diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp
index 223bb7dd5c7..f82c52204fb 100755
--- a/src/server/game/Handlers/AuctionHouseHandler.cpp
+++ b/src/server/game/Handlers/AuctionHouseHandler.cpp
@@ -241,6 +241,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
else
AH->auctioneer = GUID_LOPART(auctioneer);
+ // Required stack size of auction matches to current item stack size, just move item to auctionhouse
if (itemsCount == 1 && item->GetCount() == count[i])
{
if (GetSecurity() > SEC_PLAYER && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE))
@@ -278,7 +279,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1);
return;
}
- else
+ else // Required stack size of auction does not match to current item stack size, clone item and set correct stack size
{
Item* newItem = item->CloneItem(finalCount, _player);
if (!newItem)
@@ -313,16 +314,17 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
{
Item* item2 = items[j];
+ // Item stack count equals required count, ready to delete item - cloned item will be used for auction
if (item2->GetCount() == count[j])
{
_player->MoveItemFromInventory(item2->GetBagSlot(), item2->GetSlot(), true);
SQLTransaction trans = CharacterDatabase.BeginTransaction();
item2->DeleteFromInventoryDB(trans);
- item2->SaveToDB(trans);
+ item2->DeleteFromDB(trans);
CharacterDatabase.CommitTransaction(trans);
}
- else
+ else // Item stack count is bigger than required count, update item stack count and save to database - cloned item will be used for auction
{
item2->SetCount(item2->GetCount() - count[j]);
item2->SetState(ITEM_CHANGED, _player);
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 31dc622a724..00b52bf746b 100755
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -32,6 +32,7 @@
#include "Group.h"
#include "LFGMgr.h"
#include "DynamicTree.h"
+#include "Vehicle.h"
union u_map_magic
{
@@ -702,6 +703,8 @@ void Map::PlayerRelocation(Player* player, float x, float y, float z, float orie
Cell new_cell(x, y);
player->Relocate(x, y, z, orientation);
+ if (player->IsVehicle())
+ player->GetVehicleKit()->RelocatePassengers(x, y, z, orientation);
if (old_cell.DiffGrid(new_cell) || old_cell.DiffCell(new_cell))
{
@@ -740,6 +743,8 @@ void Map::CreatureRelocation(Creature* creature, float x, float y, float z, floa
else
{
creature->Relocate(x, y, z, ang);
+ if (creature->IsVehicle())
+ creature->GetVehicleKit()->RelocatePassengers(x, y, z, ang);
creature->UpdateObjectVisibility(false);
RemoveCreatureFromMoveList(creature);
}
diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp
index fbe609bee23..5543251e115 100755
--- a/src/server/game/Maps/MapInstanced.cpp
+++ b/src/server/game/Maps/MapInstanced.cpp
@@ -116,19 +116,21 @@ Map* MapInstanced::CreateInstanceForPlayer(const uint32 mapId, Player* player)
return NULL;
Map* map = NULL;
- uint32 NewInstanceId = 0; // instanceId of the resulting map
+ uint32 newInstanceId = 0; // instanceId of the resulting map
if (IsBattlegroundOrArena())
{
// instantiate or find existing bg map for player
// the instance id is set in battlegroundid
- NewInstanceId = player->GetBattlegroundId();
- if (!NewInstanceId) return NULL;
- map = sMapMgr->FindMap(mapId, NewInstanceId);
+ newInstanceId = player->GetBattlegroundId();
+ if (!newInstanceId)
+ return NULL;
+
+ map = sMapMgr->FindMap(mapId, newInstanceId);
if (!map)
{
if (Battleground* bg = player->GetBattleground())
- map = CreateBattleground(NewInstanceId, bg);
+ map = CreateBattleground(newInstanceId, bg);
else
{
player->TeleportToBGEntryPoint();
@@ -158,24 +160,24 @@ Map* MapInstanced::CreateInstanceForPlayer(const uint32 mapId, Player* player)
if (pSave)
{
// solo/perm/group
- NewInstanceId = pSave->GetInstanceId();
- map = FindInstanceMap(NewInstanceId);
+ newInstanceId = pSave->GetInstanceId();
+ map = FindInstanceMap(newInstanceId);
// it is possible that the save exists but the map doesn't
if (!map)
- map = CreateInstance(NewInstanceId, pSave, pSave->GetDifficulty());
+ map = CreateInstance(newInstanceId, pSave, pSave->GetDifficulty());
}
else
{
// if no instanceId via group members or instance saves is found
// the instance will be created for the first time
- NewInstanceId = sMapMgr->GenerateInstanceId();
+ newInstanceId = sMapMgr->GenerateInstanceId();
Difficulty diff = player->GetGroup() ? player->GetGroup()->GetDifficulty(IsRaid()) : player->GetDifficulty(IsRaid());
//Seems it is now possible, but I do not know if it should be allowed
//ASSERT(!FindInstanceMap(NewInstanceId));
- map = FindInstanceMap(NewInstanceId);
+ map = FindInstanceMap(newInstanceId);
if (!map)
- map = CreateInstance(NewInstanceId, NULL, diff);
+ map = CreateInstance(newInstanceId, NULL, diff);
}
}
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index e751dbf92fe..547f1679b61 100755
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -811,7 +811,9 @@ enum TrinityStrings
LANG_MOVEGENS_FOLLOW_CREATURE = 1140,
LANG_MOVEGENS_FOLLOW_NULL = 1141,
LANG_MOVEGENS_EFFECT = 1142,
- // Room for more level 3 1143-1199 not used
+ LANG_MOVEFLAGS_GET = 1143,
+ LANG_MOVEFLAGS_SET = 1144,
+ // Room for more level 3 1144-1199 not used
// Debug commands
LANG_CINEMATIC_NOT_EXIST = 1200,
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index 47751338d66..ac15bd5c985 100755
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -1295,6 +1295,11 @@ void ScriptMgr::OnPlayerBindToInstance(Player* player, Difficulty difficulty, ui
FOREACH_SCRIPT(PlayerScript)->OnBindToInstance(player, difficulty, mapid, permanent);
}
+void ScriptMgr::OnPlayerUpdateZone(Player* player, uint32 newZone, uint32 newArea)
+{
+ FOREACH_SCRIPT(PlayerScript)->OnUpdateZone(player, newZone, newArea);
+}
+
// Guild
void ScriptMgr::OnGuildAddMember(Guild* guild, Player* player, uint8& plRank)
{
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index 048a7581215..3b65a5cf256 100755
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -724,6 +724,9 @@ class PlayerScript : public ScriptObject
// Called when a player is bound to an instance
virtual void OnBindToInstance(Player* /*player*/, Difficulty /*difficulty*/, uint32 /*mapId*/, bool /*permanent*/) { }
+
+ // Called when a player switches to a new zone
+ virtual void OnUpdateZone(Player* /*player*/, uint32 /*newZone*/, uint32 /*newArea*/) { }
};
class GuildScript : public ScriptObject
@@ -993,6 +996,7 @@ class ScriptMgr
void OnPlayerCreate(Player* player);
void OnPlayerDelete(uint64 guid);
void OnPlayerBindToInstance(Player* player, Difficulty difficulty, uint32 mapid, bool permanent);
+ void OnPlayerUpdateZone(Player* player, uint32 newZone, uint32 newArea);
public: /* GuildScript */
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index e2e6772f230..e5b5b20dcfa 100755
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -769,7 +769,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x2E4*/ { "SMSG_AREA_SPIRIT_HEALER_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
/*0x2E5*/ { "CMSG_GM_UNTEACH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
/*0x2E6*/ { "SMSG_WARDEN_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2E7*/ { "CMSG_WARDEN_DATA", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleWardenDataOpcode },
+ /*0x2E7*/ { "CMSG_WARDEN_DATA", STATUS_AUTHED, PROCESS_THREADSAFE, &WorldSession::HandleWardenDataOpcode },
/*0x2E8*/ { "SMSG_GROUP_JOINED_BATTLEGROUND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
/*0x2E9*/ { "MSG_BATTLEGROUND_PLAYER_POSITIONS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlegroundPlayerPositionsOpcode},
/*0x2EA*/ { "CMSG_PET_STOP_ATTACK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetStopAttack },
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 4f4de7c72cd..2ffa94371f9 100755
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -56,6 +56,35 @@
extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS];
+SpellDestination::SpellDestination()
+{
+ _position.Relocate(0, 0, 0, 0);
+ _transportGUID = 0;
+ _transportOffset.Relocate(0, 0, 0, 0);
+}
+
+SpellDestination::SpellDestination(float x, float y, float z, float orientation, uint32 mapId)
+{
+ _position.Relocate(x, y, z, orientation);
+ _transportGUID = 0;
+ _position.m_mapId = mapId;
+}
+
+SpellDestination::SpellDestination(Position const& pos)
+{
+ _position.Relocate(pos);
+ _transportGUID = 0;
+}
+
+SpellDestination::SpellDestination(WorldObject const& wObj)
+{
+ _transportGUID = wObj.GetTransGUID();
+ _transportOffset.Relocate(wObj.GetTransOffsetX(), wObj.GetTransOffsetY(), wObj.GetTransOffsetZ(), wObj.GetTransOffsetO());
+ _position.Relocate(wObj);
+ _position.SetOrientation(wObj.GetOrientation());
+}
+
+
SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0)
{
m_objectTarget = NULL;
@@ -65,12 +94,6 @@ SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0)
m_itemTargetGUID = 0;
m_itemTargetEntry = 0;
- m_srcTransGUID = 0;
- m_srcTransOffset.Relocate(0, 0, 0, 0);
- m_srcPos.Relocate(0, 0, 0, 0);
- m_dstTransGUID = 0;
- m_dstTransOffset.Relocate(0, 0, 0, 0);
- m_dstPos.Relocate(0, 0, 0, 0);
m_strTarget = "";
m_targetMask = 0;
}
@@ -94,36 +117,36 @@ void SpellCastTargets::Read(ByteBuffer& data, Unit* caster)
if (m_targetMask & TARGET_FLAG_SOURCE_LOCATION)
{
- data.readPackGUID(m_srcTransGUID);
- if (m_srcTransGUID)
- data >> m_srcTransOffset.PositionXYZStream();
+ data.readPackGUID(m_src._transportGUID);
+ if (m_src._transportGUID)
+ data >> m_src._transportOffset.PositionXYZStream();
else
- data >> m_srcPos.PositionXYZStream();
+ data >> m_src._position.PositionXYZStream();
}
else
{
- m_srcTransGUID = caster->GetTransGUID();
- if (m_srcTransGUID)
- m_srcTransOffset.Relocate(caster->GetTransOffsetX(), caster->GetTransOffsetY(), caster->GetTransOffsetZ(), caster->GetTransOffsetO());
+ m_src._transportGUID = caster->GetTransGUID();
+ if (m_src._transportGUID)
+ m_src._transportOffset.Relocate(caster->GetTransOffsetX(), caster->GetTransOffsetY(), caster->GetTransOffsetZ(), caster->GetTransOffsetO());
else
- m_srcPos.Relocate(caster);
+ m_src._position.Relocate(caster);
}
if (m_targetMask & TARGET_FLAG_DEST_LOCATION)
{
- data.readPackGUID(m_dstTransGUID);
- if (m_dstTransGUID)
- data >> m_dstTransOffset.PositionXYZStream();
+ data.readPackGUID(m_dst._transportGUID);
+ if (m_dst._transportGUID)
+ data >> m_dst._transportOffset.PositionXYZStream();
else
- data >> m_dstPos.PositionXYZStream();
+ data >> m_dst._position.PositionXYZStream();
}
else
{
- m_dstTransGUID = caster->GetTransGUID();
- if (m_dstTransGUID)
- m_dstTransOffset.Relocate(caster->GetTransOffsetX(), caster->GetTransOffsetY(), caster->GetTransOffsetZ(), caster->GetTransOffsetO());
+ m_dst._transportGUID = caster->GetTransGUID();
+ if (m_dst._transportGUID)
+ m_dst._transportOffset.Relocate(caster->GetTransOffsetX(), caster->GetTransOffsetY(), caster->GetTransOffsetZ(), caster->GetTransOffsetO());
else
- m_dstPos.Relocate(caster);
+ m_dst._position.Relocate(caster);
}
if (m_targetMask & TARGET_FLAG_STRING)
@@ -149,20 +172,20 @@ void SpellCastTargets::Write(ByteBuffer& data)
if (m_targetMask & TARGET_FLAG_SOURCE_LOCATION)
{
- data.appendPackGUID(m_srcTransGUID); // relative position guid here - transport for example
- if (m_srcTransGUID)
- data << m_srcTransOffset.PositionXYZStream();
+ data.appendPackGUID(m_src._transportGUID); // relative position guid here - transport for example
+ if (m_src._transportGUID)
+ data << m_src._transportOffset.PositionXYZStream();
else
- data << m_srcPos.PositionXYZStream();
+ data << m_src._position.PositionXYZStream();
}
if (m_targetMask & TARGET_FLAG_DEST_LOCATION)
{
- data.appendPackGUID(m_dstTransGUID); // relative position guid here - transport for example
- if (m_dstTransGUID)
- data << m_dstTransOffset.PositionXYZStream();
+ data.appendPackGUID(m_dst._transportGUID); // relative position guid here - transport for example
+ if (m_dst._transportGUID)
+ data << m_dst._transportOffset.PositionXYZStream();
else
- data << m_dstPos.PositionXYZStream();
+ data << m_dst._position.PositionXYZStream();
}
if (m_targetMask & TARGET_FLAG_STRING)
@@ -295,31 +318,31 @@ void SpellCastTargets::UpdateTradeSlotItem()
}
}
-Position const* SpellCastTargets::GetSrc() const
+SpellDestination const* SpellCastTargets::GetSrc() const
{
- return &m_srcPos;
+ return &m_src;
+}
+
+Position const* SpellCastTargets::GetSrcPos() const
+{
+ return &m_src._position;
}
void SpellCastTargets::SetSrc(float x, float y, float z)
{
- m_srcPos.Relocate(x, y, z);
- m_srcTransGUID = 0;
+ m_src = SpellDestination(x, y, z);
m_targetMask |= TARGET_FLAG_SOURCE_LOCATION;
}
void SpellCastTargets::SetSrc(Position const& pos)
{
- m_srcPos.Relocate(pos);
- m_srcTransGUID = 0;
+ m_src = SpellDestination(pos);
m_targetMask |= TARGET_FLAG_SOURCE_LOCATION;
}
void SpellCastTargets::SetSrc(WorldObject const& wObj)
{
- uint64 guid = wObj.GetTransGUID();
- m_srcTransGUID = guid;
- m_srcTransOffset.Relocate(wObj.GetTransOffsetX(), wObj.GetTransOffsetY(), wObj.GetTransOffsetZ(), wObj.GetTransOffsetO());
- m_srcPos.Relocate(wObj);
+ m_src = SpellDestination(wObj);
m_targetMask |= TARGET_FLAG_SOURCE_LOCATION;
}
@@ -327,13 +350,13 @@ void SpellCastTargets::ModSrc(Position const& pos)
{
ASSERT(m_targetMask & TARGET_FLAG_SOURCE_LOCATION);
- if (m_srcTransGUID)
+ if (m_src._transportGUID)
{
Position offset;
- m_srcPos.GetPositionOffsetTo(pos, offset);
- m_srcTransOffset.RelocateOffset(offset);
+ m_src._position.GetPositionOffsetTo(pos, offset);
+ m_src._transportOffset.RelocateOffset(offset);
}
- m_srcPos.Relocate(pos);
+ m_src._position.Relocate(pos);
}
void SpellCastTargets::RemoveSrc()
@@ -341,41 +364,37 @@ void SpellCastTargets::RemoveSrc()
m_targetMask &= ~(TARGET_FLAG_SOURCE_LOCATION);
}
-WorldLocation const* SpellCastTargets::GetDst() const
+SpellDestination const* SpellCastTargets::GetDst() const
{
- return &m_dstPos;
+ return &m_dst;
+}
+
+WorldLocation const* SpellCastTargets::GetDstPos() const
+{
+ return &m_dst._position;
}
void SpellCastTargets::SetDst(float x, float y, float z, float orientation, uint32 mapId)
{
- m_dstPos.Relocate(x, y, z, orientation);
- m_dstTransGUID = 0;
+ m_dst = SpellDestination(x, y, z, orientation, mapId);
m_targetMask |= TARGET_FLAG_DEST_LOCATION;
- if (mapId != MAPID_INVALID)
- m_dstPos.m_mapId = mapId;
}
void SpellCastTargets::SetDst(Position const& pos)
{
- m_dstPos.Relocate(pos);
- m_dstTransGUID = 0;
+ m_dst = SpellDestination(pos);
m_targetMask |= TARGET_FLAG_DEST_LOCATION;
}
void SpellCastTargets::SetDst(WorldObject const& wObj)
{
- uint64 guid = wObj.GetTransGUID();
- m_dstTransGUID = guid;
- m_dstTransOffset.Relocate(wObj.GetTransOffsetX(), wObj.GetTransOffsetY(), wObj.GetTransOffsetZ(), wObj.GetTransOffsetO());
- m_dstPos.Relocate(wObj);
+ m_dst = SpellDestination(wObj);
m_targetMask |= TARGET_FLAG_DEST_LOCATION;
}
void SpellCastTargets::SetDst(SpellCastTargets const& spellTargets)
{
- m_dstTransGUID = spellTargets.m_dstTransGUID;
- m_dstTransOffset.Relocate(spellTargets.m_dstTransOffset);
- m_dstPos.Relocate(spellTargets.m_dstPos);
+ m_dst = spellTargets.m_dst;
m_targetMask |= TARGET_FLAG_DEST_LOCATION;
}
@@ -383,13 +402,13 @@ void SpellCastTargets::ModDst(Position const& pos)
{
ASSERT(m_targetMask & TARGET_FLAG_DEST_LOCATION);
- if (m_dstTransGUID)
+ if (m_dst._transportGUID)
{
Position offset;
- m_dstPos.GetPositionOffsetTo(pos, offset);
- m_dstTransOffset.RelocateOffset(offset);
+ m_dst._position.GetPositionOffsetTo(pos, offset);
+ m_dst._transportOffset.RelocateOffset(offset);
}
- m_dstPos.Relocate(pos);
+ m_dst._position.Relocate(pos);
}
void SpellCastTargets::RemoveDst()
@@ -417,21 +436,21 @@ void SpellCastTargets::Update(Unit* caster)
}
// update positions by transport move
- if (HasSrc() && m_srcTransGUID)
+ if (HasSrc() && m_src._transportGUID)
{
- if (WorldObject* transport = ObjectAccessor::GetWorldObject(*caster, m_srcTransGUID))
+ if (WorldObject* transport = ObjectAccessor::GetWorldObject(*caster, m_src._transportGUID))
{
- m_srcPos.Relocate(transport);
- m_srcPos.RelocateOffset(m_srcTransOffset);
+ m_src._position.Relocate(transport);
+ m_src._position.RelocateOffset(m_src._transportOffset);
}
}
- if (HasDst() && m_dstTransGUID)
+ if (HasDst() && m_dst._transportGUID)
{
- if (WorldObject* transport = ObjectAccessor::GetWorldObject(*caster, m_dstTransGUID))
+ if (WorldObject* transport = ObjectAccessor::GetWorldObject(*caster, m_dst._transportGUID))
{
- m_dstPos.Relocate(transport);
- m_dstPos.RelocateOffset(m_dstTransOffset);
+ m_dst._position.Relocate(transport);
+ m_dst._position.RelocateOffset(m_dst._transportOffset);
}
}
}
@@ -449,9 +468,9 @@ void SpellCastTargets::OutDebug() const
if (m_targetMask & TARGET_FLAG_TRADE_ITEM)
sLog->outString("Trade item target: " UI64FMTD, m_itemTargetGUID);
if (m_targetMask & TARGET_FLAG_SOURCE_LOCATION)
- sLog->outString("Source location: transport guid:" UI64FMTD " trans offset: %s position: %s", m_srcTransGUID, m_srcTransOffset.ToString().c_str(), m_srcPos.ToString().c_str());
+ sLog->outString("Source location: transport guid:" UI64FMTD " trans offset: %s position: %s", m_src._transportGUID, m_src._transportOffset.ToString().c_str(), m_src._position.ToString().c_str());
if (m_targetMask & TARGET_FLAG_DEST_LOCATION)
- sLog->outString("Destination location: transport guid:" UI64FMTD " trans offset: %s position: %s", m_dstTransGUID, m_dstTransOffset.ToString().c_str(), m_dstPos.ToString().c_str());
+ sLog->outString("Destination location: transport guid:" UI64FMTD " trans offset: %s position: %s", m_dst._transportGUID, m_dst._transportOffset.ToString().c_str(), m_dst._position.ToString().c_str());
if (m_targetMask & TARGET_FLAG_STRING)
sLog->outString("String: %s", m_strTarget.c_str());
sLog->outString("speed: %f", m_speed);
@@ -564,6 +583,11 @@ m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharme
CleanupTargetList();
CleanupEffectExecuteData();
+
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ {
+ m_destTargets[i] = SpellDestination(*m_caster);
+ }
}
Spell::~Spell()
@@ -720,6 +744,9 @@ void Spell::SelectSpellTargets()
// some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
SelectEffectTypeImplicitTargets(i);
+ if (m_targets.HasDst())
+ AddDestTarget(*m_targets.GetDst(), i);
+
if (m_spellInfo->IsChanneled())
{
uint8 mask = (1 << i);
@@ -767,7 +794,7 @@ void Spell::SelectSpellTargets()
}
else if (m_spellInfo->Speed > 0.0f)
{
- float dist = m_caster->GetDistance(*m_targets.GetDst());
+ float dist = m_caster->GetDistance(*m_targets.GetDstPos());
m_delayMoment = (uint64) floor(dist / m_spellInfo->Speed * 1000.0f);
}
}
@@ -826,7 +853,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar
m_targets.SetSrc(*m_caster);
break;
default:
- ASSERT("Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
+ ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
break;
}
break;
@@ -843,7 +870,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar
SelectImplicitDestDestTargets(effIndex, targetType);
break;
default:
- ASSERT("Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
+ ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
break;
}
break;
@@ -857,7 +884,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar
SelectImplicitTargetObjectTargets(effIndex, targetType);
break;
default:
- ASSERT("Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
+ ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
break;
}
break;
@@ -1092,10 +1119,10 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
switch (targetType.GetReferenceType())
{
case TARGET_REFERENCE_TYPE_SRC:
- center = m_targets.GetSrc();
+ center = m_targets.GetSrcPos();
break;
case TARGET_REFERENCE_TYPE_DEST:
- center = m_targets.GetDst();
+ center = m_targets.GetDstPos();
break;
case TARGET_REFERENCE_TYPE_CASTER:
case TARGET_REFERENCE_TYPE_TARGET:
@@ -1467,7 +1494,7 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT
if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
dist *= (float)rand_norm();
- Position pos = *m_targets.GetDst();
+ Position pos = *m_targets.GetDstPos();
m_caster->MovePosition(pos, dist, angle);
m_targets.ModDst(pos);
}
@@ -1581,12 +1608,12 @@ void Spell::SelectImplicitTrajTargets()
if (!dist2d)
return;
- float srcToDestDelta = m_targets.GetDst()->m_positionZ - m_targets.GetSrc()->m_positionZ;
+ float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - m_targets.GetSrcPos()->m_positionZ;
std::list<WorldObject*> targets;
- Trinity::WorldObjectSpellTrajTargetCheck check(dist2d, m_targets.GetSrc(), m_caster, m_spellInfo);
+ Trinity::WorldObjectSpellTrajTargetCheck check(dist2d, m_targets.GetSrcPos(), m_caster, m_spellInfo);
Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellTrajTargetCheck> searcher(m_caster, targets, check, GRID_MAP_TYPE_MASK_ALL);
- SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, m_targets.GetSrc(), dist2d);
+ SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, m_targets.GetSrcPos(), dist2d);
if (targets.empty())
return;
@@ -1609,8 +1636,8 @@ void Spell::SelectImplicitTrajTargets()
const float size = std::max((*itr)->GetObjectSize() * 0.7f, 1.0f); // 1/sqrt(3)
// TODO: all calculation should be based on src instead of m_caster
- const float objDist2d = m_targets.GetSrc()->GetExactDist2d(*itr) * cos(m_targets.GetSrc()->GetRelativeAngle(*itr));
- const float dz = (*itr)->GetPositionZ() - m_targets.GetSrc()->m_positionZ;
+ const float objDist2d = m_targets.GetSrcPos()->GetExactDist2d(*itr) * cos(m_targets.GetSrcPos()->GetRelativeAngle(*itr));
+ const float dz = (*itr)->GetPositionZ() - m_targets.GetSrcPos()->m_positionZ;
DEBUG_TRAJ(sLog->outError("Spell::SelectTrajTargets: check %u, dist between %f %f, height between %f %f.", (*itr)->GetEntry(), objDist2d - size, objDist2d + size, dz - size, dz + size);)
@@ -1675,11 +1702,11 @@ void Spell::SelectImplicitTrajTargets()
}
}
- if (m_targets.GetSrc()->GetExactDist2d(m_targets.GetDst()) > bestDist)
+ if (m_targets.GetSrcPos()->GetExactDist2d(m_targets.GetDstPos()) > bestDist)
{
- float x = m_targets.GetSrc()->m_positionX + cos(m_caster->GetOrientation()) * bestDist;
- float y = m_targets.GetSrc()->m_positionY + sin(m_caster->GetOrientation()) * bestDist;
- float z = m_targets.GetSrc()->m_positionZ + bestDist * (a * bestDist + b);
+ float x = m_targets.GetSrcPos()->m_positionX + cos(m_caster->GetOrientation()) * bestDist;
+ float y = m_targets.GetSrcPos()->m_positionY + sin(m_caster->GetOrientation()) * bestDist;
+ float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
if (itr != targets.end())
{
@@ -2216,12 +2243,6 @@ void Spell::AddGOTarget(GameObject* go, uint32 effectMask)
m_UniqueGOTargetInfo.push_back(target);
}
-void Spell::AddGOTarget(uint64 goGUID, uint32 effectMask)
-{
- if (GameObject* go = m_caster->GetMap()->GetGameObject(goGUID))
- AddGOTarget(go, effectMask);
-}
-
void Spell::AddItemTarget(Item* item, uint32 effectMask)
{
for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
@@ -2251,6 +2272,11 @@ void Spell::AddItemTarget(Item* item, uint32 effectMask)
m_UniqueItemInfo.push_back(target);
}
+void Spell::AddDestTarget(SpellDestination const& dest, uint32 effIndex)
+{
+ m_destTargets[effIndex] = dest;
+}
+
void Spell::DoAllEffectOnTarget(TargetInfo* target)
{
if (!target || target->processed)
@@ -2861,34 +2887,6 @@ bool Spell::UpdateChanneledTargetList()
return channelTargetEffectMask == 0;
}
-// Helper for Chain Healing
-// Spell target first
-// Raidmates then descending by injury suffered (MaxHealth - Health)
-// Other players/mobs then descending by injury suffered (MaxHealth - Health)
-struct ChainHealingOrder : public std::binary_function<const Unit*, const Unit*, bool>
-{
- const Unit* MainTarget;
- ChainHealingOrder(Unit const* Target) : MainTarget(Target) {};
- // functor for operator ">"
- bool operator()(Unit const* _Left, Unit const* _Right) const
- {
- return (ChainHealingHash(_Left) < ChainHealingHash(_Right));
- }
-
- int32 ChainHealingHash(Unit const* Target) const
- {
- if (Target->GetTypeId() == TYPEID_PLAYER && MainTarget->GetTypeId() == TYPEID_PLAYER && Target->ToPlayer()->IsInSameRaidWith(MainTarget->ToPlayer()))
- {
- if (Target->IsFullHealth())
- return 40000;
- else
- return 20000 - Target->GetMaxHealth() + Target->GetHealth();
- }
- else
- return 40000 - Target->GetMaxHealth() + Target->GetHealth();
- }
-};
-
void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggeredByAura)
{
if (m_CastItem)
@@ -4605,6 +4603,7 @@ void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOT
unitTarget = pUnitTarget;
itemTarget = pItemTarget;
gameObjTarget = pGOTarget;
+ destTarget = &m_destTargets[i]._position;
uint8 eff = m_spellInfo->Effects[i].Effect;
@@ -4845,7 +4844,7 @@ SpellCastResult Spell::CheckCast(bool strict)
if (m_targets.HasDst())
{
float x, y, z;
- m_targets.GetDst()->GetPosition(x, y, z);
+ m_targets.GetDstPos()->GetPosition(x, y, z);
if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOS(x, y, z))
return SPELL_FAILED_LINE_OF_SIGHT;
@@ -5782,9 +5781,9 @@ SpellCastResult Spell::CheckRange(bool strict)
if (m_targets.HasDst() && !m_targets.HasTraj())
{
- if (!m_caster->IsWithinDist3d(m_targets.GetDst(), max_range))
+ if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
return SPELL_FAILED_OUT_OF_RANGE;
- if (min_range && m_caster->IsWithinDist3d(m_targets.GetDst(), min_range))
+ if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
return SPELL_FAILED_TOO_CLOSE;
}
@@ -6431,6 +6430,30 @@ void Spell::UpdatePointers()
m_CastItem = m_caster->ToPlayer()->GetItemByGuid(m_castItemGUID);
m_targets.Update(m_caster);
+
+ // further actions done only for dest targets
+ if (!m_targets.HasDst())
+ return;
+
+ // cache last transport
+ WorldObject* transport = NULL;
+
+ // update effect destinations (in case of moved transport dest target)
+ for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
+ {
+ SpellDestination& dest = m_destTargets[effIndex];
+ if (!dest._transportGUID)
+ continue;
+
+ if (!transport || transport->GetGUID() != dest._transportGUID)
+ transport = ObjectAccessor::GetWorldObject(*m_caster, dest._transportGUID);
+
+ if (transport)
+ {
+ dest._position.Relocate(transport);
+ dest._position.RelocateOffset(dest._transportOffset);
+ }
+ }
}
CurrentSpellTypes Spell::GetCurrentContainer() const
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 971bc1989ab..f897092e519 100755
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -79,6 +79,18 @@ enum SpellRangeFlag
SPELL_RANGE_RANGED = 2, //hunter range and ranged weapon
};
+struct SpellDestination
+{
+ SpellDestination();
+ SpellDestination(float x, float y, float z, float orientation = 0.0f, uint32 mapId = MAPID_INVALID);
+ SpellDestination(Position const& pos);
+ SpellDestination(WorldObject const& wObj);
+
+ WorldLocation _position;
+ uint64 _transportGUID;
+ Position _transportOffset;
+};
+
class SpellCastTargets
{
public:
@@ -115,14 +127,16 @@ class SpellCastTargets
void SetTradeItemTarget(Player* caster);
void UpdateTradeSlotItem();
- Position const* GetSrc() const;
+ SpellDestination const* GetSrc() const;
+ Position const* GetSrcPos() const;
void SetSrc(float x, float y, float z);
void SetSrc(Position const& pos);
void SetSrc(WorldObject const& wObj);
void ModSrc(Position const& pos);
void RemoveSrc();
- WorldLocation const* GetDst() const;
+ SpellDestination const* GetDst() const;
+ WorldLocation const* GetDstPos() const;
void SetDst(float x, float y, float z, float orientation, uint32 mapId = MAPID_INVALID);
void SetDst(Position const& pos);
void SetDst(WorldObject const& wObj);
@@ -139,7 +153,7 @@ class SpellCastTargets
float GetSpeed() const { return m_speed; }
void SetSpeed(float speed) { m_speed = speed; }
- float GetDist2d() const { return m_srcPos.GetExactDist2d(&m_dstPos); }
+ float GetDist2d() const { return m_src._position.GetExactDist2d(&m_dst._position); }
float GetSpeedXY() const { return m_speed * cos(m_elevation); }
float GetSpeedZ() const { return m_speed * sin(m_elevation); }
@@ -158,13 +172,8 @@ class SpellCastTargets
uint64 m_itemTargetGUID;
uint32 m_itemTargetEntry;
- uint64 m_srcTransGUID;
- Position m_srcTransOffset;
- Position m_srcPos;
-
- uint64 m_dstTransGUID;
- Position m_dstTransOffset;
- WorldLocation m_dstPos;
+ SpellDestination m_src;
+ SpellDestination m_dst;
float m_elevation, m_speed;
std::string m_strTarget;
@@ -197,11 +206,6 @@ enum SpellEffectHandleMode
SPELL_EFFECT_HANDLE_HIT_TARGET,
};
-namespace Trinity
-{
- struct SpellNotifierCreatureAndPlayer;
-}
-
class Spell
{
friend void Unit::SetCurrentCastedSpell(Spell* pSpell);
@@ -529,6 +533,7 @@ class Spell
Unit* unitTarget;
Item* itemTarget;
GameObject* gameObjTarget;
+ WorldLocation* destTarget;
int32 damage;
SpellEffectHandleMode effectHandleMode;
// used in effects handlers
@@ -589,10 +594,13 @@ class Spell
};
std::list<ItemTargetInfo> m_UniqueItemInfo;
+ SpellDestination m_destTargets[MAX_SPELL_EFFECTS];
+
void AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid = true);
void AddGOTarget(GameObject* target, uint32 effectMask);
- void AddGOTarget(uint64 goGUID, uint32 effectMask);
void AddItemTarget(Item* item, uint32 effectMask);
+ void AddDestTarget(SpellDestination const& dest, uint32 effIndex);
+
void DoAllEffectOnTarget(TargetInfo* target);
SpellMissInfo DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleAura);
void DoTriggersOnSpellHit(Unit* unit, uint8 effMask);
@@ -631,7 +639,6 @@ class Spell
HitTriggerSpells m_hitTriggerSpells;
// effect helpers
- void GetSummonPosition(uint32 i, Position &pos, float radius = 0.0f, uint32 count = 0);
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const* properties, uint32 numSummons);
void CalculateJumpSpeeds(uint8 i, float dist, float & speedxy, float & speedz);
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 511d2877f24..59b6d8971cf 100755
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -800,7 +800,7 @@ void Spell::EffectDummy(SpellEffIndex effIndex)
bp = 46585;
if (m_targets.HasDst())
- targets.SetDst(*m_targets.GetDst());
+ targets.SetDst(*m_targets.GetDstPos());
else
{
targets.SetDst(*m_caster);
@@ -814,8 +814,7 @@ void Spell::EffectDummy(SpellEffIndex effIndex)
// Raise dead - take reagents and trigger summon spells
case 48289:
if (m_targets.HasDst())
- targets.SetDst(*m_targets.GetDst());
-
+ targets.SetDst(*m_targets.GetDstPos());
spell_id = CalculateDamage(0, NULL);
break;
}
@@ -1177,7 +1176,7 @@ void Spell::EffectJumpDest(SpellEffIndex effIndex)
// Init dest coordinates
float x, y, z;
- m_targets.GetDst()->GetPosition(x, y, z);
+ destTarget->GetPosition(x, y, z);
float speedXY, speedZ;
CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(x, y), speedXY, speedZ);
@@ -1250,11 +1249,11 @@ void Spell::EffectTeleportUnits(SpellEffIndex /*effIndex*/)
}
// Init dest coordinates
- uint32 mapid = m_targets.GetDst()->GetMapId();
+ uint32 mapid = destTarget->GetMapId();
if (mapid == MAPID_INVALID)
mapid = unitTarget->GetMapId();
float x, y, z, orientation;
- m_targets.GetDst()->GetPosition(x, y, z, orientation);
+ destTarget->GetPosition(x, y, z, orientation);
if (!orientation && m_targets.GetUnitTarget())
orientation = m_targets.GetUnitTarget()->GetOrientation();
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "Spell::EffectTeleportUnits - teleport unit to %u %f %f %f %f\n", mapid, x, y, z, orientation);
@@ -1883,7 +1882,7 @@ void Spell::EffectPersistentAA(SpellEffIndex effIndex)
if (!caster->IsInWorld())
return;
DynamicObject* dynObj = new DynamicObject(false);
- if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), caster, m_spellInfo->Id, *m_targets.GetDst(), radius, DYNAMIC_OBJECT_AREA_SPELL))
+ if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL))
{
delete dynObj;
return;
@@ -2357,9 +2356,6 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
if (Player* modOwner = m_originalCaster->GetSpellModOwner())
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
- Position pos;
- GetSummonPosition(effIndex, pos);
-
TempSummon* summon = NULL;
// determine how many units should be summoned
@@ -2413,11 +2409,11 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
// Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
case SUMMON_TYPE_VEHICLE:
case SUMMON_TYPE_VEHICLE2:
- summon = m_caster->GetMap()->SummonCreature(entry, pos, properties, duration, m_originalCaster, m_spellInfo->Id);
+ summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id);
break;
case SUMMON_TYPE_TOTEM:
{
- summon = m_caster->GetMap()->SummonCreature(entry, pos, properties, duration, m_originalCaster, m_spellInfo->Id);
+ summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id);
if (!summon || !summon->isTotem())
return;
@@ -2434,7 +2430,7 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
}
case SUMMON_TYPE_MINIPET:
{
- summon = m_caster->GetMap()->SummonCreature(entry, pos, properties, duration, m_originalCaster, m_spellInfo->Id);
+ summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id);
if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
return;
@@ -2454,9 +2450,14 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
for (uint32 count = 0; count < numSummons; ++count)
{
- GetSummonPosition(effIndex, pos, radius, count);
+ Position pos;
+ if (count == 0)
+ pos = *destTarget;
+ else
+ // randomize position for multiple summons
+ m_caster->GetRandomPoint(*destTarget, radius, pos);
- summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration);
+ summon = m_originalCaster->SummonCreature(entry, *destTarget, summonType, duration);
if (!summon)
continue;
@@ -2477,14 +2478,14 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
SummonGuardian(effIndex, entry, properties, numSummons);
break;
case SUMMON_CATEGORY_PUPPET:
- summon = m_caster->GetMap()->SummonCreature(entry, pos, properties, duration, m_originalCaster, m_spellInfo->Id);
+ summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id);
break;
case SUMMON_CATEGORY_VEHICLE:
// Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
// to cast a ride vehicle spell on the summoned unit.
float x, y, z;
m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
- summon = m_originalCaster->GetMap()->SummonCreature(entry, pos, properties, duration, m_caster, m_spellInfo->Id);
+ summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id);
if (!summon || !summon->IsVehicle())
return;
@@ -2706,7 +2707,7 @@ void Spell::EffectDistract(SpellEffIndex /*effIndex*/)
if (unitTarget->HasUnitState(UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING))
return;
- unitTarget->SetFacingTo(unitTarget->GetAngle(m_targets.GetDst()));
+ unitTarget->SetFacingTo(unitTarget->GetAngle(destTarget));
unitTarget->ClearUnitState(UNIT_STATE_MOVING);
if (unitTarget->GetTypeId() == TYPEID_UNIT)
@@ -2745,7 +2746,7 @@ void Spell::EffectAddFarsight(SpellEffIndex effIndex)
return;
DynamicObject* dynObj = new DynamicObject(true);
- if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, *m_targets.GetDst(), radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS))
+ if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS))
{
delete dynObj;
return;
@@ -3689,7 +3690,7 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex)
float x, y, z;
if (m_targets.HasDst())
- m_targets.GetDst()->GetPosition(x, y, z);
+ destTarget->GetPosition(x, y, z);
else
m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
@@ -4232,7 +4233,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
float radius = m_spellInfo->Effects[effIndex].CalcRadius();
for (uint8 i = 0; i < 15; ++i)
{
- m_caster->GetRandomPoint(*m_targets.GetDst(), radius, x, y, z);
+ m_caster->GetRandomPoint(*destTarget, radius, x, y, z);
m_caster->CastSpell(x, y, z, 54522, true);
}
break;
@@ -5268,7 +5269,7 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex)
float x, y, z;
// If dest location if present
if (m_targets.HasDst())
- m_targets.GetDst()->GetPosition(x, y, z);
+ destTarget->GetPosition(x, y, z);
// Summon in random point all other units if location present
else
m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
@@ -5398,7 +5399,7 @@ void Spell::EffectLeap(SpellEffIndex /*effIndex*/)
return;
Position pos;
- m_targets.GetDst()->GetPosition(&pos);
+ destTarget->GetPosition(&pos);
unitTarget->GetFirstCollisionPosition(pos, unitTarget->GetDistance(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ() + 2.0f), 0.0f);
unitTarget->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), unitTarget == m_caster);
}
@@ -5569,7 +5570,7 @@ void Spell::EffectChargeDest(SpellEffIndex /*effIndex*/)
if (m_targets.HasDst())
{
Position pos;
- m_targets.GetDst()->GetPosition(&pos);
+ destTarget->GetPosition(&pos);
float angle = m_caster->GetRelativeAngle(pos.GetPositionX(), pos.GetPositionY());
float dist = m_caster->GetDistance(pos);
m_caster->GetFirstCollisionPosition(pos, dist, angle);
@@ -5620,7 +5621,7 @@ void Spell::EffectKnockBack(SpellEffIndex effIndex)
if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
{
if (m_targets.HasDst())
- m_targets.GetDst()->GetPosition(x, y);
+ destTarget->GetPosition(x, y);
else
return;
}
@@ -5708,7 +5709,7 @@ void Spell::EffectPullTowards(SpellEffIndex effIndex)
if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
{
if (m_targets.HasDst())
- pos.Relocate(*m_targets.GetDst());
+ pos.Relocate(*destTarget);
else
return;
}
@@ -5895,7 +5896,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)
float fx, fy, fz;
if (m_targets.HasDst())
- m_targets.GetDst()->GetPosition(fx, fy, fz);
+ destTarget->GetPosition(fx, fy, fz);
//FIXME: this can be better check for most objects but still hack
else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0)
{
@@ -6476,7 +6477,11 @@ void Spell::SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const*
for (uint32 count = 0; count < numGuardians; ++count)
{
Position pos;
- GetSummonPosition(i, pos, radius, count);
+ if (count == 0)
+ pos = *destTarget;
+ else
+ // randomize position for multiple summons
+ m_caster->GetRandomPoint(*destTarget, radius, pos);
TempSummon* summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id);
if (!summon)
@@ -6507,44 +6512,6 @@ void Spell::SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const*
}
}
-void Spell::GetSummonPosition(uint32 i, Position &pos, float radius, uint32 count)
-{
- pos.SetOrientation(m_caster->GetOrientation());
-
- if (m_targets.HasDst())
- {
- // Summon 1 unit in dest location
- if (count == 0)
- pos.Relocate(*m_targets.GetDst());
- // Summon in random point all other units if location present
- else
- {
- //This is a workaround. Do not have time to write much about it
- switch (m_spellInfo->Effects[i].TargetA.GetTarget())
- {
- case TARGET_DEST_CASTER_SUMMON:
- case TARGET_DEST_CASTER_RANDOM:
- m_caster->GetNearPosition(pos, radius * (float)rand_norm(), (float)rand_norm()*static_cast<float>(2*M_PI));
- break;
- case TARGET_DEST_DEST_RANDOM:
- case TARGET_DEST_TARGET_RANDOM:
- m_caster->GetRandomPoint(*m_targets.GetDst(), radius, pos);
- break;
- default:
- pos.Relocate(*m_targets.GetDst());
- break;
- }
- }
- }
- // Summon if dest location not present near caster
- else
- {
- float x, y, z;
- m_caster->GetClosePoint(x, y, z, 3.0f);
- pos.Relocate(x, y, z);
- }
-}
-
void Spell::EffectRenamePet(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 626e0a3653e..b95ee766f38 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -99,7 +99,7 @@ float SpellImplicitTargetInfo::CalcDirectionAngle() const
case TARGET_DIR_LEFT:
return static_cast<float>(M_PI/2);
case TARGET_DIR_FRONT_RIGHT:
- return static_cast<float>(M_PI/4);
+ return static_cast<float>(-M_PI/4);
case TARGET_DIR_BACK_RIGHT:
return static_cast<float>(-3*M_PI/4);
case TARGET_DIR_BACK_LEFT:
@@ -614,7 +614,7 @@ SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] =
{EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 66 SPELL_EFFECT_CREATE_MANA_GEM
{EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 67 SPELL_EFFECT_HEAL_MAX_HEALTH
{EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 68 SPELL_EFFECT_INTERRUPT_CAST
- {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 69 SPELL_EFFECT_DISTRACT
+ {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST}, // 69 SPELL_EFFECT_DISTRACT
{EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 70 SPELL_EFFECT_PULL
{EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 71 SPELL_EFFECT_PICKPOCKET
{EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 72 SPELL_EFFECT_ADD_FARSIGHT
@@ -1192,7 +1192,6 @@ bool SpellInfo::IsAuraExclusiveBySpecificWith(SpellInfo const* spellInfo) const
SpellSpecificType spellSpec2 = spellInfo->GetSpellSpecific();
switch (spellSpec1)
{
- case SPELL_SPECIFIC_PHASE:
case SPELL_SPECIFIC_TRACKER:
case SPELL_SPECIFIC_WARLOCK_ARMOR:
case SPELL_SPECIFIC_MAGE_ARMOR:
@@ -1911,8 +1910,6 @@ SpellSpecificType SpellInfo::GetSpellSpecific() const
case SPELL_AURA_TRACK_RESOURCES:
case SPELL_AURA_TRACK_STEALTHED:
return SPELL_SPECIFIC_TRACKER;
- case SPELL_AURA_PHASE:
- return SPELL_SPECIFIC_PHASE;
}
}
}
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index 9c33db7f708..b82f7dbd61d 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -166,7 +166,6 @@ enum SpellSpecificType
SPELL_SPECIFIC_WARRIOR_ENRAGE = 26,
SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT = 27,
SPELL_SPECIFIC_HAND = 28,
- SPELL_SPECIFIC_PHASE = 29,
};
enum SpellCustomAttributes
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index 03fea614c0d..81f8bbd78c5 100755
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -323,7 +323,7 @@ SpellInfo const* SpellScript::GetSpellInfo()
WorldLocation const* SpellScript::GetTargetDest()
{
if (m_spell->m_targets.HasDst())
- return m_spell->m_targets.GetDst();
+ return m_spell->m_targets.GetDstPos();
return NULL;
}
@@ -403,6 +403,16 @@ GameObject* SpellScript::GetHitGObj()
return m_spell->gameObjTarget;
}
+WorldLocation const* SpellScript::GetHitDest()
+{
+ if (!IsInEffectHook())
+ {
+ sLog->outError("TSCR: Script: `%s` Spell: `%u`: function SpellScript::GetHitGObj was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId);
+ return NULL;
+ }
+ return m_spell->destTarget;
+}
+
int32 SpellScript::GetHitDamage()
{
if (!IsInTargetHook())
@@ -468,11 +478,6 @@ void SpellScript::PreventHitAura()
m_spell->m_spellAura->Remove();
}
-void SpellScript::GetSummonPosition(uint32 i, Position &pos, float radius = 0.0f, uint32 count = 0)
-{
- m_spell->GetSummonPosition(i, pos, radius, count);
-}
-
void SpellScript::PreventHitEffect(SpellEffIndex effIndex)
{
if (!IsInHitPhase() && !IsInEffectHook())
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index 1bf8d25adef..e84a56c8dbb 100755
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -324,6 +324,8 @@ class SpellScript : public _SpellScript
Item* GetHitItem();
// returns: target of current effect if it was GameObject otherwise NULL
GameObject* GetHitGObj();
+ // returns: destination of current effect
+ WorldLocation const* GetHitDest();
// setter/getter for for damage done by spell to target of spell hit
// returns damage calculated before hit, and real dmg done after hit
int32 GetHitDamage();
@@ -335,7 +337,6 @@ class SpellScript : public _SpellScript
void SetHitHeal(int32 heal);
void PreventHitHeal() { SetHitHeal(0); }
Spell* GetSpell() { return m_spell; }
- void GetSummonPosition(uint32 i, Position &pos, float radius, uint32 count);
// returns current spell hit target aura
Aura* GetHitAura();
// prevents applying aura on current spell hit target
diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp
index e5a12693aa7..f1088f54007 100755
--- a/src/server/game/Texts/CreatureTextMgr.cpp
+++ b/src/server/game/Texts/CreatureTextMgr.cpp
@@ -17,8 +17,53 @@
#include "Common.h"
#include "DatabaseEnv.h"
-#include "CreatureTextMgr.h"
#include "ObjectMgr.h"
+#include "Cell.h"
+#include "CellImpl.h"
+#include "GridNotifiers.h"
+#include "GridNotifiersImpl.h"
+#include "CreatureTextMgr.h"
+
+class CreatureTextBuilder
+{
+ public:
+ CreatureTextBuilder(WorldObject* obj, ChatMsg msgtype, uint8 textGroup, uint32 id, uint32 language, uint64 targetGUID)
+ : _source(obj), _msgType(msgtype), _textGroup(textGroup), _textId(id), _language(language), _targetGUID(targetGUID)
+ {
+ }
+
+ size_t operator()(WorldPacket* data, LocaleConstant locale) const
+ {
+ std::string text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _textGroup, _textId, locale);
+ char const* localizedName = _source->GetNameForLocaleIdx(locale);
+
+ *data << uint8(_msgType);
+ *data << uint32(_language);
+ *data << uint64(_source->GetGUID());
+ *data << uint32(1); // 2.1.0
+ *data << uint32(strlen(localizedName)+1);
+ *data << localizedName;
+ size_t whisperGUIDpos = data->wpos();
+ *data << uint64(_targetGUID); // Unit Target
+ if (_targetGUID && !IS_PLAYER_GUID(_targetGUID))
+ {
+ *data << uint32(1); // target name length
+ *data << uint8(0); // target name
+ }
+ *data << uint32(text.length() + 1);
+ *data << text;
+ *data << uint8(0); // ChatTag
+
+ return whisperGUIDpos;
+ }
+
+ WorldObject* _source;
+ ChatMsg _msgType;
+ uint8 _textGroup;
+ uint32 _textId;
+ uint32 _language;
+ uint64 _targetGUID;
+};
void CreatureTextMgr::LoadCreatureTexts()
{
@@ -83,17 +128,8 @@ void CreatureTextMgr::LoadCreatureTexts()
}
//entry not yet added, add empty TextHolder (list of groups)
if (mTextMap.find(temp.entry) == mTextMap.end())
- {
++creatureCount;
- CreatureTextHolder TextHolder;
- mTextMap[temp.entry] = TextHolder;
- }
- //group not yet added, add empty TextGroup (list of texts)
- if (mTextMap[temp.entry].find(temp.group) == mTextMap[temp.entry].end())
- {
- CreatureTextGroup TextGroup;
- mTextMap[temp.entry][temp.group] = TextGroup;
- }
+
//add the text into our entry's group
mTextMap[temp.entry][temp.group].push_back(temp);
@@ -104,42 +140,76 @@ void CreatureTextMgr::LoadCreatureTexts()
sLog->outString();
}
+void CreatureTextMgr::LoadCreatureTextLocales()
+{
+ uint32 oldMSTime = getMSTime();
+
+ mLocaleTextMap.clear(); // for reload case
+
+ QueryResult result = WorldDatabase.Query("SELECT entry, textGroup, id, text_loc1, text_loc2, text_loc3, text_loc4, text_loc5, text_loc6, text_loc7, text_loc8 FROM locales_creature_text");
+
+ if (!result)
+ return;
+
+ uint32 textCount = 0;
+
+ do
+ {
+ Field* fields = result->Fetch();
+ CreatureTextLocale& loc = mLocaleTextMap[CreatureTextId(fields[0].GetUInt32(), uint32(fields[1].GetUInt8()), fields[2].GetUInt32())];
+ for (uint8 i = 1; i < TOTAL_LOCALES; ++i)
+ {
+ LocaleConstant locale = LocaleConstant(i);
+ ObjectMgr::AddLocaleString(fields[2 + i - 1].GetString(), locale, loc.Text);
+ }
+
+ ++textCount;
+ } while (result->NextRow());
+
+ sLog->outString(">> Loaded %u creature localized texts in %u ms", textCount, GetMSTimeDiffToNow(oldMSTime));
+ sLog->outString();
+}
+
uint32 CreatureTextMgr::SendChat(Creature* source, uint8 textGroup, uint64 whisperGuid /*= 0*/, ChatMsg msgType /*= CHAT_MSG_ADDON*/, Language language /*= LANG_ADDON*/, TextRange range /*= TEXT_RANGE_NORMAL*/, uint32 sound /*= 0*/, Team team /*= TEAM_OTHER*/, bool gmOnly /*= false*/, Player* srcPlr /*= NULL*/)
{
if (!source)
return 0;
+
CreatureTextMap::const_iterator sList = mTextMap.find(source->GetEntry());
if (sList == mTextMap.end())
{
sLog->outErrorDb("CreatureTextMgr: Could not find Text for Creature(%s) Entry %u in 'creature_text' table. Ignoring.", source->GetName(), source->GetEntry());
return 0;
}
- CreatureTextHolder TextHolder = (*sList).second;
- CreatureTextHolder::const_iterator itr = TextHolder.find(textGroup);
- if (itr == TextHolder.end())
+
+ CreatureTextHolder const& textHolder = sList->second;
+ CreatureTextHolder::const_iterator itr = textHolder.find(textGroup);
+ if (itr == textHolder.end())
{
sLog->outErrorDb("CreatureTextMgr: Could not find TextGroup %u for Creature(%s) GuidLow %u Entry %u. Ignoring.", uint32(textGroup), source->GetName(), source->GetGUIDLow(), source->GetEntry());
return 0;
}
- CreatureTextGroup TextGroup = (*itr).second;//has all texts in the group
+
+ CreatureTextGroup const& textGroupContainer = itr->second; //has all texts in the group
CreatureTextRepeatIds repeatGroup = GetRepeatGroup(source, textGroup);//has all textIDs from the group that were already said
CreatureTextGroup tempGroup;//will use this to talk after sorting repeatGroup
- for (CreatureTextGroup::const_iterator giter = TextGroup.begin(); giter != TextGroup.end(); ++giter)
- {
- if (std::find(repeatGroup.begin(), repeatGroup.end(), (*giter).id) == repeatGroup.end())
- tempGroup.push_back((*giter));
- }
+ for (CreatureTextGroup::const_iterator giter = textGroupContainer.begin(); giter != textGroupContainer.end(); ++giter)
+ if (std::find(repeatGroup.begin(), repeatGroup.end(), giter->id) == repeatGroup.end())
+ tempGroup.push_back(*giter);
+
if (tempGroup.empty())
{
CreatureTextRepeatMap::iterator mapItr = mTextRepeatMap.find(source->GetGUID());
if (mapItr != mTextRepeatMap.end())
{
- CreatureTextRepeatGroup::iterator groupItr = (*mapItr).second.find(textGroup);
- (*groupItr).second.clear();
+ CreatureTextRepeatGroup::iterator groupItr = mapItr->second.find(textGroup);
+ groupItr->second.clear();
}
- tempGroup = TextGroup;
+
+ tempGroup = textGroupContainer;
}
+
uint8 count = 0;
float lastChance = -1;
bool isEqualChanced = true;
@@ -148,173 +218,92 @@ uint32 CreatureTextMgr::SendChat(Creature* source, uint8 textGroup, uint64 whisp
for (CreatureTextGroup::const_iterator iter = tempGroup.begin(); iter != tempGroup.end(); ++iter)
{
- if (lastChance >= 0 && lastChance != (*iter).probability)
+ if (lastChance >= 0 && lastChance != iter->probability)
isEqualChanced = false;
- lastChance = (*iter).probability;
- totalChance += (*iter).probability;
- count++;
+ lastChance = iter->probability;
+ totalChance += iter->probability;
+ ++count;
}
+
int32 offset = -1;
if (!isEqualChanced)
{
for (CreatureTextGroup::const_iterator iter = tempGroup.begin(); iter != tempGroup.end(); ++iter)
{
- uint32 chance = uint32((*iter).probability);
+ uint32 chance = uint32(iter->probability);
uint32 r = urand(0, 100);
- offset++;
+ ++offset;
if (r <= chance)
break;
}
}
+
uint32 pos = 0;
if (isEqualChanced || offset < 0)
pos = urand(0, count - 1);
else if (offset >= 0)
pos = offset;
+
CreatureTextGroup::const_iterator iter = tempGroup.begin() + pos;
- ChatMsg finalType = (msgType == CHAT_MSG_ADDON) ? (*iter).type : msgType;
- Language finalLang = (language == LANG_ADDON) ? (*iter).lang : language;
- uint32 finalSound = sound ? sound : (*iter).sound;
+ ChatMsg finalType = (msgType == CHAT_MSG_ADDON) ? iter->type : msgType;
+ Language finalLang = (language == LANG_ADDON) ? iter->lang : language;
+ uint32 finalSound = sound ? sound : iter->sound;
if (finalSound)
SendSound(source, finalSound, finalType, whisperGuid, range, team, gmOnly);
- if ((*iter).emote)
- SendEmote(srcPlr ? srcPlr->ToUnit() : source, (*iter).emote);
-
- SendChatString(srcPlr ? srcPlr->ToUnit() : source, (*iter).text.c_str(), finalType, finalLang, whisperGuid, range, team, gmOnly);
- if (isEqualChanced || (!isEqualChanced && totalChance == 100.0f))
- SetRepeatId(source, textGroup, (*iter).id);
-
- return (*iter).duration;
-}
-
-void CreatureTextMgr::SendSound(Creature* source, uint32 sound, ChatMsg msgType, uint64 whisperGuid, TextRange range, Team team, bool gmOnly)
-{
- if (!sound || !source)
- return;
- WorldPacket data(SMSG_PLAY_SOUND, 4);
- data << uint32(sound);
- SendChatPacket(&data, source, msgType, whisperGuid, range, team, gmOnly);
-}
-
-void CreatureTextMgr::SendEmote(Unit* source, uint32 emote)
-{
- if (!source) return;
- source->HandleEmoteCommand(emote);
-}
-
-void CreatureTextMgr::SetRepeatId(Creature* source, uint8 textGroup, uint8 id)
-{
- if (!source)
- return;
-
- if (mTextRepeatMap.find(source->GetGUID()) == mTextRepeatMap.end())
- {
- CreatureTextRepeatGroup TextGroup;
- mTextRepeatMap[source->GetGUID()] = TextGroup;
- }
- if (mTextRepeatMap[source->GetGUID()].find(textGroup) == mTextRepeatMap[source->GetGUID()].end())
- {
- CreatureTextRepeatIds ids;
- mTextRepeatMap[source->GetGUID()][textGroup] = ids;
- }
- if (std::find(mTextRepeatMap[source->GetGUID()][textGroup].begin(), mTextRepeatMap[source->GetGUID()][textGroup].end(), id) == mTextRepeatMap[source->GetGUID()][textGroup].end())
- {
- mTextRepeatMap[source->GetGUID()][textGroup].push_back(id);
- }
- else
- sLog->outErrorDb("CreatureTextMgr: TextGroup %u for Creature(%s) GuidLow %u Entry %u, id %u already added", uint32(textGroup), source->GetName(), source->GetGUIDLow(), source->GetEntry(), uint32(id));
-}
-
-CreatureTextRepeatIds CreatureTextMgr::GetRepeatGroup(Creature* source, uint8 textGroup)
-{
- ASSERT(source);//should never happen
- CreatureTextRepeatIds ids;
+ Unit* finalSource = source;
+ if (srcPlr)
+ finalSource = srcPlr;
- CreatureTextRepeatMap::const_iterator mapItr = mTextRepeatMap.find(source->GetGUID());
- if (mapItr != mTextRepeatMap.end())
- {
- CreatureTextRepeatGroup::const_iterator groupItr = (*mapItr).second.find(textGroup);
- if (groupItr != (*mapItr).second.end())
- {
- ids = (*groupItr).second;
- }
- }
- return ids;
-}
+ if (iter->emote)
+ SendEmote(finalSource, iter->emote);
-void CreatureTextMgr::SendChatString(WorldObject* source, char const* text, ChatMsg msgtype /*= CHAT_MSG_MONSTER_SAY*/, Language language /*= LANG_UNIVERSAL*/, uint64 whisperGuid /*= 0*/, TextRange range /*= TEXT_RANGE_NORMAL*/, Team team /*= TEAM_OTHER*/, bool gmOnly /*= false*/) const
-{
- if (!source)
- return;
+ CreatureTextBuilder builder(finalSource, finalType, iter->group, iter->id, finalLang, whisperGuid);
+ SendChatPacket(finalSource, builder, finalType, whisperGuid, range, team, gmOnly);
+ if (isEqualChanced || (!isEqualChanced && totalChance == 100.0f))
+ SetRepeatId(source, textGroup, iter->id);
- WorldPacket data(SMSG_MESSAGECHAT, 200);
- BuildMonsterChat(&data, source, msgtype, text, language, whisperGuid);//build our packet
- SendChatPacket(&data, source, msgtype, whisperGuid, range, team, gmOnly);//send our packet
+ return iter->duration;
}
-void CreatureTextMgr::BuildMonsterChat(WorldPacket* data, WorldObject* source, ChatMsg msgType, char const* text, Language language, uint64 whisperGuid) const
+float CreatureTextMgr::GetRangeForChatType(ChatMsg msgType) const
{
- if (!source)
- return;
-
+ float dist = sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY);
switch (msgType)
{
- case CHAT_MSG_MONSTER_WHISPER:
- if (!whisperGuid)
- {
- sLog->outError("CreatureTextMgr: WorldObject(%s) TypeId %u GuidLow %u sent CHAT_TYPE_WHISPER with targetGuid 0. Ignoring.", source->GetName(), uint32(source->GetTypeId()), source->GetGUIDLow());
- return;
- }
+ case CHAT_MSG_MONSTER_YELL:
+ dist = sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL);
break;
- case CHAT_MSG_RAID_BOSS_WHISPER:
- if (!whisperGuid)
- {
- sLog->outError("CreatureTextMgr: WorldObject(%s) TypeId %u GuidLow %u sent CHAT_TYPE_BOSS_WHISPER with targetGuid 0. Ignoring.", source->GetName(), uint32(source->GetTypeId()), source->GetGUIDLow());
- return;
- }
+ case CHAT_MSG_MONSTER_EMOTE:
+ case CHAT_MSG_RAID_BOSS_EMOTE:
+ dist = sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE);
break;
default:
break;
}
- *data << uint8(msgType);
- *data << uint32(language);
- *data << uint64(source->GetGUID());
- *data << uint32(0); // 2.1.0
- *data << uint32(strlen(source->GetName()) + 1);
- *data << source->GetName();
- *data << uint64(whisperGuid); // Unit Target
- if (whisperGuid && !IS_PLAYER_GUID(whisperGuid)) //can only whisper players
- {
- sLog->outError("CreatureTextMgr: WorldObject(%s) TypeId %u GuidLow %u sent WHISPER msg to Non-Player target. Ignoring.", source->GetName(), uint32(source->GetTypeId()), source->GetGUIDLow());
- return;
- // *data << (uint32)1; // target name length
- // *data << (uint8)0; // target name
- }
- *data << uint32(strlen(text) + 1);
- *data << text;
- *data << uint8(0); // ChatTag
+
+ return dist;
}
-void CreatureTextMgr::SendChatPacket(WorldPacket* data, WorldObject* source, ChatMsg msgType, uint64 whisperGuid, TextRange range, Team team, bool gmOnly) const
+void CreatureTextMgr::SendSound(Creature* source, uint32 sound, ChatMsg msgType, uint64 whisperGuid, TextRange range, Team team, bool gmOnly)
{
- if (!source)
+ if (!sound || !source)
return;
- float dist = sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY);
+ WorldPacket data(SMSG_PLAY_SOUND, 4);
+ data << uint32(sound);
+ SendNonChatPacket(source, &data, msgType, whisperGuid, range, team, gmOnly);
+}
+
+void CreatureTextMgr::SendNonChatPacket(WorldObject* source, WorldPacket* data, ChatMsg msgType, uint64 whisperGuid, TextRange range, Team team, bool gmOnly) const
+{
+ float dist = GetRangeForChatType(msgType);
switch (msgType)
{
- case CHAT_MSG_MONSTER_YELL:
- dist = sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL);
- break;
- case CHAT_MSG_MONSTER_EMOTE:
- case CHAT_MSG_RAID_BOSS_EMOTE:
- dist = sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE);
- break;
case CHAT_MSG_MONSTER_WHISPER:
case CHAT_MSG_RAID_BOSS_WHISPER:
{
@@ -337,83 +326,135 @@ void CreatureTextMgr::SendChatPacket(WorldPacket* data, WorldObject* source, Cha
case TEXT_RANGE_AREA:
{
uint32 areaId = source->GetAreaId();
- Map::PlayerList const& pList = source->GetMap()->GetPlayers();
- for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
- {
+ Map::PlayerList const& players = source->GetMap()->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
if (itr->getSource()->GetAreaId() == areaId && (!team || Team(itr->getSource()->GetTeam()) == team) && (!gmOnly || itr->getSource()->isGameMaster()))
- {
- if (data->GetOpcode() == SMSG_MESSAGECHAT)//override whisperguid with actual player's guid
- data->put<uint64>(1+4+8+4+4+(int32)(strlen(source->GetName())+1), uint64(itr->getSource()->GetGUID()));
- (itr->getSource())->GetSession()->SendPacket(data);
- }
- }
+ itr->getSource()->GetSession()->SendPacket(data);
return;
}
case TEXT_RANGE_ZONE:
{
uint32 zoneId = source->GetZoneId();
- Map::PlayerList const& pList = source->GetMap()->GetPlayers();
- for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
- {
+ Map::PlayerList const& players = source->GetMap()->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
if (itr->getSource()->GetZoneId() == zoneId && (!team || Team(itr->getSource()->GetTeam()) == team) && (!gmOnly || itr->getSource()->isGameMaster()))
- {
- if (data->GetOpcode() == SMSG_MESSAGECHAT)//override whisperguid with actual player's guid
- data->put<uint64>(1+4+8+4+4+(int32)(strlen(source->GetName())+1), uint64(itr->getSource()->GetGUID()));
- (itr->getSource())->GetSession()->SendPacket(data);
- }
- }
+ itr->getSource()->GetSession()->SendPacket(data);
return;
}
case TEXT_RANGE_MAP:
{
- Map::PlayerList const& pList = source->GetMap()->GetPlayers();
- for (Map::PlayerList::const_iterator itr = pList.begin(); itr != pList.end(); ++itr)
- {
- if (data->GetOpcode() == SMSG_MESSAGECHAT)//override whisperguid with actual player's guid
- data->put<uint64>(1+4+8+4+4+(int32)(strlen(source->GetName())+1), uint64(itr->getSource()->GetGUID()));
+ Map::PlayerList const& players = source->GetMap()->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
if ((!team || Team(itr->getSource()->GetTeam()) == team) && (!gmOnly || itr->getSource()->isGameMaster()))
- (itr->getSource())->GetSession()->SendPacket(data);
- }
+ itr->getSource()->GetSession()->SendPacket(data);
return;
}
case TEXT_RANGE_WORLD:
{
- const SessionMap smap = sWorld->GetAllSessions();
+ SessionMap const& smap = sWorld->GetAllSessions();
for (SessionMap::const_iterator iter = smap.begin(); iter != smap.end(); ++iter)
- {
- if (Player* player = (*iter).second->GetPlayer())
- {
- if (data->GetOpcode() == SMSG_MESSAGECHAT)//override whisperguid with actual player's guid
- data->put<uint64>(1+4+8+4+4+(int32)(strlen(source->GetName())+1), uint64(player->GetGUID()));
+ if (Player* player = iter->second->GetPlayer())
if (player->GetSession() && (!team || Team(player->GetTeam()) == team) && (!gmOnly || player->isGameMaster()))
player->GetSession()->SendPacket(data);
- }
- }
return;
}
case TEXT_RANGE_NORMAL:
default:
break;
}
+
source->SendMessageToSetInRange(data, dist, true);
}
+void CreatureTextMgr::SendEmote(Unit* source, uint32 emote)
+{
+ if (!source)
+ return;
+
+ source->HandleEmoteCommand(emote);
+}
+
+void CreatureTextMgr::SetRepeatId(Creature* source, uint8 textGroup, uint8 id)
+{
+ if (!source)
+ return;
+
+ CreatureTextRepeatIds& repeats = mTextRepeatMap[source->GetGUID()][textGroup];
+ if (std::find(repeats.begin(), repeats.end(), id) == repeats.end())
+ repeats.push_back(id);
+ else
+ sLog->outErrorDb("CreatureTextMgr: TextGroup %u for Creature(%s) GuidLow %u Entry %u, id %u already added", uint32(textGroup), source->GetName(), source->GetGUIDLow(), source->GetEntry(), uint32(id));
+}
+
+CreatureTextRepeatIds CreatureTextMgr::GetRepeatGroup(Creature* source, uint8 textGroup)
+{
+ ASSERT(source);//should never happen
+ CreatureTextRepeatIds ids;
+
+ CreatureTextRepeatMap::const_iterator mapItr = mTextRepeatMap.find(source->GetGUID());
+ if (mapItr != mTextRepeatMap.end())
+ {
+ CreatureTextRepeatGroup::const_iterator groupItr = (*mapItr).second.find(textGroup);
+ if (groupItr != mapItr->second.end())
+ ids = groupItr->second;
+ }
+ return ids;
+}
+
bool CreatureTextMgr::TextExist(uint32 sourceEntry, uint8 textGroup)
{
if (!sourceEntry)
return false;
+
CreatureTextMap::const_iterator sList = mTextMap.find(sourceEntry);
if (sList == mTextMap.end())
{
sLog->outDebug(LOG_FILTER_UNITS, "CreatureTextMgr::TextExist: Could not find Text for Creature (entry %u) in 'creature_text' table.", sourceEntry);
return false;
}
- CreatureTextHolder TextHolder = (*sList).second;
- CreatureTextHolder::const_iterator itr = TextHolder.find(textGroup);
- if (itr == TextHolder.end())
+
+ CreatureTextHolder const& textHolder = sList->second;
+ CreatureTextHolder::const_iterator itr = textHolder.find(textGroup);
+ if (itr == textHolder.end())
{
sLog->outDebug(LOG_FILTER_UNITS, "CreatureTextMgr::TextExist: Could not find TextGroup %u for Creature (entry %u).", uint32(textGroup), sourceEntry);
return false;
}
+
return true;
}
+
+std::string CreatureTextMgr::GetLocalizedChatString(uint32 entry, uint8 textGroup, uint32 id, LocaleConstant locale) const
+{
+ CreatureTextMap::const_iterator mapitr = mTextMap.find(entry);
+ if (mapitr == mTextMap.end())
+ return "";
+
+ CreatureTextHolder::const_iterator holderItr = mapitr->second.find(textGroup);
+ if (holderItr == mapitr->second.end())
+ return "";
+
+ CreatureTextGroup::const_iterator groupItr = holderItr->second.begin();
+ for (; groupItr != holderItr->second.end(); ++groupItr)
+ if (groupItr->id == id)
+ break;
+
+ if (groupItr == holderItr->second.end())
+ return "";
+
+ std::string baseText = groupItr->text;
+ if (locale == DEFAULT_LOCALE)
+ return baseText;
+
+ if (locale > MAX_LOCALES)
+ return baseText;
+
+ LocaleCreatureTextMap::const_iterator locItr = mLocaleTextMap.find(CreatureTextId(entry, uint32(textGroup), id));
+ if (locItr == mLocaleTextMap.end())
+ return baseText;
+
+ if (locItr->second.Text[locale].length())
+ return locItr->second.Text[locale];
+
+ return baseText;
+}
diff --git a/src/server/game/Texts/CreatureTextMgr.h b/src/server/game/Texts/CreatureTextMgr.h
index 0c80e2d568f..ddf10568411 100755
--- a/src/server/game/Texts/CreatureTextMgr.h
+++ b/src/server/game/Texts/CreatureTextMgr.h
@@ -19,6 +19,8 @@
#define TRINITY_CREATURE_TEXT_MGR_H
#include "Creature.h"
+#include "GridNotifiers.h"
+#include "ObjectAccessor.h"
#include "SharedDefines.h"
struct CreatureTextEntry
@@ -44,10 +46,33 @@ enum TextRange
TEXT_RANGE_WORLD = 4
};
+struct CreatureTextLocale
+{
+ StringVector Text;
+};
+
+struct CreatureTextId
+{
+ CreatureTextId(uint32 e, uint32 g, uint32 i) : entry(e), textGroup(g), textId(i)
+ {
+ }
+
+ bool operator<(CreatureTextId const& right) const
+ {
+ return memcmp(this, &right, sizeof(CreatureTextId)) < 0;
+ }
+
+ uint32 entry;
+ uint32 textGroup;
+ uint32 textId;
+};
+
typedef std::vector<CreatureTextEntry> CreatureTextGroup; //texts in a group
typedef UNORDERED_MAP<uint8, CreatureTextGroup> CreatureTextHolder; //groups for a creature by groupid
typedef UNORDERED_MAP<uint32, CreatureTextHolder> CreatureTextMap; //all creatures by entry
+typedef std::map<CreatureTextId, CreatureTextLocale> LocaleCreatureTextMap;
+
//used for handling non-repeatable random texts
typedef std::vector<uint8> CreatureTextRepeatIds;
typedef UNORDERED_MAP<uint8, CreatureTextRepeatIds> CreatureTextRepeatGroup;
@@ -57,9 +82,11 @@ class CreatureTextMgr
{
friend class ACE_Singleton<CreatureTextMgr, ACE_Null_Mutex>;
CreatureTextMgr() {};
+
public:
~CreatureTextMgr() {};
void LoadCreatureTexts();
+ void LoadCreatureTextLocales();
CreatureTextMap const& GetTextMap() const { return mTextMap; }
void SendSound(Creature* source, uint32 sound, ChatMsg msgType, uint64 whisperGuid, TextRange range, Team team, bool gmOnly);
@@ -67,17 +94,154 @@ class CreatureTextMgr
//if sent, returns the 'duration' of the text else 0 if error
uint32 SendChat(Creature* source, uint8 textGroup, uint64 whisperGuid = 0, ChatMsg msgType = CHAT_MSG_ADDON, Language language = LANG_ADDON, TextRange range = TEXT_RANGE_NORMAL, uint32 sound = 0, Team team = TEAM_OTHER, bool gmOnly = false, Player* srcPlr = NULL);
- void SendChatString(WorldObject* source, char const* text, ChatMsg msgtype = CHAT_MSG_MONSTER_SAY, Language language = LANG_UNIVERSAL, uint64 whisperGuid = 0, TextRange range = TEXT_RANGE_NORMAL, Team team = TEAM_OTHER, bool gmOnly = false) const;
bool TextExist(uint32 sourceEntry, uint8 textGroup);
+ std::string GetLocalizedChatString(uint32 entry, uint8 textGroup, uint32 id, LocaleConstant locale) const;
+
+ template<class Builder>
+ void SendChatPacket(WorldObject* source, Builder const& builder, ChatMsg msgType, uint64 whisperGuid = 0, TextRange range = TEXT_RANGE_NORMAL, Team team = TEAM_OTHER, bool gmOnly = false) const;
private:
CreatureTextRepeatIds GetRepeatGroup(Creature* source, uint8 textGroup);
void SetRepeatId(Creature* source, uint8 textGroup, uint8 id);
- void BuildMonsterChat(WorldPacket* data, WorldObject* source, ChatMsg msgType, char const* text, Language language, uint64 whisperGuid) const;
- void SendChatPacket(WorldPacket* data, WorldObject* source, ChatMsg msgType, uint64 whisperGuid, TextRange range, Team team, bool gmOnly) const;
+
+ void SendNonChatPacket(WorldObject* source, WorldPacket* data, ChatMsg msgType, uint64 whisperGuid, TextRange range, Team team, bool gmOnly) const;
+ float GetRangeForChatType(ChatMsg msgType) const;
CreatureTextMap mTextMap;
CreatureTextRepeatMap mTextRepeatMap;
+ LocaleCreatureTextMap mLocaleTextMap;
};
#define sCreatureTextMgr ACE_Singleton<CreatureTextMgr, ACE_Null_Mutex>::instance()
+
+template<class Builder>
+class CreatureTextLocalizer
+{
+ public:
+ CreatureTextLocalizer(Builder const& builder, ChatMsg msgType) : _builder(builder), _msgType(msgType)
+ {
+ _packetCache.resize(TOTAL_LOCALES, NULL);
+ }
+
+ ~CreatureTextLocalizer()
+ {
+ for (size_t i = 0; i < _packetCache.size(); ++i)
+ {
+ if (_packetCache[i])
+ delete _packetCache[i]->first;
+ delete _packetCache[i];
+ }
+ }
+
+ void operator()(Player* player)
+ {
+ LocaleConstant loc_idx = player->GetSession()->GetSessionDbLocaleIndex();
+ WorldPacket* messageTemplate;
+ size_t whisperGUIDpos;
+
+ // create if not cached yet
+ if (!_packetCache[loc_idx])
+ {
+ messageTemplate = new WorldPacket(SMSG_MESSAGECHAT, 200);
+ whisperGUIDpos = _builder(messageTemplate, loc_idx);
+ _packetCache[loc_idx] = new std::pair<WorldPacket*, size_t>(messageTemplate, whisperGUIDpos);
+ }
+ else
+ {
+ messageTemplate = _packetCache[loc_idx]->first;
+ whisperGUIDpos = _packetCache[loc_idx]->second;
+ }
+
+ WorldPacket data(*messageTemplate);
+ switch (_msgType)
+ {
+ case CHAT_MSG_MONSTER_WHISPER:
+ case CHAT_MSG_RAID_BOSS_WHISPER:
+ data.put<uint64>(whisperGUIDpos, player->GetGUID());
+ break;
+ }
+
+ player->SendDirectMessage(&data);
+ }
+
+ private:
+ std::vector<std::pair<WorldPacket*, size_t>* > _packetCache;
+ Builder const& _builder;
+ ChatMsg _msgType;
+};
+
+template<class Builder>
+void CreatureTextMgr::SendChatPacket(WorldObject* source, Builder const& builder, ChatMsg msgType, uint64 whisperGuid, TextRange range, Team team, bool gmOnly) const
+{
+ if (!source)
+ return;
+
+ CreatureTextLocalizer<Builder> localizer(builder, msgType);
+
+ switch (msgType)
+ {
+ case CHAT_MSG_MONSTER_WHISPER:
+ case CHAT_MSG_RAID_BOSS_WHISPER:
+ {
+ if (range == TEXT_RANGE_NORMAL) //ignores team and gmOnly
+ {
+ Player* player = ObjectAccessor::FindPlayer(whisperGuid);
+ if (!player || !player->GetSession())
+ return;
+
+ localizer(player);
+ return;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ switch (range)
+ {
+ case TEXT_RANGE_AREA:
+ {
+ uint32 areaId = source->GetAreaId();
+ Map::PlayerList const& players = source->GetMap()->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ if (itr->getSource()->GetAreaId() == areaId && (!team || Team(itr->getSource()->GetTeam()) == team) && (!gmOnly || itr->getSource()->isGameMaster()))
+ localizer(itr->getSource());
+ return;
+ }
+ case TEXT_RANGE_ZONE:
+ {
+ uint32 zoneId = source->GetZoneId();
+ Map::PlayerList const& players = source->GetMap()->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ if (itr->getSource()->GetZoneId() == zoneId && (!team || Team(itr->getSource()->GetTeam()) == team) && (!gmOnly || itr->getSource()->isGameMaster()))
+ localizer(itr->getSource());
+ return;
+ }
+ case TEXT_RANGE_MAP:
+ {
+ Map::PlayerList const& players = source->GetMap()->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ if ((!team || Team(itr->getSource()->GetTeam()) == team) && (!gmOnly || itr->getSource()->isGameMaster()))
+ localizer(itr->getSource());
+ return;
+ }
+ case TEXT_RANGE_WORLD:
+ {
+ SessionMap const& smap = sWorld->GetAllSessions();
+ for (SessionMap::const_iterator iter = smap.begin(); iter != smap.end(); ++iter)
+ if (Player* player = iter->second->GetPlayer())
+ if (player->GetSession() && (!team || Team(player->GetTeam()) == team) && (!gmOnly || player->isGameMaster()))
+ localizer(player);
+ return;
+ }
+ case TEXT_RANGE_NORMAL:
+ default:
+ break;
+ }
+
+ float dist = GetRangeForChatType(msgType);
+ Trinity::PlayerDistWorker<CreatureTextLocalizer<Builder> > worker(source, dist, localizer);
+ source->VisitNearbyWorldObject(dist, worker);
+}
+
#endif
diff --git a/src/server/game/Warden/WardenCheckMgr.cpp b/src/server/game/Warden/WardenCheckMgr.cpp
index 29f29fe5b88..7567b3976db 100644
--- a/src/server/game/Warden/WardenCheckMgr.cpp
+++ b/src/server/game/Warden/WardenCheckMgr.cpp
@@ -25,7 +25,6 @@
#include "WardenCheckMgr.h"
#include "Warden.h"
-
WardenCheckMgr::WardenCheckMgr()
{
}
@@ -49,17 +48,6 @@ void WardenCheckMgr::LoadWardenChecks()
return;
}
- // For reload case
- for (uint16 i = 0; i < CheckStore.size(); ++i)
- delete CheckStore[i];
-
- CheckStore.clear();
-
- for (CheckResultContainer::iterator itr = CheckResultStore.begin(); itr != CheckResultStore.end(); ++itr)
- delete itr->second;
- CheckResultStore.clear();
-
-
QueryResult result = WorldDatabase.Query("SELECT MAX(id) FROM warden_checks");
if (!result)
@@ -166,13 +154,13 @@ void WardenCheckMgr::LoadWardenOverrides()
return;
}
- Field* fields = result->Fetch();
-
uint32 count = 0;
+ ACE_WRITE_GUARD(ACE_RW_Mutex, g, _checkStoreLock);
+
do
{
- fields = result->Fetch();
+ Field* fields = result->Fetch();
uint16 checkId = fields[0].GetUInt16();
uint8 action = fields[1].GetUInt8();
diff --git a/src/server/game/Warden/WardenCheckMgr.h b/src/server/game/Warden/WardenCheckMgr.h
index 1b790d16716..45de18081c2 100644
--- a/src/server/game/Warden/WardenCheckMgr.h
+++ b/src/server/game/Warden/WardenCheckMgr.h
@@ -64,6 +64,8 @@ class WardenCheckMgr
void LoadWardenChecks();
void LoadWardenOverrides();
+ ACE_RW_Mutex _checkStoreLock;
+
private:
CheckContainer CheckStore;
CheckResultContainer CheckResultStore;
diff --git a/src/server/game/Warden/WardenWin.cpp b/src/server/game/Warden/WardenWin.cpp
index 53d167082d6..3e028254f28 100644
--- a/src/server/game/Warden/WardenWin.cpp
+++ b/src/server/game/Warden/WardenWin.cpp
@@ -212,6 +212,8 @@ void WardenWin::RequestData()
ByteBuffer buff;
buff << uint8(WARDEN_SMSG_CHEAT_CHECKS_REQUEST);
+ ACE_READ_GUARD(ACE_RW_Mutex, g, sWardenCheckMgr->_checkStoreLock);
+
for (uint32 i = 0; i < sWorld->getIntConfig(CONFIG_WARDEN_NUM_OTHER_CHECKS); ++i)
{
// If todo list is done break loop (will be filled on next Update() run)
@@ -377,6 +379,8 @@ void WardenWin::HandleData(ByteBuffer &buff)
uint8 type;
uint16 checkFailed = 0;
+ ACE_READ_GUARD(ACE_RW_Mutex, g, sWardenCheckMgr->_checkStoreLock);
+
for (std::list<uint16>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr)
{
rd = sWardenCheckMgr->GetWardenDataById(*itr);
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index fcdb6b7fcd6..3efa976e1d3 100755
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1651,6 +1651,9 @@ void World::SetInitialWorldSettings()
sLog->outString("Loading Creature Texts...");
sCreatureTextMgr->LoadCreatureTexts();
+ sLog->outString("Loading Creature Text Locales...");
+ sCreatureTextMgr->LoadCreatureTextLocales();
+
sLog->outString("Initializing Scripts...");
sScriptMgr->Initialize();
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index 8ca40231090..9646a881fc0 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -89,6 +89,7 @@ public:
{ "itemexpire", SEC_ADMINISTRATOR, false, &HandleDebugItemExpireCommand, "", NULL },
{ "areatriggers", SEC_ADMINISTRATOR, false, &HandleDebugAreaTriggersCommand, "", NULL },
{ "los", SEC_MODERATOR, false, &HandleDebugLoSCommand, "", NULL },
+ { "moveflags", SEC_ADMINISTRATOR, false, &HandleDebugMoveflagsCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand commandTable[] =
@@ -1283,6 +1284,41 @@ public:
handler->PSendSysMessage(LANG_SET_32BIT_FIELD, opcode, value);
return true;
}
+
+ static bool HandleDebugMoveflagsCommand(ChatHandler* handler, char const* args)
+ {
+ Unit* target = handler->getSelectedUnit();
+ if (!target)
+ target = handler->GetSession()->GetPlayer();
+
+ if (!*args)
+ {
+ //! Display case
+ handler->PSendSysMessage(LANG_MOVEFLAGS_GET, target->GetUnitMovementFlags(), target->GetExtraUnitMovementFlags());
+ }
+ else
+ {
+ char* mask1 = strtok((char*)args, " ");
+ if (!mask1)
+ return false;
+
+ char* mask2 = strtok(NULL, " \n");
+
+ uint32 moveFlags = (uint32)atoi(mask1);
+ target->SetUnitMovementFlags(moveFlags);
+
+ if (mask2)
+ {
+ uint32 moveFlagsExtra = uint32(atoi(mask2));
+ target->SetExtraUnitMovementFlags(moveFlagsExtra);
+ }
+
+ target->SendMovementFlagUpdate();
+ handler->PSendSysMessage(LANG_MOVEFLAGS_SET, target->GetUnitMovementFlags(), target->GetExtraUnitMovementFlags());
+ }
+
+ return true;
+ }
};
void AddSC_debug_commandscript()
diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp
index 8f5e862555c..9249cb3fdbc 100644
--- a/src/server/scripts/Commands/cs_wp.cpp
+++ b/src/server/scripts/Commands/cs_wp.cpp
@@ -223,6 +223,7 @@ public:
sWaypointMgr->ReloadPath(id);
return true;
}
+
static bool HandleWpUnLoadCommand(ChatHandler* handler, const char* /*args*/)
{
@@ -605,7 +606,7 @@ public:
return false;
}
- if (show == "del" && target)
+ if (show == "del")
{
handler->PSendSysMessage("|cff00ff00DEBUG: wp modify del, PathID: |r|cff00ffff%u|r", pathid);
@@ -615,9 +616,12 @@ public:
if (wpGuid != 0)
{
wpCreature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
- wpCreature->CombatStop();
- wpCreature->DeleteFromDB();
- wpCreature->AddObjectToRemoveList();
+ if (wpCreature)
+ {
+ wpCreature->CombatStop();
+ wpCreature->DeleteFromDB();
+ wpCreature->AddObjectToRemoveList();
+ }
}
PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_WAYPOINT_DATA);
@@ -638,7 +642,7 @@ public:
return true;
} // del
- if (show == "move" && target)
+ if (show == "move")
{
handler->PSendSysMessage("|cff00ff00DEBUG: wp move, PathID: |r|cff00ffff%u|r", pathid);
@@ -652,16 +656,20 @@ public:
// Respawn the owner of the waypoints
if (wpGuid != 0)
{
- wpCreature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
- wpCreature->CombatStop();
- wpCreature->DeleteFromDB();
- wpCreature->AddObjectToRemoveList();
+ wpCreature = map->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT));
+ if (wpCreature)
+ {
+ wpCreature->CombatStop();
+ wpCreature->DeleteFromDB();
+ wpCreature->AddObjectToRemoveList();
+ }
// re-create
Creature* wpCreature2 = new Creature;
if (!wpCreature2->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0, 0, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation()))
{
handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
delete wpCreature2;
+ wpCreature2 = NULL;
return false;
}
@@ -672,6 +680,7 @@ public:
{
handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
delete wpCreature2;
+ wpCreature2 = NULL;
return false;
}
//sMapMgr->GetMap(npcCreature->GetMapId())->Add(wpCreature2);
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
index 9a91e1e232b..b232cae4657 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp
@@ -16,6 +16,7 @@
*/
#include "ScriptPCH.h"
+#include "CreatureTextMgr.h"
#include "culling_of_stratholme.h"
#define MAX_ENCOUNTER 5
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
index e0fa0e2b75a..19a8e42e14b 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
@@ -26,6 +26,7 @@
#include "CellImpl.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
+#include "CreatureTextMgr.h"
#include "icecrown_citadel.h"
enum Texts
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp
index c6f72890d1f..284babb7193 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp
@@ -29,17 +29,15 @@ EndScriptData */
enum eEnums
{
//Yell
- SAY_AGGRO = -1602000,
- SAY_SLAY_1 = -1602001,
- SAY_SLAY_2 = -1602002,
- SAY_SLAY_3 = -1602003,
- SAY_DEATH = -1602004,
- SAY_BATTLE_STANCE = -1602005,
- EMOTE_BATTLE_STANCE = -1602006,
- SAY_BERSEKER_STANCE = -1602007,
- EMOTE_BERSEKER_STANCE = -1602008,
- SAY_DEFENSIVE_STANCE = -1602009,
- EMOTE_DEFENSIVE_STANCE = -1602010,
+ SAY_AGGRO = 0,
+ SAY_DEFENSIVE_STANCE = 1,
+ SAY_BATTLE_STANCE = 2,
+ SAY_BERSEKER_STANCE = 3,
+ SAY_SLAY = 4,
+ SAY_DEATH = 5,
+ EMOTE_DEFENSIVE_STANCE = 6,
+ EMOTE_BATTLE_STANCE = 7,
+ EMOTE_BERSEKER_STANCE = 8,
SPELL_DEFENSIVE_STANCE = 53790,
//SPELL_DEFENSIVE_AURA = 41105,
@@ -185,7 +183,7 @@ public:
void EnterCombat(Unit* /*who*/)
{
- DoScriptText(SAY_AGGRO, me);
+ Talk(SAY_AGGRO);
//must get both lieutenants here and make sure they are with him
me->CallForHelp(30.0f);
@@ -196,12 +194,12 @@ public:
void KilledUnit(Unit* /*victim*/)
{
- DoScriptText(RAND(SAY_SLAY_1, SAY_SLAY_2, SAY_SLAY_3), me);
+ Talk(SAY_SLAY);
}
void JustDied(Unit* /*killer*/)
{
- DoScriptText(SAY_DEATH, me);
+ Talk(SAY_DEATH);
if (m_instance)
m_instance->SetData(TYPE_BJARNGRIM, DONE);
@@ -249,20 +247,20 @@ public:
switch (m_uiStance)
{
case STANCE_DEFENSIVE:
- DoScriptText(SAY_DEFENSIVE_STANCE, me);
- DoScriptText(EMOTE_DEFENSIVE_STANCE, me);
+ Talk(SAY_DEFENSIVE_STANCE);
+ Talk(EMOTE_DEFENSIVE_STANCE);
DoCast(me, SPELL_DEFENSIVE_STANCE);
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE);
break;
case STANCE_BERSERKER:
- DoScriptText(SAY_BERSEKER_STANCE, me);
- DoScriptText(EMOTE_BERSEKER_STANCE, me);
+ Talk(SAY_BERSEKER_STANCE);
+ Talk(EMOTE_BERSEKER_STANCE);
DoCast(me, SPELL_BERSEKER_STANCE);
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SWORD, EQUIP_NO_CHANGE);
break;
case STANCE_BATTLE:
- DoScriptText(SAY_BATTLE_STANCE, me);
- DoScriptText(EMOTE_BATTLE_STANCE, me);
+ Talk(SAY_BATTLE_STANCE);
+ Talk(EMOTE_BATTLE_STANCE);
DoCast(me, SPELL_BATTLE_STANCE);
SetEquipmentSlots(false, EQUIP_MACE, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
break;
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp
index 016c4d27cfa..abdf5ecb1e1 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp
@@ -41,13 +41,10 @@ enum Spells
enum Yells
{
- SAY_AGGRO = -1602011,
- SAY_SLAY_1 = -1602012,
- SAY_SLAY_2 = -1602013,
- SAY_SLAY_3 = -1602014,
- SAY_DEATH = -1602015,
- SAY_SPLIT_1 = -1602016,
- SAY_SPLIT_2 = -1602017
+ SAY_AGGRO = 0,
+ SAY_SPLIT = 1,
+ SAY_SLAY = 2,
+ SAY_DEATH = 3
};
enum Creatures
@@ -122,7 +119,7 @@ public:
void EnterCombat(Unit* /*who*/)
{
- DoScriptText(SAY_AGGRO, me);
+ Talk(SAY_AGGRO);
if (instance)
instance->SetData(TYPE_IONAR, IN_PROGRESS);
@@ -130,7 +127,7 @@ public:
void JustDied(Unit* /*killer*/)
{
- DoScriptText(SAY_DEATH, me);
+ Talk(SAY_DEATH);
lSparkList.DespawnAll();
@@ -140,7 +137,7 @@ public:
void KilledUnit(Unit* /*victim*/)
{
- DoScriptText(RAND(SAY_SLAY_1, SAY_SLAY_2, SAY_SLAY_3), me);
+ Talk(SAY_SLAY);
}
void SpellHit(Unit* /*caster*/, const SpellInfo* spell)
@@ -278,7 +275,7 @@ public:
{
bHasDispersed = true;
- DoScriptText(RAND(SAY_SPLIT_1, SAY_SPLIT_2), me);
+ Talk(SAY_SPLIT);
if (me->IsNonMeleeSpellCasted(false))
me->InterruptNonMeleeSpells(false);
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
index 171215c605a..e4f2bb5ce01 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
@@ -30,20 +30,16 @@ enum eEnums
{
ACHIEV_TIMELY_DEATH_START_EVENT = 20384,
- SAY_AGGRO = -1602018,
- SAY_INTRO_1 = -1602019,
- SAY_INTRO_2 = -1602020,
- SAY_SLAY_1 = -1602021,
- SAY_SLAY_2 = -1602022,
- SAY_SLAY_3 = -1602023,
- SAY_DEATH = -1602024,
- SAY_NOVA_1 = -1602025,
- SAY_NOVA_2 = -1602026,
- SAY_NOVA_3 = -1602027,
- SAY_75HEALTH = -1602028,
- SAY_50HEALTH = -1602029,
- SAY_25HEALTH = -1602030,
- EMOTE_NOVA = -1602031,
+ SAY_INTRO_1 = 0,
+ SAY_INTRO_2 = 1,
+ SAY_AGGRO = 2,
+ SAY_NOVA = 3,
+ SAY_SLAY = 4,
+ SAY_75HEALTH = 5,
+ SAY_50HEALTH = 6,
+ SAY_25HEALTH = 7,
+ SAY_DEATH = 8,
+ EMOTE_NOVA = 9,
SPELL_ARC_LIGHTNING = 52921,
SPELL_LIGHTNING_NOVA_N = 52960,
@@ -106,7 +102,7 @@ public:
void EnterCombat(Unit* /*who*/)
{
- DoScriptText(SAY_AGGRO, me);
+ Talk(SAY_AGGRO);
if (m_instance)
{
@@ -117,7 +113,7 @@ public:
void JustDied(Unit* /*killer*/)
{
- DoScriptText(SAY_DEATH, me);
+ Talk(SAY_DEATH);
if (m_instance)
m_instance->SetData(TYPE_LOKEN, DONE);
@@ -125,7 +121,7 @@ public:
void KilledUnit(Unit* /*victim*/)
{
- DoScriptText(RAND(SAY_SLAY_1, SAY_SLAY_2, SAY_SLAY_3), me);
+ Talk(SAY_SLAY);
}
void UpdateAI(const uint32 uiDiff)
@@ -190,8 +186,8 @@ public:
if (m_uiLightningNova_Timer <= uiDiff)
{
- DoScriptText(RAND(SAY_NOVA_1, SAY_NOVA_2, SAY_NOVA_3), me);
- DoScriptText(EMOTE_NOVA, me);
+ Talk(SAY_NOVA);
+ Talk(EMOTE_NOVA);
DoCast(me, SPELL_LIGHTNING_NOVA_N);
m_bIsAura = false;
@@ -206,9 +202,9 @@ public:
{
switch (m_uiHealthAmountModifier)
{
- case 1: DoScriptText(SAY_75HEALTH, me); break;
- case 2: DoScriptText(SAY_50HEALTH, me); break;
- case 3: DoScriptText(SAY_25HEALTH, me); break;
+ case 1: Talk(SAY_75HEALTH); break;
+ case 2: Talk(SAY_50HEALTH); break;
+ case 3: Talk(SAY_25HEALTH); break;
}
++m_uiHealthAmountModifier;
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
index 1fc724c8b6c..83604ed4153 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
@@ -28,17 +28,13 @@ EndScriptData */
enum eEnums
{
- SAY_AGGRO = -1602032,
- SAY_SLAY_1 = -1602033,
- SAY_SLAY_2 = -1602034,
- SAY_SLAY_3 = -1602035,
- SAY_DEATH = -1602036,
- SAY_STOMP_1 = -1602037,
- SAY_STOMP_2 = -1602038,
- SAY_FORGE_1 = -1602039,
- SAY_FORGE_2 = -1602040,
- EMOTE_TO_ANVIL = -1602041,
- EMOTE_SHATTER = -1602042,
+ SAY_AGGRO = 0,
+ SAY_FORGE = 1,
+ SAY_STOMP = 2,
+ SAY_SLAY = 3,
+ SAY_DEATH = 4,
+ EMOTE_TO_ANVIL = 5,
+ EMOTE_SHATTER = 6,
SPELL_HEAT_N = 52387,
SPELL_HEAT_H = 59528,
@@ -127,7 +123,7 @@ public:
void EnterCombat(Unit* /*who*/)
{
- DoScriptText(SAY_AGGRO, me);
+ Talk(SAY_AGGRO);
if (m_instance)
m_instance->SetData(TYPE_VOLKHAN, IN_PROGRESS);
@@ -148,7 +144,7 @@ public:
void JustDied(Unit* /*killer*/)
{
- DoScriptText(SAY_DEATH, me);
+ Talk(SAY_DEATH);
DespawnGolem();
if (m_instance)
@@ -172,7 +168,7 @@ public:
void KilledUnit(Unit* /*victim*/)
{
- DoScriptText(RAND(SAY_SLAY_1, SAY_SLAY_2, SAY_SLAY_3), me);
+ Talk(SAY_SLAY);
}
void DespawnGolem()
@@ -263,11 +259,11 @@ public:
if (m_uiShatteringStomp_Timer <= uiDiff)
{
// Should he stomp even if he has no brittle golem to shatter?
- DoScriptText(RAND(SAY_STOMP_1, SAY_STOMP_2), me);
+ Talk(SAY_STOMP);
DoCast(me, SPELL_SHATTERING_STOMP_N);
- DoScriptText(EMOTE_SHATTER, me);
+ Talk(EMOTE_SHATTER);
m_uiShatteringStomp_Timer = 30000;
m_bCanShatterGolem = true;
@@ -297,7 +293,7 @@ public:
if (me->IsNonMeleeSpellCasted(false))
me->InterruptNonMeleeSpells(false);
- DoScriptText(RAND(SAY_FORGE_1, SAY_FORGE_2), me);
+ Talk(SAY_FORGE);
m_bHasTemper = true;
@@ -308,7 +304,7 @@ public:
{
case 1:
// 1 - Start run to Anvil
- DoScriptText(EMOTE_TO_ANVIL, me);
+ Talk(EMOTE_TO_ANVIL);
me->GetMotionMaster()->MoveTargetedHome();
m_uiSummonPhase = 2; // Set Next Phase
break;
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
index 408ebf3cc96..98b20f1c424 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
@@ -1756,7 +1756,7 @@ class spell_vehicle_throw_passenger : public SpellScriptLoader
if (Unit* device = seat->GetPassenger(2))
if (!device->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
{
- float dist = unit->GetExactDistSq(targets.GetDst());
+ float dist = unit->GetExactDistSq(targets.GetDstPos());
if (dist < minDist)
{
minDist = dist;
@@ -1764,13 +1764,13 @@ class spell_vehicle_throw_passenger : public SpellScriptLoader
}
}
}
- if (target && target->IsWithinDist2d(targets.GetDst(), GetSpellInfo()->Effects[effIndex].CalcRadius() * 2)) // now we use *2 because the location of the seat is not correct
+ if (target && target->IsWithinDist2d(targets.GetDstPos(), GetSpellInfo()->Effects[effIndex].CalcRadius() * 2)) // now we use *2 because the location of the seat is not correct
passenger->EnterVehicle(target, 0);
else
{
passenger->ExitVehicle();
float x, y, z;
- targets.GetDst()->GetPosition(x, y, z);
+ targets.GetDstPos()->GetPosition(x, y, z);
passenger->GetMotionMaster()->MoveJump(x, y, z, targets.GetSpeedXY(), targets.GetSpeedZ());
}
}
diff --git a/src/server/scripts/Northrend/zuldrak.cpp b/src/server/scripts/Northrend/zuldrak.cpp
index 835ad144501..4cea6d8d8aa 100644
--- a/src/server/scripts/Northrend/zuldrak.cpp
+++ b/src/server/scripts/Northrend/zuldrak.cpp
@@ -617,9 +617,9 @@ public:
pWhisker->RemoveFromWorld();
}
- void MovementInform(uint32 uiType, uint32 /*uiId*/)
+ void MovementInform(uint32 type, uint32 /*pointId*/)
{
- if (uiType != POINT_MOTION_TYPE)
+ if (type != EFFECT_MOTION_TYPE)
return;
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index ee554f4875a..e6db50f3f5a 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -769,16 +769,14 @@ class spell_dk_death_grip : public SpellScriptLoader
{
PrepareSpellScript(spell_dk_death_grip_SpellScript);
- void HandleDummy(SpellEffIndex effIndex)
+ void HandleDummy(SpellEffIndex /*effIndex*/)
{
int32 damage = GetEffectValue();
- Position pos;
+ Position const* pos = GetTargetDest();
if (Unit* target = GetHitUnit())
{
- GetSummonPosition(effIndex, pos, 0.0f, 0);
-
if (!target->HasAuraType(SPELL_AURA_DEFLECT_SPELLS)) // Deterrence
- target->CastSpell(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), damage, true);
+ target->CastSpell(pos->GetPositionX(), pos->GetPositionY(), pos->GetPositionZ(), damage, true);
}
}
diff --git a/src/server/scripts/World/areatrigger_scripts.cpp b/src/server/scripts/World/areatrigger_scripts.cpp
index 8f86f760775..d8a90b2ffd5 100644
--- a/src/server/scripts/World/areatrigger_scripts.cpp
+++ b/src/server/scripts/World/areatrigger_scripts.cpp
@@ -32,6 +32,7 @@ at_sholazar_waygate q12548
at_nats_landing q11209
at_bring_your_orphan_to q910 q910 q1800 q1479 q1687 q1558 q10951 q10952
at_brewfest
+at_area_52_entrance
EndContentData */
#include "ScriptPCH.h"
@@ -420,6 +421,75 @@ class AreaTrigger_at_brewfest : public AreaTriggerScript
std::map<uint32, time_t> _triggerTimes;
};
+/*######
+## at_area_52_entrance
+######*/
+
+enum Area52Entrance
+{
+ SPELL_A52_NEURALYZER = 34400,
+ NPC_SPOTLIGHT = 19913,
+ SUMMON_COOLDOWN = 5,
+
+ AT_AREA_52_SOUTH = 4472,
+ AT_AREA_52_NORTH = 4466,
+ AT_AREA_52_WEST = 4471,
+ AT_AREA_52_EAST = 4422,
+};
+
+class AreaTrigger_at_area_52_entrance : public AreaTriggerScript
+{
+ public:
+ AreaTrigger_at_area_52_entrance() : AreaTriggerScript("at_area_52_entrance")
+ {
+ _triggerTimes[AT_AREA_52_SOUTH] = _triggerTimes[AT_AREA_52_NORTH] = _triggerTimes[AT_AREA_52_WEST] = _triggerTimes[AT_AREA_52_EAST] = 0;
+ }
+
+ bool OnTrigger(Player* player, AreaTriggerEntry const* trigger)
+ {
+ float x, y, z;
+
+ if (!player->isAlive())
+ return false;
+
+ uint32 triggerId = trigger->id;
+ if (sWorld->GetGameTime() - _triggerTimes[trigger->id] < SUMMON_COOLDOWN)
+ return false;
+
+ switch (triggerId)
+ {
+ case AT_AREA_52_EAST:
+ x = 3044.176f;
+ y = 3610.692f;
+ z = 143.61f;
+ break;
+ case AT_AREA_52_NORTH:
+ x = 3114.87f;
+ y = 3687.619f;
+ z = 143.62f;
+ break;
+ case AT_AREA_52_WEST:
+ x = 3017.79f;
+ y = 3746.806f;
+ z = 144.27f;
+ break;
+ case AT_AREA_52_SOUTH:
+ x = 2950.63f;
+ y = 3719.905f;
+ z = 143.33f;
+ break;
+ }
+
+ player->SummonCreature(NPC_SPOTLIGHT, x, y, z, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 5000);
+ player->AddAura(SPELL_A52_NEURALYZER, player);
+ _triggerTimes[trigger->id] = sWorld->GetGameTime();
+ return false;
+ }
+
+ private:
+ std::map<uint32, time_t> _triggerTimes;
+};
+
void AddSC_areatrigger_scripts()
{
new AreaTrigger_at_coilfang_waterfall();
@@ -431,4 +501,5 @@ void AddSC_areatrigger_scripts()
new AreaTrigger_at_nats_landing();
new AreaTrigger_at_bring_your_orphan_to();
new AreaTrigger_at_brewfest();
-}
+ new AreaTrigger_at_area_52_entrance();
+} \ No newline at end of file
diff --git a/src/server/shared/Cryptography/HMACSHA1.cpp b/src/server/shared/Cryptography/HMACSHA1.cpp
index 447d0b58efc..c9de1191464 100755
--- a/src/server/shared/Cryptography/HMACSHA1.cpp
+++ b/src/server/shared/Cryptography/HMACSHA1.cpp
@@ -31,19 +31,9 @@ HmacHash::~HmacHash()
HMAC_CTX_cleanup(&m_ctx);
}
-void HmacHash::UpdateBigNumber(BigNumber* bn)
-{
- UpdateData(bn->AsByteArray(), bn->GetNumBytes());
-}
-
-void HmacHash::UpdateData(const uint8 *data, int length)
-{
- HMAC_Update(&m_ctx, data, length);
-}
-
void HmacHash::UpdateData(const std::string &str)
{
- UpdateData((uint8 const*)str.c_str(), str.length());
+ HMAC_Update(&m_ctx, (uint8 const*)str.c_str(), str.length());
}
void HmacHash::Finalize()
diff --git a/src/server/shared/Cryptography/HMACSHA1.h b/src/server/shared/Cryptography/HMACSHA1.h
index bd0418b600e..4b7667968ca 100755
--- a/src/server/shared/Cryptography/HMACSHA1.h
+++ b/src/server/shared/Cryptography/HMACSHA1.h
@@ -33,8 +33,6 @@ class HmacHash
public:
HmacHash(uint32 len, uint8 *seed);
~HmacHash();
- void UpdateBigNumber(BigNumber* bn);
- void UpdateData(const uint8 *data, int length);
void UpdateData(const std::string &str);
void Finalize();
uint8 *ComputeHash(BigNumber* bn);
diff --git a/src/server/shared/Cryptography/SHA1.h b/src/server/shared/Cryptography/SHA1.h
index b5bf97fd7d9..7c77defebfa 100755
--- a/src/server/shared/Cryptography/SHA1.h
+++ b/src/server/shared/Cryptography/SHA1.h
@@ -31,7 +31,6 @@ class SHA1Hash
SHA1Hash();
~SHA1Hash();
- void UpdateFinalizeBigNumbers(BigNumber* bn0, ...);
void UpdateBigNumbers(BigNumber* bn0, ...);
void UpdateData(const uint8 *dta, int len);
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h
index 6b99b79625d..35cb62240d8 100755
--- a/src/server/shared/Packets/ByteBuffer.h
+++ b/src/server/shared/Packets/ByteBuffer.h
@@ -27,22 +27,52 @@
class ByteBufferException
{
public:
- ByteBufferException(bool _add, size_t _pos, size_t _esize, size_t _size)
- : add(_add), pos(_pos), esize(_esize), size(_size)
+ ByteBufferException(size_t pos, size_t size, size_t valueSize)
+ : Pos(pos), Size(size), ValueSize(valueSize)
{
- PrintPosError();
}
- void PrintPosError() const
+ protected:
+ size_t Pos;
+ size_t Size;
+ size_t ValueSize;
+};
+
+class ByteBufferPositionException : public ByteBufferException
+{
+ public:
+ ByteBufferPositionException(bool add, size_t pos, size_t size, size_t valueSize)
+ : ByteBufferException(pos, size, valueSize), _add(add)
+ {
+ PrintError();
+ }
+
+ protected:
+ void PrintError() const
{
- sLog->outError("Attempted to %s in ByteBuffer (pos: " SIZEFMTD " size: "SIZEFMTD") value with size: " SIZEFMTD,
- (add ? "put" : "get"), pos, size, esize);
+ sLog->outError("Attempted to %s value with size: "SIZEFMTD" in ByteBuffer (pos: " SIZEFMTD " size: "SIZEFMTD") " ,
+ (_add ? "put" : "get"), ValueSize, Pos, Size);
}
+
private:
- bool add;
- size_t pos;
- size_t esize;
- size_t size;
+ bool _add;
+};
+
+class ByteBufferSourceException : public ByteBufferException
+{
+ public:
+ ByteBufferSourceException(size_t pos, size_t size, size_t valueSize)
+ : ByteBufferException(pos, size, valueSize)
+ {
+ PrintError();
+ }
+
+ protected:
+ void PrintError() const
+ {
+ sLog->outError("Attempted to put a %s in ByteBuffer (pos: "SIZEFMTD" size: "SIZEFMTD")",
+ (ValueSize > 0 ? "NULL-pointer" : "zero-sized value"), Pos, Size);
+ }
};
class ByteBuffer
@@ -147,14 +177,17 @@ class ByteBuffer
ByteBuffer &operator<<(const std::string &value)
{
- append((uint8 const*)value.c_str(), value.length());
+ if (size_t len = value.length())
+ append((uint8 const*)value.c_str(), len);
append((uint8)0);
return *this;
}
ByteBuffer &operator<<(const char *str)
{
- append((uint8 const*)str, str ? strlen(str) : 0);
+ size_t len = 0;
+ if (str && (len = strlen(str)))
+ append((uint8 const*)str, len);
append((uint8)0);
return *this;
}
@@ -271,7 +304,7 @@ class ByteBuffer
void read_skip(size_t skip)
{
if (_rpos + skip > size())
- throw ByteBufferException(false, _rpos, skip, size());
+ throw ByteBufferPositionException(false, _rpos, skip, size());
_rpos += skip;
}
@@ -285,7 +318,7 @@ class ByteBuffer
template <typename T> T read(size_t pos) const
{
if (pos + sizeof(T) > size())
- throw ByteBufferException(false, pos, sizeof(T), size());
+ throw ByteBufferPositionException(false, pos, sizeof(T), size());
T val = *((T const*)&_storage[pos]);
EndianConvert(val);
return val;
@@ -294,7 +327,7 @@ class ByteBuffer
void read(uint8 *dest, size_t len)
{
if (_rpos + len > size())
- throw ByteBufferException(false, _rpos, len, size());
+ throw ByteBufferPositionException(false, _rpos, len, size());
memcpy(dest, &_storage[_rpos], len);
_rpos += len;
}
@@ -302,7 +335,7 @@ class ByteBuffer
void readPackGUID(uint64& guid)
{
if (rpos() + 1 > size())
- throw ByteBufferException(false, _rpos, 1, size());
+ throw ByteBufferPositionException(false, _rpos, 1, size());
guid = 0;
@@ -314,7 +347,7 @@ class ByteBuffer
if (guidmark & (uint8(1) << i))
{
if (rpos() + 1 > size())
- throw ByteBufferException(false, _rpos, 1, size());
+ throw ByteBufferPositionException(false, _rpos, 1, size());
uint8 bit;
(*this) >> bit;
@@ -341,11 +374,6 @@ class ByteBuffer
_storage.reserve(ressize);
}
- void append(const std::string& str)
- {
- append((uint8 const*)str.c_str(), str.size() + 1);
- }
-
void append(const char *src, size_t cnt)
{
return append((const uint8 *)src, cnt);
@@ -359,7 +387,10 @@ class ByteBuffer
void append(const uint8 *src, size_t cnt)
{
if (!cnt)
- return;
+ throw ByteBufferSourceException(_wpos, size(), cnt);
+
+ if (!src)
+ throw ByteBufferSourceException(_wpos, size(), cnt);
ASSERT(size() < 10000000);
@@ -407,7 +438,11 @@ class ByteBuffer
void put(size_t pos, const uint8 *src, size_t cnt)
{
if (pos + cnt > size())
- throw ByteBufferException(true, pos, cnt, size());
+ throw ByteBufferPositionException(true, pos, cnt, size());
+
+ if (!src)
+ throw ByteBufferSourceException(_wpos, size(), cnt);
+
memcpy(&_storage[pos], src, cnt);
}
diff --git a/src/tools/map_extractor/CMakeLists.txt b/src/tools/map_extractor/CMakeLists.txt
index afeb8af99ba..bde62c24c70 100644
--- a/src/tools/map_extractor/CMakeLists.txt
+++ b/src/tools/map_extractor/CMakeLists.txt
@@ -33,9 +33,9 @@ add_executable(mapextractor
)
target_link_libraries(mapextractor
+ mpq
${BZIP2_LIBRARIES}
${ZLIB_LIBRARIES}
- mpq
)
add_dependencies(mapextractor mpq)
diff --git a/src/tools/vmap4_extractor/CMakeLists.txt b/src/tools/vmap4_extractor/CMakeLists.txt
index 1c44b01bbec..5c98d84eb17 100644
--- a/src/tools/vmap4_extractor/CMakeLists.txt
+++ b/src/tools/vmap4_extractor/CMakeLists.txt
@@ -34,9 +34,9 @@ endif()
add_executable(vmap4extractor ${sources})
target_link_libraries(vmap4extractor
+ mpq
${BZIP2_LIBRARIES}
${ZLIB_LIBRARIES}
- mpq
)
add_dependencies(vmap4extractor mpq)