```
/////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////PROJECTILE SYSTEM 2////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
constant function PS_Accel takes nothing returns integer
return 0
endfunction
constant function PS_Angle takes nothing returns integer
return 1
endfunction
constant function PS_Attach takes nothing returns integer
return 2
endfunction
constant function PS_ColColSize takes nothing returns integer
return 3
endfunction
constant function PS_ColDeath takes nothing returns integer
return 4
endfunction
constant function PS_ColNum takes nothing returns integer
return 5
endfunction
constant function PS_ColSFX takes nothing returns integer
return 6
endfunction
constant function PS_ColSize takes nothing returns integer
return 7
endfunction
constant function PS_ColUnit takes nothing returns integer
return 8
endfunction
constant function PS_Custom takes nothing returns integer
return 9
endfunction
constant function PS_Dmg takes nothing returns integer
return 10
endfunction
constant function PS_DmgAoE takes nothing returns integer
return 11
endfunction
constant function PS_Filter takes nothing returns integer
return 12
endfunction
constant function PS_Height takes nothing returns integer
return 13
endfunction
constant function PS_HeightE takes nothing returns integer
return 14
endfunction
constant function PS_HeightS takes nothing returns integer
return 15
endfunction
constant function PS_Life takes nothing returns integer
return 16
endfunction
constant function PS_MaxLife takes nothing returns integer
return 17
endfunction
constant function PS_Rate takes nothing returns integer
return 18
endfunction
constant function PS_Speed takes nothing returns integer
return 19
endfunction
constant function PS_TrailChance takes nothing returns integer
return 20
endfunction
constant function PS_TrailNum takes nothing returns integer
return 21
endfunction
constant function PS_TrailSFX takes nothing returns integer
return 22
endfunction
constant function PS_TrailUnit takes nothing returns integer
return 23
endfunction
constant function PS_Turn takes nothing returns integer
return 24
endfunction
constant function PS_TypeAttack takes nothing returns integer
return 25
endfunction
constant function PS_TypeDamage takes nothing returns integer
return 26
endfunction
constant function PS_Wiggle takes nothing returns integer
return 27
endfunction
function PS_Reset takes nothing returns nothing
set udg_PS_Accel=0
set udg_PS_Angle=0
set udg_PS_Attach="origin"
set udg_PS_ColColSize=0
set udg_PS_ColDeath=true
set udg_PS_ColNum=0
set udg_PS_ColSFX=""
set udg_PS_ColSize=0
set udg_PS_ColUnit=-1
set udg_PS_CurProjectile=null
set udg_PS_Custom=0
set udg_PS_Dmg=0
set udg_PS_DmgAoE=0
set udg_PS_Filter=1
set udg_PS_Height=0
set udg_PS_HeightE=0
set udg_PS_HeightS=0
set udg_PS_Keep=false
set udg_PS_Life=0
set udg_PS_MaxLife=0
set udg_PS_Player=Player(0)
set udg_PS_Projectile=-1
set udg_PS_Rate=1
set udg_PS_Speed=0
set udg_PS_TrailChance=0
set udg_PS_TrailNum=0
set udg_PS_TrailSFX=""
set udg_PS_TrailUnit=-1
set udg_PS_Turn=0
set udg_PS_TypeAttack=0
set udg_PS_TypeDamage=4
set udg_PS_Wiggle=0
set udg_PS_X=0
set udg_PS_Y=0
endfunction
function PS_New takes nothing returns nothing
local unit u=CreateUnit(udg_PS_Player,udg_PS_Projectile,udg_PS_X,udg_PS_Y,udg_PS_Angle)
local integer id=GetHandleId(u)
call GroupAddUnit(udg_PSG_Projectiles,u)
call SaveReal( udg_PSG_Hash,id,PS_Accel(), udg_PS_Accel)
call SaveReal( udg_PSG_Hash,id,PS_Angle(), udg_PS_Angle)
call SaveReal( udg_PSG_Hash,id,PS_Wiggle(), udg_PS_Wiggle)
call SaveReal( udg_PSG_Hash,id,PS_Turn(), udg_PS_Turn)
call SaveReal( udg_PSG_Hash,id,PS_Speed(), udg_PS_Speed)
call SaveReal( udg_PSG_Hash,id,PS_ColSize(), udg_PS_ColSize)
call SaveReal( udg_PSG_Hash,id,PS_ColColSize(), udg_PS_ColColSize)
call SaveReal( udg_PSG_Hash,id,PS_Dmg(), udg_PS_Dmg)
call SaveReal( udg_PSG_Hash,id,PS_DmgAoE(), udg_PS_DmgAoE)
call SaveReal( udg_PSG_Hash,id,PS_Rate(), udg_PS_Rate)
call SaveInteger(udg_PSG_Hash,id,PS_TrailUnit(), udg_PS_TrailUnit)
call SaveInteger(udg_PSG_Hash,id,PS_ColUnit(), udg_PS_ColUnit)
call SaveInteger(udg_PSG_Hash,id,PS_TrailChance(),udg_PS_TrailChance)
call SaveInteger(udg_PSG_Hash,id,PS_TrailNum(), udg_PS_TrailNum)
call SaveInteger(udg_PSG_Hash,id,PS_Height(), udg_PS_Height)
call SaveInteger(udg_PSG_Hash,id,PS_HeightE(), udg_PS_HeightE)
call SaveInteger(udg_PSG_Hash,id,PS_HeightS(), udg_PS_HeightS)
call SaveInteger(udg_PSG_Hash,id,PS_Life(), udg_PS_Life)
call SaveInteger(udg_PSG_Hash,id,PS_MaxLife(), udg_PS_MaxLife)
call SaveInteger(udg_PSG_Hash,id,PS_ColNum(), udg_PS_ColNum)
call SaveInteger(udg_PSG_Hash,id,PS_Custom(), udg_PS_Custom)
call SaveInteger(udg_PSG_Hash,id,PS_Filter(), udg_PS_Filter)
call SaveInteger(udg_PSG_Hash,id,PS_TypeAttack(), udg_PS_TypeAttack)
call SaveInteger(udg_PSG_Hash,id,PS_TypeDamage(), udg_PS_TypeDamage)
call SaveBoolean(udg_PSG_Hash,id,PS_ColDeath(), udg_PS_ColDeath)
call SaveStr( udg_PSG_Hash,id,PS_TrailSFX(), udg_PS_TrailSFX)
call SaveStr( udg_PSG_Hash,id,PS_ColSFX(), udg_PS_ColSFX)
call EnableTrigger(gg_trg_PS)
if udg_PS_Keep==false then
call PS_Reset()
else
set udg_PS_Keep=false
endif
set u=null
endfunction
function IsPathableEnum takes nothing returns boolean
local unit u=GetFilterUnit()
local boolean b=not(IsUnitType(u,UNIT_TYPE_STRUCTURE))or not(IsUnitInGroup(u,udg_PSG_Projectiles))
set u=null
if b then
set udg_PSG_Count2=udg_PSG_Count2+1
endif
return b
endfunction
function IsPathable takes real x,real y,integer id returns boolean
local item I=CreateItem(id,x,y)
local boolean B=false
local group g=CreateGroup()
local integer i
local boolexpr filter=Condition(function IsPathableEnum)
set udg_PSG_Count2=0
call GroupEnumUnitsInRange(g,x,y,24,filter)
call DestroyBoolExpr(filter)
set filter=null
set i=udg_PSG_Count2
if (((GetItemX(I)-x)*(GetItemX(I)-x)+(GetItemY(I)-y)*(GetItemY(I)-y))>=1024)and i==0then
set B=true
endif
call DestroyGroup(g)
set g=null
call RemoveItem(I)
set I=null
return B
endfunction
function Trig_PS_TargetFilter takes nothing returns boolean
local unit u=GetFilterUnit()
local boolean b=GetWidgetLife(u)>0.405and IsUnitEnemy(u,GetOwningPlayer(udg_PS_CurProjectile)) and IsUnitInGroup(u,udg_PSG_Projectiles)==false and IsUnitType(u,UNIT_TYPE_DEAD)==false
set u=null
if b then
set udg_PSG_Count2=udg_PSG_Count2+1
endif
return b
endfunction
function Trig_PS_Target takes nothing returns nothing
call UnitDamageTarget(udg_PS_CurProjectile,GetEnumUnit(),udg_PS_Dmg,true,false,ConvertAttackType(udg_PS_TypeAttack),ConvertDamageType(udg_PS_TypeDamage),null)
endfunction
function Trig_PS_Target2 takes nothing returns nothing
call UnitDamageTarget(udg_PS_CurProjectile,GetEnumUnit(),udg_PS_DmgAoE,true,false,ConvertAttackType(udg_PS_TypeAttack),ConvertDamageType(udg_PS_TypeDamage),null)
endfunction
function GetHeight takes real y0, real y1, real h, real d, real x returns real
local real A = (2*(y0+y1)-4*h)/(d*d)
local real B = (y1-y0-A*d*d)/d
return A*x*x + B*x + y0
endfunction
function Trig_PS_Loop takes nothing returns nothing
local unit u=GetEnumUnit()
local integer id=GetHandleId(u)
local real array xy
local boolean Boom=false
local boolean Die=false
local boolean grounded=true
local real height=0
local group g=CreateGroup()
local integer i
local integer I
local player p=GetOwningPlayer(u)
local real an
local unit U
local boolexpr filter=Condition(function Trig_PS_TargetFilter)
//Reals
set udg_PS_Rate=LoadReal(udg_PSG_Hash,id,PS_Rate())
set udg_PS_Accel=LoadReal(udg_PSG_Hash,id,PS_Accel())
set udg_PS_Wiggle=LoadReal(udg_PSG_Hash,id,PS_Wiggle())*udg_PS_Rate
set udg_PS_Turn=LoadReal(udg_PSG_Hash,id,PS_Turn())*udg_PS_Rate
set udg_PS_Angle=LoadReal(udg_PSG_Hash,id,PS_Angle())+udg_PS_Turn+GetRandomReal(-udg_PS_Wiggle,udg_PS_Wiggle)
set udg_PS_Speed=LoadReal(udg_PSG_Hash,id,PS_Speed())*udg_PS_Rate+udg_PS_Accel*udg_PS_Rate
set udg_PS_ColSize=LoadReal(udg_PSG_Hash,id,PS_ColSize())
set udg_PS_ColColSize=LoadReal(udg_PSG_Hash,id,PS_ColColSize())
set udg_PS_Dmg=LoadReal(udg_PSG_Hash,id,PS_Dmg())
set udg_PS_DmgAoE=LoadReal(udg_PSG_Hash,id,PS_DmgAoE())
//Integers
//Ids
set udg_PS_TrailUnit=LoadInteger(udg_PSG_Hash,id,PS_TrailUnit())
set udg_PS_ColUnit=LoadInteger(udg_PSG_Hash,id,PS_ColUnit())
//Ints
set udg_PS_Height=LoadInteger(udg_PSG_Hash,id,PS_Height())
set udg_PS_TrailChance=LoadInteger(udg_PSG_Hash,id,PS_TrailChance())
set udg_PS_TrailNum=LoadInteger(udg_PSG_Hash,id,PS_TrailNum())
set udg_PS_Life=LoadInteger(udg_PSG_Hash,id,PS_Life())-R2I(RAbsBJ(udg_PS_Speed))
call DisplayTextToPlayer(Player(0),0,0,R2S(udg_PS_Life))
set udg_PS_MaxLife=LoadInteger(udg_PSG_Hash,id,PS_MaxLife())
set udg_PS_ColNum=LoadInteger(udg_PSG_Hash,id,PS_ColNum())
set udg_PS_Custom=LoadInteger(udg_PSG_Hash,id,PS_Custom())
set udg_PS_Filter=LoadInteger(udg_PSG_Hash,id,PS_Filter())
set udg_PS_TypeAttack=LoadInteger(udg_PSG_Hash,id,PS_TypeAttack())
set udg_PS_TypeDamage=LoadInteger(udg_PSG_Hash,id,PS_TypeDamage())
set udg_PS_HeightS=LoadInteger(udg_PSG_Hash,id,PS_HeightS())
set udg_PS_HeightE=LoadInteger(udg_PSG_Hash,id,PS_HeightE())
//Booleans
set udg_PS_ColDeath=LoadBoolean(udg_PSG_Hash,id,PS_ColDeath())
//Strings
set udg_PS_TrailSFX=LoadStr(udg_PSG_Hash,id,PS_TrailSFX())
set udg_PS_ColSFX=LoadStr(udg_PSG_Hash,id,PS_ColSFX())
set udg_PS_Attach=LoadStr(udg_PSG_Hash,id,PS_Attach())
//System
if udg_PS_Filter==0 then
set udg_PS_Filter=1
endif
set udg_PS_CurProjectile=u
set xy[0]=GetUnitX(udg_PS_CurProjectile)+udg_PS_Speed*Cos(udg_PS_Angle*.01745)
set xy[1]=GetUnitY(udg_PS_CurProjectile)+udg_PS_Speed*Sin(udg_PS_Angle*.01745)
call SetUnitX(udg_PS_CurProjectile,xy[0])
call SetUnitY(udg_PS_CurProjectile,xy[1])
call SetUnitFacing(udg_PS_CurProjectile,udg_PS_Angle)
/////////////////////////
//Parabolic Height, if needed
/////////////////////////
if udg_PS_Height>0then
set height=GetHeight(udg_PS_HeightS,udg_PS_HeightE,udg_PS_Height,udg_PS_MaxLife,udg_PS_MaxLife-udg_PS_Life)
call SetUnitFlyHeight(udg_PS_CurProjectile,height,1000000)
if height>50then
set grounded=false
endif
endif
/////////////////////////
set udg_PSG_Count2=0
call GroupEnumUnitsInRange(g,xy[0],xy[1],udg_PS_ColSize,filter)
if udg_PSG_Count2>0and grounded then
set Boom=true
call ForGroup(g,function Trig_PS_Target)
if udg_PS_ColDeath then
set udg_PS_Life=0
endif
endif
call DestroyGroup(g)
call GroupClear(g)
set g=null
/////////////////////////
//Trail SFX and units
/////////////////////////
call DestroyEffect(AddSpecialEffectTarget(udg_PS_TrailSFX,udg_PS_CurProjectile,udg_PS_Attach))
if udg_PS_TrailChance>0and udg_PS_TrailUnit!=0and udg_PS_TrailNum>0then
if GetRandomInt(1,100)<=udg_PS_TrailChance then
set i=0
set I=GetRandomInt(0,360)
loop
exitwhen i==udg_PS_TrailNum
set i=i+1
if udg_PS_TrailNum==1then
set an=GetRandomReal(0,360)
else
set an=360/udg_PS_TrailNum*i+I
endif
set U=CreateUnit(p,udg_PS_TrailUnit,xy[0],xy[1],an)
call SaveInteger(udg_PSG_Hash,GetHandleId(U),PS_Custom(),udg_PS_Custom)
set U=null
endloop
endif
endif
/////////////////////////
//Save the values we change
/////////////////////////
call SaveReal(udg_PSG_Hash,id,PS_Angle(),udg_PS_Angle)
call SaveInteger(udg_PSG_Hash,id,PS_Life(),udg_PS_Life)
call SaveReal(udg_PSG_Hash,id,PS_Speed(),udg_PS_Speed)
/////////////////////////
//If out of life or on Death Terrain->die
/////////////////////////
if IsTerrainPathable(xy[0],xy[1],PATHING_TYPE_WALKABILITY) or IsTerrainPathable(xy[0],xy[1],ConvertPathingType(udg_PS_Filter))or IsPathable(xy[0],xy[1],udg_PSG_TestItem) then
if grounded then
set Die=true
set Boom=true
endif
endif
if GetTerrainType(xy[0],xy[1])==udg_PSG_Terrain or udg_PS_Life<=0then
set Die=true
set Boom=true
endif
/////////////////////////
//If collide with unit or die->boom
/////////////////////////
if Boom then
set g=CreateGroup()
call GroupEnumUnitsInRange(g,xy[0],xy[1],udg_PS_ColColSize,filter)
call ForGroup(g,function Trig_PS_Target2)
call DestroyGroup(g)
set g=null
call DestroyEffect(AddSpecialEffectTarget(udg_PS_ColSFX,udg_PS_CurProjectile,udg_PS_Attach))
if udg_PS_ColUnit!=0and udg_PS_ColNum>0then
set i=0
set I=GetRandomInt(0,360)
loop
exitwhen i==udg_PS_ColNum
set i=i+1
if udg_PS_ColNum==1then
set an=GetRandomReal(0,360)
else
set an=360/udg_PS_ColNum*i
endif
set U=CreateUnit(p,udg_PS_ColUnit,xy[0],xy[1],an)
call SaveInteger(udg_PSG_Hash,GetHandleId(U),PS_Custom(),udg_PS_Custom)
set U=null
endloop
endif
endif
if Die then
call KillUnit(udg_PS_CurProjectile)
call GroupRemoveUnit(udg_PSG_Projectiles,udg_PS_CurProjectile)
call FlushChildHashtable(udg_PSG_Hash,id)
endif
//clear locals
call DestroyBoolExpr(filter)
set filter=null
set p=null
set u=null
//reset globals
call PS_Reset()
set udg_PSG_Count=udg_PSG_Count+1
endfunction
function Trig_PS_Actions takes nothing returns nothing
set udg_PSG_Count=0
call ForGroup(udg_PSG_Projectiles,function Trig_PS_Loop)
if udg_PSG_Count<1then
call DisableTrigger(gg_trg_PS)
endif
endfunction
function InitTrig_PS takes nothing returns nothing
set gg_trg_PS=CreateTrigger()
call DisableTrigger(gg_trg_PS)
call TriggerRegisterTimerEvent(gg_trg_PS,0.04,true)
call TriggerAddAction(gg_trg_PS,function Trig_PS_Actions)
endfunction
```