From d79a214dd66a9cd2b5e631ba90178920891c8ee6 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Thu, 31 Mar 2022 13:16:00 +0200 Subject: EoD strikes: implement Minister Li analyzer --- src/analyzers/mod.rs | 2 +- src/analyzers/strikes.rs | 91 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 83 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/analyzers/mod.rs b/src/analyzers/mod.rs index ba800a9..8f9b1ff 100644 --- a/src/analyzers/mod.rs +++ b/src/analyzers/mod.rs @@ -132,10 +132,10 @@ pub fn for_log<'l>(log: &'l Log) -> Option> { | Encounter::FraenirOfJormag | Encounter::Boneskinner | Encounter::WhisperOfJormag - | Encounter::MinisterLi | Encounter::Dragonvoid => Some(Box::new(strikes::GenericStrike::new(log))), Encounter::CaptainMaiTrin => Some(Box::new(strikes::CaptainMaiTrin::new(log))), Encounter::Ankka => Some(Box::new(strikes::Ankka::new(log))), + Encounter::MinisterLi => Some(Box::new(strikes::MinisterLi::new(log))), } } diff --git a/src/analyzers/strikes.rs b/src/analyzers/strikes.rs index 5c43865..4c43016 100644 --- a/src/analyzers/strikes.rs +++ b/src/analyzers/strikes.rs @@ -38,13 +38,6 @@ impl<'log> Analyzer for GenericStrike<'log> { } } -/// The ID of the "Determined" buff. -/// -/// This buff is applied to the strike mission bosses when they die instead or phase. -/// -/// Teh chat link for this buff is `[&Bn8DAAA=]`. -pub const DETERMINED_ID: u32 = 895; - /// Analyzer for the Captain Mai Trin/Aetherblade Hideout strike. #[derive(Debug, Clone, Copy)] pub struct CaptainMaiTrin<'log> { @@ -53,6 +46,13 @@ pub struct CaptainMaiTrin<'log> { impl<'log> CaptainMaiTrin<'log> { pub const ECHO_OF_SCARLET_BRIAR: u16 = 24_768; + /// Determined buff that is used in Mai Trin's Strike. + /// + /// Thanks to ArenaNet's consistency, there are multiple versions of the Determined buff in + /// use. + /// + /// The chat link for this buff is `[&Bn8DAAA=]`. + pub const DETERMINED_ID: u32 = 895; /// Create a new [`CaptainMaiTrin`] analyzer for the given log. /// @@ -92,7 +92,7 @@ impl<'log> Analyzer for CaptainMaiTrin<'log> { .. } = event.kind() { - if *buff_id == DETERMINED_ID + if *buff_id == Self::DETERMINED_ID && *destination_agent_addr == mai.addr() && event.time() > scarlet.first_aware() { @@ -112,6 +112,13 @@ pub struct Ankka<'log> { } impl<'log> Ankka<'log> { + /// Determined buff that is used in Ankka's Strike. + /// + /// Thanks to ArenaNet's consistency, there are multiple versions of the Determined buff in + /// use. + /// + /// The chat link for this buff is `[&Bn8DAAA=]`. + pub const DETERMINED_ID: u32 = CaptainMaiTrin::DETERMINED_ID; /// The minimum duration of [`DETERMINED_ID`] buff applications. pub const DURATION_CUTOFF: i32 = i32::MAX; /// The expected number of times that Ankka needs to phase before we consider it a success. @@ -156,7 +163,7 @@ impl<'log> Analyzer for Ankka<'log> { .. } = event.kind() { - *buff_id == DETERMINED_ID + *buff_id == Self::DETERMINED_ID && *destination_agent_addr == ankka.addr() && *duration == Self::DURATION_CUTOFF } else { @@ -168,3 +175,69 @@ impl<'log> Analyzer for Ankka<'log> { Outcome::from_bool(phase_change_count == Self::EXPECTED_PHASE_COUNT) } } + +/// Analyzer for the Minister Li/Kaineng Overlook strike. +#[derive(Debug, Clone, Copy)] +pub struct MinisterLi<'log> { + log: &'log Log, +} + +impl<'log> MinisterLi<'log> { + /// Determined buff that is used in Minister Li's Strike. + /// + /// Thanks to ArenaNet's consistency, there are multiple versions of the Determined buff in + /// use. + /// + /// The chat link for this buff is `[&BvoCAAA=]`. + pub const DETERMINED_ID: u32 = 762; + /// The minimum number of times that Minister Li needs to phase before we consider it a success. + pub const MINIMUM_PHASE_COUNT: usize = 3; + + /// Create a new [`MinisterLi`] analyzer for the given log. + /// + /// **Do not** use this method unless you know what you are doing. Instead, rely on + /// [`Log::analyzer`]! + pub fn new(log: &'log Log) -> Self { + MinisterLi { log } + } +} + +impl<'log> Analyzer for MinisterLi<'log> { + fn log(&self) -> &Log { + self.log + } + + fn is_cm(&self) -> bool { + // EoD strike CMs are not implemented yet as of 2022-03-31 + false + } + + fn outcome(&self) -> Option { + check_reward!(self.log); + + let li = self + .log + .characters() + .find(|npc| npc.id() == Boss::MinisterLi as u16)?; + + let phase_change_count = self + .log + .events() + .iter() + .filter(|event| { + if let EventKind::BuffApplication { + destination_agent_addr, + buff_id, + .. + } = event.kind() + { + *buff_id == Self::DETERMINED_ID && *destination_agent_addr == li.addr() + } else { + false + } + }) + .count(); + + Outcome::from_bool(phase_change_count >= Self::MINIMUM_PHASE_COUNT) + } +} -- cgit v1.2.3