/* Created By EVWeb (Alex Wouters) Copyright 2011-2015 by Galactic Software LLC | All Rights Reserved */ // Display Main Menu var sd_make_main_menu = function() { sd_basic_clear(); sd_display_title(); var inner_list = document.createElement("ul"); inner_list.className = "menu_list"; inner_list.innerHTML = "
  • Demo Levels
  • "; inner_list.innerHTML += "
  • Options
  • "; inner_list.innerHTML += "
  • Credits
  • "; sd_show_window("Main Menu", inner_list, false); if( sd_g_vars.first_run == 1 ) sd_show_first_run_stuff(); }; // Display Credits function sd_show_credits() { var info = "Lead Developer: EVWeb (Alex Wouters)"; info += "
  • Assistant Designer: DarthK3v (Kevin McCormick-Kovacich)
  • "; info += "
  • Music: Dash Rantic (Jack Carlson)
  • "; info += "
  • Special Thanks To:"; info += "
    Patrick Cavanaugh - for helping me get started."; info += "
  • Engine: SD Engine 0.129 Alpha"; sd_show_detail(info, "Credits", true); } // Shows noob info function sd_show_first_run_stuff() { sd_g_vars.first_run = 0; var inner_list = document.createElement("ul"); inner_list.className = "inner_list"; inner_list.style.maxWidth = "600px"; var info = "
  • Welcome to Star Devastation
  • "; info += "
  • Before you get started we have one or two suggestions:
  • "; info += "
  • If SD is running slowly
    Try lowering the particle level to low, then try turning off moving background, then try turning off the graphical extras, and then as a last resort select very low for the particle level.
  • "; info += "
  • If SD is running smoothly
    You can try increasing the game screen size (up to 100% of window). Press F11 to enter fullscreen mode.
  • "; info += "
  • Also note, the menus may dip in fps for a while after initial loading as the game is processing game data in the background.
  • "; inner_list.innerHTML = info; inner_list.innerHTML += "
  • Done
  • "; sd_show_window("First Run", inner_list, true, "sd_close_window('First Run');", true); } function sd_show_detail(info, title, hide_others) { title = title || "More Info"; var inner_list = document.createElement("ul"); inner_list.className = "inner_list"; inner_list.style.maxWidth = "500px"; inner_list.innerHTML = "
  • " + info + "
  • "; inner_list.innerHTML += "
  • Back
  • "; sd_show_window(title, inner_list, hide_others, "sd_close_window('" + title + "');", true); } // Show the level list function sd_show_level_list() { var inner_list = document.createElement("ul"); var title = "Skirmish Levels"; var str_type = "Level"; var mult = 1; inner_list.className = "inner_list"; inner_list.style.minWidth = "700px"; var page_buttons = ""; page_buttons += ""; page_buttons += " 1 "; page_buttons += ""; var info = "
  • Search "; info += ""; info += "Select " + str_type + "" + page_buttons + "-
  • "; info += "
  • "; info += ""; info += ""; info += ""; var i; var tr_info; for (i = 0; i < sd_g_vars.levels.length; i++) { var j = i; tr_info = ""; if( i % 2 == 1 ) tr_info = "info='alt'"; info += ""; } for( i; i < sd_g_vars.list_items_per_page; i++ ) { tr_info = ""; if( i % 2 == 1 ) tr_info = "info='alt'"; info += ""; } info += "
    " + str_type + "Made ByUpdated
    " + sd_g_vars.levels[j][1]; info += "" + sd_g_vars.levels[j][4] + "" + sd_g_vars.levels[j][5] + "
    aaaa
    "; info += "" + page_buttons + "
  • "; inner_list.innerHTML += info; inner_list.innerHTML += "
  • Back
  • "; sd_show_window(title, inner_list, true, "sd_close_window('" + title + "');", false); } // Used to show the mod desciption function sd_show_level_desc(level_id) { var inner_list = document.createElement("ul"); var next_level = sd_g_vars.loaded_levels[sd_g_vars.next_level]; var title = sd_g_vars.levels[level_id][1] + " Info"; inner_list.className = "inner_list"; inner_list.style.maxWidth = "600px"; inner_list.style.minWidth = "600px"; var info = "
  • "; info += sd_g_vars.levels[level_id][3]; info += "
  • "; var id = sd_g_vars.levels[level_id][0]; info += "
  • Load Level
    "; info += "
    Back
  • "; inner_list.innerHTML = info; sd_show_window(title, inner_list, false, "sd_close_window('" + title + "');", true); } // Loads a level if needed, then moves onto the level options var sd_load_lvl_then_show_options = function(lvl_to_load) { sd_g_vars.ll_call_back = sd_show_level_options; sd_start_level_load(sd_g_vars.levels[lvl_to_load][1], sd_g_vars.levels[lvl_to_load][2], sd_g_vars.levels[lvl_to_load][3], sd_g_vars.levels[lvl_to_load][0]); }; // Used to choose various stuff about the level (ship, weapons, race, etc) // Currently just loads the level var sd_show_level_options = function() { var inner_list = document.createElement("ul"); var next_level = sd_g_vars.loaded_levels[sd_g_vars.next_level]; var i, j; sd_clear_loading(); var title = next_level.name; inner_list.className = "inner_list"; inner_list.style.minWidth = "400px"; var total_shown = 0; var total_human = 0; var human_id = -1; var p_shown = []; var p_ships = []; var p_human = []; for( i = 0; i < next_level.ships.length; i++ ) { next_level.ships[i].check_ship_hold_spawn(); if( next_level.ships[i].spawn === 0 ) { total_shown++; if( next_level.ships[i].human && p_human[next_level.ships[i].player.id] === undefined ) p_human[next_level.ships[i].player.id] = i; var add = true; for( j = 0; j < p_shown.length; j++ ) { if( p_shown[j] === next_level.ships[i].player ) { add = false; if( next_level.ships[i].customizable ) p_ships[j]++; break; } } if( add ) { p_shown.push(next_level.ships[i].player); p_ships.push( next_level.ships[i].customizable ? 1 : 0 ); } } } for( i = 0; i < p_human.length; i++ ) { if( p_human[i] !== undefined ) { total_human++; if( human_id === -1 ) human_id = p_human[i]; } } var info = "
  • "; info += ""; info += "
    "; if( human_id !== -1 && (total_human === 1 || !next_level.local_shp) ) next_level.local_shp = human_id; var h_name = "DEMO USER"; for( i = 0; i < p_shown.length; i++ ) { info += "
    4 && p_shown.length > 6) || (p_ships[i] > 8 && p_shown.length <= 6) ) info += "info='mini' "; info += "color='c" + p_shown[i].color + "'>"; info += "
    " + (h_name && next_level.local_shp && next_level.ships[next_level.local_shp].player === p_shown[i] ? h_name : p_shown[i].name) + "
    "; for( j = 0; j < p_shown[i].ships.length; j++ ) { var temp_shp = p_shown[i].ships[j]; if( temp_shp.spawn === 0 && temp_shp.customizable ) { info += "
    "; info += ""; info += "
    UNKOWN
    "; } info += "
    "; } info += "
    Level Options

    "; for( i = 0; i < next_level.options.length; i++ ) { info += "
    " + next_level.options[i].o_name + "
      "; for( j = 0; j < next_level.options[i].choices.length; j++ ) info += "
    • " + next_level.options[i].choices[j] + "
    • "; info += "

    "; } info += "
  • "; inner_list.innerHTML = info; inner_list.innerHTML += "
  • Start
    Back
  • "; sd_show_window(title, inner_list, true, "sd_close_window('Select Ship'); sd_close_window('" + title + "');", false); }; // Change an option choice on the level screen function sd_change_level_option_choice(option, choice) { var next_level = sd_g_vars.loaded_levels[sd_g_vars.next_level]; next_level.chosen_options[option] = choice; sd_show_level_options(); } // Show ship selection dialog function sd_show_ship_selection_dialog(ship_hold, level_setup, ship_at, weap_at) { var inner_list = document.createElement("ul"); var i, j, k; var title = "Select Ship"; inner_list.className = "inner_list"; inner_list.style.minWidth = "400px"; sd_g_vars.gui_object_link = ship_hold; ship_at = ship_at !== null || ship_at !== undefined ? ship_at : (ship_hold.is_random ? -1 : ship_hold.type.id); ship_at = ~~((ship_at + 1) / 5); weap_at = weap_at !== null || weap_at !== undefined ? weap_at : ship_hold.weap_choice; var info = "
  • "; var ships_list = ship_hold.types; var ship_ids = []; if( ship_hold.type_race && ship_hold.player.race !== -1 ) { ships_list = []; for( i = 0; i < ship_hold.types.length; i++ ) { if( ship_hold.types[i].race === ship_hold.player.race ) { ships_list.push(ship_hold.types[i]); ship_ids[ship_hold.type_ids[i]] = i; } } } else { for( i = 0; i < ship_hold.types.length; i++ ) ship_ids[ship_hold.type_ids[i]] = i; } ship_ids[-1] = -1; j = -1 + (ship_at * 5); info += "
    <
    "; for( k = j + 5; j < k; j++ ) { var name = ""; if( ships_list[j] && ships_list[j].icon_img ) { info += "
    "; } info += "
    = ships_list.length ? "disabled='disabled'" : "onclick='sd_switch_shiphold_ship(" + level_setup + ", " + ship_ids[ship_hold.type.id] + ", " + ((ship_at * 5) + 4) + ");'" ) + " style='top: 15px;'>>
    "; info += "
  • "; if( !ship_hold.is_random ) { info += "" + ship_hold.type.c_name + "
    " + ship_hold.type.desc; info += ""; info += ""; info += ""; info += "
    Max Velocity: " + (ship_hold.type.max_vel * 30) + "Shields: " + ship_hold.type.max_shield + "Armor: " + ship_hold.type.max_armor + "
    Acceleration: " + (ship_hold.type.accel * 900) + "Shield Recharge: " + (ship_hold.type.s_recharge * 30) + "Armor Recharge: " + (ship_hold.type.a_recharge * 30) + "
    Turn Rate: " + (~~((ship_hold.type.turn / Math.PI) * 30000) / 1000) + "
    "; } else { info += "Random Ship
    The game will randomly choose a ship from the ones available whenever this ship spawns (or respawns)"; } info += "
  • "; var weap_types = ship_hold.type.weap_types; var abil_types = ship_hold.type.abil_types; info += "
    3 ) info += " info='mini'"; info += ">
    Weapons and Abilities
    "; for( i = 0; i < weap_types.length; i++ ) { info += "

    " + temp_weap.desc; if( temp_weap.type === 0 ) { info += ""; info += ""; info += ""; info += "
    Damages: " + (temp_weap.damages) + "Fire Rate: " + (~~(((30 / temp_weap.fire_delay) * temp_weap.multi_fire) * 1000) / 1000) + "
    Range: " + temp_weap.max_dist + "Blast Radius: " + (temp_weap.blast_radius - 1) + "
    Ammo Type: " + (temp_weap.ammo_type.a_name) + "Ammo Usage: " + (temp_weap.ammo_usage) + "
    "; if( temp_weap.turn > 0 ) info += "Tracking, "; if( temp_weap.point_defense ) info += "Point Defense, "; else if( temp_weap.automated ) info += "Automatic, "; if( temp_weap.armor > 0 ) info += "Hitable, "; if( info[info.length - 2] == "," ) info = info.substr(0, info.length - 2); info += "
    "; } else { info += ""; info += ""; info += "
    Ship: " + (temp_weap.ship_type.c_name) + "Fire Rate: " + (~~(((30 / temp_weap.fire_delay) * temp_weap.multi_fire) * 1000) / 1000) + "
    Ammo Type: " + (temp_weap.ammo_type.a_name) + "Ammo Usage: " + (temp_weap.ammo_usage) + "
    Fighter Bay"; info += "
    "; } } info += "
  • "; if( level_setup ) info += "
    Back
    "; info += "
  • "; inner_list.innerHTML = info; sd_show_window(title, inner_list, false, "sd_close_window('" + title + "');", true); } // Switch shiphold ship function sd_switch_shiphold_ship(level_setup, id, ship_at) { id = sd_check_valid_range(id, -1, sd_g_vars.gui_object_link.types.length, -1, true); var temp = sd_g_vars.gui_object_link; if( id !== -1 && (temp.player.race === temp.types[id].race || temp.player.race === -1 || !temp.types[id].type_race) ) { temp.type = temp.types[id]; temp.is_random = false; } else if( id === -1 ) { temp.is_random = true; temp.type = temp.types[0]; temp.check_ship_hold_race(); } sd_show_level_options(); sd_show_ship_selection_dialog(temp, level_setup, ship_at); } // Switch shiphold weap /*function sd_switch_shiphold_weap(level_setup, id, ship_at) { var temp = sd_g_vars.gui_object_link; id = sd_check_valid_range(id, -1, temp.type.weap_types.length, -1, true); temp.weap_choice = id; sd_show_level_options(); sd_show_ship_selection_dialog(temp, level_setup, ship_at); }*/ // Switch human player function sd_switch_human_player(ship_at, weap_at) { var ship_hold = sd_g_vars.gui_object_link; if( ship_hold.human ) return; sd_close_window("Select Ship"); next_level.local_shp = ship_hold.id; sd_show_level_options(); sd_show_ship_selection_dialog(ship_hold, true, ship_at, weap_at); } // Show after endscreen function sd_show_endscreen() { var inner_list = document.createElement("ul"); var title = "End Game"; inner_list.className = "inner_list"; inner_list.style.minWidth = "500px"; var info = "
  • " + (sd_g_vars.local_player.victory ? "Victory" : "Defeat") + "
  • "; info += "
  • Stats
    "; info += "Total Time: " + ~~(sd_g_vars.tick / 30) + " seconds

    "; info += "Kills: " + sd_g_vars.local_kills + "
    "; info += "Deaths: " + sd_g_vars.local_deaths + "

    "; info += "Team Kills: " + sd_g_vars.local_player.kills + "
    "; info += "Team Deaths: " + sd_g_vars.local_player.deaths + "
    "; info += "
  • "; inner_list.innerHTML = info; var lvl_id = 0; for( i = 0; i < sd_g_vars.levels.length; i++ ) { if( sd_cur_level.id === sd_g_vars.levels[0] ) { lvl_id = i; break; } } inner_list.innerHTML += "
  • Replay
    Back
  • "; sd_show_window(title, inner_list, true, "sd_close_window('" + title + "');", true); } // Show Options Screen/Menu function sd_show_options() { var inner_list = document.createElement("ul"); inner_list.className = "menu_list"; inner_list.innerHTML = "
  • Graphics
  • "; inner_list.innerHTML += "
  • Audio
  • "; inner_list.innerHTML += "
  • Controls
  • "; inner_list.innerHTML += "
  • Back
  • "; sd_show_window("Options", inner_list, true); } function sd_show_select(event) { var parent = event.srcElement; if( sd_g_vars.browser == "ff" ) parent = event.target; var ele = parent.lastChild; if( parent == sd_g_vars.cur_select && sd_g_vars.select_last_clicked >= Number(new Date()) - 150 ) return; sd_g_vars.cur_select = parent; ele.style.visibility = "visible"; parent.setAttribute("selected","selected"); parent.onclick = null; document.onmousedown = sd_hide_select; // set key listeners } function sd_hide_select() { var parent = sd_g_vars.cur_select; var ele = parent.lastChild; ele.style.visibility = "hidden"; parent.setAttribute("selected",""); sd_g_vars.select_last_clicked = Number(new Date()); document.onmousedown = null; parent.onclick = sd_show_select; } // Show Sound Options function sd_show_sound_options() { var inner_list = document.createElement("ul"); var title = "Audio Options"; inner_list.className = "inner_list"; inner_list.style.minWidth = "500px"; var info = "
  • Music Volume
    "; var minus = "
    <
    "; if( sd_g_vars.music_level <= 0.05 ) minus = "
    <
    "; var plus = "
    >
    "; if( sd_g_vars.music_level > 0.95 ) plus = "
    >
    "; info += "
    " + minus + "
    " + (~~((sd_g_vars.music_level * 10) + 0.5)) + "
    " + plus + "
    "; info += "
  • "; info += "
  • SoundFx Volume
    "; minus = "
    <
    "; if( sd_g_vars.snd_fx_level <= 0.05 ) minus = "
    <
    "; plus = "
    >
    "; if( sd_g_vars.snd_fx_level > 0.95 ) plus = "
    >
    "; info += "
    " + minus + "
    " + (~~((sd_g_vars.snd_fx_level * 10) + 0.5)) + "
    " + plus + "
    "; info += "
  • "; info += "
  • Max Channels
    "; minus = "
    <
    "; if( sd_g_vars.max_channels <= 16 ) minus = "
    <
    "; plus = "
    >
    "; if( sd_g_vars.max_channels >= 64 ) plus = "
    >
    "; info += "
    " + minus + "
    " + (~~sd_g_vars.max_channels) + "
    " + plus + "
    "; info += "
  • "; inner_list.innerHTML = "
  • Click option name for more info
  • "; inner_list.innerHTML += info; inner_list.innerHTML += "
  • Accept
    Reset
  • "; sd_show_window(title, inner_list, true, "sd_close_window('Help'); sd_close_window('" + title + "');", true); } // Set Sound Options function sd_change_sound_option(id, value) { value = Number(value); if( isNaN(value) ) return; switch (id) { case 0: if( value > 1 ) value = 1; else if( value < 0 ) value = 0; sd_g_vars.snd_fx_level = value; localStorage.setItem("snd_fx_level", value); sd_update_sound_volume(); break; case 1: if( value > 1 ) value = 1; else if( value < 0 ) value = 0; sd_g_vars.music_level = value; localStorage.setItem("music_level", value); sd_update_sound_volume(); break; case 2: var old_max = sd_g_vars.max_channels; if( value < 16 ) value = 16; else if( value > 64 ) value = 64; sd_g_vars.max_channels = value; localStorage.setItem("max_channels", value); var diff = ~~((sd_g_vars.max_channels - old_max) / 16); sd_g_vars.all_sounds += diff * 4; sd_g_vars.explode_sounds += diff * 4; sd_g_vars.weap_fire_sounds += diff * 4; sd_g_vars.shield_sounds += diff; sd_g_vars.special_sounds += diff; sd_g_vars.thrust_sounds += diff; break; } sd_show_sound_options(); } // Reset Sound Options function sd_clear_sound() { var old_max = sd_g_vars.max_channels; sd_g_vars.snd_fx_level = 0.5; sd_g_vars.music_level = 0.5; sd_g_vars.max_channels = 16; var diff = ~~((sd_g_vars.max_channels - old_max) / 16); sd_g_vars.all_sounds += diff * 4; sd_g_vars.explode_sounds += diff * 4; sd_g_vars.weap_fire_sounds += diff * 4; sd_g_vars.shield_sounds += diff; sd_g_vars.special_sounds += diff; sd_g_vars.thrust_sounds += diff; sd_update_sound_volume(); localStorage.removeItem("snd_fx_level"); localStorage.removeItem("music_level"); localStorage.removeItem("max_channels"); sd_show_sound_options(); } // Show Graphics Options function sd_show_graphics_options() { var inner_list = document.createElement("ul"); var title = "Graphics Options"; inner_list.className = "inner_list"; inner_list.style.minWidth = "500px"; var info = "
  • Graphics Renderer
    "; var temp_setting = "Canvas"; if( sd_g_vars.web_gl == 1 ) temp_setting = "WebGL"; if( true || sd_g_vars.paused ) info += "
    " + temp_setting + "
    "; info += "
  • "; info += "
  • Screen Width
    "; var minus = "
    <
    "; if( sd_g_vars.res_width_per <= 0.05 ) minus = "
    <
    "; var plus = "
    >
    "; if( sd_g_vars.res_width_per > 0.95 ) plus = "
    >
    "; info += "
    " + minus + "
    " + (~~((sd_g_vars.res_width_per * 10) + 0.5) * 10) + "%
    " + plus + "
    "; info += "
  • "; info += "
  • Screen Height
    "; minus = "
    <
    "; if( sd_g_vars.res_height_per <= 0.05 ) minus = "
    <
    "; plus = "
    >
    "; if( sd_g_vars.res_height_per > 0.95 ) plus = "
    >
    "; info += "
    " + minus + "
    " + (~~((sd_g_vars.res_height_per * 10) + 0.5) * 10) + "%
    " + plus + "
    "; info += "
  • "; info += "
  • Max Shots
    "; minus = "
    <
    "; if( sd_g_vars.max_shots_on_screen <= 250 ) minus = "
    <
    "; plus = "
    >
    "; if( sd_g_vars.max_shots_on_screen >= 4000 ) plus = "
    >
    "; info += "
    " + minus + "
    " + (~~sd_g_vars.max_shots_on_screen) + "
    " + plus + "
    "; info += "
  • "; info += "
  • Particle Level
    "; temp_setting = "Very Low"; if( sd_g_vars.particle_level == 1 ) temp_setting = "High"; else if( sd_g_vars.particle_level == 0.6 ) temp_setting = "Medium"; else if( sd_g_vars.particle_level == 0.3 ) temp_setting = "Low"; info += "
    " + temp_setting; info += "
    "; info += "
  • "; info += "
  • Graphical Extras
    "; temp_setting = "Off"; if( sd_g_vars.graphical_extras == 1 ) temp_setting = "On"; info += "
    " + temp_setting; info += "
    "; info += "
  • "; info += "
  • Framerate Cap
    "; temp_setting = "60"; if( sd_g_vars.fps_capped == 1 ) temp_setting = "30"; info += "
    " + temp_setting; info += "
    "; info += "
  • "; inner_list.innerHTML = "
  • Click option name for more info
  • "; inner_list.innerHTML += info; inner_list.innerHTML += "
  • Accept
    Reset
  • "; sd_show_window(title, inner_list, true, "sd_close_window('Help'); sd_close_window('" + title + "');", true); } // Set Graphics Options function sd_change_graphics_option(id, value) { value = Number(value); if( isNaN(value) ) return; switch (id) { case 0: if( value > 1 ) value = 1; else if( value < 0.1 ) value = 0.1; sd_g_vars.particle_level = value; localStorage.setItem("particle_level", value); sd_update_particle_rates(); break; case 1: if( value > 1 ) value = 1; else if( value < 0 ) value = 0; sd_g_vars.res_width_per = value; localStorage.setItem("res_width_per", value); sd_change_resolution(); break; case 2: if( value > 1 ) value = 1; else if( value < 0 ) value = 0; sd_g_vars.res_height_per = value; localStorage.setItem("res_height_per", value); sd_change_resolution(); break; case 4: if( value > 0.5 ) value = 1; else value = 0; sd_g_vars.web_gl = value; localStorage.setItem("web_gl", value); break; case 5: if( value > 0.5 ) value = 1; else value = 0; sd_g_vars.fps_capped = value; localStorage.setItem("fps_capped", value); break; case 6: if( value > 0.5 ) value = 1; else value = 0; sd_g_vars.graphical_extras = value; localStorage.setItem("graphical_extras", value); break; case 8: if( value > 4000 ) value = 4000; else if( value < 250 ) value = 250; sd_g_vars.max_shots_on_screen = value; localStorage.setItem("max_shots_on_screen", value); break; } sd_show_graphics_options(); if( id === 6 ) sd_graphics_change_process(); } // Process extra stuff var sd_graphics_change_process = function() { clearTimeout(sd_g_vars.looper); var temp = sd_g_vars.frames_needing_processing; sd_g_vars.frames_needing_processing = sd_g_vars.frames_storage; var tot_time = Number(new Date()); var go_next = (sd_g_vars.tick_rate * 2); var k; sd_process_frames(go_next, tot_time, go_next, true); sd_g_vars.frames_storage = sd_g_vars.frames_needing_processing; sd_g_vars.frames_needing_processing = temp; if( sd_g_vars.frames_needing_processing.length > 0 ) { sd_g_vars.looper = setTimeout(sd_graphics_change_process, 1); return; } sd_clear_loading(); sd_g_vars.looper = setTimeout(sd_core_loop, 0); }; // Reset Graphics Options function sd_clear_graphics() { sd_g_vars.particle_level = 0.6; sd_update_particle_rates(); sd_g_vars.res_width_per = 0; sd_g_vars.res_height_per = 0; sd_g_vars.res_width = 1024; sd_g_vars.res_height = 640; sd_g_vars.web_gl = 0; sd_g_vars.graphical_extras = 1; sd_g_vars.max_shots_on_screen = 1000; sd_g_vars.fps_capped = 0; sd_change_resolution(); localStorage.removeItem("particle_level"); localStorage.removeItem("res_width_per"); localStorage.removeItem("res_height_per"); localStorage.removeItem("web_gl"); localStorage.removeItem("graphical_extras"); localStorage.removeItem("max_shots_on_screen"); localStorage.removeItem("fps_capped"); sd_show_graphics_options(); sd_graphics_change_process(); } // Check window size change var sd_detect_window_change = function() { if (sd_g_vars.is_playing) { sd_g_vars.res_changed_during_game = true; return; } sd_change_resolution(); }; // Change resolution function sd_change_resolution() { var old_w = sd_g_vars.res_width; var old_h = sd_g_vars.res_height; var temp_h = window.innerHeight; if (temp_h < 640) temp_h = 640; document.body.setAttribute("style", "height: " + temp_h + "px; min-height: " + temp_h + "px;"); sd_g_vars.res_width = 1024; if (window.innerWidth > 1024) sd_g_vars.res_width += (window.innerWidth - 1024) * sd_g_vars.res_width_per; sd_g_vars.res_width = ~~sd_g_vars.res_width; if (sd_g_vars.res_width % 2 == 1) sd_g_vars.res_width--; sd_g_vars.res_height = 640; if (window.innerHeight > 640) sd_g_vars.res_height += (window.innerHeight - 640) * sd_g_vars.res_height_per; sd_g_vars.res_height = ~~sd_g_vars.res_height; if (sd_g_vars.res_height % 2 == 1) sd_g_vars.res_height--; sd_g_vars.res_half_w = sd_g_vars.res_width / 2; sd_g_vars.res_half_h = sd_g_vars.res_height / 2; sd_g_vars.bg_part_res_rate = (sd_g_vars.res_width / 1024) * (sd_g_vars.res_height / 640); if (sd_g_vars.bg_particles.length > 0) { sd_g_vars.bg_particles = []; for (i = 0; i < sd_cur_level.bg_particle_types_all.length; i++) { // add in background particles sd_bg_particle_gen(sd_cur_level.bg_particle_types_all[i]); } } document.getElementById("sddiv").style.maxWidth = sd_g_vars.res_width + "px"; document.getElementById("sddiv").style.width = sd_g_vars.res_width + "px"; document.getElementById("sddiv").style.height = sd_g_vars.res_height + "px"; document.getElementById("sddiv").style.minHeight = sd_g_vars.res_height + "px"; document.getElementById("sddiv").style.margin = ((window.innerHeight - sd_g_vars.res_height) / 2) + "px auto"; var temp_eles = ["high_objs", "low_gui", "high_gui", "guidiv"]; for (sch = 0; sch < temp_eles.length; sch++) { var temp_ele = document.getElementById(temp_eles[sch]); temp_ele.setAttribute("style", "width: " + sd_g_vars.res_width + "px; height: " + sd_g_vars.res_height + "px;"); temp_ele.width = sd_g_vars.res_width; temp_ele.height = sd_g_vars.res_height; } sd_g_vars.cam_last_x += 1000; sd_g_vars.cam_last_y += 1000; var x = (sd_g_vars.res_width - old_w) / 2; var y = (sd_g_vars.res_height - old_h) / 2; var gui_div = document.getElementById("guidiv"); var i = 0; for (i = 0; i < gui_div.childNodes.length; i++) { var temp_ele = gui_div.childNodes[i]; var temp_top = temp_ele.style.top; var temp_left = temp_ele.style.left; temp_top = Number(temp_top.substr(0, temp_top.length - 2)); temp_left = Number(temp_left.substr(0, temp_left.length - 2)); temp_ele.style.left = (temp_left + x) + "px"; temp_ele.style.top = (temp_top + y) + "px"; } for(i = 0; i < sd_g_vars.menu_anis.length; i++) { var temp = sd_g_vars.menu_anis[i].linked; temp.x = -sd_g_vars.res_half_w + 175; temp.y = sd_g_vars.res_half_h - 175; temp.x_rad_low = temp.x - temp.radius; temp.x_rad_hi = temp.x + temp.radius; temp.y_rad_low = temp.y - temp.radius; temp.y_rad_hi = temp.y + temp.radius; } if (sd_g_vars.gui_context) sd_display_title(); if (sd_g_vars.paused && sd_g_vars.show_hud && sd_g_vars.local_shp) { sd_draw_hud_bg(); sd_draw_hud(); } } // Show Key Options function sd_show_key_options() { var inner_list = document.createElement("ul"); var title = "Key Controls"; inner_list.className = "inner_list"; inner_list.style.minWidth = "500px"; var info = "
  • Accelerate
    "; var temp_setting = sd_g_vars.key_names[sd_g_vars.accel_key]; info += "
    " + temp_setting + "
  • "; info += "
  • Turn Left
    "; temp_setting = sd_g_vars.key_names[sd_g_vars.left_key]; info += "
    " + temp_setting + "
  • "; info += "
  • Turn Right
    "; temp_setting = sd_g_vars.key_names[sd_g_vars.right_key]; info += "
  • "; info += "
  • Fire Weapon 1
    "; temp_setting = sd_g_vars.key_names[sd_g_vars.fire_1_key]; info += "
  • "; info += "
  • Fire Weapon 2
    "; temp_setting = sd_g_vars.key_names[sd_g_vars.fire_2_key]; info += "
  • "; info += "
  • Cycle Weapon 2
    "; temp_setting = sd_g_vars.key_names[sd_g_vars.fire_3_key]; info += "
  • "; info += "
  • Closest Enemy
    "; temp_setting = sd_g_vars.key_names[sd_g_vars.cls_target_key]; info += "
  • "; info += "
  • Cycle Target
    "; temp_setting = sd_g_vars.key_names[sd_g_vars.change_target_key]; info += "
  • "; info += "
  • Trigger Event
    "; temp_setting = sd_g_vars.key_names[sd_g_vars.trigger_key]; info += "
  • "; inner_list.innerHTML = "
  • Click on key to change, then press new key, or escape to cancel
  • "; inner_list.innerHTML += info; inner_list.innerHTML += "
  • Accept
    Reset
  • "; sd_show_window(title, inner_list, true, "sd_close_window('Help'); sd_close_window('" + title + "');", true); } // Undo key changes function sd_clear_keys() { sd_g_vars.left_key = 37; // Left Arrow sd_g_vars.right_key = 39; // Right Arrow sd_g_vars.accel_key = 38; // Up Arrow sd_g_vars.fire_1_key = 90; // Z sd_g_vars.fire_2_key = 88; // X sd_g_vars.fire_3_key = 67; // C sd_g_vars.cls_target_key = 32; // Space sd_g_vars.change_target_key = 81; // Q sd_g_vars.trigger_key = 13; // Return localStorage.removeItem("left_key"); localStorage.removeItem("right_key"); localStorage.removeItem("accel_key"); localStorage.removeItem("fire_1_key"); localStorage.removeItem("fire_2_key"); localStorage.removeItem("fire_3_key"); localStorage.removeItem("cls_target_key"); localStorage.removeItem("change_target_key"); localStorage.removeItem("trigger_key"); sd_g_vars.key_element_c = -1; sd_show_key_options(); } // Prepare to change key function sd_change_key(event, key_to_change) { var element = event.srcElement; if( sd_g_vars.browser == "ff" ) element = event.target; sd_g_vars.key_changing = key_to_change; element.setAttribute("type", "selected"); element.innerHTML = "<Press Key>"; document.onkeydown = sd_key_change_temp; } // Temporary key change var sd_key_change_temp = function(e) { if (typeof(e.keyCode) == 'number') { //DOM e = e.keyCode; } else if (typeof(e.charCode) == 'number') { //also NS 6+, Mozilla 0.9+ e = e.charCode; } e = sd_check_valid_key(e, -1); document.onkeydown = null; key_to_change = sd_g_vars.key_changing; if (e == 27) // cancel changing key key_to_change = -1; var str = null; switch (key_to_change) { case 0: sd_g_vars.left_key = e; str = "left_key"; break; case 1: sd_g_vars.right_key = e; str = "right_key"; break; case 2: sd_g_vars.accel_key = e; str = "accel_key"; break; case 4: sd_g_vars.fire_1_key = e; str = "fire_1_key"; break; case 5: sd_g_vars.fire_2_key = e; str = "fire_2_key"; break; case 6: sd_g_vars.fire_3_key = e; str = "fire_3_key"; break; case 7: sd_g_vars.cls_target_key = e; str = "cls_target_key"; break; case 8: sd_g_vars.change_target_key = e; str = "change_target_key"; break; case 9: sd_g_vars.trigger_key = e; str = "trigger_key"; break; } if( str ) localStorage.setItem(str, e); sd_show_key_options(); }; // Clear Menu Space function sd_clear_menu() { //sd_g_vars.low_context.clearRect(0, 0, sd_g_vars.res_width, sd_g_vars.res_height); //sd_g_vars.mid_context.clearRect(0, 0, sd_g_vars.res_width, sd_g_vars.res_height); sd_g_vars.high_context.clearRect(0, 0, sd_g_vars.res_width, sd_g_vars.res_height); sd_g_vars.gui_context.clearRect(0, 0, sd_g_vars.res_width, sd_g_vars.res_height); sd_g_vars.text_context.clearRect(0, 0, sd_g_vars.res_width, sd_g_vars.res_height); sd_g_vars.gui_context.fillStyle = "rgba(0, 0, 0, 0.25)"; sd_g_vars.gui_context.fillRect(0, 0, sd_g_vars.res_width, sd_g_vars.res_height); sd_remove_elements(); } // Clear only basic stuff, used for switching between menus function sd_basic_clear() { sd_g_vars.gui_context.clearRect(0, 0, sd_g_vars.res_width, sd_g_vars.res_height); sd_g_vars.text_context.clearRect(0, 0, sd_g_vars.res_width, sd_g_vars.res_height); //sd_g_vars.gui_context.fillStyle = "rgba(0, 0, 0, 0.25)"; //sd_g_vars.gui_context.fillRect(0, 0, sd_g_vars.res_width, sd_g_vars.res_height); if( sd_cur_level === sd_g_vars.demo_level ) sd_display_title(); } // Remove Div Elements Used In the Menus function sd_remove_elements() { if (sd_g_vars.gui_div.hasChildNodes()) { while (sd_g_vars.gui_div.childNodes.length >= 1) sd_g_vars.gui_div.removeChild(sd_g_vars.gui_div.firstChild); // remove all dom elements } } // Remove highest 'window', show next lower one function sd_close_window(win_to_close, keep_hidden) { var win_close = document.getElementById(win_to_close); if (win_close) { while (win_close.hasChildNodes()) win_close.removeChild(win_close.firstChild); // remove all dom elements sd_g_vars.gui_div.removeChild(win_close); // remove all dom elements } if (sd_g_vars.gui_div.hasChildNodes() && !keep_hidden) sd_g_vars.gui_div.lastChild.style.visibility = 'visible'; sd_display_title(); } // Remove all 'windows' except the listed ones function sd_close_all_windows_except(wins_to_keep) { var i, j, can_del; for( i = 0; sd_g_vars.gui_div.hasChildNodes() && i < sd_g_vars.gui_div.childNodes.length; i++ ) { can_del = true; for( j = 0; j < wins_to_keep.length; j++ ) { if( sd_g_vars.gui_div.childNodes[i].id === wins_to_keep[j] ) { can_del = false; break; } } if( can_del ) { var win_close = sd_g_vars.gui_div.childNodes[i]; while (win_close.hasChildNodes()) win_close.removeChild(win_close.firstChild); // remove all dom elements sd_g_vars.gui_div.removeChild(win_close); // remove all dom elements i--; } } if (sd_g_vars.gui_div.hasChildNodes()) sd_g_vars.gui_div.lastChild.style.visibility = 'visible'; sd_display_title(); } function sd_close_open_windows() { var i; for(i = 0; i < sd_g_vars.gui_div.childNodes.length; i++) { var win_close = sd_g_vars.gui_div.childNodes[i]; if (win_close && win_close.style.visibility == 'visible') { while (win_close.hasChildNodes()) win_close.removeChild(win_close.firstChild); // remove all dom elements sd_g_vars.gui_div.removeChild(win_close); // remove all dom elements i--; } } if (sd_g_vars.gui_div.hasChildNodes()) sd_g_vars.gui_div.lastChild.style.visibility = 'visible'; //sd_g_vars.gui_context.clearRect(0, 0, sd_g_vars.res_width, sd_g_vars.res_height); //sd_g_vars.gui_context.fillStyle = "rgba(0, 0, 0, 0.25)"; //sd_g_vars.gui_context.fillRect(0, 0, sd_g_vars.res_width, sd_g_vars.res_height); sd_display_title(); } // Move Window function sd_move_window(event, win_to_move) { sd_g_vars.win_moving = document.getElementById(win_to_move); var left = sd_g_vars.win_moving.style.left; left = Number(left.substr(0, left.length - 2)); var top = sd_g_vars.win_moving.style.top; top = Number(top.substr(0, top.length - 2)); sd_g_vars.win_move_m_start = [event.clientX, event.clientY]; // start location of mouse sd_g_vars.win_move_w_start = [left, top]; // start location of window document.onmouseup = sd_mouse_up; document.onmousemove = sd_mouse_move; sd_raise_window(win_to_move); } // Raise Window function sd_raise_window(win_to_move) { var temp_up = document.getElementById(win_to_move); sd_g_vars.gui_div.removeChild(temp_up); sd_g_vars.gui_div.appendChild(temp_up); } // Move Window or Scroll var sd_mouse_move = function(e) { if( sd_g_vars.win_moving ) { sd_g_vars.win_moving.style.left = (e.clientX - sd_g_vars.win_move_m_start[0] + sd_g_vars.win_move_w_start[0]) + "px"; sd_g_vars.win_moving.style.top = (e.clientY - sd_g_vars.win_move_m_start[1] + sd_g_vars.win_move_w_start[1]) + "px"; } }; // Stop Moving a Window var sd_mouse_up = function(e) { sd_g_vars.win_moving = null; document.onmouseup = null; document.onmousemove = null; }; // Create top effect using canvas, may switch to images function sd_create_title_bar(title, width, context, is_menu) { context.font = "bold 18px sans-serif"; context.textAlign = "center"; // make it display near the side context.textBaseline = "middle"; var left = 0; var top = 0; var mid = left + (width * 0.5); width = width + 4; var mid_width = (context.measureText(title).width / 2); // DRAW METAL AREA ----------------------------- context.save(); context.beginPath(); context.moveTo(0 + left, 0 + top); context.lineTo(width, 0 + top); if( !is_menu ) { context.lineTo(width, 30 + top); context.lineTo(width - 20, 30 + top); context.lineTo(width - 40, 20 + top); } else context.lineTo(width, 20 + top); context.lineTo(mid + mid_width + 20, 20 + top); context.lineTo(mid + mid_width, 30 + top); context.lineTo(mid - mid_width, 30 + top); context.lineTo(mid - mid_width - 20, 20 + top); if( !is_menu ) { context.lineTo(40 + left, 20 + top); context.lineTo(20 + left, 30 + top); context.lineTo(0 + left, 30 + top); } else context.lineTo(0 + left, 20 + top); context.clip(); context.fillStyle = sd_g_vars.menu_patterns[1]; // draw the metal context.fillRect(left, top, width, 30); var text = sd_g_vars.gui_context.createLinearGradient(0, top, 0, top + 30); // add some grad to the metal text.addColorStop(0, "rgba(160, 160, 160, 0.1)"); text.addColorStop(0.2, "rgba(80, 80, 80, 0.1)"); text.addColorStop(1, "rgba(30, 30, 30, 0.1)"); context.fillStyle = text; context.fillRect(left, top, width, 30); text = sd_g_vars.gui_context.createLinearGradient(0, top, 0, top + 30); // add some grad to the metal text.addColorStop(0, "rgba(160, 160, 160, 0.5)"); text.addColorStop(0.2, "rgba(80, 80, 80, 0.5)"); text.addColorStop(1, "rgba(30, 30, 30, 0.5)"); context.strokeStyle = text; context.stroke(); context.fillStyle = "#000000"; context.fillText(title, mid, top + 15); } // Display a normal window with elements function sd_show_window(title, inner_list, hide_others, close_script, moveable) { var i; inner_list.style.width = 'auto'; inner_list.style.height = 'auto'; if (!!hide_others) { for( i = 0; i < sd_g_vars.gui_div.childNodes.length; i++ ) sd_g_vars.gui_div.childNodes[i].style.visibility = 'hidden'; } var temp_ele = document.getElementById(title); var temp_can = null; var sd_off_div = document.getElementById("sdoffdiv"); sd_off_div.appendChild(inner_list); var top = 0; var height = sd_off_div.offsetHeight; var width = sd_off_div.offsetWidth; if( width > sd_g_vars.res_width - 40 ) width = sd_g_vars.res_width - 40; if( height > sd_g_vars.res_height - 60 ) height = sd_g_vars.res_height - 60; if (!temp_ele) { temp_ele = document.createElement('div'); sd_g_vars.gui_div.appendChild(temp_ele); temp_ele.setAttribute("style", "top: " + (sd_g_vars.res_half_h - (height / 2)) + "px; left: " + (sd_g_vars.res_half_w - (width / 2)) + "px; width: " + (width) + "px; height: " + height + "px;"); } else { if( Math.abs(temp_ele.offsetWidth - (width + 8)) > 10 || Math.abs(temp_ele.offsetHeight - (height + 30)) > 10 ) temp_ele.setAttribute("style", "top: " + (sd_g_vars.res_half_h - (height / 2)) + "px; left: " + (sd_g_vars.res_half_w - (width / 2)) + "px; width: " + (width) + "px; height: " + height + "px;"); while (temp_ele.childNodes.length > 0) // these will be remade temp_ele.removeChild(temp_ele.lastChild); } temp_ele.id = title; temp_ele.className = "sd_window"; temp_ele.style.visibility = 'visible'; var temp_mover = document.createElement('div'); temp_mover.className = "title_able"; temp_ele.appendChild(temp_mover); temp_ele.appendChild(inner_list); width = inner_list.offsetWidth; var menu_bar = document.createElement('canvas'); menu_bar.className = "title_bar"; menu_bar.width = width + 8; menu_bar.height = 30; temp_mover.style.width = width + 8 + "px"; temp_mover.appendChild(menu_bar); if (moveable) { temp_mover.className = "move_able"; temp_mover.setAttribute("onmousedown", "sd_move_window(event, '" + title + "');"); var move_ele = document.createElement("span"); move_ele.className = "move_show"; move_ele.innerHTML = "+"; temp_mover.appendChild(move_ele); } if( close_script ) { var close_ele = document.createElement("a"); close_ele.className = "close_show"; close_ele.setAttribute("onclick", close_script); close_ele.setAttribute("onmousedown", "event.stopPropagation();"); close_ele.innerHTML = "×"; temp_mover.appendChild(close_ele); } sd_create_title_bar(title, width + 8, menu_bar.getContext('2d'), inner_list.className == "menu_list"); return temp_ele; } // Display the title of the game function sd_display_title() { //sd_g_vars.gui_context.drawImage(sd_g_vars.menu_images[0], 257, 0); sd_g_vars.gui_context.font = "bold 48px sans-serif"; // display loading text, since we don't want to redraw it sd_g_vars.gui_context.textAlign = "center"; // make it display near the middle sd_g_vars.gui_context.textBaseline = "top"; var text = sd_g_vars.gui_context.createLinearGradient(0, 50, 0, 100); text.addColorStop(0, '#FF4400'); text.addColorStop(0.4, '#FFFF00'); text.addColorStop(1, '#DD6600'); sd_g_vars.gui_context.fillStyle = text; sd_g_vars.gui_context.fillText("Star Devastation", sd_g_vars.res_half_w, 40); } // Used for loading everything else function sd_draw_loading(l_text, l_title) { sd_g_vars.loading_text = l_text ? l_text : ""; sd_g_vars.loading_title = l_title ? l_title : "Loading... Please Wait"; if( sd_g_vars.is_loading ) return; sd_g_vars.is_loading = true; sd_g_vars.text_context.fillStyle = "rgba(0, 0, 0, 0.75)"; sd_g_vars.text_context.clearRect(0, 0, sd_g_vars.res_width, sd_g_vars.res_height); // clear, then draw black sd_g_vars.text_context.fillRect(0, 0, sd_g_vars.res_width, sd_g_vars.res_height); var load_can = document.getElementById("high_gui"); var sddiv = document.getElementById("sddiv"); sddiv.removeChild(load_can); sddiv.appendChild(load_can); sd_g_vars.text_context.font = "bold 32px sans-serif"; // display loading text, since we don't want to redraw it sd_g_vars.text_context.textAlign = "center"; // make it display near the middle sd_g_vars.text_context.textBaseline = "middle"; var text = sd_g_vars.text_context.createLinearGradient(sd_g_vars.res_half_w - 600, sd_g_vars.res_half_h - 18, sd_g_vars.res_half_w + 200, sd_g_vars.res_half_h + 18); // draw bar using 3 colors, vertically text.addColorStop(0, "#FF4400"); text.addColorStop(0.25, "#FFFF00"); text.addColorStop(0.5, "#FF4400"); text.addColorStop(0.75, "#FFFF00"); text.addColorStop(1, "#FF4400"); sd_g_vars.text_context.fillStyle = text; sd_g_vars.text_context.fillText(sd_g_vars.loading_title, sd_g_vars.res_half_w, sd_g_vars.res_half_h - 15); sd_g_vars.text_context.font = "18px sans-serif"; // display loading text, since we don't want to redraw it sd_g_vars.text_context.fillText(sd_g_vars.loading_text, sd_g_vars.res_half_w, sd_g_vars.res_half_h + 25); sd_g_vars.load_looper = setTimeout(sd_draw_loading_bar, sd_g_vars.tick_rate); } // Used after loading var sd_clear_loading = function() { sd_g_vars.text_context.clearRect(0, 0, sd_g_vars.res_width, sd_g_vars.res_height); // clear, then draw black clearTimeout(sd_g_vars.load_looper); sd_g_vars.is_loading = false; var load_div = document.getElementById("guidiv"); var load_can = document.getElementById("high_gui"); var sddiv = document.getElementById("sddiv"); var login_div = document.getElementById("login_bar"); sddiv.removeChild(load_can); sddiv.insertBefore(load_can, load_div); }; // Draws the loading bar function sd_draw_loading_bar() { sd_g_vars.text_context.fillStyle = "rgba(0, 0, 0, 0.75)"; sd_g_vars.text_context.clearRect(0, 0, sd_g_vars.res_width, sd_g_vars.res_height); // clear, then draw black sd_g_vars.text_context.fillRect(0, 0, sd_g_vars.res_width, sd_g_vars.res_height); sd_g_vars.text_context.font = "bold 32px sans-serif"; // display loading text, since we don't want to redraw it sd_g_vars.text_context.textAlign = "center"; // make it display near the middle sd_g_vars.text_context.textBaseline = "middle"; sd_g_vars.load_at += 10; if (sd_g_vars.load_at > 440) sd_g_vars.load_at = 0; var text = sd_g_vars.text_context.createLinearGradient(sd_g_vars.res_half_w - 600 + sd_g_vars.load_at, sd_g_vars.res_half_h - 18, sd_g_vars.res_half_w + 200 + sd_g_vars.load_at, sd_g_vars.res_half_h + 18); // draw bar using 3 colors, vertically text.addColorStop(0, "#FF4400"); text.addColorStop(0.2, "#FFFF00"); text.addColorStop(0.45, "#DD6600"); text.addColorStop(0.55, "#FF4400"); text.addColorStop(0.75, "#FFFF00"); text.addColorStop(1, "#DD6600"); sd_g_vars.text_context.fillStyle = text; sd_g_vars.text_context.fillText(sd_g_vars.loading_title, sd_g_vars.res_half_w, sd_g_vars.res_half_h - 15); sd_g_vars.text_context.font = "18px sans-serif"; // display loading text, since we don't want to redraw it sd_g_vars.text_context.fillText(sd_g_vars.loading_text, sd_g_vars.res_half_w, sd_g_vars.res_half_h + 25); sd_g_vars.load_looper = setTimeout(sd_draw_loading_bar, sd_g_vars.tick_rate); } // Init all canvases for use during the game function sd_init_canvases() { var temp = document.createElement("canvas"); var failed = false; /*temp = document.getElementById("low_objs"); sd_g_vars.low_context = temp.getContext("2d"); temp = document.getElementById("mid_objs"); sd_g_vars.mid_context = temp.getContext("2d");*/ temp = document.getElementById("high_objs"); sd_g_vars.high_context = temp.getContext("2d"); temp = document.getElementById("low_gui"); sd_g_vars.gui_context = temp.getContext("2d"); temp = document.getElementById("high_gui"); sd_g_vars.text_context = temp.getContext("2d"); sd_g_vars.gui_div = document.getElementById("guidiv"); }