Binary Hack Research & DevelopmentGot a well-founded knack with your binary Pokémon hacks? Love reverse-engineering them? For the traditional Pokémon ROM hacker, this is the spot for polling and gathering your ideas, and then implementing them! Share your hypothesis, get ideas from others, and collaborate to create!
I am concerned about this small section... what if the hack does not have a DNS inserted. or is not using RTC at all. just vanilla red. could this still work? or is there a change that makes it pick a new map every time you change maps (like it did in original GS)
I would be very interested in making this into a tool for quick insertion. but I would want it to be usable as a standalone tool if the user did not have a RTC, if they did however, they could use this tool aswell (with a time limit like it currently is).
It's using the ingame timer. So the play time timer, which imo is the best and only timer you'll ever need. There's no RTC you would need for this :)
It's using the ingame timer. So the play time timer, which imo is the best and only timer you'll ever need. There's no RTC you would need for this :)
VERY COOL!
since you brought up the in game timer (which i never knew was accessible) could you make it accessible in script.
so if I wanted to give the player 30 seconds to get through a door I could get the timer value and store it, then at the door, compare the current value to the stored value value + 30seconds and if the current value is later than that, slam the door in their face...
now that thats done, would you be terrably upset if I made a tool/program to insert your roaming hack. since its awesome and difficult lol (of course all the credits go to you)
A breif intro to those who don't know, there is an ingame timer in Fire Red which counts a little over to 41 days worth of play time. The timer can be cleverly manipulated to behave like a clock or timer because it has proper incrementations at every second, minute and hour. I wrote a few routines which you can use for timing routines and to return the current ingame Hours, mins and seconds.
Current Time into variables
This routine basically takes the current ingame hours, minutes, and seconds and places the three into the variables 0x8000 = hours(2 bytes), 0x8001 = mins(1 byte), 0x8002 = seconds(1 byte). I suppose you can merge into 0x8001 both the minutes and seconds, but this way is easier to access.
How to insert:
Compile and insert the following routine into free space.
Usage:
In a script callasm 0x[where you inserted this routine +1]. The variables 0x8000, 0x8001, 0x8002 will be updated with the current hours, minutes and seconds respectively.
Minutes Played
This routine will return your total play time in the form of total minutes played. The resulting number of minutes is a half word stored in variable 0x800D (lastresult)
To insert:
Simply compile and insert into free space the following routine:
Spoiler:
Code:
.text
.align 2
.thumb
.thumb_func
main:
push {r0-r2, lr}
ldr r0, .PlayTime
ldr r0, [r0]
add r0, r0, #0xE @hours
ldrh r1, [r0]
mov r3, #0x3C
mul r1, r1, r3 @minute representaiton of hour
add r0, r0, #0x2 @mins
ldrb r2, [r0]
add r1, r1, r2 @get total ingame mins spent
ldr r0, =(0x20370D0) @store minutes played in lastresult
strh r1, [r0]
pop {r0-r2, pc}
.align 2
.PlayTime:
.word 0x300500C
In a script callasm 0x[This routine's offset +1]. The amount of minutes played will be inserted into the lastresult or variable 0x800D. That's it.
Seconds Played
This one is a little special in the sense that I use the Minutes Played routine to help save some work generating the amount of seconds played.
How to insert:
To insert this routine you first need to have inserted the Minutes Played routine (one above this one). After that, look at the text in orange. You need to replace that with a pointer to where you inserted the routine +1.
Sorry no compiled version. You need to fix the pointer and compile yourself :P
Usage:
The pointer to the number of seconds is at RAM location 0x20370B8 and is 4 bytes long (though the first byte is 00 always). So to use in a script, you would callasm 0x[this routine +1] and then the value will be in 0x20370B8 and extend to 0x20370BC. It's accessed the same way as you would access a variable.
How to use these to make timed events:
This section is basically for noobs, so if you know what you're doing, carry on :P
If the timer for the event is less than 1 minute use the seconds played. Before starting the event, call seconds played, store the values it returns. Then at the end of the event call the seconds routine again. Subtract the new return with the return from the first time calling the routine. The resulting number is the amount of seconds which have passed since the start of the event.
If your timer is more than or equal to 1 minute, use the minutes timer. It's much easier to use because the return is in 0x800D (lastresult). Take the return and copy it into a variable. Then at the end of the event call it again and subtract the new one with the old one. The amount of time passed in minutes is the result.
If for some reason, you wanted to display start time in the format Hours, minutes, seconds, you would use the first routine where certain variables contain these values.
Quote:
Originally Posted by LocksmithArmy
since you brought up the in game timer (which i never knew was accessible) could you make it accessible in script.
now that thats done, would you be terrably upset if I made a tool/program to insert your roaming hack. since its awesome and difficult lol (of course all the credits go to you)
Yes I can make it accessible in a script :P
I don't mind if you make a tool at all.
Mini-update (not really mini kinda a big deal)
I've upgraded the original party level set function to work in constant time. Now it's quite instantaneous regardless of the level difference. Anyways, for the guy who was talking about skipping the introduction and saving the game afterwards, I've talked to both Touched and Bela. Bela gave me permission to post it, and Touch gave me the code (I forgot to ask him, but he loves me so it's probably OK).
Here are the byte changes he wants you to do in order to achieve an intro skip similar to Pokemon Rose (which you guys should all checkout, Bela's it's quite an awesome project).
Assuming you want to just use the Oak intro, but want to skip the naming of the player and the rival, which bytes would you change, and which ones would stay??
You really need to check out the script in a cut tree...
setvar 0x8002 0x1 //aka bulbasaur setvar 0x8003 0x1 // aka pound....... callasm 0xsomething...this would check the whole party for a bulbasaur with pound. -_- i am not talking about checkattack.
Assuming you want to just use the Oak intro, but want to skip the naming of the player and the rival, which bytes would you change, and which ones would stay??
I have no clue how Touched did any of that. You'd be best off asking him :D
Quote:
Originally Posted by Knight of Duty
setvar 0x8002 0x1 //aka bulbasaur setvar 0x8003 0x1 // aka pound....... callasm 0xsomething...this would check the whole party for a bulbasaur with pound. -_- i am not talking about checkattack.
You will have to use partyChecker to fetch the slot of bulbasaur. Then a modified version of party check. For the modified version, you just remove the loop and set r5 = return from the first PartyChecker. Simple stuffs :x
Quote:
Originally Posted by Dark Sneasel
Little suggestion here, even though I don't hack FR, but I think it'd be hella dank cool asf 420
How about perhaps possibly maybe new weather effects? As in, in the OW and in battle?
Not only would that require graphical hacking to modify the overworld weather/in battle weather. But for making it actually do anything in battle you'd need to use battle scripts. That being said, you can use battle by turn to make doing this a little easier. I'm not going to do it, but out of curiosity, what weather pattern did you have in mind?
Some research on setting Trainer OT, Gender, Trainer ID for pokemon captured
First of all, getting the data. If you're battling a trainer, the trainer name doesn't actually sit in RAM. So you need to derive it from the ROM. The way the game gets it (which is the way you should do it), is that it takes the current trainer flag (Trainer ID in A-trainer), and uses that to search the base trainer table for the trainer's name. I've written some code with accomplishes that. (See end of post). This trainer data structure appears to be 40 bytes long, and to reach a specific index, you do table pointer + ((ID -1) * 40).
The second piece of data, is obviously Gender. This actually doesn't seem to be used at all? I'm not 100% sure. Anyways, the gender byte is attached to the intro music as well. The gender in the table is determined by the most highest bit in the byte and the rest seems to be just the music. So if the byte is "0x86" then the trainer is female (0x80 = 10000000 in binary) and the entry music is 6. (I've written code to retrieve this, see end of post..again :P)
Finally Trainer ID. I have no clue how or where this is being derived in battle. I can probably find out, but that would require a little more research on what is appearing to be a dead end. I'm calling it a dead end because trainer ID seems to turn your Pokemon into a bad egg immediately if you change it. Unlike OT gender and OT name, PID and TID seem to have a close knit relationship in the checksum. Not only can you not change this in battle, but surprisingly you can't change it in overworld using the encrypter.
So where does this put us in terms of capturing other trainer's Pokemon? Well, in short it's looking bleak. The OT name, and gender cannot be changed in capture or the Pokemon will result in a bad egg. However, you can use the encrypter function to change these later after capture (once you reach the overworld). The other small stroke of luck, is that the trainer flag isn't wiped after the battle, or after a wild battle. So as long as you don't battle another trainer you can derive the name of the last trainer you fought.
I made a routine which retrieves the name and gender of the trainer you just faced, and assigns their name/gender as the original name/gender for a Pokemon in your party. I tried to use a modified version of this routine during the battle, but it just bad egg'd my Pokemon, which was kinda frustrating X_X
So this is the routine I used at the Pokemon capture sequence to set the values
Spoiler:
Code:
.text
.align 2
.thumb
.thumb_func
main:
ldr r6, .battleType @check if it's a trainer battle
ldrb r6, [r6]
cmp r6, #0x4
beq oldStuff
mov r6, r0
ldr r2, .trainerData @table to trainer data
ldr r0, =(0x20386AE)
ldrb r0, [r0]
sub r0, r0, #0x1
mov r1, #0x28
mul r1, r1, r0
add r2, r2, r1 @pointer to trainer's name
mov r4, r2
mov r0, r6 @pokemon
mov r1, #0x7
ldr r3, =(0x804037C +1) @set OT name
bl linker
mov r0, r6 @pokemon
mov r2, r4
sub r2, r2, #0x1 @gender byte
lsl r2, r2, #0x18
lsr r2, r2, #0x1F @Isolate first bit on the last byte, which is gender
mov r1, #0x31
ldr r3, =(0x804037C +1) @set OT gender
bl linker
oldStuff:
mov r6, r0
mov r5, #0x0
ldr r0, =(0x8040B46 +1)
bx r0
linker:
bx r3
.align 2
.battleType:
.word 0x2022B4C
.trainerData:
.word 0x823EAF4
That one has no use, except maybe making every trainer Pokemon you capture a bad egg :(
Here's the same routine modified for use in the overworld:
Spoiler:
Code:
.text
.align 2
.thumb
.thumb_func
main:
push {r0-r6, lr}
ldr r0, =(0x20370B8) @slot of pkmn to modify
ldrb r1, [r0]
mov r2, #0x64
mul r1, r1, r2
ldr r0, =(0x2024284)
add r0, r0, r1
mov r6, r0
ldr r2, .trainerData @table to trainer data
ldr r0, =(0x20370BA) @var 0x8001 = trainer's ID
ldrb r0, [r0]
sub r0, r0, #0x1
mov r1, #0x28
mul r1, r1, r0
add r2, r2, r1 @pointer to trainer's name
mov r4, r2
mov r0, r6 @pokemon
mov r1, #0x7
ldr r3, =(0x804037C +1) @set OT name
bl linker
mov r0, r6 @pokemon
mov r2, r4
sub r2, r2, #0x1 @gender byte
lsl r2, r2, #0x18
lsr r2, r2, #0x1F @Isolate first bit on the last byte, which is gender
mov r1, #0x31
ldr r3, =(0x804037C +1) @set OT gender
bl linker
pop {r0-r6, pc}
linker:
bx r3
.align 2
.battleType:
.word 0x2022B4C
.trainerData:
.word 0x823EAF4
Compile and insert anywhere in free space. Set in variable 0x8000 the slot number of the Pokemon whose name you want to change, and set in 0x8001 which trainer ID (same as ID # from A-trainer) to derive the name and gender from. I hope this is good enough for the original requester. I believe she wanted me to make a routine to allow her to steal trainer's Pokemon outside of battle, well, you can't steal a trainer's Pokemon if you have six. So you can use this in your steeling script (obviously the slot number would be equal to party size).
Anyways, this was rather disappointing. I hoped to have been able to get this done properly, but it didn't seem to work. A failed project. I hope just the research and trainer name\gender fetching routines alone will be helpful for some people. I don't think I'll be updating the first post with this though :x
Do you think there would be a way to make a pokemon's offensive and defensive typing different? Like perhaps making a pidgey act like a flying type when dealing damage but act like a psychic type when taking damage. My thought would be to tie defensive typing to personality value so individual pokemon would feel "strong" and "weak" to different things.
So last time I did just a quick swap one Pokemon at a time. Here I made some code basically "mass-swap" the storage and the current Player's party all at the same time.
How to insert:
Compile and insert into free space the following routine:
Usage:
Just callasm to the routine +1. Be careful though, always check that the storage isn't empy. You can swap out your entire party for no Pokemon and create a nice little bugged questionmark when you open the Pokemon menu (the one in my avatar :3).
This time instead of a script I present to you a video :D
I've read through these a couple of times, and have one question is there a way to pre-store pokemon into the PSS to transfer out??; store 2 pokemon which will be traded with current party during an event
How it works:
So I use the variables 0x8000 and 0x8001 again.
0x8000 Should be set to Pokemon species (2 bytes)
0x8001 Needs to be set to Item ID (1 byte...can be changes to 2 if you inserted more than 255 items)
case 1:
If a Pokemon in your party has the item specified by 0x8001 and the species matches 0x8000, return that Pokemon's slot
case 2:
If 0x8000 is set to 0x0 (no species), the routine will search your whole party and return the slot of the Pokemon holding the item specified in 0x8001
case 3:
If no Pokemon in the party are holding the item, returns 0x6.
The result will be stored in variable 0x8000. The result will, obviously, be 0x0-0x5 (slot) for item found and 0x6 for not found.
How to insert:
Compile and insert into free space the following routine:
Because, I want in my script, if I have Eevee holding Masterball then it jumps in an offset and if it has no eevee holding masterball then it jumops in other offset
__________________
This signature has been disabled.
Scrollbar appears
Please review and fix the issues by reading the signature rules.
You must edit it to meet the limits set by the rules before you may remove the [sig-reason] code from your signature. Removing this tag will re-enable it.
Do not remove the tag until you fix the issues in your signature. You may be infracted for removing this tag if you do not fix the specified issues. Do not use this tag for decoration purposes.
If anyone could help me out implementing Ditto's Imposter ability into Firered, that would be outstanding.
*FBI doesn't do battle scripts, but hopes that someone who does will pick this up for you*
Quote:
Originally Posted by heribrand
Do you think there would be a way to make a pokemon's offensive and defensive typing different? Like perhaps making a pidgey act like a flying type when dealing damage but act like a psychic type when taking damage. My thought would be to tie defensive typing to personality value so individual pokemon would feel "strong" and "weak" to different things.
*FBI doesn't do battle scripts, but hopes that someone who does will pick this up for you*
Quote:
Originally Posted by Turtl3Skulll
I've read through these a couple of times, and have one question is there a way to pre-store pokemon into the PSS to transfer out??; store 2 pokemon which will be traded with current party during an event
Yeah, you call the same routine twice giving a different slot number each time.
Quote:
Originally Posted by Dark Zeta
Would it be possible to make routines for the forme mons?
Specifically Arceus, Giratina, and Shaymin.
You already have a silent evolution routine working. This handles Deoxys already. The coding to change Rotom's attacks isn't difficult (I was able to do it on my other computer, but it was sloppy.)
You have new hold items made, party item checker, and silent evolution routines that work. If you could mix the 3 then that would probably do the trick (taking into account changing Arceus move type for Judgement. Not difficult though). This would handle Arceus and Giratina.
Shaymin is the most difficult imo. It requires the silent evolution with a time check. That's not too bad in a script. The problems arise when calling the script to change forme at night and in-battle change when it is frozen.
Public routines for formes would be a massive contribution to the entire community. At least, that's how I feel.
Hi, I agree that would be awesome. However, daniilS has already started on this and I don't want to ninja him. You can cheer him on\ask him how it's going by VMing him maybe :3
Quote:
Originally Posted by BLAxTOISE
I've came up with two new suggestions, both of them about Marts, to allow a better customization of them.
1.- Set different prices for the items regardless the original prices you put on an Item Editor.
2.- Make some items unavailable to purchase after having purchased one, like the TM on latest games.
I don't understand the point in number one. Why would you make a hack with different prices when you can fix the prices in the item editor? It just doesn't make sense to me :/
For 2, you can do this in a script I believe. Set a flag when the item is purchased and make it impossible to purchase more if that flag is set.
Quote:
Originally Posted by Lance32497
Will this works?
Because, I want in my script, if I have Eevee holding Masterball then it jumps in an offset and if it has no eevee holding masterball then it jumops in other offset
No that won't work. In the usage section of the post you've quoted it says:
setvar 0x8000 0xspecies
setvar 0x8001 0xItemID
callasm 0x[Where you inserted the above routine +1]
So if you wanted to see if there was an Eevee with a masterball, you'd do:
setvar 0x8000 0x85
setvar 0x8001 0x1
callasm 0x[offset +1]
I don't understand the point in number one. Why would you make a hack with different prices when you can fix the prices in the item editor? It just doesn't make sense to me :/
In the games, "sales" for the big shopping stores can happen randomly. Guessing he may be trying to have some control over it.
I don't think this needs any routines though. You could always create an NPC that sells you an item for a set price. Unless you make your own multichoicebox, it will only be able to sell one item type at a time. :s
Yeah, you call the same routine twice giving a different slot number each time.
I know that part, but I meant can pokemon be stored there which the player does not have, or has not store in them??
Such that when the game starts you can have a whole party stored in PSS & trade it for your starter pokemon at the beginning of the game?? or does it require you to have to manually store the pokemon in the PSS as a trainer??
Quote:
Originally Posted by FBI agent
I don't understand the point in number one. Why would you make a hack with different prices when you can fix the prices in the item editor? It just doesn't make sense to me :/
That's actually a pretty cool idea, it can make it so there's an economy-like atmosphere that in certain events, it crashes & the price of all items skyrockets or black markets being implemented as well.
I've got a suggestion.
It would be interesting to lower the players speed in half, both while walking and running, while walking on specific tiles.
Or better yet being able to control the speed, say speed in lowered slightly when walking in mud, puddles, or tall grass.
Pokemon ORAS has a similar feature when you step in sand.
This may go hand in hand with research done on the dual geared bikes if you choose to work on it.
Oh, wow, thank you so much for taking a shot at my stupidly complicated request! I’ll definitely be using the routines you posted, which should be more than good enough for what I’m wanting to do :) so thanks again!
I think with a bit of ingenuity and resourceful use of the PSS, I can get over the final hurdle, too – which is enabling steal events even when the player has a full party of six. (I just don’t want to force people to be constantly heading back to the PC to dump their new Pokémon so that they don’t miss out on an event. It always annoyed me when I had to do that in the official games, haha.) So, yeah, here’s my idea…
For a Snag Ball battle, I’d use countpokemon before starting the battle. Then, if the result is <5, I can just use your lovely routine as provided. :) If it’s 0x6, though, I could activate the PSS intercept system to push any snagged Pokémon into the PSS.
That done, I could take advantage of the fact that OTs can be modified in the overworld, and do that inside the PSS. Then (hopefully) I could push the Pokémon out of the PSS and into storage.
This would circumvent the problem I currently have, which is that Pokémon snagged by a Snag Ball go straight into the PC without the correct OT attached (if the player has a party of six). It’d also work for givepokemon events, which I’d be using as ‘steals’ – I’d countpokemon first, then activate the intercept and do much the same thing as for the snagged monsters.
So I just have a couple of questions, really:
1) Does the PSS intercept routine work on the givepokemon command as well as with captures? (Also, how safe is the nicknaming bit of the intercept routine? I saw it was commented out...)
2) Is there a way to push Pokémon from the PSS into PC storage space?
Oh, and I’m assuming that renaming the OT of a Pokémon in the PSS would be as simple as using your existing overworld routine, but replacing this line:
Code:
ldr r0, =(0x2024284)
with this:
Code:
ldr r0, =(0x203C001)
My ASM knowledge is pretty much based on staring at your code in wonder and bemusement and painstakingly trying to figure out how the magic happens, though, so please feel free to correct me if I’m being stupid :P
2: a way to stop the player using running shoes in certain areas
The map header will allow or prevent the player from being able to run (there are several threads on this topic)
if you search the forums you should be able to do this.
of course if you are looking for a way to do this within a map(some parts of a map you can run, others you cannot), idk.
a script for this would be cool, so we could put green S tiles and as the player ran over them they would stop running and walk, (or visa versa)
The map header will allow or prevent the player from being able to run (there are several threads on this topic)
if you search the forums you should be able to do this.
of course if you are looking for a way to do this within a map(some parts of a map you can run, others you cannot), idk.
a script for this would be cool, so we could put green S tiles and as the player ran over them they would stop running and walk, (or visa versa)
Can't you just remove the running shoes temporarily?
Oh, and I’m assuming that renaming the OT of a Pokémon in the PSS would be as simple as using your existing overworld routine, but replacing this line:
Code:
ldr r0, =(0x2024284)
with this:
Code:
ldr r0, =(0x203C001)
Please don't do that. Pokemon data is stored in 100 bytes for the party, but the Pokemon stored in the PC is a different matter. It only records 80 bytes of the structure. And if my 10 second glance at FBI's PSS routine didn't deceive me, FBI stored 80 bytes for each Pokemon, which means that if you just change that line, you are going to screw yourself over.
FBI how about
...
setvar 0x8000 0x85
setvar 0x8001 0x1
callasm 0x800001
compare LASTRESULT 0x1
if = goto @1
...
what I want is the NPC will check if the player has eevee holding masterball, if it has it will jump to #org @1 and if it doesnt have it will jump to #org @2.. I dont understand how the game will check if I have eevee with well in fact it just set a var but nothing to compare with, like in flag, checkflag will check if the desired flag has been set.
__________________
This signature has been disabled.
Scrollbar appears
Please review and fix the issues by reading the signature rules.
You must edit it to meet the limits set by the rules before you may remove the [sig-reason] code from your signature. Removing this tag will re-enable it.
Do not remove the tag until you fix the issues in your signature. You may be infracted for removing this tag if you do not fix the specified issues. Do not use this tag for decoration purposes.
I don't understand the point in number one. Why would you make a hack with different prices when you can fix the prices in the item editor? It just doesn't make sense to me :/
For 2, you can do this in a script I believe. Set a flag when the item is purchased and make it impossible to purchase more if that flag is set.
For number one I mean to be able to have like a discount store, where items cost half their original price.