I have two scripts that utilize the ThingCount function, where they monitor wether or not an object has been picked up before executing a script. The first script works fine but the second one, which is identical in structure to the first (save the variables) and acts completely irrational by looping the script indefinitly. These where scripts i was devolping for a sprite conversation system for those that are curious. I've included an example wad file.
What gives?
is this a bug? [No.]
Moderator: GZDoom Developers
Forum rules
Please don't bump threads here if you have a problem - it will often be forgotten about if you do. Instead, make a new thread here.
Please don't bump threads here if you have a problem - it will often be forgotten about if you do. Instead, make a new thread here.
-
- Posts: 10002
- Joined: Fri Jul 18, 2003 6:18 pm
- Location: Idaho Falls, ID
It's not a bug, it's a misusage of ThingCount. From the wiki:
Now you're probably asking why the hell the first one works but the second doesn't. To understand that, you have to understand that all strings in ACS are converted to numbers at compile time. The actual strings are then stored in a string table. For example, when the compiler processes your script, this is what gets put in the string table:
In the actual code where the functions reference these strings, the compiler instead places a reference into the string table. For example, this:
becomes this:
Since ZDoom knows that it's looking for a string (due to the s: preceeding the number), it looks up string 4 and prints it to the screen, rather than simply printing "4". However, if ZDoom was expecting an int, it will use the actual number instead. Hence, this:
becomes this:
Which works perfectly because 0 = T_NONE, or no mask. When all things with a TID of x_tid are gone, the while ends. As far as YOU see, it's working as intended. However, this line:
becomes this:
Now ZDoom is looking for a specific type of thing; in this case, a chaingunner. Since you don't have any chaingunners with a TID of x_tid, the result will always be 0 and the script will behave incorrectly.
Fixing the script in this instance should be easy. Just replace the first argument of each thingcount call to T_NONE. As long as you don't have any other things in the level that use the same TIDs, you should be set. If you absolutely need to specify the thing type, you can find the list in your zdefs.acs file. The ones you're looking for in this case are T_ARMORBONUS and T_REDKEYCARD.
You're trying to use a string for the type instead of an int. Due to that, you'll get unpredictable results.int ThingCount(int type, int tid);
Now you're probably asking why the hell the first one works but the second doesn't. To understand that, you have to understand that all strings in ACS are converted to numbers at compile time. The actual strings are then stored in a string table. For example, when the compiler processes your script, this is what gets put in the string table:
Code: Select all
String 0: "ArmorBonus"
String 1: "DeadDoomImp"
String 2: "RedCard"
String 3: "DeadMarine"
String 4: "Same script, different objects, what gives?"
String 5: "This is how it should behave"
Code: Select all
hudmessage (s: "Same script, different objects, what gives?"; HUDMSG_TYPEON | HUDMSG_LOG, 0, CR_WHITE, 0.5, 0.75, 0.0, 0.05, 2.0);
Code: Select all
hudmessage (s: 4; HUDMSG_TYPEON | HUDMSG_LOG, 0, CR_WHITE, 0.5, 0.75, 0.0, 0.05, 2.0);
Code: Select all
while (thingcount ("ArmorBonus", x_tid))
Code: Select all
while (thingcount (0, x_tid))
Code: Select all
while (thingcount ("RedCard", x_tid))
Code: Select all
while (thingcount (2, x_tid))
Fixing the script in this instance should be easy. Just replace the first argument of each thingcount call to T_NONE. As long as you don't have any other things in the level that use the same TIDs, you should be set. If you absolutely need to specify the thing type, you can find the list in your zdefs.acs file. The ones you're looking for in this case are T_ARMORBONUS and T_REDKEYCARD.
-
- Posts: 4019
- Joined: Fri Aug 15, 2003 8:15 pm
- Location: ferret ~/C/ZDL $
-
- Posts: 10002
- Joined: Fri Jul 18, 2003 6:18 pm
- Location: Idaho Falls, ID
This is also the reason that you can't add strings together and have them work as expected. Consider this example using the string table above:
Imagine the coder's surprise when this is spewed out instead:
and that 5 then converts to the above string (due to the s:), it makes perfect sense.
Code: Select all
Print(s: "DeadDoomImp" + "Same script, different objects, what gives?");
Once you understand that the line becomes"This is not how it should behave"
Code: Select all
Print(s: 1 + 4);