PDA

View Full Version : Checking for integers and floats....



Nimono
01-17-2007, 04:49 PM
One final question from me! And please, don't ask me why I made a new thread...

Okay, in my Cane of Somaria script, I've declared a variable called "SomariaCheck". Every time you change the settings of the combo two tiles away from you, a 1 is written to this variable. At the beginning of the script, it first checks for the solidity of the combo at the Block's position. If it comes back as 15 (in decimal- That'd be 1111 in binary, which is total solidity), it then checks the value of SomariaCheck. If it's a 1, it modifies the block to remove it and it then sets SomariaCheck to 0. The problem is, since I need to use that at the start of my script so it doesn't destroy a block right after I create one, I needed to declare that variable at runtime. Unfortunately, it seems to ignore that value. When I declare a variable in void run(), does it automatically set it to 0? If so, what can I do to avoid this? Telling me to not use another variable isn't going to work- I declare 4 variables at runtime- SomariaBlockX, SomariaBlockY, SomariaBlockPosition, and SomariaCheck. The first two are because I don't need to write anything to them at first. The second two are there because I use them both in the code for checking for a block. So, what's going on? Do those variables simply become 0 whenever the code ends? Would writing to d0-7 be better?

Saffith
01-17-2007, 05:12 PM
If it comes back as 15 (in decimal- That'd be 1111 in binary, which is total solidity), it then checks the value of SomariaCheck. If it's a 1, it modifies the block to remove it and it then sets SomariaCheck to 0. The problem is, since I need to use that at the start of my script so it doesn't destroy a block right after I create one, I needed to declare that variable at runtime.Technically, you're declaring them well before run time.
If you only need two different values, corresponding roughly to "yes" and "no," you might use a bool instead of a number. A bit more logical, and easier to change: you can just write SomariaCheck = !SomariaCheck; instead of going through an if/else or an equation. That's not too important, though.


When I declare a variable in void run(), does it automatically set it to 0? If so, what can I do to avoid this?I don't know if it does, actually, but I don't see why it would matter. Not unless you're planning to use an uninitialized variable for something, which is pretty much never a good idea.
If you're just trying to set the starting value, initialize it when you declare it, like this:

int x = 5;


So, what's going on? Do those variables simply become 0 whenever the code ends? Would writing to d0-7 be better?Don't know. Probably not. But what difference does it make? If it's finished with the code, you can't use the variables anymore, anyway.
You can't use d0-d7. There's no way to access them directly in ZScript.

Nimono
01-17-2007, 05:17 PM
Technically, you're declaring them well before run time.
If you only need two different values, corresponding roughly to "yes" and "no," you might use a bool instead of a number. A bit more logical, and easier to change: you can just write SomariaCheck = !SomariaCheck; instead of going through an if/else or an equation. That's not too important, though.

I don't know if it does, actually, but I don't see why it would matter. Not unless you're planning to use an uninitialized variable for something, which is pretty much never a good idea.
If you're just trying to set the starting value, initialize it when you declare it, like this:

int x = 5;

Don't know. Probably not. But what difference does it make? If it's finished with the code, you can't use the variables anymore, anyway.
You can't use d0-d7. There's no way to access them directly in ZScript.
It figures. :p

So what exactly does SomariaCheck = !SomariaCheck; do, anyways? But wouldn't I still need to do an if statement? It's supposed to do one thing if it's equal to a certain thing and not do that if it's not equal. ...Oh well. You understand this more than me. :p

Saffith
01-17-2007, 05:24 PM
Well, I'm assuming it's a bool there. Bools can be either true or false. The exclamation point is the NOT operator: !true is false, and !false is true. So, if SomariaCheck is a bool, that line has the same effect as this:

if(SomariaCheck == true) // You could also just write if(SomariaCheck)
SomariaCheck = false;
else
SomariaCheck = true;

That's only if it's a bool, though. You can't do that with numbers.

Nimono
01-17-2007, 05:34 PM
So, let's say I was to do something like Link->InputUp = true. If I used SomariaCheck = !SomariaCheck, would it look like this:



SomariaCheck = !SomariaCheck;
Link->InputUp = true;

Or would I use something else? (Please bear with me- I'll remember this for a while once I get it, trust me.)

Saffith
01-17-2007, 05:44 PM
I'm not certain I see what you're asking, but that bit of code looks perfectly fine.

Nimono
01-17-2007, 05:49 PM
I'm not certain I see what you're asking, but that bit of code looks perfectly fine.

Let me put it another way... If I was to use SomariaCheck as a bool instead of a number, at places I'd normally use if/else statements for numbers, I'd use SomariaCheck = !SomariaCheck instead of if (SomariaCheck = 1)?

Saffith
01-17-2007, 05:57 PM
SomariaCheck = !SomariaCheck will change the value from true to false or from false to true. It won't do anything else that would otherwise require an if/else.

SomariaCheck = !SomariaCheck;
Link->InputUp = true;
is equivalent to

if(SomariaCheck == true)
SomariaCheck = false;
else
SomariaCheck = true;

Link->InputUp = true;

Nimono
01-17-2007, 06:07 PM
SomariaCheck = !SomariaCheck will change the value from true to false or from false to true. It won't do anything else that would otherwise require an if/else.

SomariaCheck = !SomariaCheck;
Link->InputUp = true;
is equivalent to

if(SomariaCheck == true)
SomariaCheck = false;
else
SomariaCheck = true;

Link->InputUp = true;

....Okay, then that's not exactly what I need. Here's the basic excerpt of code that does all that for only letting one block on screen at a time:


if (SomariaCheck ==1)
{
if (Screen->ComboS [SomariaBlockPosition] == 15)
{
Screen->ComboD [SomariaBlockPosition] = CmbR;
Screen->ComboC [SomariaBlockPosition] = CmbRC;
Screen->ComboT [SomariaBlockPosition] = CmbRT;
Screen->ComboF [SomariaBlockPosition] = CmbRS;
Screen->ComboI [SomariaBlockPosition] = CmbRI;
Screen->ComboS [SomariaBlockPosition] = CmbSd;
SomariaCheck = 0;
}
}

It first checks for the value of SomariaCheck, and if that's 0, it checks for solidity at the value of SomariaBlockPosition. You could say I only need the check, but I have both as a sort of failsafe, just in case something goes a bit wrong. :rolleyes: See, your bool thing won't work because I'm not JUST changing the value of SomariaCheck. In fact, I don't have to do that at all. I'm only doing it because it makes sense that if I was using 1 for "A Block is on the Screen" that 0 should be used when a block ISN'T on the screen. Just common sense, I guess. Anyways, it modifies EVERYTHING about the block's combo and stuff so it's back to being normal, average ground. Do you understand?

Saffith
01-17-2007, 06:33 PM
Yeah. In that case, it won't save you any time.

Nimono
01-17-2007, 06:47 PM
Yeah. In that case, it won't save you any time.

So, do you think you can figure out what's wrong with my script? It doesn't seem to erase the block that's already on-screen, even though it's supposed to set SomariaCheck to 1 at the end of the script... Sigh... Do you think I should post the entire script here so you can see if I did anything wrong on it? Oh, and by the way, why is it that you can't declare the same variable twice? I'm thinking my problem might be that I don't put int at the end of the script where I put SomariaCheck = 1;. Could that be it?

Saffith
01-17-2007, 07:00 PM
Yeah, probably best to post the whole thing. Can't see anything wrong with what's been posted so far.


Oh, and by the way, why is it that you can't declare the same variable twice?Well, basically, declaring a variable creates a new variable without any regard for existing ones. If you try to declare a variable a second time, it'll think you're trying to create a new variable with the same name. That would be a problem, obviously, since you would have to refer to them the same way and it would never know which you meant.
It could be changed to allow multiple declarations, but there's really no advantage to that. If anything, it would just make code redundant and more confusing.


I'm thinking my problem might be that I don't put int at the end of the script where I put SomariaCheck = 1;. Could that be it?Very unlikely. If it compiles as it is, even if it doesn't work right, it's definitely not that.

Nimono
01-17-2007, 07:11 PM
Okay. Here's my code:


// OoA Cane of Somaria- When used, this item will create a block in front of Link if the block in front of him isn't solid.
// If the combo is solid, this script does nothing.
// Variables:
// Cmb- The combo that the Cane switches a screen's combo to. Simply enter the combo number seen in the combo editor!
// CmbC- The CSet of the new combo. Only use 0-11 for best results.
// CmbS- Secret Flag of the new combo.
// CmbI- Inherent Flag of the new combo.
// CmbT- Combo type of the new combo.
// CmbS- Solidity of the new combo. Note: SOLIDITY USES THE BINARY SYSTEM. 1111 is total solidity, which is 15 in decimal.
// SomariaCheck- A special variable used only for checking if a Somaria Block is already on-screen. Creating a Block
// sets this Variable to 1. Destroying one sets it to 0. This variable is checked only by one function. DO NOT MESS WITH IT!!!!
// CmbR- The combo the Block resets to when SomariaCheck is set to 1 when you use this item.
// CmbRC- CSet the of the reset combo.
// CmbRT- Cmbo type of the reset combo.
// CmbRS- Secret Flag of the reset combo.
// CmbRI- Inherent Flag of the reset combo.
// CmbRSd- Solidity of the reset combo. Don't mess with this unless you know what you're doing, like with CmbSd.

import "std.zh"
item script CaneSomaria
{
void run(int SomariaBlockX, int SomariaBlockY, int SomariaCheck, int SomariaBlockPosition)
{
int Cmb = 2123;
int CmbC = 10;
int CmbS = 79;
int CmbI = 61;
int CmbT = 0;
int CmbSd = 15;
int CmbR = 0;
int CmbRC = 2;
int CmbRT = 0;
int CmbRS = 0;
int CmbRI = 0;
int CmbRSd = 0;
if (SomariaCheck == 1)
{
if (Screen->ComboS [SomariaBlockPosition] == 15)
{
Screen->ComboD [SomariaBlockPosition] = CmbR;
Screen->ComboC [SomariaBlockPosition] = CmbRC;
Screen->ComboT [SomariaBlockPosition] = CmbRT;
Screen->ComboF [SomariaBlockPosition] = CmbRS;
Screen->ComboI [SomariaBlockPosition] = CmbRI;
Screen->ComboS [SomariaBlockPosition] = CmbSd;
SomariaCheck = 0;
}
}
if (Link->Dir == 0)
{
int BlockCheckY = Link->Y - 32;
int BlockCheckX = Link->X;
float BlockRmndrX = BlockCheckX % 16;
if (BlockRmndrX <= 8)
{
BlockCheckX = BlockCheckX - BlockRmndrX;
}
else
{
BlockCheckX = BlockCheckX + 16 - BlockRmndrX;
}
float BlockRmndrY = BlockCheckY % 16;
if (BlockRmndrY <= 8)
{
BlockCheckY = BlockCheckY - BlockRmndrY;
}
else
{
BlockCheckY = BlockCheckY + 16 - BlockRmndrY;
}
int BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS [BlockPosition] == 0)
{
SomariaBlockY = Link->Y - 32;
SomariaBlockX = Link->X;
float remainder = SomariaBlockX % 16;
if (remainder <= 8)
{
SomariaBlockX = SomariaBlockX - remainder;
}
else
{
SomariaBlockX = SomariaBlockX + 16 - remainder;
}
float remainderY = SomariaBlockY % 16;
if (remainderY <= 8)
{
SomariaBlockY = SomariaBlockY - remainderY;
}
else
{
SomariaBlockY = SomariaBlockY + 16 - remainderY;
}
int SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
Screen->ComboD [SomariaBlockPosition] = Cmb;
Screen->ComboC [SomariaBlockPosition] = CmbC;
Screen->ComboF [SomariaBlockPosition] = CmbS;
Screen->ComboI [SomariaBlockPosition] = CmbI;
Screen->ComboT [SomariaBlockPosition] = CmbT;
Screen->ComboS [SomariaBlockPosition] = CmbSd;
}
}
else if (Link->Dir == 1)
{
int BlockCheckY = Link->Y + 32;
int BlockCheckX = Link->X;
float BlockRmndrX = BlockCheckX % 16;
if (BlockRmndrX <= 8)
{
BlockCheckX = BlockCheckX - BlockRmndrX;
}
else
{
BlockCheckX = BlockCheckX + 16 - BlockRmndrX;
}
float BlockRmndrY = BlockCheckY % 16;
if (BlockRmndrY <= 8)
{
BlockCheckY = BlockCheckY - BlockRmndrY;
}
else
{
BlockCheckY = BlockCheckY + 16 - BlockRmndrY;
}
int BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS [BlockPosition] == 0)
{
SomariaBlockY = Link->Y + 32;
SomariaBlockX = Link->X;
float remainder = SomariaBlockX % 16;
if (remainder <= 8)
{
SomariaBlockX = SomariaBlockX - remainder;
}
else
{
SomariaBlockX = SomariaBlockX + 16 - remainder;
}
float remainderY = SomariaBlockY % 16;
if (remainderY <= 8)
{
SomariaBlockY = SomariaBlockY - remainderY;
}
else
{
SomariaBlockY = SomariaBlockY + 16 - remainderY;
}
int SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
Screen->ComboD [SomariaBlockPosition] = Cmb;
Screen->ComboC [SomariaBlockPosition] = CmbC;
Screen->ComboF [SomariaBlockPosition] = CmbS;
Screen->ComboI [SomariaBlockPosition] = CmbI;
Screen->ComboT [SomariaBlockPosition] = CmbT;
Screen->ComboS [SomariaBlockPosition] = CmbSd;
}

}
else if (Link->Dir == 2)
{
int BlockCheckY = Link->Y;
int BlockCheckX = Link->X - 32;
float BlockRmndrX = BlockCheckX % 16;
if (BlockRmndrX <= 8)
{
BlockCheckX = BlockCheckX - BlockRmndrX;
}
else
{
BlockCheckX = BlockCheckX + 16 - BlockRmndrX;
}
float BlockRmndrY = BlockCheckY % 16;
if (BlockRmndrY <= 8)
{
BlockCheckY = BlockCheckY - BlockRmndrY;
}
else
{
BlockCheckY = BlockCheckY + 16 - BlockRmndrY;
}
int BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS [BlockPosition] == 0)
{
SomariaBlockX = Link->X - 32;
SomariaBlockY = Link->Y;
float remainder = SomariaBlockX % 16;
if (remainder <= 8)
{
SomariaBlockX = SomariaBlockX - remainder;
}
else
{
SomariaBlockX = SomariaBlockX + 16 - remainder;
}
float remainderY = SomariaBlockY % 16;
if (remainderY <= 8)
{
SomariaBlockY = SomariaBlockY - remainderY;
}
else
{
SomariaBlockY = SomariaBlockY + 16 - remainderY;
}
int SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
Screen->ComboD [SomariaBlockPosition] = Cmb;
Screen->ComboC [SomariaBlockPosition] = CmbC;
Screen->ComboF [SomariaBlockPosition] = CmbS;
Screen->ComboI [SomariaBlockPosition] = CmbI;
Screen->ComboT [SomariaBlockPosition] = CmbT;
Screen->ComboS [SomariaBlockPosition] = CmbSd;
}
}
else if (Link->Dir == 3)
{
int BlockCheckY = Link->Y;
int BlockCheckX = Link->X + 32;
float BlockRmndrX = BlockCheckX % 16;
if (BlockRmndrX <= 8)
{
BlockCheckX = BlockCheckX - BlockRmndrX;
}
else
{
BlockCheckX = BlockCheckX + 16 - BlockRmndrX;
}
float BlockRmndrY = BlockCheckY % 16;
if ( BlockRmndrY <= 8 )
{
BlockCheckY = BlockCheckY - BlockRmndrY;
}
else
{
BlockCheckY = BlockCheckY + 16 - BlockRmndrY;
}
int BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS [BlockPosition] == 0)
{
SomariaBlockX = Link->X + 32;
SomariaBlockY = Link->Y;
float remainder = SomariaBlockX % 16;
if (remainder <= 8)
{
SomariaBlockX = SomariaBlockX - remainder;
}
else
{
SomariaBlockX = SomariaBlockX + 16 - remainder;
}
float remainderY = SomariaBlockY % 16;
if (remainderY <= 8)
{
SomariaBlockY = SomariaBlockY - remainderY;
}
else
{
SomariaBlockY = SomariaBlockY + 16 - remainderY;
}
int SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
Screen->ComboD [SomariaBlockPosition] = Cmb;
Screen->ComboC [SomariaBlockPosition] = CmbC;
Screen->ComboF [SomariaBlockPosition] = CmbS;
Screen->ComboI [SomariaBlockPosition] = CmbI;
Screen->ComboT [SomariaBlockPosition] = CmbT;
Screen->ComboS [SomariaBlockPosition] = CmbSd;
}
}
SomariaCheck = 1;
}
}

Hope that helps you understand my predicament. I've been working on this for about 4 or 5 days straight, and I'm so close to perfecting this... I can't just leaveit alone now...

Saffith
01-17-2007, 08:09 PM
Ah, yeah, I see now. There are a few different problems. First, this:

void run(int SomariaBlockX, int SomariaBlockY, int SomariaCheck, int SomariaBlockPosition)
{
If you declare variables there, they will be reset to 0 every time the item is used. If you want them to keep their values, declare them before run(), like this:

item script CaneSomaria
{
int SomariaBlockX = 0;
int SomariaBlockY = 0;
int SomariaCheck = 0;
int SomariaBlockPosition = 0;

void run()
{
That makes them global variables. they'll only be initialized once; after that, they'll start the script with the same values they ended with last time.
You'll also want to make those CmbRX variables global, or they'll get reset, too.
Although as it is, you never actually change their values, y'know.

However, there'll be a problem with doing this, in this case: SomariaCheck won't be reset when you go to another screen. You'll also need to check which screen and map you're on when the item is used and treat SomariaCheck as 0 if they've changed since last time.
You can't just use screen variables, since those don't get reset when you leave the screen. If you left and came back, they might be wrong.


There's also this. This might be a problem, or it might be what you intended. Just in case...

if (SomariaCheck == 1)
{
if (Screen->ComboS [SomariaBlockPosition] == 15)
{
Screen->ComboD [SomariaBlockPosition] = CmbR;
Screen->ComboC [SomariaBlockPosition] = CmbRC;
Screen->ComboT [SomariaBlockPosition] = CmbRT;
Screen->ComboF [SomariaBlockPosition] = CmbRS;
Screen->ComboI [SomariaBlockPosition] = CmbRI;
Screen->ComboS [SomariaBlockPosition] = CmbSd;
SomariaCheck = 0;
}
}
if (Link->Dir == 0)
{
That won't alternately create and destroy a block; that'll destroy a block and create a new one every time you use the item. If that's what you meant for it to do, it's fine. Otherwise, you can change it by putting an else before the second if statement or by putting Quit(); after setting SomariaCheck to 0.





That's still not quite perfect, but it'll definitely be closer, at least.

Nimono
01-17-2007, 08:38 PM
Ah, yeah, I see now. There are a few different problems. First, this:

void run(int SomariaBlockX, int SomariaBlockY, int SomariaCheck, int SomariaBlockPosition)
{
If you declare variables there, they will be reset to 0 every time the item is used. If you want them to keep their values, declare them before run(), like this:

item script CaneSomaria
{
int SomariaBlockX = 0;
int SomariaBlockY = 0;
int SomariaCheck = 0;
int SomariaBlockPosition = 0;

void run()
{
That makes them global variables. they'll only be initialized once; after that, they'll start the script with the same values they ended with last time.
You'll also want to make those CmbRX variables global, or they'll get reset, too.
Although as it is, you never actually change their values, y'know.

However, there'll be a problem with doing this, in this case: SomariaCheck won't be reset when you go to another screen. You'll also need to check which screen and map you're on when the item is used and treat SomariaCheck as 0 if they've changed since last time.
You can't just use screen variables, since those don't get reset when you leave the screen. If you left and came back, they might be wrong.


There's also this. This might be a problem, or it might be what you intended. Just in case...

if (SomariaCheck == 1)
{
if (Screen->ComboS [SomariaBlockPosition] == 15)
{
Screen->ComboD [SomariaBlockPosition] = CmbR;
Screen->ComboC [SomariaBlockPosition] = CmbRC;
Screen->ComboT [SomariaBlockPosition] = CmbRT;
Screen->ComboF [SomariaBlockPosition] = CmbRS;
Screen->ComboI [SomariaBlockPosition] = CmbRI;
Screen->ComboS [SomariaBlockPosition] = CmbSd;
SomariaCheck = 0;
}
}
if (Link->Dir == 0)
{
That won't alternately create and destroy a block; that'll destroy a block and create a new one every time you use the item. If that's what you meant for it to do, it's fine. Otherwise, you can change it by putting an else before the second if statement or by putting Quit(); after setting SomariaCheck to 0.





That's still not quite perfect, but it'll definitely be closer, at least.

Okay. In case you didn't know, the script begins by telling you the item is the OoA Cane of Somaria. In that game, using the Cane when the block was already there removed the block and created a new one. Only in LttP and FSA did the block get destroyed when you used the Cane and required you to use it again to make a new one. Speaking of which, I'm making that next. :p

Thanks Saffith. I knew I could count on you. ;) I was wondering how to define global variables- Now I don't have to ask. :laughing: So let's see... Should I use GetCurrScreen as a Global variable or a screen variable...? Let me ask you this:

I'll make four new variables, CurrScreen, LastScreen, CurrMap, and LastMap. They'll all be global, of course, or that defeats their purpose. At the start of the script, I'll write the current screen number to CurrScreen using GetCurrScreen. At the end of the script, I'll write to LastScreen by "copying" the value of CurrScreen to it. I'll do the same with CurrMap and LastMap, except using GetCurrMap instead. After the CurrMap and CurrScreen have been written to, I'll make a new check to compare the values of CurrScreen and LastScreen and CurrMap and LastMap. Of course, when I set them to global variables, I'll make sure to check for the Current Map and Screen numbers so everything doesn't get all mixed up. ;) If all 4 are equal to what they're being compared with, everything stays the same. If even ONE is messed up, it'll set SomariaCheck to 0. A few more questions, though:

1: If I wanted to do an if statement, but check if something is NOT equal to another thing, should I use !== ?
2: How would you go about setting up the checks I just mentioned? Would you have set to where it'd check for CurrScreen !== LastScreen, and if they don't, check for the Map ones, and if they're not equal, set SomariaCheck to 0, and if they are, do it anyways? Or would you instead check the Screen ones and if not equal, set Check to 0, and if they are, repeat with Map? (Note: This is simply your opinion. I just want to know how other people would do it for efficiency.)
3: Is there anything else I should do?
Edit:
4: Why is it that I can't read from "GetCurScreen()"? It's supposed to only work when you use "game->", right? But everytime I do that, I get a compiler error stating, "Left of the arrow (->). Operator must be a pointer type (ffc, etc.). But Game IS a pointer type! The ZScript FAQ says so! :(

Saffith
01-17-2007, 09:43 PM
I'll make four new variables, CurrScreen, LastScreen, CurrMap, and LastMap. They'll all be global, of course, or that defeats their purpose.Yep. Also, be sure to initialize them to something invalid like -1 to be sure you don't incorrectly get a match on the first use.


At the start of the script, I'll write the current screen number to CurrScreen using GetCurrScreen. At the end of the script, I'll write to LastScreen by "copying" the value of CurrScreen to it. I'll do the same with CurrMap and LastMap, except using GetCurrMap instead. After the CurrMap and CurrScreen have been written to, I'll make a new check to compare the values of CurrScreen and LastScreen and CurrMap and LastMap.You don't need a separate test, actually, just a change to one condition:

if (SomariaCheck == 1 && CurrScreen == LastScreen && CurrMap == LastMap)
I just realized, though... If you leave the screen and come back, you'll be on the same screen and map, but the block will be gone. This could be a bit tricky, actually...


1: If I wanted to do an if statement, but check if something is NOT equal to another thing, should I use !== ?Almost: it's !=


2: How would you go about setting up the checks I just mentioned? Would you have set to where it'd check for CurrScreen !== LastScreen, and if they don't, check for the Map ones, and if they're not equal, set SomariaCheck to 0, and if they are, do it anyways? Or would you instead check the Screen ones and if not equal, set Check to 0, and if they are, repeat with Map? (Note: This is simply your opinion. I just want to know how other people would do it for efficiency.)For efficiency? Well, you don't really need to set it to 0 at all, since you know you'll just be setting it right back to 1 anyway. I say just check them along with SomariaCheck as above, since they're all part of picking from the same set of actions.
Efficiency's not a big concern here. Unless you have a ridiculously CPU-intensive way of checking, you won't even notice a difference between two methods.


3: Is there anything else I should do?Hm. Well, again, I'm not entirely certain how you want the script to work. You may want to change the values of the CmbRX variables when the block is placed, but that's only if you want to change it back to what it was before.
More importantly, there's the question of what to do if the block is pushed. Then you don't know where it is anymore, so you can't replace it. The only solution that springs to mind is to use a unique combo for the created block, so you can scan the whole screen for it and be sure whether you found it or not.
Then again, I'm not sure what would happen if you used the cane while the block was in mid-push. That might be a serious problem.

Nimono
01-17-2007, 09:49 PM
Yep. Also, be sure to initialize them to something invalid like -1 to be sure you don't incorrectly get a match on the first use.

I'm just setting them both to the Current screen anyways at first. :p

You don't need a separate test, actually, just a change to one condition:

if (SomariaCheck == 1 && CurrScreen == LastScreen && CurrMap == LastMap)
I just realized, though... If you leave the screen and come back, you'll be on the same screen and map, but the block will be gone. This could be a bit tricky, actually...

Actually... That's what it's supposed to do. :p

Almost: it's !=

Darn it! XD

For efficiency? Well, you don't really need to set it to 0 at all, since you know you'll just be setting it right back to 1 anyway. I say just check them along with SomariaCheck as above, since they're all part of picking from the same set of actions.
Efficiency's not a big concern here. Unless you have a ridiculously CPU-intensive way of checking, you won't even notice a difference between two methods.

Okay, if you say so!

Hm. Well, again, I'm not entirely certain how you want the script to work. You may want to change the values of the CmbRX variables when the block is placed, but that's only if you want to change it back to what it was before.
More importantly, there's the question of what to do if the block is pushed. Then you don't know where it is anymore, so you can't replace it. The only solution that springs to mind is to use a unique combo for the created block, so you can scan the whole screen for it and be sure whether you found it or not.

Actually, the "CmbRX variables are the reset combos, hence the "R". There's a new and reset variable for each thing I modify on a combo. It's easier to keep track of variable settings that way. ;)

Then again, I'm not sure what would happen if you used the cane while the block was in mid-push. That might be a serious problem.

Quite. O_o


My replies are in bold. :)

Oh yeah, you missed a question. :p

Saffith
01-17-2007, 11:01 PM
I just realized, though... If you leave the screen and come back, you'll be on the same screen and map, but the block will be gone. This could be a bit tricky, actually...Actually... That's what it's supposed to do. :pWhat I mean to say is, if you leave and come back, there won't be a block there, but the script will think there is, so it'll try and replace it. So even tracking the screen and map isn't enough to be certain of whether the block is there...


Oh yeah, you missed a question. :pYeah, well, :blah:. So there.


4: Why is it that I can't read from "GetCurScreen()"? It's supposed to only work when you use "game->", right? But everytime I do that, I get a compiler error stating, "Left of the arrow (->). Operator must be a pointer type (ffc, etc.). But Game IS a pointer type! The ZScript FAQ says so! :-(Are you using "game" or "Game"? It has to be capitalized.
That's not the error message I would expect in that case, though... Be sure there's not a syntactical error or typo or something just before it.

Nimono
01-17-2007, 11:09 PM
What I mean to say is, if you leave and come back, there won't be a block there, but the script will think there is, so it'll try and replace it. So even tracking the screen and map isn't enough to be certain of whether the block is there...

Yeah, well, :blah:. So there.

Are you using "game" or "Game"? It has to be capitalized.
That's not the error message I would expect in that case, though... Be sure there's not a syntactical error or typo or something just before it.

Oh. So... I'll try to figure a workaround to the problem... See, that's why I have the failsafe of "if (Screen->ComboD [SomariaBlockPosition] == 15)"! So, if you're talking about SomariaCheck not getting reset at screen re-entry, then don't worry. :)

At first, I used "Game". When that didn't work, I put it lowercase. No change. So I just put "GetCurScreen(game)". When Compiling, I got this:

"Could not match type signature GetCurScreen(WTF)."

:laughing: HOW DID GAME TURN OUT TO BE WTF?! :laughing: I'd report it as a bug, but Ilike silly things like that. It amuses me so much. :)

I'll try again with Game->. It'd BETTER work this time, or the compiler WILL FEEL MY WRATH. :mad:

Edit: By the way, I put all that about GetCurScreen in the part where I declare CurScreen as a Global Variable. Perhaps that's the problem?

Edit2: OH NO! That WAS the problem! That messes up my whole script! :(

Edit3: Nevermind. :) But now I have a problem:


// OoA Cane of Somaria- When used, this item will create a block in front of Link if the block in front of him isn't solid.
// If the combo is solid, this script does nothing.
// Variables:
// Cmb- The combo that the Cane switches a screen's combo to. Simply enter the combo number seen in the combo editor!
// CmbC- The CSet of the new combo. Only use 0-11 for best results.
// CmbS- Secret Flag of the new combo.
// CmbI- Inherent Flag of the new combo.
// CmbT- Combo type of the new combo.
// CmbS- Solidity of the new combo. Note: SOLIDITY USES THE BINARY SYSTEM. 1111 is total solidity, which is 15 in decimal.
// SomariaCheck- A special variable used only for checking if a Somaria Block is already on-screen. Creating a Block
// sets this Variable to 1. Destroying one sets it to 0. This variable is checked only by one function. DO NOT MESS WITH IT!!!!
// CmbR- The combo the Block resets to when SomariaCheck is set to 1 when you use this item.
// CmbRC- CSet the of the reset combo.
// CmbRT- Cmbo type of the reset combo.
// CmbRS- Secret Flag of the reset combo.
// CmbRI- Inherent Flag of the reset combo.
// CmbRSd- Solidity of the reset combo. Don't mess with this unless you know what you're doing, like with CmbSd.

import "std.zh"
item script CaneSomaria
{
int SomariaBlockX = 0;
int SomariaBlockY = 0;
int SomariaCheck = 0;
int SomariaBlockPosition = 0;
int CurScreen = 0;
int LastScreen = 0;
int CurMap = 0;
int LastMap = 0;
int Cmb = 2123;
int CmbC = 10;
int CmbS = 79;
int CmbI = 61;
int CmbT = 0;
int CmbSd = 15;
int CmbR = 0;
int CmbRC = 2;
int CmbRT = 0;
int CmbRS = 0;
int CmbRI = 0;
int CmbRSd = 0;

void run()
{
CurScreen = Game->GetCurScreen();
CurMap = Game->GetCurMap();
if (CurScreen != LastScreen)
{
SomariaCheck = 0;
}
else if (CurMap != LastMap)
{
SomariaCheck = 0;
}
if (SomariaCheck == 1)
{
if (Screen->ComboS [SomariaBlockPosition] == 15)
{
Screen->ComboD [SomariaBlockPosition] = CmbR;
Screen->ComboC [SomariaBlockPosition] = CmbRC;
Screen->ComboT [SomariaBlockPosition] = CmbRT;
Screen->ComboF [SomariaBlockPosition] = CmbRS;
Screen->ComboI [SomariaBlockPosition] = CmbRI;
Screen->ComboS [SomariaBlockPosition] = CmbSd;
SomariaCheck = 0;
}
}
if (Link->Dir == 0)
{
int BlockCheckY = Link->Y - 32;
int BlockCheckX = Link->X;
float BlockRmndrX = BlockCheckX % 16;
if (BlockRmndrX <= 8)
{
BlockCheckX = BlockCheckX - BlockRmndrX;
}
else
{
BlockCheckX = BlockCheckX + 16 - BlockRmndrX;
}
float BlockRmndrY = BlockCheckY % 16;
if (BlockRmndrY <= 8)
{
BlockCheckY = BlockCheckY - BlockRmndrY;
}
else
{
BlockCheckY = BlockCheckY + 16 - BlockRmndrY;
}
int BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS [BlockPosition] == 0)
{
SomariaBlockY = Link->Y - 32;
SomariaBlockX = Link->X;
float remainder = SomariaBlockX % 16;
if (remainder <= 8)
{
SomariaBlockX = SomariaBlockX - remainder;
}
else
{
SomariaBlockX = SomariaBlockX + 16 - remainder;
}
float remainderY = SomariaBlockY % 16;
if (remainderY <= 8)
{
SomariaBlockY = SomariaBlockY - remainderY;
}
else
{
SomariaBlockY = SomariaBlockY + 16 - remainderY;
}
int SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
Screen->ComboD [SomariaBlockPosition] = Cmb;
Screen->ComboC [SomariaBlockPosition] = CmbC;
Screen->ComboF [SomariaBlockPosition] = CmbS;
Screen->ComboI [SomariaBlockPosition] = CmbI;
Screen->ComboT [SomariaBlockPosition] = CmbT;
Screen->ComboS [SomariaBlockPosition] = CmbSd;
}
}
else if (Link->Dir == 1)
{
int BlockCheckY = Link->Y + 32;
int BlockCheckX = Link->X;
float BlockRmndrX = BlockCheckX % 16;
if (BlockRmndrX <= 8)
{
BlockCheckX = BlockCheckX - BlockRmndrX;
}
else
{
BlockCheckX = BlockCheckX + 16 - BlockRmndrX;
}
float BlockRmndrY = BlockCheckY % 16;
if (BlockRmndrY <= 8)
{
BlockCheckY = BlockCheckY - BlockRmndrY;
}
else
{
BlockCheckY = BlockCheckY + 16 - BlockRmndrY;
}
int BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS [BlockPosition] == 0)
{
SomariaBlockY = Link->Y + 32;
SomariaBlockX = Link->X;
float remainder = SomariaBlockX % 16;
if (remainder <= 8)
{
SomariaBlockX = SomariaBlockX - remainder;
}
else
{
SomariaBlockX = SomariaBlockX + 16 - remainder;
}
float remainderY = SomariaBlockY % 16;
if (remainderY <= 8)
{
SomariaBlockY = SomariaBlockY - remainderY;
}
else
{
SomariaBlockY = SomariaBlockY + 16 - remainderY;
}
int SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
Screen->ComboD [SomariaBlockPosition] = Cmb;
Screen->ComboC [SomariaBlockPosition] = CmbC;
Screen->ComboF [SomariaBlockPosition] = CmbS;
Screen->ComboI [SomariaBlockPosition] = CmbI;
Screen->ComboT [SomariaBlockPosition] = CmbT;
Screen->ComboS [SomariaBlockPosition] = CmbSd;
}

}
else if (Link->Dir == 2)
{
int BlockCheckY = Link->Y;
int BlockCheckX = Link->X - 32;
float BlockRmndrX = BlockCheckX % 16;
if (BlockRmndrX <= 8)
{
BlockCheckX = BlockCheckX - BlockRmndrX;
}
else
{
BlockCheckX = BlockCheckX + 16 - BlockRmndrX;
}
float BlockRmndrY = BlockCheckY % 16;
if (BlockRmndrY <= 8)
{
BlockCheckY = BlockCheckY - BlockRmndrY;
}
else
{
BlockCheckY = BlockCheckY + 16 - BlockRmndrY;
}
int BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS [BlockPosition] == 0)
{
SomariaBlockX = Link->X - 32;
SomariaBlockY = Link->Y;
float remainder = SomariaBlockX % 16;
if (remainder <= 8)
{
SomariaBlockX = SomariaBlockX - remainder;
}
else
{
SomariaBlockX = SomariaBlockX + 16 - remainder;
}
float remainderY = SomariaBlockY % 16;
if (remainderY <= 8)
{
SomariaBlockY = SomariaBlockY - remainderY;
}
else
{
SomariaBlockY = SomariaBlockY + 16 - remainderY;
}
int SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
Screen->ComboD [SomariaBlockPosition] = Cmb;
Screen->ComboC [SomariaBlockPosition] = CmbC;
Screen->ComboF [SomariaBlockPosition] = CmbS;
Screen->ComboI [SomariaBlockPosition] = CmbI;
Screen->ComboT [SomariaBlockPosition] = CmbT;
Screen->ComboS [SomariaBlockPosition] = CmbSd;
}
}
else if (Link->Dir == 3)
{
int BlockCheckY = Link->Y;
int BlockCheckX = Link->X + 32;
float BlockRmndrX = BlockCheckX % 16;
if (BlockRmndrX <= 8)
{
BlockCheckX = BlockCheckX - BlockRmndrX;
}
else
{
BlockCheckX = BlockCheckX + 16 - BlockRmndrX;
}
float BlockRmndrY = BlockCheckY % 16;
if ( BlockRmndrY <= 8 )
{
BlockCheckY = BlockCheckY - BlockRmndrY;
}
else
{
BlockCheckY = BlockCheckY + 16 - BlockRmndrY;
}
int BlockPosition = (BlockCheckY & 240)+(BlockCheckX>>4);
if (Screen->ComboS [BlockPosition] == 0)
{
SomariaBlockX = Link->X + 32;
SomariaBlockY = Link->Y;
float remainder = SomariaBlockX % 16;
if (remainder <= 8)
{
SomariaBlockX = SomariaBlockX - remainder;
}
else
{
SomariaBlockX = SomariaBlockX + 16 - remainder;
}
float remainderY = SomariaBlockY % 16;
if (remainderY <= 8)
{
SomariaBlockY = SomariaBlockY - remainderY;
}
else
{
SomariaBlockY = SomariaBlockY + 16 - remainderY;
}
SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
Screen->ComboD [SomariaBlockPosition] = Cmb;
Screen->ComboC [SomariaBlockPosition] = CmbC;
Screen->ComboF [SomariaBlockPosition] = CmbS;
Screen->ComboI [SomariaBlockPosition] = CmbI;
Screen->ComboT [SomariaBlockPosition] = CmbT;
Screen->ComboS [SomariaBlockPosition] = CmbSd;
}
}
LastScreen = CurScreen;
LastMap = CurMap;
SomariaCheck = 1;
}
}
Something's going wrong in the code. Once it hits the point where it uses the CmbRX variables, it spawns the block in the top-left corner, makes the entire screen solid, and prevents any other blocks from appearing. It also won't remove the block that was there before. Somewhere in the script, SomariaBlockPosition is getting reset to 0. Plus, after it puts a block in the top-left corner, it seems to ignore the entire code for making a block appear! What am I doing wrong?

Saffith
01-18-2007, 02:10 PM
Simple problem to fix:

int SomariaBlockPosition = (SomariaBlockY & 240)+(SomariaBlockX>>4);
Screen->ComboD [SomariaBlockPosition] = Cmb;
Screen->ComboC [SomariaBlockPosition] = CmbC;
Screen->ComboF [SomariaBlockPosition] = CmbS;
Screen->ComboI [SomariaBlockPosition] = CmbI;
Screen->ComboT [SomariaBlockPosition] = CmbT;
Screen->ComboS [SomariaBlockPosition] = CmbSd;Take out that "int" before setting SomariaBlockPosition. That's in three different places.

It's not exactly true that you can't create two variables with the same name. More precisely, you can't create two variables with the same name and scope. If there are two variables with the same name available, the compiler will assume you mean the one with the narrowest scope.

int x = 5; // #1
{
int x = 10; // #2
x = 0; // Modifies #2
}
x = 8; // #2 no longer exists; modifies #1

So what you're doing above is creating a new local variable called SomariaBlockPosition and using that, leaving the global variable untouched.

Nimono
01-18-2007, 02:11 PM
Too late, Saffith- I finished the script. I defeated many bugs, and it's now perfected and in Script Showcase. Go check it out. This thread (and all the other ones with the questions I asked) can be closed now. :)

Fire Wizzrobe
01-18-2007, 06:41 PM
I wrote a variation of the script with a different function;


import "std.zh"
item script Somaria{

int blockY = 0;
int blockX = 0;
int blockcombo = 0;
int blocksecrect = 0;
int blockCset = 0;
bool disapear = false;

void run()

int blockcheckY = 0;
int blockcheckX = 0;
float RmndrX = 0;
float RmndrY = 0;
float BlockrmndrX = 0;
float BlockrmndrY = 0;
int Blockposition = 0;

if (dispear == false){

if (Link->Dir == 0){
blockcheckY = Link->Y - 32;
blockcheckX = Link->X;
RmndrX = blockcheckX % 16;

if (RmndX <= 8){
blockcheckX = blockcheckX - RmndrX;
}
else
{
blockcheckX = blockcheckX + 16 - RmndrX;
}

RmndrY = blockcheckY % 16;

if (RmndrY <= 8){
{
blockcheckY = blockcheckY - RmndrY;
}
else
{
blockcheckY = blockcheckY + 16 - RmndrY;
}

if (ComboAt(blockcheckX, blockcheckY) == 0){
BlockrmndrX = blockX % 16;

if (BlockrmndrX <= 8){
blockX = blockX - BlockrmndrX;
}
else
{
blockX = blockX + 16 - BlockrmndrX;
}
BlockrmndrY = blockY % 16;

if (BlockRmndrY <= 8){
{
blockY = blockY - BlockrmndrY;
}
else
{
blockY = blockY + 16 - BlockrmndrY;
}
int Blockposition = (ComboAt(blockX, blockY))
Screen->ComboD [Blockposition] = blockcombo;
Screen->ComboC [Blockposition] = blockCset;
Screen->ComboF [Blockposition] = blocksecret;
disapear = true;
}

if (Link->Dir == 1){
blockcheckY = Link->Y + 32;
blockcheckX = Link->X;
RmndrX = blockcheckX % 16;

if (RmndX <= 8){
blockcheckX = blockcheckX - RmndrX;
}
else
{
blockcheckX = blockcheckX + 16 - RmndrX;
}

RmndrY = blockcheckY % 16;

if (RmndrY <= 8){
{
blockcheckY = blockcheckY - RmndrY;
}
else
{
blockcheckY = blockcheckY + 16 - RmndrY;
}

if (ComboAt(blockcheckX, blockcheckY) == 0){
BlockrmndrX = blockX % 16;

if (BlockrmndrX <= 8){
blockX = blockX - BlockrmndrX;
}
else
{
blockX = blockX + 16 - BlockrmndrX;
}
BlockrmndrY = blockY % 16;

if (BlockRmndrY <= 8){
{
blockY = blockY - BlockrmndrY;
}
else
{
blockY = blockY + 16 - BlockrmndrY;
}
int Blockposition = (ComboAt(blockX, blockY))
Screen->ComboD [Blockposition] = blockcombo;
Screen->ComboC [Blockposition] = blockCset;
Screen->ComboF [Blockposition] = blocksecret;
disapear = true;
}


if (Link->Dir == 2){
blockcheckY = Link->Y;
blockcheckX = Link->X - 32;
RmndrX = blockcheckX % 16;

if (RmndX <= 8){
blockcheckX = blockcheckX - RmndrX;
}
else
{
blockcheckX = blockcheckX + 16 - RmndrX;
}

RmndrY = blockcheckY % 16;

if (RmndrY <= 8){
{
blockcheckY = blockcheckY - RmndrY;
}
else
{
blockcheckY = blockcheckY + 16 - RmndrY;
}

if (ComboAt(blockcheckX, blockcheckY) == 0){
BlockrmndrX = blockX % 16;

if (BlockrmndrX <= 8){
blockX = blockX - BlockrmndrX;
}
else
{
blockX = blockX + 16 - BlockrmndrX;
}
BlockrmndrY = blockY % 16;

if (BlockRmndrY <= 8){
{
blockY = blockY - BlockrmndrY;
}
else
{
blockY = blockY + 16 - BlockrmndrY;
}
int Blockposition = (ComboAt(blockX, blockY))
Screen->ComboD [Blockposition] = blockcombo;
Screen->ComboC [Blockposition] = blockCset;
Screen->ComboF [Blockposition] = blocksecret;
disapear = true;
}

if (Link->Dir == 3){
blockcheckY = Link->Y;
blockcheckX = Link->X + 32;
RmndrX = blockcheckX % 16;

if (RmndX <= 8){
blockcheckX = blockcheckX - RmndrX;
}
else
{
blockcheckX = blockcheckX + 16 - RmndrX;
}

RmndrY = blockcheckY % 16;

if (RmndrY <= 8){
{
blockcheckY = blockcheckY - RmndrY;
}
else
{
blockcheckY = blockcheckY + 16 - RmndrY;
}

if (ComboAt(blockcheckX, blockcheckY) == 0){
BlockrmndrX = blockX % 16;

if (BlockrmndrX <= 8){
blockX = blockX - BlockrmndrX;
}
else
{
blockX = blockX + 16 - BlockrmndrX;
}
BlockrmndrY = blockY % 16;

if (BlockRmndrY <= 8){
{
blockY = blockY - BlockrmndrY;
}
else
{
blockY = blockY + 16 - BlockrmndrY;
}
Blockposition = (ComboAt(blockX, blockY))
Screen->ComboD [Blockposition] = blockcombo;
Screen->ComboC [Blockposition] = blockCset;
Screen->ComboF [Blockposition] = blocksecret;
disapear = true;
}
}
else
{
Blockposition = (ComboAt(blockX, blockY))
Screen->ComboD [Blockposition] = 0;
Screen->ComboF [Blockposition] = 0;
disapear = false;
}

} //End of void run

} //End of Script


The compiler gives me "Unexpected Identifier" at this part, and I have no idea why.


Screen->ComboD [Blockposition] = blockcombo;

Saffith
01-18-2007, 06:56 PM
Because you forgot the semicolon on the line before.

Nimono
01-18-2007, 07:00 PM
So, what exactly does THAT do, Fire Wizzrobe? What's its "different function"?

Fire Wizzrobe
01-18-2007, 07:01 PM
Ooh. That's embarrassing.

It also gives me "Unexpected End" at two lines after the end of the FFC script bracket.

Pikaguy- It make appear and reappear by the swinging of the cane and does not go away when you leave the screen.

Nimono
01-18-2007, 07:10 PM
Ooh. That's embarrassing.

It also gives me "Unexpected End" at two lines after the end of the FFC script bracket.

Pikaguy- It make appear and reappear by the swinging of the cane and does not go away when you leave the screen.

WHAT?! That's not what the Cane of Somaria did in ANY Zelda game. Maybe that script should be called "the Second Cane of Somaria".

Double-check your script some more. One time, I accidentally forgot to close an "if" statement, which created my "Cane only works when facing North" problem. XD You may have forgotten some braces here and there (Brackets are [], parentheses are (), and BRACES are {}.), so check back over it. It never hurts to double-check your work before you release it, as I have just recently RElearned. (My first learning of it was when I released Adventure in Mysteria. XD I'll never make THAT mistake with quests again.) Then again, it CAN take some people a while to fix sme obvious bugs... Sometimes, answers are directly in front of your face, but you'll often miss them. Anyways... Good luck on your script.

Say, Saffith, I have a question. When testing my Cane of Somaria script, I noticed once that when I pushed a normal block with Flag 61 (Push (4-Way, Infinite, Silent)), the block triggered secrets, even though its flag wasn't supposed to do that when pushed. When I push my Somaria Block, it doesn't do that. Is Flag 61 bugged or something?

Fire Wizzrobe
01-18-2007, 07:16 PM
I can call it Cane of Somaria if I want. I don't see why that matters. It's just not being faithful to the Zelda games, but it probably will be called something else. ;)

For example, there's a room in my game where 4 four block triggers lie and they can only be accessed through 4 different passages. 3 of them have blocks next to the triggers, but one doesn't, so this is where my script comes in.

Nimono
01-18-2007, 07:27 PM
I can call it Cane of Somaria if I want. I don't see why that matters. It's just not being faithful to the Zelda games, but it probably will be called something else. ;)

For example, there's a room in my game where 4 four block triggers lie and they can only be accessed through 4 different passages. 3 of them have blocks next to the triggers, but one doesn't, so this is where my script comes in.

I must've misworded my post... I think people should call your script the Second Cane of Somaria, so they won't accidentally make newbies to the Cane think that it does that in ALL Zelda games. Then there might be people who think you're trying to recreate the LttP/FSA or OoA Canes, so they'd bug you about the fact that it doesn't work exactly like those. Or, we could call it "Superb Ultra Cane of the Great and Mighty Fire Wizzrobe". =)

Why not make an example quest of how people could use your script, like I'm doing? I'm making an example quest showing all the various ways my script can be used. :)

Saffith
01-18-2007, 07:34 PM
It also gives me "Unexpected End" at two lines after the end of the FFC script bracket.You seem to have left out a few closing braces. I haven't checked which ones, exactly.


When testing my Cane of Somaria script, I noticed once that when I pushed a normal block with Flag 61 (Push (4-Way, Infinite, Silent)), the block triggered secrets, even though its flag wasn't supposed to do that when pushed. When I push my Somaria Block, it doesn't do that. Is Flag 61 bugged or something?Yeah, seems to be. Should be easy to fix, though.

DarkDragon
01-19-2007, 07:43 AM
As to the earlier problem: global variables are initialized at the very beginning of the game, and can currently only be initialized to constants. In the next revision of the language I'll make sure Game, Screen, and Link are in scope for global variable initializations.
For now, if you need to initialize global variables at game start, write a game script called ~Init:


ffc script foo {
int global;
}

game script ~Init {
void run() {
foo->global = Game->whatever();
}
}

Fire Wizzrobe
01-19-2007, 07:28 PM
Ok, I fixed all the errors. But when I swing the cane, it does absolutely nothing.


import "std.zh"
item script Somaria{

int blockY = 0;
int blockX = 0;
int blockcombo = 0;
int blocksecret = 0;
int blockCset = 0;
int disapear = 0;

void run(){

int blockcheckY = 0;
int blockcheckX = 0;
float RmndrX = 0;
float RmndrY = 0;
float BlockrmndrX = 0;
float BlockrmndrY = 0;
int Blockposition = 0;

if (dispear == 0){

if (Link->Dir == 0){
blockcheckY = Link->Y - 32;
blockcheckX = Link->X;
RmndrX = blockcheckX % 16;

if (RmndrX <= 8){
blockcheckX = blockcheckX - RmndrX;
}
else
{
blockcheckX = blockcheckX + 16 - RmndrX;
}

RmndrY = blockcheckY % 16;

if (RmndrY <= 8){
blockcheckY = blockcheckY - RmndrY;
}
else
{
blockcheckY = blockcheckY + 16 - RmndrY;
}

if (ComboAt(blockcheckX, blockcheckY) == 0){
BlockrmndrX = blockX % 16;

if (BlockrmndrX <= 8){
blockX = blockX - BlockrmndrX;
}
else
{
blockX = blockX + 16 - BlockrmndrX;
}
BlockrmndrY = blockY % 16;

if (BlockrmndrY <= 8){

blockY = blockY - BlockrmndrY;
}
else
{
blockY = blockY + 16 - BlockrmndrY;
}
Blockposition = (blockY & 240)+(blockX>>4);
Screen->ComboD [Blockposition] = blockcombo;
Screen->ComboC [Blockposition] = blockCset;
Screen->ComboF [Blockposition] = blocksecret;
disapear = 1;}
}

if (Link->Dir == 1){
blockcheckY = Link->Y + 32;
blockcheckX = Link->X;
RmndrX = blockcheckX % 16;

if (RmndrX <= 8){
blockcheckX = blockcheckX - RmndrX;
}
else
{
blockcheckX = blockcheckX + 16 - RmndrX;
}

RmndrY = blockcheckY % 16;

if (RmndrY <= 8){

blockcheckY = blockcheckY - RmndrY;
}
else
{
blockcheckY = blockcheckY + 16 - RmndrY;
}

if (ComboAt(blockcheckX, blockcheckY) == 0){
BlockrmndrX = blockX % 16;

if (BlockrmndrX <= 8){
blockX = blockX - BlockrmndrX;
}
else
{
blockX = blockX + 16 - BlockrmndrX;
}
BlockrmndrY = blockY % 16;

if (BlockRmndrY <= 8){

blockY = blockY - BlockrmndrY;
}
else
{
blockY = blockY + 16 - BlockrmndrY;
}
Blockposition = (blockY & 240)+(blockX>>4);
Screen->ComboD [Blockposition] = blockcombo;
Screen->ComboC [Blockposition] = blockCset;
Screen->ComboF [Blockposition] = blocksecret;
disapear = 1;}
}


if (Link->Dir == 2){
blockcheckY = Link->Y;
blockcheckX = Link->X - 32;
RmndrX = blockcheckX % 16;

if (RmndrX <= 8){
blockcheckX = blockcheckX - RmndrX;
}
else
{
blockcheckX = blockcheckX + 16 - RmndrX;
}

RmndrY = blockcheckY % 16;

if (RmndrY <= 8){

blockcheckY = blockcheckY - RmndrY;
}
else
{
blockcheckY = blockcheckY + 16 - RmndrY;
}

if (ComboAt(blockcheckX, blockcheckY) == 0){
BlockrmndrX = blockX % 16;

if (BlockrmndrX <= 8){
blockX = blockX - BlockrmndrX;
}
else
{
blockX = blockX + 16 - BlockrmndrX;
}
BlockrmndrY = blockY % 16;

if (BlockrmndrY <= 8){

blockY = blockY - BlockrmndrY;
}
else
{
blockY = blockY + 16 - BlockrmndrY;
}
Blockposition = (blockY & 240)+(blockX>>4);
Screen->ComboD [Blockposition] = blockcombo;
Screen->ComboC [Blockposition] = blockCset;
Screen->ComboF [Blockposition] = blocksecret;
disapear = 1;}
}

if (Link->Dir == 3){
blockcheckY = Link->Y;
blockcheckX = Link->X + 32;
RmndrX = blockcheckX % 16;

if (RmndrX <= 8){
blockcheckX = blockcheckX - RmndrX;
}
else
{
blockcheckX = blockcheckX + 16 - RmndrX;
}

RmndrY = blockcheckY % 16;

if (RmndrY <= 8){

blockcheckY = blockcheckY - RmndrY;
}
else
{
blockcheckY = blockcheckY + 16 - RmndrY;
}

if (ComboAt(blockcheckX, blockcheckY) == 0){
BlockrmndrX = blockX % 16;

if (BlockrmndrX <= 8){
blockX = blockX - BlockrmndrX;
}
else
{
blockX = blockX + 16 - BlockrmndrX;
}
BlockrmndrY = blockY % 16;

if (BlockRmndrY <= 8){

blockY = blockY - BlockrmndrY;
}
else
{
blockY = blockY + 16 - BlockrmndrY;
}
Blockposition = (blockY & 240)+(blockX>>4);
Screen->ComboD [Blockposition] = blockcombo;
Screen->ComboC [Blockposition] = blockCset;
Screen->ComboF [Blockposition] = blocksecret;
disapear = 1;}
}
}
else
{
Blockposition = (blockY & 240)+(blockX>>4);
Screen->ComboD [Blockposition] = 0;
Screen->ComboF [Blockposition] = 0;
disapear = 0;
}

} //End of void run

} //End of Script

Saffith
01-19-2007, 07:55 PM
if (ComboAt(blockcheckX, blockcheckY) == 0){
I'm guessing you meant Screen->ComboS[ComboAt(blockcheckX, blockcheckY)].

Nimono
01-19-2007, 08:15 PM
Also, look at this:


int disapear = 0;

void run(){

int blockcheckY = 0;
int blockcheckX = 0;
float RmndrX = 0;
float RmndrY = 0;
float BlockrmndrX = 0;
float BlockrmndrY = 0;
int Blockposition = 0;

if (dispear == 0){
You misspelled "disappear" BOTH times. Technically, all that matters is that the first and last variables there aren't the same, so that'll give you many problems. Oh yeah, and thanks for stealing my variables. :mad: Just kidding. ;)

Fire Wizzrobe
01-19-2007, 11:20 PM
Now I seem to be having the same problem as Pikaguy.. the block appears only in the right hand corner and the disappearing function does not work.. Maybe my algorithm is messed up?


import "std.zh"
item script Somaria{

int blockY = 0;
int blockX = 0;
int blockcombo = 0;
int blocksecret = 0;
int blockCset = 0;
int disapear = 0;
int Blockposition = 0;

void run(){

int blockcheckY = 0;
int blockcheckX = 0;
float RmndrX = 0;
float RmndrY = 0;
float BlockrmndrX = 0;
float BlockrmndrY = 0;


if (disapear == 0){

if (Link->Dir == 0){
blockcheckY = Link->Y - 32;
blockcheckX = Link->X;
RmndrX = blockcheckX % 16;

if (RmndrX <= 8){
blockcheckX = blockcheckX - RmndrX;
}
else
{
blockcheckX = blockcheckX + 16 - RmndrX;
}

RmndrY = blockcheckY % 16;

if (RmndrY <= 8){
blockcheckY = blockcheckY - RmndrY;
}
else
{
blockcheckY = blockcheckY + 16 - RmndrY;
}

if (Screen->ComboS[ComboAt(blockcheckX, blockcheckY)] == 0){
BlockrmndrX = blockX % 16;

if (BlockrmndrX <= 8){
blockX = blockX - BlockrmndrX;
}
else
{
blockX = blockX + 16 - BlockrmndrX;
}
BlockrmndrY = blockY % 16;

if (BlockrmndrY <= 8){

blockY = blockY - BlockrmndrY;
}
else
{
blockY = blockY + 16 - BlockrmndrY;
}
Blockposition = (blockY & 240)+(blockX>>4);
Screen->ComboD [Blockposition] = blockcombo;
Screen->ComboC [Blockposition] = blockCset;
Screen->ComboF [Blockposition] = blocksecret;
disapear = 1;}
}

if (Link->Dir == 1){
blockcheckY = Link->Y + 32;
blockcheckX = Link->X;
RmndrX = blockcheckX % 16;

if (RmndrX <= 8){
blockcheckX = blockcheckX - RmndrX;
}
else
{
blockcheckX = blockcheckX + 16 - RmndrX;
}

RmndrY = blockcheckY % 16;

if (RmndrY <= 8){

blockcheckY = blockcheckY - RmndrY;
}
else
{
blockcheckY = blockcheckY + 16 - RmndrY;
}

if (Screen->ComboS[ComboAt(blockcheckX, blockcheckY)] == 0){
BlockrmndrX = blockX % 16;

if (BlockrmndrX <= 8){
blockX = blockX - BlockrmndrX;
}
else
{
blockX = blockX + 16 - BlockrmndrX;
}
BlockrmndrY = blockY % 16;

if (BlockrmndrY <= 8){

blockY = blockY - BlockrmndrY;
}
else
{
blockY = blockY + 16 - BlockrmndrY;
}
Blockposition = (blockY & 240)+(blockX>>4);
Screen->ComboD [Blockposition] = blockcombo;
Screen->ComboC [Blockposition] = blockCset;
Screen->ComboF [Blockposition] = blocksecret;
disapear = 1;}
}


if (Link->Dir == 2){
blockcheckY = Link->Y;
blockcheckX = Link->X - 32;
RmndrX = blockcheckX % 16;

if (RmndrX <= 8){
blockcheckX = blockcheckX - RmndrX;
}
else
{
blockcheckX = blockcheckX + 16 - RmndrX;
}

RmndrY = blockcheckY % 16;

if (RmndrY <= 8){

blockcheckY = blockcheckY - RmndrY;
}
else
{
blockcheckY = blockcheckY + 16 - RmndrY;
}

if (Screen->ComboS[ComboAt(blockcheckX, blockcheckY)] == 0){
BlockrmndrX = blockX % 16;

if (BlockrmndrX <= 8){
blockX = blockX - BlockrmndrX;
}
else
{
blockX = blockX + 16 - BlockrmndrX;
}
BlockrmndrY = blockY % 16;

if (BlockrmndrY <= 8){

blockY = blockY - BlockrmndrY;
}
else
{
blockY = blockY + 16 - BlockrmndrY;
}
Blockposition = (blockY & 240)+(blockX>>4);
Screen->ComboD [Blockposition] = blockcombo;
Screen->ComboC [Blockposition] = blockCset;
Screen->ComboF [Blockposition] = blocksecret;
disapear = 1;}
}

if (Link->Dir == 3){
blockcheckY = Link->Y;
blockcheckX = Link->X + 32;
RmndrX = blockcheckX % 16;

if (RmndrX <= 8){
blockcheckX = blockcheckX - RmndrX;
}
else
{
blockcheckX = blockcheckX + 16 - RmndrX;
}

RmndrY = blockcheckY % 16;

if (RmndrY <= 8){

blockcheckY = blockcheckY - RmndrY;
}
else
{
blockcheckY = blockcheckY + 16 - RmndrY;
}

if (Screen->ComboS[ComboAt(blockcheckX, blockcheckY)] == 0){
BlockrmndrX = blockX % 16;

if (BlockrmndrX <= 8){
blockX = blockX - BlockrmndrX;
}
else
{
blockX = blockX + 16 - BlockrmndrX;
}
BlockrmndrY = blockY % 16;

if (BlockrmndrY <= 8){

blockY = blockY - BlockrmndrY;
}
else
{
blockY = blockY + 16 - BlockrmndrY;
}
Blockposition = (blockY & 240)+(blockX>>4);
Screen->ComboD [Blockposition] = blockcombo;
Screen->ComboC [Blockposition] = blockCset;
Screen->ComboF [Blockposition] = blocksecret;
disapear = 1;}
}
}
else
{
Blockposition = (blockY & 240)+(blockX>>4);
Screen->ComboD [Blockposition] = 0;
Screen->ComboF [Blockposition] = 0;
disapear = 0;
}

} //End of void run

} //End of Script

beefster09
01-20-2007, 12:43 AM
WHAT?! That's not what the Cane of Somaria did in ANY Zelda game. Maybe that script should be called "the Second Cane of Somaria".

Double-check your script some more. One time, I accidentally forgot to close an "if" statement, which created my "Cane only works when facing North" problem. XD You may have forgotten some braces here and there (Brackets are [], parentheses are (), and BRACES are {}.), so check back over it. It never hurts to double-check your work before you release it, as I have just recently RElearned. (My first learning of it was when I released Adventure in Mysteria. XD I'll never make THAT mistake with quests again.) Then again, it CAN take some people a while to fix some obvious bugs... Sometimes, answers are directly in front of your face, but you'll often miss them. Anyways... Good luck on your script.

I'm absolutely crazy how I organize my scripts, well how I structure them anyway. ALWAYS, In comments, I put end... and then whatever structural element I'm using I'll add. (i.e. // end while, // end ffc script) It helps me a lot. Also, I always indent and space between elements and everything. You'll know what I'm talking about when I release my Modern-style Beamos script. but that's just me. It makes it a lot easier to deal with later on.

And Fire Wizz, I think you need an ffc script for it to work. Check that the block placer is using variables and not constants. I've had that happen to me when using TI-BASIC.