local abs = math.abs local sort = table.sort local Q = require "scriptbank\\quatlib" local asteroid_radar_screenpos_x = 14.8 local asteroid_radar_screenpos_y = 65.4 local asteroid_radar_size = 1.3 -- amount to scale up by local asteroid_radar_range = {5000, 10000, 25000, 50000, 100000, 500000} local asteroid_radar_range_selected = 1 local asteroid_radar_sprites = {} local asteroid_elev_sprites = {} local asteroid_enemy_sprite = nil local enemy_level_sprite = nil local enemy_sprite_scale = 0 local enemy_sprite_offset = 0 local enemy_sprite_factor = 1 local enemy_sprite_factorInc = 0.1 local asteroid_fueler_sprite = nil local fueler_level_sprite = nil local fueler_sprite_scale = 0 local fueler_sprite_offset = 0 local fueler_sprite_factor = 1 local fueler_sprite_factInc = 0.05 local asteroid_radar_max_entries = 11 local asteroid_radar_key_pressed = false g_y_angle = 0 g_conj = {w = 1, x = 0, y = -0, z = 0} local asteroid_colours = { {r = 128, g = 0, b = 0}, {r = 128, g = 0, b = 128}, {r = 128, g = 128, b = 0}, {r = 0, g = 128, b = 0}, {r = 0, g = 128, b = 128}, {r = 64, g = 0, b = 128}, {r = 64, g = 128, b = 0}, {r = 128, g = 64, b = 0}, {r = 128, g = 0, b = 64}, {r = 0, g = 64, b = 128}, {r = 0, g = 128, b = 64} } function asteroid_radar_init(e) Include("quatlib.lua") local radarImageBlob = LoadImage ( "scriptbank\\images\\Asteroids Cockpit\\radar_blob.png" ) local radarImageBar = LoadImage ( "scriptbank\\images\\Asteroids Cockpit\\radar_bar.png" ) local xscale = (GetDeviceHeight()/GetDeviceWidth()) radar_back_sprite = CreateSprite(LoadImage ( "scriptbank\\images\\Asteroids Cockpit\\radar3.png" )) SetSpritePosition (radar_back_sprite, asteroid_radar_screenpos_x, asteroid_radar_screenpos_y); SetSpriteSize (radar_back_sprite, -1, 31 * asteroid_radar_size * xscale) SetSpriteDepth (radar_back_sprite, 99) for i = 1, asteroid_radar_max_entries do asteroid_radar_sprites[i] = CreateSprite(radarImageBlob) SetSpriteSize (asteroid_radar_sprites[i], 0.4 * asteroid_radar_size, -1) SetSpriteOffset(asteroid_radar_sprites[i], xscale * 0.2, -1) asteroid_elev_sprites[i] = CreateSprite(radarImageBar) SetSpriteOffset(asteroid_elev_sprites[i], xscale * 0.4, 0) end asteroid_enemy_sprite = CreateSprite(LoadImage ( "scriptbank\\images\\Asteroids Cockpit\\alienship.png" )) enemy_sprite_scale = 0.4 * asteroid_radar_size enemy_sprite_offset = enemy_sprite_scale / 2 SetSpriteSize (asteroid_enemy_sprite, enemy_sprite_scale, -1) SetSpriteOffset(asteroid_enemy_sprite, enemy_sprite_offset, -1) enemy_level_sprite = CreateSprite(radarImageBar) SetSpriteOffset(enemy_level_sprite, xscale * 0.4, 0) SetSpritePosition(asteroid_enemy_sprite, 200, 200) asteroid_fueler_sprite = CreateSprite(LoadImage ( "scriptbank\\images\\Asteroids Cockpit\\fuelship.png" )) fueler_sprite_scale = 0.4 * asteroid_radar_size fueler_sprite_offset = fueler_sprite_scale / 2 SetSpriteSize (asteroid_fueler_sprite, fueler_sprite_scale, -1) SetSpriteOffset(asteroid_fueler_sprite, fueler_sprite_offset, -1) fueler_level_sprite = CreateSprite(radarImageBar) SetSpriteOffset(fueler_level_sprite, xscale * 0.4, 0) end ----------------------------------------------------------- -- this useful function iterates a list in order defined -- -- by sort function or by key order if none given -- ----------------------------------------------------------- local function sort_pairs(list, order_given) -- collect the keys local keys = {} for k in pairs(list) do keys[#keys+1] = k end if order_given then sort(keys, function(a,b) return order_given(list, a, b) end) else sort(keys) end -- return the iterator function local i = 0 return function() i = i + 1 if keys[i] then return keys[i], list[keys[i]] end end end function asteroid_radar_main(e) local x, y = asteroid_radar_screenpos_x, asteroid_radar_screenpos_y local xscale = (GetDeviceHeight()/GetDeviceWidth()) local playerX, playerZ = g_PlayerPosX, g_PlayerPosZ local range = asteroid_radar_range[asteroid_radar_range_selected] local sprite_index = 0 local max_ents = asteroid_radar_max_entries local sprites = asteroid_radar_sprites local esprites = asteroid_elev_sprites local centreX, centreY = x + 4.8 * asteroid_radar_size, y + 8.5 * asteroid_radar_size; local Px, Py, Pz = g_PlayerPosX, g_PlayerPosY, g_PlayerPosZ local sorted_ast_list = {} local asteroid_list = {} local asteroid_in_range = false local numAsts = 0 for k,_ in pairs(g_asteroid) do local asts = g_asteroid[k] if asts.active then numAsts = numAsts + 1 local Dx, Dy, Dz = asts.x - Px, asts.y - Py, asts.z - Pz local sqdistance = Dx*Dx + Dy*Dy + Dz*Dz if sqdistance < range*range then -- within range so lets add it to the list sorted_ast_list[k] = sqdistance asteroid_list[k] = {x = Dx, y = Dy, z = Dz} asteroid_in_range = true end end end if not asteroid_in_range then if asteroid_radar_range_selected < #asteroid_radar_range then asteroid_radar_range_selected = asteroid_radar_range_selected + 1 else asteroid_radar_range_selected = 1 end for i = sprite_index + 1, max_ents do SetSpritePosition (sprites[i], 200, 200) SetSpritePosition (esprites[i], 200, 200) end return end local xr, yr, zr = Q.ToEuler(g_conj) -- sort on distance from player for k, sd in sort_pairs(sorted_ast_list, function(list,a,b) return list[a] < list[b] end) do -- check for asteroid/player collision --if sd < g_asteroid[k].size then -- g_player_hit = true -- return --end if (numAsts < max_ents and sprite_index < numAsts) or (numAsts > max_ents and sprite_index < max_ents) then sprite_index = sprite_index + 1 else break end local NX, NY, NZ = Rotate3D(asteroid_list[k].x, asteroid_list[k].y, asteroid_list[k].z, xr, yr, zr); SetSpritePosition (sprites[sprite_index], centreX + ((NX / range) * 10 * xscale), centreY - (NZ / range) * 10); local cols = asteroid_colours[sprite_index] SetSpriteColor (sprites[sprite_index], cols.r, cols.g, cols.b, 180) SetSpritePosition (esprites[sprite_index], centreX + (14 * xscale) + (sprite_index * xscale / 0.8), centreY + 0.2) SetSpriteSize (esprites[sprite_index], xscale * 0.8, abs(NY) / range * 10) SetSpriteColor (esprites[sprite_index], cols.r, cols.g, cols.b, 180) if NY > 0 then SetSpriteAngle (esprites[sprite_index], 180) else SetSpriteAngle (esprites[sprite_index], 0) end end for i = sprite_index + 1, max_ents do SetSpritePosition (sprites[i], 200, 200) SetSpritePosition (esprites[i], 200, 200) end local sx, sy, sz = getJumpShipPos() if sx ~= nil then -- we have an active enemy so lets display it on the radar if within range local Dx, Dy, Dz = sx - Px, sy - Py, sz - Pz local sqdistance = Dx*Dx + Dy*Dy + Dz*Dz if sqdistance < range*range then local NX, NY, NZ = Rotate3D(Dx, Dy, Dz, xr, yr, zr); SetSpriteSize (asteroid_enemy_sprite, enemy_sprite_scale * enemy_sprite_factor, -1) SetSpriteOffset(asteroid_enemy_sprite, enemy_sprite_offset * enemy_sprite_factor, -1) SetSpritePosition (asteroid_enemy_sprite, centreX + ((NX / range) * 10 * xscale), centreY - (NZ / range) * 10); SetSpritePosition (enemy_level_sprite, centreX + (13 * xscale), centreY + 0.2) SetSpriteSize (enemy_level_sprite, xscale, abs(NY) / range * 10) SetSpriteColor (enemy_level_sprite, 255, 255, 0, 180) if enemy_sprite_factorInc > 0 and enemy_sprite_factor > 2 or enemy_sprite_factorInc < 0 and enemy_sprite_factor < 1 then enemy_sprite_factorInc = -enemy_sprite_factorInc end enemy_sprite_factor = enemy_sprite_factor + enemy_sprite_factorInc else SetSpritePosition(asteroid_enemy_sprite, 200, 200) SetSpritePosition(enemy_level_sprite, 200, 200) end else SetSpritePosition(asteroid_enemy_sprite, 200, 200) SetSpritePosition(enemy_level_sprite, 200, 200) end sx, sy, sz = getFuelShipPos() if sx ~= nil then -- we have an refueler so lets display it on the radar if within range local Dx, Dy, Dz = sx - Px, sy - Py, sz - Pz local sqdistance = Dx*Dx + Dy*Dy + Dz*Dz if sqdistance < range*range then local NX, NY, NZ = Rotate3D(Dx, Dy, Dz, xr, yr, zr); SetSpriteSize (asteroid_fueler_sprite, fueler_sprite_scale * fueler_sprite_factor, -1) SetSpriteOffset(asteroid_fueler_sprite, fueler_sprite_offset * fueler_sprite_factor, -1) SetSpritePosition (asteroid_fueler_sprite, centreX + ((NX / range) * 10 * xscale), centreY - (NZ / range) * 10); SetSpritePosition (fueler_level_sprite, centreX + (29 * xscale), centreY + 0.2) SetSpriteSize (fueler_level_sprite, xscale, abs(NY) / range * 10) SetSpriteColor (fueler_level_sprite, 0, 128, 255, 180) if fueler_sprite_factInc > 0 and fueler_sprite_factor > 2 or fueler_sprite_factInc < 0 and fueler_sprite_factor < 1 then fueler_sprite_factInc = -fueler_sprite_factInc end fueler_sprite_factor = fueler_sprite_factor + fueler_sprite_factInc else SetSpritePosition(asteroid_fueler_sprite, 200, 200) SetSpritePosition(fueler_level_sprite, 200, 200) end else SetSpritePosition(asteroid_fueler_sprite, 200, 200) SetSpritePosition(fueler_level_sprite, 200, 200) end if g_KeyPressSHIFT == 1 and g_KeyPressE == 1 then if not asteroid_radar_key_pressed then asteroid_radar_key_pressed = true if asteroid_radar_range_selected < #asteroid_radar_range then asteroid_radar_range_selected = asteroid_radar_range_selected + 1 else asteroid_radar_range_selected = 1 end end else asteroid_radar_key_pressed = false end end