The PokéCommunity Forums

The PokéCommunity Forums (https://www.pokecommunity.com/index.php)
-   Binary Hack Research & Development (https://www.pokecommunity.com/forumdisplay.php?f=195)
-   -   Code ASM Resource Thread (https://www.pokecommunity.com/showthread.php?t=339153)

MrDollSteak June 7th, 2015 4:19 AM

Quote:

Originally Posted by KDS (Post 8786554)
EV-enhancing items (Power Items)


Spoiler:

The routines assume that the Held Item Effect Bytes of the Power Items are in a particular order (same as that of Stat EVs in Pokemon Party Data Structure) and are consecutive.
For example, if Power Weight has Held Item Effect Byte 68, then Power Bracer will have 69, Power Belt 6A, Power Anklet 6B, Power Lens 6C and Power Band 6D.

So in the routines, you only need to specify the Held Item Effect Byte for Power Weight by replacing KK. The routine will automatically recognize other Power items.
Also I have not coded the Speed Drop, I might do it later and update the OP.
If you want to code the Speed Drop yourself, you can make a hook around the Macho Brace check for Speed Drop.

Fire Red:-
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

    add r4, r0, #0x0 /*EV of a particular stat before checking pokerus and applying EV enhancers*/
    push {r2}  /*Store pokerus factor*/
    mov r0, r8  /*Load pokemon slot no*/
    mov r1, #0xC
    mov r2, #0x0
    bl Decrypter /* Load pokemon's item */
    lsl r0, r0, #0x10
    lsr r0, r0, #0x10
    bl GetItemEffect /* Get Held Item's Effect Byte*/
    lsl r0, r0, #0x18
    lsr r0, r0, #0x18
    mov r3, #0xKK
    add r1, r6, r3 /* Load Power Item's Effect Byte*/
    pop {r2}
    cmp r1, r0 /*Match items*/
    bne NoPowerItem /*No Power Item or No Match for that particular stat*/
    add r4, r4, #0x4 /* Add Bonus 4+ EV */
    mul r4, r2 /*Use pokerus multiplier*/
    ldr r3, =0x080439D9
    bx r3

NoPowerItem:
    mul r4, r2
    mov r0, r8
    mov r1, #0xC
    ldr r3, =0x08043981
    bx r3

Decrypter:
    ldr r3, =0x0803FBE9
    bx r3

GetItemEffect:
    ldr r1, =0x0809A925
    bx r1

/*At 43978:00 49 08 47 XX+1 XX XX 08*/




Emerald:-
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

    add r4, r0, #0x0 /*EV of a particular stat before checking pokerus and applying EV enhancers*/
    push {r2}  /*Store pokerus factor*/
    mov r0, r8  /*Load pokemon slot no*/
    mov r1, #0xC
    mov r2, #0x0
    bl Decrypter /* Load pokemon's item */
    lsl r0, r0, #0x10
    lsr r0, r0, #0x10
    bl GetItemEffect /* Get Held Item's Effect Byte*/
    lsl r0, r0, #0x18
    lsr r0, r0, #0x18
    mov r3, #0xKK
    add r1, r6, r3 /* Load Power Item's Effect Byte*/
    pop {r2} /*Restore Pokerus Muliplier*/
    cmp r1, r0 /*Match items*/
    bne NoPowerItem /*No Power Item or No Match for that particular stat*/
    add r4, r4, #0x4 /* Add B Bonus 4+ EV */
    mul r4, r2 /*Use pokerus multiplier*/
    ldr r3, =0x0806DC25
    bx r3

NoPowerItem:
    mul r4, r2
    mov r0, r8
    mov r1, #0xC
    ldr r3, =0x0806DBCD
    bx r3

Decrypter:
    ldr r3, =0x0806A519
    bx r3

GetItemEffect:
    ldr r1, =0x080D74DD
    bx r1

/*At 6DBC4:00 49 08 47 XX+1 XX XX 08*/





KDS to make it easier, what you should do is have the same effect as the Macho Brace, and make the individual EV enhancing items use the secondary byte as 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 etc.

That way you don't need to code the extra speed drop for each individual effect.

Trainer 781 June 7th, 2015 4:36 AM

Quote:

Originally Posted by MrDollSteak (Post 8786559)
KDS to make it easier, what you should do is have the same effect as the Macho Brace, and make the individual EV enhancing items use the secondary byte as 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 etc.

That way you don't need to code the extra speed drop for each individual effect.

Hmm, this looks a great idea. Might need to add some bit of extra code for this.

EDIT: Now updated. :D

Xencleamas June 8th, 2015 9:46 PM

Quote:

Originally Posted by KDS (Post 8786554)
EV-enhancing items (Power Items)

Nice work there KDS! Your are truly an ASM Lord! Haha! Anyway, can you also implement this idea as well:

Quote:

Originally Posted by leyn09 (Post 8727097)
Is there a possibility to make sitrus berry work like on the later generations (increases 25% hp). If there is anyone knows how, please help me. Thanks!:D


Trainer 781 June 8th, 2015 10:35 PM

Quote:

Originally Posted by Sky High (Post 8789697)
Nice work there KDS! Your are truly an ASM Lord! Haha! Anyway, can you also implement this idea as well:

Thanks! My domain on ASM is only limited to Battle Mechanics though and I'm still learning new things.

Oran Berry would require some effort and some knowledge of regular scripting (which I haven't touched yet). I suppose it would require three routines:
1. One for pinch berry activation.
2. Second, when you use an Oran Berry on your Pokemon while battling.
3. Third, when you use an Oran Berry on your Pokemon in the Overworld.

BluRose June 9th, 2015 3:20 PM

I'd like to say that this thread has been really helpful for me as my ASM skills are far worse than sub-par and, also, the Chain-Fishing one in particular is really cool to me. (◕‿◕✿)

I'd also like to request something for Fire Red BPRE v1.0 (adding to the infinite list of requests...):
Stance Change.
Basically, where a Pokémon uses an offensive move and changes its form to a more offensive Pokémon (or, rather, just a different index-number Pokémon entirely). However, when it uses a certain move (or just a status move would be fine, too), it reverts back to the old form.
EDIT: Oh, and it would also have to revert to the other form outside of battle.
What I was thinking was two separate abilities in order to accomplish this, but if one is possible, then that's great too!
Thanks in advance!

God I sound so rude I am so sorry

EDIT: Also, should I go to DaniilS with this? I noticed that he had his own thread for form(e)s...

EDIT EDIT: Okay, I just noticed something while I was trying to get the Male-only and Female-only evolution methods working on Burmy.
But ALL of the Pokémon generated by your routine are Male unless if they have more of an 82 percent chance of being female, in which case they are, and the Pokémon already caught turn into females. This is also shown in you post showcasing it, as the Tyranitar are also all Male.
Just wanted to say this, haha...

Exodrake June 13th, 2015 4:18 PM

Quote:

Originally Posted by FBI agent (Post 8632913)
You need the random number routine and the shiny generator routine I made. The three of them work in conjunction to make this effect happen. I know it works, because my test ROM is only shinies :x

Can someone post links to those required routines? I've been driving myself up a wall searching for them to no avail.

Kenny1 June 13th, 2015 8:37 PM

Quote:

Originally Posted by Exodrake (Post 8796745)
Can someone post links to those required routines? I've been driving myself up a wall searching for them to no avail.

FBI kinda did in the post about the routine: http://www.pokecommunity.com/showpost.php?p=8547374&postcount=400
Anyways, just in case: Shiny and Random

Exodrake June 13th, 2015 10:19 PM

Quote:

Originally Posted by Kenny1 (Post 8797059)
FBI kinda did in the post about the routine: http://www.pokecommunity.com/showpost.php?p=8547374&postcount=400
Anyways, just in case: Shiny and Random

Gah I did not see those, were they not in the quoted version that I saved? I didn't see the original post, sorry about that! But thank you.

FamiliaWerneck June 16th, 2015 8:13 PM

Quote:

Originally Posted by FBI agent (Post 8516113)
Controling what breeds with what and what hatches from the result can be done with a Pokemon editor iirc.

Few simple questions on breeding, egg groups and all that. You said it's all doable via a Pokémon Editor. What I want, actually is that Charizard evolutionary line breeds only with its line and/or Ditto. No Dragon/Monster egg groups. Will I have to make an egg group for each evolutionary family?
Also, how can I make Ditto breeds with himself too, not only all other Pokémon? And genderless Pokémon, like Magnemite? How can I make them breed?
Finally, for Nidorans and Volbeat/Illumise, I wanna make the male breed with the female, but not breedable with Ditto. How can I do it?

Quote:

Originally Posted by FBI agent (Post 8516113)
Status update:
Today I've been working on breeding stat passing, particularly nature. I found that a Pokemon's nature in the gen iii games are determined rather randomly. It's done by PID % 25, = nature. In later games, you'll notice that nature is determined in otherways than PID. It's quite bad that FR uses this system because that means that the Pokemon's nature is going to be randomized quite well. I can't really modify the PID to match a certain nature because the PID is used to determine Pokemon IVs and all that good stuff, not to mention the checksum which turns a Pokemon into a badegg. What this means is that I would have to keep generating a new Pokemon UNTIL the PID generated from the game matches qualities of the PID I want. The process is rather complicated and I'm frankly debating whether or not it's worth the work. Honestly, does anyone actually breed farm in ROM hacks?

Here, I just want to know if I can make all Pokémon to be Docile as default or if I can change all natures' data, so all natures behave like Docile. Is either of these possible?
Thanks in advance!

Lance32497 June 16th, 2015 11:21 PM

Disabling "Gain money
" after defeating a trainer", it's useful for those who want to have a battle frontier

Trainer 781 June 17th, 2015 2:57 AM

Life Orb Recoil

Spoiler:

This only includes the Life Orb Recoil not the Life Orb Boost.
Credits to MrDollsteak for the Sheer Force Routine which I ripped from his Rombase.
Life Orb recoil is disabled for Volt Switch and U-turn in order to prevent damage to switched ally. (Special callasm in Battle Scripts of these Moves should be made in order to process Life Orb Recoil for them. Preferably before switching happens).
If you don't have Sheer Force, Magic Guard, U-turn or Volt Switch remove the bolded lines.
Replace KK with Held Effect Item Byte of Life Orb.

Bug/Oddity: It can trigger multiple times for multi-hit moves like Life Orb and multiple target moves like Earthquake in doubles. Fixed

Fire Red:-

Spoiler:


Routine at XXXXXX:
Code:

.text
.align 2
.thumb
.thumb_func
.global lifeorbrecoil

SheerForceCheck:
      ldr r1, .UserBank
      ldr r2, .BattleStruct
      ldrb r1, [r1, #0x0]
      mov r0, #0x58
      mul r0, r1
      add r0, r0, r2
      mov r2, #0x20
      add r2, r0, r2
      ldrb r2, [r2]
      cmp r2, #0x7E /*Sheer Force*/
      bne EffectCheck
      ldr r0, .CurrMove
      ldrh r3, [r0, #0x0]
      mov r0, #0x0
      ldr r1, .FEHalfWord
      ldr r2, .SheerForceTable

Loop:
      lsl r4, r0, #0x01
      add r4, r4, r2
      ldrh r4, [r4, #0x0]
      cmp r3, r4
      beq Exit
      cmp r4, r1
      beq EffectCheck
      add r0, #0x1
      b Loop

EffectCheck:
      mov r1, r8
      cmp r1, #0x3E
      beq ShellBell
      cmp r1, #0xKK
      bne Exit

CheckOutcome:
      ldr r0, .Outcome
      ldrb r0, [r0, #0x0]
      mov r5, #0x29
      and r5, r0
      cmp r5, #0x0
      bne Exit

CheckUturnVoltSwitch:
      ldr r0, .CurrMove
      ldrh r0, [r0]
      ldrh r1, .VoltSwitchID
      cmp r0, r1
      beq Exit
      ldrh r1, .UTurnID
      cmp r0, r1
      beq Exit

CheckIfMoveDamagedSomeTarget:
      ldr r1, .DamageStruct
      ldr r4, .TargetBank
      ldrb r2, [r4, #0x0]
      lsl r0, r2, #0x02
      add r0, r0, r2
      lsl r0, r0, #0x02
      add r6, r1, #0x4
      add r0, r0, r6
      ldr r1, [r0, #0x0]
      cmp r1, #0x0
      beq Exit
      ldr r0, .FFHalfWord
      cmp r1, r0
      beq Exit

CheckIfUserIsNotTheTarget:
      ldr r0, .UserBank
      ldrb r3, [r0, #0x0]
      cmp r3, r2
      beq Exit

CheckMagicGuard:
      ldr r2, .BattleStruct
      ldrb r1, [r0, #0x0]
      mov r0, #0x58
      mul r0, r1
      add r0, r0, r2
      mov r2, #0x20
      add r2, r0, r2
      ldrb r2, [r2]
      cmp r2, #0x63 /*Magic Guard*/
      beq Exit

HPCheck:
      ldrh r1, [r0, #0x28]
      cmp r1, #0x0
      beq Exit

SetLifeOrbRecoilBit:
      ldr r1, .LORBit
      mov r0, #0x1
      strb r0, [r1]

Exit:
      ldr r1, .Return2
      bx r1

ShellBell:
      ldr r1, .Return1
      bx r1

.align 2
.UserBank: .word 0x02023D6B
.TargetBank: .word 0x02023D6C
.BattleStruct: .word 0x02023BE4
.DamageStruct: .word 0x02023ECC
.CurrMove: .word 0x02023D4A
.SheerForceTable: .word 0x08XXXXXX
.Outcome: .word 0x02023DCC
.FEHalfWord: .word 0x0000FEFE
.FFHalfWord: .word 0x0000FFFF
.Return1: .word 0x0801CF11
.Return2: .word 0x0801CFA7
.LORBit: .word 0x0203C038
.UTurnID: .word 0x000001YY
.VoltSwitchID: .word 0x000001ZZ

/*At 1CE58: 00 48 00 47 XX+1 XX XX 08*/


Routine at YYYYYY:
Code:

.text
.align 2
.thumb
.thumb_func
.global endcommandwithlifeorbsupport

Main:
      ldr r1, .LORBit
      ldrb r0, [r1]
      cmp r0, #0x1
      bne EndCommand

LifeOrb:
      push {lr}
      push {r2-r7}
      mov r0, #0x0
      strb r0, [r1]
      ldr r0, .UserBank
      ldrb r3, [r0]
      mov r0, #0x58
      mul r0, r3
      ldr r2, .BattleStruct
      add r2, r2, r0
      ldrh r0, [r2, #0x28]
      cmp r0, #0x0
      beq Exit
      ldr r0, =0x02023D6F
      strb r3, [r0, #0x0]
      ldr r0, =0x02023DC4
      strb r3, [r0, #0x17]
      ldr r4, =0x02023D50
      ldrh r0, [r2, #0x2C]
      mov r1, #0xA
      bl Divider
      strh r0, [r4, #0x0]
      cmp r0, #0x0
      bne NotZero
      mov r0, #0x1

NotZero:
      strh r0, [r4, #0x0]
      bl ScriptPusher
      ldr r1, .ScriptPointer
      ldr r0, .LifeOrbDamageScript
      str r0, [r1, #0x0]
      pop {r2-r7}
      pop {r0}
      bx r0

Exit:
      pop {r2-r7}
      pop {r0}

EndCommand:
      ldr r0, =0x08022CCD @Replace this with the offset of the 4th Mold Breaker Routine if you are using Mold Breaker
      bx r0

Divider:
      ldr r2, =0x081E4019
      bx r2

ScriptPusher:
      ldr r0, =0x08017545
      bx r0

.align 2
.LifeOrbDamageScript: .word 0x08BBBBBB
.ScriptPointer: .word 0x02023D74
.UserBank: .word 0x02023D6B
.BattleStruct: .word 0x02023BE4
.LORBit: .word 0x0203C038

@Set YY+1 YY YY 08 as the 'End' Battle Script Command.


Battle Script at BBBBBB:
Code:

39 20 00 FA 20 C0 03 02 SS SS SS 08 10 84 01 12 40 00 35 D0 3D 02 02 00 01 00 00 0B 01 0C 01 19 01 00 00 00 00 00 3C


String at SSSSSS:
Code:

FD 0F 00 E0 E3 E7 E8 00 E7 E3 E1 D9 00 E3 DA 00 DD E8 E7 00 C2 CA AB FF





Squeetz June 17th, 2015 4:36 AM

I have a request.

A routine that copies the player's current pokemon in party (EVs IVs, moves, Abilities, held items, etc.) and pastes it on a trainerbattle (user gets to choose which trainer).
So, like a Battle With yourself. Would be cool as a final Battle or something.
Is this possible? Would be awesome if anyone made this.

Criminon June 18th, 2015 4:43 PM

Anyone want to try to make it so you can only use 4 items per battle so you're on equal footing with the trainers you're fighting?

Exodrake June 19th, 2015 4:28 PM

Can somebody post the code for the updated lightning rod/storm drain and sap sipper? I want to try modifying them to make my own abilities based on the same idea.

MrDollSteak June 19th, 2015 4:55 PM

Quote:

Originally Posted by KDS (Post 8802100)
Life Orb Recoil

Spoiler:

This only includes the Life Orb Recoil not the Life Orb Boost.
Credits to MrDollsteak for the Sheer Force Routine which I ripped from his Rombase.
Life Orb recoil is disabled for Volt Switch and U-turn in order to prevent damage to switched ally. (Special callasm in Battle Scripts of these Moves should be made in order to process Life Orb Recoil for them).
If you don't have Sheer Force, Magic Guard, U-turn or Volt Switch remove the bolded lines.
Replace KK with Held Effect Item Byte of Life Orb.

Bug/Oddity: It can trigger multiple times for multi-hit moves like Life Orb and multiple target moves like Earthquake in doubles. Fixed

Fire Red:-

Spoiler:


Routine at XXXXXX:
Code:

.text
.align 2
.thumb
.thumb_func
.global lifeorbrecoil

SheerForceCheck:
      ldr r1, .UserBank
      ldr r2, .BattleStruct
      ldrb r1, [r1, #0x0]
      mov r0, #0x58
      mul r0, r1
      add r0, r0, r2
      mov r2, #0x20
      add r2, r0, r2
      ldrb r2, [r2]
      cmp r2, #0x7E /*Sheer Force*/
      bne EffectCheck
      ldr r0, .CurrMove
      ldrh r3, [r0, #0x0]
      mov r0, #0x0
      ldr r1, .FEHalfWord
      ldr r2, .SheerForceTable

Loop:
      lsl r4, r0, #0x01
      add r4, r4, r2
      ldrh r4, [r4, #0x0]
      cmp r3, r4
      beq Exit
      cmp r4, r1
      beq EffectCheck
      add r0, #0x1
      b Loop

EffectCheck:
      mov r1, r8
      cmp r1, #0x3E
      beq ShellBell
      cmp r1, #0xKK
      bne Exit

CheckOutcome:
      ldr r0, .Outcome
      ldrb r0, [r0, #0x0]
      mov r5, #0x29
      and r5, r0
      cmp r5, #0x0
      bne Exit

CheckUturnVoltSwitch:
      ldr r0, .CurrMove
      ldrh r0, [r0]
      ldrh r1, .VoltSwitchID
      cmp r0, r1
      beq Exit
      ldrh r1, .UTurnID
      cmp r0, r1
      bew Exit

CheckIfMoveDamagedSomeTarget:
      ldr r1, .DamageStruct
      ldr r4, .TargetBank
      ldrb r2, [r4, #0x0]
      lsl r0, r2, #0x02
      add r0, r0, r2
      lsl r0, r0, #0x02
      add r6, r1, #0x4
      add r0, r0, r6
      ldr r1, [r0, #0x0]
      cmp r1, #0x0
      beq Exit
      ldr r0, .FFHalfWord
      cmp r1, r0
      beq Exit

CheckIfUserIsNotTheTarget:
      ldr r0, .UserBank
      ldrb r3, [r0, #0x0]
      cmp r3, r2
      beq Exit

CheckMagicGuard:
      ldr r2, .BattleStruct
      ldrb r1, [r0, #0x0]
      mov r0, #0x58
      mul r0, r1
      add r0, r0, r2
      mov r2, #0x20
      add r2, r0, r2
      ldrb r2, [r2]
      cmp r2, #0x63 /*Magic Guard*/
      beq Exit

HPCheck:
      ldrh r1, [r0, #0x28]
      cmp r1, #0x0
      beq Exit

SetLifeOrbRecoilBit:
      ldr r1, .LORBit
      mov r0, #0x1
      strb r0, [r1]

Exit:
      ldr r1, .Return2
      bx r1

ShellBell:
      ldr r1, .Return1
      bx r1

Divider:
      ldr r2, =0x081E4019
      bx r2

ScriptPusher:
      ldr r0, =0x08017545
      bx r0

.align 2
.UserBank: .word 0x02023D6B
.TargetBank: .word 0x02023D6C
.BattleStruct: .word 0x02023BE4
.DamageStruct: .word 0x02023ECC
.CurrMove: .word 0x02023D4A
.SheerForceTable: .word 0x08XXXXXX
.Outcome: .word 0x02023DCC
.FEHalfWord: .word 0x0000FEFE
.FFHalfWord: .word 0x0000FFFF
.Return1: .word 0x0801CF11
.Return2: .word 0x0801CFA7
.LORBit: .word 0x0203C038
.UTurnID: .word 0x000001YY
.VoltSwitchID: .word 0x000001ZZ

/*At 1CE58: 00 48 00 47 XX+1 XX XX 08*/


Routine at YYYYYY:
Code:

.text
.align 2
.thumb
.thumb_func
.global endcommandwithlifeorbsupport

Main:
      ldr r1, .LORBit
      ldrb r0, [r1]
      cmp r0, #0x1
      bne EndCommand

LifeOrb:
      push {lr}
      push {r2-r7}
      mov r0, #0x0
      strb r0, [r1]
      ldr r0, .UserBank
      ldrb r3, [r0]
      mov r0, #0x58
      mul r0, r3
      ldr r2, .BattleStruct
      add r2, r2, r0
      ldrh r0, [r2, #0x28]
      cmp r0, #0x0
      beq Exit
      ldr r0, =0x02023D6F
      strb r3, [r0, #0x0]
      ldr r0, =0x02023DC4
      strb r3, [r0, #0x17]
      ldr r4, =0x02023D50
      ldrh r0, [r2, #0x2C]
      mov r1, #0xA
      bl Divider
      strh r0, [r4, #0x0]
      cmp r0, #0x0
      bne NotZero
      mov r0, #0x1

NotZero:
      strh r0, [r4, #0x0]
      bl ScriptPusher
      ldr r1, .ScriptPointer
      ldr r0, .LifeOrbDamageScript
      str r0, [r1, #0x0]
      pop {r2-r7}
      pop {r0}
      bx r0

Exit:
      pop {r2-r7}
      pop {r0}

EndCommand:
      ldr r0, =0x08022CCD @Replace this with the offset of the 4th Mold Breaker Routine if you are using Mold Breaker
      bx r0

Divider:
      ldr r2, =0x081E4019
      bx r2

ScriptPusher:
      ldr r0, =0x08017545
      bx r0

.align 2
.LifeOrbDamageScript: .word 0x08BBBBBB
.ScriptPointer: .word 0x02023D74
.UserBank: .word 0x02023D6B
.BattleStruct: .word 0x02023BE4
.LORBit: .word 0x0203C038

@Set YY+1 YY YY 08 as the 'End' Battle Script Command.


Battle Script at BBBBBB:
Code:

39 20 FA 20 C0 03 02 SS SS SS 08 10 84 01 12 40 00 35 D0 3D 02 02 00 01 00 00 0B 01 0C 01 19 01 00 00 00 00 00 3C


String at SSSSSS:
Code:

FD 0F 00 E0 E3 E7 E8 00 E7 E3 E1 D9 00 E3 DA 00 DD E8 E7 00 C2 CA AB FF





I've noticed that this also prevents Sheer Force Pokemon getting any healing from the Shell Bell. This doesn't happen in the games I don't think. I'd probably do the Sheer Force Check after determining whether it has Shell Bell.

Great work! I'll have to link this post when I write up the rest of my Sheer Force routines on the Ability Resource Thread.

Quote:

Can somebody post the code for the updated lightning rod/storm drain and sap sipper? I want to try modifying them to make my own abilities based on the same idea.
These will be posted on the Ability Resource Thread eventually.

kleenexfeu June 19th, 2015 7:33 PM

Quote:

Originally Posted by KDS (Post 8802100)
Life Orb Recoil

Spoiler:

This only includes the Life Orb Recoil not the Life Orb Boost.
Credits to MrDollsteak for the Sheer Force Routine which I ripped from his Rombase.
Life Orb recoil is disabled for Volt Switch and U-turn in order to prevent damage to switched ally. (Special callasm in Battle Scripts of these Moves should be made in order to process Life Orb Recoil for them).
If you don't have Sheer Force, Magic Guard, U-turn or Volt Switch remove the bolded lines.
Replace KK with Held Effect Item Byte of Life Orb.

Bug/Oddity: It can trigger multiple times for multi-hit moves like Life Orb and multiple target moves like Earthquake in doubles. Fixed

Fire Red:-

Spoiler:


Routine at XXXXXX:
Code:

.text
.align 2
.thumb
.thumb_func
.global lifeorbrecoil

SheerForceCheck:
      ldr r1, .UserBank
      ldr r2, .BattleStruct
      ldrb r1, [r1, #0x0]
      mov r0, #0x58
      mul r0, r1
      add r0, r0, r2
      mov r2, #0x20
      add r2, r0, r2
      ldrb r2, [r2]
      cmp r2, #0x7E /*Sheer Force*/
      bne EffectCheck
      ldr r0, .CurrMove
      ldrh r3, [r0, #0x0]
      mov r0, #0x0
      ldr r1, .FEHalfWord
      ldr r2, .SheerForceTable

Loop:
      lsl r4, r0, #0x01
      add r4, r4, r2
      ldrh r4, [r4, #0x0]
      cmp r3, r4
      beq Exit
      cmp r4, r1
      beq EffectCheck
      add r0, #0x1
      b Loop

EffectCheck:
      mov r1, r8
      cmp r1, #0x3E
      beq ShellBell
      cmp r1, #0xKK
      bne Exit

CheckOutcome:
      ldr r0, .Outcome
      ldrb r0, [r0, #0x0]
      mov r5, #0x29
      and r5, r0
      cmp r5, #0x0
      bne Exit

CheckUturnVoltSwitch:
      ldr r0, .CurrMove
      ldrh r0, [r0]
      ldrh r1, .VoltSwitchID
      cmp r0, r1
      beq Exit
      ldrh r1, .UTurnID
      cmp r0, r1
      beq Exit

CheckIfMoveDamagedSomeTarget:
      ldr r1, .DamageStruct
      ldr r4, .TargetBank
      ldrb r2, [r4, #0x0]
      lsl r0, r2, #0x02
      add r0, r0, r2
      lsl r0, r0, #0x02
      add r6, r1, #0x4
      add r0, r0, r6
      ldr r1, [r0, #0x0]
      cmp r1, #0x0
      beq Exit
      ldr r0, .FFHalfWord
      cmp r1, r0
      beq Exit

CheckIfUserIsNotTheTarget:
      ldr r0, .UserBank
      ldrb r3, [r0, #0x0]
      cmp r3, r2
      beq Exit

CheckMagicGuard:
      ldr r2, .BattleStruct
      ldrb r1, [r0, #0x0]
      mov r0, #0x58
      mul r0, r1
      add r0, r0, r2
      mov r2, #0x20
      add r2, r0, r2
      ldrb r2, [r2]
      cmp r2, #0x63 /*Magic Guard*/
      beq Exit

HPCheck:
      ldrh r1, [r0, #0x28]
      cmp r1, #0x0
      beq Exit

SetLifeOrbRecoilBit:
      ldr r1, .LORBit
      mov r0, #0x1
      strb r0, [r1]

Exit:
      ldr r1, .Return2
      bx r1

ShellBell:
      ldr r1, .Return1
      bx r1

Divider:
      ldr r2, =0x081E4019
      bx r2

ScriptPusher:
      ldr r0, =0x08017545
      bx r0

.align 2
.UserBank: .word 0x02023D6B
.TargetBank: .word 0x02023D6C
.BattleStruct: .word 0x02023BE4
.DamageStruct: .word 0x02023ECC
.CurrMove: .word 0x02023D4A
.SheerForceTable: .word 0x08XXXXXX
.Outcome: .word 0x02023DCC
.FEHalfWord: .word 0x0000FEFE
.FFHalfWord: .word 0x0000FFFF
.Return1: .word 0x0801CF11
.Return2: .word 0x0801CFA7
.LORBit: .word 0x0203C038
.UTurnID: .word 0x000001YY
.VoltSwitchID: .word 0x000001ZZ

/*At 1CE58: 00 48 00 47 XX+1 XX XX 08*/


Routine at YYYYYY:
Code:

.text
.align 2
.thumb
.thumb_func
.global endcommandwithlifeorbsupport

Main:
      ldr r1, .LORBit
      ldrb r0, [r1]
      cmp r0, #0x1
      bne EndCommand

LifeOrb:
      push {lr}
      push {r2-r7}
      mov r0, #0x0
      strb r0, [r1]
      ldr r0, .UserBank
      ldrb r3, [r0]
      mov r0, #0x58
      mul r0, r3
      ldr r2, .BattleStruct
      add r2, r2, r0
      ldrh r0, [r2, #0x28]
      cmp r0, #0x0
      beq Exit
      ldr r0, =0x02023D6F
      strb r3, [r0, #0x0]
      ldr r0, =0x02023DC4
      strb r3, [r0, #0x17]
      ldr r4, =0x02023D50
      ldrh r0, [r2, #0x2C]
      mov r1, #0xA
      bl Divider
      strh r0, [r4, #0x0]
      cmp r0, #0x0
      bne NotZero
      mov r0, #0x1

NotZero:
      strh r0, [r4, #0x0]
      bl ScriptPusher
      ldr r1, .ScriptPointer
      ldr r0, .LifeOrbDamageScript
      str r0, [r1, #0x0]
      pop {r2-r7}
      pop {r0}
      bx r0

Exit:
      pop {r2-r7}
      pop {r0}

EndCommand:
      ldr r0, =0x08022CCD @Replace this with the offset of the 4th Mold Breaker Routine if you are using Mold Breaker
      bx r0

Divider:
      ldr r2, =0x081E4019
      bx r2

ScriptPusher:
      ldr r0, =0x08017545
      bx r0

.align 2
.LifeOrbDamageScript: .word 0x08BBBBBB
.ScriptPointer: .word 0x02023D74
.UserBank: .word 0x02023D6B
.BattleStruct: .word 0x02023BE4
.LORBit: .word 0x0203C038

@Set YY+1 YY YY 08 as the 'End' Battle Script Command.


Battle Script at BBBBBB:
Code:

39 20 FA 20 C0 03 02 SS SS SS 08 10 84 01 12 40 00 35 D0 3D 02 02 00 01 00 00 0B 01 0C 01 19 01 00 00 00 00 00 3C


String at SSSSSS:
Code:

FD 0F 00 E0 E3 E7 E8 00 E7 E3 E1 D9 00 E3 DA 00 DD E8 E7 00 C2 CA AB FF





Well done on that KDS !

Same routine with Emerald offset !

Here :
Spoiler:

Spoiler:

Routine at XXXXXX:
Code:

.text
.align 2
.thumb
.thumb_func
.global lifeorbrecoil

SheerForceCheck:
      ldr r1, .UserBank
      ldr r2, .BattleStruct
      ldrb r1, [r1, #0x0]
      mov r0, #0x58
      mul r0, r1
      add r0, r0, r2
      mov r2, #0x20
      add r2, r0, r2
      ldrb r2, [r2]
      cmp r2, #0x7E /*Sheer Force*/
      bne EffectCheck
      ldr r0, .CurrMove
      ldrh r3, [r0, #0x0]
      mov r0, #0x0
      ldr r1, .FEHalfWord
      ldr r2, .SheerForceTable

Loop:
      lsl r4, r0, #0x01
      add r4, r4, r2
      ldrh r4, [r4, #0x0]
      cmp r3, r4
      beq Exit
      cmp r4, r1
      beq EffectCheck
      add r0, #0x1
      b Loop

EffectCheck:
      mov r1, r8
      cmp r1, #0x1E
      beq KingsRock
      cmp r1, #0x3E
      beq ShellBell
      cmp r1, #0xKK    /*Life orb held item effect*/
      bne Exit

CheckOutcome:
      ldr r0, .Outcome
      ldrb r0, [r0, #0x0]
      mov r5, #0x29
      and r5, r0
      cmp r5, #0x0
      bne Exit

CheckUturnVoltSwitch:
      ldr r0, .CurrMove
      ldrh r0, [r0]
      ldrh r1, .VoltSwitchID
      cmp r0, r1
      beq Exit
      ldrh r1, .UTurnID
      cmp r0, r1
      beq Exit

CheckIfMoveDamagedSomeTarget:
      ldr r1, .DamageStruct
      ldr r4, .TargetBank
      ldrb r2, [r4, #0x0]
      lsl r0, r2, #0x02
      add r0, r0, r2
      lsl r0, r0, #0x02
      add r6, r1, #0x4
      add r0, r0, r6
      ldr r1, [r0, #0x0]
      cmp r1, #0x0
      beq Exit
      ldr r0, .FFHalfWord
      cmp r1, r0
      beq Exit

CheckIfUserIsNotTheTarget:
      ldr r0, .UserBank
      ldrb r3, [r0, #0x0]
      cmp r3, r2
      beq Exit

CheckMagicGuard:
      ldr r2, .BattleStruct
      ldrb r1, [r0, #0x0]
      mov r0, #0x58
      mul r0, r1
      add r0, r0, r2
      mov r2, #0x20
      add r2, r0, r2
      ldrb r2, [r2]
      cmp r2, #0x63 /*Magic Guard*/
      beq Exit

HPCheck:
      ldrh r1, [r0, #0x28]
      cmp r1, #0x0
      beq Exit

SetLifeOrbRecoilBit:
      ldr r1, .LORBit
      mov r0, #0x1
      strb r0, [r1]

Exit:
      ldr r1, .Return2
      bx r1

KingsRock:
      ldr r0, .Return3
      bx r0

ShellBell:
      ldr r1, .Return1
      bx r1

Divider:
      ldr r2, =0x082E7540+1
      bx r2

ScriptPusher:
      ldr r0, =0x0803FAFC+1
      bx r0

.align 2
.UserBank: .word 0x0202420B
.TargetBank: .word 0x0202420C
.BattleStruct: .word 0x02024084
.DamageStruct: .word 0x0202437C
.CurrMove: .word 0x020241EA
.SheerForceTable: .word 0x08XXXXXX
.Outcome: .word 0x0202427C
.FEHalfWord: .word 0x0000FEFE
.FFHalfWord: .word 0x0000FFFF
.Return1: .word 0x08045794+1
.Return2: .word 0x0804582A+1
.Return3: .word 0x080456EC+1
.LORBit: .word 0x0203E338        /*It's actually a FreeRam loc*/
.UTurnID: .word 0x00000YYY        /*ID number of U-Turn*/
.VoltSwitchID: .word 0x00000ZZZ        /*ID number of Volt Switch*/

/*At 080456DC: 00 48 00 47 XX+1 XX XX 08*/



Spoiler:

Routine at YYYYYY:
Code:

.text
.align 2
.thumb
.thumb_func
.global endcommandwithlifeorbsupport

Main:
      ldr r1, .LORBit
      ldrb r0, [r1]
      cmp r0, #0x1
      bne EndCommand

LifeOrb:
      push {lr}
      push {r2-r7}
      mov r0, #0x0
      strb r0, [r1]
      ldr r0, .UserBank
      ldrb r3, [r0]
      mov r0, #0x58
      mul r0, r3
      ldr r2, .BattleStruct
      add r2, r2, r0
      ldrh r0, [r2, #0x28]
      cmp r0, #0x0
      beq Exit
      ldr r0, =0x0202420F
      strb r3, [r0, #0x0]
      ldr r0, =0x02024274
      strb r3, [r0, #0x17]
      ldr r4, =0x020241F0
      ldrh r0, [r2, #0x2C]
      mov r1, #0xA
      bl Divider
      strh r0, [r4, #0x0]
      cmp r0, #0x0
      bne NotZero
      mov r0, #0x1

NotZero:
      strh r0, [r4, #0x0]
      bl ScriptPusher
      ldr r1, .ScriptPointer
      ldr r0, .LifeOrbDamageScript
      str r0, [r1, #0x0]
      pop {r2-r7}
      pop {r0}
      bx r0

Exit:
      pop {r2-r7}
      pop {r0}

EndCommand:
      ldr r0, =0x0804B664+1
      bx r0

Divider:
      ldr r2, =0x082E7540+1
      bx r2

ScriptPusher:
      ldr r0, =0x0803FAFC+1
      bx r0

.align 2
.LifeOrbDamageScript: .word 0x08BBBBBB
.ScriptPointer: .word 0x02024214
.UserBank: .word 0x0202420B
.BattleStruct: .word 0x02024084
.LORBit: .word 0x0203E338        /*Same as in previous routine*/

/*YY+1 YY YY 08 must replaces the "end" command pointer */



Spoiler:

Battle Script at BBBBBB:
Code:

39 20 00 FA 20 E3 03 02 SS SS SS 08 10 84 01 12 40 00 35 80 42 02 02 00 01 00

00 0B 01 0C 01 19 01 00 00 00 00 00 3C


String at SSSSSS:
Code:

FD 0F 00 E0 E3 E7 E8 00 E7 E3 E1 D9 00 E3 DA 00 DD E8 E7 00 C2 CA AB FF





Bonus:
-Life Orb boost
-Light ball updated
-Item that boost a certain type of attack for Emerald
-Timespace Orbs for Emerald

Note that for timespace orbs and new boost-type item, you can adjust the power added the same way than miracle seed and the like.

Spoiler:

Emerald:
Code:

CheckLifeOrb:
cmp r2, #0x43        /*Held item effect of life orb, I chose 0x43 (= 67 in decimal) because it's unused*/
beq Lifeorb

CheckNewItem:
cmp r2, #0x44        /*Held item effect of the boost item, I chose 0x44 (= 68 in decimal) because it's unused*/
beq NewItem

CheckAdamantOrb:
cmp r2, #0x45        /*Unused held item effect*/
bne CheckLustreous
ldrh r0, [r6]
mov r3, #0xFF        /*0xFF + 0xE4 = 0x1E3 = 483 = index number of Dialga*/
add r3, #0xE4
cmp r0, r3
beq AdamantOrb

CheckLustreous:
cmp r2, #0x46        /*Unused held item effect*/
bne CheckGriseous
ldrh r0, [r6]
mov r3, #0xFF        /*0xFF + 0xE5 = 0x1E4 = 484 = index number of Palkia*/
add r3, #0xE5
cmp r0, r3
beq LustreousOrb

CheckGriseous:
cmp r2, #0x47        /*Unused held item effect*/
bne CheckLightBall
ldrh r0, [r6]
mov r3, #0xFF        /*0xFF + 0xE8 = 0x1E7 = 487 = index number of Giratina*/
add r3, #0xE8
cmp r0, r3
beq GriseousOrb
b Back

AdamantOrb:
push {r0-r5}
mov r1, #8        /*Steel type*/
mov r2, #0x10        /*Dragon type*/
b CheckExceptionTypeAttack

LustreousOrb:
push {r0-r5}
mov r1, #0xB        /*Water type*/
mov r2, #0x10        /*Dragon type*/
b CheckExceptionTypeAttack

GriseousOrb:
push {r0-r5}
mov r1, #7        /*Ghost type*/
mov r2, #0x10        /*Dragon type*/
b CheckExceptionTypeAttack

NewItem:
push {r0-r5}
mov r1, #9        /*New type you want to boost*/
mov r2, #9        /*New type you want to boost, here I choose the same because I want it boost only one type*/

CheckExceptionTypeAttack:
ldr r4, CheckTypeLoc
ldr r4, [r4]
ldrb r4, [r4, #0x13]
cmp r4, #0
beq GetMoveType
mov r5, #0x3F
and r4, r5
cmp r4, r1
beq Boost
cmp r4, r2
beq Boost
b PopAndBack

Back:
ldr r0, Return
bx r0

PopAndBack:
pop {r0-r5}
b Back

CheckLightBall:
cmp r2, #0x2D
bne Back
ldrh r0, [r6]
cmp r0, #0x19
beq Lightball
b Back

GetMoveType:
ldr r3, CurMoveIndex
ldrh r3, [r3]
ldr r4, MoveData
mov r5, #0xC
mul r5, r3
add r4, r5
ldrb r4, [r4, #2]
cmp r4, r1
beq Boost
cmp r4, r2
bne PopAndBack

Boost:
pop {r0-r5}
ldrh r3, [r6, #0x2E]
lsl r0, r3, #4
push {r1}
mov r1, #6
mul r3, r1
pop {r1}
add r3, r0
lsl r3, #1
ldr r0, LocItems
add r3, r0
add r3, #0x13
ldrb r0, [r3]
mov r3, #0x52
mul r0, r3
lsr r0, #6
add r0, #0x7B
mul r7, r0
lsr r7, #7
mov r3, r8
mul r3, r0
lsr r3, #7
mov r8, r3
b Back

Lifeorb:
mov r0, r8
mov r3, #0xA7
mul r0, r3
lsr r0, #7
mov r8, r0
mul r7, r3
lsr r7, #7
b Back

Lightball:
mov r0, r8
lsl r0, r0, #0x1
mov r8, r0
lsl r7, r7, #0x1
b Back

.align 2
Return: .word 0x0806983E+1
LocItems: .word 0x085839A0          /*Location of your items Data*/
CurMoveIndex: .word 0x020241EA
MoveData: .word 0x0831C898          /*Location of your move data*/
CheckTypeLoc: .word 0x0202449C

/*00 48 00 47 XX XX XX 08 00 00 00 at 0x6982C*/


Fire Red:
Code:

cmp r2, #0x43  /*Held item effect, I chose 0x43 (=67 in dec) because it is unused in the game*/
beq Lifeorb
cmp r2, #0x2D
bne Back
ldrh r0, [r6]
cmp r0, #0x19
beq Lightball
b Back

Lifeorb:
mov r0, r8
mov r3, #0xA7
mul r0, r3
lsr r0, #7
mov r8, r0
mul r7, r3
lsr r7, #7
b Back

Lightball:
mov r0, r8
lsl r0, r0, #0x1
mov r8, r0
lsl r7, r7, #0x1

Back:
ldr r0, Return
bx r0

.align 2
Return: .word 0x0803F00A+1

/*00 48 00 47 XX XX XX 08 00 00 00 at 0803EFF8*/




Quote:

Originally Posted by leyn09 (Post 8813429)
Thanks! Oh, will the FR ver. be available soon? :D

Yep, it is now updated

Trainer 781 June 19th, 2015 9:20 PM

Quote:

Originally Posted by MrDollSteak (Post 8806198)
I've noticed that this also prevents Sheer Force Pokemon getting any healing from the Shell Bell. This doesn't happen in the games I don't think. I'd probably do the Sheer Force Check after determining whether it has Sheer Force. Otherwise great work! I'll have to link this post when I write up the rest of my Sheer Force routines on the Ability Resource Thread.

Thanks.
Well it does prevent according to Bulbapedia.
Also, I have already done the Sheer Force Check after checking the ability (literally copy pasted line-to-line your Sheer Force implementation xD).

Quote:

Originally Posted by kleenexfeu (Post 8806372)
Spoiler:

Well done on that KDS !
Thanks

Typo in the check Volt Switch/U-turn : bew exit instead of beq
I'll fix it, aha

Something else troubles me though. In that part :
EffectCheck:
mov r1, r8
cmp r1, #0x3E
beq ShellBell
cmp r1, #0xKK
bne Exit
Shouldn't you check King's Rock effect too ? There's cmp r1, #0x1E in the original routine.
You can. But there is no need, since the Battle Script for King Rock utilizes 'setbyte 0x2023E85' along with 'seteffecttargetwithchance' command which MrDS's Sheer Force implementation already handles. Choose whatever that looks more efficient to you.

Something else, I tried to port it to Emerald and failed. I think this is the part of the "end" command battle that causes problem.
I saw there's a difference beetwin Emerald and Fire Red Mold breaker routines regarding the part of the end command, so I tried to change a little bit that part of your routine but didn't managed to make it work.
Is there something obviously wrong ?
You have to insert the Routine at YYYYYY the same way as done in Fire Red. This involves, replacing the pointer to the 'end command' in the command table with the offset of this routine.
The 'EndCommand' label of Routine at YYYYYY should be this

Code:

EndCommand:
      ldr r1, =0x0804B666+1 @The pointer to the old 'end' command
      bx r1


Also in Emerald, you don't have to worry about whether Mold Breaker is there or not. The Pointer in the EndCommand label won't change unlike Fire Red.
Your routine was creating stack imbalance because it was not pushing and popping equal no of registers.



Responses in Bold.



Also, I might post a mini-documentation about the Battle Script Command 'cmd49' in the Quick R&D thread to provide insight of things that are happening at the End of a Move Execution.

And it will also help to create things like Weakness Policy, Rocky Helmet, Absorb Bulb etc.

Since I will be very busy doing College and Intern Projects, I don't have time to work on these for now. It would be better if some-one with free time will be able to work on these items.

leyn09 June 21st, 2015 4:11 AM

Quote:

Originally Posted by kleenexfeu (Post 8806372)
Well done on that KDS !

Bonus, Life Orb boost (lightball updated included) :

Spoiler:

Code:

cmp r2, #0x43
beq Lifeorb
cmp r2, #0x2D
bne Back
ldrh r0, [r6]
cmp r0, #19
beq Lightball
ldr r0, =(0x0806983F)
bx r0

Lifeorb:
mov r0, r8
mov r3, #0xA7
mul r0, r3
lsr r0, #7
mov r8, r0
mul r7, r3
lsr r7, #7
ldr r0, =(0x0806983F)
bx r0

Lightball:
mov r0, r8
lsl r0, r0, #0x1
mov r8, r0
lsl r7, r7, #0x1
ldr r0, =(0x0806983F)
bx r0

Back:
ldr r0, =0x0806983E+1
bx r0

/*00 48 00 47 XX XX XX 08 00 00 00 at 0x6982C*/



May I ask on how to incorporate the life orb recoil and boost?

kleenexfeu June 21st, 2015 1:02 PM

Quote:

Originally Posted by leyn09 (Post 8808440)
May I ask on how to incorporate the life orb recoil and boost?

The bunch of code you see here is ASM routine. If you don't know what is ASM, type on google or in this forum "ASM" and you'll see a lot of good tutorials.

If you know more or less what it is but don't know how to insert it, refer to that post because I can't explain it in a better way : http://www.pokecommunity.com/showpost.php?p=8526603&postcount=199

Btw you can simply read the tutorials on that thread, they're very good : http://www.pokecommunity.com/showthread.php?t=343871

For the rest, read the instruction put together with the routine.

If you still have problem (and you actually tried to make it work), you can PM me

Hope it'll help

leyn09 June 21st, 2015 3:48 PM

Quote:

Originally Posted by kleenexfeu (Post 8809042)
The bunch of code you see here is ASM routine. If you don't know what is ASM, type on google or in this forum "ASM" and you'll see a lot of good tutorials.

If you know more or less what it is but don't know how to insert it, refer to that post because I can't explain it in a better way : http://www.pokecommunity.com/showpost.php?p=8526603&postcount=199

Btw you can simply read the tutorials on that thread, they're very good : http://www.pokecommunity.com/showthread.php?t=343871

For the rest, read the instruction put together with the routine.

If you still have problem (and you actually tried to make it work), you can PM me

Hope it'll help

Oh sorry, my question was quite misleading. I know how to insert ASM. hehe. I was asking if the life orb will work if I just separately insert your LO boost and KDS' LO recoil? Or I should change a byte (the held item effect,maybe?) in your asm routine. Thanks!

kleenexfeu June 22nd, 2015 6:23 AM

Quote:

Originally Posted by leyn09 (Post 8809216)
Oh sorry, my question was quite misleading. I know how to insert ASM. hehe. I was asking if the life orb will work if I just separately insert your LO boost and KDS' LO recoil? Or I should change a byte (the held item effect,maybe?) in your asm routine. Thanks!

Oh ok. So yeah, they work seperatly, I edited my routine, the first "cmp 0x43" actually compare to held item effect of your life orb. I advice using an unused item effect.

Note that the boost power I post is only for Emerald though

leyn09 June 24th, 2015 3:30 AM

Quote:

Originally Posted by kleenexfeu (Post 8810143)
Oh ok. So yeah, they work seperatly, I edited my routine, the first "cmp 0x43" actually compare to held item effect of your life orb. I advice using an unused item effect.

Note that the boost power I post is only for Emerald though

Thanks! Oh, will the FR ver. be available soon? :D

Mr.Pkmn June 29th, 2015 10:19 AM

Can we have run-like speed for surf and mach bike speed in FR? Even better would be an arbitrary speed value!

Telemetius July 4th, 2015 2:06 AM

Hi FBI, first of all thanks for your work! You've been really helpful.
My question regards your battle routine http://www.pokecommunity.com/showthread.php?p=8527650#8527650 .
I've been trying it without success in my Ruby rom hack hoping it would work just like in Fire Red.
Is there any way to remove the whiteout after losing a battle in a Ruby hack rom?

leyn09 July 6th, 2015 7:57 PM

Quote:

Originally Posted by daniilS (Post 8532492)

Delete save and reset game after whiteout




I tried getting it to delete the save file and to return to the titlescreen afterwards, but I couldn't get a brief flash of the pokécenter to disappear. I might fix it later, but as for now, here's a much more simple version using SoftReset:
Code:

Type 5F F1 53 FC 00 DF at 0807F5B6 and F1 E7 at 0807F5D0.



Can its effectivity be toggled using flags?

Also, Is there any way how to disable the usage of bag during battle? Thanks!

DJTiki July 14th, 2015 7:32 PM

Quote:

Originally Posted by FBI agent (Post 8523908)

Bag Deletion and Restoration



Bag Delete:



Here's a compiled version:
Code:

FF B5 00 24 05 2C 1F D8 12 48 21 1C C9 00 40 18 05 1D 2D 78 03 68 00 26 AE 42 12 D2 1A 88 00 2A 0C D0 98 1C 7C B4 0C 4B 00 F0 0D F8 7C BC 01 1C 10 1C 7C B4 09 4B 00 F0 06 F8 7C BC 04 33 01 36 EA E7 01 34 DE E7 18 47 FF BD C0 46 8C 98 03 02 80 C2 03 02 8C 98 03 02 A1 9D 09 08 D9 A1 09 08



That's funny because when I complied this twice to make sure I wasn't doing it wrong and I recieved this as the compiled version:

Code:

7F B5 00 24 05 2C 1F D8 12 48 21 1C C9 00 40 18 05 1D 2D 78 03 68 00 26 AE 42 12 D2 1A 88 00 2A 0C D0 98 1C 7C B4 0C 4B 00 F0 0D F8 7C BC 01 1C 10 1C 7C B4 09 4B 00 F0 06 F8 7C BC 04 33 01 36 EA E7 01 34 DE E7 18 47 FF BD C0 46 8C 98 03 02 80 C2 03 02 8C 98 03 02 A1 9D 09 08 D9 A1 09 08


It's only one bit difference, but if I am correct, then you should probably edit your post to fix this typo since most people who don't know how to compile will use your code with the typo. But I'm most likely wrong. :)

Thanks for the code!

Exodrake July 14th, 2015 8:09 PM

I would like to request a modified Flash Fire which can be activated by another type as well as Fire. I didn't know where else to put this request since the Ability Resource Thread is for porting official ability effects and vanilla Flash Fire doesn't do this. The reason being my hack has an Oil type (0x18) which I'd like to activate Flash Fire, since we know what happens when you squirt oils onto a fire, but alas my brain refuses to comprehend ASM. It's worth noting that by default Fire is immune to Oil, so the ability would have to override that.

MrDollSteak July 14th, 2015 8:20 PM

Quote:

Originally Posted by Exodrake (Post 8846856)
I would like to request a modified Flash Fire which can be activated by another type as well as Fire. I didn't know where else to put this request since the Ability Resource Thread is for porting official ability effects and vanilla Flash Fire doesn't do this. The reason being my hack has an Oil type (0x18) which I'd like to activate Flash Fire, since we know what happens when you squirt oils onto a fire, but alas my brain refuses to comprehend ASM. It's worth noting that by default Fire is immune to Oil, so the ability would have to override that.

If you look at the Ability Resource Thread, my most recent post deals with the Type Absorb abilities. Once I've posted the Fire Red ones you could either write a new routine that activates on both Fire and Oil and replace the pointer in the table.

Alternatively you can navigate to the offsets of the routine and add a branch at the beginning of the routine and check for Oil there. You are right though, the immunity may prevent it from happening.

Exodrake July 14th, 2015 8:34 PM

Quote:

Originally Posted by MrDollSteak (Post 8846869)
If you look at the Ability Resource Thread, my most recent post deals with the Type Absorb abilities. Once I've posted the Fire Red ones you could either write a new routine that activates on both Fire and Oil and replace the pointer in the table.

Alternatively you can navigate to the offsets of the routine and add a branch at the beginning of the routine and check for Oil there. You are right though, the immunity may prevent it from happening.

Flash Fire behaves differently than the other absorb abilities in that it strengthens moves of a specific type rather than just boosting an offensive stat. I have next to no ASM capabilities to begin with and I don't think I'd have any idea how to do that. I figured it could be grouped with the other absorb abilities though.

AkimotoBubble July 15th, 2015 4:58 AM

oh i need you are help.i am do the"Preventing TMs from being consumed on use "for EM rom.And i have a trouble.
I change 1B6EE0 to 90 make we "can use TM but can not to reduce number"
but I can not remove the quantities showing up in thebag so I need help.Thanks

FamiliaWerneck July 16th, 2015 6:00 AM

Quote:

Originally Posted by AkimotoBubble (Post 8847274)
oh i need you are help.i am do the"Preventing TMs from being consumed on use "for EM rom.And i have a trouble.
I change 1B6EE0 to 90 make we "can use TM but can not to reduce number"
but I can not remove the quantities showing up in thebag so I need help.Thanks

- Open the ROM com o with HxD. Go to 0x124F78 and insert 00 00 00 00. Go to 0x125C80 and insert 00 00 00 00. This makes TMs not be consumed.
- Go to 0x1326B8 and insert 00 00 17 E0. This makes TMs ungivable.
- Go to some free space (I used 0x1BA540), select 36 FF e change them for (simply Ctrl + B in the first):
00 2D 01 D1 05 4B 18 47 38 1C 08 21 22 1C 04 4E 00 F0 02 F8 01 4B 18 47 30 47 C0 46 FF 1E 13 08 B1 35 13 08
- Go to 0x131EF4 and insert: 00 48 00 47 41 A5 1B 08
- Insert E0 at 0x131EA5.

AkimotoBubble July 16th, 2015 3:36 PM

Quote:

Originally Posted by FamiliaWerneck (Post 8848726)
- Open the ROM com o with HxD. Go to 0x124F78 and insert 00 00 00 00. Go to 0x125C80 and insert 00 00 00 00. This makes TMs not be consumed.
- Go to 0x1326B8 and insert 00 00 17 E0. This makes TMs ungivable.
- Go to some free space (I used 0x1BA540), select 36 FF e change them for (simply Ctrl + B in the first):
00 2D 01 D1 05 4B 18 47 38 1C 08 21 22 1C 04 4E 00 F0 02 F8 01 4B 18 47 30 47 C0 46 FF 1E 13 08 B1 35 13 08
- Go to 0x131EF4 and insert: 00 48 00 47 41 A5 1B 08
- Insert E0 at 0x131EA5.

It is from FR not EM :(

FamiliaWerneck July 16th, 2015 7:33 PM

Quote:

Originally Posted by AkimotoBubble (Post 8849287)
It is from FR not EM :(

Didn't see the EM thing there, sorry.

DizzyEgg July 17th, 2015 12:54 AM

Quote:

Originally Posted by KDS (Post 8802100)
Life Orb Recoil
...
@Set YY+1 YY YY 08 as the 'End' Battle Script Command.
...

I don't get that part, could you explain what and how exactly I should go about it?

Trainer 781 July 17th, 2015 1:02 AM

Quote:

Originally Posted by DizzyEgg (Post 8849827)
I don't get that part, could you explain what and how exactly I should go about it?

There is a Battle Script command table at x25011c in FR. If you have repointed this to include Jambo's callasm and/or setword commands then you have to check it yourself.

It is a table of pointers. Goto entry no. x3D (table starts from x0) and overwrite the pointer there with pointer to routine at YYYYYY.

Spherical Ice July 27th, 2015 5:24 PM

Transferred ownership of this thread to Lost Heart, so hopefully it can be updated more regularly now!

esperance July 27th, 2015 8:16 PM

Whew~! I've gone through the entire thread and compiled a list of every routine. Expect an updated first post soon! :)

EDIT: It is done.

DizzyEgg July 28th, 2015 2:13 AM

Quote:

Originally Posted by KDS (Post 8802100)
Life Orb Recoil

Spoiler:

This only includes the Life Orb Recoil not the Life Orb Boost.
Credits to MrDollsteak for the Sheer Force Routine which I ripped from his Rombase.
Life Orb recoil is disabled for Volt Switch and U-turn in order to prevent damage to switched ally. (Special callasm in Battle Scripts of these Moves should be made in order to process Life Orb Recoil for them. Preferably before switching happens).
If you don't have Sheer Force, Magic Guard, U-turn or Volt Switch remove the bolded lines.
Replace KK with Held Effect Item Byte of Life Orb.

Bug/Oddity: It can trigger multiple times for multi-hit moves like Life Orb and multiple target moves like Earthquake in doubles. Fixed

Fire Red:-

Spoiler:


Routine at XXXXXX:
Code:

.text
.align 2
.thumb
.thumb_func
.global lifeorbrecoil

SheerForceCheck:
      ldr r1, .UserBank
      ldr r2, .BattleStruct
      ldrb r1, [r1, #0x0]
      mov r0, #0x58
      mul r0, r1
      add r0, r0, r2
      mov r2, #0x20
      add r2, r0, r2
      ldrb r2, [r2]
      cmp r2, #0x7E /*Sheer Force*/
      bne EffectCheck
      ldr r0, .CurrMove
      ldrh r3, [r0, #0x0]
      mov r0, #0x0
      ldr r1, .FEHalfWord
      ldr r2, .SheerForceTable

Loop:
      lsl r4, r0, #0x01
      add r4, r4, r2
      ldrh r4, [r4, #0x0]
      cmp r3, r4
      beq Exit
      cmp r4, r1
      beq EffectCheck
      add r0, #0x1
      b Loop

EffectCheck:
      mov r1, r8
      cmp r1, #0x3E
      beq ShellBell
      cmp r1, #0xKK
      bne Exit

CheckOutcome:
      ldr r0, .Outcome
      ldrb r0, [r0, #0x0]
      mov r5, #0x29
      and r5, r0
      cmp r5, #0x0
      bne Exit

CheckUturnVoltSwitch:
      ldr r0, .CurrMove
      ldrh r0, [r0]
      ldrh r1, .VoltSwitchID
      cmp r0, r1
      beq Exit
      ldrh r1, .UTurnID
      cmp r0, r1
      beq Exit

CheckIfMoveDamagedSomeTarget:
      ldr r1, .DamageStruct
      ldr r4, .TargetBank
      ldrb r2, [r4, #0x0]
      lsl r0, r2, #0x02
      add r0, r0, r2
      lsl r0, r0, #0x02
      add r6, r1, #0x4
      add r0, r0, r6
      ldr r1, [r0, #0x0]
      cmp r1, #0x0
      beq Exit
      ldr r0, .FFHalfWord
      cmp r1, r0
      beq Exit

CheckIfUserIsNotTheTarget:
      ldr r0, .UserBank
      ldrb r3, [r0, #0x0]
      cmp r3, r2
      beq Exit

CheckMagicGuard:
      ldr r2, .BattleStruct
      ldrb r1, [r0, #0x0]
      mov r0, #0x58
      mul r0, r1
      add r0, r0, r2
      mov r2, #0x20
      add r2, r0, r2
      ldrb r2, [r2]
      cmp r2, #0x63 /*Magic Guard*/
      beq Exit

HPCheck:
      ldrh r1, [r0, #0x28]
      cmp r1, #0x0
      beq Exit

SetLifeOrbRecoilBit:
      ldr r1, .LORBit
      mov r0, #0x1
      strb r0, [r1]

Exit:
      ldr r1, .Return2
      bx r1

ShellBell:
      ldr r1, .Return1
      bx r1

.align 2
.UserBank: .word 0x02023D6B
.TargetBank: .word 0x02023D6C
.BattleStruct: .word 0x02023BE4
.DamageStruct: .word 0x02023ECC
.CurrMove: .word 0x02023D4A
.SheerForceTable: .word 0x08XXXXXX
.Outcome: .word 0x02023DCC
.FEHalfWord: .word 0x0000FEFE
.FFHalfWord: .word 0x0000FFFF
.Return1: .word 0x0801CF11
.Return2: .word 0x0801CFA7
.LORBit: .word 0x0203C038
.UTurnID: .word 0x000001YY
.VoltSwitchID: .word 0x000001ZZ

/*At 1CE58: 00 48 00 47 XX+1 XX XX 08*/


Routine at YYYYYY:
Code:

.text
.align 2
.thumb
.thumb_func
.global endcommandwithlifeorbsupport

Main:
      ldr r1, .LORBit
      ldrb r0, [r1]
      cmp r0, #0x1
      bne EndCommand

LifeOrb:
      push {lr}
      push {r2-r7}
      mov r0, #0x0
      strb r0, [r1]
      ldr r0, .UserBank
      ldrb r3, [r0]
      mov r0, #0x58
      mul r0, r3
      ldr r2, .BattleStruct
      add r2, r2, r0
      ldrh r0, [r2, #0x28]
      cmp r0, #0x0
      beq Exit
      ldr r0, =0x02023D6F
      strb r3, [r0, #0x0]
      ldr r0, =0x02023DC4
      strb r3, [r0, #0x17]
      ldr r4, =0x02023D50
      ldrh r0, [r2, #0x2C]
      mov r1, #0xA
      bl Divider
      strh r0, [r4, #0x0]
      cmp r0, #0x0
      bne NotZero
      mov r0, #0x1

NotZero:
      strh r0, [r4, #0x0]
      bl ScriptPusher
      ldr r1, .ScriptPointer
      ldr r0, .LifeOrbDamageScript
      str r0, [r1, #0x0]
      pop {r2-r7}
      pop {r0}
      bx r0

Exit:
      pop {r2-r7}
      pop {r0}

EndCommand:
      ldr r0, =0x08022CCD @Replace this with the offset of the 4th Mold Breaker Routine if you are using Mold Breaker
      bx r0

Divider:
      ldr r2, =0x081E4019
      bx r2

ScriptPusher:
      ldr r0, =0x08017545
      bx r0

.align 2
.LifeOrbDamageScript: .word 0x08BBBBBB
.ScriptPointer: .word 0x02023D74
.UserBank: .word 0x02023D6B
.BattleStruct: .word 0x02023BE4
.LORBit: .word 0x0203C038

@Set YY+1 YY YY 08 as the 'End' Battle Script Command.


Battle Script at BBBBBB:
Code:

39 20 00 FA 20 C0 03 02 SS SS SS 08 10 84 01 12 40 00 35 D0 3D 02 02 00 01 00 00 0B 01 0C 01 19 01 00 00 00 00 00 3C


String at SSSSSS:
Code:

FD 0F 00 E0 E3 E7 E8 00 E7 E3 E1 D9 00 E3 DA 00 DD E8 E7 00 C2 CA AB FF





I'm having troubles implementing it. I replaced the end command, placed a hook, inserted all routines and a battle script but...nothing happens. No resets, no freezing, the game just continues without recoil damage. I'm sure my item effect byte is correct. Do you know why it would happen? Also, I'm using DollSteak's Patch.

Quote:

Originally Posted by KDS (Post 8764736)
Damage Reduction Berries


2. Assemble this routine and make bytes changes mentioned in the code
Spoiler:


Code:

.text
.align 2
.thumb
.thumb_func
.global reductionberry

ValidMoveCheck:
    ldr r0, .Outcome
    ldrb r1, [r0]
    mov r2, #0x29
    and r2, r1
    cmp r2, #0x0
    bne Exit

SubCheck:
    ldr r3, .Target
    ldr r4, .PokemonData
    mov r2, #0x58
    ldrb r0, [r3]
    mul r0, r2
    add r7, r0, r4
    ldr r2, [r7, #0x50]
    ldr r3, .subval
    and r2, r3
    cmp r2, #0x0
    bne Exit

NormalMoveCheck:
    ldr r4, .MemoryLoc
    ldr r3, [r4]
    ldrb r6, [r3, #0x13]
    mov r2, #0x3f
    and r6, r2
    cmp r6, #0x0
    bne SuperEffectiveCheck
    ldr r4, .MoveTable
    ldr r3, .CurrMove
    mov r2, #0xC
    ldrh r1, [r3]
    mul r1, r2
    add r2, r1, r4
    ldrb r6, [r2, #0x2]
    cmp r6, #0x0
    bne SuperEffectiveCheck

ChilanBerryCheck:
    ldrh r5, [r7, #0x2E]
    ldrh r0, .ChilanIndex
    cmp r5, r0
    beq DamageReducer

SuperEffectiveCheck:
    ldr r0, .Outcome
    ldrb r1, [r0]
    mov r2, #0x2
    and r1, r2
    cmp r1, #0x0
    beq Exit

LoadItem:
    ldrh r5, [r7, #0x2E]
    ldr r3, .BerryTable
    ldrh r4, .FFHW

Loop:
    ldrh r0, [r3]
    cmp r0, r5
    beq TypeCheck
    cmp r0, r4
    beq Exit
    add r3, #0x3
    b Loop

TypeCheck:
    ldrb r0, [r3, #0x2]
    cmp r6, r0
    bne Exit

DamageReducer:
    ldr r4, .Damage
    ldrh r2, [r4]
    lsr r2, #0x1
    cmp r2, #0x0
    bne NotZero
    mov r2, #0x1

NotZero:
    strh r2, [r4]
    ldr r4, .ScriptIndex
    ldr r3, [r4]
    add r3, #0x1
    str r3, [r4]
    bl ScriptCall
    ldr r3, .BattleScript
    sub r3, #0x1
    str r3, [r4]
    ldr r0, .ItemBuffer
    strh r5, [r0]

Exit:
    bl Random
    lsl r0, r0, #0x10
    lsr r0, r0, #0x10
    mov r1, #0xF
    ldr r2, .Return
    bx r2

Random:
    ldr r2, .RNG
    bx r2

ScriptCall:
    ldr r2, =0x08017545
    bx r2

.align 2
.subval: .word 0x01000000
.ItemBuffer: .word 0x2023D68
.CurrMove: .word 0x2023D4A
.Damage: .word 0x02023D50
.Outcome: .word 0x02023DCC
.Target: .word 0x02023D6C
.PokemonData: .word 0x02023BE4
.MemoryLoc: .word 0x02023FE8
.MoveTable: .word 0x08XXXXXX
.BerryTable: .word 0x08TTTTTT
.Return: .word 0x0801F111
.RNG: .word 0x08044EC9
.ScriptIndex: .word 0x02023D74
.BattleScript: .word 0x08BBBBBB
.FFHW: .hword 0xFFFF
.ChilanIndex: .hword 0x0YYY

@1F106: 00 00 00 48 00 47 XX+1 XX XX 08


TTTTTT is the pointer to the table created above.
YYY is the index of Chilan Berry

I can't get this routine to compile. I get the following errors:
48: Error: invalid offset, target not word aligned <0x000000E2>
48: Error: invalid offset, value too big <0x0000009E>
My index number of Chilian Berry is 0x00A0 but it doesn't matter as I've tried changing the value many times and I still got the errors.

Trainer 781 July 28th, 2015 4:25 AM

For life orb, make sure that you have replaced the end command in the repointed command table.

I'll look into the Berry issue.

DizzyEgg July 28th, 2015 4:37 AM

Quote:

Originally Posted by KDS (Post 8866242)
For life orb, make sure that you have replaced the end command in the repointed command table.

I'll look into the Berry issue.

I did replace the command. It was this pointer: CD 2C 02 08 and I changed it to YY+1 YY YY 08.

Trainer 781 July 28th, 2015 4:54 AM

Quote:

Originally Posted by DizzyEgg (Post 8866258)
I did replace the command. It was this pointer: CD 2C 02 08 and I changed it to YY+1 YY YY 08.

Okk, then VM/PM me the offsets. I'll then able to see thd problem.

To fix thd damage berry routine just, change the .hword in the second last line to .word. (The error was due to some issues in Hackmew's compiler)

daniilS July 28th, 2015 8:08 AM

Quote:

Originally Posted by KDS (Post 8866282)
Okk, then VM/PM me the offsets. I'll then able to see thd problem.

To fix thd damage berry routine just, change the .hword in the second last line to .word. (The error was due to some issues in Hackmew's compiler)

Actually, you can never load a relative halfword.

mariomaniac432 July 28th, 2015 4:32 PM

I've been having some trouble getting the Berry System to work. For some reason, the script crashes when it gets to the first instance of the Get Tree Data routine. I know this is where the problem is because if I remove it from the script, it doesn't crash until it gets to the Berry Bag Selection routine, which for some reason crashes the game if I have a berry in the bag, but that could be a result of removing the Get Tree Ddata routine. I thought that maybe the problem was I installed JPAN's Save Block hack wrong (instructions seemed a little confusing at first, but I'm pretty sure I did it right), so I found this patch with the hack, applied it a clean FireRed 1.0 ROM, and then put all the other routines in, and had the same problem.

My script was a simple copy/paste from this thread, which the offsets filled in properly of course. All the ASM rotuines were also unmodified, and copied directly from this thread, I also tried compiling them myself and inserting them that way, but nothing seems to work.

leyn09 July 28th, 2015 10:08 PM

Edit : already solved. Sorry! I didnt check out first the thread.

Blah July 30th, 2015 5:38 AM

Quote:

Originally Posted by mariomaniac432 (Post 8867164)
I've been having some trouble getting the Berry System to work. For some reason, the script crashes when it gets to the first instance of the Get Tree Data routine. I know this is where the problem is because if I remove it from the script, it doesn't crash until it gets to the Berry Bag Selection routine, which for some reason crashes the game if I have a berry in the bag, but that could be a result of removing the Get Tree Ddata routine. I thought that maybe the problem was I installed JPAN's Save Block hack wrong (instructions seemed a little confusing at first, but I'm pretty sure I did it right), so I found this patch with the hack, applied it a clean FireRed 1.0 ROM, and then put all the other routines in, and had the same problem.

My script was a simple copy/paste from this thread, which the offsets filled in properly of course. All the ASM rotuines were also unmodified, and copied directly from this thread, I also tried compiling them myself and inserting them that way, but nothing seems to work.

The berry tree routine is bugged. I will go ahead and redo it sometime in the future. Sorry.

Blah July 30th, 2015 5:45 AM

Quote:

Originally Posted by Telemetius (Post 8828542)
Hi FBI, first of all thanks for your work! You've been really helpful.
My question regards your battle routine http://www.pokecommunity.com/showthread.php?p=8527650#8527650 .
I've been trying it without success in my Ruby rom hack hoping it would work just like in Fire Red.
Is there any way to remove the whiteout after losing a battle in a Ruby hack rom?

No clue. I have not even looked at a Ruby ROM since 2008.

Quote:

Originally Posted by Mr.Pkmn (Post 8822035)
Can we have run-like speed for surf and mach bike speed in FR? Even better would be an arbitrary speed value!

That's actually very easy. There's a bit in RAM somewhere which controls this. I vaguely remember posting about it here, but I'll get back to you with more content.

Quote:

Originally Posted by BluRose (Post 8790807)
I'd like to say that this thread has been really helpful for me as my ASM skills are far worse than sub-par and, also, the Chain-Fishing one in particular is really cool to me. (◕‿◕✿)

I'd also like to request something for Fire Red BPRE v1.0 (adding to the infinite list of requests...):
Stance Change.
Basically, where a Pokémon uses an offensive move and changes its form to a more offensive Pokémon (or, rather, just a different index-number Pokémon entirely). However, when it uses a certain move (or just a status move would be fine, too), it reverts back to the old form.
EDIT: Oh, and it would also have to revert to the other form outside of battle.
What I was thinking was two separate abilities in order to accomplish this, but if one is possible, then that's great too!
Thanks in advance!

God I sound so rude I am so sorry

EDIT: Also, should I go to DaniilS with this? I noticed that he had his own thread for form(e)s...

EDIT EDIT: Okay, I just noticed something while I was trying to get the Male-only and Female-only evolution methods working on Burmy.
But ALL of the Pokémon generated by your routine are Male unless if they have more of an 82 percent chance of being female, in which case they are, and the Pokémon already caught turn into females. This is also shown in you post showcasing it, as the Tyranitar are also all Male.
Just wanted to say this, haha...

Yes, go to daniilS with this. He should be done by now, 4 or so months ago he said he was working on forms and mega evolutions. He should have everything worked out now if he isn't slacking ;D

Quote:

Originally Posted by FamiliaWerneck (Post 8801700)
Few simple questions on breeding, egg groups and all that. You said it's all doable via a Pokémon Editor. What I want, actually is that Charizard evolutionary line breeds only with its line and/or Ditto. No Dragon/Monster egg groups. Will I have to make an egg group for each evolutionary family?
Also, how can I make Ditto breeds with himself too, not only all other Pokémon? And genderless Pokémon, like Magnemite? How can I make them breed?
Finally, for Nidorans and Volbeat/Illumise, I wanna make the male breed with the female, but not breedable with Ditto. How can I do it?



Here, I just want to know if I can make all Pokémon to be Docile as default or if I can change all natures' data, so all natures behave like Docile. Is either of these possible?
Thanks in advance!

For something specific like this it's better to just add in the exceptions yourself. The game will at some point check species for Ditto :)

If you give up, I can give you hints. My policy about strictly specific routines still stand however.

leyn09 August 3rd, 2015 7:22 PM

Quote:

Originally Posted by kleenexfeu (Post 8806372)
Well done on that KDS !

Same routine with Emerald offset !

Here :
Spoiler:

Spoiler:

Routine at XXXXXX:
Code:

.text
.align 2
.thumb
.thumb_func
.global lifeorbrecoil

SheerForceCheck:
      ldr r1, .UserBank
      ldr r2, .BattleStruct
      ldrb r1, [r1, #0x0]
      mov r0, #0x58
      mul r0, r1
      add r0, r0, r2
      mov r2, #0x20
      add r2, r0, r2
      ldrb r2, [r2]
      cmp r2, #0x7E /*Sheer Force*/
      bne EffectCheck
      ldr r0, .CurrMove
      ldrh r3, [r0, #0x0]
      mov r0, #0x0
      ldr r1, .FEHalfWord
      ldr r2, .SheerForceTable

Loop:
      lsl r4, r0, #0x01
      add r4, r4, r2
      ldrh r4, [r4, #0x0]
      cmp r3, r4
      beq Exit
      cmp r4, r1
      beq EffectCheck
      add r0, #0x1
      b Loop

EffectCheck:
      mov r1, r8
      cmp r1, #0x1E
      beq KingsRock
      cmp r1, #0x3E
      beq ShellBell
      cmp r1, #0xKK    /*Life orb held item effect*/
      bne Exit

CheckOutcome:
      ldr r0, .Outcome
      ldrb r0, [r0, #0x0]
      mov r5, #0x29
      and r5, r0
      cmp r5, #0x0
      bne Exit

CheckUturnVoltSwitch:
      ldr r0, .CurrMove
      ldrh r0, [r0]
      ldrh r1, .VoltSwitchID
      cmp r0, r1
      beq Exit
      ldrh r1, .UTurnID
      cmp r0, r1
      beq Exit

CheckIfMoveDamagedSomeTarget:
      ldr r1, .DamageStruct
      ldr r4, .TargetBank
      ldrb r2, [r4, #0x0]
      lsl r0, r2, #0x02
      add r0, r0, r2
      lsl r0, r0, #0x02
      add r6, r1, #0x4
      add r0, r0, r6
      ldr r1, [r0, #0x0]
      cmp r1, #0x0
      beq Exit
      ldr r0, .FFHalfWord
      cmp r1, r0
      beq Exit

CheckIfUserIsNotTheTarget:
      ldr r0, .UserBank
      ldrb r3, [r0, #0x0]
      cmp r3, r2
      beq Exit

CheckMagicGuard:
      ldr r2, .BattleStruct
      ldrb r1, [r0, #0x0]
      mov r0, #0x58
      mul r0, r1
      add r0, r0, r2
      mov r2, #0x20
      add r2, r0, r2
      ldrb r2, [r2]
      cmp r2, #0x63 /*Magic Guard*/
      beq Exit

HPCheck:
      ldrh r1, [r0, #0x28]
      cmp r1, #0x0
      beq Exit

SetLifeOrbRecoilBit:
      ldr r1, .LORBit
      mov r0, #0x1
      strb r0, [r1]

Exit:
      ldr r1, .Return2
      bx r1

KingsRock:
      ldr r0, .Return3
      bx r0

ShellBell:
      ldr r1, .Return1
      bx r1

Divider:
      ldr r2, =0x082E7540+1
      bx r2

ScriptPusher:
      ldr r0, =0x0803FAFC+1
      bx r0

.align 2
.UserBank: .word 0x0202420B
.TargetBank: .word 0x0202420C
.BattleStruct: .word 0x02024084
.DamageStruct: .word 0x0202437C
.CurrMove: .word 0x020241EA
.SheerForceTable: .word 0x08XXXXXX
.Outcome: .word 0x0202427C
.FEHalfWord: .word 0x0000FEFE
.FFHalfWord: .word 0x0000FFFF
.Return1: .word 0x08045794+1
.Return2: .word 0x0804582A+1
.Return3: .word 0x080456EC+1
.LORBit: .word 0x0203E338        /*It's actually a FreeRam loc*/
.UTurnID: .word 0x00000YYY        /*ID number of U-Turn*/
.VoltSwitchID: .word 0x00000ZZZ        /*ID number of Volt Switch*/

/*At 080456DC: 00 48 00 47 XX+1 XX XX 08*/



Spoiler:

Routine at YYYYYY:
Code:

.text
.align 2
.thumb
.thumb_func
.global endcommandwithlifeorbsupport

Main:
      ldr r1, .LORBit
      ldrb r0, [r1]
      cmp r0, #0x1
      bne EndCommand

LifeOrb:
      push {lr}
      push {r2-r7}
      mov r0, #0x0
      strb r0, [r1]
      ldr r0, .UserBank
      ldrb r3, [r0]
      mov r0, #0x58
      mul r0, r3
      ldr r2, .BattleStruct
      add r2, r2, r0
      ldrh r0, [r2, #0x28]
      cmp r0, #0x0
      beq Exit
      ldr r0, =0x0202420F
      strb r3, [r0, #0x0]
      ldr r0, =0x02024274
      strb r3, [r0, #0x17]
      ldr r4, =0x020241F0
      ldrh r0, [r2, #0x2C]
      mov r1, #0xA
      bl Divider
      strh r0, [r4, #0x0]
      cmp r0, #0x0
      bne NotZero
      mov r0, #0x1

NotZero:
      strh r0, [r4, #0x0]
      bl ScriptPusher
      ldr r1, .ScriptPointer
      ldr r0, .LifeOrbDamageScript
      str r0, [r1, #0x0]
      pop {r2-r7}
      pop {r0}
      bx r0

Exit:
      pop {r2-r7}
      pop {r0}

EndCommand:
      ldr r0, =0x0804B664+1
      bx r0

Divider:
      ldr r2, =0x082E7540+1
      bx r2

ScriptPusher:
      ldr r0, =0x0803FAFC+1
      bx r0

.align 2
.LifeOrbDamageScript: .word 0x08BBBBBB
.ScriptPointer: .word 0x02024214
.UserBank: .word 0x0202420B
.BattleStruct: .word 0x02024084
.LORBit: .word 0x0203E338        /*Same as in previous routine*/

/*YY+1 YY YY 08 must replaces the "end" command pointer */



Spoiler:

Battle Script at BBBBBB:
Code:

39 20 00 FA 20 E3 03 02 SS SS SS 08 10 84 01 12 40 00 35 80 42 02 02 00 01 00

00 0B 01 0C 01 19 01 00 00 00 00 00 3C


String at SSSSSS:
Code:

FD 0F 00 E0 E3 E7 E8 00 E7 E3 E1 D9 00 E3 DA 00 DD E8 E7 00 C2 CA AB FF





Bonus, Life Orb boost (lightball updated included). UPDATE for Emerald : I added a routine to make a new item that boost a certain type of attack. If you have a fairy type in your hack rom, you can now have an item that boost that type. You can adjust the boost the same way than miracle seed and such in G3T. I also implemented the TimeSpace orb in the routine :

Spoiler:

Emerald:
Code:

CheckLifeOrb:
cmp r2, #0x43        /*Held item effect of life orb, I chose 0x43 (= 67 in decimal) because it's unused*/
beq Lifeorb

CheckNewItem:
cmp r2, #0x44        /*Held item effect of the boost item, I chose 0x44 (= 68 in decimal) because it's unused*/
beq NewItem

CheckAdamantOrb:
cmp r2, #0x45        /*Unused held item effect*/
bne CheckLustreous
ldrh r0, [r6]
mov r3, #0xFF        /*0xFF + 0xE4 = 0x1E3 = 483 = index number of Dialga*/
add r3, #0xE4
cmp r0, r3
beq AdamantOrb

CheckLustreous:
cmp r2, #0x46        /*Unused held item effect*/
bne CheckGriseous
ldrh r0, [r6]
mov r3, #0xFF        /*0xFF + 0xE5 = 0x1E4 = 484 = index number of Palkia*/
add r3, #0xE5
cmp r0, r3
beq LustreousOrb

CheckGriseous:
cmp r2, #0x47        /*Unused held item effect*/
bne CheckLightBall
ldrh r0, [r6]
mov r3, #0xFF        /*0xFF + 0xE8 = 0x1E7 = 487 = index number of Giratina*/
add r3, #0xE8
cmp r0, r3
beq GriseousOrb
b Back

AdamantOrb:
push {r0-r5}
mov r1, #8        /*Steel type*/
mov r2, #0x10        /*Dragon type*/
b CheckExceptionTypeAttack

LustreousOrb:
push {r0-r5}
mov r1, #0xB        /*Water type*/
mov r2, #0x10        /*Dragon type*/
b CheckExceptionTypeAttack

GriseousOrb:
push {r0-r5}
mov r1, #7        /*Ghost type*/
mov r2, #0x10        /*Dragon type*/
b CheckExceptionTypeAttack

NewItem:
push {r0-r5}
mov r1, #9        /*New type you want to boost*/
mov r2, #9        /*New type you want to boost, here I choose the same because I want it boost only one type*/

CheckExceptionTypeAttack:
ldr r4, CheckTypeLoc
ldr r4, [r4]
ldrb r4, [r4, #0x13]
cmp r4, #0
beq GetMoveType
mov r5, #0x3F
and r4, r5
cmp r4, r1
beq Boost
cmp r4, r2
beq Boost
b PopAndBack

Back:
ldr r0, Return
bx r0

PopAndBack:
pop {r0-r5}
b Back

CheckLightBall:
cmp r2, #0x2D
bne Back
ldrh r0, [r6]
cmp r0, #0x19
beq Lightball
b Back

GetMoveType:
ldr r3, CurMoveIndex
ldrh r3, [r3]
ldr r4, MoveData
mov r5, #0xC
mul r5, r3
add r4, r5
ldrb r4, [r4, #2]
cmp r4, r1
beq Boost
cmp r4, r2
bne PopAndBack

Boost:
pop {r0-r5}
ldrh r3, [r6, #0x2E]
lsl r0, r3, #4
push {r1}
mov r1, #6
mul r3, r1
pop {r1}
add r3, r0
lsl r3, #1
ldr r0, LocItems
add r3, r0
add r3, #0x13
ldrb r0, [r3]
mov r3, #0x52
mul r0, r3
lsr r0, #6
add r0, #0x7B
mul r7, r0
lsr r7, #7
mov r3, r8
mul r3, r0
lsr r3, #7
mov r8, r3
b Back

Lifeorb:
mov r0, r8
mov r3, #0xA7
mul r0, r3
lsr r0, #7
mov r8, r0
mul r7, r3
lsr r7, #7
b Back

Lightball:
mov r0, r8
lsl r0, r0, #0x1
mov r8, r0
lsl r7, r7, #0x1
b Back

.align 2
Return: .word 0x0806983E+1
LocItems: .word 0x085839A0          /*Location of your items Data*/
CurMoveIndex: .word 0x020241EA
MoveData: .word 0x0831C898          /*Location of your move data*/
CheckTypeLoc: .word 0x0202449C

/*00 48 00 47 XX XX XX 08 00 00 00 at 0x6982C*/


Fire Red:
Code:

cmp r2, #0x43  /*Held item effect, I chose 0x43 (=67 in dec) because it is unused in the game*/
beq Lifeorb
cmp r2, #0x2D
bne Back
ldrh r0, [r6]
cmp r0, #0x19
beq Lightball
b Back

Lifeorb:
mov r0, r8
mov r3, #0xA7
mul r0, r3
lsr r0, #7
mov r8, r0
mul r7, r3
lsr r7, #7
b Back

Lightball:
mov r0, r8
lsl r0, r0, #0x1
mov r8, r0
lsl r7, r7, #0x1

Back:
ldr r0, Return
bx r0

.align 2
Return: .word 0x0803F00A+1

/*00 48 00 47 XX XX XX 08 00 00 00 at 0803EFF8*/






Yep, it is now updated

How should I use both the recoil and boost effect? Should it be separately compiled and just put the same held item byte effect in each routines?

kleenexfeu August 4th, 2015 3:16 AM

Quote:

Originally Posted by leyn09 (Post 8875571)
How should I use both the recoil and boost effect? Should it be separately compiled and just put the same held item byte effect in each routines?

Recoil and boost work indeed seperatly, as you can see the branch aren't done at the same places. So yeah you have to give the same effect in both routine as well as assembling them to have both recoil/boost effects.

Blah August 4th, 2015 9:49 AM

OAM routines



The first hackathon was probably the worst thing that could have happened for this thread. It completely killed my motivation for hacking and made me quit for a few months. There are some good things that came out of it, I was able to do a lot of research on things I hadn't before including field moves, OAM, trainer generation and such. I was looking around my older routines for OAM manipulation, and I had trouble understanding and ripping my own code! I had lost the source code, so I decided to rip as much as I can and redo the jibberish including some clean up.

Similar routines to these ones I'm presenting were used for the custom intro in team 4's hackoff ROM :)


Generating OAMs



This routine is only to generate OAMs which are trainer or Pokemon sprites. I've modified it to be usable with a script, but honestly, setting the values yourself via ASM would've been faster (not that this is noticeably slow, just comparatively). I will have to do more research on making it portray an arbitrary image, but with the expansion work on the Pokedex and such, I don't see it as very necessary anymore.

How to insert:
Compile and insert the following routine into a free word aligned offset.

Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r4, lr}
        sub SP, SP, #0x14

        @load PID
        ldr r2, =(0x20370B8) @PokeSlot
        ldrb r2, [r2]
        cmp r2, #0x6
        beq shiny
        ldr r0, =(0x2024284)
        mov r4, #0x64
        mul r2, r2, r4
        add r2, r2, r0
        ldrh r2, [r2] @PID

        @load TID
        ldr r1, =(0x300500C)
        ldr r1, [r1]
        ldrh r1, [r1, #0xA] @TID
        b cont

shiny:
        mov r0, #0x0
        mov r1, r0
        mov r2, r0

cont:
        @X-pos
        ldr r0, =(0x20370BA)
        ldrh r0, [r0]
        str r0, [SP] @X-Pos

        @Y-pos
        ldr r0, =(0x20370BC)
        ldrh r0, [r0]
        str r0, [SP, #0x4] @Y-Pos

        @pal #
        ldr r0, =(0x20370BE)
        ldrh r0, [r0]
        str r0, [SP, #0x8] @pal #

        ldr r3, =(0x20370C0)
        ldrb r3, [r3]
        cmp r3, #0x1
        bne nonsil
        mov r3, #0x0
        str r3, [SP, #0xC] @occupacity
        b unkn

nonsil:
        ldr r3, =(0x0000FFFF)
        str r3, [SP, #0xC] @occupacity

unkn:
        @??? - No idea, but leave as 0s
        @possibly priority?
        ldr r0, =(0x20370C6)
        ldrb r0, [r0]
        str r0, [SP, #0x10]
        mov r0, #0x0
        str r0, [SP, #0x14]

        @species/sprite ID
        ldr r0, =(0x20370C2)
        ldrh r0, [r0]

        @front VS back
        ldr r3, =(0x20370C4)
        ldrb r3, [r3]

        @display func
        ldr r4, =(0x810BDAC +1)
        bl linker
        add SP, SP, #0x14
        pop {r0-r4, pc}

linker:
        bx r4

.align 2


Compiled version:
Code:

1F B5 85 B0 18 4A 12 78 06 2A 08 D0 17 48 64 24 62 43 12 18 12 88 16 49 09 68 49 89 02 E0 00 20 01 1C 02 1C 13 48 00 88 00 90 13 48 00 88 01 90 12 48 00 88 02 90 12 4B 1B 78 01 2B 02 D1 00 23 03 93 01 E0 0F 4B 03 93 0F 48 00 78 04 90 00 20 05 90 0E 48 00 88 0E 4B 1B 78 0E 4C 00 F0 02 F8 05 B0 1F BD 20 47 C0 46 B8 70 03 02 84 42 02 02 0C 50 00 03 BA 70 03 02 BC 70 03 02 BE 70 03 02 C0 70 03 02 FF FF 00 00 C6 70 03 02 C2 70 03 02 C4 70 03 02 AD BD 10 08




Usage:
The usage is quite simple, but it takes up a lot of temporary variables :P

Code:

@var 0x8000 - Slot #. Set 0x6 for shiny.
@var 0x8001 - X-pos
@var 0x8002 - Y-pos
@var 0x8003 - Unoccupied Pal ID number. See OAM viewer.
@var 0x8004 - Occupacity silluette set 1
@var 0x8005 - species/trainer sprite ID
@var 0x8006 - Front (1) or Back (0)
@var 0x8007 - Toggle trainer or Pokemon


Some quick notes about these variables.

Variable 0x8000 is to determine the Pokemon's shinyness. If you're showing a Pokemon in your party just use that Pokemon's party slot. If you're showing a shiny Pokemon go ahead and use 0x6. Basically 0x6 = shiny, anything else (must be lower) depends on party slot.

Variable 0x8003 plays a key role. Make sure in the OAM viewer the sprite ID is free.
http://i.imgur.com/rwUxxWe.png
Here sprite number 0 is taken by Oak's OAM. Click the Arrow until you find something not occupied, and set this variable to that value!

Variable 0x8007 is a switch of sorts. It determines whether to show a trainer sprite or a Pokemon sprite.

I think the rest of the variables are self explanatory. Mess around with them a little :)


OAM tracking



So I'm sure you can imagine, that at some point in time you want your OAM to disappear. You can't have it on the screen forever, maybe even make it disappear temporarily and reshow it without having to do the painfully expensive creation call again. I made a routine which will take into account the last OAM ID which you created and stores it in var 0x8008. Note that this is an ID assigned by the game code, not the same ID as the one we assigned on creation. Therefore it's important to track this.

How to insert

Compile and insert the following routine into free space.
Spoiler:

.text
.align 2
.thumb
.thumb_func

@ID of last OAM created - 0x8008
@Hook at 0x80070B0 via r1

main:
ldr r1, =(0x20370C8)
strh r0, [r1]
lsl r6, r6, #0x10
lsr r6, r6, #0x10
lsl r4, r4, #0x18
lsr r4, r4, #0x18
lsl r0, r0, #0x4
ldr r1, =(0x80070BA +1)
bx r1

.align 2


Navigate to 080070B0 and insert the following byte changes:
Code:

00 49 08 47 XX XX XX 08


Where XX XX XX is the location your inserted your routine in reverse hex +1. The trailing "08" may change to 09 or something depending on where you inserted it. Remember to stay word aligned!

Usage:
This routine doesn't really do anything by itself. It's more of a routine which works in the background. It just writes to variable 0x8008 the last displayed OAM's ID. Basically, just insert it and do nothing :3


A quick explanation of how OAMs are shown/hidden in FireRed.



There's a neat RAM structure in FireRed which controls whether or not to show or unshow an OAM on the screen. This OAM's ID needs to be present in said structure. The structure, for some unknown reason, is 40 bytes in size. It looks like this:

[OAM ID (1 byte)] [OAM ID (1 byte)] [OAM ID (1 byte)] ... [Byte 0x3F] [Filler bytes] ...[40th filler byte]

In case you don't understand by now, it's basically a table of X entries where each entry is an OAM's ID to display. Every entry after the byte 0x3F is not read by game code, and is therefore nothing more than filler bytes!

The reason as to why I'm confused the structure is 40 bytes is because the routines which use this structure restrict themselves by using another structure. This second structure only holds 13 OAMs at a time, which is why we can only have 13 OAMs present in FR on screen at once WITHOUT fully customized code. For the most part you'll never go over 13 anyways. I used 9 in total for the custom intro and the screen was cluttered :X

My guess as to why it's 40 bytes is because it's used for animation frames as well. I'm not sure, I haven't researched that.
This structure is located at 0x2021800.

Hiding OAMs created



Now that you understood the data structure, you need to remove your OAM's byte ID from the table. But how do you know which byte is your OAM's byte? That was what the previous tracker routine was for. Right after you create your OAM the corresponding table ID will be in var 0x8008. Copy this value into somewhere you won't lose it (i,e a non-temporary variable), from there you can callasm this routine with the appropriate parameters :)

How to insert:

Compile and insert the following routine to free space:
Spoiler:

.text
.align 2
.thumb
.thumb_func

@OAM ID to hide - 0x8000

main:
push {r0-r2, lr}
ldr r0, =(0x2021800)
ldr r2, =(0x20370B8)
ldrb r2, [r2]

loop:
ldrb r1, [r0]
cmp r1, r2
beq set
add r0, r0, #0x1
b loop

set:
mov r1, #0x3F
strb r1, [r0]

done:
pop {r0-r2, pc}

.align 2



Usage:

In a script, set variable 0x8000 to the OAM ID you want to vanish, then simply callasm this routine. This data structure is updated every frame from what I was able to see, so the results should be immediate.


Show OAM



Sometimes you want to hide an OAM but only temporary. This routine will show an OAM which has already been loaded, but flagged as hidden or similar.

How to insert:

Compile and insert into free space the following routine:
Spoiler:

.text
.align 2
.thumb
.thumb_func

@OAM ID to set - 0x8000

main:
push {r0-r2, lr}
ldr r0, =(0x2021800)

loop:
ldrb r1, [r0]
cmp r1, #0x3F
beq set
add r0, r0, #0x1
b loop

set:
ldr r2, =(0x20370B8)
ldrb r2, [r2]
strb r2, [r0]
mov r1, #0x3F
add r0, r0, #0x1
strb r1, [r0]

done:
pop {r0-r2, pc}

.align 2


Usage:

In a script, set variable 0x8000 to the OAM ID you want to reappear, then simply callasm this routine. This data structure is updated every frame from what I was able to see, so the results should be immediate.

Closing notes:



I may or may not update these with animations as well. One I'm particularly interested in doing is a slow fade. The biggest thing I want to address is how to use these in a script. I think it's fairly intuitive, but a quick example may help :)

Spoiler:

Code:

#dyn 0x740000
#org @start
lock
faceplayer
fadescreen FADEOUT_BLACK

'setting up parameters for OAM creation routine
setvar 0x8007 0x0
setvar 0x8000 0x0
setvar 0x8001 0x74
setvar 0x8002 0x64
setvar 0x8003 0x1
setvar 0x8004 0x0
setvar 0x8005 0x85
setvar 0x8006 0x1
callasm 0x[location you inserted creation routine +1]

'recall our last created OAM is stored in 0x8008

copyvar 0x8009 0x8008

'simply vanishing the OAM
copyvar 0x8000 0x8008
callasm 0x[location you inserted hide routine +1]

'creating a second OAM!
setvar 0x8000 0x0
setvar 0x8001 0x74
setvar 0x8002 0x64
setvar 0x8003 0x2
setvar 0x8004 0x0
setvar 0x8005 0x86
setvar 0x8006 0x1
callasm 0x[location you inserted creation routine +1]

copyvar 0x800A 0x8008
copyvar 0x8000 0x8008
'remove visibility
callasm 0x[location you inserted hide routine +1]
jump @loop

#org @loop
'-----------------------------------
compare 0x8007 0x60
if == jump @done ' Equal To

'show OAM 1
copyvar 0x8000 0x8009
callasm 0x[location you inserted show routine +1]
pause 0x10

'hide OAM 1
copyvar 0x8000 0x8009
callasm 0x[location you inserted hide routine +1]

'show OAM 2
copyvar 0x8000 0x800A
callasm 0x[location you inserted hide routine +1]
pause 0x10

'hide OAM 2
copyvar 0x8000 0x800A
callasm 0x[location you inserted hide routine +1]

'increment loop
addvar 0x8007 0x1
jump @loop

#org @done
'-----------------------------------
fadescreen FADEIN_BLACK
msgbox @text ' Phew.
callstd MSG_LOCK ' Built-in lock command
release
end

#org @text
= Phew.




Play around with it. It can be fun, and hopefully this will open more doors for hackers. I've made it as friendly as possible even opening up the potential to use it in scripts, but if you have any questions you can direct them to me at the ASM help thread or something :D

FamiliaWerneck August 5th, 2015 4:29 AM

Quote:

Originally Posted by FBI agent (Post 8512782)

Preventing TMs from being consumed on use



Quick research:
TMs are deleted in two places. The first place is in their own function. When called from the bag, after use the TM has it's own deletion mechanism. The second way is from the bag, after you use a TM the bag attempts to delete it as well. Well, the solution is quite simple. There's two ways to do this, either go to 0809A1D8 call your own function there which checks if the item is a TM, and if it is, just jump to the end. Or much more simply you just remove the parts from the bag and tm function that deletes the TM (Which is what I did). The former way is a way you can make another item you have unconsumable.

To insert:
Do the byte changes below
0x124F78: 00 00 00 00
0x125C80: 00 00 00 00

Make it Ungivable:
insert that at 0x1326B8: 00 00 17 E0

Make it consumable after animation:
Insert: 00 00 00 00 at 0x124F78

To remove the quantities showing up in the bag:

Compile and insert into free space:
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        cmp r5, #0x0
        bne end
        ldr r3, =(0x8131EFE +1)
        bx r3

end:
        mov r0, r7
        mov r1, #0x8
        mov r2, r4
        ldr r6, =(0x81335B0 +1)
        bl link
        ldr r3, =(0x8131EFE +1)
        bx r3

link:
        bx r6

.align 2




Here's a compiled version:
Code:

00 2D 01 D1 05 4B 18 47 38 1C 08 21 22 1C 04 4E 00 F0 02 F8 01 4B 18 47 30 47 C0 46 FF 1E 13 08 B1 35 13 08


Now navigate to 0x131EF4 and insert:
Code:

00 48 00 47 XX XX XX 08


Where XX XX XX is the pointer to where you assembled the routine +1

Now navigate to 0x131EA5 and change the byte to E0

Unsellable:
Basically for the TMs, you can still sell them to vendors. To change this, you need to modify each TM individually. It's unfortunate, but the game checks if an item can be sold my comparing it's market price to zero. If it's strictly greater than zero, then you can sell it to a vendor, seems to be the rule. So to make TMs unsellable you need to set their market prices individually to zero.
I can't use my own checks to disguise the TMs as unique because the sell routine in shops are used for ALL items including potions, berries, TMs, and other items like nuggets.


Present :3
http://i.imgur.com/3nina1p.png?1

I've got a HUGE problem with this!!!!
I was playing and normally using TMs for 20k Pokémon (not a number, I'm exaggerating). I'm after the league now, and I was giving Toxic to some Pokémon, to help me catch others, so I could get the 60 Pokémon to get National Dex and be able to go to Four Island.
Problem is, when I was going to give Toxic to my Chansey, it was gone! Then I looked for the Psychic TM (other move I give to her, I took it out briefly for Rock Smash), and it was gone too. What the hell happened?
Is there a limit for this?
I got my save back, from the GBA in-game save, and I had Toxic yet. I tested giving it to one Pokémon and it didn't disappear. Then I gave it to other and then it wasn't there anymore. Is there a limited amout of times I can use a TM? Or there's something incomplete about this hack?

Blah August 5th, 2015 5:54 AM

Quote:

Originally Posted by FamiliaWerneck (Post 8877410)
I've got a HUGE problem with this!!!!
I was playing and normally using TMs for 20k Pokémon (not a number, I'm exaggerating). I'm after the league now, and I was giving Toxic to some Pokémon, to help me catch others, so I could get the 60 Pokémon to get National Dex and be able to go to Four Island.
Problem is, when I was going to give Toxic to my Chansey, it was gone! Then I looked for the Psychic TM (other move I give to her, I took it out briefly for Rock Smash), and it was gone too. What the hell happened?
Is there a limit for this?
I got my save back, from the GBA in-game save, and I had Toxic yet. I tested giving it to one Pokémon and it didn't disappear. Then I gave it to other and then it wasn't there anymore. Is there a limited amout of times I can use a TM? Or there's something incomplete about this hack?

No, there shouldn't be a limit. Can anyone else confirm this bug? Also can you give me a specific case for when the TM disappears? There was a bug where it can get consumed if 4 moves were already learned. I fixed that already (it's in a separate post).

FamiliaWerneck August 5th, 2015 6:21 AM

Quote:

Originally Posted by FBI agent (Post 8877542)
No, there shouldn't be a limit. Can anyone else confirm this bug? Also can you give me a specific case for when the TM disappears? There was a bug where it can get consumed if 4 moves were already learned. I fixed that already (it's in a separate post).

I'll confirm this second bug. Also, if you want, I can record a video of me making the TM move magically disappear. HAHAHAHA

EDIT: Second bug not confirmed!
When I noticed this, I used it in my Abra, which only had Teleport. Then it was gone after I used it in my Ekans, which had 4 moves learned.
But now, I used in an Ekans with 4 moves learned first, and I kept the TM. Then I used in my Abra, which had only one, and then the TM disappeared.
So, 4 moves learned bug is not my problem, so it seems.

Blah August 5th, 2015 9:27 AM

Frontier Routines - Opponent Party generation



I've been meaning to implement a frontier of sorts into FireRed for some time but never really got a good opportunity to do so. Today I got a little bored and decided that I might as well start up. The first problem is obviously to generate a pseudo random party for the opposing trainer. That's what I've done today!

I had made a generation routine in the past as well, but it was incomplete and a little buggy. This one, as far as I can tell in my tests, should work fine :)


Setting up some prerequisites:
When making the routine for Pokemon generation, it was important that the hacker had some customization about which Pokemon were allowed into the opponents party (to prevent legendary Pokemon, or some specific Pokemon into the competition). The best way to do that is to either make a table of the Pokemon allowed to be in the opponent's party, or a table of the Pokemon not allowed to be in it. I decided to make the hacker do a table of all the Pokemon species allowed to be in the opponent's party.

It's important to remember that Pokemon Species ID takes 2 bytes per species, and that each entry in the table is in reverse hex. Bulbasaur for example would be: "01 00" in the table. The size of the table is up to you. The biggest reason I made the table be a table of all the Pokemon allowed is because this allows you to put more than 1 entry of the same Pokemon (thus increasing it's likelihood to be selected) ==> not all Pokemon species have the same chance of being selected!

Find some half-word aligned free space (offset divisible by 2) and fill up your table with as many entries as you'd like in this format:
Code:

[2 bytes (ID)] [2 bytes (ID)] ...


Write down how many entries you have, and where the start of the table is.


How to insert:

First take a look at the routine in the spoiler. Scroll to the very bottom, and you will see two fields which need filling. The first is called "Table". Table is supposed to be a location to the table of IDs we made earlier, replace 0x8750000 with your table location. Tsize is supposed to be the amount of Pokemon your table has in it, adjust that accordingly as well.

Finally, the routine is flag toggled. If flag 0x205 is set, the opponent is generated a random party. To adjust this change these lines accordingly:
Code:

        mov r0, #0xFF
        lsl r0, r0, #0x1 @0xFF * 2
        add r0, r0, #0x7 @ 0x1FE + 7


Once the adjustments are complete, compile and insert into free space.
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

@Hook 080112F8 via r0

main:
        push {r0-r7}
        @flag check 205
        mov r0, #0xFF
        lsl r0, r0, #0x1
        add r0, r0, #0x7
        ldr r4, =(0x806E6D0 +1)
        bl linker
        cmp r0, #0x0
        beq end

genAmount:
        ldr r4, =(0x8044EC8 +1)@gen random number
        bl linker
        lsl r0, r0, #0x10
        lsr r0, r0, #0x10
        mov r1, #0x6
        ldr r4, =(0x81E4684 +1)
        bl linker
        add r0, r0, #0x1
        mov r5, r0

mallocSpace:
        mov r0, #0x64
        mul r0, r0, r5
        ldr r4, =(0x8002BB0 +1) @malloc
        bl linker
        mov r6, r0
        mov r7, #0x0

@R5 = amount of mons
@R6 = free space to put them

genLoop:
        cmp r7, r5
        beq moveParty

genSpeciesFromTable:
        ldr r4, =(0x8044EC8 +1)@gen random number
        bl linker
        lsl r0, r0, #0x10
        lsr r0, r0, #0x10
        ldr r1, Tsize
        ldr r4, =(0x81E4684 +1)
        bl linker
        lsl r0, r0, #0x1
        ldr r1, Table
        add r1, r1, r0
        ldrh r1, [r1]

createMon:
        mov r0, #0x64
        mul r0, r0, r7
        add r0, r0, r6 @free memory
        ldr r2, =(0x20370BA)
        mov r2, #0x32 @level
        mov r3, #0x20 @cnst
        ldr r4, =(0x803DA54 +1)
        bl linker
        add r7, r7, #0x1
        b genLoop

moveParty:
        ldr r0, =(0x202402C)
        mov r1, r6
        mov r2, #0x64
        mul r2, r2, r5
        ldr r4, =(0x8040B08 +1) @func
        bl linker
        mov r0, r6
        ldr r4, =(0x8002BC4 +1) @free malloc'd memory
        bl linker
        pop {r0-r7}
        ldr r3, =(0x80116AC +1)
        bx r3

end:
        pop {r0-r7}
        ldr r0, =(0x400)
        cmp r1, r0
        bne place
        mov r0, #0x0
        ldr r3, =(0x80116AC +1)
        bx r3

place:
        ldr r3, =(0x8011304 +1)
        bx r3

linker:
        bx r4

.align 2

Table:
        .word 0x8750000 @your table of Mons

Tsize:
        .word 0x32 @Amount of entries in table




Finally, in a hex editor insert the following byte changes at 0x112F8:
Code:

00 48 00 47 XX XX XX 08


Where XX XX XX is the place you inserted the routine +1. Note that the trailing 08 may change depending on where you placed the routine.


Usage:

The routine is flag toggled. Set flag 0x205 before entering battle, and the rest is done automatically.

Blah August 5th, 2015 9:30 AM

Quote:

Originally Posted by FamiliaWerneck (Post 8877577)
I'll confirm this second bug. Also, if you want, I can record a video of me making the TM move magically disappear. HAHAHAHA

EDIT: Second bug not confirmed!
When I noticed this, I used it in my Abra, which only had Teleport. Then it was gone after I used it in my Ekans, which had 4 moves learned.
But now, I used in an Ekans with 4 moves learned first, and I kept the TM. Then I used in my Abra, which had only one, and then the TM disappeared.
So, 4 moves learned bug is not my problem, so it seems.

Try the fix I posted for the 4 move bug. I'm pretty sure it's the same fix for both problems.

Xencleamas August 5th, 2015 9:37 AM

Quote:

Originally Posted by FBI agent (Post 8520402)

Set static party level


Is it just me OR and the opponent/AI as well?

azurile13 August 5th, 2015 11:26 AM

Quote:

Originally Posted by FBI agent (Post 8877758)

Frontier Routines - Opponent Party generation



I've been meaning to implement a frontier of sorts into FireRed for some time but never really got a good opportunity to do so. Today I got a little bored and decided that I might as well start up. The first problem is obviously to generate a pseudo random party for the opposing trainer. That's what I've done today!

I had made a generation routine in the past as well, but it was incomplete and a little buggy. This one, as far as I can tell in my tests, should work fine :)


Setting up some prerequisites:
When making the routine for Pokemon generation, it was important that the hacker had some customization about which Pokemon were allowed into the opponents party (to prevent legendary Pokemon, or some specific Pokemon into the competition). The best way to do that is to either make a table of the Pokemon allowed to be in the opponent's party, or a table of the Pokemon not allowed to be in it. I decided to make the hacker do a table of all the Pokemon species allowed to be in the opponent's party.

It's important to remember that Pokemon Species ID takes 2 bytes per species, and that each entry in the table is in reverse hex. Bulbasaur for example would be: "01 00" in the table. The size of the table is up to you. The biggest reason I made the table be a table of all the Pokemon allowed is because this allows you to put more than 1 entry of the same Pokemon (thus increasing it's likelihood to be selected) ==> not all Pokemon species have the same chance of being selected!

Find some half-word aligned free space (offset divisible by 2) and fill up your table with as many entries as you'd like in this format:
Code:

[2 bytes (ID)] [2 bytes (ID)] ...


Write down how many entries you have, and where the start of the table is.


How to insert:

First take a look at the routine in the spoiler. Scroll to the very bottom, and you will see two fields which need filling. The first is called "Table". Table is supposed to be a location to the table of IDs we made earlier, replace 0x8750000 with your table location. Tsize is supposed to be the amount of Pokemon your table has in it, adjust that accordingly as well.

Finally, the routine is flag toggled. If flag 0x205 is set, the opponent is generated a random party. To adjust this change these lines accordingly:
Code:

        mov r0, #0xFF
        lsl r0, r0, #0x1 @0xFF * 2
        add r0, r0, #0x7 @ 0x1FE + 7


Once the adjustments are complete, compile and insert into free space.
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

@Hook 080112F8 via r0

main:
        push {r0-r7}
        @flag check 205
        mov r0, #0xFF
        lsl r0, r0, #0x1
        add r0, r0, #0x7
        ldr r4, =(0x806E6D0 +1)
        bl linker
        cmp r0, #0x0
        beq end

genAmount:
        ldr r4, =(0x8044EC8 +1)@gen random number
        bl linker
        lsl r0, r0, #0x10
        lsr r0, r0, #0x10
        mov r1, #0x6
        ldr r4, =(0x81E4684 +1)
        bl linker
        add r0, r0, #0x1
        mov r5, r0

mallocSpace:
        mov r0, #0x64
        mul r0, r0, r5
        ldr r4, =(0x8002BB0 +1) @malloc
        bl linker
        mov r6, r0
        mov r7, #0x0

@R5 = amount of mons
@R6 = free space to put them

genLoop:
        cmp r7, r5
        beq moveParty

genSpeciesFromTable:
        ldr r4, =(0x8044EC8 +1)@gen random number
        bl linker
        lsl r0, r0, #0x10
        lsr r0, r0, #0x10
        ldr r1, Tsize
        ldr r4, =(0x81E4684 +1)
        bl linker
        lsl r0, r0, #0x1
        ldr r1, Table
        add r1, r1, r0
        ldrh r1, [r1]

createMon:
        mov r0, #0x64
        mul r0, r0, r7
        add r0, r0, r6 @free memory
        ldr r2, =(0x20370BA)
        mov r2, #0x32 @level
        mov r3, #0x20 @cnst
        ldr r4, =(0x803DA54 +1)
        bl linker
        add r7, r7, #0x1
        b genLoop

moveParty:
        ldr r0, =(0x202402C)
        mov r1, r6
        mov r2, #0x64
        mul r2, r2, r5
        ldr r4, =(0x8040B08 +1) @func
        bl linker
        mov r0, r6
        ldr r4, =(0x8002BC4 +1) @free malloc'd memory
        bl linker
        pop {r0-r7}
        ldr r3, =(0x80116AC +1)
        bx r3

end:
        pop {r0-r7}
        ldr r0, =(0x400)
        cmp r1, r0
        bne place
        mov r0, #0x0
        ldr r3, =(0x80116AC +1)
        bx r3

place:
        ldr r3, =(0x8011304 +1)
        bx r3

linker:
        bx r4

.align 2

Table:
        .word 0x8750000 @your table of Mons

Tsize:
        .word 0x32 @Amount of entries in table




Finally, in a hex editor insert the following byte changes at 0x112F8:
Code:

00 48 00 47 XX XX XX 08


Where XX XX XX is the place you inserted the routine +1. Note that the trailing 08 may change depending on where you placed the routine.


Usage:

The routine is flag toggled. Set flag 0x205 before entering battle, and the rest is done automatically.

This is quite a useful routine. Are there any issues you imagine arising from extending the entries to include custom movesets, held items, ev/iv etc?

FamiliaWerneck August 5th, 2015 7:24 PM

Quote:

Originally Posted by FBI agent (Post 8877765)
Try the fix I posted for the 4 move bug. I'm pretty sure it's the same fix for both problems.

It seemed to work. I'll report back if I find anything else.
Bro, please update your Reusable TM post with this information.
Not for me, I already have it working. For other people not to stumble in the same issue.
Thanks for the help!

esperance August 6th, 2015 7:41 PM

Quote:

Originally Posted by FamiliaWerneck (Post 8878487)
It seemed to work. I'll report back if I find anything else.
Bro, please update your Reusable TM post with this information.
Not for me, I already have it working. For other people not to stumble in the same issue.
Thanks for the help!

Don't worry, they're both linked in the first post. :3

GoGoJJTech August 7th, 2015 6:29 PM

Quote:

Originally Posted by FBI agent (Post 8524910)
I don't really feel like doing a challenge cup. Also some of your features can be achieved using the already created party checker routine. Species Clause, Evasion Clause, OHKO clause can all be done by it. Maybe if I feel like it in future :P


Custom nicknames for enemy Pokemon



So this works for any wild or trainer Pokemon. It basically allows you to nickname a Pokemon on the enemy team prior to battling. For those special trainers or maybe special Pokemon :)

How to insert:

There's actually a little bit of work before you can compile and insert routines. First look at the routine below. You'll notice at the last line there is a Pointer to something that I call "TABLE". This table is going to be a table full of nickname with each entry 0xB bytes long. Find some space in your ROM which you will use for this table and correct the offset accordingly.

Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        mov r0, #0x9C
        lsl r0, #0x2
        push {r1-r7}
            ldr r2, =(0x806E6D0 +1)
        bl linker
        pop {r1-r7}
        cmp r0, #0x0
        beq old

nick:
        ldr r0, =(0x202402C)
        sub r0, r7, r0
        mov r1, #0x64
        ldr r2, =(0x81E4018 +1) @slot number
        bl linker
        mov r3, r0
        ldr r1, = (0x20370B8) @table entry position
        ldrb r1, [r1]
        mov r2, #0xB
        mul r1, r1, r2
        ldr r0, .TABLE
        add r0, r0, r1 @table start position
        mul r3, r3, r2
        add r0, r0, r3 @name to give
        mov r1, r7
        add r1, r1, #0x8 @nickname location
        mov r4, #0x0

nameLoop:
        cmp r4, #0xB
        beq end
        ldrb r3, [r0]
        strb r3, [r1]
        add r1, r1, #0x1
        add r0, r0, #0x1
        add r4, r4, #0x1
        b nameLoop

end:
        ldr r0, =(0x8040ADA +1)
        bx r0

old:
        mov r2, #0x0
        mov r3, r7
        add r3, #0x8

oldLoop:
        add r0, r3, r2
        add r1, r4, r2
        ldrb r1, [r1]
        strb r1, [r0]
        add r2, r2, #0x1
        cmp r2, #0x9
        ble oldLoop
        ldr r0, =(0x8040ADA +1)
        bx r0

linker:
        bx r2

.align 2

.TABLE:
        .word 0x8760000



Once you've made the modification to the pointer, compile and insert the routine into freespace.
Next navigate to offset 0x406DC and insert the following:
Code:

00 48 00 47 XX XX XX 08


Where XX is the pointer to the above routine in reverse hex +1.

Usage:
First navigate to your table which will contain the nicknames (it should be the offset in the routine you changed). You need to keep the table formatted like this [10 bytes (Name in hex)] [1 byte (0xFF)]. Insert as many names as you'd like.

Next, to activate the routine, you must setflag 0x270 AND you need to setvar 0x8000 0x[table starting index].
If you're battling a trainer with 6 Pokemon, the nicknames will be determined from the table. It will read six nicknames starting from the starting index given by variable 0x8000. There is no need to callasm. :)

http://i.imgur.com/wZeZnYU.png

Danny told me to find this for Emerald, and so I did. 0x406DC is for Fire Red, 0x6AFA8 is for Emerald. I did not test this, but it should theoretically work. (Of course the offsets in the routine will have to be changed, I can start doing that but it's late and stuff)

EDIT: If you ever want me to find the Emerald offsets for you, I'd be glad to.
EDIT^2: Edited routine for Emerald (Changes in Red)

Spoiler:
Code:

.text
.align 2
.thumb
.thumb_func

main:
        mov r0, #0x9C @0x9C * 4 (which is what the next line does) = 0x270. Change this for the flag since it's most likely not free in Emerald
        lsl r0, #0x2
        push {r1-r7}
            ldr r2, =(0x809D790 +1) @Flag Check
        bl linker
        pop {r1-r7}
        cmp r0, #0x0
        beq old

nick:
        ldr r0, =(0x2024744) @Opponent RAM location
        sub r0, r7, r0
        mov r1, #0x64
        ldr r2, =(0x82E7540 +1) @slot number
        bl linker
        mov r3, r0
        ldr r1, = (0x20375D8) @table entry position
        ldrb r1, [r1]
        mov r2, #0xB
        mul r1, r1, r2
        ldr r0, .TABLE
        add r0, r0, r1 @table start position
        mul r3, r3, r2
        add r0, r0, r3 @name to give
        mov r1, r7
        add r1, r1, #0x8 @nickname location
        mov r4, #0x0

nameLoop:
        cmp r4, #0xB
        beq end
        ldrb r3, [r0]
        strb r3, [r1]
        add r1, r1, #0x1
        add r0, r0, #0x1
        add r4, r4, #0x1
        b nameLoop

end:
        ldr r0, =(0x806B3D8 +1)
        bx r0

old:
        mov r2, #0x0
        mov r3, r7
        add r3, #0x8

oldLoop:
        add r0, r3, r2
        add r1, r4, r2
        ldrb r1, [r1]
        strb r1, [r0]
        add r2, r2, #0x1
        cmp r2, #0x9
        ble oldLoop
        ldr r0, =(0x806B3D8 +1)
        bx r0

linker:
        bx r2

.align 2

.TABLE:
        .word 0x8760000



Blah August 7th, 2015 7:10 PM

Quote:

Originally Posted by Sky High (Post 8877782)
Is it just me OR and the opponent/AI as well?

Just your party.

Quote:

Originally Posted by azurile13 (Post 8877962)
This is quite a useful routine. Are there any issues you imagine arising from extending the entries to include custom movesets, held items, ev/iv etc?

Yeah that's not too hard, but I think you'd prefer to make your own trainer if you'd have something memorable like custom items and movesets no? It would mean more tables, and more work for the inserter. So much to the point that it wouldn't really be worth the effort, kind of like having 100 TMs.

Quote:

Originally Posted by Lost Heart (Post 8880068)
Don't worry, they're both linked in the first post. :3

Thanks I was too lazy to edit my post anyways!

Quote:

Originally Posted by GoGoJJTech (Post 8881308)
Danny told me to find this for Emerald, and so I did. 0x406DC is for Fire Red, 0x6AFA8 is for Emerald. I did not test this, but it should theoretically work. (Of course the offsets in the routine will have to be changed, I can start doing that but it's late and stuff)

EDIT: If you ever want me to find the Emerald offsets for you, I'd be glad to.

My old routines make my eyes bleed my eyes X_X
Someone who's keen can go back and make efficiency changes to some of these. A brave and unlazy soul!

GoGoJJTech August 7th, 2015 7:11 PM

Quote:

Originally Posted by FBI agent (Post 8672577)

HP Regeneration per step



Intro:
Basically a routine to regenerate a Pokemon's HP every step. In this routine it's set to 3 per step. You may want to modify the exact amount to a percentage or something (see the commented line).

How to insert:

First compile and insert the following routine into free space.

Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r7}
        ldr r0, =(0x2024284)
        mov r6, #0x0
        ldr r7, =(0x2024029)
        ldrb r7, [r7]

loop:
        cmp r6, r7
        beq end
        mov r1, #0x64
        mul r1, r1, r6
        add r0, r0, r1
        mov r5, r0
        mov r1, #0x39
        ldr r3, =(0x803FBE8 +1)
        bl linker
        mov r4, r0
        cmp r4, #0x0
        beq next
        mov r0, r5
        mov r1, #0x3A
        ldr r3, =(0x803FBE8 +1)
        bl linker
        add r6, r6, #0x1
        cmp r4, r0
        beq loop

addOn:
        add r4, r4, #0x3 @amount to add per step. Here it's 3
        cmp r4, r0
        ble cont
        mov r4, r0

cont:
        mov r0, r5
        mov r1, #0x39
        ldr r2, =(0x20370D0)
        strh r4, [r2]
        ldr r3, =(0x804037C)
        bl linker
        b loop

next:
        add r6, r6, #0x1
        b loop

end:
        pop {r0-r7}
        lsl r0, r0, #0x18
        lsr r0, r0, #0x18
        cmp r0, #0x1
        beq brancher
        mov r0, r5
        ldr r1, =(0x806D600 +1)
        bx r1

brancher:
        ldr r0, =(0x806D650 +1)
        bx r0

linker:
        bx r3

.align 2




Now in a hex editor navigate to 0x6D5F6. There you will need to insert the following byte changes:
Code:

01 4A 10 47 00 00 XX XX XX 08


Where XX XX XX is the pointer to where you inserted the above routine +1.

Usage:

There isn't any usage. It's automatically done. You can change the amount generated by reading the line in the code which I've commented.

For Emerald (Changes in Red):
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r7}
        ldr r0, =(0x20244EC) @Party Pokémon
        mov r6, #0x0
        ldr r7, =(0x20244E9) @Party Quantity
        ldrb r7, [r7]

loop:
        cmp r6, r7
        beq end
        mov r1, #0x64
        mul r1, r1, r6
        add r0, r0, r1
        mov r5, r0
        mov r1, #0x39
        ldr r3, =(0x806A518 +1) @Pokemon Get Attribute
        bl linker
        mov r4, r0
        cmp r4, #0x0
        beq next
        mov r0, r5
        mov r1, #0x3A
        ldr r3, =(0x806A518 +1) @Pokemon Get Attribute
        bl linker
        add r6, r6, #0x1
        cmp r4, r0
        beq loop

addOn:
        add r4, r4, #0x3 @amount to add per step. Here it's 3
        cmp r4, r0
        ble cont
        mov r4, r0

cont:
        mov r0, r5
        mov r1, #0x39
        ldr r2, =(0x20375F0) @Var 0x800D (Lastresult)
        strh r4, [r2]
        ldr r3, =(0x806ACAC) @Pokemon Set Attribute
        bl linker
        b loop

next:
        add r6, r6, #0x1
        b loop

end:
        pop {r0-r7}
        lsl r0, r0, #0x18
        lsr r0, r0, #0x18
        cmp r0, #0x1
        beq brancher
        mov r0, r5
        ldr r1, =(0x809C8F4 +1)
        bx r1

brancher:
        ldr r0, =(0x809C92E +1) @This may actually fail the routine, needs testing
        bx r0

linker:
        bx r3

.align 2



Insert at 0x9C8EA.

Blah August 7th, 2015 7:45 PM

Battle Frontier routines (Generate a random trainer sprite)



Something to compliment my opponent party generation routine, it generates a random trainer sprite for the opponent from a table of possible sprite entries. Incase you haven't noticed, tables are awesome and tables make things customizable! Lets cut to the chase.

An important note about multi-use

You may or may not be familiar with the Rival and Champion trainer class functions so I will briefly explain that to explain this multi-use. In short, if you assign a trainer the trainer class "Rival" or "Champion" they will automatically be assigned the name of your Rival (the one you name in the Oak intro).

Some people have hacks in which there are more than 2 Rivals, and it may be important to you to have this said rival's sprite appear when battling them. I've removed the class dependency, and added that capability to the sprite generator.

How to insert:

Before compiling the routine in the spoiler below, there's a few things which you may want to customize.
1) The routine is flag toggled. By default I made this flag 0x205. See spoiler below about code to modify this
Spoiler:

Code:

@change these lines
        mov r0, #0xFF
        lsl r0, r0, #0x1
        add r0, r0, #0x7




2) This routine reads from a table of byte long entries, each of the entries correspond to a specific sprite. See spoiler for info
Spoiler:

Code:

@change 0x8750000 to where your table of sprite IDs are
@change 0x32 to the amount of sprite entries in your table
@Please note that each entry in the table of sprite IDs takes 1 byte

Table:
        .word 0x8750000

Tsize:
        .word 0x32




3) This routine has an optional section described in the previous section.

To remove this section please see the spoiler below.
Spoiler:

To remove, delete:
Code:

optional:
        ldr r4, =(0x20370B8)
        ldrh r4, [r4]
        cmp r4, #0xFF
        bne randSprite
        ldr r0, location
        b end


Also delete:
Code:

Location:
        .word 0x8




To learn how to customize the optional section see the spoiler below.
Spoiler:

The optional code is run when variable 0x8000 = 0xFF. If this is the case, and the flag 0x205 is set, then the sprite ID at the label location is used. Change this sprite ID here:

Code:

@Change 0x8 to your sprite's ID!
Location:
        .word 0x8




The routine:
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

@Hook via r4 @08037D30

main:
        @flag check 0x205
        push {r0-r3}
        mov r0, #0xFF
        lsl r0, r0, #0x1
        add r0, r0, #0x7
        ldr r4, =(0x806E6D0 +1)
        bl linker
        cmp r0, #0x0
        beq norm
        pop {r0-r3}

optional:
        ldr r4, =(0x20370B8)
        ldrh r4, [r4]
        cmp r4, #0xFF
        bne randSprite
        ldr r0, location
        b end

randSprite:
        ldr r4, =(0x8044EC8 +1)@gen random number
        bl linker
        lsl r0, r0, #0x10
        lsr r0, r0, #0x10
        ldr r1, Tsize
        ldr r4, =(0x81E4684 +1)
        bl linker
        ldr r1, Table
        add r0, r0, r1
        ldrb r0, [r0]
        ldr r4, =(0x20370BA)
        strb r0, [r4]
        b end

norm:
        pop {r0-r3}
        lsl r0, r1, #0x2
        add r0, r0, r1
        lsl r0, r0, #0x3
        add r0, r0, r2
        ldrb r0, [r0, #0x3]

end:
        ldr r4, =(0x8037D3A +1)

linker:
        bx r4

.align 2

Table:
        .word 0x8750000

Tsize:
        .word 0x32

Location:
        .word 0x8




Once the changes have been made, compile and insert into free space. Then navigate to 0x37D30 and make the following byte changes:
Code:

00 4C 20 47 XX XX XX 08


Where XX XX XX is where you inserted the routine +1. Note the trailing 08 may change depending on where you've inserted the routine.


Usage:

Just set flag 0x205 and let the magic happen. Set variable 0x8000 to 0xFF for the optional part mentioned throughout the post.


Important:
Please direct questions in the ASM help thread and not to my poor PM box :(

Blah August 7th, 2015 8:06 PM

Battle Frontier routines (Generate a random trainer name)



So I've done generating the sprite, generating the team, now it's time to give our random trainer their name. Naming is a little trickier because we can't assign a male name to a female sprite and vise versa. I decided to make a simple system to avoid that which I will now explain here. Skip to the next section if you're uninterested and want to risk making your female sprite be named Arnold.

Basically, without mentioning, in my previous post's routine I secretly stored the sprite's ID in variable 0x8001. This routine uses that information to generate a name which fits the sprite. Obviously, the only way to do that is to make a table whose entries are directly linked to the sprite table. How it works is, every sprite ID has a set amount of names which can be assigned to it, when a sprite is chosen at random, a name from the table which corresponds to the sprite is chosen at random.

Here is how the table is formatted"
Code:

[13 bytes (Possible name ID 1)] [13 bytes (Possible name ID 1)] [13 bytes (Possible name ID 1)] ....[13 bytes (Possible name ID 2)] ...


Names are 0xFF terminated of course.

An important note about multi-use

You may or may not be familiar with the Rival and Champion trainer class functions so I will briefly explain that to explain this multi-use. In short, if you assign a trainer the trainer class "Rival" or "Champion" they will automatically be assigned the name of your Rival (the one you name in the Oak intro).

Some people have hacks in which there are more than 2 Rivals, and if you use some of my naming routines, the player has the ability to name the second rival. This implies that the 2nd rival or important character's name will not be written into the ROM, but rather stored somewhere in the RAM. Which means you cannot just create a custom trainer and have it have the second Rival or important character's name (because like the rival's name, you don't know it to hard code it!). I've taken this into consideration and added some optional code to support this. I've removed the class dependency as well. Now you just need to set variable 0x8000 to 0xFF

How to insert:

Before compiling the routine in the spoiler below, there's a few things which you may want to customize.
1) The routine is flag toggled. By default I made this flag 0x205. See spoiler below about code to modify this
Spoiler:

Code:

@change these lines
        mov r0, #0xFF
        lsl r0, r0, #0x1
        add r0, r0, #0x7




2) This routine reads from a table of 13 byte long entries, each of the entries correspond to a specific name for a sprite. See spoiler for info.
Spoiler:

Code:

@change 0x8750000 to where your table of names are
@change 0x32 to the amount of names there are per sprite
@Please note that each entry in the table of sprite IDs takes 13 bytes and is 0xff terminated

Table:
        .word 0x8750000

Tsize:
        .word 0x32




3) This routine has an optional section described in the previous section.

To remove this section please see the spoiler below.
Spoiler:

To remove, delete:
Code:

optionalSecondRival:
        ldr r4, =(0x20370B8)
        ldrh r4, [r4]
        cmp r4, #0xFF
        bne randName
        ldr r4, Location
        b end


Also delete:
Code:

Location:
        .word 0x8




To learn how to customize the optional section see the spoiler below.
Spoiler:

The optional code is run when variable 0x8001 = 0xFF. If this is the case, and the flag 0x205 is set, then the 0xFF terminated string at the label location is used. Change this name's location here (note the location can be in RAM or in the ROM):

Code:

@Change 0x8 to your sprite's ID!
Location:
        .word 0x8




The routine:
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

@Hook via r2 080D8134

main:
        @flag check 0x205
        push {r0-r3}
        mov r0, #0xFF
        lsl r0, r0, #0x1
        add r0, r0, #0x7
        ldr r4, =(0x806E6D0 +1)
        bl linker
        cmp r0, #0x0
        beq norm
        pop {r0-r3}

optionalSecondRival:
        ldr r4, =(0x20370B8)
        ldrh r4, [r4]
        cmp r4, #0xFF
        bne randName
        ldr r4, Location
        b end

randName:
        ldr r4, =(0x8044EC8 +1)@gen random number
        bl linker
        lsl r0, r0, #0x10
        lsr r0, r0, #0x10
        ldr r1, Tsize
        ldr r4, =(0x81E4684 +1)
        bl linker
        @Get a name from the table of names
        ldr r4, =(0x20370BA)
        ldrh r4, [r4]
        add r4, r4, r0
        mov r1, #0xD
        mul r1, r1, r4
        ldr r4, Table
        add r4, r4, r1
        b end

norm:
        pop {r0-r3}
        ldr r2, =(0x823EAC8)
        ldrh r0, [r5]
        lsl r1, r0, #0x2
        add r1, r1, r0
        lsl r1, r1, #0x3
        ldr r0, =(0x80D813E +1)
        bx r0

end:
        ldr r4, =(0x80D8382 +1)

linker:
        bx r4

.align 2

Table:
        .word 0x8750000

Tsize:
        .word 0x32

Location:
        .word 0x8740000




Once the changes have been made, compile and insert into free space. Then navigate to 0xD8134 and make the following byte changes:
Code:

00 4C 20 47 XX XX XX 08


Where XX XX XX is where you inserted the routine +1. Note the trailing 08 may change depending on where you've inserted the routine.


Usage:

Just set flag 0x205 and let the magic happen. Set variable 0x8000 to 0xFF for the optional part mentioned throughout the post.


Important:
Please direct questions in the ASM help thread and not to my poor PM box :(

Blah August 7th, 2015 8:30 PM

Excuse my triple post, but I have an update about the third routine which deals with actually making the trainer temporary. The whole idea of generating a randomized trainer using ASM routines, rather than using a script to pick a random battle from 50 or so, efficiency and time saving aside, is to save the Hacker 50 or so trainer slots which they would have used to make the trainers.

However, it became apparent to me while working on this that there was no need to make a custom trainerID or temporary trainer ID. In any frontier routine, the battle style would be
Code:

trainerbattle 0x1 0xID 0x0 @stuff @stuff


so the hacker can just clear the trainerflag after the battle, and use one trainer flag for a large selection of custom trainers. As such, I will not be making a routine for this.

I think this concludes the biggest problem about implementing a battle frontier in Fire Red. Some of the competitions, atleast the interesting ones, can be done with smart usage of the Pokemon storage system routines, and small edits of game code. I encourage people to post their solutions to said problems.

I'm currently working on making minigames in FR. Let me know some of your ideas :)

chrunch August 7th, 2015 8:51 PM

Quote:

Originally Posted by chrunch (Post 8701085)
Not sure if you're still taking these, but I have a small request: a way to force set mode that can be toggled on/off. Would be very useful for battle frontier type places.

Just going to repost this because I believe it's relevant to the other battle frontier routines, for people that don't want to permanently enable set mode.

Danny0317 August 7th, 2015 10:18 PM

Before I post this, I want to say thank you to everyone here for contributing to this thread, I'd do something if I wasn't so noob at ASM XD..

Anyways, is there a way to lose HP every step instead of regenerate?

Spherical Ice August 8th, 2015 4:51 AM

Quote:

Originally Posted by FBI agent (Post 8676227)

My condition for using this hack


Unlike most hacks, this is a little different. It's open source, and you're free to use it. However, I require you post the script you use for any of your moves. This is because I want people to keep anything regarding this hack public.
Just post the script you use in your own thread, and that'll be it (like the Sunny Day script I used).

Here's my Rock Climb script, just posting here for convenience. It's worth noting this script was made for FireRed, and uses JPAN's special 0x7F; of course, you can just compile the routine and replace special 0x7F with callasm instead.

For Emerald, I believe you need to change the pointer to evaluator to be 0x081A8D95, as well as changing the movement bytes and the animation (?). Special 0x8F isn't in Emerald afaik, so just replace instances of it with getplayerpos 0x8004 0x8005 (EDIT: it seems to not work if it isnt a special, so it's still easiest to replace one of the specials which point to a nop to point to the routine instead).

All instances of 0xA5 should be replaced with the Rock Climb behaviour byte, and all instances of 0x1AF with your attack ID for Rock Climb.

This works for any height of Rock Climb wall, provided each Rock Climb wall tile has the behaviour byte specified in this script. You should also assign this script to the behaviour byte, as well as for the field move, so it's multipurpose in that sense. The script could probably be far more efficient, the movement isn't ideal, the "Rock Climb can't be used here" isn't consistent with how trying to Surf where you cannot works, and (due to horizontal Rock Climbing being impossible / ugly with the Gen 3's 2D engine) horizontal movement doesn't work, but for all intents and purposes it's functional.

Code:

#dynamic 0x800000

'---------------
#org @start
lock
special 0x8F
comparefarbytetobyte 0x2036E50 0x11
if 0x1 call @snippet1
comparefarbytetobyte 0x2036E50 0x22
if 0x1 call @snippet2
special 0x7F
compare 0x8005 0xA5
if 0x1 goto @snippet3
goto @snippet4

'---------------
#org @snippet1
addvar 0x8005 0x1
return

'---------------
#org @snippet2
subvar 0x8005 0x1
return

'---------------
#org @snippet3
lock
special 0x8F
comparefarbytetobyte 0x2036E50 0x33
if 0x1 goto @snippet5
comparefarbytetobyte 0x2036E50 0x44
if 0x1 goto @snippet5
checkattack 0x1AF
compare LASTRESULT 0x6
if 0x1 goto @snippet5
setanimation 0x0 LASTRESULT
bufferpartypokemon 0x0 LASTRESULT
bufferattack 0x1 0x1AF
msgbox @string1 MSG_YESNO '"The wall is very rocky[.]\nWould y..."
compare LASTRESULT 0x0
if 0x1 goto @snippet6
msgbox @string2 MSG_KEEPOPEN '"[buffer1] used [buffer2]!"
closeonkeypress
doanimation 0x2
waitstate
special 0x8F
setvar 0x8006 0x0
copyvar 0x4001 0x8004
copyvar 0x4002 0x8005
comparefarbytetobyte 0x2036E50 0x11
if 0x1 goto @snippet7
comparefarbytetobyte 0x2036E50 0x22
if 0x1 goto @snippet8
goto @snippet4

'---------------
#org @snippet4
msgbox @string3 MSG_NORMAL '"Rock Climb can't be used here!"
release
end

'---------------
#org @snippet5
msgbox @string4 MSG_SIGN '"The wall is very rocky[.]\nWill a ..."
release
end

'---------------
#org @snippet6
closeonkeypress
release
end

'---------------
#org @snippet7
copyvar 0x8004 0x4001
addvar 0x4002 0x1
copyvar 0x8005 0x4002
addvar 0x8006 0x1
special 0x7F
compare 0x8005 0xA5
if 0x1 goto @snippet7
goto @snippet9

'---------------
#org @snippet8
copyvar 0x8004 0x4001
subvar 0x4002 0x1
copyvar 0x8005 0x4002
addvar 0x8006 0x1
special 0x7F
compare 0x8005 0xA5
if 0x1 goto @snippet8
goto @snippet9

'---------------
#org @snippet9
compare 0x8006 0x0
if 0x1 goto @snippet10
comparefarbytetobyte 0x2036E50 0x11
if 0x1 call @snippet11
comparefarbytetobyte 0x2036E50 0x22
if 0x1 call @snippet12
subvar 0x8006 0x1
goto @snippet9

'---------------
#org @snippet10
release
end

'---------------
#org @snippet11
applymovement MOVE_PLAYER @move1
waitmovement 0x0
return

'---------------
#org @snippet12
applymovement MOVE_PLAYER @move2
waitmovement 0x0
return

'---------
' Strings
'---------
#org @string1
= The wall is very rocky[.]\nWould you like to use [buffer2]?

#org @string2
= [buffer1] used [buffer2]!

#org @string3
= Rock Climb can't be used here!

#org @string4
= The wall is very rocky[.]\nWill a Pokémon's move scale it?

'-----------
' Movements
'-----------
#org @move1
#raw 0x35 'Slide Down (Normal)
#raw 0xFE 'End of Movements

#org @move2
#raw 0x36 'Slide Up (Normal)
#raw 0xFE 'End of Movements


Give credit, of course, to JPAN and FBI agent.

Joexv August 8th, 2015 7:05 AM

Here are some of Jpans routines ported to Emerald.
All of which will be included in DSLN.

Check D-Pad
Spoiler:
Code:

.align 2
.thumb

/*Special 0x2c checks for the D-pad. Returns
0x0 if no direction is pressed
0x1 if up is pressed
0x2 if left is pressed
0x3 if down is pressed
0x4 if right is pressed

special_2c:        ldr r0, key_reg1
                ldrh r0, [r0]
                mvn r0, r0
                lsl r0, r0, #0x18
                lsr r0, r0, #0x1c
                cmp r0, #0xE
                beq right
                cmp r0, #0xD
                beq left
                cmp r0, #0xB
                beq up
                cmp r0, #0x7
                beq down
                cmp r0, #0xFF
                beq None

                bx lr
up:                mov r0, #0x1
                bx lr
left:                mov r0, #0x2
                bx lr
down:                mov r0, #0x3
                bx lr
right:                mov r0, #0x4
                bx lr
None:          mov r0, #0x0
                bx lr

.hword .0x0000
key_reg1: .word 0x04000130




Delete Pokemon From party(special 62)
Spoiler:
Code:

.thumb
.align 2

/*Special 0x62 destroys a pokemon in your party
what it does is move all other pokemon from your party up one level until it
gets to the last, that is replaced by 0's
0x8004 is the pokemon slot to delete, f erases entire party.
returns 0 if no pokemon was left, the number of pokemon if any remained.
It will delete any pokemon, even if your last*/

special_62:        push {r1-r7, lr}
                mov r0, #0x0
                ldr r7, var_8004
                ldr r6, party_addr
                ldr r5, poke_quantity
                ldrh r7, [r7]
                cmp r7, #0xf
                beq delete_all

                cmp r7, #0x5
                bgt end_62

                cmp r7, #0x0
                blt end_62

                ldrb r4, [r5]
                cmp r7, r4
                bge end_62

                mov r4, #0x5
                sub r4, r4, r7

make_address:        cmp r7, #0x0
                beq made_address
                add r6, #0x64
                sub r7, #0x1
                b make_address

made_address:        add r7, r4, #0x0
                add r4, r6, #0x0
                add r4, #0x64

copy_loop:        cmp r7, #0x0
                beq erase_loop
                add r0, r4, #0x0
                add r1, r6, #0x0
                mov r2, #0x64
                swi #0xb
                sub r7, #0x1
                add r6, #0x64
                add r4, #0x64
                b copy_loop
erase_loop:        mov r0, #0x6
                mov r1, #0x0
                mov r2, #0x0
                mov r3, #0x0
                mov r4, #0x0
erase_last:        stmia r6!, {r1-r4}
                sub r0, #0x1
                cmp r0, #0x0
                bne erase_last
                str r6, [r1]
                ldrb r0, [r5]
                sub r0, #0x1
                strb r0, [r5]
end_62:                pop {r1-r7, pc}

delete_all:        mov r0, #0x4b
                mov r1, #0x0
                mov r2, #0x0
                mov r3, #0x0
                mov r4, #0x0
continue:        stmia r6!, {r1-r4}
                sub r0, #0x2
                cmp r0, #0x1
                bne continue
                stmia r6!, {r1,r2}
                mov r0, #0x0
                strb r0, [r5]
                pop {r1-r7, pc}

var_8004: .word 0x020375e0
poke_quantity: .word 0x020244E9
party_addr: .word 0x020244EC




Check pokemon Status (Special 63)
Spoiler:
Code:

.thumb
.align 2

/*Special 0x63 is a status checker. It allows you to check your party pokemon
status. Receives 0x8004 as the slot and returns the pokemon's status byte*/

Special_63:        push {r1, lr}
                ldr r0, var_8004
                mov r1, #0x64
                ldrb r0, [r0]
                cmp r0, #0x5
                bgt end_63
                mul r0, r1
                ldr r1, party_status_address
                add r0, r0, r1
                ldrb r0, [r0]
end_63:                pop {r1, pc}
.hword 0x0000
var_8004: .word 0x020375e0
party_status_address: .word 0x020244EC + 0x50


Inflict Status Effect(Special 64)
Spoiler:
Code:

.thumb
.align 2

/*Special 0x64 is the inflict status to pokemon special. Simply use the status
key at 0x8005 to inflict it to the pokemon in slot 0x8004, or to all if 0x8004
is 0xf*/

Special_64:        push {r1-r4, lr}
                ldr r1, var_8004
                ldrh r0, [r1,#0x2]
                ldrh r1, [r1]
                cmp r1, #0xf
                beq apply_all

                cmp r1, #0x5
                bgt end_64

                mov r2, #0x64
                mul r2, r1
                ldr r1, party_status_address
                add r1, r2, r1
                strb r0, [r1, #0x0]
end_64:                pop {r1-r4, pc}

apply_all:        mov r2, #0x6
                ldr r1, party_status_address
loop:                strb r0, [r1, #0x0]
                sub r2, #0x1
                add r1, #0x64
                cmp r2, #0x0
                bne loop
                pop {r1-r4, pc}
var_8004: .word 0x020375e0
party_status_address: .word 0x020244EC + 0x50


Hp Checker (Special 65)
Spoiler:
Code:

.thumb
.align 2

/*Special 0x65 is a HP checker. It allows you to check your party pokemon
current HP. Receives 0x8004 as the slot and returns the pokemon's current HP*/

Special_65:        push {r1, lr}
                ldr r0, var_8004
                mov r1, #0x64
                ldrb r0, [r0]
                cmp r0, #0x5
                bgt end_65
                mul r0, r1
                ldr r1, party_HP_address
                add r0, r0, r1
                ldrh r0, [r0]
end_65:                pop {r1, pc}
.hword 0x0000
var_8004: .word 0x020375e0
party_HP_address: .word 0x020244EC + 0x56



Change HP (Special 66)
Spoiler:
Code:

.thumb
.align 2

/*Special 0x66 is the Change HP pokemon special. Slot 0x8004 is the pokemon slot,
0x8005 is the HP quantity and var 0x8006 must be 1 to add, anything else to
subtract.*/

Special_66:        push {r1-r4, lr}
                ldr r1, var_8004
                ldrh r0, [r1,#0x2]
                ldrh r3, [r1, #0x4]
                ldrh r1, [r1]
                cmp r1, #0xf
                beq apply_all

                cmp r1, #0x5
                bgt end_64

                mov r2, #0x64
                mul r2, r1
                ldr r1, party_HP_address
                add r1, r2, r1
                ldrh r4, [r1]
                cmp r3, #0x1
                beq recover_one

                sub r0, r4, r0
                cmp r0, #0x0
                bge store_one
                mov r0, #0x0
                b store_one

recover_one:        add r0, r0, r4
                ldrh r4, [r1, #0x2]
                cmp r0, r4
                ble store_one
                add r0, r4, #0x0
store_one:        strh r0, [r1, #0x0]
end_66:                pop {r1-r4, pc}

apply_all:        mov r2, #0x6
                ldr r1, party_HP_address
                cmp r3, #0x1
                beq add_loop
loop:                ldrh r4, [r1, #0x0]
                sub r3, r4, r0
                cmp r3, #0x0
                bge sub_fin
                mov r3, #0x0
sub_fin:        strh r3, [r1, #0x0]
                sub r2, #0x1
                add r1, #0x64
                cmp r2, #0x0
                bne loop
                pop {r1-r4, pc}

add_loop:        ldrh r4, [r1, #0x0]
                add r3, r4, r0
                ldrh r4, [r1, #0x2]
                cmp r3, r4
                ble add_fin
                add r3, r4, #0x0
add_fin:        strh r3, [r1, #0x0]
                sub r2, #0x1
                add r1, #0x64
                cmp r2, #0x0
                bne add_loop
                pop {r1-r4, pc}
.hword 0x0000
var_8004: .word 0x020270c0
party_HP_address: .word 0x02024562




More to come when I feel like it.

daniilS August 8th, 2015 8:24 AM

If anybody ever wants the Wally thingy to use your rival's backsprite in Emerald for whatever reason, here's a routine that does just that:
Code:

.thumb

reloadpal:
        and r0, r1
        beq abort
        cmp r4, #0
        beq genderbend
abort:
        ldr r3, =0x080A96B2
        mov pc, r3

reloadsprite:
        mov r1, r0
        add r3, #1
        mov lr, r3
        ldr r3, =0x0806A12C
        b genderbend

enterfield:
        ldr r4, =0x02024064
        ldrb r1, [r4]
genderbend:
        ldr r0, =0x03005D90
        ldr r0, [r0]
        ldrb r5, [r0, #8]
        mov r0, #1
        eor r0, r5
        mov r5, r0
        mov pc, r3

loadpal:
        ldr r0, =0x03005D90
        ldr r0, [r0]
        ldrb r0, [r0, #8]
        ldr r1, =0x08305D8C
        cmp r0, #0
        bne next
        add r1, #8
next:
        ldr r0, [r1]
        ldr r3, =0x0816A9B8
        mov pc, r3

/*01 4A 01 A3 97 46 XX XX XX XX C0 46 at 0x0A969E and 0x0A98E6(+C), 00 A3 A7 46 at 0x169ECC and 0x169F98, XX XX XX XX(+16) at 0x169F70 and 0x16A03C, 28 1C at 0x169EE0 and 0x169FAC, 87 46 at 0x16A9B6, and XX XX XX XX(+28) at 0x16AA60*/


Insertion instructions are found at the bottom. (+number) means you'll need to add that number to the XX XX XX XX (pointer to the routine) when you make the byte changes at that address (so if I inserted it at 0x08123456, I'd put 01 4A 01 A3 97 46 62 34 12 08 C0 46 at 0x0A98E6).

GoGoJJTech August 8th, 2015 8:29 AM

Quote:

Originally Posted by Spherical Ice (Post 8881731)
For Emerald, I believe you need to change the pointer to evaluator to be 0x081A8D95, as well as changing the movement bytes and the animation (?). Special 0x8F isn't in Emerald afaik, so just replace instances of it with getplayerpos 0x8004 0x8005.

That special is 0x92 in Emerald. List here will be updated in the future: http://www.pokecommunity.com/showthread.php?p=8881985#post8881985

Blah August 8th, 2015 9:15 AM

Warp redirection



This is something similar to FR's elevator scripts in Celadon dept store. What it does is it redirects all warps to a specific one assigned by two variables (one for map bank and second for map number, I know you can make one variable to hold both of these, but I think the reverse hexing and math calculations might confuse people so 2 variables).

I think this will be useful for a single warp or multiple warps which warps you to a different map depending on what's happening. It's better than FR's elevator script because you can have a default warp position, and the redirection only takes 2 setvar instructions (could've been one, but you know) :D

How to insert:

Code:

MBank:
        .word 0x4012

MNumb:
        .word 0x4013


Change these two to the variables you want to use for map bank and map number (should be two non-temp vars). Then compile and insert the following routine into free space:

Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        mov r0, #0x7
        ldrsb r0, [r4, r0]
        mov r1, #0x6
        ldrsb r1, [r4, r1]
        mov r2, #0x5
        ldrsb r2, [r4, r2]

checkAltMap:
        push {r0-r2}
        ldr r0, MBank
        ldr r1, =(0x806E568 +1)
        bl linker
        cmp r0, #0x0
        bne setWarp
        pop {r0-r2}
        b noCrash

setWarp:
        ldr r0, MNumb
        ldr r1, =(0x806E568 +1)
        bl linker
        mov r1, r0
        ldr r0, =(0x20370B8)
        ldrb r0, [r0]

noCrash:
        ldr r3, =(0x806DC84 +1)
        bx r3

linker:
        bx r1

.align 2

MBank:
        .word 0x4012

MNumb:
        .word 0x4013




Insert the following byte changes at 0x6DC78:
Code:

00 48 00 47 XX XX XX 08


Where XX XX XX is where you inserted this routine +1. Note that 08 may change depending on where you insert it.

Usage

Unlike other similar routines I made, this one reads the variables to determine if it should execute. Have the Mbank var not equal to 0 to toggle execution. Of course, Mbank = map bank var and Mnumb = Map number var.

GoGoJJTech August 8th, 2015 7:48 PM

HP Removal per step



Intro:
Basically a routine to remove a Pokemon's HP every step. In this routine it's set to 3 per step. You may want to modify the exact amount to a percentage or something (see the commented lines).

How to insert:

First compile and insert the following routine into free space.

Fire Red:
Spoiler:
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r7}
        mov r0, #0x9C @0x9C * 4 (which is what the next line does) = 0x270. Change this for the flag
        lsl r0, #0x2
        ldr r3, =(0x806E6D0 +1) @Flag Check
        bl linker
        cmp r0, #0x0
        beq end
        ldr r0, =(0x2024284)
        mov r6, #0x0
        ldr r7, =(0x2024029)
        ldrb r7, [r7]

loop:
        cmp r6, r7
        beq end
        mov r1, #0x64
        mul r1, r1, r6
        add r0, r0, r1
        mov r5, r0
        mov r1, #0x39
        ldr r3, =(0x803FBE8 +1)
        bl linker
        mov r4, r0
        cmp r4, #0x0
        beq next
        mov r0, r5
        add r6, r6, #0x1

removeHP:
        cmp r4, #0x3 @assuming you're taking away 3 HP
        bge cont
        mov r4, #0x0

cont:
        mov r0, r5
        mov r1, #0x39
        ldr r2, =(0x20370D0)
        strh r4, [r2]
        ldr r3, =(0x804037C)
        bl linker
        b loop

next:
        add r6, r6, #0x1
        b loop

end:
        pop {r0-r7}
        lsl r0, r0, #0x18
        lsr r0, r0, #0x18
        cmp r0, #0x1
        beq brancher
        mov r0, r5
        ldr r1, =(0x806D600 +1)
        bx r1

brancher:
        ldr r0, =(0x806D650 +1)
        bx r0

linker:
        bx r3

.align 2




Now in a hex editor navigate to 0x6D5F6. There you will need to insert the following byte changes:
Code:

01 4A 10 47 00 00 XX XX XX XX


Where XX XX XX is the pointer to where you inserted the above routine +1.


Emerald:
Spoiler:
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r7}
        mov r0, #0x9C @0x9C * 4 (which is what the next line does) = 0x270. Change this for the flag since it's most likely not free in Emerald
        lsl r0, #0x2
        ldr r3, =(0x809D790 +1) @Flag Check
        bl linker
        cmp r0, #0x0
        beq end
        ldr r0, =(0x20244EC)
        mov r6, #0x0
        ldr r7, =(0x20244E9)
        ldrb r7, [r7]

loop:
        cmp r6, r7
        beq end
        mov r1, #0x64
        mul r1, r1, r6
        add r0, r0, r1
        mov r5, r0
        mov r1, #0x39
        ldr r3, =(0x806A518 +1)
        bl linker
        mov r4, r0
        cmp r4, #0x0
        beq next
        mov r0, r5
        add r6, r6, #0x1

removeHP:
        cmp r4, #0x3 @assuming you're taking away 3 HP
        bge cont
        mov r4, #0x0

cont:
        mov r0, r5
        mov r1, #0x39
        ldr r2, =(0x20375F0)
        strh r4, [r2]
        ldr r3, =(0x806ACAC)
        bl linker
        b loop

next:
        add r6, r6, #0x1
        b loop

end:
        pop {r0-r7}
        lsl r0, r0, #0x18
        lsr r0, r0, #0x18
        cmp r0, #0x1
        beq brancher
        mov r0, r5
        ldr r1, =(0x809C8F4 +1)
        bx r1

brancher:
        ldr r0, =(0x809C92E +1) @This may actually fail the routine, needs testing
        bx r0

linker:
        bx r3

.align 2




Now in a hex editor navigate to 0x9C8EA. There you will need to insert the following byte changes:
Code:

01 4A 10 47 00 00 XX XX XX XX


Where XX XX XX is the pointer to where you inserted the above routine +1.


Usage:

Set flag 0x270 (or the flag you customized in the routine), then the HP automatically decreases based on the amount you set in the routine every step. You can change the amount removed by reading the lines in the code which I've commented.

Note: I did not test any of these; they should work in theory even though I didn't try it personally. This routine is a modification of FBI's, and is requested by Danny. Not sure why you'd want all Pokémon to constantly lose HP per step, so I added a flag check so it's toggle-able. This also doesn't work with the previous regeneration per step routine, if you thought it would for some reason.

Blah August 9th, 2015 7:47 AM

Quote:

Originally Posted by GoGoJJTech (Post 8882719)

HP Removal per step



Intro:
Basically a routine to remove a Pokemon's HP every step. In this routine it's set to 3 per step. You may want to modify the exact amount to a percentage or something (see the commented lines).

How to insert:

First compile and insert the following routine into free space.

Fire Red:
Spoiler:
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r7}
        mov r0, #0x9C @0x9C * 4 (which is what the next line does) = 0x270. Change this for the flag
        lsl r0, #0x2
        ldr r3, =(0x806E6D0 +1) @Flag Check
        bl linker
        cmp r0, #0x0
        beq end
        ldr r0, =(0x2024284)
        mov r6, #0x0
        ldr r7, =(0x2024029)
        ldrb r7, [r7]

loop:
        cmp r6, r7
        beq end
        mov r1, #0x64
        mul r1, r1, r6
        add r0, r0, r1
        mov r5, r0
        mov r1, #0x39
        ldr r3, =(0x803FBE8 +1)
        bl linker
        mov r4, r0
        cmp r4, #0x0
        beq next
        mov r0, r5
        mov r1, #0x3A
        ldr r3, =(0x803FBE8 +1)
        bl linker
        add r6, r6, #0x1
        cmp r4, r0
        beq loop

removeHP:
        sub r1, r4 #0x3 @amount to remove per step. Customize it
        cmp r1, #0x0
        bgt cont
        mov r4, #0x0

cont:
        mov r0, r5
        mov r1, #0x39
        ldr r2, =(0x20370D0)
        strh r4, [r2]
        ldr r3, =(0x804037C)
        bl linker
        b loop

next:
        add r6, r6, #0x1
        b loop

end:
        pop {r0-r7}
        lsl r0, r0, #0x18
        lsr r0, r0, #0x18
        cmp r0, #0x1
        beq brancher
        mov r0, r5
        ldr r1, =(0x806D600 +1)
        bx r1

brancher:
        ldr r0, =(0x806D650 +1)
        bx r0

linker:
        bx r3

.align 2




Now in a hex editor navigate to 0x6D5F6. There you will need to insert the following byte changes:
Code:

01 4A 10 47 00 00 XX XX XX XX


Where XX XX XX is the pointer to where you inserted the above routine +1.


Emerald:
Spoiler:
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r7}
        mov r0, #0x9C @0x9C * 4 (which is what the next line does) = 0x270. Change this for the flag since it's most likely not free in Emerald
        lsl r0, #0x2
        ldr r3, =(0x809D790 +1) @Flag Check
        bl linker
        cmp r0, #0x0
        beq end
        ldr r0, =(0x20244EC)
        mov r6, #0x0
        ldr r7, =(0x20244E9)
        ldrb r7, [r7]

loop:
        cmp r6, r7
        beq end
        mov r1, #0x64
        mul r1, r1, r6
        add r0, r0, r1
        mov r5, r0
        mov r1, #0x39
        ldr r3, =(0x806A518 +1)
        bl linker
        mov r4, r0
        cmp r4, #0x0
        beq next
        mov r0, r5
        mov r1, #0x3A
        ldr r3, =(0x806A518 +1)
        bl linker
        add r6, r6, #0x1
        cmp r4, r0
        beq loop

removeHP:
        sub r1, r4 #0x3 @amount to remove per step. Customize it
        cmp r1, #0x0
        bgt cont
        mov r4, #0x0

cont:
        mov r0, r5
        mov r1, #0x39
        ldr r2, =(0x20375F0)
        strh r4, [r2]
        ldr r3, =(0x806ACAC)
        bl linker
        b loop

next:
        add r6, r6, #0x1
        b loop

end:
        pop {r0-r7}
        lsl r0, r0, #0x18
        lsr r0, r0, #0x18
        cmp r0, #0x1
        beq brancher
        mov r0, r5
        ldr r1, =(0x809C8F4 +1)
        bx r1

brancher:
        ldr r0, =(0x809C92E +1) @This may actually fail the routine, needs testing
        bx r0

linker:
        bx r3

.align 2




Now in a hex editor navigate to 0x9C8EA. There you will need to insert the following byte changes:
Code:

01 4A 10 47 00 00 XX XX XX XX


Where XX XX XX is the pointer to where you inserted the above routine +1.


Usage:

Set flag 0x270 (or the flag you customized in the routine), then the HP automatically decreases based on the amount you set in the routine every step. You can change the amount removed by reading the lines in the code which I've commented.

Note: I did not test any of these; they should work in theory even though I didn't try it personally. This routine is a modification of FBI's, and is requested by Danny. Not sure why you'd want all Pokémon to constantly lose HP per step, so I added a flag check so it's toggle-able. This also doesn't work with the previous regeneration per step routine, if you thought it would for some reason.

Uhh, the FR routine is incorrect, so I guess that means the EM routine is not working either.

To explain the gain routine a little more in detail, lets look at the parts which require changing.

Code:

        mov r1, #0x39
        ldr r3, =(0x803FBE8 +1)
        bl linker
        mov r4, r0
        cmp r4, #0x0
        beq next


OK, here we're checking if current HP of this Pokemon is 0x0. If it is, it's fainted so move on to the next Pokemon. So far, so good. But it's important to note that in r4 right now the Pokemon's current HP is held.


Code:

        mov r0, r5
        mov r1, #0x3A
        ldr r3, =(0x803FBE8 +1)
        bl linker
        add r6, r6, #0x1
        cmp r4, r0
        beq loop


Here we have the total HP the Pokemon has being stored in R0. Note that Total HP is not Current HP. They are very distinct. What's happening here is a check to see if Total HP == Current HP. If it is, we'll move on to the next Pokemon. This is good if the routine was to increment HP, as we can't increment the HP of a full HP Pokemon. But if you're taking away HP, the total HP doesn't matter. Instead you should check that if you take away HP, it's current HP would be negative.

Code:

removeHP:
        sub r1, r4 #0x3 @amount to remove per step. Customize it
        cmp r1, #0x0
        bgt cont
        mov r4, #0x0


Uh, the compare should not be comparing to zero. Try this:

Code:

cmp r4, #0x3 @assuming you're taking away 3 HP
bge cont
mov r4, #0x0



I thought I'd just help you out by pointing out some of the inconsistencies and the changes you'd need to make to make this work. I know you're just editing my gain HP routine, and trying to help. Good luck GoGo. :)

GoGoJJTech August 9th, 2015 7:53 AM

Quote:

Originally Posted by FBI agent (Post 8883337)
Uhh, the FR routine is incorrect, so I guess that means the EM routine is not working either.

To explain the gain routine a little more in detail, lets look at the parts which require changing.

Code:

        mov r1, #0x39
        ldr r3, =(0x803FBE8 +1)
        bl linker
        mov r4, r0
        cmp r4, #0x0
        beq next


OK, here we're checking if current HP of this Pokemon is 0x0. If it is, it's fainted so move on to the next Pokemon. So far, so good. But it's important to note that in r4 right now the Pokemon's current HP is held.


Code:

        mov r0, r5
        mov r1, #0x3A
        ldr r3, =(0x803FBE8 +1)
        bl linker
        add r6, r6, #0x1
        cmp r4, r0
        beq loop


Here we have the total HP the Pokemon has being stored in R0. Note that Total HP is not Current HP. They are very distinct. What's happening here is a check to see if Total HP == Current HP. If it is, we'll move on to the next Pokemon. This is good if the routine was to increment HP, as we can't increment the HP of a full HP Pokemon. But if you're taking away HP, the total HP doesn't matter. Instead you should check that if you take away HP, it's current HP would be negative.

Code:

removeHP:
        sub r1, r4 #0x3 @amount to remove per step. Customize it
        cmp r1, #0x0
        bgt cont
        mov r4, #0x0


Uh, the compare should not be comparing to zero. Try this:

Code:

cmp r4, #0x3 @assuming you're taking away 3 HP
bge cont
mov r4, #0x0



I thought I'd just help you out by pointing out some of the inconsistencies and the changes you'd need to make to make this work. I know you're just editing my gain HP routine, and trying to help. Good luck GoGo. :)

This is what I get for not testing :P
Changes added to the post

Blah August 10th, 2015 6:23 AM

Quote:

Originally Posted by pokemontutorialTV (Post 8884475)
It would be great, if i could warp via ASM in a script to a warp of my choice / to a location of my choice. I do not understand really function of this ASM snippet, because you don't say, which warp will be changed.

This particular routine changes every warp to a specific warp given by the variables. For the type of warping you describe, there are script commands which do that.

Joexv August 13th, 2015 8:02 PM

Update to Egg Check routine:
Now uses var 0x8004 for party slot instead of the user manually using the species.
Good idea to use with a special 0x9F(FR)

FR
Spoiler:
Code:

.text
.align 2
.thumb
.thumb_func

main:
push {r0-r5, lr}
ldr r1, =(0x20370C0) @var 0x8004
ldrb r1, [r1]
mov r2, #0x64
mul r1, r1, r2
ldr r0, =(0x2024284)
add r0, r0, r1 @slot
mov r4, r0 @save slot
mov r1, #0xB
bl Dec
ldr r2, =(0x8254784)
mov r3, #0x1c
mul r0, r0, r3
add r2, r0, r2
add r2, r2, #0x14
ldrb r0, [r2]
add r2, r2, #0x1
ldrb r1, [r2]
ldr r2, =(0x20370B8)
ldr r3, =(0x20370BA)
strb r1, [r3]
strb r0, [r2]
pop {r0-r5, pc}
Dec:
ldr r2, =(0x803FBE8 +1)
bx r2

.align 2




EM (untested but idk why it wouldnt work)
Spoiler:
Code:

.text
.align 2
.thumb
.thumb_func

main:
push {r0-r5, lr}
ldr r1, =(0x20270C0)
ldrb r1, [r1]
mov r2, #0x64
mul r1, r1, r2
ldr r0, =(0x20244EC)
add r0, r0, r1
mov r4, r0
mov r1, #0xB
bl Dec
ldr r2, =(0x83203cc)
mov r3, #0x1c
mul r0, r0, r3
add r2, r0, r2
add r2, r2, #0x14
ldrb r0, [r2]
add r2, r2, #0x1
ldrb r1, [r2]
ldr r2, =(0x20270B8)
ldr r3, =(0x20270BA)
strb r1, [r3]
strb r0, [r2]
pop {r0-r5, pc}
Dec:
ldr r2, =(0x806A519 +1)
bx r2

.align 2




I would recommend using this version of the routine over the old one as its more efficient and works better.
Thanks to Touched Senpai for telling me something I shouldve known!, but was too stupid to remember.

Lance32497 August 18th, 2015 6:58 AM

Quote:

Originally Posted by FBI agent (Post 8672577)

HP Regeneration per step



Intro:
Basically a routine to regenerate a Pokemon's HP every step. In this routine it's set to 3 per step. You may want to modify the exact amount to a percentage or something (see the commented line).

How to insert:

First compile and insert the following routine into free space.

Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        push {r0-r7}
        ldr r0, =(0x2024284)
        mov r6, #0x0
        ldr r7, =(0x2024029)
        ldrb r7, [r7]

loop:
        cmp r6, r7
        beq end
        mov r1, #0x64
        mul r1, r1, r6
        add r0, r0, r1
        mov r5, r0
        mov r1, #0x39
        ldr r3, =(0x803FBE8 +1)
        bl linker
        mov r4, r0
        cmp r4, #0x0
        beq next
        mov r0, r5
        mov r1, #0x3A
        ldr r3, =(0x803FBE8 +1)
        bl linker
        add r6, r6, #0x1
        cmp r4, r0
        beq loop

addOn:
        add r4, r4, #0x3 @amount to add per step. Here it's 3
        cmp r4, r0
        ble cont
        mov r4, r0

cont:
        mov r0, r5
        mov r1, #0x39
        ldr r2, =(0x20370D0)
        strh r4, [r2]
        ldr r3, =(0x804037C)
        bl linker
        b loop

next:
        add r6, r6, #0x1
        b loop

end:
        pop {r0-r7}
        lsl r0, r0, #0x18
        lsr r0, r0, #0x18
        cmp r0, #0x1
        beq brancher
        mov r0, r5
        ldr r1, =(0x806D600 +1)
        bx r1

brancher:
        ldr r0, =(0x806D650 +1)
        bx r0

linker:
        bx r3

.align 2




Now in a hex editor navigate to 0x6D5F6. There you will need to insert the following byte changes:
Code:

01 4A 10 47 00 00 XX XX XX 08


Where XX XX XX is the pointer to where you inserted the above routine +1.

Usage:

There isn't any usage. It's automatically done. You can change the amount generated by reading the line in the code which I've commented.

This is nice, but, it will be better if it is toggleable by flag

C me August 21st, 2015 11:18 AM

Does anyone have a routine to open the flightmap in Emerald, I don't think it's a special like the normal map.

Thanks

Exodrake August 22nd, 2015 4:58 PM

While clowning around in my game, I stumbled upon a bug with Protean. The Gale Wings ability (which Otachi has) trips Protean and changes the monster into a Flying type for some weird reason.



Video is silly but it does demonstrate the bug.

Blah August 24th, 2015 12:22 PM

Quote:

Originally Posted by pokemontutorialTV (Post 8884475)
It would be great, if i could warp via ASM in a script to a warp of my choice / to a location of my choice. I do not understand really function of this ASM snippet, because you don't say, which warp will be changed.

I don't understand what you are saying here. The routine currently changes the destination of all warps until untoggled.

Quote:

Originally Posted by Lance32497 (Post 8895166)
This is nice, but, it will be better if it is toggleable by flag

Pretty simple change. I think it's like the second ASM tutorial I made which covers this. The thing with flag toggling is that everyone wants to use a different flag, and some people prefer variables. Better to do it yourself if you want toggling imo.

Blah August 24th, 2015 1:15 PM

Scrolling Multi-choice boxes



Multiple choice boxes have been a really cool, yet in my opinion, a very unmastered feature in ROM hacks. Most people use JPAN's patch to make multichoice boxes, others edit the existing ones in the ROM. However, it seems like there is no solution for when the multiple choice box needs to hold more than just 8 or so options. Most competent hackers seem to have the last option be something which opens another box. It seems clunky and quite troublesome, so I decided to hack it and make it support scrolling and customization :)

Here are some things which are in some popular hacks which use a work around that can be avoided altogether with this hack:
http://i35.photobucket.com/albums/d178/prossy/20.pnghttp://i.imgur.com/7xjCAol.pnghttp://i.imgur.com/CnolW43.png

The hack in action:



How to insert:

Before getting started with the hack there is a little bit of setting up which is required.

You need to set up a table of pointers somewhere in your ROM. This table will be a table of pointers to possible mulitchoice boxes in your ROM. Each pointer in that table will point to a location of another table. The second table will have pointers to 0xFF terminated strings which will appear in your multichoice box. Visually this is what it should look like:
Spoiler:

http://i.imgur.com/oZfTLDB.png
I suggest first setting up atleast the first table before inserting the actual routine itself.


Once you've configured the above tables, take a look at the routine in the spoilers.
Code:

table:
        .word 0x8[Location of your table, do not +1]


Change this line according to wherever you put your first table.

Once that's done compile and insert the routine into free word-aligned space!

Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

@hook via r1

main:
        ldr r4, =(0x20370BA) @var 0x8001
        ldrh r4, [r4]
        mov r1, #0xA
        strh r4, [r5, r1]
        ldrsh r0, [r5, r1]
        lsl r0, r0, #0x3
        ldr r2, malloc
        bl linker
        ldr r4, =(0x2039A14) @RAM to hold pointer to malloc data
        str r0, [r4]
        ldr r2, boxProperties
        bl linker
        mov r6, #0x0
        mov r4, #0x0
        mov r2, #0xA
        ldrsh r0, [r5, r2]
        lsl r3, r7, #0x2
        mov r10, r3
        add r1, SP, #0x18
        mov r9, r1
        cmp r6, r0
        bge loop
        ldr r2, table
        ldr r1, =(0x20370B8) @var 0x8000
        ldrh r1, [r1]
        lsl r1, r1, #0x2
        add r2, r2, r1
        ldr r2, [r2]
        mov r8, r2
        ldr r0, =(0x80CB974 +1)
        bx r0

loop:
        ldr r0, =(0x80CB9AE +1)
        bx r0

linker:
        bx r2

.align 2

table:
        .word 0x8[Location of your table, do not +1]

malloc:
        .word 0x8002BB0 +1

boxProperties:
        .word 0x80CBA7C +1




Now navigate to 080CB94C and insert the following byte changes:
Code:

00 49 08 47 XX XX XX 08


Where XX XX XX is wherever you inserted this routine +1. Note that the trailing 08 may change depending on your ROM situation!


Usage:

So this is a hack of special 0x158. I've essentially fixed the hard coded table read, and removed limitters as well as recoded the size readings to read of a variable instead. So the script usage of this implementation is quite simple, yet there are some complications which arise along the way. I'll talk about those complications later and first describe usage!

Code:

Paramaters:
var 0x8000 = which multichoice box should be shown from the table of multichoice boxes
var 0x8001 = How many options are supposed to be shown
var 0x8004 = leave as 0x0 for expected output. It does more, but don't play with it for now (I'll document it on a later day!).

Return value:
var 0x800D = Which option was selected, where 0x0 is the first option and 0x1 is the second options....ect.


Sample script snipplet.
Code:

#dyn 0x740000
#org @start
lock
faceplayer
msgbox 0x874001B
callstd MSG_NORMAL
setvar 0x8000 0x0 'Use first multichoice box
setvar 0x8001 0x12 ' First box has 18 options
setvar 0x8004 0x0 ' standard
special 0x158
waitspecial
release
end

#org 0x874001B
= Hello here's some tough choices


Note, after the waitspecial command finishes, variable 0x800D will have the selected option's index number inside it. From there you can do your own checks to verify which option the user had selected.

Some usage requirements:

- 0x8004 = 0. Keep it like this for now until I explain it more a later day. You can play with it too if you want, but it will likely cause a game crash.

- The menu does not close unless the "B" button is pressed inplace of an option, OR the last option is selected. FR counters this by having an "EXIT" option as the last option of the multichoice box, and any scripts which use the multichoice box are looped as well. I have a fix for this:
Code:

@ 080CBB84 insert the following byte changes:
@ 00 00 00 00


So use this if you don't want to use the last option EXIT :)

kleenexfeu August 26th, 2015 4:40 AM

Quote:

Originally Posted by Exodrake (Post 8900757)
While clowning around in my game, I stumbled upon a bug with Protean. The Gale Wings ability (which Otachi has) trips Protean and changes the monster into a Flying type for some weird reason.



Video is silly but it does demonstrate the bug.

I think MrDS plans to rewrite the priority system, it should work correctly after he done that

Xencleamas August 26th, 2015 4:47 AM

Quote:

Originally Posted by FBI agent (Post 8903237)

Scrolling Multi-choice boxes



Multiple choice boxes have been a really cool, yet in my opinion, a very unmastered feature in ROM hacks. Most people use JPAN's patch to make multichoice boxes, others edit the existing ones in the ROM. However, it seems like there is no solution for when the multiple choice box needs to hold more than just 8 or so options. Most competent hackers seem to have the last option be something which opens another box. It seems clunky and quite troublesome, so I decided to hack it and make it support scrolling and customization :)

Wow! This is kewl! Gonna test it out.

What about for setting its x and y alignment? For an example, I would like to have the scrolling multichoice box on the center (or right). Just like the nature of multichoice boxes that can be aligned.

BLAx501! August 26th, 2015 8:36 AM

I want to ask for something. Would it be possible to create a routine that doesn't changes the current music when changing maps?

For expample, I start at Pallet Town with its lovely music, I activate that routine and when I move to Route 1 or enter Oak's Research Centre, it keeps playing the music, although there is specific music for each map I've mentioned.

Blah August 26th, 2015 6:40 PM

Quote:

Originally Posted by Sky High (Post 8905035)
Wow! This is kewl! Gonna test it out.

What about for setting its x and y alignment? For an example, I would like to have the scrolling multichoice box on the center (or right). Just like the nature of multichoice boxes that can be aligned.

I don't think there are any multichoice boxes which can be aligned. Anyways, if you want information about the box X-Y please see the parameters passed to the function at
ROM:08003CE4

Blah August 26th, 2015 6:42 PM

Music Overriding upon warp



Quote:

Originally Posted by BLAxTOISE (Post 8905292)
I want to ask for something. Would it be possible to create a routine that doesn't changes the current music when changing maps?

For expample, I start at Pallet Town with its lovely music, I activate that routine and when I move to Route 1 or enter Oak's Research Centre, it keeps playing the music, although there is specific music for each map I've mentioned.

Happy birthday, have an untested routine. If you experience problems, let me know.

How to insert:

Compile the following routine into free space:

Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        mov r0, #0x2
        strb r0, [r2]

flagCheck:
        mov r0, #0xFF
        lsl r0, r0, #0x1
        add r0, r0, #0x8
        ldr r4, =(0x806E6D0 +1) @check flag 0x404
        bl linker
        ldr r1, =(0x3000FC0) @current map music
        cmp r0, #0x0
        beq norm
        ldr r0, =(0x20370B8) @var 0x8000
        ldrh r0, [r0]
        strh r0, [r1]

norm:
        ldrh r0, [r1]
        ldr r1, =(0x8071994 +1) @return
        bx r1

linker:
        bx r4

.align 2




Then insert the following byte changes to 0x807198C:
Code:

00 48 00 47 XX XX XX 08


Note that the trailing 08 may change. XX XX XX is as usual wherever you've inserted the routine +1 in reverse hex.

Usage:
Have flag 0x404 set and variable 0x8000 to be the music ID you'd want to play. Only works upon warp.

kleenexfeu August 27th, 2015 7:40 AM

Better to post it here :

Here is a very simple routine that makes moves having 0 accuracy never miss. I found that more convenient than set the "always hit flag" in the battle scripts. It is for Emerald :

Spoiler:

CheckAccuracy:
add r7, r0, r1
ldrb r3, [r7, #3]
cmp r3, #0
bne Continue
mov r3, #0xFF

Continue:
mov r8, r3
mov r0, #0
ldr r1, Return
bx r1

.align 2
Return: .word 0x080467E0+1

/*00 4B 18 47 xx+1 xx xx 08 at 080467D8*/


Also, I saw few people asking for having new "-ate" abilities, which is understandable, so I post them here too if you want to make your custom ones :
Spoiler:

Emerald :
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func
.global ateabilities

Start:
push {r0-r4}
mov r0, r10
cmp r0, #0        /*Normal type*/
beq AteCheck

PopAndClassic:
pop {r0-r4}

Classic:
ldrh r0, [r6, #0x2E]
cmp r0, #0xAF
bne Back
ldr r1, SomeLoc
ldr r2, Return
mov pc, r2

Back:
ldr r0, Return1
mov pc, r0

AteCheck:
ldr r0, BankUser
ldrb r1, [r0]
ldr r2, BattleData
mov r3, #0x58
mul r1, r3
add r1, r2
add r1, #0x20
ldrb r4, [r1]
cmp r4, #0xB7        /*Index number Pixilate*/
beq Pixi
cmp r4, #0xB9        /*Index number Aerilate*/
beq Aeri
cmp r4, #0xAF        /*Index number Refrigerate*/
beq Refri
b PopAndClassic

Pixi:
mov r0, #0x17        /*Index number of your Fairy type*/
b StoreAndBoost

Aeri:
mov r0, #2        /*Index number of your Flying type*/
b StoreAndBoost

Refri:
mov r0, #0xF        /*Index number of your Ice type*/

StoreAndBoost:
mov r10, r0
Store:
ldr r0, ChangeTypeLoc
ldr r1, [r0]
add r1, #0x13
ldrb r2, [r1]
cmp r2, #0
bne PopAndClassic
mov r2, r10
strb r2, [r1]

Boost:
mov r0, r8
mov r3, #0xA7
mul r0, r3
lsr r0, #7
mov r8, r0
mul r7, r3
lsr r7, #7
b PopAndClassic

.align 2
Return: .word 0x0806961C+1
Return1: .word 0x08069634+1
BankUser: .word 0x0202420B
BattleData: .word 0x02024084
ChangeTypeLoc: .word 0x0202449C
SomeLoc: .word 0x02024404

/*00 48 00 47 xx+1 xx xx 08 at 08069614*/



So here is the official ones, what if I want to create a new one ? It is simple :
Spoiler:

That part check the ability of the user :

cmp r4, #0xB7 /*Index number Pixilate*/
beq Pixi
cmp r4, #0xB9 /*Index number Aerilate*/
beq Aeri
cmp r4, #0xAF /*Index number Refrigerate*/
beq Refri
b PopAndClassic

All we have to do is make one (or several) more check before that.

Exemple, my ability "Firething -ate" is the ability number 193 or 0xC1, all I have to do is :

cmp r4, #0xC1
beq Fire-ate

and create a new section right after the original one, say :

Fire-ate:
mov r0, #0xA /*Here is your fire type*/
b StoreAndBoost

And it is done. Note that we cannot handle Normalize the same way because of the way the engine handle some things. (actually we could but I'd have to find and alter many routines)


BLAx501! August 28th, 2015 4:40 AM

Quote:

Originally Posted by FBI agent (Post 8905965)

Music Overriding upon warp





Happy birthday, have an untested routine. If you experience problems, let me know.

How to insert:

Compile the following routine into free space:

Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        mov r0, #0x2
        strb r0, [r2]

flagCheck:
        mov r0, #0xFF
        lsl r0, r0, #0x1
        add r0, r0, #0x8
        ldr r4, =(0x806E6D0 +1) @check flag 0x404
        bl linker
        ldr r1, =(0x3000FC0) @current map music
        cmp r0, #0x0
        beq norm
        ldr r0, =(0x20370B8) @var 0x8000
        ldrh r0, [r0]
        strh r0, [r1]

norm:
        ldrh r0, [r1]
        ldr r1, =(0x8071994 +1) @return
        bx r1

linker:
        bx r4

.align 2




Then insert the following byte changes to 0x807198C:
Code:

00 48 00 47 XX XX XX 08


Note that the trailing 08 may change. XX XX XX is as usual wherever you've inserted the routine +1 in reverse hex.

Usage:
Have flag 0x404 set and variable 0x8000 to be the music ID you'd want to play. Only works upon warp.

I love you man!! I'm going to try it now to check if it works well and I'll edit this post with the results.

Anyway, thanks a lot for the effort you are putting on this thread ;)

Exodrake August 30th, 2015 5:41 AM

I'm unsure of the correct place to bring this up, but is there anybody researching expanding the move tutor yet (move reminder in later gens)? The problem is, if your Pokemon has a moveset with more than 20 moves, they won't all show up in the move tutor because that list can only show up to 20 moves. And expanded movesets with more than 20 moves are common with hacks that try to mimic later generations.

azurile13 August 30th, 2015 1:39 PM

Quote:

Originally Posted by Exodrake (Post 8910098)
I'm unsure of the correct place to bring this up, but is there anybody researching expanding the move tutor yet (move reminder in later gens)? The problem is, if your Pokemon has a moveset with more than 20 moves, they won't all show up in the move tutor because that list can only show up to 20 moves. And expanded movesets with more than 20 moves are common with hacks that try to mimic later generations.

Had a (quick) look after reading your post. So this is how you can change the limit when the subroutine is reading the learnset entry:

Code:

main: @at 0x08043DA0:
        cmp r5, #0x13 @CHANGE TO NEW LIMIT
        bgt main + 0x14


Actually you might be able to just change the first byte from 0x13 to the limit, but I’m not all that confident with compares and alignment with opcodes so I wrote it out.

Sadly it isn’t this simple. This subroutine (at 0x08043C84) is apparently writing the moves to an address contained at the offset 0x0203AAB4 + 0xE8. If anyone is familiar with with what’s going on there and if there is space to add moves (a halfword at a time) that would be great. If it isn’t possible to add more moves there without corruption, it may be necessary to use malloc and change all references to that address.

As a side note, I had also wanted to rewrite the relearner to reteach egg moves. I didn’t even know there was a limit of twenty until you brought it up.

Edit:

I went a level up, and word 0x0203AAB4 is just a temporary pointer to a malloc of size 0xA6C called at 0x080E47A6. It is necessary to understand each area used in that block, or at the very least how their size and offset relates to the maximum number of moves that can be listed. Following from the malloc call to the bl to 0x080E50CC, here’s what I have so far on the block:

Spoiler:
0x1A: number of moves on relearner list
0x20: pointer to a string later in this block, the name of move #0
0x24: word 0x00000000
0x28: pointer to string of name of move #1
0x24: word 0x00000001
. . . . .
0xB8: pointer to a string of name of move #19
0xBC: word 0x00000013
0xC0: pointer to ascii “CANCEL”
0xC4: word 0x000000FE
*0xC0 and 0xC4 are “pushed” up the list if there are less than 20 moves, right after the last one

0xE8: move #0 index
0xEA: move #1 index
. . . . .
0x10E: move #19 index

0x11A: move name #0 (0xD string)
0x127: move name #1, (0xD string)
. . . . .
0x201: move name, #19
0x20E: CANCEL
*like the pointers, 0x201 and 0x20E are pushed up if there are less than 20 moves

0x260: content var8004
0x261: content var8005
The annoying thing is that the routines use actual numbers for the “bases”, such as 0xE8 being used for move indices and 0x11A in a literal pool being used for names. I attempted changing the routines before all of the graphics comes into play and, as expected, it didn’t work. This will be fun.

JPAN August 30th, 2015 8:32 PM

2 Attachment(s)
I have something for you all. A number input box for Fire Red. Image in spoiler

This box allows the player to insert numbers in a hack, allowing for many new features such as a banking system, password protected doors and the like.
Included in the zip is the compiled code and the source. The source, however must be modified to be compiled in a normal compiler. It's included more as a study material to see how it was implemented.
The "number box.out" file contains the compiled code, ready to use. All you need to do is insert the code at a free location, edit the pointer at code + 0x164 to (pointer to code + 0x0179) and then call it with the callASM command followed by a waitstate. You also need to be in a locked state, so use lockall or lock before callASM, and release/releaseall at the end of the script.
To change the location of where the box is located change X at code+2 and Y at code+4 and to change the width of the box change the byte at code+6.

SBird August 31st, 2015 12:58 AM

Quote:

Originally Posted by JPAN (Post 8910813)
I have something for you all. A number input box for Fire Red. Image in spoiler

This box allows the player to insert numbers in a hack, allowing for many new features such as a banking system, password protected doors and the like.
Included in the zip is the compiled code and the source. The source, however must be modified to be compiled in a normal compiler. It's included more as a study material to see how it was implemented.
The "number box.out" file contains the compiled code, ready to use. All you need to do is insert the code at a free location, edit the pointer at code + 0x164 to (pointer to code + 0x0179) and then call it with the callASM command followed by a waitstate.
To change the location of where the box is located change X at code+2 and Y at code+4 and to change the width of the box change the byte at code+6.

Hey, this is great! Yet I would be glad if you would provide us the actual source code. Somebody might want to edit your code and for my part I would like to add it to my build scripts. (I don't think your code is compiled with -c)

Looking forward to combination lock like riddles :D

~SBird

Edit: Okay screw me, I just found the "number_box.tmb" and did not consider it being a code file... thanks again for the project :)

Pokemon_XY August 31st, 2015 7:10 AM

Quote:

Originally Posted by JPAN (Post 8910813)
I have something for you all. A number input box for Fire Red. Image in spoiler

This box allows the player to insert numbers in a hack, allowing for many new features such as a banking system, password protected doors and the like.
Included in the zip is the compiled code and the source. The source, however must be modified to be compiled in a normal compiler. It's included more as a study material to see how it was implemented.
The "number box.out" file contains the compiled code, ready to use. All you need to do is insert the code at a free location, edit the pointer at code + 0x164 to (pointer to code + 0x0179) and then call it with the callASM command followed by a waitstate.
To change the location of where the box is located change X at code+2 and Y at code+4 and to change the width of the box change the byte at code+6.

Your work amaze me! However I haven't passed the test in script.
1. I changed the pointer you've mentioned.
2. write a script like
Code:

#org @start
setvar 0x8008 0xffff
setvar 0x8009 0x2 //random number in my brain
callasm 0x8[address+1]
waitstate
end


But when I go to talk with the man who has the script, nothing happened.
Please point out my mistake, thanks.

JPAN August 31st, 2015 4:48 PM

Quote:

Originally Posted by Pokemon_XY (Post 8911248)
Your work amaze me! However I haven't passed the test in script.
1. I changed the pointer you've mentioned.
2. write a script like
Code:

#org @start
setvar 0x8008 0xffff
setvar 0x8009 0x2 //random number in my brain
callasm 0x8[address+1]
waitstate
end


But when I go to talk with the man who has the script, nothing happened.
Please point out my mistake, thanks.

I hadn't tested it without a lock/lockall command. Apparently, it is required, as the box does not appear without it. Instructions were edited to cover this fact.

Pokemon_XY August 31st, 2015 8:37 PM

Quote:

Originally Posted by JPAN (Post 8911957)
I hadn't tested it without a lock/lockall command. Apparently, it is required, as the box does not appear without it. Instructions were edited to cover this fact.

Thank you very much! The box worked fine now. I will try to analyze your awesome routine then

SBird September 1st, 2015 4:05 AM

Another request (A real one this time I promise) : It is quite a neusance for (most) cases that you have to switch the number lets say from 0 to 456786 - For combination locks, codes, and generally stuff that requires LARGE numbers it would be way easier if you could edit digit by digit. Probably you could consider this. :)

~SBird

Pokemon_XY September 1st, 2015 9:49 PM

Quote:

Originally Posted by JPAN (Post 8911957)
I hadn't tested it without a lock/lockall command. Apparently, it is required, as the box does not appear without it. Instructions were edited to cover this fact.

Sorry for bothering you again. I've looked at the routine and I found that maybe "func_10f7d8" is not needed to be called and after deleting it i've found nothing wrong though it's included in the original "multichoice" command for showing the triangle before the text. (number)

Another thing is that could you make a detailed note about your functions? I know that it's a bit not realistic, but i really don't know many things in the source code.

Thank you very much in advance!

Lance32497 September 4th, 2015 1:54 AM

Hello, since the EXP. Gain canceller had been effin'ly implemented, it's good to have MONEY gain and reduce canceller so that we can make a Battle frontier-like event.
Request

partys over September 6th, 2015 10:35 PM

Quote:

Originally Posted by FBI agent (Post 8512782)
I don't know where it is either. Perhaps you can ask daniilS via VM or something.




1) For forced evolution, I don't know what you're really talking about. You mean just make a Pokemon evolve without giving the player time to hit the "b" button? I'll look into Pokemon evolution sure.

2) I haven't seen it so VMing me it would be nice. Anyways this is rather easy, I've done it before. I'll post the results at the bottom of this post.

3) Skipping the introduction was already done by Knizz. There's a post in the research and development section's quick research thread.


Preventing TMs from being consumed on use



Quick research:
TMs are deleted in two places. The first place is in their own function. When called from the bag, after use the TM has it's own deletion mechanism. The second way is from the bag, after you use a TM the bag attempts to delete it as well. Well, the solution is quite simple. There's two ways to do this, either go to 0809A1D8 call your own function there which checks if the item is a TM, and if it is, just jump to the end. Or much more simply you just remove the parts from the bag and tm function that deletes the TM (Which is what I did). The former way is a way you can make another item you have unconsumable.

To insert:
Do the byte changes below
0x124F78: 00 00 00 00
0x125C80: 00 00 00 00

Make it Ungivable:
insert that at 0x1326B8: 00 00 17 E0

Make it consumable after animation:
Insert: 00 00 00 00 at 0x124F78

To remove the quantities showing up in the bag:

Compile and insert into free space:
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
        cmp r5, #0x0
        bne end
        ldr r3, =(0x8131EFE +1)
        bx r3

end:
        mov r0, r7
        mov r1, #0x8
        mov r2, r4
        ldr r6, =(0x81335B0 +1)
        bl link
        ldr r3, =(0x8131EFE +1)
        bx r3

link:
        bx r6

.align 2




Here's a compiled version:
Code:

00 2D 01 D1 05 4B 18 47 38 1C 08 21 22 1C 04 4E 00 F0 02 F8 01 4B 18 47 30 47 C0 46 FF 1E 13 08 B1 35 13 08


Now navigate to 0x131EF4 and insert:
Code:

00 48 00 47 XX XX XX 08


Where XX XX XX is the pointer to where you assembled the routine +1

Now navigate to 0x131EA5 and change the byte to E0

Unsellable:
Basically for the TMs, you can still sell them to vendors. To change this, you need to modify each TM individually. It's unfortunate, but the game checks if an item can be sold my comparing it's market price to zero. If it's strictly greater than zero, then you can sell it to a vendor, seems to be the rule. So to make TMs unsellable you need to set their market prices individually to zero.
I can't use my own checks to disguise the TMs as unique because the sell routine in shops are used for ALL items including potions, berries, TMs, and other items like nuggets.


Present :3
http://i.imgur.com/3nina1p.png?1

I've done this twice, and checked my hex editing, but it doesn't work. It still says there's 1 tm, and after I teach the tm to a pokemon the screen goes black, but the music still plays. Any idea why this happens?

DizzyEgg September 6th, 2015 11:13 PM

Quote:

Originally Posted by FrogInfected (Post 8918938)
I've done this twice, and checked my hex editing, but it doesn't work. It still says there's 1 tm, and after I teach the tm to a pokemon the screen goes black, but the music still plays. Any idea why this happens?

You probably messed up pointers. Try doing it again and make sure all your pointers are correct.

Quote:

Originally Posted by FBI agent (Post 8512782)

Preventing TMs from being consumed on use



Quick research:
TMs are deleted in two places. The first place is in their own function. When called from the bag, after use the TM has it's own deletion mechanism. The second way is from the bag, after you use a TM the bag attempts to delete it as well. Well, the solution is quite simple. There's two ways to do this, either go to 0809A1D8 call your own function there which checks if the item is a TM, and if it is, just jump to the end. Or much more simply you just remove the parts from the bag and tm function that deletes the TM (Which is what I did). The former way is a way you can make another item you have unconsumable.

To insert:
Do the byte changes below
0x124F78: 00 00 00 00
0x125C80: 00 00 00 00

Make it Ungivable:
insert that at 0x1326B8: 00 00 17 E0

Make it consumable after animation:
Insert: 00 00 00 00 at 0x124F78

To remove the quantities showing up in the bag:

Compile and insert into free space:
Spoiler:

Code:

.text
.align 2
.thumb
.thumb_func

main:
    cmp r5, #0x0
    bne end
    ldr r3, =(0x8131EFE +1)
    bx r3

end:
    mov r0, r7
    mov r1, #0x8
    mov r2, r4
    ldr r6, =(0x81335B0 +1)
    bl link
    ldr r3, =(0x8131EFE +1)
    bx r3

link:
    bx r6

.align 2




Here's a compiled version:
Code:

00 2D 01 D1 05 4B 18 47 38 1C 08 21 22 1C 04 4E 00 F0 02 F8 01 4B 18 47 30 47 C0 46 FF 1E 13 08 B1 35 13 08


Now navigate to 0x131EF4 and insert:
Code:

00 48 00 47 XX XX XX 08


Where XX XX XX is the pointer to where you assembled the routine +1

Now navigate to 0x131EA5 and change the byte to E0

Unsellable:
Basically for the TMs, you can still sell them to vendors. To change this, you need to modify each TM individually. It's unfortunate, but the game checks if an item can be sold my comparing it's market price to zero. If it's strictly greater than zero, then you can sell it to a vendor, seems to be the rule. So to make TMs unsellable you need to set their market prices individually to zero.
I can't use my own checks to disguise the TMs as unique because the sell routine in shops are used for ALL items including potions, berries, TMs, and other items like nuggets.


Present :3
http://i.imgur.com/3nina1p.png?1

It seems that TMs are still consumable if taught to a pokemon without animation, i.e. if it only knows 2 moves.


All times are GMT -8. The time now is 8:46 AM.


Like our Facebook Page Follow us on Twitter © 2002 - 2018 The PokéCommunity™, pokecommunity.com.
Pokémon characters and images belong to The Pokémon Company International and Nintendo. This website is in no way affiliated with or endorsed by Nintendo, Creatures, GAMEFREAK, The Pokémon Company or The Pokémon Company International. We just love Pokémon.
All forum styles, their images (unless noted otherwise) and site designs are © 2002 - 2016 The PokéCommunity / PokéCommunity.com.
PokéCommunity™ is a trademark of The PokéCommunity. All rights reserved. Sponsor advertisements do not imply our endorsement of that product or service. User generated content remains the property of its creator.

Acknowledgements
Use of PokéCommunity Assets
vB Optimise by DragonByte Technologies Ltd © 2023.