[9212] Implement pet speed synchronization with owner only for follow mode.

* This allow pet use own speed (and all speed affects appiedto pet itself) in combat.
* Apply this speed synhronization to minipets/guardians also.
* Also rename Unit::SetSpeed to SetSpeedRate as more close to real functionality.
This commit is contained in:
VladimirMangos 2010-01-19 03:49:09 +03:00
parent a6a5935406
commit eaecc467d5
8 changed files with 73 additions and 22 deletions

View file

@ -263,9 +263,9 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data )
SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f);
SetSpeed(MOVE_WALK, cinfo->speed );
SetSpeed(MOVE_RUN, cinfo->speed );
SetSpeed(MOVE_SWIM, cinfo->speed );
SetSpeedRate(MOVE_WALK, cinfo->speed );
SetSpeedRate(MOVE_RUN, cinfo->speed );
SetSpeedRate(MOVE_SWIM, cinfo->speed );
SetFloatValue(OBJECT_FIELD_SCALE_X, cinfo->scale);

View file

@ -1136,11 +1136,11 @@ bool ChatHandler::HandleModifyASpeedCommand(const char* args)
if (needReportToTarget(chr))
ChatHandler(chr).PSendSysMessage(LANG_YOURS_ASPEED_CHANGED, GetNameLink().c_str(), ASpeed);
chr->SetSpeed(MOVE_WALK, ASpeed,true);
chr->SetSpeed(MOVE_RUN, ASpeed,true);
chr->SetSpeed(MOVE_SWIM, ASpeed,true);
//chr->SetSpeed(MOVE_TURN, ASpeed,true);
chr->SetSpeed(MOVE_FLIGHT, ASpeed,true);
chr->SetSpeedRate(MOVE_WALK, ASpeed,true);
chr->SetSpeedRate(MOVE_RUN, ASpeed,true);
chr->SetSpeedRate(MOVE_SWIM, ASpeed,true);
//chr->SetSpeed(MOVE_TURN, ASpeed,true);
chr->SetSpeedRate(MOVE_FLIGHT, ASpeed,true);
return true;
}
@ -1184,7 +1184,7 @@ bool ChatHandler::HandleModifySpeedCommand(const char* args)
if (needReportToTarget(chr))
ChatHandler(chr).PSendSysMessage(LANG_YOURS_SPEED_CHANGED, GetNameLink().c_str(), Speed);
chr->SetSpeed(MOVE_RUN,Speed,true);
chr->SetSpeedRate(MOVE_RUN,Speed,true);
return true;
}
@ -1229,7 +1229,7 @@ bool ChatHandler::HandleModifySwimCommand(const char* args)
if (needReportToTarget(chr))
ChatHandler(chr).PSendSysMessage(LANG_YOURS_SWIM_SPEED_CHANGED, GetNameLink().c_str(), Swim);
chr->SetSpeed(MOVE_SWIM,Swim,true);
chr->SetSpeedRate(MOVE_SWIM,Swim,true);
return true;
}
@ -1274,7 +1274,7 @@ bool ChatHandler::HandleModifyBWalkCommand(const char* args)
if (needReportToTarget(chr))
ChatHandler(chr).PSendSysMessage(LANG_YOURS_BACK_SPEED_CHANGED, GetNameLink().c_str(), BSpeed);
chr->SetSpeed(MOVE_RUN_BACK,BSpeed,true);
chr->SetSpeedRate(MOVE_RUN_BACK,BSpeed,true);
return true;
}
@ -1310,7 +1310,7 @@ bool ChatHandler::HandleModifyFlyCommand(const char* args)
if (needReportToTarget(chr))
ChatHandler(chr).PSendSysMessage(LANG_YOURS_FLY_SPEED_CHANGED, GetNameLink().c_str(), FSpeed);
chr->SetSpeed(MOVE_FLIGHT,FSpeed,true);
chr->SetSpeedRate(MOVE_FLIGHT,FSpeed,true);
return true;
}

View file

@ -432,7 +432,7 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
{
sLog.outError("%sSpeedChange player %s is NOT correct (must be %f instead %f), force set to correct value",
move_type_name[move_type], _player->GetName(), _player->GetSpeed(move_type), newspeed);
_player->SetSpeed(move_type,_player->GetSpeedRate(move_type),true);
_player->SetSpeedRate(move_type,_player->GetSpeedRate(move_type),true);
}
else // must be lesser - cheating
{

View file

@ -243,6 +243,7 @@ void FollowMovementGenerator<Player>::Initialize(Player &owner)
{
owner.addUnitState(UNIT_STAT_FOLLOW|UNIT_STAT_FOLLOW_MOVE);
_updateWalkMode(owner);
_updateSpeed(owner);
_setTargetLocation(owner);
}
@ -251,6 +252,7 @@ void FollowMovementGenerator<Creature>::Initialize(Creature &owner)
{
owner.addUnitState(UNIT_STAT_FOLLOW|UNIT_STAT_FOLLOW_MOVE);
_updateWalkMode(owner);
_updateSpeed(owner);
if (((Creature*)&owner)->canFly())
owner.AddMonsterMoveFlag(MONSTER_MOVE_FLY);
@ -263,6 +265,7 @@ void FollowMovementGenerator<T>::Finalize(T &owner)
{
owner.clearUnitState(UNIT_STAT_FOLLOW|UNIT_STAT_FOLLOW_MOVE);
_updateWalkMode(owner);
_updateSpeed(owner);
}
template<class T>
@ -270,6 +273,7 @@ void FollowMovementGenerator<T>::Interrupt(T &owner)
{
owner.clearUnitState(UNIT_STAT_FOLLOW|UNIT_STAT_FOLLOW_MOVE);
_updateWalkMode(owner);
_updateSpeed(owner);
}
template<class T>
@ -278,6 +282,24 @@ void FollowMovementGenerator<T>::Reset(T &owner)
Initialize(owner);
}
template<>
void FollowMovementGenerator<Player>::_updateSpeed(Player &u)
{
// nothing to do for Player
}
template<>
void FollowMovementGenerator<Creature>::_updateSpeed(Creature &u)
{
// pet only sync speed with owner
if (!((Creature&)u).isPet() || !i_target.isValid() || i_target->GetGUID() != u.GetOwnerGUID())
return;
u.UpdateSpeed(MOVE_RUN,true);
u.UpdateSpeed(MOVE_WALK,true);
u.UpdateSpeed(MOVE_SWIM,true);
}
//-----------------------------------------------//
template void TargetedMovementGeneratorMedium<Player,ChaseMovementGenerator<Player> >::_setTargetLocation(Player &);
template void TargetedMovementGeneratorMedium<Player,FollowMovementGenerator<Player> >::_setTargetLocation(Player &);

View file

@ -116,6 +116,7 @@ class MANGOS_DLL_SPEC FollowMovementGenerator : public TargetedMovementGenerator
void _reachTarget(T &) {}
private:
void _updateWalkMode(T &u);
void _updateSpeed(T &u);
};
#endif

View file

@ -8400,7 +8400,7 @@ void Unit::SetPet(Pet* pet)
// FIXME: hack, speed must be set only at follow
if(pet && GetTypeId()==TYPEID_PLAYER)
for(int i = 0; i < MAX_MOVE_TYPE; ++i)
pet->SetSpeed(UnitMoveType(i), m_speed_rate[i], true);
pet->SetSpeedRate(UnitMoveType(i), m_speed_rate[i], true);
}
void Unit::SetCharm(Unit* pet)
@ -10428,6 +10428,23 @@ void Unit::UpdateWalkMode(Unit* source, bool self)
void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
{
// not in combat pet have same speed as owner
switch(mtype)
{
case MOVE_RUN:
case MOVE_WALK:
case MOVE_SWIM:
if (GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isPet() && hasUnitState(UNIT_STAT_FOLLOW))
{
if(Unit* owner = GetOwner())
{
SetSpeedRate(mtype,owner->GetSpeedRate(mtype),forced);
return;
}
}
break;
}
int32 main_speed_mod = 0;
float stack_bonus = 1.0f;
float non_stack_bonus = 1.0f;
@ -10519,7 +10536,7 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
if (speed < min_speed)
speed = min_speed;
}
SetSpeed(mtype, speed, forced);
SetSpeedRate(mtype, speed, forced);
}
float Unit::GetSpeed( UnitMoveType mtype ) const
@ -10527,7 +10544,15 @@ float Unit::GetSpeed( UnitMoveType mtype ) const
return m_speed_rate[mtype]*baseMoveSpeed[mtype];
}
void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
struct SetSpeedRateHelper
{
explicit SetSpeedRateHelper(UnitMoveType _mtype, bool _forced) : mtype(_mtype), forced(_forced) {}
void operator()(Unit* unit) const { unit->UpdateSpeed(mtype,forced); }
UnitMoveType mtype;
bool forced;
};
void Unit::SetSpeedRate(UnitMoveType mtype, float rate, bool forced)
{
if (rate < 0)
rate = 0.0f;
@ -10573,7 +10598,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
data.Initialize(MSG_MOVE_SET_PITCH_RATE, 8+4+2+4+4+4+4+4+4+4);
break;
default:
sLog.outError("Unit::SetSpeed: Unsupported move type (%d), data not sent to client.",mtype);
sLog.outError("Unit::SetSpeedRate: Unsupported move type (%d), data not sent to client.",mtype);
return;
}
@ -10628,7 +10653,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
data.Initialize(SMSG_FORCE_PITCH_RATE_CHANGE, 16);
break;
default:
sLog.outError("Unit::SetSpeed: Unsupported move type (%d), data not sent to client.",mtype);
sLog.outError("Unit::SetSpeedRate: Unsupported move type (%d), data not sent to client.",mtype);
return;
}
data.append(GetPackGUID());
@ -10638,8 +10663,11 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
data << float(GetSpeed(mtype));
SendMessageToSet( &data, true );
}
if(Pet* pet = GetPet())
pet->SetSpeed(MOVE_RUN, m_speed_rate[mtype],forced);
if (GetTypeId() == TYPEID_PLAYER) // need include minpet
((Player*)this)->CallForAllControlledUnits(SetSpeedRateHelper(mtype,forced),false,true,true,true);
else
CallForAllControlledUnits(SetSpeedRateHelper(mtype,forced),false,true,true);
}
void Unit::SetHover(bool on)

View file

@ -1561,7 +1561,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void UpdateSpeed(UnitMoveType mtype, bool forced);
float GetSpeed( UnitMoveType mtype ) const;
float GetSpeedRate( UnitMoveType mtype ) const { return m_speed_rate[mtype]; }
void SetSpeed(UnitMoveType mtype, float rate, bool forced = false);
void SetSpeedRate(UnitMoveType mtype, float rate, bool forced = false);
void SetHover(bool on);
bool isHover() const { return HasAuraType(SPELL_AURA_HOVER); }

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "9211"
#define REVISION_NR "9212"
#endif // __REVISION_NR_H__