SilverstarStream Posted April 9, 2021 Share Posted April 9, 2021 I've been working on a gym shuffler using dabomstew's randomizer as a base, and I started with Platinum. It shuffles the warps so that each city connects to a random gym. I've been using Spiky's DS Map Editor and its code as reference to implement everything so far, but I'm having trouble figuring out how gyms' trainers check for badges. Is there a way to change the badge-checking condition for gym trainers? After looking over some topics here, it seems like I need to edit "level scripts" to change what I want to change. If I'm on the right track with level scripts, is there a (open-source) tool I can use to edit them? If there's not any, where in the ROM structure are level scripts, and is there any documentation on how they work? Link to comment Share on other sites More sharing options...
Delta Blast Burn Posted April 12, 2021 Share Posted April 12, 2021 (edited) I believe "level scripts" are just the scripts associated with each map. You should be able to use ppre to edit them for dppt. As for documentation, I believe the project pokemon wiki has the info you need. Edited April 12, 2021 by Delta Blast Burn more info Link to comment Share on other sites More sharing options...
SilverstarStream Posted April 14, 2021 Author Share Posted April 14, 2021 (edited) After poking around I’ve figured out what my problem was. This is also a reminder to myself and other programmers to take a break from hard problems from time to time; it really does helps clear the head. I’m posting what I’ve figured out here, and I’ve edited the title to both better reflect what my problem actually was and so that it can be searched for a little easier in case anyone else is looking for this kind of stuff. One of the things overworlds do is define a trainer’s behavior. Each overworld in a map’s event file has a script field with a script number in it. This script number will either be relatively small (usually < 10), or >= 3000. If the number is >= 3000, a trainer battle is called. In this case, there’s no scripted behavior and instead the game stops player’s movement, pulls up a text box, and starts the battle. The trainer battle it calls is the script number minus 2999 (0xBB7), so to call trainer battle 10, the script number for that trainer’s overworld should be 10 + 2999 = 3009. Gardenia’s gym is an exception and calls scripts since her trainers need to move the clock and fountains after you win their battle. Otherwise, when the script number is small, the overworld calls that script number within that map’s script file*. Gym trainers don’t actually check the player’s badges to determine whether they can fight the trainer. They can check badges if scripted for it, but they don’t. Instead, gym trainers get marked as already battled in the function called by the gym leader once the player wins. It uses the SetValue “instruction” (in SDSME; in PPRE it’s the SetTrainerID instruction), so SetValue 0xF4 and SetValue 0xF5 mark trainers 244 and 245 as battled, which are the two trainers in Oreburgh’s gym. Removing these instructions let me battle them after Roark. I was swapping these instructions over to the other gym leaders’ scripts, so battling the leaders out-of-order but changing the badge I received to be the one received for that city led me to assume that gym trainers checked badges. Also, maybe I could have been a little bit more specific with what I was doing and had already accomplished in my first post. However, I didn’t want to bog it down with jargon and details that people might not understand. *Specific technical stuff here, it probably isn’t too useful to most ROM hackers. In both SDSME and PPRE, a script file’s functions are split into “scripts” and “functions.” From what I can tell the only difference between these two is whether or not their offset is mapped in the script file’s header. The header has some number of consecutive 32-bit integers and is ended by the 16-bit delimiter 0xFD13 (big-endian; it’s 0x13FD in the actual file). Each of those 32-bit integers is the offset - 4 of the start of some function in the file. If a function’s offset is referenced in the header, it’s a script. Otherwise if it isn’t referenced in the header, it’s a function. A function can only be called by an overworld if it is a script, so in turn it has to have its offset defined in the script file’s header. I should also note that the header and script numbers are 1-based instead of 0-based. So the first 32-bit integer in the header (the first 32 bits of the file), at offset 0, is referenced by script number 1. Also minor gripe: naming the functions in script files “scripts” and “functions” in PPRE and SDSME is confusing and misleading. The script files containing something called scripts is confusing. “Scripts” are not really any different from functions, so it would have been better to call them “overworld functions” or “marked functions”, or something. Edited April 15, 2021 by SilverstarStream Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now