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();
        }
Example #2
0
        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);
        }
Example #3
0
        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
            }
        }
Example #4
0
        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);
        }
Example #5
0
        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();
        }
Example #6
0
 public static void ServerTryAbortInteraction(ICharacter character, IStaticWorldObject worldObject)
 {
     InteractionCheckerSystem.Unregister(character, worldObject, isAbort: true);
 }