/////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////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
Name | Type | is_array | initial_value |
PS_Accel | real | No | |
PS_Angle | real | No | |
PS_Attach | string | No | |
PS_ColColSize | real | No | |
PS_ColDeath | boolean | No | |
PS_ColNum | integer | No | |
PS_ColSFX | string | No | |
PS_ColSize | real | No | |
PS_ColUnit | unitcode | No | |
PS_CurProjectile | unit | No | |
PS_Custom | integer | No | |
PS_Dmg | real | No | |
PS_DmgAoE | real | No | |
PS_Filter | integer | No | |
PS_Height | integer | No | |
PS_HeightE | integer | No | |
PS_HeightS | integer | No | |
PS_Keep | boolean | No | |
PS_Life | integer | No | |
PS_MaxLife | integer | No | |
PS_Player | player | No | |
PS_Projectile | unitcode | No | |
PS_Rate | real | No | |
PS_Speed | real | No | |
PS_TrailChance | integer | No | |
PS_TrailNum | integer | No | |
PS_TrailSFX | string | No | |
PS_TrailUnit | unitcode | No | |
PS_Turn | real | No | |
PS_TypeAttack | integer | No | |
PS_TypeDamage | integer | No | |
PS_Wiggle | real | No | |
PS_X | real | No | |
PS_Y | real | No | |
PSG_Count | integer | No | |
PSG_Count2 | integer | No | |
PSG_Hash | hashtable | No | |
PSG_Projectiles | group | No | |
PSG_Terrain | terraintype | No | |
PSG_TestItem | itemcode | No | |
TmpInt | integer | No | |
TmpLoc | location | No | |
TmpReal | real | No | |
x | real | No | |
y | real | No |
===========================================================================
Explaination of variables
===========================================================================
Note: Col=Hitting a unit, running out of life, or hitting the 'Death' terrain type.
====================
'LOCAL' VARIABLES
====================
udg_PS_Angle
- Real
- Determines the angle that the projectile moves in.
- NOTE: Saves after each iteration.
====================
udg_PS_ColColSize
- Real
- Radius to damage units for udg_PS_DmgAoE when the projectile collides (aka explodes)
====================
udg_PS_ColDeath
- Boolean
- Whether or not the projectiles dies when it collides.
====================
udg_PS_ColNum
- Integer
- How many units to create when the projectile collides or dies.
- WARNING: Use care with high numbers!
====================
usg_PS_ColSFX
- String
- The special effect to create when the projectile collides or dies.
- WARNING: Try to use 'small' models if udg_PS_ColDeath = true.
====================
udg_PS_ColSize
- Real
- How far of a radius to check for colliding with units.
====================
udg_PS_ColUnit
- Integer (unit type)
- The unit type to create when the projectile collides or dies.
====================
udg_PS_CurProjectile
- Unit
- This is a temporary variable used internally, basically the EnumUnit in the loop.
====================
udg_PS_Custom
- Integer
- A custom value (like a unit's custom value) that can be used to pass some data along the projectile.
- NPTE: This value is passed to all TrailUnits or ColUnits it creates.
- NOTE: Not used in the system, but by the unser on a spell by spell basis.
====================
udg_PS_Dmg
- Real
- How much damage to deal to a unit it collides with.
====================
udg_PS_DmgAoE
- Real
- How much damage to deal to all units in udg_PS_ColColSize, stacks with udg_PS_Dmg.
====================
udg_PS_Keep
- Boolean
- After calling PS_New() function if this is true you keep all the global variable values, rather thanr esetting them.
- WARNING: Each iteration of the projectile system resets the values, so don't use waits.
- NOTE: You have to set this to true after each call of PS_New() as that will always reset it to false.
====================
udg_PS_Life
- Integer
- How far (in distance) the projectile moves before dieing.
- NOTE: Saves after each iteration.
====================
udg_PS_Speed
- Real
- How far the projectile moves.
====================
udg_PS_TrailChance
- Integer
- The chance (0-100) that the projectile will create udg_PS_TrailNum udg_PS_TrailUnit's.
- WARNING: Use care with high chances!
====================
udg_PS_TrailNum
- Integer
- How many units to create when it creates a trail unit.
- WARNING: Use care with high numbers!
====================
udg_PS_TrailSFX
- String
- The special effect to create each iteration.
- WARNING: Try to use 'small' models.
====================
udg_PS_TrailUnit
- Integer (unit type)
- The unit type the projectile has a chance to make each iteration.
====================
udg_PS_Turn
- Real
- Is added to udg_PS_Angle.
====================
udg_PS_TypeAttack
- Integer
- The attack type the projectile will use.
====================
udg_PS_TypeDamage
- Integer
- The damage type the projectile will use.
====================
udg_PS_Wiggle
- Real
- Nudges udg_PS_Angle by this ammount, positive or negitive.
====================
'GLOBAL' VARIABLES
====================
udg_PSG_Count
- Integer
- Counter used internally, check if the looping trigger should be turned off.
====================
udg_PSG_Count2
- Integer
- Counter used internally, check if the projectile collides.
====================
udg_PSG_Hash
- Hashtable
- Stores all projectile data in this.
====================
udg_PSG_Projectiles
- Unit Group
- Contains all projectiles to iterate through them.
====================
udg_PS_Rate
- Real
- This is like the rate of time, and is defualted to 1.00, is put to 2.00 the projectiles move and turn twice as fast. if set to 0 they will freeze.
- WARNING: Becareful of low values!
- Note: High values are look worse (5+).
====================
udg_PSG_Terrain
- Integer (Terrian Type)
- A terrain type that will kill any touching projectile.
====================
REFERANCE LIST
====================
real udg_PS_Angle
real udg_PS_ColColSize
boolean udg_PS_ColDeath
integer udg_PS_ColNum
string udg_PS_ColSFX
real udg_PS_ColSize
unit-type udg_PS_ColUnit
unit udg_PS_CurProjectile
integer udg_PS_Custom
real udg_PS_Dmg
real udg_PS_DmgAoE
boolean udg_PS_Keep
integer udg_PS_Life
real udg_PS_Speed
integer udg_PS_TrailChance
integer udg_PS_TrailNum
string udg_PS_TrailSFX
unit-type udg_PS_TrailUnit
real udg_PS_Turn
integer udg_PS_TypeAttack
integer udg_PS_TypeDamage
real udg_PS_Wiggle
integer udg_PSG_Count
integer udg_PSG_Count2
hashtable udg_PSG_Hash
unitgroup udg_PSG_Projectiles
real udg_PS_Rate
terrain-type udg_PSG_Terrain
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