aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game')
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp13
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp8
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp52
-rw-r--r--src/server/game/Entities/Creature/Creature.h4
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp90
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h2
-rw-r--r--src/server/game/Entities/Object/Object.cpp386
-rw-r--r--src/server/game/Entities/Object/Object.h82
-rw-r--r--src/server/game/Entities/Pet/Pet.cpp4
-rw-r--r--src/server/game/Entities/Player/Player.cpp109
-rw-r--r--src/server/game/Entities/Transport/Transport.cpp16
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp359
-rw-r--r--src/server/game/Entities/Unit/Unit.h59
-rw-r--r--src/server/game/Entities/Vehicle/Vehicle.cpp12
-rw-r--r--src/server/game/Grids/GridDefines.h2
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp3
-rw-r--r--src/server/game/Handlers/GroupHandler.cpp4
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp24
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h2
-rw-r--r--src/server/game/Movement/PathGenerator.cpp34
-rw-r--r--src/server/game/Movement/Spline/MoveSpline.cpp17
-rw-r--r--src/server/game/Movement/Spline/MoveSpline.h19
-rw-r--r--src/server/game/Movement/Spline/MoveSplineFlag.h3
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.cpp2
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.h2
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInitArgs.h9
-rw-r--r--src/server/game/Movement/Spline/MovementTypedefs.h4
-rw-r--r--src/server/game/Movement/Spline/MovementUtil.cpp33
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp1
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h2
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp49
31 files changed, 659 insertions, 747 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index 4d2b5f88376..f43a7f91f32 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -724,27 +724,18 @@ uint64 SmartAI::GetGUID(int32 /*id*/) const
void SmartAI::SetRun(bool run)
{
- if (run)
- me->SetWalk(false);
- else
- me->SetWalk(true);
-
+ me->SetWalk(!run);
mRun = run;
}
void SmartAI::SetFly(bool fly)
{
me->SetDisableGravity(fly);
- me->SendMovementDisableGravity();
}
void SmartAI::SetSwim(bool swim)
{
- if (swim)
- me->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
- else
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
- me->SendMovementSwimming();
+ me->SetSwim(swim);
}
void SmartAI::sGossipHello(Player* player)
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp
index 7b4f323ac31..b5b8a7ce7e2 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp
@@ -101,10 +101,10 @@ void BattlegroundIC::DoAction(uint32 action, uint64 var)
player->SetTransport(player->GetTeamId() == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde);
- player->m_movementInfo.t_pos.m_positionX = TransportMovementInfo.GetPositionX();
- player->m_movementInfo.t_pos.m_positionY = TransportMovementInfo.GetPositionY();
- player->m_movementInfo.t_pos.m_positionZ = TransportMovementInfo.GetPositionZ();
- player->m_movementInfo.t_guid = (player->GetTeamId() == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)->GetGUID();
+ player->m_movementInfo.transport.pos.m_positionX = TransportMovementInfo.GetPositionX();
+ player->m_movementInfo.transport.pos.m_positionY = TransportMovementInfo.GetPositionY();
+ player->m_movementInfo.transport.pos.m_positionZ = TransportMovementInfo.GetPositionZ();
+ player->m_movementInfo.transport.guid = (player->GetTeamId() == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)->GetGUID();
if (player->TeleportTo(GetMapId(), TeleportToTransportPosition.GetPositionX(),
TeleportToTransportPosition.GetPositionY(),
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index ebbf11be586..d8da1e5e286 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -2416,53 +2416,6 @@ bool Creature::IsDungeonBoss() const
return cinfo && (cinfo->flags_extra & CREATURE_FLAG_EXTRA_DUNGEON_BOSS);
}
-bool Creature::SetWalk(bool enable)
-{
- if (!Unit::SetWalk(enable))
- return false;
-
- if (!movespline->Initialized())
- return true;
-
- SendMovementWalkMode();
- return true;
-}
-
-bool Creature::SetDisableGravity(bool disable, bool packetOnly/*=false*/)
-{
- //! It's possible only a packet is sent but moveflags are not updated
- //! Need more research on this
- if (!packetOnly && !Unit::SetDisableGravity(disable))
- return false;
-
- if (!movespline->Initialized())
- return true;
-
- SendMovementDisableGravity();
- return true;
-}
-
-bool Creature::SetHover(bool enable)
-{
- if (!Unit::SetHover(enable))
- return false;
-
- //! Unconfirmed for players:
- if (enable)
- SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER);
- else
- RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER);
-
- if (!movespline->Initialized())
- return true;
-
- // If creature hovers using aura, the hover movement opcode is sent from aura handler
- if (!HasAuraType(SPELL_AURA_HOVER))
- SendMovementHover();
-
- return true;
-}
-
float Creature::GetAggroRange(Unit const* target) const
{
// Determines the aggro range for creatures (usually pets), used mainly for aggressive pet target selection.
@@ -2549,10 +2502,7 @@ void Creature::UpdateMovementFlags()
SetDisableGravity(false);
}
- if (GetCreatureTemplate()->InhabitType & INHABIT_WATER && IsInWater())
- AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
- else
- RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
+ SetSwim(GetCreatureTemplate()->InhabitType & INHABIT_WATER && IsInWater());
}
void Creature::SetObjectScale(float scale)
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index d70a4268235..de826d3f310 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -503,10 +503,6 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
CreatureAI* AI() const { return (CreatureAI*)i_AI; }
- bool SetWalk(bool enable);
- bool SetDisableGravity(bool disable, bool packetOnly = false);
- bool SetHover(bool enable);
-
SpellSchoolMask GetMeleeDamageSchoolMask() const { return m_meleeDamageSchoolMask; }
void SetMeleeDamageSchool(SpellSchools school) { m_meleeDamageSchoolMask = SpellSchoolMask(1 << school); }
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 07a3c0412d2..62426e95987 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -17,22 +17,22 @@
*/
#include "GameObjectAI.h"
-#include "ObjectMgr.h"
+#include "BattlegroundAV.h"
+#include "CellImpl.h"
+#include "CreatureAISelector.h"
+#include "DynamicTree.h"
+#include "GameObjectModel.h"
+#include "GridNotifiersImpl.h"
+#include "Group.h"
#include "GroupMgr.h"
+#include "ObjectMgr.h"
+#include "OutdoorPvPMgr.h"
#include "PoolMgr.h"
+#include "ScriptMgr.h"
#include "SpellMgr.h"
+#include "UpdateFieldFlags.h"
#include "World.h"
-#include "GridNotifiersImpl.h"
-#include "CellImpl.h"
-#include "OutdoorPvPMgr.h"
-#include "BattlegroundAV.h"
-#include "ScriptMgr.h"
-#include "CreatureAISelector.h"
-#include "Group.h"
#include "MapManager.h"
-#include "GameObjectModel.h"
-#include "DynamicTree.h"
-
GameObject::GameObject(): WorldObject(false), m_model(NULL), m_goValue(), m_AI(NULL)
{
m_objectType |= TYPEMASK_GAMEOBJECT;
@@ -2084,3 +2084,71 @@ bool GameObject::IsLootAllowedFor(Player const* player) const
return true;
}
+
+void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const
+{
+ if (!target)
+ return;
+
+ bool forcedFlags = GetGoType() == GAMEOBJECT_TYPE_CHEST && GetGOInfo()->chest.groupLootRules && HasLootRecipient();
+ bool targetIsGM = target->IsGameMaster();
+
+ ByteBuffer fieldBuffer;
+
+ UpdateMask updateMask;
+ updateMask.SetCount(m_valuesCount);
+
+ uint32* flags = GameObjectUpdateFieldFlags;
+ uint32 visibleFlag = UF_FLAG_PUBLIC;
+ if (GetOwnerGUID() == target->GetGUID())
+ visibleFlag |= UF_FLAG_OWNER;
+
+ for (uint16 index = 0; index < m_valuesCount; ++index)
+ {
+ if (_fieldNotifyFlags & flags[index] ||
+ ((updateType == UPDATETYPE_VALUES ? _changesMask.GetBit(index) : m_uint32Values[index]) && (flags[index] & visibleFlag)) ||
+ (index == GAMEOBJECT_FLAGS && forcedFlags))
+ {
+ updateMask.SetBit(index);
+
+ if (index == GAMEOBJECT_DYNAMIC)
+ {
+ uint16 dynFlags = 0;
+ switch (GetGoType())
+ {
+ case GAMEOBJECT_TYPE_CHEST:
+ case GAMEOBJECT_TYPE_GOOBER:
+ if (ActivateToQuest(target))
+ dynFlags |= GO_DYNFLAG_LO_ACTIVATE | GO_DYNFLAG_LO_SPARKLE;
+ else if (targetIsGM)
+ dynFlags |= GO_DYNFLAG_LO_ACTIVATE;
+ break;
+ case GAMEOBJECT_TYPE_GENERIC:
+ if (ActivateToQuest(target))
+ dynFlags |= GO_DYNFLAG_LO_SPARKLE;
+ break;
+ default:
+ break;
+ }
+
+ fieldBuffer << uint16(dynFlags);
+ fieldBuffer << uint16(-1);
+ }
+ else if (index == GAMEOBJECT_FLAGS)
+ {
+ uint32 flags = m_uint32Values[GAMEOBJECT_FLAGS];
+ if (GetGoType() == GAMEOBJECT_TYPE_CHEST)
+ if (GetGOInfo()->chest.groupLootRules && !IsLootAllowedFor(target))
+ flags |= GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE;
+
+ fieldBuffer << flags;
+ }
+ else
+ fieldBuffer << m_uint32Values[index]; // other cases
+ }
+ }
+
+ *data << uint8(updateMask.GetBlockCount());
+ updateMask.AppendToPacket(data);
+ data->append(fieldBuffer);
+}
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index b1d55a6b200..97c9f4a4650 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -624,6 +624,8 @@ class GameObject : public WorldObject, public GridObject<GameObject>
explicit GameObject();
~GameObject();
+ void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const;
+
void AddToWorld();
void RemoveFromWorld();
void CleanupsBeforeDelete(bool finalCleanup = true);
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index eae333bc4c8..9ee58d62194 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -251,12 +251,8 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c
buf.append(GetPackGUID());
buf << uint8(m_objectTypeId);
- _BuildMovementUpdate(&buf, flags);
-
- UpdateMask updateMask;
- updateMask.SetCount(valCount);
- _SetCreateBits(&updateMask, target);
- _BuildValuesUpdate(updateType, &buf, &updateMask, target);
+ BuildMovementUpdate(&buf, flags);
+ BuildValuesUpdate(updateType, &buf, target);
data->AddUpdateBlock(buf);
}
@@ -278,15 +274,7 @@ void Object::BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target) c
buf << uint8(UPDATETYPE_VALUES);
buf.append(GetPackGUID());
- UpdateMask updateMask;
- uint32 valCount = m_valuesCount;
- if (GetTypeId() == TYPEID_PLAYER && target != this)
- valCount = PLAYER_END_NOT_SELF;
-
- updateMask.SetCount(valCount);
-
- _SetUpdateBits(&updateMask, target);
- _BuildValuesUpdate(UPDATETYPE_VALUES, &buf, &updateMask, target);
+ BuildValuesUpdate(UPDATETYPE_VALUES, &buf, target);
data->AddUpdateBlock(buf);
}
@@ -359,7 +347,7 @@ uint16 Object::GetUInt16Value(uint16 index, uint8 offset) const
return *(((uint16*)&m_uint32Values[index])+offset);
}
-void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
+void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
{
Unit const* self = NULL;
ObjectGuid guid = GetGUID();
@@ -434,12 +422,12 @@ void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
data->WriteBit(hasFallData); // Has fall data
data->WriteBit(!hasSplineElevation); // Has spline elevation
data->WriteBit(guid[5]);
- data->WriteBit(self->m_movementInfo.t_guid); // Has transport data
+ data->WriteBit(self->m_movementInfo.transport.guid); // Has transport data
data->WriteBit(0); // Is missing time
- if (self->m_movementInfo.t_guid)
+ if (self->m_movementInfo.transport.guid)
{
- ObjectGuid transGuid = self->m_movementInfo.t_guid;
+ ObjectGuid transGuid = self->m_movementInfo.transport.guid;
data->WriteBit(transGuid[1]);
data->WriteBit(hasTransportTime2); // Has transport time 2
@@ -473,7 +461,7 @@ void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
if (flags & UPDATEFLAG_GO_TRANSPORT_POSITION)
{
WorldObject const* self = static_cast<WorldObject const*>(this);
- ObjectGuid transGuid = self->m_movementInfo.t_guid;
+ ObjectGuid transGuid = self->m_movementInfo.transport.guid;
data->WriteBit(transGuid[5]);
data->WriteBit(0); // Has GO transport time 3
data->WriteBit(transGuid[0]);
@@ -521,13 +509,13 @@ void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
{
if (hasFallDirection)
{
- *data << float(self->m_movementInfo.j_cosAngle);
- *data << float(self->m_movementInfo.j_xyspeed);
- *data << float(self->m_movementInfo.j_sinAngle);
+ *data << float(self->m_movementInfo.jump.cosAngle);
+ *data << float(self->m_movementInfo.jump.xyspeed);
+ *data << float(self->m_movementInfo.jump.sinAngle);
}
- *data << uint32(self->m_movementInfo.fallTime);
- *data << float(self->m_movementInfo.j_zspeed);
+ *data << uint32(self->m_movementInfo.jump.fallTime);
+ *data << float(self->m_movementInfo.jump.zspeed);
}
*data << self->GetSpeed(MOVE_SWIM_BACK);
@@ -540,16 +528,16 @@ void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
*data << float(self->GetPositionZMinusOffset());
data->WriteByteSeq(guid[5]);
- if (self->m_movementInfo.t_guid)
+ if (self->m_movementInfo.transport.guid)
{
- ObjectGuid transGuid = self->m_movementInfo.t_guid;
+ ObjectGuid transGuid = self->m_movementInfo.transport.guid;
data->WriteByteSeq(transGuid[5]);
data->WriteByteSeq(transGuid[7]);
*data << uint32(self->GetTransTime());
*data << float(self->GetTransOffsetO());
if (hasTransportTime2)
- *data << uint32(self->m_movementInfo.t_time2);
+ *data << uint32(self->m_movementInfo.transport.time2);
*data << float(self->GetTransOffsetY());
*data << float(self->GetTransOffsetX());
@@ -557,7 +545,7 @@ void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
*data << float(self->GetTransOffsetZ());
data->WriteByteSeq(transGuid[0]);
if (hasTransportTime3)
- *data << uint32(self->m_movementInfo.t_time3);
+ *data << uint32(self->m_movementInfo.transport.time3);
*data << int8(self->GetTransSeat());
data->WriteByteSeq(transGuid[1]);
@@ -602,12 +590,12 @@ void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
if (flags & UPDATEFLAG_GO_TRANSPORT_POSITION)
{
WorldObject const* self = static_cast<WorldObject const*>(this);
- ObjectGuid transGuid = self->m_movementInfo.t_guid;
+ ObjectGuid transGuid = self->m_movementInfo.transport.guid;
data->WriteBit(transGuid[0]);
data->WriteBit(transGuid[5]);
if (hasTransportTime3)
- *data << uint32(self->m_movementInfo.t_time3);
+ *data << uint32(self->m_movementInfo.transport.time3);
data->WriteBit(transGuid[3]);
*data << float(self->GetTransOffsetX());
@@ -622,7 +610,7 @@ void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
*data << int8(self->GetTransSeat());
*data << float(self->GetTransOffsetO());
if (hasTransportTime2)
- *data << uint32(self->m_movementInfo.t_time2);
+ *data << uint32(self->m_movementInfo.transport.time2);
}
if (flags & UPDATEFLAG_ROTATION)
@@ -688,286 +676,31 @@ void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
*data << uint32(getMSTime()); // Unknown - getMSTime is wrong.
}
-void Object::_BuildValuesUpdate(uint8 updateType, ByteBuffer* data, UpdateMask* updateMask, Player* target) const
+void Object::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const
{
if (!target)
return;
- bool IsActivateToQuest = false;
+ ByteBuffer fieldBuffer;
+ UpdateMask updateMask;
+ updateMask.SetCount(m_valuesCount);
- // Before trying to convert to each type there is a check, so safe
- Unit const* unit = ToUnit();
- GameObject const* go = ToGameObject();
+ uint32* flags = NULL;
+ uint32 visibleFlag = GetUpdateFieldData(target, flags);
- if (unit)
- {
- if (unit->HasFlag(UNIT_FIELD_AURASTATE, PER_CASTER_AURA_STATE_MASK))
- updateMask->SetBit(UNIT_FIELD_AURASTATE);
- }
- else if (go)
+ for (uint16 index = 0; index < m_valuesCount; ++index)
{
- if (updateType == UPDATETYPE_CREATE_OBJECT || updateType == UPDATETYPE_CREATE_OBJECT2)
+ if (_fieldNotifyFlags & flags[index] ||
+ ((updateType == UPDATETYPE_VALUES ? _changesMask.GetBit(index) : m_uint32Values[index]) && (flags[index] & visibleFlag)))
{
- if (!go->IsDynTransport())
- {
- if (go->ActivateToQuest(target) || target->IsGameMaster())
- IsActivateToQuest = true;
-
- if (go->GetGoArtKit())
- updateMask->SetBit(GAMEOBJECT_BYTES_1);
- }
- }
- else
- {
- if (!go->IsTransport())
- {
- if (go->ActivateToQuest(target) || target->IsGameMaster())
- IsActivateToQuest = true;
-
- updateMask->SetBit(GAMEOBJECT_BYTES_1);
-
- if (go->GetGoType() == GAMEOBJECT_TYPE_CHEST && go->GetGOInfo()->chest.groupLootRules &&
- go->HasLootRecipient())
- {
- updateMask->SetBit(GAMEOBJECT_FLAGS);
- }
- }
+ updateMask.SetBit(index);
+ fieldBuffer << m_uint32Values[index];
}
}
- uint32 valCount = m_valuesCount;
- if (GetTypeId() == TYPEID_PLAYER && target != this)
- valCount = PLAYER_END_NOT_SELF;
-
- ASSERT(updateMask && updateMask->GetCount() == valCount);
-
- *data << uint8(updateMask->GetBlockCount());
- updateMask->AppendToPacket(data);
-
- // 2 specialized loops for speed optimization in non-unit case
- if (unit) // unit (creature/player) case
- {
- Creature const* creature = ToCreature();
- for (uint16 index = 0; index < valCount; ++index)
- {
- if (updateMask->GetBit(index))
- {
- if (index == UNIT_NPC_FLAGS)
- {
- // remove custom flag before sending
- uint32 appendValue = m_uint32Values[index];
-
- if (GetTypeId() == TYPEID_UNIT)
- {
- if (!target->CanSeeSpellClickOn(this->ToCreature()))
- appendValue &= ~UNIT_NPC_FLAG_SPELLCLICK;
- }
-
- *data << uint32(appendValue);
- }
- else if (index == UNIT_FIELD_AURASTATE)
- {
- // Check per caster aura states to not enable using a spell in client if specified aura is not by target
- *data << unit->BuildAuraStateUpdateForTarget(target);
- }
- // FIXME: Some values at server stored in float format but must be sent to client in uint32 format
- else if (index >= UNIT_FIELD_BASEATTACKTIME && index <= UNIT_FIELD_RANGEDATTACKTIME)
- {
- // convert from float to uint32 and send
- *data << uint32(m_floatValues[index] < 0 ? 0 : m_floatValues[index]);
- }
- // there are some float values which may be negative or can't get negative due to other checks
- else if ((index >= UNIT_FIELD_NEGSTAT0 && index <= UNIT_FIELD_NEGSTAT4) ||
- (index >= UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE && index <= (UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE + 6)) ||
- (index >= UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE && index <= (UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE + 6)) ||
- (index >= UNIT_FIELD_POSSTAT0 && index <= UNIT_FIELD_POSSTAT4))
- {
- *data << uint32(m_floatValues[index]);
- }
- // Gamemasters should be always able to select units - remove not selectable flag
- else if (index == UNIT_FIELD_FLAGS)
- {
- if (target->IsGameMaster())
- *data << (m_uint32Values[index] & ~UNIT_FLAG_NOT_SELECTABLE);
- else
- *data << m_uint32Values[index];
- }
- // use modelid_a if not gm, _h if gm for CREATURE_FLAG_EXTRA_TRIGGER creatures
- else if (index == UNIT_FIELD_DISPLAYID)
- {
- if (GetTypeId() == TYPEID_UNIT)
- {
- CreatureTemplate const* cinfo = creature->GetCreatureTemplate();
-
- // this also applies for transform auras
- if (SpellInfo const* transform = sSpellMgr->GetSpellInfo(ToUnit()->getTransForm()))
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (transform->Effects[i].IsAura(SPELL_AURA_TRANSFORM))
- if (CreatureTemplate const* transformInfo = sObjectMgr->GetCreatureTemplate(transform->Effects[i].MiscValue))
- {
- cinfo = transformInfo;
- break;
- }
-
- if (cinfo->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER)
- {
- if (target->IsGameMaster())
- {
- if (cinfo->Modelid1)
- *data << cinfo->Modelid1;//Modelid1 is a visible model for gms
- else
- *data << 17519; // world invisible trigger's model
- }
- else
- {
- if (cinfo->Modelid2)
- *data << cinfo->Modelid2;//Modelid2 is an invisible model for players
- else
- *data << 11686; // world invisible trigger's model
- }
- }
- else
- *data << m_uint32Values[index];
- }
- else
- *data << m_uint32Values[index];
- }
- // hide lootable animation for unallowed players
- else if (index == UNIT_DYNAMIC_FLAGS)
- {
- uint32 dynamicFlags = m_uint32Values[index];
-
- if (creature)
- {
- if (creature->hasLootRecipient())
- {
- if (creature->isTappedBy(target))
- {
- dynamicFlags |= (UNIT_DYNFLAG_TAPPED | UNIT_DYNFLAG_TAPPED_BY_PLAYER);
- }
- else
- {
- dynamicFlags |= UNIT_DYNFLAG_TAPPED;
- dynamicFlags &= ~UNIT_DYNFLAG_TAPPED_BY_PLAYER;
- }
- }
- else
- {
- dynamicFlags &= ~UNIT_DYNFLAG_TAPPED;
- dynamicFlags &= ~UNIT_DYNFLAG_TAPPED_BY_PLAYER;
- }
-
- if (!target->isAllowedToLoot(creature))
- dynamicFlags &= ~UNIT_DYNFLAG_LOOTABLE;
- }
-
- // unit UNIT_DYNFLAG_TRACK_UNIT should only be sent to caster of SPELL_AURA_MOD_STALKED auras
- if (dynamicFlags & UNIT_DYNFLAG_TRACK_UNIT)
- if (!unit->HasAuraTypeWithCaster(SPELL_AURA_MOD_STALKED, target->GetGUID()))
- dynamicFlags &= ~UNIT_DYNFLAG_TRACK_UNIT;
- *data << dynamicFlags;
- }
- // FG: pretend that OTHER players in own group are friendly ("blue")
- else if (index == UNIT_FIELD_BYTES_2 || index == UNIT_FIELD_FACTIONTEMPLATE)
- {
- if (unit->IsControlledByPlayer() && target != this && sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && unit->IsInRaidWith(target))
- {
- FactionTemplateEntry const* ft1 = unit->GetFactionTemplateEntry();
- FactionTemplateEntry const* ft2 = target->GetFactionTemplateEntry();
- if (ft1 && ft2 && !ft1->IsFriendlyTo(*ft2))
- {
- if (index == UNIT_FIELD_BYTES_2)
- {
- // Allow targetting opposite faction in party when enabled in config
- *data << (m_uint32Values[index] & ((UNIT_BYTE2_FLAG_SANCTUARY /*| UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5*/) << 8)); // this flag is at uint8 offset 1 !!
- }
- else
- {
- // pretend that all other HOSTILE players have own faction, to allow follow, heal, rezz (trade wont work)
- uint32 faction = target->getFaction();
- *data << uint32(faction);
- }
- }
- else
- *data << m_uint32Values[index];
- }
- else
- *data << m_uint32Values[index];
- }
- else
- {
- // send in current format (float as float, uint32 as uint32)
- *data << m_uint32Values[index];
- }
- }
- }
- }
- else if (go) // gameobject case
- {
- for (uint16 index = 0; index < valCount; ++index)
- {
- if (updateMask->GetBit(index))
- {
- // send in current format (float as float, uint32 as uint32)
- if (index == GAMEOBJECT_DYNAMIC)
- {
- if (IsActivateToQuest)
- {
- switch (go->GetGoType())
- {
- case GAMEOBJECT_TYPE_CHEST:
- if (target->IsGameMaster())
- *data << uint16(GO_DYNFLAG_LO_ACTIVATE);
- else
- *data << uint16(GO_DYNFLAG_LO_ACTIVATE | GO_DYNFLAG_LO_SPARKLE);
- break;
- case GAMEOBJECT_TYPE_GENERIC:
- if (target->IsGameMaster())
- *data << uint16(0);
- else
- *data << uint16(GO_DYNFLAG_LO_SPARKLE);
- break;
- case GAMEOBJECT_TYPE_GOOBER:
- if (target->IsGameMaster())
- *data << uint16(GO_DYNFLAG_LO_ACTIVATE);
- else
- *data << uint16(GO_DYNFLAG_LO_ACTIVATE | GO_DYNFLAG_LO_SPARKLE);
- break;
- default:
- *data << uint16(0); // unknown, not happen.
- break;
- }
- }
- else
- *data << uint16(0); // disable quest object
-
- *data << uint16(-1);
- }
- else if (index == GAMEOBJECT_FLAGS)
- {
- uint32 flags = m_uint32Values[index];
- if (go->GetGoType() == GAMEOBJECT_TYPE_CHEST)
- if (go->GetGOInfo()->chest.groupLootRules && !go->IsLootAllowedFor(target))
- flags |= GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE;
-
- *data << flags;
- }
- else
- *data << m_uint32Values[index]; // other cases
- }
- }
- }
- else // other objects case (no special index checks)
- {
- for (uint16 index = 0; index < valCount; ++index)
- {
- if (updateMask->GetBit(index))
- {
- // send in current format (float as float, uint32 as uint32)
- *data << m_uint32Values[index];
- }
- }
- }
+ *data << uint8(updateMask.GetBlockCount());
+ updateMask.AppendToPacket(data);
+ data->append(fieldBuffer);
}
void Object::ClearUpdateMask(bool remove)
@@ -1069,33 +802,6 @@ void Object::_LoadIntoDataField(std::string const& data, uint32 startOffset, uin
}
}
-void Object::_SetUpdateBits(UpdateMask* updateMask, Player* target) const
-{
- uint32* flags = NULL;
- uint32 visibleFlag = GetUpdateFieldData(target, flags);
- uint32 valCount = m_valuesCount;
- if (GetTypeId() == TYPEID_PLAYER && target != this)
- valCount = PLAYER_END_NOT_SELF;
-
- for (uint16 index = 0; index < valCount; ++index)
- if (_fieldNotifyFlags & flags[index] || ((flags[index] & visibleFlag) & UF_FLAG_SPECIAL_INFO) || (_changesMask.GetBit(index) && (flags[index] & visibleFlag)))
- updateMask->SetBit(index);
-}
-
-void Object::_SetCreateBits(UpdateMask* updateMask, Player* target) const
-{
- uint32* value = m_uint32Values;
- uint32* flags = NULL;
- uint32 visibleFlag = GetUpdateFieldData(target, flags);
- uint32 valCount = m_valuesCount;
- if (GetTypeId() == TYPEID_PLAYER && target != this)
- valCount = PLAYER_END_NOT_SELF;
-
- for (uint16 index = 0; index < valCount; ++index, ++value)
- if (_fieldNotifyFlags & flags[index] || ((flags[index] & visibleFlag) & UF_FLAG_SPECIAL_INFO) || (*value && (flags[index] & visibleFlag)))
- updateMask->SetBit(index);
-}
-
void Object::SetInt32Value(uint16 index, int32 value)
{
ASSERT(index < m_valuesCount || PrintIndexError(index, true));
@@ -1546,17 +1252,17 @@ void MovementInfo::OutDebug()
TC_LOG_INFO(LOG_FILTER_GENERAL, "flags2 %s (%u)", Movement::MovementFlagsExtra_ToString(flags2).c_str(), flags2);
TC_LOG_INFO(LOG_FILTER_GENERAL, "time %u current time %u", time, getMSTime());
TC_LOG_INFO(LOG_FILTER_GENERAL, "position: `%s`", pos.ToString().c_str());
- if (t_guid)
+ if (transport.guid)
{
TC_LOG_INFO(LOG_FILTER_GENERAL, "TRANSPORT:");
- TC_LOG_INFO(LOG_FILTER_GENERAL, "guid: " UI64FMTD, t_guid);
- TC_LOG_INFO(LOG_FILTER_GENERAL, "position: `%s`", t_pos.ToString().c_str());
- TC_LOG_INFO(LOG_FILTER_GENERAL, "seat: %i", t_seat);
- TC_LOG_INFO(LOG_FILTER_GENERAL, "time: %u", t_time);
+ TC_LOG_INFO(LOG_FILTER_GENERAL, "guid: " UI64FMTD, transport.guid);
+ TC_LOG_INFO(LOG_FILTER_GENERAL, "position: `%s`", transport.pos.ToString().c_str());
+ TC_LOG_INFO(LOG_FILTER_GENERAL, "seat: %i", transport.seat);
+ TC_LOG_INFO(LOG_FILTER_GENERAL, "time: %u", transport.time);
if (flags2 & MOVEMENTFLAG2_INTERPOLATED_MOVEMENT)
- TC_LOG_INFO(LOG_FILTER_GENERAL, "time2: %u", t_time2);
+ TC_LOG_INFO(LOG_FILTER_GENERAL, "time2: %u", transport.time2);
if (bits.hasTransportTime3)
- TC_LOG_INFO(LOG_FILTER_GENERAL, "time3: %u", t_time3);
+ TC_LOG_INFO(LOG_FILTER_GENERAL, "time3: %u", transport.time3);
}
if ((flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (flags2 & MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING))
@@ -1564,9 +1270,9 @@ void MovementInfo::OutDebug()
if (flags & MOVEMENTFLAG_FALLING || bits.hasFallData)
{
- TC_LOG_INFO(LOG_FILTER_GENERAL, "fallTime: %u j_zspeed: %f", fallTime, j_zspeed);
+ TC_LOG_INFO(LOG_FILTER_GENERAL, "fallTime: %u j_zspeed: %f", jump.fallTime, jump.zspeed);
if (flags & MOVEMENTFLAG_FALLING)
- TC_LOG_INFO(LOG_FILTER_GENERAL, "j_sinAngle: %f j_cosAngle: %f j_xyspeed: %f", j_sinAngle, j_cosAngle, j_xyspeed);
+ TC_LOG_INFO(LOG_FILTER_GENERAL, "j_sinAngle: %f j_cosAngle: %f j_xyspeed: %f", jump.sinAngle, jump.cosAngle, jump.xyspeed);
}
if (flags & MOVEMENTFLAG_SPLINE_ELEVATION)
@@ -1692,12 +1398,12 @@ bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool
if (m_transport && obj->GetTransport() && obj->GetTransport()->GetGUIDLow() == m_transport->GetGUIDLow())
{
- float dtx = m_movementInfo.t_pos.m_positionX - obj->m_movementInfo.t_pos.m_positionX;
- float dty = m_movementInfo.t_pos.m_positionY - obj->m_movementInfo.t_pos.m_positionY;
+ float dtx = m_movementInfo.transport.pos.m_positionX - obj->m_movementInfo.transport.pos.m_positionX;
+ float dty = m_movementInfo.transport.pos.m_positionY - obj->m_movementInfo.transport.pos.m_positionY;
float disttsq = dtx * dtx + dty * dty;
if (is3D)
{
- float dtz = m_movementInfo.t_pos.m_positionZ - obj->m_movementInfo.t_pos.m_positionZ;
+ float dtz = m_movementInfo.transport.pos.m_positionZ - obj->m_movementInfo.transport.pos.m_positionZ;
disttsq += dtz * dtz;
}
return disttsq < (maxdist * maxdist);
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 427d5a91afd..08bc0ae88ae 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -192,7 +192,7 @@ class Object
uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); }
void SetEntry(uint32 entry) { SetUInt32Value(OBJECT_FIELD_ENTRY, entry); }
- void SetObjectScale(float scale) { SetFloatValue(OBJECT_FIELD_SCALE_X, scale); }
+ virtual void SetObjectScale(float scale) { SetFloatValue(OBJECT_FIELD_SCALE_X, scale); }
TypeID GetTypeId() const { return m_objectTypeId; }
bool isType(uint16 mask) const { return (mask & m_objectType); }
@@ -296,10 +296,8 @@ class Object
uint32 GetUpdateFieldData(Player const* target, uint32*& flags) const;
- void _SetUpdateBits(UpdateMask* updateMask, Player* target) const;
- void _SetCreateBits(UpdateMask* updateMask, Player* target) const;
- void _BuildMovementUpdate(ByteBuffer * data, uint16 flags) const;
- void _BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask* updateMask, Player* target) const;
+ void BuildMovementUpdate(ByteBuffer* data, uint16 flags) const;
+ virtual void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const;
uint16 m_objectType;
@@ -469,19 +467,47 @@ struct MovementInfo
uint16 flags2;
Position pos;
uint32 time;
+
// transport
- uint64 t_guid;
- Position t_pos;
- int8 t_seat;
- uint32 t_time;
- uint32 t_time2;
- uint32 t_time3;
+ struct TransportInfo
+ {
+ void Reset()
+ {
+ guid = 0;
+ pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
+ seat = -1;
+ time = 0;
+ time2 = 0;
+ time3 = 0;
+ }
+
+ uint64 guid;
+ Position pos;
+ int8 seat;
+ uint32 time;
+ uint32 time2;
+ uint32 time3;
+ } transport;
+
// swimming/flying
float pitch;
- // falling
- uint32 fallTime;
+
+
// jumping
- float j_zspeed, j_sinAngle, j_cosAngle, j_xyspeed;
+ struct JumpInfo
+ {
+ void Reset()
+ {
+ fallTime = 0;
+ zspeed = sinAngle = cosAngle = xyspeed = 0.0f;
+ }
+
+ uint32 fallTime;
+
+ float zspeed, sinAngle, cosAngle, xyspeed;
+
+ } jump;
+
// spline
float splineElevation;
@@ -497,12 +523,11 @@ struct MovementInfo
} bits;
MovementInfo() :
- guid(0), flags(0), flags2(0), time(0), t_guid(0),
- t_seat(-1), t_time(0), t_time2(0), t_time3(0), pitch(0.0f), fallTime(0),
- j_zspeed(0.0f), j_sinAngle(0.0f), j_cosAngle(0.0f), j_xyspeed(0.0f)
+ guid(0), flags(0), flags2(0), time(0), pitch(0.0f)
{
pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
- t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
+ transport.Reset();
+ jump.Reset();
memset(&bits, 0, sizeof(bits));
}
@@ -513,18 +538,25 @@ struct MovementInfo
bool HasMovementFlag(uint32 flag) const { return flags & flag; }
uint16 GetExtraMovementFlags() const { return flags2; }
+ void SetExtraMovementFlags(uint16 flag) { flags2 = flag; }
void AddExtraMovementFlag(uint16 flag) { flags2 |= flag; }
+ void RemoveExtraMovementFlag(uint16 flag) { flags2 &= ~flag; }
bool HasExtraMovementFlag(uint16 flag) const { return flags2 & flag; }
- void SetFallTime(uint32 time) { fallTime = time; }
+ void SetFallTime(uint32 time) { jump.fallTime = time; }
+
+ void ResetTransport()
+ {
+ transport.Reset();
+ bits.hasTransportTime2 = false;
+ bits.hasTransportTime3 = false;
+ }
- void ClearTransport()
+ void ResetJump()
{
- t_guid = 0;
- t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
- t_seat = -1;
- t_time = 0;
- t_time2 = 0;
+ jump.Reset();
+ bits.hasFallData = false;
+ bits.hasFallDirection = false;
}
void OutDebug();
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index 55043537daa..687f1ab40b5 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -2048,6 +2048,6 @@ void Pet::SetDisplayId(uint32 modelId)
if (Unit* owner = GetOwner())
if (Player* player = owner->ToPlayer())
- if (owner->ToPlayer()->GetGroup())
- owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MODEL_ID);
+ if (player->GetGroup())
+ player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MODEL_ID);
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 0fb67ea7d07..bc326d7c232 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -24,15 +24,14 @@
#include "Battlefield.h"
#include "BattlefieldMgr.h"
#include "BattlefieldWG.h"
-#include "BattlegroundAV.h"
#include "Battleground.h"
+#include "BattlegroundAV.h"
#include "BattlegroundMgr.h"
#include "CellImpl.h"
#include "Channel.h"
#include "ChannelMgr.h"
#include "CharacterDatabaseCleaner.h"
#include "Chat.h"
-#include <cmath>
#include "Common.h"
#include "ConditionMgr.h"
#include "CreatureAI.h"
@@ -50,8 +49,8 @@
#include "GuildMgr.h"
#include "InstanceSaveMgr.h"
#include "InstanceScript.h"
-#include "Language.h"
#include "LFGMgr.h"
+#include "Language.h"
#include "Log.h"
#include "MapInstanced.h"
#include "MapManager.h"
@@ -60,17 +59,18 @@
#include "Opcodes.h"
#include "OutdoorPvP.h"
#include "OutdoorPvPMgr.h"
-#include "ReputationMgr.h"
#include "Pet.h"
#include "QuestDef.h"
+#include "ReputationMgr.h"
#include "SkillDiscovery.h"
#include "SocialMgr.h"
+#include "Spell.h"
#include "SpellAuraEffects.h"
#include "SpellAuras.h"
-#include "Spell.h"
#include "SpellMgr.h"
#include "Transport.h"
#include "UpdateData.h"
+#include "UpdateFieldFlags.h"
#include "UpdateMask.h"
#include "Util.h"
#include "Vehicle.h"
@@ -2135,7 +2135,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
{
m_transport->RemovePassenger(this);
m_transport = NULL;
- m_movementInfo.ClearTransport();
+ m_movementInfo.ResetTransport();
RepopAtGraveyard(); // teleport to near graveyard if on transport, looks blizz like :)
}
@@ -2159,7 +2159,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
{
m_transport->RemovePassenger(this);
m_transport = NULL;
- m_movementInfo.ClearTransport();
+ m_movementInfo.ResetTransport();
}
}
@@ -2317,10 +2317,10 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
if (m_transport)
{
- final_x += m_movementInfo.t_pos.GetPositionX();
- final_y += m_movementInfo.t_pos.GetPositionY();
- final_z += m_movementInfo.t_pos.GetPositionZ();
- final_o += m_movementInfo.t_pos.GetOrientation();
+ final_x += m_movementInfo.transport.pos.GetPositionX();
+ final_y += m_movementInfo.transport.pos.GetPositionY();
+ final_z += m_movementInfo.transport.pos.GetPositionZ();
+ final_o += m_movementInfo.transport.pos.GetOrientation();
}
m_teleport_dest = WorldLocation(mapid, final_x, final_y, final_z, final_o);
@@ -5137,8 +5137,7 @@ void Player::BuildPlayerRepop()
// convert player body to ghost
SetHealth(1);
- AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
- SendMovementWaterWalking();
+ SetWaterWalking(true);
if (!GetSession()->isLogingOut())
SetRooted(false);
@@ -5178,8 +5177,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
setDeathState(ALIVE);
- RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
- SendMovementWaterWalking();
+ SetWaterWalking(false);
SetRooted(false);
m_deathTimer = 0;
@@ -17244,18 +17242,18 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
// currently we do not support transport in bg
else if (transGUID)
{
- m_movementInfo.t_guid = MAKE_NEW_GUID(transGUID, 0, HIGHGUID_MO_TRANSPORT);
- m_movementInfo.t_pos.Relocate(fields[27].GetFloat(), fields[28].GetFloat(), fields[29].GetFloat(), fields[30].GetFloat());
+ m_movementInfo.transport.guid = MAKE_NEW_GUID(transGUID, 0, HIGHGUID_MO_TRANSPORT);
+ m_movementInfo.transport.pos.Relocate(fields[27].GetFloat(), fields[28].GetFloat(), fields[29].GetFloat(), fields[30].GetFloat());
if (!Trinity::IsValidMapCoord(
- GetPositionX()+m_movementInfo.t_pos.m_positionX, GetPositionY()+m_movementInfo.t_pos.m_positionY,
- GetPositionZ()+m_movementInfo.t_pos.m_positionZ, GetOrientation()+m_movementInfo.t_pos.GetOrientation()) ||
+ GetPositionX()+m_movementInfo.transport.pos.GetPositionX(), GetPositionY()+m_movementInfo.transport.pos.GetPositionY(),
+ GetPositionZ()+m_movementInfo.transport.pos.GetPositionZ(), GetOrientation()+m_movementInfo.transport.pos.GetOrientation()) ||
// transport size limited
- m_movementInfo.t_pos.m_positionX > 250 || m_movementInfo.t_pos.m_positionY > 250 || m_movementInfo.t_pos.m_positionZ > 250)
+ m_movementInfo.transport.pos.m_positionX > 250 || m_movementInfo.transport.pos.m_positionY > 250 || m_movementInfo.transport.pos.m_positionZ > 250)
{
TC_LOG_ERROR(LOG_FILTER_PLAYER, "Player (guidlow %d) have invalid transport coordinates (X: %f Y: %f Z: %f O: %f). Teleport to bind location.",
- guid, GetPositionX()+m_movementInfo.t_pos.m_positionX, GetPositionY()+m_movementInfo.t_pos.m_positionY,
- GetPositionZ()+m_movementInfo.t_pos.m_positionZ, GetOrientation()+m_movementInfo.t_pos.GetOrientation());
+ guid, GetPositionX()+m_movementInfo.transport.pos.GetPositionX(), GetPositionY()+m_movementInfo.transport.pos.GetPositionY(),
+ GetPositionZ()+m_movementInfo.transport.pos.GetPositionZ(), GetOrientation()+m_movementInfo.transport.pos.GetOrientation());
RelocateToHomebind();
}
@@ -22760,14 +22758,30 @@ void Player::UpdateTriggerVisibility()
{
if (IS_CREATURE_GUID(*itr))
{
- Creature* obj = GetMap()->GetCreature(*itr);
- if (!obj || !(obj->IsTrigger() || obj->HasAuraType(SPELL_AURA_TRANSFORM))) // can transform into triggers
+ Creature* creature = GetMap()->GetCreature(*itr);
+ // Update fields of triggers, transformed units or unselectable units (values dependent on GM state)
+ if (!creature || (!creature->IsTrigger() && !creature->HasAuraType(SPELL_AURA_TRANSFORM) && !creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)))
continue;
- obj->BuildValuesUpdateBlockForPlayer(&udata, this);
+ creature->SetFieldNotifyFlag(UF_FLAG_PUBLIC);
+ creature->BuildValuesUpdateBlockForPlayer(&udata, this);
+ creature->RemoveFieldNotifyFlag(UF_FLAG_PUBLIC);
+ }
+ else if (IS_GAMEOBJECT_GUID((*itr)))
+ {
+ GameObject* go = GetMap()->GetGameObject(*itr);
+ if (!go)
+ continue;
+
+ go->SetFieldNotifyFlag(UF_FLAG_PUBLIC);
+ go->BuildValuesUpdateBlockForPlayer(&udata, this);
+ go->RemoveFieldNotifyFlag(UF_FLAG_PUBLIC);
}
}
+ if (!udata.HasData())
+ return;
+
udata.BuildPacket(&packet);
GetSession()->SendPacket(&packet);
}
@@ -23387,13 +23401,13 @@ void Player::SendAurasForTarget(Unit* target)
These movement packets are usually found in SMSG_COMPRESSED_MOVES
*/
if (target->HasAuraType(SPELL_AURA_FEATHER_FALL))
- target->SendMovementFeatherFall();
+ target->SetFeatherFall(true, true);
if (target->HasAuraType(SPELL_AURA_WATER_WALK))
- target->SendMovementWaterWalking();
+ target->SetWaterWalking(true, true);
if (target->HasAuraType(SPELL_AURA_HOVER))
- target->SendMovementHover();
+ target->SetHover(true, true);
WorldPacket data(SMSG_AURA_UPDATE_ALL);
data.append(target->GetPackGUID());
@@ -25319,7 +25333,7 @@ void Player::HandleFall(MovementInfo const& movementInfo)
}
//Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction
- TC_LOG_DEBUG(LOG_FILTER_PLAYER, "FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d", movementInfo.pos.GetPositionZ(), height, GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall);
+ TC_LOG_DEBUG(LOG_FILTER_PLAYER, "FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d", movementInfo.pos.GetPositionZ(), height, GetPositionZ(), movementInfo.jump.fallTime, height, damage, safe_fall);
}
}
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_LANDING); // No fly zone - Parachute
@@ -25659,8 +25673,8 @@ void Player::AddKnownCurrency(uint32 itemId)
void Player::UpdateFallInformationIfNeed(MovementInfo const& minfo, uint16 opcode)
{
- if (m_lastFallTime >= minfo.fallTime || m_lastFallZ <= minfo.pos.GetPositionZ() || opcode == MSG_MOVE_FALL_LAND)
- SetFallInformation(minfo.fallTime, minfo.pos.GetPositionZ());
+ if (m_lastFallTime >= minfo.jump.fallTime || m_lastFallZ <= minfo.pos.GetPositionZ() || opcode == MSG_MOVE_FALL_LAND)
+ SetFallInformation(minfo.jump.fallTime, minfo.pos.GetPositionZ());
}
void Player::UnsummonPetTemporaryIfAny()
@@ -26829,10 +26843,9 @@ void Player::_SaveInstanceTimeRestrictions(SQLTransaction& trans)
bool Player::IsInWhisperWhiteList(uint64 guid)
{
for (WhisperListContainer::const_iterator itr = WhisperList.begin(); itr != WhisperList.end(); ++itr)
- {
if (*itr == guid)
return true;
- }
+
return false;
}
@@ -27240,35 +27253,35 @@ void Player::ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::Ext
break;
case MSETransportPositionX:
if (hasTransportData)
- data >> mi->t_pos.m_positionX;
+ data >> mi->transport.pos.m_positionX;
break;
case MSETransportPositionY:
if (hasTransportData)
- data >> mi->t_pos.m_positionY;
+ data >> mi->transport.pos.m_positionY;
break;
case MSETransportPositionZ:
if (hasTransportData)
- data >> mi->t_pos.m_positionZ;
+ data >> mi->transport.pos.m_positionZ;
break;
case MSETransportOrientation:
if (hasTransportData)
- mi->t_pos.SetOrientation(data.read<float>());
+ mi->transport.pos.SetOrientation(data.read<float>());
break;
case MSETransportSeat:
if (hasTransportData)
- data >> mi->t_seat;
+ data >> mi->transport.seat;
break;
case MSETransportTime:
if (hasTransportData)
- data >> mi->t_time;
+ data >> mi->transport.time;
break;
case MSETransportTime2:
if (hasTransportData && mi->bits.hasTransportTime2)
- data >> mi->t_time2;
+ data >> mi->transport.time2;
break;
case MSETransportTime3:
if (hasTransportData && mi->bits.hasTransportTime3)
- data >> mi->t_time3;
+ data >> mi->transport.time3;
break;
case MSEPitch:
if (mi->bits.hasPitch)
@@ -27276,23 +27289,23 @@ void Player::ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::Ext
break;
case MSEFallTime:
if (mi->bits.hasFallData)
- data >> mi->fallTime;
+ data >> mi->jump.fallTime;
break;
case MSEFallVerticalSpeed:
if (mi->bits.hasFallData)
- data >> mi->j_zspeed;
+ data >> mi->jump.zspeed;
break;
case MSEFallCosAngle:
if (mi->bits.hasFallData && mi->bits.hasFallDirection)
- data >> mi->j_cosAngle;
+ data >> mi->jump.cosAngle;
break;
case MSEFallSinAngle:
if (mi->bits.hasFallData && mi->bits.hasFallDirection)
- data >> mi->j_sinAngle;
+ data >> mi->jump.sinAngle;
break;
case MSEFallHorizontalSpeed:
if (mi->bits.hasFallData && mi->bits.hasFallDirection)
- data >> mi->j_xyspeed;
+ data >> mi->jump.xyspeed;
break;
case MSESplineElevation:
if (mi->bits.hasSplineElevation)
@@ -27315,9 +27328,9 @@ void Player::ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::Ext
}
mi->guid = guid;
- mi->t_guid = tguid;
+ mi->transport.guid = tguid;
- if (hasTransportData && mi->pos.m_positionX != mi->t_pos.m_positionX)
+ if (hasTransportData && mi->pos.m_positionX != mi->transport.pos.m_positionX)
if (GetTransport())
GetTransport()->UpdatePosition(mi);
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index 5361eaff8a2..3b1e031dbb6 100644
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -634,8 +634,8 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y,
}
creature->SetTransport(this);
- creature->m_movementInfo.t_guid = GetGUID();
- creature->m_movementInfo.t_pos.Relocate(x, y, z, o);
+ creature->m_movementInfo.transport.guid = GetGUID();
+ creature->m_movementInfo.transport.pos.Relocate(x, y, z, o);
if (anim)
creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, anim);
@@ -647,7 +647,7 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y,
o + GetOrientation());
creature->SetHomePosition(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation());
- creature->SetTransportHomePosition(creature->m_movementInfo.t_pos);
+ creature->SetTransportHomePosition(creature->m_movementInfo.transport.pos);
if (!creature->IsPositionValid())
{
@@ -674,10 +674,10 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y,
void Transport::UpdatePosition(MovementInfo* mi)
{
- float transport_o = mi->pos.GetOrientation() - mi->t_pos.GetOrientation();
- float transport_x = mi->pos.m_positionX - (mi->t_pos.m_positionX * std::cos(transport_o) - mi->t_pos.m_positionY * std::sin(transport_o));
- float transport_y = mi->pos.m_positionY - (mi->t_pos.m_positionY * std::cos(transport_o) + mi->t_pos.m_positionX * std::sin(transport_o));
- float transport_z = mi->pos.m_positionZ - mi->t_pos.m_positionZ;
+ float transport_o = mi->pos.GetOrientation() - mi->transport.pos.GetOrientation();
+ float transport_x = mi->pos.m_positionX - (mi->transport.pos.m_positionX * std::cos(transport_o) - mi->transport.pos.m_positionY * std::sin(transport_o));
+ float transport_y = mi->pos.m_positionY - (mi->transport.pos.m_positionY * std::cos(transport_o) + mi->transport.pos.m_positionX * std::sin(transport_o));
+ float transport_z = mi->pos.m_positionZ - mi->transport.pos.m_positionZ;
Relocate(transport_x, transport_y, transport_z, transport_o);
UpdatePassengerPositions();
@@ -690,7 +690,7 @@ void Transport::UpdatePassengerPositions()
Creature* npc = *itr;
float x, y, z, o;
- npc->m_movementInfo.t_pos.GetPosition(x, y, z, o);
+ npc->m_movementInfo.transport.pos.GetPosition(x, y, z, o);
CalculatePassengerPosition(x, y, z, &o);
GetMap()->CreatureRelocation(npc, x, y, z, o, false);
npc->GetTransportHomePosition(x, y, z, o);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index a6084a62fdb..9ca21adb157 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -409,7 +409,7 @@ void Unit::UpdateSplinePosition()
Movement::Location loc = movespline->ComputePosition();
if (GetTransGUID())
{
- Position& pos = m_movementInfo.t_pos;
+ Position& pos = m_movementInfo.transport.pos;
pos.m_positionX = loc.x;
pos.m_positionY = loc.y;
pos.m_positionZ = loc.z;
@@ -8594,10 +8594,7 @@ void Unit::SetCharm(Unit* charm, bool apply)
_isWalkingBeforeCharm = charm->IsWalking();
if (_isWalkingBeforeCharm)
- {
charm->SetWalk(false);
- charm->SendMovementWalkMode();
- }
m_Controlled.insert(charm);
}
@@ -8632,10 +8629,7 @@ void Unit::SetCharm(Unit* charm, bool apply)
}
if (charm->IsWalking() != _isWalkingBeforeCharm)
- {
charm->SetWalk(_isWalkingBeforeCharm);
- charm->SendMovementWalkMode();
- }
if (charm->GetTypeId() == TYPEID_PLAYER
|| !charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_MINION)
@@ -16008,14 +16002,6 @@ bool Unit::IsFalling() const
return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR) || movespline->isFalling();
}
-void Unit::SetCanFly(bool apply)
-{
- if (apply)
- AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
- else
- RemoveUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
-}
-
void Unit::NearTeleportTo(float x, float y, float z, float orientation, bool casting /*= false*/)
{
DisableSpline();
@@ -16218,11 +16204,11 @@ void Unit::WriteMovementInfo(WorldPacket& data, Movement::ExtraMovementStatusEle
break;
case MSETransportTime2:
if (hasTransportData && hasTransportTime2)
- data << mi.t_time2;
+ data << mi.transport.time2;
break;
case MSETransportTime3:
if (hasTransportData && hasTransportTime3)
- data << mi.t_time3;
+ data << mi.transport.time3;
break;
case MSEPitch:
if (hasPitch)
@@ -16230,23 +16216,23 @@ void Unit::WriteMovementInfo(WorldPacket& data, Movement::ExtraMovementStatusEle
break;
case MSEFallTime:
if (hasFallData)
- data << mi.fallTime;
+ data << mi.jump.fallTime;
break;
case MSEFallVerticalSpeed:
if (hasFallData)
- data << mi.j_zspeed;
+ data << mi.jump.zspeed;
break;
case MSEFallCosAngle:
if (hasFallData && hasFallDirection)
- data << mi.j_cosAngle;
+ data << mi.jump.cosAngle;
break;
case MSEFallSinAngle:
if (hasFallData && hasFallDirection)
- data << mi.j_sinAngle;
+ data << mi.jump.sinAngle;
break;
case MSEFallHorizontalSpeed:
if (hasFallData && hasFallDirection)
- data << mi.j_xyspeed;
+ data << mi.jump.xyspeed;
break;
case MSESplineElevation:
if (hasSplineElevation)
@@ -16700,103 +16686,146 @@ bool Unit::SetWalk(bool enable)
else
RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ ///@ TODO: Find proper opcode for walk mode setting in player mind controlling a player case
+ if (enable)
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_WALK_MODE, SMSG_SPLINE_MOVE_SET_WALK_MODE).Send();
+ else
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_RUN_MODE, SMSG_SPLINE_MOVE_SET_WALK_MODE).Send();
+
return true;
}
-bool Unit::SetDisableGravity(bool disable, bool /*packetOnly = false*/)
+bool Unit::SetDisableGravity(bool disable, bool packetOnly /*= false*/)
{
- if (disable == IsLevitating())
- return false;
+ if (!packetOnly)
+ {
+ if (disable == IsLevitating())
+ return false;
+
+ if (disable)
+ AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
+ else
+ RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
+ }
if (disable)
- AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_GRAVITY_DISABLE, SMSG_MOVE_GRAVITY_DISABLE).Send();
else
- RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_GRAVITY_ENABLE, SMSG_MOVE_GRAVITY_ENABLE).Send();
return true;
}
-bool Unit::SetHover(bool enable)
+bool Unit::SetSwim(bool enable)
{
- if (enable == HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
+ if (enable == HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING))
return false;
if (enable)
- {
- //! No need to check height on ascent
- AddUnitMovementFlag(MOVEMENTFLAG_HOVER);
- if (float hh = GetFloatValue(UNIT_FIELD_HOVERHEIGHT))
- UpdateHeight(GetPositionZ() + hh);
- }
+ AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
else
- {
- RemoveUnitMovementFlag(MOVEMENTFLAG_HOVER);
- if (float hh = GetFloatValue(UNIT_FIELD_HOVERHEIGHT))
- {
- float newZ = GetPositionZ() - hh;
- UpdateAllowedPositionZ(GetPositionX(), GetPositionY(), newZ);
- UpdateHeight(newZ);
- }
- }
+ RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
+
+ if (enable)
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_START_SWIM, NULL_OPCODE).Send();
+ else
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_STOP_SWIM, NULL_OPCODE).Send();
return true;
}
-void Unit::SendMovementHover()
+bool Unit::SetCanFly(bool enable)
{
- if (HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_HOVER, SMSG_MOVE_SET_HOVER).Send();
+ if (enable == HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY))
+ return false;
+
+ if (enable)
+ AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
else
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_UNSET_HOVER, SMSG_MOVE_UNSET_HOVER).Send();
+ RemoveUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
+
+ if (enable)
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_FLYING, SMSG_MOVE_SET_CAN_FLY).Send();
+ else
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_UNSET_FLYING, SMSG_MOVE_UNSET_CAN_FLY).Send();
+
+ return true;
}
-void Unit::SendMovementWaterWalking()
+bool Unit::SetWaterWalking(bool enable, bool packetOnly /*= false */)
{
- if (HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING))
+ if (!packetOnly)
+ {
+ if (enable == HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING))
+ return false;
+
+ if (enable)
+ AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
+ else
+ RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
+ }
+
+ if (enable)
Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_WATER_WALK, SMSG_MOVE_WATER_WALK).Send();
else
Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_LAND_WALK, SMSG_MOVE_LAND_WALK).Send();
+
+ return true;
}
-void Unit::SendMovementFeatherFall()
+bool Unit::SetFeatherFall(bool enable, bool packetOnly /*= false */)
{
- if (HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW))
+ if (!packetOnly)
+ {
+ if (enable == HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW))
+ return false;
+
+ if (enable)
+ AddUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
+ else
+ RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
+ }
+
+ if (enable)
Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_FEATHER_FALL, SMSG_MOVE_FEATHER_FALL).Send();
else
Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_NORMAL_FALL, SMSG_MOVE_NORMAL_FALL).Send();
-}
-void Unit::SendMovementCanFlyChange()
-{
- if (HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY))
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_FLYING, SMSG_MOVE_SET_CAN_FLY).Send();
- else
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_UNSET_FLYING, SMSG_MOVE_UNSET_CAN_FLY).Send();
+ return true;
}
-void Unit::SendMovementDisableGravity()
+bool Unit::SetHover(bool enable, bool packetOnly /*= false*/)
{
- if (HasUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY))
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_GRAVITY_DISABLE, SMSG_MOVE_GRAVITY_DISABLE).Send();
- else
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_GRAVITY_ENABLE, SMSG_MOVE_GRAVITY_ENABLE).Send();
-}
+ if (!packetOnly)
+ {
+ if (enable == HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
+ return false;
-void Unit::SendMovementWalkMode()
-{
- ///@ TODO: Find proper opcode for walk mode setting in player mind controlling a player case
- if (HasUnitMovementFlag(MOVEMENTFLAG_WALKING))
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_WALK_MODE, SMSG_SPLINE_MOVE_SET_WALK_MODE).Send();
- else
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_RUN_MODE, SMSG_SPLINE_MOVE_SET_WALK_MODE).Send();
-}
+ if (enable)
+ {
+ //! No need to check height on ascent
+ AddUnitMovementFlag(MOVEMENTFLAG_HOVER);
+ if (float hh = GetFloatValue(UNIT_FIELD_HOVERHEIGHT))
+ UpdateHeight(GetPositionZ() + hh);
+ }
+ else
+ {
+ RemoveUnitMovementFlag(MOVEMENTFLAG_HOVER);
+ if (float hh = GetFloatValue(UNIT_FIELD_HOVERHEIGHT))
+ {
+ float newZ = GetPositionZ() - hh;
+ UpdateAllowedPositionZ(GetPositionX(), GetPositionY(), newZ);
+ UpdateHeight(newZ);
+ }
+ }
+ }
-void Unit::SendMovementSwimming()
-{
- if (HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING))
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_START_SWIM, NULL_OPCODE).Send();
+ if (enable)
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_HOVER, SMSG_MOVE_SET_HOVER).Send();
else
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_STOP_SWIM, NULL_OPCODE).Send();
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_UNSET_HOVER, SMSG_MOVE_UNSET_HOVER).Send();
+
+ return true;
}
void Unit::SendSetPlayHoverAnim(bool enable)
@@ -16874,3 +16903,177 @@ void Unit::ReleaseFocus(Spell const* focusSpell)
if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST)
ClearUnitState(UNIT_STATE_ROTATING);
}
+
+void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const
+{
+ if (!target)
+ return;
+
+ ByteBuffer fieldBuffer;
+
+ UpdateMask updateMask;
+ updateMask.SetCount(m_valuesCount);
+
+ uint32* flags = UnitUpdateFieldFlags;
+ uint32 visibleFlag = UF_FLAG_PUBLIC;
+
+ if (target == this)
+ visibleFlag |= UF_FLAG_PRIVATE;
+
+ Player* plr = GetCharmerOrOwnerPlayerOrPlayerItself();
+ if (GetOwnerGUID() == target->GetGUID())
+ visibleFlag |= UF_FLAG_OWNER;
+
+ if (HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_SPECIALINFO))
+ if (HasAuraTypeWithCaster(SPELL_AURA_EMPATHY, target->GetGUID()))
+ visibleFlag |= UF_FLAG_SPECIAL_INFO;
+
+ if (plr && plr->IsInSameRaidWith(target))
+ visibleFlag |= UF_FLAG_PARTY_MEMBER;
+
+ Creature const* creature = ToCreature();
+ for (uint16 index = 0; index < m_valuesCount; ++index)
+ {
+ if (_fieldNotifyFlags & flags[index] ||
+ ((flags[index] & visibleFlag) & UF_FLAG_SPECIAL_INFO) ||
+ ((updateType == UPDATETYPE_VALUES ? _changesMask.GetBit(index) : m_uint32Values[index]) && (flags[index] & visibleFlag)) ||
+ (index == UNIT_FIELD_AURASTATE && HasFlag(UNIT_FIELD_AURASTATE, PER_CASTER_AURA_STATE_MASK)))
+ {
+ updateMask.SetBit(index);
+
+ if (index == UNIT_NPC_FLAGS)
+ {
+ uint32 appendValue = m_uint32Values[UNIT_NPC_FLAGS];
+
+ if (creature)
+ if (!target->CanSeeSpellClickOn(creature))
+ appendValue &= ~UNIT_NPC_FLAG_SPELLCLICK;
+
+ fieldBuffer << uint32(appendValue);
+ }
+ else if (index == UNIT_FIELD_AURASTATE)
+ {
+ // Check per caster aura states to not enable using a spell in client if specified aura is not by target
+ fieldBuffer << BuildAuraStateUpdateForTarget(target);
+ }
+ // FIXME: Some values at server stored in float format but must be sent to client in uint32 format
+ else if (index >= UNIT_FIELD_BASEATTACKTIME && index <= UNIT_FIELD_RANGEDATTACKTIME)
+ {
+ // convert from float to uint32 and send
+ fieldBuffer << uint32(m_floatValues[index] < 0 ? 0 : m_floatValues[index]);
+ }
+ // there are some float values which may be negative or can't get negative due to other checks
+ else if ((index >= UNIT_FIELD_NEGSTAT0 && index <= UNIT_FIELD_NEGSTAT4) ||
+ (index >= UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE && index <= (UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE + 6)) ||
+ (index >= UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE && index <= (UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE + 6)) ||
+ (index >= UNIT_FIELD_POSSTAT0 && index <= UNIT_FIELD_POSSTAT4))
+ {
+ fieldBuffer << uint32(m_floatValues[index]);
+ }
+ // Gamemasters should be always able to select units - remove not selectable flag
+ else if (index == UNIT_FIELD_FLAGS)
+ {
+ uint32 appendValue = m_uint32Values[UNIT_FIELD_FLAGS];
+ if (target->IsGameMaster())
+ appendValue &= ~UNIT_FLAG_NOT_SELECTABLE;
+
+ fieldBuffer << uint32(appendValue);
+ }
+ // use modelid_a if not gm, _h if gm for CREATURE_FLAG_EXTRA_TRIGGER creatures
+ else if (index == UNIT_FIELD_DISPLAYID)
+ {
+ uint32 displayId = m_uint32Values[UNIT_FIELD_DISPLAYID];
+ if (creature)
+ {
+ CreatureTemplate const* cinfo = creature->GetCreatureTemplate();
+
+ // this also applies for transform auras
+ if (SpellInfo const* transform = sSpellMgr->GetSpellInfo(getTransForm()))
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ if (transform->Effects[i].IsAura(SPELL_AURA_TRANSFORM))
+ if (CreatureTemplate const* transformInfo = sObjectMgr->GetCreatureTemplate(transform->Effects[i].MiscValue))
+ {
+ cinfo = transformInfo;
+ break;
+ }
+
+ if (cinfo->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER)
+ {
+ if (target->IsGameMaster())
+ {
+ if (cinfo->Modelid1)
+ displayId = cinfo->Modelid1; // Modelid1 is a visible model for gms
+ else
+ displayId = 17519; // world visible trigger's model
+ }
+ else
+ {
+ if (cinfo->Modelid2)
+ displayId = cinfo->Modelid2; // Modelid2 is an invisible model for players
+ else
+ displayId = 11686; // world invisible trigger's model
+ }
+ }
+ }
+
+ fieldBuffer << uint32(displayId);
+ }
+ // hide lootable animation for unallowed players
+ else if (index == UNIT_DYNAMIC_FLAGS)
+ {
+ uint32 dynamicFlags = m_uint32Values[UNIT_DYNAMIC_FLAGS] & ~(UNIT_DYNFLAG_TAPPED | UNIT_DYNFLAG_TAPPED_BY_PLAYER);
+
+ if (creature)
+ {
+ if (creature->hasLootRecipient())
+ {
+ dynamicFlags |= UNIT_DYNFLAG_TAPPED;
+ if (creature->isTappedBy(target))
+ dynamicFlags |= UNIT_DYNFLAG_TAPPED_BY_PLAYER;
+ }
+
+ if (!target->isAllowedToLoot(creature))
+ dynamicFlags &= ~UNIT_DYNFLAG_LOOTABLE;
+ }
+
+ // unit UNIT_DYNFLAG_TRACK_UNIT should only be sent to caster of SPELL_AURA_MOD_STALKED auras
+ if (dynamicFlags & UNIT_DYNFLAG_TRACK_UNIT)
+ if (!HasAuraTypeWithCaster(SPELL_AURA_MOD_STALKED, target->GetGUID()))
+ dynamicFlags &= ~UNIT_DYNFLAG_TRACK_UNIT;
+
+ fieldBuffer << dynamicFlags;
+ }
+ // FG: pretend that OTHER players in own group are friendly ("blue")
+ else if (index == UNIT_FIELD_BYTES_2 || index == UNIT_FIELD_FACTIONTEMPLATE)
+ {
+ if (IsControlledByPlayer() && target != this && sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && IsInRaidWith(target))
+ {
+ FactionTemplateEntry const* ft1 = GetFactionTemplateEntry();
+ FactionTemplateEntry const* ft2 = target->GetFactionTemplateEntry();
+ if (ft1 && ft2 && !ft1->IsFriendlyTo(*ft2))
+ {
+ if (index == UNIT_FIELD_BYTES_2)
+ // Allow targetting opposite faction in party when enabled in config
+ fieldBuffer << (m_uint32Values[UNIT_FIELD_BYTES_2] & ((UNIT_BYTE2_FLAG_SANCTUARY /*| UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5*/) << 8)); // this flag is at uint8 offset 1 !!
+ else
+ // pretend that all other HOSTILE players have own faction, to allow follow, heal, rezz (trade wont work)
+ fieldBuffer << uint32(target->getFaction());
+ }
+ else
+ fieldBuffer << m_uint32Values[index];
+ }
+ else
+ fieldBuffer << m_uint32Values[index];
+ }
+ else
+ {
+ // send in current format (float as float, uint32 as uint32)
+ fieldBuffer << m_uint32Values[index];
+ }
+ }
+ }
+
+ *data << uint8(updateMask.GetBlockCount());
+ updateMask.AppendToPacket(data);
+ data->append(fieldBuffer);
+}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 3e8abdd404b..95aaf57a84f 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1597,27 +1597,19 @@ class Unit : public WorldObject
void MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath = false, bool forceDestination = false);
- /*! These methods send the same packet to the client in apply and unapply case.
- The client-side interpretation of this packet depends on the presence of relevant movementflags
- which are sent with movementinfo. Furthermore, these packets are broadcast to nearby players as well
- as the current unit.
- */
- void SendMovementHover();
- void SendMovementFeatherFall();
- void SendMovementWaterWalking();
- void SendMovementCanFlyChange();
- void SendMovementDisableGravity();
- void SendMovementWalkMode();
- void SendMovementSwimming();
void SendSetPlayHoverAnim(bool enable);
void SendMovementSetSplineAnim(Movement::AnimType anim);
- bool IsLevitating() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);}
- bool IsWalking() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING);}
+ bool IsLevitating() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); }
+ bool IsWalking() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING); }
virtual bool SetWalk(bool enable);
virtual bool SetDisableGravity(bool disable, bool packetOnly = false);
- virtual bool SetHover(bool enable);
+ virtual bool SetSwim(bool enable);
+ virtual bool SetCanFly(bool enable);
+ virtual bool SetWaterWalking(bool enable, bool packetOnly = false);
+ virtual bool SetFeatherFall(bool enable, bool packetOnly = false);
+ virtual bool SetHover(bool enable, bool packetOnly = false);
void SetInFront(WorldObject const* target);
void SetFacingTo(float ori);
@@ -2026,17 +2018,17 @@ class Unit : public WorldObject
bool IsStopped() const { return !(HasUnitState(UNIT_STATE_MOVING)); }
void StopMoving();
- void AddUnitMovementFlag(uint32 f) { m_movementInfo.flags |= f; }
- void RemoveUnitMovementFlag(uint32 f) { m_movementInfo.flags &= ~f; }
- bool HasUnitMovementFlag(uint32 f) const { return (m_movementInfo.flags & f) == f; }
- uint32 GetUnitMovementFlags() const { return m_movementInfo.flags; }
- void SetUnitMovementFlags(uint32 f) { m_movementInfo.flags = f; }
-
- void AddExtraUnitMovementFlag(uint16 f) { m_movementInfo.flags2 |= f; }
- void RemoveExtraUnitMovementFlag(uint16 f) { m_movementInfo.flags2 &= ~f; }
- uint16 HasExtraUnitMovementFlag(uint16 f) const { return m_movementInfo.flags2 & f; }
- uint16 GetExtraUnitMovementFlags() const { return m_movementInfo.flags2; }
- void SetExtraUnitMovementFlags(uint16 f) { m_movementInfo.flags2 = f; }
+ void AddUnitMovementFlag(uint32 f) { m_movementInfo.AddMovementFlag(f); }
+ void RemoveUnitMovementFlag(uint32 f) { m_movementInfo.RemoveMovementFlag(f); }
+ bool HasUnitMovementFlag(uint32 f) const { return m_movementInfo.HasMovementFlag(f); }
+ uint32 GetUnitMovementFlags() const { return m_movementInfo.GetMovementFlags(); }
+ void SetUnitMovementFlags(uint32 f) { m_movementInfo.SetMovementFlags(f); }
+
+ void AddExtraUnitMovementFlag(uint16 f) { m_movementInfo.AddExtraMovementFlag(f); }
+ void RemoveExtraUnitMovementFlag(uint16 f) { m_movementInfo.RemoveExtraMovementFlag(f); }
+ uint16 HasExtraUnitMovementFlag(uint16 f) const { return m_movementInfo.HasExtraMovementFlag(f); }
+ uint16 GetExtraUnitMovementFlags() const { return m_movementInfo.GetExtraMovementFlags(); }
+ void SetExtraUnitMovementFlags(uint16 f) { m_movementInfo.SetExtraMovementFlags(f); }
bool IsSplineEnabled() const;
float GetPositionZMinusOffset() const;
@@ -2094,12 +2086,12 @@ class Unit : public WorldObject
bool IsOnVehicle(const Unit* vehicle) const;
Unit* GetVehicleBase() const;
Creature* GetVehicleCreatureBase() const;
- float GetTransOffsetX() const { return m_movementInfo.t_pos.GetPositionX(); }
- float GetTransOffsetY() const { return m_movementInfo.t_pos.GetPositionY(); }
- float GetTransOffsetZ() const { return m_movementInfo.t_pos.GetPositionZ(); }
- float GetTransOffsetO() const { return m_movementInfo.t_pos.GetOrientation(); }
- uint32 GetTransTime() const { return m_movementInfo.t_time; }
- int8 GetTransSeat() const { return m_movementInfo.t_seat; }
+ float GetTransOffsetX() const { return m_movementInfo.transport.pos.GetPositionX(); }
+ float GetTransOffsetY() const { return m_movementInfo.transport.pos.GetPositionY(); }
+ float GetTransOffsetZ() const { return m_movementInfo.transport.pos.GetPositionZ(); }
+ float GetTransOffsetO() const { return m_movementInfo.transport.pos.GetOrientation(); }
+ uint32 GetTransTime() const { return m_movementInfo.transport.time; }
+ int8 GetTransSeat() const { return m_movementInfo.transport.seat; }
uint64 GetTransGUID() const;
/// Returns the transport this unit is on directly (if on vehicle and transport, return vehicle)
TransportBase* GetDirectTransport() const;
@@ -2122,7 +2114,6 @@ class Unit : public WorldObject
virtual bool CanFly() const = 0;
bool IsFlying() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_DISABLE_GRAVITY); }
bool IsFalling() const;
- void SetCanFly(bool apply);
void RewardRage(uint32 baseRage, bool attacker);
@@ -2157,6 +2148,8 @@ class Unit : public WorldObject
protected:
explicit Unit (bool isWorldObject);
+ void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const;
+
UnitAI* i_AI, *i_disabledAI;
void _UpdateSpells(uint32 time);
diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp
index 797430683f4..28429387400 100644
--- a/src/server/game/Entities/Vehicle/Vehicle.cpp
+++ b/src/server/game/Entities/Vehicle/Vehicle.cpp
@@ -517,7 +517,7 @@ Vehicle* Vehicle::RemovePassenger(Unit* unit)
_me->RemoveCharmedBy(unit);
if (_me->IsInWorld())
- unit->m_movementInfo.ClearTransport();
+ unit->m_movementInfo.ResetTransport();
// only for flyable vehicles
if (unit->IsFlying())
@@ -554,7 +554,7 @@ void Vehicle::RelocatePassengers()
ASSERT(passenger->IsInWorld());
float px, py, pz, po;
- passenger->m_movementInfo.t_pos.GetPosition(px, py, pz, po);
+ passenger->m_movementInfo.transport.pos.GetPosition(px, py, pz, po);
CalculatePassengerPosition(px, py, pz, &po);
passenger->UpdatePosition(px, py, pz, po);
@@ -837,10 +837,10 @@ bool VehicleJoinEvent::Execute(uint64, uint32)
Passenger->AddUnitState(UNIT_STATE_ONVEHICLE);
VehicleSeatEntry const* veSeat = Seat->second.SeatInfo;
- Passenger->m_movementInfo.t_pos.Relocate(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ);
- Passenger->m_movementInfo.t_time = 0; // 1 for player
- Passenger->m_movementInfo.t_seat = Seat->first;
- Passenger->m_movementInfo.t_guid = Target->GetBase()->GetGUID();
+ Passenger->m_movementInfo.transport.pos.Relocate(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ);
+ Passenger->m_movementInfo.transport.time = 0;
+ Passenger->m_movementInfo.transport.seat = Seat->first;
+ Passenger->m_movementInfo.transport.guid = Target->GetBase()->GetGUID();
if (Target->GetBase()->GetTypeId() == TYPEID_UNIT && Passenger->GetTypeId() == TYPEID_PLAYER &&
Seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL)
diff --git a/src/server/game/Grids/GridDefines.h b/src/server/game/Grids/GridDefines.h
index 0cb2f32f621..1e4a9ca83b4 100644
--- a/src/server/game/Grids/GridDefines.h
+++ b/src/server/game/Grids/GridDefines.h
@@ -36,7 +36,7 @@ class AreaTrigger;
#define MAX_NUMBER_OF_GRIDS 64
-#define SIZE_OF_GRIDS 533.33333f
+#define SIZE_OF_GRIDS 533.3333f
#define CENTER_GRID_ID (MAX_NUMBER_OF_GRIDS/2)
#define CENTER_GRID_OFFSET (SIZE_OF_GRIDS/2)
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index bb7d4b1052f..6bd325f9114 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -1053,8 +1053,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form)
pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
- pCurrChar->AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
- pCurrChar->SendMovementWaterWalking();
+ pCurrChar->SetWaterWalking(true);
}
pCurrChar->ContinueTaxiFlight();
diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp
index d4bfc235595..79cb03c0ab3 100644
--- a/src/server/game/Handlers/GroupHandler.cpp
+++ b/src/server/game/Handlers/GroupHandler.cpp
@@ -1154,7 +1154,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke
if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
{
if (Vehicle* veh = player->GetVehicle())
- *data << uint32(veh->GetVehicleInfo()->m_seatID[player->m_movementInfo.t_seat]);
+ *data << uint32(veh->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]);
else
*data << uint32(0);
@@ -1335,7 +1335,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData)
data.put<uint64>(maskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS
if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
- data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.t_seat]);
+ data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]);
SendPacket(&data);
}
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index f45efe0b47e..cad1ef77daa 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -292,18 +292,18 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvPacket)
}
/* handle special cases */
- if (movementInfo.t_guid)
+ if (movementInfo.transport.guid)
{
// transports size limited
// (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
- if (movementInfo.t_pos.GetPositionX() > 50 || movementInfo.t_pos.GetPositionY() > 50 || movementInfo.t_pos.GetPositionZ() > 50)
+ if (movementInfo.transport.pos.GetPositionX() > 50 || movementInfo.transport.pos.GetPositionY() > 50 || movementInfo.transport.pos.GetPositionZ() > 50)
{
recvPacket.rfinish(); // prevent warnings spam
return;
}
- if (!Trinity::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.t_pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.t_pos.GetPositionY(),
- movementInfo.pos.GetPositionZ() + movementInfo.t_pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.t_pos.GetOrientation()))
+ if (!Trinity::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.transport.pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.transport.pos.GetPositionY(),
+ movementInfo.pos.GetPositionZ() + movementInfo.transport.pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.transport.pos.GetOrientation()))
{
recvPacket.rfinish(); // prevent warnings spam
return;
@@ -317,7 +317,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvPacket)
// elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just dismount if the guid can be found in the transport list
for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
{
- if ((*iter)->GetGUID() == movementInfo.t_guid)
+ if ((*iter)->GetGUID() == movementInfo.transport.guid)
{
plrMover->m_transport = *iter;
(*iter)->AddPassenger(plrMover);
@@ -325,13 +325,13 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvPacket)
}
}
}
- else if (plrMover->GetTransport()->GetGUID() != movementInfo.t_guid)
+ else if (plrMover->GetTransport()->GetGUID() != movementInfo.transport.guid)
{
bool foundNewTransport = false;
plrMover->m_transport->RemovePassenger(plrMover);
for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
{
- if ((*iter)->GetGUID() == movementInfo.t_guid)
+ if ((*iter)->GetGUID() == movementInfo.transport.guid)
{
foundNewTransport = true;
plrMover->m_transport = *iter;
@@ -343,25 +343,23 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvPacket)
if (!foundNewTransport)
{
plrMover->m_transport = NULL;
- movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
- movementInfo.t_time = 0;
- movementInfo.t_seat = -1;
+ movementInfo.ResetTransport();
}
}
}
if (!mover->GetTransport() && !mover->GetVehicle())
{
- GameObject* go = mover->GetMap()->GetGameObject(movementInfo.t_guid);
+ GameObject* go = mover->GetMap()->GetGameObject(movementInfo.transport.guid);
if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT)
- movementInfo.t_guid = 0;
+ movementInfo.transport.guid = 0;
}
}
else if (plrMover && plrMover->GetTransport()) // if we were on a transport, leave
{
plrMover->m_transport->RemovePassenger(plrMover);
plrMover->m_transport = NULL;
- movementInfo.ClearTransport();
+ movementInfo.ResetTransport();
}
// fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index 57faa5f3ebc..5ca07c095aa 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -4047,7 +4047,7 @@ enum PartyResult
};
const uint32 MMAP_MAGIC = 0x4d4d4150; // 'MMAP'
-#define MMAP_VERSION 3
+#define MMAP_VERSION 4
struct MmapTileHeader
{
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index 6ef93402606..ed30b59f0ec 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -97,7 +97,7 @@ dtPolyRef PathGenerator::GetPathPolyByPosition(dtPolyRef const* polyPath, uint32
for (uint32 i = 0; i < polyPathSize; ++i)
{
float closestPoint[VERTEX_SIZE];
- if (DT_SUCCESS != _navMeshQuery->closestPointOnPoly(polyPath[i], point, closestPoint))
+ if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(polyPath[i], point, closestPoint)))
continue;
float d = dtVdist2DSqr(point, closestPoint);
@@ -132,8 +132,7 @@ dtPolyRef PathGenerator::GetPolyByLocation(float const* point, float* distance)
// first try with low search box
float extents[VERTEX_SIZE] = {3.0f, 5.0f, 3.0f}; // bounds of poly search area
float closestPoint[VERTEX_SIZE] = {0.0f, 0.0f, 0.0f};
- dtStatus result = _navMeshQuery->findNearestPoly(point, extents, &_filter, &polyRef, closestPoint);
- if (DT_SUCCESS == result && polyRef != INVALID_POLYREF)
+ if (dtStatusSucceed(_navMeshQuery->findNearestPoly(point, extents, &_filter, &polyRef, closestPoint)) && polyRef != INVALID_POLYREF)
{
*distance = dtVdist(closestPoint, point);
return polyRef;
@@ -141,9 +140,10 @@ dtPolyRef PathGenerator::GetPolyByLocation(float const* point, float* distance)
// still nothing ..
// try with bigger search box
- extents[1] = 200.0f;
- result = _navMeshQuery->findNearestPoly(point, extents, &_filter, &polyRef, closestPoint);
- if (DT_SUCCESS == result && polyRef != INVALID_POLYREF)
+ // Note that the extent should not overlap more than 128 polygons in the navmesh (see dtNavMeshQuery::findNearestPoly)
+ extents[1] = 50.0f;
+
+ if (dtStatusSucceed(_navMeshQuery->findNearestPoly(point, extents, &_filter, &polyRef, closestPoint)) && polyRef != INVALID_POLYREF)
{
*distance = dtVdist(closestPoint, point);
return polyRef;
@@ -228,7 +228,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
{
float closestPoint[VERTEX_SIZE];
// we may want to use closestPointOnPolyBoundary instead
- if (DT_SUCCESS == _navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint))
+ if (dtStatusSucceed(_navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint)))
{
dtVcopy(endPoint, closestPoint);
SetActualEndPosition(G3D::Vector3(endPoint[2], endPoint[0], endPoint[1]));
@@ -319,13 +319,13 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
// we need any point on our suffix start poly to generate poly-path, so we need last poly in prefix data
float suffixEndPoint[VERTEX_SIZE];
- if (DT_SUCCESS != _navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint))
+ if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint)))
{
// we can hit offmesh connection as last poly - closestPointOnPoly() don't like that
// try to recover by using prev polyref
--prefixPolyLength;
suffixStartPoly = _pathPolyRefs[prefixPolyLength-1];
- if (DT_SUCCESS != _navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint))
+ if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint)))
{
// suffixStartPoly is still invalid, error state
BuildShortcut();
@@ -346,7 +346,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
(int*)&suffixPolyLength,
MAX_PATH_LENGTH-prefixPolyLength); // max number of polygons in output path
- if (!suffixPolyLength || dtResult != DT_SUCCESS)
+ if (!suffixPolyLength || dtStatusFailed(dtResult))
{
// this is probably an error state, but we'll leave it
// and hopefully recover on the next Update
@@ -380,7 +380,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
(int*)&_polyLength,
MAX_PATH_LENGTH); // max number of polygons in output path
- if (!_polyLength || dtResult != DT_SUCCESS)
+ if (!_polyLength || dtStatusFailed(dtResult))
{
// only happens if we passed bad data to findPath(), or navmesh is messed up
TC_LOG_ERROR(LOG_FILTER_MAPS, "%u's Path Build failed: 0 length path", _sourceUnit->GetGUIDLow());
@@ -430,7 +430,7 @@ void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoin
_pointPathLimit); // maximum number of points
}
- if (pointCount < 2 || dtResult != DT_SUCCESS)
+ if (pointCount < 2 || dtStatusFailed(dtResult))
{
// only happens if pass bad data to findStraightPath or navmesh is broken
// single point paths can be generated here
@@ -577,7 +577,7 @@ bool PathGenerator::HaveTile(const G3D::Vector3& p) const
if (tx < 0 || ty < 0)
return false;
- return (_navMesh->getTileAt(tx, ty) != NULL);
+ return (_navMesh->getTileAt(tx, ty, 0) != NULL);
}
uint32 PathGenerator::FixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, dtPolyRef const* visited, uint32 nvisited)
@@ -637,7 +637,7 @@ bool PathGenerator::GetSteerTarget(float const* startPos, float const* endPos,
uint32 nsteerPath = 0;
dtStatus dtResult = _navMeshQuery->findStraightPath(startPos, endPos, path, pathSize,
steerPath, steerPathFlags, steerPathPolys, (int*)&nsteerPath, MAX_STEER_POINTS);
- if (!nsteerPath || DT_SUCCESS != dtResult)
+ if (!nsteerPath || dtStatusFailed(dtResult))
return false;
// Find vertex far enough to steer to.
@@ -674,10 +674,10 @@ dtStatus PathGenerator::FindSmoothPath(float const* startPos, float const* endPo
uint32 npolys = polyPathSize;
float iterPos[VERTEX_SIZE], targetPos[VERTEX_SIZE];
- if (DT_SUCCESS != _navMeshQuery->closestPointOnPolyBoundary(polys[0], startPos, iterPos))
+ if (dtStatusFailed(_navMeshQuery->closestPointOnPolyBoundary(polys[0], startPos, iterPos)))
return DT_FAILURE;
- if (DT_SUCCESS != _navMeshQuery->closestPointOnPolyBoundary(polys[npolys-1], endPos, targetPos))
+ if (dtStatusFailed(_navMeshQuery->closestPointOnPolyBoundary(polys[npolys-1], endPos, targetPos)))
return DT_FAILURE;
dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos);
@@ -756,7 +756,7 @@ dtStatus PathGenerator::FindSmoothPath(float const* startPos, float const* endPo
// Handle the connection.
float startPos[VERTEX_SIZE], endPos[VERTEX_SIZE];
- if (DT_SUCCESS == _navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos))
+ if (dtStatusSucceed(_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos)))
{
if (nsmoothPath < maxSmoothPathSize)
{
diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp
index 02be702d3c2..1a35271c8c6 100644
--- a/src/server/game/Movement/Spline/MoveSpline.cpp
+++ b/src/server/game/Movement/Spline/MoveSpline.cpp
@@ -23,10 +23,6 @@
namespace Movement{
-extern float computeFallTime(float path_length, bool isSafeFall);
-extern float computeFallElevation(float time_passed, bool isSafeFall, float start_velocy);
-extern float computeFallElevation(float time_passed);
-
Location MoveSpline::ComputePosition() const
{
ASSERT(Initialized());
@@ -84,12 +80,9 @@ void MoveSpline::computeParabolicElevation(float& el) const
void MoveSpline::computeFallElevation(float& el) const
{
- float z_now = spline.getPoint(spline.first()).z - Movement::computeFallElevation(MSToSec(time_passed));
+ float z_now = spline.getPoint(spline.first()).z - Movement::computeFallElevation(MSToSec(time_passed), false);
float final_z = FinalDestination().z;
- if (z_now < final_z)
- el = final_z;
- else
- el = z_now;
+ el = std::max(z_now, final_z);
}
inline uint32 computeDuration(float length, float velocity)
@@ -160,7 +153,7 @@ void MoveSpline::init_spline(const MoveSplineInitArgs& args)
point_Idx = spline.first();
}
-void MoveSpline::Initialize(const MoveSplineInitArgs& args)
+void MoveSpline::Initialize(MoveSplineInitArgs const& args)
{
splineflags = args.flags;
facing = args.facing;
@@ -168,7 +161,6 @@ void MoveSpline::Initialize(const MoveSplineInitArgs& args)
point_Idx_offset = args.path_Idx_offset;
initialOrientation = args.initialOrientation;
- onTransport = false;
time_passed = 0;
vertical_acceleration = 0.f;
effect_start_time = 0;
@@ -196,7 +188,8 @@ void MoveSpline::Initialize(const MoveSplineInitArgs& args)
}
MoveSpline::MoveSpline() : m_Id(0), time_passed(0),
- vertical_acceleration(0.f), initialOrientation(0.f), effect_start_time(0), point_Idx(0), point_Idx_offset(0)
+ vertical_acceleration(0.f), initialOrientation(0.f), effect_start_time(0), point_Idx(0), point_Idx_offset(0),
+ onTransport(false)
{
splineflags.done = true;
}
diff --git a/src/server/game/Movement/Spline/MoveSpline.h b/src/server/game/Movement/Spline/MoveSpline.h
index a76c552079b..75ea89bee81 100644
--- a/src/server/game/Movement/Spline/MoveSpline.h
+++ b/src/server/game/Movement/Spline/MoveSpline.h
@@ -49,6 +49,7 @@ namespace Movement
Result_NextSegment = 0x08
};
friend class PacketBuilder;
+
protected:
MySpline spline;
@@ -69,30 +70,30 @@ namespace Movement
int32 point_Idx_offset;
void init_spline(const MoveSplineInitArgs& args);
- protected:
- const MySpline::ControlArray& getPath() const { return spline.getPoints(); }
+ protected:
+ MySpline::ControlArray const& getPath() const { return spline.getPoints(); }
void computeParabolicElevation(float& el) const;
void computeFallElevation(float& el) const;
UpdateResult _updateState(int32& ms_time_diff);
- int32 next_timestamp() const { return spline.length(point_Idx+1); }
- int32 segment_time_elapsed() const { return next_timestamp()-time_passed; }
+ int32 next_timestamp() const { return spline.length(point_Idx + 1); }
+ int32 segment_time_elapsed() const { return next_timestamp() - time_passed; }
int32 timeElapsed() const { return Duration() - time_passed; }
int32 timePassed() const { return time_passed; }
public:
int32 Duration() const { return spline.length(); }
- const MySpline& _Spline() const { return spline; }
+ MySpline const& _Spline() const { return spline; }
int32 _currentSplineIdx() const { return point_Idx; }
void _Finalize();
- void _Interrupt() { splineflags.done = true;}
+ void _Interrupt() { splineflags.done = true; }
public:
void Initialize(const MoveSplineInitArgs&);
bool Initialized() const { return !spline.empty(); }
- explicit MoveSpline();
+ MoveSpline();
template<class UpdateHandler>
void updateState(int32 difftime, UpdateHandler& handler)
@@ -116,8 +117,8 @@ namespace Movement
bool Finalized() const { return splineflags.done; }
bool isCyclic() const { return splineflags.cyclic; }
bool isFalling() const { return splineflags.falling; }
- const Vector3 FinalDestination() const { return Initialized() ? spline.getPoint(spline.last()) : Vector3(); }
- const Vector3 CurrentDestination() const { return Initialized() ? spline.getPoint(point_Idx+1) : Vector3(); }
+ Vector3 FinalDestination() const { return Initialized() ? spline.getPoint(spline.last()) : Vector3(); }
+ Vector3 CurrentDestination() const { return Initialized() ? spline.getPoint(point_Idx + 1) : Vector3(); }
int32 currentPathIdx() const;
bool onTransport;
diff --git a/src/server/game/Movement/Spline/MoveSplineFlag.h b/src/server/game/Movement/Spline/MoveSplineFlag.h
index 08e73c0344b..f86ce6431ed 100644
--- a/src/server/game/Movement/Spline/MoveSplineFlag.h
+++ b/src/server/game/Movement/Spline/MoveSplineFlag.h
@@ -104,7 +104,8 @@ namespace Movement
void EnableAnimation(uint8 anim) { raw() = (raw() & ~(Mask_Animations | Falling | Parabolic | FallingSlow)) | Animation | (anim & Mask_Animations); }
void EnableParabolic() { raw() = (raw() & ~(Mask_Animations | Falling | Animation | FallingSlow)) | Parabolic; }
- void EnableFalling() { raw() = (raw() & ~(Mask_Animations | Parabolic | Animation)) | Falling; }
+ void EnableFlying() { raw() = (raw() & ~(Falling)) | Flying; }
+ void EnableFalling() { raw() = (raw() & ~(Mask_Animations | Parabolic | Animation | Flying)) | Falling; }
void EnableCatmullRom() { raw() = (raw() & ~SmoothGroundPath) | Catmullrom; }
void EnableFacingPoint() { raw() = (raw() & ~Mask_Final_Facing) | Final_Point; }
void EnableFacingAngle() { raw() = (raw() & ~Mask_Final_Facing) | Final_Angle; }
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp
index 9cc1dbb3f43..65af02360e6 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.cpp
+++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp
@@ -98,6 +98,8 @@ namespace Movement
uint32 moveFlagsForSpeed = moveFlags;
if (args.flags.walkmode)
moveFlagsForSpeed |= MOVEMENTFLAG_WALKING;
+ else
+ moveFlagsForSpeed &= ~MOVEMENTFLAG_WALKING;
args.velocity = unit->GetSpeed(SelectSpeedType(moveFlagsForSpeed));
}
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h
index 1eaf1011a2c..c968f660f58 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.h
+++ b/src/server/game/Movement/Spline/MoveSplineInit.h
@@ -157,7 +157,7 @@ namespace Movement
Unit* unit;
};
- inline void MoveSplineInit::SetFly() { args.flags.flying = true; }
+ inline void MoveSplineInit::SetFly() { args.flags.EnableFlying(); }
inline void MoveSplineInit::SetWalk(bool enable) { args.flags.walkmode = enable; }
inline void MoveSplineInit::SetSmooth() { args.flags.EnableCatmullRom(); }
inline void MoveSplineInit::SetUncompressed() { args.flags.uncompressedPath = true; }
diff --git a/src/server/game/Movement/Spline/MoveSplineInitArgs.h b/src/server/game/Movement/Spline/MoveSplineInitArgs.h
index 4a086094c3f..474541cbf15 100644
--- a/src/server/game/Movement/Spline/MoveSplineInitArgs.h
+++ b/src/server/game/Movement/Spline/MoveSplineInitArgs.h
@@ -30,9 +30,9 @@ namespace Movement
union FacingInfo
{
- struct{
+ struct {
float x, y, z;
- }f;
+ } f;
uint64 target;
float angle;
@@ -43,8 +43,8 @@ namespace Movement
struct MoveSplineInitArgs
{
- MoveSplineInitArgs(size_t path_capacity = 16) : path_Idx_offset(0),
- velocity(0.f), parabolic_amplitude(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f),
+ MoveSplineInitArgs(size_t path_capacity = 16) : path_Idx_offset(0), velocity(0.f),
+ parabolic_amplitude(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f),
HasVelocity(false), TransformForTransport(true)
{
path.reserve(path_capacity);
@@ -64,6 +64,7 @@ namespace Movement
/** Returns true to show that the arguments were configured correctly and MoveSpline initialization will succeed. */
bool Validate(Unit* unit) const;
+
private:
bool _checkPathBounds() const;
};
diff --git a/src/server/game/Movement/Spline/MovementTypedefs.h b/src/server/game/Movement/Spline/MovementTypedefs.h
index f044d249fcb..1a0f3d54d27 100644
--- a/src/server/game/Movement/Spline/MovementTypedefs.h
+++ b/src/server/game/Movement/Spline/MovementTypedefs.h
@@ -44,6 +44,9 @@ namespace Movement
return ms / 1000.f;
}
+ float computeFallTime(float path_length, bool isSafeFall);
+ float computeFallElevation(float t_passed, bool isSafeFall, float start_velocity = 0.0f);
+
#ifndef static_assert
#define CONCAT(x, y) CONCAT1 (x, y)
#define CONCAT1(x, y) x##y
@@ -75,7 +78,6 @@ namespace Movement
typedef counter<uint32, 0xFFFFFFFF> UInt32Counter;
extern double gravity;
- extern float computeFallElevation(float t_passed, bool isSafeFall, float start_velocity);
extern UInt32Counter splineIdGen;
extern std::string MovementFlags_ToString(uint32 flags);
extern std::string MovementFlagsExtra_ToString(uint32 flags);
diff --git a/src/server/game/Movement/Spline/MovementUtil.cpp b/src/server/game/Movement/Spline/MovementUtil.cpp
index aaa575c752f..ee47a5ebedc 100644
--- a/src/server/game/Movement/Spline/MovementUtil.cpp
+++ b/src/server/game/Movement/Spline/MovementUtil.cpp
@@ -30,8 +30,9 @@ namespace Movement
float terminalSafefallVelocity = 7.0f;
const float terminal_length = float(terminalVelocity * terminalVelocity) / (2.0f * gravity);
- const float terminal_safefall_length = (terminalSafefallVelocity * terminalSafefallVelocity) / (2.0f * gravity);
- const float terminalFallTime = float(terminalVelocity / gravity); // the time that needed to reach terminalVelocity
+ const float terminal_safeFall_length = (terminalSafefallVelocity * terminalSafefallVelocity) / (2.0f * gravity);
+ const float terminal_fallTime = float(terminalVelocity / gravity); // the time that needed to reach terminalVelocity
+ const float terminal_safeFall_fallTime = float(terminalSafefallVelocity / gravity); // the time that needed to reach terminalVelocity with safefall
float computeFallTime(float path_length, bool isSafeFall)
{
@@ -41,15 +42,15 @@ namespace Movement
float time;
if (isSafeFall)
{
- if (path_length >= terminal_safefall_length)
- time = (path_length - terminal_safefall_length) / terminalSafefallVelocity + terminalSafefallVelocity / gravity;
+ if (path_length >= terminal_safeFall_length)
+ time = (path_length - terminal_safeFall_length) / terminalSafefallVelocity + terminal_safeFall_fallTime;
else
time = sqrtf(2.0f * path_length / gravity);
}
else
{
if (path_length >= terminal_length)
- time = (path_length - terminal_length) / terminalVelocity + terminalFallTime;
+ time = (path_length - terminal_length) / terminalVelocity + terminal_fallTime;
else
time = sqrtf(2.0f * path_length / gravity);
}
@@ -57,7 +58,7 @@ namespace Movement
return time;
}
- float computeFallElevation(float t_passed, bool isSafeFall, float start_velocity)
+ float computeFallElevation(float t_passed, bool isSafeFall, float start_velocity /*= 0.0f*/)
{
float termVel;
float result;
@@ -70,11 +71,11 @@ namespace Movement
if (start_velocity > termVel)
start_velocity = termVel;
- float terminal_time = terminalFallTime - start_velocity / gravity; // the time that needed to reach terminalVelocity
+ float terminal_time = (isSafeFall ? terminal_safeFall_fallTime : terminal_fallTime) - start_velocity / gravity; // the time that needed to reach terminalVelocity
if (t_passed > terminal_time)
{
- result = terminalVelocity * (t_passed - terminal_time) +
+ result = termVel * (t_passed - terminal_time) +
start_velocity * terminal_time +
gravity * terminal_time * terminal_time*0.5f;
}
@@ -84,22 +85,6 @@ namespace Movement
return result;
}
- float computeFallElevation(float t_passed)
- {
- float result;
-
- if (t_passed > terminalFallTime)
- {
- //result = terminalVelocity * (t_passed - terminal_time) + gravity*terminal_time*terminal_time*0.5f;
- // simplified view:
- result = terminalVelocity * (t_passed - terminalFallTime) + terminal_length;
- }
- else
- result = t_passed * t_passed * gravity * 0.5f;
-
- return result;
- }
-
#define STR(x) #x
char const* g_MovementFlag_names[] =
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 9acc4a15dc4..e6e5386626d 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -1216,7 +1216,6 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_FLYING, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_WATER_WALK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_STABLE_RESULT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_STANDSTATE_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_START_MIRROR_TIMER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index cd72faf5740..0c6d7c82c06 100644
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -1295,7 +1295,7 @@ enum Opcodes
SMSG_SPLINE_MOVE_SET_TURN_RATE = 0x78B5,
SMSG_SPLINE_MOVE_SET_WALK_MODE = 0x54B6,
SMSG_SPLINE_MOVE_SET_WALK_SPEED = 0x34A5,
- SMSG_SPLINE_MOVE_SET_WATER_WALK = 0x0000,
+ SMSG_SPLINE_MOVE_SET_WATER_WALK = 0x50A2,
SMSG_SPLINE_MOVE_START_SWIM = 0x31A5,
SMSG_SPLINE_MOVE_STOP_SWIM = 0x1DA2,
SMSG_SPLINE_MOVE_UNROOT = 0x75B6,
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index faaedf42b74..58f49f72cfd 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -2650,23 +2650,17 @@ void AuraEffect::HandleAuraAllowFlight(AuraApplication const* aurApp, uint8 mode
}
//! Not entirely sure if this should be sent for creatures as well, but I don't think so.
- target->SetCanFly(apply);
if (!apply)
{
- target->RemoveUnitMovementFlag(MOVEMENTFLAG_MASK_MOVING_FLY);
- target->GetMotionMaster()->MoveFall();
target->m_movementInfo.SetFallTime(0);
+ target->RemoveUnitMovementFlag(MOVEMENTFLAG_MASK_MOVING_FLY);
+ target->AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
}
- Player* player = target->ToPlayer();
- if (!player)
- player = target->m_movedPlayer;
-
- if (player)
- player->SendMovementCanFlyChange();
+ target->SetCanFly(apply);
- //! We still need to initiate a server-side MoveFall here,
- //! which requires MSG_MOVE_FALL_LAND on landing.
+ if (target->GetTypeId() == TYPEID_UNIT)
+ target->GetMotionMaster()->MoveFall();
}
void AuraEffect::HandleAuraWaterWalk(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -2683,12 +2677,7 @@ void AuraEffect::HandleAuraWaterWalk(AuraApplication const* aurApp, uint8 mode,
return;
}
- if (apply)
- target->AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
- else
- target->RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
-
- target->SendMovementWaterWalking();
+ target->SetWaterWalking(apply);
}
void AuraEffect::HandleAuraFeatherFall(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -2705,12 +2694,7 @@ void AuraEffect::HandleAuraFeatherFall(AuraApplication const* aurApp, uint8 mode
return;
}
- if (apply)
- target->AddUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
- else
- target->RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
-
- target->SendMovementFeatherFall();
+ target->SetFeatherFall(apply);
// start fall from current height
if (!apply && target->GetTypeId() == TYPEID_PLAYER)
@@ -2732,7 +2716,6 @@ void AuraEffect::HandleAuraHover(AuraApplication const* aurApp, uint8 mode, bool
}
target->SetHover(apply); //! Sets movementflags
- target->SendMovementHover();
}
void AuraEffect::HandleWaterBreathing(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
@@ -3054,6 +3037,8 @@ void AuraEffect::HandleAuraModIncreaseFlightSpeed(AuraApplication const* aurApp,
return;
Unit* target = aurApp->GetTarget();
+ if (mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK)
+ target->UpdateSpeed(MOVE_FLIGHT, true);
//! Update ability to fly
if (GetAuraType() == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED)
@@ -3061,22 +3046,17 @@ void AuraEffect::HandleAuraModIncreaseFlightSpeed(AuraApplication const* aurApp,
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if (mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK && (apply || (!target->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !target->HasAuraType(SPELL_AURA_FLY))))
{
- target->SetCanFly(apply);
if (!apply)
{
target->m_movementInfo.SetFallTime(0);
target->RemoveUnitMovementFlag(MOVEMENTFLAG_MASK_MOVING_FLY);
+ target->AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
}
- Player* player = target->ToPlayer();
- if (!player)
- player = target->m_movedPlayer;
-
- if (player)
- player->SendMovementCanFlyChange();
+ target->SetCanFly(apply);
- //! We still need to initiate a server-side MoveFall here,
- //! which requires MSG_MOVE_FALL_LAND on landing.
+ if (target->GetTypeId() == TYPEID_UNIT)
+ target->GetMotionMaster()->MoveFall();
}
//! Someone should clean up these hacks and remove it from this function. It doesn't even belong here.
@@ -3091,9 +3071,6 @@ void AuraEffect::HandleAuraModIncreaseFlightSpeed(AuraApplication const* aurApp,
target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 16314);
}
}
-
- if (mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK)
- target->UpdateSpeed(MOVE_FLIGHT, true);
}
void AuraEffect::HandleAuraModIncreaseSwimSpeed(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const