*Allow knockback creatures.

--HG--
branch : trunk
This commit is contained in:
megamage
2009-03-23 15:26:13 -06:00
parent 41a73f284b
commit ba957ed9f4
10 changed files with 99 additions and 39 deletions
+35 -1
View File
@@ -305,13 +305,47 @@ MotionMaster::MovePoint(uint32 id, float x, float y, float z)
} }
} }
void MotionMaster::MoveJumpFrom(float srcX, float srcY, float speedXY, float speedZ)
{
//this function may make players fall below map
if(i_owner->GetTypeId()==TYPEID_PLAYER)
return;
float x, y, z;
float dist = speedXY * speedZ * 0.1f;
i_owner->GetNearPoint(i_owner, x, y, z, i_owner->GetObjectSize(), dist, i_owner->GetAngle(srcX, srcY) + M_PI);
MoveJump(x, y, z, speedXY, speedZ);
}
void MotionMaster::MoveJump(float x, float y, float z, float speedXY, float speedZ)
{
uint32 moveFlag = MOVEFLAG_JUMP | MOVEFLAG_WALK;
uint32 time = speedZ * 100;
i_owner->SendMonsterMove(x, y, z, moveFlag, time, speedZ);
i_owner->addUnitState(UNIT_STAT_CHARGING | UNIT_STAT_JUMPING);
i_owner->m_TempSpeed = speedXY;
if(i_owner->GetTypeId()==TYPEID_PLAYER)
{
DEBUG_LOG("Player (GUID: %u) jump to point (X: %f Y: %f Z: %f)", i_owner->GetGUIDLow(), x, y, z );
Mutate(new PointMovementGenerator<Player>(0,x,y,z), MOTION_SLOT_CONTROLLED);
}
else
{
DEBUG_LOG("Creature (Entry: %u GUID: %u) jump to point (X: %f Y: %f Z: %f)",
i_owner->GetEntry(), i_owner->GetGUIDLow(), x, y, z );
Mutate(new PointMovementGenerator<Creature>(0,x,y,z), MOTION_SLOT_CONTROLLED);
}
}
void void
MotionMaster::MoveCharge(float x, float y, float z) MotionMaster::MoveCharge(float x, float y, float z, float speed)
{ {
if(Impl[MOTION_SLOT_CONTROLLED] && Impl[MOTION_SLOT_CONTROLLED]->GetMovementGeneratorType() != DISTRACT_MOTION_TYPE) if(Impl[MOTION_SLOT_CONTROLLED] && Impl[MOTION_SLOT_CONTROLLED]->GetMovementGeneratorType() != DISTRACT_MOTION_TYPE)
return; return;
i_owner->addUnitState(UNIT_STAT_CHARGING); i_owner->addUnitState(UNIT_STAT_CHARGING);
i_owner->m_TempSpeed = speed;
if(i_owner->GetTypeId()==TYPEID_PLAYER) if(i_owner->GetTypeId()==TYPEID_PLAYER)
{ {
DEBUG_LOG("Player (GUID: %u) charge point (X: %f Y: %f Z: %f)", i_owner->GetGUIDLow(), x, y, z ); DEBUG_LOG("Player (GUID: %u) charge point (X: %f Y: %f Z: %f)", i_owner->GetGUIDLow(), x, y, z );
+6 -1
View File
@@ -63,6 +63,9 @@ enum MMCleanFlag
MMCF_RESET = 2 // Flag if need top()->Reset() MMCF_RESET = 2 // Flag if need top()->Reset()
}; };
// assume it is 25 yard per 0.6 second
#define SPEED_CHARGE 42.0f
class TRINITY_DLL_SPEC MotionMaster //: private std::stack<MovementGenerator *> class TRINITY_DLL_SPEC MotionMaster //: private std::stack<MovementGenerator *>
{ {
private: private:
@@ -137,7 +140,9 @@ class TRINITY_DLL_SPEC MotionMaster //: private std::stack<MovementGenerator *>
void MoveConfused(); void MoveConfused();
void MoveFleeing(Unit* enemy); void MoveFleeing(Unit* enemy);
void MovePoint(uint32 id, float x,float y,float z); void MovePoint(uint32 id, float x,float y,float z);
void MoveCharge(float x, float y, float z); void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE);
void MoveJumpFrom(float srcX, float srcY, float speedXY, float speedZ);
void MoveJump(float x, float y, float z, float speedXY, float speedZ);
void MoveTaxiFlight(uint32 path, uint32 pathnode); void MoveTaxiFlight(uint32 path, uint32 pathnode);
void MoveDistract(uint32 time); void MoveDistract(uint32 time);
void MovePath(uint32 path_id, bool repeatable); void MovePath(uint32 path_id, bool repeatable);
+2 -2
View File
@@ -172,7 +172,7 @@ void WorldSession::HandleMoveWorldportAckOpcode()
void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
{ {
uint32 opcode = recv_data.GetOpcode(); uint32 opcode = recv_data.GetOpcode();
sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode); //sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode);
if(GetPlayer()->GetDontMove()) if(GetPlayer()->GetDontMove())
return; return;
@@ -285,7 +285,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
{ {
sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(recv_data.GetOpcode()), recv_data.GetOpcode(), recv_data.GetOpcode()); //sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(recv_data.GetOpcode()), recv_data.GetOpcode(), recv_data.GetOpcode());
CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4); CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4);
+19
View File
@@ -1278,6 +1278,25 @@ float WorldObject::GetAngle( const float x, const float y ) const
return ang; return ang;
} }
void WorldObject::GetSinCos(const float x, const float y, float &vsin, float &vcos)
{
float dx = GetPositionX() - x;
float dy = GetPositionY() - y;
if(dx < 0.001f && dy < 0.001f)
{
float angle = rand_norm()*2*M_PI;
vcos = cos(angle);
vsin = sin(angle);
}
else
{
float dist = sqrt((dx*dx) + (dy*dy));
vcos = dx / dist;
vsin = dy / dist;
}
}
bool WorldObject::HasInArc(const float arcangle, const WorldObject* obj) const bool WorldObject::HasInArc(const float arcangle, const WorldObject* obj) const
{ {
float arc = arcangle; float arc = arcangle;
+1
View File
@@ -461,6 +461,7 @@ class TRINITY_DLL_SPEC WorldObject : public Object
float GetAngle( const WorldObject* obj ) const; float GetAngle( const WorldObject* obj ) const;
float GetAngle( const float x, const float y ) const; float GetAngle( const float x, const float y ) const;
void GetSinCos(const float x, const float y, float &vsin, float &vcos);
bool HasInArc( const float arcangle, const WorldObject* obj ) const; bool HasInArc( const float arcangle, const WorldObject* obj ) const;
virtual void SendMessageToSet(WorldPacket *data, bool self, bool to_possessor = true); virtual void SendMessageToSet(WorldPacket *data, bool self, bool to_possessor = true);
+4 -3
View File
@@ -28,9 +28,10 @@
template<class T> template<class T>
void PointMovementGenerator<T>::Initialize(T &unit) void PointMovementGenerator<T>::Initialize(T &unit)
{ {
unit.StopMoving(); //unit.StopMoving();
unit.clearUnitState(UNIT_STAT_MOVING);
Traveller<T> traveller(unit); Traveller<T> traveller(unit);
i_destinationHolder.SetDestination(traveller,i_x,i_y,i_z); i_destinationHolder.SetDestination(traveller,i_x,i_y,i_z, !unit.hasUnitState(UNIT_STAT_JUMPING));
if (unit.GetTypeId() == TYPEID_UNIT && ((Creature*)&unit)->canFly()) if (unit.GetTypeId() == TYPEID_UNIT && ((Creature*)&unit)->canFly())
unit.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); unit.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
@@ -67,7 +68,7 @@ template<class T>
void PointMovementGenerator<T>:: Finalize(T &unit) void PointMovementGenerator<T>:: Finalize(T &unit)
{ {
if(unit.hasUnitState(UNIT_STAT_CHARGING)) if(unit.hasUnitState(UNIT_STAT_CHARGING))
unit.clearUnitState(UNIT_STAT_CHARGING); unit.clearUnitState(UNIT_STAT_CHARGING | UNIT_STAT_JUMPING);
else if(arrived) else if(arrived)
MovementInform(unit); MovementInform(unit);
} }
+10 -2
View File
@@ -5305,12 +5305,20 @@ void Aura::HandleAuraAllowFlight(bool apply, bool Real)
if(apply) if(apply)
{ {
data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12); data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12);
m_target->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02); if(m_target->GetTypeId() == TYPEID_UNIT)
{
m_target->SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02);
m_target->AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
}
} }
else else
{ {
data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12); data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12);
m_target->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02); if(m_target->GetTypeId() == TYPEID_UNIT)
{
m_target->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02);
m_target->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING2);
}
} }
data.append(m_target->GetPackGUID()); data.append(m_target->GetPackGUID());
data << uint32(0); // unk data << uint32(0); // unk
+11 -21
View File
@@ -5894,10 +5894,6 @@ void Spell::EffectKnockBack(uint32 i)
if(!unitTarget) if(!unitTarget)
return; return;
// Effect only works on players
if(unitTarget->GetTypeId()!=TYPEID_PLAYER)
return;
float x, y; float x, y;
if(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) if(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)
{ {
@@ -5907,26 +5903,20 @@ void Spell::EffectKnockBack(uint32 i)
else else
{ {
x = m_caster->GetPositionX(); x = m_caster->GetPositionX();
y = m_caster->GetPositionX(); y = m_caster->GetPositionY();
} }
float dx = unitTarget->GetPositionX() - x;
float dy = unitTarget->GetPositionY() - y;
float vcos, vsin;
if(dx < 0.001f && dy < 0.001f)
{
float angle = rand_norm()*2*M_PI;
vcos = cos(angle);
vsin = sin(angle);
}
else
{
float dist = sqrt((dx*dx) + (dy*dy));
vcos = dx / dist;
vsin = dy / dist;
}
float speedxy = float(m_spellInfo->EffectMiscValue[i])/10; float speedxy = float(m_spellInfo->EffectMiscValue[i])/10;
float speedz = float(damage/-10); float speedz = float(damage/-10);
if(unitTarget->GetTypeId() == TYPEID_UNIT)
{
unitTarget->GetMotionMaster()->MoveJumpFrom(x, y, speedxy, -speedz);
return;
}
float vcos, vsin;
unitTarget->GetSinCos(x, y, vsin, vcos);
WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8+4+4+4+4+4)); WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8+4+4+4+4+4));
data.append(unitTarget->GetPackGUID()); data.append(unitTarget->GetPackGUID());
+10 -7
View File
@@ -65,9 +65,7 @@ inline uint32 Traveller<T>::GetTotalTrevelTimeTo(float x, float y, float z)
{ {
float dist = GetMoveDestinationTo(x,y,z); float dist = GetMoveDestinationTo(x,y,z);
float speed = 0.001f; float speed = 0.001f;
if(GetTraveller().hasUnitState(UNIT_STAT_CHARGING)) if (Speed() <= 0.0f)
speed *= SPEED_CHARGE;
else if (Speed() <= 0.0f)
return 0xfffffffe; // almost infinity-unit should stop return 0xfffffffe; // almost infinity-unit should stop
else else
speed *= Speed(); // speed is in seconds so convert from second to millisecond speed *= Speed(); // speed is in seconds so convert from second to millisecond
@@ -78,7 +76,9 @@ inline uint32 Traveller<T>::GetTotalTrevelTimeTo(float x, float y, float z)
template<> template<>
inline float Traveller<Creature>::Speed() inline float Traveller<Creature>::Speed()
{ {
if(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE)) if(i_traveller.hasUnitState(UNIT_STAT_CHARGING))
return i_traveller.m_TempSpeed;
else if(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE))
return i_traveller.GetSpeed(MOVE_WALK); return i_traveller.GetSpeed(MOVE_WALK);
else if(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_FLYING2)) else if(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_FLYING2))
return i_traveller.GetSpeed(MOVE_FLIGHT); return i_traveller.GetSpeed(MOVE_FLIGHT);
@@ -99,7 +99,7 @@ inline float Traveller<Creature>::GetMoveDestinationTo(float x, float y, float z
float dy = y - GetPositionY(); float dy = y - GetPositionY();
float dz = z - GetPositionZ(); float dz = z - GetPositionZ();
if(i_traveller.hasUnitState(UNIT_STAT_IN_FLIGHT)) if(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_FLYING2))
return sqrt((dx*dx) + (dy*dy) + (dz*dz)); return sqrt((dx*dx) + (dy*dy) + (dz*dz));
else //Walking on the ground else //Walking on the ground
return sqrt((dx*dx) + (dy*dy)); return sqrt((dx*dx) + (dy*dy));
@@ -114,14 +114,17 @@ inline void Traveller<Creature>::MoveTo(float x, float y, float z, uint32 t)
CreatureGroupHolder.find(i_traveller.GetFormationID()) != CreatureGroupHolder.end()) CreatureGroupHolder.find(i_traveller.GetFormationID()) != CreatureGroupHolder.end())
CreatureGroupHolder[i_traveller.GetFormationID()]->LeaderMovedInEvade(); CreatureGroupHolder[i_traveller.GetFormationID()]->LeaderMovedInEvade();
i_traveller.AI_SendMoveToPacket(x, y, z, t, i_traveller.GetUnitMovementFlags(), 0); //i_traveller.AI_SendMoveToPacket(x, y, z, t, i_traveller.GetUnitMovementFlags(), 0);
i_traveller.SendMonsterMove(x, y, z, t);
} }
// specialization for players // specialization for players
template<> template<>
inline float Traveller<Player>::Speed() inline float Traveller<Player>::Speed()
{ {
if (i_traveller.isInFlight()) if(i_traveller.hasUnitState(UNIT_STAT_CHARGING))
return i_traveller.m_TempSpeed;
else if(i_traveller.isInFlight())
return PLAYER_FLIGHT_SPEED; return PLAYER_FLIGHT_SPEED;
else else
return i_traveller.GetSpeed(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE) ? MOVE_WALK : MOVE_RUN); return i_traveller.GetSpeed(i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE) ? MOVE_WALK : MOVE_RUN);
+1 -2
View File
@@ -443,8 +443,6 @@ enum UnitMoveType
#define MAX_MOVE_TYPE 9 #define MAX_MOVE_TYPE 9
extern float baseMoveSpeed[MAX_MOVE_TYPE]; extern float baseMoveSpeed[MAX_MOVE_TYPE];
// assume it is 25 yard per 0.6 second
#define SPEED_CHARGE 42.0f
enum WeaponAttackType enum WeaponAttackType
{ {
@@ -1497,6 +1495,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
float GetSpeed( UnitMoveType mtype ) const; float GetSpeed( UnitMoveType mtype ) const;
float GetSpeedRate( UnitMoveType mtype ) const { return m_speed_rate[mtype]; } float GetSpeedRate( UnitMoveType mtype ) const { return m_speed_rate[mtype]; }
void SetSpeed(UnitMoveType mtype, float rate, bool forced = false); void SetSpeed(UnitMoveType mtype, float rate, bool forced = false);
float m_TempSpeed;
void SetHover(bool on); void SetHover(bool on);
bool isHover() const { return HasAuraType(SPELL_AURA_HOVER); } bool isHover() const { return HasAuraType(SPELL_AURA_HOVER); }