예제 #1
0
        private void ReconcilePassageReferences(TwisonStory story)
        {
            foreach (var passage in story.passages)
            {
                foreach (var link in passage.links)
                {
                    var matchingPassage = story.passages.FirstOrDefault(i => i.pid == link.pid);
                    if (matchingPassage == null)
                    {
                        throw new TwisonValidationError($"No passage to match link PID {link.pid}", link);
                    }

                    link.passage = matchingPassage;
                }
            }

            // Try to resolve start node, if one is set
            if (!string.IsNullOrWhiteSpace(story.startnode))
            {
                story.startNodePassage = story.passages.FirstOrDefault(i => i.pid == story.startnode);
                if (story.startNodePassage == null)
                {
                    throw new TwisonValidationError($"No passage to match startnode PID {story.startnode}", story);
                }
            }
        }
 /// <summary>
 /// Remove newlines around the edges of passages.
 /// </summary>
 public void TrimPassages(TwisonStory story)
 {
     foreach (var passage in story.passages)
     {
         passage.text = passage.text.Trim();
     }
 }
예제 #3
0
 private void Default(TwisonStory story, Func <TwisonStory, bool> condition, Action <TwisonStory> applyDefault)
 {
     if (!condition(story))
     {
         applyDefault(story);
     }
 }
        /// <summary>
        /// Unity can't really render [[foo->bar]] as clickable links.
        /// The link data is already saved in the links object.
        /// This function removes any links in the text for each passage.
        /// </summary>
        public void RemoveLinksFromPassages(TwisonStory story)
        {
            var regex = new Regex("\\[\\[[^\\]]+\\]\\]");

            foreach (var passage in story.passages)
            {
                passage.text = regex.Replace(passage.text, "");
            }
        }
예제 #5
0
 private void OnStartRuntime(TwisonStory story, bool enterDefaultStartNode)
 {
     _active      = null;
     _activeLinks = ResolveActiveLinks();
     if (enterDefaultStartNode)
     {
         GoToPassage(story.startNodePassage, false);
     }
 }
        /// <summary>
        /// When pruning links in a story, it is common to end up with a fragment like:
        /// Hello\n[[foo->bar]]\n[[foo2->bar2]]\n...
        ///
        /// Which maps as:
        /// Hello\n\n\n...
        ///
        /// This function will trim out duplicate line sequences and replace them.
        /// Sequences longer than maxNewLineChain are reduced to that length. Sequences
        /// shorter are ignored.
        /// </summary>
        public void CollapseNewLines(TwisonStory story, int maxNewLineChain)
        {
            var pattern = "";

            for (var i = 0; i < maxNewLineChain; i++)
            {
                pattern += "\n";
            }
            var regex = new Regex($"{pattern}\n*");

            foreach (var passage in story.passages)
            {
                passage.text = regex.Replace(passage.text, pattern);
            }
        }
예제 #7
0
        private void ApplyOptions(TwisonStory story, TwisonLoaderOptions options)
        {
            var utility = new TwisonUtility();

            if (options.removeLinkTextFromPassages)
            {
                utility.RemoveLinksFromPassages(story);
            }

            if (options.collapseNewLines)
            {
                utility.CollapseNewLines(story, options.maxNewLineChain);
            }

            if (options.trimPassages)
            {
                utility.TrimPassages(story);
            }
        }
예제 #8
0
 private void ValidateStory(TwisonStory story)
 {
     Default(story, (s) => s.passages != null, (s) => s.passages             = new List <TwisonPassage>());
     Default(story, (s) => s.name != null, (s) => s.name                     = Guid.NewGuid().ToString());
     Default(story, (s) => s.creator != null, (s) => s.creator               = "");
     Default(story, (s) => s.ifid != null, (s) => s.ifid                     = Guid.NewGuid().ToString());
     Default(story, (s) => s.creatorVersion != null, (s) => s.creatorVersion = "");
     Default(story, (s) => s.startnode != null, (s) => s.startnode           = "");
     foreach (var passage in story.passages)
     {
         Default(passage, (p) => p.name != null, (p) => p.name   = Guid.NewGuid().ToString());
         Default(passage, (p) => p.text != null, (p) => p.text   = "");
         Default(passage, (p) => p.tags != null, (p) => p.tags   = new List <string>());
         Default(passage, (p) => p.links != null, (p) => p.links = new List <TwisonLink>());
         Guard(passage, (p) => !string.IsNullOrWhiteSpace(p.pid), (p) => $"Invalid passage, no PID for {p.name}");
         foreach (var link in passage.links)
         {
             Default(link, (l) => l.name != null, (l) => l.name = "");
             Default(link, (l) => l.link != null, (l) => l.link = "");
             Guard(link, (l) => !string.IsNullOrWhiteSpace(l.pid), (l) => $"Invalid passage in link, no PID for {l.name}");
         }
     }
 }
예제 #9
0
 public TwisonRuntime(TwisonStory story, ITwisonRuntimeBehaviour runtimeBehaviour, bool enterDefaultStartNode)
 {
     _story            = story;
     _runtimeBehaviour = runtimeBehaviour;
     OnStartRuntime(story, enterDefaultStartNode);
 }