extends CharacterBody3D signal station_reached const BASE_STAMINA = 50 const BASE_SPEED = 20 const SPRINT_MULT = 1.6 const SLOW_MULT = 0.5 const STAMINA_COST = 15 const STAMINA_RECOVER = 10 const SCORE_RANK = { "C": { "time": 10, "money": 500, "special": 0, "color": Color.BROWN }, "B": { "time": 20, "money": 1000, "special": 0, "color": Color.PURPLE }, "A": { "time": 30, "money": 1500, "special": 1, "color": Color.GREEN }, "S": { "time": 999, "money": 2000, "special": 1, "color": Color.YELLOW }, } var pedestrian_area_count = 0 var max_stamina: float = BASE_STAMINA var stamina: float = max_stamina # ---- Pickups ---- const BASE_BONUS_TIME_AMOUNT = 30 # seconds const BASE_SPEED_BOOST_FACTOR = 2 var bonus_time_amount: float = BASE_BONUS_TIME_AMOUNT # seconds var speed_boost_factor: float = BASE_SPEED_BOOST_FACTOR var stage_counter: int = 0 var is_active: bool = true func _ready() -> void: $Upgrades.update() $Shop.upgrade_node = $Upgrades $Shop.populate() $Shop.visible = false $FailControl.visible = false $FinishControl.visible = false is_active = true $HUD.visible = true $TimeLimit.start() func _process(delta: float) -> void: # On fail screen, ignore further input if not is_active: return $HUD/StaminaRect.scale.x = stamina / max_stamina $HUD/StageLabel.text = "Stage %d" % [stage_counter + 1] var time_left = int($TimeLimit.time_left) @warning_ignore("integer_division") $HUD/TimeLimitLabel.text = "%02d:%02d" % [time_left/60, time_left - (time_left/60) * 60] var dir = Input.get_vector("player_move_left", "player_move_right", "player_move_up", "player_move_down") var speed: float = BASE_SPEED if $SpeedBoostTimer.time_left > 0: speed *= speed_boost_factor if (pedestrian_area_count > 0): speed *= SLOW_MULT if Input.is_action_pressed("player_sprint") and stamina > 0: stamina -= STAMINA_COST * delta speed *= SPRINT_MULT elif stamina <= max_stamina: stamina += STAMINA_RECOVER * delta self.velocity = Vector3(dir.x * speed, 0, dir.y * speed) self.move_and_slide() func _on_area_area_entered(area: Area3D) -> void: if area.name == "PedestrianArea": pedestrian_area_count += 1 print(pedestrian_area_count) if area.name == "StationArea": $FinishControl.visible = true $HUD.visible = false var scoreLbl = $FinishControl/ScoreLabel for letter in SCORE_RANK: var rank = SCORE_RANK[letter] if $TimeLimit.time_left > rank["time"]: continue $Shop.available_money += rank["money"] $Shop.special_currency += rank["special"] scoreLbl.text = letter scoreLbl.add_theme_color_override("font_color", rank["color"]) $FinishControl/DescLabel.text = """ Diners guanyat: %s pessetes Diners total: %d pessetes 🥘s guanyat: %d 🥘 🥘s totals: %d 🥘 """ % [rank["money"], $Shop.available_money, rank["special"], $Shop.special_currency] break $TimeLimit.stop() is_active = false func _on_area_area_exited(area: Area3D) -> void: if area.name == "PedestrianArea": pedestrian_area_count -= 1 print(pedestrian_area_count) func _on_time_limit_timeout(): is_active = false $FailControl.visible = true $HUD.visible = false func _on_retry_button_pressed(): stage_counter = 0 $FailControl.visible = false $HUD.visible = true station_reached.emit() is_active = true $TimeLimit.start() stamina = max_stamina func _on_continue_button_pressed(): $FinishControl.visible = false $Shop.visible = true func _on_shop_shop_exit() -> void: is_active = true $Shop.visible = false stage_counter += 1 station_reached.emit() $TimeLimit.start() $HUD.visible = true stamina = max_stamina