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