Skip to content

Commit

Permalink
Duplicate all beam shields, add on death callback in doors.lua
Browse files Browse the repository at this point in the history
  • Loading branch information
ThanatosGit committed Sep 24, 2023
1 parent c65f03e commit ef8849a
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 46 deletions.
17 changes: 17 additions & 0 deletions open_samus_returns_rando/files/doors.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Doors = {}

function Doors.Dummy()
end
function Doors.RemoveDoors(_ARG_0_)
local actor_name = _ARG_0_.sName
-- TOOD: Remove the debug message
GUI.LaunchMessage(actor_name, "Doors.Dummy", "")
local ending = string.sub(actor_name, -2)
if ending == "_o" then
actor_name = string.sub(actor_name, 0, -3)
end
Game.DeleteEntity(actor_name)
Game.DeleteEntity(actor_name .. "_o")
Scenario.WriteToBlackboard("entity_" .. actor_name .. "_dead", "b", true)
Scenario.WriteToBlackboard("entity_" .. actor_name .. "_o_dead", "b", true)
end
8 changes: 0 additions & 8 deletions open_samus_returns_rando/files/randomizer_powerup.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,6 @@ RandomizerPowerup.Self = nil
function RandomizerPowerup.Dummy()
end

function RandomizerPowerup.GenerateADN()
-- TODO:
-- Add the __ARG__0 param
-- read its name and follow a name scheme for left and right side to delete other side
-- find out how to save -> reload -> permanently delete the door (guess blackboard property)
Game.DeleteEntity("LE_SpazerShield_Door008")
Game.DeleteEntity("LE_SpazerShield_Door008_a")
end

function RandomizerPowerup.SetItemAmount(item_id, quantity)
if type(quantity) == "string" then
Expand Down
40 changes: 2 additions & 38 deletions open_samus_returns_rando/samus_returns_patcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
import typing
from pathlib import Path

from construct import Container
from mercury_engine_data_structures.file_tree_editor import OutputFormat
from mercury_engine_data_structures.formats import Bmsad

from open_samus_returns_rando.bmsld_add import add_actor_to_entity_groups
from open_samus_returns_rando.lua_editor import LuaEditor
Expand All @@ -15,6 +13,7 @@
from open_samus_returns_rando.patcher_editor import PatcherEditor
from open_samus_returns_rando.pickup import patch_pickups
from open_samus_returns_rando.specific_patches import game_patches
from open_samus_returns_rando.specific_patches.door_patches import patch_shields
from open_samus_returns_rando.specific_patches.heat_room_patches import patch_heat_rooms
from open_samus_returns_rando.specific_patches.static_fixes import apply_static_fixes
from open_samus_returns_rando.validator_with_default import DefaultValidatingDraft7Validator
Expand Down Expand Up @@ -99,42 +98,6 @@ def patch_custom_pickups(editor: PatcherEditor, pickup_config: list[dict]):
editor.copy_actor(scenario_name, new_pos, base_actor, new_actor_name, 9)
add_actor_to_entity_groups(scenario, collision_camera_name, new_actor_name)

def patch_shields(editor: PatcherEditor):
# TODO: Move this function clean up this mess
# TODO: Write down all door / shields...lol
# TODO: Make unk06 a float in MEDS branch (cause I'm assign float values here)
# create custom pickup
_EXAMPLE_LEFT_SIDE = {"scenario": "s000_surface", "layer": "9", "actor": "LE_MissileShield_Door_002"}
_EXAMPLE_RIGHT_SIDE = {"scenario": "s010_area1", "layer": "9", "actor": "LE_DoorShieldMissile"}
_EXAMPLE_SPAZER = {"scenario": "s050_area5", "layer": "9", "actor": "LE_SpazerShield_Door008"}

scenario = editor.get_scenario("s050_area5")
scenario.remove_actor_from_all_groups("LE_SpazerShield_Door008")


left_actor = editor.resolve_actor_reference(_EXAMPLE_LEFT_SIDE)
left_actor["unk06"] = 90
right_actor = editor.resolve_actor_reference(_EXAMPLE_RIGHT_SIDE)
right_actor["unk06"] = 90

# messy spazer stuff (basically adds a call to RandomizerPowerup.GenerateADN when the door creature dies)
spazer_bmsad = editor.get_parsed_asset("actors/props/doorspazerbeam/charclasses/doorspazerbeam.bmsad", type_hint=Bmsad) # noqa
alpha_bmsad = editor.get_parsed_asset("actors/characters/alphanewborn/charclasses/alphanewborn.bmsad", type_hint=Bmsad) # noqa
spazer_bmsad.raw["components"]["SCRIPT"] = alpha_bmsad.raw["components"]["SCRIPT"]
spazer_bmsad.raw["components"]["SCRIPT"]["functions"][0]["params"]["Param1"]["value"] = "actors/items/randomizer_powerup/scripts/randomizer_powerup.lua" # noqa
spazer_bmsad.raw["components"]["SCRIPT"]["functions"][0]["params"]["Param2"]["value"] = "RandomizerPowerup"
unknown_mess = Container({"unk1": 22, "unk2": 1, "unk3": 0, "args": Container({601445949: Container({"type": "s", "value": "GenerateADN"})})}) # noqa
spazer_bmsad.action_sets[0].raw["animations"][0].event_counts[0] = spazer_bmsad.action_sets[0].raw["animations"][0].event_counts[0] + 1 # noqa
spazer_bmsad.action_sets[0].raw["animations"][0]["events0"].append(unknown_mess)
editor.replace_asset("actors/props/doorspazerbeam/charclasses/doorspazerbeam.bmsad", spazer_bmsad)

spazer_actor = editor.resolve_actor_reference(_EXAMPLE_SPAZER)
new_spazer_actor = editor.copy_actor(_EXAMPLE_SPAZER["scenario"], (spazer_actor["x"], spazer_actor["y"], spazer_actor["z"]), spazer_actor, "LE_SpazerShield_Door008_a", 9) # noqa
new_spazer_actor["unk05"] = 0
new_spazer_actor["unk06"] = 0
new_spazer_actor["unk07"] = 0


def patch_extracted(input_path: Path, output_path: Path, configuration: dict):
LOG.info("Will patch files from %s", input_path)

Expand Down Expand Up @@ -170,6 +133,7 @@ def patch_extracted(input_path: Path, output_path: Path, configuration: dict):
# Fix unheated heat rooms
patch_heat_rooms(editor)

# Make shields on both sides
patch_shields(editor)

# Specific game patches
Expand Down
112 changes: 112 additions & 0 deletions open_samus_returns_rando/specific_patches/door_patches.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@

import copy

from construct import Container, ListContainer
from mercury_engine_data_structures.formats import Bmsad

from open_samus_returns_rando.constants import ALL_AREAS
from open_samus_returns_rando.files import files_path
from open_samus_returns_rando.patcher_editor import PatcherEditor

SCRIPT_COMPONENT = Container({
"type": "CScriptComponent",
"unk_1": 3000,
"unk_2": -1.0,
"functions": ListContainer([
Container({
"name": "SetParams",
"unk1": True,
"unk2": False,
"params": Container({
"Param1": Container({
"type": "s",
"value": "actors/props/doors/scripts/doors.lua",
}),
"Param2": Container({
"type" :"s",
"value":"Doors",
}),
}),
}),
]),
"fields": Container(),
"dependencies": None,
})

ON_DEAD_CB = Container({
"unk1": 22,
"unk2": 1,
"unk3": 0,
"args": Container({
601445949: Container({
"type": "s",
"value": "RemoveDoors",
}),
}),
})

def _patch_missile_covers(editor: PatcherEditor):
missile_types = {"doorshieldmissile", "doorshieldpowerbomb", "doorshieldsupermissile"}
for area in ALL_AREAS:
scenario = editor.get_scenario(area)
for layer, actor_name, actor in scenario.all_actors():
if actor.type in missile_types:
actor["unk06"] = 90

def _patch_beam_covers(editor: PatcherEditor):
creature_bmsad_files = [
"actors/props/doorspazerbeam/charclasses/doorspazerbeam.bmsad",
"actors/props/doorcreature/charclasses/doorcreature.bmsad",
"actors/props/doorwave/charclasses/doorwave.bmsad",
]
for creature_bmsad_file in creature_bmsad_files:
cr_bmsad = editor.get_parsed_asset(creature_bmsad_file, type_hint=Bmsad)
cr_bmsad.raw["components"]["SCRIPT"] = SCRIPT_COMPONENT
action_set_anim = cr_bmsad.action_sets[0].raw["animations"][0]
action_set_anim.event_counts[0] = action_set_anim.event_counts[0] + 1
action_set_anim["events0"].append(ON_DEAD_CB)
action_set_anim["animation_id"] = 30
editor.replace_asset(creature_bmsad_file, cr_bmsad)

beam_types = {"doorwave", "doorspazerbeam", "doorcreature"}
for area in ALL_AREAS:
editor.ensure_present_in_scenario(area, "actors/props/doors/scripts/doors.lc")
editor.ensure_present_in_scenario(area, "actors/props/doorspazerbeam/collisions/doorspazerbeam.bmscd")
editor.ensure_present_in_scenario(area, "actors/props/doorspazerbeam/models/doorspazerbeam.bcmdl")
scenario = editor.get_scenario(area)
actor_list_copy = {actor_name: actor for layer, actor_name, actor in scenario.all_actors()}
for actor_name, actor in actor_list_copy.items():
if actor.type in beam_types:
new_actor_name = f"{actor_name}_o"
new_actor = editor.copy_actor(
area, (actor["x"], actor["y"], actor["z"]), actor, new_actor_name, 9
)
if new_actor["unk06"] == 0.0:
new_actor["unk05"] = 0
new_actor["unk06"] = 180
new_actor["unk07"] = 0
elif new_actor["unk06"] == 180.0:
new_actor["unk05"] = 0
new_actor["unk06"] = 0
new_actor["unk07"] = 0
else:
# that one is weird (because of fake surface west ?)
if area == "s000_surface" and actor_name == "LE_SpazerShield_Door_012":
continue
raise Exception

# no idea if this really gets the right door
door_name = actor_name[actor_name.find("Door"):]
door_name = door_name.replace("ShieldPlasma", "").replace("ShieldWave", "")
door_actor = actor_list_copy.get(door_name, None)
if door_actor is None:
door_actor = actor_list_copy[door_name.replace("_", "")]
door_actor.components.append(copy.deepcopy(door_actor.components[0]))
door_actor.components[1]["arguments"][3]["value"] = new_actor_name

def patch_shields(editor: PatcherEditor):
# TODO: Commit MEDS changes
editor.add_new_asset("actors/props/doors/scripts/doors.lc", files_path().joinpath("doors.lua").read_bytes(), [])

_patch_missile_covers(editor)
_patch_beam_covers(editor)
1 change: 1 addition & 0 deletions tests/test_files/thanatos_dev_heat_5_1.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
},
"starting_items": {
"ITEM_MAX_LIFE": 599,
"ITEM_MAX_SPECIAL_ENERGY": 1000,
"ITEM_WEAPON_MISSILE_MAX": 50,
"ITEM_WEAPON_SUPER_MISSILE_MAX": 10,
"ITEM_WEAPON_POWER_BOMB_MAX": 0,
Expand Down

0 comments on commit ef8849a

Please sign in to comment.