use std::borrow::Cow;
use bitfield::bitfield;
use crate::rva;
use shared::{FromStatic, InstanceResult};
bitfield! {
pub struct GestureHandle(u32);
impl Debug;
bool, acquired, set_acquired: 0;
u16, index, _: 15, 1;
u16, local_index, _: 31, 16;
}
#[repr(C)]
pub struct GestureGameData {
_vftable: usize,
_unk08: u64,
pub gestures: [GestureHandle; 40],
_unkb0: u64,
}
impl GestureGameData {
pub fn has_gesture(&self, gesture_index: u32) -> bool {
let id = gesture_index + 22;
if let Ok(data_store) = unsafe { GestureDataStore::instance() } {
for handle in &self.gestures {
if data_store.entries[handle.index() as usize].id == id {
return handle.acquired();
}
}
}
false
}
pub fn set_gesture_acquired(&mut self, gesture_index: u32, acquired: bool) -> bool {
let id = gesture_index + 22;
if let Ok(data_store) = unsafe { GestureDataStore::instance() } {
for handle in &mut self.gestures {
if data_store.entries[handle.index() as usize].id == id {
handle.set_acquired(acquired);
return true;
}
}
}
false
}
}
#[repr(C)]
pub struct GestureDataStore {
pub entries: [GestureDataStoreEntry; 41],
}
impl FromStatic for GestureDataStore {
fn name() -> Cow<'static, str> {
"GestureDataStore".into()
}
fn instance_ptr() -> InstanceResult<*mut Self> {
shared::load_static_direct(rva::get().gesture_data_store)
}
}
#[repr(C)]
pub struct GestureDataStoreEntry {
pub icon_id: u32,
_unk04: u32,
pub id: u32,
_unkc: u32,
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn proper_sizes() {
assert_eq!(0x10, size_of::<GestureDataStoreEntry>());
}
}