set display mode 1280, 1024, 32
sync on
sync rate 0
autocam off
backdrop on
color backdrop 0
randomize timer()
hide mouse
set directional light 0, 1.0, -1.0, -1.0
set ambient light 0
 
#constant ARENA_SIZE 18.0
make object plain 1, ARENA_SIZE*1.2, ARENA_SIZE*1.2
position object 1, 0, 0, 0
point object 1, 0, 1, 0
color object 1, rgb(0, 128, 0)
 
#constant bgSize 1024
make memblock 1, 12 + (bgSize * bgSize * 4)
write memblock dword 1, 0, bgSize
write memblock dword 1, 4, bgSize
write memblock dword 1, 8, 32
 
for y = 0 to bgSize-1
   for x = 0 to bgSize-1
       write memblock dword 1, (((y * bgSize) + x) * 4) + 12, rgb(0, 64 + rnd(64), 0)
   next x
next y
make image from memblock 1, 1
texture object 1, 1
delete memblock 1
 
 
 
 
 
`Create ant texture
#constant antTextureSize 32
make memblock 1, 12 + (antTextureSize * antTextureSize * 4)
write memblock dword 1, 0, antTextureSize
write memblock dword 1, 4, antTextureSize
write memblock dword 1, 8, 32
col as dword
for y = 0 to antTextureSize-1
   for x = 0 to antTextureSize-1
      b# = 255 - (sqrt(((x-16)*(x-16)) + ((y-16)*(y-16))) * 16.0)
      if b# < 0.0 then b# = 0.0
      col = rgb(0, 0, b#)
      write memblock dword 1, (((y * antTextureSize) + x) * 4) + 12, col
   next x
next y
make image from memblock 10, 1
delete memblock 1
 
 
 
 
 
 
`Create pointer texture
#constant antTextureSize 32
make memblock 1, 12 + (antTextureSize * antTextureSize * 4)
write memblock dword 1, 0, antTextureSize
write memblock dword 1, 4, antTextureSize
write memblock dword 1, 8, 32
col as dword
for y = 0 to antTextureSize-1
   for x = 0 to antTextureSize-1
      r# = 255 - (sqrt(((x-16)*(x-16)) + ((y-16)*(y-16))) * 12.0)
      if r# < 0.0 then r# = 0.0
      col = rgba(r#, 0, 0, 128)
      write memblock dword 1, (((y * antTextureSize) + x) * 4) + 12, col
   next x
next y
make image from memblock 11, 1
delete memblock 1
 
 
 
 
 
 
 
`Make Pointer
make object triangle 2, -0.3, 0.0, -0.6,   0.0, 0.0, 0.1,   0.3, 0.0, -0.6
position object 2, 0, 0.25, 0
`color object 2, rgb(255,255,255)
texture object 2, 11
set object transparency 2, 3
set object light 2, 0
position mouse screen width() * 0.5, screen height() * 0.5
Type FeederData
   x#
   z#
   mx#
   mz#
   lastCreated
endtype
Feeder as FeederData
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
#constant ANT_SPEED 4.0
#constant MAX_ANT_COUNT = 15
Type AntData
   x#
   z#
   angle#
   cx#
   cz#
   reproduce_progress#
EndType
 
Dim Ants(MAX_ANT_COUNT) as AntData
for i = 1 to 5 : createRandomAnt(i) : next i
 
 
 
position camera 0, 20.0, 0
point camera 0,0,0
null = make vector2(1)
 
`Memblock for ant data
#constant outW 11
#constant outH 33
#constant outAlpha 96
MEM_SIZE as integer
MEM_SIZE = 12 + ((outW * outH)*4)
`template memblock
make memblock 1, MEM_SIZE
write memblock dword 1, 0, outW
write memblock dword 1, 4, outH
write memblock dword 1, 8, 32
 
`memblock to use
make memblock 2, MEM_SIZE
 
`define color variable
col as DWORD
col = rgba(0,0,0,outAlpha)
for y = 0 to outH-1
   for x = 0 to outW-1
      write memblock dword 1, (((y*outW)+x)*4)+12, col
   next x
next y
 
 
 
 
 
 
 
`Create menu's
get image 999, 0,0, 1,1
sprite 999, mousex(), mousey(), 999
hide sprite 999
Dim alphas#(20)
#constant MENU_W 128
#constant MENU_H 32
#constant MENU_MIN_ALPHA 64
#constant MENU_MAX_ALPHA 144
global black as dword   : black  = rgb(0,0,0)
global menu as dword : menu = rgb(192, 192, 192)
 
set text font "Arial"
set text size 24
 
MakeMenuItem("File", 1000, 0, 0)
MakeMenuItem("Load Game", 1001, 0, MENU_H)
MakeMenuItem("Save Game", 1002, 0, MENU_H*2)
MakeMenuItem("Exit", 1003, 0, MENU_H*3)
 
MakeMenuItem("Tools", 1010, MENU_W, 0)
MakeMenuItem("Pause", 1011, MENU_W, MENU_H)
MakeMenuItem("Feeder", 1012, MENU_W, MENU_H*2)
MakeMenuItem("Ant Editor", 1013, MENU_W, MENU_H*3)
ink rgb(255,255,255), black
 
 
 
`Mouse Status
`  0 = normal
`  1 = feeder
MouseStatus = 1
MouseButton = 0
`Pause Status
`  0 = Not Paused
`  1 = Pause
PauseStatus = 0
 
 
`START OF GAME
set text font "Courier New"
set text size 16
frameTime# = 1.0
startTime = timer()
do
   if PauseStatus = 0
      frameTime# = (frameTime# * 0.8) + ((timer() - startTime) * 0.2)
   else
      frameTime# = 0.0
   endif
   startTime = timer()
   text 288,10, "FPS: " + str$(screen fps())
 
   if mouseclick() = 2
      MouseStatus = 0
      show mouse
   endif
 
 
   gosub _MOVE_ANTS
   if MouseStatus = 1 then gosub _POSITION_FEEDER
   if MouseStatus = 0 then gosub _HANDLE_MENUS
 
   sync
loop
 
 
 
 
_HANDLE_MENUS:
   sprite 999, mousex(), mousey(), 999
   col = sprite collision(999,0)
 
   for i = 1000 to 1003
      `File Menu
      if i = col
         alphas#(i-1000) = curvevalue(MENU_MAX_ALPHA, alphas#(i-1000), 100.0 / frameTime#)
      else
         alphas#(i-1000) = curvevalue(MENU_MIN_ALPHA, alphas#(i-1000), 100.0 / frameTime#)
      endif
      set sprite alpha i, alphas#(i-1000)
 
      `Tools Menu
      if i+10 = col
          alphas#(i-990) = curvevalue(MENU_MAX_ALPHA, alphas#(i-990), 100.0 / frameTime#)
      else
          alphas#(i-990) = curvevalue(MENU_MIN_ALPHA, alphas#(i-990), 100.0 / frameTime#)
      endif
      set sprite alpha i+10, alphas#(i-990)
   next i
 
   if col = 1000
      if sprite visible(1001) = 0
         for i = 1001 to 1003 : show sprite i : next i
      endif
      for i = 1011 to 1013 : hide sprite i : next i
   else
      if col = 1010
         if sprite visible(1011) = 0
            for i = 1011 to 1013 : show sprite i : next i
         endif
         for i = 1001 to 1003 : hide sprite i : next i
      endif
   endif
 
 
   if mouseclick() = 1
      if MouseButton = 0
         MouseButton = 1
         select col
            case 1000
            endcase
 
            case 1001
            endcase
 
            case 1002
            endcase
 
            case 1003
               `Exit button
               end
            endcase
 
 
 
 
            case 1010
               if sprite visible(1011)
                  for i = 1011 to 1013 : hide sprite i : next i
               else
                  for i = 1011 to 1013 : show sprite i : next i
               endif
               for i = 1001 to 1003 : hide sprite i : next i
            endcase
 
            case 1013
               `change to feeder
               MouseStatus = 1
               null = mousemovex()
               null = mousemovey()
               hide mouse
               for i = 1011 to 1013 : hide sprite i : next i
            endcase
         endselect
      endif
   else
      if MouseButton = 1 then MouseButton = 0
   endif
return
 
function MakeMenuItem(txt$, v, x, y)
   txtHeight = text height(txt$)
 
   ink menu, black : box 0,0, MENU_W, MENU_H : ink black, menu : center text MENU_W*0.5, (MENU_H-txtHeight)*0.5, txt$
   get image v, 0, 0, MENU_W, MENU_H
   sprite v, x, y, v
   set sprite alpha v, MENU_MIN_ALPHA
   alphas#(v-1000) = MENU_MIN_ALPHA
   if v mod 10 <> 0 then hide sprite v
endfunction
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
_POSITION_FEEDER:
   inc Feeder.mx#, mousemovex() * frameTime# *  0.0001
   inc Feeder.mz#, mousemovey() * frameTime# * -0.0001
   Feeder.mx# = curvevalue(0.0, Feeder.mx#, 100.0 / frameTime#)
   Feeder.mz# = curvevalue(0.0, Feeder.mz#, 100.0 / frameTime#)
 
   if Feeder.mx# <> 0 OR Feeder.mz# <> 0
      inc Feeder.x#, Feeder.mx#
      inc Feeder.z#, Feeder.mz#
      if (Feeder.x# < -ARENA_SIZE*0.5 AND Feeder.mx# < 0) OR (Feeder.x# > ARENA_SIZE*0.5 AND Feeder.mx# > 0) then Feeder.mx# = -Feeder.mx#
      if (Feeder.z# < -ARENA_SIZE*0.5 AND Feeder.mz# < 0) OR (Feeder.z# > ARENA_SIZE*0.5 AND Feeder.mz# > 0) then Feeder.mz# = -Feeder.mz#
 
      position object 2, Feeder.x#, 0.25, Feeder.z#
      yrotate object 2, atanfull(Feeder.mx#, Feeder.mz#)
   endif
 
   if mouseclick() = 1
      if object collision(2, 0) >= 200
         i = object collision(2, 0)
         s# = object size x(i)
         inc s#, frameTime# * 0.0005
         s# = (s# / 0.5) * 100.0
         scale object i, s#, 50.0, s#
      else
         if timer() - lastCreated > 750
            i = 200
            while object exist(i) AND i < 205
               inc i
            endwhile
            if object exist(i) = 0
               make object sphere i, 0.5
               scale object i, 100.0, 50.0, 100.0
               position object i,Feeder.x#, 0.25, Feeder.z#
               color object i, rgb(192, 0, 0)
               if object collision(i,0) >= 100 then delete object i
               lastCreated = timer()
            endif
         endif
      endif
   endif
return
 
 
 
 
_MOVE_ANTS:
   for i = 1 to MAX_ANT_COUNT
      obj = 100+i
      if object exist(obj)
         closestID = -1
         closest# = -1.0
         for j = 200 to 220
            if object exist(j)
               if object collision(obj, j) = 1
                  `Ant eats food
                  s# = object size x(obj)
                  inc s#, object size x(j) * 0.05
                  s# = (s# / 0.2) * 100.0
                  if s# > 300.0 then s# = 300.0
                  scale object obj, s#, 100.0, s#
                  delete object j
               else
                  `Find closest food source
                  dx# = (object position x(j) - Ants(i).x#)
                  dz# = (object position z(j) - Ants(i).z#)
 
                  set vector2 1, dx#, dz#
                  dist# = length vector2(1)
                  if closestID = -1 OR dist# < closest# then closestID = j : closest# = dist#
               endif
            endif
         next j
 
         if closestID > -1
            `Head for food source
            dx# = (object position x(closestID) - Ants(i).x#)
            dz# = (object position z(closestID) - Ants(i).z#)
            set vector2 1, dx#, dz#
            dist# = length vector2(1)
         else
            `set heading for patrol zone
            dx# = (Ants(i).cx# - Ants(i).x#)
            dz# = (Ants(i).cz# - Ants(i).z#)
            set vector2 1, dx#, dz#
            dist# = length vector2(1)
            if dist# < 5.0
               inc Ants(i).cx#, (rnd(5.0)-2.5) * frameTime# * 0.001
               inc Ants(i).cz#, (rnd(5.0)-2.5) * frameTime# * 0.001
            endif
         endif
 
         `Give the ant a radius for patrol
         if dist# < 3.0 then dist# = 3.0
 
         `calculate the angle between ant and target (patrol zone or food)
         dAngle# = atanfull(dx#, dz#)
         `gradually turn ant towards target based on the distance to target
         Ants(i).angle# = curveangle(dAngle#, Ants(i).angle#, dist# * (100.0 / frameTime#))
 
         `Set Ant Speed based on how "fat" they are
         sp# = ANT_SPEED - (object size x(obj) * 10.0)
         if sp# < 0.5 then sp# = 0.5
 
         `Calculate new position based on angle and speed and time.
         inc Ants(i).x#, sp# * sin(Ants(i).angle#) * frameTime# * 0.001
         inc Ants(i).z#, sp# * cos(Ants(i).angle#) * frameTime# * 0.001
         position object obj, Ants(i).x#, 0.25, Ants(i).z#
         yrotate object obj, Ants(i).angle#
 
 
         s# = (object size x(obj) / 0.002) - frameTime# * 0.001
         if s# < 75.0
            `Dead Ant
            delete object obj
            j = 205
            `Search for available object to create food from dead ant
            while object exist(j) AND j < 221 : inc j : endwhile
 
            if object exist(j) = 0
               `Create food from dead ant
               make object sphere j, 0.5
               scale object j, 100.0, 50.0, 100.0
               position object j, Ants(i).x#, 0.25, Ants(i).z#
               color object j, rgb(192, 0, 0)
            endif
         else
            if Ants(i).reproduce_progress# > 30.0
               `REPRODUCE CODE HERE
               j = 101
               while object exist(j) = 1 AND j < MAX_ANT_COUNT + 100 : inc j : endwhile
               if object exist(j) = 0
                  createAnt(j-100, Ants(i).x#, Ants(i).z#)
                  Ants(i).reproduce_progress# = 0.0
                  dec s#, 100.0
               endif
            else
               if s# > 200.0 then inc Ants(i).reproduce_progress#, frameTime# * 0.003
            endif
            rep# = Ants(i).reproduce_progress#
 
            scale object obj, s#, 100.0, s#
 
 
            sX# = object screen x(obj) + 15.0
            sY# = object screen y(obj) - 15.0
 
            `Max = 30.0
            `Min = 7.5
            `Range = 22.5
            `Factor to turn 22.5 to 30 = 1.33…
 
            `Bar cols:
            `  0 = black
            `  1,2,3,4 = Health
            `  5 = black
            `  6,7,8,9 = reproduce progress
            `  10 = black
 
 
            s# = ((object size x(obj) / 0.02) - 7.5) * 1.33333333333333333333333
            if s# < 0.0 then s# = 0.0
 
            `Copy template into usable
            copy memblock 1, 2, 0, 0, MEM_SIZE
 
            `Create health bar
            r# = 255.0 - (s# * 8.5) : if r# < 0 then r# = 0 else if r# > 255 then r# = 255
            g# =         (s# * 8.5) : if g# < 0 then g# = 0 else if g# > 255 then g# = 255
            col = rgba(r#, g#, 0, outAlpha)
            y = 31
            while s# > 0.0
               for x = 1 to 4
                  write memblock dword 2, (((y*outW)+x)*4)+12, col
               next x
               dec s#, 1
               dec y
            endwhile
            `Create reproduction bar
            col = rgba(0, 128, 255, outAlpha)
            y = 31
            while rep# > 0.0
               for x = 6 to 9
                  write memblock dword 2, (((y*outW)+x)*4)+12, col
               next x
               dec rep#, 1
               dec y
            endwhile
 
            make image from memblock 2, 2
            paste image 2, sX#, sY#, 1
         endif
      endif
   next i
return
 
 
end
function createRandomAnt(i)
   Ants(i).x# = rnd(ARENA_SIZE)-(ARENA_SIZE*0.5)
   Ants(i).z# = rnd(ARENA_SIZE)-(ARENA_SIZE*0.5)
 
   Ants(i).cx# = rnd(ARENA_SIZE*0.5)-(ARENA_SIZE*0.25)
   Ants(i).cz# = rnd(ARENA_SIZE*0.5)-(ARENA_SIZE*0.25)
 
   Ants(i).angle# = atanfull(-Ants(i).x#, -Ants(i).z#)
 
   Ants(i).reproduce_progress# = 0.0
 
   make object triangle 100+i, -0.1, 0.0, 0.0,    0.0, 0.0, 0.25,    0.1, 0.0, 0.0
   position object 100+i, Ants(i).x#, 0.25, Ants(i).z#
   yrotate object 100+i, Ants(i).angle#
   set object light 100+i, 0
   texture object 100+i, 10
endfunction
 
 
function createAnt(i, x#, z#)
   Ants(i).x# = x#
   Ants(i).z# = z#
 
   Ants(i).cx# = rnd(ARENA_SIZE*0.5)-(ARENA_SIZE*0.25)
   Ants(i).cz# = rnd(ARENA_SIZE*0.5)-(ARENA_SIZE*0.25)
 
   Ants(i).angle# = atanfull(-Ants(i).x#, -Ants(i).z#)
 
   Ants(i).reproduce_progress# = 0.0
 
   make object triangle 100+i, -0.1, 0.0, 0.0,    0.0, 0.0, 0.25,    0.1, 0.0, 0.0
   position object 100+i, Ants(i).x#, 0.25, Ants(i).z#
   yrotate object 100+i, Ants(i).angle#
   set object light 100+i, 0
   texture object 100+i, 10
endfunction
 
function rgba(r as integer,g as integer,b as integer,a as integer)
  colour as dword
  colour = (b)+(g*256)+(r*65536)+(a*16777216)
endfunction colour