PDA

View Full Version : Antigrav Flags for Sidescrolling



CJC
05-15-2008, 07:58 PM
I'm looking for a flag I can place in side-scroll screens to make Link ignore gravity (So he can walk up gentle slopes and climb ladders). I get the guts of the flag code, but I have no idea how to disable gravity in side-scrolling screens.



const int flag = 100;

ffc script antigrav{
void run(){
while(true){
if(Screen->ComboF[ComboAt(Link->X,Link->Y)] == flag || Screen->ComboI[ComboAt(Link->X,Link->Y)] == flag){
//I have absolutely no idea what to put here.
}
Waitframe();
}
}
}

Help!


EDIT:
This is the final code



import "std.zh"

const int ladderflag = 100;

ffc script ladder{
void run(int speed, int combotype , int dummy){
int framedelay;
int lc;
if(combotype == 0){combotype = 11;}
if(speed == 0){speed = 1;}
while(true){
lc = ComboAt(Link->X+8, Link->Y+15);
if(Screen->ComboF[lc] == ladderflag || Screen->ComboI[lc] == ladderflag){
if(Link->Jump < 0) Link->Jump = 0;
if(Link->InputDown && !isSolid(Link->X, Link->Y+16)) Link->Y += 1;
if(Link->InputUp && !isSolid(Link->X, Link->Y - 1)) Link->Y -= 1;
//[[Sets up the antigravity effect]]
if(!Link->Item[130]){ Link->Item[130] = true;}
if(Link->InputLeft && Link->Dir == 2){
if(framedelay == 3){Link->X = Link->X+1; framedelay = 0;}
else{framedelay++;}
}
if(Link->InputRight && Link->Dir == 3){
if(framedelay == speed){Link->X = Link->X-1; framedelay = 0;}
else{framedelay++;}
}
if(Link->InputUp && Link->Dir == 0){
if(framedelay == speed){Link->Y = Link->Y+1; framedelay = 0;}
else{framedelay++;}
}
if(Link->InputDown && Link->Dir == 1){
if(framedelay == speed){Link->Y = Link->Y-1; framedelay = 0;}
else{framedelay++;}
}
Link->InputA = false;
Link->InputB = false;
Link->InputL = false;
}else{if(Link->Item[130]){ Link->Item[130] = false;}
}
Waitframe();
}
}
}
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;
return (!(Screen->ComboS[ComboAt(x, y)]&mask)==0);
}


It uses an FFC slot (Which should be hidden and invisible in the corner of desired screens) and flag 100. Big thanks to Joe and C-Dawg for making this possible

Joe123
05-16-2008, 06:37 AM
http://zctut.com/ladder.php

C-Dawg
05-16-2008, 09:22 AM
I would think all you have to do is:

if(!Link->InputDown){Link->Y = last_y_location;}

then at the very end of your while loop:

last_y_location = Link->Y;

Unless, of course, Link falls faster than he walks. In which case you'd need to make your own walking down code to change the speed.

CJC
05-16-2008, 06:09 PM
Last_y_location would be an integer variable right? (That I define at the top of the code?) Or wait... it's probably a pre-established command for Zscript.


I do believe that he falls faster than he walks, though, because when I placed a conveyor-up combo to attempt non-scripted antigravity, he spasmed on the combo instead of floating up. Still, I'll try both your simple flag and (if necessary) the complex ladder flag. I'll edit this post with my findings.



const int flag = 100; //Sets custom flag 100 to antigrav flag

ffc script antigrav{
void run(){
while(true){
if(Screen->ComboF[ComboAt(Link->X,Link->Y)] == flag || Screen->ComboI[ComboAt(Link->X,Link->Y)] == flag){
if(!Link->InputDown){
Link->Y = last_y_location;
}
}
last_y_location = Link->Y;
Waitframe();
}
}
}

Let's hope this works!

EDIT: The above quoted code did not work. I did some modification to it, and came up with the following code.




import "std.zh"

const int flag = 99;

ffc script antigrav{
int last_y_location;
void run(){
while(true){
last_y_location = 64;
if(Screen->ComboF[ComboAt(Link->X,Link->Y)] == 99 || Screen->ComboI[ComboAt(Link->X,Link->Y)] == 99){
Link->InputL = false;
if(!Link->InputDown){
Link->Y = last_y_location;
}
}
Waitframe();
last_y_location = Link->Y;
}
}
}


I set an integer value for the first last_y_location because it did not function when I logged it as "last_y_location = Link->Y". Unfortunately, this code now causes Link to leap to the top of the antigrav-flag and spasm (In the last frame of his jump animation) until you move out of the flag. It also unlocks my "L" button, which screwed up my jump script. I tried to fix that within the parameters of the flag (As is visible), but it did not function.

It's neat as a Link launcher, but I don't know how to make it work practically. I'm going to test the other script now.

Joe123
05-16-2008, 07:34 PM
...

A much easier method is to put 'if(Link->Jump < 0) Link->Jump = 0;'
inside your flag checking if.

Which is what's done in that script which I posted already....

CJC
05-16-2008, 08:43 PM
I gave up on the ffc antigrav flag code, and used the one you provided Joe (I had to mod the code to include the "L button Jump" script I downloaded).

It seems to work pretty well, but when moving up-left or up-right with Link at the bottom edge of the highest flag, he gets stuck in an upward motion and cannot be dislodged. Could this be related to the large hitbox? And if so, is it possible to prevent movement off the top of the flag?


Somewhere in the voidladder function, near the input up?



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;
}
}
}

}


I'm thinking something along the lines of another flag check, or a flag false check. Would that work? (I need to prohibit movement off of the antigravity flag in the upward direction).

Joe123
05-16-2008, 08:50 PM
Ohh, you wanted it to be an ffc script?

Sorry, I didn't really think.


const int ladderflag = 100;

ffc script ladder{
void run(){
int l;
while(true){
l = ComboAt(Link->X+8, Link->Y+15);
if(Screen->ComboF[lc] == ladderflag || Screen->ComboI[lc] == ladderflag){
if(Link->Jump < 0) Link->Jump = 0;
if(Link->InputDown && !isSolid(Link->X, Link->Y+16)) Link->Y += 1;
if(Link->InputUp && !isSolid(Link->X, Link->Y - 1)) Link->Y -= 1;
}
Waitframe():
}
}
}

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;
return (!(Screen->ComboS[ComboAt(x, y)]&mask)==0);
}

That'd be how I'd do it.


And you want to make it so Link can't walk off the top of the flag?
Why?

CJC
05-16-2008, 09:04 PM
Because I am experiencing a glitch with the global version of that script that occurs when Link moves at a non-orthogonal angle off the top of the flag.

By which I mean, if I hold up and a sideways direction simultaneously as he moves off the top flag, the gravity constant traps him and I have to reset the quest to escape it. This may be related to my rejection of Z3 style movement, but I can't proove that.

Because I am uncertain what is causing the glitch, (And since I can just add the same flag one space above the peak of the ladder and then have the player disengage it horizontally, I figured it would be the easiest solution.)

EDIT: I'm going to use the FFC version you wrote in combination with that ladder climb animation script to set up a different flag for ladders (Seperate from the antigrav which is for hills). If it works, I'll post the code here.



import "std.zh"

const int ladderflag = 100;

ffc script ladder{
void run(int speed, int combotype , int dummy){
int framedelay;
int lc;
if(combotype == 0){combotype = 11;}
if(speed == 0){speed = 1;}
while(true){
lc = ComboAt(Link->X+8, Link->Y+15);
if(Screen->ComboF[lc] == ladderflag || Screen->ComboI[lc] == ladderflag){
if(Link->Jump < 0) Link->Jump = 0;
if(Link->InputDown && !isSolid(Link->X, Link->Y+16)) Link->Y += 1;
if(Link->InputUp && !isSolid(Link->X, Link->Y - 1)) Link->Y -= 1;
//[[Sets up the antigravity effect]]
if(!Link->Item[130]){ Link->Item[130] = true;}
if(Link->InputLeft && Link->Dir == 2){
if(framedelay == 3){Link->X = Link->X+1; framedelay = 0;}
else{framedelay++;}
}
if(Link->InputRight && Link->Dir == 3){
if(framedelay == speed){Link->X = Link->X-1; framedelay = 0;}
else{framedelay++;}
}
if(Link->InputUp && Link->Dir == 0){
if(framedelay == speed){Link->Y = Link->Y+1; framedelay = 0;}
else{framedelay++;}
}
if(Link->InputDown && Link->Dir == 1){
if(framedelay == speed){Link->Y = Link->Y-1; framedelay = 0;}
else{framedelay++;}
}
Link->InputA = false;
Link->InputB = false;
Link->InputL = false;
}else{if(Link->Item[130]){ Link->Item[130] = false;}
}
Waitframe();
}
}
}
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;
return (!(Screen->ComboS[ComboAt(x, y)]&mask)==0);
}


This is what I came up with. It should work, but for some reason ZQuest tells me that function "ComboAt" is undefined. So far it's worked in my Link Launcher antigrav script, so what's the problem here?

EDIT: It needed Import "std.zh", updated. The script works perfectly now, thank you. I'm going to edit it into the first post.

Joe123
05-17-2008, 05:04 AM
Heh, I wrote pretty much that exact script once before.

Glad you have it working though :thumbsup: