# HG changeset patch
# User alexandro
# Date 1391535216 -21600
# Branch trunk
# Node ID d55146f05e700115d21c445dba17983941a45b77
# Parent  0ab1e96015f2b6ef5518a8606fcd2b7c9d4b34f5
Renew fear movement /by clanat/

diff --git a/src/game/FleeingMovementGenerator.cpp b/src/game/FleeingMovementGenerator.cpp
--- a/src/game/FleeingMovementGenerator.cpp
+++ b/src/game/FleeingMovementGenerator.cpp
@@ -50,29 +50,70 @@
     init.Launch();
 
     static_cast<MovementGenerator*>(this)->_recalculateTravel = false;
-    _nextCheckTime.Reset(urand(500,1000));
+
+    if (unit.GetExactDist2d(_startPosition.x, _startPosition.y) > 30.0f)
+        _nextCheckTime.Reset(2000);
+    else
+        _nextCheckTime.Reset(0);
 }
 
 template<class UNIT>
 bool FleeingMovementGenerator<UNIT>::_getPoint(UNIT &unit, Position &dest)
 {
-    // _angle is orientation for running like hell from caster in straight line :p
-    float angle = _angle;
-    if (roll_chance_i(20))
-        angle += RAND(M_PI/4.0f, M_PI/2.0f, -M_PI/4.0f, -M_PI/2.0f, M_PI*3/4.0f, -M_PI*3/4.0f, M_PI);
+    Position tmp;
+    float angle_inc = 0.0f;
+    float angle_dec = 0.0f;
 
-    // destination point
-    unit.GetValidPointInAngle(dest, 8.0f, angle, true, true);
-    return true;
+    // If distance from start position > 30.0f, get random angle (blizzlike)
+    if (unit.GetExactDist2d(_startPosition.x, _startPosition.y) > 30.0f)
+        _angle_rand = frand(0, M_PI * 2.0f);
+    else
+        _angle_rand = 0.0f;
+
+    // Get temp point (for check)
+    unit.GetValidPointInAngle(tmp, 12.0f, _isFirstPoint ? _angle : _angle_rand, true, true);
+
+    // Get correct angle (for destination point)
+    if (unit.GetExactDist2d(tmp.x, tmp.y) < 10.0f)
+    {
+        for (uint8 i = 0; i < 6; ++i)
+        {
+            angle_inc += M_PI/6;
+            unit.GetValidPointInAngle(tmp, 9.5f, angle_inc, true, true);
+            if (unit.GetExactDist2d(tmp.x, tmp.y) < 9.0f || fabs(_startPosition.z - tmp.z) > COMMON_ALLOW_HEIGHT_DIFF)
+                continue;
+            else
+                break;
+        }
+        for (uint8 i = 0; i < 6; ++i)
+        {
+            angle_dec -= M_PI/6;
+            unit.GetValidPointInAngle(tmp, 9.5f, angle_dec, true, true);
+            if (unit.GetExactDist2d(tmp.x, tmp.y) < 9.0f || fabs(_startPosition.z - tmp.z) > COMMON_ALLOW_HEIGHT_DIFF)
+                continue;
+            else
+                break;
+        }
+
+        // Get destination point with correct angle
+        unit.GetValidPointInAngle(dest, 8.0f, angle_inc < -angle_dec ? angle_inc : angle_dec, true, true);
+        _isFirstPoint = false;
+        return true;
+    }
+    else
+    {
+        unit.GetValidPointInAngle(dest, 8.0f, _isFirstPoint ? _angle : _angle_rand, true, true);
+
+        _isFirstPoint = false;
+        return true;
+    }
 }
 
 template<class UNIT>
 void FleeingMovementGenerator<UNIT>::Initialize(UNIT &unit)
 {
-    if (Unit* pFright = unit.GetUnit(_frightGUID))
-        _angle = pFright->GetAngle(&unit);
-    else
-        _angle = unit.GetOrientation();
+
+    _angle = frand(0, M_PI * 2.0f);
 
     _nextCheckTime.Reset(0);
 
@@ -80,6 +121,9 @@
 
     unit.StopMoving();
     unit.addUnitState(UNIT_STAT_FLEEING);
+
+    _isFirstPoint = true;
+    unit.GetPosition(_startPosition);
 }
 
 template<class UNIT>
diff --git a/src/game/FleeingMovementGenerator.h b/src/game/FleeingMovementGenerator.h
--- a/src/game/FleeingMovementGenerator.h
+++ b/src/game/FleeingMovementGenerator.h
@@ -44,9 +44,12 @@
         void _moveToNextLocation(UNIT &);
         bool _getPoint(UNIT &, Position &);
 
-        float _angle;
+        float _angle, _angle_rand;
         uint64 _frightGUID;
         TimeTracker _nextCheckTime;
+
+        bool _isFirstPoint;
+        Position _startPosition;
 };
 
 class HELLGROUND_DLL_SPEC TimedFleeingMovementGenerator : public FleeingMovementGenerator<Creature>