diff --git a/open_samus_returns_rando/files/schema.json b/open_samus_returns_rando/files/schema.json index 17877fd..37deaa1 100644 --- a/open_samus_returns_rando/files/schema.json +++ b/open_samus_returns_rando/files/schema.json @@ -138,6 +138,16 @@ "type": "boolean", "description": "Removes the Super Missile weakness on Missile shields.", "default": false + }, + "patch_surface_crumbles": { + "type": "boolean", + "description": "Changes the Crumble blocks after Scan Pulse to be Power Beam blocks.", + "default": true + }, + "patch_area1_crumbles": { + "type": "boolean", + "description": "Changes the Crumble blocks leaving Area 1 to be Power Beam blocks.", + "default": true } }, "additionalProperties": false diff --git a/open_samus_returns_rando/specific_patches/game_patches.py b/open_samus_returns_rando/specific_patches/game_patches.py index de7a96a..fce77e0 100644 --- a/open_samus_returns_rando/specific_patches/game_patches.py +++ b/open_samus_returns_rando/specific_patches/game_patches.py @@ -1,4 +1,4 @@ -from mercury_engine_data_structures.formats import Bmsad +from mercury_engine_data_structures.formats import Bmsad, Bmsbk from open_samus_returns_rando.patcher_editor import PatcherEditor @@ -7,42 +7,48 @@ # Area 4 West to Area 4 East "scenario": "s040_area4", "layer": 9, - "actor": "LE_GrappleMov_001" + "actor": "LE_GrappleMov_001", }, { # Area 5 to Area 6 "scenario": "s060_area6", "layer": 9, - "actor": "LE_GrappleMov_004" + "actor": "LE_GrappleMov_004", }, { # Area 6 to Area 7 "scenario": "s070_area7", "layer": 9, - "actor": "LE_GrappleMov_001" + "actor": "LE_GrappleMov_001", }, { # Area 7 to Area 8 "scenario": "s090_area9", "layer": 9, - "actor": "LE_GrappleMov_001" - } + "actor": "LE_GrappleMov_001", + }, ] -def apply_game_patches(editor: PatcherEditor, configuration: dict): +def apply_game_patches(editor: PatcherEditor, configuration: dict): + # Weapon patches if configuration["nerf_power_bombs"]: _remove_pb_weaknesses(editor) - _remove_grapple_blocks(editor, configuration) - if configuration["nerf_super_missiles"]: _remove_super_missile_weakness(editor) + # Area patches + _remove_grapple_blocks(editor, configuration) + _patch_crumble_blocks(editor, configuration) + + def _remove_pb_weaknesses(editor: PatcherEditor): # Charge Door for door in ["doorchargecharge", "doorclosedcharge"]: - charge_door = editor.get_file(f"actors/props/{door}/charclasses/{door}.bmsad", Bmsad) + charge_door = editor.get_file( + f"actors/props/{door}/charclasses/{door}.bmsad", Bmsad + ) func = charge_door.raw.components.LIFE.functions[0] if func.params.Param1.value: func.params.Param1.value = "CHARGE_BEAM" @@ -51,7 +57,9 @@ def _remove_pb_weaknesses(editor: PatcherEditor): # Beam Doors for door in ["doorwave", "doorspazerbeam", "doorcreature"]: - beam_door = editor.get_file(f"actors/props/{door}/charclasses/{door}.bmsad", Bmsad) + beam_door = editor.get_file( + f"actors/props/{door}/charclasses/{door}.bmsad", Bmsad + ) func_wp = beam_door.raw.components.LIFE.functions[1] func_s = beam_door.raw.components.LIFE.functions[2] if func_wp.params.Param1.value: @@ -62,6 +70,7 @@ def _remove_pb_weaknesses(editor: PatcherEditor): if func_s.params.Param1.value: func_s.params.Param1.value = "SPAZER_BEAM" + def _remove_grapple_blocks(editor: PatcherEditor, configuration: dict): if configuration["remove_elevator_grapple_blocks"]: for reference in _ELEVATOR_GRAPPLE_BLOCKS: @@ -69,15 +78,40 @@ def _remove_grapple_blocks(editor: PatcherEditor, configuration: dict): if configuration["remove_grapple_block_area3_interior_shortcut"]: editor.remove_entity( - { - "scenario": "s036_area3c", - "layer": 9, - "actor": "LE_GrappleDest_004" - } + {"scenario": "s036_area3c", "layer": 9, "actor": "LE_GrappleDest_004"} ) + def _remove_super_missile_weakness(editor: PatcherEditor): - missile_door = editor.get_file("actors/props/doorshieldmissile/charclasses/doorshieldmissile.bmsad", Bmsad) + missile_door = editor.get_file( + "actors/props/doorshieldmissile/charclasses/doorshieldmissile.bmsad", Bmsad + ) func = missile_door.raw.components.LIFE.functions[1] if func.params.Param1.value: func.params.Param1.value = "MISSILE" + + +def _patch_crumble_blocks(editor: PatcherEditor, configuration: dict): + # Crumble blocks after Scan Pulse + if configuration["patch_surface_crumbles"]: + surface = editor.get_file( + "maps/levels/c10_samus/s000_surface/s000_surface.bmsbk", Bmsbk + ) + post_scan_pulse_crumbles = surface.raw["block_groups"][37] + post_scan_pulse_crumbles["types"][0]["block_type"] = "power_beam" + post_scan_pulse_crumbles["types"][0]["blocks"][0]["respawn_time"] = 0.0 + post_scan_pulse_crumbles["types"][0]["blocks"][1]["respawn_time"] = 0.0 + post_scan_pulse_crumbles["types"][0]["blocks"][2]["respawn_time"] = 0.0 + + # Crumble blocks leaving Area 1 + if configuration["patch_area1_crumbles"]: + area1 = editor.get_file( + "maps/levels/c10_samus/s010_area1/s010_area1.bmsbk", Bmsbk + ) + area1_chozo_seal_crumbles = area1.raw["block_groups"][19] + area1_chozo_seal_crumbles["types"][0]["block_type"] = "power_beam" + area1_chozo_seal_crumbles["types"][0]["blocks"][0]["respawn_time"] = 0.0 + area1_chozo_seal_crumbles["types"][0]["blocks"][1]["respawn_time"] = 0.0 + area1_chozo_seal_crumbles["types"][0]["blocks"][2]["respawn_time"] = 0.0 + area1_chozo_seal_crumbles["types"][0]["blocks"][3]["respawn_time"] = 0.0 + area1_chozo_seal_crumbles["types"][0]["blocks"][4]["respawn_time"] = 0.0 diff --git a/tests/test_files/crumble_blocks.json b/tests/test_files/crumble_blocks.json new file mode 100644 index 0000000..24cd1df --- /dev/null +++ b/tests/test_files/crumble_blocks.json @@ -0,0 +1,68 @@ +{ + "$schema": "../../open_samus_returns_rando/files/schema.json", + "starting_location": { + "scenario": "s000_surface", + "actor": "ST_CheckPoint_001" + }, + "starting_items": { + "ITEM_MAX_LIFE": 99, + "ITEM_WEAPON_MISSILE_MAX": 50, + "ITEM_WEAPON_SUPER_MISSILE_MAX": 5, + "ITEM_WEAPON_POWER_BOMB_MAX": 0, + "ITEM_MAX_SPECIAL_ENERGY": 1000, + "ITEM_SPECIAL_ENERGY_SCANNING_PULSE": 1, + "ITEM_MORPH_BALL": 1, + "ITEM_ENERGY_TANKS": 4, + "ITEM_WEAPON_BOMB": 1, + "ITEM_WEAPON_WAVE_BEAM": 1, + "ITEM_METROID_COUNT": 0, + "ITEM_METROID_TOTAL_COUNT": 40, + "ITEM_SPACE_JUMP": 1 + + }, + "pickups": [ + { + "pickup_type": "actor", + "caption": "Screw Attack acquired.", + "resources": [ + [ + { + "item_id": "ITEM_SCREW_ATTACK", + "quantity": 1 + } + ] + ], + "pickup_actor": { + "scenario": "s100_area10", + "actor": "LE_Baby_Hatching" + }, + "model": [ + "powerup_screwattack" + ] + } + ], + "energy_per_tank": 100, + "aeion_per_tank": 50, + "reveal_map_on_start": true, + "game_patches": { + "nerf_power_bombs": true, + "remove_elevator_grapple_blocks": true, + "remove_grapple_block_area3_interior_shortcut": true, + "patch_crumble_blocks": false + }, + "custom_pickups": [ + { + "new_actor": { + "actor": "LE_Baby_Hatching", + "scenario": "s100_area10" + }, + "location": { + "x": -3400.0, + "y": 11225.0, + "z": 0.0 + }, + "collision_camera_name": "collision_camera_022" + } + ] + } + \ No newline at end of file