[System] Timed Lightnings v1.0.1.1

This bundle is marked as approved. It works and satisfies the submission rules.
  • Like
Reactions: deepstrasz
A lightning system that allows easy creation of timed lightnings.

Create lightnings from
*point to point
*point to unit
*unit to point
*unit to unit

Supports moving points/units.

JASS:
/******************************************************************************
 *
 *  TIMED LIGHTNINGS by Maker v1.0.1.1
 *
 *  Allows the creation of lightnings with expiration timer.
 *  Supports:
 *      o Fading lightnings in and out
 *      o Attaching to units 
 *      o Attaching to points
 *      o Linear movement in x-, y- and z-axes
 *
 *
 *  Methods
 *
 *      P2U
 *          From a static point attached to a unit
 *          static method P2U takes lightning l, unit t, real time, real x1, real y1, real z1, real z2, real startAlpha, real endAlpha returns nothing
 *          
 *          The lightning, target unit, duration, origin x, origin y, origin z, end z
 *
 *
 *      P2UEx
 *          From a moving point attached to a unit
 *          static method P2UEx takes lightning l, unit a, real t, real zu, real x1, real y1, real z1, real x2, real y2, real z2, real startAlpha, real endAlpha returns nothing
 *
 *          The lightning, target unit, duration, target z, origin start x, origin start y, origin start z, origin end x, origin end y, origin end z
 *
 *      U2P
 *          From attached to a unit to a static point
 *          static method U2P takes lightning l, unit s, real t, real x1, real y1, real x2, real y2, real z1, real z2, real startAlpha, real endAlpha returns nothing
 *
 *          The lightning, source unit, duration, origin x, origin y, point x , point y, source z, point z
 *
 *      U2PEx
 *          From attached to a unit to a moving point
 *          static method U2PEx takes lightning l, unit a, real t, real zu, real x1, real y1, real z1, real x2, real y2, real z2, real startAlpha, real endAlpha returns nothing
 *
 *          The lightning, source unit, duration, source z, point start x, point start y, point start z, point end x, point end y, point end z
 *
 *      U2U
 *          From attached to a unit to attached to a unit
 *          static method U2U takes lightning l, unit s, unit t, real time, real z1, real z2, real startAlpha, real endAlpha returns nothing
 *
 *          The lightning, source unit, target unit, duration, source z, target z
 *
 *      P2P
 *          From a static point to a static point
 *          static method P2P takes lightning l, real t, real startAlpha, real endAlpha returns nothing
 *
 *          The lightning, duration
 *
 *      P2PEx
 *          From a moving point to a moving point
 *          static method P2PEx takes lightning l, real t, real x1, real y1, real z1, real x2, real y2, real z2, real x3, real y3, real z3, real x4, real y4, real z4, real startAlpha, real endAlpha returns nothing
 *
 *          The lightning, duration, origin start x, origin start y, origin start z, origin end x, origin end y, origin end z, target start x, target start y, target start z, target end x, target end y, target end z
 *
 *  
 *      Alpha values are between 1 and 0. 1 is fully visible, 0 is transparent.
 *
 *******************************************************************************/
library TimedLightnings

    globals
        private constant    real        TO      = 0.03125000    // Update interval 
        
        private             integer     CT      = 0             // Lightning count
        private             timer       TMR     = CreateTimer()
        private             location    loc     = Location(0,0)
    endglobals
    
    struct TimedL extends array
    
        lightning l
        real av        // aplha value
        real da        // transparency change rate
        real x1   
        real x2
        real y1
        real y2
        real z1
        real z2
        real dx1
        real dy1
        real dz1
        real dx2
        real dy2
        real dz2
        unit s          // source
        unit t          // target
        integer time    // how many ticks, time
        integer next    // next node
        integer prev    // previous node
        boolean moves
        
        private static integer rlast = 0    // previous created
        private static thistype first       // first node
        
        private static integer ic = 0
        private static integer ir = 0
        private thistype rn
        
        private static thistype dat
        private static thistype dat2
        private static thistype dat3
        
        private static method destroyL takes nothing returns nothing
        /*-Link previous node with next one-*/
            set dat3 = dat2.prev
            set dat3.next = dat2.next
        /*-----Set new last created node----*/
            if dat2 == rlast then
                set rlast = dat3
            endif
        
        /*-Link next node with previous one-*/
            set dat3 = dat2.next
            set dat3.prev = dat2.prev
        /*--------Set new first node--------*/
            if dat2 == first then
                set first = dat3
            endif
            
            call DestroyLightning(dat2.l)
            set CT = CT - 1
            if CT == 0 then
                call PauseTimer(TMR)
            endif
            set dat2.rn=ir
            set ir=dat2
        endmethod
        
        private static method looping takes nothing returns nothing
            local real z1
            local real z2
            set dat = first
            loop
                set z1 = 0
                set z2 = 0
                set dat.time = dat.time - 1
                if dat.da != 0 then
                    set dat.av = dat.av - dat.da
                    call SetLightningColor(dat.l, 1, 1, 1, dat.av)
                endif
                if dat.s == null then
                    if dat.dx1 != 0 then
                        set dat.x1 = dat.x1 + dat.dx1
                    endif
                    if dat.dy1 != 0 then
                        set dat.y1 = dat.y1 + dat.dy1
                    endif
                    if dat.dz1 != 0 then
                        set dat.z1 = dat.z1 + dat.dz1
                    endif
                else
                    set dat.x1 = GetUnitX(dat.s)
                    set dat.y1 = GetUnitY(dat.s)
                    set z1 = GetUnitFlyHeight(dat.s)
                endif
                if dat.t == null then
                    if dat.dx2 != 0 then
                        set dat.x2 = dat.x2 + dat.dx2
                    endif
                    if dat.dy2 != 0 then
                        set dat.y2 = dat.y2 + dat.dy2
                    endif
                    if dat.dz2 != 0 then
                        set dat.z2 = dat.z2 + dat.dz2
                    endif
                else
                    set dat.x2 = GetUnitX(dat.t)
                    set dat.y2 = GetUnitY(dat.t)
                    set z2 = GetUnitFlyHeight(dat.t)
                endif
                if dat.moves then
                    call MoveLocation(loc, dat.x1, dat.y1)
                    set z1 = GetLocationZ(loc) + dat.z1 + z1
                    call MoveLocation(loc, dat.x2, dat.y2)
                    set z2 = GetLocationZ(loc) + dat.z2 + z2
                    call MoveLightningEx(dat.l, true, dat.x1, dat.y1, z1, dat.x2, dat.y2, z2)
                endif
                if dat.time == 0 then
                    set dat2 = dat
                    set dat = dat.next
                    call destroyL()
                else
                    set dat = dat.next
                endif
                exitwhen dat == 0
            endloop
        endmethod
        
        private static method InitAdd takes nothing returns nothing
            /* Add node to list, make this the last on list */
            if rlast != 0 then
                set dat2 = rlast
                set dat2.next = dat
            endif
            
            /* Link this with previous node                 */
            set dat.prev = rlast
            /* Make this the last created node              */
            set rlast = dat
            
            set CT = CT + 1
            if CT == 1 then
                /* Make this the first node                 */
                set first = dat
                call TimerStart(TMR, TO, true, function thistype.looping)
            endif
        endmethod
        
        private static method Recycle takes nothing returns nothing
            if 0==ir then
                set ic=ic+1
                set dat=ic
            else
                set dat=ir
                set ir=dat.rn
            endif
        endmethod
        
        static method P2U takes lightning l, unit t, real time, real x1, real y1, real z1, real z2, real startAlpha, real endAlpha returns nothing
            local thistype this
            
            call Recycle()
            set this = dat
            
            set .x1 = x1
            set .y1 = y1
            set .z1 = z1
            set .z2 = z2
            set .s = null
            set .t = t
            set .next = 0   // Nodes are added to the end of the list, there is no next node
            set .l = l
            set .time = R2I(time/TO)   // Calculates how many loops does the lightning lasts
            set .av = startAlpha
            set .da = (startAlpha-endAlpha)*TO/time    // Transparency change speed
            set .moves = true

            call InitAdd()
        endmethod
        
        static method U2P takes lightning l, unit s, real t, real x1, real y1, real x2, real y2, real z1, real z2, real startAlpha, real endAlpha returns nothing
            local thistype this
            
            call Recycle()
            set this = dat
            
            set .x1 = x1
            set .y1 = y1
            set .x2 = x2
            set .y2 = y2
            set .z1 = z1
            set .z2 = z2
            set .s = s
            set .t = null
            set .next = 0
            set .l = l
            set .time = R2I(t/TO)
            set .av = startAlpha
            set .da = (startAlpha-endAlpha)*TO/t
            set .moves = true

            call InitAdd()
        endmethod
        
        static method U2U takes lightning l, unit s, unit t, real time, real z1, real z2, real startAlpha, real endAlpha returns nothing
            local thistype this
            
            call Recycle()
            set this = dat
            
            set .z1 = z1
            set .z2 = z2
            set .s = s
            set .t = t 
            set .next = 0
            set .l = l
            set .time = R2I(time/TO)
            set .av = startAlpha
            set .da = (startAlpha-endAlpha)*TO/time
            set .moves = true

            call InitAdd()
        endmethod
        
        static method P2P takes lightning l, real t, real startAlpha, real endAlpha returns nothing
            local thistype this
            
            call Recycle()
            set this = dat
            
            set .s = null
            set .t = null
            set .next = 0
            set .l = l
            set .time = R2I(t/TO)
            set .av = startAlpha
            set .da = (startAlpha-endAlpha)*TO/t
            set .moves = false

            call InitAdd()
        endmethod
        
        static method P2UEx takes lightning l, unit a, real t, real zu, real x1, real y1, real z1, real x2, real y2, real z2, real startAlpha, real endAlpha returns nothing
            local thistype this
            local real n = TO/t
            
            call Recycle()
            set this = dat
            
            set .x1 = x1
            set dx1 = (x2-x1)*n
            set .y1 = y1
            set dy1 = (y2-y1)*n
            set .z1 = z1
            set dz1 = (z2-z1)*n
            set .z2 = zu
            set .s = null
            set .t = a
            set .next = 0
            set .l = l
            set .time = R2I(t/TO)
            set .av = startAlpha
            set .da = (startAlpha-endAlpha)*n
            set .moves = true

            call InitAdd()
        endmethod
        
        static method U2PEx takes lightning l, unit a, real t, real zu, real x1, real y1, real z1, real x2, real y2, real z2, real startAlpha, real endAlpha returns nothing
            local thistype this
            local real n = TO/t
            
            call Recycle()
            set this = dat
            
            set .x2 = x1
            set .dx2 = (x2-x1)*n
            set .y2 = y1
            set .dy2 = (y2-y1)*n
            set .z2 = z1
            set .dz2 = (z2-z1)*n
            set .z1 = zu
            set .s = a
            set .t = null
            set .next = 0
            set .l = l
            set .time = R2I(t/TO)
            set .av = startAlpha
            set .da = (startAlpha-endAlpha)*n
            set .moves = true

            call thistype.InitAdd()
        endmethod
    
        static method P2PEx takes lightning l, real t, real x1, real y1, real z1, real x2, real y2, real z2, real x3, real y3, real z3, real x4, real y4, real z4, real startAlpha, real endAlpha returns nothing
            local thistype this
            local real n = TO/t
            
            call Recycle()
            set this = dat
            
            set .x1 = x1
            set .x2 = x3
            set .y1 = y1
            set .y2 = y3
            set .z1 = z1
            set .z2 = z3
            set .dx1 = (x2-x1)*n
            set .dy1 = (y2-y1)*n
            set .dz1 = (z2-z1)*n
            set .dx2 = (x4-x3)*n
            set .dy2 = (y4-y3)*n
            set .dz2 = (z4-z3)*n
            set .s = null
            set .t = null
            set .next = 0
            set .l = l
            set .time = R2I(t/TO)
            set .av = startAlpha
            set .da = (startAlpha-endAlpha)*n
            set .moves = true

            call InitAdd()
        endmethod
    endstruct
    
endlibrary


v1.0.0.0 uploded 10.10.11
v1.0.1.0 uploaded 10.10.11
-Combined structs
-Now runs on one timer
-Factors in flying height
v1.0.1.1
-Now uses Nestharus' instance recycling


Keywords:
lightning, timed, maker
Contents

Just another Warcraft III map (Map)

Reviews
19th Oct 2011 Bribe: Highly recommended as a system to handle your lightning needs. It can handle as many lightnings as you want without lagging.

Moderator

M

Moderator

19th Oct 2011
Bribe: Highly recommended as a system to handle your lightning needs. It can handle as many lightnings as you want without lagging.
 
Level 38
Joined
Sep 26, 2009
Messages
8,490
You could use CTL32 by Nestharus or Timer32 by Jesus4Lyf here, to
avoid needing to create so many different timers.

It would make more sense to compress this into one struct and use
booleans to determine the type of source/origin.

I am not sure what you are using to check a "moving point". Shouldn't
it take a location in such a case? Also maybe instead of a unit it should
take a widget, for example if you wanted to attach to an item. And
the lightning should take into effect the flying height of the unit.
 
Level 15
Joined
Nov 26, 2005
Messages
1,154
You need to have JassHelper 0.A.2.B to compile this.

Some older JassHelpers don't let you reference static members without the dot as a prefix.

I am almost 99.9% sure I have it ... though how can I check which version it is ? I am sure I downloaded http://www.wc3c.net/showthread.php?t=88142 that and copy/pasted the folders. But still it shows that error. Any idea on fixing ?


::
Fixed.
::
 
Level 15
Joined
Jul 4, 2008
Messages
1,106
You could use CTL32 by Nestharus or Timer32 by Jesus4Lyf here, to
avoid needing to create so many different timers.
The point of this system is not to use other peoples systems, and the another thing with
this system was to keep it as minimal JNGP use as possible. It could've been created in
Jass instead of vJass, but if I remember right; The only reason he made this in vJass is
because he did not want to use udg_* variables, as they would just take space for other
systems. I have yet to discover the reason for the Library, Structs and Methods that he
seemed to require judging by the script. ~ Now I shall take a quick review on the
performance of this system, and give my opinion on that.

The system seems to be creating smooth transition on the lightnings, enough to give it a 4/5 status.
 
Level 37
Joined
Mar 6, 2006
Messages
9,242
You could use CTL32 by Nestharus or Timer32 by Jesus4Lyf here...
It would make more sense to compress this into one struct...

I am not sure what you are using to check a "moving point". Shouldn't
it take a location in such a case? Also maybe instead of a unit it should
take a widget, for example if you wanted to attach to an item. And
the lightning should take into effect the flying height of the unit.

Now uses only one timer and one struct, but not an external timer system. Flying height added.

If I used a widget, how would I determine whether it is a unit or not, for flying height?

Moving point as in one can make the lightning travel from (x1,y1,z1) to (x2, y2,z2) during the life time. Handy for sweeping beams.

Your struct(s) should be array ones.

Yeah, I've read that before. I might update this to follow that guide.

Bribe, that is only what I had heard, or what I discussed with him.

I just originally tried to make it not require external libraries.
 
Level 22
Joined
Nov 14, 2008
Messages
3,256
Would have been cool making either CTL32 or T32 optional yet it would be a pain in the arse to optionalize both. Either way this is great, better than the Lightning library at TH.

And I don't find it bad to require a library (either CTL or T32) as they're both way too common and heavily used (if you're not stupid when mapmaking) by mapmakers.

Just a simple question, why is .time member not integer in the first place if you want to use integers? :p

@OG

Creating the structs in vanilla JASS is way harder than downloading JNGP and typing struct name / endstruct (yeah no need for the latest JH to compile structs).

There are nothing as "minimal JNGP" usage. Either you use JNGP and its features or you don't. And you know that don't you?

The only reason he made this in vJass is
because he did not want to use udg_* variables
It's not the variables that are difficult, it's the struct creation as said above.

Methods are functions with an extra integer parameter (hidden to the eye of course) and static methods are basic functions.

Libraries just put the code into the map header although it gives you the oppertunity to sort functions by typing "needs libraryname" by auto than doing it yourself.
 
CTL would be a better choice.
I still like the fact that you managed to get this to run on one timer without any requirements :)

And so you don't have to read that tutorial by Nes:

JASS:
struct YourStruct extends array
    private static integer ic = 0
    private static integer ir = 0
    private thistype rn

    // allocate like this:
    local thistype this
    if 0==ir then
        set ic=ic+1
        return ic
    else
        set this=ir
        set ir=.rn
    endif
    return this

    // deallocate like this
    set .rn=ir
    set ir=this

Pretty straight-forward :p
 
Level 33
Joined
Apr 24, 2012
Messages
5,118
JASS:
native GetLightningColorA           takes lightning whichBolt returns real

native GetLightningColorR           takes lightning whichBolt returns real

native GetLightningColorG           takes lightning whichBolt returns real

native GetLightningColorB           takes lightning whichBolt returns real

Because your lightning does not support lightning color,use these :D
 
Top