extends Control class_name GameUI enum ServerMenuItem { ServerInfo } enum PopupName { SpaceMap, EnergyUsage } onready var logs = $Logs onready var inspect_box = $InspectBox as RichTextLabel onready var item_slots_container = $ItemSlots onready var map_popup = $MapPopup onready var sever_info_popup = $ServerInfoPopup onready var scene = $"/root/scene" onready var netgame = $"/root/Multiplayer" const ItemBox = preload("res://Scenes/UI/Items/ItemBox.tscn") var left_selected = null var right_selected = null const WHISPER_RADIUS = 32*3 const CHAT_RADIUS = 32*10 const SHOUT_RADIUS = 32*14 var inspect_mode = false var current_inspecting = null func _ready() -> void: # Add options to menu buttons var serverMenu = $Menu/Margins/Grid/Server.get_popup() serverMenu.connect("id_pressed", self, "_server_option_chosen") serverMenu.add_item("Server info", ServerMenuItem.ServerInfo) # Create item slots for slot_id in range(4): var item_slot = ItemBox.instance() # By default, slot 2/3 are L/R, and 2 is selected match slot_id: 1: item_slot.selected = true item_slot.current_hand = UIItemBox.CurrentHand.Left left_selected = item_slot 2: item_slot.current_hand = UIItemBox.CurrentHand.Right right_selected = item_slot # Connect signals item_slot.connect("selected", self, "_itembox_selected", [item_slot]) item_slot.connect("used_in_hand", self, "_itembox_used", [item_slot]) item_slots_container.add_child(item_slot) func _physics_process(_delta: float) -> void: if inspect_mode: var mouse_pos = scene.world.get_local_mouse_position() * scene.world.scale var results = scene.physics.intersect_point(mouse_pos, 1, [], 2) if results.size() > 0: var obj = results[0].collider if obj != current_inspecting: current_inspecting = obj if obj.has_method("inspect"): var data = obj.inspect() inspect_box.bbcode_text = "" inspect_box.rect_size.y = 0 if "object_name" in obj and obj.object_name != "": inspect_box.append_bbcode("[b]%s[/b] (%s)" % [obj.object_name, data.type]) else: inspect_box.append_bbcode("A [b]%s[/b]" % data.type) if "description" in data: inspect_box.append_bbcode("\n" + data.description) if "interaction" in data: inspect_box.append_bbcode("\n\n[i]%s[/i]" % data.interaction) inspect_box.visible = true else: current_inspecting = null inspect_box.visible = false func _server_option_chosen(id) -> void: match id: ServerMenuItem.ServerInfo: $ServerInfoPopup.popup_centered() func open_popup(popup_name) -> void: match popup_name: PopupName.SpaceMap: $MapPopup.popup_centered_ratio() PopupName.EnergyUsage: pass func close_popup(popup_name) -> void: match popup_name: PopupName.SpaceMap: $MapPopup.visible = false PopupName.EnergyUsage: pass const say_format = "%s says \"%s\"\n" const ask_format = "%s asks \"%s\"\n" const shout_format = "%s shouts \"[b]%s[/b]\"\n" const whisper_format = "[i]%s whispers \"%s\"[/i]\n" func _send_chat(text: String) -> void: var escaped_text = text.replace("[", "[\u8203").strip_edges() # Hacky way to escape BBCode if text.ends_with("?"): scene.rpc("broadcast_zone", ask_format % [netgame.player_name, escaped_text], scene.world.player.global_position, SHOUT_RADIUS) if text.ends_with("!!"): scene.rpc("broadcast_zone", shout_format % [netgame.player_name, escaped_text], scene.world.player.global_position, SHOUT_RADIUS) elif text.begins_with("#"): scene.rpc("broadcast_zone", whisper_format % [netgame.player_name, escaped_text.substr(1)], scene.world.player.global_position, WHISPER_RADIUS) else: scene.rpc("broadcast_zone", say_format % [netgame.player_name, escaped_text], scene.world.player.global_position, CHAT_RADIUS) var inspect_offset = Vector2(20, 20) func set_inspect(active: bool) -> void: inspect_box.visible = inspect_box.visible and active inspect_mode = active inspect_box.rect_global_position = get_viewport().get_mouse_position() + inspect_offset func _input(event: InputEvent) -> void: var no_popups = not check_popups() if event.is_action_released("inspect"): set_inspect(false) elif event.is_action_pressed("inspect"): set_inspect(true) elif event.is_action_pressed("ui_scroll_left") and no_popups: select_next_box(-1, Input.is_action_pressed("alt_hand")) elif event.is_action_pressed("ui_scroll_right") and no_popups: select_next_box(1, Input.is_action_pressed("alt_hand")) elif event.is_action_pressed("swap_hands"): swap_hands() elif event is InputEventMouseMotion: var mousemotion = event as InputEventMouseMotion if inspect_mode: inspect_box.rect_global_position = mousemotion.position + inspect_offset func _itembox_selected(hand, item_box: UIItemBox) -> void: left_selected.selected = false right_selected.selected = false match hand: UIItemBox.CurrentHand.Left: if item_box.current_hand != UIItemBox.CurrentHand.None: left_selected.current_hand = item_box.current_hand match item_box.current_hand: UIItemBox.CurrentHand.Right: right_selected = left_selected else: left_selected.current_hand = UIItemBox.CurrentHand.None left_selected = item_box UIItemBox.CurrentHand.Right: if item_box.current_hand != UIItemBox.CurrentHand.None: right_selected.current_hand = item_box.current_hand match item_box.current_hand: UIItemBox.CurrentHand.Left: left_selected = right_selected else: right_selected.current_hand = UIItemBox.CurrentHand.None right_selected = item_box item_box.selected = true item_box.current_hand = hand func _itembox_used(item_box) -> void: pass func check_popups() -> bool: return map_popup.visible or sever_info_popup.visible func select_next_box(direction: int, right_hand: bool) -> void: var box = left_selected as UIItemBox if right_hand: box = right_selected var parent = box.get_parent() var child_count = parent.get_child_count() var index = box.get_index() index += direction if index < 0: index = child_count + index elif index >= child_count: index -= child_count var hand = UIItemBox.CurrentHand.Left if right_hand: hand = UIItemBox.CurrentHand.Right _itembox_selected(hand, parent.get_child(index)) func swap_hands() -> void: if left_selected.selected: _itembox_selected(UIItemBox.CurrentHand.Left, right_selected) else: _itembox_selected(UIItemBox.CurrentHand.Right, left_selected)