Moderator
M
Moderator
12:19, 3rd Aug 2013
Maker: Approved
Maker: Approved
// Lightning Bomb made by deathismyfriend
// version 1.0.4
function PolarProjectionXLightningBomb takes real x, real dist, real angle returns real // returns x
return x + dist * Cos( angle)
endfunction
function PolarProjectionYLightningBomb takes real y, real dist, real angle returns real // returns y
return y + dist * Sin( angle)
endfunction
function PolarProjectionZLightningBomb takes real y, real dist, real angle returns real // returns z
return y + dist * Tan( angle)
endfunction
function LightningBombDamageLoop takes nothing returns nothing
local integer L = 1
local integer m = udg_lightningBombMaxIndex
loop
exitwhen L > m
set udg_lightningBombTimeCounter[ L] = udg_lightningBombTimeCounter[ L] + 1
if udg_lightningBombTimeCounter[ L] >= udg_lightningBombTime[ L] then
if udg_lightningBombCaster[ L] != null then
call SetUnitPropWindow( udg_lightningBombCaster[ L], udg_lightningBombPropWindow[ L])
endif
call DestroyLightning( udg_lightningBombLightning[ L])
set udg_lightningBombCaster[ L] = udg_lightningBombCaster[ m]
set udg_lightningBombCaster[ m] = null
set udg_lightningBombTimeCounter[ L] = udg_lightningBombTimeCounter[ m]
set udg_lightningBombPropWindow[ L] = udg_lightningBombPropWindow[ m]
set udg_lightningBombLightning[ L] = udg_lightningBombLightning[ m]
set udg_lightningBombLightning[ m] = null
set udg_lightningBombTime[ L] = udg_lightningBombTime[ m]
set m = m - 1
set L = L - 1
endif
set L = L + 1
endloop
set udg_lightningBombMaxIndex = m
endfunction
function LightningBombSetup takes nothing returns nothing
local unit c = GetTriggerUnit()
local unit u
local integer abiLvl = GetUnitAbilityLevel( c, udg_lightningBombSpellId)
local integer lgth = udg_lightningBombTimeBase - ( abiLvl * udg_lightningBombTimePerLvl)
local real r = udg_lightningBombRadiusBase - ( abiLvl * udg_lightningBombRadiusPerLvl)
local real dam = udg_lightningBombDamageBase - ( abiLvl * udg_lightningBombDamagePerLvl)
local real x = GetSpellTargetX()
local real cx = GetUnitX( c)
local real y = GetSpellTargetY()
local real cy = GetUnitY( c)
local real z
local real x1
local real y1
local real z1
local real L1 = 22.5
local integer L = 1
local real d = r
local integer m = udg_lightningBombMaxIndex + 1
call MoveLocation( udg_lightningBombLocation, x, y)
set z = GetLocationZ( udg_lightningBombLocation) + 50.00
set udg_lightningBombCaster[ m] = c
set udg_lightningBombTimeCounter[ m] = 0
set udg_lightningBombTime[ m] = lgth
set udg_lightningBombLightning[ m] = AddLightning( udg_lightningBombLightningType2, true, cx, cy, x, y)
set udg_lightningBombPropWindow[ m] = GetUnitPropWindow( c)
if m == 1 then
call TimerStart( udg_lightningBombTimer, udg_lightningBombLoopTime, true, function LightningBombDamageLoop)
endif
set udg_lightningBombTime[ m] = lgth
loop
exitwhen L > 90
set z1 = PolarProjectionZLightningBomb( z, d, L)
loop
exitwhen L1 >= 360
set x1 = PolarProjectionXLightningBomb( x, d, L1)
set y1 = PolarProjectionYLightningBomb( y, d, L1)
set m = m + 1
set udg_lightningBombTimeCounter[ m] = 0
set udg_lightningBombTime[ m] = lgth
set udg_lightningBombLightning[ m] = AddLightningEx( udg_lightningBombLightningType, true, x1, y1, z1, x, y, z)
set L1 = L1 + 45
endloop
if L1 >= 380 then // this rotates the lightning so its not straight up at every 45 degree angle.
set L1 = 0
else // 360
set L1 = 22.5
endif
set L = L + 15
set d = udg_lightningBombCircleReal[ L]*r // reduces the length but not equally.
endloop
call GroupEnumUnitsInRange( udg_lightningBombGroup , x, y, r, null)
loop
set u = FirstOfGroup( udg_lightningBombGroup )
exitwhen u == null
if u != c and LightningBombFilterUnits( u, c) and not IsUnitType( u, UNIT_TYPE_DEAD) and GetUnitTypeId( u) != 0 then
call UnitDamageTarget( c, u, dam, false, false, udg_lightningBombAttackType, udg_lightningBombDamageType, null)
endif
call GroupRemoveUnit( udg_lightningBombGroup , u)
endloop
set udg_lightningBombMaxIndex = m
set c = null
endfunction
function LightningBombCreateLocation takes nothing returns nothing
set udg_lightningBombLocation = Location( 0, 0)
endfunction
function LightningBombCastConditions takes nothing returns boolean
if GetSpellAbilityId() == udg_lightningBombSpellId then
call LightningBombSetup()
endif
return false
endfunction
//===========================================================================
function InitTrig_Lightning_Bomb_Cast takes nothing returns nothing
local trigger t = CreateTrigger()
set udg_lightningBombTimer = CreateTimer()
call LightningBombCreateLocation()
set udg_lightningBombGroup = CreateGroup()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_CAST)
call TriggerAddCondition( t, Condition( function LightningBombCastConditions))
set t = null
endfunction
library LightningBomb
// Lightning Bomb made by deathismyfriend
// Alloc by Nestharus can be found here. http://www.hiveworkshop.com/forums/jass-resources-412/snippet-alloc-alternative-221493/
// version 1.0.4
globals
// These are the base values that u can set.
// Here u set the max time for it to end. For every second u need 32. So 5 seconds is 160.
private integer timeBase = 160
//
// This is the damage base. Every interval
private real damageBase = 50.00
//
// This is the radius base
private real radiusBase = 350.00
//
// ----------------------------------------------------------------------------------------------------
// These are the values that get added to the base per lvl that u can set.
// Here u set the max time for it to end per lvl. For every second u need 32. So 5 seconds is 160.
private integer timePerLvl = 0
//
// This is the damage per lvl. Every interval
private real damagePerLvl = 0.00
//
// This is the radius per lvl
private real radiusPerLvl = 0.00
//
// ----------------------------------------------------------------------------------------------------
// These are the other values that u can change
// set the lightning that gets created when the lightning bomb gets casted
private string lightningType = "LEAS"
//
// set the lightning that gets created from the caster to the target point when the lightning bomb gets casted
private string lightningType2 = "AFOD"
//
// here u can change the attack type
private attacktype attackType = ATTACK_TYPE_CHAOS
//
// here u can change the damage type
private damagetype damageType = DAMAGE_TYPE_NORMAL
//
// You can change the time for the loop. Normally u cant change this. In this case it doesnt really matter.
// Just remember when u change this u need to change the time for the spell.
private real loopTime = 0.031250000
//
// Set the spell id here
private integer spellId = 'A000'
//
// ----------------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------------
// Dont change the next couple variables. The other options u can change are under the globals block.
private timer tmr
private group grp
private real array circleReal
private location loc
private integer maxIndex = 0
private integer array structIndex
endglobals
//u can change the reals in here. This is for the semi spherical shape the lightning makes.
//Each variable is for the distance of the lightning. u can make it cylindrical, cone shaped. and a few others if u mess with it.
private function SetupCircle takes nothing returns nothing
set circleReal[ 16] = 0.96592
set circleReal[ 31] = 0.86599
set circleReal[ 46] = 0.70698
set circleReal[ 61] = 0.50000
set circleReal[ 76] = 0.25869
endfunction
private function FilterUnits takes unit u, unit c returns boolean
// u is the target
// c is the caster
// you can add the conditions you want the spell to follow here.
if not IsUnitType( u, UNIT_TYPE_STRUCTURE) and GetWidgetLife( u) > .405 then
return true
endif
return false
endfunction
//dont change anything under here
private struct lightningBomb extends array
implement Alloc
private unit caster
private integer time
private integer timeCounter
private lightning lghtning
private real propWindow
private static method pProjX takes real x, real dist, real angle returns real // returns x
return x + dist * Cos( angle)
endmethod
private static method pProjY takes real y, real dist, real angle returns real // returns y
return y + dist * Sin( angle)
endmethod
private static method pProjZ takes real y, real dist, real angle returns real // returns z
return y + dist * Tan( angle)
endmethod
private static method create takes unit c, integer t, real prop returns thistype
local thistype this = thistype.allocate()
set this.timeCounter = 0
set this.caster = c
set this.time = t
set this.propWindow = prop
set maxIndex = maxIndex + 1
return this
endmethod
private method destroy takes nothing returns nothing
if this.caster != null then
call SetUnitPropWindow( this.caster, this.propWindow)
set caster = null
endif
call DestroyLightning( this.lghtning)
set this.lghtning = null
set maxIndex = maxIndex - 1
call this.deallocate()
endmethod
private static method destroyLoop takes nothing returns nothing
local integer L = 1
local thistype this
loop
exitwhen L > maxIndex
set this = structIndex[ L]
set this.timeCounter = this.timeCounter + 1
if this.timeCounter >= this.time then
set structIndex[ L] = structIndex[ maxIndex]
call this.destroy()
set L = L - 1
endif
set L = L + 1
endloop
endmethod
private static method setup takes nothing returns nothing
local thistype this
local unit c = GetTriggerUnit()
local unit u
local integer abiLvl = GetUnitAbilityLevel( c, spellId)
local integer t = timeBase - ( abiLvl * timePerLvl)
local real r = radiusBase - ( abiLvl * radiusPerLvl)
local real dam = damageBase - ( abiLvl * damagePerLvl)
local real x = GetSpellTargetX()
local real cx = GetUnitX( c)
local real y = GetSpellTargetY()
local real cy = GetUnitY( c)
local real z
local real x1
local real y1
local real z1
local real L1 = 22.5
local integer L = 1
local real d = r
call MoveLocation( loc, x, y)
set z = GetLocationZ( loc) + 50.00
set this = thistype.create( c, t, GetUnitPropWindow( c))
set this.lghtning = AddLightning( lightningType2, true, cx, cy, x, y)
set structIndex[ maxIndex] = this
if maxIndex == 1 then
call TimerStart( tmr, loopTime, true, function thistype.destroyLoop)
endif
loop
exitwhen L > 90
set z1 = pProjZ( z, d, L)
loop
exitwhen L1 >= 360
set x1 = pProjX( x, d, L1)
set y1 = pProjY( y, d, L1)
set this = thistype.create( null, t, 0.00)
set structIndex[ maxIndex] = this
set this.lghtning = AddLightningEx( lightningType, true, x1, y1, z1, x, y, z)
set L1 = L1 + 45
endloop
if L1 >= 380 then // this rotates the lightning so its not straight up at every 45 degree angle.
set L1 = 0
else // 360
set L1 = 22.5
endif
set L = L + 15
set d = circleReal[ L]*r // reduces the length but not equally.
endloop
call GroupEnumUnitsInRange( grp, x, y, r, null)
loop
set u = FirstOfGroup( grp )
exitwhen u == null
if u != c and FilterUnits( u, c) and not IsUnitType( u, UNIT_TYPE_DEAD) and GetUnitTypeId( u) != 0 then
call UnitDamageTarget( c, u, dam, false, false, attackType, damageType, null)
endif
call GroupRemoveUnit( grp, u)
endloop
set c = null
endmethod
private static method createLocation takes nothing returns nothing
set loc = Location( 0, 0)
endmethod
private static method conditions takes nothing returns boolean
if GetSpellAbilityId() == spellId then
call setup()
endif
return false
endmethod
//===========================================================================
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call createLocation()
call SetupCircle()
set tmr = CreateTimer()
set grp = CreateGroup()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_CAST)
call TriggerAddCondition( t, Condition( function thistype.conditions))
set t = null
endmethod
endstruct
endlibrary