コード例 #1
0
        public override void DoInitialize(Creature owner)
        {
            owner.AddUnitState(UnitState.Roaming);

            if (owner.HasUnitState(UnitState.NotMove) || owner.IsMovementPreventedByCasting())
            {
                _interrupt = true;
                owner.StopMoving();
                return;
            }

            owner.AddUnitState(UnitState.RoamingMove);

            MoveSplineInit init = new MoveSplineInit(owner);

            init.MoveTo(_destination.GetPositionX(), _destination.GetPositionY(), _destination.GetPositionZ());
            if (_orientation)
            {
                init.SetFacing(_destination.GetOrientation());
            }

            switch (_moveType)
            {
            case 2:     // WAYPOINT_MOVE_TYPE_LAND
                init.SetAnimation(AnimType.ToGround);
                break;

            case 3:     // WAYPOINT_MOVE_TYPE_TAKEOFF
                init.SetAnimation(AnimType.ToFly);
                break;

            case 1:     // WAYPOINT_MOVE_TYPE_RUN
                init.SetWalk(false);
                break;

            case 0:     // WAYPOINT_MOVE_TYPE_WALK
                init.SetWalk(true);
                break;
            }

            if (_run)
            {
                init.SetWalk(false);
            }

            init.Launch();
        }
コード例 #2
0
        public override bool DoUpdate(T owner, uint diff)
        {
            if (owner == null)
            {
                return(false);
            }

            if (_movementId == EventId.ChargePrepath)
            {
                return(!owner.MoveSpline.Finalized());
            }

            if (owner.HasUnitState(UnitState.NotMove) || owner.IsMovementPreventedByCasting())
            {
                _interrupt = true;
                owner.StopMoving();
                return(true);
            }

            if ((_interrupt && owner.MoveSpline.Finalized()) || (_recalculateSpeed && !owner.MoveSpline.Finalized()))
            {
                _recalculateSpeed = false;
                _interrupt        = false;

                owner.AddUnitState(UnitState.RoamingMove);

                MoveSplineInit init = new MoveSplineInit(owner);
                init.MoveTo(_destination.GetPositionX(), _destination.GetPositionY(), _destination.GetPositionZ(), _generatePath);
                if (_speed > 0.0f) // Default value for point motion type is 0.0, if 0.0 spline will use GetSpeed on unit
                {
                    init.SetVelocity(_speed);
                }
                init.Launch();

                // Call for creature group update
                Creature creature = owner.ToCreature();
                if (creature != null)
                {
                    if (creature.GetFormation() != null && creature.GetFormation().GetLeader() == creature)
                    {
                        creature.GetFormation().LeaderMoveTo(_destination, _movementId);
                    }
                }
            }

            return(!owner.MoveSpline.Finalized());
        }
コード例 #3
0
        public override void DoInitialize(Creature owner)
        {
            owner.AddUnitState(UnitState.Roaming);

            if (owner.HasUnitState(UnitState.NotMove) || owner.IsMovementPreventedByCasting())
            {
                _interrupt = true;
                owner.StopMoving();
                return;
            }

            owner.AddUnitState(UnitState.RoamingMove);

            MoveSplineInit init = new MoveSplineInit(owner);

            init.MoveTo(_destination.GetPositionX(), _destination.GetPositionY(), _destination.GetPositionZ());
            if (_orientation)
            {
                init.SetFacing(_destination.GetOrientation());
            }

            switch (_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;
            }

            if (_run)
            {
                init.SetWalk(false);
            }

            init.Launch();
        }
コード例 #4
0
        public override void DoInitialize(T owner)
        {
            if (_movementId == EventId.ChargePrepath)
            {
                owner.AddUnitState(UnitState.Roaming | UnitState.RoamingMove);
                return;
            }

            owner.AddUnitState(UnitState.Roaming);

            if (owner.HasUnitState(UnitState.NotMove) || owner.IsMovementPreventedByCasting())
            {
                _interrupt = true;
                owner.StopMoving();
                return;
            }

            owner.AddUnitState(UnitState.RoamingMove);

            MoveSplineInit init = new MoveSplineInit(owner);

            init.MoveTo(_destination.GetPositionX(), _destination.GetPositionY(), _destination.GetPositionZ(), _generatePath);
            if (_speed > 0.0f)
            {
                init.SetVelocity(_speed);
            }

            if (_faceTarget)
            {
                init.SetFacing(_faceTarget);
            }

            if (_spellEffectExtra != null)
            {
                init.SetSpellEffectExtraData(_spellEffectExtra);
            }

            init.Launch();

            // Call for creature group update
            Creature creature = owner.ToCreature();

            if (creature != null)
            {
                creature.SignalFormationMovement(_destination, _movementId);
            }
        }
コード例 #5
0
        public override void DoInitialize(T owner)
        {
            if (!owner.IsStopped())
            {
                owner.StopMoving();
            }

            owner.AddUnitState(UnitState.Roaming | UnitState.RoamingMove);

            if (id == EventId.ChargePrepath)
            {
                return;
            }

            MoveSplineInit init = new MoveSplineInit(owner);

            init.MoveTo(i_x, i_y, i_z, m_generatePath);
            if (speed > 0.0f)
            {
                init.SetVelocity(speed);
            }

            if (i_faceTarget)
            {
                init.SetFacing(i_faceTarget);
            }

            if (i_spellEffectExtra != null)
            {
                init.SetSpellEffectExtraData(i_spellEffectExtra);
            }

            init.Launch();

            // Call for creature group update
            Creature creature = owner.ToCreature();

            if (creature != null)
            {
                if (creature.GetFormation() != null && creature.GetFormation().GetLeader() == creature)
                {
                    creature.GetFormation().LeaderMoveTo(i_x, i_y, i_z);
                }
            }
        }
コード例 #6
0
        uint SendPathSpline(Unit me, Span <Vector3> wp)
        {
            int numWp = wp.Length;

            Cypher.Assert(numWp > 1, "Every path must have source & destination");
            MoveSplineInit init = new MoveSplineInit(me);

            if (numWp > 2)
            {
                init.MovebyPath(wp.ToArray());
            }
            else
            {
                init.MoveTo(wp[1], false, true);
            }
            init.SetWalk(_walk);
            return((uint)init.Launch());
        }
コード例 #7
0
        void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, byte stepCount)
        {
            float    step  = 2 * MathFunctions.PI / stepCount * (clockwise ? -1.0f : 1.0f);
            Position pos   = new Position(x, y, z, 0.0f);
            float    angle = pos.GetAngle(_owner.GetPositionX(), _owner.GetPositionY());

            MoveSplineInit init = new MoveSplineInit(_owner);

            init.args.path = new Vector3[stepCount];
            for (byte i = 0; i < stepCount; angle += step, ++i)
            {
                Vector3 point = new Vector3();
                point.X = (float)(x + radius * Math.Cos(angle));
                point.Y = (float)(y + radius * Math.Sin(angle));

                if (_owner.IsFlying())
                {
                    point.Z = z;
                }
                else
                {
                    point.Z = _owner.GetMap().GetHeight(_owner.GetPhaseShift(), point.X, point.Y, z);
                }

                init.args.path[i] = point;
            }

            if (_owner.IsFlying())
            {
                init.SetFly();
                init.SetCyclic();
                init.SetAnimation(AnimType.ToFly);
            }
            else
            {
                init.SetWalk(true);
                init.SetCyclic();
            }

            init.Launch();
        }
コード例 #8
0
        public void MoveCharge(PathGenerator path, float speed = SPEED_CHARGE, Unit target = null, SpellEffectExtraData spellEffectExtraData = null)
        {
            Vector3 dest = path.GetActualEndPosition();

            MoveCharge(dest.X, dest.Y, dest.Z, SPEED_CHARGE, EventId.ChargePrepath);

            // Charge movement is not started when using EVENT_CHARGE_PREPATH
            MoveSplineInit init = new MoveSplineInit(_owner);

            init.MovebyPath(path.GetPath());
            init.SetVelocity(speed);
            if (target != null)
            {
                init.SetFacing(target);
            }
            if (spellEffectExtraData != null)
            {
                init.SetSpellEffectExtraData(spellEffectExtraData);
            }
            init.Launch();
        }
コード例 #9
0
        void MoveCloserAndStop(uint id, Unit target, float distance)
        {
            float distanceToTravel = _owner.GetExactDist2d(target) - distance;

            if (distanceToTravel > 0.0f)
            {
                float angle = _owner.GetAngle(target);
                float destx = _owner.GetPositionX() + distanceToTravel * (float)Math.Cos(angle);
                float desty = _owner.GetPositionY() + distanceToTravel * (float)Math.Sin(angle);
                MovePoint(id, destx, desty, target.GetPositionZ());
            }
            else
            {
                // we are already close enough. We just need to turn toward the target without changing position.
                MoveSplineInit init = new MoveSplineInit(_owner);
                init.MoveTo(_owner.GetPositionX(), _owner.GetPositionY(), _owner.GetPositionZMinusOffset());
                init.SetFacing(target);
                init.Launch();
                StartMovement(new EffectMovementGenerator(id), MovementSlot.Active);
            }
        }
コード例 #10
0
        void MoveSmoothPath(uint pointId, Vector3[] pathPoints, int pathSize, bool walk = false, bool fly = false)
        {
            MoveSplineInit init = new MoveSplineInit(_owner);

            if (fly)
            {
                init.SetFly();
                init.SetUncompressed();
                init.SetSmooth();
            }

            init.MovebyPath(pathPoints);
            init.SetWalk(walk);
            init.Launch();

            // This code is not correct
            // EffectMovementGenerator does not affect UNIT_STATE_ROAMING | UNIT_STATE_ROAMING_MOVE
            // need to call PointMovementGenerator with various pointIds
            StartMovement(new EffectMovementGenerator(pointId), MovementSlot.Active);
            //Position pos(pathPoints[pathSize - 1].x, pathPoints[pathSize - 1].y, pathPoints[pathSize - 1].z);
            //MovePoint(EVENT_CHARGE_PREPATH, pos, false);
        }
コード例 #11
0
        public override bool DoUpdate(T owner, uint time_diff)
        {
            if (owner == null)
            {
                return(false);
            }

            if (owner.HasUnitState(UnitState.Root | UnitState.Stunned))
            {
                owner.ClearUnitState(UnitState.RoamingMove);
                return(true);
            }

            owner.AddUnitState(UnitState.RoamingMove);

            if (id != EventId.ChargePrepath && i_recalculateSpeed && !owner.MoveSpline.Finalized())
            {
                i_recalculateSpeed = false;
                MoveSplineInit init = new MoveSplineInit(owner);
                init.MoveTo(i_x, i_y, i_z, m_generatePath);
                if (speed > 0.0f) // Default value for point motion type is 0.0, if 0.0 spline will use GetSpeed on unit
                {
                    init.SetVelocity(speed);
                }
                init.Launch();

                // Call for creature group update
                Creature creature = owner.ToCreature();
                if (creature != null)
                {
                    if (creature.GetFormation() != null && creature.GetFormation().GetLeader() == creature)
                    {
                        creature.GetFormation().LeaderMoveTo(i_x, i_y, i_z);
                    }
                }
            }

            return(!owner.MoveSpline.Finalized());
        }
コード例 #12
0
        public override void DoReset(Player owner)
        {
            owner.getHostileRefManager().setOnlineOfflineState(false);
            owner.AddUnitState(UnitState.InFlight);
            owner.AddUnitFlag(UnitFlags.RemoveClientControl | UnitFlags.TaxiFlight);

            MoveSplineInit init = new MoveSplineInit(owner);
            uint end = GetPathAtMapEnd();
            init.args.path = new Vector3[end];
            for (int i = (int)GetCurrentNode(); i != end; ++i)
            {
                Vector3 vertice = new Vector3(i_path[i].Loc.X, i_path[i].Loc.Y, i_path[i].Loc.Z);
                init.args.path[i] = vertice;
            }
            init.SetFirstPointId((int)GetCurrentNode());
            init.SetFly();
            init.SetSmooth();
            init.SetUncompressed();
            init.SetWalk(true);
            init.SetVelocity(30.0f);
            init.Launch();
        }
コード例 #13
0
        public void MoveJump(float x, float y, float z, float o, float speedXY, float speedZ, uint id = EventId.Jump, bool hasOrientation = false,
                             JumpArrivalCastArgs arrivalCast = null, SpellEffectExtraData spellEffectExtraData = null)
        {
            Log.outDebug(LogFilter.Server, "Unit ({0}) jump to point (X: {1} Y: {2} Z: {3})", _owner.GetGUID().ToString(), x, y, z);
            if (speedXY < 0.01f)
            {
                return;
            }

            float moveTimeHalf = (float)(speedZ / gravity);
            float max_height   = -MoveSpline.ComputeFallElevation(moveTimeHalf, false, -speedZ);

            MoveSplineInit init = new MoveSplineInit(_owner);

            init.MoveTo(x, y, z, false);
            init.SetParabolic(max_height, 0);
            init.SetVelocity(speedXY);
            if (hasOrientation)
            {
                init.SetFacing(o);
            }
            if (spellEffectExtraData != null)
            {
                init.SetSpellEffectExtraData(spellEffectExtraData);
            }
            init.Launch();

            uint       arrivalSpellId         = 0;
            ObjectGuid arrivalSpellTargetGuid = ObjectGuid.Empty;

            if (arrivalCast != null)
            {
                arrivalSpellId         = arrivalCast.SpellId;
                arrivalSpellTargetGuid = arrivalCast.Target;
            }

            StartMovement(new EffectMovementGenerator(id, arrivalSpellId, arrivalSpellTargetGuid), MovementSlot.Controlled);
        }
コード例 #14
0
        public void SetTargetLocation(T owner, bool updateDestination)
        {
            if (!IsTargetValid() || !GetTarget().IsInWorld)
            {
                return;
            }

            if (!owner || !owner.IsAlive())
            {
                return;
            }


            if (owner.HasUnitState(UnitState.NotMove) || owner.IsMovementPreventedByCasting() || HasLostTarget(owner))
            {
                _interrupt = true;
                owner.StopMoving();
                return;
            }

            if (owner.IsTypeId(TypeId.Unit) && !GetTarget().IsInAccessiblePlaceFor(owner.ToCreature()))
            {
                owner.ToCreature().SetCannotReachTarget(true);
                return;
            }

            float x, y, z;

            if (updateDestination || _path == null)
            {
                if (_offset == 0)
                {
                    if (GetTarget().IsWithinDistInMap(owner, SharedConst.ContactDistance))
                    {
                        return;
                    }

                    // to nearest contact position
                    GetTarget().GetContactPoint(owner, out x, out y, out z);
                }
                else
                {
                    float distance = _offset + 1.0f;
                    float size     = owner.GetCombatReach();

                    if (owner.IsPet() && GetTarget().GetTypeId() == TypeId.Player)
                    {
                        distance = 1.0f;
                        size     = 1.0f;
                    }

                    if (GetTarget().IsWithinDistInMap(owner, distance))
                    {
                        return;
                    }

                    GetTarget().GetClosePoint(out x, out y, out z, size, _offset, _angle);
                }
            }
            else
            {
                // the destination has not changed, we just need to refresh the path (usually speed change)
                var end = _path.GetEndPosition();
                x = end.X;
                y = end.Y;
                z = end.Z;
            }

            if (_path == null)
            {
                _path = new PathGenerator(owner);
            }

            // allow pets to use shortcut if no path found when following their master
            bool forceDest = owner.IsTypeId(TypeId.Unit) && owner.IsPet() && owner.HasUnitState(UnitState.Follow);

            bool result = _path.CalculatePath(x, y, z, forceDest);

            if (!result && Convert.ToBoolean(_path.GetPathType() & PathType.NoPath))
            {
                // Can't reach target
                _recalculateTravel = true;
                if (owner.IsTypeId(TypeId.Unit))
                {
                    owner.ToCreature().SetCannotReachTarget(true);
                }
                return;
            }

            _targetReached     = false;
            _recalculateTravel = false;
            _speedChanged      = false;

            AddUnitStateMove(owner);

            if (owner.IsTypeId(TypeId.Unit))
            {
                owner.ToCreature().SetCannotReachTarget(false);
            }

            MoveSplineInit init = new MoveSplineInit(owner);

            init.MovebyPath(_path.GetPath());
            init.SetWalk(EnableWalking());
            // Using the same condition for facing target as the one that is used for SetInFront on movement end
            // - applies to ChaseMovementGenerator mostly
            if (_angle == 0.0f)
            {
                init.SetFacing(GetTarget());
            }

            init.Launch();
        }
コード例 #15
0
ファイル: RandomMovement.cs プロジェクト: Zakkgard/CypherCore
        public void _setRandomLocation(Creature creature)
        {
            if (creature.IsMovementPreventedByCasting())
            {
                creature.CastStop();
                return;
            }

            float respX, respY, respZ, respO, destX, destY, destZ, travelDistZ;

            creature.GetHomePosition(out respX, out respY, out respZ, out respO);
            Map map = creature.GetMap();

            bool is_air_ok = creature.CanFly();

            float angle     = (float)(RandomHelper.NextDouble() * MathFunctions.TwoPi);
            float range     = (float)(RandomHelper.NextDouble() * wander_distance);
            float distanceX = (float)(range * Math.Cos(angle));
            float distanceY = (float)(range * Math.Sin(angle));

            destX = respX + distanceX;
            destY = respY + distanceY;

            // prevent invalid coordinates generation
            GridDefines.NormalizeMapCoord(ref destX);
            GridDefines.NormalizeMapCoord(ref destY);

            travelDistZ = range;   // sin^2+cos^2=1, so travelDistZ=range^2; no need for sqrt below

            if (is_air_ok)         // 3D system above ground and above water (flying mode)
            {
                // Limit height change
                float distanceZ = (float)(RandomHelper.NextDouble() * travelDistZ / 2.0f);
                destZ = respZ + distanceZ;
                float levelZ = map.GetWaterOrGroundLevel(creature.GetPhases(), destX, destY, destZ - 2.5f);

                // Problem here, we must fly above the ground and water, not under. Let's try on next tick
                if (levelZ >= destZ)
                {
                    return;
                }
            }
            else                                                    // 2D only
            {
                // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE)
                travelDistZ = travelDistZ >= 10.0f ? 10.0f : travelDistZ;

                // The fastest way to get an accurate result 90% of the time.
                // Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long.
                destZ = map.GetHeight(creature.GetPhases(), destX, destY, respZ + travelDistZ - 2.0f, false);

                if (Math.Abs(destZ - respZ) > travelDistZ)              // Map check
                {
                    // Vmap Horizontal or above
                    destZ = map.GetHeight(creature.GetPhases(), destX, destY, respZ - 2.0f, true);

                    if (Math.Abs(destZ - respZ) > travelDistZ)
                    {
                        // Vmap Higher
                        destZ = map.GetHeight(creature.GetPhases(), destX, destY, respZ + travelDistZ - 2.0f, true);

                        // let's forget this bad coords where a z cannot be find and retry at next tick
                        if (Math.Abs(destZ - respZ) > travelDistZ)
                        {
                            return;
                        }
                    }
                }
            }

            if (is_air_ok)
            {
                i_nextMoveTime.Reset(0);
            }
            else
            {
                if (RandomHelper.randChance(50))
                {
                    i_nextMoveTime.Reset(RandomHelper.IRand(5000, 10000));
                }
                else
                {
                    i_nextMoveTime.Reset(RandomHelper.IRand(50, 400));
                }
            }

            creature.AddUnitState(UnitState.RoamingMove);

            MoveSplineInit init = new MoveSplineInit(creature);

            init.MoveTo(destX, destY, destZ);
            init.SetWalk(true);
            init.Launch();

            //Call for creature group update
            if (creature.GetFormation() != null && creature.GetFormation().getLeader() == creature)
            {
                creature.GetFormation().LeaderMoveTo(destX, destY, destZ);
            }
        }
コード例 #16
0
ファイル: TargetMovement.cs プロジェクト: uvbs/CypherCore
        public void _setTargetLocation(T owner, bool updateDestination)
        {
            if (!Reftarget.IsValid() || !Target.IsInWorld)
            {
                return;
            }

            if (owner.HasUnitState(UnitState.NotMove))
            {
                return;
            }

            if (owner.IsMovementPreventedByCasting())
            {
                return;
            }

            if (owner.IsTypeId(TypeId.Unit) && !Target.IsInAccessiblePlaceFor(owner.ToCreature()))
            {
                owner.ToCreature().SetCannotReachTarget(true);
                return;
            }

            if (owner.IsTypeId(TypeId.Unit) && owner.ToCreature().IsFocusing(null, true))
            {
                return;
            }

            float x, y, z;

            if (updateDestination || i_path == null)
            {
                if (offset == 0)
                {
                    if (Target.IsWithinDistInMap(owner, SharedConst.ContactDistance))
                    {
                        return;
                    }

                    // to nearest contact position
                    Target.GetContactPoint(owner, out x, out y, out z);
                }
                else
                {
                    float dist = 0;
                    float size = 0;

                    // Pets need special handling.
                    // We need to subtract GetObjectSize() because it gets added back further down the chain
                    //  and that makes pets too far away. Subtracting it allows pets to properly
                    //  be (GetCombatReach() + i_offset) away.
                    // Only applies when i_target is pet's owner otherwise pets and mobs end up
                    //   doing a "dance" while fighting
                    if (owner.IsPet() && Target.IsTypeId(TypeId.Player))
                    {
                        dist = 1.0f; // target.GetCombatReach();
                        size = 1.0f; // target.GetCombatReach() - target.GetObjectSize();
                    }
                    else
                    {
                        dist = offset + 1.0f;
                        size = owner.GetObjectSize();
                    }

                    if (Target.IsWithinDistInMap(owner, dist))
                    {
                        return;
                    }

                    // to at i_offset distance from target and i_angle from target facing
                    Target.GetClosePoint(out x, out y, out z, size, offset, angle);
                }
            }
            else
            {
                // the destination has not changed, we just need to refresh the path (usually speed change)
                var end = i_path.GetEndPosition();
                x = end.X;
                y = end.Y;
                z = end.Z;
            }

            if (i_path == null)
            {
                i_path = new PathGenerator(owner);
            }

            // allow pets to use shortcut if no path found when following their master
            bool forceDest = (owner.IsTypeId(TypeId.Unit) && owner.IsPet() &&
                              owner.HasUnitState(UnitState.Follow));

            bool result = i_path.CalculatePath(x, y, z, forceDest);

            if (!result && Convert.ToBoolean(i_path.GetPathType() & PathType.NoPath))
            {
                // Can't reach target
                recalculateTravel = true;
                if (owner.IsTypeId(TypeId.Unit))
                {
                    owner.ToCreature().SetCannotReachTarget(true);
                }
                return;
            }

            _addUnitStateMove(owner);
            targetReached     = false;
            recalculateTravel = false;
            owner.AddUnitState(UnitState.Chase);
            if (owner.IsTypeId(TypeId.Unit))
            {
                owner.ToCreature().SetCannotReachTarget(false);
            }

            MoveSplineInit init = new MoveSplineInit(owner);

            init.MovebyPath(i_path.GetPath());
            init.SetWalk(EnableWalking());
            // Using the same condition for facing target as the one that is used for SetInFront on movement end
            // - applies to ChaseMovementGenerator mostly
            if (angle == 0.0f)
            {
                init.SetFacing(Target);
            }

            init.Launch();
        }
コード例 #17
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);
        }
コード例 #18
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);
        }
コード例 #19
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)
            {
                if ((_currentNode == _path.nodes.Count - 1) && !_repeating) // If that's our last waypoint
                {
                    WaypointNode lastWaypoint = _path.nodes.ElementAt(_currentNode);

                    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;
                    return(true);
                }

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

                // inform AI
                if (creature.IsAIEnabled)
                {
                    Cypher.Assert(_currentNode < _path.nodes.Count, $"WaypointMovementGenerator.StartMove: tried to reference a node id ({_currentNode}) which is not included in path ({_path.id})");
                    creature.GetAI().WaypointStarted(_path.nodes[(int)_currentNode].id, _path.id);
                }
            }

            WaypointNode waypoint      = _path.nodes.ElementAt(_currentNode);
            Position     formationDest = new Position(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 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(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);
        }