- Joined
- Sep 21, 2007
- Messages
- 517
basicaly, there is asystem i created for moving particles in a map, neways, i didnt finish it and just finished collision, so i started to do group damaging, then i got a critical error and even units not moving correctly, but once i made the functions related to groups comments by adding //, basically disabling them, it worked fine, here is the code: (please ignore the destructables thing, i commented it out too)
sorry for bad jass, just started, if you have any tips on efficiency please do tell, P.S. i do use coordinates usually but i felt that Location(x,y) leaks after prolonged use, so turned to location and nulled for getting Z Heights.
JASS:
library SPS
globals
constant real INTERVAL = 0.03
constant real PHeight = 50.
constant real CollisionSize = 96.
string ATTACH = "origin"
constant integer PARTICLE_ID = 'e000'
private boolexpr b
private timer sps = CreateTimer()
private group g
integer SPSIndex = 0
SPS array temp_SPS
endglobals
struct SPS
unit u
unit u2
real s
real x
real y
real x2
real y2
real a
real dx
real dy
real z1
real ph
real dz
string sfxs2
effect sfx
effect sfx2
real dmg
boolean DamageDestructible
player p
attacktype atk
//============================================
static method UnitFilter takes nothing returns boolean
return GetWidgetLife(GetFilterUnit()) > .405 and IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetFilterUnit())) and (GetUnitAbilityLevel(GetFilterUnit(), 'Bvul') == 0) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false)
endmethod
//=============================================
method onDestroy takes nothing returns nothing
call DestroyEffect( .sfx )
call DestroyEffect( .sfx2 )
set .sfx = null
set .sfx2 = null
call UnitApplyTimedLife( .u, 'BTLF', 1.0 )
call UnitApplyTimedLife( .u2, 'BTLF', 1.0 )
set .u = null
set .u2 = null
if SPSIndex == 0 then
call PauseTimer( sps )
endif
endmethod
static method GetMoveX takes real s, real a returns real
return Cos(a)*s
endmethod
static method GetMoveY takes real s, real a returns real
return Sin(a)*s
endmethod
//===============================================================
//method GetDestructables takes nothing returns nothing
//if GetDestructableOccluderHeight >= GetUnitFlyHeight(dat.u) then
//set .u2 = CreateUnit( GetOwningPlayer(.u), PARTICLE_ID, dat.x, dat.y, 0. )
//call SetUnitFlyHeight( .u2, GetUnitFlyHeight(.u), 0. )
//set dat.sfx2 = AddSpecialEffectTarget( .sfxs2, .u2, ATTACH )
//set SPSIndex = SPSIndex - 1
//set temp_SPS[i] = temp_SPS[SPSIndex]
//call dat.destroy()
//endif
//endmethod
static method move takes nothing returns nothing
local SPS dat
local real zD
local integer i = 0
local location zloc
local unit f
loop
exitwhen i >= SPSIndex
set dat = temp_SPS[i]
call SetUnitPosition( dat.u, dat.x + dat.dx, dat.y + dat.dy )
set dat.x = GetUnitX( dat.u )
set dat.y = GetUnitY( dat.u )
set dat.ph = dat.ph + dat.dz
set zloc = Location(dat.x, dat.y)
set zD = (dat.z1+dat.ph) - GetLocationZ( zloc )
call RemoveLocation( zloc )
set zloc = null
call SetUnitFlyHeight( dat.u, zD, .0 )
call GroupClear(g)
call GroupEnumUnitsInRange( g, dat.x, dat.y, CollisionSize, b)
loop
set f = FirstOfGroup( g )
exitwhen (f == null)
call DisplayTextToForce( GetPlayersAll(), "WTF" )
call UnitDamageTarget( dat.u, GetEnumUnit(), dat.dmg, FALSE, FALSE, dat.atk, DAMAGE_TYPE_NORMAL, null )
set SPSIndex = SPSIndex - 1
set temp_SPS[i] = temp_SPS[SPSIndex]
call dat.destroy()
return
endloop
//call EnumDestructablesInCircleBJ( CollisionSize, Location(dat.x, dat,y), function SPS.GetDestructables )
if zD <= 1. or IsTerrainPathable( dat.x, dat.y, ConvertPathingType(2) ) then
set dat.u2 = CreateUnit( GetOwningPlayer(dat.u), PARTICLE_ID, dat.x, dat.y, 0. )
call SetUnitFlyHeight( dat.u2, zD, 0. )
set dat.sfx2 = AddSpecialEffectTarget( dat.sfxs2, dat.u2, ATTACH )
set SPSIndex = SPSIndex - 1
set temp_SPS[i] = temp_SPS[SPSIndex]
call dat.destroy()
endif
set i = i + 1
endloop
endmethod
public static method InitSPS takes unit u, real d, real s, string sfx, string sfx2, location t, boolean DD, attacktype atk returns SPS
local SPS dat = SPS.create()
local real DSRatio
local real dxr
local real dyr
local real st = s*INTERVAL
local real z2
local location Lr
set temp_SPS[SPSIndex] = dat
set dat.x = GetUnitX( u )
set dat.x2 = GetLocationX( t )
set dat.y = GetUnitY( u )
set dat.y2 = GetLocationY( t )
set z2 = GetLocationZ(Location(dat.x2, dat.y2))
set dat.a = Atan2( dat.y2 - dat.y, dat.x2 - dat.x )
set dat.p = GetOwningPlayer( u )
set dat.u = CreateUnit( dat.p, PARTICLE_ID, dat.x, dat.y, dat.a )
call SetUnitX( dat.u, dat.x )
call SetUnitY( dat.u, dat.y )
set Lr = Location(dat.x, dat.y)
set dat.z1 = GetLocationZ(Lr)
call RemoveLocation( Lr )
set Lr = null
set dat.dx = SPS.GetMoveX( st, dat.a )
set dat.dy = SPS.GetMoveY( st, dat.a )
set dat.sfx = AddSpecialEffectTarget( sfx, dat.u, ATTACH )
set dat.sfxs2 = sfx2
set dat.dmg = d
set dat.DamageDestructible = DD
set dat.atk = atk
call UnitAddAbility( dat.u, 'Amrf' )
call UnitRemoveAbility( dat.u, 'Amrf' )
set dat.ph = PHeight
set dat.dz = z2 - dat.z1
set dxr = dat.x2 - dat.x
set dyr = dat.y2 - dat.y
set DSRatio = SquareRoot(dxr * dxr + dyr * dyr)/s
if z2 < dat.z1 then
set dat.dz = dat.dz+(dat.dz/DSRatio)
else
set dat.dz = dat.dz+(dat.dz*DSRatio)
endif
set dat.dz = dat.dz*INTERVAL
if SPSIndex == 0 then
call TimerStart( sps, INTERVAL, true, function SPS.move )
endif
set SPSIndex = SPSIndex + 1
return dat
endmethod
endstruct
function SPS_Init takes nothing returns nothing
set b = Condition( function SPS.UnitFilter )
set g = CreateGroup()
endfunction
endlibrary