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

[vJASS] How to create interface-like structure with an array struct

Status
Not open for further replies.
Level 17
Joined
Mar 21, 2011
Messages
1,597
Hi guys,
i am trying to create a system that can be used as an interface. The "interface" itself is an array struct and thus cannot be the extension for another struct.
How would i realize something like this in vJass? Thanks!

JASS:
library ExplosionTrigger uses TimerUtils

    struct ExplosionTrigger extends array
    
        stub method onTrigger takes nothing returns nothing
        endmethod
        
        stub method onExplode takes nothing returns nothing
        endmethod
    
        stub method onPeriodic takes nothing returns nothing
        endmethod
        
        private static constant real interval = 0.03125
        private static group explosionTriggerGroup = null
        private static group tempGroup = null
        private static timer periodicTimer = null
        
        readonly unit         mine
        readonly player     owner
        readonly real         duration
        readonly real         triggerDuration
        readonly boolean     isTriggered
        
        real     explosionDelay
        real     initialDelay
        real     aoe
        boolean ignoreTriggerAmp
        
        private static method onPeriodGroup takes nothing returns nothing
            local thistype this = thistype[GetUnitUserData(GetEnumUnit())]
            local unit fog = null
            call this.onPeriodic()
            set this.duration = this.duration + thistype.interval
            
            if not this.isTriggered and this.initialDelay <= this.duration then
                call GroupEnumUnitsInRange(thistype.tempGroup, GetUnitX(this.mine), GetUnitY(this.mine), this.aoe, null)
                loop
                    set fog = FirstOfGroup(thistype.tempGroup)
                    exitwhen fog == null
                    if IsUnitEnemy(fog, this.owner) and UnitAlive(fog) and not IsUnitType(fog, UNIT_TYPE_MINE) then
                        set this.isTriggered = true
                        call this.onTrigger()
                        exitwhen true
                    endif
                    call GroupRemoveUnit(thistype.tempGroup, fog)
                endloop
            else
             set this.triggerDuration = this.triggerDuration + thistype.interval
             if this.triggerDuration >= this.explosionDelay then
                call KillUnit(this.mine)
                call this.onExplode()
                call this.deallocate()
             endif
            endif
            
        endmethod
        
        private static method onPeriod takes nothing returns nothing
            call ForGroup(thistype.explosionTriggerGroup, function thistype.onPeriodGroup)
        endmethod
    
        private static method create takes unit mine returns thistype
            local thistype this = GetUnitUserData(mine)
            set this.mine = udg_UDexUnits[udg_UDex]
            set this.owner = GetOwningPlayer(this.mine)
            set this.isTriggered = false
            set this.duration = 0.0
            set this.triggerDuration = 0.0
            set this.damage = 0.0
            set this.explosionDelay = 0.0
            set this.initialDelay = 0.0
            set this.aoe = 0.0
            set this.ignoreTriggerAmp = false
            if FirstOfGroup(thistype.explosionTriggerGroup) == null then
                call TimerStart(thistype.periodicTimer, thistype.interval, true, function thistype.onPeriod)
            endif
            call GroupAddUnit(thistype.explosionTriggerGroup, this.mine)
            set mine = null
            return this
        endmethod
        
        private method deallocate takes nothing returns nothing
            call GroupRemoveUnit(thistype.explosionTriggerGroup, this.mine)
            if FirstOfGroup(thistype.explosionTriggerGroup) == null then
                call PauseTimer(thistype.periodicTimer)
            endif
        endmethod
    
        private static method onInit takes nothing returns nothing
            set thistype.explosionTriggerGroup = CreateGroup()
            set thistype.tempGroup = CreateGroup()
            set thistype.periodicTimer = NewTimer()
        endmethod
    
    endstruct

endlibrary

JASS:
scope LandMine initializer Init

    struct LandMineTrigger extends ExplosionTrigger
        
        method onExplode takes nothing returns nothing
            local unit fog = null
            local mineX = GetUnitX(this.mine)
            local mineY = GetUnitY(this.mine)
            local group tempGroup = CreateGroup()
            call GroupEnumUnitsInRange(tempGroup, mineX, mineY, 220.0, null)
            loop
                set fog = FirstOfGroup(tempGroup)
                exitwhen fog == null
                if UnitAlive(fog) and not IsUnitType(fog, UNIT_TYPE_MINE) and GetUnitFlyHeight(fog) <= 200 then
                    call UnitDamageTarget(this.mine, fog, 100.0, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
                endif
                call GroupRemoveUnit(tempGroup, fog)
            endloop
            call DestroyEffect(AddSpecialEffect("war3mapImported\\LandMineExplosion.mdx", mineX, mineY))
            call DestroyGroup(tempGroup)
            set tempGroup = null
        endmethod
        
    endstruct
    
    private function OnEnter takes nothing returns nothing
        local LandMineTrigger trig = 0
        if GetUnitTypeId(udg_UDexUnits[udg_UDex]) == 'ulam' then
            call trig.create(udg_UDexUnits[udg_UDex])
            set trig.initialDelay = 1.0
            set trig.explosionDelay = 0.5
            set trig.aoe = 200.0
        endif
    endfunction

    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 1.00 )
        call TriggerAddAction(t, function OnEnter)        
        set t = null
    endfunction

endscope
 
Level 39
Joined
Feb 27, 2007
Messages
5,024
Why do you need it to extend array? You don't appear to be using that functionality in the code you posted here and its limiting what you can do by imposing it as a requirement. Is ExplosionTrigger(instanceNumber).whatever really that much worse that ExplosionTrigger[instanceNumber].whatever for your purposes?
 
Level 39
Joined
Feb 27, 2007
Messages
5,024
Okay since it extends something else, can't that something else struct also just extend an array? If it also extends something else then whatever is furthest down the chain and all should inherit it I believe.
 
Status
Not open for further replies.
Top