sync on sync rate 0 autocam off set display mode 1280, 1024, 32 set ambient light 0 randomize timer() color backdrop 0 `CONSTANTS GO HERE `constants for the stats panel #constant STATS_IMG_W 16 #constant STATS_IMG_H 48 #constant STATS_IMG_TRANSPARENCY_MASK_A 0x66FFFFFF #constant STATS_IMG_TRANSPARENCY_MASK_B 0x33FFFFFF `constant for enemy creation #constant ENEMY_WEAPON_SIZE 3.0 #constant CREATION_TIMER 5000 `Map generation constants #constant TEXTURE_SIZE 64 `Control Keys (NOT CURRENTLY USED, but usefull to keep ;-) hehe) #constant KeyW 17 #constant KeyA 30 #constant KeyS 31 #constant KeyD 32 `Player contants #constant TARGET_COLOR 0xFF0000 :`Used for the targetting blob #constant PLAYER_SPEED 3.0 #constant PLAYER_WEAPON_SIZE 5.0 `Create the stats panel temaplate... global STATS_IMG_SIZE STATS_IMG_SIZE = 12 + (STATS_IMG_W * STATS_IMG_H * 4) CREATE_STATS_PANEL_TEMPLATE() make memblock 1, 12 + (TEXTURE_SIZE * TEXTURE_SIZE * 4) write memblock dword 1, 0, TEXTURE_SIZE write memblock dword 1, 4, TEXTURE_SIZE write memblock dword 1, 8, 32 c as dword for x = 0 to TEXTURE_SIZE - 1 for y = 0 to TEXTURE_SIZE - 1 c = rgb(32, 128 + rnd(127), 32) write memblock dword 1, 12 + ((y*TEXTURE_SIZE)+x)*4, c next y next x make image from memblock 1, 1 delete memblock 1 `This is here so I can see the arguements easier :-) `function GENERATE_TERRAIN(obj, img, W, H, MAX_HEIGHT#, SMOOTHING_ITTERATIONS, SMOOTHING_FACTOR#, MAPSCALE#, USCALE#, VSCALE#) `Create the terrain GENERATE_TERRAIN(1, 1, 64, 64, 50.0, 4, 0.75, 4.0, 2.0, 2.0) position object 1, 0, 0, 0 `Create the player + Data Type Coord x# y# z# EndType Type PlayerData Pos as Coord moved as boolean Target as Coord Health# EndType `Create player details P as PlayerData P.Pos.x# = 10 P.Pos.z# = 10 P.Pos.y# = GET_CUSTOM_TERRAIN_HEIGHT(1, P.Pos.x#, P.Pos.z#) + object size y(1) * 0.5 P.Target.x# = P.Pos.x# + 0.0001 P.Target.z# = P.Pos.z# P.Health# = 41 `Start the player as moved - this is to make sure everything starts in the right place. P.moved = 1 `Create the player CREATE_CHARACTER(2, 0xCCCCDD, PLAYER_WEAPON_SIZE) `Position it position object 2, P.Pos.x#, P.Pos.y#, P.Pos.z# `Make health bar MAKE_HEALTH_BAR(2, int(P.Health#)) `Create a temporary vector for working out headings null = make vector2(1) `Target Object stuff make object sphere 3, 0.5 :`Target Object for when moving set object transparency 3, 3 color object 3, TARGET_COLOR a as DWORD CLICK_DIST# = 0.0 `Lighting set point light 0, 0, 0, 0 set light range 0, 40 `Enemy Data Stuff EnemyTimer = 0 Type EnemyData Pos as Coord TimeToLive# Health# EndType `Create the enemies Dim Enemies(5) as EnemyData for i = 0 to 5 `Create a new character, but with a smaller weapon.. Also comes in Yellow CREATE_CHARACTER(i+1000, rgb(255,255,0) && STATS_IMG_TRANSPARENCY_MASK_A, ENEMY_WEAPON_SIZE) Enemies(i).Health# = -1 `Hide the object until its needed... Excluding would be better - but it is bugged, so hiding it is! hide object i+1000 next u `This is used for calculating distances for firing from the enemy null = make vector3(2) global msg$ `Mouse Status mouseStatus = 0 frameTime# = 1.0 startTime = timer() do frameTime# = (frameTime# * 0.8) + ((timer() - startTime) * 0.2) startTime = timer() text 0,0, "FPS: " + str$(screen fps()) paste image 10, screen width() - TEXTURE_SIZE, 0 if mouseclick() = 1 AND mouseStatus = 0 P.moved = 1 mouseStatus = mouseclick() null = pick object(mousex(), mousey(), 1, 1) P.Target.x# = camera position x() + get pick vector x() P.Target.z# = camera position z() + get pick vector z() position object 3, P.Target.x#, GET_CUSTOM_TERRAIN_HEIGHT(1,P.Target.x#,P.Target.z#) + 0.25, P.Target.z# point object 2, object position x(3), object position y(3), object position z(3) set vector2 1, P.Target.x# - P.Pos.x#, P.Target.z# - P.Pos.z# CLICK_DIST# = length vector2(1)*1.5 a = 255 else if mouseclick() = 0 then mouseStatus = 0 endif if P.moved set vector2 1, P.Target.x# - P.Pos.x#, P.Target.z# - P.Pos.z# dist# = length vector2(1) if dist# < 0.1 then P.moved = 0 a = (dist# / CLICK_DIST#) * 255.0 color object 3, (a << 24) || TARGET_COLOR normalize vector2 1, 1 inc P.Pos.x#, x vector2(1) * frameTime# * 0.001 * PLAYER_SPEED inc P.Pos.z#, y vector2(1) * frameTime# * 0.001 * PLAYER_SPEED P.Pos.y# = GET_CUSTOM_TERRAIN_HEIGHT(1, P.Pos.x#, P.Pos.z#) + 0.5 position object 2, P.Pos.x#, P.Pos.y#, P.Pos.z# position light 0, P.Pos.x#, P.Pos.y# + 10, P.Pos.z# position camera P.Pos.x# + 10, P.Pos.y# + 10, P.Pos.z# + 10 point camera P.Pos.x#, P.Pos.y#, P.Pos.z# endif `Show player health. This If statement is just to make sure nothing bad happens if its not made yet... if image exist(2) paste image 2, object screen x(2), object screen y(2) - STATS_IMG_H, 1 endif if spacekey() then show limb 2,2 else hide limb 2,2 text 0, 20, "T: " + str$(timer() - EnemyTimer) if timer() - EnemyTimer > CREATION_TIMER then CREATE_ENEMY() : EnemyTimer = timer() gosub PROCESS_ENEMIES sync loop end PROCESS_ENEMIES: for obj = 1000 to 1005 if object visible(obj) enemyId = obj-1000 enemyImg = obj-900 point object obj, P.Pos.x#, P.Pos.y#, P.Pos.z# if Enemies(enemyId).TimeToLive# < 0.5 inc Enemies(enemyId).TimeToLive#, frameTime# * 0.001 else move object obj, frameTime# * 0.0005 endif position object obj, object position x(obj), GET_CUSTOM_TERRAIN_HEIGHT(1, object position x(obj), object position z(obj)) + Enemies(enemyId).TimeToLive#, object position z(obj) Enemies(enemyId).Pos.x# = object position x(obj) Enemies(enemyId).Pos.y# = object position y(obj) Enemies(enemyId).Pos.z# = object position z(obj) set vector3 2, Enemies(enemyId).Pos.x# - P.Pos.x#, Enemies(enemyId).Pos.y# - P.Pos.y#, Enemies(enemyId).Pos.z# - P.Pos.z# if length vector3(2) < ENEMY_WEAPON_SIZE+0.5 show limb obj,2 if object collision(obj, 2) dec P.Health#, frameTime# * 0.01 MAKE_HEALTH_BAR(2, int(P.Health#)) endif else hide limb obj, 2 endif if limb visible(2,2) AND object collision(2, obj) `If enemy hit, then rediuce its health dec Enemies(enemyId).Health#, frameTime# * 0.05 MAKE_HEALTH_BAR(enemyImg, int(Enemies(enemyId).Health#)) endif `If the image exists (which it should, we just made it) then paste it. This is mainly to avoid crashes if image exist(enemyImg) paste image enemyImg, object screen x(obj), object screen y(obj) - STATS_IMG_H, 1 endif `If the enemy is out of health - delete it if Enemies(enemyId).Health# <= 0 hide object obj inc P.Health#, 20.0 if P.Health# > 41 then P.Health# = 41 endif endif next obj return function CREATE_ENEMY() obj = 1000 while Enemies(obj-1000).Health# > 0 AND obj < 1005 : inc obj : endwhile if object exist(obj) show object obj `Create Image and array index for this enemy object enemyImg = obj - 900 enemyID = obj - 1000 `Create a random position for the enemy Enemies(enemyID).Pos.x# = rnd(5.0) Enemies(enemyID).Pos.z# = rnd(5.0) `If rnd(1) = 1 then position the object in the negative x/z direction, otherwise positive. `The static 5 is to make sure its a fair minimum distance from the player when spawned if rnd(1) then Enemies(enemyID).Pos.x# = -Enemies(enemyID).Pos.x# - 5.0 else inc Enemies(enemyID).Pos.x#, 5.0 if rnd(1) then Enemies(enemyID).Pos.z# = -Enemies(enemyID).Pos.z# - 5.0 else inc Enemies(enemyID).Pos.z#, 5.0 `This offsets the enemy so the random position above is relative to the player inc Enemies(enemyID).Pos.x#, P.Pos.x# inc Enemies(enemyID).Pos.z#, P.Pos.z# `Now we know exactly where the enemy is - we can work out how high up to put it Enemies(enemyId).Pos.y# = GET_CUSTOM_TERRAIN_HEIGHT(1, Enemies(enemyID).Pos.x#, Enemies(enemyID).Pos.z#) - 0.5 `Now we have all 3 coords, we can position and point. position object obj, Enemies(enemyID).Pos.x#, Enemies(enemyID).Pos.y#, Enemies(enemyID).Pos.z# point object obj, P.Pos.x#, P.Pos.y#, P.Pos.z# `TimeToLive# is the vertical offset. It starts at -1.0 as that puts it underground. `When its +0.5 then its above ground and can start heading for the player Enemies(enemyId).TimeToLive# = -1.0 `Starting health - might be a strange number, but it just makes the health bar easier ;-) Enemies(enemyId).Health# = 41.0 `Create the health bar MAKE_HEALTH_BAR(enemyImg, int(Enemies(enemyId).Health#)) endif endfunction function MAKE_HEALTH_BAR(img, health) `Create memblock if it doesn't exist if memblock exist(img) = 0 then make memblock img, STATS_IMG_SIZE `Copy in the template memblock image copy memblock 99, img, 0, 0, STATS_IMG_SIZE `Loop through the middle bar and write in the required bar pixels for x = 3 to 12 for y = 44-health to 44 write memblock dword img, 12 + ((y*STATS_IMG_W) + x)*4, rgb(255, 0, 0) && STATS_IMG_TRANSPARENCY_MASK_A next y next x `Turn it into an image :-) make image from memblock img, img endfunction function CREATE_CHARACTER(obj, c, weaponLength#) `Main body of character make object sphere obj, 1 `The nose - mainly so you know where you're going ;-) make object cone 10000, 1 `Scale the nose to make it more "nosey" scale object 10000, 50.0, 100.0, 50.0 `Turn it into a mesh so it can be added as a limb make mesh from object 10, 10000 `Add the mesh to the bodo object add limb obj, 1, 10 `rotate and offset it to put it in the right place rotate limb obj, 1, 90, 0, 0 offset limb obj, 1, 0.0, 0.0, 0.5 `Make the bar-o-spacekey make object cone 10001, 1 `Offset it so it pivots on its end offset limb 10001, 0, 0.0, 0.0, 0.5 `scale it up to make it a big bar-o-death scale object 10001, 100, 100, 100*weaponLength# `Rotate it so it points out front and is not a bar-o-suicide rotate limb 10001, 0, -90, 0, 0 `turn it into a mesh make mesh from object 11, 10001 `add that mesh to the player add limb obj, 2, 11 `hide the limb so we can fire when needed hide limb obj, 2 `Color the object in color object obj, c set object collision to polygons obj `cleanup delete object 10000 delete object 10001 delete mesh 10 delete mesh 11 endfunction function GET_CUSTOM_TERRAIN_HEIGHT(obj, x#, z#) height# = 1000.0 - intersect object(obj, x#, 1000, z#, x#, -1000, z#) endfunction height# function GENERATE_TERRAIN(obj, img, W, H, MAX_HEIGHT#, SMOOTHING_ITTERATIONS, SMOOTHING_FACTOR#, MAPSCALE#, USCALE#, VSCALE#) dim HEIGHTMAP#(W,H) dim NORMALS#(W,H,3) for i = 0 to W-1 for j = 0 to H-1 HEIGHTMAP#(i, j) = rnd(MAX_HEIGHT#) next j next i for iters = 0 to SMOOTHING_ITTERATIONS for i = 0 to W-1 : for j = 0 to H : HEIGHTMAP#(i, j) = (HEIGHTMAP#(i,j) * SMOOTHING_FACTOR#) + (HEIGHTMAP#(i+1,j) * (1.0-SMOOTHING_FACTOR#)) : next j : next i for i = W-1 to 0 step -1: for j = 0 to H : HEIGHTMAP#(i, j) = (HEIGHTMAP#(i,j) * SMOOTHING_FACTOR#) + (HEIGHTMAP#(i+1,j) * (1.0-SMOOTHING_FACTOR#)) : next j : next i for i = 0 to W : for j = 0 to H-1 : HEIGHTMAP#(i, j) = (HEIGHTMAP#(i,j) * SMOOTHING_FACTOR#) + (HEIGHTMAP#(i,j+1) * (1.0-SMOOTHING_FACTOR#)) : next j : next i for i = 0 to W : for j = H-1 to 0 step -1 : HEIGHTMAP#(i, j) = (HEIGHTMAP#(i,j) * SMOOTHING_FACTOR#) + (HEIGHTMAP#(i,j+1) * (1.0-SMOOTHING_FACTOR#)) : next j : next i next iters colValue = 255 / MAX_HEIGHT# make memblock 1, 12 + (W*H*4) write memblock dword 1, 0, W write memblock dword 1, 4, H write memblock dword 1, 8, 32 for i = 0 to W-1 for j = 0 to H-1 c = HEIGHTMAP#(i,j)*colValue write memblock dword 1, 12 + ((j*W)+i)*4, rgb(c,c,c) next j next i make image from memblock 10, 1 ` CALCULATE NORMALS for i = 1 to W-1 for j = 1 to H-1 null = make vector3(1) null = make vector3(2) null = make vector3(3) null = make vector3(4) null = make vector3(5) null = make vector3(6) null = make vector3(7) null = make vector3(8) null = make vector3(9) set vector3 1, MAPSCALE#, HEIGHTMAP#(i,j) - HEIGHTMAP#(i+1,j ), 0 set vector3 2, 0, HEIGHTMAP#(i,j) - HEIGHTMAP#(i ,j-1), -MAPSCALE# set vector3 3, -MAPSCALE#, HEIGHTMAP#(i,j) - HEIGHTMAP#(i-1,j ), 0 set vector3 4, 0, HEIGHTMAP#(i,j) - HEIGHTMAP#(i ,j+1), MAPSCALE# cross product vector3 5, 1, 2 cross product vector3 6, 2, 3 cross product vector3 7, 3, 4 cross product vector3 8, 4, 1 add vector3 9, 9, 5 add vector3 9, 9, 6 add vector3 9, 9, 7 add vector3 9, 9, 8 divide vector3 9, 4 normalize vector3 9, 9 NORMALS#(i,j,0) = x vector3(9) NORMALS#(i,j,1) = y vector3(9) NORMALS#(i,j,2) = z vector3(9) null = delete vector3(1) null = delete vector3(2) null = delete vector3(3) null = delete vector3(4) null = delete vector3(5) null = delete vector3(6) null = delete vector3(7) null = delete vector3(8) null = delete vector3(9) next j next i if memblock exist(1) then delete memblock 1 make memblock 1, 12 + (32 * 3 * 2 * W * H) write memblock dword 1,0,274 : `FVF FORMAT write memblock dword 1,4,32 : `SIZE PER VERT write memblock dword 1,8,W*H*2*3 : `VERT NO poly = 0 for i = 0 to W-1 for j = 0 to H-1 ` ** POLY 1 ** x = i : z = j : CREATE_MESH_ENTRY(1, 12 + (poly * 192) , (x - (W/2)) * MAPSCALE#, HEIGHTMAP#(x,z), (z - (H/2)) * MAPSCALE#, NORMALS#(x,z,0), NORMALS#(x,z,1), NORMALS#(x,z,2), 0.0 , 0.0 ) x = i : z = j+1 : CREATE_MESH_ENTRY(1, 12 + (poly * 192) + 32, (x - (W/2)) * MAPSCALE#, HEIGHTMAP#(x,z), (z - (H/2)) * MAPSCALE#, NORMALS#(x,z,0), NORMALS#(x,z,1), NORMALS#(x,z,2), 0.0 , VSCALE#) x = i+1 : z = j : CREATE_MESH_ENTRY(1, 12 + (poly * 192) + 64, (x - (W/2)) * MAPSCALE#, HEIGHTMAP#(x,z), (z - (H/2)) * MAPSCALE#, NORMALS#(x,z,0), NORMALS#(x,z,1), NORMALS#(x,z,2), USCALE#, 0.0 ) ` ** POLY 2 ** x = i+1 : z = j : CREATE_MESH_ENTRY(1, 12 + (poly * 192) + 96, (x - (W/2)) * MAPSCALE#, HEIGHTMAP#(x,z), (z - (H/2)) * MAPSCALE#, NORMALS#(x,z,0), NORMALS#(x,z,1), NORMALS#(x,z,2), USCALE#, 0.0 ) x = i : z = j+1 : CREATE_MESH_ENTRY(1, 12 + (poly * 192) + 128, (x - (W/2)) * MAPSCALE#, HEIGHTMAP#(x,z), (z - (H/2)) * MAPSCALE#, NORMALS#(x,z,0), NORMALS#(x,z,1), NORMALS#(x,z,2), 0.0 , VSCALE#) x = i+1 : z = j+1 : CREATE_MESH_ENTRY(1, 12 + (poly * 192) + 160, (x - (W/2)) * MAPSCALE#, HEIGHTMAP#(x,z), (z - (H/2)) * MAPSCALE#, NORMALS#(x,z,0), NORMALS#(x,z,1), NORMALS#(x,z,2), USCALE#, VSCALE#) inc poly next j next i make mesh from memblock 1, 1 if object exist(obj) = 1 then delete object obj make object obj, 1, img delete mesh 1 delete memblock 1 endfunction function CREATE_MESH_ENTRY(memblockNum, n, x#, y#, z#, nx#, ny#, nz#, u#, v#) write memblock float 1, n + 0, x# write memblock float 1, n + 4, y# write memblock float 1, n + 8, z# write memblock float 1, n + 12, nx# write memblock float 1, n + 16, ny# write memblock float 1, n + 20, nz# write memblock float 1, n + 24, u# write memblock float 1, n + 28, v# endfunction function CREATE_STATS_PANEL_TEMPLATE() `Create Stats Panel make memblock 99, STATS_IMG_SIZE write memblock dword 99, 0, STATS_IMG_W write memblock dword 99, 4, STATS_IMG_H write memblock dword 99, 8, 32 for x = 0 to STATS_IMG_W - 1 for y = 0 to STATS_IMG_H - 1 if x > 3 AND x < 12 AND y > 3 AND y < 44 write memblock dword 99, 12 + ((y*STATS_IMG_W) + x)*4, rgb(160, 160, 160) && STATS_IMG_TRANSPARENCY_MASK_B else write memblock dword 99, 12 + ((y*STATS_IMG_W) + x)*4, rgb(160, 160, 160) && STATS_IMG_TRANSPARENCY_MASK_A endif next y next x `TopLeft x = 0 : y = 0 : write memblock dword 99, 12 + ((y*STATS_IMG_W) + x)*4, 0 x = 1 : y = 0 : write memblock dword 99, 12 + ((y*STATS_IMG_W) + x)*4, 0 x = 0 : y = 1 : write memblock dword 99, 12 + ((y*STATS_IMG_W) + x)*4, 0 `TopRight x = STATS_IMG_W-1 : y = 0 : write memblock dword 99, 12 + ((y*STATS_IMG_W) + x)*4, 0 x = STATS_IMG_W-2 : y = 0 : write memblock dword 99, 12 + ((y*STATS_IMG_W) + x)*4, 0 x = STATS_IMG_W-1 : y = 1 : write memblock dword 99, 12 + ((y*STATS_IMG_W) + x)*4, 0 `BottomRight x = STATS_IMG_W-1 : y = STATS_IMG_H-1 : write memblock dword 99, 12 + ((y*STATS_IMG_W) + x)*4, 0 x = STATS_IMG_W-2 : y = STATS_IMG_H-1 : write memblock dword 99, 12 + ((y*STATS_IMG_W) + x)*4, 0 x = STATS_IMG_W-1 : y = STATS_IMG_H-2 : write memblock dword 99, 12 + ((y*STATS_IMG_W) + x)*4, 0 `BottomLeft x = 0 : y = STATS_IMG_H-1 : write memblock dword 99, 12 + ((y*STATS_IMG_W) + x)*4, 0 x = 1 : y = STATS_IMG_H-1 : write memblock dword 99, 12 + ((y*STATS_IMG_W) + x)*4, 0 x = 0 : y = STATS_IMG_H-2 : write memblock dword 99, 12 + ((y*STATS_IMG_W) + x)*4, 0 endfunction