class_name City extends Node3D static var instance: City static var moving: bool = true static var controlling: bool = true static var delivered: bool = false @onready var block: PackedScene = preload("res://Scenes/Gameplay/block.tscn") @onready var speedRing: PackedScene = preload("res://Scenes/Gameplay/ring.tscn") @onready var slowRing: PackedScene = preload("res://Scenes/Gameplay/grinchRing.tscn") @onready var deliveryMarker: PackedScene = preload("res://Scenes/Gameplay/deliveryMarker.tscn") @onready var neighborhood: Node3D = $Neighborhood @onready var ringholder: Node3D = $Rings @export var animator: AnimationPlayer @export var ui: UI @export var hohoPlayer: AudioStreamPlayer @export var badPlayer: AudioStreamPlayer @export var houses: Array[PackedScene] @export var columns: int = 8 @export var rows: int = 15 @export var blockLength: float = 11 @export var blockScale: float = 10 @export var minDeliveryRange: int = 15 @export var maxDeliveryRange: int = 30 var distance: float = 0 var rowIndex: int = 0 var cellSize: float var santaRings: Array[SpeedRing] var grinchRings: Array[SpeedRing] var ringIndex: int = 0 var delivery: Area3D var deliveryHouse: Node3D var deliveryRow: int = 0 var streak: int = 0 func _enter_tree(): santaRings.resize(rows) grinchRings.resize(rows) if (instance == null || !is_instance_valid(instance)): instance = self else: queue_free() # Called when the node enters the scene tree for the first time. func _ready() -> void: cellSize = blockLength * blockScale delivery = deliveryMarker.instantiate() delivery.scale = Vector3(10, 10, 10) ringholder.add_child(delivery) pickHouse() for i in range(santaRings.size()): santaRings[i] = speedRing.instantiate() santaRings[i].scale = Vector3(5, 5, 5) santaRings[i].strength = 1.5 grinchRings[i] = slowRing.instantiate() grinchRings[i].scale = Vector3(5, 5, 5) grinchRings[i].strength = 0.5 ringholder.add_child(santaRings[i]) ringholder.add_child(grinchRings[i]) for y in range(rows): for x in range(columns): var road: Node3D = block.instantiate() road.position = Vector3((x - (float(columns - 2) / 2)) * cellSize, 0, rowIndex * -cellSize) neighborhood.add_child(road) var house: Node3D = houses.pick_random().instantiate() house.position = road.position + Vector3(-cellSize / 2, -0.2, -cellSize / 2) house.rotate_y(randi_range(0, 3) * (PI / 2)) neighborhood.add_child(house) rowIndex += 1 # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(_delta: float) -> void: if (rowIndex - (rows + 1) > deliveryRow): if (delivered): ui.showTitle("Present Delivered!") Sleigh.streak += 1 hohoPlayer.play() else: ui.showTitle("Delivery Failed") Sleigh.streak = 0 badPlayer.play() delivered = false pickHouse() if (distance >= cellSize): distance -= cellSize for i in range(columns * 2): neighborhood.get_child(i).queue_free() for i in range(columns): var road: Node3D = block.instantiate() road.position = Vector3((i - (float(columns - 2) / 2)) * cellSize, 0, rowIndex * -cellSize) neighborhood.add_child(road) var house: Node3D = houses.pick_random().instantiate() house.position = road.position + Vector3(-cellSize / 2, -0.2, -cellSize / 2) house.rotate_y(randi_range(0, 3) * (PI / 2)) if (house.position.distance_to(delivery.position) < 100): deliveryHouse = house neighborhood.add_child(house) if (santaRings[ringIndex].tween): santaRings[ringIndex].tween.kill() if (grinchRings[ringIndex].tween): grinchRings[ringIndex].tween.kill() santaRings[ringIndex].position = Vector3(randf_range(-25, 25), randf_range(50, 85), (rowIndex * -cellSize) - randf_range(0, cellSize * 0.8)) santaRings[ringIndex].scale = Vector3(5, 5, 5) grinchRings[ringIndex].position = Vector3(randf_range(-25, 25), randf_range(50, 85), (rowIndex * -cellSize) - randf_range(0, cellSize * 0.8)) grinchRings[ringIndex].scale = Vector3(5, 5, 5) ringIndex += 1 if (ringIndex >= santaRings.size()): ringIndex = 0 rowIndex += 1 func pickHouse() -> void: var blocksAhead: int = randi_range(minDeliveryRange, maxDeliveryRange) deliveryRow = blocksAhead + rowIndex var column: int = randi_range(0, 1) delivery.position = Vector3(-cellSize / 3 + column * cellSize * 2 / 3, 50, ((rowIndex + blocksAhead) * -cellSize) - cellSize / 2) func _on_back_pressed() -> void: get_tree().paused = false get_tree().root.add_child(load("res://Scenes/UI/MainMenu.tscn").instantiate()) instance = null moving = true controlling = true Sleigh.instance = null Sleigh.streak = 0 queue_free() func _on_timer_timeout(): City.controlling = false