mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 01:37:00 +00:00
Movement packets fix.
This commit is contained in:
parent
ad7729479c
commit
41d8f1a5d4
6 changed files with 277 additions and 241 deletions
|
|
@ -244,42 +244,42 @@ void Object::DestroyForPlayer( Player *target, bool anim ) const
|
|||
target->GetSession()->SendPacket( &data );
|
||||
}
|
||||
|
||||
void Object::BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2) const
|
||||
void Object::BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags, uint32 moveFlags) const
|
||||
{
|
||||
uint16 unk_flags = ((GetTypeId() == TYPEID_PLAYER) ? ((Player*)this)->m_movementInfo.unk1 : 0);
|
||||
uint16 moveFlags2 = ((GetTypeId() == TYPEID_PLAYER) ? ((Player*)this)->m_movementInfo.moveFlags2 : MOVEFLAG2_NONE);
|
||||
|
||||
if(GetTypeId() == TYPEID_UNIT)
|
||||
if(((Creature*)this)->isVehicle())
|
||||
unk_flags |= 0x20; // always allow pitch
|
||||
moveFlags2 |= MOVEFLAG2_ALLOW_PITCHING; // always allow pitch
|
||||
|
||||
*data << (uint16)flags; // update flags
|
||||
*data << uint16(updateFlags); // update flags
|
||||
|
||||
// 0x20
|
||||
if (flags & UPDATEFLAG_LIVING)
|
||||
if (updateFlags & UPDATEFLAG_LIVING)
|
||||
{
|
||||
switch(GetTypeId())
|
||||
{
|
||||
case TYPEID_UNIT:
|
||||
{
|
||||
flags2 = MOVEMENTFLAG_NONE;
|
||||
moveFlags = MOVEMENTFLAG_NONE;
|
||||
|
||||
// disabled, makes them run-in-same-place before movement generator updated once.
|
||||
/*if (((Creature*)this)->hasUnitState(UNIT_STAT_MOVING))
|
||||
flags2 |= MOVEMENTFLAG_FORWARD;*/ // not set if not really moving
|
||||
moveFlags |= MOVEMENTFLAG_FORWARD;*/ // not set if not really moving
|
||||
|
||||
if (((Creature*)this)->canFly())
|
||||
{
|
||||
flags2 |= MOVEMENTFLAG_LEVITATING; // (ok) most seem to have this
|
||||
moveFlags |= MOVEMENTFLAG_LEVITATING; // (ok) most seem to have this
|
||||
|
||||
if (!((Creature*)this)->hasUnitState(UNIT_STAT_MOVING))
|
||||
flags2 |= MOVEMENTFLAG_FLY_UNK1; // (ok) possibly some "hover" mode
|
||||
moveFlags |= MOVEMENTFLAG_FLY_UNK1; // (ok) possibly some "hover" mode
|
||||
else
|
||||
{
|
||||
if (((Creature*)this)->IsMounted())
|
||||
flags2 |= MOVEMENTFLAG_FLYING; // seems to be often when mounted
|
||||
moveFlags |= MOVEMENTFLAG_FLYING;// seems to be often when mounted
|
||||
/* for further research
|
||||
else
|
||||
flags2 |= MOVEMENTFLAG_FLYING2; // not seen, but work on some, even if not "correct"
|
||||
moveFlags |= MOVEMENTFLAG_FLYING2;// not seen, but work on some, even if not "correct"
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
@ -287,47 +287,49 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2)
|
|||
break;
|
||||
case TYPEID_PLAYER:
|
||||
{
|
||||
flags2 = ((Player*)this)->m_movementInfo.GetMovementFlags();
|
||||
moveFlags = ((Player*)this)->m_movementInfo.GetMovementFlags();
|
||||
|
||||
if(((Player*)this)->GetTransport())
|
||||
flags2 |= MOVEMENTFLAG_ONTRANSPORT;
|
||||
moveFlags |= MOVEMENTFLAG_ONTRANSPORT;
|
||||
else
|
||||
flags2 &= ~MOVEMENTFLAG_ONTRANSPORT;
|
||||
moveFlags &= ~MOVEMENTFLAG_ONTRANSPORT;
|
||||
|
||||
// remove unknown, unused etc flags for now
|
||||
flags2 &= ~MOVEMENTFLAG_SPLINE2; // will be set manually
|
||||
moveFlags &= ~MOVEMENTFLAG_SPLINE2; // will be set manually
|
||||
|
||||
if(((Player*)this)->isInFlight())
|
||||
{
|
||||
ASSERT(((Player*)this)->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE);
|
||||
flags2 = (MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_SPLINE2);
|
||||
moveFlags = (MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_SPLINE2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
*data << uint32(flags2); // movement flags
|
||||
*data << uint16(unk_flags); // unknown 2.3.0
|
||||
*data << uint32(moveFlags); // movement flags
|
||||
*data << uint16(moveFlags2); // moveFlags2
|
||||
*data << uint32(getMSTime()); // time (in milliseconds)
|
||||
|
||||
// position
|
||||
*data << ((WorldObject*)this)->GetPositionX();
|
||||
*data << ((WorldObject*)this)->GetPositionY();
|
||||
*data << ((WorldObject*)this)->GetPositionZ();
|
||||
*data << ((WorldObject*)this)->GetOrientation();
|
||||
*data << float(((WorldObject*)this)->GetPositionX());
|
||||
*data << float(((WorldObject*)this)->GetPositionY());
|
||||
*data << float(((WorldObject*)this)->GetPositionZ());
|
||||
*data << float(((WorldObject*)this)->GetOrientation());
|
||||
|
||||
// 0x00000200
|
||||
if(flags2 & MOVEMENTFLAG_ONTRANSPORT)
|
||||
if(moveFlags & MOVEMENTFLAG_ONTRANSPORT)
|
||||
{
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
data->append(((Player*)this)->GetTransport()->GetPackGUID());
|
||||
*data << (float)((Player*)this)->GetTransOffsetX();
|
||||
*data << (float)((Player*)this)->GetTransOffsetY();
|
||||
*data << (float)((Player*)this)->GetTransOffsetZ();
|
||||
*data << (float)((Player*)this)->GetTransOffsetO();
|
||||
*data << (uint32)((Player*)this)->GetTransTime();
|
||||
*data << (int8)((Player*)this)->GetTransSeat();
|
||||
*data << float(((Player*)this)->GetTransOffsetX());
|
||||
*data << float(((Player*)this)->GetTransOffsetY());
|
||||
*data << float(((Player*)this)->GetTransOffsetZ());
|
||||
*data << float(((Player*)this)->GetTransOffsetO());
|
||||
*data << uint32(((Player*)this)->GetTransTime());
|
||||
*data << int8(((Player*)this)->GetTransSeat());
|
||||
if(moveFlags2 & MOVEFLAG2_UNK1)
|
||||
*data << uint32(0); // unkTime, added in 3.3.0
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -336,63 +338,65 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2)
|
|||
*data << float(0) << float(0) << float(0) << float(0);
|
||||
*data << uint32(0);
|
||||
*data << uint8(-1);
|
||||
if(moveFlags2 & MOVEFLAG2_UNK1)
|
||||
*data << uint32(0); // unkTime, added in 3.3.0
|
||||
}
|
||||
}
|
||||
|
||||
// 0x02200000
|
||||
if((flags2 & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (unk_flags & 0x20))
|
||||
if((moveFlags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (moveFlags2 & MOVEFLAG2_ALLOW_PITCHING))
|
||||
{
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
*data << (float)((Player*)this)->m_movementInfo.s_pitch;
|
||||
*data << float(((Player*)this)->m_movementInfo.s_pitch);
|
||||
else
|
||||
*data << (float)0; // is't part of movement packet, we must store and send it...
|
||||
*data << float(0); // is't part of movement packet, we must store and send it...
|
||||
}
|
||||
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
*data << (uint32)((Player*)this)->m_movementInfo.fallTime;
|
||||
*data << uint32(((Player*)this)->m_movementInfo.fallTime);
|
||||
else
|
||||
*data << (uint32)0; // last fall time
|
||||
*data << uint32(0); // last fall time
|
||||
|
||||
// 0x00001000
|
||||
if(flags2 & MOVEMENTFLAG_JUMPING)
|
||||
if(moveFlags & MOVEMENTFLAG_JUMPING)
|
||||
{
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
*data << (float)((Player*)this)->m_movementInfo.j_unk;
|
||||
*data << (float)((Player*)this)->m_movementInfo.j_sinAngle;
|
||||
*data << (float)((Player*)this)->m_movementInfo.j_cosAngle;
|
||||
*data << (float)((Player*)this)->m_movementInfo.j_xyspeed;
|
||||
*data << float(((Player*)this)->m_movementInfo.j_velocity);
|
||||
*data << float(((Player*)this)->m_movementInfo.j_sinAngle);
|
||||
*data << float(((Player*)this)->m_movementInfo.j_cosAngle);
|
||||
*data << float(((Player*)this)->m_movementInfo.j_xyspeed);
|
||||
}
|
||||
else
|
||||
{
|
||||
*data << (float)0;
|
||||
*data << (float)0;
|
||||
*data << (float)0;
|
||||
*data << (float)0;
|
||||
*data << float(0);
|
||||
*data << float(0);
|
||||
*data << float(0);
|
||||
*data << float(0);
|
||||
}
|
||||
}
|
||||
|
||||
// 0x04000000
|
||||
if(flags2 & MOVEMENTFLAG_SPLINE)
|
||||
if(moveFlags & MOVEMENTFLAG_SPLINE)
|
||||
{
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
*data << (float)((Player*)this)->m_movementInfo.u_unk1;
|
||||
*data << float(((Player*)this)->m_movementInfo.u_unk1);
|
||||
else
|
||||
*data << (float)0;
|
||||
*data << float(0);
|
||||
}
|
||||
|
||||
*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_FLIGHT );
|
||||
*data << ((Unit*)this)->GetSpeed( MOVE_FLIGHT_BACK );
|
||||
*data << ((Unit*)this)->GetSpeed( MOVE_TURN_RATE );
|
||||
*data << ((Unit*)this)->GetSpeed( MOVE_PITCH_RATE );
|
||||
*data << float(((Unit*)this)->GetSpeed(MOVE_WALK));
|
||||
*data << float(((Unit*)this)->GetSpeed(MOVE_RUN));
|
||||
*data << float(((Unit*)this)->GetSpeed(MOVE_SWIM_BACK));
|
||||
*data << float(((Unit*)this)->GetSpeed(MOVE_SWIM));
|
||||
*data << float(((Unit*)this)->GetSpeed(MOVE_RUN_BACK));
|
||||
*data << float(((Unit*)this)->GetSpeed(MOVE_FLIGHT));
|
||||
*data << float(((Unit*)this)->GetSpeed(MOVE_FLIGHT_BACK));
|
||||
*data << float(((Unit*)this)->GetSpeed(MOVE_TURN_RATE));
|
||||
*data << float(((Unit*)this)->GetSpeed(MOVE_PITCH_RATE));
|
||||
|
||||
// 0x08000000
|
||||
if(flags2 & MOVEMENTFLAG_SPLINE2)
|
||||
if(moveFlags & MOVEMENTFLAG_SPLINE2)
|
||||
{
|
||||
if(GetTypeId() != TYPEID_PLAYER)
|
||||
{
|
||||
|
|
@ -414,23 +418,25 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2)
|
|||
|
||||
*data << uint32(flags3); // splines flag?
|
||||
|
||||
if(flags3 & 0x20000) // may be orientation
|
||||
if(flags3 & SPLINE_MOVE_FLAG_FACING) // may be orientation
|
||||
{
|
||||
*data << (float)0;
|
||||
*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
|
||||
if(flags3 & SPLINE_MOVE_FLAG_GUID) // probably guid there
|
||||
{
|
||||
*data << uint64(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(flags3 & SPLINE_MOVE_FLAG_POINT) // probably x,y,z coords there
|
||||
{
|
||||
*data << float(0);
|
||||
*data << float(0);
|
||||
*data << float(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Path &path = fmg->GetPath();
|
||||
|
|
@ -443,7 +449,7 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2)
|
|||
|
||||
*data << uint32(inflighttime); // passed move time?
|
||||
*data << uint32(traveltime); // full move time?
|
||||
*data << uint32(0); // ticks count?
|
||||
*data << uint32(0); // sequenceId
|
||||
|
||||
*data << float(0); // added in 3.1
|
||||
*data << float(0); // added in 3.1
|
||||
|
|
@ -456,30 +462,30 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2)
|
|||
|
||||
for(uint32 i = 0; i < poscount; ++i)
|
||||
{
|
||||
*data << path.GetNodes()[i].x;
|
||||
*data << path.GetNodes()[i].y;
|
||||
*data << path.GetNodes()[i].z;
|
||||
*data << float(path.GetNodes()[i].x);
|
||||
*data << float(path.GetNodes()[i].y);
|
||||
*data << float(path.GetNodes()[i].z);
|
||||
}
|
||||
|
||||
*data << uint8(0); // added in 3.0.8
|
||||
*data << uint8(0); // splineMode
|
||||
|
||||
*data << path.GetNodes()[poscount-1].x;
|
||||
*data << path.GetNodes()[poscount-1].y;
|
||||
*data << path.GetNodes()[poscount-1].z;
|
||||
*data << float(path.GetNodes()[poscount-1].x);
|
||||
*data << float(path.GetNodes()[poscount-1].y);
|
||||
*data << float(path.GetNodes()[poscount-1].z);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(flags & UPDATEFLAG_POSITION)
|
||||
if(updateFlags & UPDATEFLAG_POSITION)
|
||||
{
|
||||
*data << uint8(0); // unk PGUID!
|
||||
*data << ((WorldObject*)this)->GetPositionX();
|
||||
*data << ((WorldObject*)this)->GetPositionY();
|
||||
*data << ((WorldObject*)this)->GetPositionZ();
|
||||
*data << ((WorldObject*)this)->GetPositionX();
|
||||
*data << ((WorldObject*)this)->GetPositionY();
|
||||
*data << ((WorldObject*)this)->GetPositionZ();
|
||||
*data << ((WorldObject*)this)->GetOrientation();
|
||||
*data << float(((WorldObject*)this)->GetPositionX());
|
||||
*data << float(((WorldObject*)this)->GetPositionY());
|
||||
*data << float(((WorldObject*)this)->GetPositionZ());
|
||||
*data << float(((WorldObject*)this)->GetPositionX());
|
||||
*data << float(((WorldObject*)this)->GetPositionY());
|
||||
*data << float(((WorldObject*)this)->GetPositionZ());
|
||||
*data << float(((WorldObject*)this)->GetOrientation());
|
||||
|
||||
if(GetTypeId() == TYPEID_CORPSE)
|
||||
*data << float(((WorldObject*)this)->GetOrientation());
|
||||
|
|
@ -489,29 +495,29 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2)
|
|||
else
|
||||
{
|
||||
// 0x40
|
||||
if (flags & UPDATEFLAG_HAS_POSITION)
|
||||
if (updateFlags & UPDATEFLAG_HAS_POSITION)
|
||||
{
|
||||
// 0x02
|
||||
if(flags & UPDATEFLAG_TRANSPORT && ((GameObject*)this)->GetGoType() == GAMEOBJECT_TYPE_MO_TRANSPORT)
|
||||
if(updateFlags & UPDATEFLAG_TRANSPORT && ((GameObject*)this)->GetGoType() == GAMEOBJECT_TYPE_MO_TRANSPORT)
|
||||
{
|
||||
*data << (float)0;
|
||||
*data << (float)0;
|
||||
*data << (float)0;
|
||||
*data << ((WorldObject *)this)->GetOrientation();
|
||||
*data << float(0);
|
||||
*data << float(0);
|
||||
*data << float(0);
|
||||
*data << float(((WorldObject *)this)->GetOrientation());
|
||||
}
|
||||
else
|
||||
{
|
||||
*data << ((WorldObject *)this)->GetPositionX();
|
||||
*data << ((WorldObject *)this)->GetPositionY();
|
||||
*data << ((WorldObject *)this)->GetPositionZ();
|
||||
*data << ((WorldObject *)this)->GetOrientation();
|
||||
*data << float(((WorldObject *)this)->GetPositionX());
|
||||
*data << float(((WorldObject *)this)->GetPositionY());
|
||||
*data << float(((WorldObject *)this)->GetPositionZ());
|
||||
*data << float(((WorldObject *)this)->GetOrientation());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 0x8
|
||||
if(flags & UPDATEFLAG_LOWGUID)
|
||||
if(updateFlags & UPDATEFLAG_LOWGUID)
|
||||
{
|
||||
switch(GetTypeId())
|
||||
{
|
||||
|
|
@ -527,7 +533,7 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2)
|
|||
*data << uint32(0x0000000B); // unk, can be 0xB or 0xC
|
||||
break;
|
||||
case TYPEID_PLAYER:
|
||||
if(flags & UPDATEFLAG_SELF)
|
||||
if(updateFlags & UPDATEFLAG_SELF)
|
||||
*data << uint32(0x0000002F); // unk, can be 0x15 or 0x22
|
||||
else
|
||||
*data << uint32(0x00000008); // unk, can be 0x7 or 0x8
|
||||
|
|
@ -539,7 +545,7 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2)
|
|||
}
|
||||
|
||||
// 0x10
|
||||
if(flags & UPDATEFLAG_HIGHGUID)
|
||||
if(updateFlags & UPDATEFLAG_HIGHGUID)
|
||||
{
|
||||
switch(GetTypeId())
|
||||
{
|
||||
|
|
@ -555,7 +561,7 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2)
|
|||
*data << uint32(0x0000000B); // unk, can be 0xB or 0xC
|
||||
break;
|
||||
case TYPEID_PLAYER:
|
||||
if(flags & UPDATEFLAG_SELF)
|
||||
if(updateFlags & UPDATEFLAG_SELF)
|
||||
*data << uint32(0x0000002F); // unk, can be 0x15 or 0x22
|
||||
else
|
||||
*data << uint32(0x00000008); // unk, can be 0x7 or 0x8
|
||||
|
|
@ -567,7 +573,7 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2)
|
|||
}
|
||||
|
||||
// 0x4
|
||||
if(flags & UPDATEFLAG_HAS_ATTACKING_TARGET) // packed guid (current target guid)
|
||||
if(updateFlags & UPDATEFLAG_HAS_ATTACKING_TARGET) // packed guid (current target guid)
|
||||
{
|
||||
if (((Unit*)this)->getVictim())
|
||||
data->append(((Unit*)this)->getVictim()->GetPackGUID());
|
||||
|
|
@ -576,20 +582,20 @@ void Object::BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2)
|
|||
}
|
||||
|
||||
// 0x2
|
||||
if(flags & UPDATEFLAG_TRANSPORT)
|
||||
if(updateFlags & UPDATEFLAG_TRANSPORT)
|
||||
{
|
||||
*data << uint32(getMSTime()); // ms time
|
||||
}
|
||||
|
||||
// 0x80
|
||||
if(flags & UPDATEFLAG_VEHICLE) // unused for now
|
||||
if(updateFlags & UPDATEFLAG_VEHICLE) // unused for now
|
||||
{
|
||||
*data << uint32(((Vehicle*)this)->GetVehicleId()); // vehicle id
|
||||
*data << float(0); // facing adjustment
|
||||
}
|
||||
|
||||
// 0x200
|
||||
if(flags & UPDATEFLAG_ROTATION)
|
||||
if(updateFlags & UPDATEFLAG_ROTATION)
|
||||
{
|
||||
*data << uint64(((GameObject*)this)->GetRotation());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -312,7 +312,7 @@ class MANGOS_DLL_SPEC Object
|
|||
|
||||
virtual void _SetCreateBits(UpdateMask *updateMask, Player *target) const;
|
||||
|
||||
void BuildMovementUpdate(ByteBuffer * data, uint16 flags, uint32 flags2 ) const;
|
||||
void BuildMovementUpdate(ByteBuffer * data, uint16 updateFlags, uint32 moveFlags ) const;
|
||||
void BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask *updateMask, Player *target ) const;
|
||||
void BuildUpdateDataForPlayer(Player* pl, UpdateDataMapType& update_players);
|
||||
|
||||
|
|
|
|||
|
|
@ -429,6 +429,7 @@ enum DrunkenState
|
|||
|
||||
enum PlayerFlags
|
||||
{
|
||||
PLAYER_FLAGS_NONE = 0x00000000,
|
||||
PLAYER_FLAGS_GROUP_LEADER = 0x00000001,
|
||||
PLAYER_FLAGS_AFK = 0x00000002,
|
||||
PLAYER_FLAGS_DND = 0x00000004,
|
||||
|
|
@ -815,7 +816,7 @@ struct MovementInfo
|
|||
// common
|
||||
uint64 guid;
|
||||
uint32 flags; // see enum MovementFlags
|
||||
uint16 unk1;
|
||||
uint16 moveFlags2;
|
||||
uint32 time;
|
||||
float x, y, z, o;
|
||||
// transport
|
||||
|
|
@ -823,21 +824,22 @@ struct MovementInfo
|
|||
float t_x, t_y, t_z, t_o;
|
||||
uint32 t_time;
|
||||
int8 t_seat;
|
||||
uint32 t_time2;
|
||||
// swimming and unknown
|
||||
float s_pitch;
|
||||
// last fall time
|
||||
uint32 fallTime;
|
||||
// jumping
|
||||
float j_unk, j_sinAngle, j_cosAngle, j_xyspeed;
|
||||
float j_velocity, j_sinAngle, j_cosAngle, j_xyspeed;
|
||||
// spline
|
||||
float u_unk1;
|
||||
|
||||
MovementInfo()
|
||||
{
|
||||
flags = MOVEMENTFLAG_NONE;
|
||||
time = t_time = fallTime = 0;
|
||||
unk1 = 0;
|
||||
x = y = z = o = t_x = t_y = t_z = t_o = s_pitch = j_unk = j_sinAngle = j_cosAngle = j_xyspeed = u_unk1 = 0.0f;
|
||||
time = t_time = t_time2 = fallTime = 0;
|
||||
moveFlags2 = 0;
|
||||
x = y = z = o = t_x = t_y = t_z = t_o = s_pitch = j_velocity = j_sinAngle = j_cosAngle = j_xyspeed = u_unk1 = 0.0f;
|
||||
t_guid = 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,8 @@ typedef std::priority_queue<PrioritizeHealthUnitWraper, std::vector<PrioritizeHe
|
|||
bool IsQuestTameSpell(uint32 spellId)
|
||||
{
|
||||
SpellEntry const *spellproto = sSpellStore.LookupEntry(spellId);
|
||||
if (!spellproto) return false;
|
||||
if (!spellproto)
|
||||
return false;
|
||||
|
||||
return spellproto->Effect[0] == SPELL_EFFECT_THREAT
|
||||
&& spellproto->Effect[1] == SPELL_EFFECT_APPLY_AURA && spellproto->EffectApplyAuraName[1] == SPELL_AURA_DUMMY;
|
||||
|
|
@ -119,7 +120,7 @@ SpellCastTargets::SpellCastTargets()
|
|||
m_itemTargetGUID = 0;
|
||||
m_itemTargetEntry = 0;
|
||||
|
||||
m_srcX = m_srcY = m_srcZ = m_destX = m_destY = m_destZ = 0;
|
||||
m_srcX = m_srcY = m_srcZ = m_destX = m_destY = m_destZ = 0.0f;
|
||||
m_strTarget = "";
|
||||
m_targetMask = 0;
|
||||
}
|
||||
|
|
@ -380,7 +381,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
|
|||
if(m_originalCaster && !m_originalCaster->IsInWorld()) m_originalCaster = NULL;
|
||||
}
|
||||
|
||||
for(int i=0; i <3; ++i)
|
||||
for(int i = 0; i < 3; ++i)
|
||||
m_currentBasePoints[i] = m_spellInfo->EffectBasePoints[i];
|
||||
|
||||
m_spellState = SPELL_STATE_NULL;
|
||||
|
|
@ -406,7 +407,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
|
|||
m_runesState = 0;
|
||||
m_powerCost = 0; // setup to correct value in Spell::prepare, don't must be used before.
|
||||
m_casttime = 0; // setup to correct value in Spell::prepare, don't must be used before.
|
||||
m_timer = 0; // will set to castime in prepare
|
||||
m_timer = 0; // will set to cast time in prepare
|
||||
|
||||
m_needAliveTargetMask = 0;
|
||||
|
||||
|
|
@ -415,7 +416,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
|
|||
|
||||
if(m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC && !(m_spellInfo->AttributesEx2 & SPELL_ATTR_EX2_CANT_REFLECTED))
|
||||
{
|
||||
for(int j = 0;j < 3; ++j)
|
||||
for(int j = 0; j < 3; ++j)
|
||||
{
|
||||
if (m_spellInfo->Effect[j] == 0)
|
||||
continue;
|
||||
|
|
@ -553,7 +554,7 @@ void Spell::FillTargetMap()
|
|||
case TARGET_POINT_AT_NW:
|
||||
case TARGET_POINT_AT_SE:
|
||||
case TARGET_POINT_AT_SW:
|
||||
// need some target for proccesing
|
||||
// need some target for processing
|
||||
SetTargetMap(i, m_spellInfo->EffectImplicitTargetA[i], tmpUnitMap);
|
||||
SetTargetMap(i, m_spellInfo->EffectImplicitTargetB[i], tmpUnitMap);
|
||||
break;
|
||||
|
|
@ -596,7 +597,7 @@ void Spell::FillTargetMap()
|
|||
case 0:
|
||||
SetTargetMap(i, m_spellInfo->EffectImplicitTargetA[i], tmpUnitMap);
|
||||
|
||||
// need some target for proccesing
|
||||
// need some target for processing
|
||||
SetTargetMap(i, TARGET_EFFECT_SELECT, tmpUnitMap);
|
||||
break;
|
||||
case TARGET_AREAEFFECT_INSTANT: // All 17/7 pairs used for dest teleportation, A processed in effect code
|
||||
|
|
@ -615,7 +616,7 @@ void Spell::FillTargetMap()
|
|||
case TARGET_EFFECT_SELECT:
|
||||
SetTargetMap(i, m_spellInfo->EffectImplicitTargetA[i], tmpUnitMap);
|
||||
break;
|
||||
// most A/B target pairs is slef->negative and not expect adding caster to target list
|
||||
// most A/B target pairs is self->negative and not expect adding caster to target list
|
||||
default:
|
||||
SetTargetMap(i, m_spellInfo->EffectImplicitTargetB[i], tmpUnitMap);
|
||||
break;
|
||||
|
|
@ -683,13 +684,13 @@ void Spell::prepareDataForTriggerSystem()
|
|||
m_canTrigger = false;
|
||||
|
||||
if (m_CastItem)
|
||||
m_canTrigger = false; // Do not trigger from item cast spell
|
||||
m_canTrigger = false; // Do not trigger from item cast spell
|
||||
else if (!m_IsTriggeredSpell)
|
||||
m_canTrigger = true; // Normal cast - can trigger
|
||||
m_canTrigger = true; // Normal cast - can trigger
|
||||
else if (!m_triggeredByAuraSpell)
|
||||
m_canTrigger = true; // Triggered from SPELL_EFFECT_TRIGGER_SPELL - can trigger
|
||||
m_canTrigger = true; // Triggered from SPELL_EFFECT_TRIGGER_SPELL - can trigger
|
||||
|
||||
if (!m_canTrigger) // Exceptions (some periodic triggers)
|
||||
if (!m_canTrigger) // Exceptions (some periodic triggers)
|
||||
{
|
||||
switch (m_spellInfo->SpellFamilyName)
|
||||
{
|
||||
|
|
@ -803,7 +804,7 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
|
|||
if (targetGUID == ihit->targetGUID) // Found in list
|
||||
{
|
||||
if (!immuned)
|
||||
ihit->effectMask |= 1 << effIndex; // Add only effect mask if not immuned
|
||||
ihit->effectMask |= (1 << effIndex); // Add only effect mask if not immuned
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -813,7 +814,7 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
|
|||
// Get spell hit result on target
|
||||
TargetInfo target;
|
||||
target.targetGUID = targetGUID; // Store target GUID
|
||||
target.effectMask = immuned ? 0 : 1 << effIndex; // Store index of effect if not immuned
|
||||
target.effectMask = immuned ? 0 : (1 << effIndex); // Store index of effect if not immuned
|
||||
target.processed = false; // Effects not apply on target
|
||||
|
||||
// Calculate hit result
|
||||
|
|
@ -872,7 +873,7 @@ void Spell::AddGOTarget(GameObject* pVictim, uint32 effIndex)
|
|||
{
|
||||
if (targetGUID == ihit->targetGUID) // Found in list
|
||||
{
|
||||
ihit->effectMask |= 1 << effIndex; // Add only effect mask
|
||||
ihit->effectMask |= (1 << effIndex); // Add only effect mask
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -881,7 +882,7 @@ void Spell::AddGOTarget(GameObject* pVictim, uint32 effIndex)
|
|||
|
||||
GOTargetInfo target;
|
||||
target.targetGUID = targetGUID;
|
||||
target.effectMask = 1 << effIndex;
|
||||
target.effectMask = (1 << effIndex);
|
||||
target.processed = false; // Effects not apply on target
|
||||
|
||||
// Spell have speed - need calculate incoming time
|
||||
|
|
@ -889,9 +890,10 @@ void Spell::AddGOTarget(GameObject* pVictim, uint32 effIndex)
|
|||
{
|
||||
// calculate spell incoming interval
|
||||
float dist = m_caster->GetDistance(pVictim->GetPositionX(), pVictim->GetPositionY(), pVictim->GetPositionZ());
|
||||
if (dist < 5.0f) dist = 5.0f;
|
||||
if (dist < 5.0f)
|
||||
dist = 5.0f;
|
||||
target.timeDelay = (uint64) floor(dist / m_spellInfo->speed * 1000.0f);
|
||||
if (m_delayMoment==0 || m_delayMoment>target.timeDelay)
|
||||
if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
|
||||
m_delayMoment = target.timeDelay;
|
||||
}
|
||||
else
|
||||
|
|
@ -918,7 +920,7 @@ void Spell::AddItemTarget(Item* pitem, uint32 effIndex)
|
|||
{
|
||||
if (pitem == ihit->item) // Found in list
|
||||
{
|
||||
ihit->effectMask |= 1<<effIndex; // Add only effect mask
|
||||
ihit->effectMask |= (1 << effIndex); // Add only effect mask
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -927,7 +929,7 @@ void Spell::AddItemTarget(Item* pitem, uint32 effIndex)
|
|||
|
||||
ItemTargetInfo target;
|
||||
target.item = pitem;
|
||||
target.effectMask = 1 << effIndex;
|
||||
target.effectMask = (1 << effIndex);
|
||||
m_UniqueItemInfo.push_back(target);
|
||||
}
|
||||
|
||||
|
|
@ -940,7 +942,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
|||
// Get mask of effects for target
|
||||
uint32 mask = target->effectMask;
|
||||
|
||||
Unit* unit = m_caster->GetGUID()==target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster,target->targetGUID);
|
||||
Unit* unit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
|
||||
if (!unit)
|
||||
return;
|
||||
|
||||
|
|
@ -1035,7 +1037,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
|||
}
|
||||
|
||||
// Call scripted function for AI if this spell is casted upon a creature
|
||||
if(unit->GetTypeId()==TYPEID_UNIT)
|
||||
if(unit->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
// cast at creature (or GO) quest objectives update at successful cast finished (+channel finished)
|
||||
// ignore pets or autorepeat/melee casts for speed (not exist quest for spells (hm... )
|
||||
|
|
@ -1046,11 +1048,11 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
|||
}
|
||||
|
||||
if(((Creature*)unit)->AI())
|
||||
((Creature*)unit)->AI()->SpellHit(m_caster ,m_spellInfo);
|
||||
((Creature*)unit)->AI()->SpellHit(m_caster, m_spellInfo);
|
||||
}
|
||||
|
||||
// Call scripted function for AI if this spell is casted by a creature
|
||||
if(m_caster->GetTypeId()==TYPEID_UNIT && ((Creature*)m_caster)->AI())
|
||||
if(m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->AI())
|
||||
((Creature*)m_caster)->AI()->SpellHitTarget(unit, m_spellInfo);
|
||||
}
|
||||
|
||||
|
|
@ -1094,7 +1096,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
|
|||
{
|
||||
// for delayed spells ignore not visible explicit target
|
||||
if (m_spellInfo->speed > 0.0f && unit == m_targets.getUnitTarget() &&
|
||||
!unit->isVisibleForOrDetect(m_caster,m_caster,false))
|
||||
!unit->isVisibleForOrDetect(m_caster, m_caster, false))
|
||||
{
|
||||
realCaster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_EVADE);
|
||||
return;
|
||||
|
|
@ -1106,7 +1108,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
|
|||
|
||||
// can cause back attack (if detected), stealth removed at Spell::cast if spell break it
|
||||
if (!(m_spellInfo->AttributesEx & SPELL_ATTR_EX_NO_INITIAL_AGGRO) && !IsPositiveSpell(m_spellInfo->Id) &&
|
||||
m_caster->isVisibleForOrDetect(unit,unit,false))
|
||||
m_caster->isVisibleForOrDetect(unit, unit, false))
|
||||
{
|
||||
// use speedup check to avoid re-remove after above lines
|
||||
if (m_spellInfo->AttributesEx & SPELL_ATTR_EX_NOT_BREAK_STEALTH)
|
||||
|
|
@ -1292,7 +1294,7 @@ struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit,
|
|||
// functor for operator ">"
|
||||
bool operator()(const Unit* _Left, const Unit* _Right) const
|
||||
{
|
||||
return MainTarget->GetDistanceOrder(_Left,_Right);
|
||||
return MainTarget->GetDistanceOrder(_Left, _Right);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1384,7 +1386,7 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
|
|||
{
|
||||
if (!(*m)->isAffectedOnSpell(m_spellInfo))
|
||||
continue;
|
||||
unMaxTargets+=(*m)->GetModifier()->m_amount;
|
||||
unMaxTargets += (*m)->GetModifier()->m_amount;
|
||||
}
|
||||
|
||||
switch(targetMode)
|
||||
|
|
@ -1463,7 +1465,7 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
|
|||
|
||||
//Now to get us a random target that's in the initial range of the spell
|
||||
uint32 t = 0;
|
||||
std::list<Unit *>::iterator itr = tempTargetUnitMap.begin();
|
||||
std::list<Unit*>::iterator itr = tempTargetUnitMap.begin();
|
||||
while(itr!= tempTargetUnitMap.end() && (*itr)->IsWithinDist(m_caster, radius))
|
||||
++t, ++itr;
|
||||
|
||||
|
|
@ -1471,7 +1473,7 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
|
|||
break;
|
||||
|
||||
itr = tempTargetUnitMap.begin();
|
||||
std::advance(itr, rand()%t);
|
||||
std::advance(itr, rand() % t);
|
||||
Unit *pUnitTarget = *itr;
|
||||
targetUnitMap.push_back(pUnitTarget);
|
||||
|
||||
|
|
@ -1483,9 +1485,9 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
|
|||
Unit *prev = pUnitTarget;
|
||||
std::list<Unit*>::iterator next = tempTargetUnitMap.begin();
|
||||
|
||||
while(t && next != tempTargetUnitMap.end() )
|
||||
while(t && next != tempTargetUnitMap.end())
|
||||
{
|
||||
if(!prev->IsWithinDist(*next,CHAIN_SPELL_JUMP_RADIUS))
|
||||
if(!prev->IsWithinDist(*next, CHAIN_SPELL_JUMP_RADIUS))
|
||||
break;
|
||||
|
||||
if(!prev->IsWithinLOSInMap(*next))
|
||||
|
|
@ -1513,7 +1515,7 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
|
|||
Cell cell(p);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
std::list<Unit *> tempTargetUnitMap;
|
||||
std::list<Unit*> tempTargetUnitMap;
|
||||
{
|
||||
MaNGOS::AnyFriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, max_range);
|
||||
MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck> searcher(m_caster, tempTargetUnitMap, u_check);
|
||||
|
|
@ -1532,15 +1534,15 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
|
|||
|
||||
//Now to get us a random target that's in the initial range of the spell
|
||||
uint32 t = 0;
|
||||
std::list<Unit *>::iterator itr = tempTargetUnitMap.begin();
|
||||
while(itr!= tempTargetUnitMap.end() && (*itr)->IsWithinDist(m_caster, radius))
|
||||
std::list<Unit*>::iterator itr = tempTargetUnitMap.begin();
|
||||
while(itr != tempTargetUnitMap.end() && (*itr)->IsWithinDist(m_caster, radius))
|
||||
++t, ++itr;
|
||||
|
||||
if(!t)
|
||||
break;
|
||||
|
||||
itr = tempTargetUnitMap.begin();
|
||||
std::advance(itr, rand()%t);
|
||||
std::advance(itr, rand() % t);
|
||||
Unit *pUnitTarget = *itr;
|
||||
targetUnitMap.push_back(pUnitTarget);
|
||||
|
||||
|
|
@ -1554,7 +1556,7 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
|
|||
|
||||
while(t && next != tempTargetUnitMap.end())
|
||||
{
|
||||
if(!prev->IsWithinDist(*next,CHAIN_SPELL_JUMP_RADIUS))
|
||||
if(!prev->IsWithinDist(*next, CHAIN_SPELL_JUMP_RADIUS))
|
||||
break;
|
||||
|
||||
if(!prev->IsWithinLOSInMap(*next))
|
||||
|
|
@ -1598,8 +1600,8 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
|
|||
unMaxTargets = EffectChainTarget;
|
||||
|
||||
float max_range;
|
||||
if(m_spellInfo->DmgClass==SPELL_DAMAGE_CLASS_MELEE)
|
||||
max_range = radius; //
|
||||
if(m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE)
|
||||
max_range = radius;
|
||||
else
|
||||
//FIXME: This very like horrible hack and wrong for most spells
|
||||
max_range = radius + unMaxTargets * CHAIN_SPELL_JUMP_RADIUS;
|
||||
|
|
@ -1788,7 +1790,7 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
|
|||
case TARGET_SINGLE_PARTY:
|
||||
{
|
||||
Unit *target = m_targets.getUnitTarget();
|
||||
// Thoses spells apparently can't be casted on the caster.
|
||||
// Those spells apparently can't be casted on the caster.
|
||||
if( target && target != m_caster)
|
||||
{
|
||||
// Can only be casted on group's members or its pets
|
||||
|
|
@ -1947,7 +1949,7 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
|
|||
Player* Target = itr->getSource();
|
||||
|
||||
// IsHostileTo check duel and controlled by enemy
|
||||
if(Target && Target->GetSubGroup()==subgroup && !m_caster->IsHostileTo(Target))
|
||||
if(Target && Target->GetSubGroup() == subgroup && !m_caster->IsHostileTo(Target))
|
||||
{
|
||||
if( pTarget->IsWithinDistInMap(Target, radius) )
|
||||
targetUnitMap.push_back(Target);
|
||||
|
|
@ -2052,7 +2054,7 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
|
|||
{
|
||||
targetUnitMap.push_back(currentTarget);
|
||||
m_targets.setDestination(currentTarget->GetPositionX(), currentTarget->GetPositionY(), currentTarget->GetPositionZ());
|
||||
if(m_spellInfo->EffectImplicitTargetB[effIndex]==TARGET_ALL_ENEMY_IN_AREA_INSTANT)
|
||||
if(m_spellInfo->EffectImplicitTargetB[effIndex] == TARGET_ALL_ENEMY_IN_AREA_INSTANT)
|
||||
FillAreaTargets(targetUnitMap, currentTarget->GetPositionX(), currentTarget->GetPositionY(), radius, PUSH_TARGET_CENTER, SPELL_TARGETS_AOE_DAMAGE);
|
||||
}
|
||||
break;
|
||||
|
|
@ -2087,7 +2089,7 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
|
|||
SpellTargetPosition const* st = sSpellMgr.GetSpellTargetPosition(m_spellInfo->Id);
|
||||
if(st)
|
||||
{
|
||||
// teleportspells are handled in another way
|
||||
// teleport spells are handled in another way
|
||||
if (m_spellInfo->Effect[effIndex] == SPELL_EFFECT_TELEPORT_UNITS)
|
||||
break;
|
||||
if (st->target_mapId == m_caster->GetMapId())
|
||||
|
|
@ -2122,10 +2124,10 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
|
|||
|
||||
switch(targetMode)
|
||||
{
|
||||
case TARGET_INFRONT_OF_VICTIM: break;
|
||||
case TARGET_BEHIND_VICTIM: angle = M_PI; break;
|
||||
case TARGET_RIGHT_FROM_VICTIM: angle = -M_PI/2; break;
|
||||
case TARGET_LEFT_FROM_VICTIM: angle = M_PI/2; break;
|
||||
case TARGET_INFRONT_OF_VICTIM: break;
|
||||
case TARGET_BEHIND_VICTIM: angle = M_PI; break;
|
||||
case TARGET_RIGHT_FROM_VICTIM: angle = -M_PI / 2; break;
|
||||
case TARGET_LEFT_FROM_VICTIM: angle = M_PI / 2; break;
|
||||
}
|
||||
|
||||
float _target_x, _target_y, _target_z;
|
||||
|
|
@ -2154,15 +2156,15 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
|
|||
float angle = m_caster->GetOrientation();
|
||||
switch(targetMode)
|
||||
{
|
||||
case TARGET_DYNAMIC_OBJECT_FRONT: break;
|
||||
case TARGET_DYNAMIC_OBJECT_BEHIND: angle += M_PI; break;
|
||||
case TARGET_DYNAMIC_OBJECT_LEFT_SIDE: angle += M_PI/2; break;
|
||||
case TARGET_DYNAMIC_OBJECT_RIGHT_SIDE: angle -= M_PI/2; break;
|
||||
case TARGET_DYNAMIC_OBJECT_FRONT: break;
|
||||
case TARGET_DYNAMIC_OBJECT_BEHIND: angle += M_PI; break;
|
||||
case TARGET_DYNAMIC_OBJECT_LEFT_SIDE: angle += M_PI / 2; break;
|
||||
case TARGET_DYNAMIC_OBJECT_RIGHT_SIDE: angle -= M_PI / 2; break;
|
||||
}
|
||||
|
||||
float x,y;
|
||||
m_caster->GetNearPoint2D(x,y,radius,angle);
|
||||
m_targets.setDestination(x,y,m_caster->GetPositionZ());
|
||||
float x, y;
|
||||
m_caster->GetNearPoint2D(x, y, radius, angle);
|
||||
m_targets.setDestination(x, y, m_caster->GetPositionZ());
|
||||
}
|
||||
|
||||
targetUnitMap.push_back(m_caster);
|
||||
|
|
@ -2185,19 +2187,19 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
|
|||
|
||||
switch(targetMode)
|
||||
{
|
||||
case TARGET_POINT_AT_NORTH: break;
|
||||
case TARGET_POINT_AT_SOUTH: angle += M_PI; break;
|
||||
case TARGET_POINT_AT_EAST: angle -= M_PI/2; break;
|
||||
case TARGET_POINT_AT_WEST: angle += M_PI/2; break;
|
||||
case TARGET_POINT_AT_NE: angle -= M_PI/4; break;
|
||||
case TARGET_POINT_AT_NW: angle += M_PI/4; break;
|
||||
case TARGET_POINT_AT_SE: angle -= 3*M_PI/4; break;
|
||||
case TARGET_POINT_AT_SW: angle += 3*M_PI/4; break;
|
||||
case TARGET_POINT_AT_NORTH: break;
|
||||
case TARGET_POINT_AT_SOUTH: angle += M_PI; break;
|
||||
case TARGET_POINT_AT_EAST: angle -= M_PI / 2; break;
|
||||
case TARGET_POINT_AT_WEST: angle += M_PI / 2; break;
|
||||
case TARGET_POINT_AT_NE: angle -= M_PI / 4; break;
|
||||
case TARGET_POINT_AT_NW: angle += M_PI / 4; break;
|
||||
case TARGET_POINT_AT_SE: angle -= 3*M_PI / 4; break;
|
||||
case TARGET_POINT_AT_SW: angle += 3*M_PI / 4; break;
|
||||
}
|
||||
|
||||
float x,y;
|
||||
currentTarget->GetNearPoint2D(x,y,radius,angle);
|
||||
m_targets.setDestination(x,y,currentTarget->GetPositionZ());
|
||||
float x, y;
|
||||
currentTarget->GetNearPoint2D(x, y, radius, angle);
|
||||
m_targets.setDestination(x, y, currentTarget->GetPositionZ());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -2499,13 +2501,13 @@ void Spell::cancel()
|
|||
|
||||
case SPELL_STATE_CASTING:
|
||||
{
|
||||
for(std::list<TargetInfo>::const_iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
|
||||
for(std::list<TargetInfo>::const_iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
|
||||
{
|
||||
if( ihit->missCondition == SPELL_MISS_NONE )
|
||||
{
|
||||
Unit* unit = m_caster->GetGUID()==(*ihit).targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
|
||||
Unit* unit = m_caster->GetGUID() == (*ihit).targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
|
||||
if( unit && unit->isAlive() )
|
||||
unit->RemoveAurasByCasterSpell(m_spellInfo->Id,m_caster->GetGUID());
|
||||
unit->RemoveAurasByCasterSpell(m_spellInfo->Id, m_caster->GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2521,7 +2523,7 @@ void Spell::cancel()
|
|||
|
||||
finish(false);
|
||||
m_caster->RemoveDynObject(m_spellInfo->Id);
|
||||
m_caster->RemoveGameObject(m_spellInfo->Id,true);
|
||||
m_caster->RemoveGameObject(m_spellInfo->Id, true);
|
||||
}
|
||||
|
||||
void Spell::cast(bool skipCheck)
|
||||
|
|
@ -2727,10 +2729,10 @@ void Spell::handle_immediate()
|
|||
// process immediate effects (items, ground, etc.) also initialize some variables
|
||||
_handle_immediate_phase();
|
||||
|
||||
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
|
||||
for(std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
|
||||
DoAllEffectOnTarget(&(*ihit));
|
||||
|
||||
for(std::list<GOTargetInfo>::iterator ihit= m_UniqueGOTargetInfo.begin();ihit != m_UniqueGOTargetInfo.end();++ihit)
|
||||
for(std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
|
||||
DoAllEffectOnTarget(&(*ihit));
|
||||
|
||||
// spell is finished, perform some last features of the spell here
|
||||
|
|
@ -2754,7 +2756,7 @@ uint64 Spell::handle_delayed(uint64 t_offset)
|
|||
}
|
||||
|
||||
// now recheck units targeting correctness (need before any effects apply to prevent adding immunity at first effect not allow apply second spell effect and similar cases)
|
||||
for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end();++ihit)
|
||||
for(std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
|
||||
{
|
||||
if (ihit->processed == false)
|
||||
{
|
||||
|
|
@ -2766,7 +2768,7 @@ uint64 Spell::handle_delayed(uint64 t_offset)
|
|||
}
|
||||
|
||||
// now recheck gameobject targeting correctness
|
||||
for(std::list<GOTargetInfo>::iterator ighit= m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end();++ighit)
|
||||
for(std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
|
||||
{
|
||||
if (ighit->processed == false)
|
||||
{
|
||||
|
|
@ -2825,7 +2827,7 @@ void Spell::_handle_immediate_phase()
|
|||
m_damageMultipliers[j] = 1.0f;
|
||||
if( (m_spellInfo->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE || m_spellInfo->EffectImplicitTargetA[j] == TARGET_CHAIN_HEAL) &&
|
||||
(EffectChainTarget > 1) )
|
||||
m_applyMultiplierMask |= 1 << j;
|
||||
m_applyMultiplierMask |= (1 << j);
|
||||
}
|
||||
|
||||
// initialize Diminishing Returns Data
|
||||
|
|
@ -2833,7 +2835,7 @@ void Spell::_handle_immediate_phase()
|
|||
m_diminishGroup = DIMINISHING_NONE;
|
||||
|
||||
// process items
|
||||
for(std::list<ItemTargetInfo>::iterator ihit= m_UniqueItemInfo.begin();ihit != m_UniqueItemInfo.end();++ihit)
|
||||
for(std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
|
||||
DoAllEffectOnTarget(&(*ihit));
|
||||
|
||||
// process ground
|
||||
|
|
@ -2871,7 +2873,7 @@ void Spell::SendSpellCooldown()
|
|||
if(m_spellInfo->Attributes & (SPELL_ATTR_DISABLED_WHILE_ACTIVE | SPELL_ATTR_PASSIVE))
|
||||
return;
|
||||
|
||||
_player->AddSpellAndCategoryCooldowns(m_spellInfo,m_CastItem ? m_CastItem->GetEntry() : 0, this);
|
||||
_player->AddSpellAndCategoryCooldowns(m_spellInfo, m_CastItem ? m_CastItem->GetEntry() : 0, this);
|
||||
}
|
||||
|
||||
void Spell::update(uint32 difftime)
|
||||
|
|
@ -3005,7 +3007,7 @@ void Spell::finish(bool ok)
|
|||
if(!ok)
|
||||
return;
|
||||
|
||||
//remove spell mods
|
||||
// remove spell mods
|
||||
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)m_caster)->RemoveSpellMods(this);
|
||||
|
||||
|
|
@ -3015,7 +3017,8 @@ void Spell::finish(bool ok)
|
|||
{
|
||||
if (!(*i)->isAffectedOnSpell(m_spellInfo))
|
||||
continue;
|
||||
for(std::list<TargetInfo>::const_iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
|
||||
for(std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
|
||||
{
|
||||
if( ihit->missCondition == SPELL_MISS_NONE )
|
||||
{
|
||||
// check m_caster->GetGUID() let load auras at login and speedup most often case
|
||||
|
|
@ -3030,6 +3033,7 @@ void Spell::finish(bool ok)
|
|||
m_caster->CastSpell(unit, auraSpellInfo->EffectTriggerSpell[auraSpellIdx], true, NULL, (*i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Heal caster for all health leech from all targets
|
||||
|
|
@ -3053,9 +3057,9 @@ void Spell::finish(bool ok)
|
|||
bool needDrop = true;
|
||||
if (!IsPositiveSpell(m_spellInfo->Id))
|
||||
{
|
||||
for(std::list<TargetInfo>::const_iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
|
||||
for(std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
|
||||
{
|
||||
if (ihit->missCondition != SPELL_MISS_NONE && ihit->targetGUID!=m_caster->GetGUID())
|
||||
if (ihit->missCondition != SPELL_MISS_NONE && ihit->targetGUID != m_caster->GetGUID())
|
||||
{
|
||||
needDrop = false;
|
||||
break;
|
||||
|
|
@ -3090,7 +3094,7 @@ void Spell::SendCastResult(SpellCastResult result)
|
|||
if(((Player*)m_caster)->GetSession()->PlayerLoading()) // don't send cast results at loading time
|
||||
return;
|
||||
|
||||
SendCastResult((Player*)m_caster,m_spellInfo,m_cast_count,result);
|
||||
SendCastResult((Player*)m_caster, m_spellInfo, m_cast_count, result);
|
||||
}
|
||||
|
||||
void Spell::SendCastResult(Player* caster, SpellEntry const* spellInfo, uint8 cast_count, SpellCastResult result)
|
||||
|
|
@ -3326,7 +3330,7 @@ void Spell::WriteAmmoToPacket( WorldPacket * data )
|
|||
{
|
||||
if(ItemEntry const * itemEntry = sItemStore.LookupEntry(item_id))
|
||||
{
|
||||
if(itemEntry->Class==ITEM_CLASS_WEAPON)
|
||||
if(itemEntry->Class == ITEM_CLASS_WEAPON)
|
||||
{
|
||||
switch(itemEntry->SubClass)
|
||||
{
|
||||
|
|
@ -3360,7 +3364,7 @@ void Spell::WriteAmmoToPacket( WorldPacket * data )
|
|||
void Spell::WriteSpellGoTargets( WorldPacket * data )
|
||||
{
|
||||
// This function also fill data for channeled spells:
|
||||
// m_needAliveTargetMask req for stop channelig if one target die
|
||||
// m_needAliveTargetMask req for stop channeling if one target die
|
||||
uint32 hit = m_UniqueGOTargetInfo.size(); // Always hits on GO
|
||||
uint32 miss = 0;
|
||||
for(std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
|
||||
|
|
@ -3535,12 +3539,12 @@ void Spell::SendChannelUpdate(uint32 time)
|
|||
{
|
||||
if(time == 0)
|
||||
{
|
||||
m_caster->RemoveAurasByCasterSpell(m_spellInfo->Id,m_caster->GetGUID());
|
||||
m_caster->RemoveAurasByCasterSpell(m_spellInfo->Id, m_caster->GetGUID());
|
||||
|
||||
if(uint64 target_guid = m_caster->GetChannelObjectGUID())
|
||||
if(target_guid != m_caster->GetGUID() && IS_UNIT_GUID(target_guid))
|
||||
if(Unit* target = ObjectAccessor::GetUnit(*m_caster, target_guid))
|
||||
target->RemoveAurasByCasterSpell(m_spellInfo->Id,m_caster->GetGUID());
|
||||
target->RemoveAurasByCasterSpell(m_spellInfo->Id, m_caster->GetGUID());
|
||||
|
||||
m_caster->SetChannelObjectGUID(0);
|
||||
m_caster->SetUInt32Value(UNIT_CHANNEL_SPELL, 0);
|
||||
|
|
@ -3549,7 +3553,6 @@ void Spell::SendChannelUpdate(uint32 time)
|
|||
WorldPacket data( MSG_CHANNEL_UPDATE, 8+4 );
|
||||
data.append(m_caster->GetPackGUID());
|
||||
data << uint32(time);
|
||||
|
||||
m_caster->SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
|
|
@ -3585,12 +3588,13 @@ void Spell::SendChannelStart(uint32 duration)
|
|||
data.append(m_caster->GetPackGUID());
|
||||
data << uint32(m_spellInfo->Id);
|
||||
data << uint32(duration);
|
||||
|
||||
m_caster->SendMessageToSet(&data, true);
|
||||
|
||||
m_timer = duration;
|
||||
|
||||
if(target)
|
||||
m_caster->SetChannelObjectGUID(target->GetGUID());
|
||||
|
||||
m_caster->SetUInt32Value(UNIT_CHANNEL_SPELL, m_spellInfo->Id);
|
||||
}
|
||||
|
||||
|
|
@ -3765,7 +3769,7 @@ SpellCastResult Spell::CheckOrTakeRunePower(bool take)
|
|||
if(plr->GetRuneCooldown(i) == 0)
|
||||
{
|
||||
if (take)
|
||||
plr->SetRuneCooldown(i, RUNE_COOLDOWN); // 5*2=10 sec
|
||||
plr->SetRuneCooldown(i, RUNE_COOLDOWN); // 5*2=10 sec
|
||||
|
||||
--runeCost[rune];
|
||||
}
|
||||
|
|
@ -3938,7 +3942,7 @@ void Spell::AddPrecastSpell( uint32 spellId )
|
|||
|
||||
void Spell::CastTriggerSpells()
|
||||
{
|
||||
for(SpellInfoList::const_iterator si=m_TriggerSpells.begin(); si!=m_TriggerSpells.end(); ++si)
|
||||
for(SpellInfoList::const_iterator si = m_TriggerSpells.begin(); si != m_TriggerSpells.end(); ++si)
|
||||
{
|
||||
Spell* spell = new Spell(m_caster, (*si), true, m_originalCasterGUID, m_selfContainer);
|
||||
spell->prepare(&m_targets); // use original spell original targets
|
||||
|
|
@ -3947,7 +3951,7 @@ void Spell::CastTriggerSpells()
|
|||
|
||||
void Spell::CastPreCastSpells(Unit* target)
|
||||
{
|
||||
for(SpellInfoList::const_iterator si=m_preCastSpells.begin(); si!=m_preCastSpells.end(); ++si)
|
||||
for(SpellInfoList::const_iterator si = m_preCastSpells.begin(); si != m_preCastSpells.end(); ++si)
|
||||
m_caster->CastSpell(target, (*si), true, m_CastItem);
|
||||
}
|
||||
|
||||
|
|
@ -4019,7 +4023,7 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||
|
||||
// cancel autorepeat spells if cast start when moving
|
||||
// (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
|
||||
if( m_caster->GetTypeId()==TYPEID_PLAYER && ((Player*)m_caster)->isMoving() )
|
||||
if( m_caster->GetTypeId() == TYPEID_PLAYER && ((Player*)m_caster)->isMoving() )
|
||||
{
|
||||
// skip stuck spell to allow use it in falling case and apply spell limitations at movement
|
||||
if( (!((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING) || m_spellInfo->Effect[0] != SPELL_EFFECT_STUCK) &&
|
||||
|
|
@ -4072,7 +4076,7 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||
// this case can be triggered if rank not found (too low-level target for first rank)
|
||||
if (m_caster->GetTypeId() == TYPEID_PLAYER && !IsPassiveSpell(m_spellInfo->Id) && !m_CastItem)
|
||||
{
|
||||
for(int i=0;i<3;++i)
|
||||
for(int i = 0; i < 3; ++i)
|
||||
{
|
||||
// check only spell that apply positive auras
|
||||
if (IsPositiveEffect(m_spellInfo->Id, i) && m_spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA &&
|
||||
|
|
@ -4089,7 +4093,7 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||
else if (m_caster == target)
|
||||
{
|
||||
|
||||
if (m_caster->GetTypeId() == TYPEID_PLAYER) // Target - is player caster
|
||||
if (m_caster->GetTypeId() == TYPEID_PLAYER) // Target - is player caster
|
||||
{
|
||||
// Additional check for some spells
|
||||
// If 0 spell effect empty - client not send target data (need use selection)
|
||||
|
|
@ -4245,7 +4249,7 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||
uint32 zone, area;
|
||||
m_caster->GetZoneAndAreaId(zone, area);
|
||||
|
||||
SpellCastResult locRes= sSpellMgr.GetSpellAllowedInLocationError(m_spellInfo,m_caster->GetMapId(),zone,area,
|
||||
SpellCastResult locRes= sSpellMgr.GetSpellAllowedInLocationError(m_spellInfo, m_caster->GetMapId(), zone, area,
|
||||
m_caster->GetCharmerOrOwnerPlayerOrPlayerItself());
|
||||
if (locRes != SPELL_CAST_OK)
|
||||
return locRes;
|
||||
|
|
@ -4282,8 +4286,8 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||
|
||||
SpellScriptTargetBounds bounds = sSpellMgr.GetSpellScriptTargetBounds(m_spellInfo->Id);
|
||||
|
||||
if (bounds.first==bounds.second)
|
||||
sLog.outErrorDb("Spell (ID: %u) has effect EffectImplicitTargetA/EffectImplicitTargetB = TARGET_SCRIPT or TARGET_SCRIPT_COORDINATES, but does not have record in `spell_script_target`",m_spellInfo->Id);
|
||||
if (bounds.first == bounds.second)
|
||||
sLog.outErrorDb("Spell (ID: %u) has effect EffectImplicitTargetA/EffectImplicitTargetB = TARGET_SCRIPT or TARGET_SCRIPT_COORDINATES, but does not have record in `spell_script_target`", m_spellInfo->Id);
|
||||
|
||||
SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex);
|
||||
float range = GetSpellMaxRange(srange);
|
||||
|
|
@ -4342,7 +4346,7 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate();
|
||||
|
||||
MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster,i_spellST->second.targetEntry,i_spellST->second.type!=SPELL_TARGET_TYPE_DEAD,range);
|
||||
MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster, i_spellST->second.targetEntry, i_spellST->second.type != SPELL_TARGET_TYPE_DEAD, range);
|
||||
MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(m_caster, p_Creature, u_check);
|
||||
|
||||
TypeContainerVisitor<MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer > grid_creature_searcher(searcher);
|
||||
|
|
@ -4815,7 +4819,7 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||
float fx = m_caster->GetPositionX() + dis * cos(m_caster->GetOrientation());
|
||||
float fy = m_caster->GetPositionY() + dis * sin(m_caster->GetOrientation());
|
||||
// teleport a bit above terrain level to avoid falling below it
|
||||
float fz = m_caster->GetBaseMap()->GetHeight(fx,fy,m_caster->GetPositionZ(),true);
|
||||
float fz = m_caster->GetBaseMap()->GetHeight(fx, fy, m_caster->GetPositionZ(), true);
|
||||
if(fz <= INVALID_HEIGHT) // note: this also will prevent use effect in instances without vmaps height enabled
|
||||
return SPELL_FAILED_TRY_AGAIN;
|
||||
|
||||
|
|
@ -5216,7 +5220,7 @@ bool Spell::CanAutoCast(Unit* target)
|
|||
{
|
||||
FillTargetMap();
|
||||
//check if among target units, our WANTED target is as well (->only self cast spells return false)
|
||||
for(std::list<TargetInfo>::const_iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
|
||||
for(std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
|
||||
if( ihit->targetGUID == targetguid )
|
||||
return true;
|
||||
}
|
||||
|
|
@ -5251,7 +5255,7 @@ SpellCastResult Spell::CheckRange(bool strict)
|
|||
float dist = m_caster->GetCombatDistance(target);
|
||||
|
||||
if(dist > max_range)
|
||||
return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
|
||||
return SPELL_FAILED_OUT_OF_RANGE;
|
||||
if(min_range && dist < min_range)
|
||||
return SPELL_FAILED_TOO_CLOSE;
|
||||
if( m_caster->GetTypeId() == TYPEID_PLAYER &&
|
||||
|
|
@ -5323,16 +5327,16 @@ int32 Spell::CalculatePowerCost()
|
|||
powerCost += m_caster->GetInt32Value(UNIT_FIELD_POWER_COST_MODIFIER + school);
|
||||
// Shiv - costs 20 + weaponSpeed*10 energy (apply only to non-triggered spell with energy cost)
|
||||
if ( m_spellInfo->AttributesEx4 & SPELL_ATTR_EX4_SPELL_VS_EXTEND_COST )
|
||||
powerCost += m_caster->GetAttackTime(OFF_ATTACK)/100;
|
||||
powerCost += m_caster->GetAttackTime(OFF_ATTACK) / 100;
|
||||
// Apply cost mod by spell
|
||||
if(Player* modOwner = m_caster->GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, powerCost, this);
|
||||
|
||||
if(m_spellInfo->Attributes & SPELL_ATTR_LEVEL_DAMAGE_CALCULATION)
|
||||
powerCost = int32(powerCost/ (1.117f* m_spellInfo->spellLevel / m_caster->getLevel() -0.1327f));
|
||||
powerCost = int32(powerCost/ (1.117f * m_spellInfo->spellLevel / m_caster->getLevel() -0.1327f));
|
||||
|
||||
// PCT mod from user auras by school
|
||||
powerCost = int32(powerCost * (1.0f+m_caster->GetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+school)));
|
||||
powerCost = int32(powerCost * (1.0f + m_caster->GetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER + school)));
|
||||
if (powerCost < 0)
|
||||
powerCost = 0;
|
||||
return powerCost;
|
||||
|
|
@ -5563,7 +5567,7 @@ SpellCastResult Spell::CheckItems()
|
|||
}
|
||||
|
||||
if (totems != 0)
|
||||
return SPELL_FAILED_TOTEMS; //0x7C
|
||||
return SPELL_FAILED_TOTEMS;
|
||||
|
||||
// Check items for TotemCategory (items presence in inventory)
|
||||
uint32 TotemCategory = 2;
|
||||
|
|
@ -5582,9 +5586,9 @@ SpellCastResult Spell::CheckItems()
|
|||
}
|
||||
|
||||
if (TotemCategory != 0)
|
||||
return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
|
||||
|
||||
return SPELL_FAILED_TOTEM_CATEGORY;
|
||||
}
|
||||
|
||||
// special checks for spell effects
|
||||
for(int i = 0; i < 3; ++i)
|
||||
{
|
||||
|
|
@ -5677,17 +5681,17 @@ SpellCastResult Spell::CheckItems()
|
|||
{
|
||||
if(!m_targets.getItemTarget())
|
||||
return SPELL_FAILED_CANT_BE_PROSPECTED;
|
||||
//ensure item is a prospectable ore
|
||||
// ensure item is a prospectable ore
|
||||
if(!(m_targets.getItemTarget()->GetProto()->BagFamily & BAG_FAMILY_MASK_MINING_SUPP) || m_targets.getItemTarget()->GetProto()->Class != ITEM_CLASS_TRADE_GOODS)
|
||||
return SPELL_FAILED_CANT_BE_PROSPECTED;
|
||||
//prevent prospecting in trade slot
|
||||
// prevent prospecting in trade slot
|
||||
if( m_targets.getItemTarget()->GetOwnerGUID() != m_caster->GetGUID() )
|
||||
return SPELL_FAILED_CANT_BE_PROSPECTED;
|
||||
//Check for enough skill in jewelcrafting
|
||||
// Check for enough skill in jewelcrafting
|
||||
uint32 item_prospectingskilllevel = m_targets.getItemTarget()->GetProto()->RequiredSkillRank;
|
||||
if(item_prospectingskilllevel >p_caster->GetSkillValue(SKILL_JEWELCRAFTING))
|
||||
return SPELL_FAILED_LOW_CASTLEVEL;
|
||||
//make sure the player has the required ores in inventory
|
||||
// make sure the player has the required ores in inventory
|
||||
if(m_targets.getItemTarget()->GetCount() < 5)
|
||||
return SPELL_FAILED_NEED_MORE_ITEMS;
|
||||
|
||||
|
|
@ -5700,17 +5704,17 @@ SpellCastResult Spell::CheckItems()
|
|||
{
|
||||
if(!m_targets.getItemTarget())
|
||||
return SPELL_FAILED_CANT_BE_MILLED;
|
||||
//ensure item is a millable herb
|
||||
// ensure item is a millable herb
|
||||
if(!(m_targets.getItemTarget()->GetProto()->BagFamily & BAG_FAMILY_MASK_HERBS) || m_targets.getItemTarget()->GetProto()->Class != ITEM_CLASS_TRADE_GOODS)
|
||||
return SPELL_FAILED_CANT_BE_MILLED;
|
||||
//prevent milling in trade slot
|
||||
// prevent milling in trade slot
|
||||
if( m_targets.getItemTarget()->GetOwnerGUID() != m_caster->GetGUID() )
|
||||
return SPELL_FAILED_CANT_BE_MILLED;
|
||||
//Check for enough skill in inscription
|
||||
// Check for enough skill in inscription
|
||||
uint32 item_millingskilllevel = m_targets.getItemTarget()->GetProto()->RequiredSkillRank;
|
||||
if(item_millingskilllevel >p_caster->GetSkillValue(SKILL_INSCRIPTION))
|
||||
return SPELL_FAILED_LOW_CASTLEVEL;
|
||||
//make sure the player has the required herbs in inventory
|
||||
// make sure the player has the required herbs in inventory
|
||||
if(m_targets.getItemTarget()->GetCount() < 5)
|
||||
return SPELL_FAILED_NEED_MORE_ITEMS;
|
||||
|
||||
|
|
@ -5806,7 +5810,7 @@ void Spell::Delayed()
|
|||
if(!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
|
||||
return;
|
||||
|
||||
//check pushback reduce
|
||||
// check pushback reduce
|
||||
int32 delaytime = 500; // spellcasting delay is normally 500ms
|
||||
int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
|
||||
((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id, SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this);
|
||||
|
|
@ -5841,9 +5845,9 @@ void Spell::DelayedChannel()
|
|||
if(isDelayableNoMore()) // Spells may only be delayed twice
|
||||
return;
|
||||
|
||||
//check pushback reduce
|
||||
int32 delaytime = GetSpellDuration(m_spellInfo) * 25 / 100; // channeling delay is normally 25% of its time per hit
|
||||
int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
|
||||
// check pushback reduce
|
||||
int32 delaytime = GetSpellDuration(m_spellInfo) * 25 / 100;// channeling delay is normally 25% of its time per hit
|
||||
int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
|
||||
((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id, SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this);
|
||||
delayReduce += m_caster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100;
|
||||
if(delayReduce >= 100)
|
||||
|
|
@ -5889,11 +5893,11 @@ void Spell::DelayedChannel()
|
|||
|
||||
void Spell::UpdatePointers()
|
||||
{
|
||||
if(m_originalCasterGUID==m_caster->GetGUID())
|
||||
if(m_originalCasterGUID == m_caster->GetGUID())
|
||||
m_originalCaster = m_caster;
|
||||
else
|
||||
{
|
||||
m_originalCaster = ObjectAccessor::GetUnit(*m_caster,m_originalCasterGUID);
|
||||
m_originalCaster = ObjectAccessor::GetUnit(*m_caster, m_originalCasterGUID);
|
||||
if(m_originalCaster && !m_originalCaster->IsInWorld()) m_originalCaster = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -5913,10 +5917,10 @@ bool Spell::CheckTargetCreatureType(Unit* target) const
|
|||
uint32 spellCreatureTargetMask = m_spellInfo->TargetCreatureType;
|
||||
|
||||
// Curse of Doom & Exorcism: not find another way to fix spell target check :/
|
||||
if (m_spellInfo->SpellFamilyName==SPELLFAMILY_WARLOCK && m_spellInfo->Category == 1179)
|
||||
if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->Category == 1179)
|
||||
{
|
||||
// not allow cast at player
|
||||
if(target->GetTypeId()==TYPEID_PLAYER)
|
||||
if(target->GetTypeId() == TYPEID_PLAYER)
|
||||
return false;
|
||||
|
||||
spellCreatureTargetMask = 0x7FF;
|
||||
|
|
@ -5978,7 +5982,7 @@ bool Spell::CheckTarget( Unit* target, uint32 eff )
|
|||
return false;
|
||||
}
|
||||
|
||||
//Check player targets and remove if in GM mode or GM invisibility (for not self casting case)
|
||||
// Check player targets and remove if in GM mode or GM invisibility (for not self casting case)
|
||||
if( target != m_caster && target->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if(((Player*)target)->GetVisibility() == VISIBILITY_OFF)
|
||||
|
|
@ -5988,7 +5992,7 @@ bool Spell::CheckTarget( Unit* target, uint32 eff )
|
|||
return false;
|
||||
}
|
||||
|
||||
//Check targets for LOS visibility (except spells without range limitations )
|
||||
// Check targets for LOS visibility (except spells without range limitations )
|
||||
switch(m_spellInfo->Effect[eff])
|
||||
{
|
||||
case SPELL_EFFECT_SUMMON_PLAYER: // from anywhere
|
||||
|
|
@ -5996,7 +6000,7 @@ bool Spell::CheckTarget( Unit* target, uint32 eff )
|
|||
case SPELL_EFFECT_DUMMY:
|
||||
if(m_spellInfo->Id != 20577) // Cannibalize
|
||||
break;
|
||||
//fall through
|
||||
// fall through
|
||||
case SPELL_EFFECT_RESURRECT_NEW:
|
||||
// player far away, maybe his corpse near?
|
||||
if(target != m_caster && !target->IsWithinLOSInMap(m_caster))
|
||||
|
|
@ -6266,13 +6270,13 @@ void Spell::FillRaidOrPartyTargets(UnitList &targetUnitMap, Unit* member, Unit*
|
|||
if (Target && (raid || subgroup==Target->GetSubGroup())
|
||||
&& !m_caster->IsHostileTo(Target))
|
||||
{
|
||||
if ((Target==center || center->IsWithinDistInMap(Target, radius)) &&
|
||||
if ((Target == center || center->IsWithinDistInMap(Target, radius)) &&
|
||||
(withcaster || Target != m_caster))
|
||||
targetUnitMap.push_back(Target);
|
||||
|
||||
if (withPets)
|
||||
if (Pet* pet = Target->GetPet())
|
||||
if ((pet==center || center->IsWithinDistInMap(pet, radius)) &&
|
||||
if ((pet == center || center->IsWithinDistInMap(pet, radius)) &&
|
||||
(withcaster || pet != m_caster))
|
||||
targetUnitMap.push_back(pet);
|
||||
}
|
||||
|
|
@ -6281,13 +6285,13 @@ void Spell::FillRaidOrPartyTargets(UnitList &targetUnitMap, Unit* member, Unit*
|
|||
else
|
||||
{
|
||||
Unit* ownerOrSelf = pMember ? pMember : member->GetCharmerOrOwnerOrSelf();
|
||||
if ((ownerOrSelf==center || center->IsWithinDistInMap(ownerOrSelf, radius)) &&
|
||||
if ((ownerOrSelf == center || center->IsWithinDistInMap(ownerOrSelf, radius)) &&
|
||||
(withcaster || ownerOrSelf != m_caster))
|
||||
targetUnitMap.push_back(ownerOrSelf);
|
||||
|
||||
if (withPets)
|
||||
if (Pet* pet = ownerOrSelf->GetPet())
|
||||
if ((pet==center || center->IsWithinDistInMap(pet, radius)) &&
|
||||
if ((pet == center || center->IsWithinDistInMap(pet, radius)) &&
|
||||
(withcaster || pet != m_caster))
|
||||
targetUnitMap.push_back(pet);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -650,6 +650,24 @@ enum MonsterMovementFlags
|
|||
MONSTER_MOVE_SPLINE_FLY = 0x00003000, // fly by points
|
||||
};
|
||||
|
||||
enum MovementFlags2
|
||||
{
|
||||
MOVEFLAG2_NONE = 0x0000,
|
||||
MOVEFLAG2_ALLOW_PITCHING = 0x0020,
|
||||
MOVEFLAG2_UNK1 = 0x0400,
|
||||
MOVEFLAG2_UNK2 = 0x0800,
|
||||
MOVEFLAG2_UNK3 = 0x1000,
|
||||
MOVEFLAG2_INTERP_MASK = MOVEFLAG2_UNK1 | MOVEFLAG2_UNK2 | MOVEFLAG2_UNK3,
|
||||
};
|
||||
|
||||
enum SplineMoveFlags // possibly exactly same as MonsterMovementFlags
|
||||
{
|
||||
SPLINE_MOVE_FLAG_NONE = 0x00000000,
|
||||
SPLINE_MOVE_FLAG_POINT = 0x00008000,
|
||||
SPLINE_MOVE_FLAG_GUID = 0x00010000,
|
||||
SPLINE_MOVE_FLAG_FACING = 0x00020000,
|
||||
};
|
||||
|
||||
enum DiminishingLevels
|
||||
{
|
||||
DIMINISHING_LEVEL_1 = 0,
|
||||
|
|
|
|||
|
|
@ -724,7 +724,7 @@ void WorldSession::SaveTutorialsData()
|
|||
void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
|
||||
{
|
||||
data >> mi->flags;
|
||||
data >> mi->unk1;
|
||||
data >> mi->moveFlags2;
|
||||
data >> mi->time;
|
||||
data >> mi->x;
|
||||
data >> mi->y;
|
||||
|
|
@ -742,9 +742,12 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
|
|||
data >> mi->t_o;
|
||||
data >> mi->t_time;
|
||||
data >> mi->t_seat;
|
||||
|
||||
if(mi->moveFlags2 & MOVEFLAG2_UNK1)
|
||||
data >> mi->t_time2;
|
||||
}
|
||||
|
||||
if((mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING))) || (mi->unk1 & 0x20))
|
||||
if((mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING))) || (mi->moveFlags2 & MOVEFLAG2_ALLOW_PITCHING))
|
||||
{
|
||||
data >> mi->s_pitch;
|
||||
}
|
||||
|
|
@ -753,7 +756,7 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
|
|||
|
||||
if(mi->HasMovementFlag(MOVEMENTFLAG_JUMPING))
|
||||
{
|
||||
data >> mi->j_unk;
|
||||
data >> mi->j_velocity;
|
||||
data >> mi->j_sinAngle;
|
||||
data >> mi->j_cosAngle;
|
||||
data >> mi->j_xyspeed;
|
||||
|
|
@ -770,7 +773,7 @@ void WorldSession::WriteMovementInfo(WorldPacket *data, MovementInfo *mi)
|
|||
data->appendPackGUID(mi->guid);
|
||||
|
||||
*data << mi->flags;
|
||||
*data << mi->unk1;
|
||||
*data << mi->moveFlags2;
|
||||
*data << mi->time;
|
||||
*data << mi->x;
|
||||
*data << mi->y;
|
||||
|
|
@ -787,9 +790,12 @@ void WorldSession::WriteMovementInfo(WorldPacket *data, MovementInfo *mi)
|
|||
*data << mi->t_o;
|
||||
*data << mi->t_time;
|
||||
*data << mi->t_seat;
|
||||
|
||||
if(mi->moveFlags2 & MOVEFLAG2_UNK1)
|
||||
*data << mi->t_time2;
|
||||
}
|
||||
|
||||
if((mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING))) || (mi->unk1 & 0x20))
|
||||
if((mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING))) || (mi->moveFlags2 & MOVEFLAG2_ALLOW_PITCHING))
|
||||
{
|
||||
*data << mi->s_pitch;
|
||||
}
|
||||
|
|
@ -798,7 +804,7 @@ void WorldSession::WriteMovementInfo(WorldPacket *data, MovementInfo *mi)
|
|||
|
||||
if(mi->HasMovementFlag(MOVEMENTFLAG_JUMPING))
|
||||
{
|
||||
*data << mi->j_unk;
|
||||
*data << mi->j_velocity;
|
||||
*data << mi->j_sinAngle;
|
||||
*data << mi->j_cosAngle;
|
||||
*data << mi->j_xyspeed;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue