Jump to content
Sam.

Sam.'s misc WeiDU related questions

Recommended Posts

I hope it's okay if I ask a variety of not-necessarily related questions (mostly related to WeiDU coding) in the same topic rather than spamming the forum.  If not, I'll correct the error of my ways.  I'm not much of a WeiDU coder, and TBH I don't care for the style of the syntax:  I generally find it cumbersome and the opposite of intuitive.  Nevertheless, I'm interested in improving, and to that end, I have a few questions.  I'll try to keep it to a manageable number at a time.

ADD_ITEM_EQEFFECT: adds an equipping effect to an item. All variables except probability1 are 0 by default. This is a PATCH macro and function. 
[...]
SET header to number of extended header (starting from 1) the effect should be added to (by default the effect is added to every header). 
  1. Why does ADD_ITEM_EQEFFECT function call for you to set header ?  Looking at the underlying macro, I don't think it is even used?
  2. Is it typical for the bytes after the first null in the 8 bytes of a resref to contain garbage data, or am I doing something wrong?  I'm looking at items ATM, and it appears this is common.
  3. When reading a value (like a strref) with READ_LONG and then printing the value, why do I get negative values (often -1).  I would have expected this behavior with READ_SLONG, but not READ_LONG...

 

Share this post


Link to post
1 hour ago, Sam. said:
  1. Why does ADD_ITEM_EQEFFECT function call for you to set header ?  Looking at the underlying macro, I don't think it is even used?
  2. Is it typical for the bytes after the first null in the 8 bytes of a resref to contain garbage data, or am I doing something wrong?  I'm looking at items ATM, and it appears this is common.
  3. When reading a value (like a strref) with READ_LONG and then printing the value, why do I get negative values (often -1).  I would have expected this behavior with READ_SLONG, but not READ_LONG...

Might need @Wisp to weigh in.

  1. I think this is an oversight that can be removed from the docs & function parameters.
  2. If you are using READ_ASCII / WRITE_ASCII correctly, then you don't have to worry about it, so AFAIK nobody does.
  3. It looks like READ_LONG and READ_SLONG are identical in implementation.  My guess is WeiDU internally treats all numbers as signed 32-bit integers, so unsigned 32-bit integers aren't supported.

Share this post


Link to post
16 hours ago, Mike1072 said:
  1. I think this is an oversight that can be removed from the docs & function parameters.

That might count as breaking backwards compatibility (even thought it's really not), so while the documentation might be changed, I doubt the function will stop taking header.  While we're discussing potential changes, maybe the ADD_ITEM_EFFECT  and ADD_ITEM_EQEFFECT functions could return insert_point?

16 hours ago, Mike1072 said:
  1.  
  2. If you are using READ_ASCII / WRITE_ASCII correctly, then you don't have to worry about it, so AFAIK nobody does.

I'm generating code on the fly to recreate binary files.  I thought I could compare the original and new version to make sure everything was accounted for, but they are often not the same because of junk bytes behind the nulls.  It takes away a sanity check, but I'll make due.

 

16 hours ago, Mike1072 said:
  1.  
  2.  
  3. It looks like READ_LONG and READ_SLONG are identical in implementation.  My guess is WeiDU internally treats all numbers as signed 32-bit integers, so unsigned 32-bit integers aren't supported.

If anything I would have guessed it was a type casting issue when converting integers into strings.  If this really is the case, I'm shocked because doesn't that mean WeiDU couldn't do proper maths on numbers larger than signed 32-bit integers (and IE file formats do use UInt/ unsigned DWORDs, right)?  My issue is I am generating code on the fly with something like (modified for brevity):

SPRINT var "WRITE_LONG   0x000c  %IdentifiedName%        //  Identified Name (strref)"

and when %IdentifiedName% resolves to -1 I get:

WRITE_LONG   0x000c  -1        //  Identified Name (strref)

Which WeiDU chokes on.  I either have to quote every variable, or I have to add additional code to detect if the value is negative, which gets messy.  While we're at it, what's the best way to execute on-the-fly code?  Right now I'm writing to a temporary file and then INCLUDE ing it, but I feel like there has to be something better...

 

Another question or two:

4.  Is SET (as in "SET var = 123" or "SET var = ~%val%~") ever necessary to specify?

5.  What are the rules about spacing out components of commands?  For instance "SET var=123" seems to work just as well as "SET var = 123", but I've encountered other instances (none in particular come to mind ATM) where not adding enough spacing threw syntax errors.  Maybe it was not including enough spacing in STR_VAR or INT_VAR declarations in function calls.  I'll try to take note of a specific example next time I encounter one.

Share this post


Link to post
46 minutes ago, Sam. said:

If anything I would have guessed it was a type casting issue when converting integers into strings.  If this really is the case, I'm shocked because doesn't that mean WeiDU couldn't do proper maths on numbers larger than signed 32-bit integers (and IE file formats do use UInt/ unsigned DWORDs, right)?

Testing seems to confirm: the highest positive value supported is 2147483647 (binary 01111111 11111111 11111111 11111111)‬.  Adding to that will cause it to go negative.

46 minutes ago, Sam. said:

While we're at it, what's the best way to execute on-the-fly code?  Right now I'm writing to a temporary file and then INCLUDE ing it, but I feel like there has to be something better...

You can also use inlined files but it's the same idea.

46 minutes ago, Sam. said:

Another question or two:

4.  Is SET (as in "SET var = 123" or "SET var = ~%val%~") ever necessary to specify?

5.  What are the rules about spacing out components of commands?  For instance "SET var=123" seems to work just as well as "SET var = 123", but I've encountered other instances (none in particular come to mind ATM) where not adding enough spacing threw syntax errors.  Maybe it was not including enough spacing in STR_VAR or INT_VAR declarations in function calls.  I'll try to take note of a specific example next time I encounter one.

4. I always use SET.  The only time I think it's necessary is if you do something like SET EVALUATE_BUFFER ~%var%~ = 1.  It doesn't understand EVALUATE_BUFFER ~%var%~ = 1 by itself.
5. I always use spaces.  I know that hyphens can be interpreted as part of a variable name, so using spaces with operators (e.g. subtracting) can be important.

Share this post


Link to post

 

1 hour ago, Sam. said:

4.  Is SET (as in "SET var = 123" or "SET var = ~%val%~") ever necessary to specify?

SET is also necessary for Array constructs, probably for the same reasons as EVALUATE_BUFFER
SET $name(~key~) = 1

Share this post


Link to post

My recommendation is to use the function form of ADD_WHATEVER rather than the macro form. 

Share this post


Link to post

1. Looks like a copy-paste error. The doc was presumably adapted from ADD_ITEM_EFFECT. As it's unused, it's safe to remove (and I've done so).

3. Yes, TP2 integers are signed 32-bit. It was not a good choice for every conceivable situation.

4. SET and [ SET ] are not strictly equivalent. SET takes a syntactic type that allows EVAL and the array construct on the left-hand side, whereas [ SET ] only allows plain strings in the same position.

On 8/9/2019 at 9:00 PM, Sam. said:

While we're at it, what's the best way to execute on-the-fly code?  Right now I'm writing to a temporary file and then INCLUDE ing it, but I feel like there has to be something better...

As Mike said, an inlined file is the same thing but is entirely memory-resident and does not leave anything on the file system. Using REINCLUDE on an inlined file is the closet you get to invoking eval on a string in TP2, assuming that's what you want to do.

Share this post


Link to post

I am passing

STR_VAR str2 = "target"

to a function with the intent of setting the variable "str2" to the literal string "target".  WeiDU is throwing me the following warning:

WARNING: possible missing EVALUATE_BUFFER in
[STR_VAR "str2" = "target" for LAUNCH_PATCH_FUNCTION "ps_append_str_inline_unless_default"]

How can I convince WeiDU that I am doing what I intended without suppressing all warnings of this type?  All I can think of is

SPRINT target ~target~
STR_INT str2 = EVAL "%target%"

But this seems like terrible programming...

Share this post


Link to post

I think it throws that warning because you have a variable named target that you've initialized previously.  So, you could:

  • change the name or scope where the variable was used previously
  • perform your suggested abomination to hide the warning
  • disable all warnings of this type
  • leave the warning in place because it's doing its job

Share this post


Link to post

WeiDU is printing this warning because "target" evaluates to something other than its own string literal (the variable is set in the same scope from which you are calling the function).

There are no facilities for not having this warning under these circumstances, short of turning off the MODDER option. If "target" does not need to be set in the scope of the function, you can try to isolate it with another function or WITH_SCOPE.

Share this post


Link to post
29 minutes ago, Mike1072 said:

I think it throws that warning because you have a variable named target that you've initialized previously.  So, you could:

  • change the name or scope where the variable was used previously
  • perform your suggested abomination to hide the warning
  • disable all warnings of this type
  • leave the warning in place because it's doing its job

 

17 minutes ago, Wisp said:

WeiDU is printing this warning because "target" evaluates to something other than its own string literal (the variable is set in the same scope from which you are calling the function).

There are no facilities for not having this warning under these circumstances, short of turning off the MODDER option. If "target" does not need to be set in the scope of the function, you can try to isolate it with another function or WITH_SCOPE.

You are both right (of course).  I am using target as a literal and as a variable within the same function call:

STR_VAR str2 = "target" str4 = EVAL "%target%"

I seem to get my desired result, so I guess I'll live with the warnings for now because changing the variable names would complicate the code, but we'll see.

 

On an unrelated note, why does CREATE ~ITM~ leave the Item Animation field at 0x0000 instead of initializing it to the standard "none" value of 0x2020 ("  ")?

Share this post


Link to post
9 hours ago, Sam. said:

On an unrelated note, why does CREATE ~ITM~ leave the Item Animation field at 0x0000 instead of initializing it to the standard "none" value of 0x2020 ("  ")?

Because "none" is not a hex value... yes, the 0x2020 is the default for no animation... but that might not have occurred to the coder at the time and to "fix" that, you need to ask it from Wisp, preferably at WeiDU's own forum, rather than a question at a offsite. And then there's the "What if the user has no idea what they are doing... let's go with the default's, I am sure it's fine... KABOOM".

Share this post


Link to post
16 hours ago, Sam. said:

On an unrelated note, why does CREATE ~ITM~ leave the Item Animation field at 0x0000 instead of initializing it to the standard "none" value of 0x2020 ("  ")?

Largely because it's not a structurally important detail. A null value does not cause the game to crash and does not cause patches to fail or to corrupt the file. However, if you think 0x2020 is a better no-value value, I can certainly change it; it's the same deal with strrefs: -1 is a better no-value value than 0.

Share this post


Link to post
On 9/14/2019 at 6:02 AM, Wisp said:

it's the same deal with strrefs: -1 is a better no-value value than 0.

I certainly agree -1 is the best value for no-value strrefs.

On 9/14/2019 at 6:02 AM, Wisp said:

Largely because it's not a structurally important detail. A null value does not cause the game to crash and does not cause patches to fail or to corrupt the file. However, if you think 0x2020 is a better no-value value, I can certainly change it

A cursory test of ToSC shows no visible difference between 0x0000 and 0x2020 (and if any engine would care, I figure it would be the oldest), so I think the current behavior is fine.  No reason to change what isn't broken.  Thank you for the explanation.

Share this post


Link to post

Is there an analog to

OUTER_SET tmp = (~%prefix%~ STRING_EQUAL_CASE ~MOS~ = 1) ? 0 : 1

that uses the ternary operator but with strings instead of numbers?  Something like:

OUTER_TEXT_SPRINT tmp EVAL ((~%prefix%~ STRING_EQUAL_CASE ~MOS~ = 1) ? ~zero~ : ~one~)

(except that doesn't work).

Share this post


Link to post
Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...