Beispiel #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="gff3"></param>
        /// <returns></returns>
        public void GenerateXML()
        {
            #region XML Structure
            var Doc  = new XDocument();
            var root = new XElement("root");
            Doc.AddFirst(root);
            Doc.Root.Add(
                new XElement("Settings"),
                new XElement("Dialogscripts"));
            XElement Dialogscripts = Doc.Descendants("Dialogscripts").First();
            XElement Settings      = Doc.Descendants("Settings").First();
            Settings.Add(new XElement("Actors"));
            Settings.Add(new XElement("Player"));
            Settings.Add(new XElement("SectionsList"));
            #endregion


            // Speaker settings
            List <gff3struct> SpeakerList = ((CGff3ListObject <gff3struct>)GFF.GetGenericObjectByName("SpeakerList"))?.Value;
            List <string>     Actors      = SpeakerList.Select(x => x.GetCommonObjectByName("Speaker")?.Value.ToString())?.ToList();
            foreach (var actor in Actors)
            {
                Settings.Element("Actors").Add(new XElement("Actor", actor));
            }

            //Dialogscripts
            CGff3ListObject <gff3struct> StartingList = (CGff3ListObject <gff3struct>)GFF.GetGenericObjectByName("StartingList");
            for (int i = 0; i < StartingList.Value.Count; i++)
            {
                //add generic start sections to section list
                // FIXME pause?
                var startelement = new XElement("PAUSE",
                                                new XAttribute("section", $"section_start_{i}"),
                                                new XAttribute("ref", $"start_{i}")
                                                );
                Dialogscripts.Add(startelement);
                Settings.Element("SectionsList").Add(new XElement("Section", $"start_{i}", new XAttribute("Name", $"section_start_{i}")));


                //
                gff3struct         item = (gff3struct)StartingList.Value[i];
                CGff3GenericObject obj  = item.GetCommonObjectByName("Index");
                int idx = int.Parse(obj.Value.ToString());

                // Write Tree
                WriteTree(GFF, startelement, idx, "entry", true);
            }

            //Modify Speaker Section
            string        player = Settings.Element("Player").Value;
            List <string> actors = Settings.Element("Actors").Descendants()?.Select(x => x.Value).ToList();
            if (String.IsNullOrEmpty(player))
            {
                Settings.Element("Player").Value = actors.First();
            }


            XDOC = Doc;
        }
Beispiel #2
0
        /// <summary>
        /// Recursive writing dialogue tree.
        /// </summary>
        /// <param name="gff3"></param>
        /// <param name="idx"></param>
        /// <param name="type"></param>
        private void WriteTree(gff3struct gff3, XElement printparent, int idx, string type, bool isSection)
        {
            //HACK //FIXME loop detection
            string HACK_ref = $"{type}_{idx}";

            if (!HACK_Allrefs.Contains(HACK_ref))
            {
                HACK_Allrefs.Add(HACK_ref);
            }
            else
            {
                throw new Gff3Exception("Looping");
            }

            XElement output = new XElement(type);

            if (type == "entry")
            {
                gff3struct entry = gff3.GetEntryByIndex(idx);

                //PRINT DATA
                bool isquest = AnnotateXML(entry, printparent, idx, type, isSection, ref output);

                //get replies
                // there can be more than one reply
                // if there is more than one reply, this marks a CHOICE
                // and we must label all replys as goto points
                CGff3ListObject <gff3struct> replies = entry.GetListObjectByName <gff3struct>("RepliesList");


                if (replies.Value.Count == 0)
                {
                    output.Add(new XAttribute("END", "true"));
                }
                else if (replies.Value.Count > 1)
                {
                    output.Add(new XAttribute("CHOICE", "true"));
                }

                //handle circular references
                if (EntryChoices.Contains(idx))
                {
                    return;
                }

                if (replies.Value.Count > 1)
                {
                    EntryChoices.Add(idx);
                }


                foreach (gff3struct reply in replies.Value)
                {
                    int newidx = int.Parse(reply.GetCommonObjectByName("Index").Value.ToString());

                    //if there is a choice, flag the two replies
                    bool ischildSection = replies.Value.Count > 1 || isquest;
                    WriteTree(gff3, output, newidx, "reply", ischildSection);
                }
            }
            else if (type == "reply")
            {
                gff3struct reply = gff3.GetReplyByIndex(idx);

                //PRINT DATA
                var isquest = AnnotateXML(reply, printparent, idx, type, isSection, ref output);

                //get entries
                // there can never be more than two entries
                // because nps can't choose
                CGff3ListObject <gff3struct> entries = reply.GetListObjectByName <gff3struct>("EntriesList");

                if (entries.Value.Count == 0)
                {
                    output.Add(new XAttribute("END", "true"));
                }
                else if (entries.Value.Count == 1)
                {
                    int newidx = int.Parse(entries.Value.First().GetCommonObjectByName("Index").Value.ToString());
                    WriteTree(gff3, output, newidx, "entry", isquest);
                }
                else
                {
                    throw new Gff3Exception("More than one Entry in a Reply");
                }
            }
        }