use std::ptr::NonNull;
use vtable_rs::VPtr;
use crate::position::HavokPosition;
use crate::rotation::Quaternion;
use shared::F32Vector4;
use super::{CSBulletIns, ChrIns, FieldInsHandle, SpecialEffect};
#[repr(C)]
pub struct NpcThinkParamLookupResult {
pub row_id: u32,
pub param_row: usize,
pub battle_goal_id: i32,
pub logic_id: i32,
}
#[vtable_rs::vtable]
pub trait CSTargetingSystemOwnerVmt {
fn destructor(&mut self, should_free: bool);
fn get_team_type<'a>(&self, out: &'a mut i8) -> &'a mut i8;
fn get_position<'a>(&self, out: &'a mut HavokPosition) -> &'a mut HavokPosition;
fn get_target_ene0_position<'a>(&self, out: &'a mut HavokPosition) -> &'a mut HavokPosition;
fn get_outmost_forward_position<'a>(&self, out: &'a mut HavokPosition)
-> &'a mut HavokPosition;
fn get_outmost_forward_position_height_offset<'a>(
&self,
out: &'a mut HavokPosition,
) -> &'a mut HavokPosition;
fn get_orientation<'a>(&self, out: &'a mut Quaternion) -> &'a mut Quaternion;
fn get_forward<'a>(&self, out: &'a mut F32Vector4) -> &'a mut F32Vector4;
fn get_forward2<'a>(&self, out: &'a mut F32Vector4) -> &'a mut F32Vector4;
fn get_hit_height(&self) -> f32;
fn get_hit_radius(&self) -> f32;
fn get_npc_think_entry(&self) -> &NpcThinkParamLookupResult;
fn is_black_phantom(&self) -> bool;
fn is_on_solid_ground(&self) -> bool;
fn is_battle_state(&self) -> bool;
fn is_not_in_any_search_state(&self) -> bool;
fn is_ignore_effect_hear_modifiers(&self) -> bool;
fn is_ignore_effect_sight_modifiers(&self) -> bool;
fn get_ignore_fake_target_flags(&self) -> u8;
fn get_owner_handle<'a>(&self, out: &'a mut FieldInsHandle) -> &'a mut FieldInsHandle;
fn unka0(&mut self, param_2: usize);
fn get_team_ai(&self) -> usize;
fn get_unk_team_ai_struct(&self) -> usize;
fn is_climbing_ladder(&self) -> bool;
fn is_target_ene0_on_ladder(&self) -> bool;
fn unkc8(&mut self) -> usize;
fn get_sight_search_modifiers(
&self,
rate_out: &mut f32,
add_out: &mut f32,
is_nonpositive_rate_out: &mut bool,
);
fn get_hearing_search_rate(&self) -> f32;
fn get_hearing_search_add(&self) -> f32;
fn get_hearing_sound_level_overwrite(&self) -> i32;
fn get_special_effect(&mut self) -> &mut SpecialEffect;
fn unkf8(&self) -> f32;
fn unk100(&self) -> u8;
fn unk108(&self) -> u8;
fn unk110<'a>(&self, out: &'a mut F32Vector4) -> &'a mut F32Vector4;
fn get_hearing_head_size(&self) -> f32;
fn unk120(&self) -> bool;
fn is_system_owner_ai(&self) -> bool;
fn unk130(&self) -> usize;
fn unk138(&self, param_2: usize) -> u8;
fn unk140(&self, out: usize) -> usize;
fn is_in_attack_goal(&self) -> bool;
fn unk150(&self) -> bool;
fn unk158(&self) -> bool;
fn is_disappear_action_approach(&self) -> bool;
fn is_caution_important_action_approach(&self) -> bool;
fn is_caution_action_approach(&self) -> bool;
fn is_search_lvl1_action_approach(&self) -> bool;
fn is_search_lvl2_action_approach(&self) -> bool;
fn ai_get_targeting_system(&mut self) -> &mut CSTargetingSystemBase;
}
#[repr(C)]
pub struct CSTargetingSystemOwner {
vftable: VPtr<dyn CSTargetingSystemOwnerVmt, Self>,
}
#[repr(C)]
pub struct CSBulletTargetingSystemOwner {
pub base: CSTargetingSystemOwner,
pub bullet: NonNull<CSBulletIns>,
pub owner_chr_handle: FieldInsHandle,
pub owner_think: NpcThinkParamLookupResult,
}
#[repr(C)]
pub struct CSAiTargetingSystemOwner {
pub base: CSTargetingSystemOwner,
pub ai: usize,
pub owner: NonNull<ChrIns>,
}
#[repr(C)]
pub struct CSTargetingSystemBase {
vftable: usize,
pub system_owner: NonNull<CSTargetingSystemOwner>,
pub search_sys: CSTargetSearchSys,
unk8: [u8; 0x120],
}
#[repr(C)]
pub struct CSTargetSearchSys {
vftable: usize,
pub system_owner: NonNull<CSTargetingSystemOwner>,
pub search_slots: [usize; 14],
unk80: u16,
_pad82: [u8; 6],
unk88: usize,
pub latest_ai_sound_id: i32,
pub latest_sound_rank: i8,
unk95: [u8; 0xB],
}
#[allow(unused)]
enum SearchSlotIndex {
Enemy = 0,
Friend = 1,
Sound = 2,
LastSight = 5,
LastTarget = 6,
LowFriend = 7,
Corpse = 8,
LastMemory = 11,
}
#[cfg(test)]
mod test {
use crate::cs::{
CSAiTargetingSystemOwner, CSBulletTargetingSystemOwner, CSTargetingSystemBase,
CSTargetingSystemOwner,
};
#[test]
fn proper_sizes() {
assert_eq!(0x8, size_of::<CSTargetingSystemOwner>());
assert_eq!(0x30, size_of::<CSBulletTargetingSystemOwner>());
assert_eq!(0x18, size_of::<CSAiTargetingSystemOwner>());
assert_eq!(0x1d0, size_of::<CSTargetingSystemBase>());
}
}