Moderator
M
Moderator
Vortex Lightning v1.3 | Reviewed by Maker | 15th Oct 2013 | ||||
APPROVED | ||||
|
[TD]
|
|
[/td]
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
// V O R T E X L I G H T N I N G
// - Spell Create By:
// + Elphis
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
library VortexLightning /*
*/ requires /*
// -*/ CTL /* http://www.wc3c.net/showthread.php?t=101322
// -*/ SpellEffectEvent /* http://www.hiveworkshop.com/forums/jass-resources-412/snippet-spelleffectevent-187193/
// -*/ Table /* http://www.wc3c.net/showthread.php?t=101246
// -*/ IsDestructableTree /* http://www.wc3c.net/showthread.php?t=103927
// -*/ RLPluginVL /* Spell Plugin
// -*/ DOTPluginVL /* Spell Plugin
// -*/ RLPluginVL /* Spell Plugin */
// Optional:
// NuclearExplosion.mdx - http://www.hiveworkshop.com/forums/models-530/nuclearexplosion-51829/?prev=search%3DNuclear%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:
// - Use power of the earth, calling a powerful vortex of lightning accumulation in the soil and launched on ground
// spending a little time to make power, when done, it release a powerful lightning discharge on ground
// when enemies within 100 range it will shock enemies
// and deals 50/100/150/200 damage, when electric release 50/60/70/80 lightning
// this vortex will causes an explotion deals 50 damage to enemies unit and destructable around
// 500 range in 5 seconds.
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
// - Installation:
// - Import/copy the required libraries and Vortex Lightning code to your map
// - Import/copy the custom ability and unit to your map and change the SPELL_ID if needed
// - Export model NuclearExplosion.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
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//================================CONFIGURABLE================================
globals
//==============================SPELL SETTINGS========================================
//Spell rawcode, change if needed
private constant integer SPELL_ID = 'A000'
//Dummy rawcode, change if needed
private constant integer LIGHTNING_DUMMY = 'e000'
//Periodic of spell
public constant real PERIODIC = .031250000
//========================================================================
////////////////////////////////////////////////////////////////////////////////////////////
//Count of lightning release (Spell expire when reach this count)
private constant integer L_R_COUNT = 5
//Color of lightning increase per periodic
private constant integer COLOR_INC = 5
//Max distance when lightning release
private constant real MAX_DISTANCE = 1000.
//Min distance when lightning release
private constant real MIN_DISTANCE = 500.
//Max distance of vortex lightning
private constant real ORB_M_DISTANCE = 500.
//Distance increase per periodic
private constant real ORB_REACH = 5.
//Lightning powerful center size
private constant real CENTER_SIZE = 3.
//Size increase of center lightning per periodic
private constant real CENTER_SIZE_INC = 0.2
//Lightning release speed outside
private constant real RELEASE_SPEED = 10.
//Range hit enemies, don't increase this value too much because it very powerful
private constant real WIHTHIN_RANGE = 100.
//Lightning release intevar
private constant real RELEASE_INTEVAR = 0.1
//Damage when release lightning hit enemies unit
private constant real DAMAGE_BASE = 50.
//Damage fire deals to enemies unit within range of explotion
private constant real DAMAGE_FIRE = 50.
//Duration of fire damage to enemies unit and destructable
private constant real FIRE_DURATION = 5.
//Model of lightning vortex
private constant string MODEL = "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"
//Effect causes explore when lightning reach max distance
private constant string EXPLORE_MODEL = "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl"
//Explotion model when spell expire
private constant string M_EXPLOTION = "war3mapImported\\NuclearExplosion.mdx"
//Fire effect to enemies unit and destructable
private constant string FIRE_EFFECT = "Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeDamageTarget.mdl"
//Lightning attachment
private constant string ATTACH = "origin"
//Enemies attachment
private constant string ENE_ATTACH = "chest"
//Vortex lightning model
private constant string LIGHTNING_ALT = "DRAM"
//Release lightning model
private constant string L_RELEASE = "CLPB"
// ======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
// ======NON CONFIGURATION======
private constant group G = CreateGroup()
private rect RECT = Rect(0, 0, 0, 0)
//
endglobals
//
private struct VortexLightning extends array
//
player p
//
unit caster
unit dummy
//
real damage
real xx
real yy
real an
real reach
real sinc
real in
//
integer cl
integer count
//Table Installing
Table tab
//This function deals damage to destructable
static method damageDestructable takes nothing returns boolean
local destructable dummy = GetFilterDestructable()
//
if IsDestructableTree(dummy) then
call DDPluginVL.add(dummy,FIRE_EFFECT,DAMAGE_FIRE,FIRE_DURATION,1.)
endif
//
set dummy = null
//
return false
endmethod
//
static method onCount takes unit caster returns integer
return L_R_COUNT+GetUnitAbilityLevel(caster,SPELL_ID)*10 // Total count of vortex discharge lightning
endmethod
//
static method onDamage takes unit caster returns real
return DAMAGE_BASE*GetUnitAbilityLevel(caster,SPELL_ID) // Damage of lightning when hit enemies unit
endmethod
//
implement CTL
local integer i = 0
local real x
local real y
local real dd
local unit f
implement CTLExpire
//
set an = an + 5.
//
loop
exitwhen i > 10
//
set x = xx + reach * Cos((tab.real[10+i]+an)*0.01747)
set y = yy + reach * Sin((tab.real[10+i]+an)*0.01747)
//
call SetUnitX(tab.unit[i],x)
call SetUnitY(tab.unit[i],y)
//
call SetUnitVertexColor(tab.unit[i],cl,cl,cl,cl)
//
call MoveLightning(tab.lightning[20+i],true,x,y,xx,yy)
//
set i = i + 1
endloop
set i = 0
//
if count > 0 then
if reach < ORB_M_DISTANCE then
set reach = reach + ORB_REACH
else
//
if cl < 255 then
set cl = cl + COLOR_INC
elseif sinc < CENTER_SIZE then
set sinc = sinc + CENTER_SIZE_INC
call SetUnitScale(dummy,sinc,0.,0.)
else
if in < RELEASE_INTEVAR then
set in = in + PERIODIC
else
//
set in = 0.
//
set dd = GetRandomReal(MIN_DISTANCE,MAX_DISTANCE)
//
set count = count - 1
//This line release lightning
call RLPluginVL.add(caster,xx,yy,RELEASE_SPEED,damage,dd,WIHTHIN_RANGE,L_RELEASE,EXPLORE_MODEL,ATTACKTYPE,DAMAGETYPE,WEAPONTYPE)
endif
endif
endif
else
//
if reach > 0. then
//
set reach = reach - ORB_REACH
//
loop
exitwhen i > 10
//
set x = xx + reach * Cos((tab.real[10+i]+an)*0.01747)
set y = yy + reach * Sin((tab.real[10+i]+an)*0.01747)
//
call SetUnitX(tab.unit[i],x)
call SetUnitY(tab.unit[i],y)
//
call MoveLightning(tab.lightning[20+i],true,x,y,xx,yy)
//
set i = i + 1
endloop
elseif sinc > 0 then
set sinc = sinc - CENTER_SIZE_INC*2
//
call SetUnitScale(dummy,sinc,0.,0.)
//
set i = 0
//
loop
exitwhen i > 10
//
call SetUnitScale(tab.unit[i],sinc,0.,0.)
//
set i = i + 1
endloop
else
//Enum destructable
call SetRect(RECT, xx-ORB_M_DISTANCE, yy-ORB_M_DISTANCE, xx+ORB_M_DISTANCE, yy+ORB_M_DISTANCE)
//
call GroupEnumUnitsInRect(G,RECT,null)
loop
set f = FirstOfGroup(G)
exitwhen f == null
if IsUnitEnemy(f,p) or not IsUnitType(f,UNIT_TYPE_DEAD) then
//This line deals damage to enemies
call DOTPluginVL.add(caster,f,FIRE_EFFECT,ENE_ATTACH,DAMAGE_FIRE,FIRE_DURATION,1.,ATTACKTYPE,DAMAGETYPE,WEAPONTYPE)
endif
call GroupRemoveUnit(G,f)
endloop
//
call EnumDestructablesInRect(RECT,function thistype.damageDestructable,null)
//
set i = 0
//
loop
exitwhen i > 10
//
call DestroyLightning(tab.lightning[20+i])
call DestroyEffect(tab.effect[30+i])
call RemoveUnit(tab.unit[i])
//
set tab.unit[i] = null
set tab.lightning[20+i] = null
set tab.effect[30+i] = null
//
set i = i + 1
endloop
//
call DestroyEffect(AddSpecialEffect(M_EXPLOTION,xx,yy))
//
call RemoveUnit(dummy)
//
call tab.flush()
call tab.destroy()
//
set caster = null
set dummy = null
set p = null
//
call destroy()
//
endif
//
endif
//
implement CTLEnd
static method onCast takes nothing returns boolean
local thistype this = create()
local integer i = 0
local real x
local real y
//
set caster = GetTriggerUnit()
set p = GetTriggerPlayer()
//
set xx = GetSpellTargetX()
set yy = GetSpellTargetY()
set damage = onDamage(caster)
set count = onCount(caster)
set an = 0.
set reach = 0.
set sinc = 0.
set in = 0.
set cl = 0
//Table create
set tab = Table.create()
//
loop
exitwhen i > 10
//
set x = xx + 100. * Cos(0.01747*i*36)
set y = yy + 100. * Sin(0.01747*i*36)
//
set tab.unit[i] = CreateUnit(p,LIGHTNING_DUMMY,x,y,0.)
set tab.real[10+i] = 57.29582 * Atan2(y - yy, x - xx)
set tab.lightning[20+i] = AddLightning(LIGHTNING_ALT,true,x,y,xx,yy)
set tab.effect[30+i] = AddSpecialEffectTarget(MODEL,tab.unit[i],ATTACH)
call SetUnitVertexColor(tab.unit[i],0,0,0,0)
//
set i = i + 1
endloop
//
set dummy = CreateUnit(p,LIGHTNING_DUMMY,xx,yy,0.)
call SetUnitScale(dummy,0.,0.,0.)
//
return false
endmethod
static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(SPELL_ID,function thistype.onCast)
endmethod
//
endstruct
//
endlibrary
library RSEPluginVL requires CTL
struct RSEPluginVL
effect e
unit c = null
destructable d
real time
implement CTLExpire
if c != null then
if time < 0. or IsUnitType(c,UNIT_TYPE_DEAD) or GetUnitTypeId(c) == 0 then
call DestroyEffect(e)
set e = null
set c = null
call destroy()
else
set time = time - VortexLightning_PERIODIC
endif
else
if time < 0. or GetWidgetLife(d) < 0.425 then
call DestroyEffect(e)
set e = null
set d = null
call destroy()
else
set time = time - VortexLightning_PERIODIC
endif
endif
implement CTLEnd
static method addTarget takes unit u,string eff,string attach,real dur returns nothing
local thistype this = create()
set c = u
set e = AddSpecialEffectTarget(eff,c,attach)
set time = dur
endmethod
static method addPoint takes string eff,destructable des,real x,real y,real dur returns nothing
local thistype this
set e = AddSpecialEffect(eff,x,y)
set d = des
set time = dur
endmethod
endstruct
endlibrary
library RLPluginVL requires CTL
//
globals
//
private constant group G = CreateGroup()
//
endglobals
//
struct RLPluginVL
unit c
//
player p
//
real reach
real maxdis
real damage
real within
real speed
real xx
real yy
real angle
//
string ef
//
attacktype attack
damagetype dam
weapontype weapon
//
lightning ll
//
implement CTL
//
local real x
local real y
local unit f
//
implement CTLExpire
if reach < maxdis and speed > 0 then
set reach = reach + speed
//
set x = xx + reach * Cos(angle*0.01747)
set y = yy + reach * Sin(angle*0.01747)
//
call MoveLightning(ll,true,x,y,xx,yy)
//
call GroupEnumUnitsInRange(G,x,y,within,null)
loop
set f = FirstOfGroup(G)
exitwhen f == null
if IsUnitEnemy(f,p) and not IsUnitType(f,UNIT_TYPE_DEAD) or GetUnitTypeId(f) != 0 then
set speed = -1
call UnitDamageTarget(c,f,damage,true,false,attack,dam,weapon)
endif
call GroupRemoveUnit(G,f)
endloop
else
set x = xx + reach * Cos(angle*0.01747)
set y = yy + reach * Sin(angle*0.01747)
call DestroyEffect(AddSpecialEffect(ef,x,y))
call DestroyLightning(ll)
set ll = null
set c = null
set p = null
set attack = null
set weapon = null
set dam = null
call destroy()
endif
implement CTLNull
implement CTLEnd
public static method add takes unit caster,real x,real y,real sp,real da,real dis,real hit,string l,string eff,attacktype a,damagetype d,weapontype w returns nothing
//
local thistype this = create()
//
set c = caster
set p = GetOwningPlayer(c)
set maxdis = dis
set within = hit
set damage = da
set speed = sp
set ef = eff
set xx = x
set yy = y
set ll = AddLightning(l,true,xx,yy,xx,yy)
set angle = GetRandomReal(0,360)
set reach = 0.
//
set attack = a
set dam = d
set weapon = w
//
endmethod
endstruct
endlibrary
library DDPluginVL requires RSEPluginVL,CTL
struct DDPluginVL
//
destructable d
//
real ti
real dmg
real intevar = 0.
real time
//
implement CTLExpire
//
if ti > 0. or GetWidgetLife(d) > 0.425 then
set ti = ti - VortexLightning_PERIODIC
if intevar < time then
set intevar = intevar + VortexLightning_PERIODIC
else
set intevar = 0.
call SetWidgetLife(d,GetWidgetLife(d)-dmg)
endif
else
set d = null
call destroy()
endif
//
implement CTLEnd
static method add takes destructable dest, string eff,real damage,real duration,real periodic returns nothing
//
local thistype this = create()
//
set d = dest
set dmg = damage
call RSEPluginVL.addPoint(eff,dest,GetDestructableX(d),GetDestructableY(d),duration)
set ti = duration
set time = periodic
//
endmethod
endstruct
//
endlibrary
library DOTPluginVL requires RSEPluginVL,CTL
struct DOTPluginVL
//
unit c
unit d
//
real ti
real dmg
real intevar = 0.
real time
//
attacktype att
damagetype dam
weapontype wea
//
implement CTLExpire
//
if ti < 0. or IsUnitType(d,UNIT_TYPE_DEAD) or GetUnitTypeId(d) == 0 then
set d = null
set c = null
call destroy()
else
set ti = ti - VortexLightning_PERIODIC
endif
//
if intevar < time then
set intevar = intevar + VortexLightning_PERIODIC
else
set intevar = 0.
call UnitDamageTarget(c,d,dmg,true,false,att,dam,wea)
endif
//
implement CTLEnd
static method add takes unit caster,unit target, string eff,string attach,real damage,real duration,real periodic,attacktype a,damagetype dd,weapontype w returns nothing
//
local thistype this = create()
//
set c = caster
set d = target
set dmg = damage
set att = a
set dam = dd
set wea = w
call RSEPluginVL.addTarget(d,eff,attach,duration)
set ti = duration
set time = periodic
//
endmethod
endstruct
//
endlibrary