fn init(state) { conf::show_starfield(true); conf::show_phys(false); if !state.player_ship().is_landed() { print("UI error: player isn't landed when initializing outfitter scene"); return; } sprite::add( "se_box", "ui::outfitterbox", Rect( -1.0, -1.0, 202.345, 133.409, Anchor::SouthWest, Anchor::SouthWest ) ); textbox::add( "exit_text", 10.0, 10.0, Color(1.0, 1.0, 1.0, 1.0), Rect( 122.71, 48.0, 51.0, 12.0, Anchor::SouthWest, Anchor::NorthWest ) ); textbox::font_serif("exit_text"); textbox::align_center("exit_text"); textbox::set_text("exit_text", "Exit"); sprite::add( "exit_button", "ui::button", Rect( 113.35, 52.0, 69.8, 18.924, Anchor::SouthWest, Anchor::NorthWest ) ); sprite::add( "ship_bg", "ui::outfitter-ship-bg", Rect( 16.0, -16.0, 190.0, 353.0, Anchor::NorthWest, Anchor::NorthWest ) ); sprite::add( "ship_thumb", "icon::gypsum", Rect( 111.0, -95.45, 90.0, 90.0, Anchor::NorthWest, Anchor::Center ) ); sprite::preserve_aspect("ship_thumb", true); textbox::add( "ship_name", 10.0, 10.0, Color(1.0, 1.0, 1.0, 1.0), Rect( 111.0, -167.27, 145.0, 10.0, Anchor::NorthWest, Anchor::Center ) ); textbox::font_serif("ship_name"); textbox::align_center("ship_name"); textbox::add( "ship_type", 7.0, 8.5, Color(0.7, 0.7, 0.7, 1.0), Rect( 111.0, -178.0, 145.0, 8.5, Anchor::NorthWest, Anchor::Center ) ); textbox::font_sans("ship_type"); textbox::align_center("ship_type"); textbox::add( "ship_stats", 7.0, 8.5, Color(1.0, 1.0, 1.0, 1.0), Rect( 38.526, -192.332, 144.948, 154.5, Anchor::NorthWest, Anchor::NorthWest, ) ); textbox::font_mono("ship_stats"); sprite::add( "outfit_bg", "ui::outfitter-outfit-bg", Rect( -16.0, -16.0, 300.0, 480.0, Anchor::NorthEast, Anchor::NorthEast ) ); sprite::add( "outfit_thumb", "icon::engine", Rect( -166.0, -109.0, 90.0, 90.0, Anchor::NorthEast, Anchor::Center ) ); sprite::preserve_aspect("outfit_thumb", true); textbox::add( "outfit_name", 16.0, 16.0, Color(1.0, 1.0, 1.0, 1.0), Rect( -312.0, -20.0, 200.0, 16.0, Anchor::NorthEast, Anchor::NorthWest ) ); textbox::font_serif("outfit_name"); textbox::weight_bold("outfit_name"); textbox::set_text("outfit_name", ""); textbox::add( "outfit_desc", 8.5, 9.0, Color(1.0, 1.0, 1.0, 1.0), Rect( -166.0, -219.0, 260.0, 78.0, Anchor::NorthEast, Anchor::Center ) ); textbox::font_serif("outfit_desc"); textbox::set_text("outfit_desc", ""); textbox::add( "outfit_stats", 8.5, 9.0, Color(1.0, 1.0, 1.0, 1.0), Rect( -295.0, -271.0, 164.0, 216.0, Anchor::NorthEast, Anchor::NorthWest ) ); textbox::font_mono("outfit_stats"); textbox::set_text("outfit_stats", ""); sprite::add( "buy_button", "ui::button", Rect( -110.71, -281.0, 69.8, 18.924, Anchor::NorthEast, Anchor::NorthWest ) ); textbox::add( "buy_text", 10.0, 10.0, Color(1.0, 1.0, 1.0, 1.0), Rect( -100.84, -285.34, 51.0, 12.0, Anchor::NorthEast, Anchor::NorthWest ) ); textbox::font_serif("buy_text"); textbox::align_center("buy_text"); textbox::set_text("buy_text", "Buy"); sprite::add( "sell_button", "ui::button", Rect( -110.71, -306.2, 69.8, 18.924, Anchor::NorthEast, Anchor::NorthWest ) ); textbox::add( "sell_text", 10.0, 10.0, Color(1.0, 1.0, 1.0, 1.0), Rect( -100.84, -311.15, 51.0, 12.0, Anchor::NorthEast, Anchor::NorthWest ) ); textbox::font_serif("sell_text"); textbox::align_center("sell_text"); textbox::set_text("sell_text", "Sell"); let times_five = false; let times_ten = false; let times_hundred = false; textbox::add( "five_text", 7.5, 7.5, Color(0.5, 0.5, 0.5, 1.0), Rect( -110.71, -331.2, 69.8, 18.924, Anchor::NorthEast, Anchor::NorthWest ) ); textbox::font_mono("five_text"); textbox::set_text("five_text", "[shift] x5"); textbox::add( "ten_text", 7.5, 7.5, Color(0.5, 0.5, 0.5, 1.0), Rect( -110.71, -341.2, 69.8, 18.924, Anchor::NorthEast, Anchor::NorthWest ) ); textbox::font_mono("ten_text"); textbox::set_text("ten_text", "[ctrl] x10"); textbox::add( "hundred_text", 7.5, 7.5, Color(0.5, 0.5, 0.5, 1.0), Rect( -110.71, -351.2, 69.8, 18.924, Anchor::NorthEast, Anchor::NorthWest ) ); textbox::font_mono("hundred_text"); textbox::set_text("hundred_text", "[alt] x100"); // A string containing the selected outfit's index. // This is always set---if we have an outfitter, we must have at least one outfit. let selected_outfit = false; { let scrollbox_width = state.window_size().x() - (190 + 16 + 300 + 16); if scrollbox_width <= 0 { scrollbox_width = 1; } // width should be calculated as a fraction of screen width let scrollbox_rect = Rect( 222.0, -16.0, scrollbox_width, 480.0, Anchor::NorthWest, Anchor::NorthWest ); scrollbox::add("outfit_list", scrollbox_rect); // p cannot be saved in the global scope. let p = state.player_ship(); let s = ""; let x = scrollbox_rect.pos().x() + 45.0; let y = scrollbox_rect.pos().y() - 45.0; for i in p.landed_on().outfitter() { if selected_outfit == false { selected_outfit = i.index(); update_outfit_info(selected_outfit); } s = s + i.display_name() + "\n"; let thumb_name = "outfit.thumb." + i.index(); let backg_name = "outfit.backg." + i.index(); let title_name = "outfit.title." + i.index(); sprite::add( backg_name, "ui::outfitbg", Rect( x, y, 90.0, 90.0, Anchor::NorthWest, Anchor::Center ) ); sprite::preserve_aspect(backg_name, true); scrollbox::add_element("outfit_list", backg_name); sprite::add( thumb_name, i.thumbnail(), Rect( x, y, 75.0, 75.0, Anchor::NorthWest, Anchor::Center ) ); sprite::preserve_aspect(thumb_name, true); scrollbox::add_element("outfit_list", thumb_name); textbox::add( title_name, 10.0, 10.0, Color(1.0, 1.0, 1.0, 1.0), Rect( x, y - 50.0, 90.0, 10.0, Anchor::NorthWest, Anchor::Center ) ); textbox::font_sans(title_name); textbox::align_center(title_name); textbox::set_text(title_name, i.display_name()); scrollbox::add_element("outfit_list", title_name); x = x + 120.0; if x > ( scrollbox_rect.pos().x() + scrollbox_rect.dim().x() - 45.0 ) { x = scrollbox_rect.pos().x() + 45.0; y = y - 120.0; } } } update_ship_info(state); } fn event(state, event) { // TODO: update on ship outfit change only update_ship_info(state); if type_of(event) == "MouseHoverEvent" { let element = event.element(); if ( element == "exit_button" || element == "buy_button" || element == "sell_button" ){ if event.is_enter() { sprite::jump_to(element, "on:top", 0.1); } else { sprite::jump_to(element, "off:top", 0.1); } } if element.starts_with("outfit.backg.") { if event.element().split("outfit.backg.".len())[1] == selected_outfit { if event.is_enter() { sprite::jump_to(element, "hoverselected:top", 0.1); } else { sprite::jump_to(element, "selected:top", 0.1); } } else { if event.is_enter() { sprite::jump_to(element, "hover:top", 0.1); } else { sprite::jump_to(element, "off:top", 0.1); } } } return PlayerDirective::None; } if type_of(event) == "MouseClickEvent" { if !event.is_down() { return PlayerDirective::None; } let element = event.element(); if element == "exit_button" { ui::go_to_scene("landed"); return PlayerDirective::None; } if element == "buy_button" { if selected_outfit != false { let outfit = ct::get_outfit(selected_outfit); if outfit.is_some() { return PlayerDirective::BuyOutfit(outfit, 1); } } } if element == "sell_button" { if selected_outfit != false { let outfit = ct::get_outfit(selected_outfit); if outfit.is_some() { return PlayerDirective::SellOutfit(outfit, 1); } } } if ( element.starts_with("outfit.backg.") && event.element().split("outfit.backg.".len())[1] != selected_outfit ) { if selected_outfit != false { sprite::jump_to("outfit.backg." + selected_outfit, "off:top", 0.1); } /// We can't click on this sprite without first hovering! sprite::jump_to(element, "hoverselected:top", 0.1); selected_outfit = event.element().split("outfit.backg.".len())[1]; update_outfit_info(selected_outfit); return PlayerDirective::None; } return; } if type_of(event) == "KeyboardEvent" { if event.key() == "up" { times_five = event.is_down(); } if event.key() == "left" { times_ten = event.is_down(); } if event.key() == "right" { times_hundred = event.is_down(); } update_outfit_box(times_five, times_ten, times_hundred); return PlayerDirective::None; } if type_of(event) == "PlayerShipStateEvent" { if !state.player_ship().is_landed() { ui::go_to_scene("flying"); } return PlayerDirective::None; } } fn update_outfit_box(times_five, times_ten, times_hundred) { let times = 1; if times_five { times *= 5; textbox::set_color("five_text", Color(1.0, 1.0, 1.0, 1.0)); } else { textbox::set_color("five_text", Color(0.5, 0.5, 0.5, 1.0)); } if times_ten { times *= 10; textbox::set_color("ten_text", Color(1.0, 1.0, 1.0, 1.0)); } else { textbox::set_color("ten_text", Color(0.5, 0.5, 0.5, 1.0)); } if times_hundred { times *= 100; textbox::set_color("hundred_text", Color(1.0, 1.0, 1.0, 1.0)); } else { textbox::set_color("hundred_text", Color(0.5, 0.5, 0.5, 1.0)); } if times != 1 { textbox::set_text("buy_text", "Buy x" + times); textbox::set_text("sell_text", "Sell x" + times); } else { textbox::set_text("buy_text", "Buy"); textbox::set_text("sell_text", "Sell"); } } fn update_outfit_info(selected_outfit) { let outfit = ct::get_outfit(selected_outfit); if outfit.is_some() { let stats = ""; let tlen = 20; { let s = "cost "; s.pad(tlen, " "); stats += s + outfit.cost(); stats += "\n"; } { let s = "needs gun port "; s.pad(tlen, " "); if outfit.stat_is_gun() { stats += s + "yes"; } else { stats += s + "no" } stats += "\n"; } { let s = outfit.required_space(); for k in s.keys() { let v = s[k]; let s = k + " space needed "; s.pad(tlen, " "); if v != 0 { stats += s + v; stats += "\n"; } } } stats += "\n"; if outfit.stat_thrust() != 0 { let s = "thrust "; s.pad(tlen, " "); stats += s + outfit.stat_thrust(); stats += "\n"; } if outfit.stat_steer_power() != 0 { let s = "steer power "; s.pad(tlen, " "); stats += s + outfit.stat_steer_power(); stats += "\n"; } if outfit.stat_shield_strength() != 0 { let s = "shield strength "; s.pad(tlen, " "); stats += s + outfit.stat_shield_strength(); stats += "\n"; } if outfit.stat_shield_generation() != 0 { let s = "shield regen"; s.pad(tlen, " "); stats += s + outfit.stat_shield_generation(); stats += "\n"; } if outfit.stat_shield_delay() != 0 { let s = "shield delay "; s.pad(tlen, " "); stats += s + outfit.stat_shield_delay(); stats += "\n"; } if outfit.stat_shield_dps() != 0 { let s = "shield dps "; s.pad(tlen, " "); stats += s + outfit.stat_shield_dps(); stats += "\n"; } sprite::set_sprite("outfit_thumb", outfit.thumbnail()); textbox::set_text("outfit_name", outfit.display_name()); textbox::set_text("outfit_desc", outfit.desc()); textbox::set_text("outfit_stats", stats); } } fn update_ship_info(state) { let ship = state.player_ship(); if ship.is_some() { let stats = ""; let tlen = 20; { let u = ship.used_space(); let t = ship.total_space(); for k in u.keys() { let vu = u[k]; let vt = t[k]; let s = k + " space "; s.pad(tlen, " "); stats += s + (vt - vu) + "/" + vt; stats += "\n"; } } { let s = "gun points "; s.pad(tlen, " "); stats += s + ship.free_gun_points() + "/" + ship.total_gun_points(); stats += "\n\n"; } // TODO: outfits add mass // TODO: calculate acceleration { let s = "shield strength "; s.pad(tlen, " "); stats += s + ship.stat_shield_strength(); stats += "\n"; } { let s = "hull strength "; s.pad(tlen, " "); stats += s + ship.total_hull(); stats += "\n\n"; } { let s = "mass "; s.pad(tlen, " "); stats += s + ship.empty_mass(); stats += "\n"; } { let s = "thrust "; s.pad(tlen, " "); stats += s + ship.stat_thrust(); stats += "\n"; } { let s = "steer power "; s.pad(tlen, " "); stats += s + ship.stat_steer_power(); stats += "\n"; } { let s = "max shield regen"; s.pad(tlen, " "); stats += s + ship.stat_max_shield_generation(); stats += "\n"; } sprite::set_sprite("ship_thumb", ship.thumbnail()); textbox::set_text("ship_name", "Hyperion"); textbox::set_text("ship_type", state.player_ship().display_name()); textbox::set_text("ship_stats", stats); } }