private void UpdateRotation() { // rotate the npc to face the destination (x, z) var direction = destination - Position; // setting y to 0 to avoid changing the pitch direction.Y = 0; this.Transform.Rotation = Quaternion.FromToRotation(Vector3.Forward, direction); if (nextRotationCheckTime <= CurrentZone.World.GlobalTime) { var yRotation = this.Rotation.EularAngles().Y; if (Math.Abs(lastOrientation - yRotation) > 0.1f) { var rotationEvent = new ObjectTransform { ObjectId = this.Guid, Orientation = yRotation }; var message = new MmoObjectEventMessage(this, rotationEvent, new MessageParameters { ChannelId = PeerSettings.MmoObjectEventChannel }); this.EventChannel.Publish(message); this.lastOrientation = yRotation; } this.nextRotationCheckTime = CurrentZone.World.GlobalTime + ServerGameSettings.OBJECT_ROTATION_CHECK_INTERVAL; } }
/// <summary> /// Publishes a movement stop event /// </summary> private void PublishStopEvent() { var movementEvent = new ObjectMovement { ObjectId = this.Guid, Speed = 0, State = (byte)MovementState.Idle }; var message = new MmoObjectEventMessage(this, movementEvent, new MessageParameters { ChannelId = PeerSettings.MmoObjectEventChannel }); this.EventChannel.Publish(message); }
/// <summary> /// Called when a property needs to be published to client(s). Publishes a <see cref="MmoObjectEventMessage"/> on the <see cref="EventChannel"/> /// by default with the changed property. /// </summary> protected virtual void PublishProperty(PropertyCode propertyCode, object value) { var setProperty = new ObjectProperty { ObjectId = this.Guid, PropertiesCode = (byte)propertyCode, EventData = value }; var msg = new MmoObjectEventMessage(this, setProperty, new MessageParameters { ChannelId = PeerSettings.MmoObjectEventChannel }); this.EventChannel.Publish(msg); }
private void UpdateSpellRotation() { // rotation will be directly facing the destination this.Transform.Rotation = Quaternion.FromToRotation(Vector3.Forward, (destination - Position)); if (nextRotationCheckTime <= CurrentZone.World.GlobalTime) { var eularAngles = this.Rotation.EularAngles(); var xRotation = eularAngles.X; var yRotation = eularAngles.Y; var orientationChanged = Math.Abs(lastOrientation - yRotation) > 0.1f; var pitchChanged = Math.Abs(lastPitch - xRotation) > 0.1f; // send update if the rotation changed if (orientationChanged || pitchChanged) { var rotationEvent = new ObjectTransform { ObjectId = this.Guid, }; if (orientationChanged) { rotationEvent.Orientation = yRotation; this.lastOrientation = yRotation; } if (pitchChanged) { rotationEvent.Pitch = xRotation; this.lastPitch = xRotation; } var message = new MmoObjectEventMessage(this, rotationEvent, new MessageParameters { ChannelId = PeerSettings.MmoObjectEventChannel }); this.EventChannel.Publish(message); } this.nextRotationCheckTime = CurrentZone.World.GlobalTime + ServerGameSettings.OBJECT_ROTATION_CHECK_INTERVAL; } }
/// <summary> /// Moves the <see cref="Npc"/>'s position towards the destination /// </summary> private void Move(float deltaTime) { // direction is based on the velocity since the npc can move in any direction based on AI var direction = Vector3.Transform(uVelocity, this.Transform.Rotation).Normalize(); // note: deltaTime is in seconds var newPosition = this.Position + direction * this.CurrentSpeed * deltaTime; // clamping to avoid walking off the terrain newPosition = this.CurrentZone.Bounds.Clamp(newPosition); newPosition.Y = this.CurrentZone.GetHeight(newPosition.X, newPosition.Z); this.Transform.Position = newPosition; var speedChanged = (lastSpeed != this.CurrentSpeed); var directionChanged = (lastDirection != this.CurrentDirection); var stateChanged = (lastMovementState != this.CurrentMovementState); if (speedChanged || stateChanged || directionChanged) { var movementEvent = new ObjectMovement { ObjectId = this.Guid, }; if (speedChanged) { movementEvent.Speed = (byte)this.CurrentSpeed; this.lastSpeed = this.CurrentSpeed; } var yRotation = this.Rotation.EularAngles().Y; if (Math.Abs(lastOrientation - yRotation) > 0.1f) { movementEvent.Orientation = yRotation; this.lastOrientation = yRotation; } if (directionChanged) { movementEvent.Direction = (byte)this.CurrentDirection; this.lastDirection = this.CurrentDirection; } if (stateChanged) { movementEvent.State = (byte)this.CurrentMovementState; this.lastMovementState = this.CurrentMovementState; } var message = new MmoObjectEventMessage(this, movementEvent, new MessageParameters { ChannelId = PeerSettings.MmoObjectEventChannel }); this.EventChannel.Publish(message); } if (nextMovementPublishTime <= CurrentZone.World.GlobalTime) { this.UpdateInterestManagement(); var positionEvent = new ObjectTransform { ObjectId = this.Guid, Position = this.Position.ToFloatArray(3) }; var message = new MmoObjectEventMessage(this, positionEvent, new MessageParameters { ChannelId = PeerSettings.MmoObjectEventChannel }); // TODO: Consider sending this unreliable and reducing the update interval this.EventChannel.Publish(message); this.nextMovementPublishTime = CurrentZone.World.GlobalTime + ServerGameSettings.OBJECT_MOVEMENT_PUBLISH_INTERVAL; } }
/// <summary> /// Moves the <see cref="Dynamic"/>'s position towards the destination /// </summary> protected void DoSpellMove(Vector3 position, int deltaTime) { // the element can move only in the forward (+z) direction (facing the target most of the time) var direction = Vector3.Transform(Vector3.Forward, this.Rotation).Normalize(); // note: deltaTime is in milliseconds var newPos = this.Position + direction * this.CurrentSpeed * (deltaTime / 1000f); // clamping to avoid walking off the terrain this.Transform.Position = this.CurrentZone.Bounds.Clamp(newPos); // send update if the speed changed if (lastSpeed != this.CurrentSpeed) { var movementEvent = new ObjectMovement { ObjectId = this.Guid, Speed = (byte)this.CurrentSpeed, }; this.lastSpeed = this.CurrentSpeed; var eularAngles = this.Rotation.EularAngles(); var yRotation = eularAngles.Y; // check the rotation for changes so we can send it with this update rather than let the UpdateRotation() handle it // this way we can send it as one update rather than two if (Math.Abs(lastOrientation - yRotation) > 0.1f) { movementEvent.Orientation = yRotation; this.lastOrientation = yRotation; } var xRotation = eularAngles.X; // check the rotation for changes so we can send it with this update rather than let the UpdateRotation() handle it // this way we can send it as one update rather than two if (Math.Abs(lastPitch - xRotation) > 0.1f) { movementEvent.Pitch = xRotation; this.lastPitch = xRotation; } var message = new MmoObjectEventMessage(this, movementEvent, new MessageParameters { ChannelId = PeerSettings.MmoObjectEventChannel }); this.EventChannel.Publish(message); } // publishing our real position in case the client needs a position correction if (nextMovementPublishTime <= CurrentZone.World.GlobalTime) { this.UpdateInterestManagement(); var positionEvent = new ObjectTransform { ObjectId = this.Guid, Position = this.Position.ToFloatArray(3) }; var message = new MmoObjectEventMessage(this, positionEvent, new MessageParameters { ChannelId = PeerSettings.MmoObjectEventChannel }); // TODO: Consider sending this unreliable and reducing the update interval this.EventChannel.Publish(message); this.nextMovementPublishTime = CurrentZone.World.GlobalTime + ServerGameSettings.OBJECT_MOVEMENT_PUBLISH_INTERVAL; } }
/// <summary> /// The subscribed item event. /// </summary> private void SubscribedItem_OnGameObjectEvent(MmoObjectEventMessage message) { this.receiver.SendEvent(message.EventData, message.Parameters); }