How do I use getString and getInt?
Displaying 1-9 of 9 total.
1
Please enter a numerical value for the importance of this sticky.
Enter 0 to unsticky.
Technetium

I'm working on an grid inventory system similar to Diablo or Baldur's Gate

I have a whole bunch of strings contained in item[character[].x].Name, such as character[].armor, character[].clothing, etc. These refer to the pieces of equipment currently equipped by the character. When you move the mouse over the equipment, a box will appear with information about the item. To set the dimensions of the box (which are based on the number lines of information and the textwidth of the longest line), I call a function:
calcboxloc_equip(int who, int which)

You pass the character reference (0-4) to tell it who's inventory you are looking at, and the equipment to tell it which you want information on. You would put "armor" to have it check character[ ].armor, for example.

The function contains the following code, which crashes verge without logging an error message:

longestString=textwidth(bluefont,getString("item[character[who]."+which+"].Name"));


I have tested the string separated, and it is perfectly valid. I don't know what the problem is here.

Posted on 2007-03-08 00:13:52 (last edited on 2007-03-08 00:15:34)

Overkill

The problem is that GetString() and GetInt() are for global string and int variables that are NOT arrays, and GetStringArray() and GetIntArray() are for one-dimensional global string and int arrays.

You can, however, do some hackery to manipulate values inside structures, but it's pretty out there and relies a lot on how structures and arrays get represented internally.

Here are the basic rules though to manipulate anything that is partially a global user-defined variable (local variables can't be manipulated, why would you want to?). These are scary. But I was bored one day and fudged around with things.

Let's define a structure for example purposes:

#define EQUIP_SLOTS 8
struct player_type
{
int hp;
int equipment[EQUIP_SLOTS];
};

player_type player;
player_type party[4];
There is a chr(1) (an unprintable character) added to the start of the variable's name if it's a structure. Nested structures will have several chr(1)s at the beginning. Where you'd use a "." normally, use a "_".

For example:

// Represents player.hp = 5;
SetInt(chr(1) + "player_hp", 5);
Whenever a structure has an array, you need to treat the variable as an array.
// Represents player.equip[2]
GetIntArray(chr(1) + "player_equip", 2);
// Represents party[3].hp
GetIntArray(chr(1) + "party_hp", 3);
Not bad? But, when there's more than one layer of arrays, then we get fun multiplication and adding. I can't really give you a good example for this off-hand, but, I know the pseudo-code algorithm for resolving a single array index out of the several:
let a variable (offset) represent the resultant one dimensional array index.
for each dimension in the variable:
let a variable called dimension offset (dimofs) be the index [] for that dimension
for each dimension after the current:
dimofs *= upper bound of dimension
offset += dimofs
GetIntArray(variable, offset);
I can confirm that these steps work, too. I wrote a crazy wrapper function to calculate the array offset based on a string of comma-separated indices (representing each [] needed), but it's a little too crazy. But eh, I suppose the damage's already done, so here you go:
int GetMultidimIntArray(string varname, string dim_list, string max_dim_list)
{
int i, j;
int ofs, dimofs;
int dim_count = TokenCount(dim_list, ",");
int passed_dim_count = TokenCount(dim_list, ",");
int max_dim_count = TokenCount(max_dim_list, ",");

// If a token's blank, ignore it.
while (!len(GetToken(dim_list, ",", 0)))
{
i++;
passed_dim_count--;
}

if (passed_dim_count != max_dim_count)
{
Exit("GetMultidimIntArray :: Expecting " + str(max_dim_count)
+ " dimensions but was passed " + str(passed_dim_count)
+ "! Get it right, jerk.");
}

for (i = 0; i < dim_count; i++)
{
dimofs = val(GetToken(dim_list, ",", i));
if (dimofs >= val(GetToken(max_dim_list, ",", i)) || dimofs < 0)
{
Exit("GetMultidimIntArray :: "
+ "Invalid index " + str(dimofs) + " passed to array '" + varname
+ "'. Index must be >= 0 and < " + GetToken(max_dim_list, ",", i) + ".");
}
for (j = i + 1; j < dim_count; j++)
{
dimofs = dimofs * val(GetToken(max_dim_list, ",", j));
}
ofs += dimofs;
}
return GetIntArray(varname, ofs);
}


I also have a corresponding setter function which is similar, and the the getter/setter for multi-dim string arrays. My guess is these are very slow. I dunno, I only used them to copy structures to each other. I was just bored when I was developing and wrote a test of the Set*()/Get*() behaviours based on the knowledge I developed of the source.

My recommendation, if possible, is to not go as far as I've gone. Accept that there are some crazy things that shouldn't be attempted through VC, and instead, use the useful stuff like the ability to nest structures and arrays and mish-mash of the two.

Posted on 2007-03-08 02:57:45 (last edited on 2007-03-09 00:55:21)

zonker6666

Overkill - thats lovely - and I'll be making use of it quite a bit --

even if it does happen to be slow itll be a tradeoff compared to the amount of typing thats required right now to say switch 2 structs withing an array - - yay for overkill!

Posted on 2007-03-08 22:59:39

CrazyAznGamer

Jesus, that's quite....
o_o
....
o_o

So.... when I was looking at the verge engine source.... o_o... wow.... hackery indeed.

I don't like the ideas this code is giving me....

EDIT:
"even if it does happen to be slow itll be a tradeoff compared to the amount of typing thats required right now to say switch 2 structs withing an array - - yay for overkill!"

Yay indeed, though personally, I implement linked list structures in vc. XD
But this... this may allow me to make a generic vc linked list structure...

Posted on 2007-03-09 00:31:37 (last edited on 2007-03-09 00:37:18)

Overkill

Crazy, I can't see larger linked list opportunities really being made here. Getter/Setter functions don't let you create new node structures on the fly, they only let you access existing ones. So you'd just make things slower by making the pointer to the next node be a string instead of an integer index in a global array. DMA, though, allows for actually-dynamic linked lists, with the downside of strings being unable to be directly stored and used, so that MIGHT be fast.

If I'm bored one day, I may add the ability to manipulate dynamically allocated memory as a string through builtins. It'd be faster than using your own VC wrapper functions to access strings, I bet.

Posted on 2007-03-09 01:05:28

zonker6666

Overkill - when using DMA i simply store a string as an int --- the int being a handle to a dictionary ---- unfortunately theres the downside of having to convert the ID to a string for the dictionary key ....

But again its a tradeoff im willing to go with --- dictionaries are fun!

Posted on 2007-03-09 02:21:17

Gayo

That is MAD ELEET, ovk. The thing about accessing struct members is genuinely useful and might be good to document somewhere. The rest of it's possibly a little too wingnut for the average user, though.

Posted on 2007-03-09 18:58:36

CrazyAznGamer

Well, while doing something I shouldn't be doing with verge code, I got curious about struct name conflicts. Allow my following piece of code to illustrate what I discovered:

struct ZOMGWTF
{
string name_zors; // testing behavior of get/set inting with underscores
}
ZOMGWTF omg_gayzorz;

struct WTFZOMG
{
string zors; // and possible dups
}
WTFZOMG omg_gayzorz_name;

VOID AUTOEXEC()
{
omg_gayzorz_name.zors = "YAY!";
omg_gayzorz.name_zors = "GAY!";

log(
getstring(chr(1) + "omg_gayzorz_name_zors")
);
log(omg_gayzorz_name.zors);
log(omg_gayzorz.name_zors);
}

The log output was:

GAY!
GAY!
GAY!

So apparently, structs can share the same data. Just putting it out there. But this really shouldn't affect people that much...

Posted on 2007-05-26 16:59:02

Overkill

Heh, maybe I should've corrected the compile-time naming of variables when I added nested structures. The chr(1) + structvarname was just the naming convention that was already used, and I didn't change that. "blah.whatever" naming would be a lot more sensical anyways.

Also, I recently added variadic functions to VergeC which would help make the get/set functions easier to use with multidimensional arrays. Variadic functions allow the arguments passed to the argument list be either ints or arguments.

Something like this would be cool:
GetVariable(string varname, ... dims);
SetVariable(string varname, ... dims); // Last dimension is the value.
Maybe have it so strings are struct attributes, and integers are array indices. The last argument is always the value for SetVariable.
// party.member[3].hp
GetVariable("party", "member", 3, "hp");
// party.member[0].equipment[2] = 57;
SetVariable("party", "member", 0, "equipment", 2, 57);


This could even be added VergeC-side right now, but it would be nicer if it were a builtin method, so that it's always up-to-date with the internal representation of the variable naming at runtime.

Posted on 2007-05-26 20:19:15 (last edited on 2007-05-26 20:23:53)


Displaying 1-9 of 9 total.
1
 
Newest messages

Ben McGraw's lovingly crafted this website from scratch for years.
It's a lot prettier this go around because of Jon Wofford.
Verge-rpg.com is a member of the lunarnet irc network, and would like to take this opportunity to remind you that regardless how babies taste, it is wrong to eat them.