• 🏆 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] Struct limitations

Status
Not open for further replies.
Level 12
Joined
Aug 7, 2004
Messages
875
Alright, I can't seem to pickup the limitations of a struct nor its behavior, its just weird.

I created this simple wire system from point a to b, my intentions was to create a tripwire spell.

JASS:
library Wire initializer init

globals
    constant real WIRE_GAP = 30.0
    constant string WIRE_FX = "LEAS"
    private real bj_lastX
    private real bj_lastY
    private wire bj_lastCreatedWire
    private wire array bj_wireDump
    private integer bj_wireIndex = 0
    private constant integer bj_MAXINSTANCE = 8190
    private hashtable WIRE_HASH = InitHashtable()
endglobals

struct wire 

real array x[bj_MAXINSTANCE]
real array y[bj_MAXINSTANCE]
rect array r[bj_MAXINSTANCE]
real length
trigger t
lightning e

    method GetTrigger takes nothing returns trigger
        return .t
    endmethod
    
    method GetX takes integer i returns real
        return .x[i]
    endmethod
    
    method GetY takes integer i returns real
        return .y[i]
    endmethod
    
    method GetLength takes nothing returns real
        return .length
    endmethod
    
    method GetE takes nothing returns lightning
        return .e
    endmethod

    static method create takes real l, real startx, real starty, real endx, real endy, real z1, real z2, string fx returns wire
        local wire w = wire.allocate()
        local integer i = 0
        local real a = bj_RADTODEG * Atan2(endy - starty, endx - startx)
        local real ax = startx
        local real ay = starty
        set w.t = CreateTrigger()
        set w.length = l
        call BJDebugMsg(R2S(w.length))
        loop
            exitwhen i == R2I(w.length/WIRE_GAP)
            set w.x[i] = ax
            set w.y[i] = ay
            call PingMinimap(ax,ay,2.)
            set w.r[i] = Rect(ax-WIRE_GAP,ay-WIRE_GAP,ax+WIRE_GAP,ay+WIRE_GAP)
            call TriggerRegisterEnterRectSimple(w.t,w.r[i])
            set ax = ax + WIRE_GAP * Cos(a * bj_DEGTORAD)
            set ay = ay + WIRE_GAP * Sin(a * bj_DEGTORAD)
            set i = i + 1
        endloop
        set w.e = AddLightningEx(fx,true,startx,starty,z1,endx,endy,z2)
        return w
    endmethod
    
    method onDestroy takes nothing returns nothing
        call DestroyTrigger(.t)
        call DestroyLightning(.e)
    endmethod
    
endstruct

private function explode takes nothing returns nothing
    local integer i = 0
    local integer index = LoadInteger(WIRE_HASH,GetHandleId(GetTriggeringTrigger()),StringHash("wireindex"))
    local real x
    local real y
    loop
        exitwhen i == R2I(bj_wireDump[index].GetLength()/WIRE_GAP)
        set x = bj_wireDump[index].GetX(i)
        set y = bj_wireDump[index].GetY(i)
        call PingMinimap(x,y,2.)
        set i = i + 1
    endloop
    call bj_wireDump[index].destroy()
    call BJDebugMsg(I2S(index))
endfunction

private function condition takes nothing returns boolean
    local wire w
    local unit a = GetTriggerUnit()
    if bj_wireIndex < bj_MAXINSTANCE then
        if GetIssuedOrderId() == OrderId("defend") then
            set bj_lastX = GetUnitX(a)
            set bj_lastY = GetUnitY(a)
        endif
        if GetIssuedOrderId() == OrderId("undefend") then
            set w = wire.create(SquareRoot((GetUnitX(a)-bj_lastX) * (GetUnitX(a)-bj_lastX) + (GetUnitY(a)-bj_lastY) * (GetUnitY(a)-bj_lastY)),bj_lastX,bj_lastY,GetUnitX(a),GetUnitY(a),10.,10.,WIRE_FX)
            set bj_lastCreatedWire = w
            set bj_wireDump[bj_wireIndex] = w
            set bj_wireIndex = bj_wireIndex + 1
            call TriggerAddAction(w.GetTrigger(),function explode)
            call SaveInteger(WIRE_HASH,GetHandleId(w.GetTrigger()),StringHash("wireindex"),bj_wireIndex)
            call BJDebugMsg(I2S(bj_wireIndex))
        endif
    endif
    return true
endfunction

private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_ORDER )
    call TriggerAddCondition(t,Condition(function condition))
    set t = null
endfunction

endlibrary

The creation of the struct works fine, however, what doesn't is the initiation of a trip event. Whenever a unit trips a wire, it always output the x,y coordinates of the last created wire...

Can someone help me with this? :cry:

If you want to test this out yourself, you can just use a Footman to do the job then cast defend skill.
 
Level 16
Joined
Oct 12, 2008
Messages
1,570
a struct is a bunch of Global Array's. Thinking about the maximum size of an array in JASS is 8192, and you created a struct that uses 8190 per instance, you can only make one instance, thus making this struct useless.
and What the Hell do you need 8100 rects for in a friggin struct? D:
 
Level 12
Joined
Aug 7, 2004
Messages
875
He's trying to make a ******ed way of detecting when a unit goes near the wire.

The best solution would be to check all units near it on a timer (like, every 0.1 seconds).

For your information the use of the word ******ed is offensive and I've reported you for harassment, this thread is for discussion of the issue in regard and your advice didn't even come close to an efficient way of solving it, because creating loops for every point in the wire doesn't make sense.

What the Hell do you need 8100 rects for in a friggin struct? D:

Because the tripwire is almost like a bunch of small rects compiled into a line, the vjass compiler asks for an array size, i just put the number of the max instance. However, enlighten me please with the array limit? And the struct is useless because the arrays are overlimit?
 
Last edited by a moderator:
For your information the use of the word ******ed is offensive and I've reported you for harassment, this thread is for discussion of the issue in regard and your advice didn't even come close to an efficient way of solving it, because creating loops for every point in the wire doesn't make sense.
Lol. I was just trying to help. I didn't exactly call you ******ed, I merely pointed out the problem. Did you even read my solution?
 
Last edited by a moderator:
Level 12
Joined
Aug 7, 2004
Messages
875
Probably, but if i were you, i would use Regions. In a region you can add Rects, but also Cells, which are like a location, just 2 coordinates!

Thanks for the advice, I've set max instace of tripwire to 15, since don't want a Hero to put to much tripwires on a game.

JASS:
library Wire initializer init

globals
    constant real WIRE_GAP = 30.0
    constant string WIRE_FX = "LEAS"
    private real bj_lastX
    private real bj_lastY
    private wire bj_lastCreatedWire
    private wire array bj_wireDump
    private integer bj_wireIndex = 0
    private constant integer bj_MAXSUB = 100
    private constant real bj_MAXLENGTH = 3000
    private constant integer bj_MAXINSTANCE = 15
    private hashtable WIRE_HASH = InitHashtable()
endglobals

struct wire 

real array x[bj_MAXSUB]
real array y[bj_MAXSUB]
rect array r[bj_MAXSUB]
real length
trigger t
lightning e

    method GetTrigger takes nothing returns trigger
        return .t
    endmethod
    
    method GetX takes integer i returns real
        return .x[i]
    endmethod
    
    method GetY takes integer i returns real
        return .y[i]
    endmethod
    
    method GetLength takes nothing returns real
        return .length
    endmethod
    
    method GetE takes nothing returns lightning
        return .e
    endmethod

    static method create takes real l, real startx, real starty, real endx, real endy, real z1, real z2, string fx returns wire
        local wire w = wire.allocate()
        local integer i = 0
        local real a = bj_RADTODEG * Atan2(endy - starty, endx - startx)
        local real ax = startx
        local real ay = starty
        set w.t = CreateTrigger()
        set w.length = l
        call BJDebugMsg(R2S(w.length))
        loop
            exitwhen i == R2I(w.length/WIRE_GAP) or i == bj_MAXLENGTH/WIRE_GAP
            set w.x[i] = ax
            set w.y[i] = ay
            call PingMinimap(ax,ay,2.)
            set w.r[i] = Rect(ax-WIRE_GAP,ay-WIRE_GAP,ax+WIRE_GAP,ay+WIRE_GAP)
            call TriggerRegisterEnterRectSimple(w.t,w.r[i])
            set ax = ax + WIRE_GAP * Cos(a * bj_DEGTORAD)
            set ay = ay + WIRE_GAP * Sin(a * bj_DEGTORAD)
            set i = i + 1
        endloop
        set w.e = AddLightningEx(fx,true,startx,starty,z1,endx,endy,z2)
        return w
    endmethod
    
    method onDestroy takes nothing returns nothing
        call DestroyTrigger(.t)
        call DestroyLightning(.e)
    endmethod
    
endstruct

private function explode takes nothing returns nothing
    local integer i = 0
    local integer index = LoadInteger(WIRE_HASH,GetHandleId(GetTriggeringTrigger()),StringHash("wireindex"))
    local real x
    local real y
    loop
        exitwhen i == R2I(bj_wireDump[index].GetLength()/WIRE_GAP)
        set x = bj_wireDump[index].GetX(i)
        set y = bj_wireDump[index].GetY(i)
        call PingMinimap(x,y,2.)
        set i = i + 1
    endloop
    call bj_wireDump[index].destroy()
    call BJDebugMsg(I2S(index))
endfunction

private function condition takes nothing returns boolean
    local wire w
    local unit a = GetTriggerUnit()
    if bj_wireIndex < bj_MAXINSTANCE then
        if GetIssuedOrderId() == OrderId("defend") then
            set bj_lastX = GetUnitX(a)
            set bj_lastY = GetUnitY(a)
        endif
        if GetIssuedOrderId() == OrderId("undefend") then
            set w = wire.create(SquareRoot((GetUnitX(a)-bj_lastX) * (GetUnitX(a)-bj_lastX) + (GetUnitY(a)-bj_lastY) * (GetUnitY(a)-bj_lastY)),bj_lastX,bj_lastY,GetUnitX(a),GetUnitY(a),10.,10.,WIRE_FX)
            set bj_lastCreatedWire = w
            set bj_wireDump[bj_wireIndex] = w
            set bj_wireIndex = bj_wireIndex + 1
            call TriggerAddAction(w.GetTrigger(),function explode)
            call SaveInteger(WIRE_HASH,GetHandleId(w.GetTrigger()),StringHash("wireindex"),bj_wireIndex-1)
            call BJDebugMsg(I2S(bj_wireIndex-1))
        endif
    endif
    return true
endfunction

private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ISSUED_ORDER )
    call TriggerAddCondition(t,Condition(function condition))
    set t = null
endfunction

endlibrary

Also, followed what you said and had max length to 3000, hence 3000/30 is the max array of the x,y coordinates and rect. Well in theory I don't really need those x,y coordinates, can just use the rect, but then hey, whoknows maybe it could put up to good use.

Thanks!
 
Status
Not open for further replies.
Top