request_bet and request_card are now broadcast for everyone to receive and display an arrow to represent active client's turn

This commit is contained in:
2025-07-20 20:06:58 +02:00
parent 66287ee8a0
commit b6e818cc49
8 changed files with 210 additions and 27 deletions
BIN
View File
Binary file not shown.
+37
View File
@@ -0,0 +1,37 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://bdmr8tox2w2qn"
path="res://.godot/imported/arrow.glb-fbbbd1f233a05b386bf12d76bd49138b.scn"
[deps]
source_file="res://assets/arrow.glb"
dest_files=["res://.godot/imported/arrow.glb-fbbbd1f233a05b386bf12d76bd49138b.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
_subresources={}
gltf/naming_version=1
gltf/embedded_image_handling=1
+7 -4
View File
@@ -59,6 +59,9 @@ signal received_end_game_request()
signal request_next_play()
signal request_next_round()
## Notifies to signal a player's turn.
signal notify_player_turn(client_id: String, is_self: bool)
enum ConnectionStatus {
DISCONNECTED,
ATTEMPTING_CONNECTION,
@@ -156,16 +159,16 @@ func _handle_response(response: String) -> void:
"request_bet":
if data["client_id"] == _own_client_data.client_id:
received_bet_request.emit.call_deferred(data["disallowed_bet"], data["round"])
else:
pass # display currently betting person
notify_player_turn.emit.call_deferred(data["client_id"], data["client_id"] == _own_client_data.client_id)
"begin_playing_cards":
# all players know it's time to play
print(data)
_is_first_play = true
reset_first_card.emit.call_deferred()
"request_card":
# individual player asked to play card
notify_play_card_request.emit.call_deferred()
if data["client_id"] == _own_client_data.client_id:
notify_play_card_request.emit.call_deferred()
notify_player_turn.emit.call_deferred(data["client_id"], data["client_id"] == _own_client_data.client_id)
"begin_next_play":
print("beginning next play!")
_is_first_play = true
+16
View File
@@ -23,6 +23,9 @@ var _is_owned: bool
@export var hide_client_name: bool = false
@export var card_disallowed_label: Label
@export var top_arrow_container: Node3D
@export var bottom_arrow_container: Node3D
var _selected_card: PlayingCard = null
var _cards_in_hand_ids: Array[int] = []
var _allow_clicking_cards: bool = false
@@ -38,11 +41,24 @@ signal card_played(card_id: int)
func _ready() -> void:
if hide_client_name:
name_label.hide()
top_arrow_container.hide()
bottom_arrow_container.hide()
func set_player_data(client_data: ClientData) -> void:
_client_data = client_data
name_label.text = _client_data.client_name
func set_turn(is_turn: bool, is_self: bool) -> void:
if is_turn:
if is_self:
top_arrow_container.show()
else:
bottom_arrow_container.show()
else:
top_arrow_container.hide()
bottom_arrow_container.hide()
func add_card(card: PlayingCard) -> void:
card_container.add_child(card)
_arrange_cards()
+121 -2
View File
@@ -1,15 +1,102 @@
[gd_scene load_steps=3 format=3 uid="uid://jlovgr2iojrg"]
[gd_scene load_steps=8 format=3 uid="uid://jlovgr2iojrg"]
[ext_resource type="Script" uid="uid://b5b5cl2qlhywv" path="res://elements/player_hand.gd" id="1_ank64"]
[ext_resource type="PackedScene" uid="uid://b55xpcxk7g5ph" path="res://cards/playing_card.tscn" id="2_11xsc"]
[ext_resource type="PackedScene" uid="uid://bdmr8tox2w2qn" path="res://assets/arrow.glb" id="3_ksc6e"]
[node name="PlayerHand" type="Node3D" node_paths=PackedStringArray("card_container", "name_label", "rank_label")]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ksc6e"]
albedo_color = Color(0.84, 0.4725, 0.21, 1)
[sub_resource type="Animation" id="Animation_ksc6e"]
resource_name = "hover"
length = 2.0
loop_mode = 1
tracks/0/type = "bezier"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:position:x")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"handle_modes": PackedInt32Array(0, 0, 0),
"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0, 0, -0.25, 0, 0.25, 0, 0, -0.25, 0, 0.25, 0),
"times": PackedFloat32Array(0, 1, 2)
}
tracks/1/type = "bezier"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath(".:position:y")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"handle_modes": PackedInt32Array(2, 2, 2),
"points": PackedFloat32Array(-0.576859, 0, 0, 0.333333, 0, -0.720279, -0.333333, 0, 0.333333, 0, -0.576859, -0.333333, 0, 0, 0),
"times": PackedFloat32Array(0, 1, 2)
}
tracks/2/type = "bezier"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath(".:position:z")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"handle_modes": PackedInt32Array(0, 0, 0),
"points": PackedFloat32Array(-0.0702564, -0.25, 0, 0.25, 0, -0.0702564, -0.25, 0, 0.25, 0, -0.0702564, -0.25, 0, 0.25, 0),
"times": PackedFloat32Array(0, 1, 2)
}
[sub_resource type="Animation" id="Animation_j3yk6"]
length = 0.001
loop_mode = 1
tracks/0/type = "bezier"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:position:x")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"handle_modes": PackedInt32Array(0),
"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0),
"times": PackedFloat32Array(0)
}
tracks/1/type = "bezier"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath(".:position:y")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"handle_modes": PackedInt32Array(0),
"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0),
"times": PackedFloat32Array(0)
}
tracks/2/type = "bezier"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath(".:position:z")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"handle_modes": PackedInt32Array(0),
"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0),
"times": PackedFloat32Array(0)
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_v6rd7"]
_data = {
&"RESET": SubResource("Animation_j3yk6"),
&"hover": SubResource("Animation_ksc6e")
}
[node name="PlayerHand" type="Node3D" node_paths=PackedStringArray("card_container", "name_label", "rank_label", "top_arrow_container", "bottom_arrow_container")]
script = ExtResource("1_ank64")
card_scene = ExtResource("2_11xsc")
card_container = NodePath("CardContainer")
card_angle = 0.125664
name_label = NodePath("NameLabel")
rank_label = NodePath("RankLabel")
top_arrow_container = NodePath("TopArrow")
bottom_arrow_container = NodePath("BottomArrow")
[node name="NameLabel" type="Label3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.513717, 0)
@@ -23,3 +110,35 @@ text = "name goes here"
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.283052, 0)
billboard = 1
double_sided = false
[node name="TopArrow" type="Node3D" parent="."]
transform = Transform3D(-1, 8.74228e-08, 0, -8.74228e-08, -1, 0, 0, 0, 1, 0, 0, 0)
[node name="arrow" parent="TopArrow" instance=ExtResource("3_ksc6e")]
transform = Transform3D(0.35, 0, 0, 0, 0.35, 0, 0, 0, 0.35, 0, 0, 0)
[node name="Cylinder" parent="TopArrow/arrow" index="0"]
surface_material_override/0 = SubResource("StandardMaterial3D_ksc6e")
[node name="AnimationPlayer" type="AnimationPlayer" parent="TopArrow/arrow"]
libraries = {
&"": SubResource("AnimationLibrary_v6rd7")
}
autoplay = "hover"
[node name="BottomArrow" type="Node3D" parent="."]
[node name="arrow" parent="BottomArrow" instance=ExtResource("3_ksc6e")]
transform = Transform3D(0.35, 0, 0, 0, 0.35, 0, 0, 0, 0.35, 0, 0, 0)
[node name="Cylinder" parent="BottomArrow/arrow" index="0"]
surface_material_override/0 = SubResource("StandardMaterial3D_ksc6e")
[node name="AnimationPlayer" type="AnimationPlayer" parent="BottomArrow/arrow"]
libraries = {
&"": SubResource("AnimationLibrary_v6rd7")
}
autoplay = "hover"
[editable path="TopArrow/arrow"]
[editable path="BottomArrow/arrow"]
+11
View File
@@ -32,6 +32,8 @@ var _bets: Dictionary[String, Array] # Array[BetResult]
var _plays: Array[Play]
var _trump_id: int = -1
var _current_turn_client_id: String = ""
func _on_web_client_tcp_client_order_received(playing_order: Array[ClientData]) -> void:
var marker_positions: Array[Marker3D]
var client_ids: Array[String] = []
@@ -146,3 +148,12 @@ func _on_web_client_tcp_received_end_game_request() -> void:
func _on_web_client_connected_to_lobby(lobby_id: String, client_id: String) -> void:
_own_client_id = client_id
func _on_web_client_notify_player_turn(client_id: String, is_self: bool) -> void:
if _current_turn_client_id:
hand_associations[_current_turn_client_id].set_turn(false, is_self)
_current_turn_client_id = client_id
if _current_turn_client_id:
hand_associations[_current_turn_client_id].set_turn(true, is_self)
+1
View File
@@ -379,6 +379,7 @@ playing_card_scene = ExtResource("6_eow3j")
[connection signal="connection_status_changed" from="WebClient" to="Interface/ConnectionOverlay" method="_on_web_client_connection_status_changed"]
[connection signal="new_round_started" from="WebClient" to="EnvironmentManager" method="_on_web_client_tcp_new_round_started"]
[connection signal="notify_play_card_request" from="WebClient" to="HBoxContainer/GameUI" method="_on_web_client_tcp_notify_play_card_request"]
[connection signal="notify_player_turn" from="WebClient" to="EnvironmentManager" method="_on_web_client_notify_player_turn"]
[connection signal="received_bet_request" from="WebClient" to="HBoxContainer/GameUI" method="_on_web_client_tcp_received_bet_request"]
[connection signal="received_bet_request" from="WebClient" to="HBoxContainer/GameUI/BetContainer/BetInput" method="_on_web_client_tcp_received_bet_request"]
[connection signal="received_chat_message" from="WebClient" to="Interface/ClientInterface" method="_on_web_client_tcp_received_chat_message"]
+17 -21
View File
@@ -177,25 +177,21 @@ class LobbyManager:
#region gameplay
async def spread_cards(self, lobby_id, round, cards, playing_order) -> None:
client_ids = self.get_lobby_client_ids(lobby_id)
trump = None
trump = -1
if cards["trump"]:
trump = cards["trump"]
cards.pop("trump")
for client_id in client_ids:
await self.send_message(
lobby_id,
client_id,
json.dumps({
"response": "round_started",
"current_round": round,
"cards": cards,
"trump": trump,
"playing_order": playing_order,
})
)
await self.broadcast_message(
lobby_id,
json.dumps({
"response": "round_started",
"current_round": round,
"cards": cards,
"trump": trump,
"playing_order": playing_order,
})
)
async def request_bet(self, lobby_id, client_id, disallowed_bet) -> None:
await self.broadcast_message(
@@ -455,11 +451,11 @@ async def process_input(message: str, websocket) -> None:
"playing_order": lobby_manager.get_lobby(lobby_id).current_playing_order,
}),
)
await lobby_manager.send_message(
await lobby_manager.broadcast_message(
lobby_id,
lobby_manager.get_lobby(lobby_id).current_playing_order[0],
json.dumps({
"response": "request_card",
"client_id": lobby_manager.get_lobby(lobby_id).current_playing_order[0],
}),
)
@@ -517,11 +513,11 @@ async def process_input(message: str, websocket) -> None:
playing_client_id = lobby_manager.get_lobby(lobby_id).current_playing_order[0]
await lobby_manager.send_message(
await lobby_manager.broadcast_message(
lobby_id,
playing_client_id,
json.dumps({
"response": "request_card",
"client_id": playing_client_id,
"round": lobby_manager.get_lobby(lobby_id).current_round,
}),
)
@@ -569,11 +565,11 @@ async def process_input(message: str, websocket) -> None:
# not all clients have played a card yet; continue
playing_client_id = playing_order[client_index + 1]
await lobby_manager.send_message(
await lobby_manager.broadcast_message(
lobby_id,
playing_client_id,
json.dumps({
"response": "request_card",
"client_id": playing_client_id,
}),
)