164 lines
5.5 KiB
C#
164 lines
5.5 KiB
C#
/*
|
|
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
using Framework.Constants;
|
|
using Game.Entities;
|
|
using System;
|
|
|
|
namespace Game.Movement
|
|
{
|
|
public class RandomMovementGenerator : MovementGeneratorMedium<Creature>
|
|
{
|
|
public RandomMovementGenerator(float spawnDist = 0.0f)
|
|
{
|
|
_timer = new TimeTracker();
|
|
_reference = new();
|
|
_wanderDistance = spawnDist;
|
|
|
|
Mode = MovementGeneratorMode.Default;
|
|
Priority = MovementGeneratorPriority.Normal;
|
|
Flags = MovementGeneratorFlags.InitializationPending;
|
|
BaseUnitState = UnitState.Roaming;
|
|
}
|
|
|
|
public override void DoInitialize(Creature owner)
|
|
{
|
|
RemoveFlag(MovementGeneratorFlags.InitializationPending | MovementGeneratorFlags.Transitory | MovementGeneratorFlags.Deactivated);
|
|
AddFlag(MovementGeneratorFlags.Initialized);
|
|
|
|
if (owner == null || !owner.IsAlive())
|
|
return;
|
|
|
|
_reference = owner.GetPosition();
|
|
owner.StopMoving();
|
|
|
|
if (_wanderDistance == 0)
|
|
_wanderDistance = owner.GetRespawnRadius();
|
|
|
|
_timer.Reset(0);
|
|
_path = null;
|
|
}
|
|
|
|
public override void DoReset(Creature owner)
|
|
{
|
|
RemoveFlag(MovementGeneratorFlags.Transitory | MovementGeneratorFlags.Deactivated);
|
|
DoInitialize(owner);
|
|
}
|
|
|
|
public override bool DoUpdate(Creature owner, uint diff)
|
|
{
|
|
if (!owner || !owner.IsAlive())
|
|
return true;
|
|
|
|
if (owner.HasUnitState(UnitState.NotMove) || owner.IsMovementPreventedByCasting())
|
|
{
|
|
AddFlag(MovementGeneratorFlags.Interrupted);
|
|
owner.StopMoving();
|
|
_path = null;
|
|
return true;
|
|
}
|
|
else
|
|
RemoveFlag(MovementGeneratorFlags.Interrupted);
|
|
|
|
_timer.Update(diff);
|
|
if ((HasFlag(MovementGeneratorFlags.SpeedUpdatePending) && !owner.MoveSpline.Finalized()) || (_timer.Passed() && owner.MoveSpline.Finalized()))
|
|
{
|
|
RemoveFlag(MovementGeneratorFlags.Transitory);
|
|
SetRandomLocation(owner);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public override void DoDeactivate(Creature owner)
|
|
{
|
|
AddFlag(MovementGeneratorFlags.Deactivated);
|
|
owner.ClearUnitState(UnitState.RoamingMove);
|
|
}
|
|
|
|
public override void DoFinalize(Creature owner, bool active, bool movementInform)
|
|
{
|
|
AddFlag(MovementGeneratorFlags.Finalized);
|
|
if (active)
|
|
{
|
|
owner.ClearUnitState(UnitState.RoamingMove);
|
|
owner.StopMoving();
|
|
|
|
// TODO: Research if this modification is needed, which most likely isnt
|
|
owner.SetWalk(false);
|
|
}
|
|
}
|
|
|
|
void SetRandomLocation(Creature owner)
|
|
{
|
|
if (owner == null)
|
|
return;
|
|
|
|
if (owner.HasUnitState(UnitState.NotMove | UnitState.LostControl) || owner.IsMovementPreventedByCasting())
|
|
{
|
|
AddFlag(MovementGeneratorFlags.Interrupted);
|
|
owner.StopMoving();
|
|
_path = null;
|
|
return;
|
|
}
|
|
|
|
Position position = new(_reference);
|
|
float distance = RandomHelper.FRand(0.0f, 1.0f) * _wanderDistance;
|
|
float angle = RandomHelper.FRand(0.0f, 1.0f) * MathF.PI * 2.0f;
|
|
owner.MovePositionToFirstCollision(position, distance, angle);
|
|
|
|
uint resetTimer = RandomHelper.randChance(50) ? RandomHelper.URand(5000, 10000) : RandomHelper.URand(1000, 2000);
|
|
|
|
if (_path == null)
|
|
{
|
|
_path = new PathGenerator(owner);
|
|
_path.SetPathLengthLimit(30.0f);
|
|
}
|
|
|
|
bool result = _path.CalculatePath(position.GetPositionX(), position.GetPositionY(), position.GetPositionZ());
|
|
if (!result || _path.GetPathType().HasAnyFlag(PathType.NoPath))
|
|
{
|
|
_timer.Reset(100);
|
|
return;
|
|
}
|
|
|
|
owner.AddUnitState(UnitState.RoamingMove);
|
|
|
|
MoveSplineInit init = new(owner);
|
|
init.MovebyPath(_path.GetPath());
|
|
init.SetWalk(true);
|
|
int traveltime = init.Launch();
|
|
_timer.Reset(traveltime + resetTimer);
|
|
|
|
// Call for creature group update
|
|
owner.SignalFormationMovement(position);
|
|
}
|
|
|
|
public override void UnitSpeedChanged() { AddFlag(MovementGeneratorFlags.SpeedUpdatePending); }
|
|
|
|
public override MovementGeneratorType GetMovementGeneratorType()
|
|
{
|
|
return MovementGeneratorType.Random;
|
|
}
|
|
|
|
PathGenerator _path;
|
|
TimeTracker _timer;
|
|
Position _reference;
|
|
float _wanderDistance;
|
|
}
|
|
}
|