Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
real
real
real
real
angle
dx
dy
dist
loop
exitwhen i >= Index
set GetEventMissile = Dat[i]
//calculate how far the missile the missile has travelled
set GetEventMissile.CurrentDist = GetEventMissile.CurrentDist + GetE
ventMissile.sp
//If the missile is homing onto a target, recalculate a few values
if GetEventMissile.Homing then
//get the new target x/y
set GetEventMissile.TargetX = GetUnitX(GetEventMissile.Target)
set GetEventMissile.TargetY = GetUnitY(GetEventMissile.Target)
//get the angle between the missile and the target
set angle = Atan2(GetEventMissile.TargetY - GetEventMissile.Y, G
etEventMissile.TargetX - GetEventMissile.X)
//calculate the sin/cos of the angle
set GetEventMissile.sn = Sin(angle)
set GetEventMissile.cs = Cos(angle)
//make the missile face towards the target
call SetUnitFacing(GetEventMissile.Dummy, angle * bj_RADTODEG)
//cacluclate the distance between the missile and its target
set dx = GetEventMissile.TargetX - GetEventMissile.X
set dy = GetEventMissile.TargetY - GetEventMissile.Y
set dist = SquareRoot(dx * dx + dy * dy)
else
set dist = GetEventMissile.StartDist - GetEventMissile.CurrentDi
st
endif
//calculate the new x/y coordinates
set GetEventMissile.X = GetEventMissile.X + GetEventMissile.sp * Get
EventMissile.cs // set x = x + speed * cos
set GetEventMissile.Y = GetEventMissile.Y + GetEventMissile.sp * Get
EventMissile.sn // set y = y + speed * sin
//run the onLoop actions, destroying the missile if they return fals
e
if GetEventMissile.ma != 0 then
if not GetEventMissile.ma.onLoop() then
call GetEventMissile.destroy()
endif
endif
//if the missile is collideable, check for collision
if GetEventMissile.Radius > 0.00 then
//enumerate the units within range of the missile, which aren't
missiles
call GroupEnumUnitsInRange(GetEventMissile.hu, GetEventMissile.X
, GetEventMissile.Y, GetEventMissile.Radius, Conds)
//if the enumeration picked up any units, then...
if FirstOfGroup(GetEventMissile.hu) != null then
//run the onHit actions, and if they return false then...
if not GetEventMissile.ma.onHit() and GetEventMissile.ma !=
0 then
//destroy the missile
call GetEventMissile.destroy()
endif
//add the hit units to the hit units group so the system doe
sn't falsely
//think they're hit more than once
call AddGroup(GetEventMissile.hg, GetEventMissile.hu)
endif
endif
//calculate the absolute value of the distance remaining
if dist < 0 then
set dist = -dist
endif
//if the distance remaining is less than the speed of the missile th
en...
if dist < GetEventMissile.sp then
//tell the user the missile has reached its target and...
set GetEventMissile.TargetReached = true
set GetEventMissile.OnTarget = true
//run the onHit actions, destroying the missile if they return f
alse
if not GetEventMissile.ma.onHit() and GetEventMissile.ma != 0 th
en
call GetEventMissile.destroy()
endif
set GetEventMissile.OnTarget = false
endif
//and finally move the missile.
call SetUnitX(GetEventMissile.Dummy, GetEventMissile.X)
call SetUnitY(GetEventMissile.Dummy, GetEventMissile.Y)
set i = i + 1
endloop
endfunction
struct Missile
unit
string
Dummy = null
fs = ""
effect
SFX = null
unit
unit
Caster = null
Target = null
boolean
boolean
real
dm = false
Homing = false
Radius = 0.
real
real
real
real
real
real
StartX = 0.
StartY = 0.
X = 0.
Y = 0.
TargetX = 0.
TargetY = 0.
//start x
//start y
//current x
//current y
//target x
//target y
real
sn = 0.
//sin
ile
real
real
cs = 0.
StartDist = 0
//cos
//starting distance from the
real
CurrentDist = 0
real
sp = 0.
//speed
group
group
hu = null
hg = null
boolean
boolean
TargetReached = false
OnTarget = false
//target reached?
//on target now?
MissileActions
ma = 0
integer
integer
data = 0
id = 0
//attached data
//the array index of the mis
target
een hit
ns
sile
//internal create method
private static method coreCreate takes real radius, MissileActions ma re
turns Missile
local Missile d = Missile.allocate()
set
set
set
set
d.hg = CreateGroup()
d.hu = CreateGroup()
d.Radius = radius
d.ma = ma
return d
endmethod
//creates a new missile with the given model
static method create takes string sfx, real x, real y, real radius, Miss
ileActions actions returns Missile
local Missile d = Missile.coreCreate(radius, actions)
set
set
set
set
set
set
d.fs = sfx
d.StartX = x
d.StartY = y
d.X = x
d.Y = y
d.dm = true
return d
endmethod
//creates a missile from an existing unit
static method createFromUnit takes unit u, real radius, MissileActions a
ctions returns Missile
local Missile d = Missile.coreCreate(radius, actions)
set
set
set
set
set
d.Dummy = u
d.StartX = GetUnitX(u)
d.StartY = GetUnitY(u)
d.X = d.StartX
d.Y = d.StartY
return d
endmethod
method operator HitUnits takes nothing returns group
local group g = CreateGroup()
set bj_groupAddGroupDest = g
call ForGroup(.hu, function GroupAddGroupEnum)
return g
endmethod
method operator Speed takes nothing returns real
return .sp * FPS
endmethod
method operator Speed= takes real speed returns nothing
set .sp = speed / FPS
endmethod
//Internal function to fire the missile
private method fire takes unit caster, real speed returns nothing
local real angle = Atan2(.TargetY - .Y, .TargetX - .X)
local real dx = .TargetX - .X
local real dy = .TargetY - .Y
set .sn = Sin(angle)
set .cs = Cos(angle)
set .StartDist = SquareRoot(dx * dx + dy * dy)
if .Dummy == null then
set .Dummy = CreateUnit(OWNER, DUMMY_ID, .X, .Y, angle * bj_RADT
ODEG)
set .SFX = AddSpecialEffectTarget(.fs, .Dummy, "origin")
endif
set .Caster = caster
set .sp = speed / FPS
call GroupAddUnit(Missiles, .Dummy)
set Dat[Index] = this
set .id = Index
set Index = Index + 1
if Index == 1 then
call TimerStart(Tim, 1./FPS, true, function Execute)
endif
endmethod
//fires the missile at a point!
method fireFixed takes unit caster, real targetX, real targetY, real spe
ed returns nothing
set .Homing = false
set .TargetX = targetX
set .TargetY = targetY
call .fire(caster, speed)
endmethod
//fires the missile at a unit!
method fireTarget takes unit caster, unit target, real speed returns not
hing
set .Homing = true
set .Target = target
set .TargetX = GetUnitX(.Target)
set .TargetY = GetUnitY(.Target)
call .fire(caster, speed)
endmethod
method onDestroy takes nothing returns nothing
set Index = Index - 1
set Dat[.id] = Dat[Index]
set Dat[.id].id = .id
call .ma.destroy()
call GroupClear(.hg)
call DestroyGroup(.hg)
call DestroyGroup(.hu)
if .SFX != null then
call DestroyEffect(.SFX)
endif
call GroupRemoveUnit(Missiles, .Dummy)
if .dm then
call KillUnit(.Dummy)
endif
endmethod
endstruct
private function Init takes nothing returns nothing
set Conds = Filter(function CondsFunc)
endfunction
endlibrary