diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp index 4c269a1024ad7..4af5f7b4acb98 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp @@ -70,18 +70,26 @@ bool ConfusedMovementGenerator::Update(T* unit, const uint32& diff) // start moving unit->AddUnitState(UNIT_STATE_CONFUSED_MOVE); - float x = i_x + 10.0f*((float)rand_norm() - 0.5f); - float y = i_y + 10.0f*((float)rand_norm() - 0.5f); - float z = i_z; + float x = i_x + (4.0f * (float)rand_norm() - 2.0f); + float y = i_y + (4.0f * (float)rand_norm() - 2.0f); - unit->UpdateAllowedPositionZ(x, y, z); + Trinity::NormalizeMapCoord(x); + Trinity::NormalizeMapCoord(y); + + float z = unit->GetBaseMap()->GetHeight(unit->GetPhaseMask(), x, y, 10.0f, true); + + if (z <= INVALID_HEIGHT || fabs(i_z - z) > 10.0f || !unit->IsWithinLOS(x, y, z)) + { + i_nextMoveTime.Reset(100); + return true; + } PathGenerator path(unit); - path.SetPathLengthLimit(30.0f); + path.SetPathLengthLimit(20.0f); bool result = path.CalculatePath(x, y, z); - if (!result || path.GetPathType() & PATHFIND_NOPATH) + if (!result || (path.GetPathType() & PATHFIND_NOPATH)) { - i_nextMoveTime.Reset(urand(800, 1000)); + i_nextMoveTime.Reset(100); // short reset return true; } diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index b8764bd50422a..5cdbdb2434176 100644 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -39,16 +39,19 @@ void FleeingMovementGenerator::_setTargetLocation(T* owner) float x, y, z; if (!_getPoint(owner, x, y, z)) + { + i_nextCheckTime.Reset(100); return; + } owner->AddUnitState(UNIT_STATE_FLEEING_MOVE); PathGenerator path(owner); - path.SetPathLengthLimit(30.0f); + path.SetPathLengthLimit(20.0f); bool result = path.CalculatePath(x, y, z); - if (!result || path.GetPathType() & PATHFIND_NOPATH) + if (!result || (path.GetPathType() & PATHFIND_NOPATH)) { - i_nextCheckTime.Reset(urand(1000, 1500)); + i_nextCheckTime.Reset(100); return; } @@ -86,7 +89,7 @@ bool FleeingMovementGenerator::_getPoint(T* owner, float &x, float &y, float dist = frand(0.4f, 1.3f)*(MIN_QUIET_DISTANCE - dist_from_caster); angle = angle_to_caster + frand(-static_cast(M_PI)/8, static_cast(M_PI)/8); } - else if(dist_from_caster > MAX_QUIET_DISTANCE) + else if (dist_from_caster > MAX_QUIET_DISTANCE) { dist = frand(0.4f, 1.0f)*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE); angle = -angle_to_caster + frand(-static_cast(M_PI)/4, static_cast(M_PI)/4); @@ -102,9 +105,17 @@ bool FleeingMovementGenerator::_getPoint(T* owner, float &x, float &y, float x = curr_x + dist * std::cos(angle); y = curr_y + dist * std::sin(angle); - z = curr_z; - owner->UpdateAllowedPositionZ(x, y, z); + Trinity::NormalizeMapCoord(x); + Trinity::NormalizeMapCoord(y); + + z = owner->GetBaseMap()->GetHeight(owner->GetPhaseMask(), x, y, 10.0f, true); + + if (z <= INVALID_HEIGHT) + return false; + + if (fabs(curr_z - z) > 10.0f || !owner->IsWithinLOS(x, y, z)) + return false; return true; } @@ -152,6 +163,7 @@ bool FleeingMovementGenerator::Update(T* owner, const uint32& time_diff) { if (!owner || !owner->isAlive()) return false; + if (owner->HasUnitState(UNIT_STATE_ROOT | UNIT_STATE_STUNNED)) { owner->ClearUnitState(UNIT_STATE_FLEEING_MOVE); @@ -159,7 +171,7 @@ bool FleeingMovementGenerator::Update(T* owner, const uint32& time_diff) } i_nextCheckTime.Update(time_diff); - if (i_nextCheckTime.Passed() && owner->movespline->Finalized()) + if (i_nextCheckTime.Passed()) _setTargetLocation(owner); return true; diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 7a6611ed2cadb..dc6cc55b85590 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -27,7 +27,7 @@ #include "Player.h" template -void TargetedMovementGeneratorMedium::_setTargetLocation(T* owner) +void TargetedMovementGeneratorMedium::_setTargetLocation(T* owner, bool updateDestination) { if (!i_target.isValid() || !i_target->IsInWorld()) return; @@ -40,37 +40,42 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T* owner) float x, y, z; - if (!i_offset) + if (updateDestination || !i_path) { - float dist = 0.0f; - - if (owner->getVictim() && owner->getVictim()->GetGUID() == i_target->GetGUID()) - dist = owner->GetFloatValue(UNIT_FIELD_COMBATREACH) + i_target->GetFloatValue(UNIT_FIELD_COMBATREACH) - i_target->GetObjectSize() - owner->GetObjectSize() - 1.0f; - - if (dist < 0.5f) - dist = 0.5f; - - if (owner->IsWithinLOSInMap(owner->getVictim())) - i_target->GetContactPoint(owner, x, y, z, dist); + if (!i_offset) + { + // to nearest contact position + i_target->GetContactPoint(owner, x, y, z); + } else - i_target->GetPosition(x, y, z); + { + // to at i_offset distance from target and i_angle from target facing + i_target->GetClosePoint(x, y, z, owner->GetObjectSize(), i_offset, i_angle); + } } else { - // to at i_offset distance from target and i_angle from target facing - i_target->GetClosePoint(x, y, z, owner->GetObjectSize(), i_offset, i_angle); + // the destination has not changed, we just need to refresh the path (usually speed change) + G3D::Vector3 end = i_path->GetEndPosition(); + x = end.x; + y = end.y; + z = end.z; } if (!i_path) i_path = new PathGenerator(owner); - // allow pets following their master to cheat while generating paths + // allow pets to use shortcut if no path found when following their master bool forceDest = (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->isPet() && owner->HasUnitState(UNIT_STATE_FOLLOW)); bool result = i_path->CalculatePath(x, y, z, forceDest); - if (!result || i_path->GetPathType() & PATHFIND_NOPATH) + if (!result || (i_path->GetPathType() & PATHFIND_NOPATH)) + { + // Cant reach target + i_recalculateTravel = true; return; + } D::_addUnitStateMove(owner); i_targetReached = false; @@ -79,37 +84,14 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T* owner) Movement::MoveSplineInit init(owner); init.MovebyPath(i_path->GetPath()); - init.SetFacing(i_target.getTarget()); + if (forceDest && updateDestination) + init.SetFacing(i_target.getTarget()->GetOrientation()); + else + init.SetFacing(i_target.getTarget()); init.SetWalk(((D*)this)->EnableWalking()); init.Launch(); } -template<> -void TargetedMovementGeneratorMedium >::UpdateFinalDistance(float /*fDistance*/) -{ - // nothing to do for Player -} - -template<> -void TargetedMovementGeneratorMedium >::UpdateFinalDistance(float /*fDistance*/) -{ - // nothing to do for Player -} - -template<> -void TargetedMovementGeneratorMedium >::UpdateFinalDistance(float fDistance) -{ - i_offset = fDistance; - i_recalculateTravel = true; -} - -template<> -void TargetedMovementGeneratorMedium >::UpdateFinalDistance(float fDistance) -{ - i_offset = fDistance; - i_recalculateTravel = true; -} - template bool TargetedMovementGeneratorMedium::Update(T* owner, const uint32& time_diff) { @@ -140,6 +122,7 @@ bool TargetedMovementGeneratorMedium::Update(T* owner, const uint32& time_d return true; } + bool targetMoved = false; i_recheckDistance.Update(time_diff); if (i_recheckDistance.Passed()) { @@ -148,16 +131,15 @@ bool TargetedMovementGeneratorMedium::Update(T* owner, const uint32& time_d float allowed_dist = owner->GetCombatReach() + sWorld->getRate(RATE_TARGET_POS_RECALCULATION_RANGE); G3D::Vector3 dest = owner->movespline->FinalDestination(); - bool targetMoved = false; if (owner->GetTypeId() == TYPEID_UNIT && owner->ToCreature()->CanFly()) targetMoved = !i_target->IsWithinDist3d(dest.x, dest.y, dest.z, allowed_dist); else targetMoved = !i_target->IsWithinDist2d(dest.x, dest.y, allowed_dist); - - if (targetMoved || !owner->IsWithinLOSInMap(owner->getVictim())) - _setTargetLocation(owner); } + if (i_recalculateTravel || targetMoved) + _setTargetLocation(owner, targetMoved); + if (owner->movespline->Finalized()) { static_cast(this)->MovementInform(owner); @@ -170,11 +152,7 @@ bool TargetedMovementGeneratorMedium::Update(T* owner, const uint32& time_d static_cast(this)->_reachTarget(owner); } } - else - { - if (i_recalculateTravel) - _setTargetLocation(owner); - } + return true; } @@ -190,7 +168,7 @@ template<> void ChaseMovementGenerator::Initialize(Player* owner) { owner->AddUnitState(UNIT_STATE_CHASE | UNIT_STATE_CHASE_MOVE); - _setTargetLocation(owner); + _setTargetLocation(owner, true); } template<> @@ -198,7 +176,7 @@ void ChaseMovementGenerator::Initialize(Creature* owner) { owner->SetWalk(false); owner->AddUnitState(UNIT_STATE_CHASE | UNIT_STATE_CHASE_MOVE); - _setTargetLocation(owner); + _setTargetLocation(owner, true); } template @@ -262,7 +240,7 @@ void FollowMovementGenerator::Initialize(Player* owner) { owner->AddUnitState(UNIT_STATE_FOLLOW | UNIT_STATE_FOLLOW_MOVE); _updateSpeed(owner); - _setTargetLocation(owner); + _setTargetLocation(owner, true); } template<> @@ -270,7 +248,7 @@ void FollowMovementGenerator::Initialize(Creature* owner) { owner->AddUnitState(UNIT_STATE_FOLLOW | UNIT_STATE_FOLLOW_MOVE); _updateSpeed(owner); - _setTargetLocation(owner); + _setTargetLocation(owner, true); } template @@ -300,10 +278,10 @@ void FollowMovementGenerator::MovementInform(Creature* unit) } //-----------------------------------------------// -template void TargetedMovementGeneratorMedium >::_setTargetLocation(Player*); -template void TargetedMovementGeneratorMedium >::_setTargetLocation(Player*); -template void TargetedMovementGeneratorMedium >::_setTargetLocation(Creature*); -template void TargetedMovementGeneratorMedium >::_setTargetLocation(Creature*); +template void TargetedMovementGeneratorMedium >::_setTargetLocation(Player*, bool); +template void TargetedMovementGeneratorMedium >::_setTargetLocation(Player*, bool); +template void TargetedMovementGeneratorMedium >::_setTargetLocation(Creature*, bool); +template void TargetedMovementGeneratorMedium >::_setTargetLocation(Creature*, bool); template bool TargetedMovementGeneratorMedium >::Update(Player*, const uint32&); template bool TargetedMovementGeneratorMedium >::Update(Player*, const uint32&); template bool TargetedMovementGeneratorMedium >::Update(Creature*, const uint32&); diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h index 064e5bfa1a22b..f293d5976af64 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h @@ -51,10 +51,9 @@ class TargetedMovementGeneratorMedium : public MovementGeneratorMedium< T, D >, Unit* GetTarget() const { return i_target.getTarget(); } void unitSpeedChanged() { i_recalculateTravel = true; } - void UpdateFinalDistance(float fDistance); bool IsReachable() const { return (i_path) ? (i_path->GetPathType() & PATHFIND_NORMAL) : true; } protected: - void _setTargetLocation(T*); + void _setTargetLocation(T* owner, bool updateDestination); TimeTrackerSmall i_recheckDistance; float i_offset; diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 3495c4d1218ee..71617f6a6abfa 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -58,7 +58,6 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo if (!Trinity::IsValidMapCoord(destX, destY, destZ) || !Trinity::IsValidMapCoord(x, y, z)) return false; - Vector3 oldDest = GetEndPosition(); Vector3 dest(destX, destY, destZ); SetEndPosition(dest); @@ -81,24 +80,8 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo UpdateFilter(); - // check if destination moved - if not we can optimize something here - // we are following old, precalculated path? - float dist = _sourceUnit->GetObjectSize(); - if (oldDest != Vector3::zero() && InRange(oldDest, dest, dist, dist) && _pathPoints.size() > 2) - { - // our target is not moving - we just coming closer - // we are moving on precalculated path - enjoy the ride - sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::CalculatePath:: precalculated path\n"); - - _pathPoints.erase(_pathPoints.begin()); - return false; - } - else - { - // target moved, so we need to update the poly path - BuildPolyPath(start, dest); - return true; - } + BuildPolyPath(start, dest); + return true; } dtPolyRef PathGenerator::GetPathPolyByPosition(dtPolyRef const* polyPath, uint32 polyPathSize, float const* point, float* distance) const @@ -534,10 +517,10 @@ void PathGenerator::CreateFilter() if (creature->canSwim()) includeFlags |= (NAV_WATER | NAV_MAGMA | NAV_SLIME); // swim } - else if (_sourceUnit->GetTypeId() == TYPEID_PLAYER) + else // assume Player { // perfect support not possible, just stay 'safe' - includeFlags |= (NAV_GROUND | NAV_WATER); + includeFlags |= (NAV_GROUND | NAV_WATER | NAV_MAGMA | NAV_SLIME); } _filter.setIncludeFlags(includeFlags); diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index 67b019b93f7ce..b6cd1391ca3a8 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -98,7 +98,7 @@ namespace Movement if (!args.HasVelocity) args.velocity = unit->GetSpeed(SelectSpeedType(moveFlags)); - if (!args.Validate(&unit)) + if (!args.Validate(unit)) return 0; if (moveFlags & MOVEMENTFLAG_ROOT)