protected override void ClientInteractStart(ClientObjectData data) { var worldObject = data.GameObject; var character = Client.Characters.CurrentPlayerCharacter; var menuWindow = WindowCraftingStation.Open(this); ClientCurrentInteractionMenu.RegisterMenuWindow(menuWindow); InteractionCheckerSystem.Register( character, worldObject, finishAction: _ => menuWindow.CloseWindow()); ClientInteractionUISystem.Register( worldObject, menuWindow, onMenuClosedByClient: () => InteractionCheckerSystem.Unregister( character, worldObject, isAbort: false)); ClientCurrentInteractionMenu.Open(); }
private void ServerRemote_OnClientInteractFinish(IStaticWorldObject worldObject) { var character = ServerRemoteContext.Character; if (!InteractionCheckerSystem.Unregister(character, worldObject, isAbort: false)) { return; } Logger.Important($"Client {character} informed that the object interaction with {worldObject} is finished"); this.ServerFinishInteractionInternal(character, worldObject); }
private void SharedAbortActionInternal(ICharacter character, TActionRequest request) { var characterPrivateState = PlayerCharacter.GetPrivateState(character); var state = characterPrivateState.CurrentActionState; if (!(state is TActionState actionState)) { // no action or action of another state type return; } if (!request.Equals(actionState.Request)) { // different request active return; } if (!state.IsCompleted) { // reset action state actionState.Cancel(); // return now - because this method was just called again by SetCurrentActionState return; } // ensure the action state is reset characterPrivateState.SetCurrentActionState(null); Logger.Info("Action cancelled: " + state, character); if (state.TargetWorldObject != null) { InteractionCheckerSystem.Unregister(character, state.TargetWorldObject, isAbort: false); } if (IsClient && !state.IsCancelledByServer) { Instance.CallServer(_ => _.ServerRemote_AbortAction(request)); } else if (IsServer && !ServerRemoteContext.IsRemoteCall) { Instance.CallClient(character, _ => _.ClientRemote_AbortAction(request)); // TODO: notify other players as well } }
public void SharedOnActionCompleted(TActionState state) { var character = state.Character; var request = state.Request; Logger.Info("Action completed: " + request, character); if (state.TargetWorldObject != null) { InteractionCheckerSystem.Unregister(character, state.TargetWorldObject, isAbort: false); } var canComplete = true; try { // ensure the request is still valid this.SharedValidateRequest(request); } catch (Exception ex) { canComplete = false; Logger.Warning("Exception during completed action processing: " + ex.Message + Environment.NewLine + request); } if (canComplete) { try { this.SharedOnActionCompletedInternal(state, character); } catch (Exception ex) { Logger.Exception(ex, "Exception during completed action processing"); } } PlayerCharacter.GetPrivateState(character).SetCurrentActionState(null); }
private async void ClientInteractStartAsync(IStaticWorldObject worldObject) { if (this.isAwaitingServerInteraction) { return; } var character = Client.Characters.CurrentPlayerCharacter; if (InteractionCheckerSystem.GetCurrentInteraction(character) == worldObject) { // already interacting with this object return; } this.isAwaitingServerInteraction = true; try { var requestId = ++lastRequestId; var isOpened = await this.CallServer(_ => _.ServerRemote_OnClientInteractStart(worldObject)); if (!isOpened || requestId != lastRequestId) { return; } } finally { this.isAwaitingServerInteraction = false; } var menuWindow = SharedGetProto(worldObject).ClientOpenUI(worldObject); if (menuWindow == null) { Logger.Important("Cannot open menu for object interaction with " + worldObject); this.CallServer(_ => _.ServerRemote_OnClientInteractFinish(worldObject)); return; } ClientCurrentInteractionMenu.RegisterMenuWindow(menuWindow); InteractionCheckerSystem.Register( character, worldObject, finishAction: _ => menuWindow.CloseWindow()); ClientInteractionUISystem.Register( worldObject, menuWindow, onMenuClosedByClient: () => { InteractionCheckerSystem.Unregister(character, worldObject, isAbort: false); if (!worldObject.IsDestroyed) { ++lastRequestId; this.CallServer(_ => _.ServerRemote_OnClientInteractFinish(worldObject)); } }); Logger.Important("Started object interaction with " + worldObject); ClientCurrentInteractionMenu.Open(); }
public static void ServerTryAbortInteraction(ICharacter character, IStaticWorldObject worldObject) { InteractionCheckerSystem.Unregister(character, worldObject, isAbort: true); }