Name | Type | is_array | initial_value |
//TESH.scrollpos=223
//TESH.alwaysfold=0
native UnitAlive takes unit id returns boolean//Remove this if you already had one
//! zinc
library FrostBite
/*-----------------------------------------------------------------------------------/
/- v1.0.2
/- JC Helas
/-
/- Description:
/- Release an ice trap that moves back and forth, after move
/- a nova ice will expload that cause them vacuumed to caster's
/- position.
/-
/- How to Import:
/- 1. Goto File>Preferences>General
/- 2. Mark check the "Automatically create unknown varaibles while pasting data.
/- 3. Copy the imported dummy.mdx and the custom locust object
/- 4. Then copy the folder and paste on your map.
/-
/- The spell does not require any libraries.
/-
/-----------------------------------------------------------------------------------*/
{
private
{
/*- Determine the ability ID of Frost Bite -*/
constant integer SPELL_ID = 'A000' ;
/*- Determine the dummy id of that stands as frost trap -*/
constant integer DUM_ID = 'u000' ;
/*- Determine the base amount of frost trap -*/
constant integer LINES = 12 ;
/*- Determine the additional line per level -*/
constant integer LINES_LVL= 2 ;
/*- Determine the damage amount of back and forth -*/
constant real DAMAGE = 50.0 ;
/*- Determine the additional amount of damage -*/
constant real DAMAGE_LVL = 5.0 ;
/*- Determine the affect of area per line -*/
constant real DAMAGE_AOE = 75.0 ;
/*- Determine the distance travel of each line -*/
constant real DISTANCE = 600.0 ;
/*- Determine the speed of forth -*/
constant real SPEED_FORTH = 20.0 ;
/*- Determine the speed of back -*/
constant real SPEED_BACK = 35.0 ;
/*- Determine the summoning distance to target caster position -*/
constant real SUMMON_DIST = 50.0 ;
/*- Determine the speed of vacuum -*/
constant real VACUUM_SPEED= 25.0 ;
/*- Determine the flying height of vacuumed unit -*/
constant real VACUUM_Z = 300.0 ;
/*- Determine the attack type of Frost Bite -*/
constant attacktype A_TYPE= ATTACK_TYPE_MAGIC ;
/*- Determine the damage type of Frost Bite -*/
constant damagetype D_TYPE= DAMAGE_TYPE_NORMAL ;
/*- Determine the owner of dummies -*/
constant player DUM_OWNER = Player(PLAYER_NEUTRAL_PASSIVE) ;
/*- Determine the model attachment to dummy -*/
constant string ATTACH = "origin" ;
/*- Determine the model of dummy -*/
constant string MODEL = "Doodads\\Cinematic\\FrostTrapUp\\FrostTrapUp.mdl";
/*- Determine the nova fx -*/
constant string TARGETFX = "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl";
struct data
{
player owner;
unit caster,dummy;
real angle,rate,speed,dmg,dx,dy;
effect fx;
boolean b;
group g;
}
struct vacuumdata
{
unit u;
real d,r,z,bz,a;
}
constant real periodic=0.031250;
constant group grp=CreateGroup();
constant timer tmr=CreateTimer();
integer ix=0;
integer ic[];
data link=0;
constant timer vtmr=CreateTimer();
integer vix=0;
integer vic[];
function onVacuumLoop()
{
integer i=1;
real x,y;
vacuumdata this;
while(i<=vix)
{
this=vic[i];
this.r=this.r+VACUUM_SPEED;
x=GetUnitX(this.u)+VACUUM_SPEED*Cos(this.a*bj_DEGTORAD);
y=GetUnitY(this.u)+VACUUM_SPEED*Sin(this.a*bj_DEGTORAD);
SetUnitX(this.u,x);
SetUnitY(this.u,y);
SetUnitFlyHeight(this.u,this.bz+(Sin(((180.0/this.d)*this.r)*bj_DEGTORAD)*this.z),0.0);
if(this.r>=this.d)
{
SetUnitPathing(this.u,true);
SetUnitFlyHeight(this.u,GetUnitDefaultFlyHeight(this.u),0);
this.u=null;
vacuumdata.destroy(this);
vic[i]=vic[vix];
vix-=1;
i-=1;
if(vix==0)PauseTimer(vtmr);
}
i+=1;
}
}
function onVacuum(unit t,real x,real y)
{
real dx,dy,xt=GetUnitX(t),yt=GetUnitY(t);
vacuumdata this=vacuumdata.create();
vix+=1;vic[vix]=this;
dx=x-xt;dy=y-yt;
this.u=t;
this.r=0.0;
this.bz=GetUnitFlyHeight(t);
this.d=SquareRoot(dx*dx+dy*dy)*0.75;
this.z=(VACUUM_Z/(DISTANCE*0.75))*this.d;
this.a=bj_RADTODEG*Atan2(y-yt,x-xt);
UnitAddAbility(t,'Amrf');UnitRemoveAbility(t,'Amrf');
SetUnitPathing(t,false);
DestroyEffect(AddSpecialEffect(TARGETFX,xt,yt));
if(vix==1)TimerStart(vtmr,periodic,true,function onVacuumLoop);
}
function onFilter(unit t,player p) -> boolean
{
return UnitAlive(t) &&
!IsUnitType(t,UNIT_TYPE_MAGIC_IMMUNE) &&
!IsUnitType(t,UNIT_TYPE_STRUCTURE) &&
!IsUnitAlly(t,p);
}
function onLoop()
{
data this;
integer i=1;
real x,y;
unit t;
while(i<=ix)
{
this=ic[i];
x=this.dx;
y=this.dy;
if(this.rate<100.0)
{
this.rate=this.rate+this.speed;
x=x+(Sin(((180.0/100)*this.rate)*bj_DEGTORAD)*DISTANCE)*Cos(this.angle*bj_DEGTORAD);
y=y+(Sin(((180.0/100)*this.rate)*bj_DEGTORAD)*DISTANCE)*Sin(this.angle*bj_DEGTORAD);
SetUnitX(this.dummy,x);
SetUnitY(this.dummy,y);
link=this;
GroupEnumUnitsInRange(grp,x,y,DAMAGE_AOE,Filter(function()
{
unit t=GetFilterUnit();
if(onFilter(t,link.owner) && !IsUnitInGroup(t,link.g))
{
UnitDamageTarget(link.caster,t,link.dmg,true,true,A_TYPE,D_TYPE,null);GroupAddUnit(link.g,t);
if(!link.b)
{
onVacuum(t,link.dx,link.dy);
}
}
else
{
}
}));
GroupClear(grp);
if(this.rate>=50.0 && this.b)
{
this.b=false;
this.speed=(100.0/DISTANCE)*SPEED_BACK;
GroupClear(this.g);
}
}
else
{
GroupClear(this.g);
DestroyEffect(this.fx);
KillUnit(this.dummy);
this.caster=null;
this.dummy=null;
this.owner=null;
data.destroy(this);
ic[i]=ic[ix];
ix-=1;
i-=1;
if(ix==0)PauseTimer(tmr);
}
i+=1;
}
}
function onCast() -> boolean
{
unit u;
player p;
real x1,y1,x2,y2,a,d;
integer i,lvl;
data this;
if(GetSpellAbilityId()==SPELL_ID)
{
u=GetTriggerUnit();
p=GetOwningPlayer(u);
lvl=GetUnitAbilityLevel(u,SPELL_ID);
i=LINES+(LINES_LVL*lvl);
d=DAMAGE+(DAMAGE_LVL*lvl);
x1=GetUnitX(u);
y1=GetUnitY(u);
a=360.0/i;
while(i>0)
{
x2=x1+SUMMON_DIST*Cos((a*i)*bj_DEGTORAD);
y2=y1+SUMMON_DIST*Sin((a*i)*bj_DEGTORAD);
this=data.create();
ix+=1;ic[ix]=this;
this.b=true;
this.dx=x2;
this.dy=y2;
this.dmg=d;
this.rate=0.0;
this.speed=(100.0/DISTANCE)*SPEED_FORTH;
this.angle=a*i;
this.caster=u;
this.owner=p;
this.dummy=CreateUnit(DUM_OWNER,DUM_ID,x2,y2,a*i);
this.fx=AddSpecialEffectTarget(MODEL,this.dummy,ATTACH);
if(this.g==null)this.g=CreateGroup();
if(ix==1)TimerStart(tmr,periodic,true,function onLoop);
i-=1;
}
u=null;
}
return false;
}
function onInit()
{
trigger t=CreateTrigger();
integer i=0;
while(i<=11)
{
TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null);
i+=1;
}
TriggerAddCondition(t,Filter(function onCast));
t=null;
}
}
}
//! endzinc
//TESH.scrollpos=0
//TESH.alwaysfold=0
/**************************************************************
*
* RegisterPlayerUnitEvent
* v5.1.0.1
* By Magtheridon96
*
* I would like to give a special thanks to Bribe, azlier
* and BBQ for improving this library. For modularity, it only
* supports player unit events.
*
* Functions passed to RegisterPlayerUnitEvent must either
* return a boolean (false) or nothing. (Which is a Pro)
*
* Warning:
* --------
*
* - Don't use TriggerSleepAction inside registered code.
* - Don't destroy a trigger unless you really know what you're doing.
*
* API:
* ----
*
* - function RegisterPlayerUnitEvent takes playerunitevent whichEvent, code whichFunction returns nothing
* - Registers code that will execute when an event fires.
* - function RegisterPlayerUnitEventForPlayer takes playerunitevent whichEvent, code whichFunction, player whichPlayer returns nothing
* - Registers code that will execute when an event fires for a certain player.
* - function GetPlayerUnitEventTrigger takes playerunitevent whichEvent returns trigger
* - Returns the trigger corresponding to ALL functions of a playerunitevent.
*
**************************************************************/
library RegisterPlayerUnitEvent // Special Thanks to Bribe and azlier
globals
private trigger array t
endglobals
function RegisterPlayerUnitEvent takes playerunitevent p, code c returns nothing
local integer i = GetHandleId(p)
local integer k = 15
if t[i] == null then
set t[i] = CreateTrigger()
loop
call TriggerRegisterPlayerUnitEvent(t[i], Player(k), p, null)
exitwhen k == 0
set k = k - 1
endloop
endif
call TriggerAddCondition(t[i], Filter(c))
endfunction
function RegisterPlayerUnitEventForPlayer takes playerunitevent p, code c, player pl returns nothing
local integer i = 16 * GetHandleId(p) + GetPlayerId(pl)
if t[i] == null then
set t[i] = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(t[i], pl, p, null)
endif
call TriggerAddCondition(t[i], Filter(c))
endfunction
function GetPlayerUnitEventTrigger takes playerunitevent p returns trigger
return t[GetHandleId(p)]
endfunction
endlibrary
//TESH.scrollpos=60
//TESH.alwaysfold=0
struct test
private static constant integer Creeps_Amount = 5
private static constant real Revive_Duration = 2.0
private static constant real Periodic = 0.031250
private static constant timer tmr = CreateTimer()
private static integer ix = 0
private static integer array ic
private unit u
private real d
private static method onLoop takes nothing returns nothing
local thistype this
local integer i=1
local real x
local real y
local real a
loop
exitwhen i>ix
set this=ic[i]
set d=d-Periodic
if d<=0.0 then
set x=GetStartLocationX(0)
set y=GetStartLocationY(0)
if IsUnitType(u,UNIT_TYPE_HERO) then
call ReviveHero(u,x,y,true)
else
set a=GetRandomReal(0,360)
call CreateUnit(GetOwningPlayer(u),GetUnitTypeId(u),x+800*Cos(a*bj_DEGTORAD),y+800*Sin(a*bj_DEGTORAD),a)
call RemoveUnit(u)
endif
set u=null
call deallocate()
set ic[i]=ic[ix]
set ix=ix-1
set i=i-1
if ix==0 then
call PauseTimer(tmr)
endif
endif
set i=i+1
endloop
endmethod
private static method onDeath takes nothing returns nothing
local thistype this
local unit u=GetTriggerUnit()
if GetUnitAbilityLevel(u,'Aloc')==0 and not IsUnitType(u,UNIT_TYPE_SUMMONED) then
set this=allocate()
set ix=ix+1
set ic[ix]=this
set .u=u
set d=Revive_Duration
if ix==1 then
call TimerStart(tmr,Periodic,true,function thistype.onLoop)
endif
endif
endmethod
private static method onInit takes nothing returns nothing
local real x=GetStartLocationX(0)
local real y=GetStartLocationY(0)
local integer i=1
local player p=Player(0)
call CreateUnit(p,'Hblm',x,y,GetRandomReal(0,360))
call CreateItem('ciri',x,y)
set p=Player(PLAYER_NEUTRAL_AGGRESSIVE)
loop
exitwhen i>Creeps_Amount
call CreateItem('ciri',x,y)
call CreateUnit(p,ChooseRandomCreep(GetRandomInt(1,5)),x+800*Cos(0*bj_DEGTORAD),y+800*Sin(0*bj_DEGTORAD),GetRandomReal(1,360))
call CreateUnit(p,ChooseRandomCreep(GetRandomInt(1,5)),x+800*Cos(90*bj_DEGTORAD),y+800*Sin(90*bj_DEGTORAD),GetRandomReal(1,360))
call CreateUnit(p,ChooseRandomCreep(GetRandomInt(1,5)),x+800*Cos(180*bj_DEGTORAD),y+800*Sin(180*bj_DEGTORAD),GetRandomReal(1,360))
call CreateUnit(p,ChooseRandomCreep(GetRandomInt(1,5)),x+800*Cos(270*bj_DEGTORAD),y+800*Sin(270*bj_DEGTORAD),GetRandomReal(1,360))
set i=i+1
endloop
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH,function thistype.onDeath)
set p=null
endmethod
endstruct