aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/game.gd8
-rw-r--r--client/global.gd14
-rw-r--r--client/menu/character.gd32
-rw-r--r--client/menu/character.tscn70
-rw-r--r--client/menu/hairstyle_preview.gd13
-rw-r--r--client/menu/setup.gd9
-rw-r--r--client/multiplayer.gd4
-rw-r--r--client/player/character/character.gd63
-rw-r--r--client/player/player.gd20
9 files changed, 150 insertions, 83 deletions
diff --git a/client/game.gd b/client/game.gd
index e516615a..5b0062f9 100644
--- a/client/game.gd
+++ b/client/game.gd
@@ -113,13 +113,13 @@ func handle_packet(p):
"add_player":
var player_instance: Player
if p.id == player_id:
- player_instance = ControllablePlayer.new(p.id, p.name, p.position, p.character, self)
+ player_instance = ControllablePlayer.new(p.id, p.name, p.position, p.character, p.class, self)
in_lobby_updated.connect(player_instance.onscreen_controls.in_lobby_updated)
player_instance.onscreen_controls.in_lobby_updated(in_lobby)
camera.target = player_instance.movement_base
set_join_state(JoinState.JOINED)
else:
- player_instance = Player.new(p.id, p.name, p.position, p.character, self)
+ player_instance = Player.new(p.id, p.name, p.position, p.character, p.class, self)
players[p.id] = player_instance
add_child(player_instance)
update_players.emit(players)
@@ -361,7 +361,7 @@ func toggle_join():
match join_state:
JoinState.SPECTATING:
set_join_state(JoinState.WAITING)
- mp.send_join(Global.get_profile("username"), Global.get_profile("character"))
+ mp.send_join(Global.get_profile("username"), Global.get_profile("character_style"))
JoinState.WAITING:
push_error("Join/Leave action already toggled.")
JoinState.JOINED:
@@ -412,7 +412,7 @@ func spectate_center():
var player_center: Vector3 = Vector3(0.,0.,0.)
for v in players.values():
var p: Player = v
- if p.character_idx >= 0:
+ if !p.is_customer:
player_sum += 1
player_center += p.movement_base.position
sum += 1
diff --git a/client/global.gd b/client/global.gd
index 56566bbe..8fd50ac6 100644
--- a/client/global.gd
+++ b/client/global.gd
@@ -26,7 +26,11 @@ const VERSION := "2.3.1"
var default_profile := {
"username": "Giovanni",
- "character": 0,
+ "character_style": {
+ "color": 0,
+ "headwear": 0,
+ "hairstyle": 0
+ },
"last_server_url": "",
"tutorial_ingredients_played": [],
"registry_asked": false,
@@ -277,3 +281,11 @@ static func index_to_hand(i):
0: return "left"
1: return "right"
_: return "unknown"
+
+static func rem_euclid(i: int, mod: int) -> int:
+ var num := i % mod
+ if num < 0:
+ num += mod
+ num %= mod
+ return num
+
diff --git a/client/menu/character.gd b/client/menu/character.gd
index fb224dd7..f40aeffb 100644
--- a/client/menu/character.gd
+++ b/client/menu/character.gd
@@ -25,7 +25,7 @@ extends Menu
func _ready():
super()
$VBoxContainer/top_panel/a/username.text = Global.get_profile("username")
- character.set_style(Global.get_profile("character"))
+ character.set_style(Global.get_profile("character_style"), "chef")
init_map()
func init_map():
@@ -73,9 +73,31 @@ func _on_back_pressed():
replace_menu("res://menu/main.tscn")
func _on_character_back_pressed():
- Global.set_profile("character", max(Global.get_profile("character") - 1, 0))
- character.set_style(Global.get_profile("character"))
+ modify_style(func m(current_style: Dictionary):
+ current_style.color = G.rem_euclid(current_style.color - 1, character.NUM_COLORS))
func _on_character_forward_pressed():
- Global.set_profile("character", max(Global.get_profile("character") + 1, 0))
- character.set_style(Global.get_profile("character"))
+ modify_style(func m(current_style: Dictionary):
+ current_style.color = G.rem_euclid(current_style.color + 1, character.NUM_COLORS))
+
+func _on_headwear_back_pressed() -> void:
+ modify_style(func m(current_style: Dictionary):
+ current_style.headwear = G.rem_euclid(current_style.headwear - 1, character.NUM_HEADWEARS))
+
+func _on_headwear_forward_pressed() -> void:
+ modify_style(func m(current_style: Dictionary):
+ current_style.headwear = G.rem_euclid(current_style.headwear + 1, character.NUM_HEADWEARS))
+
+func _on_hairstyle_back_pressed() -> void:
+ modify_style(func m(current_style: Dictionary):
+ current_style.hairstyle = G.rem_euclid(current_style.hairstyle - 1, character.NUM_HAIRS))
+
+func _on_hairstyle_forward_pressed() -> void:
+ modify_style(func m(current_style: Dictionary):
+ current_style.hairstyle = G.rem_euclid(current_style.hairstyle + 1, character.NUM_HAIRS))
+
+func modify_style(modifier: Callable):
+ var current_style: Dictionary = Global.get_profile("character_style")
+ modifier.call(current_style)
+ Global.set_profile("character_style", current_style)
+ character.set_style(Global.get_profile("character_style"), "chef")
diff --git a/client/menu/character.tscn b/client/menu/character.tscn
index e5ec1292..f640e7cc 100644
--- a/client/menu/character.tscn
+++ b/client/menu/character.tscn
@@ -101,11 +101,11 @@ theme_override_constants/margin_bottom = 50
layout_mode = 2
alignment = 1
-[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/Spacer/VBoxContainer"]
+[node name="Headware" type="HBoxContainer" parent="VBoxContainer/Spacer/VBoxContainer"]
layout_mode = 2
alignment = 1
-[node name="Back" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/HBoxContainer"]
+[node name="Back" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Headware"]
layout_mode = 2
focus_neighbor_right = NodePath("../Forward")
texture_normal = ExtResource("5_kvd7k")
@@ -114,11 +114,61 @@ texture_hover = ExtResource("6_soj8g")
texture_focused = ExtResource("6_u31hl")
flip_h = true
-[node name="Spacer" type="Control" parent="VBoxContainer/Spacer/VBoxContainer/HBoxContainer"]
+[node name="Spacer" type="Control" parent="VBoxContainer/Spacer/VBoxContainer/Headware"]
layout_mode = 2
size_flags_horizontal = 3
-[node name="Forward" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/HBoxContainer"]
+[node name="Forward" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Headware"]
+layout_mode = 2
+focus_neighbor_left = NodePath("../Back")
+texture_normal = ExtResource("5_kvd7k")
+texture_pressed = ExtResource("5_xpff8")
+texture_hover = ExtResource("6_soj8g")
+texture_focused = ExtResource("6_u31hl")
+
+[node name="Hairstyle" type="HBoxContainer" parent="VBoxContainer/Spacer/VBoxContainer"]
+layout_mode = 2
+alignment = 1
+
+[node name="Back" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Hairstyle"]
+layout_mode = 2
+focus_neighbor_right = NodePath("../Forward")
+texture_normal = ExtResource("5_kvd7k")
+texture_pressed = ExtResource("5_xpff8")
+texture_hover = ExtResource("6_soj8g")
+texture_focused = ExtResource("6_u31hl")
+flip_h = true
+
+[node name="Spacer" type="Control" parent="VBoxContainer/Spacer/VBoxContainer/Hairstyle"]
+layout_mode = 2
+size_flags_horizontal = 3
+
+[node name="Forward" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Hairstyle"]
+layout_mode = 2
+focus_neighbor_left = NodePath("../Back")
+texture_normal = ExtResource("5_kvd7k")
+texture_pressed = ExtResource("5_xpff8")
+texture_hover = ExtResource("6_soj8g")
+texture_focused = ExtResource("6_u31hl")
+
+[node name="Character" type="HBoxContainer" parent="VBoxContainer/Spacer/VBoxContainer"]
+layout_mode = 2
+alignment = 1
+
+[node name="Back" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Character"]
+layout_mode = 2
+focus_neighbor_right = NodePath("../Forward")
+texture_normal = ExtResource("5_kvd7k")
+texture_pressed = ExtResource("5_xpff8")
+texture_hover = ExtResource("6_soj8g")
+texture_focused = ExtResource("6_u31hl")
+flip_h = true
+
+[node name="Spacer" type="Control" parent="VBoxContainer/Spacer/VBoxContainer/Character"]
+layout_mode = 2
+size_flags_horizontal = 3
+
+[node name="Forward" type="TextureButton" parent="VBoxContainer/Spacer/VBoxContainer/Character"]
layout_mode = 2
focus_neighbor_left = NodePath("../Back")
texture_normal = ExtResource("5_kvd7k")
@@ -150,10 +200,10 @@ text = "c.menu.back"
visible = false
layout_mode = 1
-[connection signal="focus_entered" from="VBoxContainer/Spacer/VBoxContainer/HBoxContainer/Back" to="." method="_on_back_focus_entered"]
-[connection signal="focus_exited" from="VBoxContainer/Spacer/VBoxContainer/HBoxContainer/Back" to="." method="_on_back_focus_exited"]
-[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/HBoxContainer/Back" to="." method="_on_character_back_pressed"]
-[connection signal="focus_entered" from="VBoxContainer/Spacer/VBoxContainer/HBoxContainer/Forward" to="." method="_on_forward_focus_entered"]
-[connection signal="focus_exited" from="VBoxContainer/Spacer/VBoxContainer/HBoxContainer/Forward" to="." method="_on_forward_focus_exited"]
-[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/HBoxContainer/Forward" to="." method="_on_character_forward_pressed"]
+[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/Headware/Back" to="." method="_on_headwear_back_pressed"]
+[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/Headware/Forward" to="." method="_on_headwear_forward_pressed"]
+[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/Hairstyle/Back" to="." method="_on_hairstyle_back_pressed"]
+[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/Hairstyle/Forward" to="." method="_on_hairstyle_forward_pressed"]
+[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/Character/Back" to="." method="_on_character_back_pressed"]
+[connection signal="pressed" from="VBoxContainer/Spacer/VBoxContainer/Character/Forward" to="." method="_on_character_forward_pressed"]
[connection signal="pressed" from="VBoxContainer/bottom_panel/back" to="." method="_on_back_pressed"]
diff --git a/client/menu/hairstyle_preview.gd b/client/menu/hairstyle_preview.gd
index 08b6aab9..415f5c21 100644
--- a/client/menu/hairstyle_preview.gd
+++ b/client/menu/hairstyle_preview.gd
@@ -1,4 +1,5 @@
# Hurry Curry! - a game about cooking
+# Copyright 2025 tpart
# Copyright 2024 nokoe
#
# This program is free software: you can redistribute it and/or modify
@@ -16,10 +17,12 @@
class_name HairstylePreview
extends VBoxContainer
-signal selected(character: int)
+signal selected(character_style: Dictionary)
-func setup(character: int, group: ButtonGroup):
- $HairViewport/Node3D/Character.set_style(character)
+func setup(hairstyle: int, group: ButtonGroup):
+ var character_style = Global.default_profile.character_style
+ character_style.hairstyle = hairstyle
+ $HairViewport/Node3D/Character.set_style(character_style, "chef")
$Select.button_group = group
- $Select.text = tr("c.setup.uniform.value").format([character + 1])
- $Select.pressed.connect(func(): selected.emit(character))
+ $Select.text = tr("c.setup.uniform.value").format([hairstyle + 1])
+ $Select.pressed.connect(func(): selected.emit(character_style))
diff --git a/client/menu/setup.gd b/client/menu/setup.gd
index 21fbc526..f38f0bf7 100644
--- a/client/menu/setup.gd
+++ b/client/menu/setup.gd
@@ -19,7 +19,7 @@ extends Menu
const SCROLL_SPEED := 500.
-var character := -1
+var character_style = null # : Dictionary?
@onready var anim: AnimationPlayer = $AnimationPlayer
@onready var username: LineEdit = $ScrollContainer/Control/TextureRect/PaperMargin/Contents/NameEntry/LineEdit
@@ -48,8 +48,8 @@ func _ready():
super()
-func _character_selected(idx: int):
- character = idx
+func _character_selected(style: Dictionary):
+ character_style = style
func _process(delta):
var s = Input.get_axis("rotate_up", "rotate_down")
@@ -58,7 +58,7 @@ func _process(delta):
func check():
if username.text == "": return tr("c.error.empty_username")
- if character == -1: return tr("c.error.select_hairstyle")
+ if character_style == null: return tr("c.error.select_hairstyle")
return null
func _on_sign_pressed():
@@ -79,6 +79,7 @@ func _on_sign_pressed():
await anim.animation_finished
Global.set_profile("username", username.text)
+ Global.set_profile("character_style", character_style)
if skip_tutorial.button_pressed:
for k in Global.profile["hints"].keys():
Global.set_hint(k, true)
diff --git a/client/multiplayer.gd b/client/multiplayer.gd
index a9006a0e..e2459eb3 100644
--- a/client/multiplayer.gd
+++ b/client/multiplayer.gd
@@ -91,11 +91,11 @@ func handle_packet(coded):
connection_closed.emit(tr("c.error.version_mismatch").format([major, minor, VERSION_MAJOR, VERSION_MINOR]))
_: packet.emit(p)
-func send_join(player_name: String, character: int):
+func send_join(player_name: String, character_style: Dictionary):
send_packet({
"type": "join",
"name": player_name,
- "character": character
+ "character": character_style
})
func send_movement(player, pos: Vector2, direction: Vector2, boost: bool):
diff --git a/client/player/character/character.gd b/client/player/character/character.gd
index 938c7c45..8479af2c 100644
--- a/client/player/character/character.gd
+++ b/client/player/character/character.gd
@@ -23,12 +23,6 @@ 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
@@ -39,6 +33,7 @@ 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
@@ -48,8 +43,9 @@ var current_animation := "idle"
@onready var knife = $Main/HandRight/Knife
@onready var cat_ears: CatEars = $Main/HeadDefault/CatEars
-const NUM_COLORS = 5;
-const NUM_HAIRS = 3;
+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),
@@ -65,26 +61,6 @@ const COLORS: Array[Color] = [
@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")
@@ -117,22 +93,23 @@ func _process(delta):
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
+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()
- 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))
+ 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_
diff --git a/client/player/player.gd b/client/player/player.gd
index 031cba29..b483c31d 100644
--- a/client/player/player.gd
+++ b/client/player/player.gd
@@ -43,7 +43,8 @@ var clear_timer: Timer = Timer.new()
var hand = [null, null]
var hand_base
-var character_idx: int
+var character_style: Dictionary
+var player_class: String
var is_customer: bool
var current_item_message = null
@@ -53,15 +54,15 @@ const DEFAULT_HAND_BASE_POSITION_CENTER: Vector3 = Vector3(0, .425, .4)
const DEFAULT_HAND_BASE_POSITION_LEFT: Vector3 = Vector3(.3, .425, .4)
const DEFAULT_HAND_BASE_POSITION_RIGHT: Vector3 = Vector3(-.3, .425, .4)
-func _init(_id: int, new_name: String, pos: Vector2, new_character_idx: int, new_game: Game):
+func _init(_id: int, name_: String, pos: Vector2, character_style: Dictionary, player_class: String, game: Game):
add_child(movement_base)
movement_base.add_child(character)
position_ = pos
position_anim = pos
- if new_name != "":
- name = new_name
- game = new_game
- username = new_name
+ if name_ != "":
+ name = name_
+ self.game = game
+ username = name_
if game.hand_count == 1:
var center = Node3D.new()
@@ -89,13 +90,14 @@ func _init(_id: int, new_name: String, pos: Vector2, new_character_idx: int, new
marker.visible = false
add_child(marker)
- character_idx = new_character_idx
- is_customer = character_idx < 0
+ self.character_style = character_style
+ self.player_class = player_class
+ is_customer = player_class == "customer"
movement_base.scale = Vector3.ONE * 0.0001
func _ready():
- character.set_style(character_idx)
+ character.set_style(character_style, player_class)
clear_timer.timeout.connect(clear_message)
Settings.hook_changed_init("gameplay.usernames", false, update_username_tag)