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

[vJASS] Lightning Bender

Level 10
Joined
Jun 17, 2014
Messages
236
JASS:
library LightningBender/*
      
                            Lightning Bender v0.90
                                By userid907
            http://www.hiveworkshop.com/members/userid907.238703/
        This library requires nothing.
      
        Allow you to create a timed/permanent lightning between two units or between two coordinates
      
        How to Import and use
        1. Copy this trigger file or copy this whole script to your map.
        2. After you copy the script, take a look to Example trigger file (located inside Demo trigger folder) to know how to use
        |=======|
        |  API  |
        |=======|
        struct LBend
            static method create takes unit target, unit source, string lightmodel, real x3, real y3, real x4, real y4, real z, real z2, real duration returns thistype
                - create a lightning, set target and source to null if you only want tocreate a lightning between a coordinates.
                else if you want to create a lightning between two units set target and source also set x3,y3,x4 and y4 to right value.
            static method forcedestroy takes thistype d returns nothing
                - destroy lightning instantly with argument LBend variable.
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
        endstruct
        */
    // CONFIGURATION
    globals
        // Timer interval
        private constant real FPS = 0.0312500
        // false = don't display debug msg, true = display debug msg
        private constant boolean TESTMODE = false
        private constant boolean TESTMODELOOP = false
    endglobals
    struct LBend
        unit source
        unit target
        real duration
        lightning l = null
        real x1
        real y1
        real x2
        real y2
        real z5
        real z6
        static integer dindex
        static timer period
        static thistype array data
        method destroy takes nothing returns nothing
            //Wash leaks
            set .target = null
            set .source = null
            call DestroyLightning( .l )
            if dindex == -1 then
                call PauseTimer( period )
            endif
            call this.deallocate( )
        endmethod
        static method forcedestroy takes thistype d returns nothing
            call d.destroy( )
        endmethod
        static method create takes unit target, unit source, string lightmodel, real x3, real y3, real x4, real y4, real z, real z2, real duration returns thistype
            local thistype this
            set this = thistype.allocate( )
            set .l = AddLightningEx( lightmodel, false, x3, y3, z, x4, y4, z2 )
            if target != null and source != null then
                set .target = target
                set .source = source
                if TESTMODE then
                    call BJDebugMsg( GetUnitName( .source ) + " as source and " + GetUnitName( .target ) + " as target" )
                endif
            elseif target == null and source != null then
                call BJDebugMsg( "ERROR : TARGET IS NULL, SET THE TARGET CORRECTLY." )
            elseif target != null and source == null then
                call BJDebugMsg( "ERROR : SOURCE IS NULL, SET THE SOURCE CORRECTLY." )
            endif
            set .z5 = z
            set .z6 = z2
            set .x1 = x3
            set .y1 = y3
            set .x2 = x4
            set .y2 = y4
            if duration > 0. then
                set .duration = duration
            else
                set .duration = 99999999.
            endif
            set dindex = dindex + 1
            set data[dindex] = this
            if dindex == 0 then
                call TimerStart( period, FPS, true, function thistype.periodic )
            endif
            return this
        endmethod
        static method periodic takes nothing returns nothing
            local integer i = 0
            local LBend this
            loop
                exitwhen i > dindex
                set this = data[i]
                if .target != null then
                    if TESTMODE and TESTMODELOOP then
                        call BJDebugMsg( GetUnitName( .source ) + " as source and " + GetUnitName( .target ) + " as target" )
                    endif
                    call MoveLightningEx( .l, false, GetUnitX( .source ), GetUnitY( .source ), .z5, GetUnitX( .target ), GetUnitY( .target ), .z6 )
                endif
                set .duration = .duration - FPS
                if .duration <= 0 then
                    set data[i] = data[dindex]
                    set i = i - 1
                    set dindex = dindex - 1
                    call this.destroy( )
                endif
                set i = i + 1
            endloop
        endmethod
        static method onInit takes nothing returns nothing
            set dindex = -1
            set period = CreateTimer( )
        endmethod
    endstruct
endlibrary

Example of using the system
JASS:
scope test initializer Init
    globals
        private LBend light1
        private LBend light2
        private LBend light3
        private LBend cord
        private LBend cord2
    endglobals
private function dexcz takes nothing returns nothing
    // Create lightning between two units with permanent duration.
    set light1 = LBend.create(gg_unit_hfoo_0006,gg_unit_hfoo_0007,"DRAL",0.,0.,0.,0.,50.,50.,0.)
    set light2 = LBend.create(gg_unit_hfoo_0000,gg_unit_hfoo_0006,"DRAL",0.,0.,0.,0.,50.,50.,0.)
    set light3 = LBend.create(gg_unit_hfoo_0000,gg_unit_hfoo_0007,"DRAL",0.,0.,0.,0.,50.,50.,0.)
endfunction
private function act takes nothing returns nothing
    // Create lightning between two coordinates with permanent duration.
    set cord = LBend.create(null,null,"DRAL",46.,827.,951.,176.,50.,50.,0.)
endfunction
private function act2 takes nothing returns nothing
    // Create lightning between two coordinates with fixed duration
    set cord2 = LBend.create(null,null,"DRAL",674.,950.,78.,-32.,50.,50.,5.)
endfunction
private function act3 takes nothing returns nothing
   call LBend.forcedestroy(light1)
   call LBend.forcedestroy(light2)
   call LBend.forcedestroy(light3)
   call LBend.forcedestroy(cord)
   call LBend.forcedestroy(cord2)
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterPlayerEventEndCinematic( t, Player(0) )
    call TriggerAddAction( t, function dexcz )
    set t = CreateTrigger()
    call TriggerRegisterPlayerChatEvent( t, Player(0), "cord test", true )
    call TriggerAddAction( t, function act)
    set t = CreateTrigger()
    call TriggerRegisterPlayerChatEvent( t, Player(0), "duration test", true )
    call TriggerAddAction( t, function act2)
    set t = null
    set t = CreateTrigger()
    call TriggerRegisterPlayerChatEvent( t, Player(0), "force end", true )
    call TriggerAddAction( t, function act3)
    set t = null
endfunction
endscope

Change Log :
v 0.9 : first release
 

Attachments

  • LightningBender.w3x
    26.1 KB · Views: 64
Last edited:
Level 13
Joined
Nov 7, 2014
Messages
571
It seemst to me that the LBend.create method is a bit overloaded:
JASS:
private function dexcz takes nothing returns nothing
    set light1 = LBend.create(gg_unit_hfoo_0006,gg_unit_hfoo_0007,"DRAL",0.,0.,0.,0.,50.,50.,0.)
    set light2 = LBend.create(gg_unit_hfoo_0000,gg_unit_hfoo_0006,"DRAL",0.,0.,0.,0.,50.,50.,0.)
    set light3 = LBend.create(gg_unit_hfoo_0000,gg_unit_hfoo_0007,"DRAL",0.,0.,0.,0.,50.,50.,0.)
endfunction
private function act takes nothing returns nothing
    set cord = LBend.create(null,null,"DRAL",46.,827.,951.,176.,50.,50.,0.)
endfunction
private function act2 takes nothing returns nothing
    set cord2 = LBend.create(null,null,"DRAL",674.,950.,78.,-32.,50.,50.,5.)
endfunction

which makes it hard to use, why not a separate method for each use case?:
JASS:
static method between_points takes string lightning_id, real x1, real y1, real z1, real x2, real y2, real z2 returns LBend
static method between_points_timed takes string lightning_id, real x1, real y1, real z1, real x2, real y2, real z2, real duration returns LBend

static method between_units takes string lightning_id, unit u1, real uz1, unit u2, real uz2 returns LBend
static method between_units_timed takes string lightning_id, unit u1, real uz1, unit u2, real uz2, real duration returns LBend
 
Level 10
Joined
Jun 17, 2014
Messages
236
It seemst to me that the LBend.create method is a bit overloaded:

which makes it hard to use, why not a separate method for each use case?:
JASS:
static method between_points takes string lightning_id, real x1, real y1, real z1, real x2, real y2, real z2 returns LBend
static method between_points_timed takes string lightning_id, real x1, real y1, real z1, real x2, real y2, real z2, real duration returns LBend

static method between_units takes string lightning_id, unit u1, real uz1, unit u2, real uz2 returns LBend
static method between_units_timed takes string lightning_id, unit u1, real uz1, unit u2, real uz2, real duration returns LBend

Yeah, i've think that before, but i forgot it.
EDIT : oh no, i don't know how to do that.
when the lightning is "forcedestroy"-ed, the lightning still appear (not destroyed), can you point it out?.

No, I meant that I have seen other systems that does what LightningBender does.

You've reinvented the wheel, that's all I am saying.

But i don't know, i create this to make lightning creating in my map is easy, but i want to share it here, so you all can create lightning easily too.
 
Last edited:
  • Make a proper encapsulation.
  • Destroy must be non-static.
  • Don't include pirinting messages other than for debugging purpose.
  • Add constant strings for lightnings models
Make the create taking "string model, unit a, unit b, real duration" as arguments and we can present it as a simple snippet to easily bind lightnings between units.
z1, z2 shoudl be then just fleight height of target units. We might call it simply "[Snippet] Unit Lightnings", so something similar.
 
Top