private void HandleGrabMove(GrabInfo data, Player player, IInteractionDelegate @delegate) { if (this.Grabbables.TryGetValue(data.GrabbableId, out IGrabbable grabbable)) { grabbable.Move(data.CameraInfo); } }
public void Update(CameraInfo cameraInfo) { if (this.Delegate == null || this.GrabDelegate == null) { throw new Exception("No Delegate"); } // Dispatch grab action to server so that server can test if grab succeed. // If grab succeed, server would update the grabbable's player for all clients // Note: // This check is done in update to counter the case of network lag // if touch down and up is very quick, the shouldTryRelease might not trigger right at touch up, // because information on grabbed grabbableID might not arrived yet if (this.isTouching && this.GrabbedGrabbable == null) { if (GameTime.FrameCount % 3 == 0) // Only send messages at 20 fps to save bandwidth { // Send grab message to server if player can grab something var grabbable = this.GrabbableToGrab(cameraInfo.Ray); if (grabbable != null) { var grab = new GrabInfo(grabbable.GrabbableId, cameraInfo); this.Delegate.DispatchActionToServer(new GameActionType { TryGrab = grab, Type = GameActionType.GActionType.TryGrab }); return; } } } if (this.GrabbedGrabbable != null) { if (!this.Delegate.IsServer) { // Client move the sling locally, ignore server's physics data to prevent lag this.GrabbedGrabbable.Move(cameraInfo); } // If touch is up or the sling is pulled too far, release the ball if (!this.isTouching || this.GrabDelegate.ShouldForceRelease(this.GrabbedGrabbable)) { if (GameTime.FrameCount % 3 == 0)// Only send messages at 20 fps to save bandwidth { var grab = new GrabInfo(this.GrabbedGrabbable.GrabbableId, cameraInfo); this.Delegate.DispatchActionToServer(new GameActionType { TryRelease = grab, Type = GameActionType.GActionType.TryRelease }); return; } } // Dispatch slingMove to server. var data = new GrabInfo(this.GrabbedGrabbable.GrabbableId, cameraInfo); this.Delegate.DispatchActionToServer(new GameActionType { GrabMove = data, Type = GameActionType.GActionType.GrabMove }); } }
private void HandleGrabStartAction(GrabInfo data, Player player, IInteractionDelegate @delegate) { if (this.GrabDelegate == null) { throw new Exception("GrabDelegate not set"); } var grabbable = this.GrabbableById(data.GrabbableId); this.GrabbedGrabbable = grabbable; this.GrabDelegate.OnGrabStart(grabbable, data.CameraInfo, player); }
private void HandleGrabbableStatus(GrabInfo status) { if (this.GrabDelegate == null) { throw new Exception("GrabDelegate not set"); } if (!this.Grabbables.TryGetValue(status.GrabbableId, out IGrabbable grabbable)) { throw new Exception($"No Grabbable {status.GrabbableId}"); } grabbable.IsGrabbed = true; this.GrabDelegate.OnUpdateGrabStatus(grabbable, status.CameraInfo); }
public void DidCollision(SCNNode node, SCNNode otherNode, SCNVector3 pos, float impulse) { var gameObject = node.NearestParentGameObject(); if (gameObject != null && gameObject is Catapult catapult) { var otherGameObject = otherNode.NearestParentGameObject(); if (otherGameObject != null) { // Projectile case if (otherGameObject is Projectile projectile) { var catapultNode = catapult.Base; if (catapultNode.PhysicsBody == null) { throw new Exception("Catapult has no physicsBody"); } // Do not let projectile from the same team kill the catapult if (catapult.Team == projectile.Team) { catapultNode.PhysicsBody.Velocity = SCNVector3.Zero; catapultNode.PhysicsBody.AngularVelocity = SCNVector4.UnitY; } } // Server tries to release the catapult if it got impulse from block or projectile if (impulse > MinImpuseToReleaseCatapult) { if (this.Delegate == null) { throw new Exception("No delegate"); } if (this.Delegate.IsServer) { // Any game objects (blocks or projectiles) case var data = new GrabInfo(catapult.CatapultId, catapult.LastCameraInfo); this.Delegate.DispatchActionToServer(new GameActionType { TryRelease = data, Type = GameActionType.GActionType.TryRelease }); } } } } }
private void HandleTryGrabAction(GrabInfo data, Player player, IInteractionDelegate @delegate) { if (this.GrabDelegate == null) { throw new Exception("GrabDelegate not set"); } // since we can't send a message only to the server, make sure we're the server // when processing. if (@delegate.IsServer) { // Check if player already owned a grabbable // This is to filter tryGrab messages a player might send because it has not received grab message yet foreach (var value in this.Grabbables.Values) { if (value.Player != null && value.Player == player) { return; } } var grabbable = this.GrabbableById(data.GrabbableId); this.GrabDelegate.OnServerGrab(grabbable, data.CameraInfo, player); grabbable.Player = player; // Inform player that the grabbable was grabbed var newData = new GrabInfo(grabbable.GrabbableId, data.CameraInfo); @delegate.DispatchToPlayer(new GameActionType { GrabStart = newData, Type = GameActionType.GActionType.GrabStart }, player); // Update grabbable in the server and clients with a new status // Note: status update only sends the information on whether this.HandleGrabbableStatus(newData); @delegate.ServerDispatchActionToAll(new GameActionType { GrabbableStatus = newData, Type = GameActionType.GActionType.GrabbableStatus }); } }
private void HandleTryReleaseAction(GrabInfo data, Player player, IInteractionDelegate @delegate) { if (this.GrabDelegate == null) { throw new Exception("GrabDelegate not set"); } if (this.Delegate.IsServer) { // Launch if player already grabbed a grabbable var grabbable = this.GrabbableById(data.GrabbableId); if (grabbable.IsGrabbed) { this.GrabDelegate.OnServerRelease(grabbable, data.CameraInfo, player); // Inform player that the grabbable was grabbed var newData = new GrabInfo(grabbable.GrabbableId, data.CameraInfo); @delegate.DispatchToPlayer(new GameActionType { ReleaseEnd = newData, Type = GameActionType.GActionType.ReleaseEnd }, player); } } }
private void HandleReleaseEndAction(GrabInfo data, Player player, IInteractionDelegate @delegate) { this.isTouching = false; }