Movement packets fix.

This commit is contained in:
tomrus88 2010-02-01 00:36:59 +03:00
parent ad7729479c
commit 41d8f1a5d4
6 changed files with 277 additions and 241 deletions

View file

@ -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());
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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;
}
@ -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;
@ -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;
@ -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,7 +890,8 @@ 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)
m_delayMoment = target.timeDelay;
@ -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);
}
@ -1599,7 +1601,7 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
float max_range;
if(m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE)
max_range = radius; //
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
@ -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
@ -3016,6 +3018,7 @@ 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)
{
if( ihit->missCondition == SPELL_MISS_NONE )
{
// check m_caster->GetGUID() let load auras at login and speedup most often case
@ -3031,6 +3034,7 @@ void Spell::finish(bool ok)
}
}
}
}
// Heal caster for all health leech from all targets
if (m_healthLeech)
@ -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)
@ -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);
}
@ -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 &&
@ -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)
{

View file

@ -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,

View file

@ -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;