diff --git a/src/game/ConfusedMovementGenerator.cpp b/src/game/ConfusedMovementGenerator.cpp index 79a657a60..1725ed66a 100644 --- a/src/game/ConfusedMovementGenerator.cpp +++ b/src/game/ConfusedMovementGenerator.cpp @@ -23,6 +23,8 @@ #include "Creature.h" #include "Player.h" +#include "VMapFactory.h" + #include "movement/MoveSplineInit.h" #include "movement/MoveSpline.h" @@ -54,36 +56,160 @@ void ConfusedMovementGenerator::Interrupt(UNIT &unit) template void ConfusedMovementGenerator::_generateMovement(UNIT &unit) { + // Get array of valid points in angle for (uint8 idx = 0; idx < MAX_RANDOM_POINTS; ++idx) - unit.GetValidPointInAngle(_randomPosition[idx], WANDER_DISTANCE, frand(0, 2*M_PI), true, true); + { + Position tmp; + float angle; + if (!unit.IsPolymorphed()) + // For blind/scatter shot and the same spells + angle = frand(-M_PI/4, M_PI/4); + else + // For polymorph + angle = frand(0, M_PI*2); + + unit.GetValidPointInAngle(tmp, WANDER_DISTANCE, angle, true, true); + if (unit.GetExactDist2d(tmp.x, tmp.y) < WANDER_DISTANCE - 0.5f) + for (uint8 j = 0; j < 8; ++j) + { + angle += M_PI/4; + unit.GetValidPointInAngle(tmp, WANDER_DISTANCE, angle, true, true); + + if (unit.GetExactDist2d(tmp.x, tmp.y) < WANDER_DISTANCE - 0.5f) + continue; + else + break; + } + unit.GetValidPointInAngle(rPos[idx], WANDER_DISTANCE, angle, true, true); + } } -template -bool ConfusedMovementGenerator::Update(UNIT &unit, const uint32 &diff) +template +bool ConfusedMovementGenerator::Update(Creature &unit, const uint32 &diff) { unit.SetSelection(0); _nextMoveTime.Update(diff); + if (_nextMoveTime.Passed() || static_cast(this)->_recalculateTravel) { uint32 nextMove = urand(0, MAX_RANDOM_POINTS-1); Movement::MoveSplineInit init(unit); - PathFinder path(&unit); - path.setPathLengthLimit(30.0f); - bool result = path.calculate(_randomPosition[nextMove].x, _randomPosition[nextMove].y, _randomPosition[nextMove].z); - if (!result || path.getPathType() & PATHFIND_NOPATH) - init.MoveTo(_randomPosition[nextMove].x, _randomPosition[nextMove].y, _randomPosition[nextMove].z); + if (to_sPos && !unit.IsPolymorphed()) + { + PathFinder path(&unit); + path.setPathLengthLimit(30.0f); + + bool resultHitPosition; + resultHitPosition = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(unit.GetMapId(), unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZ() + 0.5f, rPos[nextMove].x, rPos[nextMove].y, rPos[nextMove].z + 0.5f, rPos[nextMove].x, rPos[nextMove].y, rPos[nextMove].z, -0.5f); + resultHitPosition = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(unit.GetMapId(), unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZ() + 0.5f, sPos.x, sPos.y, sPos.z + 0.5f, sPos.x, sPos.y, sPos.z, -0.5f); + + bool result = path.calculate(sPos.x, sPos.y, sPos.z); + if (!result || path.getPathType() & PATHFIND_NOPATH) + init.MoveTo(rPos[nextMove].x, rPos[nextMove].y, rPos[nextMove].z); + else + init.MovebyPath(path.getPath()); + + init.SetWalk(true); + init.Launch(); + + static_cast(this)->_recalculateTravel = false; + _nextMoveTime.Reset(urand(800, 1000)); + + to_sPos = false; + } else - init.MovebyPath(path.getPath()); + { + PathFinder path(&unit); + path.setPathLengthLimit(30.0f); + + bool resultHitPosition; + resultHitPosition = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(unit.GetMapId(), unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZ() + 0.5f, rPos[nextMove].x, rPos[nextMove].y, rPos[nextMove].z + 0.5f, rPos[nextMove].x, rPos[nextMove].y, rPos[nextMove].z, -0.5f); + + bool result = path.calculate(rPos[nextMove].x, rPos[nextMove].y, rPos[nextMove].z); + if (!result || path.getPathType() & PATHFIND_NOPATH) + init.MoveTo(rPos[nextMove].x, rPos[nextMove].y, rPos[nextMove].z); + else + init.MovebyPath(path.getPath()); + + init.SetWalk(true); + init.Launch(); + + static_cast(this)->_recalculateTravel = false; + if (unit.IsPolymorphed()) + _nextMoveTime.Reset(urand(1500, 2000)); + else + { + to_sPos = true; + _nextMoveTime.Reset(urand(800, 1000)); + } + } + } - init.SetWalk(true); - init.Launch(); + ((Creature*)&unit)->SetNoCallAssistance(false); + ((Creature*)&unit)->CallAssistance(); - static_cast(this)->_recalculateTravel = false; - _nextMoveTime.Reset(urand(0, 2000)); + return true; +} + +template<> +bool ConfusedMovementGenerator::Update(Player &unit, const uint32 &diff) +{ + unit.SetSelection(0); + + _nextMoveTime.Update(diff); + if (_nextMoveTime.Passed() || static_cast(this)->_recalculateTravel) + { + uint32 nextMove = urand(0, MAX_RANDOM_POINTS-1); + + Movement::MoveSplineInit init(unit); + + if (to_sPos && !unit.IsPolymorphed()) + { + PathFinder path(&unit); + path.setPathLengthLimit(30.0f); + + bool result = path.calculate(sPos.x, sPos.y, sPos.z); + if (!result || path.getPathType() & PATHFIND_NOPATH) + init.MoveTo(rPos[nextMove].x, rPos[nextMove].y, rPos[nextMove].z); + else + init.MovebyPath(path.getPath()); + + init.SetWalk(true); + init.Launch(); + + static_cast(this)->_recalculateTravel = false; + _nextMoveTime.Reset(urand(800, 1000)); + + to_sPos = false; + } + else + { + PathFinder path(&unit); + path.setPathLengthLimit(30.0f); + + bool result = path.calculate(rPos[nextMove].x, rPos[nextMove].y, rPos[nextMove].z); + if (!result || path.getPathType() & PATHFIND_NOPATH) + init.MoveTo(rPos[nextMove].x, rPos[nextMove].y, rPos[nextMove].z); + else + init.MovebyPath(path.getPath()); + + init.SetWalk(true); + init.Launch(); + + static_cast(this)->_recalculateTravel = false; + if (unit.IsPolymorphed()) + _nextMoveTime.Reset(urand(1500, 2000)); + else + { + to_sPos = true; + _nextMoveTime.Reset(urand(800, 1000)); + } + } } + return true; } diff --git a/src/game/ConfusedMovementGenerator.h b/src/game/ConfusedMovementGenerator.h index 982d3f3f0..cf2a17557 100644 --- a/src/game/ConfusedMovementGenerator.h +++ b/src/game/ConfusedMovementGenerator.h @@ -49,7 +49,8 @@ class LOOKING4GROUP_EXPORT ConfusedMovementGenerator : public MovementGeneratorM TimeTrackerSmall _nextMoveTime; - Position _randomPosition[MAX_RANDOM_POINTS+1]; + Position sPos, rPos[MAX_RANDOM_POINTS+1]; + bool to_sPos; }; #endif diff --git a/src/game/FleeingMovementGenerator.cpp b/src/game/FleeingMovementGenerator.cpp index 167caac42..ae3d60543 100644 --- a/src/game/FleeingMovementGenerator.cpp +++ b/src/game/FleeingMovementGenerator.cpp @@ -23,11 +23,51 @@ #include "Unit.h" #include "CreatureAIImpl.h" +#include "VMapFactory.h" + #include "movement/MoveSplineInit.h" #include "movement/MoveSpline.h" -template -void FleeingMovementGenerator::_moveToNextLocation(UNIT &unit) +template<> +void FleeingMovementGenerator::_moveToNextLocation(Creature &unit) +{ + Position dest; + if (!_getPoint(unit, dest)) + return; + + PathFinder path(&unit); + path.setPathLengthLimit(30.0f); + + bool resultHitPosition; + resultHitPosition = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(unit.GetMapId(), unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZ() + 0.5f, dest.x, dest.y, dest.z + 0.5f, dest.x, dest.y, dest.z, -0.5f); + + bool result = path.calculate(dest.x, dest.y, dest.z); + + if (!result || path.getPathType() & PATHFIND_NOPATH) + unit.GetPosition(dest); + + Movement::MoveSplineInit init(unit); + if (path.getPathType() & PATHFIND_NOPATH) + init.MoveTo(dest.x, dest.y, dest.z); + else + init.MovebyPath(path.getPath()); + + init.SetWalk(false); + init.Launch(); + + static_cast(this)->_recalculateTravel = false; + + if (unit.GetExactDist2d(_startPosition.x, _startPosition.y) > 30.0f) + _nextCheckTime.Reset(2000); + else + _nextCheckTime.Reset(0); + + ((Creature*)&unit)->SetNoCallAssistance(false); + ((Creature*)&unit)->CallAssistance(); +} + +template<> +void FleeingMovementGenerator::_moveToNextLocation(Player &unit) { Position dest; if (!_getPoint(unit, dest)) @@ -35,7 +75,9 @@ void FleeingMovementGenerator::_moveToNextLocation(UNIT &unit) PathFinder path(&unit); path.setPathLengthLimit(30.0f); - bool result = path.calculate(dest.x, dest.y, dest.z); + + bool result = path.calculate(dest.x, dest.y, dest.z); + if (!result || path.getPathType() & PATHFIND_NOPATH) unit.GetPosition(dest); @@ -49,29 +91,69 @@ void FleeingMovementGenerator::_moveToNextLocation(UNIT &unit) init.Launch(); static_cast(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 bool FleeingMovementGenerator::_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 void FleeingMovementGenerator::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); @@ -79,6 +161,9 @@ void FleeingMovementGenerator::Initialize(UNIT &unit) unit.StopMoving(); unit.addUnitState(UNIT_STAT_FLEEING); + + _isFirstPoint = true; + unit.GetPosition(_startPosition); } template diff --git a/src/game/FleeingMovementGenerator.h b/src/game/FleeingMovementGenerator.h index e1cd3141f..6755f543a 100644 --- a/src/game/FleeingMovementGenerator.h +++ b/src/game/FleeingMovementGenerator.h @@ -44,9 +44,12 @@ class FleeingMovementGenerator : public MovementGeneratorMedium< UNIT, FleeingMo void _moveToNextLocation(UNIT &); bool _getPoint(UNIT &, Position &); - float _angle; + float _angle, _angle_rand; uint64 _frightGUID; TimeTracker _nextCheckTime; + + bool _isFirstPoint; + Position _startPosition; }; class TimedFleeingMovementGenerator : public FleeingMovementGenerator diff --git a/src/game/HomeMovementGenerator.cpp b/src/game/HomeMovementGenerator.cpp index da9b2a226..655e4a95c 100644 --- a/src/game/HomeMovementGenerator.cpp +++ b/src/game/HomeMovementGenerator.cpp @@ -50,7 +50,8 @@ void HomeMovementGenerator::_setTargetLocation(Creature & owner) // at apply we can select more nice return points base at current move generator owner.GetHomePosition(x, y, z, o); - PathFinder* _path = new PathFinder(&owner); + if (!_path) + _path = new PathFinder(&owner); bool result = _path->calculate(x, y, z, true); @@ -90,6 +91,9 @@ void HomeMovementGenerator::Finalize(Creature& owner) owner.SetWalk(true); owner.LoadCreaturesAddon(true); + owner.SetNoSearchAssistance(false); + owner.UpdateSpeed(MOVE_RUN, false); + owner.AI()->JustReachedHome(); BasicEvent* event = new RestoreReactState(owner); diff --git a/src/game/HomeMovementGenerator.h b/src/game/HomeMovementGenerator.h index eea9b4119..906e79f3e 100644 --- a/src/game/HomeMovementGenerator.h +++ b/src/game/HomeMovementGenerator.h @@ -32,8 +32,8 @@ template <> class LOOKING4GROUP_IMPORT_EXPORT HomeMovementGenerator : public MovementGeneratorMedium< Creature, HomeMovementGenerator > { public: - HomeMovementGenerator() : arrived(false) {} - ~HomeMovementGenerator() {} + HomeMovementGenerator() : arrived(false), _path(NULL) {} + ~HomeMovementGenerator() { delete _path; } void Initialize(Creature &); void Finalize(Creature &); @@ -47,6 +47,7 @@ class LOOKING4GROUP_IMPORT_EXPORT HomeMovementGenerator : public Movem private: void _setTargetLocation(Creature &); bool arrived; + PathFinder* _path; }; #endif diff --git a/src/game/PointMovementGenerator.cpp b/src/game/PointMovementGenerator.cpp index 517a8b89f..766715289 100644 --- a/src/game/PointMovementGenerator.cpp +++ b/src/game/PointMovementGenerator.cpp @@ -116,6 +116,12 @@ void AssistanceMovementGenerator::Finalize(Unit &unit) ((Creature*)&unit)->CallAssistance(); if (unit.isAlive()) unit.GetMotionMaster()->MoveSeekAssistanceDistract(sWorld.getConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY)); + + if (Creature *creature = unit.ToCreature()) + { + creature->SetNoSearchAssistance(false); + creature->UpdateSpeed(MOVE_RUN, false); + } } bool EffectMovementGenerator::Update(Unit &unit, const uint32 &) diff --git a/src/game/RandomMovementGenerator.cpp b/src/game/RandomMovementGenerator.cpp index 55b107598..93872f6d9 100644 --- a/src/game/RandomMovementGenerator.cpp +++ b/src/game/RandomMovementGenerator.cpp @@ -45,6 +45,9 @@ void RandomMovementGenerator::_setRandomLocation(Creature &creature) static_cast(this)->_recalculateTravel = false; i_nextMoveTime.Reset(urand(500, 10000)); + + creature.SetNoCallAssistance(false); + creature.CallAssistance(); } template<>