extends Node var activated = false var effect_running = false var slowness_remaining = 0 var iceland_remaining = 0 var atbash_remaining = 0 var speed_boosts_remaining = 0 var queued_iceland = 0 var skip_available = false var puzzle_focused = false var solve_mode = false var not_behind_wall = false var puzzle_to_skip = "" var text_dirty = true var orig_env var orig_walk var orig_run var wallcast func _ready(): orig_env = get_tree().get_root().get_node("Spatial/player/pivot/camera").environment orig_walk = get_tree().get_root().get_node("Spatial/player").walk_speed orig_run = get_tree().get_root().get_node("Spatial/player").run_speed wallcast = get_tree().get_root().get_node("Spatial/player/pivot/camera/wallcast") var label = Label.new() label.set_name("label") label.margin_right = 1920.0 - 20.0 label.margin_top = 20.0 label.align = Label.ALIGN_RIGHT label.valign = Label.VALIGN_TOP var dynamic_font = DynamicFont.new() dynamic_font.font_data = load("res://fonts/Lingo.ttf") dynamic_font.size = 36 dynamic_font.outline_color = Color(0, 0, 0, 1) dynamic_font.outline_size = 2 label.add_font_override("font", dynamic_font) add_child(label) var slowness_timer = Timer.new() slowness_timer.name = "SlownessTimer" slowness_timer.wait_time = 1.0 add_child(slowness_timer) slowness_timer.connect("timeout", self, "_tick_slowness") var speed_boost_timer = Timer.new() speed_boost_timer.name = "SpeedBoostTimer" speed_boost_timer.wait_time = 1.0 add_child(speed_boost_timer) speed_boost_timer.connect("timeout", self, "_tick_speed_boost") var iceland_timer = Timer.new() iceland_timer.name = "IcelandTimer" iceland_timer.wait_time = 1.0 add_child(iceland_timer) iceland_timer.connect("timeout", self, "_tick_iceland") func activate(): activated = true if queued_iceland > 0: trigger_iceland_trap(queued_iceland) queued_iceland = 0 var apclient = global.get_node("Archipelago") if apclient._speed_boost_mode: var player = get_tree().get_root().get_node("Spatial/player") player.walk_speed = orig_walk / 2.0 player.run_speed = orig_run / 2.0 func trigger_slowness_trap(length = 30): if slowness_remaining == 0: var player = get_tree().get_root().get_node("Spatial/player") player.walk_speed = orig_walk / 2.0 player.run_speed = orig_run / 2.0 $SlownessTimer.start() slowness_remaining += length text_dirty = true var apclient = global.get_node("Archipelago") apclient.saveLocaldata() func trigger_speed_boost(length = 20): if speed_boosts_remaining == 0: var player = get_tree().get_root().get_node("Spatial/player") player.walk_speed = orig_walk player.run_speed = orig_run $SpeedBoostTimer.start() speed_boosts_remaining += length text_dirty = true var apclient = global.get_node("Archipelago") apclient.saveLocaldata() func trigger_iceland_trap(length = 60): if not activated: queued_iceland += length return if iceland_remaining == 0: get_tree().get_root().get_node("Spatial/player/pivot/camera").set_environment( load("res://environments/level_iceland.tres") ) $IcelandTimer.start() iceland_remaining += length text_dirty = true var apclient = global.get_node("Archipelago") apclient.saveLocaldata() func trigger_atbash_trap(): var newly_atbash = atbash_remaining == 0 atbash_remaining += 1 if newly_atbash: var apclient = global.get_node("Archipelago") apclient.evaluateSolvability() text_dirty = true var apclient = global.get_node("Archipelago") apclient.saveLocaldata() func deactivate_atbash_trap(): if atbash_remaining > 0: atbash_remaining -= 1 if atbash_remaining == 0: var apclient = global.get_node("Archipelago") apclient.evaluateSolvability() text_dirty = true var apclient = global.get_node("Archipelago") apclient.saveLocaldata() func show_puzzle_skip_message(node_path): if puzzle_focused and node_path != puzzle_to_skip: hide_puzzle_skip_message() var panel_input = get_tree().get_root().get_node(node_path) if not panel_input.visible: return var ap_panel = panel_input.get_parent().get_parent().get_parent().get_parent().get_node_or_null( "AP_Panel" ) if ap_panel == null or not ap_panel.solvable: return puzzle_focused = true wallcast.enabled = true not_behind_wall = false text_dirty = true puzzle_to_skip = node_pat
This map is a bit of a mess. The top areas should make sense but the bottom area
is confusing because of the fact that many panels can be seen from multiple
places in the grid, and it is intended for you to solve them through the
transparent doors. The approach to this is threefold.

1. Panels that can be solved without opening any doors are all in the Entry
   region. This includes the two panels physically accessible from the warp
   hallways, as well as the two panels each that can be seen while standing next
   to those panels, for a total of six panels in the Entry region (plus the two
   that are actually upstairs).
2. The part of the grid behind where you enter is actually completely linear.
   There is one region for each grid square in this area, except for the middle
   two in the orange row. The regions are named after the positions you stand
   in, not the panels at those positions in the grid. Instead, each region
   contains the panel you can see from that position. This is why the two middle
   orange grid squares do not have regions, because they are solvable from the
   red row and entering the regions does nothing.
3. For the rest of the grid, each panel is visible from two other grid
   positions. To handle this, there is a region for every grid position you can
   stand in, and a region for every panel. The standing regions are connected to
   each adjacent grid square using event doors, and there is a oneway connection
   from each standing region into the panel regions for each panel that can be
   seen from that standing position.