Moderator
M
Moderator
Lightning Storm v1.4 | Reviewed by Maker | 17th Oct 2013 | ||||
APPROVED | ||||
|
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
// L I G H T N I N G S T O R M
// - Spell Create By:
// + Elphis
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
library LightningStorm /*
*/ requires /*
// -*/ DelFX /* http://www.hiveworkshop.com/forums/spells-569/delfx-delayed-effects-1-4-2-a-116064/?prev=search%3DDel%2520Effect%26d%3Dlist%26r%3D20%26c%3D112
// -*/ TimerUtils /* http://www.wc3c.net/showthread.php?t=101322
// -*/ SpellEffectEvent /* http://www.hiveworkshop.com/forums/jass-resources-412/snippet-spelleffectevent-187193/
// -*/ xebasic /* http://www.wc3c.net/showthread.php?t=101150
// -*/ xedamage /* http://www.wc3c.net/showthread.php?t=101150
// -*/ Table /* http://www.wc3c.net/showthread.php?t=101246
// -*/ LightningStormPlugin /* Plugin */
// Optional:
// LightningAura.mdx - http://www.hiveworkshop.com/forums/models-530/lightning-aura-98346/?prev=search%3DLightning%2520Aura%26d%3Dlist%26r%3D20
// BoundSentinel - http://www.wc3c.net/showthread.php?t=102576 (You must adding it, this library help you prevent crash the game when lightning outside XY of map.
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
// - Spell Information:
// - Call a powerful beam of energy from the ground, accumulate and discharge power super strong
// when enemies within 150 range of this power, enemies will shock and lost 30/60/90/120 hit points
// after storm release 30/40/50/60 lightning, it will absorbed all previous energy
// and discharge 30/40/50/60 lightning again also deals 30 damage to enemies
// and then, it accumulates, and exploded, the explosion caused a power flow and deals 15/30/45/60 damage to enemies.
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
// - Installation:
// - Import/copy the required libraries and Lightning Storm code to your map
// - Import/copy the custom ability and unit to your map and change the SPELL_ID,DUMMY_LIGHTNING if needed
// - Export model LightningAura.mdx, dummy.mdx and import it into your map
// - You may view the raw ID of the objects by pressing CTRL+D in the object editor
// - You may play with the configurables below
// - When you copy dummy "xe unit (Caster System?)", you must change rawcode ID of this dummy = xeca
// or you must change rawcode in xebasic with name globals: XE_DUMMY_UNITID
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
globals
//============================================SPELL CONFIGURATION==========================================================
//*************************************************************************************************************************
//Spell rawcode, change if needed
private constant integer SPELL_ID = 'A000'
//
//Dummy lightning rawcode, change if needed
private constant integer DUMMY_LIGHTNING = 'e000'
//Ability allow unit can fly change if needed
private constant integer ABI_FLY = 'Amrf'
//Spell Periodic
private constant real PERIODIC = 0.031250000
//
//*************************************************************************************************************************
//*************************************************************************************************************************
//*************************************************************************************************************************
//Damage base when lightning hit enemies
private constant real DAMAGE_BASE = 30.
//Damag radius when lightning hit ground
private constant real DAMAGE_RADIUS = 150.
//Damage radius when powerful lightning causes an explotion, don't increase this value too much because it very powerful
private constant real DAMAGE_RADIUS_EXPLORE = 75.
//Area of effect of spell
//This value must be divisible by two
private constant real AREA_OF_EFFECT = 600.
//Powerful lightning height
//This value must be divisible by two
private constant real L_HEIGHT_POWER = 600.
//Lightning release intevar, decrease if you want to spell "SPAM" ^^ (just kidding), increase if spell very powerful :)
private constant real RELEASE_INTEVAR = 0.1
//Size of center lighning (also size of other lightning/2)
private constant real SIZE = 3.
//Min height of lightning
private constant real MIN_HEIGHT = 50.
//Distance increase of other lightning per periodic
private constant real DISTANCE_INC = 10.
//Min distance release lightning
private constant real MIN_REALSE_L = 200.
//Lightning release speed
private constant real LIGHTNING_R_S = 10.
//Height of center lightning when spell expire
private constant real HEIGHT_INC = 15.
//
//*************************************************************************************************************************
//*************************************************************************************************************************
//*************************************************************************************************************************
//Total lightning release of spell (Spell expire when release all lightning with value)
private constant integer RELEASE_COUNT = 30
//
//*************************************************************************************************************************
//*************************************************************************************************************************
//*************************************************************************************************************************
//Center Lightning Vortex (Like Eye Storm)
private constant string M_MODEL = "war3mapImported\\LightningAura.mdx"
//Lightning effect when all lightning causes an explotion
private constant string E_MODEL = "war3mapImported\\Great Lightning.mdx"
//Orb of lightning model
private constant string O_MODEL = "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"
//Effect when lightning hit ground
private constant string RELEASE_L_EFFECT = "Abilities\\Weapons\\Bolt\\BoltImpact.mdl"
//Main lightning attach to orb
private constant string M_ALT = "DRAM"
//Other lightning attach to orb
private constant string O_ALT = "MFPB"
//Hmm, i don't know how to explain
private constant string E_ALT = "CLPB"
//Release lightning model
private constant string R_ALT = "AFOD"
//Attachment effect of dummy
private constant string D_ATTACHMENT = "origin"
//Attachment effect of center lightning
private constant string M_ATTACHMENT = "origin"
//
//*************************************************************************************************************************
//*************************************************************************************************************************
//*************************************************************************************************************************
// ======DAMAGE SETTINGS======
private constant attacktype ATTACKTYPE = ATTACK_TYPE_HERO
private constant damagetype DAMAGETYPE = DAMAGE_TYPE_COLD
private constant weapontype WEAPONTYPE = WEAPON_TYPE_METAL_HEAVY_BASH
//*************************************************************************************************************************
//*************************************************************************************************************************
//*************************************************************************************************************************
endglobals
struct LighningStorm
unit caster
unit dummy
//
real xx
real yy
real angle
real s
real reach = 0.
real intevar = 0.
real dam
//
integer count
integer k = 0
//
Table tab
xedamage xed
static method onCount takes unit u returns integer
return RELEASE_COUNT + GetUnitAbilityLevel(u,SPELL_ID)*10 //Count lightning release per periodic
endmethod
static method onDamage takes unit u returns real
return DAMAGE_BASE + GetUnitAbilityLevel(u,SPELL_ID) //Damage per lightning hit enemies unit
endmethod
static method onPeriodic takes nothing returns nothing
//
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
//
local integer i = 6
local real x
local real y
local real cos
local real sin
//
if k == 0 then
if s < SIZE then
set s = s + tab.real[this]
//
call SetUnitScale(dummy,s,0.,0.)
//
loop
exitwhen i == 0
call SetUnitScale(tab.unit[i],s/2,0.,0.)
call SetUnitScale(tab.unit[10+i],s/2,0.,0.)
set i = i - 1
endloop
//
set reach = reach + DISTANCE_INC
//
else
if intevar < RELEASE_INTEVAR then
set intevar = intevar + PERIODIC
else
set intevar = 0.
set count = count - 1
//This line release lightning
call RLPLLS.add(R_ALT,RELEASE_L_EFFECT,caster,tab.unit[50+GetRandomInt(1,6)],dam,GetRandomReal(MIN_REALSE_L,AREA_OF_EFFECT),DAMAGE_RADIUS,LIGHTNING_R_S,ATTACKTYPE,DAMAGETYPE,WEAPONTYPE)
//
if count == 0 then
set k = 1
set s = 0.
set intevar = 0.
endif
//
endif
endif
elseif k == 1 then
set reach = reach - DISTANCE_INC
endif
//
//
if k <= 1 then
//
set angle = angle + 5.
set i = 6
//
loop
exitwhen i == 0
//
if reach > 0. then
set cos = Cos((tab.real[20+i]+angle)*.0174533)
set sin = Sin((tab.real[20+i]+angle)*.0174533)
set x = xx + reach/2 * cos
set y = yy + reach/2 * sin
//
call SetUnitX(tab.unit[i],x)
call SetUnitY(tab.unit[i],y)
call MoveLightning(tab.lightning[30+i],true,x,y,xx,yy)
//
set x = xx + reach * cos
set y = yy + reach * sin
//
call SetUnitX(tab.unit[10+i],x)
call SetUnitY(tab.unit[10+i],y)
call MoveLightning(tab.lightning[40+i],true,x,y,GetWidgetX(tab.unit[i]),GetWidgetY(tab.unit[i]))
call MoveLightningEx(tab.lightning[60+i],true,x,y,MIN_HEIGHT,GetWidgetX(tab.unit[51]),GetWidgetY(tab.unit[51]),GetUnitFlyHeight(tab.unit[51]))
else
set k = 2
set s = 0.
call RemoveUnit(tab.unit[i])
call RemoveUnit(tab.unit[10+i])
call DestroyLightning(tab.lightning[30+i])
call DestroyLightning(tab.lightning[40+i])
call DestroyLightning(tab.lightning[60+i])
//
set tab.unit[i] = null
set tab.unit[10+i] = null
set tab.lightning[30+i] = null
set tab.lightning[40+i] = null
set tab.lightning[60+i] = null
//
endif
//
set i = i - 1
endloop
elseif s < L_HEIGHT_POWER and k == 2 then
//
set s = s + HEIGHT_INC
//
call SetUnitFlyHeight(dummy,s,0.)
//
set i = 6
//
loop
exitwhen i == 0
if s >= tab.real[70+i] and tab.unit[50+i] != null then
call RemoveUnit(tab.unit[50+i])
set tab.unit[50+i] = null
endif
set i = i - 1
endloop
//
if s >= L_HEIGHT_POWER then
//
set i = 6
set k = 3
//
loop
exitwhen i == 0
//
set x = xx + 100. * Cos(i*60*.0174533)
set y = yy + 100. * Sin(i*60*.0174533)
//
set tab.unit[i] = CreateUnit(Player(15),DUMMY_LIGHTNING,x,y,0.)
set tab.lightning[10+i] = AddLightningEx(M_ALT,true,x,y,s,xx,yy,s)
call SetUnitScale(tab.unit[i],SIZE/2,0.,0.)
call UnitAddAbility(tab.unit[i],ABI_FLY)
call UnitRemoveAbility(tab.unit[i],ABI_FLY)
call SetUnitFlyHeight(tab.unit[i],s,0.)
//
set i = i - 1
endloop
//
endif
//
elseif reach < AREA_OF_EFFECT and k == 3 then
//
set reach = reach + DISTANCE_INC
//
loop
exitwhen i == 0
//
set x = xx + reach * Cos((tab.real[20+i]+angle)*.0174533)
set y = yy + reach * Sin((tab.real[20+i]+angle)*.0174533)
//
call SetUnitX(tab.unit[i],x)
call SetUnitY(tab.unit[i],y)
call MoveLightningEx(tab.lightning[10+i],true,x,y,s,xx,yy,L_HEIGHT_POWER)
//
set i = i - 1
endloop
//
if reach >= AREA_OF_EFFECT then
set k = 4
endif
elseif s > MIN_HEIGHT and k == 4 then
//
set s = s - HEIGHT_INC*2
//
loop
exitwhen i == 0
//
set x = xx + reach * Cos((tab.real[20+i]+angle)*.0174533)
set y = yy + reach * Sin((tab.real[20+i]+angle)*.0174533)
//
call MoveLightningEx(tab.lightning[10+i],true,x,y,s,xx,yy,L_HEIGHT_POWER)
//
call SetUnitFlyHeight(tab.unit[i],s,0.)
//
set i = i - 1
endloop
//
if s <= MIN_HEIGHT then
set k = 5
set count = onCount(caster)
endif
//
elseif count > 0 and k == 5 then
set count = count - 1
//This line release lightning
call RLPLLS.add(R_ALT,RELEASE_L_EFFECT,caster,dummy,dam,GetRandomReal(MIN_REALSE_L,AREA_OF_EFFECT),DAMAGE_RADIUS,LIGHTNING_R_S*3,ATTACKTYPE,DAMAGETYPE,WEAPONTYPE)
if count == 0 then
set k = 6
endif
elseif s < L_HEIGHT_POWER and k == 6 then
set s = s + HEIGHT_INC
call SetUnitFlyHeight(dummy,GetUnitFlyHeight(dummy)-HEIGHT_INC,0.)
loop
exitwhen i == 0
//
call MoveLightningEx(tab.lightning[10+i],true,GetWidgetX(tab.unit[i]),GetWidgetY(tab.unit[i]),s,xx,yy,GetUnitFlyHeight(dummy))
//
call SetUnitFlyHeight(tab.unit[i],s,0.)
//
set i = i - 1
endloop
if s >= L_HEIGHT_POWER then
set k = 7
endif
elseif reach > 0. and k == 7 then
set reach = reach - DISTANCE_INC
loop
exitwhen i == 0
//
set x = xx + reach * Cos((tab.real[20+i]+angle)*.0174533)
set y = yy + reach * Sin((tab.real[20+i]+angle)*.0174533)
//
call MoveLightningEx(tab.lightning[10+i],true,x,y,s,xx,yy,0.)
//
call SetUnitX(tab.unit[i],x)
call SetUnitY(tab.unit[i],y)
//
set i = i - 1
endloop
if reach <= 0. then
set k = 8
endif
elseif s > MIN_HEIGHT and k == 8 then
set s = s - HEIGHT_INC*2
//
loop
exitwhen i == 0
//
call MoveLightningEx(tab.lightning[10+i],true,GetWidgetX(tab.unit[i]),GetWidgetY(tab.unit[i]),s,xx,yy,0.)
//
call SetUnitFlyHeight(tab.unit[i],s,0.)
//
set i = i - 1
endloop
//
set i = 6
//
if s <= MIN_HEIGHT then
set k = 9
//
loop
exitwhen i == 0
//
call RemoveUnit(tab.unit[i])
call DestroyLightning(tab.lightning[10+i])
//
set tab.unit[i] = null
set tab.lightning[10+i] = null
//
set i = i - 1
endloop
//
set s = SIZE
//
endif
elseif s > 0. and k == 9 then
set s = s - tab.real[this]*2
call SetUnitScale(dummy,s,0.,0.)
//
if s <= 0. then
set k = 10
call RemoveUnit(dummy)
set dummy = null
endif
elseif reach < AREA_OF_EFFECT and k == 10 then
set reach = reach + DISTANCE_INC*4
loop
exitwhen i == 0
//
set x = xx + reach * Cos(i*60*.0174533)
set y = yy + reach * Sin(i*60*.0174533)
//
call DestroyEffect(AddSpecialEffect(RELEASE_L_EFFECT,x,y))
//This line deals damage to enemies unit
call xed.damageAOE(caster,x,y,DAMAGE_RADIUS_EXPLORE,dam/2)
//
set i = i - 1
endloop
else
//Clean data
call ReleaseTimer(t)
set caster = null
call tab.flush()
call tab.destroy()
call xed.destroy()
call destroy()
endif
//
set t = null
//
endmethod
static method onCast takes nothing returns nothing
//
local thistype this = allocate()
//
local integer ii = 6
local real x
local real y
//Spell config
set caster = GetTriggerUnit()
//
set tab = Table.create()
//
set xx = GetSpellTargetX()
set yy = GetSpellTargetY()
//Xe damage install
set xed = xedamage.create()
set xed.dtype = DAMAGETYPE
set xed.atype = ATTACKTYPE
set xed.wtype = WEAPONTYPE
set xed.exception = UNIT_TYPE_STRUCTURE
set xed.damageEnemies = true
set xed.damageTrees = true
//
set dam = onDamage(caster)
set angle = L_HEIGHT_POWER/6
set count = onCount(caster)
set tab.real[this] = SIZE/AREA_OF_EFFECT*DISTANCE_INC
//
set dummy = CreateUnit(Player(15),XE_DUMMY_UNITID,xx,yy,0.)
call SetUnitScale(dummy,0.,0.,0.)
call UnitAddAbility(dummy,ABI_FLY)
call UnitRemoveAbility(dummy,ABI_FLY)
call CreateDelayedEffectTarget(M_MODEL,dummy,M_ATTACHMENT,0.,30.)
//
loop
exitwhen ii == 0
//
set x = xx + 100. * Cos(ii*60*.0174533)
set y = yy + 100. * Sin(ii*60*.0174533)
//
set tab.unit[ii] = CreateUnit(Player(15),DUMMY_LIGHTNING,x,y,0.)
set tab.real[20+ii] = 57.29582 * Atan2(y - yy, x - xx)
call SetUnitScale(tab.unit[ii],0.,0.,0.)
call UnitAddAbility(tab.unit[ii],ABI_FLY)
call UnitRemoveAbility(tab.unit[ii],ABI_FLY)
call SetUnitFlyHeight(tab.unit[ii],MIN_HEIGHT,MIN_HEIGHT)
//
set tab.unit[10+ii] = CreateUnit(Player(15),DUMMY_LIGHTNING,x,y,0.)
call SetUnitScale(tab.unit[10+ii],0.,0.,0.)
call UnitAddAbility(tab.unit[10+ii],ABI_FLY)
call UnitRemoveAbility(tab.unit[10+ii],ABI_FLY)
call SetUnitFlyHeight(tab.unit[10+ii],MIN_HEIGHT,MIN_HEIGHT)
//
set tab.unit[50+ii] = CreateUnit(Player(15),DUMMY_LIGHTNING,xx,yy,0.)
call SetUnitScale(tab.unit[50+ii],SIZE/2,0.,0.)
call UnitAddAbility(tab.unit[50+ii],ABI_FLY)
call UnitRemoveAbility(tab.unit[50+ii],ABI_FLY)
set s = s + angle
call SetUnitFlyHeight(tab.unit[50+ii],s,s)
set tab.real[70+ii] = s
//
set tab.lightning[30+ii] = AddLightning(M_ALT,true,x,y,xx,yy)
set tab.lightning[40+ii] = AddLightning(O_ALT,true,x,y,xx,yy)
set tab.lightning[60+ii] = AddLightning(E_ALT,true,x,y,xx,yy)
//
//
set ii = ii - 1
endloop
//
set angle = 0.
set s = 0.
//
call TimerStart(NewTimerEx(this),PERIODIC,true,function thistype.onPeriodic)
//
endmethod
static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(SPELL_ID,function thistype.onCast)
endmethod
endstruct
endlibrary[/HIDDEN]
library LightningStormPlugin requires TimerUtils,xedamage
//
globals
private constant real PERIODIC = 0.031250000
endglobals
//
struct RLPLLS
//
unit c
unit dummy
//
lightning l
//
real xx
real yy
real an
real s
real reach
real in
real dam
real cos
real sin
real sp
real dr
//
string ef
//
xedamage xed
//
//PLUGIN OF STORM LIGHTNING
static method periodicPlugin takes nothing returns nothing
//
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
//
local real x
local real y
//
if an > 0. then
//
set an = an - in
//
set reach = reach + sp
//
set x = xx + reach * cos
set y = yy + reach * sin
//
call MoveLightningEx(l,true,xx,yy,s,x,y,an)
//
else
//
call ReleaseTimer(t)
//
set x = xx + reach * cos
set y = yy + reach * sin
//
call xed.damageAOE(c,x,y,dr,dam)
call DestroyEffect(AddSpecialEffect(ef,x,y))
//
call DestroyLightning(l)
set l = null
set dummy = null
set c = null
call xed.destroy()
call destroy()
endif
//
set t = null
//
endmethod
static method add takes string lightningmodel,string effe,unit caster,unit attach,real damage,real dis,real damageradius,real speed,attacktype a,damagetype dd,weapontype w returns nothing
local thistype this = allocate()
//
set c = caster
set ef = effe
set dummy = attach
set dam = damage
set sp = speed
set reach = 0.
set an = GetRandomReal(0,360)
set s = GetUnitFlyHeight(dummy)
set in = s/dis*sp
set l = AddLightning(lightningmodel,true,GetUnitX(dummy),GetUnitY(dummy),GetUnitX(dummy),GetUnitY(dummy))
set xx = GetUnitX(dummy)
set yy = GetUnitY(dummy)
set cos = Cos(an*0.0174533)
set sin = Sin(an*0.0174533)
set dr = damageradius
set an = s
//
set xed = xedamage.create()
set xed.dtype = dd
set xed.atype = a
set xed.wtype = w
set xed.damageEnemies = true
set xed.damageTrees = true
//
call TimerStart(NewTimerEx(this),PERIODIC,true,function thistype.periodicPlugin)
//
endmethod
//
endstruct
//
endlibrary