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

[JASS] Few Questions

Status
Not open for further replies.
Level 5
Joined
Nov 22, 2009
Messages
181
thanks.
if a struct has an array member, why do all instances of that struct share the same variable? why doesn't it each struct have its own variable array?

can a single struct extend multiple interfaces?
 
Last edited:
Level 18
Joined
Jan 21, 2006
Messages
2,552
This was typed up just now in TextPad, you can do this in Java:

Code:
interface thisInterface {

}
interface thatInterface {

}

class MegaClass implements thisInterface, thatInterface {

}

You can even do:

Code:
interface thisInterface {

}
interface thatInterface {

}

class SuperMegaClass {

}
class MegaClass extends SuperMegaClass implements thisInterface, thatInterface {

}
 
Level 5
Joined
Nov 22, 2009
Messages
181
i have no idea what i'm looking at. its like a whole different language. lol

how do you set a variable equal to a preplaced object without using the variable editor?
 
Level 5
Joined
Nov 22, 2009
Messages
181
ok. is there any way to get a similar effect in vJass?

how do you set a variable = a preplaced object without using the variable editor?
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
In vJass terminology, the above code would appear as:

JASS:
interface panelA
endinterface

interface panelB
endinterface

struct parent
endstruct

struct child extends parent, panelA, panelB
endstruct

But that would give you a few syntax errors in vJass. The ways to achieve this in vJass are limited, but if your interface has only optional methods you can get away with it like so:

JASS:
struct panelA
endstruct

struct panelB
endstruct

struct parent
endstruct

struct child extends parent
    
    delegate panelA defaultA
    delegate panelB defaultB
    
endstruct
 
Level 5
Joined
Nov 22, 2009
Messages
181
i never understood the whole delegate thing. can you give and explain an example?

how do you set a variable equal to a preplaced object withought using the variable editor?
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Delegates act like "reverse" interfaces. If a method does not appear in the interface of a struct, but it does appear in a method of a delegate type, then it will use the delegate instead. I really wish Vexorian gave a better explanation as to the functionality of this, because if all these delegates are possible then he should easily be able to implement "real" interfaces. The interfaces that currently exist in vJass are more like abstract classes in Java.

JASS:
struct ActionList
    method runActions takes nothing returns nothing
    
    endmethod
endstruct

struct CommandList
    delegate ActionList     del_a
    
    static method create takes nothing returns thistype
        local thistype a = allocate()
        
        call a.runActions()
        return a
    endmethod
endstruct

Notice how CommandList doesn't have the method runActions? It will still work fine though since one of the struct's delegates has that method, so it will just use that.

how do you set a variable equal to a preplaced object withought using the variable editor?

When a unit is preplaced in the editor it gets a variable name, the prefix is gg_unit_. Then the type of the unit, and then the placement order in the World Editor. If you don't know what these values are, then just use a GUI trigger that allows you to select a pre-placed unit, then convert that trigger into custom text; there you will see the "name" of the preplaced unit.

Here's another example of delegates:

JASS:
struct ActionList
    real    b       = 1.0

    method runActions takes nothing returns nothing
        set b = b * 3
    endmethod
    
    method toValue takes nothing returns real
        return b
    endmethod
    
    method toString takes nothing returns string
        return R2S(b)
    endmethod
endstruct

struct CommandList
    delegate ActionList     del_a
    
    static method create takes nothing returns thistype
        local thistype a = allocate()
        
        set a.b = 2
        
        call a.runActions()
        call BJDebugMsg(R2S(a.toValue()))
        return a
    endmethod
endstruct

If you don't use set a.b = 2 then 0.00 will be printed. It seems that delegates allow the use of struct members as well as methods, though the struct members are not initialized as they were in the delegate struct. As I have it not 6.00 will be displayed.

But, if you have:

JASS:
struct ActionList
    real    b       = 1.0

    method runActions takes nothing returns nothing
        set b = b * 3
    endmethod
    
    method toValue takes nothing returns real
        return b
    endmethod
    
    method toString takes nothing returns string
        return R2S(b)
    endmethod
endstruct

struct CommandList
    delegate ActionList     del_a
    
    static method create takes nothing returns thistype
        local thistype a = allocate()
        set a.del_a = ActionList.create()
        
        //set a.b = 2
        
        call a.runActions()
        call BJDebugMsg(R2S(a.toValue()))
        return a
    endmethod
endstruct

Then you are assigning the value of the delegate to a newly created struct, so the set a.b = 2 is not necessary, as b will be initialized to 1.0 in the constructor of ActionList.
 
Level 5
Joined
Nov 22, 2009
Messages
181
ok that makes sense. although i dont really see how these could be used as interfaces. unless you mean to give this to whatever struct i want instead of having it extend the interface.
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Well what a delegate does is give any members that the delegate struct has to the delegating struct. This will allow you to re-define a method that the delegate struct has and use a member from the delegate in that method. If the delegate is not initialized (created) then the usefulness of it plummets. If it is initialized (I don't know why it's not initialized automatically) then it works in the exact same way as an interface would.

JASS:
struct exampleA
    real    r = 2
    
    method add takes nothing returns nothing
        set r=r+r
    endmethod

endstruct

struct exampleB

    delegate exampleA   a
    
    method add takes nothing returns nothing
        set r = r + r + r
    endmethod
    
    static method create takes nothing returns thistype
        local thistype m = allocate()
        set m.a = exampleA.create()
        
        call m.add()
        call BJDebugMsg(R2S(m.r))
        
        return m
    endmethod
    
    static method onInit takes nothing returns nothing
        call thistype.create()
    endmethod
    
endstruct

This will print out 6.00 because it will perform set r = r + r + r (r starts at 2) using a delegate's member. If you remove the method add from the delegating struct, then it will print out 4.00 because it will perform set r = r + r (r starts at 2).

If you've got a struct with many delegates, and those delegates share certain methods, then whichever delegate was declared first will take control of the actions that need to be performed.

Basically the delegate keyword just allows an automatic association of actions with the delegate object. If you were to not include the delegate keyword, and simply declare exampleA a then you would manually have to use a.add(). Since you're using a delegate, you can consider the add method apart of the delegating struct's interface.
 
Level 5
Joined
Nov 22, 2009
Messages
181
do you know why the game keeps crashing when i try to test it?
here is my entire script that i have entered into the map so far:
JASS:
globals
    integer array pindex//player index
    integer array lindex//to reference the owner of the instance of the struct: P
    integer MP = 0//max players
    boolean MIS = false
    boolean WG = false
    boolean AB = false
    boolean AV = false
    boolean ES = false
    boolean SA = false
    string array CS
    string CE = "c|"
    region array BG
    rect array BGR
    rect array ARSDB
    rect array ARSDBE
    rect array AHB
    rect array HRSDB
    rect array HRSDBE
    rect array HHB
    rect DZ 
    real DZX 
    real DZY 
    rect HTR 
    rect HCS 
    rect FDZ 
    group AH = CreateGroup()
    group HH = CreateGroup()
    group ASDB = CreateGroup()
    group HSDB = CreateGroup()
    item array M
    integer array MID
    stats array s
endglobals

struct stats
    private integer id
    static multiboard mb = CreateMultiboard()
    integer array fpu[3]//wg,es,total
    integer array fd[3]//wg,es,total
    integer array fc[3]//wg,es,total
    integer array ba[3]//ab,es,total
    integer array bd[3]//ab,es,total
    integer array bc[3]//ab,es,total
    integer array sd[3]//avtd,sagd,total
    integer array w[6]//wins
    integer array l[6]//losses
    integer array os[4]//wgfr,vu,vd,vl
    integer array bs[2]//k,d
    real kdr
    multiboarditem array mfpy[3]
    multiboarditem array mfd[3]
    multiboarditem array mfc[3]
    multiboarditem array mba[3]
    multiboarditem array mbd[3]
    multiboarditem array mbc[3]
    multiboarditem array msd[3]
    multiboarditem array mw[6]
    multiboarditem array ml[6]
    multiboarditem array mos[4]
    multiboarditem array mbs[3]
    
    method operator b= takes integer i returns nothing
        set.bs[i] = .bs[i] + 1
        set .kdr = I2R(.bs[0]/.bs[1])
        call MultiboardSetItemValue(.mbs[i], I2S(.bs[i]))
        call MultiboardReleaseItem(.mbs[i])
        set .mbs[i] = MultiboardGetItem(thistype.mb, 4 + .id, 3 + i)
        call MultiboardSetItemValue(.mbs[2], R2S(.kdr))
        call MultiboardReleaseItem(.mbs[2])
        set .mbs[2] = MultiboardGetItem(thistype.mb, 4 + .id, 6)
    endmethod
    
    method operator o= takes integer i returns nothing
        set.os[i] = .os[i] + 1
        call MultiboardSetItemValue(.mos[i], I2S(.os[i]))
        call MultiboardReleaseItem(.mos[i])
        if i == 1 then
            set .mos[i] = MultiboardGetItem(thistype.mb, 4 + .id, 25)
        else
            set .mos[i] = MultiboardGetItem(thistype.mb, 4 + .id, 37 + i)
        endif
    endmethod
    
    static method create takes integer id, boolean inA returns thistype
        local thistype p = thistype.allocate()
        local multiboarditem array mbi
        local string n = GetPlayerName(Player(id))
        local playercolor c = GetPlayerColor(Player(id))
        local string cs
        local integer i = 1
            set p.id = id
            if id == 0 then
                set cs = "Red"
            elseif id == 1 then
                set cs = "Blue"
            elseif id == 2 then
                set cs = "Teal"
            elseif id == 3 then
                set cs = "Purple"
            elseif id == 4 then
                set cs = "Yellow"
            elseif id == 5 then
                set cs = "Orange"
            elseif id == 6 then
                set cs = "Green"
            elseif id == 7 then
                set cs = "Pink"
            elseif id == 8 then
                set cs = "Gray"
            elseif id == 9 then
                set cs = "Light Blue"
            elseif id == 10 then
                set cs = "Dark Green"
            elseif id == 11 then
                set cs = "Brown"
            endif
            set id = id + 1
            loop
                exitwhen i == 3
                set mbi[i] = MultiboardGetItem(thistype.mb, 3 + id, i)
            endloop
            if (inA) then
                set n = CS[1]+n+CE
            else
                set n = CS[2]+n+CE
            endif
            call MultiboardSetItemValue(mbi[1], n)
            call MultiboardSetItemValue(mbi[2], I2S(id))
            call MultiboardSetItemValue(mbi[3], cs)
            return p
    endmethod
endstruct

function InitTrig_teststart takes nothing returns nothing
    local integer i = 0
        set CS[1] = "|cffff0000"//red
        set CS[2] = "|cff0000ff"//blue
        set CS[3] = "|cffc60000"//dark red
        set CS[4] = "|cffffff00"//topaz
        set CS[5] = "|cffff8800"//citrine
        set CS[6] = "|cff00dc00"//emerald
        set CS[7] = "|cff5000bb"//amethyst
        set CS[8] = "|cff000000"//black (onyx)
        set CS[9] = "|cffffffff"//white (opal)
        loop
            exitwhen i == 11
            if i < 6 then
                set s[i] = stats.create(i, true)
            else
                set s[i] = stats.create(i, false)
            endif
        endloop
        call MultiboardSetColumnCount(stats.mb, 45)
        call MultiboardSetRowCount(stats.mb, 15)
        call MultiboardSetItemsStyle(stats.mb, true, false)
        call MultiboardDisplay(stats.mb, true)
endfunction

function Trig_unit_death_Actions takes nothing returns nothing
    local unit d = GetDyingUnit()
    local unit k = GetKillingUnit()
    local integer did = GetPlayerId(GetOwningPlayer(d))
    local integer kid = GetPlayerId(GetOwningPlayer(k))
        set s[did].b= 1
        set s[kid].b=0
endfunction

//===========================================================================
function InitTrig_unit_death takes nothing returns nothing
    set gg_trg_unit_death = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_unit_death, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddAction( gg_trg_unit_death, function Trig_unit_death_Actions )
endfunction
i know there is a lot of stuff that is not being used at the moment (esp in the globals section) but they will be used eventually.
please tell me what is wrong.
 
Last edited:
Level 18
Joined
Jan 21, 2006
Messages
2,552
I suppose it's not super similar to interfaces, I was just trying to explain it to him in words he mildly understood. I don't know, I forget why were talking about them; it was definitely off-topic.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Berbanog said:
If the delegate is not initialized (created) then the usefulness of it plummets. If it is initialized (I don't know why it's not initialized automatically) then it works in the exact same way as an interface would.

I don't know how much you've tinkered around with delegates, but they definitely do not need to be created. For efficiency, a struct which only performs delegated behavior should just extend an array so that there are no allocate/deallocate methods/triggers/arrays wastefully auto-generated for it.
 
Level 5
Joined
Nov 22, 2009
Messages
181
well, i guess this thread is now just about a ton of questions concerning jass and the world editor. should be a great forum for those noobs (like me) who have a question and need to see if it has been answered already. i also just find it easier to update this one thread than to have to try to follow 50 different threads.

does that sound ok?

back on topic: but if i use a delegate instead of an interface then i can't have it treated for example as a "killable" unit and a "Targetable" unit (like for a specific spell or some sort of action) at the same time. it would have to be one or the other. so i don't see how delegates could be useful for something like that.

does the WE support the use of any other languages like java?
 
The WE allows for different language "interfaces" through means of hacking, but not usage of the language itself. For example, in normal WE you can't type in Java/C++ and expect it to work. Someone has to make a compiler and the syntax for it, so it can be translated to normal JASS for wc3 to be able to execute it.

At the moment, the custom languages available for JNGP are vJass, ZINC, and cJASS.

@Bribe: cJASS is hosted on xgm.
 
Level 5
Joined
Nov 22, 2009
Messages
181
I have no idea what you are referring to by "killable" / "targetable". Sorry.

think of a unit's classification. it can be dead, ground, ancient, invulnerable, etc. wouldn't each of those be an interface? or would that just be a bunch of static boolean members within the struct?
 
Level 5
Joined
Nov 22, 2009
Messages
181
You know how you can hold down shift while clicking in-game to que commands? well is there a way to que commands that have been issued to a unit with a function?
 
Last edited:
Status
Not open for further replies.
Top