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

Lightning System v1.03

  • Like
Reactions: deepstrasz
Basically, its a system that manages lightning creation and has useful add-ons like event handlers and the possibility of attaching any custom data to the lightnings...

Features and how to use is at the code header below... :)


JASS:
/*
    Lightning System v1.03
    by Adiktuz
    
    Basically it allows you to easily create timed or un-timed lightning effects
    
    Features:
        ->You can create lightnings between two points, two unit, or a point and a unit.
        ->For lightnings attached to a unit, the system automatically updates the lightning
          for changes on the unit (like  unit position, height etc)
        ->Specify the height of the lightning
        ->Create timed-lightnings that get automatically destroyed when their duration is over
        ->Supports moving points too (but the lightnings are forced to be timed)
        ->Allows you to add actions that will run when a lightning has ended and during
          update (time of which is equal to T32's period)
        ->Allows you to attach any type of custom data to each instance
        
    Methods available
        
        How to use: call Lightning.methodName(parameters)
        
        unitToPoint takes unit unit1, real x, real y, real sourceZ, real targetZ, boolean timed, real duration, string leffect, integer eventkey returns thistype
        unitToUnit takes unit unit1, unit unit2, real sourceZ, real targetZ, boolean timed, real duration, string leffect, integer eventkey  returns thistype
        pointToPoint takes real sourceX, real sourceY,real targetX, real targetY, real sourceZ, real targetZ, boolean timed, real duration, string leffect, integer eventkey  returns thistype
        pointToPointEx takes real sourceX, real deltaSourceX, real sourceY, real deltaSourceY, real targetX, real deltaTargetX, real targetY, real deltaTargetY, real sourceZ, real targetZ, real duration, string leffect, integer eventkey  returns thistype
        unitToPointEx takes unit unit1, real x, real xx, real y, real yx, real sourceZ, real targetZ, real duration, string leffect, integer eventkey  returns thistype
        pointToPointExZ takes real sourceX, real deltaSourceX, real sourceY, real deltaSourceY, real targetX, real deltaTargetX, real targetY, real deltaTargetY, real sourceZ, real sourceCurZ, real targetZ, real targetCurZ, real duration, string leffect, integer eventkey  returns thistype
        unitToPointExZ takes unit unit1, real x, real xx, real y, real yx, real sourceZ, real targetZ, real targetCurZ, real duration, string leffect, integer eventkey  returns thistype
        
        Parameters:
        
        unit unit1 -> unit end of the lightning
        unit unit2 -> other unit end of the lightning for the UTU methods
        real x,y -> X,Y coordinates of the point end of the lightning for the UTP methods
        real sourceX,sourceY -> X,Y coordinates of the first point of the lightning for the PTP methods
        real sourceZ,targetZ -> height of the lightning at each ends (actual height is calculated as z + height of unit (if there's a unit end) + locationZ)
        real deltaSourceX,deltaSourceY,deltaTargetX,deltaTargetY,sourceCurZ,targetCurZ -> for the Ex and ExZ methods, the final value of each coordinate/height
             (the lightning moves from sourceX to deltaSourceX, etc through the given time)
        boolean timed -> whether the lightning has a timed life or not, defaulted to true for the Ex and ExZ methods
        real duration -> timed life of the lightning
        string leffect -> string name of the lightning effect
        integer eventkey -> a key used to determine the correct update and end functions to run if available
                            (if you're not using the update and end events, you're probably saf to just set it to 0)
        
        Note: all of the above methods return the Lightning instance so you can save it in a variable
        
        Extra/Interface/Events:
        
        registerUpdateEvent(integer eventkey, code ToDo) returns nothing
        -> allows you to register an action that will be run whenever a lightning with the
           same eventkey as the one registered is updated (every T32_PERIOD)
        
        registerEndEvent(integer eventkey, code ToDo) returns nothing
        -> allows you to register an action that will be run whenever a lightning with the
           same eventkey as the one registered ends
        
        NOTE: If you're going to use the next three functions/methods, make sure you set the
              corresponding boolean at the globals block to true
        
        registerGlobalUpdateEvent(code ToDo) returns nothing
        -> allows you to register an action that will be run whenever a lightning 
           is updated (every T32_PERIOD)
        
        registerGlobalEndEvent(code ToDo) returns nothing
        -> allows you to register an action that will be run whenever a lightning ends
        
        registerGlobalCreateEvent(code ToDo) returns nothing
        -> allows you to register an action that will be run whenever a lightning is created
        
        To allow creation and usage of custom data that is attached to every instance
        turn the boolean USE_CUSTOM_DATA to true
        
        then to add a custom data to an instance:
        
        for integers:
        
        set YourLightningInstance.customData[integer key] = value
        
        for others:
        
        set YourLightningInstance.customData.type[integer key] = value
        
        ->type can be real,unit,trigger,effect, etc...
        
        ->integer key is the key that will point to the data, you can utilize StringHash if you want to use strings
          something like: customData.real[StringHash("damage")]
          
        then to load data:
        
        YourLightningInstance.customData.type[integer key] 
        
        To forcefully remove a lightning:
        
        remove() returns nothing
        
        To obtain which lightning instance triggered the events:
        
        instance()
*/


    //DO NOT EDIT ANYTHING BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING
    
    
    //Note: I've set the checkvisibility field to false because the lightnings look
    //      weird when I set it to true (sometimes they "jump")
    
library LightningSystem requires T32, Table

    globals
        //Set this to true if you're gonna use the global update event handler
        private constant boolean USE_GLOBAL_UPDATE = false 
        //Set this to true if you're gonna use the global end event handler
        private constant boolean USE_GLOBAL_END = false 
        //Set this to true if you're gonna use the global create event handler
        private constant boolean USE_GLOBAL_CREATE = false 
        //Set this to true if you're gonna use the custom data feature
        private constant boolean USE_CUSTOM_DATA = true 
        private location loc = Location(0,0)
        public Table UpdateTable
        public Table EndTable
        private trigger globalUpdate
        private trigger globalEnd
        private trigger globalCreate
    endglobals
    
    private module init
        static method onInit takes nothing returns nothing
            set EndTable = Table.create()
            set UpdateTable = Table.create()
            static if USE_GLOBAL_UPDATE then
                set globalUpdate = CreateTrigger()
            endif
            static if USE_GLOBAL_END then
                set globalEnd = CreateTrigger()
            endif
            static if USE_GLOBAL_CREATE then
                set globalCreate = CreateTrigger()
            endif
        endmethod
    endmodule
    
    struct Lightning extends array
        lightning light
        real sourceX
        real targetX
        real sourceY
        real targetY
        real sourceZ
        real targetZ
        real deltaSourceX
        real deltaTargetX
        real deltaSourceY
        real deltaTargetY
        real sourceCurZ
        real targetCurZ
        real deltaSourceZ
        real deltaTargetZ
        unit u1
        unit u2
        integer xtype
        boolean timed
        boolean moving
        real duration
        integer eventkey
        Table customData
        static thistype instance
        private static integer instanceCount = 0
        private static thistype recycle = 0
        private thistype recycleNext
        
        static method registerEndEvent takes integer eventkey, code toDo returns nothing
            if not EndTable.handle.has(eventkey) then
                set EndTable.trigger[eventkey] = CreateTrigger()
            endif
            call TriggerAddCondition(EndTable.trigger[eventkey],Filter(toDo))
        endmethod
        
        static method registerUpdateEvent takes integer eventkey, code toDo returns nothing
            if not UpdateTable.handle.has(eventkey) then
                set UpdateTable.trigger[eventkey] = CreateTrigger()
            endif
            call TriggerAddCondition(UpdateTable.trigger[eventkey],Filter(toDo))
        endmethod
        
        static method registerGlobalEndEvent takes code toDo returns nothing
            call TriggerAddCondition(globalEnd,Filter(toDo))
        endmethod
        
        static method registerGlobalUpdateEvent takes code toDo returns nothing
            call TriggerAddCondition(globalUpdate,Filter(toDo))
        endmethod
        
        static method registerGlobalCreateEvent takes code toDo returns nothing
            call TriggerAddCondition(globalCreate,Filter(toDo))
        endmethod
        
        method remove takes nothing returns nothing
            call DestroyLightning(this.light)
            set instance = this
            if EndTable.handle.has(this.eventkey) then
                call TriggerEvaluate(EndTable.trigger[this.eventkey])
            endif
            static if USE_GLOBAL_END then
                call TriggerEvaluate(globalEnd)
            endif
            call this.stopPeriodic()
            set this.deltaSourceZ = 0.0
            set this.deltaTargetZ = 0.0
            set .recycleNext=recycle
            set recycle=this
        endmethod
        
        static method new takes nothing returns thistype
            local thistype this
            if (recycle == 0) then
                set instanceCount = instanceCount + 1
                return instanceCount
            else
                set this = recycle
                set recycle = recycle.recycleNext
            endif
            return this
        endmethod
        
        private method periodic takes nothing returns nothing
            if this.xtype == 1 then
                set this.sourceX = GetUnitX(this.u1)
                set this.sourceY = GetUnitY(this.u1)
                call MoveLocation(loc, this.sourceX,this.sourceY)
                set this.sourceCurZ = sourceZ + GetUnitFlyHeight(this.u1) + GetLocationZ(loc)
                if this.moving then
                    set this.targetX = this.targetX + this.deltaTargetX
                    set this.targetY = this.targetY + this.deltaTargetY
                endif
                call MoveLocation(loc, this.targetX,this.targetY)
                if this.deltaTargetZ != 0.0 then
                    set this.targetZ = this.targetZ + this.deltaTargetZ
                endif
                set this.targetCurZ = targetZ + GetLocationZ(loc) + this.deltaTargetZ
                call MoveLightningEx(this.light,false,this.sourceX,this.sourceY,this.sourceCurZ,this.targetX,this.targetY,this.targetCurZ)
            elseif this.xtype == 2 then
                set this.sourceX = GetUnitX(this.u1)
                set this.sourceY = GetUnitY(this.u1)
                set this.targetX = GetUnitX(this.u2)
                set this.targetY = GetUnitY(this.u2)
                call MoveLocation(loc, this.sourceX,this.sourceY)
                set this.sourceCurZ = sourceZ + GetUnitFlyHeight(this.u1) + GetLocationZ(loc)
                call MoveLocation(loc, this.targetX,this.targetY)
                set this.targetCurZ = targetZ + GetUnitFlyHeight(this.u2) + GetLocationZ(loc)
                call MoveLightningEx(this.light,false,this.sourceX,this.sourceY,this.sourceCurZ,this.targetX,this.targetY,this.targetCurZ)
            else
                if this.moving then
                    set this.sourceX = this.sourceX + this.deltaSourceX
                    set this.targetX = this.targetX + this.deltaTargetX
                    set this.sourceY = this.sourceY + this.deltaSourceY
                    set this.targetY = this.targetY + this.deltaTargetY
                    call MoveLocation(loc, this.sourceX,this.sourceY)
                    if this.deltaSourceZ != 0.0 then
                        set this.sourceZ = this.sourceZ + this.deltaSourceZ
                    endif
                    if this.deltaTargetZ != 0.0 then
                        set this.targetZ = this.targetZ + this.deltaTargetZ
                    endif
                    set this.sourceCurZ = sourceZ + GetLocationZ(loc) + this.deltaSourceZ
                    call MoveLocation(loc, this.targetX,this.targetY)
                    set this.targetCurZ = targetZ + GetLocationZ(loc) + this.deltaTargetZ
                    call MoveLightningEx(this.light,false,this.sourceX,this.sourceY,this.sourceCurZ,this.targetX,this.targetY,this.targetCurZ)
                endif
            endif
            set instance = this
            if UpdateTable.handle.has(this.eventkey) then
                call TriggerEvaluate(UpdateTable.trigger[this.eventkey])
            endif
            static if USE_GLOBAL_UPDATE then
                call TriggerEvaluate(globalUpdate)
            endif
            if this.timed then
                set this.duration = this.duration - T32_PERIOD
                if this.duration <= 0.0 then
                    call this.remove()
                endif
            endif
        endmethod
        
        implement T32x
        
        static method unitToPoint takes unit unit1, real x, real y, real sourceZ, real targetZ, boolean timed, real duration, string leffect, integer eventkey returns thistype
            local thistype this = thistype.new()
            set this.u1 = unit1
            set this.u2 = null
            set this.sourceX = GetUnitX(this.u1)
            set this.sourceY = GetUnitY(this.u1)
            set this.targetX = x
            set this.targetY = y
            call MoveLocation(loc, this.sourceX,this.sourceY)
            set this.sourceZ = sourceZ + GetUnitFlyHeight(this.u1) + GetLocationZ(loc)
            call MoveLocation(loc, this.targetX,this.targetY)
            set this.targetZ = targetZ + GetLocationZ(loc)
            set this.timed = timed
            set this.duration = duration
            set this.eventkey = eventkey
            set this.light = AddLightningEx(leffect,false,this.sourceX,this.sourceY,this.sourceZ,this.targetX,this.targetY,this.targetZ)
            set this.xtype = 1
            set this.moving = false
            static if USE_CUSTOM_DATA then
                if this.customData < 0 then
                    set this.customData = Table.create()
                endif
            endif
            static if USE_GLOBAL_CREATE then
                call TriggerEvaluate(globalCreate)
            endif
            call this.startPeriodic()
            return this
        endmethod
        
        static method unitToUnit takes unit unit1, unit unit2, real sourceZ, real targetZ, boolean timed, real duration, string leffect, integer eventkey  returns thistype
            local thistype this = thistype.new()
            set this.u1 = unit1
            set this.u2 = unit2
            set this.sourceX = GetUnitX(this.u1)
            set this.sourceY = GetUnitY(this.u1)
            set this.targetX = GetUnitX(this.u2)
            set this.targetY = GetUnitY(this.u2)
            call MoveLocation(loc, this.sourceX,this.sourceY)
            set this.sourceZ = sourceZ + GetUnitFlyHeight(this.u1) + GetLocationZ(loc)
            call MoveLocation(loc, this.targetX,this.targetY)
            set this.targetZ = targetZ + GetUnitFlyHeight(this.u2) + GetLocationZ(loc)
            set this.timed = timed
            set this.duration = duration
            set this.eventkey = eventkey
            set this.light = AddLightningEx(leffect,false,this.sourceX,this.sourceY,this.sourceZ,this.targetX,this.targetY,this.targetZ)
            set this.xtype = 2
            set this.moving = false
            static if USE_CUSTOM_DATA then
                if this.customData < 0 then
                    set this.customData = Table.create()
                endif
            endif
            static if USE_GLOBAL_CREATE then
                call TriggerEvaluate(globalCreate)
            endif
            call this.startPeriodic()
            return this
        endmethod
        
        static method pointToPoint takes real sourceX, real sourceY,real targetX, real targetY, real sourceZ, real targetZ, boolean timed, real duration, string leffect, integer eventkey  returns thistype
            local thistype this = thistype.new()
            set this.u1 = null
            set this.u2 = null
            set this.sourceX = sourceX
            set this.sourceY = sourceY
            set this.targetX = targetX
            set this.targetY = targetY
            call MoveLocation(loc, this.sourceX,this.sourceY)
            set this.sourceZ = sourceZ + GetLocationZ(loc)
            call MoveLocation(loc, this.targetX,this.targetY)
            set this.targetZ = targetZ + GetLocationZ(loc)
            set this.timed = timed
            set this.duration = duration
            set this.eventkey = eventkey
            set this.light = AddLightningEx(leffect,false,this.sourceX,this.sourceY,this.sourceZ,this.targetX,this.targetY,this.targetZ)
            set this.xtype = 3
            set this.moving = false
            static if USE_CUSTOM_DATA then
                if this.customData < 0 then
                    set this.customData = Table.create()
                endif
            endif
            static if USE_GLOBAL_CREATE then
                call TriggerEvaluate(globalCreate)
            endif
            call this.startPeriodic()
            return this
        endmethod
        
        static method pointToPointEx takes real sourceX, real deltaSourceX, real sourceY, real deltaSourceY, real targetX, real deltaTargetX, real targetY, real deltaTargetY, real sourceZ, real targetZ, real duration, string leffect, integer eventkey  returns thistype
            local thistype this = thistype.new()
            set this.u1 = null
            set this.u2 = null
            set this.sourceX = sourceX
            set this.sourceY = sourceY
            set this.targetX = targetX
            set this.targetY = targetY
            set this.deltaSourceX = (deltaSourceX - sourceX)*(T32_PERIOD/duration)
            set this.deltaSourceY = (deltaSourceY - sourceY)*(T32_PERIOD/duration)
            set this.deltaTargetX = (deltaTargetX - targetX)*(T32_PERIOD/duration)
            set this.deltaTargetY = (deltaTargetY - targetY)*(T32_PERIOD/duration)
            call MoveLocation(loc, this.sourceX,this.sourceY)
            set this.sourceZ = sourceZ + GetLocationZ(loc)
            call MoveLocation(loc, this.targetX,this.targetY)
            set this.targetZ = targetZ + GetLocationZ(loc)
            set this.timed = true
            set this.duration = duration
            set this.eventkey = eventkey
            set this.light = AddLightningEx(leffect,false,this.sourceX,this.sourceY,this.sourceZ,this.targetX,this.targetY,this.targetZ)
            set this.xtype = 3
            set this.moving = true
            static if USE_CUSTOM_DATA then
                if this.customData < 0 then
                    set this.customData = Table.create()
                endif
            endif
            static if USE_GLOBAL_CREATE then
                call TriggerEvaluate(globalCreate)
            endif
            call this.startPeriodic()
            return this
        endmethod
        
        static method unitToPointEx takes unit unit1, real x, real xx, real y, real yx, real sourceZ, real targetZ, real duration, string leffect, integer eventkey  returns thistype
            local thistype this = thistype.new()
            set this.u1 = unit1
            set this.u2 = null
            set this.sourceX = GetUnitX(this.u1)
            set this.sourceY = GetUnitY(this.u1)
            set this.targetX = x
            set this.targetY = y
            set this.deltaTargetX = (xx - x)*(T32_PERIOD/duration)
            set this.deltaTargetY = (yx - y)*(T32_PERIOD/duration)
            call MoveLocation(loc, this.sourceX,this.sourceY)
            set this.sourceZ = sourceZ + GetUnitFlyHeight(this.u1) + GetLocationZ(loc)
            call MoveLocation(loc, this.targetX,this.targetY)
            set this.targetZ = targetZ + GetLocationZ(loc)
            set this.timed = true
            set this.duration = duration
            set this.eventkey = eventkey
            set this.light = AddLightningEx(leffect,false,this.sourceX,this.sourceY,this.sourceZ,this.targetX,this.targetY,this.targetZ)
            set this.xtype = 1
            set this.moving = true
            static if USE_CUSTOM_DATA then
                if this.customData < 0 then
                    set this.customData = Table.create()
                endif
            endif
            static if USE_GLOBAL_CREATE then
                call TriggerEvaluate(globalCreate)
            endif
            call this.startPeriodic()
            return this
        endmethod
        
        static method pointToPointExZ takes real sourceX, real deltaSourceX, real sourceY, real deltaSourceY, real targetX, real deltaTargetX, real targetY, real deltaTargetY, real sourceZ, real sourceCurZ, real targetZ, real targetCurZ, real duration, string leffect, integer eventkey  returns thistype
            local thistype this = thistype.new()
            set this.u1 = null
            set this.u2 = null
            set this.sourceX = sourceX
            set this.sourceY = sourceY
            set this.targetX = targetX
            set this.targetY = targetY
            set this.deltaSourceZ = (sourceCurZ - sourceZ)*(T32_PERIOD/duration)
            set this.deltaTargetZ = (targetCurZ-targetZ)*(T32_PERIOD/duration)
            set this.deltaSourceX = (deltaSourceX - sourceX)*(T32_PERIOD/duration)
            set this.deltaSourceY = (deltaSourceY - sourceY)*(T32_PERIOD/duration)
            set this.deltaTargetX = (deltaTargetX - targetX)*(T32_PERIOD/duration)
            set this.deltaTargetY = (deltaTargetY - targetY)*(T32_PERIOD/duration)
            call MoveLocation(loc, this.sourceX,this.sourceY)
            set this.sourceZ = sourceZ + GetLocationZ(loc)
            call MoveLocation(loc, this.targetX,this.targetY)
            set this.targetZ = targetZ + GetLocationZ(loc)
            set this.timed = true
            set this.duration = duration
            set this.eventkey = eventkey
            set this.light = AddLightningEx(leffect,false,this.sourceX,this.sourceY,this.sourceZ,this.targetX,this.targetY,this.targetZ)
            set this.xtype = 3
            set this.moving = true
            static if USE_CUSTOM_DATA then
                if this.customData < 0 then
                    set this.customData = Table.create()
                endif
            endif
            static if USE_GLOBAL_CREATE then
                call TriggerEvaluate(globalCreate)
            endif
            call this.startPeriodic()
            return this
        endmethod
        
        static method unitToPointExZ takes unit unit1, real x, real xx, real y, real yx, real sourceZ, real targetZ, real targetCurZ, real duration, string leffect, integer eventkey  returns thistype
            local thistype this = thistype.new()
            set this.u1 = unit1
            set this.u2 = null
            set this.sourceX = GetUnitX(this.u1)
            set this.sourceY = GetUnitY(this.u1)
            set this.targetX = x
            set this.targetY = y
            set this.deltaTargetZ = (targetCurZ - targetZ)*(T32_PERIOD/duration)
            set this.deltaTargetX = (xx - x)*(T32_PERIOD/duration)
            set this.deltaTargetY = (yx - y)*(T32_PERIOD/duration)
            call MoveLocation(loc, this.sourceX,this.sourceY)
            set this.sourceZ = sourceZ + GetUnitFlyHeight(this.u1) + GetLocationZ(loc)
            call MoveLocation(loc, this.targetX,this.targetY)
            set this.targetZ = targetZ + GetLocationZ(loc)
            set this.timed = true
            set this.duration = duration
            set this.eventkey = eventkey
            set this.light = AddLightningEx(leffect,false,this.sourceX,this.sourceY,this.sourceZ,this.targetX,this.targetY,this.targetZ)
            set this.xtype = 1
            set this.moving = true
            static if USE_CUSTOM_DATA then
                if this.customData < 0 then
                    set this.customData = Table.create()
                endif
            endif
            static if USE_GLOBAL_CREATE then
                call TriggerEvaluate(globalCreate)
            endif
            call this.startPeriodic()
            return this
        endmethod
        
        implement init
    endstruct
    
endlibrary



JASS:
library Example initializer init requires LightningSystem 
    
    globals
        private group tmpG = CreateGroup()
    endglobals
    
    private function Timed takes nothing returns nothing
        call LightningUtils.addLightningGradient(Lightning.unitToUnit(udg_UNIT4,udg_UNIT5,50.0,50,true,6.0,"CLPB",1),1.0,1.0,1.0,1.0,0.0,0.0,1.0,0.1)
        //Note: There seems to be a z buffer for fly height for a flying unit
        call Lightning.unitToPointExZ(udg_UNIT6,853.0,853.0,-2382.0,-2382.0,100.0,0.0,400.0,3.0,"LEAS",0)
    endfunction
    
    
    private function XD takes nothing returns nothing
        call BJDebugMsg("Lightning created on: " + R2S(Lightning.instance.customData.real[0]))
        call Lightning.pointToPointEx(-1231.7,-1231.7,-2382.0,-3485.0,1198.2,1198.2,-2382.0,-3485.0,100.0,100,3.0,"AFOD",3)
    endfunction
    
    private function XF takes nothing returns nothing
        set Lightning.pointToPointEx(-1231.7,-1231.7,-3485.0,-2382.0,1198.2,1198.2,-3485.0,-2382.0,100.0,100,3.0,"CLPB",2).customData.real[0] = GetTimeOfDay()
    endfunction
    
    private function Create takes nothing returns nothing
        call Lightning.pointToPoint(-1231.7,-3485.0,1198.2,-3485.0,100.0,100,false,0.0,"CLPB",0)
        call Lightning.unitToPoint(udg_UNIT1,1198.2,-3485.0,50.0,100,false,0.0,"CLPB",4)
        call Lightning.unitToUnit(udg_UNIT2,udg_UNIT3,50.0,100,false,0.0,"DRAB",0)
        call XF()
        call TimerStart(GetExpiredTimer(), 7.0, true, function Timed)
    endfunction
    
    private function Lols takes nothing returns nothing
        call BJDebugMsg("Lols")
    endfunction
    
    private function Hit takes nothing returns nothing
        local unit u = null
        call LightningUtils.enumUnits(tmpG,Lightning.instance,150.0)
        loop
            set u = FirstOfGroup(tmpG)
            exitwhen u == null
            if u != Lightning.instance.u1 and u != Lightning.instance.u2 then
                call Lightning.unitToPoint(u,GetUnitX(u),GetUnitY(u),0.0,400,true,0.03,"AFOD",0)
            endif
            call GroupRemoveUnit(tmpG,u)
        endloop
        set u = null
    endfunction
    
    private function init takes nothing returns nothing
        call TimerStart(CreateTimer(), 2.0, false, function Create)
        call LightningUtils.registerGradientKey(1)
        call Lightning.registerEndEvent(1,function Lols)
        call Lightning.registerEndEvent(2,function XD)
        call Lightning.registerEndEvent(3,function XF)
        call Lightning.registerUpdateEvent(4,function Hit)
    endfunction
    
endlibrary

System Add-On:
Lightning Utils

CREDITS:
Jesus4Lyf for T32
Bribe for Table


v1.01 - changed the struct member names
v1.02 - added global event handlers
v1.03 - added creation global event handler
- added custom data capability


Extra notes:

If you need a list of lightning strings you can check this out (by Maker):
http://www.hiveworkshop.com/forums/spells-569/lightning-test-v1-0-a-204927/

Keywords:
system, adiktuz,scrolls,jngp,vjass,lightning,timed,effects,t32,
Contents

Lightning System 1.03 (Map)

Reviews
15:07, 18th Oct 2012 Magtheridon96: Approved. Nice wrapper.

Moderator

M

Moderator

15:07, 18th Oct 2012
Magtheridon96: Approved.
Nice wrapper.
 
@Frotty - I guess the user can already handle that using the enumUnits function of the Lightning Utils...

EDIT: reverted to 1.01... this method of handling events [system handles the checks to fire the correct actions] is less tedious for the user than making it run Blizzard-like [the user checks manually if his actions should fire]...
 
Last edited:
Updated!

Added global event handlers for the two event handlers... Global meaning event handlers that will fire for all lightnings... they are toggled via constant booleans and static ifs so that the system won't include them if they're not gonna be used... :)

EDIT: I will add a global event handler for Lightning creation so that you can fire a general event for all created lightnings...


UPDATE:

Added capability of adding any custom data to each instance (courtesy of Table)... I think it will bring lots of possibilities when coupled with the event handlers...

This possibility is of course already present before, but the user would then need to make his own variables [probably another struct too] and such but now the user only needs to toggle one boolean variable and he can freely add and retrieve any custom data that he wants each lightning to have...

before:
JASS:
struct B
    real damage
    Lightning lig
    
    static method create takes blahblah returns B
        local thistype this = .allocate()
        set this.lig = Lightning.blahblah
        set this.damage = blahblah
    endmethod
endstruct

function boom takes nothing returns nothing
    call B.create(blahblah)
endfunction

now:

JASS:
function boom takes nothing returns nothing
    local Lightning lig = Lightning.blahblah
    set lig.customData.real[StringHash("damage")] = blahblah
    //or even just    
    set lig.customData.real[0] = blahblah
    //too much lines still? then how about a one liner?
    set Lightning.blahblah.customData.real[0] = blahblah
    //note that the one-liner approach will only work if you will only attach one custom data
    //for 2 or more data, you will really need to save the Lightning to a variable first
endfunction

EDIT: I might add a function for hiding lightnings on the Utils lib... might...
 
Last edited:
So I don't really understand JASS or vJASS but I managed to get this to work, but I can't destroy the lightning in time. I stored the created lightning in a variable and destroyed it later in a different trigger as I don't understand how to use remove().

It stays in existence for like 3 seconds before being removed.

EDIT: Nvm, figured it out.

For those wondering how I did it, you can't use (last created lightning). Instead use an Integer variable to store the lightning, eg:
JASS:
set udg_Beam[udg_ID] = Lightning.unitToUnit(udg_u1[udg_ID1],udg_u2[udg_ID2],0,60.0,false,0.0,"LEAS",0)
Then remove it afterwards with:

JASS:
local Lightning beam = udg_Beam[udg_ID]
call beam.remove()
 
Last edited:
Top