Carnerox
The one and only.
- Reaction score
- 84
PHP:
The Death Knight tethers a target unit to a demonic obelisk.
If the target unit exceeds a set distance from the obelisk,
the link will snap dealing damage and instantly moveing
the target unit back to the obelisk.
Level 1 - Deals 75 damage. 500 max distance. Last for 15 seconds.
Level 2 - Deals 125 damage. 600 max distance. Last for 20 seconds.
Level 3 - Deals 175 damage. 700 max distance. Last for 25 seconds.
Level 4 - Deals 225 damage. 800 max distance. Last for 30 seconds.
Mana Cost: 100
Cooldown: 26 / 24 / 22 / 20
- MUI: Yes
- MPI: Yes
- Lagless: Yes
- Leakless: Hopefully
Requirements:
GTrigger
JNGP
Optional
Damage
AIDS
Event
JASS:
///////////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// Death Coil \\
// by: Carnerox \\
// credits to: \\
//Jesus4Lyf for Damage, AIDS, Event, and GTrigger\\
//Vexorian for TimerUtils\\
// How to use import this spell:
// 1) Copy this trigger
// 2) Open your map, create a new trigger with the name "Death Coil".
// 3) Click Edit, and convert the trigger to custom text.
// 4) Copy the trigger, and paste it into the trigger.
// 5) Add all the systems that the spell uses.
// 6) Change the ABIL_ID, and DUMMY_ID to the correct rawcodes, and customize the spell to what you want.
////////////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
scope DeathCoil
////////////////////////////////CONFIGURATION DATA!\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
globals
private constant integer ABIL_ID = 039;A000039;
private constant integer DUMMY_ID = 039;h000039;
private constant real PERIODIC = 0.04
private constant real COLOR_R = 100.00
private constant real COLOR_G = 0.00
private constant real COLOR_B = 0.00
private constant real COLOR_A = 1.00
private constant real FLOAT = 45.00
private constant string LIGHTNING_ID = "MFPB"
private constant string EFFECT_ID = "Abilities\\Spells\\Demon\\DarkPortal\\DarkPortalTarget.mdl"
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_MAGIC
private constant weapontype WEAPON_TYPE = null
private constant boolean SHARED_VISION = true
endglobals
constant native UnitAlive takes unit whichUnit returns boolean
private function Damage takes integer level returns real
return 50.00*level+25.00
endfunction
private function Distance takes integer level returns real
return 100*level+400.00
endfunction
private function Duration takes integer level returns real
return 5.00*level+10.00
endfunction
private function GetUnitZ takes unit whichUnit returns real
local location Point=Location(GetUnitX(whichUnit),GetUnitY(whichUnit))
local real Real=GetLocationZ(Point)+GetUnitFlyHeight(whichUnit)
call RemoveLocation(Point)
set Point=null
return Real
endfunction
///////////////////////////END OF CONFIGURATION DATA!\\\\\\\\\\\\\\\\\\\\\\\
private struct DeathCoil
unit caster
unit target
unit dummy
player owner
lightning light
integer level
real x1
real x2
real y1
real y2
real z1
real z2
private static method onLoop takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local real x
local real y
set this.x2=GetUnitX(this.target)
set this.y2=GetUnitY(this.target)
set this.z2=GetUnitZ(this.target)+FLOAT
set x=this.x2-this.x1
set y=this.y2-this.y1
call MoveLightningEx(this.light,true,this.x1,this.y1,this.z1,this.x2,this.y2,this.z2)
if (SquareRoot(x*x+y*y)>=Distance(this.level)) then
call ReleaseTimer(t)
call DestroyLightning(this.light)
call DestroyEffect(AddSpecialEffect(EFFECT_ID,this.x1,this.y1))
call DestroyEffect(AddSpecialEffect(EFFECT_ID,this.x2,this.y2))
call RemoveUnit(this.dummy)
call SetUnitX(this.target,this.x1)
call SetUnitY(this.target,this.y1)
static if (LIBRARY_Damage) then
call Damage_Spell(this.dummy,this.target,Damage(this.level))
else
call UnitDamageTarget(this.dummy,this.target,Damage(this.level),true,false,ATTACK_TYPE,DAMAGE_TYPE,WEAPON_TYPE)
endif
if (SHARED_VISION) then
call UnitShareVision(this.target,this.owner,false)
endif
set this.caster=null
set this.target=null
set this.dummy=null
set this.light=null
set t=null
elseif not (UnitAlive(this.dummy)) or not (UnitAlive(this.target)) then
call ReleaseTimer(t)
call DestroyLightning(this.light)
call DestroyEffect(AddSpecialEffect(EFFECT_ID,this.x1,this.y1))
call RemoveUnit(this.dummy)
if (SHARED_VISION==true) then
call UnitShareVision(this.target,this.owner,false)
endif
set this.caster=null
set this.target=null
set this.dummy=null
set this.light=null
set t=null
endif
endmethod
private static method onEffect takes nothing returns boolean
local thistype this = thistype.allocate()
local timer t = NewTimer()
set this.caster=GetTriggerUnit()
set this.target=GetSpellTargetUnit()
set this.owner=GetTriggerPlayer()
set this.level=GetUnitAbilityLevel(this.caster,ABIL_ID)
set this.x2=GetUnitX(this.target)
set this.y2=GetUnitY(this.target)
set this.z2=GetUnitZ(this.target)+FLOAT
set this.dummy=CreateUnit(this.owner,DUMMY_ID,this.x2,this.y2,0.00)
set this.x1=GetUnitX(this.dummy)
set this.y1=GetUnitY(this.dummy)
set this.z1=GetUnitZ(this.dummy)+FLOAT
set this.light=AddLightningEx(LIGHTNING_ID,true,this.x1,this.y1,this.z1,this.x2,this.y2,this.z2)
call UnitApplyTimedLife(this.dummy,039;BTLF039;,Duration(this.level))
call SetLightningColor(this.light,COLOR_R,COLOR_G,COLOR_B,COLOR_A)
if (SHARED_VISION==true) then
call UnitShareVision(this.target,this.owner,true)
endif
call SetTimerData(t,this)
call TimerStart(t,PERIODIC,true,function thistype.onLoop)
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerAddCondition(GT_RegisterStartsEffectEvent(trig,ABIL_ID),Condition(function thistype.onEffect))
endmethod
endstruct
endscope
JASS:
////////////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// Death Coil \\
// by: Carnerox \\
// credits to: \\
//Jesus4Lyf for Damage, AIDS, Event, and GTrigger\\
//Vexorian for TimerUtils\\
// How to use import this spell:
// 1) Copy this trigger
// 2) Open your map, create a new trigger with the name "Death Coil".
// 3) Click Edit, and convert the trigger to custom text.
// 4) Copy the trigger, and paste it into the trigger.
// 5) Add all the systems that the spell uses.
// 6) Change the ABIL_ID, and DUMMY_ID to the correct rawcodes, and customize the spell to what you want.
////////////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//! zinc
library DeathCoil requires Damage,GT,TimerUtils
{
////////////////////////////////CONFIGURATION DATA!\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
private constant integer ABIL_ID = 039;A000039;;
private constant integer DUMMY_ID = 039;h000039;;
private constant real PERIODIC = 0.04;
private constant real COLOR_R = 100.00;
private constant real COLOR_G = 0.00;
private constant real COLOR_B = 0.00;
private constant real COLOR_A = 1.00;
private constant real FLOAT = 45.00;
private constant string LIGHTNING_ID = "MFPB";
private constant string EFFECT_ID = "Abilities\\Spells\\Demon\\DarkPortal\\DarkPortalTarget.mdl";
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL;
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_MAGIC;
private constant weapontype WEAPON_TYPE = null;
private constant boolean SHARED_VISION = true;
function Damage(integer level) -> real
{
return 50.00*level+25.00;
}
function Distance(integer level) -> real
{
return 100.00*level+400.00;
}
function Duration(integer level) -> real
{
return 5.00*level+10.00;
}
function GetUnitZ(unit whichUnit) -> real
{
location l = Location(GetUnitX(whichUnit),GetUnitY(whichUnit));
real r = GetLocationZ(l)+GetUnitFlyHeight(whichUnit);
RemoveLocation(l);
l=null;
return r;
}
///////////////////////////END OF CONFIGURATION DATA!\\\\\\\\\\\\\\\\\\\\\\\
struct data
{
unit u; //Caster
unit t; //Target
unit d; //Dummy
player p; // Owner of Caster.
integer i;
real x1;
real x2;
real y1;
real y2;
real z1;
real z2;
lightning l;
}
function GetDistance(real x,real y) -> real
{
return SquareRoot(x*x+y*y);
}
function onTimer()
{
timer t = GetExpiredTimer();
data this = GetTimerData(t);
real x; real y;
this.x2=GetUnitX(this.t);
this.y2=GetUnitY(this.t);
this.z2=GetUnitZ(this.t)+FLOAT;
x=this.x2-this.x1; y=this.y2-this.y1;
MoveLightningEx(this.l,true,this.x1,this.y1,this.z1,this.x2,this.y2,this.z2);
if (GetDistance(x,y)>=Distance(this.i))
{
ReleaseTimer(t);
DestroyLightning(this.l);
DestroyEffect(AddSpecialEffect(EFFECT_ID,this.x1,this.y1));
DestroyEffect(AddSpecialEffect(EFFECT_ID,this.x2,this.y2));
RemoveUnit(this.d);
SetUnitX(this.t,this.x1);
SetUnitY(this.t,this.y1);
static if (LIBRARY_Damage){ Damage_Spell(this.d,this.t,Damage(this.i)); }
else{ UnitDamageTarget(this.d,this.t,Damage(this.i),true,false,ATTACK_TYPE,DAMAGE_TYPE,WEAPON_TYPE); }
if (SHARED_VISION){ UnitShareVision(this.t,this.p,false); }
this.u=null;
this.t=null;
this.d=null;
this.p=null;
this.l=null;
t=null;
}
else if (GetWidgetLife(this.d)<=0.405 || GetWidgetLife(this.t)<=0.405)
{
ReleaseTimer(t);
DestroyLightning(this.l);
DestroyEffect(AddSpecialEffect(EFFECT_ID,this.x1,this.y1));
RemoveUnit(this.d);
if (SHARED_VISION==true){ UnitShareVision(this.t,this.p,false); }
this.u=null;
this.t=null;
this.d=null;
this.p=null;
this.l=null;
t=null;
}
}
function onEffect() -> boolean
{
data this = data.create();
timer t = NewTimer();
this.u=GetTriggerUnit();
this.t=GetSpellTargetUnit();
this.p=GetTriggerPlayer();
this.i=GetUnitAbilityLevel(this.u,ABIL_ID);
this.x2=GetUnitX(this.t);
this.y2=GetUnitY(this.t);
this.z2=GetUnitZ(this.t)+FLOAT;
this.d=CreateUnit(this.p,DUMMY_ID,this.x2,this.y2,0.00);
this.x1=GetUnitX(this.d);
this.y1=GetUnitY(this.d);
this.z1=GetUnitZ(this.d)+FLOAT;
this.l=AddLightningEx(LIGHTNING_ID,true,this.x1,this.y1,this.z1,this.x2,this.y2,this.z2);
UnitApplyTimedLife(this.d,039;BTLF039;,Duration(this.i));
SetLightningColor(this.l,COLOR_R,COLOR_G,COLOR_B,COLOR_A);
if (SHARED_VISION==true){ UnitShareVision(this.t,this.p,true); }
SetTimerData(t,integer(this));
TimerStart(t,PERIODIC,true,function onTimer);
t=null;
return false;
}
function onInit()
{
trigger t = CreateTrigger();
TriggerAddCondition(GT_RegisterStartsEffectEvent(t,ABIL_ID),Filter(function onEffect));
t=null;
}
}
//! endzinc
Change Log:
v1.0b
- Changed the model of the link.
- Now gives vision over the target
- Made the spell more customizable.
- Changed the model of the Link.
- Removed Jesus4Lyf Damage, AIDS, and Event system till I figure how I'll add the optional Damage system.
- Allowed an option to use the Damage system.
- Improved some parts of the code.
- Made it so Damage/Distance/Duration can be set with a function, instead of being constant.
- An effect is created at the target's x/y before it is moved to the obelisk.
- Improved the documentation.
- Raised the height of the link so it doesn't look like it's on the ground.
- The link now works correctly with flying units so it's on attached to their x/y on the ground.
- Created a constant for the floating height for the link.
- Improved the documentation again.
- Created a version that doesn't use the SpellStruct.
- Slightly improved the documentation.
- Fixed the z location with help of Laiev.
- Improved the documentation.
- Added a constant boolean to check if target shares vision.
- Changed the DUMMY/LIGHTNING/etc.. to Dummy/Lightning/etc..
- Changed the trigger from a Library to a Scope.
- Removed Spellstruct/version.
- Made it MUI/MPI.
- Cleaned the spell up a little.
- Added GTrigger.
- Added a zinc version.