Index: game/SpellAuras.cpp =================================================================== --- game/SpellAuras.cpp (revision 5370) +++ game/SpellAuras.cpp (working copy) @@ -2755,10 +2755,34 @@ if(m_modifier.m_amount<=1) return; - float rate = (100.0f + m_modifier.m_amount)/100.0f; + // no need to handle it now + if(m_modifier.m_amount < m_target->GetSpeedMod(MOD_SPEED)) + return; - m_target->ApplySpeedMod(MOVE_RUN, rate, true, apply ); + if ( apply ) + { + m_target->SetSpeedMod(MOD_SPEED, m_modifier.m_amount); + } + // find another best effect + else + { + float unapplyRate = (100.0f + m_target->GetSpeedMod(MOD_SPEED))/100.0f; + m_target->ApplySpeedMod(MOVE_RUN, unapplyRate, true, apply ); + m_target->SetSpeedMod(MOD_SPEED, 0); + Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_SPEED); + for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + if ((*itr)->GetModifier()->m_amount > m_target->GetSpeedMod(MOD_SPEED)) + m_target->SetSpeedMod(MOD_SPEED, (*itr)->GetModifier()->m_amount); + + if ( m_target->GetSpeedMod(MOD_SPEED) <= 0 ) + return; + } + + float rate = (100.0f + m_target->GetSpeedMod(MOD_SPEED))/100.0f; + + m_target->ApplySpeedMod(MOVE_RUN, rate, true, true ); + sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_RUN)); } @@ -2789,10 +2813,35 @@ if(m_modifier.m_amount<=1) return; - float rate = (100.0f + m_modifier.m_amount)/100.0f; + // no need to handle it now + if(m_modifier.m_amount < m_target->GetSpeedMod(MOD_SPEED)) + return; - m_target->ApplySpeedMod(MOVE_MOUNTED, rate, true, apply ); + if ( apply ) + { + m_target->SetSpeedMod(MOD_SPEED_MOUNT, m_modifier.m_amount); + } + // find another best effect + else + { + float unapplyRate = (100.0f + m_target->GetSpeedMod(MOD_SPEED_MOUNT))/100.0f; + m_target->ApplySpeedMod(MOVE_MOUNTED, unapplyRate, true, apply ); + m_target->SetSpeedMod(MOD_SPEED_MOUNT, 0); + Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED); + for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + if ((*itr)->GetModifier()->m_amount > m_target->GetSpeedMod(MOD_SPEED_MOUNT)) + m_target->SetSpeedMod(MOD_SPEED_MOUNT, (*itr)->GetModifier()->m_amount); + + if ( m_target->GetSpeedMod(MOD_SPEED_MOUNT) <= 0 ) + return; + } + + + float rate = (100.0f + m_target->GetSpeedMod(MOD_SPEED_MOUNT))/100.0f; + + m_target->ApplySpeedMod(MOVE_MOUNTED, rate, true, true ); + sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_MOUNTED)); } @@ -2803,20 +2852,50 @@ return; sLog.outDebug("HandleAuraModDecreaseSpeed: Current Speed:%f \tmodify percent:%f", m_target->GetSpeed(MOVE_RUN),(float)m_modifier.m_amount); - if(m_modifier.m_amount <= 0) - { //for new spell dbc - float rate = (100.0f + m_modifier.m_amount)/100.0f; + + // convert to negative + int32 modAmmount=0; + if(m_modifier.m_amount > 0 ) + modAmmount = m_modifier.m_amount - 100; + else + modAmmount = m_modifier.m_amount; - m_target->ApplySpeedMod(MOVE_RUN, rate, true, apply ); - m_target->ApplySpeedMod(MOVE_MOUNTED, rate, true, apply ); + // don't care now + if ( modAmmount >= m_target->GetSpeedMod(MOD_SPEED_SNARE)) + return; + + if ( apply ) + { + m_target->SetSpeedMod(MOD_SPEED_SNARE, m_modifier.m_amount); + } + + // find another best effect + else + { + float unapplyRate = (100.0f + m_target->GetSpeedMod(MOD_SPEED_SNARE))/100.0f; + m_target->ApplySpeedMod(MOVE_RUN, unapplyRate, true, apply ); + m_target->ApplySpeedMod(MOVE_MOUNTED, unapplyRate, true, apply ); + m_target->SetSpeedMod(MOD_SPEED_SNARE, 0); + + Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_DECREASE_SPEED); + for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + { + if ( (*itr)->GetModifier()->m_amount > 0 ) + if (((*itr)->GetModifier()->m_amount - 100) < m_target->GetSpeedMod(MOD_SPEED_SNARE)) + m_target->SetSpeedMod(MOD_SPEED_SNARE, (*itr)->GetModifier()->m_amount-100); + else if ((*itr)->GetModifier()->m_amount < m_target->GetSpeedMod(MOD_SPEED_SNARE)) + m_target->SetSpeedMod(MOD_SPEED_SNARE, (*itr)->GetModifier()->m_amount); + } + + if ( m_target->GetSpeedMod(MOD_SPEED_SNARE) >= 0 ) + return; } - else - { //for old spell dbc - float rate = m_modifier.m_amount / 100.0f; - m_target->ApplySpeedMod(MOVE_RUN, rate, true, apply ); - m_target->ApplySpeedMod(MOVE_MOUNTED, rate, true, apply ); - } + float rate = (100.0f + m_target->GetSpeedMod(MOD_SPEED_SNARE))/100.0f; + + m_target->ApplySpeedMod(MOVE_RUN, rate, true, true ); + m_target->ApplySpeedMod(MOVE_MOUNTED, rate, true, true ); + sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_RUN)); } @@ -2830,10 +2909,30 @@ if(m_modifier.m_amount<=1) return; - float rate = (100.0f + m_modifier.m_amount)/100.0f; + if ( apply ) + { + m_target->SetSpeedMod(MOD_SPEED_SWIM, m_modifier.m_amount); + } + // find another best effect + else + { + float unapplyRate = (100.0f + m_target->GetSpeedMod(MOD_SPEED_SWIM))/100.0f; + m_target->ApplySpeedMod(MOVE_SWIM, unapplyRate, true, apply ); + m_target->SetSpeedMod(MOD_SPEED_SWIM, 0); - m_target->ApplySpeedMod(MOVE_SWIM, rate, true, apply ); + Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_SWIM_SPEED); + for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + if ((*itr)->GetModifier()->m_amount > m_target->GetSpeedMod(MOD_SPEED_SWIM)) + m_target->SetSpeedMod(MOD_SPEED_SWIM, (*itr)->GetModifier()->m_amount); + if ( m_target->GetSpeedMod(MOD_SPEED_SWIM) <= 0 ) + return; + } + + float rate = (100.0f + m_target->GetSpeedMod(MOD_SPEED_SWIM))/100.0f; + + m_target->ApplySpeedMod(MOVE_SWIM, rate, true, true ); + sLog.outDebug("ChangeSpeedTo:%f", m_target->GetSpeed(MOVE_SWIM)); } Index: game/Unit.h =================================================================== --- game/Unit.h (revision 5370) +++ game/Unit.h (working copy) @@ -309,6 +309,15 @@ UNIT_STAT_ALL_STATE = 0xffff //(UNIT_STAT_STOPPED | UNIT_STAT_MOVING | UNIT_STAT_IN_COMBAT | UNIT_STAT_IN_FLIGHT) }; +enum SpeedModType +{ + MOD_SPEED = 0, + MOD_SPEED_SNARE = 1, + MOD_SPEED_MOUNT = 2, + MOD_SPEED_SWIM = 3, + MAX_SPEEDMOD_TYPE = 4 +}; + enum UnitMoveType { MOVE_WALK = 0, @@ -975,6 +984,8 @@ uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage); void CalcAbsorbResist(Unit *pVictim, SpellSchools school, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist); + int32 GetSpeedMod( SpeedModType modtype ) const { return m_speed_mods[modtype]; } + void SetSpeedMod( SpeedModType modtype, int32 ammount ) { m_speed_mods[modtype] = ammount; } float GetSpeed( UnitMoveType mtype ) const; float GetSpeedRate( UnitMoveType mtype ) const { return m_speed_rate[mtype]; } void SetSpeed(UnitMoveType mtype, float rate, bool forced = false); @@ -1056,6 +1067,7 @@ bool m_canModifyStats; //std::list< spellEffectPair > AuraSpells[TOTAL_AURAS]; // TODO: use this if ok for mem + int32 m_speed_mods[MAX_SPEEDMOD_TYPE]; float m_speed_rate[MAX_MOVE_TYPE]; CharmInfo *m_charmInfo;