Struct array members all have the same value for each instance

dudeim

New Member
Reaction score
22
Hey,

ok so I'm having a problem with array struct members.

JASS:
//creating a random struct with struct array member
struct test

real array value[25] //so this is a simple real array with 25 indexes (or instance dunno precisly but doesn't matter)

endstruct
//ok now i'm gonna use another function to set values to the struct

function init takes....
local test a = test.create()
local test b = test.create()
//now i'm gonna set the values
set a.value[1] = 1
set b.value[1] = 2

call BJDebugMsg(R2S(a.value[1])) //displays 2 while it has to be 1
call BJDebugMsg(R2S(b.value[2])) //displays 2
endfunction


So am I doing something wrong or is it impossible to have array struct members for each instance or something? as that would be rather stupid.

Thanks
 

Sevion

The DIY Ninja
Reaction score
424
JASS:
//creating a random struct with struct array member
struct test

real array value[25] //so this is a simple real array with 25 indexes (or instance dunno precisly but doesn't matter)

endstruct
//ok now i'm gonna use another function to set values to the struct

scope sa initializer init
function init takes nothing returns nothing
local test a = test.create()
local test b = test.create()
//now i'm gonna set the values
set a.value[1] = 1
set b.value[2] = 2

call BJDebugMsg(R2S(a.value[1])) //displays 2 while it has to be 1
call BJDebugMsg(R2S(b.value[2])) //displays 2
set a.value[1] = 2
set b.value[2] = 3
call BJDebugMsg(R2S(a.value[1])) //displays 2 while it has to be 1
call BJDebugMsg(R2S(b.value[2])) //displays 2
set a.value[1] = 4
set b.value[2] = 5
call BJDebugMsg(R2S(a.value[1])) //displays 2 while it has to be 1
call BJDebugMsg(R2S(b.value[2])) //displays 2
set a.value[1] = 6
set b.value[2] = 7
call BJDebugMsg(R2S(a.value[1])) //displays 2 while it has to be 1
call BJDebugMsg(R2S(b.value[2])) //displays 2
endfunction
endscope


Works fine for me.
 

dudeim

New Member
Reaction score
22
Hmmm ok that does seem to work for me too, but why is this code not working then (my real problem code:p)

JASS:
scope ItemInit initializer init

private function init takes nothing returns nothing
local Item i = Item.create('I000') //custom create method to assign an index to an item type
local Item i2 = Item.create('I001') //Each item has their own struct instance so I can set data to each ItemType
set i.data[1] = 123
set i2.data[1] = 456
    
    call BJDebugMsg("value from i [" + I2S(i.data[1]) + ":::" + I2S(i)) //this displays "value from i [456:::1" should be "value from i[123:::1"
    call BJDebugMsg("Value from i2 [" + I2S(i2.data[1])+ ":::" + I2S(i2))//this displays "value from i2 [456:::2" this one is correct
    //so the instances of the struct are diffrent but why are the i.data[1] and i2.data[1] both 456
endfunction
//the create method is probably not the problem but if you want to see it just ask
endscope


So why is this not working then?
 

Narks

Vastly intelligent whale-like being from the stars
Reaction score
90
can we see the code where the struct is defined?
 

dudeim

New Member
Reaction score
22
Sure
It might be a bit messy
JASS:
library ItemData requires TimerUtils
    globals
    private integer index = 1
    hashtable Hash = InitHashtable()
    endglobals
    
    function SetItemData takes integer i returns integer
    if HaveSavedInteger(Hash, 0, i) == false then
        call SaveInteger(Hash, 0, i, index)
        set index = index + 1
    endif
	return index-1 //to return the index of this item id
endfunction

function GetItemData takes integer i returns integer
	return LoadInteger(Hash, 0, i)
endfunction

function HasItemData takes integer i returns boolean
    return HaveSavedInteger(Hash, 0, i)
endfunction    

    
    struct Item
        integer ThisItemId
        real array stats[26]
        real array leveladd[26]
        unit owner
        integer array data[5]
        
    
        implement ItemStats //aditional methods so this whole trigger stays small
        implement ItemMisc
    
    static method create takes integer itemid returns Item
        local Item i
        if HasItemData(itemid) == false then
            set i = Item(SetItemData(itemid))
            set i.ThisItemId = itemid
        else
            set i = Item(GetItemData(itemid))
        endif
        return i
    endmethod
    
    endstruct
endlibrary
 

Narks

Vastly intelligent whale-like being from the stars
Reaction score
90
i don't suppose you're running out of struct indexes to allocate (lots of items being allocated I guess)? declaring an array[26] as a member limits the number of instances you can have to about 307

but I'm guessing this is test code for this system and that's not the case


edit: it's probably your create method, you don't even have a call to allocate()

try something like

JASS:
static method create takes integer itemid returns Item
    local Item i
    if HasItemData(itemid) then
        return HaveSavedInteger(Hash, 0, itemid)
    endif
    set i = Item.allocate()
    i.ThisItemId = itemid
    SaveInteger(Hash, 0, itemid, i)
    return i
endmethod
 

dudeim

New Member
Reaction score
22
Thanks this worked didn't know .allocate was needed thought it was an extra simplere method to Structname(index)
And I probably won't have so many items registered but know I know the limit:p thanks;)
Well the weirdest thing whas that normal members (non-array) did have different values for the indexes
Rep+
 

Tyrulan

Ultra Cool Member
Reaction score
37
I take it you're used to languages like Java or C# which Allocate for you.
 

Solmyr

Ultra Cool Member
Reaction score
30
To make it clear, there's nothing wrong with your create method, even though you don't use [ljass].allocate()[/ljass]. However, inside the struct's allocator (that is generated by JassHelper and called by [ljass].allocate()[/ljass]), there is some stuff which makes sure that the array members of each different struct instance get different indices. You, on the other hand, don't have it (and doing it manually would be a pain in the ass), so you're basically doing this:

[ljass]set data[1] = 123[/ljass]
[ljass]set data[1] = 456 /* This overrides the previous value. */[/ljass]

Whereas, when you use [ljass].allocate[/ljass], the aforementioned turns into:

[ljass]set data[1] = 123[/ljass]
[ljass]set data[6] = 456[/ljass]

Now, as I believe that using [ljass].allocate()[/ljass] is completely senseless in this case, I would suggest you use dynamic arrays. It is quite easy:
JASS:
type itemStats extends real array [26]
type itemLevelAdd extends real array [26]
type itemData extends integer array [5]

struct Item
    integer ThisItemId
    itemStats stats
    itemLevelAdd leveladd
    unit owner
    itemData data

    method onDestroy takes nothing returns nothing
        call this.stats.destroy()
        call this.leveladd.destroy()
        call this.data.destroy()
    endmethod

    static method create takes integer itemid returns Item
        local Item i
        if (not HasItemData(itemid)) then
            set i = Item(SetItemData(itemid))
            set i.ThisItemId = itemid
        else
            set i = Item(GetItemData(itemid))
        endif
        set i.stats = itemStats.create()
        set i.leveladd = itemLevelAdd.create()
        set i.data = itemData.create()
        return i
    endmethod
endstruct


I take it you're used to languages like Java or C# which Allocate for you.
What you said here is completely irrelevant.
 

dudeim

New Member
Reaction score
22
Na what I'm using now works for me also I heard that you can't perfectly detect when an item is destroyed/created.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top