Lately I have been mucking around with a projectile system just for kicks. However I am stuck on setting the dummy units animations correctly to get it to face the right angle while moving.
To learn more to go this thread.
Heres my projectile system so far (Still got heaps to do):
So as you probably notice, it is partially a rip off of xefx, however, that part of the system is getting a major overhaul soon enough.
The line I am having problem with is this one:
It only works a little bit (for about 20% of the whole arc). I've tried almost everything, any ideas?
I'm pretty sure it is meant to be:
But it doesn't seem to work.
To learn more to go this thread.
Heres my projectile system so far (Still got heaps to do):
JASS:
library ProjectileSystem initializer Init requires T32, Recycle
globals
private constant integer MAX_INSTANCES = 8190
private constant integer DUMMY_UNIT_ID = 039;e000039;
private constant integer ENABLE_HEIGHT = 039;Amrf039;
private constant real MAX_COLLISION = 197.00
private constant real MAXIMUM_SPEED = 1500.00
private constant real FIN_THRESHOLD = 32.00
endglobals
private interface ProjBase
method onStart takes nothing returns nothing defaults nothing
method onFinish takes nothing returns nothing defaults nothing
method onLoop takes nothing returns nothing defaults nothing
method onHit takes nothing returns nothing defaults nothing
endinterface
struct ProjFx[MAX_INSTANCES]
private unit dum = null
private effect fx = null
private real zang = 0.00
private boolean kill = false
static method create takes real x, real y, real facing returns thistype
local thistype this = thistype.allocate()
set this.dum = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE),DUMMY_UNIT_ID,x,y,facing * bj_RADTODEG)
call UnitAddAbility(this.dum,ENABLE_HEIGHT)
call UnitRemoveAbility(this.dum,ENABLE_HEIGHT)
call SetUnitX(this.dum,x)
call SetUnitY(this.dum,y)
return this
endmethod
method operator dummy takes nothing returns unit
return this.dum
endmethod
method operator killdummy= takes boolean bool returns nothing
set this.kill = bool
endmethod
method operator scale= takes real value returns nothing
call SetUnitScale(this.dum,value,0.00,0.00)
endmethod
method operator owner takes nothing returns player
return GetOwningPlayer(this.dum)
endmethod
method operator owner= takes player p returns nothing
call SetUnitOwner(this.dum,p,false)
endmethod
method operator x takes nothing returns real
return GetUnitX(this.dum)
endmethod
method operator y takes nothing returns real
return GetUnitY(this.dum)
endmethod
method operator z takes nothing returns real
return GetUnitFlyHeight(this.dum)
endmethod
method operator x= takes real value returns nothing
call SetUnitX(this.dum,value)
endmethod
method operator y= takes real value returns nothing
call SetUnitY(this.dum,value)
endmethod
method operator z= takes real value returns nothing
call SetUnitFlyHeight(this.dum,value,0.00)
endmethod
method operator xyangle takes nothing returns real
return GetUnitFacing(this.dum) * bj_DEGTORAD
endmethod
method operator xyangle= takes real value returns nothing
call SetUnitFacing(this.dum,value * bj_RADTODEG)
endmethod
method operator zangle takes nothing returns real
return this.zang
endmethod
method operator zangle= takes real value returns nothing
local integer i = R2I(value * bj_RADTODEG + 90.50)
set this.zang = value
if i >= 180 then
set i = 179
elseif i < 0 then
set i = 0
endif
call SetUnitAnimationByIndex(this.dum,i)
endmethod
method operator fxpath= takes string newpath returns nothing
if this.fx != null then
call DestroyEffect(this.fx)
endif
if newpath == "" then
set this.fx = null
else
set this.fx = AddSpecialEffectTarget(newpath,this.dum,"origin")
endif
endmethod
method flash takes string fx returns nothing
call DestroyEffect(AddSpecialEffectTarget(fx,this.dum,"origin"))
endmethod
private method onDestroy takes nothing returns nothing
if this.fx != null then
call DestroyEffect(this.fx)
set this.fx = null
endif
if this.kill then
call KillUnit(this.dum)
else
call RemoveUnit(this.dum)
endif
set this.dum = null
endmethod
endstruct
struct ProjCore extends ProjBase
private delegate ProjFx fx = 0
// Projectile Coords.
private real xP = 0.00
private real yP = 0.00
private real zP = 0.00
// Target coords.
private real xT = 0.00
private real yT = 0.00
private real zT = 0.00
// Velocities.
private real xV = 0.00
private real yV = 0.00
private real zV = 0.00
// Movement.
private real facing = 0.00
private real pitch = 0.00
private real speed = 0.00
// Distances.
private real dist = 0.00
private real total = 0.00
private real done = 0.00
private real height = 0.00
private real resist = 1.00
// Booleans.
private boolean end = false
private boolean stp = false
// Static members.
private static location tempLoc = null
private static group enumGroup = null
private static real tempReal = 0.00
method operator pauseProjectile= takes boolean bool returns nothing
set this.stp = bool
endmethod
private method getDist takes real x, real y, real z returns real
return SquareRoot((this.xP - x) * (this.xP - x) + (this.yP - y) * (this.yP - y) + (this.zP - z) * (this.zP - z))
endmethod
private method getFacing takes real x, real y returns real
return Atan2((y - this.yP),(x - this.xP))
endmethod
private method getPitch takes real x, real y, real z returns real
return Atan2(SquareRoot((x - this.xP) * (x - this.xP) + (y - this.yP) * (y - this.yP)),(z - this.zP))
endmethod
private method setVelX takes nothing returns nothing
set this.xV = Sin(this.pitch) * Cos(this.facing) * this.speed
endmethod
private method setVelY takes nothing returns nothing
set this.yV = Sin(this.pitch) * Sin(this.facing) * this.speed
endmethod
private method setVelZ takes nothing returns nothing
set this.zV = Cos(this.pitch) * this.speed
endmethod
static method create takes real x, real y, real z, real facing returns thistype
local thistype this = thistype.allocate()
set this.fx = ProjFx.create(x,y,facing)
set this.z = z
set this.xP = this.x
set this.yP = this.y
set this.zP = this.z
set this.fxpath = "Abilities\\Weapons\\Arrow\\ArrowMissile.mdl"
set this.scale = 2.00
return this
endmethod
method start takes real x, real y, real z, real speed, real height returns nothing
set this.xT = x
set this.yT = y
set this.zT = z
set this.facing = this.getFacing(this.xT,this.yT)
set this.pitch = this.getPitch(this.xT,this.yT,this.zT)
set this.speed = speed * T32_PERIOD
set this.dist = this.getDist(this.xT,this.yT,this.zT)
set this.total = this.dist
set this.height = height
set this.done = 0.00
call this.setVelX()
call this.setVelY()
call this.setVelZ()
if this.onStart.exists then
call this.onStart()
endif
call this.startPeriodic()
endmethod
private method periodic takes nothing returns boolean
if this.dist <= FIN_THRESHOLD or this.end then
if this.onFinish.exists then
call this.onFinish()
endif
call this.destroy()
return true
endif
if this.stp == false then
if this.onLoop.exists then
call this.onLoop()
endif
set this.xV = this.xV * this.resist
set this.yV = this.yV * this.resist
set this.zV = this.zV * this.resist
set this.xP = this.xP + this.xV
set this.yP = this.yP + this.yV
if this.height == 0.00 then
set this.zP = this.zP + this.zV
else
set this.zP = (4.00 * this.height / this.total) * (this.total - this.done) * (this.done / this.total)
endif
call MoveLocation(thistype.tempLoc,this.xP,this.yP)
set thistype.tempReal = GetLocationZ(thistype.tempLoc)
set this.x = this.xP
set this.y = this.yP
set this.z = (this.zP - thistype.tempReal)
set this.xyangle = this.facing
set this.zangle = Atan2(this.zP - thistype.tempReal,SquareRoot(this.xP * this.xP + this.yP * this.yP))
set this.dist = this.getDist(this.xT,this.yT,this.zT)
set this.done = this.done + this.speed
endif
return false
endmethod
method terminate takes nothing returns nothing
set this.end = true
set this.fxpath = ""
endmethod
private method onDestroy takes nothing returns nothing
call this.fx.destroy()
set this.end = false
endmethod
static method doInit takes nothing returns nothing
set thistype.tempLoc = Location(0.00,0.00)
set thistype.enumGroup = CreateGroup()
endmethod
implement T32
endstruct
private function Init takes nothing returns nothing
call ProjCore.doInit()
endfunction
endlibrary
So as you probably notice, it is partially a rip off of xefx, however, that part of the system is getting a major overhaul soon enough.
The line I am having problem with is this one:
JASS:
set this.zangle = Atan2(this.zP - thistype.tempReal,SquareRoot(this.xP * this.xP + this.yP * this.yP))
It only works a little bit (for about 20% of the whole arc). I've tried almost everything, any ideas?
I'm pretty sure it is meant to be:
JASS:
Atan2(ZVelocity,SquareRoot(XVelocity * XVelocity + YVelocity * YVelocity))
But it doesn't seem to work.