tojam20-elevator/scenes/world.gd

83 lines
2.6 KiB
GDScript

extends Node3D
const DIM_FACTOR := 0.5
const DIM_DURATION := 0.5
const WALL_DISPLAY_COLOR := Color(0.83, 0.63, 0.09)
const RobotScene := preload("res://scenes/robot.tscn")
@onready var _wall_display: Label3D = $ElevatorSafeZone/Elevator/WallDisplay
@onready var _hum: AudioStreamPlayer3D = $ElevatorSafeZone/Elevator/ElevatorHum
@onready var _robot_spawn: Marker3D = %RobotSpawn
var _dim_targets: Array = []
var _original_modulates: Array[Color] = []
var _modulate_tween: Tween = null
var _current_floor: int = EventBus.STARTING_FLOOR
var _robot: Node3D = null
func _ready() -> void:
_collect_dim_targets()
_wall_display.modulate = WALL_DISPLAY_COLOR
_wall_display.text = str(_current_floor)
EventBus.doors_closed.connect(_on_doors_closed)
EventBus.doors_fully_closed.connect(_free_robot_unless_winning)
EventBus.doors_opened.connect(_on_doors_opened)
EventBus.floor_changed.connect(_on_floor_changed)
EventBus.game_lost.connect(func(_reason: String): _free_robot_unless_winning())
EventBus.game_won.connect(_free_robot)
func _collect_dim_targets() -> void:
for path in [
"ElevatorSafeZone/Elevator/ElevatorWallLeft/Wall",
"ElevatorSafeZone/Elevator/ElevatorWallRight/Wall",
"ElevatorSafeZone/Elevator/ElevatorDoorLeft/Panel",
"ElevatorSafeZone/Elevator/ElevatorDoorRight/Panel",
]:
var node := get_node_or_null(path)
if node and node is GeometryInstance3D:
_dim_targets.append(node)
_original_modulates.append(node.modulate)
func _on_doors_closed(_fast: bool) -> void:
_tween_dim(DIM_FACTOR)
if _hum.stream:
_hum.play()
var next_floor: int = max(1, _current_floor - 1)
_wall_display.text = str(next_floor)
func _on_doors_opened() -> void:
_tween_dim(1.0)
_hum.stop()
_spawn_robot()
func _spawn_robot() -> void:
_free_robot()
_robot = RobotScene.instantiate()
_robot.position = _robot_spawn.position
_robot.safety_zone = $ElevatorSafeZone
add_child(_robot)
func _free_robot() -> void:
if is_instance_valid(_robot):
_robot.queue_free()
_robot = null
func _free_robot_unless_winning() -> void:
if is_instance_valid(_robot) and _robot.robot_win:
return
_free_robot()
func _on_floor_changed(new_floor: int) -> void:
_current_floor = new_floor
_wall_display.text = str(new_floor)
func _tween_dim(factor: float) -> void:
if _modulate_tween:
_modulate_tween.kill()
_modulate_tween = create_tween()
_modulate_tween.set_parallel(true)
for i in _dim_targets.size():
var node: GeometryInstance3D = _dim_targets[i]
var base: Color = _original_modulates[i]
var target := Color(base.r * factor, base.g * factor, base.b * factor, base.a)
_modulate_tween.tween_property(node, "modulate", target, DIM_DURATION)