Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added directory for migration scripts and added item_ball migration script #3997

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions migration_scripts/README.md
Original file line number Diff line number Diff line change
@@ -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"
},
```
85 changes: 85 additions & 0 deletions migration_scripts/item_ball_refactor.py
Original file line number Diff line number Diff line change
@@ -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()

pkmnsnfrn marked this conversation as resolved.
Show resolved Hide resolved
# 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
Comment on lines +11 to +14
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those need changing if you run it from a sub-folder right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah, I just tested it in a different Emerald and it seems to work, but somebody else should check on me on this.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is odd. Afaik . is the root folder so it shouldn't work? I'll test it tomorrow.

Copy link
Collaborator

@AlexOn1ine AlexOn1ine Jan 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, just tested. It doesn't work. It needs to be changed to the parent directory.

Well, Idk. I guess a decision should be made here since you can run the script from the root folder python sub-folder/script.py. I guess it doesn't really matter but I would probably move into the scripts folder to run it if I didn't know better.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Migration scripts are executed by running the following commands from the root directory of a developer's project.

chmod +x migration_scripts/*.py ;
python3 migration_scripts/*.py ;

these are the instructions in the README. Do these instructions fail?

OR did you do:

cd migration_scripts ;
chmod +x *.py ;
python3 *.py

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that python3 migration_scripts/*.py works. I'm just saying that people will go into the sub-folder and run the script from there without reading the instructions. Which will not work.

Btw is there a reason to add the executable permissions? It works fine without.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ig it's not really an important conversation. Whether you go into the folder and run the script from there or specify the correct path to it does accomplish the same thing in the end. Maybe there is a way to sneak in an Error Message if you run it from the wrong path?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay.

I don't think there's a good way to make sure it runs no matter where you run the script from. I could be wrong.

If a dev doesn't read the file called README, and then just runs a python script without context...

I'll remove the chmod line.

An error message would is a good idea!


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!")
Loading