diff --git a/content/ui/outfitter.rhai b/content/ui/outfitter.rhai index 5d9ed7c..93cef2e 100644 --- a/content/ui/outfitter.rhai +++ b/content/ui/outfitter.rhai @@ -3,6 +3,11 @@ 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", @@ -15,12 +20,13 @@ fn init(state) { 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::NorthWest, - Anchor::SouthWest - ), - Color(1.0, 1.0, 1.0, 1.0) + Anchor::SouthWest, + Anchor::NorthWest + + ) ); textbox::font_serif("exit_text"); textbox::align_center("exit_text"); @@ -31,8 +37,8 @@ fn init(state) { "ui::button", Rect( 113.35, 52.0, 69.8, 18.924, - Anchor::NorthWest, - Anchor::SouthWest + Anchor::SouthWest, + Anchor::NorthWest ) ); @@ -53,53 +59,46 @@ fn init(state) { "icon::gypsum", Rect( 111.0, -95.45, 90.0, 90.0, - Anchor::Center, - Anchor::NorthWest + 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::Center, - Anchor::NorthWest - ), - Color(1.0, 1.0, 1.0, 1.0) + Anchor::NorthWest, + Anchor::Center + ) ); textbox::font_serif("ship_name"); textbox::align_center("ship_name"); - textbox::set_text("ship_name", "Hyperion"); 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::Center, - Anchor::NorthWest - ), - Color(0.7, 0.7, 0.7, 1.0) + Anchor::NorthWest, + Anchor::Center + ) ); textbox::font_sans("ship_type"); textbox::align_center("ship_type"); - if state.player_ship().is_some() { - textbox::set_text("ship_type", state.player_ship().display_name()); - } - 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, - ), - Color(1.0, 1.0, 1.0, 1.0) + ) ); textbox::font_mono("ship_stats"); - textbox::set_text("ship_stats", "Earth"); - sprite::add( "outfit_bg", @@ -116,8 +115,8 @@ fn init(state) { "icon::engine", Rect( -166.0, -109.0, 90.0, 90.0, - Anchor::Center, - Anchor::NorthEast + Anchor::NorthEast, + Anchor::Center ) ); sprite::preserve_aspect("outfit_thumb", true); @@ -125,139 +124,258 @@ fn init(state) { 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::NorthWest, Anchor::NorthEast, - ), - Color(1.0, 1.0, 1.0, 1.0) + Anchor::NorthWest + ) ); textbox::font_serif("outfit_name"); textbox::weight_bold("outfit_name"); - textbox::set_text("outfit_name", "Earth"); + textbox::set_text("outfit_name", ""); textbox::add( - "outfit_desc", 7.0, 8.5, + "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::Center, Anchor::NorthEast, - ), - Color(1.0, 1.0, 1.0, 1.0) + Anchor::Center + ) ); textbox::font_serif("outfit_desc"); - textbox::set_text("outfit_desc", "Earth"); + textbox::set_text("outfit_desc", ""); textbox::add( - "outfit_stats", 7.0, 8.5, + "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::NorthWest, Anchor::NorthEast, - ), - Color(1.0, 1.0, 1.0, 1.0) + Anchor::NorthWest + ) ); textbox::font_mono("outfit_stats"); - textbox::set_text("outfit_stats", "Earth"); + textbox::set_text("outfit_stats", ""); - - // width should be calculated as a fraction of screen width - let scrollbox_rect = Rect( - 222.0, -16.0, 470.0, 480.0, - Anchor::NorthWest, - Anchor::NorthWest, + + sprite::add( + "buy_button", + "ui::button", + Rect( + -110.71, -281.0, 69.8, 18.924, + Anchor::NorthEast, + Anchor::NorthWest + ) ); - scrollbox::add("outfit_list", scrollbox_rect); + 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(); - if p.is_landed() { - let s = ""; - let x = scrollbox_rect.pos().x() + 45.0; - let y = scrollbox_rect.pos().y() - 45.0; - for xxx in ["1","2","3"] { - for i in p.landed_on().outfitter() { - s = s + i.display_name() + "\n"; + 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() { - let thumb_name = "outfit.thumb." + i.index() + xxx; - let backg_name = "outfit.backg." + i.index() + xxx; - let title_name = "outfit.title." + i.index() + xxx; - - sprite::add( - backg_name, - "ui::outfitbg", - Rect( - x, y, 90.0, 90.0, - Anchor::Center, - Anchor::NorthWest - ) - ); - 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::Center, - Anchor::NorthWest - ) - ); - sprite::preserve_aspect(thumb_name, true); - scrollbox::add_element("outfit_list", thumb_name); - - textbox::add( - title_name, - 10.0, 10.0, - Rect( - x, y - 50.0, 90.0, 10.0, - Anchor::Center, - Anchor::NorthWest, - ), - Color(1.0, 1.0, 1.0, 1.0) - ); - 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; - } + 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; } - textbox::set_text("outfit_stats", s); } } + + update_ship_info(state); } fn event(state, event) { if type_of(event) == "MouseHoverEvent" { let element = event.element(); - if element == "exit_button" { + + if ( + element == "exit_button" + || element == "buy_button" + || element == "sell_button" + ){ if event.is_enter() { - sprite::jump_to("exit_button", "on:top", 0.1); + sprite::jump_to(element, "on:top", 0.1); } else { - sprite::jump_to("exit_button", "off:top", 0.1); + sprite::jump_to(element, "off:top", 0.1); } } - if element.starts_with("outfit.backg.") && element != selected_outfit { - if event.is_enter() { - sprite::jump_to(element, "hover: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 { - sprite::jump_to(element, "off:top", 0.1); + if event.is_enter() { + sprite::jump_to(element, "hover:top", 0.1); + } else { + sprite::jump_to(element, "off:top", 0.1); + } } } @@ -265,15 +383,10 @@ fn event(state, event) { } - // TODO: this occasionally breaks because of sprite ordering. - // Clicks go to se_box instead! if type_of(event) == "MouseClickEvent" { if !event.is_down() { return PlayerDirective::None; } - - print(event.element()); - let element = event.element(); if element == "exit_button" { @@ -281,22 +394,183 @@ fn event(state, event) { return PlayerDirective::None; } - if element.starts_with("outfit.backg.") && element != selected_outfit { + if ( + element.starts_with("outfit.backg.") && + event.element().split("outfit.backg.".len())[1] != selected_outfit + ) { if selected_outfit != false { - sprite::jump_to(selected_outfit, "off:top", 0.1); + sprite::jump_to("outfit.backg." + selected_outfit, "off:top", 0.1); } - sprite::jump_to(element, "selected:top", 0.1); - selected_outfit = element; + /// 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; + 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; + + + // TODO: outfits add mass + // TODO: calculate radial 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); + + } } \ No newline at end of file