cleeezzz
The Undead Ranger.
- Reaction score
- 268
JASS:
library ProSys initializer Init requires KT, GroupUtils
function interface OnRun takes unit u returns nothing
function interface UnitImpact takes unit d, unit u returns nothing
function interface OnDeath takes unit u returns nothing
globals
group projectiles
private constant integer FLYID = 039;amrf039;
private real Game_maxX
private real Game_maxY
private real Game_minX
private real Game_minY
private unit TP
endglobals
private function SafeX takes real x returns real
if x<Game_minX then
return Game_minX
endif
if x>Game_maxX then
return Game_maxX
endif
return x
endfunction
private function IsXSafe takes real x returns boolean
if x>Game_minX and x<Game_maxX then
return true
endif
return false
endfunction
private function SafeY takes real y returns real
if y<Game_minY then
return Game_minY
endif
if y>Game_maxY then
return Game_maxY
endif
return y
endfunction
private function IsYSafe takes real y returns boolean
if y>Game_minY and y<Game_maxY then
return true
endif
return false
endfunction
private function SetUnitZ takes unit u, real height returns nothing
call UnitAddAbility(u, 039;Arav039;)
call UnitRemoveAbility(u, 039;Arav039;)
call SetUnitFlyHeight(u, height, 0.)
endfunction
//=======================================================================
struct P
//! runtextmacro PUI()
player play
unit p
real x
real y
real endcd // yes i know i dont use this variable, ill remove later
real maxd
real r
real cx
OnRun OR
UnitImpact UI
OnDeath OD
group g
method onDestroy takes nothing returns nothing
call GroupRemoveUnit(projectiles,.p)
set .play = null
call KillUnit(.p)
set .p = null
set .UI = 0
set .OD = 0
call ReleaseGroup(.g)
set .g = null
endmethod
endstruct
private function GlobalFilter takes unit u returns boolean // global filter for range check
return GetWidgetLife(u) > .405 and (IsUnitVisible(u, GetOwningPlayer(TP)) or GetUnitTypeId(u) == 039;oeye039;)
endfunction
private function ExecuteCPS takes nothing returns boolean
local P d = KT_GetData()
local AP s // struct AP (not in this trigger) works together with ProSys (AP stands for Arrow Properties)
local real x // AP stores damage, movement speed, and etc.
local real y
local real f
local group g
local unit fog
local real dist
call GroupRefresh(projectiles)
if GetWidgetLife(d.p) < .405 then
if d.p != null then
if d.OD != 0 then
call d.OD.evaluate(d.p)
endif
call d.release()
return true
else
debug call BJDebugMsg("|cffffcc00CPS ERROR: DO NOT REMOVE PROJECTILES USING THE OnRun/GroundImpact/UnitImpact/OnDeath FUNCTIONS!|r")
call d.release()
return true
endif
call GroupRemoveUnit(projectiles,d.p)
endif
set TP = d.p
if d.OR != 0 then
call d.OR.evaluate(d.p)
endif
set s = AP[d.p]
set x = GetUnitX(d.p)
set y = GetUnitY(d.p)
set dist = SquareRoot((d.x-x)*(d.x-x) + (d.y-y)*(d.y-y))
set d.cx = d.cx + dist
set s.totaldistance = d.cx
if d.cx > d.maxd then
if d.OD != 0 then
call d.OD.evaluate(d.p)
endif
call d.release()
return true
endif
set d.x = x
set d.y = y
set f = GetUnitFacing(d.p) * bj_DEGTORAD
set x = x+s.currentspeed*Cos(f)
set y = y+s.currentspeed*Sin(f)
if s.currentspeed < s.basespeed then
set s.currentspeed = s.currentspeed + s.acceleration
endif
if s.anglechange != 0. and GetUnitTypeId(d.p) != 039;h00K039; then
call SetUnitFacing(d.p, ModuloReal((GetUnitFacing(d.p)*bj_DEGTORAD) + s.anglechange,bj_PI*2)*bj_RADTODEG)
set s.anglechange = 0.
endif
if IsXSafe(x) == true and IsYSafe(y) == true then
call SetUnitX(d.p,x)
call SetUnitY(d.p,y)
else
if d.OD != 0 then
call d.OD.evaluate(d.p)
endif
call d.release()
return true
endif
if s.radius > 0 then // range check, if there are enemies, run UnitImpact function
set g = NewGroup()
call GroupEnumUnitsInRange(g,x,y,s.radius,null)
if FirstOfGroup(g) == null then
call GroupClear(d.g)
endif
loop
set fog = FirstOfGroup(g)
exitwhen fog == null
if IsUnitInGroup(fog,d.g) == false then
call GroupAddUnit(d.g,fog)
if d.UI != 0 and GlobalFilter(fog) then
call d.UI.evaluate(d.p,fog)
endif
endif
call GroupRemoveUnit(g,fog)
endloop
call ReleaseGroup(g)
set g = null
endif
return false
endfunction
function ProjectileAddEventOnRun takes unit proj, OnRun OR returns nothing //adds event to projectile, every time it runs
local P d = P[proj]
if d == 0 then
return
endif
set d.OR = OR
endfunction
function ProjectileAddEventUnitImpact takes unit proj, UnitImpact UI returns nothing //adds event to projectile, every time it hits a unit
local P d = P[proj]
if d == 0 then
return
endif
set d.UI = UI
endfunction
function ProjectileAddEventOnDeath takes unit proj, OnDeath OD returns nothing //adds event to projectile, when projectile dies
local P d = P[proj]
if d == 0 then
return
endif
set d.OD = OD
endfunction
function CPS takes integer ut, player play, real angle, real startX, real startY, real maxd returns unit
local P d
local AP z
if maxd == 0 then
debug call BJDebugMsg("|cffffcc00ProSys-CPS ERROR: No max distance|r")
return null
endif
set d = P.create()
set d.play = play
set d.p = CreateUnit(play, ut, startX, startY, bj_RADTODEG*(angle))
call GroupAddUnit(projectiles,d.p) //global projectile group
set z = AP.create(d.p)
set P[d.p] = d
set AP[d.p] = z
set d.maxd = maxd
set d.x = startX
set d.y = startY
set d.cx = 0
set d.g = NewGroup()
set d.UI = 0
set d.OD = 0
set d.OR = 0
call SetUnitPathing(d.p,false)
call UnitAddAbility(d.p,FLYID)
call SetUnitFlyHeight(d.p,50.,0.00)
call KT_Add(function ExecuteCPS, d, 0.03)
return d.p
endfunction
private function Init takes nothing returns nothing
set projectiles = NewGroup()
set Game_maxX = GetRectMaxX(bj_mapInitialPlayableArea)-50.00
set Game_maxY = GetRectMaxY(bj_mapInitialPlayableArea)-50.00
set Game_minX = GetRectMinX(bj_mapInitialPlayableArea)+50.00
set Game_minY = GetRectMinY(bj_mapInitialPlayableArea)+50.00
endfunction
endlibrary
This is a projectile system that I created and it needs some serious improvement. I thought this version would be better than my previous system (its better in flexibility i guess), but its HUGELY lacking in power.
my old system wouldn't lag with about 100 projectiles but this one starts lagging around there.