From 9f6f3db682ab927fef4f1399d13c4cfc91313f82 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Thu, 14 Jun 2018 17:26:23 +0200 Subject: deal with multiple boss agents Exemplary done with Xera. --- src/lib.rs | 25 +++++++++++++++++++++++++ src/statistics/gamedata.rs | 25 +++++++++++++++++++------ 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c81a519..ab32bd1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,6 +35,8 @@ pub use event::{Event, EventKind}; pub mod statistics; +use statistics::gamedata::{self, Boss}; + /// A macro that returns `true` when the given expression matches the pattern. /// /// ```rust @@ -165,12 +167,35 @@ impl Log { } /// Return the boss agent. + /// + /// Be careful with encounters that have multiple boss agents, such as Trio + /// and Xera. pub fn boss(&self) -> &Agent { self.npcs() .find(|n| matches!(n.kind, AgentKind::Character(x) if x == self.boss_id)) .expect("Boss has no agent!") } + /// Return all boss agents. + /// + /// 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 == Boss::Xera as u16 { + vec![self.boss_id, gamedata::XERA_PHASE2_ID] + } else { + vec![self.boss_id] + }; + self.npcs() + .filter(|a| matches!(a.kind, AgentKind::Character(x) if boss_ids.contains(&x))) + .collect() + } + + /// Check whether the given address is a boss agent. + pub fn is_boss(&self, addr: u64) -> bool { + self.boss_agents().into_iter().any(|a| *a.addr() == addr) + } + /// Return all events present in this log. pub fn events(&self) -> &[Event] { &self.events diff --git a/src/statistics/gamedata.rs b/src/statistics/gamedata.rs index ea1be39..1b5fec6 100644 --- a/src/statistics/gamedata.rs +++ b/src/statistics/gamedata.rs @@ -5,9 +5,24 @@ use super::boon::{BoonQueue, BoonType}; /// Enum containing all bosses with their IDs. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Boss { - ValeGuardian = 15483, + ValeGuardian = 0x3C4E, + + /// Xera ID for phase 1. + /// + /// This is only half of Xera's ID, as there will be a second agent for the + /// second phase. This agent will have another ID, see + /// [`XERA_PHASE2_ID`](constant.XERA_PHASE2_ID.html). + Xera = 0x3F76, } +/// ID for Xera in the second phase. +/// +/// The original Xera will despawn, and after the tower phase, a separate spawn +/// will take over. This new Xera will have this ID. Care needs to be taken when +/// calculating boss damage on this encounter, as both Xeras have to be taken +/// into account. +pub const XERA_PHASE2_ID: u16 = 0x3F9E; + /// Contains a boon. /// /// Fields: @@ -103,11 +118,9 @@ macro_rules! mechanics { } /// A slice of all mechanics that we know about. -pub static MECHANICS: &[Mechanic] = &[ - mechanics! { Boss::ValeGuardian => [ - "Unstable Magic Spike" => Trigger::SkillOnPlayer(31860), - ]}, -]; +pub static MECHANICS: &[Mechanic] = &[mechanics! { Boss::ValeGuardian => [ + "Unstable Magic Spike" => Trigger::SkillOnPlayer(31860), +]}]; /// Get all mechanics that belong to the given boss. pub fn get_mechanics(boss_id: u16) -> Vec<&'static Mechanic> { -- cgit v1.2.3