PDA

View Full Version : Sidescroll Ladder Script



Sillycat2
12-12-2007, 09:56 PM
Hey guys, this is my first post here. I recognize a lot of people.

Anyway, I need a script made for sidescroll ladders.
I need either a combo type or a flag that, when Link stands on it, he won't fall with "Sideview Gravity" checked. Kind of like the ladders in Link's Awakening.

I made the same request at PZC but I heard that there are some expert scripters here.
Can anyone make the script?

pkmnfrk
12-12-2007, 11:29 PM
Hmm... Sounds doable. Gimme a few minutes.

pkmnfrk
12-13-2007, 12:32 AM
Ok, done. It's very basic, but very easy to use. Just assign the script to any old FFC, and you're done.

http://zctut.com/ladder.php - Archived on my site

It uses flag #98 (the first of the flags set aside just for scripts), but you can change that by passing the flag number in to D0.

As a bonus, I was going to throw in an option of forcing Link to face up while on a ladder (a la Gameboy Zeldas), but Link is not very flexible, and I ended up having to re-invent his movement and collision detection, and it was buggy anyway. So, I just left it at that.

Russ
12-13-2007, 12:37 AM
Wait, so all we have to do is attack the script to any FFC in the screen. Then how does it know what combos are the ladder combos?

pkmnfrk
12-13-2007, 12:43 AM
It uses flag #98 (the first of the flags set aside just for scripts), but you can change that by passing the flag number in to D0.

Read closer

Joe123
12-13-2007, 08:53 AM
You can make him face upwards via Link Tile Modifiers.
http://www.armageddongames.net/forums/showthread.php?t=99828

Russ
12-13-2007, 11:23 AM
Finally. Real ladders. And combined with Joe's script, we have treu sideview ladders. Is there anything scripting can't do?

Sillycat2
12-13-2007, 01:53 PM
*posts on PZC*
Beautiful. The whole ZC world should know about this script.

C-Dawg
12-14-2007, 02:19 AM
Finally. Real ladders. And combined with Joe's script, we have treu sideview ladders. Is there anything scripting can't do?

Yes, but there's always a workaround.

zcAmazing
12-18-2007, 12:24 AM
Hey, pkmnfrk:

I have been trying out the script you made for one of my quests. It's wonderful... :) but can you make an improvement?

I found a flaw. Using the script while Link has Z3 (diagonal) movement, when he walks at the bottom of the ladder in a gravity screen and it is a solid floor with no flag, he walks in one solid tile down.

You can reply here, but I liked to be notified too because I don't come here often, so send in a PM to me also.

pkmnfrk
12-18-2007, 07:06 PM
Oohh... huh. I was hoping to avoid having to check for diagonals... Hmm, let me think on this...


You can reply here, but I liked to be notified too because I don't come here often, so send in a PM to me also.

There is a thread subscription option. I'll send you a PM once, if/when I update the script.

Mega Link
12-21-2007, 09:31 PM
It doesn't work!


PASS 1: PARSING
LINE 41: SYNTAX ERROR, UNEXPECTED $END, EXPECTING RBRACE, ON TOKEN
FATAL ERROR P00: CAN'T OPEN OR PARSE INPUT FILE!

-- PRESS A KEY --

pkmnfrk
12-21-2007, 10:43 PM
Ah, cripes. My bad, I forgot a } in the code block. Try it now.

Mega Link
12-23-2007, 10:10 PM
Still doesn't work.

pkmnfrk
12-29-2007, 08:18 AM
Did you recopy the script? Or, add the } at the end? I know for a fact this script works.

Mega Link
12-29-2007, 11:00 AM
Well apparently, you have to put all the scripts in one file. (Which I didn't know.)

zcAmazing
01-03-2008, 05:00 AM
pkmnfrk, when going on the ladder with flag 98's for that sideview ladder script while Link has the Hover Boots item, as he goes up, the Hover Boots takes effect repeatedly. As he goes down, he acts flickering funny. Can you add to your script that prohibits the use of Hover Boots when Link is on Flag 98?

pkmnfrk
01-03-2008, 05:50 AM
Yes, I can. But, I just thought about it, and there isn't really any foolproof method of ensuring that Link has the hover boots when he leaves the screen. Consider this:


bool hashover;
hashover = Link->Item[I_HOVERBOOTS];

while(true) {
//...
if(this combo is 98)
Link->Item[I_HOVERBOOTS] = false;
else
Link->Item[I_HOVERBOOTS] = hashover;

Waitframe();
}

This code works great as long as Link is on the screen. And, heck, if he leaves the screen while not on a ladder. However, if he leaves via a warp on a ladder (a very common thing one would do), then the last thing it would do is take away his boots, and then the script dies!

The only thing I can suggest is disabling the hoverboots on screens with ladders, OR waiting until 2.5+ to get real ladders.

Joe123
01-03-2008, 07:51 AM
Or putting flag 98 and that script around the warp destination?

pkmnfrk
01-03-2008, 05:15 PM
No, that wouldn't work. Look again at my code. It records whether Link has the hover boots or not, and then goes on. In the loop, if Link's on a ladder, it takes away the hover boots. Otherwise, it gives him <whether or not he had them when the loop started>.

So, if he warps away while on a ladder, he won't have the boots. Then, the next copy of th script will check, and see that he doesn't have the boots. Then, it'll give him either no boots, or no boots. Which is the problem.

Now, that said, I suppose I could make this into a global script, which doesn't die with a screen. Let me work on that for a bit...

Joe123
01-03-2008, 05:34 PM
Couldn't you just make 'hashover' into a global boolean?

pkmnfrk
01-03-2008, 05:42 PM
I suppose, but I would have to make things complicated, and unless you use the hack you mentioned, you'll lose the hoverboots until the next time you touch a ladder.

In light of this, I think it'll work best as a global script, which I'm just in the middle of preparing for general release.

Edit: I've updated the ladder script (http://zctut.com/ladder.php). It now uses a global script. More details on global scripts (as I require you to use them) here: Global OnStart Script (http://zctut.com/start.php)

zcAmazing
01-03-2008, 08:26 PM
Got notified. I will be trying this out shortly. EDIT: Actually, I will be trying out that global script, the update to it.

Umm, please edit the link: "the ladder script." You are missing a "t" in between "c" and "u."

Joe123
01-03-2008, 08:36 PM
(which, by themselves, cannot run more than one frame for no particular reason)

I did see a reason for that once, but I forget what it is now. Might be in the pinned threads in scripting discussion.


For your sake any mine,
Should that be and?

And also, howcome you always declare booleans, then set them on the next line?

bool somethingfoo;
somethingfoo = true;
like that?

bool somethingfoo = true;
is just as acceptable isn't it?

pkmnfrk
01-03-2008, 08:42 PM
All the reported typos are fixed (sheesh, my inner-dictionary must be out to lunch or something >_>)

I do variables like that because I thought you couldn't initialize them on the same line.

*tests*

... I coulda sworn I saw an error before... <_< updating scripts

Edit: And, actually, the example you pasted is a typo. Or, a copy-and-pasto, rather. I intended to just have the declaration, before I started copying and pasting stuff in my code blocks -_-'''

Anyway, fixed.

zcAmazing
01-03-2008, 09:26 PM
I have learned how a global script does in your neat tutorial site. There are problems with compiliation, here is how I set up your global script.
bool ladderhashover;
bool onladder;

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 &#37; 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(!onladder) {
ladderhashover = Link->Item[I_HOVERBOOTS];
Link->Item[I_HOVERBOOTS] = false;
onladder = true;
}

if(Link->Jump < 0) Link->Jump = 0;
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;
}
} else {
if(onladder) {
Link->Item[I_HOVERBOOTS] = ladderhashover;
onladder = false;
}
}
}
}
The errors in Pass 3 were returned was:
TMP, LINE 37: ERROR S10: FUNCTION COMBOAT IS UNDECLARED.
TMP, LINE 45: ERROR S10: FUNCTION COMBOAT IS UNDECLARED.
TMP, LINE 49: ERROR S09: VARIABLE I_HOVERBOOTS IS UNDECLARED.
TMP, LINE 50: ERROR S09: VARIABLE I_HOVERBOOTS IS UNDECLARED.
TMP, LINE 63: ERROR S09: VARIABLE I_HOVERBOOTS IS UNDECLARED.

pkmnfrk
01-03-2008, 09:32 PM
Tsk, tsk, import "std.zh", my friend.

I missed it from the tutorial, but, it should appear at the top of every .z file...

Joe123
01-03-2008, 09:33 PM
This is because you didn't tell ZC to import std.zh.

ComboAt is a utility routine, which turns a pixel reference number into coordinates for that pixel, and it's located in std.zh.

Also, why do you have Saffith's bool within your global script?

And how can you declare your own voids?

I don't think I understand voids very well...

pkmnfrk
01-03-2008, 09:37 PM
I beat you to it, but:

The "isSolid" script is used by my script. That's why it's there. I credited it to Saffith and beefster09 because I didn't write it.

As for it's location, it could be moved to the global namespace (i.e. outside of any script), but it's not that big a deal.

Joe123
01-03-2008, 09:42 PM
Damn, I didn't notice =P

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

zcAmazing
01-03-2008, 09:56 PM
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.

pkmnfrk
01-03-2008, 10:22 PM
Damn, I didn't notice =P

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

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.


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!


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.

Joe123
01-03-2008, 10:26 PM
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?

pkmnfrk
01-03-2008, 10:36 PM
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

Joe123
01-03-2008, 10:42 PM
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.

pkmnfrk
01-03-2008, 10:46 PM
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

Joe123
01-03-2008, 10:48 PM
So where does it tell it to go back?
Where the void ladder(){} ends?

pkmnfrk
01-03-2008, 10:50 PM
Yup.

Joe123
01-03-2008, 10:53 PM
Ah ok.

Thankyou very much, I've learnt quite a lot just now.

pkmnfrk
01-03-2008, 11:23 PM
Any time. It's quite confusing, but once you get it, quite rewarding ;)

Joe123
01-08-2008, 05:37 PM
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...

pkmnfrk
01-08-2008, 07:02 PM
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;
}

Joe123
01-08-2008, 07:03 PM
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 :)

zcAmazing
07-30-2008, 01:31 AM
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.

pkmnfrk
07-30-2008, 03:25 AM
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 (http://zctut.com/ladder.php).

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.

zcAmazing
07-30-2008, 05:07 PM
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.

pkmnfrk
07-30-2008, 05:13 PM
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 (http://zctut.com/ladder.php). 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...

zcAmazing
07-30-2008, 08:28 PM
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 (;) 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.

pkmnfrk
07-30-2008, 08:33 PM
Oh, shoot. I noticed that in my own script file, and thought I typed it in by accident after. I will fix it, though.

zcAmazing
07-30-2008, 08:43 PM
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 = true;
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.

zcAmazing
07-31-2008, 09:42 PM
Bumped to try to get attention. Editing a post doesn't make a bump, double-posting is. Since this post is in page 3, follow the link to the last post in page 2 where my edit is.

http://www.armageddongames.net/forums/showpost.php?p=1188346&postcount=50

Sorry about this...

Shazza Dani
01-01-2009, 05:52 PM
Can someone help—I have no idear how to use this script. The function call thing is confusing me.

Joe123
01-01-2009, 06:15 PM
http://www.purezc.com/forums/index.php?showtopic=38773

Shazza Dani
01-01-2009, 06:27 PM
*brain explodes* Okay… I'll read that later.

pkmnfrk
01-01-2009, 09:13 PM
Can someone help—I have no idear how to use this script. The function call thing is confusing me.

What, exactly, do you need help with?

Christian
01-02-2009, 12:33 AM
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.

Shazza Dani
01-02-2009, 01:45 AM
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.

pkmnfrk
01-02-2009, 02:17 AM
Read this page: http://zctut.com/start.php (which is conveniently located at the top of the ladder script page)

Christian
01-02-2009, 04:03 AM
isn't:

ladder(98);

the flag onto which you put on the ladder?

Shazza Dani
01-02-2009, 04:26 AM
Yeah, but I don't know where to put that in the code, or the global variables.

Christian
01-02-2009, 04:43 AM
You'd do it this way:



global script Slot_2{
void run(){
while(true){
//call the ladder function
ladder(98);
Waitframe();
}
}
}

global variablies and constants goes on top of the global script file, each variable ending in a semi-colon.

you can also change the variable 98 to any other flag number of your choice. you can only use flags 98 - 102 for now though.

pkmnfrk
01-02-2009, 02:09 PM
Doing the work for you:

import "std.zh"

//global variables go here
bool has_hover = false;
bool on_ladder = false;

global script onstart {
void run() {

//one time things go here

while(true) {

//function calls go here
ladder(98);

Waitframe();
}
}

//functions go here
//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;
}
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 = false;
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;
on_ladder = false;
}
}
}
}