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

Development: Taking Pokémon away

HackMew

Mewtwo Strikes Back
1,314
Posts
17
Years
    • Seen Oct 26, 2011

    Brief Intro

    How many times has this been asked before? Quite a lot, I guess. While I cannot stop people from asking the same questions over and over again because they're too lazy to search or whatever, I can still give you a nice ASM routine to do the job.

    Description

    It is not commented, but if you're any experienced you shouldn't have problems understanding it. Basically the routine will take the value stored into variable 0x8004 and remove that Pokémon from the party. The first one would be setvar 0x8004 0x0, and so on. The routine also performs some safety checks in case you want to set the variable manually. Of course, it's not a bad idea to use the select Pokémon special(s). To prevent obvious problems, the routine won't allow you to take away your last Pokémon. If everything goes fine, the return value (conveniently stored into LASTRESULT) will be 0x1. In any other case it will be set to 0x0.

    There's another short routine too, which is similar but has no safety checks and requires no input: it will simply erase the first Pokémon. It can be useful in some occasions, for example having a starter and then getting a new one or similar. In this case, the previous routine would not work indeed.

    The Code


    TakePokemon


    • FireRed/LeafGreen

      Code:
      [div="font-family:consolas,courier new,monospace"].text
      .align 2
      .thumb
      .thumb_func
      .global TakePokemon
      
      main:
      	push {r0-r7, lr}
      	mov r5, #0x0
      	ldr r6, .VAR
      	ldr r7, .POKEMON_AMOUNT
      	ldrb r4, [r7]
      	cmp r4, #0x2
      	blt return
      	ldrh r3, [r6]
      	cmp r3, r4
      	bhs return
      	sub r2, r4, #0x1
      	strb r2, [r7]
      	add r3, #0x1
      	sub r2, r4, r3
      	mov r5, #0x64
      	mul r2, r5
      	lsr r2, r2, #0x1
      	mul r3, r5
      	ldr r7, .POKEMON_PARTY
      	add r0, r7, r3
      	sub r1, r0, r5
      	swi #0xB
      	mul r4, r5
      	add r7, r4
      	sub r7, r5
      	mov r0, #0x0
      	mov r2, #0x19
      	mov r5, #0x1
      
      erase_loop:
      	stmia r7!, {r0}
      	sub r2, #0x1
      	cmp r2, #0x0
      	bne erase_loop
      
      return:
      	strh r5, [r6, #0x10]
      	pop {r0-r7, pc}
      
      .align 2
      .POKEMON_AMOUNT:
      	.word 0x02024029
      .POKEMON_PARTY:
      	.word 0x02024284
      .VAR:
      	.word 0x020270B8 + (0x8004 * 2)
      [/div]
    • Ruby/Sapphire

      Note: The routine is the same as the FR/LG one; just replace the bottom part with the following:

      Code:
      [div="font-family:consolas,courier new,monospace"].align 2
      .POKEMON_AMOUNT:
      	.word 0x03004350
      .POKEMON_PARTY:
      	.word 0x03004360
      .VAR:
      	.word 0x0201E8C4 + (0x8004 * 2)[/div]
    • Emerald

      Note: The routine is the same as the FR/LG one; just replace the bottom part with the following:

      Code:
      [div="font-family:consolas,courier new,monospace"].align 2
      .POKEMON_AMOUNT:
      	.word 0x020244E9
      .POKEMON_PARTY:
      	.word 0x020244EC
      .VAR:
      	.word 0x020275D8 + (0x8004 * 2)[/div]

    EraseFirstPokemon


    • FireRed/LeafGreen

      Code:
      [div="font-family:consolas,courier new,monospace"].text
      .align 2
      .thumb
      .thumb_func
      .global EraseFirstPokemon
      
      main:
      	push {r0-r2, lr}
      	mov r0, #0x0
      	ldr r1, .POKEMON_PARTY
      	mov r2, #0x19
      
      erase_loop:
      	stmia r1!, {r0}
      	sub r2, #0x1
      	cmp r2, #0x0
      	bne erase_loop
      
      return:
      	pop {r0-r2, pc}
      
      .align 2
      .POKEMON_PARTY:
      	.word 0x02024284[/div]
    • Ruby/Sapphire

      Note: The routine is the same as the FR/LG one; just replace the bottom part with the following:

      Code:
      [div="font-family:consolas,courier new,monospace"].align 2
      .POKEMON_PARTY:
      	.word 0x03004360[/div]
    • Emerald

      Note: The routine is the same as the FR/LG one; just replace the bottom part with the following:

      Code:
      [div="font-family:consolas,courier new,monospace"].align 2
      .POKEMON_PARTY:
      	.word 0x020244EC[/div]


    This research document is Copyright © 2010 by HackMew.
    You are not allowed to copy, modify or distribute it without permission.
     
    Last edited:

    Darthatron

    巨大なトロール。
    1,152
    Posts
    18
    Years
  • Looks good, except for some things that would seem to backfire. If you wouldn't mind telling me if my thoughts are wrong or not, that would be great.

    Code:
    ...
    	cmp r4, #0x2
    	blt return
    	ldr r6, .VAR
    ...
    return:
    	strh r5, [r6, #0x10]
    	pop {r0-r7, pc}

    r4 contains the the Pokemon Amount and if it's less than 2 then it quits, but when quitting wouldn't it write 0x0 to the address 0x00000010 in the RAM? Surely it's not meant to do that.

    EDIT: Also, isn't it supposed to return the value to 0x800D, not 0x8004? Or did I miss something?
     

    HackMew

    Mewtwo Strikes Back
    1,314
    Posts
    17
    Years
    • Seen Oct 26, 2011
    Looks good, except for some things that would seem to backfire. If you wouldn't mind telling me if my thoughts are wrong or not, that would be great.

    Code:
    ...
    	cmp r4, #0x2
    	blt return
    	ldr r6, .VAR
    ...
    return:
    	strh r5, [r6, #0x10]
    	pop {r0-r7, pc}

    r4 contains the the Pokemon Amount and if it's less than 2 then it quits, but when quitting wouldn't it write 0x0 to the address 0x00000010 in the RAM? Surely it's not meant to do that.

    EDIT: Also, isn't it supposed to return the value to 0x800D, not 0x8004? Or did I miss something?

    Not really... since the value of r6 would then be unpredictable, a random address would be used, basically. E.g. it would not work properly, obviously. I fixed that already even before posting this, anyway. As for the return value, that's correct. Because variable 0x8004 is exactly 0x10 byte before 0x800D.
     

    HackMew

    Mewtwo Strikes Back
    1,314
    Posts
    17
    Years
    • Seen Oct 26, 2011
    Bumping this because I just wanted to say I've updated and fixed the first routine.
    In case you used it before February 13th, I strongly suggest you to get the new one.
     

    Ben.

    Orange I s l a n d s~
    623
    Posts
    14
    Years
  • Looks great, HackMew.
    I will be using this, thanks a bunch!
     

    altariaking

    Needs NO VMs...
    1,087
    Posts
    14
    Years
  • looks good. it didn't work for me but then i can only apply asm and then never be able to use it lol. i tried to take away treeko with
    setvar 0x8004 0x115
    ...i know, my scripting is bad...
     

    HackMew

    Mewtwo Strikes Back
    1,314
    Posts
    17
    Years
    • Seen Oct 26, 2011
    Looks great, HackMew.
    I will be using this, thanks a bunch!

    You're welcome.


    Alright! The routine worked!
    Thank you, again!

    My, you are the best hacker I've ever seen. (And good with ASM too ^^)

    ~ ^^

    Thanks :)


    looks good. it didn't work for me but then i can only apply asm and then never be able to use it lol. i tried to take away treeko with
    setvar 0x8004 0x115
    ...i know, my scripting is bad...

    No, the routine doesn't work like that; the setvar 0x8004 needs the value of the actual slot of your Pokémon party. The first one would be setvar 0x8004 0x0 and so on.


    pretty sure that the var should be set to the slot of the pokemon you want to take away(1-6) not the actual species.

    Almost right. The first slot is 0x0, just like the select Pokémon special(s). I did that for compatibility, indeed.
     

    xGGxToiZ

    >.//:SO HOT:\\.<
    44
    Posts
    14
    Years
  • Edit2: I managed to solve the problem! You just need to switch your main Pokémon with the "?". Then you use an item from your bag and it disappears! (Needs to be refreshed?)

    Still, taking Pokémon away is cool! ^^
     
    Last edited:
    190
    Posts
    14
    Years
    • Seen Apr 14, 2016
    could someone give an example of using this in a script for ruby. im just very confused by asm.
     

    Shiny Quagsire

    I'm Still Alive, Elsewhere
    697
    Posts
    14
    Years
  • The only part that's asm is inserting the compiled asm into the game. To use the asm, put this in your script:

    setvar 0x8004 0x0 (Party slot. This is the first slot)
    callasm 0x(ASM OFFSET)
     

    HackMew

    Mewtwo Strikes Back
    1,314
    Posts
    17
    Years
    • Seen Oct 26, 2011
    Edit2: I managed to solve the problem! You just need to switch your main Pokémon with the "?". Then you use an item from your bag and it disappears! (Needs to be refreshed?)

    Still, taking Pokémon away is cool! ^^

    Well, before you removed the script you had a setvar 0x8004 0x1, and then the callasm. Could you tell me what was the script meant to do, exactly?
     

    xGGxToiZ

    >.//:SO HOT:\\.<
    44
    Posts
    14
    Years
  • Well, before you removed the script you had a setvar 0x8004 0x1, and then the callasm. Could you tell me what was the script meant to do, exactly?

    Well, my script was supposed to loan you a Pokémon then have a wildbattle with your soon-to-be starter. (I used a special along with setwildbattle.)

    Then after catching your starter, the loaned Pokémon was supposed to be erased so that you only have your starter.

    Thing is, there's are a blank spot before the starter.
    (To fix it, you need to access the Pokémon Menu then you have to switch the two Pokémon then use an item from your bag before it disappears.)

    Oh and one more thing, that script was messed up, I meant it to be
    setvar 0x8004 0x0 to erase the first Pokémon.

    I'm using the EraseFirstPokemon routine. (Was it unnecessary to put a setvar since it Erases the first Pokémon?)

    To see the Wild Battle, click Here.
    To see the Battle, click Here. (Low quality, sped up)
    To see how to make the empty slot disappear, click Here.

    Hope you can see through the problem . .

    ^^

    Edit: Solved it! It's a sin to use EraseFirstPokemon in that type of script, I need to use the first one.
    Whew! (Because, it only ERASES the POKEMON right? It doesn't take?)
     
    Last edited:

    HackMew

    Mewtwo Strikes Back
    1,314
    Posts
    17
    Years
    • Seen Oct 26, 2011
    Well, my script was supposed to loan you a Pokémon then have a wildbattle with your soon-to-be starter. (I used a special along with setwildbattle.)

    Then after catching your starter, the loaned Pokémon was supposed to be erased so that you only have your starter.

    Thing is, there's are a blank spot before the starter.
    (To fix it, you need to access the Pokémon Menu then you have to switch the two Pokémon then use an item from your bag before it disappears.)

    Oh and one more thing, that script was messed up, I meant it to be
    setvar 0x8004 0x0 to erase the first Pokémon.

    I'm using the EraseFirstPokemon routine. (Was it unnecessary to put a setvar since it Erases the first Pokémon?)

    To see the Wild Battle, click Here.
    To see the Battle, click Here. (Low quality, sped up)
    To see how to make the empty slot disappear, click Here.

    Hope you can see through the problem . .

    ^^

    Edit: Solved it! It's a sin to use EraseFirstPokemon in that type of script, I need to use the first one.
    Whew! (Because, it only ERASES the POKEMON right? It doesn't take?)

    Well... I watched the videos. And yeah, you shouldn't use EraseFirstPokemon at all: that's only meant to erase the first, and only the first, Pokémon in your party when you have only one Pokémon though (because the TakePokemon wouldn't work in that case, due to the safety checks). Anyway, while TakePokemon can actually take away any Pokémon in the team (as long as the necessary conditions are met), how can you be sure that the borrowed Pokémon (the one that should be removed from the team) is always the first one in the party? The player could change the order eventually. Have you thought about that?
     

    xGGxToiZ

    >.//:SO HOT:\\.<
    44
    Posts
    14
    Years
  • Right after you catch your starter, the loaned Pokémon is taken instantly. (The script doesn't stop after the battle, the whole battle against the starter is a special and oh, it's a level script to be exact.)

    So that means, the loaned Pokémon will always be the first and the Pokémon menu will be available when the script ends.
     

    HackMew

    Mewtwo Strikes Back
    1,314
    Posts
    17
    Years
    • Seen Oct 26, 2011
    Right after you catch your starter, the loaned Pokémon is taken instantly. (The script doesn't stop after the battle, the whole battle against the starter is a special and oh, it's a level script to be exact.)

    So that means, the loaned Pokémon will always be the first and the Pokémon menu will be available when the script ends.

    I see. Well, when I tried the routine on Ruby it worked fine, so it might have something to do with the special you used. So please send me the full script either via PM/VM.
     
    Back
    Top