Exemplo n.º 1
0
        /// <summary>
        /// Called after the current node or the index of the current dialogue entry has changed.
        /// </summary>
        /// <remarks>
        /// The game state will be updated according to walkedThroughNodes and current dialogue index.
        /// This method will check if the game state has changed and trigger proper events
        /// </remarks>
        /// <param name="forceRefreshDialogue">refresh dialogue no matter the game state has change or not</param>
        /// <param name="forceRefreshNode">refresh the node no matter the node has changed or not</param>
        private void UpdateGameState(bool forceRefreshDialogue = false, bool forceRefreshNode = false)
        {
            Assert.IsFalse(walkedThroughNodes.Count == 0,
                           "Nova: walkedThroughNodes is empty, can not update game state.");

            // update current node
            var desiredNodeName = walkedThroughNodes.Last();
            var nodeChanged     = currentNode == null || currentNode.name != desiredNodeName;

            if (nodeChanged || forceRefreshNode)
            {
                currentNode = flowChartTree.FindNode(desiredNodeName);
                if (NodeChanged != null)
                {
                    NodeChanged.Invoke(new NodeChangedData(currentNode.name, currentNode.description));
                }
            }

            // update dialogue
            var dialogueChanged = nodeChanged || currentIndex != oldIndex;

            if (dialogueChanged || forceRefreshDialogue)
            {
                Assert.IsTrue(currentIndex >= 0 && currentIndex < currentNode.DialogueEntryCount,
                              "Nova: dialogue index out of range");
                currentDialogueEntry = currentNode.GetDialogueEntryAt(currentIndex);
                oldIndex             = currentIndex;

                if (checkpointManager.IsReached(currentNode.name, currentIndex) == null)
                {
                    // tell the checkpoint manager a new dialogue entry has been reached
                    checkpointManager.SetReached(currentNode.name, currentIndex, GetGameStateStepRestoreEntry());
                }

                if (DialogueWillChange != null)
                {
                    DialogueWillChange.Invoke();
                }

                state = State.ActionRunning;
                currentDialogueEntry.ExecuteAction();
                StartCoroutine(WaitActionEnd());
            }
        }
Exemplo n.º 2
0
        private void DialogueSaveCheckpoint(bool firstEntryOfNode, bool dialogueStepped, out bool isReached,
                                            out bool isReachedAnyHistory)
        {
            if (!firstEntryOfNode && dialogueStepped)
            {
                stepNumFromLastCheckpoint++;
            }

            var entry = checkpointManager.GetReached(nodeHistory, currentIndex);

            isReached           = entry != null;
            isReachedAnyHistory = checkpointManager.IsReachedAnyHistory(currentNode.name, currentIndex);
            if (entry == null)
            {
                // Tell CheckpointManager that a new dialogue entry has been reached
                checkpointManager.SetReached(nodeHistory, currentIndex, GetRestoreEntry());
            }

            // Change states after creating or restoring from checkpoint
            if (shouldSaveCheckpoint)
            {
                stepNumFromLastCheckpoint = 0;
            }

            if (entry != null)
            {
                this.RuntimeAssert(stepNumFromLastCheckpoint == entry.stepNumFromLastCheckpoint,
                                   $"stepNumFromLastCheckpoint mismatch: {stepNumFromLastCheckpoint} {entry.stepNumFromLastCheckpoint}. Try to clear save data.");
                this.RuntimeAssert(restrainCheckpointNum == entry.restrainCheckpointNum,
                                   $"restrainCheckpointNum mismatch: {restrainCheckpointNum} {entry.restrainCheckpointNum}. Try to clear save data.");
            }

            if (checkpointRestrained)
            {
                restrainCheckpointNum--;
            }

            // As the action for this dialogue will be re-run, it's fine to just reset forceCheckpoint to false
            forceCheckpoint = false;
        }
Exemplo n.º 3
0
        /// <summary>
        /// Called after the current node or the index of the current dialogue entry has changed.
        /// </summary>
        /// <remarks>
        /// Trigger events according to the current game state and how it is changed
        /// </remarks>
        /// <param name="nodeChanged"></param>
        /// <param name="dialogueChanged"></param>
        /// <param name="firstEntryOfNode"></param>
        /// <param name="dialogueStepped"></param>
        private void UpdateGameState(bool nodeChanged, bool dialogueChanged, bool firstEntryOfNode,
                                     bool dialogueStepped)
        {
            // Debug.LogFormat("UpdateGameState begin {0} {1} {2}", stepNumFromLastCheckpoint, restrainCheckpoint, forceCheckpoint);

            if (nodeChanged)
            {
                // Debug.Log($"Nova: node changed to {currentNode.name}");

                if (firstEntryOfNode)
                {
                    EnsureCheckpoint();                   // always get a checkpoint at the beginning of the node
                }
                NodeChanged?.Invoke(new NodeChangedData(currentNode.name));
            }

            if (dialogueChanged)
            {
                this.RuntimeAssert(currentIndex >= 0 && currentIndex < currentNode.dialogueEntryCount,
                                   "Dialogue index out of range.");

                if (!firstEntryOfNode && dialogueStepped)
                {
                    stepNumFromLastCheckpoint++;
                }

                var gameStateRestoreEntry = checkpointManager.IsReached(currentNode.name, currentIndex, variables.hash);
                if (gameStateRestoreEntry == null)
                {
                    // Tell the checkpoint manager a new dialogue entry has been reached
                    checkpointManager.SetReached(currentNode.name, currentIndex, variables,
                                                 GetGameStateStepRestoreEntry());
                }

                // Change states after creating or restoring from checkpoint
                if (shouldSaveRealCheckpoint)
                {
                    stepNumFromLastCheckpoint = 0;
                }

                if (gameStateRestoreEntry != null)
                {
                    this.RuntimeAssert(stepNumFromLastCheckpoint == gameStateRestoreEntry.stepNumFromLastCheckpoint,
                                       $"StepNumFromLastCheckpoint mismatch: {stepNumFromLastCheckpoint} {gameStateRestoreEntry.stepNumFromLastCheckpoint}");
                    this.RuntimeAssert(restrainCheckpoint == gameStateRestoreEntry.restrainCheckpointNum,
                                       $"RestrainCheckpointNum mismatch: {restrainCheckpoint} {gameStateRestoreEntry.restrainCheckpointNum}");
                }

                if (checkpointRestrained)
                {
                    restrainCheckpoint--;
                    if (restrainCheckpoint == 1)
                    {
                        Debug.LogWarning($"Nova: restrainCheckpoint reaches 1");
                    }
                }

                // As the action for this dialogue will be re-run, it's fine to just reset forceCheckpoint to false
                forceCheckpoint = false;

                DialogueWillChange?.Invoke();

                state = State.ActionRunning;
                lastVariablesHashBeforeAction = variables.hash;
                currentDialogueEntry          = currentNode.GetDialogueEntryAt(currentIndex);
                currentDialogueEntry.ExecuteAction();
                StartCoroutine(WaitActionEnd(gameStateRestoreEntry != null));
            }

            // Debug.LogFormat("UpdateGameState end {0} {1} {2} {3}", stepNumFromLastCheckpoint, restrainCheckpoint, forceCheckpoint, currentDialogueEntry?.displayData.FormatNameDialogue());
        }