diff options
author | Daniel Schadt <kingdread@gmx.de> | 2024-08-26 00:04:26 +0200 |
---|---|---|
committer | Daniel Schadt <kingdread@gmx.de> | 2024-08-26 00:04:26 +0200 |
commit | 4fc02e2d9be5e421fd9ae3839aa8e2d8b0a3b6da (patch) | |
tree | 4ab33322b295d33314ec959f6cf220f664919ef9 | |
parent | 095369c320f98dfc8a8a0e93e9439c111eb3eaa0 (diff) | |
download | evtclib-4fc02e2d9be5e421fd9ae3839aa8e2d8b0a3b6da.tar.gz evtclib-4fc02e2d9be5e421fd9ae3839aa8e2d8b0a3b6da.tar.bz2 evtclib-4fc02e2d9be5e421fd9ae3839aa8e2d8b0a3b6da.zip |
impl PartialOrd for gamedata::Encounter
-rw-r--r-- | src/gamedata.rs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/gamedata.rs b/src/gamedata.rs index f880ba6..9f0f9d4 100644 --- a/src/gamedata.rs +++ b/src/gamedata.rs @@ -345,6 +345,53 @@ impl Display for Encounter { } } +macro_rules! ordering_group { + ($self:expr, $other:expr ; $($group:expr;)*) => { + $( + let group = &$group; + if let Some(pos_a) = group.iter().position(|x| *x == $self) { + if let Some(pos_b) = group.iter().position(|x| *x == $other) { + return Some(pos_a.cmp(&pos_b)); + } + } + )* + } +} + +// We could implement (or even derive) PartialOrd for all bosses, but there is no "canonical" order +// (do fractal bosses come before raid bosses or after?). This implements a conservative order, +// such that at least the bosses that appear in a single raid wing/fractal are ordered relative to +// each other, but there is no order between different wings. This still allows some useful cases +// (like sorting bosses within a wing). +// +// There are some edge cases, like the Wing 5 events (Eater/Eyes/Broken King) and Adina/Sabir, +// which technically happen at the same time, but we're just defining a fixed order for those here. +// +// In the future, this implementation might be expanded to a total order, but by keeping it a +// partial order for now we can implement the cases that are clear (bosses within a wing) while +// allowing future extensions in a backwards-compatible way (once we figured out how we want to +// order the different wings/strikes/fractals). +impl PartialOrd for Encounter { + fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { + use Encounter::*; + ordering_group!(*self, *other; + // Raids + [ValeGuardian, Gorseval, Sabetha]; + [Slothasor, BanditTrio, Matthias]; + [KeepConstruct, TwistedCastle, Xera]; + [Cairn, MursaatOverseer, Samarog, Deimos]; + [SoullessHorror, RiverOfSouls, BrokenKing, EaterOfSouls, StatueOfDarkness, VoiceInTheVoid]; + [ConjuredAmalgamate, TwinLargos, Qadim]; + [CardinalAdina, CardinalSabir, QadimThePeerless]; + // Shattered Observatory CM + [Skorvald, Artsariiv, Arkk]; + // Nightmare CM + [MAMA, Siax, Ensolyss]; + ); + None + } +} + /// Enum containing all boss IDs. /// /// For a high-level event categorization, take a look at the [`Encounter`] enum. The IDs listed @@ -1142,6 +1189,21 @@ mod tests { } #[test] + fn test_encounter_partial_cmp() { + // Just a few example cases + use Encounter::*; + assert!(ValeGuardian < Gorseval); + assert!(ValeGuardian < Sabetha); + assert!(Gorseval < Sabetha); + assert!(ValeGuardian.partial_cmp(&Slothasor).is_none()); + + assert!(VoiceInTheVoid > SoullessHorror); + assert!(Qadim > TwinLargos); + + assert!(Ankka.partial_cmp(&Dragonvoid).is_none()); + } + + #[test] fn test_boss_parsing_ok() { use Boss::*; let tests: &[(&'static str, Boss)] = &[ |