AGS v2.7 Final: Yet Another Edition

Started by Pumaman, Sat 13/11/2004 21:02:00

Previous topic - Next topic

RickJ

You might try making the char[]s 201+ bytes as below:
Quote
char name[201]; // Name of the character
char title[201]; // Character's job title

I bet other elements in your struct are zero as well when this problem occurs.

Rui 'Trovatore' Pires

#161
This is going to need some better documentation, I'm afraid. I don't understand, for instance, why

Code: ags
GUIControl *whichBut=GetGUIControlAtLocation(mouse.x, mouse.y);
if (whichBut==null) {
Ã,  if (gAction.Visible || gShort.Visible) {}
}


works and

Code: ags
GUIControl *whichBut=GetGUIControlAtLocation(mouse.x, mouse.y);
if ((gAction.Visible || gShort.Visible) && whichBut==null) {} 


gives the following error upon compiling:

QuoteError (line 628): Type mismatch: cannot convert 'null*' to 'bool'

And incidently, I've been experimenting with that "GetGUIAt(mouse.x,mouse.y) replacement a bit. WHY do we need to compare with null first? I mean, logically, if I just did stuff like "if (whichGUI.ID == INVENTORY)" and kept on with that sort of thing, why should ANYTHING happen when it returns "null" since I didn't code it?

EDIT - Ok, nevermind the 1st one, I just tripped on the answer - we can't use operators with this type. This should be documented indeed. But the second question remains.
Reach for the moon. Even if you miss, you'll land among the stars.

Kneel. Now.

Never throw chicken at a Leprechaun.

SSH

Er... would it work if you put more brackets around the == null comparison?

Indeed, it might make life easier if there was a shorthand like

if (something.safeID == INVENTORY)

where safeID was like ID, but was also defined for the null pointer too, as -1 or something

or even...

try { if (something.ID == INVENTORY) { .... } }
catch {}

:=
12

Pumaman

#163
QuoteYou might try making the char[]s 201+ bytes as below:

Exactly right. Your problem is that StrCopy assumes the destination has a 200 byte buffer (since all "string" variables are allocated one) and therefore blats over it, padding out the text with zeros.

I'll see about changing this behaviour because it is a bit odd, but for now do as Rick suggests and increase the char buffer lengths to 200.

Quoteif ((gAction.Visible || gShort.Visible) && whichBut==null) {}

gives the following error upon compiling:

Error (line 628): Type mismatch: cannot convert 'null*' to 'bool'

Well spotted, that's a bug in the compiler -- that line should compile fine. I'll get it fixed.

QuoteWHY do we need to compare with null first? I mean, logically, if I just did stuff like "if (whichGUI.ID == INVENTORY)" and kept on with that sort of thing, why should ANYTHING happen when it returns "null" since I didn't code it?

It's to do with the way object oriented systems work. If there is no GUI, then there is nothing to access in the script, so null is returned instead. If you then try and access the ID of nothing, it all breaks down and cries.

What I could do is rather than returning null, return some sort of dummy GUI object with an ID of -1 or something ... might make it easier for people to get to grips with.

Rui 'Trovatore' Pires

#164
QuoteEr... would it work if you put more brackets around the == null comparison?

Sadly, no. The following line:

if ((whichGUI!=null) && (whichBut!=null)) {

...displays the same operator error.

Er, I think I misunderstood the second part of your post, SSH. Was that "try" for me to try something?

EDIT - And

    if ((gAction.Visible || gShort.Visible) && (whichBut==null)) {}

still has the same error, too.
Reach for the moon. Even if you miss, you'll land among the stars.

Kneel. Now.

Never throw chicken at a Leprechaun.

Pumaman


SSH

No, try and catch are C++/Java keywords used to do exception handling. That way, you can make a piece of code never have any runtime errors occur. But I think that you should be able to use && and || on the boolean result of an == to null... CJ get fixing!
12

Rui 'Trovatore' Pires

Ok then, glad to have been of assistance in bug reporting. :)

QuoteWhat I could do is rather than returning null, return some sort of dummy GUI object with an ID of -1 or something

Actually, what about SSH's "safeID" suggestion? It sounds nice...
Reach for the moon. Even if you miss, you'll land among the stars.

Kneel. Now.

Never throw chicken at a Leprechaun.

Pumaman

QuoteNo, try and catch are C++/Java keywords used to do exception handling. That way, you can make a piece of code never have any runtime errors occur.

Oh dear, I can just imagine the chaos that would ensue if that was added. Whenever anybody got an error message they would start to wrap all their code in try-catch blocks to make the message go away, and then they'd wonder why their script wasn't working properly :P

QuoteActually, what about SSH's "safeID" suggestion? It sounds nice...

It's not possible. If the returned value is null, then there is no GUI there, nothing exists to ask for its SafeID.

Rui 'Trovatore' Pires

Ok then, your suggestion sounds nice. As long as we don't have to start by checking whether the thing is null, that's one of those little extra hassles no one really needs.
Reach for the moon. Even if you miss, you'll land among the stars.

Kneel. Now.

Never throw chicken at a Leprechaun.

Pumaman

I suppose you could argue the same about putting a semicolon at the end of all your lines; anyone who's done any Java or C# will be used to checking if things are null ... I guess it's just something you pick up with the language.

Anyway, I'll see what I can do because I agree that it would make things easier to use.

Rui 'Trovatore' Pires

Yeah, but anyone who's worked with previous versions of AGS has picked up the semicolon. And has ALSO picked up not-checking-for-null and related...
Reach for the moon. Even if you miss, you'll land among the stars.

Kneel. Now.

Never throw chicken at a Leprechaun.

SSH

#172
If our macros could be parameterised, and if we had the ?: operator...

#define SafeID(x) ((x == null) ? -1 : x.ID)


btw...

Having this semi-OOP stuff will make co-operative programming easier, but it would be great if there was a way to have multiple "files" in a global script and a way to import and export them
12

Scorpiorus

Thanks, Chris, for the fixes and new features for the beta 7. All the previous issues with compiling were successfully resolved. :)

Quote* Autocomplete now shows struct types as well as global variables.
Hehe, thanks for that. ;)

Quote* Added support for static member functions.
* Added support for protected member variables/functions.
These are great!
Sorry to bug you about autocomplete/calltips again, but the editor doesn't show parameters list for new static and protected functions, thus:

mouse.SetPosition(
and
this.SomeProtectedFunction(

won't show the list.

Quote from: Pumaman on Wed 22/12/2004 12:15:27
QuoteYou might try making the char[]s 201+ bytes as below:
Exactly right. Your problem is that StrCopy assumes the destination has a 200 byte buffer (since all "string" variables are allocated one) and therefore blats over it, padding out the text with zeros.
By the way, it just occured to me, what if we change character[].name variable with StrCopy? It's declared as char name[40]; in the built-in header.

Also there is a character[].scrname variable (char scrname[20]) which isn't readonly so when I'd tried doing:

StrCopy(character[ 0 ].scrname, "XXX");

...the following char GameCharacter::on variable was overwritten with 0. Not sure about variables of the next character in the character[] array.

I'm worried because we had questions like "How can I change character's name?" and the answer was in using StrCopy to alter character[].name.Ã,  :-\

QuoteI'll see about changing this behaviour because it is a bit odd
Maybe for now the compiler could allow declaring strings in structs and substitute string text; for char text[200];?

QuoteI suppose you could argue the same about putting a semicolon at the end of all your lines; anyone who's done any Java or C# will be used to checking if things are null ... I guess it's just something you pick up with the language.
Seconded! I would rather prefer to compare a returned value with null. I think it would be more conventionally correct for all object-reference-getting functions to return null if the object doesn't exist or is out of the coverage. Because if a dummy object is returned instead then I can't use null anymore. I believe, that means all such functions would return their own dummy object whereas others would still return null? Hmm, personally, it makes things confusing to me.

Pumaman

#174
QuoteSorry to bug you about autocomplete/calltips again, but the editor doesn't show parameters list for new static and protected functions

Oops, well spotted, I'll get it fixed.

QuoteBy the way, it just occured to me, what if we change character[].name variable with StrCopy? It's declared as char name[40]; in the built-in header.

Changing the name like this is ok -- StrCopy does a special check to see if the string is a character name variable, and if so limits it to 40 characters instead.

However, scrname is a very good point. I'll make it readonly, but the problem is that won't stop you passing it to StrCopy. Really, I hope nobody is silly enough to try and change the script name at runtime.

QuoteMaybe for now the compiler could allow declaring strings in structs and substitute string text; for char text[200];?

That's a possibility; I'd still like to implement string support properly but we'll see.

QuoteSeconded! I would rather prefer to compare a returned value with null. I think it would be more conventionally correct for all object-reference-getting functions to return null if the object doesn't exist or is out of the coverage. Because if a dummy object is returned instead then I can't use null anymore. I believe, that means all such functions would return their own dummy object whereas others would still return null? Hmm, personally, it makes things confusing to me.

Personally, I agree with you 100%. However, in terms of GetGUIAt, having to check for null is an "extra step" and I can see a lot of people complaining that "they never had to do that in 2.62, so why do they have to now?" and so forth -- therefore I'm quite tempted to add the dummy object.

Functions like OpenFile would still return null because you need to check for success anyway before using a file. (on a sidenote, should OpenFile become File.Open now that static funcs are implemented?)

The other possibility for GetGUIAt is to retain the old versions that return the GUI number, and then just have some sort of GetGUIByID(int id) function to return the GUI object if you need it.

Rui 'Trovatore' Pires

Yeah. Same for GetGUIObjectAt, if possible - it's kind of a pain to have to initialize a *thingy everytime I want to check for them, especially if in different functions.
Reach for the moon. Even if you miss, you'll land among the stars.

Kneel. Now.

Never throw chicken at a Leprechaun.

Scorpiorus

#176
I have just tried the following:

repeatedly execute:

GUI *gui = GetGUIAtLocation(mouse.x ,mouse.y);

if (gui == gInventory) {...}
if (gui == gIconbarÃ,  ) {...}
if (gui == gStatusbar) {...}

It didn't compile but, Redrum, maybe it is that what you're trying to convert the things to?

Could this be added, CJ?

It won't work with GUI objects since they can be objects of different types and didn't have names in 2.62 or earlier.

But names can be added automatically -- gInventory_Object0, gInventory_Object1, etc.

Unfortunately, the compiler won't allow to compare a base pointer with a pointer to an object of a child struct. I see a workaround in allowing pointer comparison regardless of their types but this is, of course, not the best solution as we may end up comparing two entirely different objects (although, such if-blocks shouldn't run at run time as long as both pointers don't hold nulls).

QuoteThe other possibility for GetGUIAt is to retain the old versions that return the GUI number, and then just have some sort of GetGUIByID(int id) function to return the GUI object if you need it.
So, you mean there will be no GUI* GetGUIAtLocation? But then it means that we still will have to use ID in object-oriented scripting? EDIT: On the other hand, we still, in any case, have to access many things through ID (in fact, that's the only way to iterate, since arrays of pointers are not supported). Hmm...


Quoteon a sidenote, should OpenFile become File.Open now that static funcs are implemented?
Seems reasonable to me.

Quote from: strazer on Mon 20/12/2004 08:40:41And how about making MODE_LOOK, MODE_USEINV etc. enums too?
Btw, a good idea -- thus the modes would be shown for the appropriate mouse function.

Rui 'Trovatore' Pires

Yes, Scorpiorus, that's quite what I was trying to do. And it was also in rep_execute.
Reach for the moon. Even if you miss, you'll land among the stars.

Kneel. Now.

Never throw chicken at a Leprechaun.

Radiant

Well, full-scale try/catching for errors is going way too far, obviously - but a bit more control over it would be nice. It seems rather arbitrary which errors crash your game, and which merely put a warning in the logfile, for instance. Also, I believe that teleporting to a non-existant room (especailly with the ^X debug command) should not crash your game, but for instance stay in the current room.

Jet Kobayashi Zala

Alrighty, thanks all. I didn't know about the 200 string size. Sorry about that. However, I don't know why I'm not using the character.name anyway which would work just as fine. Thanks CJ, Scorp, and all!

SMF spam blocked by CleanTalk