aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gamedata.rs89
-rw-r--r--src/lib.rs20
2 files changed, 92 insertions, 17 deletions
diff --git a/src/gamedata.rs b/src/gamedata.rs
index 1f38b0e..fa7998f 100644
--- a/src/gamedata.rs
+++ b/src/gamedata.rs
@@ -72,6 +72,51 @@ pub enum Encounter {
WhisperOfJormag = Boss::WhisperOfJormag as u16,
}
+impl Encounter {
+ /// Return all possible bosses that can appear in this encounter.
+ ///
+ /// This returns the possible boss IDs, not actual agents. For a similar function check
+ /// [`Log::boss_agents`][crate::Log::boss_agents].
+ ///
+ /// Note that not all of them have to be present in a log, for example if the encounter stopped
+ /// before all of them spawned.
+ pub fn bosses(self) -> &'static [Boss] {
+ match self {
+ Encounter::ValeGuardian => &[Boss::ValeGuardian],
+ Encounter::Gorseval => &[Boss::Gorseval],
+ Encounter::Sabetha => &[Boss::Sabetha],
+ Encounter::Slothasor => &[Boss::Slothasor],
+ Encounter::Matthias => &[Boss::Matthias],
+ Encounter::KeepConstruct => &[Boss::KeepConstruct],
+ Encounter::Xera => &[Boss::Xera, Boss::Xera2],
+ Encounter::Cairn => &[Boss::Cairn],
+ Encounter::MursaatOverseer => &[Boss::MursaatOverseer],
+ Encounter::Samarog => &[Boss::Samarog],
+ Encounter::Deimos => &[Boss::Deimos],
+ Encounter::SoullessHorror => &[Boss::SoullessHorror],
+ Encounter::VoiceInTheVoid => &[Boss::Dhuum],
+ Encounter::ConjuredAmalgamate => &[Boss::ConjuredAmalgamate],
+ Encounter::TwinLargos => &[Boss::Nikare, Boss::Kenut],
+ Encounter::Qadim => &[Boss::Qadim],
+ Encounter::CardinalAdina => &[Boss::CardinalAdina],
+ Encounter::CardinalSabir => &[Boss::CardinalSabir],
+ Encounter::QadimThePeerless => &[Boss::QadimThePeerless],
+ Encounter::Ai => &[Boss::Ai],
+ Encounter::Skorvald => &[Boss::Skorvald],
+ Encounter::Artsariiv => &[Boss::Artsariiv],
+ Encounter::Arkk => &[Boss::Arkk],
+ Encounter::MAMA => &[Boss::MAMA],
+ Encounter::Siax => &[Boss::Siax],
+ Encounter::Ensolyss => &[Boss::Ensolyss],
+ Encounter::IcebroodConstruct => &[Boss::IcebroodConstruct],
+ Encounter::SuperKodanBrothers => &[Boss::VoiceOfTheFallen, Boss::ClawOfTheFallen],
+ Encounter::FraenirOfJormag => &[Boss::FraenirOfJormag],
+ Encounter::Boneskinner => &[Boss::Boneskinner],
+ Encounter::WhisperOfJormag => &[Boss::WhisperOfJormag],
+ }
+ }
+}
+
/// Error for when converting a string to an encounter fails.
#[derive(Debug, Clone, Hash, PartialEq, Eq, Error)]
#[error("Invalid encounter identifier: {0}")]
@@ -243,6 +288,50 @@ pub enum Boss {
WhisperOfJormag = 0x58B7,
}
+impl Boss {
+ /// Get the encounter ID in which this boss can appear.
+ ///
+ /// This is the counterpart to [`Encounter::bosses`].
+ pub fn encounter(self) -> Encounter {
+ match self {
+ Boss::ValeGuardian => Encounter::ValeGuardian,
+ Boss::Gorseval => Encounter::Gorseval,
+ Boss::Sabetha => Encounter::Sabetha,
+ Boss::Slothasor => Encounter::Slothasor,
+ Boss::Matthias => Encounter::Matthias,
+ Boss::KeepConstruct => Encounter::KeepConstruct,
+ Boss::Xera => Encounter::Xera,
+ Boss::Xera2 => Encounter::Xera,
+ Boss::Cairn => Encounter::Cairn,
+ Boss::MursaatOverseer => Encounter::MursaatOverseer,
+ Boss::Samarog => Encounter::Samarog,
+ Boss::Deimos => Encounter::Deimos,
+ Boss::SoullessHorror => Encounter::SoullessHorror,
+ Boss::Dhuum => Encounter::VoiceInTheVoid,
+ Boss::ConjuredAmalgamate => Encounter::ConjuredAmalgamate,
+ Boss::Nikare => Encounter::TwinLargos,
+ Boss::Kenut => Encounter::TwinLargos,
+ Boss::Qadim => Encounter::Qadim,
+ Boss::CardinalAdina => Encounter::CardinalAdina,
+ Boss::CardinalSabir => Encounter::CardinalSabir,
+ Boss::QadimThePeerless => Encounter::QadimThePeerless,
+ Boss::Ai => Encounter::Ai,
+ Boss::Skorvald => Encounter::Skorvald,
+ Boss::Artsariiv => Encounter::Artsariiv,
+ Boss::Arkk => Encounter::Arkk,
+ Boss::MAMA => Encounter::MAMA,
+ Boss::Siax => Encounter::Siax,
+ Boss::Ensolyss => Encounter::Ensolyss,
+ Boss::IcebroodConstruct => Encounter::IcebroodConstruct,
+ Boss::VoiceOfTheFallen => Encounter::SuperKodanBrothers,
+ Boss::ClawOfTheFallen => Encounter::SuperKodanBrothers,
+ Boss::FraenirOfJormag => Encounter::FraenirOfJormag,
+ Boss::Boneskinner => Encounter::Boneskinner,
+ Boss::WhisperOfJormag => Encounter::WhisperOfJormag,
+ }
+ }
+}
+
/// Error for when converting a string to a profession fails.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Error)]
#[error("Invalid profession identifier: {0}")]
diff --git a/src/lib.rs b/src/lib.rs
index 764f8ce..2233c93 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -759,17 +759,9 @@ impl Log {
/// This correctly returns multiple agents on encounters where multiple
/// agents are needed.
pub fn boss_agents(&self) -> Vec<&Agent> {
- let boss_ids = if self.boss_id == Encounter::Xera as u16 {
- vec![self.boss_id, Boss::Xera2 as u16]
- } else if self.boss_id == Encounter::TwinLargos as u16 {
- vec![Boss::Nikare as u16, Boss::Kenut as u16]
- } else if self.encounter() == Some(Encounter::SuperKodanBrothers) {
- vec![Boss::VoiceOfTheFallen as u16, Boss::ClawOfTheFallen as u16]
- } else {
- vec![self.boss_id]
- };
+ let bosses = self.encounter().map(Encounter::bosses).unwrap_or(&[] as &[_]);
self.npcs()
- .filter(|c| boss_ids.contains(&c.character().id))
+ .filter(|c| bosses.iter().any(|boss| *boss as u16 == c.character().id))
.map(Agent::erase)
.collect()
}
@@ -792,13 +784,7 @@ impl Log {
/// if we know about it in [`Encounter`].
#[inline]
pub fn encounter(&self) -> Option<Encounter> {
- // Sometimes, encounters of the strike mission "Voice of the Fallen and Claw of the Fallen"
- // are saved with the ID of the Claw and sometimes with the Voice. Therefore, we need to
- // unify those cases.
- if self.boss_id == Boss::ClawOfTheFallen as u16 {
- return Some(Encounter::SuperKodanBrothers);
- }
- Encounter::from_u16(self.boss_id)
+ Boss::from_u16(self.boss_id).map(Boss::encounter)
}
/// Return an analyzer suitable to analyze the given log.