HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Getting variable value if you have variable name as string

08-04-2007, 05:09 PM#1
Lej
Is there any easy way to get the value of an member of a struct when you have the variables name as a string so you can easily loop through a lot of variables. I don't want to use arrays as it limits the max numbers of structs to much.

Collapse JASS:
struct example
    integer number1 = 123
    integer number2 = 234
    integer number3 = 6325
    integer number4 = 986
    
    method getnumbervalue takes nothing returns nothing
    
        local integer i = 1
    
        loop
            exitwhen i > 4
            //Get value of the member number'i' here
        endloop

    endmethod
endstruct
08-04-2007, 05:15 PM#2
DioD
funtion number1 takes nothins returns nothing
set some global = 99
endfunction

funtion number2 takes nothins returns nothing
set some global = 99
endfunction

other function is

call ExecuteFunc("number" + I2S(number))
08-04-2007, 05:20 PM#3
Lej
Hmm I guess I could use something like that but instead of a global I could use a temp integer in the struct if I pass the struct as a second argument to the functions to avoid problems with multi instancing?

meh was thinking of .execute() which takes arguments but I can't use that with a string...
08-05-2007, 02:22 AM#4
DioD
you may force new struct fo store temporal data.

or use game cache
08-05-2007, 02:55 AM#5
PipeDream
Random access, my old favorite warcraft topic. Plug for DARY, and plug for vJass's dynamic arrays. See the JassHelper readme.
08-05-2007, 04:29 PM#6
Lej
Quote:
Originally Posted by PipeDream
Plug for DARY, and plug for vJass's dynamic arrays.
I did look at dynamic arrays but what I got from the manual it's to limited.
Quote:
Originally Posted by JassHelper Manual
Dynamic arrays are arrays you can instanciate dynamically, EACH custom array type has got a limit of 8190 TOTAL indexes, that means that an array type of size 100 has got an 81 instances limit.

This is for a td kind of map and one of these structs is going to be attached to each tower and the wanted arrays was to be used to store the upgrade/spell levels. I really want the system not to be limited to how many upgrades that can be added. Let's say 30 upgrades, then that means an 8190/30=273 instance limit. With 9 players that's around 30 towers each. That might work depending on how the player build but if I add more upgrades or players the limit will drop even more?

Gonna look for/at Dary.
08-05-2007, 06:40 PM#7
grim001
Why the hell do you need a member array to "store upgrade/spell levels" anyway?
08-05-2007, 08:26 PM#8
Lej
The abilities on the tower has a lot of levels (25) and I would prefer not to create many of those abilities as they affect load time pretty badly. So I want some way to store the abilities' levels in the tower struct in a way that makes them easy to loop through and access. Easy looping because the skill level-up system is going to use dialogs and those need to be generated. Many of the abilites are not really abilites at all but triggered effects. It doesn't need to be an array member, I'm open to suggestions.
08-05-2007, 09:16 PM#9
grim001
So why exactly does each tower need its own unique set of arrays of size 25 or 30? I think that your design goal isn't very clear here and it's leading you to make false assumptions about what you actually need.
08-05-2007, 10:42 PM#10
Lej
There is only one type of tower you can build. The tower can be upgraded with 30 different upgrades. Each tower got a struct attached to it.

On each tower there's a button to buy an upgrade. When you press the button a method upgrade is run on the struct attached to the tower. If the conditions are met (player got gold etc.) it continues.

A dialog with a dialogbutton for each upgrade is show. The text on the buttons is something like "<skillname> <current lvl>/<max lvl>". Max level is 25. All the dialogbuttons will probably not fit on the screen at once but that can be fixed by making a "next/previous page" dialogbutton. When a dialogbutton is pressed the level of that ability is set +1.

To generate this dialog I want to have a simple loop that goes from 1 to 'totalNumberOfSkills' and creates the dialogbuttons. This, I think, could be easily done by having an integer array member of the size 'totalNumberOfSkills' that stored the level of each upgrade as well as a global array with the names of the skills. Thus when looping you could retrieve the name as well as the towers current level of the skill. The levels must be easily accessed as they are used in different triggers.

The towers will also be able to learn spells. These will also use dialogs to level-up. A button on the tower will allow you to select one of the learned spells to be the one in use.

The numbers 30 and 25 are only what's currently used and should be considered minimums.

The upgrades are to be things such as improved damage, attack speed, range, slow, debuffs, area effect for all learned abilities, etc. The stuff is mostly triggered and not actually abilities added to the towers. The most important thing I guess is that it's easy to add new upgrades and spells. This is how I want it to work. Hope I made it a bit clearer.
08-06-2007, 02:40 AM#11
grim001
Now that I know your actual goal there should be a better way to do it.

It seems that each tower actually does need a place to store 30+ different numbers that you can iterate through.

Option A:
Split the upgrades into different categories so that you can have smaller array members. For example, 3 arrays of size 10.

Option B:
Declare several non-member dynamic arrays and switch to the next when you run out of space. This method would require a flag for which array to read from and an if/then chain inside the code for the dialog so that it reads the right array based on the flag.

Option C:
Use gamecache. Example:
Collapse JASS:
 call StoreInteger(gc, I2S(integer(towerstruct)), "AbilityName", abilitylevel)
Basically this method is attaching an integer to the struct under the name of the ability. GC is known to be slow but since you're just dealing with dialogs and integers here performance is not an issue.

You can also adapt this to the method you wanted to use to construct the dialog:
Collapse JASS:
 call GetStoredInteger(gc, I2S(integer(TowerStructs[n])), AbilityNames[n])

I think that the gamecache method is best here, and I normally hate gamecache so that's saying something.
08-06-2007, 11:13 PM#12
Lej
Yes, of those methods C seems to be the best. The only thing that worries me is the speed of the gamecache. With 9 players the amount of attacks per second will quickly add up. The triggers doing effects from attacks on the "takes damage" event will need to check the level of the abilities the attacking tower has.

Compared to reading from gamecache using H2I how fast is GetUnitAbilityLevel()? I tried to test this but ran into problems with big loops. If it's a lot faster maybe using dummy abilities to keep track of the levels and sacrificing loadtime to speed it up ingame is the way to go. I'd just have a global array with the ability ids instead of names.
08-07-2007, 12:30 AM#13
grim001
For keeping track of the level of abilities you should simply store it in regular non-array member... after all you don't need to loop through everything within a single ability.