• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Forum moderator applications are now open! Click here for details.
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Development: [FR] Inverse Battles

DoesntKnowHowToPlay

Tiny Umbrella with Lots and Lots of Good
265
Posts
12
Years
  • Seen Feb 24, 2024
myyB1O5.png


In XY, there is a new type of battle known as the Inverse Battle. In this mode, type match-ups are reversed- moves that are normally super-effective become ineffective, and moves that are normally resisted or would have no effect become super-effective. I did some poking at the type chart code recently and found that it's actually quite easy to implement these in FR.

"But that's easy! Just edit the well-documented type chart so every match-up is backwards!"

That isn't what this does. This hack hijacks the code that reads the type chart to make the game use the inverse of what's there. This means you can use a flag to have hacks with both regular and inverse battles.

The routine is as follows:

Code:
.align 2
.thumb
.thumb_func
push {r4, r5, lr}
mov r4, r0
mov r0, #0x02
lsl r0, #0x8
mov r1, #0x3D
add r0, r1
bl FlagCheck
cmp r0, #0x0
beq End
cmp r4, #0x0
beq SuperEffective
cmp r4, #0x5
beq SuperEffective
cmp r4, #0x14
beq Ineffective
b End

SuperEffective:
mov r4, #0x14
b End

Ineffective:
mov r4, #0x5

End:
ldr r5, .damageAddr
ldr r0, [r5, #0x0]
mul r0, r4
ldr r1, .returnAddr
bx r1

FlagCheck:
ldr r2, .flagAddr
bx r2


.align 2
.returnAddr: .word 0x0801e77d
.flagAddr: .word 0x0806e6d1
.damageAddr: .word 0x02023d50
.end
You can insert it anywhere. To call it, insert 00 49 08 47 at x1E770, followed by a pointer to where you inserted the method + 1. (For example, I inserted the method at x170900- I would put 00 49 08 47 01 09 17 08 at x1E770).

This code ties the Inverse Battle rules to flag x23D. If flag x23D is set, battles will use the Inverse Battle ruleset- otherwise they will work normally. If you want to use a different flag, you can change it quite easily by adjusting the values on the sixth and eighth lines. Note that in vanilla FireRed, flag x23D is used by the Pokeflute- if that script is still in the game you will want to pick a different one.
 

MrDollSteak

Formerly known as 11bayerf1
858
Posts
15
Years
That's fantastic Doesn't!

A very useful feature for hacks looking for different things!

You never cease to amaze me!
 

xGal

Mhm
241
Posts
12
Years
This routine just gave me an idea for my hack. Thanks for the routine! I will give you a credit if i will use it ;).
 

Lance32497

LanceKoijer of Pokemon_Addicts
792
Posts
9
Years
myyB1O5.png


In XY, there is a new type of battle known as the Inverse Battle. In this mode, type match-ups are reversed- moves that are normally super-effective become ineffective, and moves that are normally resisted or would have no effect become super-effective. I did some poking at the type chart code recently and found that it's actually quite easy to implement these in FR.

"But that's easy! Just edit the well-documented type chart so every match-up is backwards!"

That isn't what this does. This hack hijacks the code that reads the type chart to make the game use the inverse of what's there. This means you can use a flag to have hacks with both regular and inverse battles.

The routine is as follows:

Code:
.align 2
.thumb
.thumb_func
push {r4, r5, lr}
mov r4, r0
mov r0, #0x02
lsl r0, #0x8
mov r1, #0x3D
add r0, r1
bl FlagCheck
cmp r0, #0x0
beq End
cmp r4, #0x0
beq SuperEffective
cmp r4, #0x5
beq SuperEffective
cmp r4, #0x14
beq Ineffective
b End

SuperEffective:
mov r4, #0x14
b End

Ineffective:
mov r4, #0x5

End:
ldr r5, .damageAddr
ldr r0, [r5, #0x0]
mul r0, r4
ldr r1, .returnAddr
bx r1

FlagCheck:
ldr r2, .flagAddr
bx r2


.align 2
.returnAddr: .word 0x0801e77d
.flagAddr: .word 0x0806e6d1
.damageAddr: .word 0x02023d50
.end
You can insert it anywhere. To call it, insert 00 49 08 47 at x1E770, followed by a pointer to where you inserted the method + 1. (For example, I inserted the method at x170900- I would put 00 49 08 47 01 09 17 08 at x1E770).

This code ties the Inverse Battle rules to flag x23D. If flag x23D is set, battles will use the Inverse Battle ruleset- otherwise they will work normally. If you want to use a different flag, you can change it quite easily by adjusting the values on the sixth and eighth lines. Note that in vanilla FireRed, flag x23D is used by the Pokeflute- if that script is still in the game you will want to pick a different one.

Why when I use it in a rom, when I use a move that the type is expanded, the game crashed?
 
416
Posts
11
Years
  • Age 34
  • Seen Feb 10, 2024
Code:
.align 2
.thumb
.thumb_func
push {r4, r5, lr}
mov r4, r0
mov r0, #0x02
lsl r0, #0x8
mov r1, #0x3D
add r0, r1
bl FlagCheck
cmp r0, #0x0
beq End
cmp r4, #0x0
beq SuperEffective
cmp r4, #0x5
beq SuperEffective
cmp r4, #0x14
beq Ineffective
b End

SuperEffective:
mov r4, #0x14
b End

Ineffective:
mov r4, #0x5

End:
ldr r5, .damageAddr
ldr r0, [r5, #0x0]
mul r0, r4
ldr r1, .returnAddr
bx r1

FlagCheck:
ldr r2, .flagAddr
bx r2


.align 2
.returnAddr: .word 0x0801e77d
.flagAddr: .word 0x0806e6d1
.damageAddr: .word 0x02023d50
.end

I kinda wanna make this as a tool lol... but I dont know how to compile ASM into hex bytes...

how would I do that?

P.S. Amazing work, really cool option for any hack.

On a completely unrelated note, wouldn't this make a cool hold item... wouldn't know what to call it though lol
 
Last edited:

Deokishisu

Mr. Magius
989
Posts
18
Years
On a completely unrelated note, wouldn't this make a cool hold item... wouldn't know what to call it though lol

Like an item that forces the inverse ruleset when a Pokemon that is holding one comes into battle?

It'd be super cool, but super broken. Put it on all your pure Ice-types. #IceMasterType

Or giving Normal-type moves unresisted coverage.
 
Last edited:
416
Posts
11
Years
  • Age 34
  • Seen Feb 10, 2024
Like an item that forces the inverse ruleset when a Pokemon that is holding one comes into battle?

It'd be super cool, but super broken. Put it on all your pure Ice-types. #IceMasterType

Or giving Normal-type moves unresisted coverage.

Ud have to only give 1 per game...
 
416
Posts
11
Years
  • Age 34
  • Seen Feb 10, 2024
myyB1O5.png


In XY, there is a new type of battle known as the Inverse Battle. In this mode, type match-ups are reversed- moves that are normally super-effective become ineffective, and moves that are normally resisted or would have no effect become super-effective. I did some poking at the type chart code recently and found that it's actually quite easy to implement these in FR.

"But that's easy! Just edit the well-documented type chart so every match-up is backwards!"

That isn't what this does. This hack hijacks the code that reads the type chart to make the game use the inverse of what's there. This means you can use a flag to have hacks with both regular and inverse battles.

The routine is as follows:

Code:
.align 2
.thumb
.thumb_func
push {r4, r5, lr}
mov r4, r0
mov r0, #0x02
lsl r0, #0x8
mov r1, #0x3D
add r0, r1
bl FlagCheck
cmp r0, #0x0
beq End
cmp r4, #0x0
beq SuperEffective
cmp r4, #0x5
beq SuperEffective
cmp r4, #0x14
beq Ineffective
b End

SuperEffective:
mov r4, #0x14
b End

Ineffective:
mov r4, #0x5

End:
ldr r5, .damageAddr
ldr r0, [r5, #0x0]
mul r0, r4
ldr r1, .returnAddr
bx r1

FlagCheck:
ldr r2, .flagAddr
bx r2


.align 2
.returnAddr: .word 0x0801e77d
.flagAddr: .word 0x0806e6d1
.damageAddr: .word 0x02023d50
.end
You can insert it anywhere. To call it, insert 00 49 08 47 at x1E770, followed by a pointer to where you inserted the method + 1. (For example, I inserted the method at x170900- I would put 00 49 08 47 01 09 17 08 at x1E770).

This code ties the Inverse Battle rules to flag x23D. If flag x23D is set, battles will use the Inverse Battle ruleset- otherwise they will work normally. If you want to use a different flag, you can change it quite easily by adjusting the values on the sixth and eighth lines. Note that in vanilla FireRed, flag x23D is used by the Pokeflute- if that script is still in the game you will want to pick a different one.

View attachment 73380

Soo here is the tool I made... if it meets your approval I would like to publish it about the web (it seems to work as prescribed)

View attachment 73379
 
416
Posts
11
Years
  • Age 34
  • Seen Feb 10, 2024
how do i to set in a script the inverse batle?
someone can show me an expample please?
i'm not understand so

Code:
setflag 0x23D //turns on inverse battles

Code:
clearflag 0x23D //returns battles to normal

the flag you set or clear should be the flag you chose, not specifically 23D
 
416
Posts
11
Years
  • Age 34
  • Seen Feb 10, 2024
For anyone wanting to know how to make a trainer have an inverse battle with you... here is a detailed script:

Code:
#dynamic 0x725BEF ' any free space
#org @start
'-----------------------------------
setflag 0x33D ' the flag you chose
trainerbattle 0x1 0x[COLOR="Red"][B](battle)[/B][/COLOR] 0x0 @text1 0x[COLOR="Blue"][B](oldtext2)[/B][/COLOR] @clearinverse 
msgbox 0x[COLOR="DarkOrange"][B](oldwon)[/B][/COLOR]
callstd MSG_LOCK ' Built-in lock command
clearflag 0x33D ' the flag you chose
end

#org @text1
= [COLOR="Magenta"][B](old intro text)[/B][/COLOR]\pThis will be an\nINVERSE BATTLE.

#org @clearinverse
'-----------------------------------
clearflag 0x33D ' the flag you chose
release
end
It is color coded to the parts that need to be pasted in:
Code:
#org 0x816A63E
'-----------------------------------
trainerbattle 0x0 0x[COLOR="red"][B]8E[/B][/COLOR] 0x0 0x81911EC 0x[COLOR="Blue"][B]8191237[/B][/COLOR]
msgbox 0x[COLOR="DarkOrange"][B]819126B[/B][/COLOR] ' You're pretty hot.\n...
callstd MSG_LOCK ' Built-in lock command
end


#org 0x81911EC
= [COLOR="Magenta"][B]Stop right there, kid!\pYou're ten thousand light-years \nfrom facing BROCK![/B][/COLOR]

#org 0x8191237
= Darn!\pLight-years isn't time[.]\nIt measures distance!

#org 0x819126B
= You're pretty hot.\n[.]But not as hot as BROCK!

The example trainer(above) is the trainer in brocks gym, but the same parts can be copied from any trainer.

trainers using this script will not approach the player, they must be talked too.

X and Y usually ask the player if they want to continue... this script warns the player but does not let them back out. A simple yes/no script can make that happen. If you can't figure that out, you probably shouldn't be scripting.

If you are doing this for multiple trainers, you do not need to compile the '@clearinverse' section each time, you can just use the same offset where it is compiled once.
 
252
Posts
10
Years
  • Age 27
  • Seen Jul 6, 2019
Managed to port this to EM.

Replace the addresses at the end with this:

Code:
.returnAddr: .word 0x08046f6d
.flagAddr: .word 0x0809d791
.damageAddr: .word 0x020241f0

Next, put 00 49 08 47 at 0x46f60, followed by the pointer to where you inserted the ASM + 1.

That's it! I believe flag 0x2CD is used by something in EM as well, so just change the values in the sixth and eighth line if you want a different flag.
 
199
Posts
12
Years
  • Seen Jul 18, 2016
I believe flag 0x2CD is used by something in EM as well, so just change the values in the sixth and eighth line if you want a different flag.

1. Thanks for the port of this (and of course to you, Doesnt)
2. Flag 0x2CD appears to be set sometime during the Hall of Fame script. So you probably would like to change that. :P
 
416
Posts
11
Years
  • Age 34
  • Seen Feb 10, 2024
Managed to port this to EM.

Replace the addresses at the end with this:

Code:
.returnAddr: .word 0x08046f6d
.flagAddr: .word 0x0809d791
.damageAddr: .word 0x020241f0

Next, put 00 49 08 47 at 0x46f60, followed by the pointer to where you inserted the ASM + 1.

That's it! I believe flag 0x2CD is used by something in EM as well, so just change the values in the sixth and eighth line if you want a different flag.

would you care terrably if I added this to my tool? cedit given of course.
 
Back
Top