PDA

View Full Version : Uncatchable Pokemon


metapod23
April 25th, 2011, 07:21 PM
I was just wondering if there was a way we could take special 0x156 for the ghost Pokemon battle in Fire Red and remove the beginning where it has the silph scope identify the ghost - basically just have it open up with the Pokemon identified and no ghost message.

This would be essentially the same as having an uncatchable Pokemon. I'm using JPAN's engine, which allows pretty much any Pokemon to appear, but I want to use it to make various special Pokemon appear in wild battles as actual Pokemon (not ghosts) that are not intended to be captured by the main hero

Having the silph scope or not shouldn't be a problem, since you can just give that to the player before the special and remove it afterwards.

I know there would be some ASM involved, but I'm hoping it wouldn't be overly complicated.

Darthatron
April 29th, 2011, 04:19 AM
Would setting the catch rate to 0 (zero) not have the same effect? If not, I think it would be easier to add a "Branch if zero" command before the catch check routine. Using this seems a tad silly to me.

Banjora Marxvile
April 29th, 2011, 07:35 AM
Would setting the catch rate to 0 (zero) not have the same effect?

I think the idea is a special event sort of thing, where the Pokemon can be fought then, yet not captured, but other Pokemon of that can be caught later in the wild, like a Mew that you are advised not to catch early on, due to it needing to do something to balance everything out, yet able to catch it later on.

Darthatron
April 29th, 2011, 07:40 AM
In that case, hacking the Pokeball routine to say "Now is not the time to use that..." if a flag is not set would probably be the best option. Frankly, changing the Ghost routine seems like a strange way of doing it. Not to mention it wouldn't work with Ruby/Sapphire/Emerald. :\

metapod23
April 30th, 2011, 03:39 AM
In that case, hacking the Pokeball routine to say "Now is not the time to use that..." if a flag is not set would probably be the best option. Frankly, changing the Ghost routine seems like a strange way of doing it. Not to mention it wouldn't work with Ruby/Sapphire/Emerald. :\

The Marowak/Ghost battle has a routine where, when you throw a Poke Ball, the Pokemon dodges to the side so the ball misses and a message is displayed that says "This Pokemon cannot be captured." That's what I want most of all. If the routine for when the Pokeball is thrown can be changed so that when a certain flag or variable is set, that routine will activate in Fire Red, that would be perfect.

I wish I knew how to locate/display different routines/assembly instructions in the game. If anyone knows the location of the Poke Ball routine and how to hack it to add the Marawak Poke Ball routine when a certain flag/variable is set, let me know.

Derlo
April 30th, 2011, 05:15 AM
Wow..
I have done this routine for over a year ...

To do this simply just set a bite in the right place.
(dont remember where XD).

When I have free time, put a video of it here.

EDIT:
CrDeD7oZzds

Is not complete.. i forgot inser the routine to remove the text of MAROWAK GHOsT. ^^v

sonic1
April 30th, 2011, 08:31 AM
Yeah i remember this. Derlo, we both worked on this together, dont we remember (im darkrayquaza from myutsu).´

Actually im not in my usual Laptop of hacking, but i believe this is the offset (in ram): 02022B4C <-- Just mess around with values when you're in black screen right before the wild battle to get different effects. ;)

Derlo, confirm the offset plz

~Sonic1

metapod23
May 2nd, 2011, 04:58 AM
Yeah i remember this. Derlo, we both worked on this together, dont we remember (im darkrayquaza from myutsu).´

Actually im not in my usual Laptop of hacking, but i believe this is the offset (in ram): 02022B4C <-- Just mess around with values when you're in black screen right before the wild battle to get different effects. ;)

Derlo, confirm the offset plz

~Sonic1

Can you tell me exactly how I would go about changing the values in the ram?

sonic1
May 2nd, 2011, 08:43 AM
Go to tools menu in VBA and then go to memory viewer and in the blank box put the offset 02022B4C. Click enter and then edit the first 00 numbers that are in the memory viewer.

The reason you want to do this its because that changes the behaviour of the battle and its type. Example: if you set (exactly when the battle music starts, but before the black screen, WHEN THE VALUE IS 00 IN THAT OFFSET) 01 to that offset you get a wild double battle. if otherwise you put 08 to that offset, you get a trainerbattle (even if its a wildbattle!!). Find the value that makes the pokemon turn uncatchable. I already did that but i forgot what byte is....

~Sonic1

metapod23
May 2nd, 2011, 06:52 PM
Go to tools menu in VBA and then go to memory viewer and in the blank box put the offset 02022B4C. Click enter and then edit the first 00 numbers that are in the memory viewer.

The reason you want to do this its because that changes the behaviour of the battle and its type. Example: if you set (exactly when the battle music starts, but before the black screen, WHEN THE VALUE IS 00 IN THAT OFFSET) 01 to that offset you get a wild double battle. if otherwise you put 08 to that offset, you get a trainerbattle (even if its a wildbattle!!). Find the value that makes the pokemon turn uncatchable. I already did that but i forgot what byte is....

~Sonic1

Thanks, after some research I can say that it seems that 0x02022B4D is the byte that determines the ghost battle itself. If it's set to A0, B0, C0, D0, E0, or F0 it becomes an identified ghost (Silph Scope reveals it) Pokemon that can't be caught. If set to 80 or 90 it is the unidentifiable ghost which cannot be caught or battled.

Is this the information I need, and if so, what do I do with it?

EDIT: Also, interestingly, if you change the second part of the byte at that offset, it goes from the old man catching a wild Pokemon to a dialogue box that says "Items can't be used now" whenever you select "Bag."

sonic1
May 4th, 2011, 01:41 PM
Well now you would need to search where is the routine (the part of it) that sets the byte at 02022B4C to 00. In case you haven't noticed yet, the routine writes values to that adress (Which i usually call Battle Flag, so lets call it for now on) 2 times. The first time its for resetting the flag to 00 and the second time is to ADD (NOT SET!! <--IMPORTANT!) a value depending the original event (trainer or wild battle).
To help you, here's the offset of the final write (the one that's going to decide what type of battle it is): 0801065C. At this location you're going to find an asm command "str r1 [r2, #0x0]". This is when the routine sets the the value for the battle. Make a branch there and change r1 into the value whatever A0 or whatever the value you need to put the ghost battle before that command is executed.

~sonic1

metapod23
May 8th, 2011, 05:57 AM
Well now you would need to search where is the routine (the part of it) that sets the byte at 02022B4C to 00. In case you haven't noticed yet, the routine writes values to that adress (Which i usually call Battle Flag, so lets call it for now on) 2 times. The first time its for resetting the flag to 00 and the second time is to ADD (NOT SET!! <--IMPORTANT!) a value depending the original event (trainer or wild battle).
To help you, here's the offset of the final write (the one that's going to decide what type of battle it is): 0801065C. At this location you're going to find an asm command "str r1 [r2, #0x0]". This is when the routine sets the the value for the battle. Make a branch there and change r1 into the value whatever A0 or whatever the value you need to put the ghost battle before that command is executed.

~sonic1

^ But I want to remove the ghost part of the battle, like in the video Derio posted except without the Silph Scope message and transformation animation. The A0 value still causes all these things to happen - I need to alter the way the ghost battle itself works.

NarutoActor
May 8th, 2011, 07:07 AM
What I would do is have a check. If 0x8000 is set to 0x1 then go to the new edited version of the ghost battle, if not continue to the original ghost battle. That way you can have both routines, and have the new routine not be constricted by space.

metapod23
June 28th, 2011, 10:31 AM
Just bumping because I'm still interested in executing this, but still don't know what I'd need to do (what sort of routine I'd need to write and where the original routine is located) to alter the Marowak battle to remove the transforming sequence and the Ghost/Silph Scope text that appears.

Jambo51
June 28th, 2011, 12:24 PM
Just bumping because I'm still interested in executing this, but still don't know what I'd need to do (what sort of routine I'd need to write and where the original routine is located) to alter the Marowak battle to remove the transforming sequence and the Ghost/Silph Scope text that appears.

Do you still NEED the Marowak transformation thing? If not, it would be slightly easier to do. Do you still need the Pokémon in question to dodge the Poké Ball, or do you just want it to be "uncatchable"? (What I mean by this is do you want to be able to get it in a Poké Ball, but can't catch it).

IIRC, there is a message isn't there? I think that'd be easy enough to hack.

Tell me the answers to the above stuff, and I'll see what I can do!

metapod23
July 2nd, 2011, 04:46 AM
Do you still NEED the Marowak transformation thing? If not, it would be slightly easier to do. Do you still need the Pokémon in question to dodge the Poké Ball, or do you just want it to be "uncatchable"? (What I mean by this is do you want to be able to get it in a Poké Ball, but can't catch it).

IIRC, there is a message isn't there? I think that'd be easy enough to hack.

Tell me the answers to the above stuff, and I'll see what I can do!

All I need is the Poke Ball being thrown and the message that says "This Pokemon cannot be caught" when you try to use a Poke Ball.

I don't want any transformations or transformation messages (A wild Ghost appeared; the Silph Scope identified the Ghost" etc.) - I want it to be like the ghost Marowak battle, except as if Marowak wasn't a ghost, lol.

Thanks in a advance for any help. :)

Jambo51
July 2nd, 2011, 08:15 AM
All I need is the Poke Ball being thrown and the message that says "This Pokemon cannot be caught" when you try to use a Poke Ball.

I don't want any transformations or transformation messages (A wild Ghost appeared; the Silph Scope identified the Ghost" etc.) - I want it to be like the ghost Marowak battle, except as if Marowak wasn't a ghost, lol.

Thanks in a advance for any help. :)

That sounds like a simple edit of the Pokéball throw routine actually. I assume all Poké Balls have a mutual check to have this effect in the Marowak battle, If I can edit this mutual check to include a variable check or something, It should be easy enough to replicate the dodge without any of the other stuff.

metapod23
July 2nd, 2011, 10:32 AM
That sounds like a simple edit of the Pokéball throw routine actually. I assume all Poké Balls have a mutual check to have this effect in the Marowak battle, If I can edit this mutual check to include a variable check or something, It should be easy enough to replicate the dodge without any of the other stuff.

Yes, it would be perfect if I could just have a routine that checks to see if a certain variable or flag is set, and when it is, have the wild Pokemon go into the dodge animation and the dialogue saying the Pokemon can't be captured box come up whenever a Poke Ball is thrown. I just don't know where the Poke Ball routine is located, or where the routine for the Poke Ball dodge in the ghost script is so that it can be called in a new routine.

NintendoBoyDX
July 6th, 2011, 01:41 PM
To clear something up 02022b4c is value checked by several routines (for more than one thing). This value is set at the routine for special 0x156 (this routine is called by a special pokemon battle, not the special). It checks a word at 02022b4c, if the 3rd byte of the word is 80, you don't have the silph scope, marowak doesn't appear and can't be battled. If it's set it to A0 you do have the silph scope, marowak appears and can be battled. Either way, it is still uncatchable. Also I say "3rd byte of the word" but when the game writes the value, it writes it as a halfword.

Example of what the byte would look like: 0000A000, 00008004
Special 0x156 routine: 0807F904

If you go into a wild battle, and have it break at the first write to 02022b4c, then write 0000a000, you'll get the ghost to show up, and the marowak-animation sequence with an uncatchable pokemon. If you write 00008000, you'll get the ghost to show up, but you won't be able to identify or battle it. No matter what, the pokemon is uncatchable. So I'm sure that the catchable/uncatchable value is either stored somewhere completely different, or at 02022b4c at a different point in time.

Also, while testing, I found that setting the last byte to 1C will get you the tutorial battle with Gary/Oak.

The script that the marowak uses: 081634B8
'---------------
#org 0x1634B8
lockall
textcolor 0x2
msgbox 0x817A2F8 MSG_KEEPOPEN '"Be gone[.]\nIntruders[.]"
special 0x187
compare LASTRESULT 0x2
if 0x1 goto 0x81A7AE0
wildbattle2 0x69 0x1E 0x0 0x6
special 0x188
compare LASTRESULT 0x0
if 0x1 goto 0x81634F5
applymovement MOVE_PLAYER 0x8163512
waitmovement 0x0
releaseall
end

'---------------
#org 0x1A7AE0
release
end

'---------------
#org 0x1634F5
preparemsg 0x817A30C '"The ghost was the restless spirit\..."
waitmsg
checksound
cry 0x69 0x0
waitkeypress
waitcry
msgbox 0x817A342 MSG_KEEPOPEN '"The mother's spirit was calmed.\pI..."
setvar 0x4059 0x1
releaseall
end


'---------
' Strings
'---------
#org 0x17A2F8
= Be gone[.]\nIntruders[.]

#org 0x17A30C
= The ghost was the restless spirit\nof CUBONE's mother!

#org 0x17A342
= The mother's spirit was calmed.\pIt departed to the afterlife[.]


'-----------
' Movements
'-----------
#org 0x163512
#raw 0x11 'Step Up (Normal)
#raw 0xFE 'End of Movements

Special 0x156 is never used, but it's routine is called by the wildbattle2 (or it could be one of the two other special commands for all I know).

0807F730 is a check for a regular pokemon vs wild ghost pokemon battle. If 0 is set then 0 is stored at 02022b4c and you get a regular battle, if 1 is set then you get a unidentified ghost pokemon battle.

Also while messing around, I found out that the tutorial battle vs gary happens when you set the last byte equal to 1c. It does take priority over the ghost battles so that gets mention.

EDIT: I've figured out how make a pokemon uncatchable.
During a battle set the word 02022b4c equal to 0x8000. After refreshing the battle(go into your bag or something), it becomes an uncatchable ghost.

If you set it to 0xA000 however, it becomes an uncatchable pokemon.

It's worth mention that setting it to 0x2000 does not make a pokemon uncatchable. So it's not 1 bit that makes it uncatchable.

0x8000 - (00000000000000001000000000000000) Uncatchable ghost, does not change the name to ghost though.
0xA000 - (00000000000000001010000000000000) Uncatchable pokemon.
0x2000 - (00000000000000000010000000000000) I speculated that it would make the pokemon uncatchable but it does NOT. YOU get a regular battle, a catchable pokemon if you set it equal to this.

- However, the problem with setting it equal to 0xA000 before the battle is the text still prints that a "ghost appears" and then it goes through the animation and prints "it was a mother marowak."
- I think the bit set with 0x2000 is the silph scope bit somehow.

sonic1
July 12th, 2011, 04:00 AM
NintendoBoyDX, In the memory viewer please set to 8bit, so you can see the offsets of my table.
http://gyazo.com/bdf3834a998dbbc4a5e1faa5d66266f0.png

Thats basically what you can mess with the battles.

Hope this helps, because i want this feature too, for my own researchs.

~Sonic1

Mr.Pkmn
July 12th, 2011, 11:22 AM
NintendoBoyDX, In the memory viewer please set to 8bit, so you can see the offsets of my table.
http://gyazo.com/bdf3834a998dbbc4a5e1faa5d66266f0.png

Thats basically what you can mess with the battles.

Hope this helps, because i want this feature too, for my own researchs.

~Sonic1
I wonder if with this we could make use of the third parameter of the trainerbattle command (used for oak's tutorial). It would allow battle tower-like trainers in fire red...

ShadowMrk
July 12th, 2011, 09:03 PM
It seems to me that you guys are drawing this out longer than it has to be. If all you want is the Pokemon to be uncatchable then just do this:

-First, find the place in RAM that holds the current wild Pokemon's catch rate and find at what place it stores that data into a register.

-Then make a check right before the game calculates the catch rate for a certain address that isn't used for anything that you can use to see whether or not this battle is of the uncatchable type.

-If that variable IS set then jump to a custom routine that sets the temporary catch rate to 0 and stores the original catch rate into another unused variable.

-Then make another jump after the catch rate calculation that sets the temporary catch rate back to the original catch rate.

-Then make two more routines, one to set the uncatchable variable and another to clear it. Then use those routines in a script before and after an important wild Pokemon battle. Tada! You don't even have to touch the Ghost Marowak ASM.

It was late at night when I wrote this so if I missed something please tell me. Also, if the game doesn't store the catch rate into a temporary location (which is doubtful that they wouldn't) then doing this would be alot harder ,but not impossible.

Jambo51
July 13th, 2011, 05:55 AM
It seems to me that you guys are drawing this out longer than it has to be. If all you want is the Pokemon to be uncatchable then just do this:

-First, find the place in RAM that holds the current wild Pokemon's catch rate and find at what place it stores that data into a register.

-Then make a check right before the game calculates the catch rate for a certain address that isn't used for anything that you can use to see whether or not this battle is of the uncatchable type.

-If that variable IS set then jump to a custom routine that sets the temporary catch rate to 0 and stores the original catch rate into another unused variable.

-Then make another jump after the catch rate calculation that sets the temporary catch rate back to the original catch rate.

-Then make two more routines, one to set the uncatchable variable and another to clear it. Then use those routines in a script before and after an important wild Pokemon battle. Tada! You don't even have to touch the Ghost Marowak ASM.

It was late at night when I wrote this so if I missed something please tell me. Also, if the game doesn't store the catch rate into a temporary location (which is doubtful that they wouldn't) then doing this would be alot harder ,but not impossible.

While this would work, it's not what the OP actually wants.

I've managed to track down what I believe to be the ghost check for the Pokéball throw. This could be a useful lead.

metapod23
July 13th, 2011, 08:22 AM
While this would work, it's not what the OP actually wants.

I've managed to track down what I believe to be the ghost check for the Pokéball throw. This could be a useful lead.

Awesome. I really appreciate you looking into it. :cool:

ShadowMrk
July 13th, 2011, 07:09 PM
While this would work, it's not what the OP actually wants.

I've managed to track down what I believe to be the ghost check for the Pokéball throw. This could be a useful lead.

Nonetheless, this has motivated me to do some research on it. If I could the function(s) that display text and a textbox on the screen then we could still do it the way I suggested while giving Metapod what he wants.

JPAN
July 13th, 2011, 09:55 PM
I believe I have the answer to this question.

BattleScript 0xef is the pokeball catch routine. It is used whenever a ball is thrown, and depending on several checks, jumps to the script best equiped to handle the situation. Near the beginning, it makes three checks to check for situations where the outcome is always the same.


Starting at at 0802D452, we have:

the ghost battle check; continues to the script at 0x081D9Ad1
the trainer battle check; contiu 0x081D9AC1
the fake battle check; continues to the script at 0x081D9A88
With a small bypass near that area, we can use the ghost script (that has nothing related to the ghost battle in it) to prevent capture of a pokemon when a certain flag, variable or another address in the RAM has the desired value. The code is presented below:
Catch_me_not: ldr r0, num_to_check /*can be anything you want, like flags, variables or addresses. Here, we'll use addresses*/
ldrb r0, [r0]
cmp r0, #0x1 /*or any other value you want*/
bne return_to_normal
ldr r1, battleFlags
ldr r1, [r1]
ldr r0, afterGhostAddr
bx r0

return_to_normal: ldr r1, battleFlags
ldr r1, [r1]
ldr r0, ghostCheckAddr
bx r0

num_to_check: .word 0x020370c0 /*var 8004 address, in this example*/
battleFlags: .word 0x02022b4c
afterGhostAddr: .word 0x0802d461
ghostCheckAddr: .word 0x0802d457

In the attachment, you have the compiled version of this code, as well as the source that contains a variable access and a flag access code, commented. For those versions, replace num_to_check with the number of the flag/variable you want.

Note: There was a typo on the commented code, on the Load variable commented function: the address should be 0x0806e569, not 0x0806e568.

metapod23
July 14th, 2011, 07:11 AM
I believe I have the answer to this question.

BattleScript 0xef is the pokeball catch routine. It is used whenever a ball is thrown, and depending on several checks, jumps to the script best equiped to handle the situation. Near the beginning, it makes three checks to check for situations where the outcome is always the same.

Starting at at 0802D452, we have:

the ghost battle check; continues to the script at 0x081D9Ad1
the trainer battle check; contiu 0x081D9AC1
the fake battle check; continues to the script at 0x081D9A88
With a small bypass near that area, we can use the ghost script (that has nothing related to the ghost battle in it) to prevent capture of a pokemon when a certain flag, variable or another address in the RAM has the desired value. The code is presented below:
Catch_me_not: ldr r0, num_to_check /*can be anything you want, like flags, variables or addresses. Here, we'll use addresses*/
ldrb r0, [r0]
cmp r0, #0x1 /*or any other value you want*/
bne return_to_normal
ldr r1, battleFlags
ldr r1, [r1]
ldr r0, afterGhostAddr
bx r0

return_to_normal: ldr r1, battleFlags
ldr r1, [r1]
ldr r0, ghostCheckAddr
bx r0

num_to_check: .word 0x020370c0 /*var 8004 address, in this examle*/
battleFlags: .word 0x02022b4c
afterGhostAddr: .word 0x0802d461
ghostCheckAddr: .word 0x0802d457

In the attachment, you have the compiled version of this code, as well as the source that contains a variable access and a flag access code, commented. For those versions, replace num_to_check with the number of the flag/variable you want.

I tried it out, but haven't gotten it to work. Here's the code I'm using:

.thumb
.align 2

Catch_me_not: ldr r0, =00007015
bl LoadVariable
cmp r0, #0x01
bne return_to_normal
ldrb r0, [r0]
cmp r0, #0x1
bne return_to_normal
ldr r1, battleFlags
ldr r1, [r1]
ldr r0, afterGhostAddr
bx r0

return_to_normal: ldr r1, battleFlags
ldr r1, [r1]
ldr r0, ghostCheckAddr
bx r0

battleFlags: .word 0x02022b4c
afterGhostAddr: .word 0x0802d461
ghostCheckAddr: .word 0x0802d457


LoadVariable: ldr r1, ld_Var_addr
bx r1
ld_Var_addr: .word 0x0806e568

Unfortunately, the game freezes any time I try to use a Poke Ball at all, whether a variable is set or not, freezing on [player] used Poke Ball!

With the code, I'm trying to use variable 0x7015. I placed the code at offset 0x08874120.

At offset 0x0802D484 where the original bytes were:
4C 2B 02 02

I replaced them with a pointer to the new code:

21 41 87 08


And at offset 0x0802D454 where the original bytes were:

01 68

I replaced them with:

00 47

JPAN
July 14th, 2011, 08:02 AM
I tried it out, but haven't gotten it to work.
Sorry about that, copy-paste function from an early code that was bugged, the line
ld_Var_addr: .word 0x0806e568
should read
ld_Var_addr: .word 0x0806e569

That way, it should work.

metapod23
July 14th, 2011, 09:41 AM
Sorry about that, copy-paste function from an early code that was bugged, the line
ld_Var_addr: .word 0x0806e568
should read
ld_Var_addr: .word 0x0806e569

That way, it should work.

It doesn't freeze, but the Pokemon isn't dodging the Poke Ball for me either when the variable is set. Not sure if it's something I'm doing wrong.

Masou Shoujo Haruna
July 14th, 2011, 10:38 AM
it worked for me, though i used JPAN's already made .out file

ShadowMrk
July 14th, 2011, 10:58 AM
It amazes me how fast JPAN did that. I salute you, JPAN. I have alot to learn... :\

metapod23
July 14th, 2011, 11:41 AM
it worked for me, though i used JPAN's already made .out file

Maybe someone can explain to me what's wrong with my code then ... I suspect now that I have more than I need in there, but it still isn't working.

From how I read it, it seems to compare the variable to the value, and if it's not equal, goes to the return_to_normal instruction.

But the instruction following that (if it doesn't take you to return_to_normal) appears to be exactly the same, so I guess I don't understand where the direction is to take you to the uncatchable code if they are equal. It may be that I'm writing it wrong or understanding what I'm supposed to do wrong.

JPAN
July 14th, 2011, 12:19 PM
I tried it out, but haven't gotten it to work. Here's the code I'm using:
.thumb
.align 2

Catch_me_not: ldr r0, =00007015
bl LoadVariable
cmp r0, #0x01
bne return_to_normal
ldrb r0, [r0]
cmp r0, #0x1
bne return_to_normal
ldr r1, battleFlags
ldr r1, [r1]
ldr r0, afterGhostAddr
bx r0

return_to_normal: ldr r1, battleFlags
ldr r1, [r1]
ldr r0, ghostCheckAddr
bx r0

battleFlags: .word 0x02022b4c
afterGhostAddr: .word 0x0802d461
ghostCheckAddr: .word 0x0802d457


LoadVariable: ldr r1, ld_Var_addr
bx r1
ld_Var_addr: .word 0x0806e569
All the underlined code is what's throwing the code off. The value returned by the variable loader is the value to compare right after. After that, loading from R0 would be loading from address 1, a BIOS address. That address value (if even loaded) will most likely not be 1, so the second check fails.
That second check is used only on the "address reading" version of the code. Clean it off, and it should work.

Mr.Pkmn
July 14th, 2011, 12:23 PM
With a small bypass near that area, we can use the ghost script (that has nothing related to the ghost battle in it) to prevent capture of a pokemon when a certain flag, variable or another address in the RAM has the desired value.
Hey JPAN, can you do the same with the trainerbattle command? Making a check to activate the battle tower bit that starts an item forbidden trainer/wild pokemon battle. It's not the same as an uncatchable pokemon, but that would also allow "special", multiplayer-like trainer battles...

JPAN
July 14th, 2011, 03:33 PM
Hey JPAN, can you do the same with the trainerbattle command? Making a check to activate the battle tower bit that starts an item forbidden trainer/wild pokemon battle. It's not the same as an uncatchable pokemon, but that would also allow "special", multiplayer-like trainer battles...
Not sure if it's this, but in the same way we disable the capture, we can disable the item usage. Before the bag is open, a rather large function that deals with input from the Fight-Bag-Party-run box eventually reaches a check for the item-denying battles. At 080143D4, that check starts, and when successful, continues to 0x080143E0, that loads the script to execute. Placing a bypass there, we get a code amost identical to the one for the capture prevention. The code and compiled address version are included in the attachment. Right now, it's loading from 0x020370c0 (var 8004 address), so change it and compile it as you need it.

war rock exe
July 14th, 2011, 05:40 PM
So does this create it possible 2 catch trainers pokemon?

Deokishisu
July 14th, 2011, 11:27 PM
^Just what I was about to ask.

Since we have the code for what prevents a capture, can we enable a capture during a trainer battle?

I can already foresee a problem with this though. I'm pretty sure capturing an enemy trainer's Pokemon immediately ends the battle, not to mention the fact that it'd be difficult to make only a certain Pokemon from an enemy trainer's roster catchable.

So I guess the question is not can an opponent's Pokemon be captured, but can it be implemented well?

Mr.Pkmn
July 15th, 2011, 04:04 AM
Not sure if it's this, but in the same way we disable the capture, we can disable the item usage. Before the bag is open, a rather large function that deals with input from the Fight-Bag-Party-run box eventually reaches a check for the item-denying battles. At 080143D4, that check starts, and when successful, continues to 0x080143E0, that loads the script to execute. Placing a bypass there, we get a code amost identical to the one for the capture prevention. The code and compiled address version are included in the attachment. Right now, it's loading from 0x020370c0 (var 8004 address), so change it and compile it as you need it.
Crashes when the bag is selected. It works if i put 0x080143d9 as the pointer (but obviously this is permanent).

Also, while it's useful to have only items disabled (eg: wild battle) the other things (no experience gained, no switch prompt after ko) are activated if 0x02022B4D is 0x1, so you could integrate these other routines if the variable has an another value.

metapod23
July 15th, 2011, 09:01 AM
All the underlined code is what's throwing the code off. The value returned by the variable loader is the value to compare right after. After that, loading from R0 would be loading from address 1, a BIOS address. That address value (if even loaded) will most likely not be 1, so the second check fails.
That second check is used only on the "address reading" version of the code. Clean it off, and it should work.

I think I finally got it to work! Thanks JPAN! :) I'll credit you for the code in my hack's thread.

One last thing: Isn't there any way to include the poke ball thrown animation and the dodge animation as well? This does the trick, but shouldn't you be able to load the address that plays those animations as well?

Mr.Pkmn
July 15th, 2011, 09:36 AM
Crashes when the bag is selected. It works if i put 0x080143d9 as the pointer (but obviously this is permanent).
Uh I've fixed this, now the routine is working using writebytetooffset with a custom ram address to turn off items. Still would like to see a "complete" battle tower-like routine ;)

droomph
December 24th, 2011, 10:19 AM
I think I finally got it to work! Thanks JPAN! :) I'll credit you for the code in my hack's thread.

One last thing: Isn't there any way to include the poke ball thrown animation and the dodge animation as well? This does the trick, but shouldn't you be able to load the address that plays those animations as well?

Sorry to revive this thread, but I think that I *may* have "found" something.

I was screwing around one afternoon, and I was looking at the Clock Routine (Special 0x9D in Emerald, I believe), one that has actual pictures and animations and stuff, and I had found the address.

Then I looked at the actual code (in PKSV, because it's not like I was serious), and it was suspiciously short (only about ten or fifteen instructions), and most of them were the branch-with-link instructions or whatever you call them, to some addresses in the ROM straight into the six-digit adresses (around 0x700000) from the five-digits (around 0xB0000) where the specials are. I was also using the actual machine-code-to-assembly .pdf I found on the internets, and so I'm pretty sure it's branch to God knows where.

Just a thought.

Cosmic Power
March 4th, 2012, 06:50 AM
an uncatchable pokemon is actually a pretty good research.. we'll check up on it later on ScriptEd.