MasterOfRa
New Member
- Reaction score
- 10
The library works perfectly, except for a slight problem. if I attach a effect with a ribbon effect to it, then the ribbon jumps to the new location when the dummy gets recycled. What can i do about this, other than not recycle them?
JASS:
library Projectile initializer init uses Recycler, TT
// uses Cjass
location TempLoc // Used for height calculations
group dummyPool // Used for recycling
function NewDummy takes real x, real y returns unit
local unit u = FirstOfGroup(dummyPool) // Get first of group
if u == null then
// if group was empty, create a new one
u = CreateUnit(Player(15), UID_DUMMY,x,y,0)
DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,2,I2S(GetRandomInt(1,5)))
else
// otherwise, set location, and remove unit from group
SetUnitX(u,x)
SetUnitY(u,y)
GroupRemoveUnit(dummyPool, u)
endif
return u
endfunction
function ReleaseDummy takes unit u returns nothing
GroupAddUnit(dummyPool,u)
// Add Dummy to Group
endfunction
struct Projectile
implement PAM_Property
//instance list
readonly static integer num = 0
readonly static Projectile array list
readonly integer listIndex
//unit
readonly unit u = null // The Dummy
readonly effect sfx = null // The Effect
readonly real dx = 0 // MomentumX
readonly real dy = 0 // MomentumY
readonly real dz = 0 // MomentumX
readonly real x = 0 // CurrentX
readonly real y = 0 // CurrentY
readonly real z = 0 // CurrentZ
///Updates all Projectiles by one second
public static method CatchTick takes nothing returns nothing
integer i
Projectile t
//Apply Momentum
loopForIntBelow(i, Projectile.num)
t = Projectile.list<i>
t.ApplyMomentum()
endloop
endmethod
method ApplyMomentum takes nothing returns nothing
.x+= .dx * TT_PERIOD// offset Location
.y+= .dy * TT_PERIOD//
.z+= .dz * TT_PERIOD//
SetUnitX(.u,.x)// Move the unit
SetUnitY(.u,.y)
MoveLocation(TempLoc,.x,.y)
if .z - GetLocationZ(TempLoc) <= 0 then // Check for ground hit.
.destroy()
endif
SetUnitFlyHeight(.u,.z - GetLocationZ(TempLoc),0) // Set Height
SetUnitFacing(.u,Atan2(.dy,.dx)*bj_RADTODEG) // Set facing
real dxy = SquareRoot(.dx*.dx+.dy*.dy)
integer angle = R2I(Atan2(dxy,.dz)*bj_RADTODEG)
if angle < 0 then
angle *= -1
endif
angle = 180 - angle
SetUnitAnimationByIndex(.u,angle+1) // Set AngleV
.dz -= 10
endmethod
///Creates a Projectile structure for a given unit
public static method create takes string SFX ,\ // Attached Effect
real scale ,\ // Size
real x ,\ // StartLocation
real y ,\
real z ,\
real dx ,\ // StartMomentum
real dy ,\
real dz \
returns thistype
Projectile this
macro_AllocCheck(this, Projectile)
.u = NewDummy(x,y) // Get a new dummy unit
SetUnitScale(.u,scale,scale,scale) // Set Size
.sfx = AddSpecialEffectTarget(SFX,.u,"origin") // Attach the Effect
.x = x // Set Stored Location
.y = y
.z = z
.dx = dx // Set Momentum
.dy = dy
.dz = dz
call UnitAddAbility(.u,AID_FLY) // Enable HeightChange
call UnitRemoveAbility(.u,AID_FLY)
MoveLocation(TempLoc,x,y)
SetUnitFlyHeight(.u,z-GetLocationZ(TempLoc),0) // Set Height
SetUnitFacing(.u,Atan2(.dy,.dx)*bj_RADTODEG)
real dxy = SquareRoot(dx*dx+dy*dy)
integer angle = R2I(Atan2(dxy,dz)*bj_RADTODEG)
if angle < 0 then
angle *= -1
endif
SetUnitAnimationByIndex(.u,angle+1) // Set AngleV
.listIndex = Projectile.num
Projectile.list[Projectile.num] = this
Projectile.num += 1
Projectile[.u] = this
return this
endmethod
///Cleans up properly
private method onDestroy takes nothing returns nothing
assert(this != 0)
//remove from global array
Projectile.num -= 1
Projectile.list[Projectile.num].listIndex = .listIndex
Projectile.list[.listIndex] = Projectile.list[Projectile.num]
Projectile.list[Projectile.num] = 0
//destroy other stuff
Projectile.RemoveKey(.u)
DestroyEffect(.sfx)
schedule_unit(Action_unit.ReleaseDummy, 2.5, .u)
.u = null
endmethod
endstruct
private function test takes nothing returns nothing
// This simply creates projectiles at the center of the map at random angles and speeds.
real angle = GetRandomReal(0,2*bj_PI)
real anglez = GetRandomReal(0.25*bj_PI,0.40*bj_PI)
real speed = GetRandomReal(300,600)
real SpeedX = speed*Cos(angle)*Cos(anglez)
real SpeedY = speed*Sin(angle)*Cos(anglez)
real SpeedZ = speed*Sin(anglez)
real X = 0
real Y = 0
real Z
MoveLocation(TempLoc,X,Y)
Z = 10+GetLocationZ(TempLoc)
Projectile.create("Abilities\\Weapons\\WaterElementalMissile\\WaterElementalMissile.mdl",GetRandomReal(.2,.8),X,Y,Z,SpeedX,SpeedY,SpeedZ)
endfunction
private function test2 takes nothing returns nothing
integer z = 0
loop
test()
z++
exitwhen z >= 30
endloop
endfunction
private function init takes nothing returns nothing
TempLoc = Location(0.0,0.0) // Create the Temp Location
dummyPool = NewGroup() // Create the dummyPool
TriggerSleepAction(.01)
macro_AddPeriodicHandler(TT_PERIOD, function Projectile.CatchTick) // Start a periodic timer
macro_AddPeriodicHandler(2, function test2)// Start another one
endfunction
endlibrary
</i>