Moderator
M
Moderator
15:30, 23rd Aug 2013
PurgeandFire: Approved and recommended. An cool-looking, lightning-tastic spell.
PurgeandFire: Approved and recommended. An cool-looking, lightning-tastic spell.
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
//*************************************************************************************
// E L E C T R I C W A L L S
// - Spell Create By:
// + Elphis
//*************************************************************************************
library ElectricWalls /*
*/ 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/
// -*/ SJS /* Spell staus library
// -*/ xebasic /* http://www.wc3c.net/showthread.php?t=101150
// -*/ xedamage /* http://www.wc3c.net/showthread.php?t=101150
// -*/ xecast /* http://www.wc3c.net/showthread.php?t=101150
// -*/ Table /* http://www.wc3c.net/showthread.php?t=101246 */
//*************************************************************************************
// - Spell Information:
// - Create a lightning walls, but this walls does'nt block, this walls will protect all allies in 600 AOE
// and chain lightning deals 15/30/45/60 damage to all enemies coming, when enemies nearly walls, this walls
// will make emeies paralysis in 4 seconds last 7/8/9/10 seconds
// //****************************NOTIICE****************************
// //- Damage chain lightning, you can change it in Object -> Ability -> Chain Lightning -> Change Damage per Target
// //***************************************************************
//*************************************************************************************
// - Installation:
// - Import/copy the required libraries and Electric Walls code to your map
// - Import/copy the custom ability and unit to your map and change the SPELL_ID, ABI_SLOW_ID, ABI_CHAIN_ID if needed
// - You may view the raw ID of the objects by pressing CTRL+D in the object editor
// - You may play with the configurables below
//*************************************************************************************
//
globals
//==================================CONFIGURABLES=============================================//
//Spell rawcode, change if needed
private constant integer SPELL_ID = 'A000'
//Ability slow rawcode, change if needed
private constant integer ABI_SLOW_ID = 'A001'
//Ability chain lightning rawcode, change if needed
private constant integer ABI_CHAIN_ID = 'A002'
//Orb of lightning created count
private constant integer ORB_OF_LIGHTNING_C = 5
//Periodic Timer
private constant real LOOP_TIMER = 0.031250
//Height per orb of lightning create
private constant real ORB_PER_HEIGHT = 100.
//Orb angle
private constant real ORB_ANGLE = -90.
//Orb column distance between
private constant real ORB_COLUMN = 400.
//Laser orb move speed
private constant real ORB_LASER_SPEED = 7.
//Height of first orb
private constant real ORB_HEIGHT_BASE = 100.
//Orb duration
private constant real ORB_DURATION = 10.
//This value is optional (Effect Only)
private constant real SAFE_TIMER = 2.
//This value is optional (Effect Only)
private constant real ORB_TIMER = 0.7
//Orb Slow and Damage Radius
private constant real ORB_SLOW_RADIUS = 200.
//Orb Slow and Damage Radius
private constant real ORB_CHAIN_LIGHTNING_R = 600.
//Damage per target when enemies come nearly electic walls
private constant real DAMAGE_PER_TARGET = 15.
//---------------------------ORB COLOR---------------------------
//Red color of orb
private constant integer ORB_RED = 255
//Green color of orb
private constant integer ORB_GREEN = 255
//Blue color of orb
private constant integer ORB_BLUE = 0
//Orb alpha
private constant integer ORB_ALPHA = 255
//Orb casting ability intevar, decrease if you want to dummies cast faster
private constant real ORB_CAST_INTEVAR = 0.3
//Model orb of lightning
private constant string ORB_MODEL = "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"
//Attach model orb
private constant string ORB_ATTACH = "origin"
//Order of Slow
private constant string SLOW_ORDER = "slow"
//Order of Chain Lightning
private constant string CHAIN_LIGHTNING_ORDER = "chainlightning"
//
private constant attacktype ATTACKTYPE = ATTACK_TYPE_HERO
private constant damagetype DAMAGETYPE = DAMAGE_TYPE_COLD
private constant weapontype WEAPONTYPE = WEAPON_TYPE_METAL_HEAVY_BASH
// NON-CONFIGURABLES
private constant group GROUP = CreateGroup()
//==================================CONFIGURABLES=============================================//
//
endglobals
//
struct ElectricWalls
//Table
Table dummy
//
real tarx
real tary
boolean fade
real reach
real facing
real duration
real intevar
real dam
real offsetx
real offsety
player p
//xe
xecast xec
xedamage xed
//
//Duration of Orb
static method onDuration takes unit u returns real
return ORB_DURATION + GetUnitAbilityLevel(u,SPELL_ID)
endmethod
//Damage per target
static method onDamage takes unit u returns real
return DAMAGE_PER_TARGET * GetUnitAbilityLevel(u,SPELL_ID)
endmethod
//Check Enemies
static method filterUnit takes unit caster, unit u returns boolean
return /*
*/ IsUnitEnemy(u, GetOwningPlayer(caster)) and /* Target is an enemy of caster
*/ not IsUnitType(u, UNIT_TYPE_DEAD) and GetUnitTypeId(u) != 0 and /* Target is alive
*/ not IsUnitType(u, UNIT_TYPE_STRUCTURE) /* Target is not a structure
*/
endmethod
//Periodic, call every times
static method onPeriodic takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local real x
local real y
local unit f
local unit d
local integer i = 0
//
if not fade then
set reach = reach + ORB_LASER_SPEED
if reach >= ORB_COLUMN then
set fade = true
endif
else
set reach = reach - ORB_LASER_SPEED
if reach <= 0 then
set fade = false
endif
endif
//
//This loop make all dummies moving
loop
//
exitwhen i >= ORB_OF_LIGHTNING_C
//
if not fade then
set x = GetUnitX(dummy.unit[i]) + offsetx
set y = GetUnitY(dummy.unit[i]) + offsety
call SetUnitPosition(dummy.unit[i],x,y)
else
set x = GetUnitX(dummy.unit[i]) - offsetx
set y = GetUnitY(dummy.unit[i]) - offsety
call SetUnitPosition(dummy.unit[i],x,y)
endif
set i = i + 1
//
endloop
//
if intevar < ORB_CAST_INTEVAR then //Intevar increase per seconds before dummies cast
set intevar = intevar + LOOP_TIMER
else
//
set intevar = 0
// //Begin make dummies casting ability
call GroupEnumUnitsInRange(GROUP,x,y,ORB_CHAIN_LIGHTNING_R,null)
loop
set f = FirstOfGroup(GROUP)
exitwhen f == null
//
set d = dummy.unit[GetRandomInt(0,ORB_OF_LIGHTNING_C)]
//
if not IsUnitInRange(dummy.unit[0],f,ORB_SLOW_RADIUS) and filterUnit(dummy.unit[0],f) then
//if enemies not in range of ORB_SLOW_RADIUS dummies will casting chain lightning/deals damage to enemies
if d != null then
set x = GetUnitX(d)
set y = GetUnitY(d)
set xec.abilityid = ABI_CHAIN_ID
set xec.orderstring = CHAIN_LIGHTNING_ORDER
call xed.damageTarget(d,f,dam)
endif
else
//if enemies in range of ORB_SLOW_RADIUS dummies will casting slow but no damage deals to enemies
set xec.abilityid = ABI_SLOW_ID
set xec.orderstring = SLOW_ORDER
endif
//
call xec.setSourcePoint(x,y,GetUnitFlyHeight(d))
call xec.castOnTarget(f)
//
call GroupRemoveUnit(GROUP,f)
endloop
//
endif
//
if IsUnitType(dummy.unit[0],UNIT_TYPE_DEAD) and GetUnitTypeId(dummy.unit[0]) != 0 then
//Destroy Leaks....
call ReleaseTimer(t)
call xec.destroy()
call xed.destroy()
set p = null
call dummy.destroy()
call destroy()
endif
endmethod
//Setup spell if any unit casting this ability
static method onCast takes nothing returns nothing
local thistype this = allocate()
//unit
local unit u = GetTriggerUnit()
//real
local unit d
local unit d1
local real h = ORB_HEIGHT_BASE
local real f = GetUnitFacing(u)
local real tarx = GetSpellTargetX()
local real tary = GetSpellTargetY()
local real o = tarx + ORB_COLUMN * Cos((f+ORB_ANGLE)*0.01747)
local real z = tary + ORB_COLUMN * Sin((f+ORB_ANGLE)*0.01747)
//integer
local integer i = 0
local integer abilevel = GetUnitAbilityLevel(u,SPELL_ID) //Check ability level of caster
//Begin config spell ability
set dummy = Table.create() //install Table
set duration = onDuration(u) //Check duration of orb per level of caster
set intevar = 0
set p = GetTriggerPlayer()
set fade = false
set reach = 0
set dam = onDamage(u)
//Xe install
set xec = xecast.create()
set xec.owningplayer = p
set xec.level = abilevel
set xec.recycledelay = 1.
//
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 = false
//Begin run spell ability
loop
//
exitwhen i >= ORB_OF_LIGHTNING_C
//
//
set d = CreateUnit(p,'xeca',tarx,tary,0.)
//Dummies call
set dummy.unit[i] = CreateUnit(p,XE_DUMMY_UNITID,tarx,tary,0.)
call J.Jumping(0.,true,duration-SAFE_TIMER,dummy.unit[i],h,"","",false,false,true,0.)
call CreateDelayedEffectTarget(ORB_MODEL,dummy.unit[i],ORB_ATTACH,0.,duration-SAFE_TIMER+ORB_TIMER)
call SetUnitVertexColor(dummy.unit[i],ORB_RED,ORB_GREEN,ORB_BLUE,ORB_ALPHA)
//
set d1 = CreateUnit(p,XE_DUMMY_UNITID,o,z,ORB_ANGLE)
set facing = Angle(GetUnitX(dummy.unit[i]),GetUnitY(dummy.unit[i]),o,z)
call LL.LLSU(0.,d,d1,"CLPB",duration-SAFE_TIMER+ORB_TIMER)
call J.Jumping(0.,true,duration-SAFE_TIMER,d,h,"","",false,false,false,0.)
call J.Jumping(0.,true,duration-SAFE_TIMER,d1,h,"","",false,false,false,0.)
call CreateDelayedEffectTarget(ORB_MODEL,d,ORB_ATTACH,0.,duration-SAFE_TIMER+ORB_TIMER)
call CreateDelayedEffectTarget(ORB_MODEL,d1,ORB_ATTACH,0.,duration-SAFE_TIMER+ORB_TIMER)
//Increase height per orb
set h = h + ORB_PER_HEIGHT
//
set i = i + 1
endloop
//
//Set dummies move angle
set offsetx = ORB_LASER_SPEED * Cos(facing*0.01747)
set offsety = ORB_LASER_SPEED * Sin(facing*0.01747)
//
//Remove varriables
set d = null
set d1 = null
set u = null
//
call TimerStart(NewTimerEx(this),LOOP_TIMER,true,function thistype.onPeriodic)
endmethod
//
static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(SPELL_ID,function thistype.onCast)
endmethod
//
endstruct
endlibrary
[/HIDDEN]
//! zinc
//
library SJS requires TimerUtils,AaD
{
constant real time = .032;
public struct J
{
real Fly;
real Dis;
real ins;
boolean kill;
unit U;
real High;
real d;
real Highsettings;
real Timer;
boolean Ag;
real ag;
boolean Jumpag;
boolean rem;
string EfEnd;
//
real savehigh;
boolean blockhig;
real timeblocking;
//
static method onLoopJ()
{
thistype this = GetTimerData(GetExpiredTimer());
if(IsUnitType(U, UNIT_TYPE_DEAD) != true && GetUnitTypeId(U) != 0)
{
if(d > 0)
d = d - time;
else
{
if (Fly > 0)
{
if(Fly >= savehigh)
{
Timer = Timer + 180/(Dis / 30.);
Fly = Sin(Timer*bj_DEGTORAD)*Highsettings*1.3;
if(blockhig && Fly > savehigh)
savehigh = Fly;
if (Ag == false)
SetUnitFlyHeight(U,Fly,0.);
else
SetUnitFlyHeight(U,Fly/ag,0.);
}
else
{
if(timeblocking > 0)
timeblocking = timeblocking - .032500000;
else
{
blockhig = false;
savehigh = 0.;
}
}
}
else
if (Jumpag == true)
{
Ag = true;
ag = ag + 1;
Fly = 1.;
Timer = 1.;
if (ag > 3.)
{
if(kill && !rem)
KillUnit(U);
if(!kill && rem && ins <= 0)
RemoveUnit(U);
if(!kill && rem && ins > 0)
Dum.Remove(U,ins);
UnitAddAbility(U,'Amrf');
UnitRemoveAbility(U,'Amrf');
SetUnitFlyHeight(U,0.,GetUnitDefaultFlyHeight(U));
DestroyEffect(AddSpecialEffect(EfEnd,GetUnitX(U),GetUnitY(U)));
U = null;
EfEnd = null;
ReleaseTimer(GetExpiredTimer());
destroy();
}
}
else
{
if(kill && !rem)
KillUnit(U);
if(!kill && rem && ins <= 0)
RemoveUnit(U);
if(!kill && rem && ins > 0)
Dum.Remove(U,ins);
UnitAddAbility(U,'Amrf');
UnitRemoveAbility(U,'Amrf');
SetUnitFlyHeight(U,0.,GetUnitDefaultFlyHeight(U));
DestroyEffect(AddSpecialEffect(EfEnd,GetUnitX(U),GetUnitY(U)));
U = null;
EfEnd = null;
ReleaseTimer(GetExpiredTimer());
destroy();
}
}
}
else
{
if(kill && !rem)
KillUnit(U);
if(!kill && rem && ins <= 0)
RemoveUnit(U);
if(!kill && rem && ins > 0)
Dum.Remove(U,ins);
UnitAddAbility(U,'Amrf');
UnitRemoveAbility(U,'Amrf');
SetUnitFlyHeight(U,0.,GetUnitDefaultFlyHeight(U));
U = null;
EfEnd = null;
ReleaseTimer(GetExpiredTimer());
destroy();
}
}
//
static method Jumping(real delay,boolean blockhe,real pauhe,unit wunit,real hei,string XJ,string EJ,boolean jumpags,boolean rems,boolean kills,real inss)
{
thistype this;
if(IsUnitType(wunit, UNIT_TYPE_DEAD) != true && GetUnitTypeId(wunit) != 0 && GetUnitFlyHeight(wunit) <= GetUnitDefaultFlyHeight(wunit)+10)
{
this = allocate();
U = wunit;
Timer = 0.;
Fly = 1.;
blockhig = blockhe;
timeblocking = pauhe;
ins = inss;
d = delay;
rem = rems;
kill = kills;
Dis = hei;
savehigh = 0.;
Jumpag = jumpags;
Ag = false;
ag = 0.5;
EfEnd = EJ;
DestroyEffect(AddSpecialEffect(XJ,GetUnitX(U),GetUnitY(U)));
High = 0.4;
Highsettings = Dis*High;
UnitAddAbility(U,'Amrf');
UnitRemoveAbility(U,'Amrf');
TimerStart(NewTimerEx(this),.032500000,true,function thistype.onLoopJ);
}
}
}
}
//
library AaD
{
public function Distance(real xa,real ya,real xb,real yb) -> real
{
real dx = xb - xa;
real dy = yb - ya;
return SquareRoot(dx * dx + dy * dy);
}
//
public function Angle(real xa,real ya,real xb,real yb) -> real
{
return bj_RADTODEG * Atan2(yb - ya, xb - xa);
}
}
//
library DummRemove requires TimerUtils
{
public struct Dum
{
unit u;
//
static method Loop()
{
thistype this = GetTimerData(GetExpiredTimer());
RemoveUnit(u);
u = null;
ReleaseTimer(GetExpiredTimer());
destroy();
}
//
static method Remove(unit whatunit,real dura) -> unit
{
thistype this = allocate();
u = whatunit;
TimerStart(NewTimerEx(this),dura,false,function thistype.Loop);
return whatunit;
}
}
}
//
library Linked requires TimerUtils
{
public struct LL
{
unit u;
unit tg;
lightning l;
boolean linked;
real time;
real x;
real y;
real w;
//
static method onPeriodic()
{
thistype this = GetTimerData(GetExpiredTimer());
boolean release = false;
//
if(w > 0)
w = w - .04;
else
{
if(!linked)
{
if(IsUnitType(u,UNIT_TYPE_DEAD) != true && GetUnitTypeId(u) != 0)
MoveLightningEx(l,true,GetUnitX(u),GetUnitY(u),GetUnitFlyHeight(u),x,y,0.);
else
release = true;
}
else
{
if(IsUnitType(u,UNIT_TYPE_DEAD) != true && GetUnitTypeId(u) != 0 && IsUnitType(tg,UNIT_TYPE_DEAD) != true && GetUnitTypeId(tg) != 0)
MoveLightningEx(l,true,GetUnitX(u),GetUnitY(u),GetUnitFlyHeight(u),GetUnitX(tg),GetUnitY(tg),GetUnitFlyHeight(tg));
else
release = true;
}
//
if(time > 0)
time = time - .04;
else
release = true;
//
}
//
if(release)
{
DestroyLightning(l);
ReleaseTimer(GetExpiredTimer());
u = null;
destroy();
}
}
//
static method LLSU(real wait,unit us,unit tgs,string ls,real times)
{
thistype this = allocate();
u = us;
tg = tgs;
time = times;
w = wait;
linked = true;
l = AddLightning(ls,true,GetUnitX(u),GetUnitY(u),x,y);
TimerStart(NewTimerEx(this),.04,true,function thistype.onPeriodic);
}
}
}
//! endzinc[/HIDDEN]