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

[GUI-Friendly] Custom Lightning Locker (GCLL) v1.5

What is this?
This is a system that can
  • lock your lightning to units, (x, y) and points
  • apply timed life to your lightning
  • fade out or fade in your lightning
  • change your lightning color periodically
How to import?
  1. Go to File tab > [tab]Preferences. Make sure "Automatically create unknwon variables... is ticked.
    [*]Copy "GUI Custom Lightning Locker" category with "gCLL" and "gCLL VariablesGen" triggers in it.
    [*]Paste it to your map
    [*]Finish!
    [/tab]
[tab]


JASS:
//  =========================================================================================
//                         Custom Lightning Locker v1.5
//                              by Reventhous
//  =========================================================================================
//  -----------------------------------------------------------------------------------------
//    ¬This is a system that allows you to manipulate wc3 lightning with ease
//
//     1. You can lock a lightning between:
//
//               -two unit (U2U)
//               -point and unit (P2U)
//               -location and unit (P2ULoc)
//               -two point (P2P)
//               -two location (P2PLoc)
//
//
//     2. You can modify their lightning's:
//
//               -alpha channel or transperancy
//               -life time
//               -red value (the RGB)
//               -green value (the RGB)
//               -blue value (the RGB)
//
//        All of the above modification can be done within a duration
//
//   
//     3. Available events:
//
//               -GCLL_Event Equal to 1.00 -> when the lightning makes any movement
//               -GCLL_Event Equal to 2.00 -> when the lightning changes its color
//               -GCLL_Event Equal to 3.00 -> when the lightning get destroyed
//
//  -----------------------------------------------------------------------------------------
//  NOTE     : Let's take "CLL" as this system instance name
//  -----------------------------------------------------------------------------------------
// 
//    ¬HOW TO IMPORT
//     1. Go to File [tab] > Preferences. Make sure "Automatically create unknown variables...
//        is ticked.
//     2. Copy this "GUI Custom Lightning Locker" category with "GCLL" and "GCLL VariablesGen" triggers in it.
//     3. Paste it to your map
//     4. Finish!
//

//  =========================================================================================
//                  C  O  N  F  I  G  U  R  A  T  I  O  N  S
//  =========================================================================================

//  -----------------------------------------------------------------------------------------
//  The interval. 0.031250000 means 32 frame per second
//  -----------------------------------------------------------------------------------------
constant function GCLL_INTERVAL takes nothing returns real
    return 0.031250000
endfunction

//  -----------------------------------------------------------------------------------------
//  The max life time for CLL. Automatically destroy created CLL after 2 hours
//  REMEMBER! 0h0m0s means this system will do nothing for you!
//  -----------------------------------------------------------------------------------------
constant function GCLL_MAX_LIFE_TIME takes nothing returns integer
    local integer hour   = 2
    local integer minute = 0
    local integer second = 0
  
    local integer fps    = 32 //calculate-> 1.00/GCLL_INTERVAL = 32
    return hour*60*60*fps + minute*60*fps + second*fps
endfunction

//  -----------------------------------------------------------------------------------------
//  Debug mode toggle. You will see helpful messages ingame when this is "true"
//  -----------------------------------------------------------------------------------------
constant function GCLL_DEBUG_MODE takes nothing returns boolean
    return true
endfunction

//  =========================================================================================
//              E  N  D     O  F     C  O  N  F  I  G  U  R  A  T  I  O  N  S
//  =========================================================================================

//  -----------------------------------------------------------------------------------------
//  What ever you do below this line is at your own risk
//  -----------------------------------------------------------------------------------------

// Will get the current ground z- axis
function GCLL_GetZ takes real x, real y returns real
    call MoveLocation(udg_GCLL_Location, x, y)
    return GetLocationZ(udg_GCLL_Location)
endfunction

// Deallocate
function GCLL_Deallocate takes integer this returns nothing
    if this == udg_GCLL_MaxIndex then
        set udg_GCLL_MaxIndex = udg_GCLL_MaxIndex - 1
    else
        set udg_GCLL_Recycle[this] = udg_GCLL_Recycle[0]
        set udg_GCLL_Recycle[0] = this
    endif
  
    //remove the index from the list
    set udg_GCLL_Next[udg_GCLL_Prev[this]] = udg_GCLL_Next[this]
    set udg_GCLL_Prev[udg_GCLL_Next[this]] = udg_GCLL_Prev[this]
  
    //stop timer when last index on list is 0
    if udg_GCLL_Next[0] == 0 then
        call PauseTimer(udg_GCLL_Iterator)
    endif
endfunction

// allocate
function GCLL_Allocate takes nothing returns integer
    local integer this
  
    if (udg_GCLL_Recycle[0] == 0) then
        set udg_GCLL_MaxIndex = udg_GCLL_MaxIndex + 1
        set this = udg_GCLL_MaxIndex
    else
        set this = udg_GCLL_Recycle[0]
        set udg_GCLL_Recycle[0] = udg_GCLL_Recycle[this]
    endif

    //add the index to the list
    set udg_GCLL_Prev[udg_GCLL_Next[0]] = this
    set udg_GCLL_Next[this] = udg_GCLL_Next[0]
    set udg_GCLL_Next[0] = this
    set udg_GCLL_Prev[this] = 0
  
    return this
endfunction

// Data reset
function GCLL_Reset takes integer i returns nothing
    set udg_GCLL_Lightning[i] = null
  
    set udg_GCLL_SourceUnit[i] = null
    set udg_GCLL_StaticSourcePoint[i] = null
    set udg_GCLL_SourcePoint[i] = null
  
    set udg_GCLL_TargetUnit[i] = null
    set udg_GCLL_StaticTargetPoint[i] = null
    set udg_GCLL_TargetPoint[i] = null
  
    set udg_GCLL_CurrentX1[i] = 0.00
    set udg_GCLL_CurrentY1[i] = 0.00
    set udg_GCLL_CurrentZ1[i] = 0.00
    set udg_GCLL_CurrentX2[i] = 0.00
    set udg_GCLL_CurrentY2[i] = 0.00
    set udg_GCLL_CurrentZ2[i] = 0.00
  
    set udg_GCLL_SourceX[i] = 0.00
    set udg_GCLL_SourceY[i] = 0.00
    set udg_GCLL_StaticSourceX[i] = 0.00
    set udg_GCLL_StaticSourceY[i] = 0.00
    set udg_GCLL_TargetX[i] = 0.00
    set udg_GCLL_TargetY[i] = 0.00
    set udg_GCLL_StaticTargetX[i] = 0.00
    set udg_GCLL_StaticTargetY[i] = 0.00
    set udg_GCLL_Alpha[i] = 1.00
    set udg_GCLL_Red[i] = 1.00
    set udg_GCLL_Green[i] = 1.00
    set udg_GCLL_Blue[i] = 1.00
    set udg_GCLL_FadeRate[i] = 0.00
    set udg_GCLL_RedChangeRate[i] = 0.00
    set udg_GCLL_GreenChangeRate[i] = 0.00
    set udg_GCLL_BlueChangeRate[i] = 0.00
    set udg_GCLL_InitialZ1[i] = 0.00
    set udg_GCLL_InitialZ2[i] = 0.00
  
    set udg_GCLL_Time[i] = GCLL_MAX_LIFE_TIME()
  
    set udg_GCLL_IsTimed[i] = false
    set udg_GCLL_IsSourceStatic[i] = false
    set udg_GCLL_IsTargetStatic[i] = false
    set udg_GCLL_Destroy[i] = false
endfunction

// destroy
function GCLL_Destroy takes integer i returns nothing
    if udg_GCLL_Lightning[i] != null then
        call DestroyLightning(udg_GCLL_Lightning[i])
    endif
  
    if udg_GCLL_SourcePoint[i] != null then
        call RemoveLocation(udg_GCLL_SourcePoint[i])
    endif
  
    if udg_GCLL_StaticSourcePoint[i] != null then
        call RemoveLocation(udg_GCLL_SourcePoint[i])
    endif
  
    if udg_GCLL_TargetPoint[i] != null then
        call RemoveLocation(udg_GCLL_SourcePoint[i])
    endif
  
    if udg_GCLL_StaticTargetPoint[i] != null then
        call RemoveLocation(udg_GCLL_SourcePoint[i])
    endif

    set udg_GCLL_EventIndex = i
    set udg_GCLL_Event = 3.00
    set udg_GCLL_Event = 0.00
  
    call GCLL_Reset(i)
    call GCLL_Deallocate(i)
endfunction

//this function will update alpha, red, green and blue color value of the lightning
function GCLL_UpdateARGB takes integer i returns boolean
    if udg_GCLL_FadeRate[i] != 0.00 then
        if udg_GCLL_Alpha[i] > 0.00 and udg_GCLL_Alpha[i] < 1.00 then
            set udg_GCLL_Alpha[i] = udg_GCLL_Alpha[i] + udg_GCLL_FadeRate[i]
        else
            set udg_GCLL_FadeRate[i] = 0.00
        endif
    endif
  
    if udg_GCLL_RedChangeRate[i] != 0.00 then
        if udg_GCLL_Red[i] > 0.00 and udg_GCLL_Red[i] < 1.00 then
            set udg_GCLL_Red[i] = udg_GCLL_Red[i] + udg_GCLL_RedChangeRate[i]
        else
            set udg_GCLL_RedChangeRate[i] = 0.00
        endif
    endif
  
    if udg_GCLL_GreenChangeRate[i] != 0.00 then
        if udg_GCLL_Green[i] > 0.00 and udg_GCLL_Green[i] < 1.00 then
            set udg_GCLL_Green[i] = udg_GCLL_Green[i] + udg_GCLL_GreenChangeRate[i]
        else
            set udg_GCLL_GreenChangeRate[i] = 0.00
        endif
    endif
  
    if udg_GCLL_BlueChangeRate[i] != 0.00 then
        if udg_GCLL_Blue[i] > 0.00 and udg_GCLL_Blue[i] < 1.00 then
            set udg_GCLL_Blue[i] = udg_GCLL_Blue[i] + udg_GCLL_BlueChangeRate[i]
        else
            set udg_GCLL_BlueChangeRate[i] = 0.00
        endif
    endif
  
    //We don't want negative value
    if udg_GCLL_Alpha[i] < 0.00 then
        set udg_GCLL_Alpha[i] = 0.00
    endif
              
    if udg_GCLL_Red[i] < 0.00 then
        set udg_GCLL_Red[i] = 0.00
    endif
              
    if udg_GCLL_Green[i] < 0.00 then
        set udg_GCLL_Green[i] = 0.00
    endif
          
    if udg_GCLL_Blue[i] < 0.00 then
        set udg_GCLL_Blue[i] = 0.00
    endif
          
    //Greater than 1.00 doesn't mean anything. It slows down the fading process
    if udg_GCLL_Alpha[i] > 1.00 then
        set udg_GCLL_Alpha[i] = 1.00
    endif
              
    if udg_GCLL_Red[i] > 1.00 then
        set udg_GCLL_Red[i] = 1.00
    endif
              
    if udg_GCLL_Green[i] > 1.00 then
        set udg_GCLL_Green[i] = 1.00
    endif
              
    if udg_GCLL_Blue[i] > 1.00 then
        set udg_GCLL_Blue[i] = 1.00
    endif
  
    return udg_GCLL_Alpha[i] != GetLightningColorA(udg_GCLL_Lightning[i]) or udg_GCLL_Red[i] != GetLightningColorR(udg_GCLL_Lightning[i]) or udg_GCLL_Green[i] != GetLightningColorG(udg_GCLL_Lightning[i]) or udg_GCLL_Blue[i] != GetLightningColorB(udg_GCLL_Lightning[i])
endfunction

//this function will update the lightning source and target x,y,z
function GCLL_MoveLightning takes integer i returns boolean
    local real x1
    local real y1
    local real z1
    local real x2
    local real y2
    local real z2
    local boolean r
  
    if not udg_GCLL_IsSourceStatic[i] then
        if udg_GCLL_Type[i] == udg_GCLL_Type_U2U then
            set x1 = GetUnitX(udg_GCLL_SourceUnit[i])
            set y1 = GetUnitY(udg_GCLL_SourceUnit[i])
            set z1 = GCLL_GetZ(x1, y1) + GetUnitFlyHeight(udg_GCLL_SourceUnit[i]) + udg_GCLL_InitialZ1[i]
          
        elseif udg_GCLL_Type[i] == udg_GCLL_Type_P2U then
            set x1 = udg_GCLL_SourceX[i]
            set y1 = udg_GCLL_SourceY[i]
            set z1 = GCLL_GetZ(x1, y1) + udg_GCLL_InitialZ1[i]
      
        elseif udg_GCLL_Type[i] == udg_GCLL_Type_P2ULoc then
            set x1 = GetLocationX(udg_GCLL_SourcePoint[i])
            set y1 = GetLocationY(udg_GCLL_SourcePoint[i])
            set z1 = GetLocationZ(udg_GCLL_SourcePoint[i]) + udg_GCLL_InitialZ1[i]
          
        elseif udg_GCLL_Type[i] == udg_GCLL_Type_P2P then
            set x1 = udg_GCLL_SourceX[i]
            set y1 = udg_GCLL_SourceY[i]
            set z1 = GCLL_GetZ(x1, y1) + udg_GCLL_InitialZ1[i]
          
        elseif udg_GCLL_Type[i] == udg_GCLL_Type_P2PLoc then
            set x1 = GetLocationX(udg_GCLL_SourcePoint[i])
            set y1 = GetLocationY(udg_GCLL_SourcePoint[i])
            set z1 = GetLocationZ(udg_GCLL_SourcePoint[i]) + udg_GCLL_InitialZ1[i]
        endif

    else
        if udg_GCLL_Type[i] == udg_GCLL_Type_U2U then
            set x1 = udg_GCLL_StaticSourceX[i]
            set y1 = udg_GCLL_StaticSourceY[i]
            set z1 = GCLL_GetZ(x1, y1) + udg_GCLL_InitialZ1[i]
          
        elseif udg_GCLL_Type[i] == udg_GCLL_Type_P2U then
            set x1 = udg_GCLL_StaticSourceX[i]
            set y1 = udg_GCLL_StaticSourceY[i]
            set z1 = GCLL_GetZ(x1, y1) + udg_GCLL_InitialZ1[i]
          
        elseif udg_GCLL_Type[i] == udg_GCLL_Type_P2ULoc then
            set x1 = GetLocationX(udg_GCLL_StaticSourcePoint[i])
            set y1 = GetLocationY(udg_GCLL_StaticSourcePoint[i])
            set z1 = GetLocationZ(udg_GCLL_StaticSourcePoint[i]) + udg_GCLL_InitialZ1[i]
          
        elseif udg_GCLL_Type[i] == udg_GCLL_Type_P2P then
            set x1 = udg_GCLL_StaticSourceX[i]
            set y1 = udg_GCLL_StaticSourceY[i]
            set z1 = GCLL_GetZ(x1, y1) + udg_GCLL_InitialZ1[i]
          
        elseif udg_GCLL_Type[i] == udg_GCLL_Type_P2PLoc then
            set x1 = GetLocationX(udg_GCLL_StaticSourcePoint[i])
            set y1 = GetLocationY(udg_GCLL_StaticSourcePoint[i])
            set z1 = GetLocationY(udg_GCLL_StaticSourcePoint[i]) + udg_GCLL_InitialZ1[i]
          
        endif
    endif
          
    if not udg_GCLL_IsTargetStatic[i] then
        if udg_GCLL_Type[i] == udg_GCLL_Type_U2U then
            set x2 = GetUnitX(udg_GCLL_TargetUnit[i])
            set y2 = GetUnitY(udg_GCLL_TargetUnit[i])
            set z2 = GCLL_GetZ(x2, y2) + GetUnitFlyHeight(udg_GCLL_TargetUnit[i]) + udg_GCLL_InitialZ2[i]
          
        elseif udg_GCLL_Type[i] == udg_GCLL_Type_P2U then
            set x2 = GetUnitX(udg_GCLL_TargetUnit[i])
            set y2 = GetUnitY(udg_GCLL_TargetUnit[i])
            set z2 = GCLL_GetZ(x2, y2) + GetUnitFlyHeight(udg_GCLL_TargetUnit[i]) + udg_GCLL_InitialZ2[i]
              
        elseif udg_GCLL_Type[i] == udg_GCLL_Type_P2ULoc then
            set x2 = GetUnitX(udg_GCLL_TargetUnit[i])
            set y2 = GetUnitY(udg_GCLL_TargetUnit[i])
            set z2 = GCLL_GetZ(x2, y2) + GetUnitFlyHeight(udg_GCLL_TargetUnit[i]) + udg_GCLL_InitialZ2[i]
          
        elseif udg_GCLL_Type[i] == udg_GCLL_Type_P2P then
            set x2 = udg_GCLL_TargetX[i]
            set y2 = udg_GCLL_TargetY[i]
            set z2 = GCLL_GetZ(x2, y2) + udg_GCLL_InitialZ2[i]
          
        elseif udg_GCLL_Type[i] == udg_GCLL_Type_P2PLoc then
            set x2 = GetLocationX(udg_GCLL_TargetPoint[i])
            set y2 = GetLocationY(udg_GCLL_TargetPoint[i])
            set z2 = GetLocationZ(udg_GCLL_TargetPoint[i]) + udg_GCLL_InitialZ2[i]
        endif
    else
        if udg_GCLL_Type[i] == udg_GCLL_Type_U2U then
            set x2 = udg_GCLL_StaticTargetX[i]
            set y2 = udg_GCLL_StaticTargetY[i]
            set z2 = GCLL_GetZ(x2, y2) + udg_GCLL_InitialZ2[i]
          
        elseif udg_GCLL_Type[i] == udg_GCLL_Type_P2U then
            set x2 = udg_GCLL_StaticTargetX[i]
            set y2 = udg_GCLL_StaticTargetY[i]
            set z2 = GCLL_GetZ(x2, y2) + udg_GCLL_InitialZ2[i]
      
        elseif udg_GCLL_Type[i] == udg_GCLL_Type_P2ULoc then
            set x2 = udg_GCLL_StaticTargetX[i]
            set y2 = udg_GCLL_StaticTargetY[i]
            set z2 = GCLL_GetZ(x2, y2) + udg_GCLL_InitialZ2[i]
          
        elseif udg_GCLL_Type[i] == udg_GCLL_Type_P2P then
            set x2 = udg_GCLL_StaticTargetX[i]
            set y2 = udg_GCLL_StaticTargetY[i]
            set z2 = GCLL_GetZ(x2, y2) + udg_GCLL_InitialZ2[i]
          
        elseif udg_GCLL_Type[i] == udg_GCLL_Type_P2PLoc then
            set x2 = GetLocationX(udg_GCLL_StaticTargetPoint[i])
            set y2 = GetLocationY(udg_GCLL_StaticTargetPoint[i])
            set z2 = GetLocationZ(udg_GCLL_StaticTargetPoint[i]) + udg_GCLL_InitialZ2[i]
          
        endif

    endif
  
    set r = x1 != udg_GCLL_CurrentX1[i] or y1 != udg_GCLL_CurrentY1[i] or z1 != udg_GCLL_CurrentZ1[i] or x2 != udg_GCLL_CurrentX2[i] or y2 != udg_GCLL_CurrentY2[i] or z2 != udg_GCLL_CurrentZ2[i]
  
    //check the reverse mode
    if r then
        if not udg_GCLL_IsReversed[i] then
            set udg_GCLL_CurrentX1[i] = x1
            set udg_GCLL_CurrentY1[i] = y1
            set udg_GCLL_CurrentZ1[i] = z1
            set udg_GCLL_CurrentX2[i] = x2
            set udg_GCLL_CurrentY2[i] = y2
            set udg_GCLL_CurrentZ2[i] = z2
        else
            set udg_GCLL_CurrentX1[i] = x2
            set udg_GCLL_CurrentY1[i] = y2
            set udg_GCLL_CurrentZ1[i] = z2
            set udg_GCLL_CurrentX2[i] = x1
            set udg_GCLL_CurrentY2[i] = y1
            set udg_GCLL_CurrentZ2[i] = z1
        endif
    endif
  
    return r
endfunction

// The iterating/main function
function GCLL_OnIterate takes nothing returns nothing
    local integer i = udg_GCLL_Next[0]

    loop
        exitwhen i == 0
      
        // Will automatically destroy when the system can't find the lightning
        if udg_GCLL_Lightning[i] != null then
      
            //won't do anything when nothing to do
            if GCLL_MoveLightning(i) then
                call MoveLightningEx(udg_GCLL_Lightning[i], true, udg_GCLL_CurrentX1[i], udg_GCLL_CurrentY1[i], udg_GCLL_CurrentZ1[i], udg_GCLL_CurrentX2[i], udg_GCLL_CurrentY2[i], udg_GCLL_CurrentZ2[i])

                set udg_GCLL_EventIndex = i
                set udg_GCLL_Event = 1.00
                set udg_GCLL_Event = 0.00
            endif
              
            if GCLL_UpdateARGB(i) then
                call SetLightningColor(udg_GCLL_Lightning[i], udg_GCLL_Red[i], udg_GCLL_Green[i], udg_GCLL_Blue[i], udg_GCLL_Alpha[i])
              
                set udg_GCLL_EventIndex = i
                set udg_GCLL_Event = 2.00
                set udg_GCLL_Event = 0.00
            endif
              
            // The countdown for the lightning
            if udg_GCLL_Time[i] > 0 then
                set udg_GCLL_Time[i] = udg_GCLL_Time[i] - 1
            else
                call GCLL_Destroy(i)
            endif
      
        else
            call GCLL_Destroy(i)
        endif
      
        // For destroy method
        if udg_GCLL_Destroy[i] then
            call GCLL_Destroy(i)
        endif
      
        // Get the previous index on the list
        set i = udg_GCLL_Next[i]
    endloop
endfunction

//  -----------------------------------------------------------------------------------------
//  Everything below this line is the "create" method for this system
//  -----------------------------------------------------------------------------------------

function GCLL_StartTimer takes nothing returns nothing
    if udg_GCLL_Next[0] == 0 then
        call TimerStart(udg_GCLL_Iterator, GCLL_INTERVAL(), true, function GCLL_OnIterate)
    endif
endfunction

function GCLL_AssignConstant takes integer node returns nothing
    set udg_GCLL_Red[node] = 1.00
    set udg_GCLL_Green[node] = 1.00
    set udg_GCLL_Blue[node] = 1.00
    set udg_GCLL_Alpha[node] = 1.00
    set udg_GCLL_Time[node] = GCLL_MAX_LIFE_TIME()
endfunction

function GCLL_U2U takes string codeName, unit source, unit target, real initialZ1, real initialZ2, boolean isSourceStatic, boolean isTargetStatic returns nothing
    local integer i
    local real x1
    local real y1
    local real z1
    local real x2
    local real y2
    local real z2
  
    call GCLL_StartTimer()
  
    set i = GCLL_Allocate()
      
    set x1 = GetUnitX(source)
    set y1 = GetUnitY(source)
    set z1 = GCLL_GetZ(x1, y1) + GetUnitFlyHeight(source) + initialZ1
    set x2 = GetUnitX(target)
    set y2 = GetUnitY(target)
    set z2 = GCLL_GetZ(x2, y2) + GetUnitFlyHeight(target) + initialZ2

    call GCLL_AssignConstant(i)
      
    set udg_GCLL_Lightning[i] = AddLightningEx(codeName, true, x1, y1, z1, x2, y2, z2)
    set udg_GCLL_SourceUnit[i] = source
    set udg_GCLL_TargetUnit[i] = target
    set udg_GCLL_InitialZ1[i] = initialZ1
    set udg_GCLL_InitialZ2[i] = initialZ2
    set udg_GCLL_IsSourceStatic[i] = isSourceStatic
    set udg_GCLL_StaticSourceX[i] = x1
    set udg_GCLL_StaticSourceY[i] = y1
    set udg_GCLL_IsTargetStatic[i] = isTargetStatic
    set udg_GCLL_StaticTargetX[i] = x2
    set udg_GCLL_StaticTargetY[i] = y2
    set udg_GCLL_IsReversed[i] = false
      
    set udg_GCLL_Type[i] = udg_GCLL_Type_U2U
      
    set udg_GCLL_CurrentX1[i] = x1
    set udg_GCLL_CurrentY1[i] = y1
    set udg_GCLL_CurrentZ1[i] = z1
    set udg_GCLL_CurrentX2[i] = x2
    set udg_GCLL_CurrentY2[i] = y2
    set udg_GCLL_CurrentZ2[i] = z2
      
    set udg_GCLL_LastCreatedCLL = i
endfunction

function GCLL_P2U takes string codeName, real x1, real y1, unit target, real initialZ1, real initialZ2, boolean isSourceStatic, boolean isTargetStatic returns nothing
    local integer i
    local real z1
    local real x2
    local real y2
    local real z2
  
    call GCLL_StartTimer()
  
    set i = GCLL_Allocate()
      
    set z1 = GCLL_GetZ(x1, y1) + initialZ1
    set x2 = GetUnitX(target)
    set y2 = GetUnitY(target)
    set z2 = GCLL_GetZ(x2, y2) + GetUnitFlyHeight(target) + initialZ2
      
    call GCLL_AssignConstant(i)
      
    set udg_GCLL_Lightning[i] = AddLightningEx(codeName, true, x1, y1, z1, x2, y2, z2)
    set udg_GCLL_SourceX[i] = x1
    set udg_GCLL_SourceY[i] = y1       
    set udg_GCLL_TargetUnit[i] = target
    set udg_GCLL_InitialZ1[i] = initialZ1
    set udg_GCLL_InitialZ2[i] = initialZ2
    set udg_GCLL_IsSourceStatic[i] = isSourceStatic
    set udg_GCLL_StaticSourceX[i] = udg_GCLL_SourceX[i]
    set udg_GCLL_StaticSourceY[i] = udg_GCLL_SourceY[i]
    set udg_GCLL_IsTargetStatic[i] = isTargetStatic
    set udg_GCLL_StaticTargetX[i] = x2
    set udg_GCLL_StaticTargetY[i] = y2
    set udg_GCLL_IsReversed[i] = false
    set udg_GCLL_Type[i] = udg_GCLL_Type_P2U
              
    set udg_GCLL_CurrentX1[i] = x1
    set udg_GCLL_CurrentY1[i] = y1
    set udg_GCLL_CurrentZ1[i] = z1
    set udg_GCLL_CurrentX2[i] = x2
    set udg_GCLL_CurrentY2[i] = y2
    set udg_GCLL_CurrentZ2[i] = z2

    set udg_GCLL_LastCreatedCLL = i
endfunction

function GCLL_P2ULoc takes string codeName, location source, unit target, real initialZ1, real initialZ2, boolean isSourceStatic, boolean isTargetStatic returns nothing
    local integer i
    local real x1
    local real y1
    local real z1
    local real x2
    local real y2
    local real z2

    call GCLL_StartTimer()
  
    set i = GCLL_Allocate()
  
    set x1 = GetLocationX(source)
    set y1 = GetLocationY(source)
    set z1 = GCLL_GetZ(x1, y1) + initialZ1
    set x2 = GetUnitX(target)
    set y2 = GetUnitY(target)
    set z2 = GCLL_GetZ(x2, y2)+ GetUnitFlyHeight(target) + initialZ2
  
    call GCLL_AssignConstant(i)
  
    set udg_GCLL_Lightning[i] = AddLightningEx(codeName, true, x1, y1, z1, x2, y2, z2)
    set udg_GCLL_SourcePoint[i] = source
    set udg_GCLL_TargetUnit[i] = target
    set udg_GCLL_InitialZ1[i] = initialZ1
    set udg_GCLL_InitialZ2[i] = initialZ2
    set udg_GCLL_IsSourceStatic[i] = isSourceStatic
    set udg_GCLL_StaticSourcePoint[i] = source
    set udg_GCLL_IsTargetStatic[i] = isTargetStatic
    set udg_GCLL_StaticTargetX[i] = x2
    set udg_GCLL_StaticTargetY[i] = y2
    set udg_GCLL_IsReversed[i] = false
    set udg_GCLL_Type[i] = udg_GCLL_Type_P2ULoc
      
    set udg_GCLL_CurrentX1[i] = x1
    set udg_GCLL_CurrentY1[i] = y1
    set udg_GCLL_CurrentX2[i] = x2
    set udg_GCLL_CurrentY2[i] = y2

    set udg_GCLL_LastCreatedCLL = i
endfunction

function GCLL_P2P takes string codeName, real x1, real y1, real x2, real y2, real initialZ1, real initialZ2, boolean isSourceStatic, boolean isTargetStatic returns nothing
    local integer i
    local real z1
    local real z2

    call GCLL_StartTimer()
  
    set i = GCLL_Allocate()
      
    set z1 = GCLL_GetZ(x1, y1) + initialZ1
    set z2 = GCLL_GetZ(x2, y2) + initialZ2
      
    call GCLL_AssignConstant(i)
      
    set udg_GCLL_Lightning[i] = AddLightningEx(codeName, true, x1, y1, z1, x2, y2, z2)
    set udg_GCLL_SourceX[i] = x1
    set udg_GCLL_SourceY[i] = y1 
    set udg_GCLL_InitialZ1[i] = initialZ1
    set udg_GCLL_InitialZ2[i] = initialZ2
    set udg_GCLL_IsSourceStatic[i] = isSourceStatic
    set udg_GCLL_StaticSourceX[i] = x1
    set udg_GCLL_StaticSourceY[i] = y1
    set udg_GCLL_IsTargetStatic[i] = isTargetStatic
    set udg_GCLL_StaticTargetX[i] = x2
    set udg_GCLL_StaticTargetY[i] = y2
    set udg_GCLL_IsReversed[i] = false
    set udg_GCLL_Type[i] = udg_GCLL_Type_P2P
      
    set udg_GCLL_CurrentX1[i] = x1
    set udg_GCLL_CurrentY1[i] = y1
    set udg_GCLL_CurrentZ1[i] = z1
    set udg_GCLL_CurrentX2[i] = x2
    set udg_GCLL_CurrentY2[i] = y2
    set udg_GCLL_CurrentZ2[i] = z2
      
    set udg_GCLL_LastCreatedCLL = i
endfunction

function GCLL_P2PLoc takes string codeName, location source, location target, real initialZ1, real initialZ2, boolean isSourceStatic, boolean isTargetStatic returns nothing
    local integer i
    local real x1
    local real y1
    local real z1
    local real x2
    local real y2
    local real z2
  
    call GCLL_StartTimer()
  
    set i = GCLL_Allocate()
      
    set x1 = GetLocationX(source)
    set y1 = GetLocationY(source)
    set z1 = GCLL_GetZ(x1, y1) + initialZ1
    set x2 = GetLocationX(target)
    set y2 = GetLocationY(target)
    set z2 = GCLL_GetZ(x2, y2) + initialZ2
      
    call GCLL_AssignConstant(i)
      
    set udg_GCLL_Lightning[i] = AddLightningEx(codeName, true, x1, y1, z1, x2, y2, z2)
    set udg_GCLL_SourcePoint[i] = source
    set udg_GCLL_TargetPoint[i] = target
    set udg_GCLL_InitialZ1[i] = initialZ1
    set udg_GCLL_InitialZ2[i] = initialZ2
    set udg_GCLL_IsSourceStatic[i] = isSourceStatic
    set udg_GCLL_StaticSourcePoint[i] = source
    set udg_GCLL_IsTargetStatic[i] = isTargetStatic
    set udg_GCLL_StaticTargetPoint[i] = target
    set udg_GCLL_IsReversed[i] = false
    set udg_GCLL_Type[i] = udg_GCLL_Type_P2PLoc
      
    set udg_GCLL_CurrentX1[i] = x1
    set udg_GCLL_CurrentY1[i] = y1
    set udg_GCLL_CurrentZ1[i] = z1
    set udg_GCLL_CurrentX2[i] = x2
    set udg_GCLL_CurrentY2[i] = y2
    set udg_GCLL_CurrentZ2[i] = z2

    set udg_GCLL_LastCreatedCLL = i
endfunction

function GCLL_ApplyTimedLife takes integer cll, real duration returns nothing
    if duration == 0.00 then
        set udg_GCLL_Destroy[cll] = true
    else
        set udg_GCLL_IsTimed[cll] = true
        set udg_GCLL_Time[cll] = R2I(duration/GCLL_INTERVAL())
    endif
endfunction

function GCLL_SetFadeRate takes real sAlpha, real eAlpha, real duration, integer cll returns nothing
    if duration == 0.00 then
        set udg_GCLL_Alpha[cll] = eAlpha
    else
        set udg_GCLL_FadeRate[cll] = (eAlpha - sAlpha)/(duration/GCLL_INTERVAL())
        set udg_GCLL_Alpha[cll] = sAlpha + udg_GCLL_FadeRate[cll]
    endif
endfunction

function GCLL_SetRedCRate takes real sRed, real eRed, real duration, integer cll returns nothing
    if duration <= 0.00 then
        set udg_GCLL_Red[cll] = eRed
    else
        set udg_GCLL_RedChangeRate[cll] = (eRed - sRed)/(duration/GCLL_INTERVAL())
        set udg_GCLL_Red[cll] = sRed + udg_GCLL_RedChangeRate[cll]
    endif
endfunction

function GCLL_SetGreenCRate takes real sGreen, real eGreen, real duration, integer cll returns nothing
    if duration <= 0.00 then
        set udg_GCLL_Green[cll] = eGreen
    else
        set udg_GCLL_GreenChangeRate[cll] = (eGreen - sGreen)/(duration/GCLL_INTERVAL())
        set udg_GCLL_Green[cll] = sGreen + udg_GCLL_GreenChangeRate[cll]
    endif
endfunction

function GCLL_SetBlueCRate takes real sBlue, real eBlue, real duration, integer cll returns nothing
    if duration <= 0.00 then
        set udg_GCLL_Blue[cll] = eBlue
    else
        set udg_GCLL_BlueChangeRate[cll] = (eBlue - sBlue)/(duration/GCLL_INTERVAL())
        set udg_GCLL_Blue[cll] = sBlue + udg_GCLL_BlueChangeRate[cll]
    endif
endfunction

function GCLL_CapParameter takes nothing returns nothing
    if udg_GCLL_Register_StartValue > 1.00 then
        set udg_GCLL_Register_StartValue = 1.00
    elseif udg_GCLL_Register_StartValue < 0.00 then
        set udg_GCLL_Register_StartValue = 0.00
    endif
  
    if udg_GCLL_Register_EndValue > 1.00 then
        set udg_GCLL_Register_EndValue = 1.00
    elseif udg_GCLL_Register_EndValue < 0.00 then
        set udg_GCLL_Register_EndValue = 0.00
    endif
  
    if udg_GCLL_Register_Duration < 0.00 then
        set udg_GCLL_Register_Duration = 0.00
    endif
endfunction

function GCLL_Actions takes nothing returns nothing
    local string array msg
    local boolean b = false

    if udg_GCLL_Register_Type < 1 or 10 < udg_GCLL_Register_Type then
        if GCLL_DEBUG_MODE() then
            call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 30, "|CFFFFCC00[GCLL]|R: (Register) " + "Using undefined state/method id" )
        endif
  
        return
    endif
  
    set msg[udg_GCLL_Type_U2U] = "(U2U Register) "
    set msg[udg_GCLL_Type_P2U] = "(P2U Register) "
    set msg[udg_GCLL_Type_P2ULoc] = "(P2ULoc Register) "
    set msg[udg_GCLL_Type_P2P] = "(P2P Register) "
    set msg[udg_GCLL_Type_P2PLoc] = "(P2PLoc Register) "
    set msg[udg_GCLL_Type_Fade] = "(Fade Register) "
    set msg[udg_GCLL_Type_ApplyTimed] = "(ApplyTimed Register) "
    set msg[udg_GCLL_Type_ChangeRed] = "(ChangeRed Register) "
    set msg[udg_GCLL_Type_ChangeGreen] = "(ChangeGreen Register) "
    set msg[udg_GCLL_Type_ChangeBlue] = "(ChangeBlue Register) "

    if udg_GCLL_Register_Type == 1 then
        set b = udg_GCLL_Register_SourceUnit == null or udg_GCLL_Register_TargetUnit == null
    elseif udg_GCLL_Register_Type == 2 or 3 == udg_GCLL_Register_Type then
        set b = udg_GCLL_Register_TargetUnit == null
    elseif udg_GCLL_Register_Type == 5 then
        set b = udg_GCLL_Register_TargetPoint == null
    endif
      
    if udg_GCLL_Register_Type == 3 or 5 == udg_GCLL_Register_Type then
        set b = b or udg_GCLL_Register_SourcePoint == null
    endif
  
    if b then
        if GCLL_DEBUG_MODE() then
            call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 30, "|CFFFFCC00[GRapid Sound]|R: " + msg[udg_GCLL_Register_Type] + "Using null as parameter is not allowed" )
        endif
          
        return
    endif

    if udg_GCLL_Register_Type >= 6 and 10 >= udg_GCLL_Register_Type then
        call GCLL_CapParameter()
      
        if udg_GCLL_Register_WhichCLL > udg_GCLL_MaxIndex then
            if GCLL_DEBUG_MODE() then
                call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 30, "|CFFFFCC00[GRapid Sound]|R: " + msg[udg_GCLL_Register_Type] + "CLL doesn't exist")
            endif
          
            return
        endif
    endif
      
    if udg_GCLL_Register_Type >= 1 and 5 >= udg_GCLL_Register_Type then
      
        if udg_GCLL_Register_Type == udg_GCLL_Type_U2U then
            call GCLL_U2U(udg_GCLL_Register_LightningType, udg_GCLL_Register_SourceUnit, udg_GCLL_Register_TargetUnit, udg_GCLL_Register_InitialSourceZ, udg_GCLL_Register_InitialTargetZ, udg_GCLL_Register_IsSourceStatic, udg_GCLL_Register_IsTargetStatic)
            return
      
        elseif udg_GCLL_Register_Type == udg_GCLL_Type_P2U then
            call GCLL_P2U(udg_GCLL_Register_LightningType, udg_GCLL_Register_SourceX, udg_GCLL_Register_SourceY, udg_GCLL_Register_TargetUnit, udg_GCLL_Register_InitialSourceZ, udg_GCLL_Register_InitialTargetZ, udg_GCLL_Register_IsSourceStatic, udg_GCLL_Register_IsTargetStatic)
            return
      
        elseif udg_GCLL_Register_Type == udg_GCLL_Type_P2ULoc then
            call GCLL_P2ULoc(udg_GCLL_Register_LightningType, udg_GCLL_Register_SourcePoint, udg_GCLL_Register_TargetUnit, udg_GCLL_Register_InitialSourceZ, udg_GCLL_Register_InitialTargetZ, udg_GCLL_Register_IsSourceStatic, udg_GCLL_Register_IsTargetStatic)
            return

        elseif udg_GCLL_Register_Type == udg_GCLL_Type_P2P then
            call GCLL_P2P(udg_GCLL_Register_LightningType, udg_GCLL_Register_SourceX, udg_GCLL_Register_SourceY, udg_GCLL_Register_TargetX, udg_GCLL_Register_TargetY, udg_GCLL_Register_InitialSourceZ, udg_GCLL_Register_InitialTargetZ, udg_GCLL_Register_IsSourceStatic, udg_GCLL_Register_IsTargetStatic)
            return
          
        elseif udg_GCLL_Register_Type == udg_GCLL_Type_P2PLoc then
            call GCLL_P2PLoc(udg_GCLL_Register_LightningType, udg_GCLL_Register_SourcePoint, udg_GCLL_Register_TargetPoint, udg_GCLL_Register_InitialSourceZ, udg_GCLL_Register_InitialTargetZ, udg_GCLL_Register_IsSourceStatic, udg_GCLL_Register_IsTargetStatic)
            return
      
        endif
      
    elseif udg_GCLL_Register_Type >= 6 and 10 >= udg_GCLL_Register_Type then
  
        if udg_GCLL_Register_Type == udg_GCLL_Type_Fade then
            call GCLL_SetFadeRate(udg_GCLL_Register_StartValue, udg_GCLL_Register_EndValue, udg_GCLL_Register_Duration, udg_GCLL_Register_WhichCLL)
            return
          
        elseif udg_GCLL_Register_Type == udg_GCLL_Type_ApplyTimed then
            call GCLL_ApplyTimedLife(udg_GCLL_Register_WhichCLL, udg_GCLL_Register_Duration)
            return
          
        elseif udg_GCLL_Register_Type == udg_GCLL_Type_ChangeRed then
            call GCLL_SetRedCRate(udg_GCLL_Register_StartValue, udg_GCLL_Register_EndValue, udg_GCLL_Register_Duration, udg_GCLL_Register_WhichCLL)
            return
          
        elseif udg_GCLL_Register_Type == udg_GCLL_Type_ChangeGreen then
            call GCLL_SetGreenCRate(udg_GCLL_Register_StartValue, udg_GCLL_Register_EndValue, udg_GCLL_Register_Duration, udg_GCLL_Register_WhichCLL)
            return
          
        elseif udg_GCLL_Register_Type == udg_GCLL_Type_ChangeBlue then
            call GCLL_SetBlueCRate(udg_GCLL_Register_StartValue, udg_GCLL_Register_EndValue, udg_GCLL_Register_Duration, udg_GCLL_Register_WhichCLL)
            return
          
        endif
    endif
endfunction

//Never-ever think to touch this function
function InitTrig_GCLL takes nothing returns nothing
    //The methods id
    set udg_GCLL_Type_U2U = 1
    set udg_GCLL_Type_P2U = 2
    set udg_GCLL_Type_P2ULoc = 3
    set udg_GCLL_Type_P2P = 4
    set udg_GCLL_Type_P2PLoc = 5
    set udg_GCLL_Type_Fade = 6
    set udg_GCLL_Type_ApplyTimed = 7
    set udg_GCLL_Type_ChangeRed = 8
    set udg_GCLL_Type_ChangeGreen = 9
    set udg_GCLL_Type_ChangeBlue = 10
  
    set udg_GCLL_Location = Location(0.00, 0.00)
  
    set gg_trg_GCLL = CreateTrigger()
    call TriggerAddAction( gg_trg_GCLL, function GCLL_Actions )
endfunction
// THE END

Changelog:

v0.1
-release
v1.0
-remaked the code
v1.1
-fixed indexing problem
v1.2
-changed function and variable name
-added some variable in variable generator
v1.5
-changed indexing system
-reconstructed the periodic function
-reconstructed the action function
-changed the debug messages
-fixed delayed lightning movement on creation
-system now take lightningtype instead lightning
-fixed the events
-optimized the events
-added GCLL_CurrentZ1 and GCLL_CurrentZ2
-removed alpha from GCLL_Register_
[/tab]
Contents

Custom Lightning Locker v1.5 (Map)

[JASS/GUI] Custom Lightning Locker (Map)

Reviews
KILLCIDE
Other than an awkward data structure and mediocre demo map, I don't see anything game breaking with this system. Given that you are aiming for GUI-Friendly, forcing people to read the extremely lengthy HOW TO USE in the custom text was sort of off...
Level 37
Joined
Jul 22, 2015
Messages
3,485
I apologize for having to set this to Awaiting Update for something so minor, but I'm going to be stuck on my MacBook for the next few weeks, and I have no way of being able to open up the maps in the editor :p


Needs Fixed

  • Please post the updated triggers. No one really cares about how the "old" one looked :p
  • You're missing "How to Install" and credits (if there are any) instructions in your description

Suggestions

  • Nothing

Status

Awaiting Update
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
Other than an awkward data structure and mediocre demo map, I don't see anything game breaking with this system. Given that you are aiming for GUI-Friendly, forcing people to read the extremely lengthy HOW TO USE in the custom text was sort of off putting for me. I recommend updating this and maybe having very basic demos and also some more complicated ones like the Pull spell you already have added. This is honestly not the best lightning system we have, but the database is rather lacking in GUI friendly systems which I am always for. This is a good step forward, but I'm hoping you can update it with more features.

Needs Fixed

  • Nothing

Suggestions

  • Why is gcLLL_MaxLifeTime an integer? Seems kind of pointless to have to keep converting reals into integer because of this reason
  • I would personally get rid of the local declarations in the SetColorCRate functions and SetFadRate. Other than readability, I think it's kind of pointless to declare a local you will only use in once
  • Instead of constantly checking if udg_gCLL_Location is null everytime the GetZ function is called, just create the location on map init
  • To improve readability of the OnIterate function, I would move the different types of methods into different functions

Status

Approved
 
Level 5
Joined
May 2, 2015
Messages
109
Other than an awkward data structure and mediocre demo map, I don't see anything game breaking with this system. Given that you are aiming for GUI-Friendly, forcing people to read the extremely lengthy HOW TO USE in the custom text was sort of off putting for me. I recommend updating this and maybe having very basic demos and also some more complicated ones like the Pull spell you already have added. This is honestly not the best lightning system we have, but the database is rather lacking in GUI friendly systems which I am always for. This is a good step forward, but I'm hoping you can update it with more features.

Needs Fixed

  • Nothing

Suggestions

  • Why is gcLLL_MaxLifeTime an integer? Seems kind of pointless to have to keep converting reals into integer because of this reason
  • I would personally get rid of the local declarations in the SetColorCRate functions and SetFadRate. Other than readability, I think it's kind of pointless to declare a local you will only use in once
  • Instead of constantly checking if udg_gCLL_Location is null everytime the GetZ function is called, just create the location on map init
  • To improve readability of the OnIterate function, I would move the different types of methods into different functions

Status

Approved

THANKS!! I'll update, but after I finished my school project. T.T


Finally a lightning system for GUI users. May I ask if there is an option call for destroying the lightning when it reach certain condition? Like when unit dies or distance broken?

Simple, just set udg_gCLL_Destroy[the gcll instance/index] = true and the system will automatically destroy your lightning
you can get the "the gcll instance/index" by storing udg_gCLL_LastCreatedCLL just after the gCLL creation
 
Could it be that you forgot to add udg_gCLL_Counter into the Trigger "gCLL VariablesGen" to let it create automatic?

Edit: Wanted to use this System, but got a error on testing after copying the "GUI Custom Lightning Locker - Category" into another map. The Debugger said something like unknown name.
 
Last edited:
Level 5
Joined
May 2, 2015
Messages
109
Why is
gcLLL_MaxLifeTime
an integer? Seems kind of pointless to have to keep converting reals into integer because of this reason
It is an integer because it is for counting, for accuracy. With 0.03125 interval, 1s = 32 tick. So, 2h = 120m. Then , 120*60 = 7200s. Finally, 7200*32 = 230400. So, I decreased it by one in every tick.

Instead of constantly checking if
udg_gCLL_Location
is null everytime the GetZ function is called, just create the location on map init
I don't know if this is necessary. I just want to make sure the GCLL_Location is indestructible.
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
It is an integer because it is for counting, for accuracy. With 0.03125 interval, 1s = 32 tick. So, 2h = 120m. Then , 120*60 = 7200s. Finally, 7200*32 = 230400. So, I decreased it by one in every tick.
As I mentioned, it seems pointless.

I don't know if this is necessary. I just want to make sure the GCLL_Location is indestructible.
It's thrown under Suggestions for a reason.
 
Level 5
Joined
May 2, 2015
Messages
109
Updated v1.5
  • -changed indexing system
  • -reconstructed the periodic function
  • -reconstructed the action function
  • -changed the debug messages
  • -fixed delayed lightning movement on creation
  • -system now take lightningtype instead lightning
  • -fixed the events
  • -optimized the events
  • -added GCLL_CurrentZ1 and GCLL_CurrentZ2
  • -removed alpha from GCLL_Register_
EDIT: A pack of demo spell coming soon!
 
Last edited:
Top