- Joined
- Jun 10, 2007
- Messages
- 225
I've wanted to do a system like this for awhile. It allows you to easily create chain lightnings and modify every aspect of them, and even allow them to bounce twice on one unit in certain situations.
Requires vJass and CSCache in a library called CSCache
Below is the code:
Chain Lighting takes
unit caster - The casting unit, the first bolt will originate from this unit. Using GetLightningCaster() in the handlerFunc will return this unit.
unit target - The first unit to be hit.
real bouncedist - The maximum distance the lightning will look for a new target to bounce to.
string ltype - The model the lightning will use.
real ldur - The duration each lightning will last. 0.5 - 1.0 are the best, in my opinion.
integer bounceamount - The number of bounces. Using GetLightningBounceNumber() in the handlerFunc will return how many bounces so far.
integer bouncesbetweenbouncetwice - The number of bounces there must be before the lightning can hit a unit again. If a unit is hit, and this is 7, it must bounce 7 more times before the target will become strikeable again. Using 0 means it cna never bounce twice.
real bouncerate - The time between the lightning's bounces.
boolexpr filter - A function which must return true, or else the target cannot be hit.
code handlerFunc - This will run whenever the lightning strikes a unit. GetLightning() returns the lightning going to the unit, GetLightningCaster() returns the lightning's caster, GetLightningUnit() returns the current unit being hit, GetLightningBounceNumber() returns how many bounces there have been so far.
Edit1: Fixed some suggestions purplepoot made, attached an updated map.
Edit2: Removed the map, theres a thread about this in the S&S section.
You can also download the attached map to see some example spells:
Requires vJass and CSCache in a library called CSCache
Below is the code:
JASS:
library ChainLightning requires CSCache
//Requires vJass to compile
//Requires CSCache system in a library called CSCache
//Use GetLightningTarget() to refer to the unit being hit by lightning in any handlerFuncs you use
//Use GetLightningCaster() to refer to the casting unit
//Use GetLightningBounceNumber() to refer to how many bounces there have been so far
//Use GetLightning() to refer to the lightning connecting the last unit to the current unit
//Use 0 for bouncesbetweenbouncetwice to make it so you can never bounce twice
//Currently there is a 99 bounce limit if you want bouncesbetweenbouncetwice to work
//function ChainLightning takes unit caster, unit target,real bouncedist, string ltype,real ldur, integer bounceamount,integer bouncesbetweenbouncetwice,real bouncerate,boolexpr filter, code handlerFunc returns nothing
struct ChainData
integer maxbounces
integer sofar
unit target
unit caster
unit lastunit
string ltype
real maxdist
trigger t
real time
group alreadyhit = CreateGroup()
boolexpr filter
unit array units[100]
integer bounces
real ldur
static lightning Lightning
static unit LightningTarget
static unit LightningCaster
static integer LightningBounceNumber
endstruct
struct LightningAttachData
lightning l
unit u1
unit u2
real h1
real h2
real dur
endstruct
constant function GetLightning takes nothing returns lightning
return ChainData.Lightning
endfunction
constant function GetLightningTarget takes nothing returns unit
return ChainData.LightningTarget
endfunction
constant function GetLightningCaster takes nothing returns unit
return ChainData.LightningCaster
endfunction
constant function GetLightningBounceNumber takes nothing returns integer
return ChainData.LightningBounceNumber
endfunction
function AttachTempLightning_Timer takes nothing returns nothing
local LightningAttachData la = LightningAttachData(GetAttachedInt(GetExpiredTimer(),"la"))
call MoveLightningEx(la.l,true,GetUnitX(la.u1),GetUnitY(la.u1),la.h1,GetUnitX(la.u2),GetUnitY(la.u2),la.h2)
set la.dur = la.dur - 0.04
if la.dur <= 0.0 then
call PauseTimer(GetExpiredTimer())
set la.u1 = null
set la.u2 = null
call DestroyLightning(la.l)
set la.l = null
call LightningAttachData.destroy(la)
call CleanAttachedVars(GetExpiredTimer())
call DestroyTimer(GetExpiredTimer())
endif
endfunction
function AttachTempLightning takes string s,unit u1, unit u2, real dur, real height1, real height2 returns lightning
local LightningAttachData la = LightningAttachData.create()
local timer t = CreateTimer()
set la.u1 = u1
set la.u2 = u2
set la.l = AddLightningEx(s,true,GetUnitX(u1),GetUnitY(u1),height1,GetUnitX(u2),GetUnitY(u2),height2)
set la.dur = dur
set la.h1 = height1
set la.h2 = height2
call AttachInt(t,"la",la)
call TimerStart(t,0.04,true,function AttachTempLightning_Timer)
set t = null
return la.l
endfunction
function DuplicateUnit takes unit u returns unit
return u
endfunction
function ChainLightning_Timer takes nothing returns nothing
local ChainData cd = ChainData(GetAttachedInt(GetExpiredTimer(),"cd"))
local group g = CreateGroup()
local group g2 = CreateGroup()
local unit u
local integer i
local lightning l
local timer t = GetExpiredTimer()
set cd.sofar = cd.sofar + 1
set cd.units[cd.sofar] = cd.target
if cd.bounces > 0 then
set i = cd.sofar - cd.bounces
if i > 0 and cd.units[i] != null then
call GroupRemoveUnit(cd.alreadyhit,cd.units[i])
set cd.units[i] = null
endif
endif
set l = AttachTempLightning(cd.ltype,cd.target,cd.lastunit,cd.ldur,GetUnitFlyHeight(cd.target) + 50,GetUnitFlyHeight(cd.lastunit) + 50)
set ChainData.LightningTarget = cd.target
set ChainData.LightningCaster = cd.caster
set ChainData.LightningBounceNumber = cd.sofar
set ChainData.Lightning = l
call TriggerExecute(cd.t)
call GroupAddUnit(cd.alreadyhit,cd.target)
call GroupEnumUnitsInRange(g,GetUnitX(cd.target),GetUnitY(cd.target),cd.maxdist,cd.filter)
call GroupAddGroup(g,g2)
loop
set u = FirstOfGroup(g2)
exitwhen u == null
call GroupRemoveUnit(g2,u)
if IsUnitInGroup(u,cd.alreadyhit) then
call GroupRemoveUnit(g,u)
endif
endloop
set cd.lastunit = DuplicateUnit(cd.target)
set cd.target = GroupPickRandomUnit(g)
call DestroyGroup(g)
set g = null
if cd.sofar >= cd.maxbounces or cd.target == null then
call PauseTimer(t)
set cd.target = null
set cd.caster = null
set cd.lastunit = null
set cd.ltype = null
set cd.t = null
set cd.filter = null
call DestroyGroup(cd.alreadyhit)
set cd.alreadyhit = null
call ChainData.destroy(cd)
call CleanAttachedVars(t)
call DestroyTimer(t)
endif
if cd.sofar == 1 then
call TimerStart(GetExpiredTimer(),cd.time,true,function ChainLightning_Timer)
endif
call DestroyGroup(g2)
set g2 = null
set u = null
set l = null
endfunction
function ChainLightning takes unit caster, unit target,real bouncedist, string ltype,real ldur, integer bounceamount,integer bouncesbetweenbouncetwice,real bouncerate,boolexpr filter, code handlerFunc returns nothing
local ChainData cd = ChainData.create()
local timer t = CreateTimer()
local trigger trig = CreateTrigger()
call TriggerAddAction(trig,handlerFunc)
set cd.ldur = ldur
set cd.bounces = bouncesbetweenbouncetwice
set cd.filter = filter
set cd.t = trig
set cd.target = target
set cd.caster = caster
set cd.lastunit = caster
set cd.maxdist = bouncedist
set cd.ltype = ltype
set cd.maxbounces = bounceamount
set cd.t = trig
set cd.time = bouncerate
set cd.sofar = 0
call GroupAddUnit(cd.alreadyhit,target)
call AttachInt(t,"cd",cd)
call TimerStart(t,0.00,false,function ChainLightning_Timer)
set trig = null
set t = null
endfunction
endlibrary
Chain Lighting takes
unit caster - The casting unit, the first bolt will originate from this unit. Using GetLightningCaster() in the handlerFunc will return this unit.
unit target - The first unit to be hit.
real bouncedist - The maximum distance the lightning will look for a new target to bounce to.
string ltype - The model the lightning will use.
real ldur - The duration each lightning will last. 0.5 - 1.0 are the best, in my opinion.
integer bounceamount - The number of bounces. Using GetLightningBounceNumber() in the handlerFunc will return how many bounces so far.
integer bouncesbetweenbouncetwice - The number of bounces there must be before the lightning can hit a unit again. If a unit is hit, and this is 7, it must bounce 7 more times before the target will become strikeable again. Using 0 means it cna never bounce twice.
real bouncerate - The time between the lightning's bounces.
boolexpr filter - A function which must return true, or else the target cannot be hit.
code handlerFunc - This will run whenever the lightning strikes a unit. GetLightning() returns the lightning going to the unit, GetLightningCaster() returns the lightning's caster, GetLightningUnit() returns the current unit being hit, GetLightningBounceNumber() returns how many bounces there have been so far.
Edit1: Fixed some suggestions purplepoot made, attached an updated map.
Edit2: Removed the map, theres a thread about this in the S&S section.
You can also download the attached map to see some example spells:
Last edited: