Moderator
M
Moderator
23:35, 7th Aug 2013
PurgeandFire: Approved and recommended! Very pretty, eye-catching spell.
PurgeandFire: Approved and recommended! Very pretty, eye-catching spell.
//*******************************************************************
//******************D*E*V*I*L**B*L*A*C*K**H*O*L*E********************
//*****************Requires:
// - SimpleJumpSystem
// - UnitScale
// - xebasic - http://www.wc3c.net/showthread.php?t=101150
// - TimerUtils - http://www.wc3c.net/showthread.php?t=101322
// - DelDX - 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
//*****************Optional:
// - xebasic - http://www.wc3c.net/showthread.php?t=101150
// - SpellEffectEvent - http://www.hiveworkshop.com/forums/jass-resources-412/snippet-spelleffectevent-187193/
//**********Spell Create By:
// - Elphis
//********Spell Information:
// - Pull all enemies into devil black hole, enemies can go inside black hole but can't not run out of black hole
// and it call some black/fire missle slash to that enemies.
// - Level 1: Deals 4 damage/slash and hole will destroy when size = 4
// - Level 2: Deals 6 damage/slash and hole will destroy when size = 5
// - Level 3: Deals 8 damage/slash and hole will destroy when size = 6
// - Level 4: Deals 10 damage/slash and hole will destroy when size = 7
//*************Installation:
// - Import/copy the required libraries and Black Hole code to your map
// - Import/copy the custom ability and unit to your map and change the SPELL_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
//*******************************************************************
//*******************************************************************
//*******************************************************************
library DevilBlackHole uses SJS,UnitScale,AaD,TimerUtils,DelFX optional xebasic,SpellEffectEvent
globals
//============================CONFIGURABLES============================================================//
//Missle slash count
private constant integer COUNT_BLACK_MISSLE = 6
//Rawcode of spell
private constant integer SPELL_ID = 'A000'
//Time of every timer run
private constant real LOOP_TIMER = .05
//Base limit size of Black hole
private constant real SIZE_EXPLORE = 3.
//Area of Effect
private constant real AOE = 2000.
//Range of Block unit pass through
private constant real BLOCK_UNIT_AOE = 300.
//Size of black hole increase every timer runing
private constant real SIZE_INCREASE = .05
//Pull speed
private constant real PULL_SPEED = 10.
//Damage radius every missle slashed
private constant real DAMAGE_RADIUS = 100.
//Speed of missle slash
private constant real SPEED_AROUND = 15.
//Base damage deals to enemy every missle slashed
private constant real BASE_DAMAGE = 2.
//Explore all unit in AOE speed
private constant real SPEED_EXPLORE_AOE = 50.
//This value is optional of missle slash
private constant real SAFE_HOLE = 1.
//Distance explore when black hole destroyed
private constant real EXPLORE_UNIT_AOE = 600.
//Hole destroying speed
private constant real HOLE_DESTROY = 15.
//Black Hole model
private constant string HOLE = "BlackHOLE.mdl"
//Effect of black hole combine
private constant string HOLE_EFFECT = "Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeTarget.mdl"
//Missle slash Model
private constant string BLACK_MISSLE = "Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl"
//Explore Effect
private constant string EXPLORE = "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl"
//Fire effect when missle slash every time
private constant string EXPLORE_FIRE = "Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplode.mdl"
//Attachment effect of dummy
private constant string ATTACHMENT = "chest"
//Non - Configurables
private group GROUP = CreateGroup()
//============================CONFIGURABLES============================================================//
endglobals
//
//==================================DO NOT EDIT ANYTHING BELOW=======================================================//
private struct DevilBlackHole
//
unit caster
unit dummy
unit dumm
real size
real xx
real yy
real maxsize
//
static method onDamage takes unit u returns real
return BASE_DAMAGE*GetUnitAbilityLevel(u,SPELL_ID) //Damage when slashed
endmethod
static method sizeLimit takes unit u returns real
return SIZE_EXPLORE+I2R(GetUnitAbilityLevel(u,SPELL_ID)) // Size of Hole Limited
endmethod
static method filterUnit takes unit caster, unit u returns boolean
return /*
*/ IsUnitEnemy(u, GetTriggerPlayer()) 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
static method onPeriodic takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
local unit f
local real ang
local real x
local real y
//
call GroupEnumUnitsInRange(GROUP,xx,yy,AOE,null)
loop
set f = FirstOfGroup(GROUP)
exitwhen f == null
//
if filterUnit(caster,f) and IsUnitInRange(caster,f,BLOCK_UNIT_AOE) != true then
set ang = Angle(GetUnitX(f),GetUnitY(f),xx,yy)
set x = GetUnitX(f) + PULL_SPEED * Cos(ang*0.01747)
set y = GetUnitY(f) + PULL_SPEED * Sin(ang*0.01747)
call SetUnitX(f,x)
call SetUnitY(f,y)
endif
//
if filterUnit(caster,f) then
if size >= maxsize then
set ang = Angle(xx,yy,GetUnitX(f),GetUnitY(f))
set x = GetUnitX(f) + EXPLORE_UNIT_AOE * Cos(ang*0.01747)
set y = GetUnitY(f) + EXPLORE_UNIT_AOE * Sin(ang*0.01747)
call J.JumpTarget(f,x,y,SPEED_EXPLORE_AOE,EXPLORE,EXPLORE,false,false,0.)
endif
endif
//
call GroupRemoveUnit(GROUP,f)
//
endloop
//
set size = size + SIZE_INCREASE
call SetUnitScale(dummy,size,0,0)
//
if size >= maxsize then
call ReleaseTimer(GetExpiredTimer())
call USC.USCS(0.,dummy,maxsize*100,0.,HOLE_DESTROY,true,false,true,0.)
call RemoveUnit(dumm)
set dumm = null
set dummy = null
set caster = null
call destroy()
endif
//
endmethod
static method onCast takes nothing returns nothing
local thistype this = allocate()
local integer i = COUNT_BLACK_MISSLE
local unit d
local real temp = -100
local real x = GetSpellTargetX()
local real y = GetSpellTargetY()
local player p = GetTriggerPlayer()
set caster = GetTriggerUnit()
set dumm = CreateUnit(p,XE_DUMMY_UNITID,x,y,0.)
set maxsize = sizeLimit(caster)
loop
exitwhen i == 0
set temp = temp + 100.
set d = CreateUnit(p,XE_DUMMY_UNITID,x,y,0.)
call CreateDelayedEffectTarget(BLACK_MISSLE,d,ATTACHMENT,0.,maxsize)
call Effect.Around(0.,dumm,d,temp,DAMAGE_RADIUS,-SPEED_AROUND,maxsize,true,true,onDamage(caster),EXPLORE_FIRE,0.1,"")
set i = i - 1
endloop
//
set dummy = CreateUnit(Player(15),XE_DUMMY_UNITID,x,y,0.)
set xx = GetUnitX(dummy)
set yy = GetUnitY(dummy)
call CreateDelayedEffectTarget(HOLE,dummy,ATTACHMENT,0.,maxsize)
call CreateDelayedEffectTarget(HOLE_EFFECT,dummy,ATTACHMENT,0.,maxsize)
call SetUnitScale(dummy,0,0,0)
set size = 0.
set d = 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]
//I Created xe dummy by Vexorian in your Object, Just create trigger and copy this in your trigger: //! runtextmacro RunXeUnit()
//! textmacro RunXeUnit
//! external ObjectMerger w3u ewsp xeca unam "xe unit" uhpm 1 uabi Aloc,Aeth, umdl "war3mapImported\dummy.mdx" uico "ReplaceableTextures\CommandButtons\BTNtemp.blp" usid 1 usin 1 unsf "(Caster System?)" uble 0.00 ucbs 0.00 umxp 0.00 umxr 0.00 uimz 0.00 ulpz 0.00 uprw 1.00 uspa "" udty Divine umvs 522 ucol 0.00 ufoo 0 uhom 1 umpi 1000 umpm 1000 umpr 1.00 urac Commoner utyp "" ubui "" upgr "" utub "http://wc3campaigns.net/vexorian-External By Elphis" utip ""
//! endtextmacro
//---------------------------------------------
//
//
//! zinc
//
//
//---------------------------------------------
//
library SJS requires TimerUtils,AaD
{
constant real time = .032;
//
public struct J
{
real Reach;
real Fly;
real Dis;
real Angle;
real sp;
real ins;
boolean kill;
unit U;
real High;
real d;
real Highsettings;
real Timer;
boolean B;
boolean Ag;
real ag;
boolean Jumpag;
boolean rem;
string EfEnd;
//
static method onLoop()
{
real x;
real y;
thistype this = GetTimerData(GetExpiredTimer());
if(!IsUnitType(U, UNIT_TYPE_DEAD) && GetUnitTypeId(U) != 0)
{
if (Reach < Dis)
{
x = GetUnitX(U) + sp * Cos(Angle * bj_DEGTORAD);
y = GetUnitY(U) + sp * Sin(Angle * bj_DEGTORAD);
SetUnitPosition(U,x,y);
Reach = Reach + sp;
Timer = Timer + 180/(Dis / sp);
Fly = Sin(Timer*bj_DEGTORAD)*Highsettings*1.3;
SetUnitFlyHeight(U,Fly,0.);
}
else
{
if(kill && !rem)
KillUnit(U);
if(!kill && rem && ins <= 0)
RemoveUnit(U);
if(!kill && rem && ins > 0)
Dum.Remove(U,ins);
DestroyEffect(AddSpecialEffect(EfEnd,GetUnitX(U),GetUnitY(U)));
SetUnitPathing(U,true);
UnitAddAbility(U,'Amrf');
UnitRemoveAbility(U,'Amrf');
SetUnitFlyHeight(U,0.,GetUnitDefaultFlyHeight(U));
if(rem)
RemoveUnit(U);
EfEnd = null;
ReleaseTimer(GetExpiredTimer());
U = null;
destroy();
}
}
else
{
if(kill && !rem)
KillUnit(U);
if(!kill && rem && ins <= 0)
RemoveUnit(U);
if(!kill && rem && ins > 0)
Dum.Remove(U,ins);
SetUnitPathing(U,true);
UnitAddAbility(U,'Amrf');
UnitRemoveAbility(U,'Amrf');
SetUnitFlyHeight(U,0.,GetUnitDefaultFlyHeight(U));
if(rem)
RemoveUnit(U);
EfEnd = null;
ReleaseTimer(GetExpiredTimer());
U = null;
destroy();
}
}
static method JumpTarget(unit whatunit,real xj,real yj,real speed,string XJ,string EJ,boolean rems,boolean kills,real inss)
{
thistype this;
if(!IsUnitType(U, UNIT_TYPE_DEAD) && GetUnitTypeId(U) != 0)
{
this = allocate();
U = whatunit;
Reach = 0.;
Timer = 0.;
ins = inss;
rem = rems;
kill = kills;
rem = rems;
sp = speed;
Fly = 0.;
EfEnd = EJ;
Dis = Distance(GetUnitX(whatunit),GetUnitY(whatunit),xj,yj);
Angle = Angle(GetUnitX(whatunit),GetUnitY(whatunit),xj,yj);
High = .35;
Highsettings = Dis*High;
DestroyEffect(AddSpecialEffect(XJ,GetUnitX(U),GetUnitY(U)));
SetUnitPathing(U,false);
UnitAddAbility(U,'Amrf');
UnitRemoveAbility(U,'Amrf');
TimerStart(NewTimerEx(this),time,true,function thistype.onLoop);
}
}
}
}
//
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 UnitScale requires TimerUtils
{
public struct USC
{
unit u;
real s;
real sta;
real end;
real time;
boolean fade;
boolean rem;
boolean kill;
real ins;
//
static method Loop()
{
thistype this = GetTimerData(GetExpiredTimer());
if(time > 0)
time = time - .04;
else
{
SetUnitScale(u,sta*0.01,sta*0.01,sta*0.01);
if(fade)
{
sta = sta - s;
if(sta <= end)
{
if(kill && !rem)
KillUnit(u);
if(!kill && rem && ins <= 0)
RemoveUnit(u);
if(!kill && rem && ins > 0)
Dum.Remove(u,ins);
ReleaseTimer(GetExpiredTimer());
u = null;
destroy();
}
}
else
{
sta = sta + s;
if(sta > end)
{
if(kill && !rem)
KillUnit(u);
if(!kill && rem && ins <= 0)
RemoveUnit(u);
if(!kill && rem && ins > 0)
Dum.Remove(u,ins);
ReleaseTimer(GetExpiredTimer());
u = null;
destroy();
}
}
}
}
//
static method USCS(real waits,unit us,real stas,real ends,real ss,boolean fades,boolean kills,boolean rems,real inss)
{
thistype this;
//fade <=> true = >
//fade <=> false = <
if(fades)
{
if(stas > ends)
{
this = allocate();
u = us;
time = waits;
sta = stas;
kill = kills;
ins = inss;
end = ends;
fade = fades;
s = ss;
rem = rems;
TimerStart(NewTimerEx(this),.04,true,function thistype.Loop);
}
else
BJDebugMsg("Start value must > end value");
}
else
if(stas < ends)
{
this = allocate();
u = us;
time = waits;
sta = stas;
kill = kills;
ins = inss;
end = ends;
fade = fades;
s = ss;
rem = rems;
TimerStart(NewTimerEx(this),.04,true,function thistype.Loop);
}
else
BJDebugMsg("Start value must < end value");
}
}
}
//
library SpecialEffect requires TimerUtils,DummRemove,xedamage
{
public struct Effect
{
unit u;
unit tg;
string ef;
real dura;
effect E;
real a;
real Area;
real Dl;
real run;
string w;
real wai;
real dma;
boolean RM;
boolean dmg;
real within;
real sp;
string whentaken;
xedamage dam;
//
static method ArLoop()
{
thistype this = GetTimerData(GetExpiredTimer());
real x;
real y;
group g;
unit f;
if(!IsUnitType(u, UNIT_TYPE_DEAD) && !IsUnitType(tg, UNIT_TYPE_DEAD) && GetUnitTypeId(u) != 0 && GetUnitTypeId(tg) != 0)
{
if(wai > 0)
wai = wai - .03250000;
else
{
a = a + sp;
x = GetUnitX(u) + Area * Cos(a*bj_DEGTORAD);
y = GetUnitY(u) + Area * Sin(a*bj_DEGTORAD);
SetUnitX(tg,x);
SetUnitY(tg,y);
if(run < Dl)
run = run + .032500000;
else
{
run = 0.;
DestroyEffect(AddSpecialEffect(ef,GetUnitX(tg),GetUnitY(tg)));
}
if(dmg)
{
dam.useSpecialEffect(whentaken,"chest");
dam.damageAOE(u,x,y,within,dma);
}
if(dura > 0)
dura = dura - .03250000;
if(dura <= 0 || GetWidgetLife(tg) < 0.425 || GetWidgetLife(u) < 0.425)
{
if(RM)
RemoveUnit(tg);
ReleaseTimer(GetExpiredTimer());
u = null;
tg = null;
destroy();
}
}
}
else
{
if(RM)
RemoveUnit(tg);
ReleaseTimer(GetExpiredTimer());
u = null;
tg = null;
destroy();
}
}
//
static method Around(real wait,unit aro,unit tgs,real AOE,real withinn,real speed,real dur,boolean rms,boolean DMGs,real dmgg,string effe,real Delay,string effwhentaken)
{
thistype this;
if(!IsUnitType(tgs, UNIT_TYPE_DEAD) && !IsUnitType(aro, UNIT_TYPE_DEAD) && GetUnitTypeId(tgs) != 0 && GetUnitTypeId(aro) != 0)
{
this = allocate();
u = aro;
whentaken = effwhentaken;
tg = tgs;
wai = wait;
dura = dur;
ef = effe;
dma = dmgg;
within = withinn;
dmg = DMGs;
a = 0.;
run = 0.;
Dl = Delay;
RM = rms;
sp = speed;
Area = AOE;
dam = xedamage.create();
dam.dtype = DAMAGE_TYPE_FIRE;
dam.atype = ATTACK_TYPE_NORMAL;
dam.damageEnemies = true;
dam.damageTrees = false;
TimerStart(NewTimerEx(this),.0325000,true,function thistype.ArLoop);
}
}
}
}
//! endzinc
[/HIDDEN]