• 🏆 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!

[vJASS] Alternative to code array?

Status
Not open for further replies.
Level 17
Joined
Sep 8, 2007
Messages
994
Short Version:
Is there an alternative to a code array, or rather is there a way to let a struct's attribute be of type code?
JASS:
private struct Example
        
        code c

        public static method create takes code c returns thistype
            local thistype data = thistype.allocate()
            set data.c = c
            return data
        endmethod
   endstruct

Long Version:

Ok here's the situation:

I have 6 different itemtypes and a hero that can pick up up to 3 of those, including multiple items of the same type.
That hero has an ability. Everytime he casts it, I want to run a different trigger depending on the items he's got. Taking NO_ITEM as an option, that makes 7 * 7 * 7 = 343 possibilities of carrying a set of items, which can easily be saved in a database like this, using a triple nested loop:

JASS:
private function Settings takes nothing returns nothing 
        local integer i = 0
        local integer j = 0
        local integer k = 0
        local integer array i1
        
        set i1[0] = 0
        set i1[1] = FIRE_ID
        set i1[2] = WATER_ID
        set i1[3] = NATURE_ID
        set i1[4] = LIGHT_ID
        set i1[5] = DARK_ID
        set i1[6] = HUMAN_ID
        
        //adding ALL possible partitions, filtering internally for doubles
        loop
            exitwhen i > 6
            
            loop
                exitwhen j > 6
                loop
                    exitwhen k > 6
                    call FormulaData.create(i1[i],i1[j],i1[k])
                    
                    set k = k + 1
                endloop
                set j = j + 1
                set k = 0
            endloop
            set i = i + 1
            set j = 0
        endloop
        
        call FormulaData.stopAdd()
    endfunction

   private struct FormulaData
   
        readonly integer array id[3]
        readonly static integer cnt = 0
        private static boolean add = true
        private static thistype array dt[MAX_ARRAY_SIZE]
        
        public static method stopAdd takes nothing returns nothing
            set add = false
        endmethod
        
        public static method create takes integer id1, integer id2, integer id3 returns thistype
            local thistype data = thistype.allocate()
            
            set data.id[0] = id1
            set data.id[1] = id2
            set data.id[2] = id3
            
            call data.sort()
            
            //if not already saved into database, save it
            if get(data.id[0], data.id[1], data.id[2]) == 0 and add then
                set dt[cnt] = data
                set cnt = cnt + 1
            endif
            
            return data
        endmethod
        
        private method sort takes nothing returns nothing
            local integer temp
            
            if (this.id[0] < this.id[1]) then
                set temp = this.id[0]
                set this.id[0] = this.id[1]
                set this.id[1] = temp
            endif
            
            if (this.id[1] < this.id[2]) then
                set temp = this.id[1]
                set this.id[1] = this.id[2]
                set this.id[2] = temp
            endif
            
            if (this.id[0] < this.id[1]) then
                set temp = this.id[0]
                set this.id[0]= this.id[1]
                set this.id[1] = this.id[0]
            endif
        endmethod
        
        public static method get takes integer id1, integer id2, integer id3 returns thistype
            local integer i = 0
            loop
                exitwhen i > cnt
                if dt[i].id[0] == id1 and dt[i].id[1] == id2 and dt[i].id[2] == id3 then
                    return dt[i]
                endif
                set i = i+1
            endloop
            
            return 0
        endmethod

I tried to use a code-attribute in the corresponding FormulaData object to trigger further actions, but apparently I can't, because code arrays aren't allowed (struct attributes will internally be compiled to arrays).

Any idea? :(
 
You can basically have code arrays with the return bug.

JASS:
library CodeArray requires Typecast
    
    globals
        private integer array A
    endglobals

    struct CodeArray

        method operator[]= takes integer index, code func returns nothing
            set A[index] = C2I(func)
        endmethod

        method operator[] takes integer index returns code
            return I2C(A[index])
        endmethod

    endstruct

endlibrary
Not sure if you want to rely on that though.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
I wouldnt really rely on that return bug too much, because it will most likely get fixed + it requires either manual edit of the .j file, or pJass that has //# nosemanticerrors because most likely even standard wc3 compiler wont eat this.

you can use boolexpr array, trigger array or as mentioned, you can also go use function interfaces, which even have parameter type "safety".

I disagree with Almia, since .execute does exactly the same thing as function interfaces do, invoking triggers.
 
Status
Not open for further replies.
Top