PDA

View Full Version : Magnetic Gloves



pkmnfrk
07-30-2008, 04:03 AM
Magnetic Gloves (http://zctut.com/magnagloves.php) -- Now with iron balls and rotating poles! (not as dirty as it sounds!)

Everything you need to know is on the above page. Enjoy ;)

lucas92
07-30-2008, 01:14 PM
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;

What is mask useful for?

btw, awesome script, it must have took a long time to think about it, and making it work. :D

pkmnfrk
07-30-2008, 02:29 PM
Well, it's used in the first half of a script that checks passability at a given point.

Screen->ComboS[] stores the passability of every combo on the screen as a bitset. That is, a fully impassable tile is 1111b, and a fully walkable one is 0000b. One that's half walkable is 1010b, 0101b or some other value that's half-on, half-off. Check zscript.txt for details.

If you work out the math, you'll see that each if block is checking "top-half, or bottom?" and "left or right?", and &ing the appropriate masks together, so that at the end, only one bit is left one, the one we want to check.

This particular function was not actually written by me, as I am not that clever. You have Saffith and beefster09 to thank for it.

The rest of it, of course, is all mine. :)

The_Amaster
08-01-2008, 02:36 PM
I'm having trouble figuring out what goes where in your global template. If I've got it right, is it as follows?



import "std.zh"

//global variables go here
bool magna_gloves_active = false;
bool magna_gloves_positive = false;

const int magna_flag = 99;
const int magna_positive = 144;

global script onstart {
void run() {

//one time things go here

while(true) {

//function calls go here
if(magna_gloves_active) MagnaGlovesWork();

Waitframe();
}
}

//functions go here
Big long magna glove script here
}

Shoelace
08-01-2008, 03:02 PM
That is awesome! I have been asking for a very long time as I want to put it in EotM. But the only thing is the puzzle ideas I had for it was to be able to move the 'Magnetic' things in the room. So hopefully that will be scripted too, as I would use that one for sure.

pkmnfrk
08-01-2008, 03:18 PM
I'm having trouble figuring out what goes where in your global template. If I've got it right, is it as follows?



import "std.zh"

//global variables go here
bool magna_gloves_active = false;
bool magna_gloves_positive = false;

const int magna_flag = 99;
const int magna_positive = 144;

global script onstart {
void run() {

//one time things go here

while(true) {

//function calls go here
if(magna_gloves_active) MagnaGlovesWork();

Waitframe();
}
}

//functions go here
Big long magna glove script here
}


That is correct.


That is awesome! I have been asking for a very long time as I want to put it in EotM. But the only thing is the puzzle ideas I had for it was to be able to move the 'Magnetic' things in the room. So hopefully that will be scripted too, as I would use that one for sure.

I'm nearly done that, and the rotating version of the pole you see in Oracle of Seasons. I'm just ironing out a few collision detection issues.

pkmnfrk
08-12-2008, 03:09 AM
Ding! The script has been updated with roughly 12000 kilojoules of pure awesome!

Iron Balls - for killing monsters, with sexy results!
Rotating poles - more complex movement puzzles, with sexy results!
Soon, buttons which react to the balls, with sexy results!

(although, the buttons will be in a separate thread, since they're used for more than just magnetic glove puzzles)

Shoelace
08-20-2008, 04:25 AM
Awesome, Thank you so much! I have one question though. I am sort of new at the scripting but, say I am was planning on using both the bombchu and the Magnetic Gloves in my game. Well I was reading about global scripts, and I saw that the bombchu uses #2 and #3 slots for it to work. And the Magnetic Gloves, I didn't see a number on it. Would I be able to put both of them in my game?

Either way, I can't wait to see how the buttons will react to the Iron Balls script thing. As that is basically what I want to use the Magnetic Gloves for. That is where all of my puzzle ideas come into play. :)

Joe123
08-20-2008, 05:48 AM
You have to compile both of the scripts into the same global script.
Someone'll do it for you if you ask nicely I'm sure.

Shoelace
08-20-2008, 12:51 PM
Ah okay, thanks Joe123, I will probably ask someone then. But I won't right now as the script may change because he is still adding the button with the Iron Ball script. So I wait until after that. I am glad it will work though. :)

pkmnfrk
08-20-2008, 03:01 PM
Check out this page about global scripts (http://zctut.com/start.php) for information on how to combine them.

I wish more people used my template for writing their global scripts, since everyone has to play along, but it should be easy to combine.

In a nutshell, you need to paste all the functions (except main) below the main in the bombchu script. You also need to paste a single line somewhere in the bombchu script's "while(true)" loop (if it has one):


if(magna_gloves_active) MagnaGlovesWork();

And, the global variables/constants go at the very top.

Joe123
08-20-2008, 03:11 PM
I wish more people used my template for writing their global scripts

I tried doing it like that, putting everything into a seperate void, but I found that I had lots of variables crossing over which I'd then have to declare globally and things, and in the end I decided it was too much hassle for not enough gain.

pkmnfrk
08-20-2008, 03:14 PM
Well, take a look at how I did my script. Essentially, I just took everything that was in the while(true) loop, and plopped it into a separate function. That way, the main loop (which is public property) stays neat and clean, while retaining the ability to do whatever I want in my private property. That's what I advocate.

Joe123
08-20-2008, 06:58 PM
I know, that's what I did.
But if I then want variables to use in two different voids in the same global script, I can't declare them at script-scope, I have to declare them at global scope.
I didn't want to do that :shrug:

pkmnfrk
08-20-2008, 07:01 PM
Well, that's also what I did.

But, you know you can also pass parameters to functions, right?




void Foo() {
Bar(1);
}

void Bar(int a) {
Trace(a);
}

Joe123
08-20-2008, 07:08 PM
I do.

pkmnfrk
08-20-2008, 07:11 PM
Well, then, someone's not understanding what the other person is saying.

I'll take a look at your script, and see if I can fix it to fit in the template. In a few minutes.

Joe123
08-20-2008, 07:14 PM
ffc script example{
void run(){
int i;
npc e[10];
Waitframes(4);
LoadEnemies();
while(true){
for(i=0;i<10;i++) e[i]->Jump = 0;
Waitframe();
}
}
void LoadEnemies(){
for(i=0;i<10;i++) npc e[i] = Screen->LoadNPC(i+1);
}
}

Something like that for example wouldn't compile, because the npc and the integer are both declared only in void run, but not in void LoadEnemies.
Passing an integer into a void as a parameter is one thing, but I can't exactly pass in an array of enemies, can I?

pkmnfrk
08-20-2008, 07:33 PM
I dunno. I haven't tried using arrays for anything yet.

But, anyway, I'm going over your script, and I'm already noticing a few problems. In a few places, you have loops inside the while() loop that will, while running, prevent other global scripts (such as my magna gloves script) from working.

Let me finish going over it, and I'll show you how to best set it up.

pkmnfrk
08-20-2008, 08:24 PM
import "std.zh"

const int bombchuflag = 98; //Flag the bombchu can pass through (even if solid)
const int bombchutile = 21752; //Set the tile for your weapon here. Up, Down, Left, Right it should be on the tilepage.
const int bombchuframes = 2; //Set the number of animation frames here.
const int bombchuaspeed = 10;//Set the animation speed here
const int bombchucset = 7; //Set the CSet here

const int bombchudmg = 2; //Set the damage here
const int bombchuspeed = 1; //Set the speed of the bombchu here

int bombchuattack = 0;
int bombchux = 0;
int bombchuy = 0;
int bdir = 0;

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

bool bombchucheck(int x, int y){
if((isSolid(x,y) && Screen->ComboF[ComboAt(x,y)] != bombchuflag && Screen->ComboI[ComboAt(x,y)] != bombchuflag)
|| (Screen->ComboF[ComboAt(x,y)] == 6 || Screen->ComboI[ComboAt(x,y)] == 6 ||Screen->ComboF[ComboAt(x,y)] == 11 || Screen->ComboI[ComboAt(x,y)] == 11)) return true;
}

void noaction(){
Link->InputR = false;
Link->InputL = false;
Link->InputA = false;
Link->InputB = false;
Link->InputUp = false;
Link->InputDown = false;
Link->InputRight = false;
Link->InputLeft = false;
}

global script slot_2{
void run(){

while(true){
if(bombchuattack == 2) run_bombchu();
if(bombchuattack == 1) start_bombchu();
Waitframe();
}
}

void run_bombchu() {
lweapon bombchu;
lweapon explosion;
int HP = 0;
bool found = false;
for(int i = 1; i <= Screen->NumLWeapons(); i+= 1) {
bombchu = Screen->LoadLWeapon(i);
if(bombchu->ID == LW_SCRIPT1) {
found = true;
HP = Link->HP;
if(Link->InputUp) bdir = 0;
if(Link->InputDown) bdir = 1;
if(Link->InputLeft) bdir = 2;
if(Link->InputRight) bdir = 3;
if(bdir == 0 && bombchucheck(bombchu->X+8,bombchu->Y+4)
|| (bdir == 1 && bombchucheck(bombchu->X+8,bombchu->Y+12))
|| (bdir == 2 && bombchucheck(bombchu->X+4,bombchu->Y+8))
|| (bdir == 3 && bombchucheck(bombchu->X+12,bombchu->Y+8))) bombchu->DeadState = 0;
bombchu->Dir = bdir;
bombchu->Tile = bombchutile+(bdir*bombchuframes);
bombchu->OriginalTile = bombchutile+(bdir*bombchuframes);
bombchux = bombchu->X;
bombchuy = bombchu->Y;
noaction();
if(Link->HP < HP) bombchu->DeadState = 0;
break;
}
}

if(found == false) {
explosion = Screen->CreateLWeapon(LW_SBOMB);
explosion->Damage = bombchudmg;
explosion->X = bombchux;
explosion->Y = bombchuy;

Link->Action = 0;
bombchuattack = 0;

}
}

void start_bombchu() {
if(Link->X > 15 && Link->X < 241 && Link->Y > 15 && Link->Y < 153){
lweapon bombchu = Screen->CreateLWeapon(LW_SCRIPT1);
bdir = Link->Dir;
bombchu->OriginalTile = bombchutile+(bdir*bombchuframes);
bombchu->Tile = bombchutile+(bdir*bombchuframes);
bombchu->NumFrames = bombchuframes;
bombchu->ASpeed = bombchuaspeed;
bombchu->CSet = bombchucset;
bombchux = 0; bombchuy = 0;
if(bdir>1) bombchux = (((bdir-2)*2)-1)*16;
if(bdir<2) bombchuy = ((bdir*2)-1)*16;
bombchu->X = Link->X+bombchux;
bombchu->Y = Link->Y+bombchuy;
bombchu->Step = bombchuspeed;
Link->Action = LA_ATTACKING;
Game->Counter[6]--;
bombchuattack = 2;
}else{
bdir = Link->Dir;
bombchux = 0; bombchuy = 0;
if(bdir>1) bombchux = (((bdir-2)*2)-1)*16;
if(bdir<2) bombchuy = ((bdir*2)-1)*16;
lweapon explosion = Screen->CreateLWeapon(LW_SBOMB);
explosion->X = Link->X+bombchux;
explosion->Y = Link->Y+bombchuy;
explosion->Damage = bombchudmg;
Link->Action = 0;
bombchuattack = 0;
}
}
}

global script slot_3{
void run(){
bombchuattack = 0;
}
}

item script bombchu{
void run(){
if(Game->Counter[6] > 0) bombchuattack = 1;
}
}

I changed a few things:

* I turned all the variables you didn't want to be globals into globals, and made them constant. That's how you should do it.
* For the ones I didn't make constant, I still had to move them out. There's no two ways about it.
* I split the main script into two different scripts: start_bombchu(), which creates the bombchu, and run_bombchu() which handles its movement and death.
* I changed bombchuattack from a bool to an int, so that the main loop knows which script to call. Check run() to see what I did.
* I also made use of the LW_SCRIPT1 constant.

Joe123
08-21-2008, 02:32 PM
Hrm ok.
You've changed quite a lot.

I can see how it's better though.

If I'dve been organising it to run along-side another global script, I'dve changed the while parts into ifs so that it all ran on the same waitframe.
But fair enough.

Rastael
11-29-2010, 07:45 AM
Hi,
very good script. ^^
But I still have some troubles...

1.) I want to use it with the "A"-button too. How can I do it?
2.) When I use the ffc-Ironball-script, there is always Link's head in cset2 on the Ironball, when I push or pull the Ironball with thew gloves. Anybody know why?