- Joined
- Oct 18, 2007
- Messages
- 930
Isn't it
X = X+Speed*Cos(Phi)*Cos(Theta)
Y = Y+Speed*Cos(Phi)*Sin(Theta)
Z = Z+Speed*Cos(Phi)
?
function GetSphereLoc takes real x, real y, real z, real r, real xyAngle, real zAngle returns location
local location loc = Location( x + r * Cos(zAngle) * Sin(xyAngle), y + r * Sin(zAngle) * Sin(xyAngle) )
call SetLocationZ( loc, z + r * Cos(xyAngle) )
return loc
endfunction
library SphereMotion
globals
private constant real FPS = 40.00
private constant integer FlyId = 'Amrf'
private constant integer DumId = 'n000'
endglobals
private struct Data
unit Object
real x0
real y0
real z0
real zA = 0.0
real xyA = 0.0
real zV
real xyV
real r
effect Art
static integer array Sphere
static integer TotalSpheres = 0
static timer Timer = null
static method Loop takes nothing returns nothing
local Data dat
local integer i = 0
loop
exitwhen i >= Data.TotalSpheres
set dat = Data.Sphere[i]
if GetWidgetLife(dat.Object) > .405 then
call SetUnitX(dat.Object, dat.x0 + (dat.r * Sin(dat.xyA) * Cos(dat.zA)))
call SetUnitY(dat.Object, dat.x0 + (dat.r * Sin(dat.xyA) * Sin(dat.zA)))
call SetUnitFlyHeight(dat.Object, dat.z0 + (dat.r * Cos(dat.xyA)), 0.0)
set dat.zA = (dat.zA + dat.zV) * bj_RADTODEG
set dat.xyA = (dat.xyA + dat.xyV) * bj_RADTODEG
if dat.zA > 360 then
set dat.zA = 0.0
elseif dat.zA < -360 then
set dat.zA = 0.0
else
set dat.zA = dat.zA * bj_DEGTORAD
endif
if dat.xyA > 360 then
set dat.xyA = 0.0
elseif dat.xyA < -360 then
set dat.xyA = 0.0
else
set dat.xyA = dat.xyA * bj_DEGTORAD
endif
else
call DestroyEffect(dat.Art)
set dat.Object = null
set dat.Art = null
call dat.destroy()
set Data.TotalSpheres = Data.TotalSpheres - 1
set Data.Sphere[i] = dat.Sphere[Data.TotalSpheres]
set i = i - 1
endif
set i = i + 1
endloop
if Data.TotalSpheres == 0 then
call PauseTimer(Data.Timer)
endif
endmethod
static method Start takes real x0, real y0, real z0, real r, real zA, real xyA, real zV, real xyV, string Art, real Time returns unit
local Data dat = Data.allocate()
set dat.x0 = x0
set dat.y0 = y0
set dat.z0 = z0 + r
set dat.zA = zA * bj_DEGTORAD
set dat.xyA = xyA * bj_DEGTORAD
set dat.zV = (zV / FPS) * bj_DEGTORAD
set dat.xyV = (xyV / FPS) * bj_DEGTORAD
set dat.Object = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), DumId, x0, y0, 0)
call UnitAddAbility(dat.Object, FlyId)
call UnitRemoveAbility(dat.Object, FlyId)
call SetUnitFlyHeight(dat.Object, z0, 0)
set dat.Art = AddSpecialEffectTarget(Art, dat.Object, "origin")
call SetUnitAnimationByIndex(dat.Object, 90)
if Time > 0.0 then
call UnitApplyTimedLife(dat.Object, 'BTLF', Time)
endif
if Data.TotalSpheres == 0 then
call TimerStart(Data.Timer, 1.0/FPS, true, function Data.Loop)
endif
set Data.Sphere[Data.TotalSpheres] = dat
set Data.TotalSpheres = Data.TotalSpheres + 1
return dat.Object
endmethod
endstruct
function CreateSphere takes real x0, real y0, real z0, real r, real zA, real xyA, real zV, real xyV, string Art, real Time, integer Parts, boolean Return returns group
local group g = CreateGroup()
local integer i = 0
local real a = 360/Parts
loop
exitwhen i > Parts
call GroupAddUnit(g, Data.Start(x0, y0, z0, r, zA, xyA + (a * i), zV, xyV, Art, Time))
set i = i + 1
endloop
if Return then
return g
else
call DestroyGroup(g)
set g = null
return g
endif
endfunction
endlibrary
Does it at least work in 2 dimensions? (θ is 0)
call SetUnitX(dat.Object, dat.x0 + (dat.r * Sin(dat.xyA) * Cos(dat.zA)))
call SetUnitY(dat.Object, dat.x0 + (dat.r * Sin(dat.xyA) * Sin(dat.zA)))
call SetUnitFlyHeight(dat.Object, dat.z0 + (dat.r * Cos(dat.xyA)), 0.0)
set dat.zA = (dat.zA + dat.zV) * bj_RADTODEG
set dat.xyA = (dat.xyA + dat.xyV) * bj_RADTODEG
if dat.zA > 360 then
set dat.zA = 0.0
elseif dat.zA < -360 then
set dat.zA = 0.0
else
set dat.zA = dat.zA * bj_DEGTORAD
endif
if dat.xyA > 360 then
set dat.xyA = 0.0
elseif dat.xyA < -360 then
set dat.xyA = 0.0
else
set dat.xyA = dat.xyA * bj_DEGTORAD
endif
Nice, now what are you going to do with it? I'm intrigued now...
OK cool. Now why should they use this which will lag if they use it a lot over custom models?
I suppose... maybe you should make functions like angle cutoff point - so you can make like semi-spheres and stuff, like if you want a big dome on the ground... and I'd make an option so the missiles can damage units...
But you will do the angle cutoff thing right?
Lets say you have 2 cutoff points, 90 and 270. You would increase the angle by the velocity each interval, and if angle becomes greater than 270, multiply the velocity by -1, and if the angle becomes less than 90, multiply the velocity by -1. That way, you get a semi-circle motion, bouncing between those 2 angles.
You should have it with a master radius and x, y and z scales rather than a, b and c, methinks.
yeah well the scales would be xS, yS, zS or something... they don't have to be x0, y0, z0...
Awsome! You could do something like attach 2 spheres to a sphere, each of those has 2 attached to it, each of those has 2 attached to it etc etc. And each one would be smaller than the last .