# Hurry Curry! - a game about cooking # Copyright 2024 tpart # Copyright 2024, 2025 nokoe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, version 3 of the License only. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # extends Node3D class_name Character const DEFAULT_MAIN_MESH = preload("res://player/character/default/main.res") const CUSTOMER_MAIN_MESH = preload("res://player/character/customer_body.res") const WALK_ANIM_STRENGTH := 0.05 const WALK_ANIM_SPEED:= 15.0 enum CharacterKind { PERSON, BOT, TRAM } var walking := false var holding := false var boosting := false var cutting := false var was_boosting := boosting var current_animation := "idle" @onready var hand_animations = $HandAnimations @onready var main = $Main @onready var default_height = main.position.y @onready var main_height_target = default_height @onready var walking_particles = $Walking @onready var boosting_particles = $Boosting @onready var username_tag = $Username @onready var tie = $Main/Tie @onready var knife = $Main/HandRight/Knife @onready var cat_ears: CatEars = $Main/HeadDefault/CatEars const NUM_COLORS = 5; const NUM_HAIRS = 3; @onready var hairstyles := [$Main/HeadDefault/Hair, $Main/HeadDefault/Hair2, $Main/HeadDefault/Hair3] const COLORS: Array[Color] = [ Color(0.204, 0.361, 0.624), Color(0.568, 0.256, 0.602), Color(0.575, 0.341, 0.117), Color(0.3, 0.455, 0.221), Color(0.101, 0.452, 0.521) ] @onready var head_default: MeshInstance3D = $Main/HeadDefault @onready var head_robot: MeshInstance3D = $Main/HeadRobot @onready var step_sounds: PlayRandom = $Steps @onready var boost_sounds: PlayRandom = $Boosts class ParsedStyle: var color: int var hair: int var kind: CharacterKind = CharacterKind.PERSON var customer: bool var cat_ears: bool func _init(n: int) -> void: customer = n < 0 if customer: n *= -1 if n == 51: kind = CharacterKind.BOT elif n == 52: kind = CharacterKind.TRAM else: hair = n % NUM_HAIRS color = n / NUM_HAIRS % NUM_COLORS cat_ears = floor(n / 4) % 2 == 0 func pack() -> int: if CharacterKind.BOT: return 51 elif CharacterKind.TRAM: return 52 return (hair + color * NUM_HAIRS) * (-1 if customer else 1) func _ready(): play_animation("idle") var t := 0.0 func _process(delta): t += delta if walking: main_height_target = default_height + sin(t * WALK_ANIM_SPEED) * WALK_ANIM_STRENGTH cat_ears.ear_target = sin(t * WALK_ANIM_SPEED) * 0.075 else: t = 0 cat_ears.ear_target = 0. main.position.y = G.interpolate(main.position.y, main_height_target, delta * 10.) # Update animation: var next_animation: String if holding: next_animation = "hold" elif cutting: next_animation = "cut" elif walking: next_animation = "walk" else: next_animation = "idle" if current_animation != next_animation: play_animation(next_animation) walking_particles.emitting = walking if boosting and walking and not was_boosting: boosting_particles.emitting = true boost_sounds.play_random() else: boosting_particles.emitting = false was_boosting = boosting and walking func set_style(id: int): var p := ParsedStyle.new(id) main.mesh = CUSTOMER_MAIN_MESH if p.customer else DEFAULT_MAIN_MESH if p.customer: tie.queue_free() head_robot.visible = p.kind == CharacterKind.BOT head_default.visible = p.kind == CharacterKind.PERSON $Main.visible = not p.kind == CharacterKind.TRAM $Tram.visible = p.kind == CharacterKind.TRAM cat_ears.visible = p.cat_ears for h in hairstyles: h.hide() hairstyles[p.hair].show() $Main.get_active_material(0).albedo_color = Color(0.349, 0.349, 0.349) if p.kind == CharacterKind.BOT else COLORS[p.color] if p.cat_ears: cat_ears.set_inner_mat($Main.get_active_material(0)) cat_ears.set_outer_mat(hairstyles[p.hair].get_active_material(0)) func play_animation(name_: String): current_animation = name_ hand_animations.play(name_) if name_ == "walk": step_sounds.start_autoplay() else: step_sounds.stop_autoplay() knife.visible = name_ == "cut" func _on_hand_animations_animation_finished(_name): hand_animations.play(current_animation)