• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Vote for the theme of Hive's HD Modeling Contest #7! Click here to vote! - Please only vote if you plan on participating❗️

Lightning is not getting destroyed (forgroup wait problem)

Status
Not open for further replies.
Level 4
Joined
Mar 23, 2008
Messages
87
So.. do I have to update to 1.24 and start learning hashtables or is there a workaround for this problem?
JASS:
function emmitLIGHTNING takes nothing returns nothing
    local lightning rawr = AddLightningLoc( "CLPB", GetUnitLoc(udg_RAWR[udg_i]), GetUnitLoc(GetEnumUnit()) )
    call TriggerSleepAction( 0.30 ) //The wait stops the script for some reason
    call DestroyLightning(rawr)
endfunction

function isnotself takes nothing returns boolean
    return (GetFilterUnit() != udg_RAWR[udg_i])
endfunction

function LIGHTNING takes nothing returns nothing
    local group uGroup
    set udg_i = 0
    loop
        set uGroup = GetUnitsInRangeOfLocMatching(256.00, GetUnitLoc(udg_RAWR[udg_i]), Condition(function isnotself ))
        call ForGroupBJ( uGroup, function emmitLIGHTNING )
        call DestroyGroup( uGroup )
        set udg_i=udg_i+1
        exitwhen udg_i>=2
    endloop
endfunction

//===========================================================================
function InitTrig_LIGHTNING takes nothing returns nothing
    set gg_trg_LIGHTNING = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_LIGHTNING, 0.5 )
    call TriggerAddAction( gg_trg_LIGHTNING, function LIGHTNING )
endfunction

EDIT: Fixed the typo Yixx made me aware of
 
Last edited:
The no-1.24 way would be using an array of lightnings to store all lightnings created and destroy them later. However it would not be MUI.

It would be something like this:

loop
set udg_Lightnings = Create a lightning
set i = i + 1
endloop

Wait 0.3 second

loop
destroy udg_Lightnings
set i = i + 1
endloop

Edit: with hashtables it would be mui and faster I guess xD
 
Level 16
Joined
Oct 12, 2008
Messages
1,570
You create a local, and you create a lightning,, but you do not set the local to the lightning! So the local is still null,, and you will DestroyLightning() null,, which does nothing duh,,,
do it like this:
JASS:
function emmitLIGHTNING takes nothing returns nothing
    local lightning rawr = AddLightningLoc(...)
    call TriggerSleepAction(0.3)
    call DestroyLightning(rawr)
endfunction

works,,
 
Level 4
Joined
Mar 23, 2008
Messages
87
You create a local, and you create a lightning,, but you do not set the local to the lightning! So the local is still null,, and you will DestroyLightning() null,, which does nothing duh,,,
do it like this:
JASS:
function emmitLIGHTNING takes nothing returns nothing
    local lightning rawr = AddLightningLoc(...)
    call TriggerSleepAction(0.3)
    call DestroyLightning(rawr)
endfunction

works,,
You didn't test it, did you? Bless you anyway ;)
No, it won't work, TSA stops forgroup loops for some reason.
Sorry for the mistake though, i have a much longer and more complex trigger with the same issue so i just made this quickly to illustrate the problem.

@Marcelo problem with storing ligthning in arrays is that you have to store them in a 2d array with unknown dimensions.
eg lightArr[x*10+x2] wouldn't work since there could easily be more than 10 units within range of the original unit...
You need 2d arrays because the forgroup loop is allready inside another loop and if you just use an 1d array the lightnings will overlap.
Other suggestions?
 
Last edited:
Level 4
Joined
Mar 23, 2008
Messages
87
If you dont mind use H2I and Game Cache, you could use timers with CSCache.
I wouldn't mind if I knew how.

EDIT: This works but lags, and is really not an ideal solution:
JASS:
function isnotself takes nothing returns boolean
    local location array pos
    if (GetFilterUnit() != GetEnumUnit()) then
        set pos[0] = GetUnitLoc(GetFilterUnit())
        set pos[1] = GetUnitLoc(GetEnumUnit())
        set udg_rawr[udg_ti] = AddLightningLoc( "CLPB", pos[0], pos[1] )
        set udg_ti = udg_ti + 1
        
        if udg_ti > 100 then
            set udg_ti = 0
        endif
        call TimerStart(udg_tid[udg_ti], 0.5, false, null)
        call RemoveLocation(pos[0])
        call RemoveLocation(pos[1])
        set pos[0] = null
        set pos[1] = null
    endif
    return true
endfunction

function LIGHTNING takes nothing returns nothing
    local group uGroup
    local lightning rawr 
    local location array pos
    set pos[0] = GetUnitLoc(GetEnumUnit())
    set uGroup = GetUnitsInRangeOfLocMatching(256.00, pos[0], Condition(function isnotself ))
    call DestroyGroup( uGroup )
    call RemoveLocation(pos[0])
    set uGroup = null
    set pos[0] = null
    
endfunction

function startStorm takes nothing returns nothing
    call ForGroupBJ(udg_rawrGroup, function LIGHTNING)
endfunction

//===========================================================================
function InitTrig_LIGHTNING takes nothing returns nothing
    set gg_trg_LIGHTNING = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_LIGHTNING, 0.50 )
    call TriggerAddAction( gg_trg_LIGHTNING, function startStorm )
endfunction
JASS:
function endLIGHTNING takes nothing returns nothing
    local integer i = 100
    loop
        if TimerGetRemaining(udg_tid[i])<=0.00 then
            call DestroyLightning(udg_rawr[i])
            //call DisplayTextToPlayer(Player(0), 0,0, "RAWR "+I2S(i))
            set udg_rawr[i]=null
        endif
        set i = i -1
        exitwhen i<0
    endloop
endfunction

//===========================================================================
function InitTrig_endLIGHTNING takes nothing returns nothing
    local integer i = 0
    set gg_trg_endLIGHTNING = CreateTrigger(  )
    set udg_ti = 100
    loop
        set udg_tid[udg_ti] = CreateTimer()
        call TriggerRegisterTimerExpireEventBJ( gg_trg_endLIGHTNING, udg_tid[udg_ti] )
        call TriggerAddAction( gg_trg_endLIGHTNING, function endLIGHTNING )
        set udg_ti = udg_ti -1
        exitwhen udg_ti<0
    endloop
    set udg_ti = 0
endfunction
 
This is CSCache (thanks to Vex):
JASS:
//*************************************************************************************************
// Caster System Free Attach Variables / Sets and Tables (from 12.7)
//
// Requirement: gamecache global variable udg_cscache
//
//*************************************************************************************************

//##Begin of CS Gamecache engine##
//=================================================================================================
// GameCache - Return bug module : Without gamecache or return bug, JASS would be a
// retarded-limited scripting language.
//
//=================================================================================================
// a.k.a H2I, changed name to CS_H2I to prevent conflicts with other systems (I intended this
// system to be easy to copy
//
function CS_H2I takes handle h returns integer
    return h
    return 0
endfunction

//=================================================================================================
// Main Gamecache handler
//
function CSCache takes nothing returns gamecache
    if udg_cscache==null then
        call FlushGameCache(InitGameCache("CasterSystem.vx"))
        set udg_cscache=InitGameCache("CasterSystem.vx")
        call StoreInteger(udg_cscache,"misc","TableMaxReleasedIndex",100)
    endif
 return udg_cscache
endfunction

//==================================================================================================
// Attachable vars : Attacheable variables are what most other people call Handle Variables, they
// allow to relate data with any handle, using a label, and its value, the stuff auto flushes if
// the value is 0, false, "", or null .
//
// Differences between Attacheable variables and "Local Handle Variables" :
// - The names of the functions
// - The name of the function group does not cause confusion, it is difficult to say:
//   "you should set local handle variables to null at the end of a function" since
//   it sounds as if you were talking about the "Local Handle Variables"
// - Also Have Attacheable Sets.
// - And can work together with Tables.
//
// Notes: don't "attach" variables on texttags nor those handle types used mostly for parameters
// (for example damagetype) , Although there is no reason to do so anyways
//
// Gamecache stuff are NOT Case Sensitive, don't ever use "" for label (Crashes game!)
//

//============================================================================================================
// For integers
//
function AttachInt takes handle h, string label, integer x returns nothing
 local string k=I2S(CS_H2I(h))
    if x==0 then
        call FlushStoredInteger(CSCache(),k,label)
    else
        call StoreInteger(CSCache(),k,label,x)
    endif
endfunction
function GetAttachedInt_FromSet takes handle h, gamecache g returns integer
    return GetStoredInteger(g,I2S(CS_H2I(h))+";"+GetStoredString(g,"argpass","set"),GetStoredString(g,"argpass","seti"))
endfunction
function GetAttachedInt takes handle h, string label returns integer
    if (label=="") then
        return GetAttachedInt_FromSet(h,CSCache())
    endif
 return GetStoredInteger(CSCache(), I2S(CS_H2I(h)), label)
endfunction

//=============================================================================================================
function AttachReal takes handle h, string label, real x returns nothing
 local string k=I2S(CS_H2I(h))
    if x==0 then
        call FlushStoredReal(CSCache(),k,label)
    else
        call StoreReal(CSCache(),k,label,x)
    endif
endfunction
function GetAttachedReal takes handle h, string label returns real
    return GetStoredReal(CSCache(),I2S(CS_H2I(h)),label)
endfunction

//=============================================================================================================
function AttachBoolean takes handle h, string label, boolean x returns nothing
 local string k=I2S(CS_H2I(h))
    if not x then
        call FlushStoredBoolean(CSCache(),k,label)
    else
        call StoreBoolean(CSCache(),k,label,x)
    endif
endfunction
function GetAttachedBoolean takes handle h, string label returns boolean
    return GetStoredBoolean(CSCache(),I2S(CS_H2I(h)),label)
endfunction

//=============================================================================================================
function AttachString takes handle h, string label, string x returns nothing
 local string k=I2S(CS_H2I(h))
    if x=="" then
        call FlushStoredString(CSCache(),k,label)
    else
        call StoreString(CSCache(),k,label,x)
    endif
endfunction
function GetAttachedString takes handle h, string label returns string
    return GetStoredString(CSCache(),I2S(CS_H2I(h)),label)
endfunction

//=============================================================================================================
function AttachObject takes handle h, string label, handle x returns nothing
 local string k=I2S(CS_H2I(h))
    if (x==null) then
        call FlushStoredInteger(CSCache(),k,label)
    else
        call StoreInteger(CSCache(),k,label,CS_H2I(x))
    endif
endfunction
function GetAttachedObject takes handle h, string label returns handle
    return GetAttachedInt(h,label)
    return null
endfunction
function GetAttachedWidget takes handle h, string label returns widget
    return GetAttachedInt(h,label)
    return null
endfunction
function GetAttachedRect takes handle h, string label returns rect
    return GetAttachedInt(h,label)
    return null
endfunction
function GetAttachedRegion takes handle h, string label returns region
    return GetAttachedInt(h,label)
    return null
endfunction
function GetAttachedTimerDialog takes handle h, string label returns timerdialog
    return GetAttachedInt(h,label)
    return null
endfunction
function GetAttachedUnit takes handle h, string label returns unit
    return GetAttachedInt(h,label)
    return null
endfunction
function GetAttachedItem takes handle h, string label returns item
    return GetAttachedInt(h,label)
    return null
endfunction
function GetAttachedEffect takes handle h, string label returns effect
    return GetAttachedInt(h,label)
    return null
endfunction
function GetAttachedDestructable takes handle h, string label returns destructable
    return GetAttachedInt(h,label)
    return null
endfunction
function GetAttachedTrigger takes handle h, string label returns trigger
    return GetAttachedInt(h,label)
    return null
endfunction
function GetAttachedTimer takes handle h, string label returns timer
    return GetAttachedInt(h,label)
    return null
endfunction
function GetAttachedGroup takes handle h, string label returns group
    return GetAttachedInt(h,label)
    return null
endfunction
function GetAttachedTriggerAction takes handle h, string label returns triggeraction
    return GetAttachedInt(h,label)
    return null
endfunction
function GetAttachedLightning takes handle h, string label returns lightning
    return GetAttachedInt(h,label)
    return null
endfunction
function GetAttachedImage takes handle h, string label returns image
    return GetAttachedInt(h,label)
    return null
endfunction
function GetAttachedUbersplat takes handle h, string label returns ubersplat
    return GetAttachedInt(h,label)
    return null
endfunction

//============================================================================================================
// Attached Sets: Attachable Sets are handy in some situations and are a part of attachable variables,
// you can add integers or objects to a set, order doesn't matter and adding the same object twice is
// meaningless. CleanAttachedVars is always ready to clean every set owned by the handle.
//
//============================================================================================================
function AttachedSetAddInt takes handle h, string setn, integer int returns nothing
 local gamecache g=CSCache()
 local string k=I2S(CS_H2I(h))
 local integer n
 local integer x=GetStoredInteger(g,k,"#setnumberof;"+setn)
 local integer y
    if x==0 then
        set y=GetStoredInteger(g,k,"#totalsets")+1
        call StoreInteger(g,k,"#totalsets",y)
        call StoreInteger(g,k,"#setnumberof;"+setn,y)
        call StoreString(g,k,"#setName;"+I2S(y),setn)
    endif
    set k=k+";"+setn
    if not HaveStoredInteger(g,k,"Pos"+I2S(int)) then
        set n=GetStoredInteger(g,k,"n")+1
        call StoreInteger(g,k,"n",n)
        call StoreInteger(g,k,I2S(n),int)
        call StoreInteger(g,k,"Pos"+I2S(int),n)
    endif
 set g=null
endfunction
function AttachedSetAddObject takes handle h, string setn, handle val returns nothing
    call AttachedSetAddInt(h,setn,CS_H2I(val))
endfunction

//============================================================================================================
function AttachedSetHasInt takes handle h, string setn, integer int returns boolean
    return HaveStoredInteger(CSCache(),I2S(CS_H2I(h))+";"+setn,"Pos"+I2S(int))
endfunction
function AttachedSetHasObject takes handle h, string setn, handle val returns boolean
    return AttachedSetHasInt(h,setn,CS_H2I(val))
endfunction

//============================================================================================================
function GetAttachedSetSize takes handle h, string setn returns integer
    return GetStoredInteger(CSCache(),I2S(CS_H2I(h))+";"+setn,"n")
endfunction

//============================================================================================================
function AttachedSetRemInt takes handle h, string setn, integer int returns nothing
 local gamecache g=CSCache()
 local string k=I2S(CS_H2I(h))+";"+setn
 local integer n
 local integer x
 local integer y
    if HaveStoredInteger(g,k,"Pos"+I2S(int)) then
        set x=GetStoredInteger(g,k,"Pos"+I2S(int))
        set n=GetStoredInteger(g,k,"n")
        if x!=n then
            set y=GetStoredInteger(g,k,I2S(n))
            call StoreInteger(g,k,I2S(x),y)
            call StoreInteger(g,k,"Pos"+I2S(y),x)
        endif
        call FlushStoredInteger(g,k,"Pos"+I2S(int))
        call FlushStoredInteger(g,k,I2S(n))
        call StoreInteger(g,k,"n",n-1)
    endif
 set g=null
endfunction
function AttachedSetRemObject takes handle h, string setn, handle val returns nothing
    call AttachedSetRemInt(h,setn,CS_H2I(val))
endfunction

//============================================================================================================
function FromSetElement takes string setn, integer index returns string
 local gamecache g=CSCache()
    call StoreString(g,"argpass","set",setn)
    call StoreString(g,"argpass","seti",I2S(index))
 set g=null
 return ""
endfunction

//============================================================================================================
function ClearAttachedSet takes handle h, string setn returns nothing
    call FlushStoredMission(CSCache(),I2S(CS_H2I(h))+";"+setn)
endfunction

function CleanAttachedVars takes handle h returns nothing
 local gamecache g=CSCache()
 local string k=I2S(CS_H2I(h))
 local integer n=GetStoredInteger(g,k,"#totalsets")
 local integer i=1
    loop
        exitwhen i>n
        call FlushStoredMission(g,k+";"+GetStoredString(g,k,"#setName;"+I2S(i)))
        set i=i+1
    endloop
    call FlushStoredMission(g, k )
 set g=null
endfunction

function CleanAttachedVars_NoSets takes handle h returns nothing
    call FlushStoredMission(CSCache(), I2S(CS_H2I(h)) )
endfunction



//=============================================================================================
// Tables
//
// Tables are lame, the real name would be hash tables, they are just abbreviated usage
// of gamecache natives with the addition that you can also Copy the values of a table to
// another one, but don't expect it to be automatic, it must use a FieldData object to know
// which fields and of wich types to copy, Copying a table to another, with a lot of Fields,
// should surelly be lag friendly.
//
// The other thing about tables is that I can say that the Attached variables of a handle work
// inside a table and GetAttachmentTable which is just return bug and I2S , works to allow you
// to manipulate a handle's attached variables through a table.
//
// NewTable and DestroyTable were created to allow to create tables in the fly, but you can
// simply use strings for tables, but place the table names should be between "("")" for example
// "(mytable)" to avoid conflicts with other caster system stuff.
//
function NewTableIndex takes nothing returns integer
 local gamecache g=CSCache()
 local integer n=GetStoredInteger(g,"misc","FreeTableTotal")
 local integer i
     if (n>0) then
         set i=GetStoredInteger(g,"misc","FreeTable1")
         if (n>1) then
             call StoreInteger(g,"misc","FreeTable1", GetStoredInteger(g,"misc","FreeTable"+I2S(n)) )
             call FlushStoredInteger(g,"misc","FreeTable"+I2S(n))
         endif
         call StoreInteger(g,"misc","FreeTableTotal", n-1)
     else
         set i=GetStoredInteger(g,"misc","TableMaxReleasedIndex")+1
         call StoreInteger(g,"misc","TableMaxReleasedIndex",i)
     endif
     call StoreBoolean(g,"misc","Created"+I2S(i),true)

 set g=null
 return i
endfunction
function NewTable takes nothing returns string
    return I2S(NewTableIndex())
endfunction
function GetAttachmentTable takes handle h returns string
    return I2S(CS_H2I(h))
endfunction

//============================================================================================================
function DestroyTable takes string table returns nothing
 local gamecache g=CSCache()
 local integer i=S2I(table)
 local integer n
     if (i!=0) and (GetStoredBoolean(g,"misc","Created"+table)) then
         call FlushStoredBoolean(g,"misc","Created"+table)
         set n=GetStoredInteger(g,"misc","FreeTableTotal")+1
         call StoreInteger(g,"misc","FreeTableTotal",n)
         call StoreInteger(g,"misc","FreeTable"+I2S(n),i)
     endif
     call FlushStoredMission(g,table)
 set g=null
endfunction

//============================================================================================================
function ClearTable takes string table returns nothing
     call FlushStoredMission(CSCache(),table)
endfunction


//============================================================================================================
function SetTableInt takes string table, string field, integer val returns nothing
 local gamecache g=CSCache()
    if (val==0) then
        call FlushStoredInteger(g,table,field)
    else
        call StoreInteger(g,table,field,val)
    endif
 set g=null
endfunction
function GetTableInt takes string table, string field returns integer
    return GetStoredInteger(CSCache(),table,field)
endfunction

//============================================================================================================
function SetTableReal takes string table, string field, real val returns nothing
 local gamecache g=CSCache()
    if (val==0) then
        call FlushStoredReal(g,table,field)
    else
        call StoreReal(g,table,field,val)
    endif
 set g=null
endfunction
function GetTableReal takes string table, string field returns real
    return GetStoredReal(CSCache(),table,field)
endfunction

//============================================================================================================
function SetTableBoolean takes string table, string field, boolean val returns nothing
 local gamecache g=CSCache()
    if (not(val)) then
        call FlushStoredBoolean(g,table,field)
    else
        call StoreBoolean(g,table,field,val)
    endif
 set g=null
endfunction
function GetTableBoolean takes string table, string field returns boolean
    return GetStoredBoolean(CSCache(),table,field)
endfunction

//============================================================================================================
function SetTableString takes string table, string field, string val returns nothing
 local gamecache g=CSCache()
    if (val=="") or (val==null) then
        call FlushStoredString(g,table,field)
    else
        call StoreString(g,table,field,val)
    endif
 set g=null
endfunction
function GetTableString takes string table, string field returns string
    return GetStoredString(CSCache(),table,field)
endfunction

//============================================================================================================
// You may ask why am I using thousands of functions instead of multi-use return bug exploiters? Well,
// these make the thing much easier to read (in my opinion) and it is also better in performance since we
// have less function calls (H2U(GetTableObject("table","unit"))) would be worse than GetTableUnit that is
// quite direct.
//
function SetTableObject takes string table, string field, handle val returns nothing
  local gamecache g=CSCache()
    if (val==null) then
        call FlushStoredInteger(g,table,field)
    else
        call StoreInteger(g,table,field,CS_H2I(val))
    endif
 set g=null
endfunction
function GetTableObject takes string table, string field returns handle
    return GetStoredInteger(CSCache(),table,field)
    return null
endfunction
function GetTableWidget takes string table, string field returns widget
    return GetStoredInteger(CSCache(),table,field)
    return null
endfunction
function GetTableRect takes string table, string field returns rect
    return GetStoredInteger(CSCache(),table,field)
    return null
endfunction
function GetTableRegion takes string table, string field returns region
    return GetStoredInteger(CSCache(),table,field)
    return null
endfunction
function GetTableTimerDialog takes string table, string field returns timerdialog
    return GetStoredInteger(CSCache(),table,field)
    return null
endfunction
function GetTableUnit takes string table, string field returns unit
    return GetStoredInteger(CSCache(),table,field)
    return null
endfunction
function GetTableItem takes string table, string field returns item
    return GetStoredInteger(CSCache(),table,field)
    return null
endfunction
function GetTableEffect takes string table, string field returns effect
    return GetStoredInteger(CSCache(),table,field)
    return null
endfunction
function GetTableDestructable takes string table, string field returns destructable
    return GetStoredInteger(CSCache(),table,field)
    return null
endfunction
function GetTableTrigger takes string table, string field returns trigger
    return GetStoredInteger(CSCache(),table,field)
    return null
endfunction
function GetTableTimer takes string table, string field returns timer
    return GetStoredInteger(CSCache(),table,field)
    return null
endfunction
function GetTableGroup takes string table, string field returns group
    return GetStoredInteger(CSCache(),table,field)
    return null
endfunction
function GetTableTriggerAction takes string table, string field returns triggeraction
    return GetStoredInteger(CSCache(),table,field)
    return null
endfunction
function GetTableLightning takes string table, string field returns lightning
    return GetStoredInteger(CSCache(),table,field)
    return null
endfunction
function GetTableImage takes string table, string field returns image
    return GetStoredInteger(CSCache(),table,field)
    return null
endfunction
function GetTableUbersplat takes string table, string field returns ubersplat
    return GetStoredInteger(CSCache(),table,field)
    return null
endfunction

//============================================================================================================
// Returns true if the fiel contains a value different from 0, false,  null, or "" (depending on the type)
// it is worthless to use this with boolean, since it would be the same as reading the boolean value
//
function HaveSetField takes string table, string field, integer fieldType returns boolean
    if (fieldType == bj_GAMECACHE_BOOLEAN) then
        return HaveStoredBoolean(CSCache(),table,field)
    elseif (fieldType == bj_GAMECACHE_INTEGER) then
        return HaveStoredInteger(CSCache(),table,field)
    elseif (fieldType == bj_GAMECACHE_REAL) then
        return HaveStoredReal(CSCache(),table,field)
    elseif (fieldType == bj_GAMECACHE_STRING) then
        return HaveStoredString(CSCache(),table,field)
    endif
 return false
endfunction

//============================================================================================================
// Allows to copy a table to another one, but it needs a FieldData object to know which fields of which type
// it is supposed to copy.
//
function CopyTable takes integer FieldData, string sourceTable, string destTable returns nothing
 local gamecache g=CSCache()
 local integer i=1
 local string k=I2S(FieldData)
 local string k2
 local string k3
 local integer n=GetStoredInteger(g,k,"N")
 local integer t
    loop
        exitwhen (i>n)
        set k2=I2S(i)
        set t=GetStoredInteger(g,k,k2)
        set k3=GetStoredString(g,k,k2)
        if (t==bj_GAMECACHE_BOOLEAN) then
            if (HaveStoredBoolean(g,sourceTable,k3)) then
                call StoreBoolean(g,destTable,k3,GetStoredBoolean(g,sourceTable,k3))
            else
                call FlushStoredBoolean(g,destTable,k3)
            endif
        elseif (t==bj_GAMECACHE_INTEGER) then
            if (HaveStoredInteger(g,sourceTable,k3)) then
                call StoreInteger(g,destTable,k3,GetStoredInteger(g,sourceTable,k3))
            else
                call FlushStoredInteger(g,destTable,k3)
            endif
        elseif (t==bj_GAMECACHE_REAL) then
            if (HaveStoredReal(g,sourceTable,k3)) then
                call StoreReal(g,destTable,k3,GetStoredReal(g,sourceTable,k3))
            else
                call FlushStoredReal(g,destTable,k3)
            endif
        elseif (t==bj_GAMECACHE_STRING) then
            if (HaveStoredString(g,sourceTable,k3)) then
                call StoreString(g,destTable,k3,GetStoredString(g,sourceTable,k3))
            else
                call FlushStoredString(g,destTable,k3)
            endif
        endif
        set i=i+1
    endloop


 set g=null
endfunction

//=============================================================================================
// FieldData inherits from Table, was just designed to be used by CopyTable.
//
function FieldData_Create takes nothing returns integer
    return NewTableIndex()
endfunction

//============================================================================================================
// valueType uses the same integer variables from blizzard.j :
// bj_GAMECACHE_BOOLEAN, bj_GAMECACHE_INTEGER, bj_GAMECACHE_REAL and bj_GAMECACHE_STRING
//
function FieldData_AddField takes integer fielddata, string field, integer valueType returns nothing
 local gamecache g=CSCache()
 local string k=I2S(fielddata)
 local integer n=GetStoredInteger(g,k,"N")+1
 local string k2=I2S(n)

    call StoreString(g,k,k2,field)
    call StoreInteger(g,k,k2,valueType)
    call StoreInteger(g,k,"N",n)
 set g=null
endfunction

//=============================================================================================
// Destroys Field Data
function FieldData_Destroy takes integer fielddata returns nothing
    call DestroyTable(I2S(fielddata))
endfunction

//##End of CS Gamecache engine##

Copy it to your map header (the very first thing that appears in the trigger list that has your map's name) and now you'll have several extra functions. Two of these are:

1. AttachObject( handle, string, handle ): will "attach" a variable to the first handle (I used timer in my example). So you can get it later (even if it was a local)

2. GetAttachedLightning( handle, string ): will get the attached lightning back from the first handle. Make sure you use the same string!

So, you can "attach" your lightning to a timer and, in the function called by the timer, get the lightning back and destroy it.
However you'll have to create a new timer for every lightning and destroy it when finish using it. This is known to cause bugs... Therefore I suggest you to look for TimerUtils.

Rememer: this code does NOT work in 1.24 as it makes use of the broken H2I function.
 
Level 4
Joined
Mar 23, 2008
Messages
87
@Marcelo: Thanks :) It's a little too much code for me though. Think I'll either update or find a workaround. I think I'm onto something with timers here so I'll probably experiment some more with that when i get home from work. :)
 
Status
Not open for further replies.
Top