use std::ptr::NonNull;
use bitfield::bitfield;
use pelite::pe64::Pe;
use shared::program::Program;
use super::{CSEzTask, CSEzUpdateTask, OptionalItemId};
use crate::rva;
pub const STATUS_MESSAGE_DEMIGOD_FELLED: i32 = 1;
pub const STATUS_MESSAGE_LEGEND_FELLED: i32 = 2;
pub const STATUS_MESSAGE_GREAT_ENEMY_FELLED: i32 = 3;
pub const STATUS_MESSAGE_ENEMY_FELLED: i32 = 4;
pub const STATUS_MESSAGE_YOU_DIED: i32 = 5;
pub const STATUS_MESSAGE_HOST_VANQUISHED: i32 = 7;
pub const STATUS_MESSAGE_BLOOD_FINGER_VANQUISHED: i32 = 8;
pub const STATUS_MESSAGE_DUTY_FULL_FILLED: i32 = 9;
pub const STATUS_MESSAGE_LOST_GRACE_DISCOVERED: i32 = 11;
pub const STATUS_MESSAGE_COMMENCE: i32 = 13;
pub const STATUS_MESSAGE_VICTORY: i32 = 14;
pub const STATUS_MESSAGE_STALEMATE: i32 = 15;
pub const STATUS_MESSAGE_DEFEAT: i32 = 16;
pub const STATUS_MESSAGE_MAP_FOUND: i32 = 17;
pub const STATUS_MESSAGE_GREAT_RUNE_RESTORED: i32 = 21;
pub const STATUS_MESSAGE_GOD_SLAIN: i32 = 22;
pub const STATUS_MESSAGE_DUELIST_VANQUISHED: i32 = 23;
pub const STATUS_MESSAGE_RECUSANT_VANQUISHED: i32 = 24;
pub const STATUS_MESSAGE_INVADER_VANQUISHED: i32 = 25;
pub const STATUS_MESSAGE_FURLED_FINGER_RANK_ADVANCED: i32 = 30;
pub const STATUS_MESSAGE_FURLED_FINGER_RANK_ADVANCED2: i32 = 31;
pub const STATUS_MESSAGE_DUELIST_RANK_ADVANCED: i32 = 32;
pub const STATUS_MESSAGE_DUELIST_RANK_ADVANCED2: i32 = 33;
pub const STATUS_MESSAGE_BLOODY_FINGER_RANK_ADVANCED: i32 = 34;
pub const STATUS_MESSAGE_BLOODY_FINGER_RANK_ADVANCED2: i32 = 35;
pub const STATUS_MESSAGE_RECUSANT_RANK_ADVANCED: i32 = 36;
pub const STATUS_MESSAGE_RECUSANT_RANK_ADVANCED2: i32 = 37;
pub const STATUS_MESSAGE_HUNTER_RANK_ADVANCED: i32 = 38;
pub const STATUS_MESSAGE_HUNTER_RANK_ADVANCED2: i32 = 39;
pub const STATUS_MESSAGE_HEART_STOLEN: i32 = 40;
pub const STATUS_MESSAGE_MENU_TEXT: i32 = 41;
#[repr(C)]
#[shared::singleton("CSMenuMan")]
pub struct CSMenuManImp {
vftable: usize,
menu_data: usize,
player_status_calculator: usize,
unk18: [u8; 2],
pub disable_mouse_cursor: bool,
unk1b: [u8; 0x65],
pub popup_menu: Option<NonNull<CSPopupMenu>>,
window_job: usize,
unk90: [u8; 0xAC],
pub disable_save_menu: u32,
unk140: [u8; 0x520],
pub player_menu_ctrl: CSPlayerMenuCtrl,
null_player_menu_ctrl: usize,
unk6b0: [u8; 0x60],
pub back_screen_data: BackScreenData,
pub loading_screen_data: LoadingScreenData,
unk748: [u8; 0x118],
system_announce_view_model: usize,
pub update_task: CSEzUpdateTask<CSEzTask, Self>,
unk890: [u8; 0x10],
}
impl CSMenuManImp {
pub fn display_status_message(&mut self, message: i32) -> bool {
let rva = Program::current()
.rva_to_va(rva::get().cs_menu_man_imp_display_status_message)
.unwrap();
let target = unsafe {
std::mem::transmute::<u64, extern "C" fn(&mut CSMenuManImp, i32) -> bool>(rva)
};
target(self, message)
}
}
#[repr(C)]
pub struct CSMenuData {
vftable: usize,
unk8: [u8; 0x54],
pub show_steam_names: bool,
unk5d: [u8; 0x13],
pub menu_gaitem_use_state: CSMenuGaitemUseState,
unk88: bool,
unk89: [u8; 0x67],
}
#[repr(C)]
pub struct CSMenuGaitemUseState {
vftable: usize,
unk8: u32,
pub quick_slot_item_id: u32,
unk10: u32,
unk14: u32,
}
#[repr(C)]
pub struct CSPopupMenu {
vftable: usize,
pub menu_man: NonNull<CSMenuManImp>,
unk10: usize,
unk18: usize,
unk20: [u8; 0x90],
current_top_menu_job: usize,
unkb8: [u8; 0xb0],
input_data: u64,
unk170: [u8; 0x120],
pub show_failed_to_save: bool,
unkb91: [u8; 0x8f],
}
#[repr(C)]
pub struct CSPlayerMenuCtrl {
vftable: usize,
pub selected_goods_item: OptionalItemId,
pub selected_magic_item: OptionalItemId,
unk10: i32,
unk14: i32,
pub chr_menu_flags: CSChrMenuFlags,
unk28: [u8; 0x20],
}
#[repr(C)]
pub struct CSChrMenuFlags {
vftable: usize,
pub flags: ChrMenuFlags,
}
bitfield! {
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct ChrMenuFlags(u32);
impl Debug;
pub pause_menu_state, set_pause_menu_state: 3;
}
#[repr(C)]
pub struct BackScreenData {
vftable: usize,
unk8: [u8; 0x8],
}
#[repr(C)]
pub struct LoadingScreenData {
vftable: usize,
unk8: [u8; 0x20],
}
#[repr(C)]
pub struct FeSystemAnnounceViewModel {
menu_view_model: usize,
view: usize,
message_queue: FeSystemAnnounceViewModelMessageQueue,
}
#[repr(C)]
pub struct FeSystemAnnounceViewModelMessageQueue {
unk0: usize,
unk8: usize,
elements: usize,
capacity: usize,
unk20: usize,
count: usize,
}
#[cfg(test)]
mod test {
use crate::cs::{
BackScreenData, CSMenuData, CSMenuGaitemUseState, CSMenuManImp, CSPlayerMenuCtrl,
CSPopupMenu, FeSystemAnnounceViewModel, FeSystemAnnounceViewModelMessageQueue,
LoadingScreenData,
};
#[test]
fn proper_sizes() {
assert_eq!(0x8a0, size_of::<CSMenuManImp>());
assert_eq!(0xF0, size_of::<CSMenuData>());
assert_eq!(0x18, size_of::<CSMenuGaitemUseState>());
assert_eq!(0x320, size_of::<CSPopupMenu>());
assert_eq!(0x48, size_of::<CSPlayerMenuCtrl>());
assert_eq!(0x10, size_of::<BackScreenData>());
assert_eq!(0x28, size_of::<LoadingScreenData>());
assert_eq!(0x40, size_of::<FeSystemAnnounceViewModel>());
assert_eq!(0x30, size_of::<FeSystemAnnounceViewModelMessageQueue>());
}
}