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

Roll Script. MC style... sort of.

17 replies · 10,180 views · Started 13 August 2007

import "std.zh"

bool isSolid(int x, int y) {

// x=23, y=130
// Obviously in range...
if(x<0 || x>255 || y<0 || y>175)
return false;
int mask=1111b;

// x &#37; 16 = 7, so
// mask = 1111 & 0011 = 0011
if(x%16<8)
mask&=0011b;
else
mask&=1100b;

// y % 16 = 2, so
// mask = 0011 & 0101 = 0001
if(y%16<8)
mask&=0101b;
else
mask&=1010b;

// All but the top-right quarter of the combo is solid, so ComboS = 1011
// mask & ComboS = 0001 & 1011 = 0001
// The result wasn't 0, so return false
return (!(Screen->ComboS[ComboAt(x, y)]&mask)==0);

}

global script roll {

void run() {

int counter;
bool justRolled = false;
int DustTile = 20; //the starting animation tile of the 5-frame dust animation.
int DustCSet = 7; //the CSet of the tile animation.
int xca; int xcb; int xcc; int xcd; int xce;
int yca; int ycb; int ycc; int ycd; int yce;
int DustFrame;

while(true) {

if(Link->InputL && Link->Action == LA_WALKING) {

Link->Jump = 2;
counter = 20;
DustFrame = 1;
xca = -1;
xcb = -1;
xcc = -1;
xcd = -1;
xce = -1;
yca = -1;
ycb = -1;
ycc = -1;
ycd = -1;
yce = -1;
Game->PlaySound(66); //Change/Disable SFX if needed

while(counter > 0) {

Link->Z = 0;
Link->InputUp = false;
Link->InputDown = false;
Link->InputLeft = false;
Link->InputRight = false;
Link->InputA = false;
Link->InputB = false;
Link->InputR = false;
Link->InputL = false;

if(Floor(counter/2) == counter/2) { //trigger animation every other frame

xce = xcd;
xcd = xcc;
xcc = xcb;
xcb = xca;

yce = ycd;
ycd = ycc;
ycc = ycb;
ycb = yca;

xca = Link->X;
yca = Link->Y;

if(DustFrame >= 5) {

xca = -1;
yca = -1;

}

DustFrame ++;

}

if(!(xca == -1) && !(yca == -1)) {Screen->DrawTile(2, xca, yca, DustTile, 1, 1, DustCSet, 1, 0, 0, 0, 0, true, 128);}
if(!(xcb == -1) && !(ycb == -1)) {Screen->DrawTile(2, xcb, ycb, DustTile + 1, 1, 1, DustCSet, 1, 0, 0, 0, 0, true, 128);}
if(!(xcc == -1) && !(ycc == -1)) {Screen->DrawTile(2, xcc, ycc, DustTile + 2, 1, 1, DustCSet, 1, 0, 0, 0, 0, true, 128);}
if(!(xcd == -1) && !(ycd == -1)) {Screen->DrawTile(2, xcd, ycd, DustTile + 3, 1, 1, DustCSet, 1, 0, 0, 0, 0, true, 128);}
if(!(xce == -1) && !(yce == -1)) {Screen->DrawTile(2, xce, yce, DustTile + 4, 1, 1, DustCSet, 1, 0, 0, 0, 0, true, 128);}

if(Link->Dir == DIR_UP) {

if(!isSolid(Link->X+4, Link->Y+6) && !isSolid(Link->X+12, Link->Y+6) && (Screen->ComboF[ComboAt(Link->X+8, Link->Y+6)] != 98)) {Link->Y -= 2;}

} else if(Link->Dir == DIR_DOWN) {

if(!isSolid(Link->X+4, Link->Y+18) && !isSolid(Link->X+12, Link->Y+18) && (Screen->ComboF[ComboAt(Link->X+8, Link->Y+18)] != 98)) {Link->Y += 2;}

} else if(Link->Dir == DIR_LEFT) {

if(!isSolid(Link->X-2, Link->Y+12) && (Screen->ComboF[ComboAt(Link->X-2, Link->Y+4)] != 98)) {Link->X -= 2;}

} else if (Link->Dir == DIR_RIGHT) {

if(!isSolid(Link->X+18, Link->Y+12) && (Screen->ComboF[ComboAt(Link->X+18, Link->Y+4)] != 98)) {Link->X += 2;}

} //end if

counter --;
justRolled = true;

Waitframe();

} //end while

} //end if

if(justRolled) {

Link->Jump = 0;
justRolled = false;

}

Link->InputL = false;

Waitframe();

} //end while

} //end void run

} //end script

Notes:

*It's a global script, so there are no parameters and it cannot be disabled without another script.
*By default, L is used to roll. To change it, replace InputL with InputR and vice-versa.
*It is customizable by the options at the top. You can change the CSet and Starting dust "kick up" tile. You can also change the sound effect. It is SFX #66 by default.
*You can roll through layers if you don't mark them with flag 98.
*Mark anything you don't want roll-onto-able on layer 0 with flag 98. G'head. Use it. That's what the general purpose flags are for!
*You can roll over warps, so be careful with cutscenes by marking the tiles ahead of the pits/warps with flag 98s.
*You need jump tiles for this to work. And your jump tiles must be of the rolling variety.
[SIZE="1"]*As of now, the collision detection isn't very accurate, so if there is any unwalkable part of the tile, you cannot roll through it.[/SIZE] This is no longer true. It now goes down to the quarter-combo.
*It really is a psudo-roll. You actually do a jump that brings you to Z = 0 each frame and moves you forward if possible.
*You'll probably want the "poof" tiles or similar for the dust "kick up."
*the dust "kick up" is at a fixed 5-frame animation. If you want more frames, you'll have to edit the script. If you want less, leave blanks at the end of the animation
*You can't perform anything else during a roll.
*I forgot to mention this before, but it is designed for the smaller Link hitbox. To enable it for the large hitbox, change the +6s to -2s on the up rolling fork and add [FONT="Fixedsys"]!isSolid(Link->X-2, Link->Y+4)[/FONT] to the left fork and [FONT="Fixedsys"]!isSolid(Link->X+18, Link->Y+4)[/FONT] to the right DIR fork.

EDIT: Due to the new allocation of general purpose flags I changed flag 97 to flag 98! Thankfully, I don't have a whole lot to change in AMN to make it consistent. You WILL have to painstakingly change every last flag 97 to a flag 98. With the improved collision detection, it is now sensitive down to the quarter-combo!

This script works nicely! It's official. It's a scripting revolution! Anyway thanks for the script Beefster!

Right. Time for the person with no scripting experiance to ask a question...

How do I actually set it up?

So far I've gone to Scripts->Compile ZScript, imported then compiled and assigned it to one of my three Global slots. Now what do I do?

That should do it.. Maybe get the newest version of the script. You might have grabbed it before I edited it to be correct.

No I grabbed the most recent one. I just assumed it was more comlicated then that, and never tested it. I'll see if that works.

If you're using this script, you may find it useful to accompany it with this one:

ffc script disable_roll{
void run(){
while(true){
Link->InputL = false;
Waitframe();
}
}
}

Which stops you from using it on a screen when you don't want it to be used, courtesy of Matthew at purezc.

I updated it to deal with the new flag standards, I fixed a bug, and improved the collision detection similarly to Saffith's CanMove function. (I actually copy-pasted it and negated the return value) Enjoy while I bump this.

Oh dear, now Link doesn't roll for long enough, so it only plays the first tile of the jump animation and looks like he's doing some funny headbutt or something. Could you make it go for a bit longer please? I can't seem to fathom how it works at all.

It shouldn't have anything to do with my script... It should work fine. Talk to a dev. In the meantime, I'll check the code. I gotta go to bed since I have to wake up at the buttcrack of dawn, otherwise I'd do it now.

				//if(!(xca == -1) && !(yca == -1)) {Screen->DrawTile(2, xca, yca, DustTile, 1, 1, DustCSet, 1, 0, 0, 0, 0, true, 128);}
//if(!(xcb == -1) && !(ycb == -1)) {Screen->DrawTile(2, xcb, ycb, DustTile + 1, 1, 1, DustCSet, 1, 0, 0, 0, 0, true, 128);}
//if(!(xcc == -1) && !(ycc == -1)) {Screen->DrawTile(2, xcc, ycc, DustTile + 2, 1, 1, DustCSet, 1, 0, 0, 0, 0, true, 128);}
//if(!(xcd == -1) && !(ycd == -1)) {Screen->DrawTile(2, xcd, ycd, DustTile + 3, 1, 1, DustCSet, 1, 0, 0, 0, 0, true, 128);}
//if(!(xce == -1) && !(yce == -1)) {Screen->DrawTile(2, xce, yce, DustTile + 4, 1, 1, DustCSet, 1, 0, 0, 0, 0, true, 128);}

Why not just comment them out (with //)for optimization purpose.

I put the script in, and it appears there is a silhouette of Link behind the rolling animation.

That's because you didn't set the values rights. See at the top where is has Dusttile and cset equals some number? Change those numbers to equal the tile for the dust, and the cset it's in.

Hi,
the script works good, but my problem is that Link moves forward without a rolling-animations. (I can see Link, the Dust, but no rolling-animation).
Can anybody help me?

(I'm using the newest windows-build, actually 1330)