use crate::{
analyzers::{helpers, Analyzer, Outcome},
EventKind, Log,
};
pub const AI_INVULNERABILITY_ID: u32 = 895;
pub const AI_PHASE_SKILL: u32 = 53_569;
pub const AI_HAS_DARK_MODE_SKILL: u32 = 61_356;
fn get_dark_phase_start(log: &Log) -> Option<u64> {
if !log.events().iter().any(|event|
matches!(event.kind(), EventKind::SkillUse { skill_id, ..} if *skill_id == AI_HAS_DARK_MODE_SKILL)
) {
return None;
};
let mut dark_phase_start = None;
for event in log.events() {
if let EventKind::SkillUse { skill_id, .. } = event.kind() {
if *skill_id == AI_PHASE_SKILL {
dark_phase_start = Some(event.time());
}
}
}
dark_phase_start.or(Some(0))
}
#[derive(Debug, Clone, Copy)]
pub struct Ai<'log> {
log: &'log Log,
}
impl<'log> Ai<'log> {
pub fn new(log: &'log Log) -> Self {
Ai { log }
}
}
impl<'log> Analyzer for Ai<'log> {
fn log(&self) -> &Log {
self.log
}
fn is_cm(&self) -> bool {
true
}
fn outcome(&self) -> Option<Outcome> {
let dark_phase_start = get_dark_phase_start(self.log);
if dark_phase_start.is_none() {
return Some(Outcome::Failure);
}
let dark_phase_start = dark_phase_start.unwrap();
for event in self.log.events() {
if event.time() < dark_phase_start {
continue;
}
if let EventKind::BuffApplication {
buff_id,
destination_agent_addr,
..
} = event.kind()
{
if *buff_id == AI_INVULNERABILITY_ID && self.log.is_boss(*destination_agent_addr) {
return Some(Outcome::Success);
}
}
}
Some(Outcome::Failure)
}
}
pub const SKORVALD_CM_HEALTH: u64 = 5_551_340;
pub static SKORVALD_CM_ANOMALY_IDS: &[u16] = &[17_599, 17_673, 17_770, 17_851];
#[derive(Debug, Clone, Copy)]
pub struct Skorvald<'log> {
log: &'log Log,
}
impl<'log> Skorvald<'log> {
pub fn new(log: &'log Log) -> Self {
Skorvald { log }
}
}
impl<'log> Analyzer for Skorvald<'log> {
fn log(&self) -> &Log {
self.log
}
fn is_cm(&self) -> bool {
if Some(true) == helpers::boss_health(self.log).map(|h| h >= SKORVALD_CM_HEALTH) {
return true;
}
self.log
.characters()
.any(|character| SKORVALD_CM_ANOMALY_IDS.contains(&character.id()))
}
fn outcome(&self) -> Option<Outcome> {
Outcome::from_bool(self.log.was_rewarded() || helpers::boss_is_dead(self.log))
}
}
#[derive(Debug, Clone, Copy)]
pub struct GenericFractal<'log> {
log: &'log Log,
}
impl<'log> GenericFractal<'log> {
pub fn new(log: &'log Log) -> Self {
GenericFractal { log }
}
}
impl<'log> Analyzer for GenericFractal<'log> {
fn log(&self) -> &Log {
self.log
}
fn is_cm(&self) -> bool {
true
}
fn outcome(&self) -> Option<Outcome> {
Outcome::from_bool(self.log.was_rewarded() || helpers::boss_is_dead(self.log))
}
}