diff --git a/rabi_splitter_WPF/BossFightConfig.cs b/rabi_splitter_WPF/BossFightConfig.cs
new file mode 100644
index 0000000..8695aa4
--- /dev/null
+++ b/rabi_splitter_WPF/BossFightConfig.cs
@@ -0,0 +1,163 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace rabi_splitter_WPF
+{
+ // The descriptions of all the boss fights are listed here.
+ // Fields can be omitted to keep them unspecified.
+ public partial class BossFight
+ {
+ public static BossFight UNKNOWN =
+ new BossFight (
+ displayName: "UNKNOWN"
+ );
+
+ public static BossFight Cocoa1 =
+ new BossFight (
+ displayName: "Cocoa1",
+ music: Music.GET_ON_WITH_IT,
+ map: Map.SouthernWoodland,
+ startingBosses: new[] {Boss.Cocoa}
+ );
+
+ public static BossFight Ribbon =
+ new BossFight (
+ displayName: "Ribbon",
+ music: Music.GET_ON_WITH_IT,
+ map: Map.SouthernWoodland,
+ startingBosses: new[] {Boss.Ribbon}
+ );
+
+ public static BossFight Ashuri1 =
+ new BossFight (
+ displayName: "Ashuri1",
+ music: Music.GET_ON_WITH_IT,
+ map: Map.WesternCoast,
+ startingBosses: new[] {Boss.Ashuri}
+ );
+
+ public static BossFight Ashuri2 =
+ new BossFight (
+ displayName: "Ashuri2",
+ music: Music.BRAWL_BREAKS_VER_2,
+ map: Map.EasternHighlands,
+ startingBosses: new[] {Boss.Ashuri}
+ );
+
+ public static BossFight BigBox =
+ new BossFight (
+ displayName: "Big Box",
+ music: Music.MIDBOSS_BATTLE,
+ map: Map.EasternHighlands,
+ startingBosses: new[] {Boss.BigBox}
+ );
+
+ public static BossFight RainbowMaid =
+ new BossFight (
+ displayName: "Rainbow Maid",
+ music: Music.MIDBOSS_BATTLE,
+ map: Map.EasternHighlands,
+ startingBosses: new[] {Boss.RainbowMaid}
+ );
+
+ public static BossFight Seana1 =
+ new BossFight (
+ displayName: "Seana1",
+ music: Music.KITTY_ATTACK,
+ map: Map.NorthernTundra,
+ startingBosses: new[] {Boss.Seana}
+ );
+
+ public static BossFight Seana2 =
+ new BossFight (
+ displayName: "Seana2",
+ music: Music.BOUNCE_BOUNCE,
+ map: Map.IslandCore,
+ startingBosses: new[] {Boss.Seana}
+ );
+
+ public static BossFight Kotri1 =
+ new BossFight (
+ displayName: "Kotri1",
+ music: Music.BRAWL_BREAKS,
+ map: Map.IslandCore,
+ startingBosses: new[] {Boss.Kotri}
+ );
+
+ public static BossFight Kotri2 =
+ new BossFight (
+ displayName: "Kotri2",
+ music: Music.BRAWL_BREAKS,
+ map: Map.WesternCoast,
+ startingBosses: new[] {Boss.Kotri}
+ );
+
+ public static BossFight Kotri3 =
+ new BossFight (
+ displayName: "Kotri3",
+ music: Music.BRAWL_BREAKS,
+ map: Map.SubterraneanArea,
+ startingBosses: new[] {Boss.Kotri}
+ );
+
+ public static BossFight Alius1 =
+ new BossFight (
+ displayName: "Alius1",
+ music: Music.SUDDEN_DEATH,
+ map: Map.WarpDestination,
+ startingBosses: new[] {Boss.IllusionAlius}
+ );
+
+ public static BossFight Alius2 =
+ new BossFight (
+ displayName: "Alius2",
+ music: Music.SUDDEN_DEATH,
+ map: Map.WarpDestination,
+ startingBosses: new[] {Boss.Noah1, Boss.IllusionAlius}
+ );
+
+ public static BossFight Alius3 =
+ new BossFight (
+ displayName: "Alius3",
+ music: Music.SUDDEN_DEATH,
+ map: Map.WarpDestination,
+ startingBosses: new[] {Boss.Noah1}
+ );
+
+ public static BossFight Miru =
+ new BossFight (
+ displayName: "Miru",
+ music: Music.M_R_,
+ map: Map.WarpDestination,
+ startingBosses: new[] {Boss.Miru}
+ );
+
+ public static BossFight Noah1 =
+ new BossFight (
+ displayName: "Noah1",
+ music: Music.THE_TRUTH_NEVER_SPOKEN,
+ map: Map.WarpDestination,
+ startingBosses: new[] {Boss.Noah1}
+ );
+
+ public static BossFight Noah3 =
+ new BossFight (
+ displayName: "Noah3",
+ music: Music.RFN_III,
+ map: Map.WarpDestination,
+ startingBosses: new[] {Boss.Noah3}
+ );
+
+ public static BossFight SideChapter =
+ new BossFight (
+ displayName: "Side Chapter",
+ music: Music.GET_ON_WITH_IT,
+ map: Map.RabiRabiTown,
+ extraCondition: (startingBosses, music, map) => {
+ return startingBosses.Count == 3;
+ }
+ );
+ }
+}
diff --git a/rabi_splitter_WPF/BossFightEnum.cs b/rabi_splitter_WPF/BossFightEnum.cs
new file mode 100644
index 0000000..e5c3e5c
--- /dev/null
+++ b/rabi_splitter_WPF/BossFightEnum.cs
@@ -0,0 +1,99 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+
+namespace rabi_splitter_WPF
+{
+ ///
+ /// enum
+ ///
+ public partial class BossFight
+ {
+ // Do not make these properties public.
+ private static int nextAvailableValue = 0;
+ private readonly int _value;
+ private static BossFight[] _bossFights;
+
+ // Do not make these properties static.
+ public readonly string displayName;
+ public readonly Music? music;
+ public readonly Map? map;
+ public readonly HashSet startingBosses;
+ public readonly Func, Music, Map, bool> extraCondition;
+
+ private BossFight(string displayName = null,
+ Music? music = null,
+ Map? map = null,
+ Boss[] startingBosses = null,
+ Func, Music, Map, bool> extraCondition = null)
+ {
+ _value = nextAvailableValue++;
+ this.displayName = displayName;
+ this.music = music;
+ this.map = map;
+ this.startingBosses = (startingBosses != null) ? new HashSet(startingBosses) : null;
+ this.extraCondition = extraCondition;
+ }
+
+ public int Value
+ {
+ get { return _value; }
+ }
+
+ public override string ToString()
+ {
+ return displayName;
+ }
+
+ private static BossFight[] GetAllBossFights()
+ {
+ var type = typeof(BossFight);
+ var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);
+
+ var bossFights = new List();
+ foreach (var info in fields)
+ {
+ var instance = new BossFight();
+ var locatedValue = info.GetValue(instance) as BossFight;
+
+ if (locatedValue != null && locatedValue != BossFight.UNKNOWN)
+ {
+ bossFights.Add(locatedValue);
+ }
+ }
+
+ return bossFights.ToArray();
+ }
+
+ public static IEnumerable GetBossFights()
+ {
+ if (_bossFights == null) _bossFights = GetAllBossFights();
+
+ foreach (var bossFight in _bossFights)
+ {
+ yield return bossFight;
+ }
+ }
+
+ public override bool Equals(object obj)
+ {
+ var otherValue = obj as BossFight;
+
+ if (otherValue == null)
+ {
+ return false;
+ }
+
+ var typeMatches = GetType().Equals(obj.GetType());
+ var valueMatches = _value.Equals(otherValue.Value);
+
+ return typeMatches && valueMatches;
+ }
+
+ public override int GetHashCode()
+ {
+ return _value.GetHashCode();
+ }
+ }
+}
diff --git a/rabi_splitter_WPF/BossFightIdentifier.cs b/rabi_splitter_WPF/BossFightIdentifier.cs
new file mode 100644
index 0000000..795ef44
--- /dev/null
+++ b/rabi_splitter_WPF/BossFightIdentifier.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace rabi_splitter_WPF
+{
+ public static partial class BossFightIdentifier
+ {
+ private static ILookup, BossFight> _matchMusicAndMap;
+ private static ILookup _matchMusic;
+ private static ILookup