diff --git a/schema/randomprime.schema.json b/schema/randomprime.schema.json index 7ac8a953..12c7dd74 100644 --- a/schema/randomprime.schema.json +++ b/schema/randomprime.schema.json @@ -1102,6 +1102,11 @@ "type": "boolean", "default": false, "deprecated": true + }, + "patchWallcrawling": { + "description": "If true, it becomes nearly impossible to transition most doors while oob.", + "type": "boolean", + "default": false } }, "required": [], diff --git a/src/patch_config.rs b/src/patch_config.rs index 26a5450a..4a469388 100644 --- a/src/patch_config.rs +++ b/src/patch_config.rs @@ -1186,6 +1186,7 @@ pub struct PatchConfig pub shoot_in_grapple: bool, pub difficulty_behavior: DifficultyBehavior, pub legacy_block_size: bool, + pub patch_wallcrawling: bool, pub ctwk_config: CtwkConfig, } @@ -1285,6 +1286,7 @@ struct GameConfig shoot_in_grapple: Option, difficulty_behavior: Option, legacy_block_size: Option, + patch_wallcrawling: Option, } #[derive(Deserialize, Debug, Default, Clone)] @@ -2234,6 +2236,7 @@ impl PatchConfigPrivate shoot_in_grapple: self.game_config.shoot_in_grapple.unwrap_or(false), difficulty_behavior: self.game_config.difficulty_behavior.unwrap_or(DifficultyBehavior::Either), legacy_block_size: self.game_config.legacy_block_size.unwrap_or(false), + patch_wallcrawling: self.game_config.patch_wallcrawling.unwrap_or(false), map_default_state, starting_items, diff --git a/src/patches.rs b/src/patches.rs index f6a784aa..67672e5c 100644 --- a/src/patches.rs +++ b/src/patches.rs @@ -12141,6 +12141,43 @@ fn patch_remove_blast_shields<'r>( Ok(()) } +fn patch_anti_oob<'r>( + _ps: &mut PatcherState, + area: &mut mlvl_wrapper::MlvlArea<'r, '_, '_, '_>, +) +-> Result<(), String> +{ + let scly = area.mrea().scly_section_mut(); + let layer_count = scly.layers.len(); + for i in 0..layer_count { + let layer = &mut scly.layers.as_mut_vec()[i]; + for obj in layer.objects.as_mut_vec() { + if let Some(dock) = obj.property_data.as_dock_mut() { + let scale: [f32; 3] = dock.scale.into(); + let volume = scale[0] * scale[1] * scale[2]; + if volume < 49.9 || volume > 50.1 { + continue; // This dock is weird don't touch it + } + + if scale[0] > 4.9 { + dock.scale[0] = 2.6; + } + + if scale[1] > 4.9 { + dock.scale[1] = 2.6; + } + + dock.scale[2] = 2.0; + + // Center with the door + dock.position[2] = dock.position[2] - 0.6; + } + } + } + + Ok(()) +} + fn patch_remove_control_disabler<'r>( _ps: &mut PatcherState, area: &mut mlvl_wrapper::MlvlArea<'r, '_, '_, '_>, @@ -15202,6 +15239,14 @@ fn build_and_run_patches<'r>(gc_disc: &mut structs::GcDisc<'r>, config: &PatchCo ); } + if config.patch_wallcrawling + { + patcher.add_scly_patch( + (pak_name.as_bytes(), room_info.room_id.to_u32()), + patch_anti_oob, + ); + } + if config.remove_vanilla_blast_shields { patcher.add_scly_patch( (pak_name.as_bytes(), room_info.room_id.to_u32()),