From 9885463d93fbc55b71ea1d5b570dbb3f712e50c9 Mon Sep 17 00:00:00 2001 From: spuds <71292624+bananaturtlesandwich@users.noreply.github.com> Date: Sat, 29 Jul 2023 12:17:50 +0100 Subject: [PATCH] use name map --- Cargo.toml | 2 +- src/map/transform.rs | 41 +++++++++++++------------ src/writing.rs | 66 ++++++++++++++++++++++++++++++---------- src/writing/overworld.rs | 38 +++++++++++++---------- src/writing/savegames.rs | 51 ++++++++++++++++++++++--------- 5 files changed, 131 insertions(+), 67 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7af4fdd..f1f15ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "blue-fire-rando" description = "a gamemode for blue fire which shuffles pickups" repository = "https://github.com/bananaturtlesandwich/blue-fire-rando" -version = "1.1.2" +version = "1.1.3" authors = ["spuds"] edition = "2021" diff --git a/src/map/transform.rs b/src/map/transform.rs index 540c5eb..5a46c8f 100644 --- a/src/map/transform.rs +++ b/src/map/transform.rs @@ -1,8 +1,7 @@ use unreal_asset::{ exports::ExportNormalTrait, - // exports::*, properties::{struct_property::StructProperty, vector_property::VectorProperty, *}, - types::{fname::FName, vector::Vector}, + types::vector::Vector, *, }; @@ -46,6 +45,7 @@ pub fn set_location( new: Vector, offset: (f64, f64, f64), ) { + let mut name_map = asset.get_name_map(); let (x, y, z) = offset; let Some(transform) = get_transform_index(index, asset) else { return @@ -67,28 +67,31 @@ pub fn set_location( } } } - None => norm - .properties - .push(Property::StructProperty(StructProperty { - name: FName::from_slice("RelativeLocation"), - ancestry: unversioned::ancestry::Ancestry { - ancestry: Vec::new(), - }, - struct_type: Some(FName::from_slice("Vector")), - struct_guid: None, - property_guid: None, - duplication_index: 0, - serialize_none: true, - value: vec![Property::VectorProperty(VectorProperty { - name: FName::from_slice("RelativeLocation"), + None => { + let name = name_map.get_mut().add_fname("RelativeLocation"); + let struct_type = Some(name_map.clone_resource().get_mut().add_fname("Vector")); + norm.properties + .push(Property::StructProperty(StructProperty { + name, ancestry: unversioned::ancestry::Ancestry { ancestry: Vec::new(), }, + struct_type, + struct_guid: None, property_guid: None, duplication_index: 0, - value: Vector::new(new.x.into(), new.y.into(), new.z.into()), - })], - })), + serialize_none: true, + value: vec![Property::VectorProperty(VectorProperty { + name: name_map.get_mut().add_fname("RelativeLocation"), + ancestry: unversioned::ancestry::Ancestry { + ancestry: Vec::new(), + }, + property_guid: None, + duplication_index: 0, + value: Vector::new(new.x.into(), new.y.into(), new.z.into()), + })], + })); + } } } diff --git a/src/writing.rs b/src/writing.rs index 151f752..ea82301 100644 --- a/src/writing.rs +++ b/src/writing.rs @@ -1,6 +1,6 @@ use super::logic::*; use crate::{io::*, map::*}; -use unreal_asset::{exports::*, properties::*, types::fname::FName, *}; +use unreal_asset::{exports::*, properties::*, *}; mod cutscenes; mod overworld; @@ -45,19 +45,27 @@ fn extract( Ok((open(&loc)?, loc)) } -fn byte_property(name: &str, enum_type: &str, val: &str) -> Property { +fn byte_property( + name: &str, + enum_ty: &str, + val: &str, + name_map: &mut containers::shared_resource::SharedResource, +) -> Property { + let name = name_map.get_mut().add_fname(name); + let enum_type = Some(name_map.get_mut().add_fname(enum_ty)); Property::ByteProperty(int_property::ByteProperty { - name: FName::from_slice(name), + name, ancestry: unversioned::ancestry::Ancestry { ancestry: Vec::new(), }, property_guid: None, duplication_index: 0, - enum_type: Some(FName::from_slice(enum_type)), - value: int_property::BytePropertyValue::FName(FName::new_dummy( - format!("{}::NewEnumerator{}", enum_type, val), - 0, - )), + enum_type, + value: int_property::BytePropertyValue::FName( + name_map + .get_mut() + .add_fname(&format!("{}::NewEnumerator{}", enum_ty, val)), + ), }) } @@ -66,6 +74,7 @@ fn set_byte( enum_type: &str, val: &str, export: &mut normal_export::NormalExport, + name_map: &mut containers::shared_resource::SharedResource, ) -> Result<(), Error> { match export .properties @@ -74,10 +83,13 @@ fn set_byte( { Some(byte) => { use int_property::BytePropertyValue; - *cast!(BytePropertyValue, FName, &mut byte.value).ok_or(Error::Assumption)? = - FName::new_dummy(format!("{}::NewEnumerator{}", enum_type, val), 0) + *cast!(BytePropertyValue, FName, &mut byte.value).ok_or(Error::Assumption)? = name_map + .get_mut() + .add_fname(&format!("{}::NewEnumerator{}", enum_type, val)) } - None => export.properties.push(byte_property(name, enum_type, val)), + None => export + .properties + .push(byte_property(name, enum_type, val, name_map)), } Ok(()) } @@ -233,7 +245,23 @@ fn create_hook( } impl Drop { - pub fn as_shop_entry(&self, price: i32) -> Vec { + pub fn as_shop_entry( + &self, + price: i32, + name_map: &mut containers::shared_resource::SharedResource, + ) -> Vec { + let amount_name = name_map + .get_mut() + .add_fname("Amount_6_185C591747EF40A592FB63886FDB4281"); + let resets_name = name_map + .get_mut() + .add_fname("Resets_8_E303F5DF4270CCEE83F05F974F3661C9"); + let original_amounts_name = name_map + .get_mut() + .add_fname("OriginalAmount_11_58C3C17D426D49A439C0EE85D7E9B6EC"); + let price_name = name_map + .get_mut() + .add_fname("Price_26_80A37F3645AE8292A9F311B86094C095"); use int_property::*; [ byte_property( @@ -245,9 +273,10 @@ impl Drop { Drop::Duck => Items::Duck.as_ref(), _ => "25", }, + name_map, ), Property::IntProperty(IntProperty { - name: FName::from_slice("Amount_6_185C591747EF40A592FB63886FDB4281"), + name: amount_name, ancestry: unversioned::ancestry::Ancestry { ancestry: Vec::new(), }, @@ -260,7 +289,7 @@ impl Drop { }, }), Property::BoolProperty(BoolProperty { - name: FName::from_slice("Resets_8_E303F5DF4270CCEE83F05F974F3661C9"), + name: resets_name, ancestry: unversioned::ancestry::Ancestry { ancestry: Vec::new(), }, @@ -269,7 +298,7 @@ impl Drop { value: false, }), Property::IntProperty(IntProperty { - name: FName::from_slice("OriginalAmount_11_58C3C17D426D49A439C0EE85D7E9B6EC"), + name: original_amounts_name, ancestry: unversioned::ancestry::Ancestry { ancestry: Vec::new(), }, @@ -284,6 +313,7 @@ impl Drop { "Type_17_9B84CFD04716464F71190CB4CECE0F49", "InventoryItemType", self.as_ref(), + name_map, ), byte_property( "Tunic_23_B7D465CA4DCF57F409450789A6DB8590", @@ -293,6 +323,7 @@ impl Drop { } else { "0" }, + name_map, ), byte_property( "Weapon_22_F3B61F384438EE8A8193F385AE45F88A", @@ -302,6 +333,7 @@ impl Drop { } else { "0" }, + name_map, ), byte_property( "Spirit_21_55691F2E4B399DB3F381209D33BBE30B", @@ -311,9 +343,10 @@ impl Drop { } else { "0" }, + name_map, ), Property::IntProperty(IntProperty { - name: FName::from_slice("Price_26_80A37F3645AE8292A9F311B86094C095"), + name: price_name, ancestry: unversioned::ancestry::Ancestry { ancestry: Vec::new(), }, @@ -333,6 +366,7 @@ impl Drop { } else { "0" }, + name_map, ), ] .to_vec() diff --git a/src/writing/overworld.rs b/src/writing/overworld.rs index c95be71..a76c5a2 100644 --- a/src/writing/overworld.rs +++ b/src/writing/overworld.rs @@ -14,6 +14,7 @@ pub fn write( |(location, checks)| -> Result>, Error> { Ok(thread.spawn(move || { let (mut map, loc) = extract(app, pak, &format!("{PREFIX}{location}.umap"))?; + let mut name_map = map.get_name_map(); for Check { context, drop, .. } in checks { match context { Context::Shop(shop, index, ..) => { @@ -50,11 +51,11 @@ pub fn write( .value ) .ok_or(Error::Assumption)? - = FName::new_dummy(format!("E_Emotes::NewEnumerator{}", emote.as_ref()), 0); + = name_map.get_mut().add_fname(&format!("E_Emotes::NewEnumerator{}", emote.as_ref())); } if let Drop::Ability(ability) = drop { - set_byte("Ability", "Abilities", ability.as_ref(), norm)?; - set_byte("Type", "InventoryItemType", drop.as_ref(), norm)?; + set_byte("Ability", "Abilities", ability.as_ref(), norm, &mut name_map)?; + set_byte("Type", "InventoryItemType", drop.as_ref(), norm, &mut name_map)?; } cast!( Property, @@ -146,7 +147,7 @@ pub fn write( Some(id) => id.value = Some(format!("{name}{counter}")), None => norm.properties.push(Property::StrProperty( str_property::StrProperty { - name: FName::from_slice("ID"), + name: name_map.get_mut().add_fname("ID"), ancestry: unversioned::ancestry::Ancestry { ancestry: Vec::new() }, property_guid: None, duplication_index: 0, @@ -170,8 +171,9 @@ pub fn write( "InventoryItemType", drop.as_ref(), chest, + &mut name_map )?; - set_byte("Item", "Items", item.as_ref(), chest)?; + set_byte("Item", "Items", item.as_ref(), chest, &mut name_map)?; match chest.properties.iter_mut().find_map(|prop| { cast!(Property, BoolProperty, prop) .filter(|bool| bool.name == "KeyItem") @@ -180,7 +182,7 @@ pub fn write( None if item.key_item() => { chest.properties.push(Property::BoolProperty( int_property::BoolProperty { - name: FName::from_slice("KeyItem"), + name: name_map.get_mut().add_fname("KeyItem"), ancestry: unversioned::ancestry::Ancestry { ancestry: Vec::new() }, property_guid: None, duplication_index: 0, @@ -197,7 +199,7 @@ pub fn write( Some(num) => num.value = *amount, None => chest.properties.push(Property::IntProperty( int_property::IntProperty { - name: FName::from_slice("Amount"), + name: name_map.get_mut().add_fname("Amount"), ancestry: unversioned::ancestry::Ancestry { ancestry: Vec::new() }, property_guid: None, duplication_index: 0, @@ -218,8 +220,9 @@ pub fn write( "InventoryItemType", drop.as_ref(), chest, + &mut name_map )?; - set_byte("Weapon", "Weapons", weapon.as_ref(), chest)?; + set_byte("Weapon", "Weapons", weapon.as_ref(), chest, &mut name_map)?; } Drop::Tunic(tunic) => { if !is_chest() { @@ -233,8 +236,9 @@ pub fn write( "InventoryItemType", drop.as_ref(), chest, + &mut name_map )?; - set_byte("Tunic", "Tunics", tunic.as_ref(), chest)?; + set_byte("Tunic", "Tunics", tunic.as_ref(), chest, &mut name_map)?; } Drop::Spirit(spirit) if is_chest() => { let chest = map.asset_data.exports[i] @@ -245,8 +249,9 @@ pub fn write( "InventoryItemType", drop.as_ref(), chest, + &mut name_map )?; - set_byte("Amulet", "Spirits", spirit.as_ref(), chest)?; + set_byte("Amulet", "Spirits", spirit.as_ref(), chest, &mut name_map)?; } Drop::Spirit(spirit) => { if class != "Spirit_C" { @@ -255,7 +260,7 @@ pub fn write( let spirit_bp = map.asset_data.exports[i] .get_normal_export_mut() .ok_or(Error::Assumption)?; - set_byte("Amulet", "Spirits", spirit.as_ref(), spirit_bp)?; + set_byte("Amulet", "Spirits", spirit.as_ref(), spirit_bp, &mut name_map)?; } Drop::Ability(ability) => { if !is_chest() { @@ -269,8 +274,9 @@ pub fn write( "InventoryItemType", drop.as_ref(), chest, + &mut name_map )?; - set_byte("Ability", "Abilities", ability.as_ref(), chest)?; + set_byte("Ability", "Abilities", ability.as_ref(), chest, &mut name_map)?; } Drop::Emote(emote) => { if class != "EmoteStatue_BP_C" { @@ -279,7 +285,7 @@ pub fn write( let statue = map.asset_data.exports[i] .get_normal_export_mut() .ok_or(Error::Assumption)?; - set_byte("Emote", "E_Emotes", emote.as_ref(), statue)?; + set_byte("Emote", "E_Emotes", emote.as_ref(), statue, &mut name_map)?; } Drop::Ore(amount) => { if class != "Pickup_C" { @@ -288,7 +294,7 @@ pub fn write( let pickup = map.asset_data.exports[i] .get_normal_export_mut() .ok_or(Error::Assumption)?; - set_byte("Type", "PickUpList", "5", pickup)?; + set_byte("Type", "PickUpList", "5", pickup, &mut name_map)?; match pickup.properties.iter_mut().find_map(|prop| { cast!(Property, IntProperty, prop).filter(|amount| { amount.name == "Souls/LifeAmount" @@ -297,8 +303,8 @@ pub fn write( Some(num) => num.value = *amount, None => pickup.properties.push(Property::IntProperty( int_property::IntProperty { - name: FName::from_slice("Souls/LifeAmount"), - ancestry: unversioned::ancestry::Ancestry { ancestry: Vec::new() }, + name: name_map.get_mut().add_fname("Souls/LifeAmount"), + ancestry: unversioned::ancestry::Ancestry { ancestry: Vec::new() }, property_guid: None, duplication_index: 0, value: *amount, diff --git a/src/writing/savegames.rs b/src/writing/savegames.rs index f8d714e..1f6ad4a 100644 --- a/src/writing/savegames.rs +++ b/src/writing/savegames.rs @@ -22,9 +22,12 @@ pub fn write( .value .clear() } + let mut name_map = savegame.get_name_map(); for Check { context, drop, .. } in checks { match context { Context::Shop(shop, index, price) => { + let name = name_map.get_mut().add_fname(shop.as_ref()); + let struct_type = Some(name_map.get_mut().add_fname("Inventory")); savegame.asset_data.exports[1] .get_normal_export_mut() .and_then(|norm| { @@ -33,21 +36,34 @@ pub fn write( .ok_or(Error::Assumption)? .value[index] = Property::StructProperty( unreal_asset::properties::struct_property::StructProperty { - name: FName::from_slice(shop.as_ref()), + name, ancestry: unversioned::ancestry::Ancestry { ancestry: Vec::new(), }, - struct_type: Some(FName::from_slice("Inventory")), + struct_type, struct_guid: None, property_guid: None, duplication_index: 0, serialize_none: true, - value: drop.as_shop_entry(price), + value: drop.as_shop_entry(price, &mut name_map), }, ); } Context::Starting => { - fn add_item(savegame: &mut Asset, drop: Drop) -> Result<(), Error> { + fn add_item( + savegame: &mut Asset, + drop: Drop, + name_map: &mut containers::shared_resource::SharedResource< + asset::name_map::NameMap, + >, + ) -> Result<(), Error> { + let name = name_map.get_mut().add_fname(match drop { + Drop::Item(item, ..) if item.key_item() => { + "PassiveInventory_48_636C916F4A37F051CF9B14A1402B4C94" + } + _ => "Inventory_23_288399C5416269F828550FB7376E7942", + }); + let struct_type = Some(name_map.get_mut().add_fname("Inventory")); savegame.asset_data.exports[1] .get_normal_export_mut() .and_then(|default| { @@ -67,28 +83,27 @@ pub fn write( .value .push(unreal_asset::properties::Property::StructProperty( unreal_asset::properties::struct_property::StructProperty { - name: FName::from_slice(match drop { - Drop::Item(item, ..) if item.key_item() => { - "PassiveInventory_48_636C916F4A37F051CF9B14A1402B4C94" - } - _ => "Inventory_23_288399C5416269F828550FB7376E7942", - }), + name, ancestry: unversioned::ancestry::Ancestry { ancestry: Vec::new(), }, - struct_type: Some(FName::from_slice("Inventory")), + struct_type, struct_guid: None, property_guid: None, duplication_index: 0, serialize_none: true, - value: drop.as_shop_entry(0), + value: drop.as_shop_entry(0, name_map), }, )); Ok(()) } match &drop { Drop::Ability(ability) => { - add_item(&mut savegame, Drop::Item(ability.as_item(), 1))?; + add_item( + &mut savegame, + Drop::Item(ability.as_item(), 1), + &mut name_map, + )?; savegame.asset_data.exports[1] .get_normal_export_mut() .and_then(|default| { @@ -115,6 +130,7 @@ pub fn write( &emotes.value.len().to_string(), "E_Emotes", emote.as_ref(), + &mut name_map, )) } Drop::Ore(amount) => { @@ -127,8 +143,10 @@ pub fn write( .ok_or(Error::Assumption)? .value += *amount; } - Drop::Duck => add_item(&mut savegame, Drop::Item(Items::Duck, 1))?, - Drop::Item(..) => add_item(&mut savegame, drop)?, + Drop::Duck => { + add_item(&mut savegame, Drop::Item(Items::Duck, 1), &mut name_map)? + } + Drop::Item(..) => add_item(&mut savegame, drop, &mut name_map)?, Drop::Spirit(spirit) => { let spirits = savegame.asset_data.exports[1] .get_normal_export_mut() @@ -143,6 +161,7 @@ pub fn write( &spirits.value.len().to_string(), "Spirits", spirit.as_ref(), + &mut name_map, )) } Drop::Weapon(weapon) => { @@ -159,6 +178,7 @@ pub fn write( &weapons.value.len().to_string(), "Weapons", weapon.as_ref(), + &mut name_map, )) } Drop::Tunic(tunic) => { @@ -175,6 +195,7 @@ pub fn write( &tunics.value.len().to_string(), "Tunics", tunic.as_ref(), + &mut name_map, )) } }