Skeetendo

’Cause all games were better on the GBC

You are not logged in.

#1 2013-10-17 21:23:17

Crystal_
Member
From: Spain
Registered: 2012-09-16
Post 121/450
Website

Gym "door closing" (without triggers!)

First of all, this can be done with triggers in perhaps a more "professional" way, but then it'd require you to repoint the trigger table (unless there are plenty of other maps that you no longer plan to have triggers on) and work with it. In addition, since we would have to be adding triggers to the script header of maps that do not have any trigger, we'd have to repoint and edit the pointers of at least the initial script to make room for the trigger definitions. In short, here I'm going to show a very simple way to "close" the gym "doors" so that the player is unable to leave the gym until the leader is beaten or all his/her pokemon faint (blackout), which makes a very original way to make your hack more difficult (forces the player to beat all gym trainer in succession unless he/she blackouts, in which case the player would lose half his money).

To make things easier, I'm going to use Pokemon Crystal's Violet Gym as an example, as it is a very simple gym. This can be done in different ways, but I'm going to show you the one I'm using myself as I think it's easy to do and understand. It's recommended that you have the GS scripting compendium handy.

First you'd edit the block at the entrance so that it becomes a normal floor block. You can do this with CrystalMap easily. This makes the warp not function, even if it's there. For example, in the Violet Gym map, we'd have to change the block at X:2,Y:7 from block 1C to block 2D.

The next thing we have to do is make the gym leader "open" the doors if he's beaten. We'll need a hex editor for this. Falkner's script is...

UnknownScript_0x683c2: ; 0x683c2
faceplayer
loadfont
checkbit1 $04bd
iftrue UnknownScript_0x683ec
2writetext UnknownText_0x68473
closetext
loadmovesprites
winlosstext UnknownText_0x6854a, $0000
loadtrainer FALKNER, 1
startbattle
returnafterbattle
setbit1 $04bd
loadfont
2writetext UnknownText_0x685af
playsound $009c
waitbutton
setbit2 $001b
checkcode $7
2call UnknownScript_0x68418
UnknownScript_0x683ec: ; 0x683ec
checkbit1 $0008
iftrue UnknownScript_0x68412
setbit1 $03fb
setbit1 $03fc
domaptrigger GROUP_ELMS_LAB, MAP_ELMS_LAB, $2
specialphonecall $3
2writetext UnknownText_0x685c8
keeptextopen
verbosegiveitem TM_31, 1
iffalse UnknownScript_0x68416
setbit1 $0008
2writetext UnknownText_0x68648 -> 00 70 7a
closetext
loadmovesprites
end
; 0x68412

... and we want to add an additional code that changes the block at the entrance when Falkner is beaten. Since this requires additional space we can use the 00 pointer code:
00 = 2byte pointer points to script; when pointed script ends --> return to old script
Since it takes three bytes we can remove the code that writes the last text as it also occupies three bytes (see in red above) and insert there the 00 code. To determine the two-byte pointer we have to find blank space at the end of the bank we are at. In our case we are at the bank that goes from 0x68000 to 0x6b000. We can, for example, find space at 0x6ba70. So our pointer will be 0x70 0x7a (see in green above).
We now head to that location (0x6ba70) and insert the code (three bytes) that we removed in Falkner's main script (it's the 2writetext code that is above in red).
Now we have to insert the changeblock code that will change the block at the entrance to the block that will let us leave the gym (will make the warps work): for Violet Gym, it's block 0x1C.

Changes a block on the current map by giving the new block number and its X/Y values measured in half-blocks.
Structure:
[7A][X][Y][Block]


X and Y are the coordinates, but keep an eye out because it's measured in half-blocks. A good way to find the coordinates we want, is to open CrystalMap in the events tab. We could then see that all of X=04,Y=0E ; X=05,Y=0E ; X=04,Y=0F ; X=05,Y=0F are part of the block we want to change. So a valid code will for example be:

[7A][04][0E][1C]

so we can insert this right after the 2writetext code resulting on:

[7A][04][0E][1C][4C][48][46][91]

at address 0x6ba70.


Now we are almost done. However, what if for some reason the player enters the gym when the leader has already been beaten? He'd be stuck forever! To solve this, the best solution in my eyes is to edit the script of the gym guy so that it applies the same change block ONLY when the leader has been beaten. Violet Gym guy's script is:

VioletGymGuyScript: ; 0x6844f
faceplayer
loadfont
checkbit1 $04bd
iftrue .VioletGymGuyWinScript
2writetext VioletGymGuyText
closetext
loadmovesprites
end

.VioletGymGuyWinScript
2writetext VioletGymGuyWinText
closetext
loadmovesprites
end

; 0x68463

Since the leader must have been beaten for the gym guy to open the doors, the only script we care about is the one in green above. Again, a simple way to do it is with another 00 code, inserting it over the 2writetext code (in brown above). For example our pointer can be 0x80 0x7A, meaning we are going to insert our additional script at 0x6ba80. The script is similar to the one we added for the gym leader:

[7A][04][0E][1C][4C][48][46][91]

However, considering that the gym guy is very close to the entrance and that the changeblock can be seen by the player, to make our script look better we can add an apply sound code (85) of for example sound 0023 (which corresponds to the sound made by the switches in the team rocket hideout). This will make our additional gym guy script look like this:

[7A][04][0E][1C][4C][48][46][85][23][00][91]



Finally, note that maps are reseted after entering a warp (this could for example be a problem in Ekruteak Gym, but at least the gym guy script should guarantee that it's not possible to get stuck. However, in Cianwood and Blackthorn Gyms you WILL need to find a way around that it's possible to get stuck with the strength boulders.

Last edited by Crystal_ (2013-10-17 21:28:34)

Offline

#2 2013-11-21 17:54:48

G0ld Z!
Member
From: New Bark Town
Registered: 2013-11-01
Post 25/82
Website

Re: Gym "door closing" (without triggers!)

Oh great job, this tutorial is very informative, I'll use to my hack, thanks :)
============================================================
Buen trabajo, un tutorial bastante completo, de seguro lo usare, gracias :)

Offline

#3 2013-11-21 19:25:10

Crystal_
Member
From: Spain
Registered: 2012-09-16
Post 137/450
Website

Re: Gym "door closing" (without triggers!)

Thanks for showing your interest mate, but I 'discovered' a better looking way to do it, that is, perhaps, even easier to code. (actually, full credit to Miksy91 who showed me that using a callback is much easier than I thought; it genuinely never occurred to me that you could just repoint the script header to 'make room' for the callback, instead of having to start repointing scripts).

Basically, you'd find black space in the end of the same bank and write something like this:
0x00; no triggers (or if the map has triggers, keep the trigger data untouched)
0x01; one callback
0x01-0x05; type of callback. I don't exactly know what the difference between each type of callback is. I just know it has to do with the order in which each thing is executed. Misky suggested that I would use 05, but I've always used type 01 so far and I've never experienced any weird thing (plus, some gyms already use a callback of type 01).
Then you'd repoint the script pointer to wherever you wrote this. Oh, and make sure that you end the script with 0x90 instead of 0x91 (or whichever the G/S equivalents are)

Callbacks are executed once when the map is loaded, as far as I know. So you would make a script that checks if badge has been obtained or not and closes or does not close the gym doors accordingly.

For example, for violet gym, the script (at 0x6baa0), in Pokemon Crystal, would look like

31 BD 04 09 AA 7A 7A 04 0E 2D 90.  (4BD) is the flag set by falkner when you beat him; AA 7A points to 0x6baaa, where the 0x90 is)

I think in G/S it would be 31 BD 04 09 AA 7A 79 04 0E 2D 8F, but I'm not 100% sure.


The only thing you'll need to keep from the first post is the leader script, since the badge is received and the badge bit is set after returning from battle.

What's good about this new way to do it is that you don't need to talk to anyone if you get stuck, because the doors will not close if you have the badge. At first I thought myself that doing something similar to this would be a lot more complicated but once again credit to Miksy for showing me the way!

Offline

#4 2013-11-22 12:51:26

Miksy91
Member
Registered: 2010-10-16
Post 1,980/2,339

Re: Gym "door closing" (without triggers!)

Crystal_ wrote:

...but once again credit to Miksy for showing me the way!

Thanks, but you really don't have to crdit me for everything! :D
But yeah, using script headers for scripts that you want to execute every time the map is loaded is much more convenient than trying to get around it with a "less complicated" method (which actually isn't). Same goes for all kinds of programming related issues actually. If you come up with something complicated, you have probably programmed it in a stupid way.

Offline

#5 2013-11-22 17:31:47

G0ld Z!
Member
From: New Bark Town
Registered: 2013-11-01
Post 26/82
Website

Re: Gym "door closing" (without triggers!)

Crystal_ wrote:

Thanks for showing your interest mate, but I 'discovered' a better looking way to do it, that is, perhaps, even easier to code. (actually, full credit to Miksy91 who showed me that using a callback is much easier than I thought; it genuinely never occurred to me that you could just repoint the script header to 'make room' for the callback, instead of having to start repointing scripts).

Basically, you'd find black space in the end of the same bank and write something like this:
0x00; no triggers (or if the map has triggers, keep the trigger data untouched)
0x01; one callback
0x01-0x05; type of callback. I don't exactly know what the difference between each type of callback is. I just know it has to do with the order in which each thing is executed. Misky suggested that I would use 05, but I've always used type 01 so far and I've never experienced any weird thing (plus, some gyms already use a callback of type 01).
Then you'd repoint the script pointer to wherever you wrote this. Oh, and make sure that you end the script with 0x90 instead of 0x91 (or whichever the G/S equivalents are)

Callbacks are executed once when the map is loaded, as far as I know. So you would make a script that checks if badge has been obtained or not and closes or does not close the gym doors accordingly.

For example, for violet gym, the script (at 0x6baa0), in Pokemon Crystal, would look like

31 BD 04 09 AA 7A 7A 04 0E 2D 90.  (4BD) is the flag set by falkner when you beat him; AA 7A points to 0x6baaa, where the 0x90 is)

I think in G/S it would be 31 BD 04 09 AA 7A 79 04 0E 2D 8F, but I'm not 100% sure.


The only thing you'll need to keep from the first post is the leader script, since the badge is received and the badge bit is set after returning from battle.

What's good about this new way to do it is that you don't need to talk to anyone if you get stuck, because the doors will not close if you have the badge. At first I thought myself that doing something similar to this would be a lot more complicated but once again credit to Miksy for showing me the way!

Thanks bro, i try the easier method, can i use this script for other things right?
=======================================================
Gracias carnal, usare el metodo facil, y sera que podria usar ese script para otra cosa? Tengo esa dudilla

Offline

#6 2013-11-22 18:29:08

Crystal_
Member
From: Spain
Registered: 2012-09-16
Post 140/450
Website

Re: Gym "door closing" (without triggers!)

Of course, you can do a similar thing everytime you want to add a callback into a map. However, you should be careful that you keep the original triggers/callbacks when doing that!

Offline

#7 2014-09-21 07:47:24

Skurbert
Member
Registered: 2012-12-16
Post 82/95

Re: Gym "door closing" (without triggers!)

This a great guide. I'm glad you also showed us how to make it all into hex, not just only in PKSV. I learned how to do this by looking at the Rocket Hideout code in Mahogany. This way, I could recreate the trash-can puzzle in Vermilion City Gym.

z9OLsiO.png

iC1MJbv.png

d06050W.png

jQ1bfzu.png

Last edited by Skurbert (2014-09-21 07:48:23)

Offline

#8 2014-09-21 10:29:05

Crystal_
Member
From: Spain
Registered: 2012-09-16
Post 211/450
Website

Re: Gym "door closing" (without triggers!)

Thanks! I have never used any tool for scripts though, so for me it's natural to think in hex when it comes to scripting.

Offline

Board footer

Powered by FluxBB