aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortpart <tpart@noreply.codeberg.org>2026-01-15 21:56:33 +0100
committertpart <tpart@noreply.codeberg.org>2026-01-15 21:56:33 +0100
commit79910a55f7b6a952b05bfb7d1e8317036ae44207 (patch)
tree081072d7f00c777d5a3f72b8a2ddde76abf2e3e6
parent202a63be327bc62b514a73e325b73c055026fa48 (diff)
parentfa5ece0abdf0ecca256e7c99d91ac248c1f45820 (diff)
downloadhurrycurry-79910a55f7b6a952b05bfb7d1e8317036ae44207.tar
hurrycurry-79910a55f7b6a952b05bfb7d1e8317036ae44207.tar.bz2
hurrycurry-79910a55f7b6a952b05bfb7d1e8317036ae44207.tar.zst
Merge branch 'master' into master
-rw-r--r--client/map/tiles/active_interact_counter.gd60
-rw-r--r--client/map/tiles/active_interact_counter.gd.uid1
-rw-r--r--client/map/tiles/cutting_board.gd37
-rw-r--r--client/map/tiles/rolling_board.gd39
-rw-r--r--server/src/server.rs11
-rw-r--r--test-client/main.ts12
6 files changed, 76 insertions, 84 deletions
diff --git a/client/map/tiles/active_interact_counter.gd b/client/map/tiles/active_interact_counter.gd
new file mode 100644
index 00000000..742f147f
--- /dev/null
+++ b/client/map/tiles/active_interact_counter.gd
@@ -0,0 +1,60 @@
+# Hurry Curry! - a game about cooking
+# Copyright (C) 2025 Hurry Curry! contributors
+#
+# 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/>.
+#
+@abstract
+class_name ActiveInteractCounter
+extends CounterBase
+
+var interact_sound: AudioStreamPlayer3D = AudioStreamPlayer3D.new()
+var interact_tool: Node3D
+var acting_players: Array[Player] = []
+var play_character_animation: Callable
+
+func _init(ctx: TileFactory.TileCC, station_model_: PackedScene, interact_tool_path: NodePath, play_character_animation_: Callable, audio_stream_: AudioStream):
+ super(ctx, station_model_)
+ interact_sound.stream = audio_stream_
+ add_child(interact_sound)
+ interact_tool = base.get_node(interact_tool_path)
+ play_character_animation = play_character_animation_
+
+func progress(position_: float, speed: float, warn: bool, acting_players_: Array[Player]):
+ super(position_, speed, warn, acting_players)
+
+ if speed != 0.:
+ if not interact_sound.playing: interact_sound.play()
+ acting_players = acting_players.filter(is_instance_valid) # Some players might have disconnected
+ var players_who_stopped := G.unordered_array_difference(acting_players, acting_players_)
+ for p: Player in players_who_stopped:
+ if p != null: play_character_animation.call(p, false)
+ for p: Player in acting_players_:
+ interact_tool.visible = false
+ play_character_animation.call(p, true)
+ elif speed == 0:
+ interact_sound.stop()
+ interact_tool.visible = true
+ for p: Player in acting_players:
+ play_character_animation.call(p, false)
+ acting_players = acting_players_
+
+func finish():
+ super()
+ acting_players = acting_players.filter(is_instance_valid) # Some players might have disconnected
+ for p: Player in acting_players:
+ play_character_animation.call(p, false)
+ interact_tool.visible = true
+ interact_sound.stop()
+
+static func interact_target() -> Vector3:
+ return Vector3(0., 0.575, 0.)
diff --git a/client/map/tiles/active_interact_counter.gd.uid b/client/map/tiles/active_interact_counter.gd.uid
new file mode 100644
index 00000000..c83526ff
--- /dev/null
+++ b/client/map/tiles/active_interact_counter.gd.uid
@@ -0,0 +1 @@
+uid://bc4l8km0pnuq5
diff --git a/client/map/tiles/cutting_board.gd b/client/map/tiles/cutting_board.gd
index 4bc6608f..a7975a44 100644
--- a/client/map/tiles/cutting_board.gd
+++ b/client/map/tiles/cutting_board.gd
@@ -14,43 +14,10 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name CuttingBoard
-extends CounterBase
-
-var chopping: AudioStreamPlayer3D = AudioStreamPlayer3D.new()
-var acting_players: Array[Player] = []
+extends ActiveInteractCounter
func _init(ctx: TileFactory.TileCC):
- super(ctx, preload("res://map/tiles/cutting_board.tscn"))
- chopping.stream = preload("res://map/tiles/sounds/chop.ogg")
- add_child(chopping)
-
-func progress(position_: float, speed: float, warn: bool, acting_players_: Array[Player]):
- super(position_, speed, warn, acting_players)
- var knife: Node3D = base.get_node("CuttingBoard").get_node("Knife")
-
- if speed != 0.:
- if not chopping.playing: chopping.play()
- acting_players = acting_players.filter(is_instance_valid) # Some players might have disconnected
- var players_who_stopped := G.unordered_array_difference(acting_players, acting_players_)
- for p: Player in players_who_stopped:
- if p != null: p.character.cutting = false
- for p: Player in acting_players_:
- knife.visible = false
- p.character.cutting = true
- elif speed == 0:
- chopping.stop()
- knife.visible = true
- for p: Player in acting_players:
- p.character.cutting = false
- acting_players = acting_players_
-
-func finish():
- super()
- acting_players = acting_players.filter(is_instance_valid) # Some players might have disconnected
- for p: Player in acting_players:
- p.character.cutting = false
- base.get_node("CuttingBoard").get_node("Knife").visible = true
- chopping.stop()
+ super(ctx, preload("res://map/tiles/cutting_board.tscn"), "CuttingBoard/Knife", func (p: Player, x: bool): p.character.cutting = x, preload("res://map/tiles/sounds/chop.ogg"))
static func interact_target() -> Vector3:
return Vector3(0., 0.575, 0.)
diff --git a/client/map/tiles/rolling_board.gd b/client/map/tiles/rolling_board.gd
index f9477de8..81934dbc 100644
--- a/client/map/tiles/rolling_board.gd
+++ b/client/map/tiles/rolling_board.gd
@@ -14,45 +14,10 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name RollingBoard
-extends CounterBase
-
-var board = load("res://map/tiles/rolling_board.tscn")
-var rolling: AudioStreamPlayer3D = AudioStreamPlayer3D.new()
-var acting_players: Array[Player]
+extends ActiveInteractCounter
func _init(ctx: TileFactory.TileCC):
- super(ctx, board)
- rolling.stream = preload("res://map/tiles/sounds/roll.ogg")
- rolling.volume_db = -10
- add_child(rolling)
-
-func progress(position_: float, speed: float, warn: bool, acting_players_: Array[Player]):
- super(position_, speed, warn, acting_players_)
- var pin: Node3D = base.get_node("RollingBoard").get_node("RollingPin")
-
- if speed != 0.:
- if not rolling.playing: rolling.play()
- acting_players = acting_players.filter(is_instance_valid) # Some players might have disconnected
- var players_who_stopped := G.unordered_array_difference(acting_players, acting_players_)
- for p: Player in players_who_stopped:
- if p != null: p.character.rolling = false
- for p: Player in acting_players_:
- pin.visible = false
- p.character.rolling = true
- elif speed == 0:
- rolling.stop()
- pin.visible = true
- for p: Player in acting_players:
- p.character.rolling = false
- acting_players = acting_players_
-
-func finish():
- super()
- acting_players = acting_players.filter(is_instance_valid) # Some players might have disconnected
- for p: Player in acting_players:
- p.character.rolling = false
- base.get_node("RollingBoard").get_node("RollingPin").visible = true
- rolling.stop()
+ super(ctx, preload("res://map/tiles/rolling_board.tscn"), "RollingBoard/RollingPin", func (p: Player, x: bool): p.character.rolling = x, preload("res://map/tiles/sounds/roll.ogg"))
static func interact_target() -> Vector3:
return Vector3(0., 0.575, 0.)
diff --git a/server/src/server.rs b/server/src/server.rs
index 627ba5c2..49b9cbd7 100644
--- a/server/src/server.rs
+++ b/server/src/server.rs
@@ -513,7 +513,7 @@ impl Server {
.get_mut(&player)
.ok_or(tre!("s.error.no_player"))?;
- if pd.movement.input_direction != dir {
+ if pd.movement.input_direction != dir || pd.movement.boosting != boost {
pd.movement_input_changed = true;
}
pd.movement.input(dir, boost);
@@ -702,13 +702,8 @@ impl Server {
for (&pid, player) in &mut self.game.players {
if player.movement_input_changed || player.movement_must_sync {
player.movement_input_changed = false;
- self.packet_out.push_back(PacketC::Movement {
- player: pid,
- pos: player.movement.position,
- dir: player.movement.input_direction,
- boost: player.movement.boosting,
- rot: player.movement.rotation,
- });
+ self.packet_out
+ .push_back(player.movement.movement_packet_c(pid));
if player.movement_must_sync {
player.movement_must_sync = false;
self.packet_out
diff --git a/test-client/main.ts b/test-client/main.ts
index e106a135..34291984 100644
--- a/test-client/main.ts
+++ b/test-client/main.ts
@@ -72,8 +72,6 @@ document.addEventListener("DOMContentLoaded", async () => {
document.addEventListener("keydown", ev => keyboard(ev, true))
document.addEventListener("keyup", ev => keyboard(ev, false))
document.addEventListener("contextmenu", ev => ev.preventDefault())
- const tick_int = setInterval(tick_update, 1000 / 25);
- ws.addEventListener("close", () => clearInterval(tick_int))
})
export interface ItemData {
@@ -460,12 +458,14 @@ function set_interact(edge: boolean, hand: number) {
if (!edge) interacting = undefined
}
-function tick_update() {
+function send_movement() {
const p = players.get(my_id)
if (!p) return
- send({ player: my_id, type: "movement", pos: [p.position.x, p.position.y], dir: [p.input_direction.x, p.input_direction.y], boost: p.boosting })
+ send({ player: my_id, type: "movement", pos: [p.position.x, p.position.y], dir: [p.input_direction.x, p.input_direction.y], boost: p.input_boost })
}
+let last_direction: V2 = { x: 0, y: 0 }
+let last_boost: boolean = false
function frame_update(dt: number) {
const p = players.get(my_id)
if (!p) return
@@ -479,6 +479,10 @@ function frame_update(dt: number) {
if (interacting) direction.x *= 0, direction.y *= 0
p.input_direction = direction
p.input_boost = keys_down.has("KeyK")
+ if (last_boost != p.input_boost || last_direction.x != p.input_direction.x || last_direction.y != p.input_direction.y)
+ send_movement()
+ last_direction = p.input_direction
+ last_boost = p.input_boost
players.forEach(p => update_movement(p, dt))