Challenge: 
Winner?: 
No
Code Snippet: 
REM Project: Hunting
REM Created: 10/11/2005 20:33:09
REM
REM ***** Main Source File *****
REM

sync on
sync rate 60
autocam off
set camera range 0.5,500


global speed# = 0.4
global turnspeed# = 0.2
global anglex#
global angley#
global xmovement#
global zmovement#
global launch
global ClickBounce
global CurrentSpear = 0
global state = 0
global targetX
global targetY
global targetZ
global beasthealth = 100
global playerhealth = 100


type XYZ

   X as Float
   Y as Float
   Z as Float

endtype

type projectile

   Pos as XYZ
   Velocity as XYZ
   Rot as XYZ
   Object as Integer

endtype


#CONSTANT NUMPARTICLES 128
#CONSTANT TIMEPASSED 0.016666





GLOBAL currentfreeparticle
GLOBAL debouncemouseclick
GLOBAL currenteffect

type vertex
   X as float
   Y as float
   Z as float
endtype

type redgreenblue
   Red as float
   Green as float
   Blue as float
endtype

sync on
sync rate 60



type particle

   Pos as vertex
   PosVel as vertex
   PosAcc as vertex

   Rot as vertex
   RotVel as vertex

   Scale as Float
   ScaleVel as Float

   Lifetime as Float
   Active as Boolean
   Gravity as Boolean
   Facing as Boolean

   UOffset as Float
   VOffset as Float

   Object as Integer

   ColourBlend as Boolean
   Colour as redgreenblue
   ColourVel as redgreenblue


endtype

`**************
dim Particles(NUMPARTICLES) as particle
`**************


type particleemitter

   Pos as vertex

   Lifetime as Float
   Active as Boolean

   Repeatrate as Float
   Repeattime as Float

   EffectType as Integer

endtype

`**************
dim ParticleEmitters(0) as particleemitter
`**************


initialise_particles()
currenteffect = 1


create bitmap 2,8,8
set current bitmap 2
ink rgb(150,80,10),0
box 0,0,8,8
ink rgb(255,128,50),0
line 0,0,4,0
ink rgb(30,15,0),0
line 3,3,8,3
get image 1,0,0,8,8
ink rgb(60,60,60),0
box 0,0,8,8
for i = 0 to 3
   dot rnd(7),rnd(7),rgb(128,128,128)
next i
get image 2,0,0,8,8
ink rgb(0,100,0),0
box 0,0,8,8
get image 3,0,0,8,8

ink 0,0
box 0,0,8,8
ink rgb(255,255,255),0
for i = 0 to 4
   dot rnd(8),rnd(8)
next i

get image 4,0,0,8,8



delete bitmap 2
set current bitmap 0













rem ***************** SPEAR MAKING *****************


tempspear = 43
make object cylinder tempspear,0.10
scale object tempspear,100,1800,100
position object tempspear,15,5,10

tempspear2 = 42
make object cylinder tempspear2,0.10
scale object tempspear2,100,1800,100
position object tempspear2,15,5,10

speardummy2 = 40
make object sphere speardummy2,0.3,3,3
scale object speardummy2,100,200,100
make mesh from object 3,tempspear
delete object tempspear
add limb speardummy2,1,3
link limb speardummy2,0,1
offset limb speardummy2,1,0,-1,0


texture limb speardummy2,1,1
texture limb speardummy2,0,2




global spear as projectile
spear.Object = 40

position object spear.Object, 1,0,0
set object cull spear.Object,0
rotate object spear.Object,90,0,0
fix object pivot spear.Object

speardummy = 41
make object sphere speardummy,0.3,3,3
scale object speardummy,100,200,100
make mesh from object 2,tempspear2
delete object tempspear2
add limb speardummy,1,2
link limb speardummy,0,1
offset limb speardummy,1,0,-1,0

texture limb speardummy,1,1
texture limb speardummy,0,2


rem ***************** END OF SPEAR MAKING



temp = 10
make object sphere temp,8
position object temp,0,5,20
scale object temp,100,90,100
temp2 = 11
make object sphere temp2,4
position object temp2,0,4,16
temp3 = 12
temp4 = 13
temp5 = 14
temp6 = 15
make object cylinder temp3,4
position object temp3,1.5,2,18.5
scale object temp3,60,100,60
make object cylinder temp4,4
position object temp4,-1.5,2,18.5
scale object temp4,60,100,60
make object cylinder temp5,4
position object temp5,1.5,2,22
scale object temp5,60,100,60
make object cylinder temp6,4
position object temp6,-1.5,2,22
scale object temp6,60,100,60

texture object temp,3
texture object temp2,3
texture object temp3,3
texture object temp4,3
texture object temp5,3
texture object temp6,3

make mesh from object 10,temp2      `Head
make mesh from object 11,temp3      `Leg
make object cube 16,1
make mesh from object 12,16         `Dummy object
delete object 16

add limb temp,1,10
link limb temp,0,1
offset limb temp,1,0,-1,4

delete object temp2

add limb temp,2,12      `add a dummy object for first leg - limb2
link limb temp,0,2      `adds to the body limb (0)
offset limb temp,2,1.5,-1,-1.5

add limb temp,3,11
link limb temp,2,3
offset limb temp,3,0,-2.5,0

delete object temp3

add limb temp,4,12      `add dummy for second leg (front right) - limb 4
link limb temp,0,4      `add to body (0)
offset limb temp,4,-1.5,-1,-1.5

add limb temp,5,11      `second leg object (5)
link limb temp,4,5
offset limb temp,5,0,-2.5,0

delete object temp4

add limb temp,6,12
link limb temp,0,6
offset limb temp,6,1.5,-1,2

add limb temp,7,11
link limb temp,6,7
offset limb temp,7,0,-2.5,0

delete object temp5

add limb temp,8,12
link limb temp,0,8
offset limb temp,8,-1.5,-1,2

add limb temp,9,11
link limb temp,8,9
offset limb temp,9,0,-2.5,0

delete object temp6

texture limb temp,3,3
texture limb temp,5,3
texture limb temp,7,3
texture limb temp,9,3

texture limb temp,1,3




beastie = temp


set object collision on beastie
set object collision to polygons beastie




make object plain 3,1000,1000
rotate object 3,-90,0,0
color object 3,rgb(0,128,0)
texture object 3,3

color backdrop rgb(30,40,255)




global thrownspear as projectile
thrownspear.Object = 41
position object thrownspear.Object, spear.Pos.X, spear.Pos.Y, spear.Pos.Z
set object cull thrownspear.Object,0
rotate object thrownspear.Object,90,0,0
fix object pivot thrownspear.Object
rotate object thrownspear.Object, object angle x(spear.Object),object angle y(spear.Object),object angle z(spear.Object)
hide object thrownspear.Object


hide mouse



`********************MAIN LOOP*******************
do

MouseLook()

Position_HUDSpear()
throwspear()

`rotate the beastie
`yrotate object 10,wrapvalue(object angle y(10)+1)

text 5,30,"Enemy health"
text screen width()-110,30,"Player health"
ink 0,0
box 0+1,1,100+8,24
box screen width()-100-9,1,screen width()-1,24
ink rgb(255,0,0),0
box 0+5,5,beasthealth+5,20
box screen width()-playerhealth-5,5,screen width()-5,20
`print "Camera Pos:",camera position x(),",",camera position y(),",",camera position z()
`print "Launch Pos:",tempX#,", ",tempY#,", ",tempZ#
`print "Spear Pos:",object position x(thrownspear.Object),", ",object position y(thrownspear.Object),", ",object position z(thrownspear.Object)
`print "Beasty rotation:",object angle y(2)


disttotarg = get_distancesquaredpos(10,targetX,targetY,targetZ)

if state = 0
   targetX = camera position x()
   targetY = camera position y()
   targetZ = camera position z()
   state = 1
endif

if state = 1
   if (disttotarg > 50)
      beastie_move(10,targetX,targetY,targetZ)
      rotate limb temp,2,sin(timer()/3)*9,0,0
      rotate limb temp,4,-sin(timer()/3)*9,0,0

      rotate limb temp,6,-sin(timer()/3)*9,0,0
      rotate limb temp,8,sin(timer()/3)*9,0,0
   else
      state = 0
   endif
endif

distfromplayer = get_distancesquaredpos(10,camera position x(),camera position y(),camera position z())
if distfromplayer < 50
   playerhealth = playerhealth - rnd(1)
endif

`if distfromplayer < 700
   `rotate camera camera angle x()+rnd((700-dist)/100)-((700-dist)/200), camera angle y()+rnd((700-dist)/100)-((700-dist)/200),0
`endif

update_emitters()
update_particles()

if playerhealth < 0
   box 0,0,screen width(),screen height()
   ink 0,0
   for i = 0 to 50
      text rnd(screen width()),rnd(screen height()),"YOU DIED"
   next i
   sync
   wait key
   exit
endif

if beasthealth < 0
   ink 0,0
   for i = 0 to 50
      ink rgb(rnd(255),rnd(255),rnd(255)),0
      text rnd(screen width()),rnd(screen height()),"YOU WON!"
   next i
   sync
   wait key
   exit
endif


sync
loop
`****************END OF MAIN LOOP**************



`Position the Spear close enough to the player to look held in the hand.
function Position_HUDSpear()

   AtX# = -0.6     `The offset for the spear object.
   AtY# = 0.1
   AtZ# = 1.5

   temp# = (Cos( Camera Angle X()) * AtY#) - (Sin(Camera Angle X()) * AtZ#)
   AtZ# = (Sin(Camera Angle X()) * AtY#) + (Cos(Camera Angle X()) * AtZ#)
   AtY# = temp#

   temp# = (Cos(Camera Angle Y()) * AtX#) + (Sin(Camera Angle Y()) * AtZ#)
   AtZ# = (Cos(Camera Angle Y()) * AtZ#) - (Sin(Camera Angle Y()) * AtX#)
   AtX# = temp#

   spear.Pos.X = Camera Position X() + AtX#
   spear.Pos.Y = Camera Position Y() + AtY#
   spear.Pos.Z = Camera Position Z() + AtZ#

   Position Object spear.Object, spear.Pos.X, spear.Pos.Y, spear.Pos.Z
   Rotate Object spear.Object, wrapvalue(Camera Angle X()-20), Camera Angle Y(), Camera Angle Z()

endfunction




function MouseLook()

position mouse 320,240

   `forwards (w)
   if keystate(17)=1
      xmovement# = newxvalue(xmovement#,wrapvalue(camera angle y()),speed#)
      zmovement# = newzvalue(zmovement#,wrapvalue(camera angle y()),speed#)
   endif
   `backwards (s)
   if keystate(31)=1
      xmovement# = newxvalue(xmovement#,wrapvalue(camera angle y()-180),speed#)
      zmovement# = newzvalue(zmovement#,wrapvalue(camera angle y()-180),speed#)
   endif
   `left (a)
   if keystate(30)=1
      xmovement# = newxvalue(xmovement#,wrapvalue(camera angle y()-90),speed#)
      zmovement# = newzvalue(zmovement#,wrapvalue(camera angle y()-90),speed#)
   endif
   `right (d)
   if keystate(32)=1
      xmovement# = newxvalue(xmovement#,wrapvalue(camera angle y()+90),speed#)
      zmovement# = newzvalue(zmovement#,wrapvalue(camera angle y()+90),speed#)
   endif

   position camera xmovement#,1,zmovement#

   anglex# = wrapvalue( anglex# + mousemovey() * turnspeed#)
   angley# = wrapvalue( angley# + mousemovex() * turnspeed#)

   set cursor 0,0

   rem stops mouse from going upside down
   if anglex# < 180 AND anglex# > 90 then anglex# = 90
   if anglex# < 270 AND anglex# > 180 then anglex# = 270

   rotate camera 0,anglex#, angley#, 0

endfunction



function spearvelocity()

   VelX# = 0
   VelY# = 0
   VelZ# = 0.2

   temp# = (Cos(Object Angle X(spear.Object)) * VelY#) - (Sin(Object Angle X(spear.Object)) * VelZ#)
   VelZ# = (Sin(Object Angle X(spear.Object)) * VelY#) + (Cos(Object Angle X(spear.Object)) * VelZ#)
   VelY# = temp#

   temp# = (Cos(Object Angle Y(spear.Object)) * VelX#) + (Sin(Object Angle Y(spear.Object)) * VelZ#)
   VelZ# = (Cos(Object Angle Y(spear.Object)) * VelZ#) - (Sin(Object Angle Y(spear.Object)) * VelX#)
   VelX# = temp#

   thrownspear.Velocity.X = VelX#
   thrownspear.Velocity.Y = VelY#
   thrownspear.Velocity.Z = VelZ#

endfunction





function resetspear()

show object spear.Object
hide object thrownspear.Object
launch = 0

endfunction


function fixatanfu()

   FixX# = thrownspear.Velocity.X
   FixY# = thrownspear.Velocity.Y
   FixZ# = thrownspear.Velocity.Z

   temp# = (Cos(-Object Angle Y(spear.Object)) * FixX#) + (Sin(-Object Angle Y(spear.Object)) * FixZ#)
   FixZ# = (Cos(-Object Angle Y(spear.Object)) * FixZ#) - (Sin(-Object Angle Y(spear.Object)) * FixX#)
   FixX# = temp#

   local_z# = FixX#
   local_y# = FixY#
   local_z# = FixZ#

   curverot# = atanfull (local_z#,local_y#)
endfunction curverot#




function throwspear()

thrownspear.Pos.X = object position x(thrownspear.Object)
thrownspear.Pos.Y = object position y(thrownspear.Object)
thrownspear.Pos.Z = object position z(thrownspear.Object)

`******************************* THROW THE SPEAR ***********************
if mouseclick() = 1 AND ClickBounce = 0

   show object thrownspear.Object
   thrownspear.Pos.X = object position x(spear.Object)
   thrownspear.Pos.Y = object position y(spear.Object)
   thrownspear.Pos.Z = object position z(spear.Object)
   position object thrownspear.Object, thrownspear.Pos.X, thrownspear.Pos.Y, thrownspear.Pos.Z
   rotate object thrownspear.Object, object angle x(spear.Object),object angle y(spear.Object),object angle z(spear.Object)
   hide object spear.Object

   tempX# = thrownspear.Pos.X
   tempY# = thrownspear.Pos.Y
   tempZ# = thrownspear.Pos.Z

   spearvelocity()
   ClickBounce = 1
   launch = 1

endif

if mouseclick() = 0
   ClickBounce = 0
endif

if launch = 1

   turnything# = fixatanfu()

   thrownspear.Rot.X = wrapvalue(turnything#-90.0)
   thrownspear.Rot.Y = object angle Y(thrownspear.Object)
   thrownspear.Rot.Z = object angle Z(thrownspear.Object)

   thrownspear.Pos.X = thrownspear.Pos.X + thrownspear.Velocity.X
   thrownspear.Pos.Y = thrownspear.Pos.Y + thrownspear.Velocity.Y
   thrownspear.Pos.Z = thrownspear.Pos.Z + thrownspear.Velocity.Z
   position object thrownspear.Object, thrownspear.Pos.X, thrownspear.Pos.Y, thrownspear.Pos.Z
   xrotate object thrownspear.Object, thrownspear.Rot.X
   thrownspear.Velocity.Y = thrownspear.Velocity.Y - (0.1/60.0)

   checkspearcollision()

endif

if mouseclick() = 2 AND launch > 0
   unglue object thrownspear.Object
   resetspear()
endif

endfunction



function checkspearcollision()

   if object position y(thrownspear.Object) < 0.1
      launch = 2
   endif

   if object collision (thrownspear.Object,10) = 1
      hitposX# = object position x(thrownspear.Object)
      hitposY# = object position y(thrownspear.Object)
      hitposZ# = object position z(thrownspear.Object)
      hitposoffsetX# = hitposX#-object position x(10)
      hitposoffsetY# = hitposY#-object position y(10)
      hitposoffsetZ# = hitposZ#-object position z(10)


      temp# = (Cos(-Object Angle Y(10)) * hitposoffsetX#) + (Sin(-Object Angle Y(10)) * hitposoffsetZ#)
      hitposoffsetZ# = (Cos(-Object Angle Y(10)) * hitposoffsetZ#) - (Sin(-Object Angle Y(10)) * hitposoffsetX#)
      hitposoffsetX# = temp#


      position object thrownspear.Object,hitposoffsetX#,hitposoffsetY#,hitposoffsetZ#
      yrotate object thrownspear.Object,object angle y(thrownspear.Object)-Object Angle Y(10)
      glue object to limb thrownspear.Object,10,0

      makebloodeffect(hitposX#,hitposY#,hitposZ#)
      beasthealth = beasthealth - rnd(3)-2

      launch = 2
   endif

endfunction



function beastie_move(beastienum,targX#,targY#,targZ#)

   PosX# = object position x(beastienum)
   PosZ# = object position z(beastienum)

   MoveX# = -sin(-Object Angle Y(beastienum)) * 0.2
   MoveZ# = cos(-Object Angle Y(beastienum)) * 0.2

   `Update the positions in the X and Z using the vector.
   PosX#=PosX#+MoveX#
   PosZ#=PosZ#+MoveZ#

   `Do the rotation
   XDiff = targX# - Object Position X(beastienum)
   ZDiff = targZ# - Object Position Z(beastienum)

   angle# = ATanFull(XDiff, ZDiff)

   angle# = WrapValue(angle#)

   AngleDiff# = Object Angle Y(beastienum) - angle#

   while (AngleDiff# < -180)
      AngleDiff# = AngleDiff# + 360
   endwhile

   while (AngleDiff# > 180)
      AngleDiff# = AngleDiff# - 360
   endwhile

   YRotate Object beastienum,Object Angle Y(beastienum) - (AngleDiff#/40)
   position object beastienum,PosX#,5,PosZ#

endfunction





function get_distancesquaredpos(object1,obj2x#,obj2y#,obj2z#)

   obj1x# = object position x(object1)
   obj1y# = object position y(object1)
   obj1z# = object position z(object1)

   distancesquared# = ((obj1x#-obj2x#)*(obj1x#-obj2x#)) + ((obj1y#-obj2y#)*(obj1y#-obj2y#)) + ((obj1z#-obj2z#)*(obj1z#-obj2z#))

endfunction distancesquared#





Function update_particles()


   for i = 0 to array count(Particles())

      if Particles(i).Active = 1

         if Particles(i).Gravity = 1
            Particles(i).PosVel.Y = Particles(i).PosVel.Y - (9.81 * TIMEPASSED)
         endif

         Particles(i).PosVel.X = Particles(i).PosVel.X + (Particles(i).PosAcc.X * TIMEPASSED)
         Particles(i).PosVel.Y = Particles(i).PosVel.Y + (Particles(i).PosAcc.Y * TIMEPASSED)
         Particles(i).PosVel.Z = Particles(i).PosVel.Z + (Particles(i).PosAcc.Z * TIMEPASSED)

         Particles(i).Pos.X = Particles(i).Pos.X + (Particles(i).PosVel.X * TIMEPASSED)
         Particles(i).Pos.Y = Particles(i).Pos.Y + (Particles(i).PosVel.Y * TIMEPASSED)
         Particles(i).Pos.Z = Particles(i).Pos.Z + (Particles(i).PosVel.Z * TIMEPASSED)

         Particles(i).Rot.X = Particles(i).Rot.X + (Particles(i).RotVel.X * TIMEPASSED)
         Particles(i).Rot.Y = Particles(i).Rot.Y + (Particles(i).RotVel.Y * TIMEPASSED)
         Particles(i).Rot.Z = Particles(i).Rot.Z + (Particles(i).RotVel.Z * TIMEPASSED)

         Particles(i).Scale = Particles(i).Scale + (Particles(i).ScaleVel * TIMEPASSED)

         if Particles(i).Scale < 1
            Particles(i).Lifetime = 0.0
         endif

         Position Object Particles(i).Object,Particles(i).Pos.X,Particles(i).Pos.Y,Particles(i).Pos.Z
         Rotate Object Particles(i).Object,Particles(i).Rot.X,Particles(i).Rot.Y,Particles(i).Rot.Z
         Scale Object Particles(i).Object,Particles(i).Scale,Particles(i).Scale,Particles(i).Scale


         if Particles(i).Facing = 1
            Point Object Particles(i).Object,camera position x(),camera position y(),camera position z()
         endif

         if Particles(i).ColourBlend = 1
            Particles(i).Colour.Red = Particles(i).Colour.Red + (Particles(i).ColourVel.Red * TIMEPASSED)
            Particles(i).Colour.Green = Particles(i).Colour.Green + (Particles(i).ColourVel.Green * TIMEPASSED)
            Particles(i).Colour.Blue = Particles(i).Colour.Blue + (Particles(i).ColourVel.Blue * TIMEPASSED)
            If Particles(i).Colour.Red > 255 then Particles(i).Colour.Red = 255
            If Particles(i).Colour.Red < 0 then Particles(i).Colour.Red = 0
            If Particles(i).Colour.Green > 255 then Particles(i).Colour.Green = 255
            If Particles(i).Colour.Green < 0 then Particles(i).Colour.Green = 0
            If Particles(i).Colour.Blue > 255 then Particles(i).Colour.Blue = 255
            If Particles(i).Colour.Blue < 0 then Particles(i).Colour.Blue = 0
            set object emissive Particles(i).Object, rgb(Particles(i).Colour.Red, Particles(i).Colour.Green, Particles(i).Colour.Blue)
            set object diffuse Particles(i).Object, rgb(Particles(i).Colour.Red, Particles(i).Colour.Green, Particles(i).Colour.Blue)
         endif


         show object Particles(i).Object

         Particles(i).Lifetime = Particles(i).Lifetime - TIMEPASSED

         if Particles(i).Lifetime <= 0
            Particles(i).Active = 0
            hide object Particles(i).Object
            scroll object texture Particles(i).Object,-Particles(i).UOffset,-Particles(i).VOffset
            Particles(i).UOffset = 0
            Particles(i).VOffset = 0
         endif

      endif
   next i


Endfunction





Function initialise_particles()

for i = 0 to array count(Particles())

   Particles(i).Object = free_object()
   make object plain Particles(i).Object,1,1
   texture object Particles(i).Object,4
   ghost object on Particles(i).Object
   hide object Particles(i).Object
   disable object zwrite Particles(i).Object
   set object specular Particles(i).Object,0
   Particles(i).Active = 0
   set object collision off Particles(i).Object

next i

Endfunction







Function allocate_particle()

   particle_index = currentfreeparticle
   currentfreeparticle = (currentfreeparticle+1) MOD NUMPARTICLES

   Particles(particle_index).Active = 1

Endfunction particle_index








Function reset_particle(index)

   scroll object texture Particles(index).Object,-Particles(index).UOffset,-Particles(index).VOffset
   Particles(index).Pos.X = 0
   Particles(index).Pos.Y = 0
   Particles(index).Pos.Z = 0
   Particles(index).PosVel.X = 0
   Particles(index).PosVel.Y = 0
   Particles(index).PosVel.Z = 0
   Particles(index).PosAcc.X = 0
   Particles(index).PosAcc.Y = 0
   Particles(index).PosAcc.Z = 0


   Particles(index).Rot.X = 0
   Particles(index).Rot.Y = 0
   Particles(index).Rot.Z = 0
   Particles(index).RotVel.X = 0
   Particles(index).RotVel.Y = 0
   Particles(index).RotVel.Z = 0

   Particles(index).Scale = 100
   Particles(index).ScaleVel = 0

   Particles(index).Lifetime = 1

   Particles(index).UOffset = 0
   Particles(index).VOffset = 0

   Particles(index).Colour.Red = 255
   Particles(index).Colour.Green = 255
   Particles(index).Colour.Blue = 255

   Particles(index).ColourVel.Red = 0
   Particles(index).ColourVel.Green = 0
   Particles(index).ColourVel.Blue = 0

   Particles(index).ColourBlend = 0

Endfunction




Function particle_colourblend(local_initialred,local_initialgreen,local_initialblue,local_finalred,local_finalgreen,local_finalblue,local_particleindex)

    Particles(local_particleindex).Colour.Red = local_initialred
    Particles(local_particleindex).Colour.Green = local_initialgreen
    Particles(local_particleindex).Colour.Blue = local_initialblue

    Particles(local_particleindex).ColourVel.Red = (local_finalred - local_initialred)/ Particles(local_particleindex).Lifetime
    Particles(local_particleindex).ColourVel.Green = (local_finalgreen - local_initialgreen)/Particles(local_particleindex).Lifetime
    Particles(local_particleindex).ColourVel.Blue = (local_finalblue - local_initialblue)/Particles(local_particleindex).Lifetime


Endfunction





Function free_object()
   i=100
   Do
      If Object Exist(i)=0 then Exit
      inc i
   Loop
Endfunction i


Function free_image()
   i=100
   Do
      If Image Exist(i)=0 then Exit
      inc i
   Loop
Endfunction i


Function update_emitters()

   for i = 0 to array count(ParticleEmitters())

      if ParticleEmitters(i).Active = 1

         ParticleEmitters(i).Repeattime = ParticleEmitters(i).Repeattime - TIMEPASSED
         ParticleEmitters(i).Lifetime = ParticleEmitters(i).Lifetime - TIMEPASSED

         if ParticleEmitters(i).Repeattime <= 0

            Select ParticleEmitters(i).EffectType

               case 1
                  makeblood(ParticleEmitters(i).Pos.X,ParticleEmitters(i).Pos.Y,ParticleEmitters(i).Pos.Z)
               endcase

            endselect

            ParticleEmitters(i).Repeattime = ParticleEmitters(i).Repeatrate
         endif

         if ParticleEmitters(i).Lifetime <= 0
            ParticleEmitters(i).Active = 0
         endif
      endif

   next i

Endfunction





Function allocate_emitter()

   for i = 0 to array count(ParticleEmitters())
      if ParticleEmitters(i).Active = 0
         particleemitter_index = i
         exitfunction particleemitter_index
      endif
   next i

   array insert at bottom ParticleEmitters()
   particleemitter_index = array count(ParticleEmitters())

endfunction particleemitter_index






Function reset_emitter(index)

   ParticleEmitters(index).Pos.X = 0
   ParticleEmitters(index).Pos.Y = 0
   ParticleEmitters(index).Pos.Z = 0

   ParticleEmitters(index).Lifetime = 1
   ParticleEmitters(index).Repeatrate = 1
   ParticleEmitters(index).Repeattime = 0

   ParticleEmitters(index).EffectType = 0

Endfunction





Function makebloodeffect(local_xpos,local_ypos,local_zpos)

   index = allocate_emitter()                         `This is required to get a free emitter from the list.
   reset_emitter(index)                               `Starts the emitter clean and defaulty.

   ParticleEmitters(index).Pos.X = local_xpos         `Positions the emitter in the world.  Used for spell locations etc
   ParticleEmitters(index).Pos.Y = local_ypos
   ParticleEmitters(index).Pos.Z = local_zpos

   ParticleEmitters(index).Lifetime = 0.2               `The lifetime in seconds of the EMITTER - not the particles.
   ParticleEmitters(index).Repeatrate = 0.1          `How often the emitter will spew out particles in seconds.

   ParticleEmitters(index).EffectType = 1             `Number of the effect that the emitter spews.  You can use CONSTANTs
   ParticleEmitters(index).Active = 1                 `Sets it to active.  Required.

Endfunction








Function makeblood(local_xpos,local_ypos,local_zpos)

for i = 0 to 60

    index = allocate_particle()              `These are required for getting the next free particle.
    reset_particle(index)                    `This ensures the particle has a 'clean slate' to begin.

    Particles(index).Pos.X = local_xpos      `The particle's initial start position.  Usually given by
    Particles(index).Pos.Y = local_ypos      `the emitter when it calls the particle.
    Particles(index).Pos.Z = local_zpos

    Particles(index).PosVel.X = rnd(6)       `The initial velocity of the particle.  If you have gravity
    Particles(index).PosVel.Y = rnd(8)+5     `enabled, the Y velocity should be quite large (in the 8-10
    Particles(index).PosVel.Z = rnd(6)       `range) to counteract it.

    Particles(index).PosAcc.X = 0            `Any initial acceleration on the particle.  If you want it
    Particles(index).PosAcc.Z = 0            `to get increasingly faster in a direction, accelleration
    Particles(index).PosAcc.Y = 0            `is where it's at.

    Particles(index).Rot.X = 0               `The rotation of the particle - NOTE if you have facing ON
    Particles(index).Rot.Y = 0               `then these numbers will be ignored.
    Particles(index).Rot.Z = 0

    Particles(index).RotVel.X = 0            `If you want the particle to spin at all, then use these,
    Particles(index).RotVel.Y = 0            `but remember - if Facing is ON, these will have little
    Particles(index).RotVel.Z = 0            `or no effect.


    Particles(index).Scale = 5.0            `The initial scale of the particle in percent.  Size is 1.
    Particles(index).ScaleVel = 25           `The change in scale per second for the object.  Negative
                                             `numbers to shrink over time, positive numbers to expand.

    Particles(index).Lifetime = 1            `The length of time, in seconds, that each particle lasts.

    Particles(index).Gravity = 1             `1 or 0 for affected by gravity or not.
    Particles(index).Facing = 1              `1 or 0 for facing the player always, or not.

    Particles(index).UOffset = 0             `Offset in the particle texture.  Values between 0 and 0.75, in 0.25s.
    Particles(index).VOffset = 0             `Same as above, but up and down, instead of left and right.

    local_initialred = 255                   `Temporary variables to set the start and end colour of your
    local_initialgreen = 0                   `particle system.  If you only want one colour, just set it as
    local_initialblue = 0                    `the start colour.
    local_finalred = 0                     `The function below (particle_colourblend) sets the colour velocities.
    local_finalgreen = 0
    local_finalblue = 0

    Particles(index).ColourBlend = 1         `This boolean sets whether you want to blend.  1 to blend.

    particle_colourblend(local_initialred,local_initialgreen,local_initialblue,local_finalred,local_finalgreen,local_finalblue,index)

                                             `The following three lines set up the look of the particle initially.
    set object emissive Particles(index).Object,rgb(Particles(index).Colour.Red,Particles(index).Colour.Green,Particles(index).Colour.Blue)
    set object diffuse Particles(index).Object,rgb(Particles(index).Colour.Red,Particles(index).Colour.Green,Particles(index).Colour.Blue)
    scroll object texture Particles(index).Object,Particles(index).UOffset,Particles(index).VOffset
next i

Endfunction