diff --git a/src/bin/gui.rs b/src/bin/gui.rs index 3d758a8..95db0e1 100644 --- a/src/bin/gui.rs +++ b/src/bin/gui.rs @@ -3,9 +3,7 @@ use std::{env, io::Cursor}; use binrw::BinRead; use eframe::egui; use ireko::{ - CompressedSaveFile, - property::map_property::{MabSubProperty, MapKeyProperty}, - save_object::{LocalProfileObject, PersistentObject}, + property::{array_property::ArrayValue, map_property::{MabSubProperty, MapKeyProperty}}, save_object::{generic::Property, LocalProfileObject, PersistentObject}, structure::{DAAssembleIdDataStruct, DABuildDataStruct, DACustomizeAssetIdDataStruct, DAHumanoidColoringDataStruct, DAHumanoidFigureData, DAMachineColoringDataStruct, DAModuleColorStruct, DATriggerDataStruct, DATuningDataStruct, Guid, LinearColorStruct, PrimaryAssetIdStruct, Struct}, CompressedSaveFile }; fn main() -> eframe::Result { @@ -18,7 +16,6 @@ fn main() -> eframe::Result { let compressed = CompressedSaveFile::::read_le(&mut local_profile_data).unwrap(); - println!("{:#?}", compressed); let local_profile = compressed.value.objs; let options = eframe::NativeOptions { @@ -35,6 +32,28 @@ fn main() -> eframe::Result { }; let mut state = AppState::SelectSlot; + enum Tab { + General, + ItemWheel, + ItemInventory, + ModuleInventory, + PartsInventory, + Build, + Presets + }; + let mut tab = Tab::General; + + enum ModuleType { + Mobility, + FrontWeapon, + RearWeapon, + Hanger, + Utility, + Thruster, + Headset, + }; + let mut module = ModuleType::Mobility; + eframe::run_simple_native("My egui App", options, move |ctx, _frame| { egui::CentralPanel::default().show(ctx, |ui| match &mut state { AppState::SelectSlot => { @@ -68,10 +87,459 @@ fn main() -> eframe::Result { AppState::EditSlot { name, persistent } => { ui.heading(format!("Editing {name}")); - ui.checkbox(&mut persistent.demo_version.value, "Demo Version"); + ui.horizontal(|ui| { + if ui.button("General").clicked() { + tab = Tab::General; + } + if ui.button("Item Wheel").clicked() { + tab = Tab::ItemWheel; + } + if ui.button("Items").clicked() { + tab = Tab::ItemInventory; + } + if ui.button("Modules").clicked() { + tab = Tab::ModuleInventory; + } + if ui.button("Parts").clicked() { + tab = Tab::PartsInventory; + } + if ui.button("Build").clicked() { + tab = Tab::Build; + } + if ui.button("Presets").clicked() { + tab = Tab::Presets; + } + }); - ui.add(egui::DragValue::new(&mut persistent.money.value).suffix(" cell")); + match tab { + Tab::General => { + ui.checkbox(&mut persistent.demo_version.value, "Demo Version"); + + ui.horizontal(|ui| { + ui.add(egui::DragValue::new(&mut persistent.money.value).suffix(" cell")); + ui.label("Money") + }); + + ui.horizontal(|ui| { + ui.add(egui::DragValue::new(&mut persistent.current_item_slot.value).range(0..=5)); + ui.label("Selected Item"); + }); + }, + Tab::ItemWheel => { + for (i, item) in persistent.item_slots.entries.iter_mut().enumerate() { + let ArrayValue::Struct { ref mut r#struct } = item.key else { + panic!("Expecting a struct!"); + }; + + let Struct::PrimaryAssetId(primary_asset_id) = r#struct else { + panic!("Expecting PrimaryAssetId!"); + }; + + ui.horizontal(|ui| { + edit_primary_asset(ui, primary_asset_id); + ui.label(format!("{i:02}")); + }); + } + }, + Tab::ItemInventory => { + for item in &mut persistent.normal_item_inventory.entries { + let MapKeyProperty::StructMaybe(ref key) = item.key else { + panic!("Expecting a struct!"); + }; + + let Property::Name(ref name) = **(key.extra_fields[0].key.as_ref().unwrap()) else { + panic!("Expecting a name property!"); + }; + + let MabSubProperty::Struct(ref value) = item.value else { + panic!("Expecting a struct!"); + }; + + let Property::Int(ref carry_count) = **(value.fields[0].key.as_ref().unwrap()) else { + panic!("Expecting an int!"); + }; + + let Property::Int(ref store_count) = **(value.fields[1].key.as_ref().unwrap()) else { + panic!("Expecting an int!"); + }; + + ui.horizontal(|ui| { + ui.label(format!("{}", name.value)); + ui.label(format!("carry: {}", carry_count.value)); + ui.label(format!("store: {}", store_count.value)); + }); + } + }, + Tab::ModuleInventory => { + ui.horizontal(|ui| { + if ui.button("Mobility").clicked() { + module = ModuleType::Mobility; + } + + if ui.button("Front Weapon").clicked() { + module = ModuleType::FrontWeapon; + } + + if ui.button("Rear Weapon").clicked() { + module = ModuleType::RearWeapon; + } + + if ui.button("Hanger").clicked() { + module = ModuleType::Hanger; + } + + if ui.button("Utility").clicked() { + module = ModuleType::Utility; + } + + if ui.button("Thruster").clicked() { + module = ModuleType::Thruster; + } + + if ui.button("Headset").clicked() { + module = ModuleType::Headset; + } + }); + + for entry in &mut persistent.module_inventory.entries { + let MapKeyProperty::Enum(ref key) = entry.key else { + panic!("Expecting enum key!"); + }; + + let matches = match module { + ModuleType::Mobility => key.value == "EDAModuleItemType::Mobility", + ModuleType::FrontWeapon => key.value == "EDAModuleItemType::FrontWeapon", + ModuleType::RearWeapon => key.value == "EDAModuleItemType::RearWeapon", + ModuleType::Hanger => key.value == "EDAModuleItemType::Hanger", + ModuleType::Utility => key.value == "EDAModuleItemType::Utility", + ModuleType::Thruster => key.value == "EDAModuleItemType::Thruster", + ModuleType::Headset => key.value == "EDAModuleItemType::Headset", + }; + + if matches { + let MabSubProperty::Struct(ref mut value) = entry.value else { + panic!("Expecting struct value!"); + }; + + let Property::Map(ref mut map) = **value.fields[0].key.as_mut().unwrap() else { + panic!("Expecting map!"); + }; + + for entry in &mut map.entries { + println!("{:#?}", entry); + + let MapKeyProperty::GUID(ref mut key) = entry.key else { + panic!("Expecting id key!"); + }; + + let MabSubProperty::Struct(ref mut value) = entry.value else { + panic!("Expecting struct value!"); + }; + + let Property::Struct(ref asset_id) = **value.fields[0].key.as_mut().unwrap() else { + panic!("Expecting struct!"); + }; + + let Struct::PrimaryAssetId(ref asset_id) = asset_id.r#struct else { + panic!("Expecting primary asset id!"); + }; + + /*let Property::Struct(ref module_data) = **value.fields[1].key.as_ref().unwrap() else { + panic!("Expecting struct!"); + }; + + let Struct::DAModuleItemData(ref module_data) = module_data.r#struct else { + panic!("Expecting module data!"); + };*/ + + ui.horizontal(|ui| { + ui.label(format!("{:#?} {} level", key, asset_id.primary_asset_name.value)); + }); + } + } + } + + //println!("{:#?}", persistent.module_inventory); + }, + Tab::PartsInventory => { + println!("{:#?}", persistent.parts_inventory); + }, + Tab::Build => { + edit_build_data(ui, &mut persistent.current_build_data); + }, + Tab::Presets => { + + }, + } } }); }) } + +fn edit_build_data(ui: &mut egui::Ui, build_data: &mut DABuildDataStruct) { + ui.label(&build_data.name.value); + + ui.label("Assemble"); + edit_assemble_data(ui, &mut build_data.assemble); + + ui.label("Trigger"); + edit_trigger_data(ui, &mut build_data.trigger); + + ui.label("Customize"); + edit_customize_data(ui, &mut build_data.customize); + + ui.label("Tuning"); + edit_tuning_data(ui, &mut build_data.tuning); +} + +fn edit_tuning_data(ui: &mut egui::Ui, tuning: &mut DATuningDataStruct) { + ui.label("not implemented yet"); +} + +fn edit_customize_data(ui: &mut egui::Ui, customize: &mut DACustomizeAssetIdDataStruct) { + ui.horizontal(|ui| { + edit_primary_asset(ui, &mut customize.body); + ui.label("Body"); + }); + + ui.horizontal(|ui| { + edit_primary_asset(ui, &mut customize.face); + ui.label("Face"); + }); + + ui.horizontal(|ui| { + edit_primary_asset(ui, &mut customize.front_hair); + ui.label("Front Hair"); + }); + + ui.horizontal(|ui| { + edit_primary_asset(ui, &mut customize.back_hair); + ui.label("Back Hair"); + }); + + edit_humanoid_coloring(ui, &mut customize.coloring_data); + + edit_humanoid_figure(ui, &mut customize.figure_data); + + ui.checkbox(&mut customize.inverse_face_mesh.value, "Inverse Face"); + ui.checkbox(&mut customize.inverse_front_hair_mesh.value, "Inverse Front Hair"); + ui.checkbox(&mut customize.inverse_back_hair_mesh.value, "Inverse Back Hair"); +} + +fn edit_humanoid_figure(ui: &mut egui::Ui, figure_data: &mut DAHumanoidFigureData) { + ui.horizontal(|ui| { + ui.add(egui::Slider::new(&mut figure_data.bust_up.value, 0.0..=1.0)); + ui.label("Bust"); + }); + + ui.horizontal(|ui| { + ui.add(egui::Slider::new(&mut figure_data.fat_up.value, 0.0..=1.0)); + ui.label("Fat"); + }); + + ui.horizontal(|ui| { + ui.add(egui::Slider::new(&mut figure_data.arm_up.value, 0.0..=1.0)); + ui.label("Arm"); + }); + + ui.horizontal(|ui| { + ui.add(egui::Slider::new(&mut figure_data.leg_up.value, 0.0..=1.0)); + ui.label("Leg"); + }); + + ui.horizontal(|ui| { + ui.add(egui::Slider::new(&mut figure_data.waist_up.value, 0.0..=1.0)); + ui.label("Waist"); + }); +} + +fn edit_humanoid_coloring(ui: &mut egui::Ui, coloring_data: &mut DAHumanoidColoringDataStruct) { + ui.horizontal(|ui| { + edit_color(ui, &mut coloring_data.skin); + ui.label("Body"); + }); + + ui.horizontal(|ui| { + edit_color(ui, &mut coloring_data.hair_base); + ui.label("Hair Base"); + }); + + ui.horizontal(|ui| { + edit_color(ui, &mut coloring_data.hair_gradation); + ui.label("Hair Gradation"); + }); + + ui.horizontal(|ui| { + edit_color(ui, &mut coloring_data.hair_highlight); + ui.label("Hair Highlight"); + }); + + ui.horizontal(|ui| { + edit_color(ui, &mut coloring_data.head_option); + ui.label("Head Option"); + }); + + ui.horizontal(|ui| { + edit_color(ui, &mut coloring_data.eye_l); + ui.label("Eye Left"); + }); + + ui.horizontal(|ui| { + edit_color(ui, &mut coloring_data.eye_r); + ui.label("Eye Right"); + }); + + ui.horizontal(|ui| { + edit_color(ui, &mut coloring_data.body_main); + ui.label("Body Main"); + }); + + ui.horizontal(|ui| { + edit_color(ui, &mut coloring_data.body_sub1); + ui.label("Body Sub 1"); + }); + + ui.horizontal(|ui| { + edit_color(ui, &mut coloring_data.body_sub2); + ui.label("Body Sub 2"); + }); + + ui.horizontal(|ui| { + edit_color(ui, &mut coloring_data.body_sub3); + ui.label("Body Sub 3"); + }); +} + +fn edit_primary_asset(ui: &mut egui::Ui, asset: &mut PrimaryAssetIdStruct) { + ui.label(format!("{}", asset.primary_asset_name.value)); +} + +fn edit_trigger_data(ui: &mut egui::Ui, trigger: &mut DATriggerDataStruct) { + ui.label("not implemented yet"); +} + +fn edit_assemble_data(ui: &mut egui::Ui, assemble: &mut DAAssembleIdDataStruct) { + ui.horizontal(|ui| { + edit_guid(ui, &mut assemble.hanger); + ui.label("Hanger"); + }); + + ui.horizontal(|ui| { + edit_guid(ui, &mut assemble.headset); + ui.label("Headset"); + }); + + ui.horizontal(|ui| { + edit_guid(ui, &mut assemble.mobility); + ui.label("Mobility"); + }); + + ui.horizontal(|ui| { + edit_guid(ui, &mut assemble.thruster); + ui.label("Thruster"); + }); + + ui.horizontal(|ui| { + edit_guid(ui, &mut assemble.utility); + ui.label("Utility"); + }); + + ui.horizontal(|ui| { + edit_guid(ui, &mut assemble.primary_front_weapon); + ui.label("Primary Front Weapon"); + }); + + ui.horizontal(|ui| { + edit_guid(ui, &mut assemble.secondary_front_weapon); + ui.label("Secondary Front Weapon"); + }); + + ui.horizontal(|ui| { + edit_guid(ui, &mut assemble.left_rear_weapon); + ui.label("Left Rear Weapon"); + }); + + ui.horizontal(|ui| { + edit_guid(ui, &mut assemble.right_rear_weapon); + ui.label("Right Rear Weapon"); + }); + + edit_machine_coloring(ui, &mut assemble.coloring_data); +} + +fn edit_machine_coloring(ui: &mut egui::Ui, coloring_data: &mut DAMachineColoringDataStruct) { + ui.horizontal(|ui| { + edit_module_color(ui, &mut coloring_data.hanger); + ui.label("Hanger"); + }); + + ui.horizontal(|ui| { + edit_module_color(ui, &mut coloring_data.headset); + ui.label("Headset"); + }); + + ui.horizontal(|ui| { + edit_module_color(ui, &mut coloring_data.mobility); + ui.label("Mobility"); + }); + + ui.horizontal(|ui| { + edit_module_color(ui, &mut coloring_data.thruster); + ui.label("Thruster"); + }); + + ui.horizontal(|ui| { + edit_module_color(ui, &mut coloring_data.utility); + ui.label("Utility"); + }); + + ui.horizontal(|ui| { + edit_module_color(ui, &mut coloring_data.primary_front_weapon); + ui.label("Primary Front Weapon"); + }); + + ui.horizontal(|ui| { + edit_module_color(ui, &mut coloring_data.secondary_front_weapon); + ui.label("Secondary Front Weapon"); + }); + + ui.horizontal(|ui| { + edit_module_color(ui, &mut coloring_data.left_rear_weapon); + ui.label("Left Rear Weapon"); + }); + + ui.horizontal(|ui| { + edit_module_color(ui, &mut coloring_data.right_rear_weapon); + ui.label("Right Rear Weapon"); + }); +} + +fn edit_module_color(ui: &mut egui::Ui, module_color: &mut DAModuleColorStruct) { + ui.horizontal(|ui| { + edit_color(ui, &mut module_color.main); + ui.label("Main"); + }); + + ui.horizontal(|ui| { + edit_color(ui, &mut module_color.main); + ui.label("Sub"); + }); + + ui.horizontal(|ui| { + edit_color(ui, &mut module_color.main); + ui.label("Inner"); + }); + + ui.horizontal(|ui| { + edit_color(ui, &mut module_color.main); + ui.label("Glow"); + }); +} + +fn edit_color(ui: &mut egui::Ui, hanger: &mut LinearColorStruct) { + ui.label("test"); +} + +fn edit_guid(ui: &mut egui::Ui, hanger: &mut Guid) { + ui.label("test"); +} diff --git a/src/property/map_property.rs b/src/property/map_property.rs index 5d1c73e..52863a1 100644 --- a/src/property/map_property.rs +++ b/src/property/map_property.rs @@ -29,7 +29,7 @@ fn cc() -> BinResult> { #[derive(Debug)] pub struct MapSubStructProperty { #[br(parse_with = cc)] - fields: Vec, + pub fields: Vec, } #[binrw] @@ -53,7 +53,7 @@ pub struct StructMaybeKey { pub r#struct: Struct, #[br(parse_with = cc)] - extra_fields: Vec, + pub extra_fields: Vec, } #[binrw]