Narks
Vastly intelligent whale-like being from the stars
- Reaction score
- 90
Hmm, could we have projectiles that home in on another projectile? Like interception.
Projectile.projectArcingTarget(real sx, real sy, real speed, real archeight, real arcangle, widget target)
// same like the one with "Point" but targeting and following a target
Projectile.projectLinePoint(real sx, real sy, real speed, real tx, real ty)
Projectile.projectLineTarget(real sx, real sy, real speed, widget target)
// follows the target if it moves
Again, I thought that would be something that a user would make from this system.Hmm, could we have projectiles that home in on another projectile? Like interception.
Not quite sure I understand.. Don't you just mean the:How do we control collision size of units and projectiles?
.unitCollision // Collision detection radius for units.
.projCollision // Collision detection radius for projectiles.
.unitCollision // Collision detection radius for units.
.projCollision // Collision detection radius for projectiles.
Probably the projectile's collision radius when colliding with regular units, and then other projectiles, respectively.JASS:.unitCollision // Collision detection radius for units. .projCollision // Collision detection radius for projectiles.
But this doesn't make sense - if I call .unitCollision on my projectile, what does that do? Does that set the "size" of all units on the map? I am assuming .projCollision sets the size of the projectile.
One global boolean to replace dynamic group usage? Wouldn't really work, unless I use a 2D array or something.It seems you use dmgGroup like a way to link a boolean with an unit.
Wouldn't it be better to simply use a global boolean array, since you already use an unit indexer ?
Those members are just reals that represent a collision radius for the projectile... How would I go about adding booleans for them? I don't think you understand how that part of the system works.Shouldn't .unitcollision and .projcollision be like conditions that return true if the projectile has collided?
Haha, yes it was.oh and, was time warp inspired by me by any chance?
Yeah, the red arrow is double damage. I couldn't think of a good way to show it, so I just did that (it looks pretty crap).im guessing the Red arrow on the archers was double damage? i thought it was a bug at first (iono it looks weird)
The system uses [ljass]TriggerRegisterUnitInRange()[/ljass], which I thought took unit collision radii into account. Maybe I am wrong though, but from tests it seems that way.If you set .unitCollision to 64, the projectile will collide with any unit whose origin is within 64 units of the projectile?
No it doesn't. Again, that would be something for an attack system that a user would make off this.Or does this system use the actual collision size of the unit?
Oh! In that case, I'll take your word for it. You might want to mention this on the documentation though.The system uses [ljass]TriggerRegisterUnitInRange()[/ljass], which I thought took unit collision radii into account. Maybe I am wrong though, but from tests it seems that way.
Oh, I was talking about how the projectile collides, not the default unitCollision value.No it doesn't. Again, that would be something for an attack system that a user would make off this.
library Projectile initializer OnInit requires AIDS, T32, Event, Vector, AutoFly, GroupUtils, ListModule
globals
public constant integer DUMMY_ID = 'proj'
public constant player OWNER_ID = Player(0) // Player(PLAYER_NEUTRAL_PASSIVE)
public constant boolean RECYCLE = true
private constant real DEFAULT_UNIT_COLL = 64.00
private constant real DEFAULT_PROJ_COLL = 32.00
private constant real REMOVAL_DELAY = 2.00
private constant boolean PRELOAD_PROJECTILES = true
private constant integer PRELOAD_AMOUNT = 50
endglobals
//------------------------------------------------------------------------\\
// \\
// DO NOT TOUCH PAST THIS POINT UNLESS YOU KNOW WHAT YOUR ARE DOING!! \\
// \\
//------------------------------------------------------------------------\\
globals
private Event OnRecycleEvent = 0
private Event CollisionEvent = 0
private Projectile FirstProjData = 0
private Projectile SecondProjData = 0
private Projectile ProjectileList = 0
private integer RecycledCount = 0
private real WorldMaxX = 0.00
private real WorldMaxY = 0.00
private real WorldMinX = 0.00
private real WorldMinY = 0.00
private unit RecycledProj = null
private hashtable TriggerHash = null
private unit array RecycledUnits
endglobals
//------------------------------------------------------------------------\\
// Function interfaces: Bonus functions available for greater control.
function interface OnStart takes Projectile instance returns nothing
function interface OnLoop takes Projectile instance returns nothing
function interface OnFinish takes Projectile instance returns nothing
function interface OnLand takes Projectile instance returns nothing
function interface OnUnit takes Projectile instance, unit whichUnit returns nothing
function interface OnProj takes Projectile instance, Projectile whichProj returns nothing
function interface ForGroupCallback takes Projectile whichProj, integer whichInst returns nothing
//------------------------------------------------------------------------\\
// Projectile recycling: For more efficient projectile creation.
private function NewProjectile takes real xPos, real yPos, real facing returns unit
if RecycledCount == 0 then
set RecycledUnits[0] = CreateUnit(OWNER_ID,DUMMY_ID,xPos,yPos,facing * bj_RADTODEG)
else
set RecycledCount = RecycledCount - 1
call PauseUnit(RecycledUnits[RecycledCount],false)
call SetUnitFacing(RecycledUnits[RecycledCount],facing * bj_RADTODEG)
endif
return RecycledUnits[RecycledCount]
endfunction
private function ReleaseProjectile takes unit whichUnit returns boolean
call SetUnitX(whichUnit,WorldMaxX + 164.00)
call SetUnitY(whichUnit,WorldMaxY + 164.00)
call PauseUnit(whichUnit,true)
set RecycledUnits[RecycledCount] = whichUnit
set RecycledCount = RecycledCount + 1
set RecycledProj = whichUnit
call OnRecycleEvent.fire()
return true
endfunction
//------------------------------------------------------------------------\\
// ProjData: Stores Projectile structs allocated to dummy units.
private struct ProjData extends array
//! runtextmacro AIDS()
Projectile data
private static method AIDS_filter takes unit whichUnit returns boolean
return GetUnitTypeId(whichUnit) == DUMMY_ID
endmethod
private method AIDS_onCreate takes nothing returns nothing
set this.data = 0
endmethod
private method AIDS_onDestroy takes nothing returns nothing
set this.data = 0
endmethod
endstruct
//------------------------------------------------------------------------\\
// ForGroupStack: For recursion safety for ForProjectileGroup().
private struct ForGroupStack extends array
group forGroup
integer instance
integer callback
static thistype top = 0
static method increment takes nothing returns nothing
set thistype.top = thistype(thistype.top + 1)
endmethod
static method decrement takes nothing returns nothing
set thistype.top = thistype(thistype.top - 1)
endmethod
endstruct
//------------------------------------------------------------------------\\
// Unit recycler: To show the death effect of projectiles.
private struct DelayedRemoval
unit temp = null
real tick = 0.00
private method destroy takes nothing returns nothing
static if RECYCLE then
call ReleaseProjectile(this.temp)
else
call RemoveUnit(this.temp)
endif
set this.temp = null
call this.deallocate()
endmethod
private method periodic takes nothing returns nothing
if this.tick == T32_Tick then
call this.stopPeriodic()
call this.destroy()
endif
endmethod
implement T32x
static method add takes unit whichUnit returns nothing
local thistype this = thistype.allocate()
set this.temp = whichUnit
set this.tick = T32_Tick + R2I(REMOVAL_DELAY / T32_PERIOD)
call this.startPeriodic()
endmethod
endstruct
//------------------------------------------------------------------------\\
// Projectile: The main struct interface for the system.
struct Projectile
implement LinkedList // Need linked list for GroupEnum function.
unit caster = null // Casting unit of the projectile.
unit target = null // Target unit of the projectile (if there is one).
player owner = null // Normally the owning unit of the caster.
real unitDamage = 0.00 // Easier to pass damage through projectile.
real unitCollision = DEFAULT_UNIT_COLL // Collision radius for unit/proj collisions.
real projCollision = DEFAULT_PROJ_COLL // Collision radius for proj/proj collisions.
boolean pauseProj = false // If the projectile has been paused or not.
boolean collideable = false // If the projectile can collide with other projectiles.
boolean enableHoming = false // If the projectile is homing (must have a target unit to work).
boolean showDeathFx = true // Whether or not to show the projectiles death effect.
OnStart onStart = 0 // Function that is executed when the projectile is launched.
OnLoop onLoop = 0 // Function that is executed each iteration or the periodic timer.
OnFinish onFinish = 0 // Function that is executed when the projectile ends.
OnLand onLand = 0 // Function that is executed when the projectile hits the ground.
OnUnit onUnit = 0 // Function that is executed when the projectile hits a unit.
OnProj onProj = 0 // Function that is executed when the projectile hits another projectile.
readonly unit proj = null // The actual projectile unit.
readonly real angle = 0.00 // The angle at which the projectile is facing.
readonly real pitch = 0.00 // The pitch at which the projectile is facing.
readonly vector pos = 0 // A vector struct holding the XYZ coordinates of the projectiles position.
readonly vector vel = 0 // A vector struct holding the XYZ coordinates of the projectiles velocity.
readonly vector start = 0 // A vector struct holidng the XYZ coordinates of the projectiles starting location.
readonly vector targ = 0 // A vector struct holding the XYZ coordinates of the projectiles target location.
private trigger unitTrig = null // Trigger needed for the unit comes in range event.
private group dmgGroup = null // Group needed so units aren't hit more than once.
private region projReg = null // Region for the unit enters region event.
private rect projRect = null // Rect that is added and removed from the region periodically.
private trigger projTrig = null // Trigger needed for the unit enters region event.
private real height = 0.00 // Maximum height of an arcing projectile.
private real maxDist = 0.00 // Maximum distance of an arcing projectile.
private real distDone = 0.00 // Distance travelled by an arcing projectile.
private real tick = 0.00 // Ticks to count projectile life span.
private boolean arcing = false // If the projectile should be arcing or not.
private effect sfx = null // The effect attached to the projectile.
private string path = "" // The path of the above effect.
private boolean stop = false // If the projectile instance has been stopped (destroyed).
private real speed = 0.00 // The current speed of the projectile.
private real oriSpeed = 0.00 // The previous speed of the projectile.
private real oldSpeed = 0.00 // The original speed of the projectile.
private static boolexpr unitFilt = null // The condition used for unit collision.
private static boolexpr projFilt = null // The condition used for projectile collision.
private static vector tempVect = 0 // The helper vector needed for z height.
static method operator[] takes unit whichUnit returns thistype
return ProjData[whichUnit].data
endmethod
method operator scaleSize= takes real value returns nothing
call SetUnitScale(this.proj,value,0.00,0.00)
endmethod
method operator timedLife= takes real value returns nothing
set this.tick = T32_Tick + R2I(value / T32_PERIOD)
endmethod
method operator effectPath= takes string whichPath returns nothing
if this.sfx != null then
call DestroyEffect(this.sfx)
set this.path = ""
endif
if whichPath == "" then
set this.sfx = null
set this.path = ""
else
set this.sfx = AddSpecialEffectTarget(whichPath,this.proj,"origin")
set this.path = whichPath
endif
endmethod
method operator effectPath takes nothing returns string
return this.path
endmethod
method operator currentSpeed takes nothing returns real
return this.speed / T32_PERIOD
endmethod
method operator previousSpeed takes nothing returns real
return this.oldSpeed / T32_PERIOD
endmethod
method operator originalSpeed takes nothing returns real
return this.oriSpeed / T32_PERIOD
endmethod
method operator isTerminated takes nothing returns boolean
return this.stop
endmethod
method terminate takes nothing returns nothing
set this.effectPath = ""
set this.stop = true
endmethod
method isUnitInHeightRange takes unit whichUnit returns boolean
local real height = GetUnitFlyHeight(whichUnit)
call thistype.tempVect.getTerrainPoint(GetUnitX(whichUnit),GetUnitY(whichUnit))
set height = height - thistype.tempVect.z
return height <= this.pos.z + this.unitCollision and height >= (this.pos.z - this.unitCollision) - 128.00
endmethod
method modifyTargeting takes real xPos, real yPos, real zPos returns nothing
set this.angle = Atan2((yPos - this.pos.y),(xPos - this.pos.x))
set this.pitch = Atan2(SquareRoot((xPos - this.pos.x) * (xPos - this.pos.x) + (yPos - this.pos.y) * (yPos - this.pos.y)),(zPos - this.pos.z))
set this.vel.x = Sin(this.pitch) * Cos(this.angle) * speed
set this.vel.y = Sin(this.pitch) * Sin(this.angle) * speed
set this.vel.z = Cos(this.pitch) * speed
set this.targ.x = xPos
set this.targ.y = yPos
set this.targ.z = zPos
if not this.arcing then
call SetUnitAnimationByIndex(this.proj,R2I(bj_RADTODEG * Atan2(this.vel.z,SquareRoot(this.vel.x * this.vel.x + this.vel.y * this.vel.y)) + 0.50) + 90)
endif
call SetUnitFacing(this.proj,this.angle * bj_RADTODEG)
endmethod
method modifyPositioning takes real xPos, real yPos, real zPos returns nothing
set this.pos.x = xPos
set this.pos.y = yPos
set this.pos.z = zPos
endmethod
method modifySpeed takes real value returns nothing
set this.oldSpeed = this.speed
set this.speed = value * T32_PERIOD
set this.vel.x = Sin(this.pitch) * Cos(this.angle) * this.speed
set this.vel.y = Sin(this.pitch) * Sin(this.angle) * this.speed
set this.vel.z = Cos(this.pitch) * this.speed
endmethod
private method destroy takes nothing returns nothing
call this.onFinish.execute(this)
call this.pos.destroy()
call this.vel.destroy()
call this.targ.destroy()
call this.start.destroy()
if this.sfx != null then
call DestroyEffect(this.sfx)
endif
if this.showDeathFx then
call DelayedRemoval.add(this.proj)
else
static if RECYCLE then
call ReleaseProjectile(this.proj)
else
call RemoveUnit(this.proj)
endif
endif
call TriggerClearConditions(this.unitTrig)
call DisableTrigger(this.unitTrig)
call DestroyTrigger(this.unitTrig)
call TriggerClearConditions(this.projTrig)
call DisableTrigger(this.projTrig)
call DestroyTrigger(this.projTrig)
call RemoveRegion(this.projReg)
call RemoveRect(this.projRect)
call ReleaseGroup(this.dmgGroup)
set ProjData[this.proj].data = 0
set this.projTrig = null
set this.projRect = null
set this.projReg = null
set this.unitTrig = null
set this.dmgGroup = null
set this.caster = null
set this.proj = null
set this.sfx = null
set this.path = ""
call this.deallocate()
endmethod
private static method projectileFilter takes nothing returns boolean
local thistype this = LoadInteger(TriggerHash,GetHandleId(GetTriggeringTrigger()),0)
local unit filt = GetEnteringUnit()
local thistype that = Projectile[filt]
if that != 0 and this != 0 and this != that then
if that.collideable and this.collideable then
if (this.pos.z - that.pos.z) * (this.pos.z - that.pos.z) < this.projCollision * this.projCollision or /*
*/ (that.pos.z - this.pos.z) * (that.pos.z - this.pos.z) < that.projCollision * that.projCollision then
call this.onProj.execute(this,that)
call that.onProj.execute(that,this)
set FirstProjData = this
set SecondProjData = that
call CollisionEvent.fire()
endif
endif
endif
set filt = null
return false
endmethod
private static method collisionFilter takes nothing returns boolean
local thistype this = LoadInteger(TriggerHash,GetHandleId(GetTriggeringTrigger()),0)
local unit filt = GetFilterUnit()
if not IsUnitInGroup(filt,this.dmgGroup) then
call GroupAddUnit(this.dmgGroup,filt)
call this.onUnit.execute(this,filt)
endif
set filt = null
return false
endmethod
private method periodic takes nothing returns nothing
local real tempX = 0.00
local real tempY = 0.00
local real tempZ = 0.00
if this.stop or this.tick == T32_Tick then
call this.stopPeriodic()
call this.destroyThis()
else
if this.onLoop != 0 then
call this.onLoop.execute(this)
endif
if not this.pauseProj then
call RegionClearRect(this.projReg,this.projRect)
call SetRect(this.projRect,this.pos.x - this.projCollision,this.pos.y - this.projCollision,this.pos.x + this.projCollision,this.pos.y + this.projCollision)
call RegionAddRect(this.projReg,this.projRect)
if this.target != null and this.enableHoming then
set tempX = GetUnitX(this.target)
set tempY = GetUnitY(this.target)
if this.targ.x != tempX and this.targ.y != tempY then
if this.arcing then
set this.arcing = false
endif
call this.modifyTargeting(tempX,tempY,this.targ.z)
endif
endif
call this.pos.add(this.vel)
call thistype.tempVect.getTerrainPoint(this.pos.x,this.pos.y)
if this.arcing then
set tempZ = this.pos.z
set this.pos.z = this.start.z + (4.00 * this.height / this.maxDist) * (this.maxDist - this.distDone) * (this.distDone / this.maxDist)
set this.distDone = this.distDone + this.speed
call SetUnitAnimationByIndex(this.proj,R2I(bj_RADTODEG * Atan2((this.pos.z - tempZ) + this.vel.z,SquareRoot(this.vel.x * this.vel.x + this.vel.y * this.vel.y)) + 0.50) + 90)
endif
call SetUnitX(this.proj,this.pos.x)
call SetUnitY(this.proj,this.pos.y)
call SetUnitFlyHeight(this.proj,this.pos.z - thistype.tempVect.z,0.00)
if this.pos.z <= thistype.tempVect.z then
call this.onLand.execute(this)
set this.stop = true
endif
endif
endif
endmethod
implement T32x
private method setCommon takes real xPos, real yPos, real zPos, real speed returns nothing
local real tempX = xPos - this.pos.x
local real tempY = yPos - this.pos.y
local real tempZ = zPos - this.pos.z
set this.angle = Atan2(tempY,tempX)
set this.pitch = Atan2(SquareRoot(tempX * tempX + tempY * tempY),tempZ)
set this.speed = speed * T32_PERIOD
set this.vel = vector.create(Sin(this.pitch) * Cos(this.angle) * this.speed,Sin(this.pitch) * Sin(this.angle) * this.speed,Cos(this.pitch) * this.speed)
set this.targ = vector.create(xPos,yPos,zPos)
set this.oriSpeed = this.speed
set this.oldSpeed = this.speed
call SetUnitAnimationByIndex(this.proj,R2I(bj_RADTODEG * Atan2(this.vel.z,SquareRoot(this.vel.x * this.vel.x + this.vel.y * this.vel.y)) + 0.50) + 90)
set this.unitTrig = CreateTrigger()
call SaveInteger(TriggerHash,GetHandleId(this.unitTrig),0,this)
call TriggerRegisterUnitInRange(this.unitTrig,this.proj,this.unitCollision,null)
call TriggerAddCondition(this.unitTrig,thistype.unitFilt)
set this.projTrig = CreateTrigger()
set this.projReg = CreateRegion()
set this.projRect = Rect(xPos - this.projCollision,yPos - this.projCollision,xPos + this.projCollision,yPos + this.projCollision)
call SaveInteger(TriggerHash,GetHandleId(this.projTrig),0,this)
call RegionAddRect(this.projReg,this.projRect)
call TriggerRegisterEnterRegion(this.projTrig,this.projReg,null)
call TriggerAddCondition(this.projTrig,thistype.projFilt)
endmethod
method projectNormal takes real xPos, real yPos, real zPos, real speed returns nothing
call thistype.tempVect.getTerrainPoint(xPos,yPos)
if zPos <= thistype.tempVect.z then
set zPos = zPos + thistype.tempVect.z + 1.00
call this.setCommon(xPos,yPos,zPos,speed)
else
call this.setCommon(xPos,yPos,zPos,speed)
endif
call this.onStart.execute(this)
call this.startPeriodic()
endmethod
method projectArcing takes real xPos, real yPos, real zPos, real speed, real maxHeight returns nothing
call thistype.tempVect.getTerrainPoint(xPos,yPos)
if (zPos + thistype.tempVect.z > maxHeight - this.start.z) or (this.start.z > maxHeight - this.start.z) then
call this.projectNormal(xPos,yPos,zPos + thistype.tempVect.z,speed)
else
set this.maxDist = SquareRoot((xPos - this.pos.x) * (xPos - this.pos.x) + (yPos - this.pos.y) * (yPos - this.pos.y) + (zPos - this.start.z) * (zPos - this.start.z)) - this.start.z
set this.height = maxHeight - this.start.z
set this.arcing = true
call this.projectNormal(xPos,yPos,zPos,speed)
endif
endmethod
static method create takes real xPos, real yPos, real zPos, real facing returns thistype
local thistype this = thistype.allocate()
static if RECYCLE then
set this.proj = NewProjectile(xPos,yPos,facing)
else
set this.proj = CreateUnit(OWNER_ID,DUMMY_ID,xPos,yPos,facing * bj_RADTODEG)
endif
call thistype.tempVect.getTerrainPoint(xPos,yPos)
if zPos <= thistype.tempVect.z then
set zPos = zPos + thistype.tempVect.z + 1.00
endif
call SetUnitX(this.proj,xPos)
call SetUnitY(this.proj,yPos)
call SetUnitFlyHeight(this.proj,zPos - thistype.tempVect.z,0.00)
set this.pos = vector.create(xPos,yPos,zPos)
set this.start = vector.create(xPos,yPos,zPos)
set this.dmgGroup = NewGroup()
set ProjData[this.proj].data = ProjectileList.addToStart(this)
return this
endmethod
private static method onInit takes nothing returns nothing
set thistype.tempVect = vector.create(0.00,0.00,0.00)
set thistype.unitFilt = Condition(function thistype.collisionFilter)
set thistype.projFilt = Condition(function thistype.projectileFilter)
endmethod
endstruct
//------------------------------------------------------------------------\\
// GroupEnum function: Groups all projectiles in range, very useful.
function GroupProjectilesInRange takes group whichGroup, real x, real y, real z, real radius returns nothing
local Projectile p = ProjectileList.head
local vector v = vector.create(x,y,z)
call GroupClear(whichGroup)
loop
exitwhen p == 0
if p.pos.isInSphere(v,radius) then
call GroupAddUnit(whichGroup,p.proj)
endif
set p = p.next
endloop
call v.destroy()
endfunction
//------------------------------------------------------------------------\\
// ForProjectileGroup: For those who want a cleaner interface. Not recommended.
private function ForProjectileGroupCallback takes nothing returns nothing
call ForGroupCallback(ForGroupStack.top.callback).execute(ProjData[GetEnumUnit()].data,ForGroupStack.top.instance) // Don't kill me for this.
endfunction
function ForProjectileGroup takes group whichGroup, ForGroupCallback whichCallback, integer whichInst returns nothing
call ForGroupStack.increment()
set ForGroupStack.top.forGroup = whichGroup
set ForGroupStack.top.instance = whichInst
set ForGroupStack.top.callback = whichCallback
call ForGroup(whichGroup,function ForProjectileGroupCallback)
call ForGroupStack.decrement()
endfunction
//------------------------------------------------------------------------\\
// Global collision event: Useful for a variety of spells. Has event responses.
function RegisterProjectileCollisionEvent takes trigger whichTrigger returns EventReg
return CollisionEvent.register(whichTrigger)
endfunction
function GetFirstCollisionProj takes nothing returns Projectile
return FirstProjData
endfunction
function GetSecondCollisionProj takes nothing returns Projectile
return SecondProjData
endfunction
//------------------------------------------------------------------------\\
// On recycle event: Simulates an on projectile 'removal' event for users.
function RegisterProjectileRecycledEvent takes trigger whichTrigger returns EventReg
return OnRecycleEvent.register(whichTrigger)
endfunction
function GetRecycledProjectile takes nothing returns unit
return RecycledProj
endfunction
//------------------------------------------------------------------------\\
// WC3 style wrappers: For people who like normal WC3 style functions.
function IsUnitProjectile takes unit whichUnit returns boolean
return Projectile[whichUnit] != 0
endfunction
function GetUnitProjectileData takes unit whichUnit returns Projectile
return Projectile[whichUnit]
endfunction
//------------------------------------------------------------------------\\
// Bounds detection: Projectiles are destroyed when they try to leave the map.
private function OutsideMapRemoval takes nothing returns boolean
local unit u = GetLeavingUnit()
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local Projectile p = Projectile<u>
if p != 0 then
call p.terminate()
else
if(x > WorldMaxX) then
set x = WorldMaxX
elseif(x < WorldMinX) then
set x = WorldMinX
endif
if(y > WorldMaxY) then
set y = WorldMaxY
elseif(y < WorldMinY) then
set y = WorldMinY
endif
call SetUnitX(u,x)
call SetUnitY(u,y)
endif
set u=null
return false
endfunction
//------------------------------------------------------------------------\\
// Initialisation: Collision event, linked list, hashtable.
private function OnInit takes nothing returns nothing
local trigger trig = CreateTrigger()
local region reg = CreateRegion()
local rect rec = null
static if RECYCLE then
set OnRecycleEvent = Event.create()
endif
set CollisionEvent = Event.create()
set ProjectileList = Projectile.createList()
set TriggerHash = InitHashtable()
set WorldMaxX = GetRectMaxX(bj_mapInitialPlayableArea) - 64.00
set WorldMaxY = GetRectMaxY(bj_mapInitialPlayableArea) - 64.00
set WorldMinX = GetRectMinX(bj_mapInitialPlayableArea) + 64.00
set WorldMinY = GetRectMinY(bj_mapInitialPlayableArea) + 64.00
set rec = Rect(WorldMinX,WorldMinY,WorldMaxX,WorldMaxY)
static if PRELOAD_PROJECTILES and RECYCLE then
loop
exitwhen RecycledCount == PRELOAD_AMOUNT
set RecycledUnits[RecycledCount] = CreateUnit(OWNER_ID,DUMMY_ID,WorldMaxX + 164.00,WorldMaxY + 164.00,0.00)
set RecycledCount = RecycledCount + 1
endloop
set RecycledCount = PRELOAD_AMOUNT
endif
call RegionAddRect(reg,rec)
call TriggerRegisterLeaveRegion(trig,reg,null)
call TriggerAddCondition(trig,Condition(function OutsideMapRemoval))
call RemoveRect(rec)
set trig = null
set rec = null
set reg = null
endfunction
endlibrary
</u>
True, but you could simply use the boolean of GroupAddUnit though.Kenny said:One global boolean to replace dynamic group usage? Wouldn't really work, unless I use a 2D array or something.
Do you mind explaining that in more detail to me?True, but you could simply use the boolean of GroupAddUnit though.
if not IsUnitInGroup(filt,this.dmgGroup) then
call GroupAddUnit(this.dmgGroup,filt)
call this.onUnit.execute(this,filt)
endif
if GroupAddUnit(this.dmgGroup,filt)
call this.onUnit.execute(this,filt)
endif
It returns a valid boolean, you just have never use it like that, since in jass2 you're able to ignore the return of a function and act as if the function returns nothing.Wait a sec...
Are you sure that works? Doesn't [ljass]GroupAddUnit()[/ljass] return nothing?