User:Alice/Dialogue Converter

From Len'en Wiki
Jump to: navigation, search

This is source for dialogue converter program used for BPoHC talk dialogues. You are free to adapt it to other projects and such. You might really, really, really want to change data declarations, if you work on other projects than BPoHC.

Paste it in Visual Studio Console Application project or something to get proper formatting.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace quicky
{
    class Program
    {
        class Team
        {
            public string Id { get; set; }

            public Character Leader { get; set; }

            public IList<Character> Supports { get; set; }
        }

        class Character
        {
            public string Id { get; set; }

            public string Name { get; set; }

            public string FullName { get; set; }

            public string JapName { get; set; }

            public string Title { get; set; }

            public string JapTitle { get; set; }

            public string Bgm { get; set; }

            public string JapBgm { get; set; }

            public IList<Place> PossiblePlaces { get; set; }

            public IList<Character> Supports { get; set; }

            public string OnContinue { get; set; }

            public string On1cc { get; set; }

            public string PreIdx { get; set; } = "0";
            public string PostIdx { get; set; } = "1";
        }

        class Place
        {
            public string Name { get; set; }

            public string WikiName { get; set; }

            public string JapName { get; set; }

            public string Img { get; set; }
        }

        static void Main(string[] args)
        {
            var basePath = @"D:\Fun\Len'en\BACKUP Len'en 04.0 ~ Brilliant Pagoda or Haze Castle - Copy\text_dat\talk";

            DirectoryInfo info = new DirectoryInfo(basePath);

            info.EnumerateFiles().Select(f => f.Name).ToList();

            Dictionary<string, Place> places = new Dictionary<string, Place>()
            {
                { "Senri Shrine Road", new Place() { Name = "Senri Shrine Road", WikiName = "[[Shrine Road|Senri Shrine Road]]", JapName = "闡裡神社参道", Img = "Le04Stage1Title.jpg" } },
                { "Senri Shrine Road (far)", new Place() { Name = "Senri Shrine Road (far)", WikiName = "[[Shrine Road|Senri Shrine Road]] (far)", JapName = "闡裡神社参道", Img = "Le04Stage4ShrineTitle.jpg" } },
                { "Senri Shrine Road (remote)", new Place() { Name = "Senri Shrine Road (remote)", WikiName = "[[Shrine Road|Senri Shrine Road]] (remote)", JapName = "闡裡神社参道", Img = "Le04StageExTitle.jpg" } },
                { "Senri Shrine Road (distant)", new Place() { Name = "Senri Shrine Road (distant)", WikiName = "[[Shrine Road|Senri Shrine Road]] (distant)", JapName = "闡裡神社参道", Img = "Le04StageExaTitle.jpg" } },

                { "Unlost Woods", new Place() { Name = "The Unlost Woods", WikiName = "The [[Unlost Woods]]", JapName = "迷えずの森", Img = "Le04Stage2HazeTitle.jpg" } },
                { "Outpost Base Camp", new Place() { Name = "The Outpost Base Camp", WikiName = "The [[Outpost Base Camp]]", JapName = "前哨陣地", Img = "Le04Stage3HazeTitle.jpg" } },
                { "Summonsing Fortress", new Place() { Name = "The Summonsing Fortress", WikiName = "The [[Summonsing Fortress]]", JapName = "召喚城郭", Img = "Le04Stage4HazeTitle.jpg" } },
                { "Dragonfly Castle", new Place() { Name = "The Dragonfly Castle", WikiName = "The [[Dragonfly Castle]]", JapName = "蜻蛉之城", Img = "Le04Stage5HazeTitle.jpg" } },
                { "Ukifune's Room", new Place() { Name = "Ukifune's Room", WikiName = "[[Ukifune's Room]]", JapName = "浮舟の間", Img = "Le04Stage6HazeTitle.jpg" } },

                { "Battlefront River", new Place() { Name = "The Frontline River", WikiName = "The [[Frontline River]]", JapName = "戦線となる川", Img = "Le04Stage2BrillTitle.jpg" } },
                { "Fantasy Seawall", new Place() { Name = "The Fantasy Seawall", WikiName = "The [[Fantasy Seawall]]", JapName = "夢幻堤防", Img = "Le04Stage3BrillTitle.jpg" } },
                { "Gloomy Straits", new Place() { Name = "The Gloomy Straits", WikiName = "The [[Gloomy Straits]]", JapName = "幽暗海橋", Img = "Le04Stage4BrillTitle.jpg" } },
                { "Devanagara", new Place() { Name = "Devanagara", WikiName = "[[Devanagara]]", JapName = "デーヴァナガラ", Img = "Le04Stage5BrillTitle.jpg" } },
                { "Pagoda of the Heavenly Mirror", new Place() { Name = "Pagoda of the Heavenly Mirror", WikiName = "[[Pagoda of the Heavenly Mirror]]", JapName = "天鏡の塔", Img = "Le04Stage6BrillTitle.jpg" } },

                { "A Certain Ceremonial Place", new Place() { Name = "A Certain Ceremonial Place", WikiName = "A Certain Ceremonial Place", JapName = "とある儀式場", Img = "Le04Stage61HazeTitle.jpg" } },
                { "A Certain Withering Flower", new Place() { Name = "A Certain Withering Flower", WikiName = "A Certain Withering Flower", JapName = "とある枯れ花", Img = "Le04Stage61BrillTitle.jpg" } }
            };

            Dictionary<string, Character> characters = new Dictionary<string, Character>()
            {
                // Shrine Team
                { "Yabusame", new Character() {
                    Id = "Yabusame", Name = "Yabusame",
                    FullName = "Yabusame Houren", JapName = "鳳聯 藪雨", Title = "Flawless Thoughtlessness", JapTitle = "天衣無縫の能天気",
                    Bgm = "Feathers Flying off the Beaten Path ~ Eleven-dimensional", JapBgm = "常軌の外に飛ぶ羽 ~ Eleven-dimensional",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Summonsing Fortress"], places["Outpost Base Camp"], places["Senri Shrine Road (far)"], places["Devanagara"]},
                    On1cc = "Neutral", OnContinue = "Neutral"
                    } },
                { "Tsubakura", new Character() {
                    Id = "Tsubakura", Name = "Tsubakura",
                    FullName = "Tsubakura Enraku", JapName = "燕楽 玄鳥", Title = "Loafing Monochrome", JapTitle = "酒嚢飯袋な単彩",
                    Bgm = "Another Mind", JapBgm = "アナザーマインド",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Senri Shrine Road (far)"], places["Fantasy Seawall"], places["Gloomy Straits"], places["Devanagara"]},
                    On1cc = "Neutral", OnContinue = "Neutral"
                    } },
                { "Shion", new Character() {
                    Id = "Shion", Name = "Shion",
                    FullName = "Shion", JapName = "シオン", Title = "An Individual Born from the Aggregate", JapTitle = "総体から産まれし個体",
                    Bgm = "One Hundred Lives and One Connection ~ Chimera soul", JapBgm = "百の命と一つの縁 ~ Chimera soul",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["A Certain Withering Flower"]},
                    On1cc = "Neutral", OnContinue = "Neutral"
                    } },

                // New Emperor Team
                { "Humikado", new Character() {
                    Id = "Humikado", Name = "Fumikado",
                    FullName = "Taira no Fumikado", JapName = "平 文門", Title = "The Vessel for the New Emperor", JapTitle = "新帝の盃",
                    Bgm = "Hands That Can't Reach The Moon ~ Moon Child", JapBgm = "月には届かぬ手 ~ Moon Child",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Dragonfly Castle"], places["Summonsing Fortress"], places["Outpost Base Camp"], places["Unlost Woods"], places["Senri Shrine Road (far)"], places["Battlefront River"], places["Fantasy Seawall"], places["Gloomy Straits"], places["Devanagara"] }
                    } },
                { "Iyozane", new Character() {
                    Id = "Iyozane", Name = "Iyozane",
                    FullName = "Fujiwara no Iyozane", JapName = "藤原 伊代真", Title = "Anachronistic Ambitious Person", JapTitle = "時代錯誤の野心家",
                    Bgm = "Waves and Wind Swaying The Spirits ~ not steady body", JapBgm = "幽霊うごく波と風 ~ not steady body",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Outpost Base Camp"], places["Unlost Woods"], places["Senri Shrine Road"], places["Battlefront River"], places["Fantasy Seawall"] }
                    } },
                { "Tsugumi", new Character() {
                    Id = "Tsugumi", Name = "Tsugumi",
                    FullName = "Tsugumi Umatachi", JapName = "馬立 ツグミ", Title = "Faithful Pumpkin Auriga", JapTitle = "義者張る南瓜のアウリガ",
                    Bgm = "Let's 'n Go ~ to run away!", JapBgm = "レッツエンド号 ~ to run away!",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Unlost Woods"], places["Senri Shrine Road"], places["Battlefront River"] }
                    } },

                // Preschool Team
                { "Tenkai", new Character() {
                    Id = "Tenkai", Name = "Tenkai",
                    FullName = "Tenkai Zuifeng", JapName = "瑞風 天堺", Title = "One of the Old Dictators", JapTitle = "古き独裁者の片割れ",
                    Bgm = "Burst Overflow", JapBgm = "決壊オーバーフロー",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Summonsing Fortress"], places["Outpost Base Camp"], places["Senri Shrine Road (far)"], places["Battlefront River"], places["Fantasy Seawall"], places["Gloomy Straits"], places["Devanagara"] },
                    On1cc = "Neutral", OnContinue = "Neutral"
                    } },
                { "Sukune", new Character() {
                    Id = "Sukune", Name = "Sukune",
                    FullName = "Sukune Katano", JapName = "片埜 宿禰", Title = "Pure and Genius Haniwa", JapTitle = "無垢なる天才埴輪",
                    Bgm = "スーパーハニーワ ~ NEXT FORM!!", JapBgm = "Super Haniwa ~ NEXT FORM!!",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Dragonfly Castle"], places["Summonsing Fortress"], places["Outpost Base Camp"], places["Unlost Woods"], places["Senri Shrine Road (far)"], places["Battlefront River"], places["Fantasy Seawall"], places["Gloomy Straits"], places["Devanagara"] }
                    } },
                { "Sese", new Character() {
                    Id = "Sese", Name = "Sese",
                    FullName = "Sese Kitsugai", JapName = "乞骸 セセ", Title = "A Corpse in Search of Themself", JapTitle = "自分探し中の骸",
                    Bgm = "Necromaster", JapBgm = "ネクロマスター",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Outpost Base Camp"], places["Unlost Woods"], places["Senri Shrine Road"], places["Battlefront River"], places["Fantasy Seawall"] }
                    } },

                // Scoundrel Team
                { "Kuroji", new Character() {
                    Id = "Kuroji", Name = "Kuroji",
                    FullName = "Kuroji Shitodo", JapName = "鵐 黒巫鳥", Title = "Ambiguously Paper-thin Archaeologist", JapTitle = "曖昧で紙一重な考古学者",
                    Bgm = "Room The History", JapBgm = "ルームザヒストリー",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Dragonfly Castle"], places["Summonsing Fortress"], places["Outpost Base Camp"], places["Unlost Woods"], places["Senri Shrine Road (far)"], places["Battlefront River"], places["Fantasy Seawall"], places["Gloomy Straits"], places["Devanagara"] }
                    } },
                { "Hooaka", new Character() {
                    Id = "Hooaka", Name = "Hooaka",
                    FullName = "Hooaka Shitodo", JapName = "鵐 頬赤", Title = "Cool-Headed Hot-Heeled Thermal Runaway", JapTitle = "頭寒足熱で熱暴走",
                    Bgm = "Overheat Down", JapBgm = "オーバーヒートダウン",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Summonsing Fortress"], places["Outpost Base Camp"], places["Unlost Woods"], places["Senri Shrine Road (far)"], places["Battlefront River"], places["Fantasy Seawall"], places["Gloomy Straits"] }
                    } },
                { "Aoji", new Character() {
                    Id = "Aoji", Name = "Aoji",
                    FullName = "Aoji Shitodo", JapName = "鵐 蒿雀", Title = "Weak-Willed Youngest Child", JapTitle = "意志薄弱な末っ子",
                    Bgm = "Blue Storm ~ Plastic Vortex", JapBgm = "青嵐 ~ Plastic Vortex",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Unlost Woods"], places["Senri Shrine Road"], places["Battlefront River"] }
                    } },

                // Haze route
                { "Souko", new Character() {
                    Id = "Souko", Name = "Souko",
                    FullName = "Souko Shirami", JapName = "銀鏡 蒼枯", Title = "Unwithering Flower", JapTitle = "枯れぬが花",
                    Bgm = "Scatter, O Flowers ~ Consumed with JEALOUSY!", JapBgm = "花よ散れ ~ Consumed with JEALOUSY!",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Senri Shrine Road"] }
                    } },
                { "Kujiru", new Character() {
                    Id = "Kujiru", Name = "Kujiru",
                    FullName = "Kujiru Kesa", JapName = "袈裟 クジル", Title = "Being who becomes One, and yet Many", JapTitle = "唯一且つ数多なる者",
                    Bgm = "Slug Agent", JapBgm = "スラグエージェント",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Unlost Woods"] }
                    } },
                { "Kaisen", new Character() {
                    Id = "Kaisen", Name = "Kaisen",
                    FullName = "Kaisen Azuma", JapName = "東 海仙", Title = "Three-legged Moon Seeker", JapTitle = "月を仰ぐ三つの足",
                    Bgm = "Eccentrically Drunken Dance ~ This Drunkard!", JapBgm = "酔狂の舞 ~ This drunkard!",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Outpost Base Camp"] }
                    } },
                { "Garaiya", new Character() {
                    Id = "Garaiya", Name = "Garaiya",
                    FullName = "Garaiya Ogata", JapName = "尾形 ガライヤ", Title = "Everyone's Hero", JapTitle = "一叢の英雄",
                    Bgm = "Meeting A Hero!!", JapBgm = "ヒーロー見参!!",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Summonsing Fortress"] }
                    } },
                { "Para", new Character() {
                    Id = "Para", Name = "Para",
                    FullName = "Para", JapName = "パラ", Title = "Stolen Omniscience and Omnipotence", JapTitle = "奪われた全知全能",
                    Bgm = "Microcosm ~ Homunculus nightmare", JapBgm = "ミクロコスモス ~ Homunculus nightmare",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Dragonfly Castle"] }
                    } },
                { "Chouki", new Character() {
                    Id = "Chouki", Name = "Chouki",
                    FullName = "Taira no Chouki", JapName = "平 蝶鬼", Title = "New Emperor from Among the Dragonflies", JapTitle = "陽炎の内の新皇",
                    Bgm = "Ruler of the Deceased Moon", JapBgm = "亡き月の王",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Ukifune's Room"] },
                    On1cc = "Haze", OnContinue = "Haze"
                    } },

                // Brilliant route
                { "Mitsumo", new Character() {
                    Id = "Mitsumo", Name = "Mitsumo",
                    FullName = "Mitsumo", JapName = "照雲", Title = "Visualized Mental Trauma", JapTitle = "可視化する心の傷跡",
                    Bgm = "Nightmare Syndrome", JapBgm = "ナイトメアシンドローム",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Senri Shrine Road"] }
                    } },
                { "Medias", new Character() {
                    Id = "Medias", Name = "Medias",
                    FullName = "Medias Moritake", JapName = "守武 メリヤス", Title = "Southern Meteor Shower", JapTitle = "南方の流星群",
                    Bgm = "Emperor Road ~ So Cute!", JapBgm = "エンペラーロード ~ So cute!",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Battlefront River"] }
                    } },
                { "Kunimitsu", new Character() {
                    Id = "Kunimitsu", Name = "Kunimitsu",
                    FullName = "Kunimitsu Ooya", JapName = "大宅 都光", Title = "Royal Court's Youkai Exterminator", JapTitle = "宮仕えの妖怪退治屋",
                    Bgm = "Killing Superior ~ Giant Killing", JapBgm = "キリングスペリオル ~ Giant killing",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Fantasy Seawall"] }
                    } },
                { "Kaoru", new Character() {
                    Id = "Kaoru", Name = "Kaoru",
                    FullName = "Kaoru Kashiwagi", JapName = "柏木 薫", Title = "Imperial Loitering Dense Fog", JapTitle = "帝都に佇む濃霧",
                    Bgm = "Fatal Brilliance ~ Toxic gem", JapBgm = "死に至る絢爛 ~ Toxic gem",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Gloomy Straits"] }
                    } },
                { "Sanra", new Character() {
                    Id = "Sanra", Name = "Sanra",
                    FullName = "Fujiwara no Shirogane no Sanra", JapName = "藤原 銀 讃良", Title = "The Imperial Capital's Silver Bullet", JapTitle = "帝都の銀の弾丸",
                    Bgm = "SILVER", JapBgm = "SILVER",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Devanagara"] }
                    } },
                { "Mitori", new Character() {
                    Id = "Mitori", Name = "Mitori",
                    FullName = "Ooama no Ake no Mitori", JapName = "大天 朱 壬鳥", Title = "Blood-dyed Throne", JapTitle = "朱に染まった玉座",
                    Bgm = "Arch Heaven ~ Spirit of nagara", JapBgm = "大天 ~ Spirit of nagara",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Pagoda of the Heavenly Mirror"] },
                    On1cc = "Brilliant", OnContinue = "Brilliant"
                    } },

                // Neutral route
                { "Kurohebi", new Character() {
                    Id = "Kurohebi", Name = "Kurohebi",
                    FullName = "Kurohebi", JapName = "烏蛇", Title = "Strong-Willed Shadow", JapTitle = "得手勝手な影",
                    Bgm = "Made in Black ~ Double Snake", JapBgm = "メイドインブラック ~ Double Snake",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Senri Shrine Road"] }
                    } },
                { "Jun", new Character() {
                    Id = "Jun", Name = "Jun",
                    FullName = "Jun Amanomiya", JapName = "天宮 潤", Title = "Raincoat Between a Rock and a Hard Place", JapTitle = "進退両難あまがっぱ",
                    Bgm = "The Water Dyed in Crimson ~DYE~", JapBgm = "韓紅に水は括る ~DYE~",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Senri Shrine Road"] }
                    } },
                { "Shou", new Character() {
                    Id = "Shou", Name = "Shou",
                    FullName = "Shou Amanomori", JapName = "雨杏 宵", Title = "Walking Lubricant", JapTitle = "歩く潤滑剤",
                    Bgm = "Act the Fool ~ HAHAHA", JapBgm = "アクト・ザ・フール ~ HAHAHA",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Unlost Woods"], places["Senri Shrine Road"], places["Battlefront River"] }
                    } },
                { "Lumen", new Character() {
                    Id = "Lumen", Name = "Lumen",
                    FullName = "Lumen Celeritas", JapName = "ケレリタス・ルーメン", Title = "Carefree Converging Sunlight", JapTitle = "無頓着に収束する恩光",
                    Bgm = "Prismic Drive", JapBgm = "プリズミックドライブ",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Outpost Base Camp"], places["Unlost Woods"], places["Senri Shrine Road"], places["Battlefront River"], places["Fantasy Seawall"] }
                    } },
                { "Hibaru", new Character() {
                    Id = "Hibaru", Name = "Hibaru",
                    FullName = "Hibaru Kokutenshi", JapName = "旭天子 ヒバル", Title = "Cheerful Debt Collector", JapTitle = "陽気な取立て屋",
                    Bgm = "Abandoning 1000 Ryo, Finding 10,000 Ryo ~ MONEY GAME", JapBgm = "見切り千両、目玉万両 ~ MONEY GAME",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Summonsing Fortress"], places["Outpost Base Camp"], places["Unlost Woods"], places["Senri Shrine Road (far)"], places["Battlefront River"], places["Fantasy Seawall"], places["Gloomy Straits"] }
                    } },
                { "Saragimaru", new Character() {
                    Id = "Saragimaru", Name = "Saragimaru",
                    FullName = "Adagumo no Saragimaru", JapName = "徒雲 蛇穴丸", Title = "Final Eye", JapTitle = "最後の瞳",
                    Bgm = "Opened Eye ~ Mono EYE", JapBgm = "開かれた瞳 ~ Mono EYE",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Summonsing Fortress"], places["Outpost Base Camp"], places["Unlost Woods"], places["Senri Shrine Road (far)"], places["Battlefront River"], places["Fantasy Seawall"], places["Gloomy Straits"] }
                    } },
                { "Yaorochi", new Character() {
                    Id = "Yaorochi", Name = "Yaorochi",
                    FullName = "Adagumo no Yaorochi", JapName = "徒雲 八尾呂智", Title = "Descendant of Orochi", JapTitle = "大蛇の末裔",
                    Bgm = "Mowed-down Relationship", JapBgm = "薙ぎ払われた繋がり",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["A Certain Ceremonial Place"] },
                    On1cc = "Neutral", OnContinue = "Neutral"
                    } },
                { "Clause", new Character() {
                    Id = "Clause", Name = "Clause",
                    FullName = "Clause", JapName = "(前略)クラウゼ(後略)", Title = "(Title omitted)", JapTitle = "(全略)",
                    Bgm = "Eternal Power ~ BIG STAR", JapBgm = "エターナルパワー ~ BIG STAR",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Dragonfly Castle"], places["Summonsing Fortress"], places["Outpost Base Camp"], places["Senri Shrine Road (far)"], places["Battlefront River"], places["Fantasy Seawall"], places["Gloomy Straits"], places["Devanagara"] },
                    On1cc = "Neutral", OnContinue = "Neutral"
                    } },
                { "Suzum1", new Character() {
                    Id = "Suzumi_01", Name = "Suzumi",
                    FullName = "Suzumi Kuzu", JapName = "國主 雀巳", Title = "Treacherous and Superfluous Memory", JapTitle = "奸佞邪智な過ぎたる記憶",
                    Bgm = "MO-NA-D-2 ~ Memory Forgery", JapBgm = "MO-NA-D-2 ~ 記憶偽筆",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Senri Shrine Road (far)"] },
                    On1cc = "Good", OnContinue = "Bad"
                    } },

                //Extra stage
                { "Yago", new Character() {
                    Id = "Yago", Name = "Yago",
                    FullName = "Yago Ametsukana", JapName = "天目津金 ヤゴ", Title = "A Thousand Blades and a Thousand Arms", JapTitle = "千の刃と千の腕",
                    Bgm = "The Road-Pounding Steel ~ Cyclops Tech", JapBgm = "道を打つ刃金 ~ Cyclops Tech",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Senri Shrine Road (remote)"] }
                    } },
                { "Haiji", new Character() {
                    Id = "Haiji", Name = "Haiji",
                    FullName = "Haiji Senri", JapName = "千理 牌示", Title = "Fad-following Spell Collector", JapTitle = "ミーハーなスペルコレクター",
                    Bgm = "Eternal Imitation Dance ~ Spell Collector", JapBgm = "永劫模倣演舞 ~ Spell Collector",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Senri Shrine Road (remote)"] }
                    } },
                { "Xeno a", new Character() {
                    Id = "Xeno_a", Name = "Xeno a",
                    FullName = "Xeno a", JapName = "ゼノア", Title = "Eyes Forsaken by the Gods, But Loved by the World", JapTitle = "神に見捨てられ、世界に愛されし眼",
                    Bgm = "Lost Jackpot", JapBgm = "ロストジャックポット",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Senri Shrine Road (remote)"] }
                    } },
                { "Tsurubami", new Character() {
                    Id = "Tsurubami", Name = "Tsurubami",
                    FullName = "Tsurubami Senri", JapName = "闡裡 鶴喰", Title = "Inexplicable Hakama", JapTitle = "不可解な袴",
                    Bgm = "Broken Eternal Dance Engine", JapBgm = "壊れかけの永劫舞踏機関",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Senri Shrine Road (distant)"] }
                    } },
                { "Su2umi", new Character() {
                    Id = "Suzumi_02", Name = "Suzumi",
                    FullName = "Suzumi Kuzu", JapName = "國主 雀巳", Title = "Mysterious and Troubling Memory", JapTitle = "幻怪の記憶",
                    Bgm = "MO-NA-D-1 ~ Memory Pursuit", JapBgm = "MO-NA-D-1 〜 記憶追蹤",
                    Supports = new List<Character>(),
                    PossiblePlaces = new List<Place>() { places["Senri Shrine Road (distant)"] },
                    PreIdx = "1", PostIdx = "2"
                    } }
            };
            characters["Garaiya"].Supports.Add(characters["Kaisen"]);
            characters["Garaiya"].Supports.Add(characters["Kujiru"]);

            Dictionary<string, Team> teams = new Dictionary<string, Team>()
            {
                { "Yabusame", new Team() { Id = "Yabusame", Leader = characters["Yabusame"], Supports = new List<Character>() { characters["Tsubakura"], characters["Shion"] } } },
                { "Humikado", new Team() { Id = "Humikado", Leader = characters["Humikado"], Supports = new List<Character>() { characters["Iyozane"], characters["Tsugumi"] } } },
                { "Tenkai", new Team() { Id = "Tenkai", Leader = characters["Tenkai"], Supports = new List<Character>() { characters["Sukune"], characters["Sese"] } } },
                { "Kuroji", new Team() { Id = "Kuroji", Leader = characters["Kuroji"], Supports = new List<Character>() { characters["Hooaka"], characters["Aoji"] } } },
            };

            var clist = characters.Values.OrderBy(c => c.Name).ToList();

            foreach (var team in teams.Values)
            {
                var sw = new StreamWriter(@"D:\whatever_" + team.Id + ".txt");
                sw.NewLine = "\n";
                foreach (var character in characters.Values)
                {
                    if (character == team.Leader || team.Supports.Contains(character)) continue;

                    sw.WriteLine($"=== {character.Name} ===");
                    sw.WriteLine();
                    if (character.PossiblePlaces.Count == 1)
                    {
                        var place = character.PossiblePlaces[0];
                        sw.WriteLine($"[[File:{place.Img}|frame|{place.Name}]]");
                    }
                    else
                    {
                        sw.WriteLine("{{multiple image|caption_align=center|header_align=center|direction=vertical");
                        sw.WriteLine("| width=238");
                        for (var i = 0; i < character.PossiblePlaces.Count; i++)
                        {
                            var place = character.PossiblePlaces[i];
                            sw.WriteLine($"| image{i + 1} = {place.Img}");
                            sw.WriteLine($"| caption{i + 1} = {place.Name}" + (i == character.PossiblePlaces.Count - 1 ? "" : " or"));
                        }
                        sw.WriteLine("}}");
                    }

                    var prepath = basePath + $"\\talk_{team.Id}_{character.Id}_{character.PreIdx}.txt";
                    if (!File.Exists(prepath))
                    {
                        Console.WriteLine($"No pre-battle dialogue found between {team.Leader.Name} and {character.Name}");
                        sw.WriteLine("");
                        continue;
                    }

                    sw.WriteLine("{{DialogTable/Header}}");
                    sw.WriteLine("{{DialogTable|h1");
                    sw.WriteLine("| ja = " + string.Join(" or ", character.PossiblePlaces.Select(p => p.JapName)));
                    sw.WriteLine("| en = " + string.Join(" or ", character.PossiblePlaces.Select(p => p.WikiName)));
                    sw.WriteLine("}}");

                    var entered = false;
                    var titled = false;

                    var lines = File.ReadAllLines(prepath);
                    foreach (var line in lines)
                    {
                        var cells = line.Split(',');
                        var cidx = int.Parse(cells[0].Trim());
                        if (cells[1].Trim() == "") break;

                        string charname;
                        if (cells[1].Trim() == "???") charname = "???";
                        else charname = cidx > 0 ? (cidx == 1 ? character.Name : character.Supports[cidx - 2].Name) : (cidx == -1 ? team.Leader.Name : team.Supports[-cidx - 2].Name);

                        if (!entered && cidx > 0 && cells[2].Trim() != "0")
                        {
                            sw.Write("{{DialogTable|status\n| status =[[" + character.FullName + "]] ENTERS\n}}\n");
                            entered = true;
                        }
                        if (!titled && cidx == 1 && charname != "???")
                        {
                            sw.Write("{{DialogTable|h1\n| ja = " + character.JapTitle + "<br>" + character.JapName + "\n| en = " + character.Title + "<br>[[" + character.FullName + "]]\n}}\n");
                            titled = true;
                        }
                        sw.Write("{{DialogTable\n| char =" + charname + "\n| ja   =" + cells[3] + (cells[4].Trim() != "" ? "<br>" : "") + cells[4] + "\n| en   =\n}}\n");
                    }
                    sw.Write("{{DialogTable|h1\n| ja =BGM: " + character.JapBgm + "\n| en =" + character.Bgm + "\n}}\n");
                    sw.Write("{{DialogTable|status\n| status =Please position the soundtrack correctly if you find its position! Thank you!\n}}\n");
                    sw.Write("{{DialogTable|status\n| status =[[" + character.FullName + "]] DEFEATED\n}}\n");

                    var postpath = basePath + $"\\talk_{team.Id}_{character.Id}_{character.PostIdx}.txt";
                    if (character.On1cc != null)
                    {
                        if (File.Exists(postpath))
                        {
                            Console.WriteLine($"Post-battle dialogue found between {team.Leader.Name} and {character.Name}, even though there is ending");
                        }
                        if (character.On1cc == character.OnContinue)
                        {
                            sw.Write("{{DialogTable|status\n| status =If player has or has not continued\n}}\n");
                            sw.Write("{{DialogTable|statusnr\n| status =[[../??? Team's " + character.On1cc + " Ending|" + character.On1cc + " Ending]]\n}}\n");
                        }
                        else
                        {
                            sw.Write("{{DialogTable|status\n| status =If player has continued\n}}\n");
                            sw.Write("{{DialogTable|statusnr\n| status =[[../??? Team's " + character.OnContinue + " Ending|" + character.OnContinue + " Ending]]\n}}\n");
                            sw.Write("{{DialogTable|status\n| status =If player has not continued\n}}\n");
                            sw.Write("{{DialogTable|statusnr\n| status =[[../??? Team's " + character.On1cc + " Ending|" + character.On1cc + " Ending]]\n}}\n");
                        }
                    }
                    else
                    {
                        if (!File.Exists(postpath))
                        {
                            Console.WriteLine($"Post-battle dialogue between {team.Leader.Name} and {character.Name} not found");
                        }
                        else
                        {
                            lines = File.ReadAllLines(postpath);
                            foreach (var line in lines)
                            {
                                var cells = line.Split(',');
                                var cidx = int.Parse(cells[0].Trim());
                                if (cells[1].Trim() == "") break;

                                string charname = cidx > 0 ? (cidx == 1 ? character.Name : character.Supports[cidx - 2].Name) : (cidx == -1 ? team.Leader.Name : team.Supports[-cidx - 2].Name);

                                if (!entered && cidx > 0 && cells[2].Trim() != "0") sw.Write("{{DialogTable|status\n| status =[[" + character.FullName + "]] ENTERS\n}}\n");
                                if (!titled && cidx == 1 && charname != "???") sw.Write("{{DialogTable|h1\n| ja = " + character.JapTitle + "<br>" + character.JapName + "\n| en = " + character.Title + "<br>[[" + character.FullName + "]]\n}}\n");
                                sw.Write("{{DialogTable\n| char =" + charname + "\n| ja   =" + cells[3] + (cells[4].Trim() != "" ? "<br>" : "") + cells[4] + "\n| en   =\n}}\n");
                            }
                        }
                    }

                    sw.WriteLine("{{DialogTable/Footer}}");
                    sw.WriteLine("");
                }
            }

            Console.WriteLine("=====");
            Console.WriteLine("done");
            Console.ReadLine();
        }
    }
}