//TESH.scrollpos=0
//TESH.alwaysfold=0
Name | Type | is_array | initial_value |
AttractorBall | unit | Yes | |
AttractorInstances | integer | No | |
AttractorSpeed | real | Yes | |
FireChainBalls | unit | Yes | |
FireChainInstances | integer | No | |
FireChainLength | real | Yes | |
FireChainSpeed | real | Yes | |
FireChainTarget | unit | Yes | |
HomingBall | unit | Yes | |
HomingInstances | integer | No | |
HomingSpeed | real | Yes | |
HomingTarget | unit | Yes | |
RepulsionCaster | unit | Yes | |
RepulsionInstances | integer | No | |
RepulsionLength | real | Yes |
//TESH.scrollpos=0
//TESH.alwaysfold=0
library TerrainPathability initializer Init
//******************************************************************************
//* BY: Rising_Dusk
//*
//* This script can be used to detect the type of pathing at a specific point.
//* It is valuable to do it this way because the IsTerrainPathable is very
//* counterintuitive and returns in odd ways and aren't always as you would
//* expect. This library, however, facilitates detecting those things reliably
//* and easily.
//*
//******************************************************************************
//*
//* > function IsTerrainDeepWater takes real x, real y returns boolean
//* > function IsTerrainShallowWater takes real x, real y returns boolean
//* > function IsTerrainLand takes real x, real y returns boolean
//* > function IsTerrainPlatform takes real x, real y returns boolean
//* > function IsTerrainWalkable takes real x, real y returns boolean
//*
//* These functions return true if the given point is of the type specified
//* in the function's name and false if it is not. For the IsTerrainWalkable
//* function, the MAX_RANGE constant below is the maximum deviation range from
//* the supplied coordinates that will still return true.
//*
//* The IsTerrainPlatform works for any preplaced walkable destructable. It will
//* return true over bridges, destructable ramps, elevators, and invisible
//* platforms. Walkable destructables created at runtime do not create the same
//* pathing hole as preplaced ones do, so this will return false for them. All
//* other functions except IsTerrainWalkable return false for platforms, because
//* the platform itself erases their pathing when the map is saved.
//*
//* After calling IsTerrainWalkable(x, y), the following two global variables
//* gain meaning. They return the X and Y coordinates of the nearest walkable
//* point to the specified coordinates. These will only deviate from the
//* IsTerrainWalkable function arguments if the function returned false.
//*
//* Variables that can be used from the library:
//* [real] TerrainPathability_X
//* [real] TerrainPathability_Y
//*
globals
private constant real MAX_RANGE = 10.
private constant integer DUMMY_ITEM_ID = 'wolg'
endglobals
globals
private item Item = null
private rect Find = null
private item array Hid
private integer HidMax = 0
public real X = 0.
public real Y = 0.
endglobals
function IsTerrainDeepWater takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
endfunction
function IsTerrainShallowWater takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
endfunction
function IsTerrainLand takes real x, real y returns boolean
return IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY)
endfunction
function IsTerrainPlatform takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
endfunction
private function HideItem takes nothing returns nothing
if IsItemVisible(GetEnumItem()) then
set Hid[HidMax] = GetEnumItem()
call SetItemVisible(Hid[HidMax], false)
set HidMax = HidMax + 1
endif
endfunction
function IsTerrainWalkable takes real x, real y returns boolean
//Hide any items in the area to avoid conflicts with our item
call MoveRectTo(Find, x, y)
call EnumItemsInRect(Find ,null, function HideItem)
//Try to move the test item and get its coords
call SetItemPosition(Item, x, y) //Unhides the item
set X = GetItemX(Item)
set Y = GetItemY(Item)
static if LIBRARY_IsTerrainWalkable then
//This is for compatibility with the IsTerrainWalkable library
set IsTerrainWalkable_X = X
set IsTerrainWalkable_Y = Y
endif
call SetItemVisible(Item, false)//Hide it again
//Unhide any items hidden at the start
loop
exitwhen HidMax <= 0
set HidMax = HidMax - 1
call SetItemVisible(Hid[HidMax], true)
set Hid[HidMax] = null
endloop
//Return walkability
return (X-x)*(X-x)+(Y-y)*(Y-y) <= MAX_RANGE*MAX_RANGE and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
endfunction
private function Init takes nothing returns nothing
set Find = Rect(0., 0., 128., 128.)
set Item = CreateItem(DUMMY_ITEM_ID, 0, 0)
call SetItemVisible(Item, false)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library BoundSentinel initializer init
//*************************************************
//* BoundSentinel
//* -------------
//* Don't leave your units unsupervised, naughty
//* them may try to get out of the map bounds and
//* crash your game.
//*
//* To implement, just get a vJass compiler and
//* copy this library/trigger to your map.
//*
//*************************************************
//==================================================
globals
// High enough so the unit is no longer visible, low enough so the
// game doesn't crash...
//
// I think you need 0.0 or soemthing negative prior to patch 1.22
//
private constant real EXTRA = 500.0
endglobals
//=========================================================================================
globals
private real maxx
private real maxy
private real minx
private real miny
endglobals
//=======================================================================
private function dis takes nothing returns nothing
local unit u=GetTriggerUnit()
local real x=GetUnitX(u)
local real y=GetUnitY(u)
if(x>maxx) then
set x=maxx
elseif(x<minx) then
set x=minx
endif
if(y>maxy) then
set y=maxy
elseif(y<miny) then
set y=miny
endif
call SetUnitX(u,x)
call SetUnitY(u,y)
set u=null
endfunction
private function init takes nothing returns nothing
local trigger t=CreateTrigger()
local region r=CreateRegion()
local rect rc
set minx=GetCameraBoundMinX() - EXTRA
set miny=GetCameraBoundMinY() - EXTRA
set maxx=GetCameraBoundMaxX() + EXTRA
set maxy=GetCameraBoundMaxY() + EXTRA
set rc=Rect(minx,miny,maxx,maxy)
call RegionAddRect(r, rc)
call RemoveRect(rc)
call TriggerRegisterLeaveRegion(t,r, null)
call TriggerAddAction(t, function dis)
//this is not necessary but I'll do it anyway:
set t=null
set r=null
set rc=null
endfunction
endlibrary
//TESH.scrollpos=486
//TESH.alwaysfold=0
library ZPhysixMaster initializer init
//************************
//Physix Master Spellpack
//Made by Alien@System
//
//required ressources: Jass New Gen Pack
//recommended ressources: Bound Sentinel (by Vexorian)
//optional ressources: TerrainPathability (by Rising_Dusk)
//
//Contains:
//
//Holy Chain: Summons 2 Balls of Light which will fly into the target direction. The balls are connected by an invisible Spring which follows Hooke's law.
// When hitting a unit, the balls will stick to them, healing or damaging their target proportional to the length of the spring.
// The Units death will release the balls again. Should the balls come to close to eachother or stick on the same unit, they will deal damage to their targets and explode.
//
//Divine Attractor: Summons a Ball of godly might which will fly towards the target direction and attracts all Physics objects (Holy Chains, Divine Attractors and Gods Fists) with Newtons law.
//
//Gods Fist: Summons an inert Missile which will accelerates towards he target, but is slowed down by friction. Upon hit, it heals or damages the target.
//
//Repulsion: Repulses all Physics objects (Holy Chains, Divine Attractors and Gods Fists) with an inverse Newtons law.
//
//If TerrainPathability is imported in your map, the objects will be reflected from unpathable areas.
//
//Comments:
//Highly configurable - all data can be changed according to you needs and are instance-spezific
//Does not support channeled spells
//
//How to import:
//Copy this library into your map.
//*******************
globals
//general Physics Data
private constant real intervall=0.03125
private constant timer AllTimer=CreateTimer()
private constant integer DurID='BTLF' //The Buff for the timed life
private constant real TerrainZDetectionSize = 5
private constant real TerrainZInfluenceFactor = 0.1
//general Physics System Data
private location loc=Location(0,0)
private real XGradient=0
private real YGradient=0
//Holy Chain static Data
private constant real HCSize=50 //How close a Ball must come to a unit to stick to it
private constant real HCDfSize=32 //How close the Balls must come to produce a double-free
//Holy Chain System Variables
private integer HCInstances=0
private unit array HCBalls
private real array HCSpeed
private unit array HCVictims
private real array HCLength
private real array HCDpsFactor
private real array HCHpsFactor
private real array HCDfDamage
private real array HCD
private real array HCFriction
private real array HCGradientFactor
private integer array HCExplosion
//Divine Attractor static Data
private constant real DAsSize=4096 //To prevent the infinite gravitation hole, there is a radius cap in which the balls will not be attracted. This value is the square of this radius.
//Divine Attractor System Variables
private integer DAInstances=0
private unit array DABalls
private real array DASpeed
private real array DAGamma
private real array DAHCGamma
private real array DAGFGamma
private real array DAFriction
private real array DAGradientFactor
//Gods Fist static Data
private constant real GFSize= 1024 //How close the Fist must come to the target to hit. This value is the square of this radius
//Gods Fist System Variables
private group TempGroup=CreateGroup()
private integer GFInstances=0
private unit array GFBalls
private unit array GFTargets
private real array GFSpeed
private real array GFFriction
private real array GFAcceleration
private real array GFDamage
private real array GFHeal
private real array GFGradientFactor
//Repulsion static Data
private constant real RsSize=1024 //"Schwarzschild Radius" of the Repulsion. Inside the circle with the square root of this value as radius, the repulsion wont work.
//Repulsion System Variables
private integer RInstances=0
private real array RLength
private real array RPosition
private unit array RCaster
private real array RHCGamma
private real array RDAGamma
private real array RGFGamma
endglobals
private function GetGradient takes real X, real Y returns nothing
local real Zw
local real Ze
local real Zn
local real Zs
call MoveLocation(loc,X+TerrainZDetectionSize,Y)
set Ze=GetLocationZ(loc)
call MoveLocation(loc,X-TerrainZDetectionSize,Y)
set Zw=GetLocationZ(loc)
call MoveLocation(loc,X,Y+TerrainZDetectionSize)
set Zn=GetLocationZ(loc)
call MoveLocation(loc,X,Y-TerrainZDetectionSize)
set Zs=GetLocationZ(loc)
set XGradient=(Ze-Zw)/TerrainZDetectionSize
set YGradient=(Zn-Zs)/TerrainZDetectionSize
endfunction
private function GetReflection takes real X, real Y, real vX, real vY returns integer //0-no reflection, 1-horizontal, 2-vertikal, 3-negative speed
local boolean vert
local boolean hor
if IsTerrainWalkable(X+vX,Y+vY) then
return 0
endif
set vert=IsTerrainWalkable(X-vX,Y+vY)
set hor=IsTerrainWalkable(X+vX,Y-vY)
if (not vert and not hor) or (hor and vert) then
return 3
endif
if not vert then
return 2
endif
return 1
endfunction
private function beFilterfunction takes nothing returns boolean //a general Filter function wich detects vulnerable, not magic immune, alive units which are neither dummy nor structure
local unit u=GetFilterUnit()
return GetUnitAbilityLevel(u, 'Avul' ) <= 0 and not IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE) and GetUnitAbilityLevel(u, 'Aloc' ) <= 0 and not IsUnitType(u, UNIT_TYPE_DEAD) and not IsUnitType(u, UNIT_TYPE_STRUCTURE)
endfunction
function CreateGF takes real X, real Y,player Owner, unit victim,integer DummyID, real StartSpeed, real Duration, real Friction, real Acceleration, real Damage, real Heal, real GradientFactor returns integer
local real x1=GetUnitX(victim)
local real y1=GetUnitY(victim)
local real angle=Atan2(y1-Y,x1-X)
local real dx=Cos(angle)
local real dy=Sin(angle)
set StartSpeed=StartSpeed*intervall
set GFBalls[GFInstances]=CreateUnit( Owner,DummyID,X,Y,0)
set GFSpeed[2*GFInstances]=StartSpeed*dx
set GFSpeed[2*GFInstances+1]=StartSpeed*dy
set GFTargets[GFInstances]=victim
set GFFriction[GFInstances]=Pow(Friction,intervall)
set GFAcceleration[GFInstances]=Acceleration*intervall
set GFDamage[GFInstances]=Damage
set GFHeal[GFInstances]=Heal
set GFGradientFactor[GFInstances]=GradientFactor*intervall
call UnitApplyTimedLife(GFBalls[GFInstances], DurID, Duration )
set GFInstances=GFInstances+1
return GFInstances
endfunction
function CreateDA takes real X, real Y, real TargetX, real TargetY, player Owner, integer DummyID, real StartSpeed, real Duration,real DaGamma,real HCGamma,real GFGamma, real Friction, real GradientFactor returns integer
local real angle=Atan2(TargetY-Y,TargetX-X)
local real dx=Cos(angle)
local real dy=Sin(angle)
set StartSpeed=StartSpeed*intervall
set DABalls[DAInstances]=CreateUnit(Owner,DummyID,X,Y,0)
set DASpeed[2*DAInstances]=StartSpeed*dx
set DASpeed[2*DAInstances+1]=StartSpeed*dy
set DAGamma[DAInstances]=DaGamma*intervall
set DAGFGamma[DAInstances]=GFGamma*intervall
set DAHCGamma[DAInstances]=HCGamma*intervall
set DAFriction[DAInstances]=Pow(Friction,intervall)
set DAGradientFactor[DAInstances]=GradientFactor*intervall
call UnitApplyTimedLife(DABalls[DAInstances], DurID, Duration )
set DAInstances=DAInstances+1
return DAInstances
endfunction
function CreateHC takes real X, real Y, real TargetX, real TargetY, player Owner, integer DummyID, real StartSpeed, real StartLength, real Length, real Duration, real Dps, real Hps, real D, real DfDamage, real Friction, real GradientFactor, integer ExplosionID returns integer
local real angle=Atan2(TargetY-Y,TargetX-X)
local real dx=Cos(angle)
local real dy=Sin(angle)
set HCBalls[2*HCInstances]=CreateUnit(Owner,DummyID,X+StartLength/2*dy,Y-StartLength/2*dx,0)
call UnitApplyTimedLife( HCBalls[2*HCInstances], DurID,Duration )
set HCBalls[2*HCInstances+1]=CreateUnit(Owner,DummyID,X-StartLength/2*dy,Y+StartLength/2*dx,0)
call UnitApplyTimedLife( HCBalls[2*HCInstances+1], DurID, Duration )
set HCSpeed[4*HCInstances]=StartSpeed*dx*intervall
set HCSpeed[4*HCInstances+1]=StartSpeed*dy*intervall
set HCSpeed[4*HCInstances+2]=HCSpeed[4*HCInstances]
set HCSpeed[4*HCInstances+3]=HCSpeed[4*HCInstances+1]
set HCVictims[2*HCInstances]=null
set HCVictims[2*HCInstances+1]=null
set HCLength[HCInstances]=Length
set HCDpsFactor[HCInstances]=Dps*intervall
set HCHpsFactor[HCInstances]=Hps*intervall
set HCD[HCInstances]=D*intervall
set HCDfDamage[HCInstances]=DfDamage
set HCFriction[HCInstances]=Pow(Friction,intervall)
set HCGradientFactor[HCInstances]=GradientFactor*intervall
set HCExplosion[HCInstances]=ExplosionID
set HCInstances =HCInstances + 1
return HCInstances
endfunction
function CreateRep takes real X, real Y, real Duration, real HCGamma, real GFGamma, real DaGamma returns integer
set RPosition[2*RInstances]=X
set RPosition[2*RInstances+1]=Y
set RLength[RInstances]=Duration/intervall
set RHCGamma[RInstances]=HCGamma*intervall
set RGFGamma[RInstances]=GFGamma*intervall
set RDAGamma[RInstances]=DaGamma*intervall
set RCaster[RInstances]=null
set RInstances=RInstances+1
return RInstances
endfunction
function CreateRepOnUnit takes unit Caster, real Duration, real HCGamma, real GFGamma, real DaGamma returns integer
set RPosition[2*RInstances]=0
set RPosition[2*RInstances+1]=0
set RLength[RInstances]=Duration/intervall
set RHCGamma[RInstances]=HCGamma*intervall
set RGFGamma[RInstances]=GFGamma*intervall
set RDAGamma[RInstances]=DaGamma*intervall
set RCaster[RInstances]=Caster
set RInstances=RInstances+1
return RInstances
endfunction
private function HCLoop takes nothing returns nothing
local unit u1
local unit u2
local unit victim
local integer LoopIndex=0
local integer IndexLoop
local real r
local real x1
local real x2
local real y1
local real y2
local real dx
local real dy
local player owner
local integer Reflection
loop
set u1=HCBalls[2*LoopIndex]
set u2=HCBalls[2*LoopIndex+1]
set x1=GetUnitX(u1)
set x2=GetUnitX(u2)
set y1=GetUnitY(u1)
set y2=GetUnitY(u2)
set owner=GetOwningPlayer(u1)
if IsUnitType(u1, UNIT_TYPE_DEAD)==false then
set r=SquareRoot((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
if r>= HCDfSize then //32 is the smallest collision-size of units, meaning that you can only double-free if the two balls are really on the same unit.
set dx=(HCLength[LoopIndex]-r)*(x1-x2)/r*HCD[LoopIndex]
set dy=(HCLength[LoopIndex]-r)*(y1-y2)/r*HCD[LoopIndex]
if HCVictims[2*LoopIndex]==null then
if HCGradientFactor[LoopIndex]>0 then
call GetGradient(x1,y1)
else
set XGradient=0
set YGradient=0
endif
set HCSpeed[4*LoopIndex]=HCSpeed[4*LoopIndex]*HCFriction[LoopIndex]+dx-HCGradientFactor[LoopIndex]*XGradient
set HCSpeed[4*LoopIndex+1]=HCSpeed[4*LoopIndex+1]*HCFriction[LoopIndex]+dy-HCGradientFactor[LoopIndex]*YGradient
static if LIBRARY_TerrainPathability then
set Reflection=GetReflection(x1,y1,HCSpeed[4*LoopIndex],HCSpeed[4*LoopIndex+1])
if Reflection==1 then
set HCSpeed[4*LoopIndex]=-HCSpeed[4*LoopIndex]
endif
if Reflection==2 then
set HCSpeed[4*LoopIndex+1]=-HCSpeed[4*LoopIndex+1]
endif
if Reflection==3 then
set HCSpeed[4*LoopIndex]=-HCSpeed[4*LoopIndex]
set HCSpeed[4*LoopIndex+1]=-HCSpeed[4*LoopIndex+1]
endif
endif
call SetUnitX(u1, x1+HCSpeed[4*LoopIndex])
call SetUnitY(u1, y1+HCSpeed[4*LoopIndex+1])
set TempGroup=CreateGroup()
call GroupEnumUnitsInRange(TempGroup,x1,y1,HCSize, Condition(function beFilterfunction))
set HCVictims[2*LoopIndex]=FirstOfGroup(TempGroup)
call GroupClear(TempGroup)
else
if not IsUnitType(HCVictims[2*LoopIndex], UNIT_TYPE_DEAD) then
call SetUnitX(u1,GetUnitX(HCVictims[2*LoopIndex]))
call SetUnitY(u1,GetUnitY(HCVictims[2*LoopIndex]))
if IsUnitAlly(HCVictims[2*LoopIndex],owner) then
call SetWidgetLife(HCVictims[2*LoopIndex], GetWidgetLife(HCVictims[2*LoopIndex])+r*HCHpsFactor[LoopIndex])
else
call UnitDamageTarget(u2,HCVictims[2*LoopIndex], r*HCDpsFactor[LoopIndex], false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPIRIT_LINK, WEAPON_TYPE_WHOKNOWS)
endif
else
set HCVictims[2*LoopIndex]=null
set HCSpeed[4*LoopIndex]=0
set HCSpeed[4*LoopIndex+1]=0
endif
endif
if HCVictims[2*LoopIndex+1]==null then
if HCGradientFactor[LoopIndex]>0 then
call GetGradient(x2,y2)
else
set XGradient=0
set YGradient=0
endif
set HCSpeed[4*LoopIndex+2]=HCSpeed[4*LoopIndex+2]*HCFriction[LoopIndex]-dx-HCGradientFactor[LoopIndex]*XGradient
set HCSpeed[4*LoopIndex+3]=HCSpeed[4*LoopIndex+3]*HCFriction[LoopIndex]-dy-HCGradientFactor[LoopIndex]*YGradient
static if LIBRARY_TerrainPathability then
set Reflection=GetReflection(x2,y2,HCSpeed[4*LoopIndex+2],HCSpeed[4*LoopIndex+3])
if Reflection==1 then
set HCSpeed[4*LoopIndex+2]=-HCSpeed[4*LoopIndex+2]
endif
if Reflection==2 then
set HCSpeed[4*LoopIndex+3]=-HCSpeed[4*LoopIndex+3]
endif
if Reflection==3 then
set HCSpeed[4*LoopIndex+2]=-HCSpeed[4*LoopIndex+2]
set HCSpeed[4*LoopIndex+3]=-HCSpeed[4*LoopIndex+3]
endif
endif
call SetUnitX(u2, x2+HCSpeed[4*LoopIndex+2])
call SetUnitY(u2, y2+HCSpeed[4*LoopIndex+3])
set TempGroup=CreateGroup()
call GroupEnumUnitsInRange(TempGroup,x2,y2,HCSize,Condition(function beFilterfunction))
set HCVictims[2*LoopIndex+1]=FirstOfGroup(TempGroup)
call GroupClear(TempGroup)
else
if IsUnitType(HCVictims[2*LoopIndex+1],UNIT_TYPE_DEAD)==false then
call SetUnitX(u2, GetUnitX(HCVictims[2*LoopIndex+1]))
call SetUnitY(u2, GetUnitY(HCVictims[2*LoopIndex+1]))
if IsUnitAlly(HCVictims[2*LoopIndex+1],owner) then
call SetWidgetLife(HCVictims[2*LoopIndex+1], GetWidgetLife(HCVictims[2*LoopIndex+1])+r*HCHpsFactor[LoopIndex])
else
call UnitDamageTarget(u1,HCVictims[2*LoopIndex+1], r*HCDpsFactor[LoopIndex], false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPIRIT_LINK, WEAPON_TYPE_WHOKNOWS)
endif
else
set HCVictims[2*LoopIndex+1]=null
set HCSpeed[4*LoopIndex+2]=0
set HCSpeed[4*LoopIndex+3]=0
endif
endif
set LoopIndex = LoopIndex + 1
else
set IndexLoop=LoopIndex+1
call RemoveUnit(u1)
call RemoveUnit(u2)
call KillUnit(CreateUnit(owner,HCExplosion[LoopIndex],x1,y1,0))
call KillUnit(CreateUnit(owner,HCExplosion[LoopIndex],x2,y2,0))
call UnitDamageTarget(u1,HCVictims[2*LoopIndex], HCDfDamage[LoopIndex], false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPIRIT_LINK, WEAPON_TYPE_WHOKNOWS)
call UnitDamageTarget(u2,HCVictims[2*LoopIndex+1], HCDfDamage[LoopIndex], false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPIRIT_LINK, WEAPON_TYPE_WHOKNOWS)
loop
set HCSpeed[4*IndexLoop-4]=HCSpeed[4*IndexLoop]
set HCSpeed[4*IndexLoop-3]=HCSpeed[4*IndexLoop+1]
set HCSpeed[4*IndexLoop-2]=HCSpeed[4*IndexLoop+2]
set HCSpeed[4*IndexLoop-1]=HCSpeed[4*IndexLoop+3]
set HCBalls[2*IndexLoop-2]=HCBalls[2*IndexLoop]
set HCBalls[2*IndexLoop-1]=HCBalls[2*IndexLoop+1]
set HCVictims[2*IndexLoop-2]=HCVictims[2*IndexLoop]
set HCVictims[2*IndexLoop-1]=HCVictims[2*IndexLoop+1]
set HCGradientFactor[IndexLoop-1]=HCGradientFactor[IndexLoop]
set HCFriction[IndexLoop-1]=HCGradientFactor[IndexLoop]
set IndexLoop=IndexLoop+1
exitwhen IndexLoop>HCInstances
endloop
set HCInstances = HCInstances -1
endif
else
call KillUnit(u1)
call KillUnit(u2)
set IndexLoop=LoopIndex+1
loop
set HCSpeed[4*IndexLoop-4]=HCSpeed[4*IndexLoop]
set HCSpeed[4*IndexLoop-3]=HCSpeed[4*IndexLoop+1]
set HCSpeed[4*IndexLoop-2]=HCSpeed[4*IndexLoop+2]
set HCSpeed[4*IndexLoop-1]=HCSpeed[4*IndexLoop+3]
set HCBalls[2*IndexLoop-2]=HCBalls[2*IndexLoop]
set HCBalls[2*IndexLoop-1]=HCBalls[2*IndexLoop+1]
set HCVictims[2*IndexLoop-2]=HCVictims[2*IndexLoop]
set HCVictims[2*IndexLoop-1]=HCVictims[2*IndexLoop+1]
set HCLength[IndexLoop-1]=HCLength[IndexLoop]
set HCDpsFactor[IndexLoop-1]=HCDpsFactor[IndexLoop]
set HCHpsFactor[IndexLoop-1]=HCHpsFactor[IndexLoop]
set HCD[IndexLoop-1]=HCD[IndexLoop]
set HCExplosion[IndexLoop-1]=HCExplosion[IndexLoop]
set IndexLoop=IndexLoop+1
exitwhen IndexLoop>HCInstances
endloop
set HCInstances = HCInstances -1
endif
exitwhen LoopIndex >= HCInstances
endloop
endfunction
private function DALoop takes nothing returns nothing
local unit u
local unit victim
local integer LoopIndex=0
local integer IndexLoop
local real x1
local real x2
local real y1
local real y2
local real angle
local real r
local real dx
local real dy
local integer Reflection
loop
set u=DABalls[LoopIndex]
set x1=GetUnitX(u)
set y1=GetUnitY(u)
if IsUnitType(u,UNIT_TYPE_DEAD)==false then
set IndexLoop=0
loop //First loop - other Attractors
if(LoopIndex!=IndexLoop)then
set victim=DABalls[IndexLoop]
set x2=GetUnitX(victim)
set y2=GetUnitY(victim)
set dx=x1-x2
set dy=y1-y2
set r=dx*dx+dy*dy
if r>DAsSize then //Schwarzschild Radius XD. Ok, that was a joke, but its to prevent the infinite gravitation hole.
set angle=Atan2(dy,dx)
set dx=Cos(angle)*DAGamma[LoopIndex]/r
set dy=Sin(angle)*DAGamma[LoopIndex]/r
set DASpeed[2*IndexLoop]=DASpeed[2*IndexLoop]+dx
set DASpeed[2*IndexLoop+1]=DASpeed[2*IndexLoop+1]+dy
endif
endif
set IndexLoop=IndexLoop+1
exitwhen IndexLoop>=DAInstances
endloop
set IndexLoop=0
loop //Second Loop - Holy Chain
set victim=HCBalls[2*IndexLoop]
set x2=GetUnitX(victim)
set y2=GetUnitY(victim)
set dx=x1-x2
set dy=y1-y2
set r=dx*dx+dy*dy
if r>DAsSize then //Schwarzschild Radius
set angle=Atan2(dy,dx)
set dx=Cos(angle)*DAHCGamma[LoopIndex]/r
set dy=Sin(angle)*DAHCGamma[LoopIndex]/r
set HCSpeed[4*IndexLoop]=HCSpeed[4*IndexLoop]+dx
set HCSpeed[4*IndexLoop+1]=HCSpeed[4*IndexLoop+1]+dy
endif
set victim=HCBalls[2*IndexLoop+1]
set x2=GetUnitX(victim)
set y2=GetUnitY(victim)
set dx=x1-x2
set dy=y1-y2
set r=dx*dx+dy*dy
if r>DAsSize then //Schwarzschild Radius
set angle=Atan2(dy,dx)
set dx=Cos(angle)*DAHCGamma[LoopIndex]/r
set dy=Sin(angle)*DAHCGamma[LoopIndex]/r
set HCSpeed[4*IndexLoop+2]=HCSpeed[4*IndexLoop+2]+dx
set HCSpeed[4*IndexLoop+3]=HCSpeed[4*IndexLoop+3]+dy
endif
set IndexLoop=IndexLoop+1
exitwhen IndexLoop>=HCInstances
endloop
set IndexLoop=0
loop //Third Loop - Gods Fist
set victim=GFBalls[IndexLoop]
set x2=GetUnitX(victim)
set y2=GetUnitY(victim)
set dx=x1-x2
set dy=y1-y2
set r=dx*dx+dy*dy
if r>DAsSize then //Schwarzschild Radius
set angle=Atan2(dy,dx)
set dx=Cos(angle)*DAGFGamma[LoopIndex]/r
set dy=Sin(angle)*DAGFGamma[LoopIndex]/r
set GFSpeed[2*IndexLoop]=GFSpeed[2*IndexLoop]+dx
set GFSpeed[2*IndexLoop+1]=GFSpeed[2*IndexLoop+1]+dy
endif
set IndexLoop=IndexLoop+1
exitwhen IndexLoop>=GFInstances
endloop
static if LIBRARY_TerrainPathability then
set Reflection=GetReflection(x1,y1,DASpeed[2*LoopIndex],DASpeed[2*LoopIndex+1])
if Reflection==1 then
set DASpeed[2*LoopIndex]=-DASpeed[2*LoopIndex]
endif
if Reflection==2 then
set DASpeed[2*LoopIndex+1]=-DASpeed[2*LoopIndex+1]
endif
if Reflection==3 then
set DASpeed[2*LoopIndex]=-DASpeed[2*LoopIndex]
set DASpeed[2*LoopIndex+1]=-DASpeed[2*LoopIndex+1]
endif
endif
if DAGradientFactor[LoopIndex]>0 then
call GetGradient(x1,y1)
else
set XGradient=0
set YGradient=0
endif
set DASpeed[2*LoopIndex]=DASpeed[2*LoopIndex]*DAFriction[LoopIndex]-DAGradientFactor[LoopIndex]*XGradient
set DASpeed[2*LoopIndex+1]=DASpeed[2*LoopIndex+1]*DAFriction[LoopIndex]-DAGradientFactor[LoopIndex]*YGradient
call SetUnitX(u, x1+DASpeed[2*LoopIndex])
call SetUnitY(u, y1+DASpeed[2*LoopIndex+1])
set LoopIndex=LoopIndex+1
else
set IndexLoop=LoopIndex+1
loop
set DABalls[IndexLoop-1]=DABalls[IndexLoop]
set DASpeed[2*IndexLoop-2]=DASpeed[2*IndexLoop]
set DASpeed[2*IndexLoop-1]=DASpeed[2*IndexLoop+1]
set DAGamma[IndexLoop-1]=DAGamma[IndexLoop]
set DAHCGamma[IndexLoop-1]=DAHCGamma[IndexLoop]
set DAGFGamma[IndexLoop-1]=DAGFGamma[IndexLoop]
set DAFriction[IndexLoop-1]=DAFriction[IndexLoop]
set DAGradientFactor[IndexLoop-1]=DAGradientFactor[IndexLoop]
exitwhen IndexLoop>DAInstances
set IndexLoop=IndexLoop+1
endloop
set DAInstances=DAInstances-1
endif
exitwhen LoopIndex>=DAInstances
endloop
endfunction
private function GFLoop takes nothing returns nothing
local unit u
local unit victim
local integer LoopIndex=0
local integer IndexLoop
local real angle
local real r
local real x1
local real x2
local real y1
local real y2
local real dx
local real dy
local integer Reflection
loop
set u=GFBalls[LoopIndex]
set victim=GFTargets[LoopIndex]
set x1=GetUnitX(u)
set x2=GetUnitX(victim)
set y1=GetUnitY(u)
set y2=GetUnitY(victim)
set dx=x1-x2
set dy=y1-y2
if IsUnitType(u,UNIT_TYPE_DEAD)==false and IsUnitType(victim,UNIT_TYPE_DEAD)==false then
set angle=Atan2(dy,dx)
set r=dx*dx+dy*dy
if r>GFSize then
set dx=Cos(angle)*GFAcceleration[LoopIndex]
set dy=Sin(angle)*GFAcceleration[LoopIndex]
if GFGradientFactor[LoopIndex]>0 then
call GetGradient(x1,y1)
else
set XGradient=0
set YGradient=0
endif
set GFSpeed[2*LoopIndex]=GFSpeed[2*LoopIndex]*GFFriction[LoopIndex]-dx-GFGradientFactor[LoopIndex]*XGradient
set GFSpeed[2*LoopIndex+1]=GFSpeed[2*LoopIndex+1]*GFFriction[LoopIndex]-dy-GFGradientFactor[LoopIndex]*YGradient
static if LIBRARY_TerrainPathability then
set Reflection=GetReflection(x1,y1,GFSpeed[2*LoopIndex],GFSpeed[2*LoopIndex+1])
if Reflection==1 then
set GFSpeed[2*LoopIndex]=-GFSpeed[2*LoopIndex]
endif
if Reflection==2 then
set GFSpeed[2*LoopIndex+1]=-GFSpeed[2*LoopIndex+1]
endif
if Reflection==3 then
set GFSpeed[2*LoopIndex]=-GFSpeed[2*LoopIndex]
set GFSpeed[2*LoopIndex+1]=-GFSpeed[2*LoopIndex+1]
endif
endif
call SetUnitX(u, x1+GFSpeed[2*LoopIndex])
call SetUnitY(u, y1+GFSpeed[2*LoopIndex+1])
else
call KillUnit(u)
if IsUnitAlly(victim,GetOwningPlayer(u)) then
call SetUnitState(victim, UNIT_STATE_LIFE, GetUnitState(victim,UNIT_STATE_LIFE)+GFHeal[LoopIndex])
else
call UnitDamageTarget(u,victim, GFDamage[LoopIndex], false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPIRIT_LINK, WEAPON_TYPE_WHOKNOWS)
endif
endif
set LoopIndex=LoopIndex+1
else
call KillUnit(u)
set IndexLoop=LoopIndex+1
loop
set GFBalls[IndexLoop-1]=GFBalls[IndexLoop]
set GFTargets[IndexLoop-1]=GFTargets[IndexLoop]
set GFSpeed[2*IndexLoop-2]=GFSpeed[2*IndexLoop]
set GFSpeed[2*IndexLoop-1]=GFSpeed[2*IndexLoop+1]
set GFAcceleration[IndexLoop-1]=GFAcceleration[IndexLoop]
set GFFriction[IndexLoop-1]=GFFriction[IndexLoop]
set GFDamage[IndexLoop-1]=GFHeal[IndexLoop]
set GFGradientFactor[IndexLoop-1]=GFGradientFactor[IndexLoop]
exitwhen IndexLoop>GFInstances
set IndexLoop=IndexLoop+1
endloop
set GFInstances=GFInstances-1
endif
exitwhen LoopIndex>=GFInstances
endloop
endfunction
private function RLoop takes nothing returns nothing
local unit victim
local integer LoopIndex=0
local integer IndexLoop
local real x1
local real x2
local real y1
local real y2
local real angle
local real r
local real dx
local real dy
loop
if RCaster[LoopIndex]==null then
set x1=RPosition[2*LoopIndex]
set y1=RPosition[2*LoopIndex+1]
else
set x1=GetUnitX(RCaster[LoopIndex])
set y1=GetUnitY(RCaster[LoopIndex])
endif
if RLength[LoopIndex]>0 then
set IndexLoop=0
loop //First loop - other Attractors
set victim=DABalls[IndexLoop]
set x2=GetUnitX(victim)
set y2=GetUnitY(victim)
set dx=x1-x2
set dy=y1-y2
set r=dx*dx+dy*dy
if r>RsSize then //Schwarzschild Radius
set angle=Atan2(dy,dx)
set dx=Cos(angle)*RDAGamma[LoopIndex]/r
set dy=Sin(angle)*RDAGamma[LoopIndex]/r
set DASpeed[2*IndexLoop]=DASpeed[2*IndexLoop]-dx
set DASpeed[2*IndexLoop+1]=DASpeed[2*IndexLoop+1]-dy
endif
set IndexLoop=IndexLoop+1
exitwhen IndexLoop>=DAInstances
endloop
set IndexLoop=0
loop //Second Loop - Holy Chain
set victim=HCBalls[2*IndexLoop]
set x2=GetUnitX(victim)
set y2=GetUnitY(victim)
set dx=x1-x2
set dy=y1-y2
set r=dx*dx+dy*dy
if r>RsSize then //Schwarzschild Radius
set angle=Atan2(dy,dx)
set dx=Cos(angle)*RHCGamma[LoopIndex]/r
set dy=Sin(angle)*RHCGamma[LoopIndex]/r
set HCSpeed[4*IndexLoop]=HCSpeed[4*IndexLoop]-dx
set HCSpeed[4*IndexLoop+1]=HCSpeed[4*IndexLoop+1]-dy
endif
set victim=HCBalls[2*IndexLoop+1]
set x2=GetUnitX(victim)
set y2=GetUnitY(victim)
set dx=x1-x2
set dy=y1-y2
set r=dx*dx+dy*dy
if r>DAsSize then //Schwarzschild Radius
set angle=Atan2(dy,dx)
set dx=Cos(angle)*RHCGamma[LoopIndex]/r
set dy=Sin(angle)*RHCGamma[LoopIndex]/r
set HCSpeed[4*IndexLoop+2]=HCSpeed[4*IndexLoop+2]-dx
set HCSpeed[4*IndexLoop+3]=HCSpeed[4*IndexLoop+3]-dy
endif
set IndexLoop=IndexLoop+1
exitwhen IndexLoop>=HCInstances
endloop
set IndexLoop=0
loop //Third Loop - Gods Fist
set victim=GFBalls[IndexLoop]
set x2=GetUnitX(victim)
set y2=GetUnitY(victim)
set dx=x1-x2
set dy=y1-y2
set r=dx*dx+dy*dy
if r>DAsSize then //Schwarzschild Radius
set angle=Atan2(dy,dx)
set dx=Cos(angle)*RGFGamma[LoopIndex]/r
set dy=Sin(angle)*RGFGamma[LoopIndex]/r
set GFSpeed[2*IndexLoop]=GFSpeed[2*IndexLoop]-dx
set GFSpeed[2*IndexLoop+1]=GFSpeed[2*IndexLoop+1]-dy
endif
set IndexLoop=IndexLoop+1
exitwhen IndexLoop>=GFInstances
endloop
set RLength[LoopIndex]=RLength[LoopIndex]-1
set LoopIndex=LoopIndex+1
else
set IndexLoop=LoopIndex+1
loop
set RLength[IndexLoop-1]=RLength[IndexLoop]
set RCaster[IndexLoop-1]=RCaster[IndexLoop]
set RPosition[2*IndexLoop-2]=RPosition[2*IndexLoop]
set RPosition[2*IndexLoop-1]=RPosition[2*IndexLoop+1]
set RDAGamma[IndexLoop-1]=RDAGamma[IndexLoop]
set RGFGamma[IndexLoop-1]=RGFGamma[IndexLoop]
set RHCGamma[IndexLoop-1]=RHCGamma[IndexLoop]
exitwhen IndexLoop>RInstances
set IndexLoop=IndexLoop+1
endloop
set RInstances=RInstances-1
endif
exitwhen LoopIndex>=RInstances
endloop
endfunction
private function TimerLoop takes nothing returns nothing
if HCInstances > 0 then
call HCLoop()
endif
if DAInstances > 0 then
call DALoop()
endif
if GFInstances > 0 then
call GFLoop()
endif
if RInstances > 0 then
call RLoop()
endif
endfunction
private function init takes nothing returns nothing
call TimerStart(AllTimer, intervall, true, function TimerLoop)
endfunction
endlibrary
//TESH.scrollpos=2
//TESH.alwaysfold=0
scope HolyChain initializer init
globals
private constant integer HCSpellID='A000' //Spell ID of the Holy Chain Spell. It should be a point-targeted spell
private constant integer HCBallID='u000' //Unit ID of the effect. It does not need anything in particular, but you probably want it to have Locust
private constant integer HCExplosionID='u003' //The Dummy unit which death animation the Holy Chain will play when it comes to a double-free
private constant real HCLength=400.0 //The length of the imaginary spring between the balls
private constant real HCStartLength=400.0 //The initial distance between the Balls when created. Setting this to a value different than the normal length will cause the balls to 'wobble'. Please do not set this 0, or it will bug (division by zero)
private constant real HCDuration=20.0 //How may Seconds the balls will last
private constant real HCStartSpeed=200.0 //How fast the Balls will fly when created
private constant real HCDpsFactor=0.05 //How much damage the balls will cause per seconds and chain length
private constant real HCHpsFactor=0.1//How much the balls will heal per second and chain length
private constant real HCDfDamage=250 //How much damage it will cause on a unit if both balls stick to her (double-free)
private constant real HCD=0.32 //The stiffness of the spring. High values will make the chain to look more 'constant', but when expanded, they balls will oscillate fast. Lesser values pruduce a more elastic spring which will oscillate slowly.
private constant real Friction=0.8 //The percentage of Speed that would be left after 1 second.
private constant real GradientFactor=3.2 //Factor with wich the Terrain Z will affect the unit
endglobals
private function HCCast takes nothing returns boolean
local unit u=GetTriggerUnit()
if GetSpellAbilityId()==HCSpellID then
//function CreateHC takes real X, real Y, real TargetX, real TargetY, player Owner, integer DummyID, real StartSpeed, real StartLength, real Length, real Duration, real Dps, real Hps, real D, real DfDamage, real Friction, real GradientFactor integer ExplosionID returns integer
call CreateHC(GetUnitX(u), GetUnitY(u), GetSpellTargetX(), GetSpellTargetY(), GetTriggerPlayer(), HCBallID, GetRandomReal(0.5,2)*HCStartSpeed, GetRandomReal(0.75,1.66)*HCStartLength, GetRandomReal(0.75,1.66)*HCLength, GetRandomReal(0.5,2)*HCDuration, GetRandomReal(0.5,2)*HCDpsFactor, GetRandomReal(0.5,2)*HCHpsFactor, GetRandomReal(0.5,2)*HCD, GetRandomReal(0.5,2)*HCDfDamage, GetRandomReal(0.1,1)*Friction, GetRandomReal(0.5,2)*GradientFactor, HCExplosionID)
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger trig= CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trig,Condition(function HCCast))
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope GodsFist initializer init
globals
private constant integer GFSpellID='A003' //Spell Id of the 'Gods Fist' spell.It must be a unit targeted Spell
private constant integer GFBallID='u002' //Unit ID of the effect. It does not need anything in particular, but you probably want it to have Locust (you've heard that already? Probably.;)
private constant real GFStartSpeed=300.0 //How fast the Fist will be when cast
private constant real GFDuration= 20.0 //How many seconds the Fist will follow the target
private constant real GFAcceleration=5//How much speed the Fist will gain every second
private constant real GFFriction=0.5 //The percentage of Speed that would be left after 1 second.
private constant real GFDamage=400.0
private constant real GFHeal=200.0
private constant real GradientFactor=1.6 //Factor with wich the Terrain Z will affect the unit
endglobals
private function GFCast takes nothing returns boolean
local unit u=GetTriggerUnit()
if GetSpellAbilityId()==GFSpellID then
//CreateGF takes real X, real Y,player Owner, unit victim,integer DummyID, real StartSpeed, real Duration, real Friction, real Acceleration, real Damage, real Heal, real GradientFactor returns integer
call CreateGF(GetUnitX(u), GetUnitY(u), GetTriggerPlayer(), GetSpellTargetUnit(), GFBallID, GetRandomReal(0.5,2)*GFStartSpeed, GetRandomReal(0.5,2)*GFDuration, GetRandomReal(0.5,2)*GFFriction, GetRandomReal(0.5,2)*GFAcceleration, GetRandomReal(0.5,2)*GFDamage, GetRandomReal(0.5,2)*GFHeal, GetRandomReal(0.5,2)*GradientFactor)
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger trig= CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trig,Condition(function GFCast))
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope DivineAttractor initializer init
globals
private constant real DAGamma=320000//Multiplier for the acceleration of other Divinie Attractors
private constant real DAHCGamma=320000//Multiplier for the acceleration of Holy Chain Nodes
private constant real DAGFGamma=320000//Multiplier for the acceleration of Gods Fists
private constant integer DASpellID='A002' //Spell ID of the 'Divine Attractor' Spell. I should be point-targeted
private constant integer DABallID='u001' //Unit ID of the effect. It does not need anything in particular, but you probably want it to have Locust
private constant real DADuration=20.0//How many Seconds the Attractor will last
private constant real DAStartSpeed=100.0 //How fast the Attractor will be when cast
private constant real Friction=0.8 //The percentage of Speed that would be left after 1 second.
private constant real GradientFactor=3.2 //Factor with wich the Terrain Z will affect the unit
endglobals
private function DACast takes nothing returns boolean
local unit u=GetTriggerUnit()
if GetSpellAbilityId()==DASpellID then
//function CreateDA takes real X, real Y, real TargetX, real TargetY, player Owner, integer DummyID, real StartSpeed, real Duration,real DaGamma,real HCGamma,real GFGamma, real Friction, real GradientFactor returns integer
call CreateDA(GetUnitX(u), GetUnitY(u), GetSpellTargetX(), GetSpellTargetY(), GetTriggerPlayer(), DABallID, GetRandomReal(0.5,2)*DAStartSpeed, GetRandomReal(0.5,2)*DADuration, GetRandomReal(0.5,2)*DAGamma, GetRandomReal(0.5,2)*DAHCGamma, GetRandomReal(0.5,2)*DAGFGamma, GetRandomReal(0.1,1)*Friction, GetRandomReal(0.5,2)*GradientFactor)
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger trig= CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trig,Condition(function DACast))
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope Repulsion initializer init
globals
private constant integer RSpellID='A004'
private constant real RDuration=1.0 //How many seconds it will repulse
private constant real RHCGamma= 480000 //Factor with which the Holy Chain will be repulsed
private constant real RDAGamma= 480000 //Factor with which the Divine Attractors will be repulsed
private constant real RGFGamma= 960000 //Factor with which Gods Fist will be repulsed
endglobals
private function RCast takes nothing returns boolean
local unit u=GetTriggerUnit()
if GetSpellAbilityId()==RSpellID then
//unction CreateRepOnUnit takes unit Caster, real Duration, real HCGamma, real GFGamma, real DaGamma returns integer
call CreateRepOnUnit(u, RDuration, GetRandomReal(0.5,2)*RHCGamma, GetRandomReal(0.5,2)*RGFGamma, GetRandomReal(0.5,2)*RDAGamma)
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger trig= CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trig,Condition(function RCast))
endfunction
endscope
//TESH.scrollpos=3
//TESH.alwaysfold=0
function Trig_Fire_Chain_Cast_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A000'
endfunction
function Trig_Fire_Chain_Cast_Actions takes nothing returns nothing
local real r=SquareRoot((GetSpellTargetX()-GetUnitX(GetTriggerUnit()))*(GetSpellTargetX()-GetUnitX(GetTriggerUnit()))+(GetSpellTargetY()-GetUnitY(GetTriggerUnit()))*(GetSpellTargetY()-GetUnitY(GetTriggerUnit())))
local real dx=(GetSpellTargetX()-GetUnitX(GetTriggerUnit()))/r
local real dy=(GetSpellTargetY()-GetUnitY(GetTriggerUnit()))/r
set udg_FireChainBalls[2*udg_FireChainInstances]=CreateUnit( GetOwningPlayer(GetTriggerUnit()),'u000',GetUnitX(GetTriggerUnit())+200*dy,GetUnitY(GetTriggerUnit())-200*dx,0)
call UnitApplyTimedLife( udg_FireChainBalls[2*udg_FireChainInstances], 'BTLF', 20.00 )
set udg_FireChainBalls[2*udg_FireChainInstances+1]=CreateUnit( GetOwningPlayer(GetTriggerUnit()),'u000',GetUnitX(GetTriggerUnit())-200*dy,GetUnitY(GetTriggerUnit())+200*dx,0)
call UnitApplyTimedLife( udg_FireChainBalls[2*udg_FireChainInstances+1], 'BTLF', 20.00 )
set udg_FireChainSpeed[4*udg_FireChainInstances]=10*dx
set udg_FireChainSpeed[4*udg_FireChainInstances+1]=10*dy
set udg_FireChainSpeed[4*udg_FireChainInstances+2]=udg_FireChainSpeed[4*udg_FireChainInstances]
set udg_FireChainSpeed[4*udg_FireChainInstances+3]=udg_FireChainSpeed[4*udg_FireChainInstances+1]
set udg_FireChainLength[udg_FireChainInstances]=400
set udg_FireChainTarget[2*udg_FireChainInstances]=null
set udg_FireChainTarget[2*udg_FireChainInstances+1]=null
set udg_FireChainInstances =udg_FireChainInstances + 1
endfunction
//===========================================================================
function InitTrig_Fire_Chain_Cast takes nothing returns nothing
set gg_trg_Fire_Chain_Cast = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Fire_Chain_Cast, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Fire_Chain_Cast, Condition( function Trig_Fire_Chain_Cast_Conditions ) )
call TriggerAddAction( gg_trg_Fire_Chain_Cast, function Trig_Fire_Chain_Cast_Actions )
endfunction
//TESH.scrollpos=105
//TESH.alwaysfold=0
function Trig_Fire_Chain_Loop_Conditions takes nothing returns boolean
return udg_FireChainInstances > 0
endfunction
function beFilterfunction takes nothing returns boolean
return GetUnitAbilityLevel( GetFilterUnit(), 'Avul' ) <= 0 and GetUnitAbilityLevel( GetFilterUnit(), 'Amim' ) <= 0 and GetUnitAbilityLevel( GetFilterUnit(), 'Aloc' ) <= 0 and IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD)==false
endfunction
function Trig_Fire_Chain_Loop_Actions takes nothing returns nothing
local group TempGroup
local unit u1
local unit u2
local unit victim
local integer LoopIndex=0
local integer IndexLoop
local real r
local real dx
local real dy
loop
set u1=udg_FireChainBalls[2*LoopIndex]
set u2=udg_FireChainBalls[2*LoopIndex+1]
if IsUnitType(u1, UNIT_TYPE_DEAD)==false then
set r=SquareRoot((GetUnitX(u1)-GetUnitX(u2))*(GetUnitX(u1)-GetUnitX(u2))+(GetUnitY(u1)-GetUnitY(u2))*(GetUnitY(u1)-GetUnitY(u2)))
if r>= 32 then //32 is the smallest collision-size of units, meaning that you can only double-free if the two balls are really on the same unit.
set dx=(udg_FireChainLength[LoopIndex]-r)*((GetUnitX(u1)-GetUnitX(u2))/r)/100
set dy=(udg_FireChainLength[LoopIndex]-r)*((GetUnitY(u1)-GetUnitY(u2))/r)/100
if udg_FireChainTarget[2*LoopIndex]==null then
set udg_FireChainSpeed[4*LoopIndex]=udg_FireChainSpeed[4*LoopIndex]+dx
set udg_FireChainSpeed[4*LoopIndex+1]=udg_FireChainSpeed[4*LoopIndex+1]+dy
call SetUnitX(u1, GetUnitX(u1)+udg_FireChainSpeed[4*LoopIndex])
call SetUnitY(u1, GetUnitY(u1)+udg_FireChainSpeed[4*LoopIndex+1])
set TempGroup=CreateGroup()
call GroupEnumUnitsInRange(TempGroup,GetUnitX(u1),GetUnitY(u1),50.00, Condition(function beFilterfunction))
set udg_FireChainTarget[2*LoopIndex]=FirstOfGroup(TempGroup)
call DestroyGroup(TempGroup)
else
if IsUnitType(udg_FireChainTarget[2*LoopIndex], UNIT_TYPE_DEAD)==false then
call SetUnitX(u1,GetUnitX(udg_FireChainTarget[2*LoopIndex]))
call SetUnitY(u1,GetUnitY(udg_FireChainTarget[2*LoopIndex]))
if IsUnitAlly(udg_FireChainTarget[2*LoopIndex],GetOwningPlayer(u1)) then
call SetUnitState(udg_FireChainTarget[2*LoopIndex], UNIT_STATE_LIFE, GetUnitState(udg_FireChainTarget[2*LoopIndex],UNIT_STATE_LIFE)+r/200)
else
call UnitDamageTarget(u2,udg_FireChainTarget[2*LoopIndex], r/400, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPIRIT_LINK, WEAPON_TYPE_WHOKNOWS)
endif
else
set udg_FireChainTarget[2*LoopIndex]=null
set udg_FireChainSpeed[4*LoopIndex]=0
set udg_FireChainSpeed[4*LoopIndex+1]=0
endif
endif
if udg_FireChainTarget[2*LoopIndex+1]==null then
set udg_FireChainSpeed[4*LoopIndex+2]=udg_FireChainSpeed[4*LoopIndex+2]-dx
set udg_FireChainSpeed[4*LoopIndex+3]=udg_FireChainSpeed[4*LoopIndex+3]-dy
call SetUnitX(u2, GetUnitX(u2)+udg_FireChainSpeed[4*LoopIndex+2])
call SetUnitY(u2, GetUnitY(u2)+udg_FireChainSpeed[4*LoopIndex+3])
set TempGroup=CreateGroup()
call GroupEnumUnitsInRange(TempGroup,GetUnitX(u2),GetUnitY(u2),50.00,Condition(function beFilterfunction))
set udg_FireChainTarget[2*LoopIndex+1]=FirstOfGroup(TempGroup)
call DestroyGroup(TempGroup)
else
if IsUnitType(udg_FireChainTarget[2*LoopIndex+1],UNIT_TYPE_DEAD)==false then
call SetUnitX(u2, GetUnitX(udg_FireChainTarget[2*LoopIndex+1]))
call SetUnitY(u2, GetUnitY(udg_FireChainTarget[2*LoopIndex+1]))
if IsUnitAlly(udg_FireChainTarget[2*LoopIndex+1],GetOwningPlayer(u2)) then
call SetUnitState(udg_FireChainTarget[2*LoopIndex+1], UNIT_STATE_LIFE, GetUnitState(udg_FireChainTarget[2*LoopIndex+1],UNIT_STATE_LIFE)+r/200)
else
call UnitDamageTarget(u1,udg_FireChainTarget[2*LoopIndex+1], r/400, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPIRIT_LINK, WEAPON_TYPE_WHOKNOWS)
endif
else
set udg_FireChainTarget[2*LoopIndex+1]=null
set udg_FireChainSpeed[4*LoopIndex+2]=0
set udg_FireChainSpeed[4*LoopIndex+3]=0
endif
endif
set LoopIndex = LoopIndex + 1
else
set IndexLoop=LoopIndex+1
call AddUnitAnimationProperties( u1, "alternate", true )
call AddUnitAnimationProperties( u2, "alternate", true )
call KillUnit(u1)
call KillUnit(u2)
call UnitDamageTarget(u1,udg_FireChainTarget[2*LoopIndex], 250, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPIRIT_LINK, WEAPON_TYPE_WHOKNOWS)
call UnitDamageTarget(u2,udg_FireChainTarget[2*LoopIndex+1], 250, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPIRIT_LINK, WEAPON_TYPE_WHOKNOWS)
loop
set udg_FireChainSpeed[4*IndexLoop-4]=udg_FireChainSpeed[4*IndexLoop]
set udg_FireChainSpeed[4*IndexLoop-3]=udg_FireChainSpeed[4*IndexLoop+1]
set udg_FireChainSpeed[4*IndexLoop-2]=udg_FireChainSpeed[4*IndexLoop+2]
set udg_FireChainSpeed[4*IndexLoop-1]=udg_FireChainSpeed[4*IndexLoop+3]
set udg_FireChainBalls[2*IndexLoop-2]=udg_FireChainBalls[2*IndexLoop]
set udg_FireChainBalls[2*IndexLoop-1]=udg_FireChainBalls[2*IndexLoop+1]
set udg_FireChainLength[IndexLoop-1]=udg_FireChainLength[IndexLoop]
set udg_FireChainTarget[2*IndexLoop-2]=udg_FireChainTarget[2*IndexLoop]
set udg_FireChainTarget[2*IndexLoop-1]=udg_FireChainTarget[2*IndexLoop+1]
set IndexLoop=IndexLoop+1
exitwhen IndexLoop>udg_FireChainInstances
endloop
set udg_FireChainInstances = udg_FireChainInstances -1
endif
else
set IndexLoop=LoopIndex+1
loop
set udg_FireChainSpeed[4*IndexLoop-4]=udg_FireChainSpeed[4*IndexLoop]
set udg_FireChainSpeed[4*IndexLoop-3]=udg_FireChainSpeed[4*IndexLoop+1]
set udg_FireChainSpeed[4*IndexLoop-2]=udg_FireChainSpeed[4*IndexLoop+2]
set udg_FireChainSpeed[4*IndexLoop-1]=udg_FireChainSpeed[4*IndexLoop+3]
set udg_FireChainBalls[2*IndexLoop-2]=udg_FireChainBalls[2*IndexLoop]
set udg_FireChainBalls[2*IndexLoop-1]=udg_FireChainBalls[2*IndexLoop+1]
set udg_FireChainLength[IndexLoop-1]=udg_FireChainLength[IndexLoop]
set udg_FireChainTarget[2*IndexLoop-2]=udg_FireChainTarget[2*IndexLoop]
set udg_FireChainTarget[2*IndexLoop-1]=udg_FireChainTarget[2*IndexLoop+1]
set IndexLoop=IndexLoop+1
exitwhen IndexLoop>udg_FireChainInstances
endloop
set udg_FireChainInstances = udg_FireChainInstances -1
endif
exitwhen LoopIndex >= udg_FireChainInstances
endloop
endfunction
//===========================================================================
function InitTrig_Fire_Chain_Loop takes nothing returns nothing
set gg_trg_Fire_Chain_Loop = CreateTrigger( )
call TriggerRegisterTimerEventPeriodic( gg_trg_Fire_Chain_Loop, 0.05 )
call TriggerAddCondition( gg_trg_Fire_Chain_Loop, Condition( function Trig_Fire_Chain_Loop_Conditions ) )
call TriggerAddAction( gg_trg_Fire_Chain_Loop, function Trig_Fire_Chain_Loop_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Repulsion_Cast_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A004'
endfunction
function Trig_Repulsion_Cast_Actions takes nothing returns nothing
set udg_RepulsionCaster[udg_RepulsionInstances]=GetSpellAbilityUnit()
set udg_RepulsionLength[udg_RepulsionInstances]=20
set udg_RepulsionInstances=udg_RepulsionInstances+1
endfunction
//===========================================================================
function InitTrig_Repulsion_Cast takes nothing returns nothing
set gg_trg_Repulsion_Cast = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Repulsion_Cast, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Repulsion_Cast, Condition( function Trig_Repulsion_Cast_Conditions ) )
call TriggerAddAction( gg_trg_Repulsion_Cast, function Trig_Repulsion_Cast_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Repulsion_Loop_Conditions takes nothing returns boolean
return udg_RepulsionInstances > 0
endfunction
function Trig_Repulsion_Loop_Actions takes nothing returns nothing
local unit u
local unit victim
local integer LoopIndex=0
local integer IndexLoop
local real r
local real dx
local real dy
loop
set u=udg_RepulsionCaster[LoopIndex]
if udg_RepulsionLength[LoopIndex]>0 then
set IndexLoop=0
loop //First loop - other Attractors
set victim=udg_AttractorBall[IndexLoop]
set r=SquareRoot((GetUnitX(u)-GetUnitX(victim))*(GetUnitX(u)-GetUnitX(victim))+(GetUnitY(u)-GetUnitY(victim))*(GetUnitY(u)-GetUnitY(victim)))
if r>64 then //Schwarzschild Radius XD. Ok, that was a joke, but its to prevent the infinite gravitation hole.
set dx=(1/(r*r))*((GetUnitX(u)-GetUnitX(victim))/r)*15000
set dy=(1/(r*r))*((GetUnitY(u)-GetUnitY(victim))/r)*15000
set udg_AttractorSpeed[2*IndexLoop]=udg_AttractorSpeed[2*IndexLoop]-dx
set udg_AttractorSpeed[2*IndexLoop+1]=udg_AttractorSpeed[2*IndexLoop+1]-dy
endif
set IndexLoop=IndexLoop+1
exitwhen IndexLoop>=udg_AttractorInstances
endloop
set IndexLoop=0
loop //Second Loop - Holy Chain
set victim=udg_FireChainBalls[2*IndexLoop]
set r=SquareRoot((GetUnitX(u)-GetUnitX(victim))*(GetUnitX(u)-GetUnitX(victim))+(GetUnitY(u)-GetUnitY(victim))*(GetUnitY(u)-GetUnitY(victim)))
if r>64 then //Schwarzschild Radius
set dx=(1/(r*r))*((GetUnitX(u)-GetUnitX(victim))/r)*15000
set dy=(1/(r*r))*((GetUnitY(u)-GetUnitY(victim))/r)*15000
set udg_FireChainSpeed[4*IndexLoop]=udg_FireChainSpeed[4*IndexLoop]-dx
set udg_FireChainSpeed[4*IndexLoop+1]=udg_FireChainSpeed[4*IndexLoop+1]-dy
endif
set victim=udg_FireChainBalls[2*IndexLoop+1]
set r=SquareRoot((GetUnitX(u)-GetUnitX(victim))*(GetUnitX(u)-GetUnitX(victim))+(GetUnitY(u)-GetUnitY(victim))*(GetUnitY(u)-GetUnitY(victim)))
if r>64 then //Schwarzschild Radius
set dx=(1/(r*r))*((GetUnitX(u)-GetUnitX(victim))/r)*15000
set dy=(1/(r*r))*((GetUnitY(u)-GetUnitY(victim))/r)*15000
set udg_FireChainSpeed[4*IndexLoop+2]=udg_FireChainSpeed[4*IndexLoop+2]-dx
set udg_FireChainSpeed[4*IndexLoop+3]=udg_FireChainSpeed[4*IndexLoop+3]-dy
endif
set IndexLoop=IndexLoop+1
exitwhen IndexLoop>=udg_FireChainInstances
endloop
set IndexLoop=0
loop //Third Loop - Homing Missiles
set victim=udg_HomingBall[IndexLoop]
set r=SquareRoot((GetUnitX(u)-GetUnitX(victim))*(GetUnitX(u)-GetUnitX(victim))+(GetUnitY(u)-GetUnitY(victim))*(GetUnitY(u)-GetUnitY(victim)))
if r>64 then //Schwarzschild Radius XD. Ok, that was a joke, but its to prevent the infinite gravitation hole.
set dx=(1/(r*r))*((GetUnitX(u)-GetUnitX(victim))/r)*15000
set dy=(1/(r*r))*((GetUnitY(u)-GetUnitY(victim))/r)*15000
set udg_HomingSpeed[2*IndexLoop]=udg_HomingSpeed[2*IndexLoop]-dx
set udg_HomingSpeed[2*IndexLoop+1]=udg_HomingSpeed[2*IndexLoop+1]-dy
endif
set IndexLoop=IndexLoop+1
exitwhen IndexLoop>=udg_HomingInstances
endloop
set udg_RepulsionLength[LoopIndex]=udg_RepulsionLength[LoopIndex]-1
set LoopIndex=LoopIndex+1
else
set IndexLoop=LoopIndex+1
loop
set udg_RepulsionCaster[IndexLoop-1]=udg_RepulsionCaster[IndexLoop]
set udg_RepulsionLength[IndexLoop-1]=udg_RepulsionLength[IndexLoop]
exitwhen IndexLoop>udg_RepulsionInstances
set IndexLoop=IndexLoop+1
endloop
set udg_RepulsionInstances=udg_RepulsionInstances-1
endif
exitwhen LoopIndex>=udg_RepulsionInstances
endloop
endfunction
//===========================================================================
function InitTrig_Repulsion_Loop takes nothing returns nothing
set gg_trg_Repulsion_Loop = CreateTrigger( )
call TriggerRegisterTimerEventPeriodic( gg_trg_Repulsion_Loop, 0.05 )
call TriggerAddCondition( gg_trg_Repulsion_Loop, Condition( function Trig_Repulsion_Loop_Conditions ) )
call TriggerAddAction( gg_trg_Repulsion_Loop, function Trig_Repulsion_Loop_Actions )
endfunction
function Trig_Attractor_Cast_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A002'
endfunction
function Trig_Attractor_Cast_Actions takes nothing returns nothing
local real r=SquareRoot((GetSpellTargetX()-GetUnitX(GetTriggerUnit()))*(GetSpellTargetX()-GetUnitX(GetTriggerUnit()))+(GetSpellTargetY()-GetUnitY(GetTriggerUnit()))*(GetSpellTargetY()-GetUnitY(GetTriggerUnit())))
local real dx=(GetSpellTargetX()-GetUnitX(GetTriggerUnit()))/r
local real dy=(GetSpellTargetY()-GetUnitY(GetTriggerUnit()))/r
set udg_AttractorBall[udg_AttractorInstances]=CreateUnit( GetOwningPlayer(GetTriggerUnit()),'u001',GetUnitX(GetTriggerUnit()),GetUnitY(GetTriggerUnit()),0)
set udg_AttractorSpeed[2*udg_AttractorInstances]=5*dx
set udg_AttractorSpeed[2*udg_AttractorInstances+1]=5*dy
call UnitApplyTimedLife(udg_AttractorBall[udg_AttractorInstances], 'BTLF', 20.00 )
set udg_AttractorInstances=udg_AttractorInstances+1
endfunction
//===========================================================================
function InitTrig_Attractor_Cast takes nothing returns nothing
set gg_trg_Attractor_Cast = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Attractor_Cast, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Attractor_Cast, Condition( function Trig_Attractor_Cast_Conditions ) )
call TriggerAddAction( gg_trg_Attractor_Cast, function Trig_Attractor_Cast_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Attractor_Loop_Conditions takes nothing returns boolean
return udg_AttractorInstances > 0
endfunction
function Trig_Attractor_Loop_Actions takes nothing returns nothing
local unit u
local unit victim
local integer LoopIndex=0
local integer IndexLoop
local real r
local real dx
local real dy
loop
set u=udg_AttractorBall[LoopIndex]
if IsUnitType(u,UNIT_TYPE_DEAD)==false then
set IndexLoop=0
loop //First loop - other Attractors
if(LoopIndex!=IndexLoop)then
set victim=udg_AttractorBall[IndexLoop]
set r=SquareRoot((GetUnitX(u)-GetUnitX(victim))*(GetUnitX(u)-GetUnitX(victim))+(GetUnitY(u)-GetUnitY(victim))*(GetUnitY(u)-GetUnitY(victim)))
if r>64 then //Schwarzschild Radius XD. Ok, that was a joke, but its to prevent the infinite gravitation hole.
set dx=(1/(r*r))*((GetUnitX(u)-GetUnitX(victim))/r)*10000
set dy=(1/(r*r))*((GetUnitY(u)-GetUnitY(victim))/r)*10000
set udg_AttractorSpeed[2*IndexLoop]=udg_AttractorSpeed[2*IndexLoop]+dx
set udg_AttractorSpeed[2*IndexLoop+1]=udg_AttractorSpeed[2*IndexLoop+1]+dy
endif
endif
set IndexLoop=IndexLoop+1
exitwhen IndexLoop>=udg_AttractorInstances
endloop
set IndexLoop=0
loop //Second Loop - Holy Chain
set victim=udg_FireChainBalls[2*IndexLoop]
set r=SquareRoot((GetUnitX(u)-GetUnitX(victim))*(GetUnitX(u)-GetUnitX(victim))+(GetUnitY(u)-GetUnitY(victim))*(GetUnitY(u)-GetUnitY(victim)))
if r>64 then //Schwarzschild Radius
set dx=(1/(r*r))*((GetUnitX(u)-GetUnitX(victim))/r)*10000
set dy=(1/(r*r))*((GetUnitY(u)-GetUnitY(victim))/r)*10000
set udg_FireChainSpeed[4*IndexLoop]=udg_FireChainSpeed[4*IndexLoop]+dx
set udg_FireChainSpeed[4*IndexLoop+1]=udg_FireChainSpeed[4*IndexLoop+1]+dy
endif
set victim=udg_FireChainBalls[2*IndexLoop+1]
set r=SquareRoot((GetUnitX(u)-GetUnitX(victim))*(GetUnitX(u)-GetUnitX(victim))+(GetUnitY(u)-GetUnitY(victim))*(GetUnitY(u)-GetUnitY(victim)))
if r>64 then //Schwarzschild Radius
set dx=(1/(r*r))*((GetUnitX(u)-GetUnitX(victim))/r)*10000
set dy=(1/(r*r))*((GetUnitY(u)-GetUnitY(victim))/r)*10000
set udg_FireChainSpeed[4*IndexLoop+2]=udg_FireChainSpeed[4*IndexLoop+2]+dx
set udg_FireChainSpeed[4*IndexLoop+3]=udg_FireChainSpeed[4*IndexLoop+3]+dy
endif
set IndexLoop=IndexLoop+1
exitwhen IndexLoop>=udg_FireChainInstances
endloop
set IndexLoop=0
loop //Third Loop - Homing Missiles
set victim=udg_HomingBall[IndexLoop]
set r=SquareRoot((GetUnitX(u)-GetUnitX(victim))*(GetUnitX(u)-GetUnitX(victim))+(GetUnitY(u)-GetUnitY(victim))*(GetUnitY(u)-GetUnitY(victim)))
if r>64 then //Schwarzschild Radius
set dx=(1/(r*r))*((GetUnitX(u)-GetUnitX(victim))/r)*10000
set dy=(1/(r*r))*((GetUnitY(u)-GetUnitY(victim))/r)*10000
set udg_HomingSpeed[2*IndexLoop]=udg_HomingSpeed[2*IndexLoop]+dx
set udg_HomingSpeed[2*IndexLoop+1]=udg_HomingSpeed[2*IndexLoop+1]+dy
endif
set IndexLoop=IndexLoop+1
exitwhen IndexLoop>=udg_HomingInstances
endloop
call SetUnitX(u, GetUnitX(u)+udg_AttractorSpeed[2*LoopIndex])
call SetUnitY(u, GetUnitY(u)+udg_AttractorSpeed[2*LoopIndex+1])
set LoopIndex=LoopIndex+1
else
set IndexLoop=LoopIndex+1
loop
set udg_AttractorBall[IndexLoop-1]=udg_AttractorBall[IndexLoop]
set udg_AttractorSpeed[2*IndexLoop-2]=udg_AttractorSpeed[2*IndexLoop]
set udg_AttractorSpeed[2*IndexLoop-1]=udg_AttractorSpeed[2*IndexLoop+1]
exitwhen IndexLoop>udg_AttractorInstances
set IndexLoop=IndexLoop+1
endloop
set udg_AttractorInstances=udg_AttractorInstances-1
endif
exitwhen LoopIndex>=udg_AttractorInstances
endloop
endfunction
//===========================================================================
function InitTrig_Attractor_Loop takes nothing returns nothing
set gg_trg_Attractor_Loop = CreateTrigger( )
call TriggerRegisterTimerEventPeriodic( gg_trg_Attractor_Loop, 0.05 )
call TriggerAddCondition( gg_trg_Attractor_Loop, Condition( function Trig_Attractor_Loop_Conditions ) )
call TriggerAddAction( gg_trg_Attractor_Loop, function Trig_Attractor_Loop_Actions )
endfunction
function Trig_Homing_Cast_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A003'
endfunction
function Trig_Homing_Cast_Actions takes nothing returns nothing
local real r=SquareRoot((GetSpellTargetX()-GetUnitX(GetTriggerUnit()))*(GetSpellTargetX()-GetUnitX(GetTriggerUnit()))+(GetSpellTargetY()-GetUnitY(GetTriggerUnit()))*(GetSpellTargetY()-GetUnitY(GetTriggerUnit())))
local real dx=(GetSpellTargetX()-GetUnitX(GetTriggerUnit()))/r
local real dy=(GetSpellTargetY()-GetUnitY(GetTriggerUnit()))/r
set udg_HomingBall[udg_HomingInstances]=CreateUnit( GetOwningPlayer(GetTriggerUnit()),'u002',GetUnitX(GetTriggerUnit()),GetUnitY(GetTriggerUnit()),0)
set udg_HomingSpeed[2*udg_HomingInstances]=15*dx
set udg_HomingSpeed[2*udg_HomingInstances+1]=15*dy
set udg_HomingTarget[udg_HomingInstances]=GetSpellTargetUnit()
call UnitApplyTimedLife(udg_HomingBall[udg_HomingInstances], 'BTLF', 20.00 )
set udg_HomingInstances=udg_HomingInstances+1
endfunction
//===========================================================================
function InitTrig_Homing_Cast takes nothing returns nothing
set gg_trg_Homing_Cast = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Homing_Cast, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Homing_Cast, Condition( function Trig_Homing_Cast_Conditions ) )
call TriggerAddAction( gg_trg_Homing_Cast, function Trig_Homing_Cast_Actions )
endfunction
//TESH.scrollpos=33
//TESH.alwaysfold=0
function Trig_Homing_Loop_Conditions takes nothing returns boolean
if ( not ( udg_HomingInstances > 0 ) ) then
return false
endif
return true
endfunction
function Trig_Homing_Loop_Actions takes nothing returns nothing
local unit u
local unit victim
local integer LoopIndex=0
local integer IndexLoop
local real r
local real dx
local real dy
loop
set u=udg_HomingBall[LoopIndex]
set victim=udg_HomingTarget[LoopIndex]
if IsUnitType(u,UNIT_TYPE_DEAD)==false and IsUnitType(victim,UNIT_TYPE_DEAD)==false then
set r=SquareRoot((GetUnitX(u)-GetUnitX(victim))*(GetUnitX(u)-GetUnitX(victim))+(GetUnitY(u)-GetUnitY(victim))*(GetUnitY(u)-GetUnitY(victim)))
if r>32 then
set dx=((GetUnitX(u)-GetUnitX(victim))/r)/2
set dy=((GetUnitY(u)-GetUnitY(victim))/r)/2
set udg_HomingSpeed[2*LoopIndex]=udg_HomingSpeed[2*LoopIndex]-dx
set udg_HomingSpeed[2*LoopIndex+1]=udg_HomingSpeed[2*LoopIndex+1]-dy
call SetUnitX(u, GetUnitX(u)+udg_HomingSpeed[2*LoopIndex])
call SetUnitY(u, GetUnitY(u)+udg_HomingSpeed[2*LoopIndex+1])
else
call KillUnit(u)
if IsUnitAlly(victim,GetOwningPlayer(u)) then
call SetUnitState(victim, UNIT_STATE_LIFE, GetUnitState(victim,UNIT_STATE_LIFE)+200)
else
call UnitDamageTarget(u,victim, 400, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SPIRIT_LINK, WEAPON_TYPE_WHOKNOWS)
endif
endif
set LoopIndex=LoopIndex+1
else
call KillUnit(u)
set IndexLoop=LoopIndex+1
loop
set udg_HomingBall[IndexLoop-1]=udg_HomingBall[IndexLoop]
set udg_HomingTarget[IndexLoop-1]=udg_HomingTarget[IndexLoop]
set udg_HomingSpeed[2*IndexLoop-2]=udg_HomingSpeed[2*IndexLoop]
set udg_HomingSpeed[2*IndexLoop-1]=udg_HomingSpeed[2*IndexLoop+1]
exitwhen IndexLoop>udg_HomingInstances
set IndexLoop=IndexLoop+1
endloop
set udg_HomingInstances=udg_HomingInstances-1
endif
exitwhen LoopIndex>=udg_HomingInstances
endloop
endfunction
//===========================================================================
function InitTrig_Homing_Loop takes nothing returns nothing
set gg_trg_Homing_Loop = CreateTrigger( )
call TriggerRegisterTimerEventPeriodic( gg_trg_Homing_Loop, 0.05 )
call TriggerAddCondition( gg_trg_Homing_Loop, Condition( function Trig_Homing_Loop_Conditions ) )
call TriggerAddAction( gg_trg_Homing_Loop, function Trig_Homing_Loop_Actions )
endfunction