示例#1
0
        /// <summary>
        /// Exports a xoreos xml (export) to yml.
        /// </summary>
        /// <param name="infile"></param>
        private static void Xml2Yml(string infile)
        {
            #region Save Settings
            var filename      = Path.GetFileNameWithoutExtension(infile);
            var fileDirectory = Path.GetDirectoryName(infile);
            //var newDirectory = Path.Combine(fileDirectory, $"out/{filename}");
            var ymlDirectory = Path.Combine(fileDirectory, $"out");

            if (!Directory.Exists(ymlDirectory))
            {
                Directory.CreateDirectory(ymlDirectory);
            }

            //string outfile = Path.Combine(newDirectory, $"{filename}_out.xml");
            //string outfile_sections = Path.Combine(newDirectory, $"{filename}_sections.xml");
            string outfile_yml = Path.Combine(ymlDirectory, $"{filename}.yml");

            #endregion

            gff3struct parsedClass = gff3Reader.Read(infile);


            var gffWriter = new gff3Writer(parsedClass, infile);
            gffWriter.GenerateXML();
            //gffWriter.XDOC.Save(outfile); //dbg

            gffWriter.GenerateSectionsXML();
            //gffWriter.XDOC_SECTIONS.Save(outfile_sections); //dbg

            ymlWriter.Write(outfile_yml, gffWriter.XDOC_SECTIONS);
        }
示例#2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="data"></param>
        /// <param name="idx"></param>
        /// <returns></returns>
        private SDialogscriptdata AttributeData(gff3struct data, ref List <XAttribute> ret)
        {
            var sdata = new SDialogscriptdata();

            //MISC
            //ret.Add(new XAttribute("Interlocutor", data.GetCommonObjectByName("Interlocutor").Value.ToString()));
            //ret.Add(new XAttribute("NodeType", data.GetCommonObjectByName("NodeType").Value.ToString()));
            //ret.Add(new XAttribute("Id", data.GetCommonObjectByName("Id").Value.ToString()));

            string qf      = data.GetCommonObjectByName("Quest")?.Value?.ToString();
            bool   isquest = !string.IsNullOrEmpty(qf);

            if (isquest)
            {
                //remove special characters
                qf = qf.Replace(' ', '_');
                Regex rgx = new Regex("[^a-zA-Z0-9_]");
                qf = rgx.Replace(qf, "").ToLower();

                ret.Add(new XAttribute("Quest", qf));
                sdata.questfact = qf;
            }



            return(sdata);
        }
示例#3
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;
        }
示例#4
0
        /// <summary>
        /// pass the xstruct node, return a gff3 struct
        /// </summary>
        /// <param name="in_xstruct"></param>
        /// <param name="parentStruct"></param>
        private static void ParseStruct(XElement in_xstruct, gff3struct parentStruct)
        {
            string structID = in_xstruct.Attribute("id").Value;

            foreach (var node in in_xstruct.Elements())
            {
                // if node is a list
                if (ReadType(node) == "list")
                {
                    //get variables
                    var label    = ReadLabel(node);
                    var type     = ReadType(node);
                    var children = new List <gff3struct>();

                    var xchildren = node.Elements(); //nodes with name struct id=0, id=1 etc...
                    foreach (var childnode in xchildren)
                    {
                        var schild = new gff3struct(ReadID(childnode));
                        ParseStruct(childnode, schild); //passes the struct
                        children.Add(schild);
                    }

                    //create object and add to parent struct
                    var obj = new CGff3List(type, label, children);
                    parentStruct.Data.Add(obj);
                }
                // if node is a common type
                else
                {
                    if (ReadType(node) == "locstring")
                    {
                        var label    = ReadLabel(node);
                        var type     = ReadType(node);
                        var children = new List <CGff3String>();
                        //strref

                        var xchildren = node.Elements();
                        foreach (var childnode in xchildren)
                        {
                            CGff3String xstring = ReadString(childnode);
                            children.Add(xstring);
                        }

                        var obj = new CGff3Locstring(type, label, children);

                        parentStruct.Data.Add(obj);
                    }
                    // add common type to paremt struct
                    else
                    {
                        parentStruct.Data.Add(ReadGeneric(node));
                    }
                }
            }
        }
示例#5
0
        /// <summary>
        /// Reads an xml and returns a gff3 struct.
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static gff3struct Read(string path)
        {
            var doc = XDocument.Load(path);


            XElement   in_xstruct   = doc.Element("gff3").Element("struct");
            gff3struct parentStruct = new gff3struct(ReadID(in_xstruct));

            ParseStruct(in_xstruct, parentStruct);

            return(parentStruct);
        }
示例#6
0
        private List <string> HACK_Allrefs = new List <string>(); //HACK //FIXME

        public gff3Writer(gff3struct gff, string name)
        {
            GFF  = gff;
            Name = name;
        }
示例#7
0
        /// <summary>
        /// Prints custom data to xml element
        /// </summary>
        /// <param name="data"></param>
        /// <param name="parent"></param>
        /// <param name="idx"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private bool AnnotateXML(gff3struct data, XElement parent, int idx, string type, bool isSection, ref XElement output)
        {
            //Document Settings
            var      Doc    = parent.Document;
            XElement Actors = Doc.Descendants("Settings").First()?.Element("Actors");
            XElement Player = Doc.Descendants("Settings").First()?.Element("Player");

            List <XAttribute> attributes = new List <XAttribute>();

            //attributes.Add(new XAttribute("Idx", idx));
            output.Add(new XAttribute("ref", $"{type}_{idx}"));

            //TEXT
            CGff3Locstring locstring = (CGff3Locstring)data.GetListObjectByName <CGff3String>("Text");
            string         Text      = "";

            if (locstring != null)
            {
                CGff3String englishText = locstring.Value.FirstOrDefault(x => x.Language == "6");
                if (englishText != null)
                {
                    Text = englishText.Value;
                }
            }
            attributes.Add(new XAttribute("Text", Text));

            //SPEAKER
            string Speaker = data.GetCommonObjectByName("Speaker").Value.ToString();

            if (Speaker == "__player__")
            {
                Speaker = "geralt";
            }
            if (Speaker == "__owner__")
            {
                Speaker = "npc";
            }
            //write speakers to settings
            if (Actors == null)
            {
                throw new Gff3Exception("No Actors in Database"); //should never go offbut keep it for testing
            }
            List <string> ActorList = Actors.Elements().Select(x => x.Value.ToString()).ToList();

            //Add actors to actorlist
            if (!ActorList.Contains(Speaker))
            {
                Actors.Add(new XElement("Actor", Speaker));
            }
            if (Speaker == "geralt" && Player.Value != null)
            {
                Player.Value = Speaker;
            }
            attributes.Add(new XAttribute("Speaker", Speaker));

            // Adding soundfile var
            string Sound = data.GetCommonObjectByName("Sound").Value.ToString();

            attributes.Add(new XAttribute("Sound", Sound));

            //OTHER
            var dsdata = AttributeData(data, ref attributes);

            //QUESTS


            //ADD
            output.Add(attributes.ToArray());

            //add section data
            if (isSection)
            {
                //remove special charactersand to lower
                string sectionname = Text.Split(' ').First();
                Regex  rgx         = new Regex("[^a-zA-Z0-9]");
                sectionname = $"section_{rgx.Replace(sectionname, "").ToLower()}_{idx}";

                //add to sections list
                AddToSectionsNoDuplicates(Doc, sectionname, $"{type}_{idx}");
                output.Add(new XAttribute("section", sectionname));
            }

            bool isQuestParent = !String.IsNullOrEmpty(dsdata.questfact);

            if (isQuestParent)
            {
                //add to quest list
                AddToSectionsNoDuplicates(Doc, $"script_setfact_{dsdata.questfact}", $"quest_{idx}");

                //add quest xml tags

                var scriptelement = new XElement("SCRIPT",
                                                 new XAttribute("function", "AddFact_S"),
                                                 new XElement("parameter",
                                                              new XAttribute("factName", $"{dsdata.questfact}"),
                                                              new XAttribute("value", $"1"),
                                                              new XAttribute("validFor", $"0")
                                                              ));
                var questelement = new XElement("QUEST",
                                                new XAttribute("Name", dsdata.questfact),
                                                new XAttribute("section", $"script_setfact_{dsdata.questfact}"),
                                                new XAttribute("ref", $"quest_{idx}"),
                                                scriptelement
                                                );

                // reshuffle nodes
                output.Add(questelement);
                parent.Add(output);
                output = output.Element("QUEST");
            }
            else
            {
                parent.Add(output);
            }

            return(isQuestParent);
        }
示例#8
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");
                }
            }
        }