extends PanelContainer # Floor state var current_floor := 10 var saved_count := 0 var doors_closing_flag := false var _onboarded := false # Survivors per floor: more at top, fewer as you descend var base_survivors := 2 var survivors_per_floor_increase := 1 # per floor above ground var survivors_remaining := 0 # Flat threshold: must save at least this many per floor var threshold := 2 # Scoring var score := 0 var points_per_person := 100 # base + bonus per person above threshold var people_in_elevator := 0 func _ready(): var button = $PanelMargin/PanelColumn/CloseButton button.text = "BLOCK" button.pressed.connect(_on_block_pressed) var screen = $PanelMargin/PanelColumn/Screen screen.pulse_blocked.connect(_on_pulse_blocked) screen.doors_closing.connect(_on_doors_closing) 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() # --- Floor lifecycle --- func _start_floor(): $SfxOpen.play() doors_closing_flag = false people_in_elevator = 0 # More survivors on higher floors, fewer near the ground 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 screen = $PanelMargin/PanelColumn/Screen screen.start() if not _onboarded: _onboarded = true screen.show_onboarding("BLOCK\nIN GREEN ZONE") get_tree().create_timer(3.0).timeout.connect( func(): screen.end_onboarding() screen.launch_pulse(), CONNECT_ONE_SHOT ) else: screen.launch_pulse() # first survivor arrives # --- Input --- func _on_block_pressed(): if doors_closing_flag: return $PanelMargin/PanelColumn/Screen.attempt_block() # --- Pulse callbacks --- func _on_pulse_blocked(): # This survivor made it in survivors_remaining -= 1 people_in_elevator += 1 $SfxDing.play() EventBus.people_changed.emit(people_in_elevator, threshold) if survivors_remaining <= 0: # Everyone's in, close doors (auto-success). Brief delay so the # last ding doesn't collide with the close sound. get_tree().create_timer(0.25).timeout.connect(_on_doors_closing, CONNECT_ONE_SHOT) return # More survivors approaching: launch next pulse after gap 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(): if doors_closing_flag: return doors_closing_flag = true var screen = $PanelMargin/PanelColumn/Screen # Lose: not enough people if people_in_elevator < threshold: screen.show_loss("TOO FEW") EventBus.game_lost.emit() return # Score this floor 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 # Win: reached ground floor if current_floor <= 1: screen.show_win() EventBus.floor_changed.emit(current_floor) EventBus.game_won.emit() return # Next floor after countdown $SfxClose.play() screen.show_countdown() screen.shrink_block_zone() var tween = create_tween() tween.tween_interval(2.0) tween.tween_callback(_start_floor)