[11543] Fixed change form to same (powershifting)

Inspired by patch provided by darkstalker.

Client expected receive form field change at form switing including case with switch to same form.
In fact problem too good mangos optimization in part avoid send unchanged values in update fields.

* Added function Object::SendForcedObjectUpdate()
* It used in form apply code for make sure received by client non-form applied state in middle form shifting state.
* It also used for fishing code when client also expected received some update fields chnages before
  animation update. New function send update to all all client instead before used code that send it to fishing player
  and resend later one more time to other players and player itself as normal update.
This commit is contained in:
VladimirMangos 2011-05-26 17:09:09 +04:00
parent 81984732a3
commit c5b6cc0b37
5 changed files with 50 additions and 31 deletions

View file

@ -190,11 +190,7 @@ void GameObject::Update(uint32 update_diff, uint32 /*p_time*/)
SetGoState(GO_STATE_ACTIVE);
// SetUInt32Value(GAMEOBJECT_FLAGS, GO_FLAG_NODESPAWN);
UpdateData udata;
WorldPacket packet;
BuildValuesUpdateBlockForPlayer(&udata,((Player*)caster));
udata.BuildPacket(&packet);
((Player*)caster)->GetSession()->SendPacket(&packet);
SendForcedObjectUpdate();
SendGameObjectCustomAnim(GetObjectGuid());
}

View file

@ -108,6 +108,25 @@ void Object::SetObjectScale(float newScale)
SetFloatValue(OBJECT_FIELD_SCALE_X, newScale);
}
void Object::SendForcedObjectUpdate()
{
if (!m_inWorld || !m_objectUpdated)
return;
UpdateDataMapType update_players;
BuildUpdateData(update_players);
RemoveFromClientUpdateList();
WorldPacket packet; // here we allocate a std::vector with a size of 0x10000
for(UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter)
{
iter->second.BuildPacket(&packet);
iter->first->GetSession()->SendPacket(&packet);
packet.clear(); // clean the string
}
}
void Object::BuildMovementUpdateBlock(UpdateData * data, uint16 flags ) const
{
ByteBuffer buf(500);

View file

@ -164,6 +164,7 @@ class MANGOS_DLL_SPEC Object
virtual void RemoveFromClientUpdateList();
virtual void BuildUpdateData(UpdateDataMapType& update_players);
void MarkForClientUpdate();
void SendForcedObjectUpdate();
void BuildValuesUpdateBlockForPlayer( UpdateData *data, Player *target ) const;
void BuildOutOfRangeUpdateBlock( UpdateData *data ) const;

View file

@ -3203,25 +3203,8 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
}
}
// now only powertype must be set
switch(form)
{
case FORM_CAT:
PowerType = POWER_ENERGY;
break;
case FORM_BEAR:
case FORM_DIREBEAR:
case FORM_BATTLESTANCE:
case FORM_BERSERKERSTANCE:
case FORM_DEFENSIVESTANCE:
PowerType = POWER_RAGE;
break;
default:
break;
}
// remove polymorph before changing display id to keep new display id
switch ( form )
switch (form)
{
case FORM_CAT:
case FORM_TREE:
@ -3258,7 +3241,7 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
}
// and polymorphic affects
if(target->IsPolymorphed())
if (target->IsPolymorphed())
target->RemoveAurasDueToSpell(target->getTransForm());
break;
@ -3267,21 +3250,41 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
break;
}
if(apply)
if (apply)
{
// remove other shapeshift before applying a new one
target->RemoveSpellsCausingAura(SPELL_AURA_MOD_SHAPESHIFT, GetHolder());
if(modelid > 0)
// need send to client not form active state, or at re-apply form client go crazy
target->SendForcedObjectUpdate();
if (modelid > 0)
target->SetDisplayId(modelid);
if(PowerType != POWER_MANA)
// now only powertype must be set
switch (form)
{
case FORM_CAT:
PowerType = POWER_ENERGY;
break;
case FORM_BEAR:
case FORM_DIREBEAR:
case FORM_BATTLESTANCE:
case FORM_BERSERKERSTANCE:
case FORM_DEFENSIVESTANCE:
PowerType = POWER_RAGE;
break;
default:
break;
}
if (PowerType != POWER_MANA)
{
// reset power to default values only at power change
if(target->getPowerType() != PowerType)
if (target->getPowerType() != PowerType)
target->setPowerType(PowerType);
switch(form)
switch (form)
{
case FORM_CAT:
case FORM_BEAR:
@ -3290,7 +3293,7 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)
// get furor proc chance
int32 furorChance = 0;
Unit::AuraList const& mDummy = target->GetAurasByType(SPELL_AURA_DUMMY);
for(Unit::AuraList::const_iterator i = mDummy.begin(); i != mDummy.end(); ++i)
for (Unit::AuraList::const_iterator i = mDummy.begin(); i != mDummy.end(); ++i)
{
if ((*i)->GetSpellProto()->SpellIconID == 238)
{

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "11542"
#define REVISION_NR "11543"
#endif // __REVISION_NR_H__