Пример #1
0
        /// <summary>
        /// Sends a network message for moving a creature to a new position
        /// </summary>
        public void MoveTo(Position position, float runRate = 1.0f, bool setLoc = true, float?walkRunThreshold = null, float?speed = null)
        {
            var motion = GetMoveToPosition(position, runRate, walkRunThreshold, speed);

            // todo: use physics MoveToManager
            // todo: handle landblock updates
            if (setLoc)
            {
                Location = new Position(position);
                PhysicsObj.SetPositionSimple(new Physics.Common.Position(position), true);
            }

            EnqueueBroadcastMotion(motion);
        }
Пример #2
0
        /// <summary>
        /// Sends a network message for moving a creature to a new position
        /// </summary>
        public void MoveTo(Position position, float runRate = 1.0f, bool setLoc = true, float?walkRunThreshold = null, float?speed = null)
        {
            // TODO: change parameters to accept an optional MoveToParameters

            var motion = new Motion(this, position);

            motion.MovementType = MovementType.MoveToPosition;
            //motion.Flag |= MovementParams.CanCharge | MovementParams.FailWalk | MovementParams.UseFinalHeading | MovementParams.MoveAway;
            if (walkRunThreshold != null)
            {
                motion.MoveToParameters.WalkRunThreshold = walkRunThreshold.Value;
            }
            if (speed != null)
            {
                motion.MoveToParameters.Speed = speed.Value;
            }

            // always use final heading?
            var frame = new AFrame(position.Pos, position.Rotation);

            motion.MoveToParameters.DesiredHeading      = frame.get_heading();
            motion.MoveToParameters.MovementParameters |= MovementParams.UseFinalHeading;
            motion.MoveToParameters.DistanceToObject    = 0.6f;

            if (runRate > 0)
            {
                motion.RunRate = runRate;
            }
            else
            {
                motion.MoveToParameters.MovementParameters &= ~MovementParams.CanRun;
            }

            // todo: use physics MoveToManager
            // todo: handle landblock updates
            if (setLoc)
            {
                Location = new Position(position);
                PhysicsObj.SetPositionSimple(new Physics.Common.Position(position), true);
            }

            EnqueueBroadcastMotion(motion);
        }
Пример #3
0
        public void UseTime()
        {
            if (PhysicsObj == null)
            {
                return;
            }

            if (NodeFailCounter > 3 || PositionQueue.Count == 0)
            {
                if (NodeFailCounter <= 0)
                {
                    return;
                }

                var last = PositionQueue.Last();
                if (last.Type != InterpolationNodeType.JumpType && last.Type != InterpolationNodeType.VelocityType)
                {
                    if (PhysicsObj.SetPositionSimple(last.Position, true) != SetPositionError.OK)
                    {
                        return;
                    }

                    StopInterpolating();
                    return;
                }

                if (PositionQueue.Count > 1)
                {
                    for (var i = PositionQueue.Count; i >= 0; --i)
                    {
                        var node = PositionQueue.ElementAt(i);
                        if (node.Type == InterpolationNodeType.PositionType)
                        {
                            if (PhysicsObj.SetPositionSimple(node.Position, true) != SetPositionError.OK)
                            {
                                return;
                            }

                            PhysicsObj.set_velocity(last.Velocity, true);
                            StopInterpolating();
                            return;
                        }
                    }
                }

                if (PhysicsObj.SetPositionSimple(BlipToPosition, true) != SetPositionError.OK)
                {
                    return;
                }

                StopInterpolating();
                return;
            }

            var first = PositionQueue.FirstOrDefault();

            switch (first.Type)
            {
            case InterpolationNodeType.JumpType:
                NodeCompleted(true);
                break;

            case InterpolationNodeType.VelocityType:
                PhysicsObj.set_velocity(first.Velocity, true);
                NodeCompleted(true);
                break;
            }
        }
Пример #4
0
        public void HandleActionEnterPkLite()
        {
            // ensure permanent npk
            if (PlayerKillerStatus != PlayerKillerStatus.NPK || MinimumTimeSincePk != null)
            {
                Session.Network.EnqueueSend(new GameEventWeenieError(Session, WeenieError.OnlyNonPKsMayEnterPKLite));
                return;
            }

            if (TooBusyToRecall)
            {
                Session.Network.EnqueueSend(new GameEventWeenieError(Session, WeenieError.YoureTooBusy));
                return;
            }

            var animTime = 0.0f;

            if (CombatMode != CombatMode.NonCombat)
            {
                Session.Network.EnqueueSend(new GameMessagePrivateUpdatePropertyInt(this, PropertyInt.CombatMode, (int)CombatMode.NonCombat));
                animTime += SetCombatMode(CombatMode.NonCombat);
            }

            var actionChain = new ActionChain();

            actionChain.AddDelaySeconds(animTime);
            actionChain.AddAction(this, () =>
            {
                IsBusy = true;

                EnqueueBroadcast(new GameMessageSystemChat($"{Name} is looking for a fight!", ChatMessageType.Broadcast), LocalBroadcastRange);

                // perform pk lite entry motion / effect
                SendMotionAsCommands(MotionCommand.EnterPKLite, MotionStance.NonCombat);

                var innerChain = new ActionChain();

                // wait for animation to complete
                animTime = DatManager.PortalDat.ReadFromDat <MotionTable>(MotionTableId).GetAnimationLength(MotionCommand.EnterPKLite);
                innerChain.AddDelaySeconds(animTime);
                innerChain.AddAction(this, () =>
                {
                    IsBusy = false;

                    if (PropertyManager.GetBool("allow_pkl_bump").Item)
                    {
                        // check for collisions
                        PlayerKillerStatus = PlayerKillerStatus.PKLite;

                        var colliding = PhysicsObj.ethereal_check_for_collisions();

                        if (colliding)
                        {
                            // try initial placement
                            var result = PhysicsObj.SetPositionSimple(PhysicsObj.Position, true);

                            if (result == SetPositionError.OK)
                            {
                                // handle landblock update?
                                SyncLocation();

                                // force broadcast
                                Sequences.GetNextSequence(SequenceType.ObjectForcePosition);
                                SendUpdatePosition();
                            }
                        }
                    }
                    UpdateProperty(this, PropertyInt.PlayerKillerStatus, (int)PlayerKillerStatus.PKLite, true);

                    Session.Network.EnqueueSend(new GameEventWeenieError(Session, WeenieError.YouAreNowPKLite));
                });

                innerChain.EnqueueChain();
            });
            actionChain.EnqueueChain();
        }
Пример #5
0
        public void HandleActionEnterPkLite()
        {
            // ensure permanent npk
            if (PlayerKillerStatus != PlayerKillerStatus.NPK || MinimumTimeSincePk != null)
            {
                Session.Network.EnqueueSend(new GameEventWeenieError(Session, WeenieError.OnlyNonPKsMayEnterPKLite));
                return;
            }

            if (TooBusyToRecall)
            {
                Session.Network.EnqueueSend(new GameEventWeenieError(Session, WeenieError.YoureTooBusy));
                return;
            }

            EnqueueBroadcast(new GameMessageSystemChat($"{Name} is looking for a fight!", ChatMessageType.Broadcast), LocalBroadcastRange);

            // perform pk lite entry motion / effect

            IsBusy = true;

            var prevStance = CurrentMotionState.Stance;

            var actionChain = new ActionChain();

            var animTime = 0.0f;

            animTime += EnqueueMotion_Force(actionChain, MotionStance.NonCombat, MotionCommand.EnterPKLite);

            actionChain.AddAction(this, () =>
            {
                if (PropertyManager.GetBool("allow_pkl_bump").Item)
                {
                    // check for collisions
                    PlayerKillerStatus = PlayerKillerStatus.PKLite;

                    var colliding = PhysicsObj.ethereal_check_for_collisions();

                    if (colliding)
                    {
                        // try initial placement
                        var result = PhysicsObj.SetPositionSimple(PhysicsObj.Position, true);

                        if (result == SetPositionError.OK)
                        {
                            // handle landblock update?
                            SyncLocation();

                            // force broadcast
                            Sequences.GetNextSequence(SequenceType.ObjectForcePosition);
                            SendUpdatePosition();
                        }
                    }
                }
                UpdateProperty(this, PropertyInt.PlayerKillerStatus, (int)PlayerKillerStatus.PKLite, true);

                Session.Network.EnqueueSend(new GameEventWeenieError(Session, WeenieError.YouAreNowPKLite));
            });

            // return to previous stance, if applicable
            if (prevStance != MotionStance.NonCombat)
            {
                animTime += EnqueueMotion_Force(actionChain, prevStance, MotionCommand.Ready, MotionCommand.NonCombat);
            }

            actionChain.AddAction(this, () => IsBusy = false);

            actionChain.EnqueueChain();
        }