• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Lua][vJass] New Table

Level 6
Joined
Jun 20, 2011
Messages
249
And he's correct, but the order you use them is irrelevant because you would reach the var in the same way anyways...
tb[1][2] = 3
tb[2][1] = 3
However the Parent can't go over 8190 because it's a struct array allocator, but the child is a hashtable index, so it can go beyond.
Anyways, i've never ever had to use TableArray anyways, you can always avoid it
 
Level 7
Joined
Oct 11, 2008
Messages
304
JASS:
struct S extends array
     static TableArray ta
     /* Is basically 'the same' as */
     Table t

     method m ....
          set ta[this]['A000'] = 1
          set this.t['A000'] = 2

          if ta[this]['A000'] == 1 then
          endif
          if this.t['A000'] == 2 then
          endif
     endmethod
endstruct
 
Well, there's only a small difference between Table arrays and TableArrays :p

TableArrays need no initialization after setting them to TableArray[...]
Table arrays need you to check if the Table is equal to 0 or not before creating it ;o

TableArrays just make things cleaner :p

But you know what would be better? :D
A TableArray array 8)

JASS:
struct Hash extends array
    
    private static constant integer DEFAULT_SIZE = 0x2000
    private static TableArray array H4X
    
    static method operator [] takes integer i returns TableArray
        if H4X[i] == 0 then
            set H4X[i] = TableArray[DEFAULT_SIZE]
        endif
        return H4X[i]
    endmethod

endstruct

Demo

JASS:
// ...
set Hash[4680][1212]['A!8*'] = 9
// ...

And this would work 100% ^.^
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
You could always store Tables within Tables and have syntax like tb[2424234][0xFEFE][22][-69][101010101]

Of course you pretty much never need that level of complexity.

@Dirac, not so much that 8192 is the "limit" of TableArrays, it's just typically the most someone will ever need.

To prevent clashes, it would be impractical to create a large enough TableArray to support handle ID's and rawcodes for the first index. Which is why I wrote on the first post "if you need such a large index, store a Table within a Table, or even a TableArray".
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
And he's correct, but the order you use them is irrelevant because you would reach the var in the same way anyways...
tb[1][2] = 3
tb[2][1] = 3
However the Parent can't go over 8190 because it's a struct array allocator, but the child is a hashtable index, so it can go beyond.
Anyways, i've never ever had to use TableArray anyways, you can always avoid it

even if it's like this set ai = TableArray[2], parent ID's can still be reduced by this set ai[id-id+1][1] = 5...although you're right about the order...
one problem though, I cant destroy nor flush it...
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
What do you mean you can't destroy nor flush it?

call ta.destroy()
call ta.flush()

If you have a TableArray[2], you can access slots 0 and 1, not 1 and 0. It works exactly like a normal JASS array where it starts at 0 and ends at 8191. Actually, pretty much all arrays in computer science start at 0 and stop at "size - 1".

If you look at what I have going in the Retro library, I use what is basically a TableArray (but I did it with a hashtable at the time) with offsetting so I actually have 3-D arrays:

http://www.hiveworkshop.com/forums/2050808-post39.html
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
I can't destroy nor flush it coz it causes debug message errors...
But the problem is fixed now, coz I put it inside the loop...suppose to be outside...
I have same results even though I reverse the order like Dirac said...
JASS:
set ai = TableArray[2]
    loop
        set t = CreateTimer()
        set id = GetHandleId(t)
        set ai[id-id+1][1] = 88
        set ai[id-id+1][2] = 999
        set ai[id-id+1].string[1] = "hello"
        set ai[id-id+1].string[2] = "table"
        call BJDebugMsg(I2S(ai[id-id+1][1]))
        call BJDebugMsg(I2S(ai[id-id+1][2]))
        call BJDebugMsg(ai[id-id+1].string[1])
        call BJDebugMsg(ai[id-id+1].string[2])
        //TableArray Error: Tried to double-free instance:
        //but this is OK now, suppose to be ourside
        call ai.flush()
        set i = i-1
        set t = null
        exitwhen i==0
    endloop
 
Level 6
Joined
Jun 20, 2011
Messages
249
You didn't reverse the order.
[id-id] is equal to 0, don't know where are you getting at
You're storing a string over an integer instance
JASS:
ai[1][1] = 88
ai[1][2] = 999
ai[1].string[1] = "hello"
ai[1].string[2] = "table"
You're confusing the TableArray feature with common Table functionality.
ai[TableArray index][hashtable index] not the other way around.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
I recommend TimerUtils + structs for things like that. A timer is predictable and data attachment is an equally predictable utility. SetTimerData/GetTimerData has worked perfectly for years.

Generally, I recommend to use Table instances for more complicated storage needs. Tables are often used for the longer-term or if there is some crazy data structure going on, like an item recipe system.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
y does having 2 TableArrays[0x2000] in the same library cause them to bug up ? heres how im doing this
this is in the init function
JASS:
set itemIdTable = TableArray[0x2000]
            set itemDropTable = TableArray[0x2000]

here is the problem
JASS:
set this.index = this.index + 1
                    set this.percent = this.percent + percents[L]
                    set itemDropTable[this][index] = this.percent
                    set itemIdTable[this][index] = itemIds[L]

when i call this
JASS:
call BJDebugMsg( I2S( itemDropTable[this][L]))
                    call BJDebugMsg( I2S( itemIdTable[this][L]))

it displays the same values as the itemIdTable but when i use the
call BJDebugMsg( I2S( itemDropTable[this][L])) in between the
JASS:
                    set itemDropTable[this][index] = this.percent
                    set itemIdTable[this][index] = itemIds[L]
it displays the correct numbers
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
so from what i posted it looks like it should work ?

heres the full init method if that helps
JASS:
private static method onInit takes nothing returns nothing
            local trigger t = CreateTrigger()
            set unitTypeTable = Table.create()
            set unitIdTable = Table.create()
            set itemIdTable = TableArray[0x2000]
            set itemDropTable = TableArray[0x2000]
            call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_DEATH)
            call TriggerAddCondition( t, function thistype.deathEvent)
            set t = null
        endmethod

JASS:
method addItem takes integer itemId1, integer percent1, integer itemId2, integer percent2, integer itemId3, integer percent3, integer itemId4, integer percent4, integer itemId5, integer percent5 returns nothing
            local integer L = 1
            local integer array itemIds
            local integer array percents
            set itemIds[1] = itemId1
            set itemIds[2] = itemId2
            set itemIds[3] = itemId3
            set itemIds[4] = itemId4
            set itemIds[5] = itemId5
            set percents[1] = percent1
            set percents[2] = percent2
            set percents[3] = percent3
            set percents[4] = percent4
            set percents[5] = percent5
            loop
                exitwhen L > 5
                if itemIds[L] != 0 then
                    set this.index = this.index + 1
                    set this.percent = this.percent + percents[L]
                    set itemDropTable[this][index] = this.percent
                    set itemIdTable[this][index] = itemIds[L]
                    call BJDebugMsg( I2S( itemDropTable[this][L]))
                    call BJDebugMsg( I2S( itemIdTable[this][L]))
                endif
                set L = L + 1
            endloop
            if this.percent > 100 then
                call BJDebugMsg( "|c00ff0303WARNING|r |cffffcc00Please Change The Percents of the Items for unit with Item Type Id = |c00ff0303" + I2S( this.unitTypeId) + "|r 
                |cffffcc00as the items are over 100% which will cause bugs|r |c00ff0303WARNING|r")
            endif
        endmethod

edit: i got it to work another way just want to know y it doesnt work this way?
 
Last edited:
Level 29
Joined
Oct 24, 2012
Messages
6,543
You are debugging [this ][ L ], but it looks like you need to debug [this ][ index ].

sry when i edited the top post i didnt change that back to index. in this case tho index and L are the same values.

i attached the map itself so u can see the problem the one up top is the fixed version. the one labeled problem is the problem if u just start the test map u will see that the values r the same. thx for ur help
 

Attachments

  • System Item Drop System.w3x
    36.8 KB · Views: 62
Last edited:
Level 29
Joined
Mar 10, 2009
Messages
5,016
Found a nasty bug...
JASS:
scope BUG

struct Bug
    static Table t
   
    static method onInit takes nothing returns nothing
        local effect sfx = AddSpecialEffect("Abilities\\Spells\\NightElf\\Starfall\\StarfallCaster.mdl", 0,0)
        set t = Table.create()
        set t.effect[123] = sfx
        set t.player[123] = Player(1) //if I disable this line, it will work
        call DestroyEffect(t.effect[123])
    endmethod
endstruct

endscope
so the player and effect share the same childKey?

EDIT:

BTW, normal hashtable works;
JASS:
scope BUG

struct Bug
    static hashtable h = InitHashtable()
   
    static method onInit takes nothing returns nothing
        local effect sfx = AddSpecialEffect("Abilities\\Spells\\NightElf\\Starfall\\StarfallCaster.mdl", 0,0)
        call SaveEffectHandle(h, 123, 1, sfx)
        call SavePlayerHandle(h, 123, 2, Player(1))
        call DestroyEffect(LoadEffectHandle(h, 123, 1))
   endmethod
endstruct

endscope
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
Question.
How do i compare integers saved in the Table?
I tried something like this:
JASS:
if someTable[id] > SomeConstantInt then
    set someTable[id] = someTable[id] + 1
endif
But,errors says that I cannot compare Relative Type to Native Type.

if someTable[id] > SomeConstantInt then
==>
if (someTable[id] > SomeConstantInt) then
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
That is because Table drops Tables instead of integers, so due to Vexorian's compilation priorities it thinks you are trying to do an operator overload of an integer comparison. As others stated, the fix would be to either do a typecast "integer(table[data])" or simply set an integer variable to the Table variable (which you might do anyway, in case you need to repeat reference it).
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
BTW, normal hashtable works;
JASS:
struct Bug
    static hashtable h = InitHashtable()
   
    static method onInit takes nothing returns nothing
        local effect sfx = AddSpecialEffect("Abilities\\Spells\\NightElf\\Starfall\\StarfallCaster.mdl", 0,0)
        call SaveEffectHandle(h, 123, 1, sfx)
        call SavePlayerHandle(h, 123, 2, Player(1))
        call DestroyEffect(LoadEffectHandle(h, 123, 1))
   endmethod
endstruct

Why would that not work? I think you should compare to this :)
JASS:
struct Bug
    static hashtable h = InitHashtable()
   
    static method onInit takes nothing returns nothing
        local effect sfx = AddSpecialEffect("Abilities\\Spells\\NightElf\\Starfall\\StarfallCaster.mdl", 0,0)
        call SaveEffectHandle(h, 123, 1, sfx)
        call SavePlayerHandle(h, 123, 1, Player(1))
        call DestroyEffect(LoadEffectHandle(h, 123, 1)) // You're screwed :(
   endmethod
endstruct
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
@Troll, do you think I dont know how to use keys in HT's?, please read my post carefully, I'm NOT using the SAME key '1', Maker did that:

I did this:
call SavePlayerHandle(h, 123, 2, Player(1))
He did this:
call SavePlayerHandle(h, 123, 1, Player(1))

and BTW Im not complaining about hashtables anyway, but the Table made by Bribe, look at my post before that...
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Found a nasty bug...
JASS:
scope BUG

struct Bug
    static Table t
   
    static method onInit takes nothing returns nothing
        local effect sfx = AddSpecialEffect("Abilities\\Spells\\NightElf\\Starfall\\StarfallCaster.mdl", 0,0)
        set t = Table.create()
        set t.effect[123] = sfx
        set t.player[123] = Player(1) //if I disable this line, it will work
        call DestroyEffect(t.effect[123])
    endmethod
endstruct

endscope
so the player and effect share the same childKey?

EDIT:

BTW, normal hashtable works;
JASS:
scope BUG

struct Bug
    static hashtable h = InitHashtable()
   
    static method onInit takes nothing returns nothing
        local effect sfx = AddSpecialEffect("Abilities\\Spells\\NightElf\\Starfall\\StarfallCaster.mdl", 0,0)
        call SaveEffectHandle(h, 123, 1, sfx)
        call SavePlayerHandle(h, 123, 2, Player(1))
        call DestroyEffect(LoadEffectHandle(h, 123, 1))
   endmethod
endstruct

endscope

Pride is such a pity ...

As said for the table way you use the same keys but you don't with the native hashtable way, you just can't compare them ...

EDIT :
so the player and effect share the same childKey?

Obvioulsy yes, not hard to check anyway, the code is available.
So it's not a bug just an expected behavior, but yes you have to we aware about this.
If you really need to store different types of handle just use a struct.
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
Obvioulsy yes, not hard to check anyway, the code is available.
So it's not a bug just an expected behavior, but yes you have to we aware about this.
If you really need to store different types of handle just use a struct.

Truth to be told, I really didnt examine that the 'key' is set as a child, that's why it keeps on overwriting, well I guess TableArray is just fine to use...
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
I suppose it's worth to write this behavior in the Table documentation though.
That's not that obvious, i mean if you didn't use hashtables that way before.
And anyway, let's face it, people don't always read/understand a code before using it, you're a perfect example ^^
 
Level 6
Joined
May 11, 2013
Messages
205
Hello everyone. I need help with creating a table for map called Heroes and Armies x1.49 (example: Table who can shows numbers of creeps all allies/enemy hero icons, kills assists deaths and creep, kills and game time if possible)
 

Cokemonkey11

Spell Reviewer
Level 29
Joined
May 9, 2006
Messages
3,534
JASS:
/*
    | method flush takes nothing returns nothing
    |     flush all stored values inside of it
    |    
    | method remove takes integer key returns nothing
    |     remove the value at index "key"
    |    
    | method operator []= takes integer key, $TYPE$ value returns nothing
    |     assign "value" to index "key"
    |    
    | method operator [] takes integer key returns $TYPE$
    |     load the value at index "key"
    |    
    | method has takes integer key returns boolean
    |     whether or not the key was assigned
*/

Just chiming in here to let you know that this is absolutely unacceptable API design. You, under no circumstances, should change or remove behavior from the library you updated.

If your Table is meant to be completely different, then Table is an unacceptable name.

I suggest you take a look at this: http://www.youtube.com/watch?v=heh4OeB9A-c
 
Top