use std::ptr::NonNull;
use shared::OwnedPtr;
use crate::param::SP_EFFECT_PARAM_ST;
use super::ChrIns;
#[repr(C)]
pub struct SpecialEffect {
vftable: usize,
head: Option<OwnedPtr<SpecialEffectEntry>>,
pub owner: NonNull<ChrIns>,
unk18: usize,
unk20: [u8; 0x118],
}
impl SpecialEffect {
pub fn entries(&self) -> impl Iterator<Item = &SpecialEffectEntry> {
let mut current = self.head.as_ref().map(|e| e.as_ptr());
std::iter::from_fn(move || {
let ret = current.and_then(|c| unsafe { c.as_ref() });
current = ret?.next.map(|e| e.as_ptr());
ret
})
}
}
#[repr(C)]
pub struct SpecialEffectEntry {
pub param_data: Option<NonNull<SP_EFFECT_PARAM_ST>>,
pub param_id: i32,
_padc: u32,
pub accumulator_info: SpecialEffectEntryAccumulatorInfo,
next: Option<NonNull<SpecialEffectEntry>>,
previous: Option<NonNull<SpecialEffectEntry>>,
pub removal_timer: f32,
unk_removal_timer: f32,
pub duration: f32,
pub interval_timer: f32,
unk50: [u8; 0x28],
}
#[repr(C)]
pub struct SpecialEffectEntryAccumulatorInfo {
unk0: usize,
pub upper_trigger_count: i32,
pub effect_on_upper_or_higher: i32,
pub lower_trigger_count: i32,
pub effect_on_lower_or_below: i32,
unk18: i32,
unk1c: u32,
}
#[repr(C)]
pub struct NpcSpEffectEquipCtrl {
pub sp_effect_equip_ctrl: SpEffectEquipCtrl,
}
#[repr(C)]
pub struct SpEffectEquipCtrl {
vfptr: usize,
pub owner: NonNull<ChrIns>,
pub sp_effect: NonNull<SpecialEffect>,
}