extends PanelContainer var current_floor := 10 var saved_count := 0 var doors_closing_flag := false var _onboarded := false var base_survivors := 2 var survivors_per_floor_increase := 1 var survivors_remaining := 0 var threshold := 2 var score := 0 var points_per_person := 100 const MOVING_ZONE_START_FLOOR := 7 const MOVING_ZONE_BASE_SPEED := 40.0 const MOVING_ZONE_SPEED_PER_FLOOR := 12.0 var robot_speed_top := 1.0 var robot_speed_per_floor := 0.15 var robot_delay_top := 8.0 var robot_delay_per_floor := 0.6 var robot_delay_min := 1.0 var people_in_elevator := 0 const PERFECT_STUN_DURATION := 0.25 const PRE_PULSE_DELAY := 3.5 func _ready(): var button = $PanelMargin/PanelColumn/CloseButton button.text = "CLOSE" button.pressed.connect(_on_block_pressed) var screen = $PanelMargin/PanelColumn/Screen screen.pulse_started.connect(_on_pulse_started) screen.pulse_blocked.connect(_on_pulse_blocked) screen.pulse_blocked_perfect.connect(_on_pulse_blocked_perfect) screen.doors_closing.connect(func(): _on_doors_closing(true)) EventBus.game_started.connect(_start_floor) func _unhandled_input(event): if event is InputEventKey and event.pressed and not event.echo: if event.keycode == KEY_SPACE: _on_block_pressed() elif event.keycode == KEY_R: get_tree().reload_current_scene() func _start_floor(): $SfxOpen.play() $SfxBell.play() doors_closing_flag = false people_in_elevator = 0 $PanelMargin/PanelColumn/CloseButton.text = "CLOSE" EventBus.doors_opened.emit() var floors_remaining = current_floor - 1 survivors_remaining = base_survivors + (floors_remaining * survivors_per_floor_increase) EventBus.people_changed.emit(people_in_elevator, threshold) EventBus.floor_changed.emit(current_floor) EventBus.floor_started.emit(survivors_remaining) var floors_descended = 10 - current_floor var robot_speed = robot_speed_top + floors_descended * robot_speed_per_floor var robot_delay = max(robot_delay_min, robot_delay_top - floors_descended * robot_delay_per_floor) EventBus.robot_floor_started.emit(robot_delay, robot_speed) var screen = $PanelMargin/PanelColumn/Screen screen.start(current_floor) if current_floor <= MOVING_ZONE_START_FLOOR: var floors_below = MOVING_ZONE_START_FLOOR - current_floor screen.set_block_zone_movement(MOVING_ZONE_BASE_SPEED + floors_below * MOVING_ZONE_SPEED_PER_FLOOR) if not _onboarded: _onboarded = true screen.show_onboarding("BLOCK\nIN GREEN ZONE") get_tree().create_timer(3.0).timeout.connect( func(): if not is_instance_valid(screen): return screen.end_onboarding() screen.launch_pulse(), CONNECT_ONE_SHOT ) else: get_tree().create_timer(PRE_PULSE_DELAY).timeout.connect( func(): if not is_instance_valid(self) or doors_closing_flag: return screen.launch_pulse(), CONNECT_ONE_SHOT ) func _on_block_pressed(): if doors_closing_flag: return var screen = $PanelMargin/PanelColumn/Screen if screen.pulse_active: screen.attempt_block() else: _on_doors_closing(false) func _on_pulse_started(duration: float): $PanelMargin/PanelColumn/CloseButton.text = "BLOCK" EventBus.pulse_started.emit(duration) func _on_pulse_blocked_perfect(): EventBus.robot_stun_requested.emit(PERFECT_STUN_DURATION) func _on_pulse_blocked(): $PanelMargin/PanelColumn/CloseButton.text = "CLOSE" EventBus.pulse_blocked.emit() survivors_remaining -= 1 people_in_elevator += 1 $SfxDing.play() EventBus.people_changed.emit(people_in_elevator, threshold) if survivors_remaining <= 0: get_tree().create_timer(0.25).timeout.connect(_on_doors_closing, CONNECT_ONE_SHOT) return var screen = $PanelMargin/PanelColumn/Screen var gap = screen.get_pulse_gap() get_tree().create_timer(gap).timeout.connect( func(): if not doors_closing_flag: screen.launch_pulse(), CONNECT_ONE_SHOT ) func _on_doors_closing(fast: bool = false): if doors_closing_flag: return doors_closing_flag = true EventBus.doors_closed.emit(fast) var screen = $PanelMargin/PanelColumn/Screen if people_in_elevator < threshold: screen.show_loss("TOO FEW") EventBus.game_lost.emit("TOO FEW") return var base_points = people_in_elevator * points_per_person var bonus = max(0, people_in_elevator - threshold) * points_per_person score += base_points + bonus saved_count += people_in_elevator EventBus.score_changed.emit(score) EventBus.saved_changed.emit(saved_count) current_floor -= 1 if current_floor <= 1: screen.show_win() EventBus.floor_changed.emit(current_floor) EventBus.game_won.emit() return $SfxClose.play() screen.show_countdown() screen.shrink_block_zone() var tween = create_tween() tween.tween_interval(3.0) tween.tween_callback(_start_floor)