syntax = "proto2"; package com.fourisland.lingo2_archipelago; message Proxy { optional string answer = 1; optional string path = 2; } enum DoorType { DOOR_TYPE_UNKNOWN = 0; // This door is a location unless panelsanity is on, and it is an item as long as door shuffle is on. STANDARD = 1; // This door is never an item or a location. EVENT = 2; // This door is never a location, and is an item as long as door shuffle is on. ITEM_ONLY = 3; // This door is never a location, and is an item as long as control center color shuffle is on. CONTROL_CENTER_COLOR = 4; // This door is never an item, and is a location as long as panelsanity is not on. LOCATION_ONLY = 5; // This door is an item if gravestone shuffle is enabled, and is a location as long as panelsanity is not on. GRAVESTONE = 6; // This door is never a location, and is an item as long as gallery painting shuffle is on. GALLERY_PAINTING = 7; } enum DoorGroupType { DOOR_GROUP_TYPE_UNKNOWN = 0; // These doors border a worldport. They should be grouped when connections are // not shuffled. CONNECTOR = 1; // Similar to CONNECTOR, but these doors are also ordinarily opened by solving // the COLOR panel in the Control Center. These should be grouped when // connections are not shuffled, but are not items at all when control center // colors are not shuffled. COLOR_CONNECTOR = 2; // Groups with this type become an item if cyan door behavior is set to item. CYAN_DOORS = 3; // Groups with this type always become an item if door shuffle is on. SHUFFLE_GROUP = 4; } enum MapType { NORMAL_MAP = 0; ICARUS = 1; GIFT_MAP = 2; } enum AxisDirection { AXIS_DIRECTION_UNKNOWN = 0; X_PLUS = 1; X_MINUS = 2; Y_PLUS = 3; Y_MINUS = 4; Z_PLUS = 5; Z_MINUS = 6; } enum PuzzleSymbol { PUZZLE_SYMBOL_UNKNOWN = 0; SUN = 1; SPARKLES = 2; ZERO = 3; EXAMPLE = 4; BOXES = 5; PLANET = 6; PYRAMID = 7; CROSS = 8; SWEET = 9; GENDER = 10; AGE = 11; SOUND = 12; ANAGRAM = 13; JOB = 14; STARS = 15; NULL = 16; EVAL = 17; LINGO = 18; QUESTION = 19; } message Vec3d { optional double x = 1; optional double y = 2; optional double z = 3; } message VersionNumber { optional uint64 major = 1; optional uint64 minor = 2; optional uint64 patch = 3; } message ProxyIdentifier { optional uint64 panel = 1; optional string answer = 2; } message KeyholderAnswer { optional uint64 keyholder = 1; optional string key = 2; } message Connection { optional uint64 from_room = 1; optional uint64 to_room = 2; optional uint64 required_door = 3; oneof trigger { uint64 port = 4; uint64 painting = 5; ProxyIdentifier panel = 6; } optional bool roof_access = 7; optional bool purple_ending = 8; optional bool cyan_ending = 9; optional bool vanilla_only = 10; } message Door { optional uint64 id = 1; optional uint64 ap_id = 11; optional uint64 map_id = 9; optional uint64 room_id = 10; optional string name = 2; repeated string receivers = 3; repeated uint64 move_paintings = 4; repeated ProxyIdentifier panels = 5; optional uint64 complete_at = 12; optional string control_center_color = 6; repeated KeyholderAnswer keyholders = 13; repeated uint64 rooms = 14; repeated uint64 doors = 15; repeated uint64 endings = 16; optional bool double_letters = 18; repeated string senders = 19; optional DoorType type = 8; optional bool latch = 20; optional string location_name = 17; } message PanelData { optional uint64 id = 1; optional uint64 ap_id = 10; optional uint64 room_id = 2; optional string name = 3; optional string path = 4; optional string clue = 5; optional string answer = 6; repeated PuzzleSymbol symbols = 7; repeated Proxy proxies = 8; optional uint64 required_door = 9; optional uint64 required_room = 11; optional string display_name = 12; } message PaintingData { optional uint64 id = 1; optional uint64 room_id = 2; optional string name = 9; optional string path = 10; optional string display_name = 4; optional string orientation = 3; optional bool move = 6; optional bool enter_only = 7; optional AxisDirection gravity = 8; optional bool exit_only = 11; optional uint64 required_door = 5; } message Port { optional uint64 id = 1; optional uint64 room_id = 2; optional string name = 3; optional string display_name = 10; optional string path = 4; optional Vec3d destination = 5; optional double rotation = 8; optional AxisDirection gravity = 7; optional bool no_shuffle = 9; optional uint64 required_door = 6; } message KeyholderData { optional uint64 id = 1; optional uint64 ap_id = 6; optional uint64 room_id = 2; optional string name = 3; optional string path = 4; optional string key = 5; } message Letter { optional uint64 id = 3; optional uint64 ap_id = 5; optional uint64 room_id = 4; optional string key = 1; optional bool level2 = 2; optional string path = 6; } message Mastery { optional uint64 id = 1; optional uint64 ap_id = 2; optional uint64 room_id = 3; optional string name = 4; optional string path = 5; } message Ending { optional uint64 id = 1; optional uint64 ap_id = 2; optional uint64 room_id = 3; optional string name = 4; optional string path = 5; } message Room { optional uint64 id = 1; optional uint64 map_id = 8; optional string name = 2; optional string display_name = 3; optional string panel_display_name = 13; repeated uint64 panels = 4; repeated uint64 paintings = 5; repeated uint64 letters = 6; repeated uint64 ports = 7; repeated uint64 doors = 9; repeated uint64 masteries = 10; repeated uint64 keyholders = 11; repeated uint64 endings = 12; }
extends CanvasLayer

var SCRIPT_rainbowText

var _message_queue = []
var _font
var _container
var _ordered_labels = []


func _ready():
	_container = VBoxContainer.new()
	_container.set_name("Container")
	_container.anchor_bottom = 1
	_container.offset_left = 20.0
	_container.offset_right = 1920.0
	_container.offset_top = 0.0
	_container.offset_bottom = -20.0
	_container.alignment = BoxContainer.ALIGNMENT_END
	_container.mouse_filter = Control.MOUSE_FILTER_IGNORE
	self.add_child(_container)

	_font = load("res://assets/fonts/Lingo2.ttf")


func _add_message(text):
	var new_label = RichTextLabel.new()
	new_label.install_effect(SCRIPT_rainbowText.new())
	new_label.push_font(_font)
	new_label.push_font_size(36)
	new_label.push_outline_color(Color(0, 0, 0, 1))
	new_label.push_outline_size(2)
	new_label.append_text(text)
	new_label.fit_content = true

	_container.add_child(new_label)
	_ordered_labels.push_back(new_label)


func showMessage(text):
	if _ordered_labels.size() >= 9:
		_message_queue.append(text)
		return

	_add_message(text)

	if _ordered_labels.size() > 1:
		return

	var timeout = 10.0
	while !_ordered_labels.is_empty():
		await get_tree().create_timer(timeout).timeout

		if !_ordered_labels.is_empty():
			var to_remove = _ordered_labels.pop_front()
			var to_tween = get_tree().create_tween().bind_node(to_remove)
			to_tween.tween_property(to_remove, "modulate:a", 0.0, 0.5)
			to_tween.tween_callback(to_remove.queue_free)

		if !_message_queue.is_empty():
			var next_msg = _message_queue.pop_front()
			_add_message(next_msg)

		if timeout > 4:
			timeout -= 3


func clear():
	_message_queue.clear()

	for message_label in _ordered_labels:
		message_label.queue_free()

	_ordered_labels.clear()