PDA

View Full Version : Warning: Cast from Float to Bool.



CJC
01-12-2007, 02:29 AM
I'm working on a script to 'gimp' some Link Tile modifiers, so that they only appear after an item has been activated and only disappear upon the activation of another item.

To test it, I combined it with my dash boots script to create a new B-button item.

However, I've got an error message I can't repair. Though it doesn't damage compiling at all, it freezes ZC after 2 frames (Heavy calculations for no reason.)


The error message says "Warning: Cast from Float to Bool". As I'm unsure of what exactly that means, I was hoping I'd find an answer in here.




global script CJCitems{

int selectionflag;

void run(){
while(true){
if(selectionflag==112){

!TileMod();

} // end of item condition
else{
!TileKill();
}
}//end of while loop
} // end of void run


bool TileMod(){

int item_number;
int item_state;

if(selectionflag==112){
if( Link->Item[113] ){
return false;
}
else{
if (item_number > 0 && item_number < 255){
if (item_state == 0 || item_state == 1){
item_state = 1;
Link->Item[113] = item_state;
}
}
}
}
}//! End of TileMod

bool TileKill(){

int item_number;
int item_state;

if(selectionflag==1){
if( Link->Item[113] ){
if (item_number > 0 && item_number < 255){
if (item_state == 0 || item_state == 1){
item_state = 0;
Link->Item[113] = item_state;
}//!End of item_state validation
}//!End of item_number validation
}
}
else{
return false;
}
}//! End of TileKill
}// end of global script

Above is the script in its entirety, but these are the parts that I'm really having problems with:





bool TileMod(){

int item_number;
int item_state;

if(selectionflag==112){
if( Link->Item[113] ){
return false;
}
else{
if (item_number > 0 && item_number < 255){
if (item_state == 0 || item_state == 1){
item_state = 1;
Link->Item[113] = item_state;
}
}
}
}
}//! End of TileMod

bool TileKill(){

int item_number;
int item_state;

if(selectionflag==1){
if( Link->Item[113] ){
if (item_number > 0 && item_number < 255){
if (item_state == 0 || item_state == 1){
item_state = 0;
Link->Item[113] = item_state;
}//!End of item_state validation
}//!End of item_number validation
}
}
else{
return false;
}
}//! End of TileKill





Selection flag is a set integer that's put into place by an item script on the boots item (Which is currently overlapping the 'Bait' item so that I could have it in my inventory.)
Other items that I had provided have a 'null selection' flag that changes the number to 1, a number that only makes the final 'if' statement true.


This portion of the script is designed to check if an item is in the inventory. If it is and the Selection flag is 112, then it does nothing. If the Selection flag is 112 but the item is not in the inventory, it adds it.
However, if the item is in the inventory and the Selection flag is 1, it removes it from the inventory. If it isn't there and the flag is 1, then the code does nothing.


What's confusing me is this 'Cast from Float to Bool' statement. It doesn't harm the script compiling, but it freezes ZC when the quest is loaded.
I need it to just process in the background. Right now it seems the interference between 'float' and 'bool'... whatever that means, is slowing the engine's calculations to a crawl.


EDIT: You'll pardon if the script isn't exactly horizontal-bar friendly... it's got a lot of scopes.

EDIT2: I snipped the 'Boots' code out of the global code, in the hopes it would run better. More in my reply.

Nick
01-12-2007, 02:45 AM
Essentially, that message should mean you are trying to convert what is essentially a rounded decimal (float) to a boolean (0 or 1). This works fine and dandy with integers so long as the integer is 1 or 0, but it's obviously not liking this with floats very much.

However... upon looking at the actual script, I dunno if that's the case. Why are TileKill() and TileMod() returning boolean values? The only calls to them I can see don't compare anything outside of the function, so why are they returning things? Wouldn't they be better as void functions or am I missing something?

Also, I dunno about ZScript, but in C++, any function that isn't void has to return something. I can see a few instances where nothing is returned if certain circumstances are met... so the function never terminates from memory?

I dunno if any of these things are right. They are just my guesses.

CJC
01-12-2007, 03:27 AM
Well, I really don't know anything about scripting or C++... everything I've been throwing together has been a tweak of something I saw in another script.

So I'm not real sure how to create a void function, or how it would work.


But to help other people spot the problem, I removed the portion of the code that was unnecessary to the situation (The dash boots, as they work already).

Tested again, I recieved the exact same error with no differences.



...I like the sound of a 'void' function, Nick. Maybe it could check to see if the item is there and then void the function so it isn't calculating constantly. But I don't know how to code that, as I haven't seen it anywhere else yet. So I'll try it, but I need a little guidance on the matter.


EDIT: Also, concerning the portions of the script that don't return anything... that was the only way I could conceive to check if Link didn't have the item in his inventory. As the one code I'm aware of checks if you own the item, I figured using an 'else' statement was the direction to take when you don't own the item.

Nick
01-12-2007, 04:13 AM
Hmm. When I said void, I was basically saying to replace bool TileMod() and bool TileKill() with void TileMod() and void TileKill(). When doing this, comment out those return statements within those functions and see what happens.

Also, IF statements don't require ELSE statements to be bundled with them. For instance rather than:


if (cheese == 3)
{
random_number = 42;
}
else
{
// Nothing is here. (about the same as your return statements)
}


if (cheese == 3)
{
random_number = 42;
}

Note that I didn't do anything else. This means that nothing will happen if the IF statement is not true. ELSE statements are used if you wish for an alternative action to happen if the IF test is not true.

Edit: I'm not really sure what those two functions are trying to accomplish, really. They are thrown out by themselves. I'm pretty much saying what I think might be the fix the current problem. I'm not sure if this will make the script work how you want it to work.

Edit 2: Well.. what I suggested makes pretty compile errors.

Edit 3: I want to slap myself in the face now. The new compile error with my change is because of:


if(selectionflag==112){

!TileMod(); // ---This line---

} // end of item condition
else{
!TileKill(); // ---And this line---
}


And as for what is causing the bool to float error... it's line 33 (for me):


Link->Item[113] = item_state;


...and line 50 (for me)...



Link->Item[113] = item_state;


Hmm... I'm not sure what's causing the slowdown and crash, though. My changes didn't really do anything at all in that regard.

Edit 4: On my continuing debugging (and rambling about it), I've noticed something strange with how you are defining (or rather, lack of defining) item state. It might not be necessary at all. I'm toying with that now.

Basically, you are comparing item state before you even define a value for it. You are doing the same thing with item number.

Edit 5: Well I'm miffed about this one. Even after I simplified things a great deal, it still locks up. Here's what I ended up with (though it may not even be what you were looking for... I'm halfway asleep now)

On a related note, you still need to define selectionflag. I couldn't really do that for you in this situation since I dunno how this script interfaces with anything else (you should have left that other code floating around for me to look at). I tried manually defining it and this bugger still locked up.


global script CJCitems{

int selectionflag;

void run(){
while(true){
if(selectionflag==112){

TileMod();

} // end of item condition
else{
TileKill();
}
Waitframe();
}//end of while loop
} // end of void run


void TileMod(){

//int item_number;
//int item_state;

if(selectionflag==112){
if(!Link->Item[113]){ // I tried comparing this (without !) to 0, but it didn't like that.
Link->Item[113] = 1;
}
}
}//! End of TileMod

void TileKill(){

if(selectionflag==1){
if( Link->Item[113]){ // I tried comparing this to 1, but it didn't like that either.
Link->Item[113] = 0;
}
}
}//! End of TileKill
}// end of global script

If I were more awake, I'd probably have a better chance of figuring out what the problem is. My guess is that it's not liking something about Link->Item[113]. I really don't know what, as I've had limited experience with the inner workings of the actual scripting. For all I know, I've completely screwed up on all of this. Sorry I wasn't of much help. :shrug:

Here is a question though: are global scripts even working? I know it's assumed they are, but are they actually working? No one has really tested them until now.

Edit 6: I just realized something that is missing. Waitframe();

Final Edit: And that was the problem. Added it to the above code. Whew! You can tell I'm new to this. :sweat:

The codebox above should compile and work, but I'm not sure it will do what you wanted it to do. This is partially because I have no clue what you were trying to do. If that code fails to satisfy you, then just add Waitframe(); to your loop in your version like I did with this one and it should at least execute without locking up ZC.

CJC
01-12-2007, 05:18 PM
Thank you, Nick. That fixed the freezeups, and let me assign my boots to a 'b' button item.


My intention was to make it add an item to the inventory when 'B' was pressed, so that that item could use it's tile modifiers on Link. Then, when you switched to a different item and pressed 'B' again, the modifier would be removed.
Unfortunately, it didn't work. Either the variable I set into my item script doesn't carry over to its global counterpart, or I'm coding it wrong.


Still, you fixed my freezeup, and I'm very grateful.




item script resetselectionflag {
void run() {

int selectionflag;

//This sets the item ID to one that isn't referenced in the global script.
selectionflag = 1;

Waitframe();
}
}//end of script

This is the reset flag script that I use on the item to set that selection flag to 1.




item script resetselectionflag {
void run() {

int selectionflag;

//This sets the item ID to the one in the Global script.
selectionflag = 112;

Waitframe();
}
}//end of script

And this is the one I use to set the selection flag to 112. Maybe I just need to pick a different item number (I figured 113 because it was a Zitem and I'd know which number it was. But maybe that's not as true as I thought.)

Or maybe the item variables just don't carry over to global. I don't know, I'll have to mess around with it some more.

But I just want to thank you again, for trying so hard. I feel badly that the biggest portion of the problem was caused by omitting a waitframe.

EDIT: Hmm... I just got a thought. Since the item script runs the frame after 'B' is pressed and no more, maybe I should try adding and removing the item in there. I'm going to give it a shot.









EDIT2: If found out why the item isn't being added to my inventory, and possibly why the script is freezing.



item script dashbootsflag {
void run() {


int selectionflag;
//ID is the item ID.
selectionflag = 112;

TileMod();

waitframe();

}
void TileMod(){

int item_number;
int item_state;
int item_stasis;

if(selectionflag==112){
if( Link->Item[113] ){
item_stasis = 1;
}
else{
if (item_number > 0 && item_number < 255){
if (item_state == 0 || item_state == 1){
Link->Item[113] = 1;
}
}
}
}
}//! End of TileMod
}//end of script






item script resetselectionflag {
void run() {

int selectionflag;

//This sets the item ID to one that isn't referenced in the global script.
selectionflag = 1;

TileKill();

Waitframe();
}
void TileKill(){

int item_number;
int item_state;
int item_stasis;

if(selectionflag==1){
if( Link->Item[113] ){
if (item_number > 0 && item_number < 255){
if (item_state == 0 || item_state == 1){
Link->Item[113] = 0;
}
}
}
}
}//! End of TileMod
}//end of script


In this script, I was trying to make the item set a global flag 'selection flag'. However, this flag doesn't seem to carry over from script to script. I need to replace it with a global variable, I believe, but I'm unsure of how to do that.
Also, the freezing seems to be caused by an infinite loop, possibly the item check and addition. I'm currently working on how to fix that, but pointers are welcome.







EDIT3: I've come up with a method of only checking for the inventory item once.


item script dashbootsflag {
void run() {


int selectionflag;
//ID is the item ID.
selectionflag = 12;

TileMod();

Waitframe();

}
void TileMod(){

int item_number;
int item_state;
int selectionflag;

if(selectionflag==12){
if( Link->Item[113] ){
selectionflag = 13;
}
else{
if (item_number > 0 && item_number < 255){
if (item_state == 0 || item_state == 1){
Link->Item[113] = 1;
}
}
}
}
}//! End of TileMod
}//end of script






item script resetselectionflag {
void run() {

int selectionflag;

//This sets the item ID to one that isn't referenced in the global script.
selectionflag = 1;

TileKill();

Waitframe();
}
void TileKill(){

int item_number;
int item_state;
int selectionflag;

if(selectionflag==1){
if( Link->Item[113] ){
if (item_number > 0 && item_number < 255){
if (item_state == 0 || item_state == 1){
Link->Item[113] = 0;
}
}
}
else{
selectionflag = 2;
}
}
}//! End of TileMod
}//end of script


In this new version, the 'action' assigned to the global (Not presented) can be triggered by both flags 12 and 13... but only flag 12 triggers an item check. If the player already has the item, the flag is converted to flag 13, which only triggers the global action.

Likewise, the item removal now has flags 1 and 2, where only flag 1 triggers the item check.

Still, without 'selectionflag' functioning as a global variable, it doesn't do me any good.