/// <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"); } } }