Пример #1
0
        void StartMove(Creature owner, bool relaunch = false)
        {
            // sanity checks
            if (owner == null || !owner.IsAlive() || HasFlag(MovementGeneratorFlags.Finalized) || _path == null || _path.nodes.Empty() || (relaunch && (HasFlag(MovementGeneratorFlags.InformEnabled) || !HasFlag(MovementGeneratorFlags.Initialized))))
            {
                return;
            }

            if (owner.HasUnitState(UnitState.NotMove) || owner.IsMovementPreventedByCasting() || (owner.IsFormationLeader() && !owner.IsFormationLeaderMoveAllowed())) // if cannot move OR cannot move because of formation
            {
                _nextMoveTime.Reset(1000);                                                                                                                             // delay 1s
                return;
            }

            bool transportPath = !owner.GetTransGUID().IsEmpty();

            if (HasFlag(MovementGeneratorFlags.InformEnabled) && HasFlag(MovementGeneratorFlags.Initialized))
            {
                if (ComputeNextNode())
                {
                    Cypher.Assert(_currentNode < _path.nodes.Count, $"WaypointMovementGenerator.StartMove: tried to reference a node id ({_currentNode}) which is not included in path ({_path.id})");
                    // inform AI
                    CreatureAI ai = owner.GetAI();
                    if (ai != null)
                    {
                        ai.WaypointStarted(_path.nodes[_currentNode].id, _path.id);
                    }
                }
                else
                {
                    WaypointNode currentWaypoint = _path.nodes[_currentNode];
                    float        x = currentWaypoint.x;
                    float        y = currentWaypoint.y;
                    float        z = currentWaypoint.z;
                    float        o = owner.GetOrientation();

                    if (!transportPath)
                    {
                        owner.SetHomePosition(x, y, z, o);
                    }
                    else
                    {
                        Transport trans = owner.GetTransport();
                        if (trans)
                        {
                            o -= trans.GetOrientation();
                            owner.SetTransportHomePosition(x, y, z, o);
                            trans.CalculatePassengerPosition(ref x, ref y, ref z, ref o);
                            owner.SetHomePosition(x, y, z, o);
                        }
                        // else if (vehicle) - this should never happen, vehicle offsets are const
                    }

                    AddFlag(MovementGeneratorFlags.Finalized);
                    owner.UpdateCurrentWaypointInfo(0, 0);

                    // inform AI
                    CreatureAI ai = owner.GetAI();
                    if (ai != null)
                    {
                        ai.WaypointPathEnded(currentWaypoint.id, _path.id);
                    }
                    return;
                }
            }
            else if (!HasFlag(MovementGeneratorFlags.Initialized))
            {
                AddFlag(MovementGeneratorFlags.Initialized);

                // inform AI
                CreatureAI ai = owner.GetAI();
                if (ai != null)
                {
                    ai.WaypointStarted(_path.nodes[_currentNode].id, _path.id);
                }
            }

            Cypher.Assert(_currentNode < _path.nodes.Count, $"WaypointMovementGenerator.StartMove: tried to reference a node id ({_currentNode}) which is not included in path ({_path.id})");
            WaypointNode waypoint      = _path.nodes[_currentNode];
            Position     formationDest = new(waypoint.x, waypoint.y, waypoint.z, (waypoint.orientation != 0 && waypoint.delay != 0) ? waypoint.orientation : 0.0f);

            RemoveFlag(MovementGeneratorFlags.Transitory | MovementGeneratorFlags.InformEnabled | MovementGeneratorFlags.TimedPaused);

            owner.AddUnitState(UnitState.RoamingMove);

            MoveSplineInit init = new(owner);

            //! If creature is on transport, we assume waypoints set in DB are already transport offsets
            if (transportPath)
            {
                init.DisableTransportPathTransformations();
                ITransport trans = owner.GetDirectTransport();
                if (trans != null)
                {
                    float orientation = formationDest.GetOrientation();
                    trans.CalculatePassengerPosition(ref formationDest.posX, ref formationDest.posY, ref formationDest.posZ, ref orientation);
                    formationDest.SetOrientation(orientation);
                }
            }

            //! Do not use formationDest here, MoveTo requires transport offsets due to DisableTransportPathTransformations() call
            //! but formationDest contains global coordinates
            init.MoveTo(waypoint.x, waypoint.y, waypoint.z);

            //! Accepts angles such as 0.00001 and -0.00001, 0 must be ignored, default value in waypoint table
            if (waypoint.orientation != 0 && waypoint.delay != 0)
            {
                init.SetFacing(waypoint.orientation);
            }

            switch (waypoint.moveType)
            {
            case WaypointMoveType.Land:
                init.SetAnimation(AnimType.ToGround);
                break;

            case WaypointMoveType.Takeoff:
                init.SetAnimation(AnimType.ToFly);
                break;

            case WaypointMoveType.Run:
                init.SetWalk(false);
                break;

            case WaypointMoveType.Walk:
                init.SetWalk(true);
                break;
            }

            init.Launch();

            // inform formation
            owner.SignalFormationMovement(formationDest, waypoint.id, waypoint.moveType, (waypoint.orientation != 0 && waypoint.delay != 0));
        }
Пример #2
0
        bool StartMove(Creature creature)
        {
            if (!creature || !creature.IsAlive())
            {
                return(false);
            }

            if (path == null || path.nodes.Empty())
            {
                return(false);
            }

            if (Stopped())
            {
                return(true);
            }

            bool transportPath = creature.GetTransport() != null;

            if (isArrivalDone)
            {
                if ((currentNode == path.nodes.Count - 1) && !repeating) // If that's our last waypoint
                {
                    WaypointNode waypoint = path.nodes.LookupByIndex((int)currentNode);

                    float x = waypoint.x;
                    float y = waypoint.y;
                    float z = waypoint.z;
                    float o = creature.GetOrientation();

                    if (!transportPath)
                    {
                        creature.SetHomePosition(x, y, z, o);
                    }
                    else
                    {
                        Transport trans = creature.GetTransport();
                        if (trans)
                        {
                            o -= trans.GetOrientation();
                            creature.SetTransportHomePosition(x, y, z, o);
                            trans.CalculatePassengerPosition(ref x, ref y, ref z, ref o);
                            creature.SetHomePosition(x, y, z, o);
                        }
                        else
                        {
                            transportPath = false;
                        }
                        // else if (vehicle) - this should never happen, vehicle offsets are const
                    }

                    return(false);
                }

                currentNode = (uint)((currentNode + 1) % path.nodes.Count);
            }

            float            finalOrient = 0.0f;
            WaypointMoveType finalMove   = WaypointMoveType.Walk;

            List <Vector3> pathing = new List <Vector3>();

            pathing.Add(new Vector3(creature.GetPositionX(), creature.GetPositionY(), creature.GetPositionZ()));
            for (int i = (int)currentNode; i < path.nodes.Count; ++i)
            {
                WaypointNode waypoint = path.nodes.LookupByIndex(i);

                pathing.Add(new Vector3(waypoint.x, waypoint.y, waypoint.z));

                finalOrient = waypoint.orientation;
                finalMove   = waypoint.moveType;

                if (waypoint.delay != 0)
                {
                    break;
                }
            }

            // if we have only 1 point, only current position, we shall return
            if (pathing.Count < 2)
            {
                return(false);
            }

            isArrivalDone    = false;
            recalculateSpeed = false;

            creature.AddUnitState(UnitState.RoamingMove);

            MoveSplineInit init          = new MoveSplineInit(creature);
            var            node          = path.nodes.LookupByIndex((int)currentNode);
            Position       formationDest = new Position(node.x, node.y, node.z, 0.0f);

            //! If creature is on transport, we assume waypoints set in DB are already transport offsets
            if (transportPath)
            {
                init.DisableTransportPathTransformations();
                ITransport trans = creature.GetDirectTransport();
                if (trans != null)
                {
                    trans.CalculatePassengerPosition(ref formationDest.posX, ref formationDest.posY, ref formationDest.posZ, ref formationDest.Orientation);
                }
            }

            init.MovebyPath(pathing.ToArray(), (int)currentNode);
            switch (finalMove)
            {
            case WaypointMoveType.Land:
                init.SetAnimation(AnimType.ToGround);
                break;

            case WaypointMoveType.Takeoff:
                init.SetAnimation(AnimType.ToFly);
                break;

            case WaypointMoveType.Run:
                init.SetWalk(false);
                break;

            case WaypointMoveType.Walk:
                init.SetWalk(true);
                break;
            }

            if (finalOrient != 0.0f)
            {
                init.SetFacing(finalOrient);
            }

            init.Launch();

            //Call for creature group update
            if (creature.GetFormation() != null && creature.GetFormation().getLeader() == creature)
            {
                creature.GetFormation().LeaderMoveTo(formationDest.posX, formationDest.posY, formationDest.posZ);
            }

            return(true);
        }
Пример #3
0
        bool StartMove(Creature creature)
        {
            if (path == null || path.Empty())
            {
                return(false);
            }

            if (Stopped())
            {
                return(true);
            }

            bool transportPath = creature.GetTransport() != null;

            if (isArrivalDone)
            {
                if ((currentNode == path.Count - 1) && !repeating) // If that's our last waypoint
                {
                    WaypointData waypoint = path.LookupByIndex((int)currentNode);

                    float x = waypoint.x;
                    float y = waypoint.y;
                    float z = waypoint.z;
                    float o = creature.GetOrientation();

                    if (!transportPath)
                    {
                        creature.SetHomePosition(x, y, z, o);
                    }
                    else
                    {
                        Transport trans = creature.GetTransport();
                        if (trans)
                        {
                            o -= trans.GetOrientation();
                            creature.SetTransportHomePosition(x, y, z, o);
                            trans.CalculatePassengerPosition(ref x, ref y, ref z, ref o);
                            creature.SetHomePosition(x, y, z, o);
                        }
                        else
                        {
                            transportPath = false;
                        }
                        // else if (vehicle) - this should never happen, vehicle offsets are const
                    }

                    creature.GetMotionMaster().Initialize();
                    return(false);
                }

                currentNode = (uint)((currentNode + 1) % path.Count);
            }

            var node = path.LookupByIndex((int)currentNode);

            isArrivalDone = false;

            creature.AddUnitState(UnitState.RoamingMove);

            Position       formationDest = new Position(node.x, node.y, node.z, (node.orientation != 0 && node.delay != 0) ? node.orientation : 0.0f);
            MoveSplineInit init          = new MoveSplineInit(creature);

            //! If creature is on transport, we assume waypoints set in DB are already transport offsets
            if (transportPath)
            {
                init.DisableTransportPathTransformations();
                ITransport trans = creature.GetDirectTransport();
                if (trans != null)
                {
                    float orientation = formationDest.GetOrientation();
                    trans.CalculatePassengerPosition(ref formationDest.posX, ref formationDest.posY, ref formationDest.posZ, ref orientation);
                    formationDest.SetOrientation(orientation);
                }
            }

            //! Do not use formationDest here, MoveTo requires transport offsets due to DisableTransportPathTransformations() call
            //! but formationDest contains global coordinates
            init.MoveTo(node.x, node.y, node.z);

            //! Accepts angles such as 0.00001 and -0.00001, 0 must be ignored, default value in waypoint table
            if (node.orientation != 0 && node.delay != 0)
            {
                init.SetFacing(node.orientation);
            }

            switch (node.moveType)
            {
            case WaypointMoveType.Land:
                init.SetAnimation(AnimType.ToGround);
                break;

            case WaypointMoveType.Takeoff:
                init.SetAnimation(AnimType.ToFly);
                break;

            case WaypointMoveType.Run:
                init.SetWalk(false);
                break;

            case WaypointMoveType.Walk:
                init.SetWalk(true);
                break;
            }

            init.Launch();

            //Call for creature group update
            if (creature.GetFormation() != null && creature.GetFormation().GetLeader() == creature)
            {
                creature.GetFormation().LeaderMoveTo(formationDest, node.id, (uint)node.moveType, (node.orientation != 0 && node.delay != 0) ? true : false);
            }

            return(true);
        }
Пример #4
0
        bool StartMove(Creature creature)
        {
            if (!creature || !creature.IsAlive())
            {
                return(true);
            }

            if (_done || _path == null || _path.nodes.Empty())
            {
                return(true);
            }

            // if the owner is the leader of its formation, check members status
            if (creature.IsFormationLeader() && !creature.IsFormationLeaderMoveAllowed())
            {
                _nextMoveTime.Reset(1000);
                return(true);
            }

            bool transportPath = creature.GetTransport() != null;

            if (_isArrivalDone)
            {
                Cypher.Assert(_currentNode < _path.nodes.Count, $"WaypointMovementGenerator.StartMove: tried to reference a node id ({_currentNode}) which is not included in path ({_path.id})");
                WaypointNode lastWaypoint = _path.nodes.ElementAt(_currentNode);
                if ((_currentNode == _path.nodes.Count - 1) && !_repeating) // If that's our last waypoint
                {
                    float x = lastWaypoint.x;
                    float y = lastWaypoint.y;
                    float z = lastWaypoint.z;
                    float o = creature.GetOrientation();

                    if (!transportPath)
                    {
                        creature.SetHomePosition(x, y, z, o);
                    }
                    else
                    {
                        Transport trans = creature.GetTransport();
                        if (trans)
                        {
                            o -= trans.GetOrientation();
                            creature.SetTransportHomePosition(x, y, z, o);
                            trans.CalculatePassengerPosition(ref x, ref y, ref z, ref o);
                            creature.SetHomePosition(x, y, z, o);
                        }
                        else
                        {
                            transportPath = false;
                        }
                        // else if (vehicle) - this should never happen, vehicle offsets are const
                    }
                    _done = true;
                    creature.UpdateCurrentWaypointInfo(0, 0);

                    // inform AI
                    if (creature.IsAIEnabled)
                    {
                        creature.GetAI().WaypointPathEnded(lastWaypoint.id, _path.id);
                    }
                    return(true);
                }

                _currentNode = (_currentNode + 1) % _path.nodes.Count;

                // inform AI
                if (creature.IsAIEnabled)
                {
                    creature.GetAI().WaypointStarted(lastWaypoint.id, _path.id);
                }
            }

            Cypher.Assert(_currentNode < _path.nodes.Count, $"WaypointMovementGenerator.StartMove: tried to reference a node id ({_currentNode}) which is not included in path ({_path.id})");
            WaypointNode waypoint      = _path.nodes.ElementAt(_currentNode);
            Position     formationDest = new(waypoint.x, waypoint.y, waypoint.z, (waypoint.orientation != 0 && waypoint.delay != 0) ? waypoint.orientation : 0.0f);

            _isArrivalDone    = false;
            _recalculateSpeed = false;

            creature.AddUnitState(UnitState.RoamingMove);

            MoveSplineInit init = new(creature);

            //! If creature is on transport, we assume waypoints set in DB are already transport offsets
            if (transportPath)
            {
                init.DisableTransportPathTransformations();
                ITransport trans = creature.GetDirectTransport();
                if (trans != null)
                {
                    float orientation = formationDest.GetOrientation();
                    trans.CalculatePassengerPosition(ref formationDest.posX, ref formationDest.posY, ref formationDest.posZ, ref orientation);
                    formationDest.SetOrientation(orientation);
                }
            }

            //! Do not use formationDest here, MoveTo requires transport offsets due to DisableTransportPathTransformations() call
            //! but formationDest contains global coordinates
            init.MoveTo(waypoint.x, waypoint.y, waypoint.z);

            //! Accepts angles such as 0.00001 and -0.00001, 0 must be ignored, default value in waypoint table
            if (waypoint.orientation != 0 && waypoint.delay != 0)
            {
                init.SetFacing(waypoint.orientation);
            }

            switch (waypoint.moveType)
            {
            case WaypointMoveType.Land:
                init.SetAnimation(AnimType.ToGround);
                break;

            case WaypointMoveType.Takeoff:
                init.SetAnimation(AnimType.ToFly);
                break;

            case WaypointMoveType.Run:
                init.SetWalk(false);
                break;

            case WaypointMoveType.Walk:
                init.SetWalk(true);
                break;
            }

            init.Launch();

            // inform formation
            creature.SignalFormationMovement(formationDest, waypoint.id, waypoint.moveType, (waypoint.orientation != 0 && waypoint.delay != 0) ? true : false);
            return(true);
        }