Read-only archive of the Armageddon Games Forums Archive (2000–2026) · About this archive

Sidescroll Ladder Script

61 replies · 10,990 views · Started 13 December 2007

Hooray! It works now. And the flaw with the Z3 (diagnol) movement is corrected, too. Also, no need an extra flag 98 on one tile above the ladder. Well done pkmnfrk.

EDIT: pkmnfrk, don't forget to inform Sillycat2 because he/she is the thread starter in Script Requests.

Joe123 wrote:Damn, I didn't notice =P

But won't it never be reached within that global script because of the loop? 😕

Hm? It never "gets" to that function, it's called from within ladder(). See, the script contains three functions: "run", "ladder" and "isSolid". "run" is invoked by the game engine, "ladder" and "isSolid" are never invoked directly. They are, however, used by "run", and thus get used.

zcAmazing wrote:Hooray! It works now. And the flaw with the Z3 (diagnol) movement is corrected, too. Also, no need an extra flag 98 on one tile above the ladder. Well done pkmnfrk.

Not sure, um, how I managed to fix the diagonal movement, but yay!

zcAmazing wrote:EDIT: pkmnfrk, don't forget to inform Sillycat2 because he/she is the thread starter in Script Requests.

I trust that they are quite able to check this thread themselves, as they have shown the ability to do so in the past.

pkmnfrk wrote:Hm? It never "gets" to that function, it's called from within ladder(). See, the script contains three functions: "run", "ladder" and "isSolid". "run" is invoked by the game engine, "ladder" and "isSolid" are never invoked directly. They are, however, used by "run", and thus get used.

The Global Script is rather different to ffc scripts then.

When I looked at what you'd written, I read as far as:

global script ladder {
void run() {

while(true) {

ladder(98);

Waitframe();
}
}

Saw a while(true) loop with a waitframe, and assumed that the script would progress no further, therefore whatever was after that would be obsolete.

Is a void another type of variable like int bool and float then?

I'll answer your first question, uh, first:

global script ladder {
void run() {

while(true) {

ladder(98);

Waitframe();
}
}

What this is, in effect, doing is:

global script ladder {
void run() {

while(true) {

int lc = 0;

lc = ComboAt(Link->X+8, Link->Y+15); //for speed

if(Screen->ComboF[lc] == f || Screen->ComboI[lc] == f) {
//...
}

Waitframe();
}
}

If you continue the concept, then at some point, you'll substitute a call to "isSolid" with the contents of the script. (which won't compile, since it isn't the same, but that's beside the point).

Your second question, the nature of void. Void is, well, nothing.

void foo = ??? //not valid. Can't declare a "nothing" variable

Void comes from C/C++, and means exactly the same thing. It's used to indicate the a function returns void, aka. nothing.

void foo() { ... } //valid

void bar() { return(???); } //not valid, void is nothing, can't return nothing

Technical side note that should be disregarded entirely if you don't understand it: In C, void still means nothing, but you can also use it to create a pointer that doesn't have any particular type (i.e. it "points to nothing in particular"😉:

void * foo = 0x123; //valid, technically

It can't be used directly (you can't deference it, because then you'd have a nothing type), but can be cast to a different type (i.e. a pointer to an integer).
End nerd-note

Ah, so in declaring a void with that chunk of script in, it's like telling ZC to refer to that chunk of script, instead of writing it out within the void run(){}?

And I didn't realise you could refer to different parts of a script that are declared after a loop that the script is stuck on, I thought you had to declare them globally.
Thanks for that.

No. There's no actual replacement going on. When you make a function call, you're telling the scripting engine to temporarily jump to some other part of the overall code, until it gets a command to go back. This is known as the "execution stack" (since, each function "stacks" on top of the last one).

In the case of the ladder script, the stack would look like this:

1. isSolid()
2. ladder()
3. run()
4. the rest of Zelda Classic

In this script, you set it so that if Link is falling, the script tells ZC he isn't, therefore he is maintained in mid-air, without gravity affecting him.
This stops any vertical or horizontal movement, even if Link presses up or down, correct?

Is there any way I can do something similar for normal top-down screens?

I don't want Link to be able to move when he presses up or down or whatever, I just want the script to make him do that.
I've tried setting his Z to 1, but then he just jumps continually, and I've tried setting his action to LA_FROZEN and passing Inputdirections = false for all of them after my functions, but I still need Link to be able to turn around normally...

You could try setting Link->Jump to 0 like I do, but I'm not entirely sure how gravity works.

That said, you said you set InputLeft, etc to false. Why not do something like this?

if(Link->InputLeft) {
Link->Dir = DIR_LEFT;
Link->InputLeft = false;
}

Setting Link->Jump to 0 wouldn't work on a top-down map, it's just a direct acceleration, so setting it to 0 would give Link 0 acceleration (and I also tried it and it didn't work =P).

However, that bit, is exactly what I need (I think), thanks 😊

Sorry to bring this back from the dead (I have a point).

pkmnfrk, if you have a chance, I need to tell you something is wrong with your script when used with ZC alpha 846. Link flickers funny and he moves slower if combined with the climbing script. I will need to run test quests to verify the problem that I am encountering in my custom quest. I don't know if your script can't adapt to this ZC version, or there is a bug somewhere in ZC (I cannot report it as a Beta bug unless it is true).

I know you may not be available for a long time because of you enjoying the life. I hope you can come back soon and help out.

EDIT 11:06 PM PDT 7/29/08: Ran some tests. I replicated the problem postively. And anybody who helped pkmnfrk develop the script are welcome to reply.

Huh. Crazy. I just checked here randomly, and it seems I'm needed.

Anyway, the problem was caused by the use of the hover boots. And, I have no idea why I used the hover boots. Anyway, I've updated the script, which can be found on ZCTut.

To update your script file, you need to remove both global variables (since they are no longer used), and replace the "ladder" script with this version. Keep everything else the same.

  void ladder(int f) {
int lc;

lc = ComboAt(Link->X+8, Link->Y+15); //for speed

if(Screen->ComboF[lc] == f || Screen->ComboI[lc] == f) {
Link->Jump = 0;
Link->Dir = DIR_UP;

if(Link->InputDown) {
if(!isSolid(Link->X, Link->Y + 16)) Link->Y += 1;
}
if(Link->InputUp) {
if(!isSolid(Link->X, Link->Y - 1)) Link->Y -= 1;
}
if(Link->InputLeft) {
if(!isSolid(Link->X - 1 , Link->Y)) Link->X -= 1;
}
if(Link->InputRight) {
if(!isSolid(Link->X + 16, Link->Y)) Link->X += 1;
}
}
}

I've added the ability to move left and right on the ladder, as well.

You used the hoverboots part to stop the hoverboots effect repeat over (backtrack to page 1 and see post 17 and 18), and now it has returned on my tests. Well moving down the ladder is okay but when you go up or not move at all, hover boots repeat over.

There is a big problem for non-diagonal (classic four directional) Link movements. Link can get stuck.

Ohh, snap. I... uh, misread what I was doing. I was *taking away* the hoverboots, not giving them to him.

Hmm... give me a bit to think about this.

Edit: I updated the script. It now takes away the boots like it should, and I never got stuck or anything. However, Link doesn't animate while on the ladder. Was it like this before? I forget...

LINE 75: SYNTAX ERROR, UNEXPECTED IDENTIFIER, EXPECTING SEMICOLON OR OR, ON TOKEN LINK
FATAL ERROR P00: CAN'T OPEN OR PARSE INPUT FILE!

I spotted a 0 after the semicolon [noparse](😉[/noparse] in line 74 which caused this error, can you remove it in the zctut? (don't do it yet until after my test to save you little time and trip to the zctut)

I will continue my testing and will soon edit this post after my test. Results will come soon.

Oh, shoot. I noticed that in my own script file, and thought I typed it in by accident after. I will fix it, though.

Results are now in.
It works (only for diagonal Z3 Link movements), but Link wasn't animating as he climbs and descends, and this could eliminate the need of a climbing script (mentioned in another thread). I'll tell you, he WAS animating before. Can you make Link animate while climbing/descending?

Still, the problem with the classic (4-directional) Link movement still exists. When he steps on the ladder (the flag 98), he wouldn't get through. I had to move him alot of directions to get him through.

EDIT 6:34 PM PDT 7/31/08: I was able to make him animate as he only climbs, making the movement like the "Super Mario Bros. 2" style. I changed this part from 'false' to 'true':

if(Link->InputUp) {
Link->InputUp = [highlight]true[/highlight];
Link->Action = LA_WALKING;
if(!isSolid(Link->X, Link->Y - 1)) Link->Y -= 1;
}
But, can you still make him animate while descending, or moving side to side while he still faces up?

Can you also fix the problem relating to the classic Link movement (Tell me if you need a test quest).

I found another flaw. The 'Scroll: Spin Attack' item can be a problem when he is on the ladder. If Link charges up for spin attack and he moves, his sword disappears and he will be stuck in that position (he can still move) until he moves to another screen or gets hit by enemy. EDIT 11:54 PM PDT 7/31/08: I had resolved that issue myself, tested and worked. EDIT 8:41 PM PDT 8/3/08: Another flaw with 'Scroll: Quake Hammer' item. If he is charging up while on ladder, he will still move and will be frozen if he gets off the ladder. I carefully add another disablement to the script, but will not test it because I know it is the same result as removing the hover boots.

The script with my modifications, how is it? (Remember, dependant only on diagonal Link movements)
EDIT_Note: Even if he is charging for spin attack while off ladder, if he steps on the ladder, he will be stuck in position. The script only takes away the 'Scroll: Spin Attack' item, preventing him to charge up after sword swing until he is off the ladder.

import "std.zh"

bool has_hover = false;
bool has_spinattack = false;
bool has_quakescroll = false;
bool on_ladder = false;

global script ladder {
void run() {

while(true) {

ladder(98);

Waitframe();
}
}

//Courtesy of Saffith/beefster09
bool isSolid(int x, int y) {

if(x<0 || x>255 || y<0 || y>175) return false;
int mask=1111b;

if(x % 16 < 8)
mask &= 0011b;
else
mask &= 1100b;

if(y % 16 < 8)
mask &= 0101b;
else
mask &= 1010b;

int ret = Screen->ComboS[ComboAt(x, y)] & mask;
return (ret!=0);

}

void ladder(int f) {
int lc;

lc = ComboAt(Link->X+8, Link->Y+15); //for speed

if(Screen->ComboF[lc] == f || Screen->ComboI[lc] == f) {
if(!on_ladder) {
on_ladder = true;
has_hover = Link->Item[I_HOVERBOOTS];
Link->Item[I_HOVERBOOTS] = false;
has_spinattack = Link->Item[I_SPINSCROLL1];
Link->Item[I_SPINSCROLL1] = false;
has_quakescroll = Link->Item[I_QUAKESCROLL1];
Link->Item[I_QUAKESCROLL1] = false;
}
Link->Jump = 0;
Link->Z = 0;
Link->Dir = DIR_UP;

if(Link->InputDown) {
Link->InputDown = false;
Link->Action = LA_WALKING;
if(!isSolid(Link->X, Link->Y + 16)) Link->Y += 1;
}
if(Link->InputUp) {
Link->InputUp = true;
Link->Action = LA_WALKING;
if(!isSolid(Link->X, Link->Y - 1)) Link->Y -= 1;
}
if(Link->InputLeft) {
Link->InputLeft = false;
Link->Action = LA_WALKING;
if(!isSolid(Link->X - 1 , Link->Y)) Link->X -= 1;
}
if(Link->InputRight) {
Link->InputRight = false;
Link->Action = LA_WALKING;
if(!isSolid(Link->X + 16, Link->Y)) Link->X += 1;
}
} else {
if(on_ladder) {
Link->Item[I_HOVERBOOTS] = has_hover;
Link->Item[I_SPINSCROLL1] = has_spinattack;
Link->Item[I_QUAKESCROLL1] = has_quakescroll;
on_ladder = false;
}
}
}
}

- Can you still make him animate while descending, or moving side to side while he still faces up?

- Please check what needs improvement for compatibility with classic Link movements or you may need to create a separate script specifically for that movement.

Is it really that hard for you to combine those global scripts? if you read it carefully && take the time too, it's really simple.

pkmnfrk wrote:What, exactly, do you need help with?

Where it says,

"This section is the function call:"

ladder(98);

That's not part of the main script, so I don't know what to do with it.