aboutsummaryrefslogtreecommitdiff
path: root/client/player/character/character.gd
blob: 8479af2c625bec1d5013aeab364a192ee2c8990f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# 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 <https://www.gnu.org/licenses/>.
#
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

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 tram = $Tram
@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
const NUM_HEADWEARS = 2
@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

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(style: Dictionary, character_class: String):
	var is_human := character_class == "customer" || character_class == "chef"
	
	main.mesh = CUSTOMER_MAIN_MESH if character_class == "customer" else DEFAULT_MAIN_MESH
	tie.visible = character_class != "customer"
	head_robot.visible = character_class == "bot"
	head_default.visible = is_human
	main.visible = character_class != "tram"
	tram.visible = character_class == "tram"
	cat_ears.visible = style.headwear == 1
	for h in hairstyles: h.hide()
	var my_hairstyle = hairstyles[G.rem_euclid(style.hairstyle, NUM_HAIRS)]
	my_hairstyle.show()
	main.get_active_material(0).albedo_color = Color(0.349, 0.349, 0.349) if character_class == "bot" else COLORS[G.rem_euclid(style.color, NUM_COLORS)]
	if cat_ears.visible:
		cat_ears.set_inner_mat(main.get_active_material(0))
		cat_ears.set_outer_mat(my_hairstyle.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)