diff options
author | Daniel Schadt <kingdread@gmx.de> | 2020-06-28 17:22:43 +0200 |
---|---|---|
committer | Daniel Schadt <kingdread@gmx.de> | 2020-06-28 17:22:43 +0200 |
commit | 0978345648cf9cdad6222f583dd21497b409d07e (patch) | |
tree | 9470f87a879e36c68104ef067c6657eb94cd98e5 /src/analyzers/raids | |
parent | acdc4d977e573d54c73530f77ba210efd2184cf0 (diff) | |
download | evtclib-0978345648cf9cdad6222f583dd21497b409d07e.tar.gz evtclib-0978345648cf9cdad6222f583dd21497b409d07e.tar.bz2 evtclib-0978345648cf9cdad6222f583dd21497b409d07e.zip |
start implementing analyzers
It turns out that the different encounters do require quite some
encounter-specific logic, not only to determine whether the CM was
activated, but also to determine whether the fight was successful, the
duration of the fight, later the phases, ...
Wrapping all of this in pre-defined "triggers" (like CmTrigger) feels
like it will be a bit unfitting, so with this patch we have introduced
the evtclib::Analyzer, which can be used to analyze the fights.
Currently, the whole CM detection logic has been moved to this new
interface, and soon we also want the success-detection logic in there.
The tests pass and the interface of Log::is_cm is unchanged.
Diffstat (limited to 'src/analyzers/raids')
-rw-r--r-- | src/analyzers/raids/mod.rs | 11 | ||||
-rw-r--r-- | src/analyzers/raids/w4.rs | 116 | ||||
-rw-r--r-- | src/analyzers/raids/w5.rs | 62 | ||||
-rw-r--r-- | src/analyzers/raids/w6.rs | 87 | ||||
-rw-r--r-- | src/analyzers/raids/w7.rs | 86 |
5 files changed, 362 insertions, 0 deletions
diff --git a/src/analyzers/raids/mod.rs b/src/analyzers/raids/mod.rs new file mode 100644 index 0000000..91b0dba --- /dev/null +++ b/src/analyzers/raids/mod.rs @@ -0,0 +1,11 @@ +mod w4; +pub use w4::{Cairn, Deimos, MursaatOverseer, Samarog}; + +mod w5; +pub use w5::{Dhuum, SoullessHorror}; + +mod w6; +pub use w6::{ConjuredAmalgamate, LargosTwins, Qadim}; + +mod w7; +pub use w7::{CardinalAdina, CardinalSabir, QadimThePeerless}; diff --git a/src/analyzers/raids/w4.rs b/src/analyzers/raids/w4.rs new file mode 100644 index 0000000..efdab8f --- /dev/null +++ b/src/analyzers/raids/w4.rs @@ -0,0 +1,116 @@ +//! Boss fight analyzers for Wing 4 (Bastion of the Penitent). +use crate::{ + analyzers::{helpers, Analyzer}, + Log, +}; + +pub const CAIRN_CM_BUFF: u32 = 38_098; + +/// Analyzer for the first fight of Wing 4, Cairn. +/// +/// The CM is detected by the presence of the buff representing the countdown before which you have +/// to use your special action skill. +#[derive(Debug, Clone, Copy)] +pub struct Cairn<'log> { + log: &'log Log, +} + +impl<'log> Cairn<'log> { + pub fn new(log: &'log Log) -> Self { + Cairn { log } + } +} + +impl<'log> Analyzer for Cairn<'log> { + fn log(&self) -> &Log { + self.log + } + + fn is_cm(&self) -> bool { + helpers::buff_present(self.log, CAIRN_CM_BUFF) + } +} + +pub const MO_CM_HEALTH: u64 = 30_000_000; + +/// Analyzer for the second fight of Wing 4, Mursaat Overseer. +/// +/// The CM is detected by the boss's health, which is higher in the challenge mote. +#[derive(Debug, Clone, Copy)] +pub struct MursaatOverseer<'log> { + log: &'log Log, +} + +impl<'log> MursaatOverseer<'log> { + pub fn new(log: &'log Log) -> Self { + MursaatOverseer { log } + } +} + +impl<'log> Analyzer for MursaatOverseer<'log> { + fn log(&self) -> &Log { + self.log + } + + fn is_cm(&self) -> bool { + helpers::boss_health(self.log) + .map(|h| h >= MO_CM_HEALTH) + .unwrap_or(false) + } +} + +pub const SAMAROG_CM_HEALTH: u64 = 40_000_000; + +/// Analyzer for the third fight of Wing 4, Samarog. +/// +/// The CM is detected by the boss's health, which is higher in the challenge mote. +#[derive(Debug, Clone, Copy)] +pub struct Samarog<'log> { + log: &'log Log, +} + +impl<'log> Samarog<'log> { + pub fn new(log: &'log Log) -> Self { + Samarog { log } + } +} + +impl<'log> Analyzer for Samarog<'log> { + fn log(&self) -> &Log { + self.log + } + + fn is_cm(&self) -> bool { + helpers::boss_health(self.log) + .map(|h| h >= SAMAROG_CM_HEALTH) + .unwrap_or(false) + } +} + +pub const DEIMOS_CM_HEALTH: u64 = 42_000_000; + +/// Analyzer for the fourth fight of Wing 4, Deimos. +/// +/// The CM is detected by the boss's health, which is higher in the challenge mote. +#[derive(Debug, Clone, Copy)] +pub struct Deimos<'log> { + log: &'log Log, +} + +impl<'log> Deimos<'log> { + pub fn new(log: &'log Log) -> Self { + Deimos { log } + } +} + +impl<'log> Analyzer for Deimos<'log> { + fn log(&self) -> &Log { + self.log + } + + fn is_cm(&self) -> bool { + helpers::boss_health(self.log) + .map(|h| h >= DEIMOS_CM_HEALTH) + .unwrap_or(false) + } +} diff --git a/src/analyzers/raids/w5.rs b/src/analyzers/raids/w5.rs new file mode 100644 index 0000000..b8c3f3c --- /dev/null +++ b/src/analyzers/raids/w5.rs @@ -0,0 +1,62 @@ +//! Boss fight analyzers for Wing 5 (Hall of Chains) +use crate::{ + analyzers::{helpers, Analyzer}, + Log, +}; + +pub const DESMINA_BUFF_ID: u32 = 47414; +pub const DESMINA_MS_THRESHOLD: u64 = 11_000; + +/// Analyzer for the first fight of Wing 5, Soulless Horror (aka. Desmina). +/// +/// The CM is detected by the time between applications of the Necrosis debuff, which is applied at +/// a faster rate when the challenge mote is active. +#[derive(Debug, Clone, Copy)] +pub struct SoullessHorror<'log> { + log: &'log Log, +} + +impl<'log> SoullessHorror<'log> { + pub fn new(log: &'log Log) -> Self { + SoullessHorror { log } + } +} + +impl<'log> Analyzer for SoullessHorror<'log> { + fn log(&self) -> &Log { + self.log + } + + fn is_cm(&self) -> bool { + let tbb = helpers::time_between_buffs(self.log, DESMINA_BUFF_ID); + tbb > 0 && tbb <= DESMINA_MS_THRESHOLD + } +} + +pub const DHUUM_CM_HEALTH: u64 = 40_000_000; + +/// Analyzer for the second fight of Wing 5, Dhuum. +/// +/// The CM is detected by the boss's health, which is higher in the challenge mote. +#[derive(Debug, Clone, Copy)] +pub struct Dhuum<'log> { + log: &'log Log, +} + +impl<'log> Dhuum<'log> { + pub fn new(log: &'log Log) -> Self { + Dhuum { log } + } +} + +impl<'log> Analyzer for Dhuum<'log> { + fn log(&self) -> &Log { + self.log + } + + fn is_cm(&self) -> bool { + helpers::boss_health(self.log) + .map(|h| h >= DHUUM_CM_HEALTH) + .unwrap_or(false) + } +} diff --git a/src/analyzers/raids/w6.rs b/src/analyzers/raids/w6.rs new file mode 100644 index 0000000..c4e5b1a --- /dev/null +++ b/src/analyzers/raids/w6.rs @@ -0,0 +1,87 @@ +//! Boss fight analyzers for Wing 6 (Mythwright Gambit) +use crate::{ + analyzers::{helpers, Analyzer}, + Log, +}; + +pub const CA_CM_BUFF: u32 = 53_075; + +/// Analyzer for the first fight of Wing 6, Conjured Amalgamate. +/// +/// The CM is detected by the presence of the buff that the player targeted by the laser has. +#[derive(Debug, Clone, Copy)] +pub struct ConjuredAmalgamate<'log> { + log: &'log Log, +} + +impl<'log> ConjuredAmalgamate<'log> { + pub fn new(log: &'log Log) -> Self { + ConjuredAmalgamate { log } + } +} + +impl<'log> Analyzer for ConjuredAmalgamate<'log> { + fn log(&self) -> &Log { + self.log + } + + fn is_cm(&self) -> bool { + helpers::buff_present(self.log, CA_CM_BUFF) + } +} + +pub const LARGOS_CM_HEALTH: u64 = 19_200_000; + +/// Analyzer for the second fight of Wing 6, Largos Twins. +/// +/// The CM is detected by the boss's health, which is higher in the challenge mote. +#[derive(Debug, Clone, Copy)] +pub struct LargosTwins<'log> { + log: &'log Log, +} + +impl<'log> LargosTwins<'log> { + pub fn new(log: &'log Log) -> Self { + LargosTwins { log } + } +} + +impl<'log> Analyzer for LargosTwins<'log> { + fn log(&self) -> &Log { + self.log + } + + fn is_cm(&self) -> bool { + helpers::boss_health(self.log) + .map(|h| h >= LARGOS_CM_HEALTH) + .unwrap_or(false) + } +} + +pub const QADIM_CM_HEALTH: u64 = 21_100_000; + +/// Analyzer for the third fight of Wing 6, Qadim. +/// +/// The CM is detected by the boss's health, which is higher in the challenge mote. +#[derive(Debug, Clone, Copy)] +pub struct Qadim<'log> { + log: &'log Log, +} + +impl<'log> Qadim<'log> { + pub fn new(log: &'log Log) -> Self { + Qadim { log } + } +} + +impl<'log> Analyzer for Qadim<'log> { + fn log(&self) -> &Log { + self.log + } + + fn is_cm(&self) -> bool { + helpers::boss_health(self.log) + .map(|h| h >= QADIM_CM_HEALTH) + .unwrap_or(false) + } +} diff --git a/src/analyzers/raids/w7.rs b/src/analyzers/raids/w7.rs new file mode 100644 index 0000000..a8319a3 --- /dev/null +++ b/src/analyzers/raids/w7.rs @@ -0,0 +1,86 @@ +//! Boss fight analyzers for Wing 6 (Mythwright Gambit) +use crate::{ + analyzers::{helpers, Analyzer}, + Log, +}; + +pub const ADINA_CM_HEALTH: u64 = 24_800_000; + +/// Analyzer for the first fight of Wing 7, Cardinal Adina. +/// +/// The CM is detected by the boss's health, which is higher in the challenge mote. +#[derive(Debug, Clone, Copy)] +pub struct CardinalAdina<'log> { + log: &'log Log, +} + +impl<'log> CardinalAdina<'log> { + pub fn new(log: &'log Log) -> Self { + CardinalAdina { log } + } +} + +impl<'log> Analyzer for CardinalAdina<'log> { + fn log(&self) -> &Log { + self.log + } + + fn is_cm(&self) -> bool { + helpers::boss_health(self.log) + .map(|h| h >= ADINA_CM_HEALTH) + .unwrap_or(false) + } +} + +pub const SABIR_CM_HEALTH: u64 = 32_400_000; + +/// Analyzer for the second fight of Wing 7, Cardinal Sabir. +/// +/// The CM is detected by the boss's health, which is higher in the challenge mote. +#[derive(Debug, Clone, Copy)] +pub struct CardinalSabir<'log> { + log: &'log Log, +} + +impl<'log> CardinalSabir<'log> { + pub fn new(log: &'log Log) -> Self { + CardinalSabir { log } + } +} + +impl<'log> Analyzer for CardinalSabir<'log> { + fn log(&self) -> &Log { + self.log + } + + fn is_cm(&self) -> bool { + helpers::boss_health(self.log) + .map(|h| h >= SABIR_CM_HEALTH) + .unwrap_or(false) + } +} + +pub const QADIMP_CM_HEALTH: u64 = 51_000_000; + +#[derive(Debug, Clone, Copy)] +pub struct QadimThePeerless<'log> { + log: &'log Log, +} + +impl<'log> QadimThePeerless<'log> { + pub fn new(log: &'log Log) -> Self { + QadimThePeerless { log } + } +} + +impl<'log> Analyzer for QadimThePeerless<'log> { + fn log(&self) -> &Log { + self.log + } + + fn is_cm(&self) -> bool { + helpers::boss_health(self.log) + .map(|h| h >= QADIMP_CM_HEALTH) + .unwrap_or(false) + } +} |