aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities
diff options
context:
space:
mode:
authorMachiavelli <machiavelli.trinity@gmail.com>2012-01-14 15:34:41 +0100
committerMachiavelli <machiavelli.trinity@gmail.com>2012-01-14 15:36:07 +0100
commitdbbac0bdaae4b6d8a0125999962c4a686092bd80 (patch)
tree8962da6db594ae27fc5ac5e6a930b6292a997ea6 /src/server/game/Entities
parent798677ca54553a9da688deef7b7c33ccbc17b801 (diff)
Core/Movement: Implement spline movement subsystem.
Spline movement controls movements of server-side controlled units (monster movement, taxi movement, etc). Proper implementation of effects such as charge, jump, cyclic movement will rely on it. However, need improve our states system before. Technical changes: * Added linear, catmullrom and bezier3 splines which based on client's algorthims. They can be reused for proper transport position interpolation. * Precission increased. There are no more position desync issues since client's position calculation formulas used. * Now possible to move by paths with multiple points, send whole path to client. -- Original author of research and implementation: SilverIce. Massive kudos. Original port for Trinity (ref #4629) Chaplain and Venugh With the following incremental fixes during my review: - Restore flightmaster end grid pre-loading - Fix uninitialized Creature::m_path_id - Add missing trinity_string entries for .movegens command - Fix a bug in WaypointMovementGenerator that would trigger unexpected pausing at waypoints for various amounts of time Known issues: - Errors like WaypointMovementGenerator::LoadPath creature XXX (Entry: YYYYY GUID: ZZZZZZ) doesn't have waypoint path id: 0. This is caused by bad DB data. This commit didn't "break" it. Do not forget to re-run CMake before compiling.
Diffstat (limited to 'src/server/game/Entities')
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.cpp72
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.h4
-rwxr-xr-xsrc/server/game/Entities/Creature/CreatureGroups.cpp4
-rwxr-xr-xsrc/server/game/Entities/GameObject/GameObject.cpp2
-rwxr-xr-xsrc/server/game/Entities/Object/Object.cpp139
-rwxr-xr-xsrc/server/game/Entities/Object/Object.h3
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp38
-rwxr-xr-xsrc/server/game/Entities/Player/Player.h1
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp252
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h126
10 files changed, 232 insertions, 409 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index ff627f78ea0..23865dd9e41 100755
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -48,6 +48,8 @@
#include "Vehicle.h"
#include "SpellAuraEffects.h"
#include "Group.h"
+#include "MoveSplineInit.h"
+#include "MoveSpline.h"
// apply implementation of the singletons
TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const
@@ -143,7 +145,7 @@ m_PlayerDamageReq(0), m_lootMoney(0), m_lootRecipient(0), m_lootRecipientGroup(0
m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_reactState(REACT_AGGRESSIVE),
m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_AlreadyCallAssistance(false),
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
-m_creatureInfo(NULL), m_creatureData(NULL), m_formation(NULL)
+m_creatureInfo(NULL), m_creatureData(NULL), m_formation(NULL), m_path_id(0)
{
m_regenTimer = CREATURE_REGEN_INTERVAL;
m_valuesCount = UNIT_END;
@@ -332,6 +334,7 @@ bool Creature::InitEntry(uint32 Entry, uint32 /*team*/, const CreatureData* data
SetSpeed(MOVE_FLIGHT, 1.0f); // using 1.0 rate
SetFloatValue(OBJECT_FIELD_SCALE_X, cinfo->scale);
+ SetLevitate(canFly());
// checked at loading
m_defaultMovementType = MovementGeneratorType(cinfo->MovementType);
@@ -435,6 +438,17 @@ void Creature::Update(uint32 diff)
m_vehicleKit->Reset();
}
+ if (IsInWater())
+ {
+ if (canSwim())
+ AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
+ }
+ else
+ {
+ if (canWalk())
+ RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
+ }
+
switch (m_deathState)
{
case JUST_ALIVED:
@@ -472,9 +486,7 @@ void Creature::Update(uint32 diff)
}
case CORPSE:
{
- m_Events.Update(diff);
- _UpdateSpells(diff);
-
+ Unit::Update(diff);
// deathstate changed on spells update, prevent problems
if (m_deathState != CORPSE)
break;
@@ -565,9 +577,6 @@ void Creature::Update(uint32 diff)
m_regenTimer = CREATURE_REGEN_INTERVAL;
break;
}
- case DEAD_FALLING:
- GetMotionMaster()->UpdateMotion(diff);
- break;
default:
break;
}
@@ -945,7 +954,8 @@ void Creature::AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint3
m_startMove = getMSTime();
m_moveTime = time;*/
- SendMonsterMove(x, y, z, time);
+ float speed = GetDistance(x, y, z) / ((float)time * 0.001f);
+ MonsterMoveWithSpeed(x, y, z, speed);
}
Player* Creature::GetLootRecipient() const
@@ -1507,8 +1517,8 @@ void Creature::setDeathState(DeathState s)
if (m_formation && m_formation->getLeader() == this)
m_formation->FormationReset(true);
- if ((canFly() || IsFlying()) && FallGround())
- return;
+ if ((canFly() || IsFlying()))
+ i_motionMaster.MoveFall();
Unit::setDeathState(CORPSE);
}
@@ -1520,7 +1530,7 @@ void Creature::setDeathState(DeathState s)
SetLootRecipient(NULL);
ResetPlayerDamageReq();
CreatureTemplate const* cinfo = GetCreatureInfo();
- AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ SetWalk(true);
if (GetCreatureInfo()->InhabitType & INHABIT_AIR)
AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_FLYING);
if (GetCreatureInfo()->InhabitType & INHABIT_WATER)
@@ -1536,24 +1546,6 @@ void Creature::setDeathState(DeathState s)
}
}
-bool Creature::FallGround()
-{
- // Let's abort after we called this function one time
- if (getDeathState() == DEAD_FALLING)
- return false;
-
- float x, y, z;
- GetPosition(x, y, z);
- // use larger distance for vmap height search than in most other cases
- float ground_Z = GetMap()->GetHeight(x, y, z, true, MAX_FALL_DISTANCE);
- if (fabs(ground_Z - z) < 0.1f)
- return false;
-
- GetMotionMaster()->MoveFall(ground_Z, EVENT_FALL_GROUND);
- Unit::setDeathState(DEAD_FALLING);
- return true;
-}
-
void Creature::Respawn(bool force)
{
DestroyForNearbyPlayers();
@@ -2415,3 +2407,25 @@ bool Creature::IsDungeonBoss() const
CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(GetEntry());
return cinfo && (cinfo->flags_extra & CREATURE_FLAG_EXTRA_DUNGEON_BOSS);
}
+
+void Creature::SetWalk(bool enable)
+{
+ if (enable)
+ AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ else
+ RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_WALK_MODE : SMSG_SPLINE_MOVE_SET_RUN_MODE, 9);
+ data.append(GetPackGUID());
+ SendMessageToSet(&data, true);
+}
+
+void Creature::SetLevitate(bool enable)
+{
+ if (enable)
+ AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ else
+ RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ WorldPacket data(enable ? SMSG_SPLINE_MOVE_GRAVITY_DISABLE : SMSG_SPLINE_MOVE_GRAVITY_ENABLE, 9);
+ data.append(GetPackGUID());
+ SendMessageToSet(&data, true);
+}
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index adad02653bf..05339f1da53 100755
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -520,6 +520,9 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
void AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type);
CreatureAI* AI() const { return (CreatureAI*)i_AI; }
+ void SetWalk(bool enable);
+ void SetLevitate(bool enable);
+
uint32 GetShieldBlockValue() const //dunno mob block value
{
return (getLevel()/2 + uint32(GetStat(STAT_STRENGTH)/20));
@@ -573,7 +576,6 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
const char* GetNameForLocaleIdx(LocaleConstant locale_idx) const;
void setDeathState(DeathState s); // override virtual Unit::setDeathState
- bool FallGround();
bool LoadFromDB(uint32 guid, Map* map) { return LoadCreatureFromDB(guid, map, false); }
bool LoadCreatureFromDB(uint32 guid, Map* map, bool addToMap = true);
diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp
index abf82dc5919..f440fd497fc 100755
--- a/src/server/game/Entities/Creature/CreatureGroups.cpp
+++ b/src/server/game/Entities/Creature/CreatureGroups.cpp
@@ -212,10 +212,12 @@ void CreatureGroup::FormationReset(bool dismiss)
void CreatureGroup::LeaderMoveTo(float x, float y, float z)
{
+ //! To do: This should probably get its own movement generator or use WaypointMovementGenerator.
+ //! If the leader's path is known, member's path can be plotted as well using formation offsets.
if (!m_leader)
return;
- float pathangle = atan2(m_leader->GetPositionY() - y, m_leader->GetPositionX() - x);
+ float pathangle = atan2(m_leader->GetPositionY() - y, m_leader->GetPositionX() - x);
for (CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 22f001d0224..fd094938da8 100755
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -1869,4 +1869,4 @@ void GameObject::SetLootState(LootState s)
{
m_lootState = s;
AI()->OnStateChanged(s);
-} \ No newline at end of file
+}
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 3cd02d05a90..5c034f1a42a 100755
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -45,6 +45,7 @@
#include "TemporarySummon.h"
#include "Totem.h"
#include "OutdoorPvPMgr.h"
+#include "MovementPacketBuilder.h"
uint32 GuidHigh2TypeId(uint32 guid_hi)
{
@@ -312,78 +313,17 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags) const
*data << ((Unit*)this)->GetSpeed(MOVE_WALK);
*data << ((Unit*)this)->GetSpeed(MOVE_RUN);
- *data << ((Unit*)this)->GetSpeed(MOVE_SWIM_BACK);
- *data << ((Unit*)this)->GetSpeed(MOVE_SWIM);
*data << ((Unit*)this)->GetSpeed(MOVE_RUN_BACK);
+ *data << ((Unit*)this)->GetSpeed(MOVE_SWIM);
+ *data << ((Unit*)this)->GetSpeed(MOVE_SWIM_BACK);
*data << ((Unit*)this)->GetSpeed(MOVE_FLIGHT);
*data << ((Unit*)this)->GetSpeed(MOVE_FLIGHT_BACK);
*data << ((Unit*)this)->GetSpeed(MOVE_TURN_RATE);
*data << ((Unit*)this)->GetSpeed(MOVE_PITCH_RATE);
- const Player* player = ToPlayer();
-
// 0x08000000
- if (player && player->isInFlight())
- {
- uint32 flags3 = SPLINEFLAG_GLIDE;
-
- *data << uint32(flags3); // splines flag?
-
- if (flags3 & 0x20000) // may be orientation
- {
- *data << (float)0;
- }
- else
- {
- if (flags3 & 0x8000) // probably x, y, z coords there
- {
- *data << (float)0;
- *data << (float)0;
- *data << (float)0;
- }
-
- if (flags3 & 0x10000) // probably guid there
- {
- *data << uint64(0);
- }
- }
-
- FlightPathMovementGenerator *fmg =
- (FlightPathMovementGenerator*)(player->GetMotionMaster()->top());
- TaxiPathNodeList const& path = fmg->GetPath();
-
- float x, y, z;
- player->GetPosition(x, y, z);
-
- uint32 inflighttime = uint32(path.GetPassedLength(fmg->GetCurrentNode(), x, y, z) * 32);
- uint32 traveltime = uint32(path.GetTotalLength() * 32);
-
- *data << uint32(inflighttime); // passed move time?
- *data << uint32(traveltime); // full move time?
- *data << uint32(0); // ticks count?
-
- *data << float(0); // added in 3.1
- *data << float(0); // added in 3.1
- *data << float(0); // added in 3.1
-
- *data << uint32(0); // added in 3.1
-
- uint32 poscount = uint32(path.size());
- *data << uint32(poscount); // points count
-
- for (uint32 i = 0; i < poscount; ++i)
- {
- *data << float(path[i].x);
- *data << float(path[i].y);
- *data << float(path[i].z);
- }
-
- *data << uint8(0); // added in 3.0.8
-
- *data << float(path[poscount-1].x);
- *data << float(path[poscount-1].y);
- *data << float(path[poscount-1].z);
- }
+ if (((Unit*)this)->m_movementInfo.GetMovementFlags() & MOVEMENTFLAG_SPLINE_ENABLED)
+ Movement::PacketBuilder::WriteCreate(*((Unit*)this)->movespline, *data);
}
else
{
@@ -487,7 +427,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags) const
// 0x200
if (flags & UPDATEFLAG_ROTATION)
{
- *data << uint64(((GameObject*)this)->GetRotation());
+ *data << int64(((GameObject*)this)->GetRotation());
}
}
@@ -1595,6 +1535,70 @@ void WorldObject::UpdateGroundPositionZ(float x, float y, float &z) const
z = new_z+ 0.05f; // just to be sure that we are not a few pixel under the surface
}
+void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
+{
+ switch (GetTypeId())
+ {
+ case TYPEID_UNIT:
+ {
+ // non fly unit don't must be in air
+ // non swim unit must be at ground (mostly speedup, because it don't must be in water and water level check less fast
+ if (!((Creature const*)this)->canFly())
+ {
+ bool canSwim = ((Creature const*)this)->canSwim();
+ float ground_z = z;
+ float max_z = canSwim
+ ? GetBaseMap()->GetWaterOrGroundLevel(x, y, z, &ground_z, !((Unit const*)this)->HasAuraType(SPELL_AURA_WATER_WALK))
+ : ((ground_z = GetBaseMap()->GetHeight(x, y, z, true)));
+ if (max_z > INVALID_HEIGHT)
+ {
+ if (z > max_z)
+ z = max_z;
+ else if (z < ground_z)
+ z = ground_z;
+ }
+ }
+ else
+ {
+ float ground_z = GetBaseMap()->GetHeight(x, y, z, true);
+ if (z < ground_z)
+ z = ground_z;
+ }
+ break;
+ }
+ case TYPEID_PLAYER:
+ {
+ // for server controlled moves playr work same as creature (but it can always swim)
+ if (!((Player const*)this)->canFly())
+ {
+ float ground_z = z;
+ float max_z = GetBaseMap()->GetWaterOrGroundLevel(x, y, z, &ground_z, !((Unit const*)this)->HasAuraType(SPELL_AURA_WATER_WALK));
+ if (max_z > INVALID_HEIGHT)
+ {
+ if (z > max_z)
+ z = max_z;
+ else if (z < ground_z)
+ z = ground_z;
+ }
+ }
+ else
+ {
+ float ground_z = GetBaseMap()->GetHeight(x, y, z, true);
+ if (z < ground_z)
+ z = ground_z;
+ }
+ break;
+ }
+ default:
+ {
+ float ground_z = GetBaseMap()->GetHeight(x, y, z, true);
+ if(ground_z > INVALID_HEIGHT)
+ z = ground_z;
+ break;
+ }
+ }
+}
+
bool Position::IsPositionValid() const
{
return Trinity::IsValidMapCoord(m_positionX, m_positionY, m_positionZ, m_orientation);
@@ -2033,7 +2037,8 @@ void Unit::BuildHeartBeatMsg(WorldPacket* data) const
void WorldObject::SendMessageToSet(WorldPacket* data, bool self)
{
- SendMessageToSetInRange(data, GetVisibilityRange(), self);
+ if (IsInWorld())
+ SendMessageToSetInRange(data, GetVisibilityRange(), self);
}
void WorldObject::SendMessageToSetInRange(WorldPacket* data, float dist, bool /*self*/)
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 3f78ec662e8..4cc298e4349 100755
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -497,7 +497,9 @@ struct MovementInfo
}
uint32 GetMovementFlags() { return flags; }
+ void SetMovementFlags(uint32 flag) { flags = flag; }
void AddMovementFlag(uint32 flag) { flags |= flag; }
+ void RemoveMovementFlag(uint32 flag) { flags &= ~flag; }
bool HasMovementFlag(uint32 flag) const { return flags & flag; }
uint16 GetExtraMovementFlags() { return flags2; }
@@ -615,6 +617,7 @@ class WorldObject : public Object, public WorldLocation
return (m_valuesCount > UNIT_FIELD_COMBATREACH) ? m_floatValues[UNIT_FIELD_COMBATREACH] : DEFAULT_WORLD_OBJECT_SIZE;
}
void UpdateGroundPositionZ(float x, float y, float &z) const;
+ void UpdateAllowedPositionZ(float x, float y, float &z) const;
void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const;
void GetRandomPoint(const Position &srcPos, float distance, Position &pos) const
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 7f7facfaff1..46f903ee71a 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -2101,6 +2101,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
// reset movement flags at teleport, because player will continue move with these flags after teleport
SetUnitMovementFlags(0);
+ DisableSpline();
if (m_transport)
{
@@ -5148,43 +5149,10 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
}
}
-/**
- * FallMode = 0 implies that the player is dying, or already dead, and the proper death state will be set.
- * = 1 simply causes the player to plummet towards the ground, and not suffer any damage.
- * = 2 causes the player to plummet towards the ground, and causes falling damage, regardless
- * of any auras that might of prevented fall damage.
- */
-bool Player::FallGround(uint8 FallMode)
-{
- // Let's abort after we called this function one time
- if (getDeathState() == DEAD_FALLING && FallMode == 0)
- return false;
-
- float x, y, z;
- GetPosition(x, y, z);
- float ground_Z = GetMap()->GetHeight(x, y, z);
- float z_diff = 0.0f;
- if ((z_diff = fabs(ground_Z - z)) < 0.1f)
- return false;
-
- GetMotionMaster()->MoveFall(ground_Z, EVENT_FALL_GROUND);
-
- // Below formula for falling damage is from Player::HandleFall
- if (FallMode == 2 && z_diff >= 14.57f)
- {
- uint32 damage = std::min(GetMaxHealth(), (uint32)((0.018f * z_diff - 0.2426f) * GetMaxHealth() * sWorld->getRate(RATE_DAMAGE_FALL)));
- if (damage)
- EnvironmentalDamage(DAMAGE_FALL, damage);
- }
- else if (FallMode == 0)
- Unit::setDeathState(DEAD_FALLING);
- return true;
-}
-
void Player::KillPlayer()
{
if (IsFlying() && !GetTransport())
- FallGround();
+ i_motionMaster.MoveFall();
SetMovement(MOVE_ROOT);
@@ -21474,8 +21442,6 @@ void Player::SendInitialVisiblePackets(Unit* target)
SendAurasForTarget(target);
if (target->isAlive())
{
- if (target->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE)
- target->SendMonsterMoveWithSpeedToCurrentDestination(this);
if (target->HasUnitState(UNIT_STAT_MELEE_ATTACKING) && target->getVictim())
target->SendMeleeAttackStart(target->getVictim());
}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 21c87a993dc..aa1d4e8185e 100755
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1964,7 +1964,6 @@ class Player : public Unit, public GridObject<Player>
Corpse* GetCorpse() const;
void SpawnCorpseBones();
void CreateCorpse();
- bool FallGround(uint8 FallMode = 0);
void KillPlayer();
uint32 GetResurrectionSpellId();
void ResurrectPlayer(float restore_percent, bool applySickness = false);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 2d6e8f1b724..63aa7771063 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -45,16 +45,16 @@
#include "InstanceSaveMgr.h"
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
-#include "Path.h"
#include "CreatureGroups.h"
#include "PetAI.h"
#include "PassiveAI.h"
-#include "Traveller.h"
#include "TemporarySummon.h"
#include "Vehicle.h"
#include "Transport.h"
#include "InstanceScript.h"
#include "SpellInfo.h"
+#include "MoveSplineInit.h"
+#include "MoveSpline.h"
#include <math.h>
@@ -62,9 +62,9 @@ float baseMoveSpeed[MAX_MOVE_TYPE] =
{
2.5f, // MOVE_WALK
7.0f, // MOVE_RUN
- 2.5f, // MOVE_RUN_BACK
+ 4.5f, // MOVE_RUN_BACK
4.722222f, // MOVE_SWIM
- 4.5f, // MOVE_SWIM_BACK
+ 2.5f, // MOVE_SWIM_BACK
3.141594f, // MOVE_TURN_RATE
7.0f, // MOVE_FLIGHT
4.5f, // MOVE_FLIGHT_BACK
@@ -73,9 +73,9 @@ float baseMoveSpeed[MAX_MOVE_TYPE] =
float playerBaseMoveSpeed[MAX_MOVE_TYPE] = {
2.5f, // MOVE_WALK
7.0f, // MOVE_RUN
- 2.5f, // MOVE_RUN_BACK
+ 4.5f, // MOVE_RUN_BACK
4.722222f, // MOVE_SWIM
- 4.5f, // MOVE_SWIM_BACK
+ 2.5f, // MOVE_SWIM_BACK
3.141594f, // MOVE_TURN_RATE
7.0f, // MOVE_FLIGHT
4.5f, // MOVE_FLIGHT_BACK
@@ -148,7 +148,7 @@ Unit::Unit(bool isWorldObject): WorldObject(isWorldObject),
m_movedPlayer(NULL), m_lastSanctuaryTime(0), IsAIEnabled(false), NeedChangeAI(false),
m_ControlledByPlayer(false), i_AI(NULL), i_disabledAI(NULL), m_procDeep(0),
m_removedAurasCount(0), i_motionMaster(this), m_ThreatManager(this), m_vehicle(NULL),
-m_vehicleKit(NULL), m_unitTypeMask(UNIT_MASK_NONE), m_HostileRefManager(this)
+m_vehicleKit(NULL), m_unitTypeMask(UNIT_MASK_NONE), m_HostileRefManager(this), movespline(new Movement::MoveSpline())
{
#ifdef _MSC_VER
#pragma warning(default:4355)
@@ -280,6 +280,7 @@ Unit::~Unit()
delete m_charmInfo;
delete m_vehicleKit;
+ delete movespline;
ASSERT(!m_duringRemoveFromWorld);
ASSERT(!m_attacking);
@@ -346,6 +347,7 @@ void Unit::Update(uint32 p_time)
ModifyAuraState(AURA_STATE_HEALTH_ABOVE_75_PERCENT, HealthAbovePct(75));
}
+ UpdateSplineMovement(p_time);
i_motionMaster.UpdateMotion(p_time);
}
@@ -357,151 +359,46 @@ bool Unit::haveOffhandWeapon() const
return m_canDualWield;
}
-void Unit::SendMonsterMoveWithSpeedToCurrentDestination(Player* player)
+void Unit::MonsterMoveWithSpeed(float x, float y, float z, float speed)
{
- float x, y, z;
- if (GetMotionMaster()->GetDestination(x, y, z))
- SendMonsterMoveWithSpeed(x, y, z, 0, player);
-}
-
-void Unit::SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime, Player* player)
-{
- if (!transitTime)
- {
- if (GetTypeId() == TYPEID_PLAYER)
- {
- Traveller<Player> traveller(*(Player*)this);
- transitTime = traveller.GetTotalTrevelTimeTo(x, y, z);
- }
- else
- {
- Traveller<Creature> traveller(*ToCreature());
- transitTime = traveller.GetTotalTrevelTimeTo(x, y, z);
- }
- }
- //float orientation = (float)atan2((double)dy, (double)dx);
- SendMonsterMove(x, y, z, transitTime, player);
+ Movement::MoveSplineInit init(*this);
+ init.MoveTo(x,y,z);
+ init.SetVelocity(speed);
+ init.Launch();
}
-void Unit::SetFacing(float ori, WorldObject* obj)
+void Unit::UpdateSplineMovement(uint32 t_diff)
{
- SetOrientation(obj ? GetAngle(obj) : ori);
-
- WorldPacket data(SMSG_MONSTER_MOVE, (1+12+4+1+(obj ? 8 : 4)+4+4+4+12+GetPackGUID().size()));
- data.append(GetPackGUID());
- data << uint8(0); // unk
- data << GetPositionX() << GetPositionY() << GetPositionZ();
- data << getMSTime();
- if (obj)
- {
- data << uint8(SPLINETYPE_FACING_TARGET);
- data << uint64(obj->GetGUID());
- }
- else
- {
- data << uint8(SPLINETYPE_FACING_ANGLE);
- data << ori;
- }
- data << uint32(SPLINEFLAG_NONE);
- data << uint32(0); // move time 0
- data << uint32(1); // one point
- data << GetPositionX() << GetPositionY() << GetPositionZ();
- SendMessageToSet(&data, true);
-}
-
-void Unit::SendMonsterStop(bool on_death)
-{
- WorldPacket data(SMSG_MONSTER_MOVE, (17 + GetPackGUID().size()));
- data.append(GetPackGUID());
- data << uint8(0); // new in 3.1
- data << GetPositionX() << GetPositionY() << GetPositionZ();
- data << getMSTime();
-
- if (on_death == true)
- {
- data << uint8(0);
- data << uint32((GetUnitMovementFlags() & MOVEMENTFLAG_LEVITATING) ? SPLINEFLAG_FLYING : SPLINEFLAG_WALKING);
- data << uint32(0); // Time in between points
- data << uint32(1); // 1 single waypoint
- data << GetPositionX() << GetPositionY() << GetPositionZ();
- }
- else
- data << uint8(1);
-
- SendMessageToSet(&data, true);
-
- ClearUnitState(UNIT_STAT_MOVE);
-}
-
-void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 Time, Player* player)
-{
- WorldPacket data(SMSG_MONSTER_MOVE, 1+12+4+1+4+4+4+12+GetPackGUID().size());
- data.append(GetPackGUID());
-
- data << uint8(0); // new in 3.1
- data << GetPositionX() << GetPositionY() << GetPositionZ();
- data << getMSTime();
-
- data << uint8(0);
- data << uint32((GetUnitMovementFlags() & MOVEMENTFLAG_LEVITATING) ? SPLINEFLAG_FLYING : SPLINEFLAG_WALKING);
- data << Time; // Time in between points
- data << uint32(1); // 1 single waypoint
- data << NewPosX << NewPosY << NewPosZ; // the single waypoint Point B
-
- if (player)
- player->GetSession()->SendPacket(&data);
- else
- SendMessageToSet(&data, true);
-
- AddUnitState(UNIT_STAT_MOVE);
-}
+ enum{
+ POSITION_UPDATE_DELAY = 400,
+ };
-void Unit::SendMonsterMove(MonsterMoveData const& moveData, Player* player)
-{
- WorldPacket data(SMSG_MONSTER_MOVE, GetPackGUID().size() + 1 + 12 + 4 + 1 + 4 + 8 + 4 + 4 + 12);
- data.append(GetPackGUID());
+ if (movespline->Finalized())
+ return;
- data << uint8(0); // new in 3.1
- data << GetPositionX() << GetPositionY() << GetPositionZ();
- data << getMSTime();
+ movespline->updateState(t_diff);
+ bool arrived = movespline->Finalized();
- data << uint8(0);
- data << moveData.SplineFlag;
+ if (arrived)
+ DisableSpline();
- if (moveData.SplineFlag & SPLINEFLAG_ANIMATIONTIER)
+ m_movesplineTimer.Update(t_diff);
+ if (m_movesplineTimer.Passed() || arrived)
{
- data << uint8(moveData.AnimationState);
- data << uint32(0);
- }
+ m_movesplineTimer.Reset(POSITION_UPDATE_DELAY);
+ Movement::Location loc = movespline->ComputePosition();
- data << moveData.Time;
-
- if (moveData.SplineFlag & SPLINEFLAG_TRAJECTORY)
- {
- data << moveData.SpeedZ;
- data << uint32(0); // walk time after jump
+ if (GetTypeId() == TYPEID_PLAYER)
+ ((Player*)this)->UpdatePosition(loc.x,loc.y,loc.z,loc.orientation);
+ else
+ GetMap()->CreatureRelocation((Creature*)this,loc.x,loc.y,loc.z,loc.orientation);
}
-
- data << uint32(1); // waypoint count
- data << moveData.DestLocation.GetPositionX();
- data << moveData.DestLocation.GetPositionY();
- data << moveData.DestLocation.GetPositionZ();
-
- if (player)
- player->GetSession()->SendPacket(&data);
- else
- SendMessageToSet(&data, true);
}
-void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 MoveFlags, uint32 time, float speedZ, Player* player)
+void Unit::DisableSpline()
{
- MonsterMoveData data;
- data.DestLocation.Relocate(NewPosX, NewPosY, NewPosZ);
- data.SplineFlag = MoveFlags;
- data.Time = time;
- data.SpeedZ = speedZ;
-
- SendMonsterMove(data, player);
+ m_movementInfo.RemoveMovementFlag(MovementFlags(MOVEMENTFLAG_SPLINE_ENABLED|MOVEMENTFLAG_FORWARD));
+ movespline->_Interrupt();
}
void Unit::SendMonsterMoveExitVehicle(Position const* newPos)
@@ -3106,17 +3003,6 @@ bool Unit::isInBackInMap(Unit const* target, float distance, float arc) const
return IsWithinDistInMap(target, distance) && !HasInArc(2 * M_PI - arc, target);
}
-void Unit::SetFacingToObject(WorldObject* pObject)
-{
- // update orientation at server
- SetOrientation(GetAngle(pObject));
-
- // and client
- WorldPacket data;
- BuildHeartBeatMsg(&data);
- SendMessageToSet(&data, false);
-}
-
bool Unit::isInAccessiblePlaceFor(Creature const* c) const
{
if (IsInWater())
@@ -12744,7 +12630,7 @@ void Unit::setDeathState(DeathState s)
ClearDiminishings();
GetMotionMaster()->Clear(false);
GetMotionMaster()->MoveIdle();
- SendMonsterStop(true);
+ StopMoving();
// without this when removing IncreaseMaxHealth aura player may stuck with 1 hp
// do not why since in IncreaseMaxHealth currenthealth is checked
SetHealth(0);
@@ -13565,7 +13451,7 @@ void Unit::SetHealth(uint32 val)
{
if (getDeathState() == JUST_DIED)
val = 0;
- else if (GetTypeId() == TYPEID_PLAYER && (getDeathState() == DEAD || getDeathState() == DEAD_FALLING))
+ else if (GetTypeId() == TYPEID_PLAYER && getDeathState() == DEAD)
val = 1;
else
{
@@ -14682,22 +14568,20 @@ void Unit::StopMoving()
{
ClearUnitState(UNIT_STAT_MOVING);
- // send explicit stop packet
- // rely on vmaps here because for example stormwind is in air
- //float z = sMapMgr->GetBaseMap(GetMapId())->GetHeight(GetPositionX(), GetPositionY(), GetPositionZ(), true);
- //if (fabs(GetPositionZ() - z) < 2.0f)
- // Relocate(GetPositionX(), GetPositionY(), z);
- //Relocate(GetPositionX(), GetPositionY(), GetPositionZ());
+ // not need send any packets if not in world
+ if (!IsInWorld())
+ return;
- if (!(GetUnitMovementFlags() & MOVEMENTFLAG_ONTRANSPORT))
- SendMonsterStop();
+ Movement::MoveSplineInit init(*this);
+ init.SetFacing(GetOrientation());
+ init.Launch();
}
void Unit::SendMovementFlagUpdate()
{
WorldPacket data;
BuildHeartBeatMsg(&data);
- SendMessageToSet(&data, false);
+ SendMessageToSet(&data, true);
}
bool Unit::IsSitState() const
@@ -17097,7 +16981,7 @@ void Unit::_ExitVehicle(Position const* exitPosition)
WorldPacket data2;
BuildHeartBeatMsg(&data2);
- SendMessageToSet(&data2, false);
+ SendMessageToSet(&data2, true);
if (vehicle->GetBase()->HasUnitTypeMask(UNIT_MASK_MINION))
if (((Minion*)vehicle->GetBase())->GetOwner() == this)
@@ -17116,25 +17000,6 @@ void Unit::_ExitVehicle(Position const* exitPosition)
void Unit::BuildMovementPacket(ByteBuffer *data) const
{
- switch (GetTypeId())
- {
- case TYPEID_UNIT:
- if (canFly())
- const_cast<Unit*>(this)->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
- break;
- case TYPEID_PLAYER:
- // remove unknown, unused etc flags for now
- const_cast<Unit*>(this)->RemoveUnitMovementFlag(MOVEMENTFLAG_SPLINE_ENABLED);
- if (isInFlight())
- {
- WPAssert(const_cast<Unit*>(this)->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE);
- const_cast<Unit*>(this)->AddUnitMovementFlag(MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_SPLINE_ENABLED);
- }
- break;
- default:
- break;
- }
-
*data << uint32(GetUnitMovementFlags()); // movement flags
*data << uint16(m_movementInfo.flags2); // 2.3.0
*data << uint32(getMSTime()); // time
@@ -17198,13 +17063,13 @@ void Unit::SetFlying(bool apply)
void Unit::NearTeleportTo(float x, float y, float z, float orientation, bool casting /*= false*/)
{
+ DisableSpline();
if (GetTypeId() == TYPEID_PLAYER)
ToPlayer()->TeleportTo(GetMapId(), x, y, z, orientation, TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (casting ? TELE_TO_SPELL : 0));
else
{
- // FIXME: this interrupts spell visual
- DestroyForNearbyPlayers();
UpdatePosition(x, y, z, orientation, true);
+ SendMovementFlagUpdate();
}
}
@@ -17486,3 +17351,26 @@ bool CharmInfo::IsReturning()
{
return m_isReturning;
}
+
+void Unit::SetInFront(Unit const* target)
+{
+ if (!HasUnitState(UNIT_STAT_CANNOT_TURN))
+ SetOrientation(GetAngle(target));
+}
+
+void Unit::SetFacingTo(float ori)
+{
+ Movement::MoveSplineInit init(*this);
+ init.SetFacing(ori);
+ init.Launch();
+}
+
+void Unit::SetFacingToObject(WorldObject* pObject)
+{
+ // never face when already moving
+ if (!IsStopped())
+ return;
+
+ // TODO: figure out under what conditions creature will move towards object instead of facing it where it currently is.
+ SetFacingTo(GetAngle(pObject));
+}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 5a6b34bc380..b64a2e210bc 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -465,7 +465,6 @@ enum DeathState
CORPSE = 2,
DEAD = 3,
JUST_ALIVED = 4,
- DEAD_FALLING= 5
};
enum UnitState
@@ -493,13 +492,22 @@ enum UnitState
UNIT_STAT_MOVE = 0x00100000,
UNIT_STAT_ROTATING = 0x00200000,
UNIT_STAT_EVADE = 0x00400000,
+ UNIT_STAT_ROAMING_MOVE = 0x00800000,
+ UNIT_STAT_CONFUSED_MOVE = 0x01000000,
+ UNIT_STAT_FLEEING_MOVE = 0x02000000,
+ UNIT_STAT_CHASE_MOVE = 0x04000000,
+ UNIT_STAT_FOLLOW_MOVE = 0x08000000,
UNIT_STAT_UNATTACKABLE = (UNIT_STAT_IN_FLIGHT | UNIT_STAT_ONVEHICLE),
- UNIT_STAT_MOVING = (UNIT_STAT_ROAMING | UNIT_STAT_CHASE),
+ //UNIT_STAT_MOVING = (UNIT_STAT_ROAMING | UNIT_STAT_CHASE),
+ // for real move using movegen check and stop (except unstoppable flight)
+ UNIT_STAT_MOVING = UNIT_STAT_ROAMING_MOVE | UNIT_STAT_CONFUSED_MOVE | UNIT_STAT_FLEEING_MOVE| UNIT_STAT_CHASE_MOVE | UNIT_STAT_FOLLOW_MOVE ,
UNIT_STAT_CONTROLLED = (UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING),
UNIT_STAT_LOST_CONTROL = (UNIT_STAT_CONTROLLED | UNIT_STAT_JUMPING | UNIT_STAT_CHARGING),
UNIT_STAT_SIGHTLESS = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_EVADE),
UNIT_STAT_CANNOT_AUTOATTACK = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_CASTING),
UNIT_STAT_CANNOT_TURN = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_ROTATING),
+ // stay by different reasons
+ UNIT_STAT_NOT_MOVE = UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED | UNIT_STAT_DISTRACTED,
UNIT_STAT_ALL_STATE = 0xffffffff //(UNIT_STAT_STOPPED | UNIT_STAT_MOVING | UNIT_STAT_IN_COMBAT | UNIT_STAT_IN_FLIGHT)
};
@@ -719,59 +727,18 @@ enum MovementFlags2
MOVEMENTFLAG2_UNK15 = 0x00004000,
MOVEMENTFLAG2_UNK16 = 0x00008000,
};
+
enum SplineFlags
{
- SPLINEFLAG_NONE = 0x00000000,
- SPLINEFLAG_FORWARD = 0x00000001,
- SPLINEFLAG_BACKWARD = 0x00000002,
- SPLINEFLAG_STRAFE_LEFT = 0x00000004,
- SPLINEFLAG_STRAFE_RIGHT = 0x00000008,
- SPLINEFLAG_LEFT = 0x00000010,
- SPLINEFLAG_RIGHT = 0x00000020,
- SPLINEFLAG_PITCH_UP = 0x00000040,
- SPLINEFLAG_PITCH_DOWN = 0x00000080,
- SPLINEFLAG_DONE = 0x00000100,
- SPLINEFLAG_FALLING = 0x00000200,
- SPLINEFLAG_NO_SPLINE = 0x00000400,
- SPLINEFLAG_TRAJECTORY = 0x00000800,
- SPLINEFLAG_WALKING = 0x00001000,
- SPLINEFLAG_FLYING = 0x00002000,
- SPLINEFLAG_KNOCKBACK = 0x00004000,
- SPLINEFLAG_FINAL_POINT = 0x00008000,
- SPLINEFLAG_FINAL_TARGET = 0x00010000,
- SPLINEFLAG_FINAL_FACING = 0x00020000,
- SPLINEFLAG_CATMULL_ROM = 0x00040000,
- SPLINEFLAG_UNKNOWN20 = 0x00080000,
- SPLINEFLAG_UNKNOWN21 = 0x00100000,
- SPLINEFLAG_ANIMATIONTIER = 0x00200000,
- SPLINEFLAG_UNKNOWN23 = 0x00400000,
- SPLINEFLAG_TRANSPORT = 0x00800000,
- SPLINEFLAG_EXIT_VEHICLE = 0x01000000,
- SPLINEFLAG_UNKNOWN26 = 0x02000000,
- SPLINEFLAG_UNKNOWN27 = 0x04000000,
- SPLINEFLAG_UNKNOWN28 = 0x08000000,
- SPLINEFLAG_UNKNOWN29 = 0x10000000,
- SPLINEFLAG_ANIMATION = 0x20000000,
- SPLINEFLAG_UNKNOWN31 = 0x40000000,
- SPLINEFLAG_UNKNOWN32 = 0x80000000,
-
- SPLINEFLAG_GLIDE = SPLINEFLAG_WALKING | SPLINEFLAG_FLYING,
-};
-
-enum SplineMode
-{
- SPLINEMODE_LINEAR = 0,
- SPLINEMODE_CATMULL_ROM = 1,
- SPLINEMODE_BEZIER3 = 2
+ SPLINEFLAG_WALKMODE = 0x00001000,
+ SPLINEFLAG_FLYING = 0x00002000,
+ SPLINEFLAG_TRANSPORT = 0x00800000,
+ SPLINEFLAG_EXIT_VEHICLE = 0x01000000,
};
enum SplineType
{
- SPLINETYPE_NORMAL = 0,
- SPLINETYPE_STOP = 1,
- SPLINETYPE_FACING_SPOT = 2,
- SPLINETYPE_FACING_TARGET = 3,
- SPLINETYPE_FACING_ANGLE = 4
+ SPLINETYPE_FACING_ANGLE = 4,
};
enum UnitTypeMask
@@ -789,6 +756,10 @@ enum UnitTypeMask
UNIT_MASK_ACCESSORY = 0x00000200,
};
+namespace Movement{
+ class MoveSpline;
+}
+
enum DiminishingLevels
{
DIMINISHING_LEVEL_1 = 0,
@@ -1628,20 +1599,18 @@ class Unit : public WorldObject
void JumpTo(float speedXY, float speedZ, bool forward = true);
void JumpTo(WorldObject* obj, float speedZ);
- void SetFacing(float ori, WorldObject* obj = NULL);
- void SendMonsterStop(bool on_death = false);
- void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 Time, Player* player = NULL);
- void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 MoveFlags, uint32 time, float speedZ, Player* player = NULL);
- void SendMonsterMove(MonsterMoveData const& moveData, Player* receiver = NULL);
+ void MonsterMoveWithSpeed(float x, float y, float z, float speed);
+ //void SetFacing(float ori, WorldObject* obj = NULL);
void SendMonsterMoveExitVehicle(Position const* newPos);
//void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL);
void SendMonsterMoveTransport(Unit* vehicleOwner);
- void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0, Player* player = NULL);
- void SendMonsterMoveWithSpeedToCurrentDestination(Player* player = NULL);
void SendMovementFlagUpdate();
+ bool IsLevitating() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_LEVITATING);}
+ bool IsWalking() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING);}
- template<typename PathElem, typename PathNode>
- void SendMonsterMoveByPath(Path<PathElem, PathNode> const& path, uint32 start, uint32 end);
+ void SetInFront(Unit const* target);
+ void SetFacingTo(float ori);
+ void SetFacingToObject(WorldObject* pObject);
void SendChangeCurrentVictimOpcode(HostileReference* pHostileReference);
void SendClearThreatListOpcode();
@@ -1951,13 +1920,7 @@ class Unit : public WorldObject
void SetBaseWeaponDamage(WeaponAttackType attType, WeaponDamageRange damageRange, float value) { m_weaponDamage[attType][damageRange] = value; }
bool isInFrontInMap(Unit const* target, float distance, float arc = M_PI) const;
- void SetInFront(Unit const* target)
- {
- if (!HasUnitState(UNIT_STAT_CANNOT_TURN))
- SetOrientation(GetAngle(target));
- }
bool isInBackInMap(Unit const* target, float distance, float arc = M_PI) const;
- void SetFacingToObject(WorldObject* pObject);
// Visibility system
bool IsVisible() const { return (m_serverSideVisibility.GetValue(SERVERSIDE_VISIBILITY_GM) > SEC_PLAYER) ? false : true; }
@@ -2232,6 +2195,9 @@ class Unit : public WorldObject
SetUInt64Value(UNIT_FIELD_TARGET, 0);
}
+ // Movement info
+ Movement::MoveSpline * movespline;
+
protected:
explicit Unit (bool isWorldObject);
@@ -2303,6 +2269,8 @@ class Unit : public WorldObject
bool IsAlwaysVisibleFor(WorldObject const* seer) const;
bool IsAlwaysDetectableFor(WorldObject const* seer) const;
+
+ void DisableSpline();
private:
bool IsTriggeredAtSpellProcEvent(Unit* pVictim, Aura* aura, SpellInfo const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const* & spellProcEvent);
bool HandleDummyAuraProc(Unit* pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
@@ -2316,6 +2284,8 @@ class Unit : public WorldObject
bool HandleAuraRaidProcFromChargeWithValue(AuraEffect* triggeredByAura);
bool HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura);
+ void UpdateSplineMovement(uint32 t_diff);
+
// player or player's pet
float GetCombatRatingReduction(CombatRating cr) const;
uint32 GetCombatRatingDamageReduction(CombatRating cr, float rate, float cap, uint32 damage) const;
@@ -2330,6 +2300,7 @@ class Unit : public WorldObject
uint32 m_state; // Even derived shouldn't modify
uint32 m_CombatTimer;
uint32 m_lastManaUse; // msecs
+ TimeTrackerSmall m_movesplineTimer;
Diminishing m_Diminishing;
// Manage all Units that are threatened by us
@@ -2382,31 +2353,4 @@ namespace Trinity
const bool m_ascending;
};
}
-
-template<typename Elem, typename Node>
-inline void Unit::SendMonsterMoveByPath(Path<Elem, Node> const& path, uint32 start, uint32 end)
-{
- uint32 traveltime = uint32(path.GetTotalLength(start, end) * 32);
- uint32 pathSize = end - start;
- WorldPacket data(SMSG_MONSTER_MOVE, (GetPackGUID().size()+1+4+4+4+4+1+4+4+4+pathSize*4*3));
- data.append(GetPackGUID());
- data << uint8(0);
- data << GetPositionX();
- data << GetPositionY();
- data << GetPositionZ();
- data << uint32(getMSTime());
- data << uint8(0);
- data << uint32(((GetUnitMovementFlags() & MOVEMENTFLAG_LEVITATING) || isInFlight()) ? (SPLINEFLAG_FLYING|SPLINEFLAG_WALKING) : SPLINEFLAG_WALKING);
- data << uint32(traveltime);
- data << uint32(pathSize);
-
- for (uint32 i = start; i < end; ++i)
- {
- data << float(path[i].x);
- data << float(path[i].y);
- data << float(path[i].z);
- }
-
- SendMessageToSet(&data, true);
-}
#endif