//TESH.scrollpos=0
//TESH.alwaysfold=0
constant native UnitAlive takes unit id returns boolean
Name | Type | is_array | initial_value |
//TESH.scrollpos=46
//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=0
//TESH.alwaysfold=0
//============================================================================
// SpellEffectEvent
// - Version 1.1.0.0
//
// API
// ---
// RegisterSpellEffectEvent(integer abil, code onCast)
//
// Requires
// --------
// RegisterPlayerUnitEvent: hiveworkshop.com/forums/showthread.php?t=203338
//
// Optional
// --------
// Table: hiveworkshop.com/forums/showthread.php?t=188084
//
library SpellEffectEvent requires RegisterPlayerUnitEvent, optional Table
//============================================================================
private module M
static if LIBRARY_Table then
static Table tb
else
static hashtable ht = InitHashtable()
endif
static method onCast takes nothing returns nothing
static if LIBRARY_Table then
call TriggerEvaluate(.tb.trigger[GetSpellAbilityId()])
else
call TriggerEvaluate(LoadTriggerHandle(.ht, 0, GetSpellAbilityId()))
endif
endmethod
private static method onInit takes nothing returns nothing
static if LIBRARY_Table then
set .tb = Table.create()
endif
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function thistype.onCast)
endmethod
endmodule
//============================================================================
private struct S extends array
implement M
endstruct
//============================================================================
function RegisterSpellEffectEvent takes integer abil, code onCast returns nothing
static if LIBRARY_Table then
if not S.tb.handle.has(abil) then
set S.tb.trigger[abil] = CreateTrigger()
endif
call TriggerAddCondition(S.tb.trigger[abil], Filter(onCast))
else
if not HaveSavedHandle(S.ht, 0, abil) then
call SaveTriggerHandle(S.ht, 0, abil, CreateTrigger())
endif
call TriggerAddCondition(LoadTriggerHandle(S.ht, 0, abil), Filter(onCast))
endif
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library UnitIndexer initializer init /* v1.0.1 by JC Helas
*******************************************************************
*
* A simple unit indexer with triggerless and very easy to use.
* feel free to use this without credits, this system is not surely
* work safetly but contact me if may happens, also help me improve
* this as well.
*
* *USAGE*
*
* UnitIndexerEvent = 1.0 A unit has been index.
* Returns UnitIndexerEventObject
* UnitIndexerEventData
* UnitIndexerEvent = 2.0 A unit has been removed from game.
* Returns UnitIndexerEventData
* UnitIndexerEvent = 3.0 Index has initialize.
* UnitIndexerEvent = 4.0 Index has not initialize.
*
* You can simply stop unit from being index by turning UnitIndexerStop
* into "true". make sure to turn it to false.
*
* set UnitIndexerStop=true
* call CreateUnit(...)
* set UnitIndexerStop=false
*
*******************************************************************/
globals
real UnitIndexerEvent = 0.0
unit UnitIndexerEventObject = null
integer UnitIndexerEventData = 0
boolean UnitIndexerStop = false
private constant group grup = CreateGroup()
private constant timer tmr = CreateTimer()
private player uowner = null
endglobals
private function createfilter takes nothing returns boolean
local unit u=GetFilterUnit()
local integer data=GetUnitUserData(u)
if not UnitIndexerStop /*
*/and not IsUnitIllusion(u) /*
*/and ((data==0) or not(UnitStruct.filter(u,data))) then
call UnitStruct.createthis(u)
endif
set u=null
return false
endfunction
struct UnitStruct
public unit UnitIndexed
public player UnitPlayerIndexed
public integer UnitPlayerIdIndexed
static method removethis takes thistype this returns nothing
set UnitIndexerEventData=this
set UnitIndexerEvent=2.0
set UnitIndexerEvent=0.0
set UnitIndexed=null
set UnitPlayerIndexed=null
set UnitPlayerIdIndexed=0
call deallocate()
endmethod
static method createthis takes unit u returns nothing
local thistype this=allocate()
set UnitIndexed=u
set UnitPlayerIndexed=GetOwningPlayer(u)
set UnitPlayerIdIndexed=GetPlayerId(UnitPlayerIndexed)
call SetUnitUserData(u,this)
set UnitIndexerEventObject=u
set UnitIndexerEventData=this
set UnitIndexerEvent=1.0
set UnitIndexerEvent=0.0
endmethod
static method filter takes unit u,thistype this returns boolean
return UnitIndexed==u
endmethod
endstruct
private function removed takes unit u returns nothing
local integer data=GetUnitUserData(u)
if UnitStruct.filter(u,data) then
call UnitStruct.removethis(GetUnitUserData(u))
endif
endfunction
private function init takes nothing returns nothing
local unit u
local region reg=CreateRegion()
local rect rct=GetWorldBounds()
set gg_trg_UnitIndexer=CreateTrigger()
call RegionAddRect(reg,rct)
set UnitIndexerEvent=4.0
set UnitIndexerEvent=0.0
call GroupEnumUnitsInRect(grup,rct,Filter(function createfilter))
call GroupClear(grup)
call TriggerRegisterEnterRegion(gg_trg_UnitIndexer,reg,Filter(function createfilter))
set UnitIndexerEvent=3.0
set UnitIndexerEvent=0.0
call RemoveRect(rct)
set u=null
set reg=null
set rct=null
endfunction
hook RemoveUnit removed
endlibrary
//TESH.scrollpos=30
//TESH.alwaysfold=0
struct AirBurn
static constant real MaxHeight=1000.0
static constant real Periodic=0.0312500
static constant real DefaultDur=10
static constant real DefaultHeight=5000.0
static constant real SinMax=90.0
static constant integer fly='Amrf'
static constant real RateHeight=DefaultDur/DefaultHeight
static timer Tmr=CreateTimer()
static integer Imax=0
static integer array Icon[8190]
static real array Usin[8190]
static real array Uheight[8190]
static boolean array Ucondition[8190]
integer ID
static method SinSpeed takes real h returns real
return SinMax/((RateHeight*h)/Periodic)
endmethod
static method HeightUpdate takes real s, real h returns real
return Sin(s*bj_DEGTORAD)*h
endmethod
static method lop takes nothing returns nothing
local unit u
local integer id
local thistype this
local integer i=1
loop
exitwhen i>Imax
set this=Icon[i]
set u=UnitStruct(ID).UnitIndexed
if Ucondition[ID] then
set Usin[ID]=Usin[ID]+SinSpeed(Uheight[ID])
if Usin[ID]>=SinMax then
set Ucondition[ID]=false
endif
else
set Usin[ID]=Usin[ID]-SinSpeed(Uheight[ID])
if Usin[ID]<=0 then
set Icon[i]=Icon[Imax]
set Imax=Imax-1
set i=i-1
call deallocate(ID)
if Imax==0 then
call PauseTimer(Tmr)
endif
endif
endif
call SetUnitFlyHeight(u,HeightUpdate(Usin[ID],Uheight[ID]),0.0)
set i=i+1
endloop
set u=null
endmethod
static method exe takes unit u, real h returns nothing
local integer id=GetUnitUserData(u)
local real rh
local thistype this
if Usin[id]==0 then
call UnitAddAbility(u,fly)
call UnitRemoveAbility(u,fly)
set Usin[id]=0
set Uheight[id]=h
set Ucondition[id]=true
set this=allocate()
set Imax=Imax+1
set Icon[Imax]=this
set ID=id
if Imax==1 then
call TimerStart(Tmr,Periodic,true,function AirBurn.lop)
endif
elseif Ucondition[id] then
set rh=GetUnitFlyHeight(u)
set Uheight[id]=Uheight[id]+(h/2)
set Usin[id]=(SinMax/Uheight[id])*rh
elseif not Ucondition[id] then
set Ucondition[id]=true
set rh=GetUnitFlyHeight(u)
set Uheight[id]=rh+h
set Usin[id]=(SinMax/Uheight[id])*rh
endif
endmethod
endstruct
//TESH.scrollpos=0
//TESH.alwaysfold=0
struct Slow
private static constant real PERIODIC = 0.031250
private static timer tmr=CreateTimer()
private static integer ix=0
private static integer array ic
private static real array duration
private static real array base
private static real array amount
private static real array fade
private unit object
private static method onLoop takes nothing returns nothing
local thistype this
local integer i=1
local integer id
loop
exitwhen i>ix
set this=ic[i]
set id=GetUnitUserData(object)
if duration[id]>=PERIODIC then
set duration[id]=duration[id]-PERIODIC
call SetUnitMoveSpeed(object,base[id]-((amount[id]/fade[id])*duration[id]))
else
set object=null
set base[id]=0.0
set fade[id]=0.0
set amount[id]=0.0
set duration[id]=0.0
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
public static method Add takes unit u,real a,real d,boolean stack returns nothing
local thistype this
local integer id=GetUnitUserData(u)
set base[id]=GetUnitDefaultMoveSpeed(u)
set amount[id]=a
if duration[id]<=0.0 then
set this=allocate()
set ix=ix+1
set ic[ix]=this
set object=u
if ix==1 then
call TimerStart(tmr,PERIODIC,true,function thistype.onLoop)
endif
set duration[id]=d
set fade[id]=d
elseif stack then
set duration[id]=duration[id]+d
set fade[id]=duration[id]
else
set duration[id]=d
set fade[id]=d
endif
endmethod
endstruct
//TESH.scrollpos=132
//TESH.alwaysfold=0
scope Distributor
//*****************************************************************
//
// CONFIGURES
//
//*****************************************************************
globals
//*****************************************************************
//
// Determine the ability id of Life Distributor
//
//*****************************************************************
private constant integer ABI_LIFE = 'A000'
//*****************************************************************
//
// Determine the ability id if Mana Distributor
//
//*****************************************************************
private constant integer ABI_MANA = 'A001'
//*****************************************************************
//
// Determine the unit type id of dummy
// Note: Make sure to import the dummy model
//
//*****************************************************************
private constant integer DUMMY_ID = 'u000'
//*****************************************************************
//
// Determine the ball life time of ball after contributing
// state of enemies
//
//*****************************************************************
private constant real BALL_TIME = 30.0
//*****************************************************************
//
// Determine the base amount of contribution
//
//*****************************************************************
private constant real DIST_AMT = 5.0
//*****************************************************************
//
// Determine the additional amount of contribution
// -Max 100 being rate by casters int
//
//*****************************************************************
private constant real DIST_INT = 3.25
//*****************************************************************
//
// Determine the duration of state contribution
//
//*****************************************************************
private constant real DURATION = 10.0
//*****************************************************************
//
// Determine the constant height of ball at contributing
//
//*****************************************************************
private constant real HEIGHT = 50.0
//*****************************************************************
//
// Determine the travel distance at caster position
//
//*****************************************************************
private constant real RANGE = 600.0
//*****************************************************************
//
// Determine the distance aquired of constributing
//
//*****************************************************************
private constant real AOE = 50.0
//*****************************************************************
//
// Determine the speed of ball
// -Basing to range
// -100 Max,could be heigher but plays unpleasing
//
//*****************************************************************
private constant real SPEED = 2.0
//*****************************************************************
//
// Determine the model of life ball
//
//*****************************************************************
private constant string LIFE_MODEL= "Abilities\\Weapons\\BloodElfMissile\\BloodElfMissile.mdl"
//*****************************************************************
//
// Determine the model of mana ball
//
//*****************************************************************
private constant string MANA_MODEL= "Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl"
//*****************************************************************
//
// Determine the effect of life collisions
//
//*****************************************************************
private constant string LIFE_HIT = "Abilities\\Spells\\Human\\Feedback\\SpellBreakerAttack.mdl"
//*****************************************************************
//
// Determine the effect mana collisions
//
//*****************************************************************
private constant string MANA_HIT = "Abilities\\Spells\\Human\\Feedback\\ArcaneTowerAttack.mdl"
//*****************************************************************
//
// Determine the location of model attachment
//
//*****************************************************************
private constant string ATTACH = "origin"
//*****************************************************************
//
// Determine the attack type of life contributing
//
//*****************************************************************
private constant attacktype ATK_TYPE = ATTACK_TYPE_MAGIC
//*****************************************************************
//
// Determine the damage type of life contributing
//
//*****************************************************************
private constant damagetype DMG_TYPE = DAMAGE_TYPE_NORMAL
//*****************************************************************
//
// The followings are not configureable
//
//*****************************************************************
private constant player OWNER = Player(PLAYER_NEUTRAL_PASSIVE)
private constant real PERIODIC = 0.0312500
private constant integer LIFE_TYPE = 1
private constant integer MANA_TYPE = 2
endglobals
constant native UnitAlive takes unit id returns boolean
private function Filters takes unit t returns boolean
return UnitAlive(t) and not IsUnitType(t,UNIT_TYPE_MAGIC_IMMUNE) and not IsUnitType(t,UNIT_TYPE_STRUCTURE)
endfunction
private function DistanceBetweenXY takes real x1,real y1,real x2,real y2 returns real
local real dx=x2-x1
local real dy=y2-y1
return dx*dx+dy*dy
endfunction
struct DISTRIBUTOR_dummy//DISTRIBUTOR_ to prevent conflictions because the struct is not privatize
static constant hashtable hash=InitHashtable()
private static constant timer tmr = CreateTimer()
private static integer ix = 0
private static integer array ic
private unit dummy
private unit target
private real dur
private real dist
private real rate
private real deg
private real degc
private real speed
private real z
private boolean bol
private static method Death takes nothing returns nothing
local unit u=GetTriggerUnit()
local integer id=GetHandleId(u)
if GetUnitTypeId(u)==DUMMY_ID and IsUnitInGroup(u,LoadGroupHandle(hash,GetHandleId(LoadUnitHandle(hash,id,1)),0)) then
call DestroyEffect(LoadEffectHandle(hash,id,0))
call SaveEffectHandle(hash,id,0,null)
call SaveUnitHandle(hash,id,1,null)
call SaveBoolean(hash,id,0,false)
call RemoveSavedHandle(hash,id,0)
call RemoveSavedHandle(hash,id,1)
call RemoveSavedBoolean(hash,id,0)
endif
set u=null
endmethod
private static method Loop takes nothing returns nothing
local thistype this
local integer i= 1
local real xd
local real yd
local real x
local real y
local real z
local real r
local integer id
loop
exitwhen i>ix
set this = ic[i]
set id = GetHandleId(dummy)
set z = .z
if dur>0.0 then
if target!=null and UnitAlive(target) then
set x = GetUnitX(target)-(dist/2.0)*Cos(deg*bj_DEGTORAD)
set y = GetUnitY(target)-(dist/2.0)*Sin(deg*bj_DEGTORAD)
set dur = dur-PERIODIC
if rate>=180.0 then
set rate=0
if bol then
set bol=false
else
set bol=true
endif
else
set rate=rate+(180.0/dist)*speed
if bol then
set r=(dist/180.0)*(180.0-rate)
else
set r=(dist/180.0)*rate
endif
endif
set x = x+r*Cos(deg*bj_DEGTORAD)
set y = y+r*Sin(deg*bj_DEGTORAD)
set x = x+(Sin((rate*2.0)*bj_DEGTORAD)*(dist/2.0))*Cos((deg+degc)*bj_DEGTORAD)
set y = y+(Sin((rate*2.0)*bj_DEGTORAD)*(dist/2.0))*Sin((deg+degc)*bj_DEGTORAD)
call SetUnitX(dummy,x)
call SetUnitY(dummy,y)
call SetUnitFlyHeight(dummy,z,0.0)
else
set target=LoadUnitHandle(hash,id,1)
set x=GetUnitX(target)
set y=GetUnitY(target)
set xd=GetUnitX(dummy)
set yd=GetUnitY(dummy)
call SetUnitFlyHeight(dummy,z,0.0)
set r=DistanceBetweenXY(x,y,xd,yd)
if r>((dist*dist)/2.0) then
set deg=bj_RADTODEG*Atan2(y-yd,x-xd)
elseif r<((dist*dist)/2.0) then
set deg=bj_RADTODEG*Atan2(yd-y,xd-x)
endif
if UnitAlive(target) then
set xd=xd+speed*Cos(deg*bj_DEGTORAD)
set yd=yd+speed*Sin(deg*bj_DEGTORAD)
call SetUnitX(dummy,xd)
call SetUnitY(dummy,yd)
set rate=0.0
if deg<=0.0 then
set deg=deg+360.0
endif
if r>(dist/2.0) then
set r=r-(dist/2.0)
else
set r=(dist/2.0)-r
endif
if r>speed then
set target=null
endif
else
set dur=0.0
endif
endif
else
call UnitApplyTimedLife(.dummy,'BTLF',BALL_TIME)
call SaveBoolean(hash,id,0,true)
set dummy=null
set target=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
static method Add takes unit dum,string fx,unit target,real dist,real speed,real deg,real z,real dur,boolean bol,boolean left returns unit
local thistype this
local unit u = null
local integer id
set this = allocate()
set ix = ix + 1
set ic[ix] = this
set .z = z
set .bol = bol
set .deg = deg
set .dur = dur
set .rate = 0.0
set .dist = dist
set .speed = (dist/100.0)*speed
set .target= target
if left then
set .degc=90.0
else
set .degc=-90.0
endif
if dum==null then
set UnitIndexerStop=true
set .dummy=CreateUnit(OWNER,DUMMY_ID,GetUnitX(target),GetUnitY(target),0.0)
set UnitIndexerStop=false
set u=.dummy
set id=GetHandleId(u)
call SaveBoolean(hash,id,0,false)
call UnitAddAbility(u,'Amrf')
call UnitRemoveAbility(u,'Amrf')
call SaveEffectHandle(hash,id,0,AddSpecialEffectTarget(fx,.dummy,ATTACH))
else
set .dummy=dum
set id=GetHandleId(dum)
call SaveBoolean(hash,id,0,false)
endif
if ix==1 then
call TimerStart(tmr,PERIODIC,true,function thistype.Loop)
endif
return u
endmethod
private static method onInit takes nothing returns nothing
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH,function thistype.Death)
endmethod
endstruct
private struct createballs
private static constant timer tmr = CreateTimer()
private static constant group grp = CreateGroup()
private static integer ix=0
private static integer array ic
private unit dummy
private unit caster
private player owner
private integer dtype
private real distribute
private static method onLoop takes nothing returns nothing
local thistype this
local integer i=1
local real x
local real y
local unit t
local real amt
local real dist
local real state
local boolean ally
loop
exitwhen i>ix
set this=ic[i]
if not LoadBoolean(DISTRIBUTOR_dummy.hash,GetHandleId(.dummy),0) then
set x=GetUnitX(.dummy)
set y=GetUnitY(.dummy)
if IsUnitType(.caster,UNIT_TYPE_HERO) then
set amt=DIST_AMT+((GetHeroInt(.caster,true)/100.0)*DIST_INT)
else
set amt=DIST_AMT
endif
call GroupEnumUnitsInRange(grp,x,y,AOE,null)
loop
set t=FirstOfGroup(grp)
exitwhen t==null
if Filters(t) and GetUnitTypeId(t)!=DUMMY_ID then
set ally=IsUnitAlly(t,.owner)
if .dtype==LIFE_TYPE then
set state=GetWidgetLife(t)
if ally then
call SetWidgetLife(t,state+distribute)
set distribute=0.0
else
call UnitDamageTarget(.caster,t,amt,true,true,ATK_TYPE,DMG_TYPE,null)
set distribute=distribute+amt
endif
if GetWidgetLife(t)!=state then
call DestroyEffect(AddSpecialEffectTarget(LIFE_HIT,t,ATTACH))
endif
elseif .dtype==MANA_TYPE then
set state=GetUnitState(t,UNIT_STATE_MANA)
if ally then
call SetUnitState(t,UNIT_STATE_MANA,state+distribute)
set distribute=0.0
else
if state>0.0 then
call SetUnitState(t,UNIT_STATE_MANA,state-amt)
set distribute=distribute+amt
endif
endif
if GetUnitState(t,UNIT_STATE_MANA)!=state then
call DestroyEffect(AddSpecialEffectTarget(MANA_HIT,t,ATTACH))
endif
endif
endif
call GroupRemoveUnit(grp,t)
endloop
call GroupClear(grp)
else
set .dummy=null
set .caster=null
set .owner=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 onCast takes nothing returns nothing
local integer abi=GetSpellAbilityId()
local thistype this
local string fx
if abi==ABI_LIFE or abi==ABI_MANA then
set this=allocate()
set ix=ix+1
set ic[ix]=this
set .caster=GetTriggerUnit()
set .owner=GetOwningPlayer(.caster)
if abi==ABI_LIFE then
set fx=LIFE_MODEL
set .dtype=LIFE_TYPE
else
set fx=MANA_MODEL
set .dtype=MANA_TYPE
endif
if GetRandomInt(1,100)>50 then
set .dummy=DISTRIBUTOR_dummy.Add(null,fx,GetSpellTargetUnit(),RANGE,SPEED,GetRandomReal(0,360),HEIGHT,DURATION,false,true)
else
set .dummy=DISTRIBUTOR_dummy.Add(null,fx,GetSpellTargetUnit(),RANGE,SPEED,GetRandomReal(0,360),HEIGHT,DURATION,true,false)
endif
set .distribute=0.0
set abi=GetHandleId(.dummy)
call SaveInteger(DISTRIBUTOR_dummy.hash,abi,0,.dtype)
call SaveUnitHandle(DISTRIBUTOR_dummy.hash,abi,1,.caster)
set abi=GetHandleId(.caster)
if not HaveSavedHandle(DISTRIBUTOR_dummy.hash,abi,0) then
call SaveGroupHandle(DISTRIBUTOR_dummy.hash,abi,0,CreateGroup())
endif
call GroupAddUnit(LoadGroupHandle(DISTRIBUTOR_dummy.hash,abi,0),.dummy)
if ix==1 then
call TimerStart(tmr,PERIODIC,true,function thistype.onLoop)
endif
endif
endmethod
private static method onInit takes nothing returns nothing
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function thistype.onCast)
endmethod
endstruct
endscope
//TESH.scrollpos=292
//TESH.alwaysfold=0
scope DistributorSlam
globals
//*****************************************************************
//
// Determine the ability id of distributor slam
//
//*****************************************************************
private constant integer ABILITY_ID = 'A002'
//*****************************************************************
//
// Determine the model of life ball
//
//*****************************************************************
private constant string LIFE_MODEL = "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
//*****************************************************************
//
// Determine the model of mana ball
//
//*****************************************************************
private constant string MANA_MODEL = "Abilities\\Weapons\\FrostWyrmMissile\\FrostWyrmMissile.mdl"
//*****************************************************************
//
// Determine the effect of life slam
//
//*****************************************************************
private constant string LIFE_SLAM = "Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl"
//*****************************************************************
//
// Determine the effect of mana slam
//
//*****************************************************************
private constant string MANA_SLAM = "Objects\\Spawnmodels\\NightElf\\NEDeathSmall\\NEDeathSmall.mdl"
//*****************************************************************
//
// Determine the location of model attachment
//
//*****************************************************************
private constant string ATTACH = "origin"
//*****************************************************************
//
// Determine the attack type of life slam
//
//*****************************************************************
private constant attacktype ATK_TYPE = ATTACK_TYPE_MAGIC
//*****************************************************************
//
// Determine the damage type of life slam
//
//*****************************************************************
private constant damagetype DMG_TYPE = DAMAGE_TYPE_NORMAL
//*****************************************************************
//
// Determine the range of ball search
//
//*****************************************************************
private constant real SEARCH = 600.0
//*****************************************************************
//
// Determine the damage base amount of life ball
//
//*****************************************************************
private constant real DMG_LIFE = 75
//*****************************************************************
//
// Determine the damage base amount of mana ball
//
//*****************************************************************
private constant real DMG_MANA = 75
//*****************************************************************
//
// Determine the damage level amount of life ball
//
//*****************************************************************
private constant real DMG_LIFELV= 25
//*****************************************************************
//
// Determine the damage level amount of mana ball
//
//*****************************************************************
private constant real DMG_MANALV= 25
//*****************************************************************
//
// Determine the int percent amount damage will be
//
//*****************************************************************
private constant real DMG_INT = 3.50
//*****************************************************************
//
// Determine the life affect of area damage
//
//*****************************************************************
private constant real AOE = 200.0
//*****************************************************************
//
// Determine the raise height of balls
//
//*****************************************************************
private constant real Z_RAISE = 600.0
//*****************************************************************
//
// Determine the travel duration to Z Raise
//
//*****************************************************************
private constant real TRAVEL_DUR= 2.0
//*****************************************************************
//
// Determine the travel duration to target area
//
//*****************************************************************
private constant real SLAM_DUR = 0.50
//*****************************************************************
//
// Determine the travel duration to target area
//
//*****************************************************************
private constant real SLAM_INTER= 0.25
//*****************************************************************
//
// Determine the arc speed of ball
//
//*****************************************************************
private constant real ARC_SPEED = 15.0
//*****************************************************************
//
// Determine the airburn height to enemy exploded of life explotion
//
//*****************************************************************
private constant real AIR_BURN = 300.0
//*****************************************************************
//
// Determine the slow amount of mana explotion
//
//*****************************************************************
private constant real SLOW_AMT = 250.0
//*****************************************************************
//
// Determine the slow duration
//
//*****************************************************************
private constant real SLOW_DUR = 2.0
//*****************************************************************
//
// The followings are not configureable
//
//*****************************************************************
private constant real PERIODIC = 0.0312500
endglobals
private function Filters takes unit t returns boolean
return UnitAlive(t) and not IsUnitType(t,UNIT_TYPE_MAGIC_IMMUNE)
endfunction
private function DistanceBetweenXY takes real x1,real y1,real x2,real y2 returns real
local real dx=x2-x1
local real dy=y2-y1
return SquareRoot(dx*dx+dy*dy)
endfunction
private struct slam_cast
private static constant timer tmr=CreateTimer()
private static constant group grp=CreateGroup()
private static integer ix=0
private static integer array ic
private unit caster
private unit dummy
private player owner
private real dspeed
private real tspeed
private real zspeed
private real distc
private real distt
private real xc
private real yc
private real xt
private real yt
private real arnd
private real dmg
private string fx
private static method AddGroup takes nothing returns nothing
call GroupAddUnit(grp, GetEnumUnit())
endmethod
private static method onLoop takes nothing returns nothing
local thistype this
local integer i=1
local real x
local real y
local real a
local integer id
local unit t
loop
exitwhen i>ix
set this=ic[i]
set id=GetHandleId(dummy)
if not LoadBoolean(DISTRIBUTOR_dummy.hash,id,0) then
if distc>0.0 then
set distc=distc-dspeed
set x=GetUnitX(dummy)
set y=GetUnitY(dummy)
set a=bj_RADTODEG*Atan2(yc-y,xc-x)
set x=x+dspeed*Cos(a*bj_DEGTORAD)
set y=y+dspeed*Sin(a*bj_DEGTORAD)
set x=x+ARC_SPEED*Cos((a+arnd)*bj_DEGTORAD)
set y=y+ARC_SPEED*Sin((a+arnd)*bj_DEGTORAD)
call SetUnitX(dummy,x)
call SetUnitY(dummy,y)
call SetUnitFlyHeight(dummy,GetUnitFlyHeight(dummy)+zspeed,0.0)
if distc<=0.0 then
call DestroyEffect(LoadEffectHandle(DISTRIBUTOR_dummy.hash,id,0))
if LoadInteger(DISTRIBUTOR_dummy.hash,id,0)==1 then
call SaveEffectHandle(DISTRIBUTOR_dummy.hash,id,0,AddSpecialEffectTarget(LIFE_MODEL,dummy,ATTACH))
else
call SaveEffectHandle(DISTRIBUTOR_dummy.hash,id,0,AddSpecialEffectTarget(MANA_MODEL,dummy,ATTACH))
endif
set zspeed=Z_RAISE/(((distt/tspeed)*PERIODIC)/PERIODIC)
endif
elseif distt>0.0 then
set distt=distt-tspeed
set x=GetUnitX(dummy)
set y=GetUnitY(dummy)
set a=bj_RADTODEG*Atan2(yt-y,xt-x)
set x=x+tspeed*Cos(a*bj_DEGTORAD)
set y=y+tspeed*Sin(a*bj_DEGTORAD)
//set x=x+ARC_SPEED*Cos((a+arnd)*bj_DEGTORAD)
//set y=y+ARC_SPEED*Sin((a+arnd)*bj_DEGTORAD)
call SetUnitX(dummy,x)
call SetUnitY(dummy,y)
call SetUnitFlyHeight(dummy,GetUnitFlyHeight(dummy)-zspeed,0.0)
if distt<=0 then
call SaveBoolean(DISTRIBUTOR_dummy.hash,id,0,true)
call DestroyEffect(LoadEffectHandle(DISTRIBUTOR_dummy.hash,id,0))
set id=LoadInteger(DISTRIBUTOR_dummy.hash,id,0)
call GroupEnumUnitsInRange(grp,x,y,AOE,null)
loop
set t=FirstOfGroup(grp)
exitwhen t==null
if Filters(t) and not IsUnitAlly(t,owner) then
call UnitDamageTarget(caster,t,dmg,true,true,ATK_TYPE,DMG_TYPE,null)
if id==1 then
if GetUnitFlyHeight(t)<(AIR_BURN/4.0) then
call AirBurn.exe(t,AIR_BURN)
endif
else
call Slow.Add(t,SLOW_AMT,SLOW_DUR,false)
endif
endif
call GroupRemoveUnit(grp,t)
endloop
call GroupClear(grp)
call DestroyEffect(AddSpecialEffect(fx,x,y))
call KillUnit(dummy)
endif
endif
else
set caster=null
set dummy=null
set owner=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
set t=null
endmethod
private static method onCast takes nothing returns nothing
local thistype this
local unit u
local unit d
local real x1
local real y1
local real x2
local real y2
local real xt
local real yt
local real dist
local real dur
local player p
local integer lv
local integer id
set u=GetTriggerUnit()
set x1=GetUnitX(u)
set y1=GetUnitY(u)
set xt=GetSpellTargetX()
set yt=GetSpellTargetY()
set lv=GetUnitAbilityLevel(u,ABILITY_ID)
set id=GetHandleId(u)
call ForGroup(LoadGroupHandle(DISTRIBUTOR_dummy.hash,id,0),function thistype.AddGroup)
set dur=0
set p=GetOwningPlayer(u)
loop
set d=FirstOfGroup(grp)
exitwhen d==null
set id=GetHandleId(d)
set x2=GetUnitX(d)
set y2=GetUnitY(d)
set dist=DistanceBetweenXY(x2,y2,x1,y1)
if UnitAlive(d) and LoadBoolean(DISTRIBUTOR_dummy.hash,id,0) and dist<=SEARCH then
set this=allocate()
set ix=ix+1
set ic[ix]=this
set caster=u
set dummy=d
set owner=p
set xc=x1
set yc=y1
set distc=dist
set dist=GetRandomReal(-AOE,AOE)
set .xt=xt+dist*Cos(GetRandomReal(0,360)*bj_DEGTORAD)
set .yt=yt+dist*Sin(GetRandomReal(0,360)*bj_DEGTORAD)
set dur=dur+SLAM_INTER
set distt=DistanceBetweenXY(x1,y1,xt,yt)
set dspeed=distc/(TRAVEL_DUR/PERIODIC)
set tspeed=distt/(SLAM_DUR+dur/PERIODIC)
set zspeed=Z_RAISE/(TRAVEL_DUR/PERIODIC)
if GetRandomInt(1,100)>50 then
set arnd=90
else
set arnd=-90
endif
if IsUnitType(caster,UNIT_TYPE_HERO) then
set dmg=(GetHeroInt(caster,true)/100.0)*DMG_INT
else
set dmg=0.0
endif
if LoadInteger(DISTRIBUTOR_dummy.hash,id,0)==1 then
set dmg=dmg+(DMG_LIFE+(DMG_LIFELV*lv))
set fx=LIFE_SLAM
else
set dmg=dmg+(DMG_MANA+(DMG_MANALV*lv))
set fx=MANA_SLAM
endif
call UnitAddAbility(d,'Amrf')
call UnitRemoveAbility(d,'Amrf')
call SaveBoolean(DISTRIBUTOR_dummy.hash,id,0,false)
if ix==1 then
call TimerStart(tmr,PERIODIC,true,function thistype.onLoop)
endif
endif
call GroupRemoveUnit(grp,d)
endloop
call GroupClear(grp)
set u=null
set d=null
set p=null
endmethod
private static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(ABILITY_ID,function thistype.onCast)
endmethod
endstruct
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope DistributorSlingShot
globals
//*****************************************************************
//
// Determine the ability id of distributor slingshot
//
//*****************************************************************
private constant integer ABILITY_ID = 'A003'
//*****************************************************************
//
// Determine the model of life ball
//
//*****************************************************************
private constant string LIFE_MODEL = "Abilities\\Weapons\\KeeperGroveMissile\\KeeperGroveMissile.mdl"
//*****************************************************************
//
// Determine the model of mana ball
//
//*****************************************************************
private constant string MANA_MODEL = "Abilities\\Weapons\\BlackKeeperMissile\\BlackKeeperMissile.mdl"
//*****************************************************************
//
// Determine the effect of life slam
//
//*****************************************************************
private constant string LIFE_HIT = "Abilities\\Spells\\Undead\\ReplenishHealth\\ReplenishHealthCaster.mdl"
//*****************************************************************
//
// Determine the effect of mana slam
//
//*****************************************************************
private constant string MANA_HIT = "Abilities\\Spells\\Undead\\ReplenishMana\\ReplenishManaCaster.mdl"
//*****************************************************************
//
// Determine the location of model attachment
//
//*****************************************************************
private constant string ATTACH = "origin"
//*****************************************************************
//
// Determine the attack type of life slingshot
//
//*****************************************************************
private constant attacktype ATK_TYPE = ATTACK_TYPE_MAGIC
//*****************************************************************
//
// Determine the damage type of life slingshot
//
//*****************************************************************
private constant damagetype DMG_TYPE = DAMAGE_TYPE_NORMAL
//*****************************************************************
//
// Determine the range of ball search
//
//*****************************************************************
private constant real SEARCH = 600.0
//*****************************************************************
//
// Determine the damage base amount of life ball
//
//*****************************************************************
private constant real DMG_LIFE = 50
//*****************************************************************
//
// Determine the damage base amount of mana ball
//
//*****************************************************************
private constant real DMG_MANA = 50
//*****************************************************************
//
// Determine the damage level amount of life ball
//
//*****************************************************************
private constant real DMG_LIFELV = 25
//*****************************************************************
//
// Determine the damage level amount of mana ball
//
//*****************************************************************
private constant real DMG_MANALV = 25
//*****************************************************************
//
// Determine the int percent amount damage will be
//
//*****************************************************************
private constant real DMG_INT = 8.0
//*****************************************************************
//
// Determine the life affect of area damage
//
//*****************************************************************
private constant real AOE = 64.0
//*****************************************************************
//
// Determine the duration dummy before travel
//
//*****************************************************************
private constant real READY_DUR = 0.75
//*****************************************************************
//
// Determine the interval of each travels
//
//*****************************************************************
private constant real INTERVAL = 0.125
//*****************************************************************
//
// Determine the ready speed. must slow so it will look cooler
//
//*****************************************************************
private constant real RED_SPED = 2.0
//*****************************************************************
//
// Determine the travel speed
//
//*****************************************************************
private constant real SPEED = 50.0
//*****************************************************************
//
// Determine the penetrate distance
//
//*****************************************************************
private constant real PEN_DIST = 600.0
//*****************************************************************
//
// Determine the knockback distance
//
//*****************************************************************
private constant real KNOCK_BACK = 10.0
//*****************************************************************
//
// Determine the height of ball
//
//*****************************************************************
private constant real HEIGHT = 50.0
//*****************************************************************
//
// The followings are not configureable
//
//*****************************************************************
private constant real PERIODIC = 0.0312500
endglobals
private function Filters takes unit t returns boolean
return UnitAlive(t) and not IsUnitType(t,UNIT_TYPE_MAGIC_IMMUNE) and not IsUnitType(t,UNIT_TYPE_STRUCTURE)
endfunction
private function DistanceBetweenXY takes real x1,real y1,real x2,real y2 returns real
local real dx=x2-x1
local real dy=y2-y1
return SquareRoot(dx*dx+dy*dy)
endfunction
private struct slingshot_cast
private static constant timer tmr=CreateTimer()
private static constant group grp=CreateGroup()
private static integer ix=0
private static integer array ic
private unit caster
private unit target
private unit dummy
private real dmg
private real interval
private real dist
private group grup
private player owner
private string fx
private static method AddGroup takes nothing returns nothing
call GroupAddUnit(grp, GetEnumUnit())
endmethod
private static method onLoop takes nothing returns nothing
local thistype this
local integer i=1
local real x1
local real y1
local real x2
local real y2
local real a
local integer id
loop
exitwhen i>ix
set this=ic[i]
set x1=GetUnitX(dummy)
set y1=GetUnitY(dummy)
set id=GetHandleId(dummy)
call SetUnitFlyHeight(dummy,HEIGHT,0.0)
if not LoadBoolean(DISTRIBUTOR_dummy.hash,id,0) then
if interval>0.0 then
set interval=interval-PERIODIC
set x2=GetUnitX(target)
set y2=GetUnitY(target)
set a=bj_RADTODEG*Atan2(y2-y1,x2-x1)
set x1=x1-RED_SPED*Cos(a*bj_DEGTORAD)
set y1=y1-RED_SPED*Sin(a*bj_DEGTORAD)
call SetUnitX(dummy,x1)
call SetUnitY(dummy,y1)
call SetUnitFacing(dummy,a)
if interval<=0.0 then
set dist=dist+DistanceBetweenXY(x1,y1,x2,y2)
call DestroyEffect(LoadEffectHandle(DISTRIBUTOR_dummy.hash,id,0))
if LoadInteger(DISTRIBUTOR_dummy.hash,id,0)==1 then
call SaveEffectHandle(DISTRIBUTOR_dummy.hash,id,0,AddSpecialEffectTarget(LIFE_MODEL,dummy,ATTACH))
else
call SaveEffectHandle(DISTRIBUTOR_dummy.hash,id,0,AddSpecialEffectTarget(MANA_MODEL,dummy,ATTACH))
endif
endif
elseif dist>0.0 then
set dist=dist-SPEED
set a=GetUnitFacing(dummy)
set x1=x1+SPEED*Cos(a*bj_DEGTORAD)
set y1=y1+SPEED*Sin(a*bj_DEGTORAD)
call SetUnitX(dummy,x1)
call SetUnitY(dummy,y1)
call GroupEnumUnitsInRange(grp,x1,y1,AOE,null)
loop
set target=FirstOfGroup(grp)
exitwhen target==null
if Filters(target) and not IsUnitAlly(target,owner) and not IsUnitInGroup(target,grup) then
call GroupAddUnit(grup,target)
call UnitDamageTarget(caster,target,dmg,true,true,ATK_TYPE,DMG_TYPE,null)
call SetUnitX(target,GetUnitX(target)+KNOCK_BACK*Cos(a*bj_DEGTORAD))
call SetUnitY(target,GetUnitY(target)+KNOCK_BACK*Sin(a*bj_DEGTORAD))
call AddSpecialEffectTarget(fx,target,ATTACH)
endif
call GroupRemoveUnit(grp,target)
endloop
call GroupClear(grp)
if dist<=0.0 then
call SaveBoolean(DISTRIBUTOR_dummy.hash,id,0,true)
call DestroyEffect(LoadEffectHandle(DISTRIBUTOR_dummy.hash,id,0))
call KillUnit(dummy)
endif
endif
else
set caster=null
set target=null
set dummy=null
set owner=null
call GroupClear(grup)
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 onCast takes nothing returns nothing
local thistype this
local unit u
local unit t
local unit d
local real x1
local real y1
local real x2
local real y2
local real dur
local real dist
local integer lv
local integer id
local player p
set u=GetTriggerUnit()
set t=GetSpellTargetUnit()
set x1=GetUnitX(u)
set y1=GetUnitY(u)
set lv=GetUnitAbilityLevel(u,ABILITY_ID)
set id=GetHandleId(u)
set p=GetOwningPlayer(u)
set dur=0
call ForGroup(LoadGroupHandle(DISTRIBUTOR_dummy.hash,id,0),function thistype.AddGroup)
loop
set d=FirstOfGroup(grp)
exitwhen d==null
set id=GetHandleId(d)
set x2=GetUnitX(d)
set y2=GetUnitY(d)
set dist=DistanceBetweenXY(x2,y2,x1,y1)
if UnitAlive(d) and LoadBoolean(DISTRIBUTOR_dummy.hash,id,0) and dist<=SEARCH then
set this=allocate()
set ix=ix+1
set ic[ix]=this
set caster=u
set target=t
set dummy=d
set owner=p
set .dist=PEN_DIST
set dur=dur+INTERVAL
set interval=READY_DUR+dur
if grup==null then
set grup=CreateGroup()
else
call GroupClear(grup)
endif
if IsUnitType(caster,UNIT_TYPE_HERO) then
set dmg=(GetHeroInt(caster,true)/100.0)*DMG_INT
else
set dmg=0.0
endif
if LoadInteger(DISTRIBUTOR_dummy.hash,id,0)==1 then
set dmg=dmg+(DMG_LIFE+(DMG_LIFELV*lv))
set fx=LIFE_HIT
else
set dmg=dmg+(DMG_MANA+(DMG_MANALV*lv))
set fx=MANA_HIT
endif
call UnitAddAbility(d,'Amrf')
call UnitRemoveAbility(d,'Amrf')
call SaveBoolean(DISTRIBUTOR_dummy.hash,id,0,false)
if ix==1 then
call TimerStart(tmr,PERIODIC,true,function thistype.onLoop)
endif
endif
call GroupRemoveUnit(grp,d)
endloop
call GroupClear(grp)
endmethod
private static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(ABILITY_ID,function thistype.onCast)
endmethod
endstruct
endscope
//TESH.scrollpos=42
//TESH.alwaysfold=0
scope DistributorDragon
globals
//*****************************************************************
//
// Determine the ability id of distributor dragon
//
//*****************************************************************
private constant integer ABILITY_ID = 'A004'
//*****************************************************************
//
// Determine the unit type id of dummy
// Note: Make sure to import the dummy model
//
//*****************************************************************
private constant integer DUMMY_ID = 'u000'
//*****************************************************************
//
// Determine the model of life dragon
//
//*****************************************************************
private constant integer LIFE_DRAGON = 'nrwm'
//*****************************************************************
//
// Determine the model of mana dragon
//
//*****************************************************************
private constant integer MANA_DRAGON = 'nadr'
//*****************************************************************
//
// Determine the model of life ball
//
//*****************************************************************
private constant string LIFE_MODEL = "Abilities\\Spells\\Undead\\UnholyAura\\UnholyAura.mdl"
//*****************************************************************
//
// Determine the model of mana ball
//
//*****************************************************************
private constant string MANA_MODEL = "Abilities\\Spells\\Undead\\VampiricAura\\VampiricAura.mdl"
//*****************************************************************
//
// Determine the location of model attachment
//
//*****************************************************************
private constant string ATTACH = "origin"
//*****************************************************************
//
// Determine the range of ball search
//
//*****************************************************************
private constant real SEARCH = 600.0
//*****************************************************************
//
// Determine the interval of hatch
//
//*****************************************************************
private constant real HATCH_INTER = 3.0
//*****************************************************************
//
// Determine the interval of spawning
//
//*****************************************************************
private constant real SPAWN_INTER = 1.5
//*****************************************************************
//
// Determine the duration of dragon
//
//*****************************************************************
private constant real DURATION = 10.0
//*****************************************************************
//
// Determine the additional duration of each level
//
//*****************************************************************
private constant real DURATIONLV = 5.0
//*****************************************************************
//
// Determine the max size of spawn effect
//
//*****************************************************************
private constant real SPAWN_SCALE = 3.0
//*****************************************************************
//
// Determine the max size of spawn effect
//
//*****************************************************************
private constant real HATCH_SCALE = 30.0
//*****************************************************************
//
// Determine the max size of dragon
//
//*****************************************************************
private constant real DRAGON_SCALE= 1.75
//*****************************************************************
//
// Determine the effect of life slam
//
//*****************************************************************
private constant player OWNER = Player(PLAYER_NEUTRAL_PASSIVE)
private constant real PERIODIC = 0.0312500
endglobals
private function Filters takes unit t returns boolean
return UnitAlive(t) and not IsUnitType(t,UNIT_TYPE_MAGIC_IMMUNE) and not IsUnitType(t,UNIT_TYPE_STRUCTURE)
endfunction
private function DistanceBetweenXY takes real x1,real y1,real x2,real y2 returns real
local real dx=x2-x1
local real dy=y2-y1
return SquareRoot(dx*dx+dy*dy)
endfunction
private struct dragon_cast
private static constant timer tmr=CreateTimer()
private static constant group grp=CreateGroup()
private static integer ix=0
private static integer array ic
private unit caster
private unit dummy
private unit dragon
private unit spawndummy
private real spawninterval
private real hatchinterval
private real duration
private player owner
private effect fx
private static method AddGroup takes nothing returns nothing
call GroupAddUnit(grp, GetEnumUnit())
endmethod
private static method onLoop takes nothing returns nothing
local thistype this
local integer i=1
local integer id
local real scale
local real a
loop
exitwhen i>ix
set this=ic[i]
set a=GetUnitFacing(dummy)
set id=GetHandleId(dummy)
if not LoadBoolean(DISTRIBUTOR_dummy.hash,id,0) then
if spawninterval>0.0 then
set spawninterval=spawninterval-PERIODIC
if hatchinterval<=0.0 then
set scale=(SPAWN_SCALE/SPAWN_INTER)*spawninterval
call SetUnitFacing(spawndummy,((360.0/SPAWN_INTER)-(SPAWN_INTER-spawninterval))+a)
call SetUnitFacing(dragon,((360.0/SPAWN_INTER)-(SPAWN_INTER-spawninterval))+a)
set a=(DRAGON_SCALE/SPAWN_INTER)*(SPAWN_INTER-spawninterval)
call SetUnitScale(dragon,a,a,a)
call SetUnitPosition(dragon,GetUnitX(dummy),GetUnitY(dummy))
if spawninterval<=0.0 then
call PauseUnit(dragon,false)
call UnitApplyTimedLife(dragon,'BTLF',duration)
call SaveBoolean(DISTRIBUTOR_dummy.hash,id,0,true)
call KillUnit(dummy)
call DestroyEffect(fx)
call KillUnit(spawndummy)
endif
else
set scale=(SPAWN_SCALE/SPAWN_INTER)*(SPAWN_INTER-spawninterval)
endif
call SetUnitScale(spawndummy,scale,scale,scale)
elseif hatchinterval>0.0 then
set hatchinterval=hatchinterval-PERIODIC
set scale=(HATCH_SCALE/HATCH_INTER)*(HATCH_INTER-hatchinterval)
call SetUnitFacing(spawndummy,((360.0/HATCH_INTER)-(HATCH_INTER-hatchinterval))+a)
call SetUnitScale(dummy,scale,scale,scale)
if hatchinterval<=0.0 then
call DestroyEffect(LoadEffectHandle(DISTRIBUTOR_dummy.hash,id,0))
set spawninterval=SPAWN_INTER
if LoadInteger(DISTRIBUTOR_dummy.hash,id,0)==1 then
set dragon=CreateUnit(owner,LIFE_DRAGON,GetUnitX(dummy),GetUnitY(dummy),a)
else
set dragon=CreateUnit(owner,MANA_DRAGON,GetUnitX(dummy),GetUnitY(dummy),a)
endif
call SetUnitScale(dragon,0.10,0.10,0.10)
call PauseUnit(dragon,true)
endif
endif
else
set caster=null
set spawndummy=null
set dummy=null
set owner=null
set dragon=null
set fx=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 onCast takes nothing returns nothing
local thistype this
local unit u
local unit d
local real x1
local real y1
local real x2
local real y2
local integer lv
local integer id
local player p
set u=GetTriggerUnit()
set x1=GetUnitX(u)
set y1=GetUnitY(u)
set lv=GetUnitAbilityLevel(u,ABILITY_ID)
set id=GetHandleId(u)
set p=GetOwningPlayer(u)
call ForGroup(LoadGroupHandle(DISTRIBUTOR_dummy.hash,id,0),function thistype.AddGroup)
loop
set d=FirstOfGroup(grp)
exitwhen d==null
set id=GetHandleId(d)
set x2=GetUnitX(d)
set y2=GetUnitY(d)
if UnitAlive(d) and LoadBoolean(DISTRIBUTOR_dummy.hash,id,0) and DistanceBetweenXY(x2,y2,x1,y1)<=SEARCH then
set this=allocate()
set ix=ix+1
set ic[ix]=this
set caster=u
set dummy=d
set owner=p
set dragon=null
set duration=DURATION+(DURATIONLV*lv)
set spawninterval=SPAWN_INTER
set hatchinterval=HATCH_INTER
set spawndummy=CreateUnit(OWNER,DUMMY_ID,x2,y2,GetUnitFacing(dummy))
call SetUnitScale(spawndummy,0.10,0.10,0.10)
if LoadInteger(DISTRIBUTOR_dummy.hash,id,0)==1 then
set fx=AddSpecialEffectTarget(LIFE_MODEL,spawndummy,ATTACH)
else
set fx=AddSpecialEffectTarget(MANA_MODEL,spawndummy,ATTACH)
endif
call SaveBoolean(DISTRIBUTOR_dummy.hash,id,0,false)
if ix==1 then
call TimerStart(tmr,PERIODIC,true,function thistype.onLoop)
endif
endif
call GroupRemoveUnit(grp,d)
endloop
call GroupClear(grp)
endmethod
private static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(ABILITY_ID,function thistype.onCast)
endmethod
endstruct
endscope
//TESH.scrollpos=21
//TESH.alwaysfold=0
scope DistributorReunion
globals
//*****************************************************************
//
// Determine the ability id of distributor reunion
//
//*****************************************************************
private constant integer ABILITY_ID = 'A005'
//*****************************************************************
//
// Determine the speed of ball
// -Basing to range
// -100 Max,could be heigher but plays unpleasing
//
//*****************************************************************
private constant real SPEED = 5.0
endglobals
private struct reunion_cast extends array
private static constant group grp=CreateGroup()
private static method AddGroup takes nothing returns nothing
call GroupAddUnit(grp, GetEnumUnit())
endmethod
private static method onCast takes nothing returns nothing
local unit u
local unit d
local real x1
local real y1
local real x2
local real y2
local integer id
set u=GetTriggerUnit()
set x1=GetUnitX(u)
set y1=GetUnitY(u)
set id=GetHandleId(u)
call ForGroup(LoadGroupHandle(DISTRIBUTOR_dummy.hash,id,0),function thistype.AddGroup)
loop
set d=FirstOfGroup(grp)
exitwhen d==null
set id=GetHandleId(d)
if UnitAlive(d) and LoadBoolean(DISTRIBUTOR_dummy.hash,id,0) then
set x2=GetUnitX(u)
set y2=GetUnitY(u)
set y2=bj_RADTODEG*Atan2(y1-y2,x1-x2)
if y2<0.0 then
set y2=y2+360.0
endif
call DISTRIBUTOR_dummy.Add(d,"",null,600,SPEED,y2,50.0,1.0,true,false)
endif
call GroupRemoveUnit(grp,d)
endloop
call GroupClear(grp)
endmethod
private static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(ABILITY_ID,function thistype.onCast)
endmethod
endstruct
endscope
//TESH.scrollpos=57
//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