Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 139 additions & 13 deletions src/game/ConfusedMovementGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include "Creature.h"
#include "Player.h"

#include "VMapFactory.h"

#include "movement/MoveSplineInit.h"
#include "movement/MoveSpline.h"

Expand Down Expand Up @@ -54,36 +56,160 @@ void ConfusedMovementGenerator<UNIT>::Interrupt(UNIT &unit)
template<class UNIT>
void ConfusedMovementGenerator<UNIT>::_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<class UNIT>
bool ConfusedMovementGenerator<UNIT>::Update(UNIT &unit, const uint32 &diff)
template<class Creature>
bool ConfusedMovementGenerator<Creature>::Update(Creature &unit, const uint32 &diff)
{
unit.SetSelection(0);

_nextMoveTime.Update(diff);

if (_nextMoveTime.Passed() || static_cast<MovementGenerator*>(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<MovementGenerator*>(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<MovementGenerator*>(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<MovementGenerator*>(this)->_recalculateTravel = false;
_nextMoveTime.Reset(urand(0, 2000));
return true;
}

template<>
bool ConfusedMovementGenerator<Player>::Update(Player &unit, const uint32 &diff)
{
unit.SetSelection(0);

_nextMoveTime.Update(diff);
if (_nextMoveTime.Passed() || static_cast<MovementGenerator*>(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<MovementGenerator*>(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<MovementGenerator*>(this)->_recalculateTravel = false;
if (unit.IsPolymorphed())
_nextMoveTime.Reset(urand(1500, 2000));
else
{
to_sPos = true;
_nextMoveTime.Reset(urand(800, 1000));
}
}
}

return true;
}

Expand Down
3 changes: 2 additions & 1 deletion src/game/ConfusedMovementGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
115 changes: 100 additions & 15 deletions src/game/FleeingMovementGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,61 @@
#include "Unit.h"
#include "CreatureAIImpl.h"

#include "VMapFactory.h"

#include "movement/MoveSplineInit.h"
#include "movement/MoveSpline.h"

template<class UNIT>
void FleeingMovementGenerator<UNIT>::_moveToNextLocation(UNIT &unit)
template<>
void FleeingMovementGenerator<Creature>::_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<MovementGenerator*>(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<Player>::_moveToNextLocation(Player &unit)
{
Position dest;
if (!_getPoint(unit, dest))
return;

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);

Expand All @@ -49,36 +91,79 @@ void FleeingMovementGenerator<UNIT>::_moveToNextLocation(UNIT &unit)
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);

unit.InterruptNonMeleeSpells(false);

unit.StopMoving();
unit.addUnitState(UNIT_STAT_FLEEING);

_isFirstPoint = true;
unit.GetPosition(_startPosition);
}

template<class UNIT>
Expand Down
5 changes: 4 additions & 1 deletion src/game/FleeingMovementGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<Creature>
Expand Down
6 changes: 5 additions & 1 deletion src/game/HomeMovementGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ void HomeMovementGenerator<Creature>::_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);

Expand Down Expand Up @@ -90,6 +91,9 @@ void HomeMovementGenerator<Creature>::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);
Expand Down
Loading