PDA

View Full Version : Link's Awakening-Style Compass



SpacemanDan
05-11-2008, 01:26 PM
This is my first actual working script. It's simple, but I had to look all over the place to figure out how to do what. This script will play a sound effect when you enter the screen if you have a certain item. (In case you have something else in mind, you can set the item to whatever. Perhaps a trap detector to let you know there is a hidden trap on the screen?) As of now, I can't get it to work with the compass for a specific level, and I have no idea as to why it won't work with the compass. Any help?


//LA Compass
//This script will play a sound when you enter the screen
//and have a specific item.
//D0= Item Needed
//D1= Sound Played
import "std.zh"

ffc script la_compass
{
void run(int have_item, int sound)
{
if(Link->Item[have_item]) //Checks to see if Link has the item
{
Game->PlaySound(sound); //Plays the sound
Quit(); //End of Script
}
}
}

Enjoy! :D

Joe123
05-11-2008, 02:58 PM
Cause of the way ZC register the compass.
When it's on the screen, it's an item.
When it's in Link's invetory, it's a LItem.
So you have to use Game->LItems to check whether he has it or not.

ffc script la_compass{
void run(int h, int l, int s){
bool c;
if(s==0) s = 27;
if(h==0 && Game->LItems[l]&4 != 0) c = true;
if(h!=0 && Link->Item[h]) c = true;
if(c) Game->PlaySound(s);
}
}
Got a bit carried away sorry, I was just going to change your one to check for the compass, but now if you leave D0 blank it checks for the compass, and if you put a number in it checks for that item.

D0: item to check for (0 is compass)
D1: level number of current level (have to put that in if you're using the compass)
D2: sound to use (default is 27)



EDIT:

ffc script la_compass{
void run(int l,int s){
if(s==0) s=27;
Waitframes(4);
item i = Screen->LoadItem(1);
if(i->isValid() && Game->LItems[l]&4 != 0) Game->PlaySound(s);
}
}
D0: current level number
D1: sfx (default 27)

And if you use that one and there's a key as the screens item, it'll only play when you haven't picked up the key.
Won't work unless the key's there when the screen loads though.
Which I only just though about.
Which actually makes it pretty useless ¬_¬


Sorry for posting lots of scripts in your thread.
Boredom strikes again.

SpacemanDan
05-11-2008, 03:15 PM
Wow, I'm confused now. Could you explain the changes you did? I have no idea whats going on.
Still, thanks for adding to it so it works as intended. :D

Joe123
05-11-2008, 03:29 PM
Ah sorry, I was lazy when I wrote it before.


ffc script la_compass{
void run(int haveitem, int levelnum, int sfx){
bool checker;
if(sfx == 0) sfx = 27; //If D2 == 0, set the sfx to the secret sound by default

//haveitem == 0, so we're checking for the compass
if(haveitem == 0 && Game->LItems[levelnum] & LI_COMPASS != 0) checker = true;
//Game->LItems[levelnum]. That much means 'bring up the number for what level
//items Link has for the level 'levelnum'.
//It works in binary, and the 3rd bit of the byte is the compass, so we need to check if that's 1 or 0.
//We do that by 'anding' (&) the integer we get by calling 'Game->LItems' with LI_COMPASS (which is 4)
//If what we get isn't 0, then Link has the compass for the level 'levelnum'.
//the boolean is because of the dual function of the script.

//So if haveitem != 0, we want to check whether Link has the item 'haveitem' to see whether to play the sfx
if(haveitem !=0 && Link->Item[haveitem]) checker = true;

//And if one of the two statements above is true, checker will be true, and we can play the sound effect
if(checker) Game->PlaySound(sfx);
}
}

Noted up it should make more sense.
If you don't get the binary I can explain it a bit better?


I feel like I've 1-uped you abit, so sorry =(

SpacemanDan
05-11-2008, 03:42 PM
Ah, no problem. Thanks for explaining that. :D I'm not all too sure about binary, but it make sense to me now.

Joe123
05-11-2008, 04:01 PM
Well, let's take 'Game->LItems[foo];'.

If we pass that through ZC, it brings up a 5 bit byte, 00000b.
Now, each bit of that byte correspondes to an LItem, so you could think of it like an array of 5 booleans.
A bit like this:
Boss Key,Boss,Compass,Map,Triforce.

The 'Boss' one is whether Link has killed the dungen's boss, and the other ones are if he has the items for the level 'foo'.

So if we run 'Game->LItems[foo];' and get '10101', then for the level 'foo', Link has the Boss Key, Compass and Triforce Piece, but he hasn't killed the dungeon's boss or got the map.

Then you need the 'Binary And' tool.
Let's take two bytes.

int foo = 0011b;
int bar = 0101b;

We want to compare these two bytes together, to see which bits are the same in the two bytes.
This is 'and' or '&' in C++.


return foo & bar;

So if we do that, we get a little 'sum'.


foo|0011
bar|0101
--------
&|0001

As you can see, the only bit that's the same in both of them is the last bit.
So when we 'and' them together, the product is '0001', or just '1' in decimal.

So then if we take Game->LItems[foo], which happens to be '10101' again (just as an example), and LI_COMPASS, which is always '00100', and and them together:


Game->LItems[foo]|10101
LI_COMPASS|00100
-----------------------
&|00100

So all of the other bits are ignored, because they're '0' in LI_COMPASS, and we just check the compass bit.
If we then check that the response is not 0 in the if statement, we can see whether Link has the compass or not.

If Link doesn't have the compass...

Game->LItems[foo]|10001
LI_COMPASS|00100
-----------------------
&|00000

Then the response will be 0.


LI_COMPASS in decimal is '4', so that's why it's 'Game->LItems[l]&4' in the first script.