- Joined
- Nov 25, 2008
- Messages
- 1,309
I'm coding a projectile system in jass and I've gotten a long way, but i want to be able for it to have the functionality of a fire ball that when it blows up the nearby ground catches on fire.
However I want it to be that with a few changes in the trigger (that uses the system) you can make it an ice field from a blizzard.
All this can be done except the AoE damaging/slowing overtime. The slowing part I can do, but I'm lost on making the basic 'deals x dmg over y seconds in z area' effect.
NOTE: this is just the core system, not the two helper function that clear/set a projectile.
Explanation of variables:
However I want it to be that with a few changes in the trigger (that uses the system) you can make it an ice field from a blizzard.
All this can be done except the AoE damaging/slowing overtime. The slowing part I can do, but I'm lost on making the basic 'deals x dmg over y seconds in z area' effect.
NOTE: this is just the core system, not the two helper function that clear/set a projectile.
JASS:
function Trig_PS_TargetFilter takes nothing returns boolean
local unit u=GetFilterUnit()
local boolean b=GetUnitState(u,UNIT_STATE_LIFE)>0and IsUnitEnemy(u,GetOwningPlayer(udg_PS_CurProjectile))==true and IsUnitInGroup(u,udg_PSG_Projectiles)==false
set u=null
return b
endfunction
function Trig_PS_Target takes nothing returns nothing
call UnitDamageTarget(udg_PS_CurProjectile,GetEnumUnit(),udg_PS_Dmg,true,false,ATTACK_TYPE_MELEE,DAMAGE_TYPE_NORMAL,null)
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 group g
local location l
local integer i
local player p=GetOwningPlayer(u)
local real an
local unit U
//Reals
set udg_PS_Wiggle=LoadReal(udg_PSG_Hash,id,StringHash("Wiggle"))*udg_PSG_Rate
set udg_PS_Turn=LoadReal(udg_PSG_Hash,id,StringHash("Turn"))*udg_PSG_Rate
set udg_PS_Angle=LoadReal(udg_PSG_Hash,id,StringHash("Angle"))+udg_PS_Turn+GetRandomReal(-udg_PS_Wiggle,udg_PS_Wiggle)
set udg_PS_Speed=LoadReal(udg_PSG_Hash,id,StringHash("Speed"))*udg_PSG_Rate
set udg_PS_ColSize=LoadReal(udg_PSG_Hash,id,StringHash("ColSize"))
set udg_PS_ColColSize=LoadReal(udg_PSG_Hash,id,StringHash("ColColSize"))
set udg_PS_Dmg=LoadReal(udg_PSG_Hash,id,StringHash("Dmg"))
set udg_PS_DmgAoE=LoadReal(udg_PSG_Hash,id,StringHash("DmgAoE"))
set udg_PS_DmgDoT=LoadReal(udg_PSG_Hash,id,StringHash("DmgDot"))
//Integers
//Ids
set udg_PS_TrailUnit=LoadInteger(udg_PSG_Hash,id,StringHash("TrailUnit"))
set udg_PS_ColUnit=LoadInteger(udg_PSG_Hash,id,StringHash("ColUnit"))
//Ints
set udg_PS_TrailChance=LoadInteger(udg_PSG_Hash,id,StringHash("TrailChance"))
set udg_PS_TrailNum=LoadInteger(udg_PSG_Hash,id,StringHash("TrailNum"))
set udg_PS_Life=LoadInteger(udg_PSG_Hash,id,StringHash("Life"))-R2I(udg_PS_Speed)
set udg_PS_ColNum=LoadInteger(udg_PSG_Hash,id,StringHash("ColNum"))
set udg_PS_Custom=LoadInteger(udg_PSG_Hash,id,StringHash("Custom"))
set udg_PS_Filter=LoadInteger(udg_PSG_Hash,id,StringHash("Filter"))
//Booleans
set udg_PS_ColDeath=LoadBoolean(udg_PSG_Hash,id,StringHash("ColDeath"))
//Strings
set udg_PS_TrailSFX=LoadStr(udg_PSG_Hash,id,StringHash("TrailSFX"))
set udg_PS_ColSFX=LoadStr(udg_PSG_Hash,id,StringHash("ColSFX"))
set udg_PS_AoESFX=LoadStr(udg_PSG_Hash,id,StringHash("AoESFX"))
set udg_PS_DoTSFX=LoadStr(udg_PSG_Hash,id,StringHash("DoTSFX"))
//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)
set l=Location(xy[0],xy[1])
set g=GetUnitsInRangeOfLocMatching(udg_PS_ColSize,l,Condition(function Trig_PS_TargetFilter))
call RemoveLocation(l)
set l=null
if CountUnitsInGroup(g)>0then
set Boom=true
call ForGroup(g,function Trig_PS_Target)
if udg_PS_ColDeath then
set udg_PS_Life=0
endif
endif
call GroupClear(g)
set g=null
/////////////////////////
//Trail SFX and units
/////////////////////////
call DestroyEffect(AddSpecialEffect(udg_PS_TrailSFX,xy[0],xy[1]))
if udg_PS_TrailChance>0and udg_PS_TrailUnit!=0and udg_PS_TrailNum>0then
if GetRandomInt(1,100)<=udg_PS_TrailChance then
set i=0
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
endif
set U=CreateUnit(p,udg_PS_TrailUnit,xy[0],xy[1],an)
call SaveInteger(udg_PSG_Hash,GetHandleId(U),StringHash("Custom"),udg_PS_Custom)
set U=null
endloop
endif
endif
/////////////////////////
//Save the values we change
/////////////////////////
call SaveReal(udg_PSG_Hash,id,StringHash("Angle"),udg_PS_Angle)
call SaveInteger(udg_PSG_Hash,id,StringHash("Life"),udg_PS_Life)
/////////////////////////
//If out of life or on Death Terrain->die
/////////////////////////
if GetTerrainType(xy[0],xy[1])==udg_PSG_Terrain or udg_PS_Life<=0 or IsTerrainPathable(xy[0],xy[1],PATHING_TYPE_WALKABILITY) or IsTerrainPathable(xy[0],xy[1],ConvertPathingType(udg_PS_Filter))or IsPathable(xy[0],xy[1],'I001') then
set Boom=true
call KillUnit(udg_PS_CurProjectile)
call GroupRemoveUnit(udg_PSG_Projectiles,udg_PS_CurProjectile)
call FlushChildHashtable(udg_PSG_Hash,id)
endif
/////////////////////////
//If collide with unit or die->boom
/////////////////////////
if Boom then
call DestroyEffect(AddSpecialEffect(udg_PS_ColSFX,xy[0],xy[1]))
call UnitDamagePoint(udg_PS_CurProjectile,0,udg_PS_ColColSize,xy[0],xy[1],udg_PS_DmgAoE,true,false,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_UNIVERSAL,null)
if udg_PS_ColUnit!=0and udg_PS_ColNum>0then
set i=0
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),StringHash("Custom"),udg_PS_Custom)
set U=null
endloop
endif
endif
//clear locals
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
JASS:
===========================================================================
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_AoESFX
- String
- <Not In Use>
====================
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_DmgDoT
- Real
- <Not In Use>
====================
udg_PS_DoTSFX
- String
- <Not In Use>
====================
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_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_Hash
- Hashtable
- Stores all projectile data in this.
====================
udg_PSG_Projectiles
- Unit Group
- Contains all projectiles to iterate through them.
====================
udg_PSG_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
string udg_PS_AoESFX
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
real udg_PS_DmgDoT
string udg_PS_DoTSFX
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
real udg_PS_Wiggle
integer udg_PSG_Count
hashtable udg_PSG_Hash
unitgroup udg_PSG_Projectiles
real udg_PSG_Rate
terrain-type udg_PSG_Terrain