diff options
author | tpart <tpart120@proton.me> | 2025-06-03 22:25:32 +0200 |
---|---|---|
committer | tpart <tpart120@proton.me> | 2025-06-03 22:25:37 +0200 |
commit | a2c2f9c84ba43c218556926b0f6650318e701d68 (patch) | |
tree | 3251dd8004a83c6e3e219cc616a819eea64372f8 | |
parent | 29772d6b2f244c6c172347c5e96530a16ca4517d (diff) | |
download | hurrycurry-a2c2f9c84ba43c218556926b0f6650318e701d68.tar hurrycurry-a2c2f9c84ba43c218556926b0f6650318e701d68.tar.bz2 hurrycurry-a2c2f9c84ba43c218556926b0f6650318e701d68.tar.zst |
Support new character style system
-rw-r--r-- | client/game.gd | 8 | ||||
-rw-r--r-- | client/global.gd | 14 | ||||
-rw-r--r-- | client/menu/character.gd | 32 | ||||
-rw-r--r-- | client/menu/character.tscn | 70 | ||||
-rw-r--r-- | client/menu/hairstyle_preview.gd | 13 | ||||
-rw-r--r-- | client/menu/setup.gd | 9 | ||||
-rw-r--r-- | client/multiplayer.gd | 4 | ||||
-rw-r--r-- | client/player/character/character.gd | 63 | ||||
-rw-r--r-- | client/player/player.gd | 20 |
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) |