• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a faction for Warcraft 3 and enter Hive's 19th Techtree Contest: Co-Op Commanders! Click here to enter!
  • Get your art tools and paintbrushes ready and enter Hive's 34th Texturing Contest: Void! 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,611
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 45
Joined
Feb 27, 2007
Messages
5,578
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?
 
Status
Not open for further replies.
Top