diff --git a/extra_assets/cog.CMDL b/extra_assets/cog.CMDL new file mode 100644 index 00000000..82e5560a Binary files /dev/null and b/extra_assets/cog.CMDL differ diff --git a/extra_assets/zoomer.CMDL b/extra_assets/zoomer.CMDL new file mode 100644 index 00000000..89396bda Binary files /dev/null and b/extra_assets/zoomer.CMDL differ diff --git a/generated/json_data/qol.jsonc b/generated/json_data/qol.jsonc index 5f1b4f53..345e3171 100644 --- a/generated/json_data/qol.jsonc +++ b/generated/json_data/qol.jsonc @@ -5899,12 +5899,14 @@ { "id": 524657, // [CameraFilterKeyframe] Camera Filter Keyframe WideScreen "color": [0, 0, 0, 1], + "filterIndex": 1, "filterType": "Multiply", "filterShape": "CinemaBars" }, { "id": 524816, // [CameraFilterKeyframe] Camera Filter Keyframe "color": [0, 0, 0, 1], + "filterIndex": 1, "filterType": "Multiply", "filterShape": "CinemaBars" } diff --git a/generated/json_data/skippable_cutscenes.jsonc b/generated/json_data/skippable_cutscenes.jsonc index f8079e08..222c7dff 100644 --- a/generated/json_data/skippable_cutscenes.jsonc +++ b/generated/json_data/skippable_cutscenes.jsonc @@ -10914,12 +10914,6 @@ "state": "INACTIVE", "message": "DECREMENT" }, - { - "senderId": 666666, // [Camera] Cinematic Camera Hold - "targetId": 42069, // [CameraFilterKeyframe] Camera Filter Keyframe Hold Black - "state": "INACTIVE", - "message": "DECREMENT" - }, { "senderId": 4128769, // [Dock] Dock "targetId": 666555, // [Timer] Load Timer @@ -11716,13 +11710,13 @@ }, { "senderId": 524805, // [Camera] Cinematic Camera - "targetId": 524657, // [CameraFilterKeyframe] Camera Filter Keyframe WideScreen + "targetId": 524816, // [CameraFilterKeyframe] Camera Filter Keyframe "state": "ACTIVE", "message": "INCREMENT" }, { "senderId": 524805, // [Camera] Cinematic Camera - "targetId": 524657, // [CameraFilterKeyframe] Camera Filter Keyframe WideScreen + "targetId": 524816, // [CameraFilterKeyframe] Camera Filter Keyframe "state": "INACTIVE", "message": "DECREMENT" }, @@ -11760,7 +11754,7 @@ }, { "senderId": 524290, // [Relay] Bomb Slot Cinematic Start - "targetId": 524293, // [SpecialFunction] SpecialFunction Cinematic Skip + "targetId": 524293, // [SpecialFunction] Bomb Slot Cinematic Skip "state": "ZERO", "message": "INCREMENT" }, @@ -11796,42 +11790,42 @@ }, { "senderId": 524292, // [Relay] Bomb Slot Cinematic End - "targetId": 524293, // [SpecialFunction] SpecialFunction Cinematic Skip + "targetId": 524293, // [SpecialFunction] Bomb Slot Cinematic Skip "state": "ZERO", "message": "DECREMENT" }, { - "senderId": 524293, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524293, // [SpecialFunction] Bomb Slot Cinematic Skip "targetId": 524292, // [Relay] Bomb Slot Cinematic End "state": "ZERO", "message": "SET_TO_ZERO" }, { - "senderId": 524293, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524293, // [SpecialFunction] Bomb Slot Cinematic Skip "targetId": 524650, // [Camera] Cinematic Camera "state": "ZERO", "message": "DEACTIVATE" }, { - "senderId": 524293, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524293, // [SpecialFunction] Bomb Slot Cinematic Skip "targetId": 524656, // [Timer] Timer - Delay Grate Opening "state": "ZERO", "message": "STOP_AND_RESET" }, { - "senderId": 524293, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524293, // [SpecialFunction] Bomb Slot Cinematic Skip "targetId": 524551, // [Platform] Platform - Upper Grate "state": "ZERO", "message": "DEACTIVATE" }, { - "senderId": 524293, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524293, // [SpecialFunction] Bomb Slot Cinematic Skip "targetId": 524567, // [Platform] Platform - Upper Grate Final Position "state": "ZERO", "message": "ACTIVATE" }, { - "senderId": 524293, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524293, // [SpecialFunction] Bomb Slot Cinematic Skip "targetId": 524726, // [MemoryRelay] Memory Relay - open gate "state": "ZERO", "message": "ACTIVATE" @@ -11844,13 +11838,13 @@ }, { "senderId": 524294, // [Relay] Wallbreak Cinema Start - "targetId": 524296, // [SpecialFunction] SpecialFunction Cinematic Skip + "targetId": 524296, // [SpecialFunction] Wall Destruction Cinematic Skip "state": "ZERO", "message": "INCREMENT" }, { "senderId": 524294, // [Relay] Wallbreak Cinema Start - "targetId": 524657, // [CameraFilterKeyframe] Camera Filter Keyframe WideScreen + "targetId": 524816, // [CameraFilterKeyframe] Camera Filter Keyframe "state": "ZERO", "message": "INCREMENT" }, @@ -11928,66 +11922,66 @@ }, { "senderId": 524295, // [Relay] Wallbreak Cinema End - "targetId": 524657, // [CameraFilterKeyframe] Camera Filter Keyframe WideScreen + "targetId": 524816, // [CameraFilterKeyframe] Camera Filter Keyframe "state": "ZERO", "message": "DECREMENT" }, { "senderId": 524295, // [Relay] Wallbreak Cinema End - "targetId": 524296, // [SpecialFunction] SpecialFunction Cinematic Skip + "targetId": 524296, // [SpecialFunction] Wall Destruction Cinematic Skip "state": "ZERO", "message": "DECREMENT" }, { - "senderId": 524296, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524296, // [SpecialFunction] Wall Destruction Cinematic Skip "targetId": 524295, // [Relay] Wallbreak Cinema End "state": "ZERO", "message": "SET_TO_ZERO" }, { - "senderId": 524296, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524296, // [SpecialFunction] Wall Destruction Cinematic Skip "targetId": 524790, // [Platform] Platform_arms_up "state": "ZERO", "message": "DEACTIVATE" }, { - "senderId": 524296, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524296, // [SpecialFunction] Wall Destruction Cinematic Skip "targetId": 524801, // [Timer] Timer_pause for drop "state": "ZERO", "message": "STOP_AND_RESET" }, { - "senderId": 524296, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524296, // [SpecialFunction] Wall Destruction Cinematic Skip "targetId": 524787, // [Actor] Actor_arms_anim "state": "ZERO", "message": "DEACTIVATE" }, { - "senderId": 524296, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524296, // [SpecialFunction] Wall Destruction Cinematic Skip "targetId": 524805, // [Camera] Cinematic Camera "state": "ZERO", "message": "DEACTIVATE" }, { - "senderId": 524296, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524296, // [SpecialFunction] Wall Destruction Cinematic Skip "targetId": 524803, // [Timer] Timer_dooropen_pause "state": "ZERO", "message": "STOP_AND_RESET" }, { - "senderId": 524296, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524296, // [SpecialFunction] Wall Destruction Cinematic Skip "targetId": 524789, // [Platform] Platform_arms_down "state": "ZERO", "message": "ACTIVATE" }, { - "senderId": 524296, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524296, // [SpecialFunction] Wall Destruction Cinematic Skip "targetId": 524876, // [SpecialFunction] SpecialFunction PlayerFollowLocator "state": "ZERO", "message": "DEACTIVATE" }, { - "senderId": 524296, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524296, // [SpecialFunction] Wall Destruction Cinematic Skip "targetId": 524297, // [Relay] Destroy Wall Cutscene Skip "state": "ZERO", "message": "SET_TO_ZERO" @@ -12012,7 +12006,7 @@ }, { "senderId": 524298, // [Relay] Decrement Ice Cinematic Start - "targetId": 524300, // [SpecialFunction] SpecialFunction Cinematic Skip + "targetId": 524300, // [SpecialFunction] Ice Melting Cinematic Skip "state": "ZERO", "message": "INCREMENT" }, @@ -12024,7 +12018,7 @@ }, { "senderId": 524299, // [Relay] Decrement Ice Cinematic End - "targetId": 524300, // [SpecialFunction] SpecialFunction Cinematic Skip + "targetId": 524300, // [SpecialFunction] Ice Melting Cinematic Skip "state": "ZERO", "message": "DECREMENT" }, @@ -12035,52 +12029,46 @@ "message": "SET_TO_ZERO" }, { - "senderId": 524300, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524300, // [SpecialFunction] Ice Melting Cinematic Skip "targetId": 524299, // [Relay] Decrement Ice Cinematic End "state": "ZERO", "message": "SET_TO_ZERO" }, { - "senderId": 524300, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524300, // [SpecialFunction] Ice Melting Cinematic Skip "targetId": 524902, // [Camera] Cinematic Camera "state": "ZERO", "message": "DEACTIVATE" }, { - "senderId": 524300, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524300, // [SpecialFunction] Ice Melting Cinematic Skip "targetId": 524797, // [Timer] Timer_start hand trigger "state": "ZERO", "message": "STOP_AND_RESET" }, { - "senderId": 524300, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524300, // [SpecialFunction] Ice Melting Cinematic Skip "targetId": 524798, // [Trigger] Trigger_ballstart "state": "ZERO", "message": "ACTIVATE" }, { - "senderId": 524300, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524300, // [SpecialFunction] Ice Melting Cinematic Skip "targetId": 524804, // [Timer] Timer_allice_deactivate "state": "ZERO", "message": "RESET_AND_START" }, { - "senderId": 524300, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524300, // [SpecialFunction] Ice Melting Cinematic Skip "targetId": 524901, // [Effect] Effect-Bluelight "state": "ZERO", "message": "ACTIVATE" }, { - "senderId": 524300, // [SpecialFunction] SpecialFunction Cinematic Skip + "senderId": 524300, // [SpecialFunction] Ice Melting Cinematic Skip "targetId": 524900, // [Sound] Sound-Glowsound "state": "ZERO", "message": "PLAY" - }, - { - "senderId": 524300, // [SpecialFunction] SpecialFunction Cinematic Skip - "targetId": 524299, // [Relay] Decrement Ice Cinematic End - "state": "ZERO", - "message": "SET_TO_ZERO" } ], "relays": [ @@ -12109,15 +12097,15 @@ ], "specialFunctions": [ { - "id": 524293, // [SpecialFunction] SpecialFunction Cinematic Skip + "id": 524293, // [SpecialFunction] Bomb Slot Cinematic Skip "type": "CinematicSkip" }, { - "id": 524296, // [SpecialFunction] SpecialFunction Cinematic Skip + "id": 524296, // [SpecialFunction] Wall Destruction Cinematic Skip "type": "CinematicSkip" }, { - "id": 524300, // [SpecialFunction] SpecialFunction Cinematic Skip + "id": 524300, // [SpecialFunction] Ice Melting Cinematic Skip "type": "CinematicSkip" } ] @@ -13972,7 +13960,7 @@ }, { "senderId": 131593, // [Relay] Relay One Shot Out - "targetId": 231092, // [SpecialFunction] Wall Unlock Cinematic Skip + "targetId": 131219, // [SpecialFunction] Wall Unlock Cinematic Skip "state": "ZERO", "message": "INCREMENT" }, @@ -13990,7 +13978,7 @@ }, { "senderId": 131088, // [Relay] One Shot End - "targetId": 231092, // [SpecialFunction] Wall Unlock Cinematic Skip + "targetId": 131219, // [SpecialFunction] Wall Unlock Cinematic Skip "state": "ZERO", "message": "DECREMENT" }, @@ -14001,31 +13989,31 @@ "message": "SET_TO_ZERO" }, { - "senderId": 231092, // [SpecialFunction] Wall Unlock Cinematic Skip + "senderId": 131219, // [SpecialFunction] Wall Unlock Cinematic Skip "targetId": 131088, // [Relay] One Shot End "state": "ZERO", "message": "SET_TO_ZERO" }, { - "senderId": 231092, // [SpecialFunction] Wall Unlock Cinematic Skip + "senderId": 131219, // [SpecialFunction] Wall Unlock Cinematic Skip "targetId": 131347, // [Platform] Platform_Blockage "state": "ZERO", "message": "NEXT" }, { - "senderId": 231092, // [SpecialFunction] Wall Unlock Cinematic Skip + "senderId": 131219, // [SpecialFunction] Wall Unlock Cinematic Skip "targetId": 131587, // [Timer] Timer - open spiderball hole "state": "ZERO", "message": "STOP" }, { - "senderId": 231092, // [SpecialFunction] Wall Unlock Cinematic Skip + "senderId": 131219, // [SpecialFunction] Wall Unlock Cinematic Skip "targetId": 131572, // [Camera] Cinematic Camera "state": "ZERO", "message": "DEACTIVATE" }, { - "senderId": 231092, // [SpecialFunction] Wall Unlock Cinematic Skip + "senderId": 131219, // [SpecialFunction] Wall Unlock Cinematic Skip "targetId": 131571, // [PlayerActor] PlayerActor-scan_cine_forward "state": "ZERO", "message": "DEACTIVATE" @@ -14051,7 +14039,7 @@ "layer": 4 }, { - "id": 231092, // [SpecialFunction] Wall Unlock Cinematic Skip + "id": 131219, // [SpecialFunction] Wall Unlock Cinematic Skip "type": "CinematicSkip" } ] @@ -16241,6 +16229,33 @@ } ] }, + "Save Station B": { + "addConnections": [ + { + "senderId": 262147, // [SpecialFunction] Player Exits Room + "targetId": 262262, // [SpecialFunction] SpecialFunction Cinematic Skip Load + "state": "EXITED", + "message": "DECREMENT" + }, + { + "senderId": 262147, // [SpecialFunction] Player Exits Room + "targetId": 262263, // [SpecialFunction] SpecialFunction Cinematic Skip Save + "state": "EXITED", + "message": "DECREMENT" + } + ], + "specialFunctions": [ + { + "id": 262147, // [SpecialFunction] Player Exits Room + "type": "PlayerInAreaRelay", + "position": [ + -70.700981, + -212.262238, + 0.032295 + ] + } + ] + }, "Transport to Magmoor Caverns South": { "deleteIds": [ 1900622 // [Timer] Timer - Delay End Of Cinematic @@ -19314,12 +19329,6 @@ "state": "ZERO", "message": "DEACTIVATE" }, - { - "senderId": 1441796, // [SpecialFunction] Arrival Cinematic Skip - "targetId": 1441878, // [CameraFilterKeyframe] cinema bars - "state": "ZERO", - "message": "DECREMENT" - }, { "senderId": 1441796, // [SpecialFunction] Arrival Cinematic Skip "targetId": 1441913, // [SpecialFunction] SpecialFunction - Display Billboard @@ -19421,6 +19430,7 @@ "id": 42069, // [CameraFilterKeyframe] Camera Filter Keyframe Hold Black "filterType": "Multiply", "filterShape": "Fullscreen", + "fadeOutTime": 0.5, "filterIndex": 2 } ] @@ -23149,7 +23159,7 @@ { "senderId": 852694, // [Relay] Relay One Shot Out "targetId": 852702, // [CameraFilterKeyframe] Camera Filter Keyframe Widescreen - "state": "ACTIVE", + "state": "ZERO", "message": "INCREMENT" }, { diff --git a/schema/randomprime.schema.json b/schema/randomprime.schema.json index 2ab99768..c28d2302 100644 --- a/schema/randomprime.schema.json +++ b/schema/randomprime.schema.json @@ -2804,6 +2804,8 @@ "Artifact of Nature", "Artifact of Strength", "Nothing", + "Zoomer", + "Cog", "Gamecube", "Health Refill", "Missile Refill", @@ -2861,7 +2863,7 @@ "default": false }, "liquids": { - "description": "Add liquid volumes to this room.", + "description": "Add liquid volumes to this room. The bigger their size, the bigger the `tileSize` and `tileSubdivisions` values must be in order for the liquid to render properly.", "type": "array", "items": { "type": "object", @@ -2894,6 +2896,42 @@ "scale": { "description": "The extent of the liquid volume.", "$ref": "#/$defs/vector3Positive" + }, + "morphInTime": { + "description": "Duration in which the water will be traveling to it's destination.", + "type": "number", + "minimum": 0.0, + "default": 3.0 + }, + "morphOutTime": { + "description": "Duration in which the water will be traveling back to it's source position.", + "type": "number", + "minimum": 0.0, + "default": 3.0 + }, + "tileSize": { + "description": "Specify the size of the water tiles.", + "type": "number", + "minimum": 0.0, + "default": 2.4 + }, + "tileSubdivisions": { + "description": "Specify the amount of tile subdivisions on the liquid.", + "type": "integer", + "minimum": 0, + "default": 6 + }, + "alphaInTime": { + "description": "Duration in which the water will be fading back in view.", + "type": "number", + "minimum": 0.0, + "default": 3.0 + }, + "alphaOutTime": { + "description": "Duration in which the water will be fading out of view.", + "type": "number", + "minimum": 0.0, + "default": 3.0 } }, "required": [ diff --git a/src/add_modify_obj_patches.rs b/src/add_modify_obj_patches.rs index 8a6d0b09..e96a8a25 100644 --- a/src/add_modify_obj_patches.rs +++ b/src/add_modify_obj_patches.rs @@ -329,6 +329,32 @@ pub fn patch_add_liquid<'r>( .as_mut_vec(); water_obj.property_data.as_water_mut().unwrap().active = config.active.unwrap_or(true) as u8; + water_obj + .property_data + .as_water_mut() + .unwrap() + .morph_in_time = config.morph_in_time.unwrap_or(1.0); + water_obj + .property_data + .as_water_mut() + .unwrap() + .morph_out_time = config.morph_out_time.unwrap_or(1.0); + water_obj.property_data.as_water_mut().unwrap().tile_size = config.tile_size.unwrap_or(2.4); + water_obj + .property_data + .as_water_mut() + .unwrap() + .tile_subdivisions = config.tile_subdivisions.unwrap_or(6); + water_obj + .property_data + .as_water_mut() + .unwrap() + .alpha_in_time = config.alpha_in_time.unwrap_or(3.0); + water_obj + .property_data + .as_water_mut() + .unwrap() + .alpha_out_time = config.alpha_out_time.unwrap_or(3.0); let property_data: structs::SclyProperty = water_obj.property_data; assert!(property_data.object_type() == structs::Water::OBJECT_TYPE); diff --git a/src/bin/resource_tracing.rs b/src/bin/resource_tracing.rs index 2f7125b4..9b0046b6 100644 --- a/src/bin/resource_tracing.rs +++ b/src/bin/resource_tracing.rs @@ -737,8 +737,6 @@ fn create_nothing(pickup_table: &mut HashMap) { ResourceKey::from(custom_asset_ids::NOTHING_CMDL), ResourceKey::from(custom_asset_ids::NOTHING_ANCS), ResourceKey::from(custom_asset_ids::NOTHING_TXTR), - ResourceKey::from(ResId::::new(0x2f976e86)), // Metroid - ResourceKey::from(ResId::::new(0xBE4CD99D)), // white door ]); assert!(pickup_table .insert( @@ -752,6 +750,84 @@ fn create_nothing(pickup_table: &mut HashMap) { .is_none()); } +fn create_zoomer(pickup_table: &mut HashMap) { + let mut bytes = Vec::new(); + { + let mut pickup: structs::Pickup = + Reader::new(&pickup_table[&PickupModel::PhazonSuit].bytes) + .read::(()) + .clone(); + pickup.name = Cow::Borrowed(CStr::from_bytes_with_nul(b"Zoomer\0").unwrap()); + pickup.kind = PickupType::Missile.kind(); + pickup.max_increase = 0; + pickup.curr_increase = 0; + pickup.cmdl = custom_asset_ids::ZOOMER_CMDL; + pickup.ancs.file_id = custom_asset_ids::ZOOMER_ANCS; + pickup.part = ResId::::invalid(); + pickup.write_to(&mut bytes).unwrap(); + } + let mut deps: HashSet<_> = pickup_table[&PickupModel::PhazonSuit] + .deps + .iter() + .filter(|i| ![b"SCAN".into(), b"STRG".into(), b"CMDL".into()].contains(&i.fourcc)) + .cloned() + .collect(); + deps.extend(&[ + ResourceKey::from(custom_asset_ids::ZOOMER_CMDL), + ResourceKey::from(custom_asset_ids::ZOOMER_ANCS), + ResourceKey::from(custom_asset_ids::NOTHING_TXTR), + ]); + assert!(pickup_table + .insert( + PickupModel::Zoomer, + PickupData { + bytes, + deps, + attainment_audio_file_name: b"/audio/itm_x_short_02.dsp\0".to_vec(), + } + ) + .is_none()); +} + +fn create_cog(pickup_table: &mut HashMap) { + let mut bytes = Vec::new(); + { + let mut pickup: structs::Pickup = + Reader::new(&pickup_table[&PickupModel::PhazonSuit].bytes) + .read::(()) + .clone(); + pickup.name = Cow::Borrowed(CStr::from_bytes_with_nul(b"Cog\0").unwrap()); + pickup.kind = PickupType::Missile.kind(); + pickup.max_increase = 0; + pickup.curr_increase = 0; + pickup.cmdl = custom_asset_ids::COG_CMDL; + pickup.ancs.file_id = custom_asset_ids::COG_ANCS; + pickup.part = ResId::::invalid(); + pickup.write_to(&mut bytes).unwrap(); + } + let mut deps: HashSet<_> = pickup_table[&PickupModel::PhazonSuit] + .deps + .iter() + .filter(|i| ![b"SCAN".into(), b"STRG".into(), b"CMDL".into()].contains(&i.fourcc)) + .cloned() + .collect(); + deps.extend(&[ + ResourceKey::from(custom_asset_ids::COG_CMDL), + ResourceKey::from(custom_asset_ids::COG_ANCS), + ResourceKey::new(0x50DF3CAD, b"TXTR".into()), + ]); + assert!(pickup_table + .insert( + PickupModel::Cog, + PickupData { + bytes, + deps, + attainment_audio_file_name: b"/audio/itm_x_short_02.dsp\0".to_vec(), + } + ) + .is_none()); +} + fn create_gamecube(pickup_table: &mut HashMap) { let mut bytes = Vec::new(); { @@ -1458,6 +1534,20 @@ fn main() { assert!(cmdl_aabbs .insert(custom_asset_ids::NOTHING_CMDL, suit_aabb) .is_none()); + assert!(cmdl_aabbs + .insert(custom_asset_ids::ZOOMER_CMDL, suit_aabb) + .is_none()); + let cog_aabb = [ + suit_aabb[0], + suit_aabb[1], + suit_aabb[2] + 0.5, + suit_aabb[3], + suit_aabb[4], + suit_aabb[5] + 0.5, + ]; + assert!(cmdl_aabbs + .insert(custom_asset_ids::COG_CMDL, cog_aabb) + .is_none()); let missile_aabb = *cmdl_aabbs .get(&ResId::::new( @@ -1485,6 +1575,8 @@ fn main() { create_gamecube(&mut pickup_table); create_nothing(&mut pickup_table); + create_zoomer(&mut pickup_table); + create_cog(&mut pickup_table); create_shiny_missile(&mut pickup_table); create_thermal_visor(&mut pickup_table); create_xray_visor(&mut pickup_table); diff --git a/src/custom_assets.rs b/src/custom_assets.rs index 51e5164a..ba8fc84a 100644 --- a/src/custom_assets.rs +++ b/src/custom_assets.rs @@ -61,6 +61,10 @@ pub mod custom_asset_ids { NOTHING_TXTR: TXTR, NOTHING_CMDL: CMDL, NOTHING_ANCS: ANCS, + ZOOMER_CMDL: CMDL, + ZOOMER_ANCS: ANCS, + COG_CMDL: CMDL, + COG_ANCS: ANCS, THERMAL_CMDL: CMDL, THERMAL_ANCS: ANCS, XRAY_CMDL: CMDL, @@ -650,6 +654,17 @@ pub fn custom_assets<'r>( custom_asset_ids::NOTHING_TXTR, ResId::::new(0xF68DF7F1), )); + assets.extend_from_slice(&create_zoomer_cmdl_and_ancs( + resources, + custom_asset_ids::ZOOMER_CMDL, + custom_asset_ids::ZOOMER_ANCS, + custom_asset_ids::NOTHING_TXTR, + )); + assets.extend_from_slice(&create_cog_cmdl_and_ancs( + resources, + custom_asset_ids::COG_CMDL, + custom_asset_ids::COG_ANCS, + )); assets.extend_from_slice(&create_randovania_gamecube_cmdl_and_ancs( resources, custom_asset_ids::RANDOVANIA_GAMECUBE_CMDL, @@ -705,7 +720,7 @@ pub fn custom_assets<'r>( vec![ "Toaster's Champions: Awp82, DiggleWrath, Yeti2000, freak532486, AlphaRage, Csabi,\0".to_string(), "\0".to_string(), - "BajaBlood, hammergoboom, Firemetroid, Lokir, MeriKatt, Cosmonawt, Haldadrin, RXM, Schwartz, Samuel, Miguel, chliu\0".to_string(), + "BajaBlood, hammergoboom, Firemetroid, Lokir, MeriKatt, Cosmonawt, Haldadrin, RXM, Schwartz, Samuel, Miguel, chliu, JeffGainsNGames\0".to_string(), ], 1, 0, @@ -1312,8 +1327,12 @@ pub fn collect_game_resources<'r>( let orange_light: Vec<(u32, FourCC)> = vec![(0xB4A658C3, FourCC::from_bytes(b"PART"))]; looking_for.extend(orange_light); - let gamecube: Vec<(u32, FourCC)> = vec![(0x770939c0, FourCC::from_bytes(b"CMDL"))]; - looking_for.extend(gamecube); + let pickup_model_assets: Vec<(u32, FourCC)> = vec![ + (0x770939C0, FourCC::from_bytes(b"CMDL")), + (0x663E4DEB, FourCC::from_bytes(b"CMDL")), + (0x2F976E86, FourCC::from_bytes(b"CMDL")), + ]; + looking_for.extend(pickup_model_assets); let ghost_ball: Vec<(u32, FourCC)> = vec![ // used for lock on point model @@ -1643,6 +1662,78 @@ fn create_randovania_gamecube_cmdl_and_ancs<'r>( [new_cmdl, new_ancs] } +fn create_zoomer_cmdl_and_ancs<'r>( + resources: &HashMap<(u32, FourCC), structs::Resource<'r>>, + new_cmdl_id: ResId, + new_ancs_id: ResId, + new_txtr1: ResId, +) -> [structs::Resource<'r>; 2] { + let cmdl = { + let cmdl = include_bytes!("../extra_assets/zoomer.CMDL"); + let mut cmdl = Reader::new(&cmdl[..]).read::(()); + + cmdl.material_sets.as_mut_vec()[0].texture_ids.as_mut_vec()[0] = new_txtr1; + + let mut new_cmdl_bytes = vec![]; + cmdl.write_to(&mut new_cmdl_bytes).unwrap(); + + build_resource( + new_cmdl_id, + structs::ResourceKind::External(new_cmdl_bytes, b"CMDL".into()), + ) + }; + let ancs = { + let ancs = ResourceData::new(&resources[&resource_info!("Node1_11.ANCS").into()]); + let ancs_bytes = ancs.decompress().into_owned(); + let mut ancs = Reader::new(&ancs_bytes[..]).read::(()); + + ancs.char_set.char_info.as_mut_vec()[0].cmdl = new_cmdl_id; + + let mut new_ancs_bytes = vec![]; + ancs.write_to(&mut new_ancs_bytes).unwrap(); + + build_resource( + new_ancs_id, + structs::ResourceKind::External(new_ancs_bytes, b"ANCS".into()), + ) + }; + [cmdl, ancs] +} + +fn create_cog_cmdl_and_ancs<'r>( + resources: &HashMap<(u32, FourCC), structs::Resource<'r>>, + new_cmdl_id: ResId, + new_ancs_id: ResId, +) -> [structs::Resource<'r>; 2] { + let cmdl = { + let cmdl = include_bytes!("../extra_assets/cog.CMDL"); + let cmdl = Reader::new(&cmdl[..]).read::(()); + let mut bytes = vec![]; + cmdl.write_to(&mut bytes).unwrap(); + + build_resource( + new_cmdl_id, + structs::ResourceKind::External(bytes, b"CMDL".into()), + ) + }; + let ancs = { + let ancs = ResourceData::new(&resources[&resource_info!("Node1_11.ANCS").into()]); + let bytes = ancs.decompress().into_owned(); + let mut ancs = Reader::new(&bytes[..]).read::(()); + + ancs.char_set.char_info.as_mut_vec()[0].cmdl = new_cmdl_id; + + let mut bytes = vec![]; + ancs.write_to(&mut bytes).unwrap(); + + build_resource( + new_ancs_id, + structs::ResourceKind::External(bytes, b"ANCS".into()), + ) + }; + [cmdl, ancs] +} + fn create_visor_cmdl_and_ancs<'r>( resources: &HashMap<(u32, FourCC), structs::Resource<'r>>, new_cmdl_id: ResId, diff --git a/src/patch_config.rs b/src/patch_config.rs index 5c0367b9..4b122bb5 100644 --- a/src/patch_config.rs +++ b/src/patch_config.rs @@ -175,6 +175,12 @@ pub struct WaterConfig { pub liquid_type: String, pub position: [f32; 3], pub scale: [f32; 3], + pub morph_in_time: Option, + pub morph_out_time: Option, + pub tile_size: Option, + pub tile_subdivisions: Option, + pub alpha_in_time: Option, + pub alpha_out_time: Option, } #[derive(PartialEq, Debug, Serialize, Deserialize, Copy, Clone)] @@ -1370,7 +1376,9 @@ pub struct PatchConfig { pub comment: String, pub main_menu_message: String, + #[serde(skip_serializing)] // skipped for competitive integrity reasons pub credits_string: Option, + pub results_string: Option, pub artifact_hints: Option>, // e.g. "Strength":"This item can be found in Ruined Fountain" pub required_artifact_count: Option, diff --git a/src/patches.rs b/src/patches.rs index a0b0b398..94d98cd6 100644 --- a/src/patches.rs +++ b/src/patches.rs @@ -1000,7 +1000,7 @@ fn patch_door<'r>( 0x001E000B, // Biohazard Containment 0x0020000D, // Biotech Research Area 1 0x000F01D1, // Ruined Courtyard - 0x001B0088, + 0x001B0088, 0x0028005C, // Research Core ] .contains(&door_open_trigger_id); @@ -1928,11 +1928,11 @@ fn patch_door<'r>( (0xAC2C58FE, 1), // biohazard containment (0x5F2EB7B6, 1), // biotech research area 1 (0x1921876D, 3), // ruined courtyard - (0xA49B2544, 1), + (0xA49B2544, 1), // research core ] .contains(&(mrea_id, door_loc.dock_number)) { - /* Add two relays which can activated/deactivated to control which shield appears */ + /* Add two relays which can be activated/deactivated to control which shield appears */ layers[0].objects.as_mut_vec().push(structs::SclyObject { instance_id: activate_new_door_id, connections: vec![ @@ -1965,37 +1965,6 @@ fn patch_door<'r>( .into(), }); - layers[0].objects.as_mut_vec().push(structs::SclyObject { - instance_id: update_door_timer_id, - property_data: structs::Timer { - name: b"update_door_timer\0".as_cstr(), - start_time: 0.5, - max_random_add: 0.0, - looping: 0, - start_immediately: 0, - active: 1, - } - .into(), - connections: vec![ - structs::Connection { - state: structs::ConnectionState::ZERO, - message: structs::ConnectionMsg::SET_TO_ZERO, - target_object_id: activate_old_door_id, - }, - structs::Connection { - state: structs::ConnectionState::ZERO, - message: structs::ConnectionMsg::SET_TO_ZERO, - target_object_id: activate_new_door_id, - }, - structs::Connection { - state: structs::ConnectionState::ZERO, - message: structs::ConnectionMsg::ACTIVATE, - target_object_id: auto_open_relay_id, - }, - ] - .into(), - }); - layers[0].objects.as_mut_vec().push(structs::SclyObject { instance_id: activate_old_door_id, connections: vec![ @@ -2028,6 +1997,37 @@ fn patch_door<'r>( .into(), }); + layers[0].objects.as_mut_vec().push(structs::SclyObject { + instance_id: update_door_timer_id, + property_data: structs::Timer { + name: b"update_door_timer\0".as_cstr(), + start_time: 0.5, + max_random_add: 0.0, + looping: 0, + start_immediately: 0, + active: 1, + } + .into(), + connections: vec![ + structs::Connection { + state: structs::ConnectionState::ZERO, + message: structs::ConnectionMsg::SET_TO_ZERO, + target_object_id: activate_old_door_id, + }, + structs::Connection { + state: structs::ConnectionState::ZERO, + message: structs::ConnectionMsg::SET_TO_ZERO, + target_object_id: activate_new_door_id, + }, + structs::Connection { + state: structs::ConnectionState::ZERO, + message: structs::ConnectionMsg::ACTIVATE, + target_object_id: auto_open_relay_id, + }, + ] + .into(), + }); + /* Change blast shield auto-start timer behavior */ let obj = layers[blast_shield_layer_idx] .objects @@ -2083,7 +2083,7 @@ fn patch_door<'r>( 0xAC2C58FE => (Some(0x001E01DA), Some(0x001E01D8)), // biohazard containment 0x5F2EB7B6 => (Some(0x00200027), Some(0x00200025)), // biotech research area 1 0x1921876D => (Some(0x000F01D5), Some(0x000F01D6)), // ruined courtyard - 0xA49B2544 => (Some(0x0028043D), Some(0x0028043C)), // research core + 0xA49B2544 => (Some(0x0028043D), None), // research core _ => (None, None), }; @@ -2139,22 +2139,123 @@ fn patch_door<'r>( .contains(&conn.target_object_id) }); - obj.connections.as_mut_vec().push(structs::Connection { - state: structs::ConnectionState::ZERO, - message: structs::ConnectionMsg::RESET_AND_START, - target_object_id: update_door_timer_id, - }); - if mrea_id == 0xA49B2544 { // research core + + // Start with the correct door + let timer = layers[0] + .objects + .iter_mut() + .find(|obj| obj.instance_id == update_door_timer_id) + .unwrap_or_else(|| { + panic!( + "Could not find 0x{:X} in room 0x{:X}", + update_door_timer_id, mrea_id + ) + }) + .property_data + .as_timer_mut() + .unwrap(); + timer.start_immediately = 1; + + // When the outage happens, deactivate both doors + let obj = layers[0] + .objects + .iter_mut() + .find(|obj| obj.instance_id == 0x0028043C) + .unwrap_or_else(|| { + panic!("Could not find 0x0028043C in room 0x{:X}", mrea_id) + }); + + obj.connections.as_mut_vec().extend_from_slice(&[ + structs::Connection { + state: structs::ConnectionState::ZERO, + message: structs::ConnectionMsg::DEACTIVATE, + target_object_id: door_shield_id, + }, + structs::Connection { + state: structs::ConnectionState::ZERO, + message: structs::ConnectionMsg::DEACTIVATE, + target_object_id: door_force_id, + }, + structs::Connection { + state: structs::ConnectionState::ZERO, + message: structs::ConnectionMsg::DEACTIVATE, + target_object_id: existing_door_shield_id, + }, + structs::Connection { + state: structs::ConnectionState::ZERO, + message: structs::ConnectionMsg::DEACTIVATE, + target_object_id: existing_door_force_id, + }, + structs::Connection { + state: structs::ConnectionState::ZERO, + message: structs::ConnectionMsg::DEACTIVATE, + target_object_id: auto_open_relay_id, + }, + structs::Connection { + state: structs::ConnectionState::ZERO, + message: structs::ConnectionMsg::DEACTIVATE, + target_object_id: 0x0028005C, // door open trigger + }, + ]); + + let obj = layers[0] + .objects + .iter_mut() + .find(|obj| obj.instance_id == update_door_timer_id) + .unwrap_or_else(|| { + panic!( + "Could not find update_door_timer_id in room 0x{:X}", + mrea_id + ) + }); + obj.connections + .as_mut_vec() + .retain(|conn| conn.target_object_id != auto_open_relay_id); + + // The thermal conduit re-activates the appropriate door let obj = layers[0] .objects .iter_mut() .find(|obj| obj.instance_id == 0x0028043F) - .expect("Could not find conduit damageable trigger in research core"); + .unwrap_or_else(|| { + panic!("Could not find 0x0028043F in room 0x{:X}", mrea_id) + }); + obj.connections.as_mut_vec().extend_from_slice(&[ + structs::Connection { + state: structs::ConnectionState::DEAD, + message: structs::ConnectionMsg::RESET_AND_START, + target_object_id: update_door_timer_id, + }, + structs::Connection { + state: structs::ConnectionState::ZERO, + message: structs::ConnectionMsg::ACTIVATE, + target_object_id: auto_open_relay_id, + }, + ]); + // Keep dt and force shield in sync + let obj = layers[0] + .objects + .iter_mut() + .find(|obj| obj.instance_id == existing_door_force_id) + .unwrap_or_else(|| { + panic!( + "Could not find existing_door_force_id in room 0x{:X}", + mrea_id + ) + }); + obj.connections + .as_mut_vec() + .extend_from_slice(&[structs::Connection { + state: structs::ConnectionState::ACTIVE, + message: structs::ConnectionMsg::ACTIVATE, + target_object_id: existing_door_shield_id, + }]); + } else { obj.connections.as_mut_vec().push(structs::Connection { - state: structs::ConnectionState::DEAD, + state: structs::ConnectionState::ZERO, message: structs::ConnectionMsg::RESET_AND_START, target_object_id: update_door_timer_id, }); @@ -2214,6 +2315,17 @@ fn patch_door<'r>( }, ]); + if mrea_id == 0xA49B2544 { + new_door_force + .connections + .as_mut_vec() + .extend_from_slice(&[structs::Connection { + state: structs::ConnectionState::ACTIVE, + message: structs::ConnectionMsg::ACTIVATE, + target_object_id: door_shield_id, + }]); + } + new_door_force_data.pattern_txtr0 = door_type_after_open.pattern0_txtr(); new_door_force_data.pattern_txtr1 = door_type_after_open.pattern1_txtr(); new_door_force_data.color_txtr = door_type_after_open.color_txtr(); @@ -3101,7 +3213,7 @@ fn patch_remove_water( #[derive(Copy, Clone, Debug)] pub enum WaterType { Normal, - Poision, + Poison, Lava, Phazon, } @@ -3110,7 +3222,7 @@ impl WaterType { pub fn iter() -> impl Iterator { [ WaterType::Normal, - WaterType::Poision, + WaterType::Poison, WaterType::Lava, WaterType::Phazon, ] @@ -3124,7 +3236,7 @@ impl WaterType { if string == "water" || string == "normal" { WaterType::Normal } else if string == "poison" || string == "acid" { - WaterType::Poision + WaterType::Poison } else if string == "lava" || string == "magma" { WaterType::Lava } else if string == "phazon" { @@ -3139,18 +3251,21 @@ impl WaterType { let water = water_obj.property_data.as_water().unwrap(); let mut deps: Vec<(u32, FourCC)> = vec![ - (water.txtr1, FourCC::from_bytes(b"TXTR")), - (water.txtr2, FourCC::from_bytes(b"TXTR")), - (water.txtr3, FourCC::from_bytes(b"TXTR")), - (water.txtr4, FourCC::from_bytes(b"TXTR")), - (water.refl_map_txtr, FourCC::from_bytes(b"TXTR")), - (water.txtr6, FourCC::from_bytes(b"TXTR")), - (water.lightmap_txtr, FourCC::from_bytes(b"TXTR")), - (water.small_enter_part, FourCC::from_bytes(b"PART")), - (water.med_enter_part, FourCC::from_bytes(b"PART")), - (water.large_enter_part, FourCC::from_bytes(b"PART")), - (water.part4, FourCC::from_bytes(b"PART")), - (water.part5, FourCC::from_bytes(b"PART")), + (water.pattern_map_1, FourCC::from_bytes(b"TXTR")), + (water.pattern_map_2, FourCC::from_bytes(b"TXTR")), + (water.color_map, FourCC::from_bytes(b"TXTR")), + (water.bump_map, FourCC::from_bytes(b"TXTR")), + (water.env_map, FourCC::from_bytes(b"TXTR")), + (water.env_bump_map, FourCC::from_bytes(b"TXTR")), + (water.lightmap, FourCC::from_bytes(b"TXTR")), + (water.splash_particle_1, FourCC::from_bytes(b"PART")), + (water.splash_particle_2, FourCC::from_bytes(b"PART")), + (water.splash_particle_3, FourCC::from_bytes(b"PART")), + (water.visor_runoff_particle, FourCC::from_bytes(b"PART")), + ( + water.unmorph_visor_runoff_particle, + FourCC::from_bytes(b"PART"), + ), ]; deps.retain(|i| i.0 != 0xffffffff && i.0 != 0); deps @@ -3171,94 +3286,94 @@ impl WaterType { radius: 0.0, knockback_power: 0.0, }, - unknown1: [0.0, 0.0, 0.0].into(), - unknown2: 2047, - unknown3: 0, - display_fluid_surface: 1, - txtr1: 2837040919, - txtr2: 2565985674, - txtr3: 3001645351, - txtr4: 4294967295, - refl_map_txtr: 4294967295, - txtr6: 1899158552, - unknown5: [3.0, 3.0, -1.0].into(), - unknown6: 35.0, + force: [0.0, 0.0, 0.0].into(), + flags: 2047, + thermal_cold: 0, + display_surface: 1, + pattern_map_1: 2837040919, + pattern_map_2: 2565985674, + color_map: 3001645351, + bump_map: 4294967295, + env_map: 4294967295, + env_bump_map: 1899158552, + bump_map_dir: [3.0, 3.0, -1.0].into(), + bump_scale: 35.0, morph_in_time: 5.0, morph_out_time: 5.0, active: 1, fluid_type: 0, - unknown11: 0, - unknown12: 0.65, + unknown1: 0, + alpha: 0.65, fluid_uv_motion: structs::FluidUVMotion { fluid_layer_motion1: structs::FluidLayerMotion { fluid_uv_motion: 0, - unknown1: 20.0, - unknown2: 0.0, - unknown3: 0.15, - unknown4: 20.0, + time_to_wrap: 20.0, + orientation: 0.0, + magnitude: 0.15, + multiplication: 20.0, }, fluid_layer_motion2: structs::FluidLayerMotion { fluid_uv_motion: 0, - unknown1: 15.0, - unknown2: 0.0, - unknown3: 0.15, - unknown4: 10.0, + time_to_wrap: 15.0, + orientation: 0.0, + magnitude: 0.15, + multiplication: 10.0, }, fluid_layer_motion3: structs::FluidLayerMotion { fluid_uv_motion: 0, - unknown1: 30.0, - unknown2: 0.0, - unknown3: 0.15, - unknown4: 20.0, + time_to_wrap: 30.0, + orientation: 0.0, + magnitude: 0.15, + multiplication: 20.0, }, - unknown1: 70.0, - unknown2: 0.0, + time_to_wrap: 70.0, + orientation: 0.0, }, - unknown30: 0.0, - unknown31: 10.0, - unknown32: 1.0, - unknown33: 1.0, - unknown34: 0.0, - unknown35: 90.0, - unknown36: 0.0, - unknown37: 0.0, - unknown38: [1.0, 1.0, 1.0, 1.0].into(), - unknown39: [0.443137, 0.568627, 0.623529, 1.0].into(), - small_enter_part: 0xffffffff, - med_enter_part: 0xffffffff, - large_enter_part: 0xffffffff, - part4: 0xffffffff, - part5: 0xffffffff, - sound1: 2499, - sound2: 2499, - sound3: 463, - sound4: 464, - sound5: 465, - unknown40: 2.4, - unknown41: 6, - unknown42: 0.0, - unknown43: 1.0, - unknown44: 0.5, - unknown45: 0.8, - unknown46: 0.5, - unknown47: 0.0, - heat_wave_height: 0.0, - heat_wave_speed: 1.0, - heat_wave_color: [1.0, 1.0, 1.0, 1.0].into(), - lightmap_txtr: 231856622, - unknown51: 0.3, - alpha_in_time: 5.0, - alpha_out_time: 5.0, - unknown54: 0, - unknown55: 0, - crash_the_game: 0, + turb_speed: 20.0, + turb_distance: 100.0, + turb_frequence_max: 1.0, + turb_frequence_min: 3.0, + turb_phase_max: 0.0, + turb_phase_min: 90.0, + turb_amplitude_max: 0.0, + turb_amplitude_min: 0.0, + splash_color: [1.0, 1.0, 1.0, 1.0].into(), + inside_fog_color: [0.443137, 0.568627, 0.623529, 1.0].into(), + splash_particle_1: 1688698462, + splash_particle_2: 678723448, + splash_particle_3: 1571480382, + visor_runoff_particle: 1859537006, + unmorph_visor_runoff_particle: 1390596347, + visor_runoff_sound: 2499, + unmorph_visor_runoff_sound: 2499, + splash_sfx_1: 463, + splash_sfx_2: 464, + splash_sfx_3: 465, + tile_size: 2.4, + tile_subdivisions: 6, + specular_min: 0.0, + specular_max: 1.0, + reflection_size: 0.5, + ripple_intensity: 0.8, + reflection_blend: 0.5, + fog_bias: 0.0, + fog_magnitude: 0.0, + fog_speed: 1.0, + fog_color: [1.0, 1.0, 1.0, 1.0].into(), + lightmap: 4294967295, + units_per_lightmap_texel: 2.3, + alpha_in_time: 1.0, + alpha_out_time: 1.0, + unknown2: 0, + unknown3: 0, + unknown4: 0, })), }, - WaterType::Poision => structs::SclyObject { + WaterType::Poison => structs::SclyObject { instance_id: 0xFFFFFFFF, connections: vec![].into(), property_data: structs::SclyProperty::Water(Box::new(structs::Water { - name: b"poision water\0".as_cstr(), + name: b"poison water\0".as_cstr(), position: [405.3748, -43.92318, 10.530313].into(), scale: [13.0, 30.0, 1.0].into(), damage_info: structs::scly_structs::DamageInfo { @@ -3267,87 +3382,87 @@ impl WaterType { radius: 0.0, knockback_power: 0.0, }, - unknown1: [0.0, 0.0, 0.0].into(), - unknown2: 2047, - unknown3: 0, - display_fluid_surface: 1, - txtr1: 2671389366, - txtr2: 430856216, - txtr3: 1337209902, - txtr4: 4294967295, - refl_map_txtr: 4294967295, - txtr6: 1899158552, - unknown5: [3.0, 3.0, -4.0].into(), - unknown6: 48.0, + force: [0.0, 0.0, 0.0].into(), + flags: 2047, + thermal_cold: 0, + display_surface: 1, + pattern_map_1: 2671389366, + pattern_map_2: 430856216, + color_map: 1337209902, + bump_map: 4294967295, + env_map: 4294967295, + env_bump_map: 1899158552, + bump_map_dir: [3.0, 3.0, -4.0].into(), + bump_scale: 48.0, morph_in_time: 5.0, morph_out_time: 5.0, active: 1, fluid_type: 1, - unknown11: 0, - unknown12: 0.8, + unknown1: 0, + alpha: 0.8, fluid_uv_motion: structs::FluidUVMotion { fluid_layer_motion1: structs::FluidLayerMotion { fluid_uv_motion: 0, - unknown1: 20.0, - unknown2: 0.0, - unknown3: 0.15, - unknown4: 20.0, + time_to_wrap: 20.0, + orientation: 0.0, + magnitude: 0.15, + multiplication: 20.0, }, fluid_layer_motion2: structs::FluidLayerMotion { fluid_uv_motion: 0, - unknown1: 10.0, - unknown2: 180.0, - unknown3: 0.15, - unknown4: 10.0, + time_to_wrap: 10.0, + orientation: 180.0, + magnitude: 0.15, + multiplication: 10.0, }, fluid_layer_motion3: structs::FluidLayerMotion { fluid_uv_motion: 0, - unknown1: 40.0, - unknown2: 0.0, - unknown3: 0.15, - unknown4: 25.0, + time_to_wrap: 40.0, + orientation: 0.0, + magnitude: 0.15, + multiplication: 25.0, }, - unknown1: 100.0, - unknown2: 0.0, + time_to_wrap: 100.0, + orientation: 0.0, }, - unknown30: 20.0, - unknown31: 100.0, - unknown32: 1.0, - unknown33: 3.0, - unknown34: 0.0, - unknown35: 90.0, - unknown36: 0.0, - unknown37: 0.0, - unknown38: [1.0, 1.0, 1.0, 1.0].into(), - unknown39: [0.619608, 0.705882, 0.560784, 1.0].into(), - small_enter_part: 0xffffffff, - med_enter_part: 0xffffffff, - large_enter_part: 0xffffffff, - part4: 0xffffffff, - part5: 0xffffffff, - sound1: 2499, - sound2: 2499, - sound3: 463, - sound4: 464, - sound5: 465, - unknown40: 2.4, - unknown41: 6, - unknown42: 0.0, - unknown43: 1.0, - unknown44: 0.5, - unknown45: 0.8, - unknown46: 1.0, - unknown47: 0.0, - heat_wave_height: 0.0, - heat_wave_speed: 1.0, - heat_wave_color: [0.784314, 1.0, 0.27451, 1.0].into(), - lightmap_txtr: 1723170806, - unknown51: 0.3, - alpha_in_time: 5.0, - alpha_out_time: 5.0, - unknown54: 0, - unknown55: 0, - crash_the_game: 0, + turb_speed: 20.0, + turb_distance: 100.0, + turb_frequence_max: 1.0, + turb_frequence_min: 3.0, + turb_phase_max: 0.0, + turb_phase_min: 90.0, + turb_amplitude_max: 0.0, + turb_amplitude_min: 0.0, + splash_color: [1.0, 1.0, 1.0, 1.0].into(), + inside_fog_color: [0.619608, 0.705882, 0.560784, 1.0].into(), + splash_particle_1: 2237216893, + splash_particle_2: 4804096, + splash_particle_3: 3159663901, + visor_runoff_particle: 1859537006, + unmorph_visor_runoff_particle: 1390596347, + visor_runoff_sound: 2499, + unmorph_visor_runoff_sound: 2499, + splash_sfx_1: 463, + splash_sfx_2: 464, + splash_sfx_3: 465, + tile_size: 2.4, + tile_subdivisions: 6, + specular_min: 0.0, + specular_max: 1.0, + reflection_size: 0.5, + ripple_intensity: 0.8, + reflection_blend: 1.0, + fog_bias: 0.0, + fog_magnitude: 0.0, + fog_speed: 1.0, + fog_color: [0.784314, 1.0, 0.27451, 1.0].into(), + lightmap: 4294967295, + units_per_lightmap_texel: 0.5, + alpha_in_time: 1.0, + alpha_out_time: 1.0, + unknown2: 0, + unknown3: 0, + unknown4: 0, })), }, WaterType::Lava => structs::SclyObject { @@ -3363,87 +3478,87 @@ impl WaterType { radius: 0.0, knockback_power: 0.0, }, - unknown1: [0.0, 0.0, 0.0].into(), - unknown2: 2047, - unknown3: 1, - display_fluid_surface: 1, - txtr1: 117134624, - txtr2: 2154768270, - txtr3: 3598011320, - txtr4: 1249771730, - refl_map_txtr: 4294967295, - txtr6: 4294967295, - unknown5: [3.0, 3.0, -4.0].into(), - unknown6: 70.0, - morph_in_time: 5.0, - morph_out_time: 5.0, + force: [0.0, 0.0, 0.0].into(), + flags: 2047, + thermal_cold: 1, + display_surface: 1, + pattern_map_1: 117134624, + pattern_map_2: 2154768270, + color_map: 3598011320, + bump_map: 1249771730, + env_map: 4294967295, + env_bump_map: 4294967295, + bump_map_dir: [3.0, 3.0, -4.0].into(), + bump_scale: 70.0, + morph_in_time: 15.0, + morph_out_time: 15.0, active: 1, fluid_type: 2, - unknown11: 0, - unknown12: 0.65, + unknown1: 0, + alpha: 0.65, fluid_uv_motion: structs::FluidUVMotion { fluid_layer_motion1: structs::FluidLayerMotion { fluid_uv_motion: 0, - unknown1: 30.0, - unknown2: 0.0, - unknown3: 0.15, - unknown4: 10.0, + time_to_wrap: 30.0, + orientation: 0.0, + magnitude: 0.15, + multiplication: 10.0, }, fluid_layer_motion2: structs::FluidLayerMotion { fluid_uv_motion: 0, - unknown1: 40.0, - unknown2: 180.0, - unknown3: 0.15, - unknown4: 20.0, + time_to_wrap: 40.0, + orientation: 180.0, + magnitude: 0.15, + multiplication: 20.0, }, fluid_layer_motion3: structs::FluidLayerMotion { fluid_uv_motion: 0, - unknown1: 45.0, - unknown2: 0.0, - unknown3: 0.15, - unknown4: 10.0, + time_to_wrap: 45.0, + orientation: 0.0, + magnitude: 0.15, + multiplication: 10.0, }, - unknown1: 70.0, - unknown2: 0.0, + time_to_wrap: 70.0, + orientation: 0.0, }, - unknown30: 20.0, - unknown31: 100.0, - unknown32: 1.0, - unknown33: 3.0, - unknown34: 0.0, - unknown35: 90.0, - unknown36: 0.0, - unknown37: 0.0, - unknown38: [1.0, 1.0, 1.0, 1.0].into(), - unknown39: [0.631373, 0.270588, 0.270588, 1.0].into(), - small_enter_part: 0xffffffff, - med_enter_part: 0xffffffff, - large_enter_part: 0xffffffff, - part4: 0xffffffff, - part5: 0xffffffff, - sound1: 2412, - sound2: 2412, - sound3: 1373, - sound4: 1374, - sound5: 1375, - unknown40: 2.4, - unknown41: 6, - unknown42: 0.0, - unknown43: 1.0, - unknown44: 0.5, - unknown45: 0.8, - unknown46: 0.5, - unknown47: 1.7, - heat_wave_height: 1.2, - heat_wave_speed: 1.0, - heat_wave_color: [1.0, 0.682353, 0.294118, 1.0].into(), - lightmap_txtr: 4294967295, - unknown51: 0.3, - alpha_in_time: 5.0, - alpha_out_time: 5.0, - unknown54: 4294967295, - unknown55: 4294967295, - crash_the_game: 0, + turb_speed: 20.0, + turb_distance: 100.0, + turb_frequence_max: 1.0, + turb_frequence_min: 3.0, + turb_phase_max: 0.0, + turb_phase_min: 90.0, + turb_amplitude_max: 0.0, + turb_amplitude_min: 0.0, + splash_color: [1.0, 1.0, 1.0, 1.0].into(), + inside_fog_color: [0.631373, 0.270588, 0.270588, 1.0].into(), + splash_particle_1: 1773746298, + splash_particle_2: 343573999, + splash_particle_3: 1354016026, + visor_runoff_particle: 3917594797, + unmorph_visor_runoff_particle: 1390596347, + visor_runoff_sound: 2412, + unmorph_visor_runoff_sound: 2412, + splash_sfx_1: 1373, + splash_sfx_2: 1374, + splash_sfx_3: 1375, + tile_size: 2.4, + tile_subdivisions: 6, + specular_min: 0.0, + specular_max: 1.0, + reflection_size: 0.5, + ripple_intensity: 0.8, + reflection_blend: 0.5, + fog_bias: 1.7, + fog_magnitude: 1.2, + fog_speed: 1.0, + fog_color: [1.0, 0.682353, 0.294118, 1.0].into(), + lightmap: 4294967295, + units_per_lightmap_texel: 0.3, + alpha_in_time: 1.0, + alpha_out_time: 1.0, + unknown2: 4294967295, + unknown3: 4294967295, + unknown4: 0, })), }, WaterType::Phazon => { @@ -8017,51 +8132,37 @@ fn patch_ruined_courtyard_thermal_conduits( area: &mut mlvl_wrapper::MlvlArea, version: Version, ) -> Result<(), String> { - let scly = area.mrea().scly_section_mut(); - let layer = &mut scly.layers.as_mut_vec()[0]; - let thermal_conduit_damageable_trigger_obj_id = 0xF01C8; - let thermal_conduit_actor_obj_id = 0xF01C7; - let debris_generator_obj_id = 0xF01DD; - let thermal_conduit_cover_actor_obj_id = 0xF01D9; - - layer - .objects - .as_mut_vec() + let layer = area + .mrea() + .scly_section_mut() + .layers .iter_mut() - .find(|obj| obj.instance_id == thermal_conduit_damageable_trigger_obj_id) - .and_then(|obj| obj.property_data.as_damageable_trigger_mut()) - .unwrap() - .active = 1; + .next() + .unwrap(); if version == Version::NtscU0_02 { - layer - .objects - .as_mut_vec() + let objects = layer.objects.as_mut_vec(); + // Thermal Conduit Actor + objects .iter_mut() - .find(|obj| obj.instance_id == thermal_conduit_actor_obj_id) + .find(|obj: &&mut structs::SclyObject| obj.instance_id & 0x00FFFFFF == 0xF01C7) .and_then(|obj| obj.property_data.as_actor_mut()) .unwrap() .active = 1; + + // Damageable Trigger Activation Relay + objects + .iter_mut() + .find(|obj| obj.instance_id & 0x00FFFFFF == 0xF0312) + .and_then(|obj| obj.property_data.as_relay_mut()) + .unwrap() + .active = 1; } else if version == Version::NtscJ || version == Version::Pal || version == Version::NtscUTrilogy || version == Version::NtscJTrilogy || version == Version::PalTrilogy { - layer - .objects - .as_mut_vec() - .iter_mut() - .find(|obj| obj.instance_id == debris_generator_obj_id) - .unwrap() - .connections - .as_mut_vec() - .push(structs::Connection { - state: structs::ConnectionState::ZERO, - message: structs::ConnectionMsg::DEACTIVATE, - target_object_id: thermal_conduit_cover_actor_obj_id, - }); - let flags = &mut area.layer_flags.flags; *flags |= 1 << 6; // Turn on "Thermal Target" } @@ -8681,11 +8782,7 @@ fn patch_remove_cutscenes( Ok(()) } -/** - * Patch is actually for QAA - * - */ -fn patch_fix_central_dynamo_crash( +fn patch_purge_debris_extended( _ps: &mut PatcherState, area: &mut mlvl_wrapper::MlvlArea, ) -> Result<(), String> { @@ -8694,12 +8791,188 @@ fn patch_fix_central_dynamo_crash( layer .objects .as_mut_vec() - .retain(|obj| ![0x45].contains(&obj.property_data.object_type())); + .retain(|obj| !obj.property_data.is_debris_extended()); } Ok(()) } +fn patch_fix_deck_beta_security_hall_crash( + _ps: &mut PatcherState, + area: &mut mlvl_wrapper::MlvlArea, +) -> Result<(), String> { + let trigger1_id = area.new_object_id_from_layer_id(0); + let trigger2_id = area.new_object_id_from_layer_id(0); + + let scly = area.mrea().scly_section_mut(); + let objects = scly.layers.as_mut_vec()[0].objects.as_mut_vec(); + + // Insert our own load triggers + objects.extend_from_slice(&[ + structs::SclyObject { + instance_id: trigger1_id, + property_data: structs::Trigger { + name: b"Trigger\0".as_cstr(), + position: [-86.4, 265.1, -67.6].into(), + scale: [10.0, 5.0, 10.0].into(), + damage_info: structs::scly_structs::DamageInfo { + weapon_type: 0, + damage: 0.0, + radius: 0.0, + knockback_power: 0.0, + }, + force: [0.0, 0.0, 0.0].into(), + flags: 1, + active: 1, + deactivate_on_enter: 0, + deactivate_on_exit: 0, + } + .into(), + connections: vec![ + structs::Connection { + state: structs::ConnectionState::ENTERED, + message: structs::ConnectionMsg::SET_TO_ZERO, + target_object_id: 0x001F0001, + }, + structs::Connection { + state: structs::ConnectionState::ENTERED, + message: structs::ConnectionMsg::SET_TO_MAX, + target_object_id: 0x001F0002, + }, + ] + .into(), + }, + structs::SclyObject { + instance_id: trigger2_id, + property_data: structs::Trigger { + name: b"Trigger\0".as_cstr(), + position: [-94.5, 272.3, -68.6].into(), + scale: [5.0, 10.0, 10.0].into(), + damage_info: structs::scly_structs::DamageInfo { + weapon_type: 0, + damage: 0.0, + radius: 0.0, + knockback_power: 0.0, + }, + force: [0.0, 0.0, 0.0].into(), + flags: 1, + active: 1, + deactivate_on_enter: 0, + deactivate_on_exit: 0, + } + .into(), + connections: vec![ + structs::Connection { + state: structs::ConnectionState::ENTERED, + message: structs::ConnectionMsg::SET_TO_ZERO, + target_object_id: 0x001F0002, + }, + structs::Connection { + state: structs::ConnectionState::ENTERED, + message: structs::ConnectionMsg::SET_TO_MAX, + target_object_id: 0x001F0001, + }, + ] + .into(), + }, + ]); + + // Disable auto-loading of adjacent rooms + for obj in objects { + if let Some(dock) = obj.property_data.as_dock_mut() { + dock.load_connected = 0; + } + } + + Ok(()) +} + +fn patch_fix_central_dynamo_crash( + _ps: &mut PatcherState, + area: &mut mlvl_wrapper::MlvlArea, +) -> Result<(), String> { + let timer_id = area.new_object_id_from_layer_id(0); + + let scly = area.mrea().scly_section_mut(); + let objects = scly.layers.as_mut_vec()[0].objects.as_mut_vec(); + + // Decouple door-unlocking from maze disabling + let obj = objects + .iter_mut() + .find(|obj| obj.instance_id == 0x001B03FA) // Deactivate Maze Relay + .unwrap(); + obj.connections + .as_mut_vec() + .retain(|conn| conn.target_object_id != 0x001B065E); // Activate Rooms Relay + + // Always close the maze entrance when disabling the maze walls + obj.connections.as_mut_vec().push(structs::Connection { + state: structs::ConnectionState::ZERO, + message: structs::ConnectionMsg::ACTIVATE, + target_object_id: 0x001B02F2, // Maze Entrance Door + }); + + // Disallow the deactivation of the maze until it's actually enabled + objects.push(structs::SclyObject { + instance_id: timer_id, + property_data: structs::Timer { + name: b"my timer\0".as_cstr(), + start_time: 0.04, // but only after a couple of frames because of the memory relay + max_random_add: 0.0, + looping: 0, + start_immediately: 1, + active: 1, + } + .into(), + connections: vec![structs::Connection { + target_object_id: 0x001B03FA, // Deactivate Maze Relay + state: structs::ConnectionState::ZERO, + message: structs::ConnectionMsg::DEACTIVATE, + }] + .into(), + }); + + // Have the pickup unlock the doors instead of maze deactivation + let obj = objects + .iter_mut() + .find(|obj| obj.instance_id == 0x001B04B1) // Pickup + .unwrap(); + obj.connections.as_mut_vec().push(structs::Connection { + state: structs::ConnectionState::ARRIVED, + message: structs::ConnectionMsg::SET_TO_ZERO, + target_object_id: 0x001B065E, // Activate Rooms Relay + }); + + // Re-allow deactivation of the maze once it's actually activated + let obj = objects + .iter_mut() + .find(|obj| obj.instance_id == 0x001B0305) // Pop Foot Relay + .unwrap(); + obj.connections.as_mut_vec().push(structs::Connection { + state: structs::ConnectionState::ZERO, + message: structs::ConnectionMsg::ACTIVATE, + target_object_id: 0x001B03FA, // Deactivate Maze Relay + }); + + // Whenever the door to QAA is interacted with, attempt to disable the maze + let obj = objects + .iter_mut() + .find(|obj| obj.instance_id == 0x001B0474) // Door to QAA + .unwrap(); + obj.connections.as_mut_vec().push(structs::Connection { + state: structs::ConnectionState::OPEN, + message: structs::ConnectionMsg::SET_TO_ZERO, + target_object_id: 0x001B03FA, // Deactivate Maze Relay + }); + obj.connections.as_mut_vec().push(structs::Connection { + state: structs::ConnectionState::CLOSED, + message: structs::ConnectionMsg::SET_TO_ZERO, + target_object_id: 0x001B03FA, // Deactivate Maze Relay + }); + + Ok(()) +} + fn patch_main_quarry_door_lock_pal( _ps: &mut PatcherState, area: &mut mlvl_wrapper::MlvlArea, @@ -13921,12 +14194,24 @@ fn patch_qol_game_breaking( ) { // Crashes patcher.add_scly_patch( - resource_info!("00j_mines_connect.MREA").into(), + resource_info!("07_mines_electric.MREA").into(), patch_fix_central_dynamo_crash, ); patcher.add_scly_patch( - resource_info!("05_under_intro_zoo.MREA").into(), // stop crashing from too much stuff in biohazard containment + our patches - patch_fix_central_dynamo_crash, + resource_info!("07_mines_electric.MREA").into(), + patch_purge_debris_extended, + ); + patcher.add_scly_patch( + resource_info!("00j_mines_connect.MREA").into(), + patch_purge_debris_extended, + ); + patcher.add_scly_patch( + resource_info!("00d_under_intro_hall.MREA").into(), + patch_fix_deck_beta_security_hall_crash, + ); + patcher.add_scly_patch( + resource_info!("05_under_intro_zoo.MREA").into(), + patch_purge_debris_extended, ); patcher.add_scly_patch( resource_info!("00p_mines_connect.MREA").into(), @@ -16068,15 +16353,6 @@ fn build_and_run_patches<'r>( ); } - if config.qol_cutscenes == CutsceneMode::Major - && is_elevator(room_info.room_id.to_u32()) - { - patcher.add_scly_patch( - (pak_name.as_bytes(), room_info.room_id.to_u32()), - move |ps, area| patch_remove_cutscenes(ps, area, vec![], vec![], true), - ); - } - let map_default_state = { let mut map_default_state = config.map_default_state; if let Some(level) = level_data.get(world.to_json_key()) { @@ -16909,7 +17185,15 @@ fn build_and_run_patches<'r>( // Some doors have their object IDs changed in non NTSC-U versions // NTSC-K is based on NTSC-U and shouldn't be part of those changes - if [Version::Pal, Version::NtscJ, Version::NtscJTrilogy, Version::NtscUTrilogy, Version::PalTrilogy].contains(&config.version) { + if [ + Version::Pal, + Version::NtscJ, + Version::NtscJTrilogy, + Version::NtscUTrilogy, + Version::PalTrilogy, + ] + .contains(&config.version) + { // Tallon Overworld - Temple Security Station if mrea_id == 0xBDB1FCAC && local_dl.door_location.unwrap().instance_id == 0x00070055 @@ -17211,22 +17495,6 @@ fn build_and_run_patches<'r>( ); let skip_frigate = skip_frigate && starting_room.mlvl != World::FrigateOrpheon.mlvl(); - match config.qol_cutscenes { - CutsceneMode::Original => {} - CutsceneMode::Skippable => {} - CutsceneMode::SkippableCompetitive => {} - CutsceneMode::Competitive => { - patch_qol_competitive_cutscenes(&mut patcher, config.version, skip_frigate); - } - CutsceneMode::Minor => { - patch_qol_minor_cutscenes(&mut patcher, config.version); - } - CutsceneMode::Major => { - patch_qol_minor_cutscenes(&mut patcher, config.version); - patch_qol_major_cutscenes(&mut patcher, config.shuffle_pickup_position); - } - } - let mut smoother_teleports = false; for (_, level) in level_data.iter() { if smoother_teleports { @@ -18427,6 +18695,34 @@ fn build_and_run_patches<'r>( ); } + /* Run these last for legacy support reasons */ + match config.qol_cutscenes { + CutsceneMode::Original => {} + CutsceneMode::Skippable => {} + CutsceneMode::SkippableCompetitive => {} + CutsceneMode::Competitive => { + patch_qol_competitive_cutscenes(&mut patcher, config.version, skip_frigate); + } + CutsceneMode::Minor => { + patch_qol_minor_cutscenes(&mut patcher, config.version); + } + CutsceneMode::Major => { + patch_qol_minor_cutscenes(&mut patcher, config.version); + patch_qol_major_cutscenes(&mut patcher, config.shuffle_pickup_position); + + for (pak_name, rooms) in pickup_meta::ROOM_INFO.iter() { + for room_info in rooms.iter() { + if is_elevator(room_info.room_id.to_u32()) { + patcher.add_scly_patch( + (pak_name.as_bytes(), room_info.room_id.to_u32()), + move |ps, area| patch_remove_cutscenes(ps, area, vec![], vec![], true), + ); + } + } + } + } + } + patcher.run(gc_disc)?; Ok(()) diff --git a/src/pickup_meta.rs b/src/pickup_meta.rs index db43efc5..27046717 100644 --- a/src/pickup_meta.rs +++ b/src/pickup_meta.rs @@ -353,6 +353,8 @@ pub enum PickupModel { ArtifactOfNature, ArtifactOfStrength, Nothing, + Zoomer, + Cog, HealthRefill, MissileRefill, PowerBombRefill, @@ -403,6 +405,8 @@ impl PickupModel { PickupModel::ArtifactOfNature => "Artifact of Nature", PickupModel::ArtifactOfStrength => "Artifact of Strength", PickupModel::Nothing => "Nothing", + PickupModel::Zoomer => "Zoomer", + PickupModel::Cog => "Cog", PickupModel::RandovaniaGamecube => "Gamecube", PickupModel::HealthRefill => "Health Refill", PickupModel::MissileRefill => "Missile Refill", @@ -424,6 +428,10 @@ impl PickupModel { pickup.scale[2] = 0.475; } else if self.name() == PickupModel::PowerBomb.name() { pickup.actor_params.enable_thermal_heat = 1; + } else if self.name() == PickupModel::Cog.name() { + pickup.scale[0] = 0.7; + pickup.scale[1] = 0.7; + pickup.scale[2] = 0.7; } pickup } @@ -469,6 +477,8 @@ impl PickupModel { PickupModel::ArtifactOfNature, PickupModel::ArtifactOfStrength, PickupModel::Nothing, + PickupModel::Zoomer, + PickupModel::Cog, PickupModel::RandovaniaGamecube, PickupModel::HealthRefill, PickupModel::MissileRefill, diff --git a/src/pickup_meta.rs.in b/src/pickup_meta.rs.in index cabc8353..4c1adef0 100644 --- a/src/pickup_meta.rs.in +++ b/src/pickup_meta.rs.in @@ -10270,7 +10270,7 @@ pub const ROOM_INFO: &[(&str, &[RoomInfo]); 8] = &[ }, ]), ]; -const PICKUP_CMDL_AABBS: [(u32, [u32; 6]); 39] = [ +const PICKUP_CMDL_AABBS: [(u32, [u32; 6]); 41] = [ (0x009771B9, [0xBF032D07, 0xBEF982E1, 0x3D3B29A0, 0x3F032D07, 0x3EF982F1, 0x3FFBFE22]), (0x10EDFFCC, [0xBFA12B7D, 0xBE9C29A5, 0xBFF5A1AE, 0x3FE1A34C, 0x34A7D97F, 0x3FD69829]), (0x12174A4C, [0xBFA12B7D, 0xBE9C29A5, 0xBFF5A1AE, 0x3FE1A34C, 0x34A7D97F, 0x3FD69829]), @@ -10302,10 +10302,12 @@ const PICKUP_CMDL_AABBS: [(u32, [u32; 6]); 39] = [ (0xDA25B1BE, [0xBF032CFF, 0xBEF982E4, 0x3D3B29F0, 0x3F032D02, 0x3EF982DE, 0x3FFBFE22]), (0xDEAF0002, [0xBED70230, 0xBE2637A1, 0xBEE9CA69, 0x3ED7022F, 0x3E2637A0, 0x3EDEBAA6]), (0xDEAF0005, [0xBED70230, 0xBE2637A1, 0xBEE9CA69, 0x3ED7022F, 0x3E2637A0, 0x3EDEBAA6]), - (0xDEAF0007, [0xBED5A986, 0xBED5A986, 0xBF1004EA, 0x3ED5A986, 0x3ED5A986, 0x3F1004EA]), - (0xDEAF0009, [0xBED5A986, 0xBED5A986, 0xBF1004EA, 0x3ED5A986, 0x3ED5A986, 0x3F1004EA]), + (0xDEAF0007, [0xBED70230, 0xBE2637A1, 0xBEE9CA69, 0x3ED7022F, 0x3E2637A0, 0x3EDEBAA6]), + (0xDEAF0009, [0xBED70230, 0xBE2637A1, 0x3D31ACB8, 0x3ED7022F, 0x3E2637A0, 0x3F6F5D53]), (0xDEAF000B, [0xBED5A986, 0xBED5A986, 0xBF1004EA, 0x3ED5A986, 0x3ED5A986, 0x3F1004EA]), - (0xDEAF0010, [0xBEBF4CAC, 0xBEBF4C8C, 0x3F3CB4FA, 0x3EBF4CAD, 0x3EBF4CD0, 0x4000D66D]), + (0xDEAF000D, [0xBED5A986, 0xBED5A986, 0xBF1004EA, 0x3ED5A986, 0x3ED5A986, 0x3F1004EA]), + (0xDEAF000F, [0xBED5A986, 0xBED5A986, 0xBF1004EA, 0x3ED5A986, 0x3ED5A986, 0x3F1004EA]), + (0xDEAF0014, [0xBEBF4CAC, 0xBEBF4C8C, 0x3F3CB4FA, 0x3EBF4CAD, 0x3EBF4CD0, 0x4000D66D]), (0xF86621C9, [0xBEDCA1FE, 0xBF5C1DF2, 0xBF80444F, 0x3EDC79E0, 0x3F5AC836, 0x3F66A5F1]), (0xFCD66153, [0xBFA12B7D, 0xBE9C29A5, 0xBFF5A1AE, 0x3FE1A34C, 0x34A7D97F, 0x3FD69829]), (0xFE2CD4D3, [0xBFA12B7D, 0xBE9C29A5, 0xBFF5A1AE, 0x3FE1A34C, 0x34A7D97F, 0x3FD69829]), @@ -10454,8 +10456,8 @@ impl PickupModel (0x79B5BD15, FourCC::from_bytes(b"TXTR")), (0xA0DA476B, FourCC::from_bytes(b"PART")), (0xC4AD9154, FourCC::from_bytes(b"TXTR")), - (0xDEAF000B, FourCC::from_bytes(b"CMDL")), - (0xDEAF000C, FourCC::from_bytes(b"ANCS")), + (0xDEAF000F, FourCC::from_bytes(b"CMDL")), + (0xDEAF0010, FourCC::from_bytes(b"ANCS")), (0xE224FF03, FourCC::from_bytes(b"TXTR")), ]; DATA @@ -10475,8 +10477,8 @@ impl PickupModel (0x79B5BD15, FourCC::from_bytes(b"TXTR")), (0xA0DA476B, FourCC::from_bytes(b"PART")), (0xC4AD9154, FourCC::from_bytes(b"TXTR")), - (0xDEAF0007, FourCC::from_bytes(b"CMDL")), - (0xDEAF0008, FourCC::from_bytes(b"ANCS")), + (0xDEAF000B, FourCC::from_bytes(b"CMDL")), + (0xDEAF000C, FourCC::from_bytes(b"ANCS")), (0xE224FF03, FourCC::from_bytes(b"TXTR")), (0xFC095F6C, FourCC::from_bytes(b"TXTR")), ]; @@ -10498,8 +10500,8 @@ impl PickupModel (0xA0DA476B, FourCC::from_bytes(b"PART")), (0xBE4CD99D, FourCC::from_bytes(b"TXTR")), (0xC4AD9154, FourCC::from_bytes(b"TXTR")), - (0xDEAF0009, FourCC::from_bytes(b"CMDL")), - (0xDEAF000A, FourCC::from_bytes(b"ANCS")), + (0xDEAF000D, FourCC::from_bytes(b"CMDL")), + (0xDEAF000E, FourCC::from_bytes(b"ANCS")), (0xE224FF03, FourCC::from_bytes(b"TXTR")), ]; DATA @@ -10909,11 +10911,11 @@ impl PickupModel (0xAE6410BE, FourCC::from_bytes(b"CSKR")), (0xB59EB7E6, FourCC::from_bytes(b"TXTR")), (0xDBDF0424, FourCC::from_bytes(b"CINF")), - (0xDEAF0018, FourCC::from_bytes(b"CMDL")), - (0xDEAF0019, FourCC::from_bytes(b"ANCS")), - (0xDEAF001A, FourCC::from_bytes(b"TXTR")), - (0xDEAF001B, FourCC::from_bytes(b"TXTR")), - (0xDEAF001C, FourCC::from_bytes(b"TXTR")), + (0xDEAF001C, FourCC::from_bytes(b"CMDL")), + (0xDEAF001D, FourCC::from_bytes(b"ANCS")), + (0xDEAF001E, FourCC::from_bytes(b"TXTR")), + (0xDEAF001F, FourCC::from_bytes(b"TXTR")), + (0xDEAF0020, FourCC::from_bytes(b"TXTR")), (0xE224FF03, FourCC::from_bytes(b"TXTR")), ]; DATA @@ -11284,7 +11286,6 @@ impl PickupModel (0x0DEB9456, FourCC::from_bytes(b"PART")), (0x1544D478, FourCC::from_bytes(b"TXTR")), (0x29782CA6, FourCC::from_bytes(b"TXTR")), - (0x2F976E86, FourCC::from_bytes(b"CMDL")), (0x394D3877, FourCC::from_bytes(b"ANIM")), (0x454FB170, FourCC::from_bytes(b"TXTR")), (0x4B26EFDA, FourCC::from_bytes(b"EVNT")), @@ -11293,7 +11294,6 @@ impl PickupModel (0x79B5BD15, FourCC::from_bytes(b"TXTR")), (0xA0DA476B, FourCC::from_bytes(b"PART")), (0xAF9DEFBE, FourCC::from_bytes(b"CINF")), - (0xBE4CD99D, FourCC::from_bytes(b"TXTR")), (0xDEAF0000, FourCC::from_bytes(b"TXTR")), (0xDEAF0001, FourCC::from_bytes(b"TXTR")), (0xDEAF0003, FourCC::from_bytes(b"ANCS")), @@ -11305,6 +11305,54 @@ impl PickupModel ]; DATA }, + PickupModel::Zoomer => { + const DATA: &[(u32, FourCC)] = &[ + (0x0DEB9456, FourCC::from_bytes(b"PART")), + (0x1544D478, FourCC::from_bytes(b"TXTR")), + (0x29782CA6, FourCC::from_bytes(b"TXTR")), + (0x394D3877, FourCC::from_bytes(b"ANIM")), + (0x454FB170, FourCC::from_bytes(b"TXTR")), + (0x4B26EFDA, FourCC::from_bytes(b"EVNT")), + (0x57FE7E67, FourCC::from_bytes(b"AGSC")), + (0x5E027EA1, FourCC::from_bytes(b"TXTR")), + (0x79B5BD15, FourCC::from_bytes(b"TXTR")), + (0xA0DA476B, FourCC::from_bytes(b"PART")), + (0xAF9DEFBE, FourCC::from_bytes(b"CINF")), + (0xDEAF0000, FourCC::from_bytes(b"TXTR")), + (0xDEAF0001, FourCC::from_bytes(b"TXTR")), + (0xDEAF0003, FourCC::from_bytes(b"ANCS")), + (0xDEAF0004, FourCC::from_bytes(b"TXTR")), + (0xDEAF0007, FourCC::from_bytes(b"CMDL")), + (0xDEAF0008, FourCC::from_bytes(b"ANCS")), + (0xE224FF03, FourCC::from_bytes(b"TXTR")), + (0xFEBBC197, FourCC::from_bytes(b"CSKR")), + ]; + DATA + }, + PickupModel::Cog => { + const DATA: &[(u32, FourCC)] = &[ + (0x0DEB9456, FourCC::from_bytes(b"PART")), + (0x1544D478, FourCC::from_bytes(b"TXTR")), + (0x29782CA6, FourCC::from_bytes(b"TXTR")), + (0x394D3877, FourCC::from_bytes(b"ANIM")), + (0x454FB170, FourCC::from_bytes(b"TXTR")), + (0x4B26EFDA, FourCC::from_bytes(b"EVNT")), + (0x50DF3CAD, FourCC::from_bytes(b"TXTR")), + (0x57FE7E67, FourCC::from_bytes(b"AGSC")), + (0x5E027EA1, FourCC::from_bytes(b"TXTR")), + (0x79B5BD15, FourCC::from_bytes(b"TXTR")), + (0xA0DA476B, FourCC::from_bytes(b"PART")), + (0xAF9DEFBE, FourCC::from_bytes(b"CINF")), + (0xDEAF0000, FourCC::from_bytes(b"TXTR")), + (0xDEAF0001, FourCC::from_bytes(b"TXTR")), + (0xDEAF0003, FourCC::from_bytes(b"ANCS")), + (0xDEAF0009, FourCC::from_bytes(b"CMDL")), + (0xDEAF000A, FourCC::from_bytes(b"ANCS")), + (0xE224FF03, FourCC::from_bytes(b"TXTR")), + (0xFEBBC197, FourCC::from_bytes(b"CSKR")), + ]; + DATA + }, PickupModel::RandovaniaGamecube => { const DATA: &[(u32, FourCC)] = &[ (0x0DEB9456, FourCC::from_bytes(b"PART")), @@ -11322,10 +11370,10 @@ impl PickupModel (0xDEAF0000, FourCC::from_bytes(b"TXTR")), (0xDEAF0001, FourCC::from_bytes(b"TXTR")), (0xDEAF0003, FourCC::from_bytes(b"ANCS")), - (0xDEAF0014, FourCC::from_bytes(b"CMDL")), - (0xDEAF0015, FourCC::from_bytes(b"ANCS")), - (0xDEAF0016, FourCC::from_bytes(b"TXTR")), - (0xDEAF0017, FourCC::from_bytes(b"TXTR")), + (0xDEAF0018, FourCC::from_bytes(b"CMDL")), + (0xDEAF0019, FourCC::from_bytes(b"ANCS")), + (0xDEAF001A, FourCC::from_bytes(b"TXTR")), + (0xDEAF001B, FourCC::from_bytes(b"TXTR")), (0xE224FF03, FourCC::from_bytes(b"TXTR")), (0xFEBBC197, FourCC::from_bytes(b"CSKR")), ]; @@ -11415,13 +11463,13 @@ impl PickupModel (0x5E027EA1, FourCC::from_bytes(b"TXTR")), (0x79B5BD15, FourCC::from_bytes(b"TXTR")), (0xA0DA476B, FourCC::from_bytes(b"PART")), - (0xDEAF000D, FourCC::from_bytes(b"TXTR")), - (0xDEAF000E, FourCC::from_bytes(b"TXTR")), - (0xDEAF000F, FourCC::from_bytes(b"TXTR")), - (0xDEAF0010, FourCC::from_bytes(b"CMDL")), - (0xDEAF0011, FourCC::from_bytes(b"ANCS")), - (0xDEAF0012, FourCC::from_bytes(b"EVNT")), - (0xDEAF0013, FourCC::from_bytes(b"ANIM")), + (0xDEAF0011, FourCC::from_bytes(b"TXTR")), + (0xDEAF0012, FourCC::from_bytes(b"TXTR")), + (0xDEAF0013, FourCC::from_bytes(b"TXTR")), + (0xDEAF0014, FourCC::from_bytes(b"CMDL")), + (0xDEAF0015, FourCC::from_bytes(b"ANCS")), + (0xDEAF0016, FourCC::from_bytes(b"EVNT")), + (0xDEAF0017, FourCC::from_bytes(b"ANIM")), (0xE224FF03, FourCC::from_bytes(b"TXTR")), (0xF8333189, FourCC::from_bytes(b"CINF")), ]; @@ -11576,7 +11624,7 @@ PickupModel::IceTrap => { 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x42, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAF, 0x00, - 0x0B, 0xDE, 0xAF, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x0F, 0xDE, 0xAF, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x01, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, @@ -11610,7 +11658,7 @@ PickupModel::IceTrap => { 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x42, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAF, - 0x00, 0x07, 0xDE, 0xAF, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x0B, 0xDE, 0xAF, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x01, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, @@ -11643,8 +11691,8 @@ PickupModel::IceTrap => { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x42, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAF, 0x00, 0x09, - 0xDE, 0xAF, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAF, 0x00, 0x0D, + 0xDE, 0xAF, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x01, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x00, @@ -12235,7 +12283,7 @@ PickupModel::IceTrap => { 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x42, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAF, 0x00, - 0x18, 0xDE, 0xAF, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x1C, 0xDE, 0xAF, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x01, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, @@ -12790,6 +12838,72 @@ PickupModel::IceTrap => { 0x00, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, ], + PickupModel::Zoomer => &[ + 0x00, 0x00, 0x00, 0x12, 0x5A, 0x6F, 0x6F, 0x6D, + 0x65, 0x72, 0x00, 0xC3, 0x18, 0x19, 0x25, 0x41, + 0xCB, 0xC3, 0x2E, 0xC3, 0x0C, 0xB0, 0x2F, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xC2, + 0x82, 0x1E, 0x3D, 0x3F, 0xE6, 0x45, 0xA3, 0x3F, + 0xE6, 0x45, 0xA3, 0x3F, 0xE6, 0x45, 0xA3, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x42, 0xC8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, + 0xAF, 0x00, 0x07, 0xDE, 0xAF, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x01, + 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0x80, 0x00, 0x00, 0x41, 0xA0, 0x00, 0x00, + 0x3F, 0x80, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, + 0x3F, 0x80, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x01, 0x3F, 0x80, 0x00, 0x00, 0x3F, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0x01, 0x00, 0x00, + 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + ], + PickupModel::Cog => &[ + 0x00, 0x00, 0x00, 0x12, 0x43, 0x6F, 0x67, 0x00, + 0xC3, 0x18, 0x19, 0x25, 0x41, 0xCB, 0xC3, 0x2E, + 0xC3, 0x0C, 0xB0, 0x2F, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0xC2, 0x82, 0x1E, 0x3D, + 0x3F, 0xE6, 0x45, 0xA3, 0x3F, 0xE6, 0x45, 0xA3, + 0x3F, 0xE6, 0x45, 0xA3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAF, 0x00, 0x09, + 0xDE, 0xAF, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, + 0x00, 0x00, 0x00, 0x0E, 0x01, 0x3F, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x00, + 0x00, 0x41, 0xA0, 0x00, 0x00, 0x3F, 0x80, 0x00, + 0x00, 0x3F, 0x80, 0x00, 0x00, 0x3F, 0x80, 0x00, + 0x00, 0x3F, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, + 0x3F, 0x80, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0x01, 0x00, 0x00, 0x3F, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, + ], PickupModel::RandovaniaGamecube => &[ 0x00, 0x00, 0x00, 0x12, 0x47, 0x61, 0x6D, 0x65, 0x63, 0x75, 0x62, 0x65, 0x00, 0xC3, 0x18, 0x19, @@ -12803,8 +12917,8 @@ PickupModel::IceTrap => { 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xDE, 0xAF, 0x00, 0x14, 0xDE, 0xAF, 0x00, - 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xDE, 0xAF, 0x00, 0x18, 0xDE, 0xAF, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x01, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0x41, 0xA0, @@ -12942,7 +13056,7 @@ PickupModel::IceTrap => { 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x42, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAF, - 0x00, 0x10, 0xDE, 0xAF, 0x00, 0x11, 0x00, 0x00, + 0x00, 0x14, 0xDE, 0xAF, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x01, 0x3F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, diff --git a/structs/src/scly_props/water.rs b/structs/src/scly_props/water.rs index 577af8d4..bc999292 100644 --- a/structs/src/scly_props/water.rs +++ b/structs/src/scly_props/water.rs @@ -14,63 +14,63 @@ pub struct Water<'r> { pub position: GenericArray, pub scale: GenericArray, pub damage_info: DamageInfo, - pub unknown1: GenericArray, - pub unknown2: u32, - pub unknown3: u8, - pub display_fluid_surface: u8, - pub txtr1: u32, - pub txtr2: u32, - pub txtr3: u32, - pub txtr4: u32, - pub refl_map_txtr: u32, - pub txtr6: u32, - pub unknown5: GenericArray, - pub unknown6: f32, + pub force: GenericArray, + pub flags: u32, + pub thermal_cold: u8, + pub display_surface: u8, + pub pattern_map_1: u32, + pub pattern_map_2: u32, + pub color_map: u32, + pub bump_map: u32, + pub env_map: u32, + pub env_bump_map: u32, + pub bump_map_dir: GenericArray, + pub bump_scale: f32, pub morph_in_time: f32, pub morph_out_time: f32, pub active: u8, pub fluid_type: u32, - pub unknown11: u8, - pub unknown12: f32, + pub unknown1: u8, + pub alpha: f32, pub fluid_uv_motion: FluidUVMotion, - pub unknown30: f32, - pub unknown31: f32, - pub unknown32: f32, - pub unknown33: f32, - pub unknown34: f32, - pub unknown35: f32, - pub unknown36: f32, - pub unknown37: f32, - pub unknown38: GenericArray, // RGBA - pub unknown39: GenericArray, // RGBA - pub small_enter_part: u32, - pub med_enter_part: u32, - pub large_enter_part: u32, - pub part4: u32, - pub part5: u32, - pub sound1: u32, - pub sound2: u32, - pub sound3: u32, - pub sound4: u32, - pub sound5: u32, - pub unknown40: f32, - pub unknown41: u32, - pub unknown42: f32, - pub unknown43: f32, - pub unknown44: f32, - pub unknown45: f32, - pub unknown46: f32, - pub unknown47: f32, - pub heat_wave_height: f32, - pub heat_wave_speed: f32, - pub heat_wave_color: GenericArray, // RGBA - pub lightmap_txtr: u32, - pub unknown51: f32, + pub turb_speed: f32, + pub turb_distance: f32, + pub turb_frequence_max: f32, + pub turb_frequence_min: f32, + pub turb_phase_max: f32, + pub turb_phase_min: f32, + pub turb_amplitude_max: f32, + pub turb_amplitude_min: f32, + pub splash_color: GenericArray, // RGBA + pub inside_fog_color: GenericArray, // RGBA + pub splash_particle_1: u32, + pub splash_particle_2: u32, + pub splash_particle_3: u32, + pub visor_runoff_particle: u32, + pub unmorph_visor_runoff_particle: u32, + pub visor_runoff_sound: u32, + pub unmorph_visor_runoff_sound: u32, + pub splash_sfx_1: u32, + pub splash_sfx_2: u32, + pub splash_sfx_3: u32, + pub tile_size: f32, + pub tile_subdivisions: u32, + pub specular_min: f32, + pub specular_max: f32, + pub reflection_size: f32, + pub ripple_intensity: f32, + pub reflection_blend: f32, + pub fog_bias: f32, + pub fog_magnitude: f32, + pub fog_speed: f32, + pub fog_color: GenericArray, // RGBA + pub lightmap: u32, + pub units_per_lightmap_texel: f32, pub alpha_in_time: f32, pub alpha_out_time: f32, - pub unknown54: u32, - pub unknown55: u32, - pub crash_the_game: u8, + pub unknown2: u32, + pub unknown3: u32, + pub unknown4: u8, } #[auto_struct(Readable, Writable)] @@ -79,18 +79,18 @@ pub struct FluidUVMotion { pub fluid_layer_motion1: FluidLayerMotion, pub fluid_layer_motion2: FluidLayerMotion, pub fluid_layer_motion3: FluidLayerMotion, - pub unknown1: f32, - pub unknown2: f32, + pub time_to_wrap: f32, + pub orientation: f32, } #[auto_struct(Readable, Writable)] #[derive(Debug, Clone)] pub struct FluidLayerMotion { pub fluid_uv_motion: u32, - pub unknown1: f32, - pub unknown2: f32, - pub unknown3: f32, - pub unknown4: f32, + pub time_to_wrap: f32, + pub orientation: f32, + pub magnitude: f32, + pub multiplication: f32, } use crate::{impl_position, impl_scale};