Skeetendo

’Cause all games were better on the GBC

You are not logged in.

#1 2012-06-10 00:32:25

Poketto...
Member
Registered: 2011-12-28
Post 17/39

Start game with pokemon already on team.

So I'm a little stumped on this one. Would this require a script that starts up the moment you finish the title and "enter your name" screen?

I'm assuming it would use the "give pokemon" script

[2D][PKMN][PKMNlvl][PKMNitem][TRAINER]

So if I wanted lets say to start the game with bulbasaur level 5 it would be
2D 01 05 00 00

I may also put text at the beginning also.

However I'm not to sure how to make this all happen automatically. Would this require a timed trigger?(if thats even possible)

Offline

#2 2012-06-10 02:22:21

Mateo
Member
From: The Sims 4
Registered: 2009-11-25
Post 1,412/3,508

Re: Start game with pokemon already on team.

Using the Give Pokemon command from a script will automatically call a dialogue asking you to give the Pokemon a nickname, but will not automatically call text saying you received a pokemon. There are a few ways you could go about doing this.

The best way to do it using the scripting system would be to have the starting map in the trigger table. You would have it so the first pointer in the script header (for when the trigger timing is on 0, which it would be the first time) and have it give you the Bulbasaur and whatever else you want to do. Then at the end of the script, you would change the trigger timing to 01, then end the script normally. The second script pointer in the script header would just point to a return code. To make this easier, you could just have it point to the same 0x90 you used at the end of your first script.

This way, when you first start the game you will receive the Pokemon, and it will change the trigger timing so that you won't be given another bulbasaur every time you enter the map.

If you wanted to do it in the intro, you would have to add an additional ASM routine that would manually write the data to the RAM addresses for your first pokemon in your party. This would be the more complicated way to do it, and wouldn't allow you to Nickname the Pokemon.

I guess another way to do it in the intro would be to find the location of the ASM routine that the "give pokemon" script calls, and call that somewhere in the intro, presumably specifying the values for the pokemon, level, etc, ahead of time.

I won't be a lot of help on either of the in-the-intro methods, but I think the in-game method will work just as well.

Last edited by Mateo (2012-06-10 02:22:42)

Offline

#3 2012-06-10 08:07:55

Miksy91
Member
Registered: 2010-10-16
Post 911/2,317

Re: Start game with pokemon already on team.

Mateo wrote:

If you wanted to do it in the intro, you would have to add an additional ASM routine that would manually write the data to the RAM addresses for your first pokemon in your party. This would be the more complicated way to do it, and wouldn't allow you to Nickname the Pokemon.

This is actually also the "easiest" thing to be done of these.
I remember trying to make it so you were automatically given the Pidgeot and Arcanine in the start of that minihack - Zombieland. Unfortunately, normal map loading process is not loaded when you appear in your room at the start of the game so no scripts from map's script header can be loaded either.

Only thing, that had to be done, would be finding a good place to insert a call code (CD) for your own assembly code for adding the specific pokemon in your party.

scaled.php?server=32&filename=aaalp.png&res=landing

I did some debugging and noticed that for example, this code is called straight after Oak's sprite appears and he's about to say "Welcome to world of..." etc.

Well, there is no space for an additional call command here but what we could do instead, would be changing ld hl, $6056 into call 7520 (assuming you haven't put anything there yet). However, we have to make sure that rp (register pair) hl is loaded "into" $6056 when our own assembly routine ends.
But...we should also make sure the other register values (seen on the right side of the image) are correct as well.

Anyway, in $7520 we should put a command line as simple as this.

ld hl, $DA22
ld a, $01
ldi [hl], a
ld a,$01
ldi [hl], a
ld a, $FF
ld [hl], a
ld hl, $DA2A
ld a, $01
ldi [hl], a
ld a, $AD (if holding Berry)
ldi [hl], a
...same thing over and over again till we reach hl = $DA59 (end of pokemon data of 1st pokemon in party)

Commands:
ld hl, $DA22 - loads the address into a 2-byte register pair (formed with two registers, for example h and l)
ld a, $01 - loads value 01 into register a
ldi [hl], a - loads the value in a into register pair hl and increments it (after the code: hl = hl (in the beginning) + 1, a = [value before the command], [hl (in the beginning)] = a)

*ldi [hl], a can also be inputted this way: ld [hl], a + inc hl (but wastes more space then needed)


Register values before our own assembly code:
a = 00
hl = 6056

I don't think they (Gamefreak) paid a close attention to register values at every single time so instead, they're probably often loaded with different values during the call commands but let's just change them back to normal.

So after ldi hl, $a (hl = DA58)
ld a, $xx
ld hl, a (there is no use incrementing it anymore)
(this is where we would normally put ret for going back to the main script)

ld a, $00 
ld hl, $6056
ret

Voila! You've just made it so you receive your starter pokemon without anyone noticing a thing happened, during the intro.


P.S
Probably a more user-friendly way to do the job would be writing your data, somewhere in rom, what would be loaded for the data of the first pokemon in your party and use the method Sawakita introduced for copying data in from address to another. You'll have to make sure all register values are corrected after the code though: http://hax.iimarck.us/topic/676/

bc will eventually reach 0000 but C3 would have to be loaded to register d afterwards


Hopefully you'll get it working though, I really put some time into creating this post :)
If not, feel free to ask and I'll guide you through this.

Last edited by Miksy91 (2012-06-10 09:07:14)

Offline

#4 2012-06-10 17:31:04

Poketto...
Member
Registered: 2011-12-28
Post 18/39

Re: Start game with pokemon already on team.

@Mateo
I'll consider this method, Thanks.

@Miksy91

Ok thanks for clearing that up.

However to be honest I'm not very good with assembly codes/call codes (like the "ld hl, a" stuff). Unless I'm just not looking at it the right way.
From what I see $7520 is just a place to put the code, from there we keep adding data until the pokemon is completly added to the party.


I'm trying to learn though. So could I get a little guidance on this?(assuming this type of code could also be used to start the game with items in your inventory)

Offline

#5 2012-06-10 18:39:02

Miksy91
Member
Registered: 2010-10-16
Post 913/2,317

Re: Start game with pokemon already on team.

Poketto... wrote:

I'm trying to learn though. So could I get a little guidance on this?(assuming this type of code could also be used to start the game with items in your inventory)

I see why not, items inventory ought to be cleared when the game is reseted as well and loaded only when you choose Continue in the start menu.

Let's see, I could just do all the job for you and upload an ips-patch somewhere which you could use but then you wouldn't learn anything from it so let's not do that :P

First, download this tool: http://www.romhacking.net/utilities/282/
By opening the rom with it, you'll notice it shows all the hexadecimal numbers and what they correspond to in assembly language.

So by going to 01:5FD1 (0x5FD1), you should find ld hl, $6056 in there so just change it to call $7520 first.
In that call code, you're going to have to add the routine for adding the pokemon in your party and after routine, changing register a into $00 and hl into $6056.

I assume you understand what DA22 and DA2A correspond to but if not, they're part of pokemon data of the 1st pokemon in your party (RAM map will help you with this).

Anyway, instead of writing the following stuff here...

ld hl, $DA22
ld a, $01
ldi [hl], a
ld a,$01
ldi [hl], a
ld a, $FF
ld [hl], a
ld hl, $DA2A
ld a, $01
ldi [hl], a
ld a, $AD (if holding Berry)
ldi [hl], a...

...I've decided to explain how the loop works which Sawakita introduced in the thread I linked to my previous post.

; hl = source
; de = destination
; bc = number of bytes to copy

loop:
    ld a,[hli]
    ld [de],a
    inc de
    dec bc
    ld a,c
    or b
    jr nz,loop
    ret

Basically, you've to make that call command look for an assembly code (in 0x7520) in which you first change the register pair values of hl, de and bc and after that, write that loop code in there.

So first, this is what you've gotta put there:

01:7520

 ld hl, $7570 (choose your own address but this is where you're going to have to put Bulbasaur's data according to the ram map)
 ld de, $DA2A (RAM address where to copy data to)
 ld bc, $0030 (DA59 - DA2A + 0x1 = 0x30)
 ldi a, [hl]
 ld [de], a
 inc de
 dec bc
 ld a, c
 or a, b (could also be cp a, $00 I guess?)
 jr nz, @loop (starts at ldi a, [hli])
 ld hl, $DA22
 ld [hl], $01
 inc hl
 ld [hl], $01
 inc hl
 ld [hl], $FF
 ld a, $00
 ld hl, $6056
 ret

The loop starts with ldi a, [hl]. This instruction loads register a (can store a 1-byte value (00-FF)) with the value stored in register pair hl (in the beginning, with the value at rom address $7570) but it also increments the rom address stored in hl. Basically, after this code hl = $7571. That value that was loaded in register a (value in rom address $7570) is now loaded in register pair de (in ram address $DA2A) but the value in register a will also stay the same. After that, inc de changes the address loaded to de into $DA2B and dec bc accordingly changes register pair de into $002F. After that, we load the value in register c (at this point, bc consists of b = $00 and c = $2F) into register a. or a, b compares the values in registers a and b (now a = $2F, b = $00) and if they match (only if a = $00), z flag is set. jr nz command checks if z flag is not set and if it's so, the program jumps back to @loop and same thing goes over and over again...

Eventually (not a long time here), 0x30 bytes starting at 0x7570 will be copied to ram address $DA2A and after that, command ld a, c is used to load value in c (c = $00) into register a and so register a matches with b and z flag is set. Now that z flag is set, the program won't go through the same instructions again.

After this is done, we load hl with address $DA22, load $01 into that address (ld [hl], $01), increment hl (hl = $DA23), load $01 in there, increment hl again (hl = $DA24) and load $FF into that address for making the game know that you've got 01 pokemon which is number 01 and FF for "Cancel".

In the end, we change the registers back to "normal" (or what they were before our little assembly routine): ld a, $00 & ld hl, $6056.
ret is a command which acts like Return code2 (90) while scripting, and so the program will continue executing code at $5FD4 like it would have done if this code wasn't added here.

Edit:
I checked how it works and it's fine expect for the fact you've got to determine the ID of the given pokemon. So before the code ends, (before ld a, $00 and ld hl, $6056) make it also transfer your trainer ID to Bulbasaur (nice to see it's already added after you click NEW GAME).

Example code:

ld a, [$D1A1]
ld [$DA30], a
ld a, [$D1A2]
ld [$DA31], a

Edit2:
After all this, it works but the pokemon is still missing a name and OT. Expand the loop code to put these up or load them manually like I show with the example before (and the ID example).

Last edited by Miksy91 (2012-06-10 19:10:56)

Offline

#6 2012-06-10 19:58:38

Tauwasser
Member
Registered: 2010-10-16
Post 283/448

Re: Start game with pokemon already on team.

Why would you do this all by hand? There are a lot of routines that already deal with exactly this! Seriously, doing everything by hand like this is definitely not the way to go!

Also, the hero upstairs room's script header is processed just like any other map, so I don't see why you would have to go through all that trouble to begin with :-/

cYa,

Tauwasser

Offline

#7 2012-06-11 04:36:02

Miksy91
Member
Registered: 2010-10-16
Post 916/2,317

Re: Start game with pokemon already on team.

Tauwasser wrote:

Why would you do this all by hand? There are a lot of routines that already deal with exactly this! Seriously, doing everything by hand like this is definitely not the way to go!

Also, the hero upstairs room's script header is processed just like any other map, so I don't see why you would have to go through all that trouble to begin with :-/

cYa,

Tauwasser

I've just gotten into assembly hacking so I've really no idea how to properly call stuff from rom bank 0x1 (as it's hard to tell which call command calls which kind of function).

No idea why I didn't get the script header working the way I intended then :S

Offline

#8 2012-06-11 22:09:01

Tauwasser
Member
Registered: 2010-10-16
Post 284/448

Re: Start game with pokemon already on team.

rst $8 is your friend.

cYa,

Tauwasser

Offline

Board footer

Powered by FluxBB