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

[Extension] Lightning Utils

Well, basically its a library containing additional tools for my
Lightning System

Uploaded it here as Magtheridon96 suggested


Features

->Obtain units between the Lightning
->Set color/alpha gradient for Timed Lightnings


JASS:
/*
    Lightning Utilities v1.01
    by Adiktuz
    
    A set of methods that can help you make more out of the
    lightning system.
    
    I chose to separate it from the main system because these are
    extra methods only to extend the capabilities of the LS. 
    This way, the user has the option of not using LU library
    as the LS will work fine without it.
    
    How to use:
    
        LightningUtils.method(parameters)
    
    Methods:
    
        enumUnits(group g, Lightning light, real radius)
        
    Parameters:
    
        group g -> group that you want to fill with the units between the Lightning's ends
        Lightning light -> the Lightning object
        real radius -> radius around the Lightning in which unit's will be picked
        
    Note: the following Gradient methods are only for timed lightnings
        
        registerGradientKey(integer eventkey)
        
        ->eventkey of the Lightning's that you want to have a color/alpha gradient
        
    Notes:
        
        ->it is important that you register first the eventkey using this method
          before using the next method which sets the gradient of each Lightning
          instance.
        ->Do this registration only once per eventkey
        
        addLightningGradient(Lightning light, real red1, real blue1, real green1, real alpha1,real red2, real blue2, real green2, real alpha2)
        
    Parameters:
    
        Lightning light -> the Lightning instance that you want to have a gradient
        real red1,blue1,green1,alpha1 -> the initial values of the colors/alpha of the Lightning
        real red2,blue2,green2,alpha2 -> the final values of the colors/alpha of the Lightning
                                      ->these reals are from 0.0 up to 1.0
        
    Notes:
        
        ->Make sure that the eventkey used by this Lightning is already registered using the
         method above (registerGradientKey)
        ->This method automatically fetches the duration of the Lightning
        ->Do not modify the Lightning's duration afterwards else it might look bad
        
        See the Example trigger for an example of how to use these methods.
*/

library LightningUtilities requires LightningSystem
    
    private module init 
        static method onInit takes nothing returns nothing
            set thistype.redTable = Table.create()
            set thistype.blueTable = Table.create()
            set thistype.greenTable = Table.create()
            set thistype.alphaTable = Table.create()
            set thistype.redCTable = Table.create()
            set thistype.blueCTable = Table.create()
            set thistype.greenCTable = Table.create()
            set thistype.alphaCTable = Table.create()
        endmethod
    endmodule
    
    struct LightningUtils extends array
        
        private static group tmpGroup = CreateGroup()
        private static unit tmpUnit = null
        private static Table redTable
        private static Table blueTable
        private static Table greenTable
        private static Table alphaTable
        private static Table redCTable
        private static Table blueCTable
        private static Table greenCTable
        private static Table alphaCTable
        
        static method enumUnits takes group g, Lightning light, real radius returns nothing
            local real tdy = (light.targetY-light.sourceY)
            local real tdx = (light.targetX-light.sourceX)
            local real angle = Atan2(tdy,tdx)
            local real distance = (tdy*tdy)+(tdx*tdx)
            local integer iend = R2I(distance/(radius*radius))
            local real dx = tdx/iend
            local real dy = tdy/iend
            //we only get units in between the lightning
            local integer i = 1
            set iend = iend - 1
            call GroupClear(g)
            loop
                call GroupEnumUnitsInRange(tmpGroup,light.sourceX+i*dx,light.sourceY+i*dy,radius,null)
                loop
                    set tmpUnit = FirstOfGroup(tmpGroup)
                    exitwhen tmpUnit == null
                    if not IsUnitInGroup(tmpUnit,g) then
                        call GroupAddUnit(g,tmpUnit)
                    endif
                    call GroupRemoveUnit(tmpGroup,tmpUnit)
                endloop
                set i = i + 1
                exitwhen i > iend
            endloop
        endmethod
        
        //I used Table to save the RGBA values because if I use the GeLightningColor natives, it returns
        //rounded down values, resulting to bad behavior at durations > 4.0
        static method updateGradient takes nothing returns nothing
            set redCTable.real[Lightning.instance] = redCTable.real[Lightning.instance] + redTable.real[Lightning.instance]
            set blueCTable.real[Lightning.instance] = blueCTable.real[Lightning.instance] + blueTable.real[Lightning.instance]
            set greenCTable.real[Lightning.instance] = greenCTable.real[Lightning.instance] + greenTable.real[Lightning.instance]
            set alphaCTable.real[Lightning.instance] = alphaCTable.real[Lightning.instance] + alphaTable.real[Lightning.instance]
            call SetLightningColor(Lightning.instance.light, redCTable.real[Lightning.instance],greenCTable.real[Lightning.instance],blueCTable.real[Lightning.instance],alphaCTable.real[Lightning.instance])
        endmethod
        
        static method addLightningGradient takes Lightning light, real red1, real blue1, real green1, real alpha1,real red2, real blue2, real green2, real alpha2 returns nothing
            set redCTable.real[light] = red1
            set blueCTable.real[light] = blue1
            set greenCTable.real[light] = green1
            set alphaCTable.real[light] = alpha1
            set redTable.real[light] = (((red2-red1)/light.duration)*T32_PERIOD)
            set blueTable.real[light] = (((blue2-blue1)/light.duration)*T32_PERIOD)
            set greenTable.real[light] = (((green2-green1)/light.duration)*T32_PERIOD)
            set alphaTable.real[light] = (((alpha2-alpha1)/light.duration)*T32_PERIOD)
        endmethod
        
        static method registerGradientKey takes integer eventkey returns nothing
            call Lightning.registerUpdateEvent(eventkey,function thistype.updateGradient)
        endmethod
        
        implement init
    endstruct

endlibrary

the test map of the linked system contains usage examples of this snippet

This snippet will be updated to account for updates in the Lightning System when necessary

Be sure to always have the latest version of Lightning System to ensure everything works correctly.
 
Last edited:
@Frotty - compare the squares? you mean like using distance/(radius*radius), while removing SquareRoot from the distance formula?

@Magtheridon96 - I don't use GroupEnum for the cleared group because what I clear is the group fed by the user, while I use GroupEnum for the dummy global group... :)... but maybe I can add a boolean parameter to the method so that the user can decide whether he wants the group to be cleared or not...
 
Last edited:
Level 19
Joined
Mar 18, 2012
Messages
1,716
I also suggest moving to the spell section.

Why the usage of Table when you use struct instances as key for storing data?
I looked into Lightning and the maximum allocation possible is within array size.
Ergo: Just use normal real arrays for storing your data.

in enumUnits you calculate an angle for polar projection, which is not used anywhere.

Everything could be done with simple functions. Writing it into a struct is completly unnessesary.
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
Graveyarded due to obvious code deficiencies. I can restore the thread if you
plan to update your code.

Suggestions:

1.) Remove usage of Table, stick to arrays, as the maximum instance is within jass array size.

2.) Cleanup your code ( problem mentioned in comment above )

3.) Design it as module, which is implemented optional into the main system struct.
Alternatively go with simple functions as a struct is completly useless here. ( except syntax sugar using "." )
 
Top