public GameStateMap Pop(PlaybackSpot playbackSpot)
        {
            var spotFound = false;
            var node      = rollbackList.First;

            while (node != null)
            {
                if (node.Value.PlaybackSpot == playbackSpot)
                {
                    spotFound = true; break;
                }
                node = node.Next;
            }
            if (!spotFound)
            {
                return(null);
            }

            while (rollbackList.First != node)
            {
                Pop();
            }

            return(Pop());
        }
Beispiel #2
0
        /// <summary>
        /// Initializes the backlog message.
        /// </summary>
        /// <param name="message">Text of the message.</param>
        /// <param name="author">Actor ID of the message author.</param>
        /// <param name="voiceClipNames">Voice replay clip names associated with the message. Provide null to disable voice replay.</param>
        /// <param name="rollbackSpot">Rollback spot associated with the message. Provide <see cref="PlaybackSpot.Invalid"/> to disable rollback.</param>
        public virtual void Initialize(string message, string author, IReadOnlyCollection <string> voiceClipNames, PlaybackSpot rollbackSpot)
        {
            SetMessage(message);
            SetAuthor(author);

            this.voiceClipNames.Clear();
            if (voiceClipNames?.Count > 0)
            {
                this.voiceClipNames.AddRange(voiceClipNames);
                if (PlayVoiceButton)
                {
                    PlayVoiceButton.gameObject.SetActive(true);
                }
            }
            else
            {
                if (PlayVoiceButton)
                {
                    PlayVoiceButton.gameObject.SetActive(false);
                }
            }

            this.rollbackSpot = rollbackSpot;
            var canRollback = rollbackSpot.Valid && stateManager.CanRollbackTo(s => s.PlaybackSpot == rollbackSpot);

            if (RollbackButton)
            {
                RollbackButton.gameObject.SetActive(canRollback);
            }
        }
Beispiel #3
0
 public BacklogMessageState(string messageText, string actorNameText,
                            IEnumerable <string> voiceClipNames, PlaybackSpot rollbackSpot)
 {
     this.messageText    = messageText;
     this.actorNameText  = actorNameText;
     this.voiceClipNames = voiceClipNames?.ToArray();
     this.rollbackSpot   = rollbackSpot;
 }
Beispiel #4
0
 public int IndexOf(PlaybackSpot playbackSpot)
 {
     for (int i = 0; i < Count; i++)
     {
         if (this[i].PlaybackSpot == playbackSpot)
         {
             return(i);
         }
     }
     return(-1);
 }
Beispiel #5
0
        /// <summary>
        /// Attempts to rollback (revert) all the engine services to a state they had at the provided playback spot.
        /// Has no effect when the rollback feature is disabled.
        /// </summary>
        /// <param name="playbackSpot">The playback spot to revert to.</param>
        /// <returns>Whether the provided playback spot was found in the rollback stack and the operation succeeded.</returns>
        public async Task <bool> RollbackAsync(PlaybackSpot playbackSpot)
        {
            var state = rollbackStateStack.Pop(playbackSpot);

            if (state is null)
            {
                return(false);
            }

            await RollbackToStateAsync(state);

            return(true);
        }
Beispiel #6
0
        /// <summary>
        /// Initializes the backlog message.
        /// </summary>
        /// <param name="message">Text of the message.</param>
        /// <param name="authorName">Name of the message author.</param>
        /// <param name="voiceClipNames">Voice replay clip names associated with the message. Provide null to disable voice replay.</param>
        /// <param name="rollbackSpot">Rollback spot associated with the message. Provide <see cref="PlaybackSpot.Invalid"/> to disable rollback.</param>
        public virtual void Initialize(string message, string authorName, List <string> voiceClipNames, PlaybackSpot rollbackSpot)
        {
            MessageText.text = message;
            if (string.IsNullOrWhiteSpace(authorName))
            {
                ActorNameText.text = null;
                ActorNameText.transform.parent.gameObject.SetActive(false);
            }
            else
            {
                ActorNameText.text = authorName;
                ActorNameText.transform.parent.gameObject.SetActive(true);
            }

            this.voiceClipNames.Clear();
            if (voiceClipNames?.Count > 0)
            {
                this.voiceClipNames.AddRange(voiceClipNames);
                if (PlayVoiceButton)
                {
                    PlayVoiceButton.gameObject.SetActive(true);
                }
            }
            else
            {
                if (PlayVoiceButton)
                {
                    PlayVoiceButton.gameObject.SetActive(false);
                }
            }

            this.rollbackSpot = rollbackSpot;
            var canRollback = rollbackSpot.Valid && stateManager.CanRollbackTo(s => s.PlaybackSpot == rollbackSpot);

            if (RollbackButton)
            {
                RollbackButton.gameObject.SetActive(canRollback);
            }
        }
 public static string GetAutoVoiceClipPath(PlaybackSpot playbackSpot)
 {
     return(string.Format(AutoVoiceClipNameTemplate, playbackSpot.ScriptName, playbackSpot.LineNumber, playbackSpot.InlineIndex));
 }
Beispiel #8
0
 public DynamicValue(PlaybackSpot playbackSpot, string valueText, IEnumerable <string> expressions)
 {
     PlaybackSpot = playbackSpot;
     ValueText    = valueText;
     Expressions  = expressions.ToArray();
 }
Beispiel #9
0
        /// <summary>
        /// Depending on whether the provided <paramref name="lineIndex"/> being before or after currently played command' line index,
        /// performs a fast-forward playback or state rollback of the currently loaded script.
        /// </summary>
        /// <param name="lineIndex">The line index to rewind at.</param>
        /// <param name="inlineIndex">The inline index to rewind at.</param>
        /// <param name="resumePlayback">Whether to resume script playback after the rewind.</param>
        /// <returns>Whether the <paramref name="lineIndex"/> has been reached.</returns>
        public async Task <bool> RewindAsync(int lineIndex, int inlineIndex = 0, bool resumePlayback = true)
        {
            if (IsPlaying)
            {
                Stop();
            }

            if (PlayedCommand is null)
            {
                Debug.LogError("Script player failed to rewind: played command is not valid.");
                if (resumePlayback)
                {
                    Play();
                }
                return(false);
            }

            var targetCommand = Playlist.GetFirstCommandAfterLine(lineIndex, inlineIndex);

            if (targetCommand is null)
            {
                Debug.LogError($"Script player failed to rewind: target line index ({lineIndex}) is not valid for `{PlayedScript.Name}` script.");
                if (resumePlayback)
                {
                    Play();
                }
                return(false);
            }

            var targetPlaylistIndex = Playlist.IndexOf(targetCommand);

            if (targetPlaylistIndex == PlayedIndex)
            {
                if (resumePlayback)
                {
                    Play();
                }
                return(true);
            }

            DisableAutoPlay();
            DisableSkip();
            DisableWaitingForInput();

            playRoutineCTS = new CancellationTokenSource();
            var cancellationToken = playRoutineCTS.Token;

            bool result;

            if (targetPlaylistIndex > PlayedIndex)
            {
                result = await FastForwardRoutineAsync(cancellationToken, targetPlaylistIndex);
            }
            else
            {
                var targetSpot = new PlaybackSpot(PlayedScript.Name, lineIndex, inlineIndex);
                result = await stateManager.RollbackAsync(targetSpot);
            }

            if (resumePlayback)
            {
                Play();
            }
            else
            {
                Stop();
            }

            return(result);
        }