diff --git a/migration_scripts/README.md b/migration_scripts/README.md new file mode 100644 index 0000000000..5845348cdf --- /dev/null +++ b/migration_scripts/README.md @@ -0,0 +1,54 @@ +# Migration Scripts + +## What are migration scripts? + +pokeemerald-expansion rewrites existing systems in pokeemerald to improve their efficiency and make them easier to use and implement for developers. If developers were previously using a system that has been deprecated, it can be difficult to manually migrate between systems. + +These scripts exist to help developers make the transition between refactored systems. + +## Requirements + +All migration scripts require [`python3`](https://www.python.org/downloads/) to be installed. Migration scripts are executed by running the following commands from the root directory of a developer's project. + +```bash +chmod +x migration_scripts/*.py ; #give permision to make the script executable +python3 migration_scripts/*.py ; #run the migration script +``` + +`*` will need to be replaced with the name of the appropriate script. + +### Item Balls + +* Filepath [`migration_scripts/item_ball_refactor.py`](item_ball_refactor.py) +* Introduced in [Item Ball refactor / Pluralize item names for giveitem and finditem #3942](https://github.com/rh-hideout/pokeemerald-expansion/pull/3942) + +Modifies all item ball scripts defined using to original Game Freak method to the new refactored method. + +#### [data/scripts/item_ball_scripts.inc](../data/scripts/item_ball_scripts.inc) +```diff +- Route102_EventScript_ItemPotion:: +- finditem ITEM_POTION ++ Common_EventScript_FindItem:: ++ callnative GetObjectEventTrainerRangeFromTemplate ++ finditem VAR_RESULT + end +``` + +#### [data/maps/Route102/map.json](../data/maps/Route102/map.json) +```diff + { + "graphics_id": "OBJ_EVENT_GFX_ITEM_BALL", + "x": 50, + "y": 5, + "elevation": 3, + "movement_type": "MOVEMENT_TYPE_LOOK_AROUND", + "movement_range_x": 1, + "movement_range_y": 1, + "trainer_type": "TRAINER_TYPE_NONE", +- "trainer_sight_or_berry_tree_id": "0", +- "script": "Route102_EventScript_ItemPotion", ++ "trainer_sight_or_berry_tree_id": "ITEM_POTION", ++ "script": "Common_EventScript_FindItem", + "flag": "FLAG_ITEM_ROUTE_102_POTION" + }, +``` diff --git a/migration_scripts/item_ball_refactor.py b/migration_scripts/item_ball_refactor.py new file mode 100755 index 0000000000..f121978ec8 --- /dev/null +++ b/migration_scripts/item_ball_refactor.py @@ -0,0 +1,85 @@ +import glob +import re +import json +import os + +if not os.path.exists("Makefile"): + print("Please run this script from your root folder.") + quit() + +# scan incs +incs_to_check = glob.glob('./data/scripts/*.inc') # all .incs in the script folder +incs_to_check += glob.glob('./data/maps/*/scripts.inc') # all map scripts +pories_to_check = glob.glob('./data/scripts/*.pory') ## all .porys in the script folder +pories_to_check += glob.glob('./data/maps/*/scripts.pory') # all map scripts + +array = [] +array_pories = [] + +# make a list of which script corresponds to which item +for file in incs_to_check: + with open(file, "r") as f2: + raw = f2.read() + array += re.findall("(.*)::\n[ ]*finditem (.*)\n[ ]*end", raw) + +# since this doesn't catch poryscript-generated inc files, do the same for poryscript +for file in pories_to_check: + with open(file, "r") as f2: + raw = f2.read() + array_pories += re.findall("script ([\w]*)[ \n]*\{[ \n]*finditem\((.*)\)[ \n]*\}", raw) + +dict = {} +# poryscript values are prioritised because they would overwrite inc files anyway if different +for x in array_pories: + dict[x[0]] = x[1] +for x in array: + if not x[0] in dict: + dict[x[0]] = x[1] + +# apply changes to inc files +for map in glob.glob('./data/maps/*/map.json'): + with open(map, "r") as f2: + data = json.load(f2) + if not 'object_events' in data: + continue + for objevent in data['object_events']: + if objevent["script"] in dict: + objevent["trainer_sight_or_berry_tree_id"] = dict[objevent["script"]] + objevent["script"] = "Common_EventScript_FindItem" + with open(map, "w") as f2: + f2.write(json.dumps(data, indent=2) + "\n") + +# do another map search to find out which finditem scripts would somehow be still in use +still_in_use = [] +for map in glob.glob('./data/maps/*/map.json'): + with open(map, "r") as f2: + data = json.load(f2) + if not 'object_events' in data: + continue + for objevent in data['object_events']: + if objevent["script"] in dict and not objevent["script"] in still_in_use: + still_in_use.append(objevent["script"]) + +for x in list(dict.keys()): + if x in still_in_use: + del dict[x] + +# clean up scripts that are now no longer in use +for file in incs_to_check: + with open(file, "r") as f2: + raw = f2.read() + for unused in list(dict.keys()): + raw = re.sub("%s::\n[ ]*finditem (.*)\n[ ]*end\n*" % unused, "", raw) + with open(file, "w") as f2: + f2.write(raw) + +# also clean up pory files +for file in pories_to_check: + with open(file, "r") as f2: + raw = f2.read() + for unused in list(dict.keys()): + raw = re.sub("script %s[ \n]*\{[ \n]*finditem\((.*)\)[ \n]*\}[ \n]*" % unused, "", raw) + with open(file, "w") as f2: + f2.write(raw) + +print("Done!")