Index: game/ConfusedMovementGenerator.cpp =================================================================== --- game/ConfusedMovementGenerator.cpp (revision 5427) +++ game/ConfusedMovementGenerator.cpp (working copy) @@ -99,7 +99,7 @@ { if(!&unit) return true; - if(unit.hasUnitState(UNIT_STAT_ROOT) || unit.hasUnitState(UNIT_STAT_STUNDED)) + if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED)) return true; if( i_nextMoveTime.Passed() ) Index: game/HomeMovementGenerator.cpp =================================================================== --- game/HomeMovementGenerator.cpp (revision 5427) +++ game/HomeMovementGenerator.cpp (working copy) @@ -43,7 +43,7 @@ if( !&owner )asd return; - if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED) ) + if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED) ) return; float x, y, z; Index: game/MotionMaster.cpp =================================================================== --- game/MotionMaster.cpp (revision 5427) +++ game/MotionMaster.cpp (working copy) @@ -69,7 +69,7 @@ void MotionMaster::UpdateMotion(const uint32 &diff) { - if(i_owner->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED)) + if(i_owner->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED)) return; assert( !empty() ); if (!top()->Update(*i_owner, diff)) Index: game/Object.cpp =================================================================== --- game/Object.cpp (revision 5427) +++ game/Object.cpp (working copy) @@ -1243,7 +1243,7 @@ float x,y,z; - if( !c->isAlive() || c->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED) || c->GetMotionMaster()->top()->GetMovementGeneratorType() != TARGETED_MOTION_TYPE || + if( !c->isAlive() || c->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED) || c->GetMotionMaster()->top()->GetMovementGeneratorType() != TARGETED_MOTION_TYPE || !((TargetedMovementGenerator*)(c->GetMotionMaster()->top()))->GetDestination(x,y,z) ) { x = c->GetPositionX(); Index: game/RandomMovementGenerator.cpp =================================================================== --- game/RandomMovementGenerator.cpp (revision 5427) +++ game/RandomMovementGenerator.cpp (working copy) @@ -103,7 +103,7 @@ { if(!&creature) return true; - if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED)) + if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED)) return true; i_nextMoveTime.Update(diff); #ifdef USE_INTERPOLATION Index: game/SpellEffects.cpp =================================================================== --- game/SpellEffects.cpp (revision 5427) +++ game/SpellEffects.cpp (working copy) @@ -2533,29 +2533,31 @@ void Spell::EffectDistract(uint32 /*i*/) { //Check for possible target - if (!unitTarget) + if (!unitTarget || unitTarget->isInCombat()) return; - #if 0 - ToDo - Dont use Relocate here !!! - int32 levelDiff = int32(m_caster->getLevel()) - int32(unitTarget->getLevel()); + + // target must be OK to do this + if( unitTarget->hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNDED | UNIT_STAT_FLEEING) ) + return; - //If there is a victim to distract - if ((levelDiff > -5) && unitTarget->IsHostileTo(m_caster)) - { - // Gets angle of distract epicenter / target - float angle = unitTarget->GetAngle(m_targets.m_destX, m_targets.m_destY); + float angle = unitTarget->GetAngle(m_targets.m_destX, m_targets.m_destY); - //Set proper orientation - unitTarget->SetOrientation(angle); - Creature& pUnit = *((Creature *)unitTarget); - // Update animation if target is creature and player removed previous check + // For players just turn them + if ( unitTarget->GetTypeId() == TYPEID_PLAYER ) + { + WorldPacket data; + ((Player*)unitTarget)->BuildTeleportAckMsg(&data, unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), angle); + ((Player*)unitTarget)->GetSession()->SendPacket( &data ); + ((Player*)unitTarget)->SetPosition(unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), angle, false); + return; + } - ((Creature *)unitTarget)->StopMoving() ; - unitTarget->Relocate(unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetOrientation()); - ((Creature *)unitTarget)->StopMoving() ; - } - #endif + // Set creature Distracted, Stop it, And turn it + unitTarget->SetOrientation(angle); + ((Creature *)unitTarget)->StopMoving(); + unitTarget->addUnitState(UNIT_STAT_DISTRACTED); + unitTarget->m_distractTime = damage*1000; + } void Spell::EffectPickPocket(uint32 /*i*/) Index: game/TargetedMovementGenerator.cpp =================================================================== --- game/TargetedMovementGenerator.cpp (revision 5427) +++ game/TargetedMovementGenerator.cpp (working copy) @@ -46,7 +46,7 @@ if( !i_target.isValid() || !&owner ) return; - if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED) ) + if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED) ) return; // prevent redundant micro-movement for pets, other followers. @@ -107,7 +107,7 @@ if( !&owner || !owner.isAlive()) return true; - if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_FLEEING) ) + if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED) ) return true; if( !owner.isInCombat() && !owner.hasUnitState(UNIT_STAT_FOLLOW) ) { Index: game/Unit.cpp =================================================================== --- game/Unit.cpp (revision 5427) +++ game/Unit.cpp (working copy) @@ -292,6 +292,15 @@ ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, GetHealth() < GetMaxHealth()*0.35f); i_motionMaster.UpdateMotion(p_time); + + // Update Distract State + if (hasUnitState(UNIT_STAT_DISTRACTED)) + { + if (m_distractTime <= p_time || isInCombat()) + clearUnitState(UNIT_STAT_DISTRACTED); + else + m_distractTime -= p_time; + } } bool Unit::haveOffhandWeapon() const Index: game/Unit.h =================================================================== --- game/Unit.h (revision 5427) +++ game/Unit.h (working copy) @@ -306,6 +306,7 @@ UNIT_STAT_FOLLOW = 512, UNIT_STAT_ROOT = 1024, UNIT_STAT_CONFUSED = 2048, + UNIT_STAT_DISTRACTED = 4096, UNIT_STAT_ALL_STATE = 0xffff //(UNIT_STAT_STOPPED | UNIT_STAT_MOVING | UNIT_STAT_IN_COMBAT | UNIT_STAT_IN_FLIGHT) }; @@ -608,7 +609,7 @@ bool CanFreeMove() const { return !hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING | UNIT_STAT_IN_FLIGHT | - UNIT_STAT_ROOT | UNIT_STAT_STUNDED ) && GetOwnerGUID()==0; + UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED ) && GetOwnerGUID()==0; } uint32 getLevel() const { return GetUInt32Value(UNIT_FIELD_LEVEL); }; @@ -1025,6 +1026,8 @@ void StartReactiveTimer( ReactiveType reactive ) { m_reactiveTimer[reactive] = REACTIVE_TIMER_START;} void UpdateReactives(uint32 p_time); + // distract effect + int32 m_distractTime; protected: explicit Unit ( WorldObject *instantiator ); Index: game/WaypointMovementGenerator.cpp =================================================================== --- game/WaypointMovementGenerator.cpp (revision 5427) +++ game/WaypointMovementGenerator.cpp (working copy) @@ -181,7 +181,7 @@ // Waypoint movement can be switched on/off // This is quite handy for escort quests and other stuff - if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED)) + if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED)) return true; // prevent crash at empty waypoint path.