diff --git a/.gitignore b/.gitignore index 4709183..fda6318 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,15 @@ # Godot 4+ specific ignores .godot/ + +# Godot-specific ignores +.import/ +export.cfg +export_presets.cfg + +# Imported translations +*.translation + +# Mono-specific ignores +.mono/ +data_*/ +mono_crash.*.json diff --git a/Assets/client_deck.png b/Assets/client_deck.png new file mode 100644 index 0000000..a74f481 Binary files /dev/null and b/Assets/client_deck.png differ diff --git a/Assets/client_deck.png.import b/Assets/client_deck.png.import new file mode 100644 index 0000000..725e3a4 --- /dev/null +++ b/Assets/client_deck.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://s8r4ura4chsf" +path="res://.godot/imported/client_deck.png-f96560222837ebbce8520d1b93416dde.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/client_deck.png" +dest_files=["res://.godot/imported/client_deck.png-f96560222837ebbce8520d1b93416dde.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/client_deck.png~ b/Assets/client_deck.png~ new file mode 100644 index 0000000..a74f481 Binary files /dev/null and b/Assets/client_deck.png~ differ diff --git a/Assets/player_board.png b/Assets/player_board.png new file mode 100644 index 0000000..0b290d4 Binary files /dev/null and b/Assets/player_board.png differ diff --git a/Assets/player_board.png.import b/Assets/player_board.png.import new file mode 100644 index 0000000..196624e --- /dev/null +++ b/Assets/player_board.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://olxh7d7xkr5k" +path="res://.godot/imported/player_board.png-373db31276dbff48ec4d20708076002e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/player_board.png" +dest_files=["res://.godot/imported/player_board.png-373db31276dbff48ec4d20708076002e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/player_board.png~ b/Assets/player_board.png~ new file mode 100644 index 0000000..1a749ed Binary files /dev/null and b/Assets/player_board.png~ differ diff --git a/Assets/table.png b/Assets/table.png new file mode 100644 index 0000000..f8b5b62 Binary files /dev/null and b/Assets/table.png differ diff --git a/Assets/table.png.import b/Assets/table.png.import new file mode 100644 index 0000000..743d841 --- /dev/null +++ b/Assets/table.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://crk6m37iy1itk" +path="res://.godot/imported/table.png-177b454fdc598cd5a4f023de2d4f1fe3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/table.png" +dest_files=["res://.godot/imported/table.png-177b454fdc598cd5a4f023de2d4f1fe3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/worker_deck.png b/Assets/worker_deck.png new file mode 100644 index 0000000..1ec54a5 Binary files /dev/null and b/Assets/worker_deck.png differ diff --git a/Assets/worker_deck.png.import b/Assets/worker_deck.png.import new file mode 100644 index 0000000..c0004af --- /dev/null +++ b/Assets/worker_deck.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ch8n7vn43fg0p" +path="res://.godot/imported/worker_deck.png-774d96864218b24f32961dc9a007c5aa.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/worker_deck.png" +dest_files=["res://.godot/imported/worker_deck.png-774d96864218b24f32961dc9a007c5aa.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/worker_deck.png~ b/Assets/worker_deck.png~ new file mode 100644 index 0000000..35090e2 Binary files /dev/null and b/Assets/worker_deck.png~ differ diff --git a/Assets/worker_slot.png b/Assets/worker_slot.png new file mode 100644 index 0000000..5f1da7a Binary files /dev/null and b/Assets/worker_slot.png differ diff --git a/Assets/worker_slot.png.import b/Assets/worker_slot.png.import new file mode 100644 index 0000000..cada312 --- /dev/null +++ b/Assets/worker_slot.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cpitf556hf0g" +path="res://.godot/imported/worker_slot.png-2bda2bed0ee6abe2ba94892d141a9b27.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/worker_slot.png" +dest_files=["res://.godot/imported/worker_slot.png-2bda2bed0ee6abe2ba94892d141a9b27.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/PlayerBoard.gd b/PlayerBoard.gd new file mode 100644 index 0000000..2cecd9c --- /dev/null +++ b/PlayerBoard.gd @@ -0,0 +1,11 @@ +extends Node2D + + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + pass diff --git a/Scenes/Table.tscn b/Scenes/Table.tscn new file mode 100644 index 0000000..f201651 --- /dev/null +++ b/Scenes/Table.tscn @@ -0,0 +1,76 @@ +[gd_scene load_steps=5 format=3 uid="uid://x8fd0k3qhn1x"] + +[ext_resource type="Texture2D" uid="uid://crk6m37iy1itk" path="res://Assets/table.png" id="1_gchuv"] +[ext_resource type="Script" path="res://Scripts/game.gd" id="1_ne3d3"] +[ext_resource type="Script" path="res://Scripts/chat.gd" id="4_dww8o"] +[ext_resource type="PackedScene" uid="uid://y2i3u6n1oowh" path="res://Scenes/deck.tscn" id="4_ugbip"] + +[node name="Table" type="Node2D" node_paths=PackedStringArray("worker_deck", "client_deck", "worker_discard", "client_discard", "seat1", "seat2", "seat3", "seat4")] +script = ExtResource("1_ne3d3") +worker_deck = NodePath("Workers") +client_deck = NodePath("Clients") +worker_discard = NodePath("WorkerDiscard") +client_discard = NodePath("ClientDiscard") +seat1 = NodePath("Seat1") +seat2 = NodePath("Seat2") +seat3 = NodePath("Seat3") +seat4 = NodePath("Seat4") + +[node name="Sprite2D" type="Sprite2D" parent="."] +scale = Vector2(5, 5) +texture = ExtResource("1_gchuv") + +[node name="Workers" parent="." instance=ExtResource("4_ugbip")] +position = Vector2(-3244, -211) + +[node name="WorkerDiscard" parent="." instance=ExtResource("4_ugbip")] +position = Vector2(-3244, 212) + +[node name="Clients" parent="." instance=ExtResource("4_ugbip")] +position = Vector2(-2820, -211) +type = 1 + +[node name="ClientDiscard" parent="." instance=ExtResource("4_ugbip")] +position = Vector2(-2820, 212) +type = 1 + +[node name="Seat1" type="Node2D" parent="."] +position = Vector2(1315, 738) + +[node name="Seat2" type="Node2D" parent="."] +position = Vector2(-1342, 728) + +[node name="Seat3" type="Node2D" parent="."] +position = Vector2(-1341, -737) + +[node name="Seat4" type="Node2D" parent="."] +position = Vector2(1313, -747) + +[node name="Players" type="Node2D" parent="."] + +[node name="LobbyCamera" type="Camera2D" parent="."] +zoom = Vector2(0.225, 0.225) + +[node name="Button" type="Button" parent="LobbyCamera"] +offset_left = -155.0 +offset_top = -1410.0 +offset_right = 149.0 +offset_bottom = -1265.0 +theme_override_font_sizes/font_size = 100 +text = "Ready" + +[node name="RichTextLabel" type="RichTextLabel" parent="LobbyCamera"] +offset_left = -2563.0 +offset_top = 561.0 +offset_right = -1210.0 +offset_bottom = 1256.0 +theme_override_font_sizes/normal_font_size = 100 +fit_content = true +script = ExtResource("4_dww8o") + +[node name="LineEdit" type="LineEdit" parent="LobbyCamera"] +offset_left = -2547.0 +offset_top = 1276.0 +offset_right = -1204.0 +offset_bottom = 1421.0 +theme_override_font_sizes/font_size = 100 diff --git a/Scenes/bot_player.tscn b/Scenes/bot_player.tscn new file mode 100644 index 0000000..fded407 --- /dev/null +++ b/Scenes/bot_player.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://gxofrq3ug6qe"] + +[ext_resource type="Script" path="res://Scripts/PlayerStateMachine/bot_controller.gd" id="1_rr26g"] + +[node name="BotPlayer" type="Node2D"] +script = ExtResource("1_rr26g") diff --git a/Scenes/card_pile.tscn b/Scenes/card_pile.tscn deleted file mode 100644 index 458bdc1..0000000 --- a/Scenes/card_pile.tscn +++ /dev/null @@ -1,27 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://y2i3u6n1oowh"] - -[ext_resource type="Script" path="res://Scripts/slot_button.gd" id="1_qbsj1"] - -[sub_resource type="RectangleShape2D" id="RectangleShape2D_2yi2r"] -size = Vector2(229, 145) - -[node name="CardPile" type="Node2D"] -script = ExtResource("1_qbsj1") - -[node name="Label" type="Label" parent="."] -offset_left = 66.0 -offset_top = 55.0 -offset_right = 158.0 -offset_bottom = 81.0 -text = "Deck" -horizontal_alignment = 1 -vertical_alignment = 1 - -[node name="Area2D" type="Area2D" parent="."] - -[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] -position = Vector2(112.5, 71.5) -shape = SubResource("RectangleShape2D_2yi2r") -disabled = true - -[connection signal="input_event" from="Area2D" to="." method="_on_area_2d_input_event"] diff --git a/Scenes/deck.tscn b/Scenes/deck.tscn new file mode 100644 index 0000000..20a6745 --- /dev/null +++ b/Scenes/deck.tscn @@ -0,0 +1,42 @@ +[gd_scene load_steps=6 format=3 uid="uid://y2i3u6n1oowh"] + +[ext_resource type="Script" path="res://Scripts/deck.gd" id="1_3qpwi"] +[ext_resource type="Texture2D" uid="uid://s8r4ura4chsf" path="res://Assets/client_deck.png" id="2_v2nvn"] +[ext_resource type="Texture2D" uid="uid://ch8n7vn43fg0p" path="res://Assets/worker_deck.png" id="3_h83vm"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_2yi2r"] +size = Vector2(350, 250) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_y5k83"] +size = Vector2(250, 350) + +[node name="Deck" type="Node2D"] +script = ExtResource("1_3qpwi") + +[node name="Area2D" type="Area2D" parent="."] + +[node name="ClientSprite" type="Sprite2D" parent="Area2D"] +texture = ExtResource("2_v2nvn") + +[node name="WorkerSprite" type="Sprite2D" parent="Area2D"] +texture = ExtResource("3_h83vm") + +[node name="ClientShape" type="CollisionShape2D" parent="Area2D"] +visible = false +shape = SubResource("RectangleShape2D_2yi2r") +disabled = true + +[node name="WorkerShape" type="CollisionShape2D" parent="Area2D"] +visible = false +shape = SubResource("RectangleShape2D_y5k83") +disabled = true + +[node name="Worker" type="Node2D" parent="."] +position = Vector2(-125, -175) + +[node name="Client" type="Node2D" parent="."] +position = Vector2(-175, -125) + +[connection signal="input_event" from="Area2D" to="." method="_on_area_2d_input_event"] +[connection signal="mouse_entered" from="Area2D" to="." method="_on_area_2d_mouse_entered"] +[connection signal="mouse_exited" from="Area2D" to="." method="_on_area_2d_mouse_exited"] diff --git a/Scenes/gameplay.tscn b/Scenes/gameplay.tscn index 6224cfe..636662f 100644 --- a/Scenes/gameplay.tscn +++ b/Scenes/gameplay.tscn @@ -1,20 +1,19 @@ [gd_scene load_steps=2 format=3 uid="uid://b33xjpvgbjl08"] -[ext_resource type="Script" path="res://Scenes/network_lobby.gd" id="1_yetq7"] +[ext_resource type="Script" path="res://Scripts/network_lobby.gd" id="1_dsni2"] [node name="Root" type="Node2D"] -script = ExtResource("1_yetq7") - -[node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="."] -_spawnable_scenes = PackedStringArray("res://Scenes/player.tscn", "res://Scenes/board.tscn") -spawn_path = NodePath("../Network") - -[node name="Network" type="Node" parent="."] +script = ExtResource("1_dsni2") [node name="UI" type="VBoxContainer" parent="."] offset_right = 116.0 offset_bottom = 136.0 +[node name="Username" type="LineEdit" parent="UI"] +layout_mode = 2 +placeholder_text = "username" +alignment = 2 + [node name="IPField" type="LineEdit" parent="UI"] layout_mode = 2 placeholder_text = "localhost" @@ -37,20 +36,6 @@ text = "Host" layout_mode = 2 text = "SinglePlayer" -[node name="TablePosition1" type="Node2D" parent="."] -position = Vector2(-2, 1475) - -[node name="TablePosition2" type="Node2D" parent="."] -position = Vector2(1922, 1475) - -[node name="TablePosition3" type="Node2D" parent="."] -position = Vector2(-2, -339) -rotation = 3.14159 - -[node name="TablePosition4" type="Node2D" parent="."] -position = Vector2(1922, -339) -rotation = 3.14159 - [connection signal="pressed" from="UI/Connect" to="." method="connect_to_server"] [connection signal="pressed" from="UI/Host" to="." method="host_server"] [connection signal="pressed" from="UI/SinglePlayer" to="." method="_on_single_player_pressed"] diff --git a/Scenes/human_player.tscn b/Scenes/human_player.tscn new file mode 100644 index 0000000..35a8af2 --- /dev/null +++ b/Scenes/human_player.tscn @@ -0,0 +1,62 @@ +[gd_scene load_steps=3 format=3 uid="uid://cpl32lvhwd5da"] + +[ext_resource type="Script" path="res://Scripts/PlayerStateMachine/human_controller.gd" id="1_pu5r2"] +[ext_resource type="Theme" uid="uid://d26ldkm1br1bo" path="res://UI_Theme.tres" id="2_ja0q8"] + +[node name="HumanPlayer" type="Node2D"] +script = ExtResource("1_pu5r2") + +[node name="Camera2D" type="Camera2D" parent="."] + +[node name="UI" type="Control" parent="."] +layout_mode = 3 +anchors_preset = 0 +offset_right = 40.0 +offset_bottom = 40.0 +theme = ExtResource("2_ja0q8") + +[node name="Cash" type="Label" parent="UI"] +layout_mode = 0 +offset_left = -561.0 +offset_top = -27.0 +offset_right = -521.0 +offset_bottom = -1.0 +text = "$100" + +[node name="Profit" type="Label" parent="UI"] +layout_mode = 0 +offset_left = -521.0 +offset_top = -27.0 +offset_right = -481.0 +offset_bottom = -1.0 +theme_override_colors/font_color = Color(0, 0.870588, 0, 1) +text = "+23 +" + +[node name="Loss" type="Label" parent="UI"] +layout_mode = 0 +offset_left = -491.0 +offset_top = -27.0 +offset_right = -451.0 +offset_bottom = -1.0 +theme_override_colors/font_color = Color(0.909804, 0, 0, 1) +text = "-38" + +[node name="Phase" type="Label" parent="UI"] +layout_mode = 0 +offset_left = -113.0 +offset_top = -311.0 +offset_right = 103.0 +offset_bottom = -285.0 +text = "{Management / Shift} Phase" + +[node name="Label" type="Label" parent="UI"] +layout_mode = 0 +offset_left = -397.0 +offset_top = -938.0 +offset_right = 401.0 +offset_bottom = -798.0 +theme_override_font_sizes/font_size = 100 +text = "99999999999999" +horizontal_alignment = 1 +vertical_alignment = 1 diff --git a/Scenes/main_menu.tscn b/Scenes/main_menu.tscn index cddb88a..83657f1 100644 --- a/Scenes/main_menu.tscn +++ b/Scenes/main_menu.tscn @@ -13,10 +13,10 @@ script = ExtResource("1_cg0id") [node name="Title" type="Label" parent="."] layout_mode = 0 -offset_left = 462.0 -offset_top = 67.0 -offset_right = 1395.0 -offset_bottom = 246.0 +offset_left = 94.0 +offset_top = 4.0 +offset_right = 1027.0 +offset_bottom = 183.0 theme_override_font_sizes/font_size = 129 text = "Lexi's Game" horizontal_alignment = 1 @@ -24,20 +24,20 @@ vertical_alignment = 1 [node name="Play Game" type="Button" parent="."] layout_mode = 0 -offset_left = 740.0 -offset_top = 297.0 -offset_right = 1094.0 -offset_bottom = 460.0 +offset_left = 389.0 +offset_top = 187.0 +offset_right = 743.0 +offset_bottom = 350.0 theme_override_font_sizes/font_size = 40 text = "Play" [node name="Worker Deck" type="Button" parent="."] visible = false layout_mode = 0 -offset_left = 740.0 -offset_top = 569.0 -offset_right = 1094.0 -offset_bottom = 732.0 +offset_left = 383.0 +offset_top = 394.0 +offset_right = 737.0 +offset_bottom = 557.0 theme_override_font_sizes/font_size = 40 text = "worker deck dev tool" @@ -45,28 +45,28 @@ dev tool" [node name="Task Deck" type="Button" parent="."] visible = false layout_mode = 0 -offset_left = 740.0 -offset_top = 745.0 -offset_right = 1094.0 -offset_bottom = 908.0 +offset_left = 383.0 +offset_top = 570.0 +offset_right = 737.0 +offset_bottom = 733.0 theme_override_font_sizes/font_size = 40 text = "task deck dev tool" [node name="CheckButton" type="CheckButton" parent="."] layout_mode = 0 -offset_left = 1009.0 -offset_top = 491.0 -offset_right = 1053.0 -offset_bottom = 515.0 +offset_left = 652.0 +offset_top = 343.0 +offset_right = 696.0 +offset_bottom = 367.0 scale = Vector2(2, 2) [node name="Label" type="Label" parent="."] layout_mode = 0 -offset_left = 738.0 -offset_top = 482.0 -offset_right = 1002.0 -offset_bottom = 540.0 +offset_left = 378.0 +offset_top = 344.0 +offset_right = 642.0 +offset_bottom = 402.0 theme_override_font_sizes/font_size = 35 text = "Show dev tools" horizontal_alignment = 1 diff --git a/Scenes/network_lobby.gd b/Scenes/network_lobby.gd deleted file mode 100644 index eb30e78..0000000 --- a/Scenes/network_lobby.gd +++ /dev/null @@ -1,62 +0,0 @@ -extends Node2D - -const SERVER_PORT := 58008 -const MAX_PLAYERS := 4 - -var player_scene = preload("res://Scenes/player.tscn") -var board_scene = preload("res://Scenes/board.tscn") - -@export var seats : Array[Node2D] = [null, null, null, null] -var enet_peer = ENetMultiplayerPeer.new() -var board : Board -var players_connected = 0 - - -func _ready() -> void: - seats[0] = $TablePosition1 - seats[1] = $TablePosition2 - seats[2] = $TablePosition3 - seats[3] = $TablePosition4 - - -func host_server() -> void: - $UI.visible = false - - enet_peer.create_server(SERVER_PORT, MAX_PLAYERS) - multiplayer.multiplayer_peer = enet_peer - - multiplayer.peer_connected.connect(create_player) - create_player(multiplayer.get_unique_id()) - - -func connect_to_server() -> void: - $UI.visible = false - - var ip = $UI/IPField.text if $UI/IPField.text != "" else $UI/IPField.placeholder_text - var port = $UI/PortField.text if $UI/PortField.text != "" else $UI/PortField.placeholder_text - enet_peer.create_client(ip, int(port)) - multiplayer.multiplayer_peer = enet_peer - - -func create_player(id): - if board == null: - board = board_scene.instantiate() as Board - $Network.add_child(board) - var player = player_scene.instantiate() as Player - player.set_name(str(id)) - player.set_multiplayer_authority(id) - player.position = seats[players_connected].position - player.rotation = seats[players_connected].rotation - $Network.add_child(player) - player.rpc("attach_board", board.get_path()) - players_connected += 1 - - -func _on_single_player_pressed() -> void: - $UI.visible = false - board = board_scene.instantiate() as Board - add_child(board) - var player = player_scene.instantiate() as Player - add_child(player) - player.attach_board(board.get_path()) - diff --git a/Scenes/player.tscn b/Scenes/player.tscn index dc605fa..51e6c7c 100644 --- a/Scenes/player.tscn +++ b/Scenes/player.tscn @@ -1,8 +1,16 @@ -[gd_scene load_steps=7 format=3 uid="uid://cuptyfol5sy52"] +[gd_scene load_steps=15 format=3 uid="uid://cuptyfol5sy52"] [ext_resource type="Script" path="res://Scripts/player.gd" id="1_5kyvf"] +[ext_resource type="Script" path="res://Scripts/PlayerStateMachine/state_machine.gd" id="2_ub14e"] [ext_resource type="PackedScene" uid="uid://baoec8cqmedf6" path="res://Scenes/worker_slot.tscn" id="2_ugx0h"] -[ext_resource type="PackedScene" uid="uid://y2i3u6n1oowh" path="res://Scenes/card_pile.tscn" id="3_gwbfn"] +[ext_resource type="PackedScene" uid="uid://y2i3u6n1oowh" path="res://Scenes/deck.tscn" id="3_gwbfn"] +[ext_resource type="Script" path="res://Scripts/PlayerStateMachine/draft_state.gd" id="3_lo4ro"] +[ext_resource type="Script" path="res://Scripts/PlayerStateMachine/setup_state.gd" id="3_t8u1m"] +[ext_resource type="Script" path="res://Scripts/PlayerStateMachine/management_state.gd" id="4_fkrfk"] +[ext_resource type="Script" path="res://Scripts/PlayerStateMachine/worker_state.gd" id="5_u4lqc"] +[ext_resource type="Script" path="res://Scripts/PlayerStateMachine/holding_worker_state.gd" id="6_j37yg"] +[ext_resource type="Script" path="res://Scripts/PlayerStateMachine/shift_state.gd" id="7_4jvhu"] +[ext_resource type="Script" path="res://Scripts/PlayerStateMachine/holding_client_state.gd" id="8_0374u"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_78syh"] size = Vector2(920, 268) @@ -15,74 +23,28 @@ properties/0/path = NodePath(".:position") properties/0/spawn = true properties/0/sync = true -[node name="Player" type="Node2D"] +[node name="Player" type="Node2D" node_paths=PackedStringArray("fsm")] script = ExtResource("1_5kyvf") -seconds_to_hide_hand = 0.3 -seconds_to_show_hand = 0.3 +fsm = NodePath("StateMachine") [node name="Camera2D" type="Camera2D" parent="."] -[node name="Money" type="Label" parent="Camera2D"] -offset_left = -860.0 -offset_top = -154.0 -offset_right = -803.0 -offset_bottom = -14.0 -theme_override_font_sizes/font_size = 80 -text = "$" +[node name="StateMachine" type="Node" parent="."] +script = ExtResource("2_ub14e") -[node name="Payout" type="Label" parent="Camera2D"] -offset_left = -624.0 -offset_top = -154.0 -offset_right = -567.0 -offset_bottom = -14.0 -theme_override_colors/font_color = Color(0, 0.858824, 0, 1) -theme_override_font_sizes/font_size = 80 +[node name="Draft" type="Node2D" parent="StateMachine"] +visible = false +script = ExtResource("3_lo4ro") -[node name="Cost" type="Label" parent="Camera2D"] -offset_left = -624.0 -offset_top = -154.0 -offset_right = -567.0 -offset_bottom = -14.0 -theme_override_colors/font_color = Color(0.839216, 0, 0.105882, 1) -theme_override_font_sizes/font_size = 80 - -[node name="PhaseLabel" type="Label" parent="Camera2D"] +[node name="Label" type="Label" parent="StateMachine/Draft"] offset_left = -151.0 offset_top = -518.0 offset_right = 117.0 offset_bottom = -476.0 theme_override_font_sizes/font_size = 28 -text = "Management Phase" +text = "Choose x cards" -[node name="EndManagement" type="Button" parent="Camera2D"] -offset_left = 138.0 -offset_top = -530.0 -offset_right = 483.0 -offset_bottom = -467.0 -theme_override_font_sizes/font_size = 40 -text = "End Management" - -[node name="EndShift" type="Button" parent="Camera2D"] -visible = false -offset_left = 138.0 -offset_top = -530.0 -offset_right = 317.0 -offset_bottom = -467.0 -theme_override_font_sizes/font_size = 40 -text = "End Shift -" - -[node name="EndTurn" type="Button" parent="Camera2D"] -visible = false -offset_left = 699.0 -offset_top = -525.0 -offset_right = 879.0 -offset_bottom = -462.0 -theme_override_font_sizes/font_size = 40 -text = "End Turn" - -[node name="EndDraft" type="Button" parent="Camera2D"] -visible = false +[node name="ConfirmDraft" type="Button" parent="StateMachine/Draft"] offset_left = -214.0 offset_top = 275.0 offset_right = 184.0 @@ -90,7 +52,7 @@ offset_bottom = 420.0 theme_override_font_sizes/font_size = 100 text = "Confirm" -[node name="CancelDraft" type="Button" parent="Camera2D"] +[node name="CancelDraft" type="Button" parent="StateMachine/Draft"] visible = false offset_left = -435.0 offset_top = 313.0 @@ -99,7 +61,54 @@ offset_bottom = 390.0 theme_override_font_sizes/font_size = 50 text = "Cancel" -[node name="RoundCounter" type="Label" parent="Camera2D"] +[node name="Setup" type="Node2D" parent="StateMachine"] +visible = false +script = ExtResource("3_t8u1m") + +[node name="Management" type="Node2D" parent="StateMachine"] +visible = false +script = ExtResource("4_fkrfk") + +[node name="RosterButton" type="Area2D" parent="StateMachine/Management"] +position = Vector2(0, 476) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="StateMachine/Management/RosterButton"] +position = Vector2(13, 19) +shape = SubResource("RectangleShape2D_78syh") + +[node name="Money" type="Label" parent="StateMachine/Management"] +offset_left = -860.0 +offset_top = -154.0 +offset_right = -803.0 +offset_bottom = -14.0 +theme_override_font_sizes/font_size = 80 +text = "$" + +[node name="Cost" type="Label" parent="StateMachine/Management"] +offset_left = -624.0 +offset_top = -154.0 +offset_right = -567.0 +offset_bottom = -14.0 +theme_override_colors/font_color = Color(0.839216, 0, 0.105882, 1) +theme_override_font_sizes/font_size = 80 + +[node name="HireWorkerButton" type="Button" parent="StateMachine/Management"] +offset_left = 629.0 +offset_top = -103.0 +offset_right = 833.0 +offset_bottom = -54.0 +theme_override_font_sizes/font_size = 24 +text = "Hire Worker: $60" + +[node name="StartRound" type="Button" parent="StateMachine/Management"] +offset_left = 138.0 +offset_top = -530.0 +offset_right = 483.0 +offset_bottom = -467.0 +theme_override_font_sizes/font_size = 40 +text = "End Management" + +[node name="RoundCounter" type="Label" parent="StateMachine/Management"] offset_left = -410.0 offset_top = -519.0 offset_right = -308.0 @@ -107,30 +116,117 @@ offset_bottom = -482.0 theme_override_font_sizes/font_size = 24 text = "Round: 1" -[node name="TurnCounter" type="Label" parent="Camera2D"] +[node name="PhaseLabel" type="Label" parent="StateMachine/Management"] +offset_left = -151.0 +offset_top = -518.0 +offset_right = 117.0 +offset_bottom = -476.0 +theme_override_font_sizes/font_size = 28 +text = "Management Phase" + +[node name="Worker" type="Node2D" parent="StateMachine"] visible = false +script = ExtResource("5_u4lqc") + +[node name="ReturnButton" type="Area2D" parent="StateMachine/Worker"] +position = Vector2(-844, 180) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="StateMachine/Worker/ReturnButton"] +position = Vector2(-68, 2) +shape = SubResource("RectangleShape2D_vw0g8") +disabled = true + +[node name="Label" type="Label" parent="StateMachine/Worker/ReturnButton"] +offset_left = -45.0 +offset_top = 54.0 +offset_right = 5.0 +offset_bottom = 80.0 +text = "return" + +[node name="WorkerPlaySlots" type="Node2D" parent="StateMachine/Worker"] + +[node name="Slot1" parent="StateMachine/Worker/WorkerPlaySlots" instance=ExtResource("2_ugx0h")] +position = Vector2(-631, 169) +scale = Vector2(1.5, 1.5) + +[node name="Slot2" parent="StateMachine/Worker/WorkerPlaySlots" instance=ExtResource("2_ugx0h")] +position = Vector2(-317, 169) +scale = Vector2(1.5, 1.5) + +[node name="Slot3" parent="StateMachine/Worker/WorkerPlaySlots" instance=ExtResource("2_ugx0h")] +position = Vector2(0, 169) +scale = Vector2(1.5, 1.5) + +[node name="Slot4" parent="StateMachine/Worker/WorkerPlaySlots" instance=ExtResource("2_ugx0h")] +position = Vector2(317, 169) +scale = Vector2(1.5, 1.5) + +[node name="Slot5" parent="StateMachine/Worker/WorkerPlaySlots" instance=ExtResource("2_ugx0h")] +position = Vector2(629, 169) +scale = Vector2(1.5, 1.5) + +[node name="HoldingWorker" type="Node2D" parent="StateMachine/Worker"] +script = ExtResource("6_j37yg") + +[node name="Shift" type="Node2D" parent="StateMachine"] +visible = false +script = ExtResource("7_4jvhu") + +[node name="EndRound" type="Button" parent="StateMachine/Shift"] +visible = false +offset_left = 138.0 +offset_top = -530.0 +offset_right = 317.0 +offset_bottom = -467.0 +theme_override_font_sizes/font_size = 40 +text = "End Shift" + +[node name="HoldingClient" type="Node2D" parent="StateMachine/Shift"] +script = ExtResource("8_0374u") + +[node name="PreviewTask" type="Node2D" parent="StateMachine/Shift/HoldingClient"] +position = Vector2(-154, -346) + +[node name="Payout" type="Label" parent="StateMachine/Shift/HoldingClient"] +offset_left = -624.0 +offset_top = -154.0 +offset_right = -567.0 +offset_bottom = -14.0 +theme_override_colors/font_color = Color(0, 0.858824, 0, 1) +theme_override_font_sizes/font_size = 80 + +[node name="EndTurn" type="Button" parent="StateMachine/Shift/HoldingClient"] +visible = false +offset_left = 699.0 +offset_top = -525.0 +offset_right = 879.0 +offset_bottom = -462.0 +theme_override_font_sizes/font_size = 40 +text = "End Turn" + +[node name="Money" type="Label" parent="StateMachine/Shift"] +offset_left = -860.0 +offset_top = -154.0 +offset_right = -803.0 +offset_bottom = -14.0 +theme_override_font_sizes/font_size = 80 +text = "$" + +[node name="TurnCounter" type="Label" parent="StateMachine/Shift"] offset_left = -545.0 offset_top = -518.0 -offset_right = -491.0 +offset_right = -464.0 offset_bottom = -481.0 theme_override_font_sizes/font_size = 24 text = "Turn: 1" -[node name="States" type="Node2D" parent="."] - -[node name="Draft" type="Node2D" parent="States"] - -[node name="Setup" type="Node2D" parent="States"] - -[node name="Management" type="Node2D" parent="States"] - -[node name="Worker" type="Node2D" parent="States"] - -[node name="HoldingWorker" type="Node2D" parent="States"] - -[node name="Shift" type="Node2D" parent="States"] - -[node name="HoldingClient" type="Node2D" parent="States"] +[node name="PhaseLabel" type="Label" parent="StateMachine/Shift"] +offset_left = -151.0 +offset_top = -518.0 +offset_right = 117.0 +offset_bottom = -476.0 +theme_override_font_sizes/font_size = 28 +text = "Shift Phase" [node name="RosterSection" type="Node2D" parent="."] @@ -179,28 +275,6 @@ position = Vector2(263, 1201) [node name="Position15" type="Node2D" parent="RosterSection"] position = Vector2(516, 1201) -[node name="WorkerPlaySlots" type="Node2D" parent="."] - -[node name="Slot1" parent="WorkerPlaySlots" instance=ExtResource("2_ugx0h")] -position = Vector2(-631, 169) -scale = Vector2(1.5, 1.5) - -[node name="Slot2" parent="WorkerPlaySlots" instance=ExtResource("2_ugx0h")] -position = Vector2(-317, 169) -scale = Vector2(1.5, 1.5) - -[node name="Slot3" parent="WorkerPlaySlots" instance=ExtResource("2_ugx0h")] -position = Vector2(0, 169) -scale = Vector2(1.5, 1.5) - -[node name="Slot4" parent="WorkerPlaySlots" instance=ExtResource("2_ugx0h")] -position = Vector2(317, 169) -scale = Vector2(1.5, 1.5) - -[node name="Slot5" parent="WorkerPlaySlots" instance=ExtResource("2_ugx0h")] -position = Vector2(629, 169) -scale = Vector2(1.5, 1.5) - [node name="TaskDrawDeck" parent="." instance=ExtResource("3_gwbfn")] position = Vector2(500, -400) scale = Vector2(1.5, 1.5) @@ -224,55 +298,19 @@ scale = Vector2(1.5, 1.5) position = Vector2(6.10352e-05, -400) scale = Vector2(1.5, 1.5) -[node name="RosterButton" type="Area2D" parent="."] -position = Vector2(0, 476) - -[node name="CollisionShape2D" type="CollisionShape2D" parent="RosterButton"] -position = Vector2(13, 19) -shape = SubResource("RectangleShape2D_78syh") - -[node name="ReturnButton" type="Area2D" parent="."] -visible = false -position = Vector2(-844, 180) - -[node name="CollisionShape2D" type="CollisionShape2D" parent="ReturnButton"] -position = Vector2(-68, 2) -shape = SubResource("RectangleShape2D_vw0g8") -disabled = true - -[node name="Label" type="Label" parent="ReturnButton"] -offset_left = -45.0 -offset_top = 54.0 -offset_right = 5.0 -offset_bottom = 80.0 -text = "return" - -[node name="HireWorkerButton" type="Button" parent="."] -offset_left = 629.0 -offset_top = -103.0 -offset_right = 833.0 -offset_bottom = -54.0 -theme_override_font_sizes/font_size = 24 -text = "Hire Worker: $60" - -[node name="PreviewTask" type="Node2D" parent="."] -position = Vector2(-154, -346) - [node name="Hand" type="Node2D" parent="."] position = Vector2(0, 612) [node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."] replication_config = SubResource("SceneReplicationConfig_jxmks") -[connection signal="pressed" from="Camera2D/EndManagement" to="." method="enter_shift_overview_state"] -[connection signal="pressed" from="Camera2D/EndShift" to="." method="enter_management_overview_state"] -[connection signal="pressed" from="Camera2D/EndTurn" to="." method="enter_shift_overview_state"] -[connection signal="pressed" from="Camera2D/EndDraft" to="." method="confirm_draft"] -[connection signal="pressed" from="Camera2D/CancelDraft" to="." method="cancel_draft"] -[connection signal="button_pushed" from="TaskDrawDeck" to="." method="_on_task_draw_deck_button_pushed"] -[connection signal="button_pushed" from="PoorDiscardPile" to="." method="move_to_poor_discard"] -[connection signal="input_event" from="RosterButton" to="." method="_on_area_2d_input_event"] -[connection signal="mouse_entered" from="RosterButton" to="." method="lift_hand"] -[connection signal="mouse_exited" from="RosterButton" to="." method="drop_hand"] -[connection signal="input_event" from="ReturnButton" to="." method="_on_area_2d_2_input_event"] -[connection signal="pressed" from="HireWorkerButton" to="." method="_on_hire_button_pressed"] +[connection signal="pressed" from="StateMachine/Draft/ConfirmDraft" to="StateMachine/Draft" method="confirm_draft"] +[connection signal="pressed" from="StateMachine/Draft/CancelDraft" to="StateMachine/Draft" method="cancel_draft"] +[connection signal="input_event" from="StateMachine/Management/RosterButton" to="." method="_on_area_2d_input_event"] +[connection signal="mouse_entered" from="StateMachine/Management/RosterButton" to="." method="lift_hand"] +[connection signal="mouse_exited" from="StateMachine/Management/RosterButton" to="." method="drop_hand"] +[connection signal="pressed" from="StateMachine/Management/HireWorkerButton" to="StateMachine/Management" method="_on_hire_button_pressed"] +[connection signal="pressed" from="StateMachine/Management/StartRound" to="StateMachine/Management" method="_on_start_round_pressed"] +[connection signal="input_event" from="StateMachine/Worker/ReturnButton" to="." method="_on_area_2d_2_input_event"] +[connection signal="pressed" from="StateMachine/Shift/EndRound" to="." method="enter_management_overview_state"] +[connection signal="pressed" from="StateMachine/Shift/HoldingClient/EndTurn" to="." method="enter_shift_overview_state"] diff --git a/Scenes/player_board.tscn b/Scenes/player_board.tscn new file mode 100644 index 0000000..905a5f9 --- /dev/null +++ b/Scenes/player_board.tscn @@ -0,0 +1,40 @@ +[gd_scene load_steps=5 format=3 uid="uid://bvxgkv7pwxh7"] + +[ext_resource type="Script" path="res://PlayerBoard.gd" id="1_80bvu"] +[ext_resource type="Texture2D" uid="uid://olxh7d7xkr5k" path="res://Assets/player_board.png" id="2_rx76r"] +[ext_resource type="PackedScene" uid="uid://y2i3u6n1oowh" path="res://Scenes/deck.tscn" id="3_ypq4b"] +[ext_resource type="PackedScene" uid="uid://baoec8cqmedf6" path="res://Scenes/worker_slot.tscn" id="4_o73ea"] + +[node name="PlayerBoard" type="Node2D"] +script = ExtResource("1_80bvu") + +[node name="Sprite2D" type="Sprite2D" parent="."] +texture = ExtResource("2_rx76r") + +[node name="ShiftDeck" parent="." instance=ExtResource("3_ypq4b")] +position = Vector2(835, -345) +type = 1 + +[node name="GreatDeck" parent="." instance=ExtResource("3_ypq4b")] +position = Vector2(85, -345) +type = 1 + +[node name="GoodDeck" parent="." instance=ExtResource("3_ypq4b")] +position = Vector2(-385, -345) +type = 1 + +[node name="PoorDeck" parent="." instance=ExtResource("3_ypq4b")] +position = Vector2(-855, -345) +type = 1 + +[node name="Slot1" parent="." instance=ExtResource("4_o73ea")] +position = Vector2(-805, 235) + +[node name="Slot2" parent="." instance=ExtResource("4_o73ea")] +position = Vector2(-275, 235) + +[node name="Slot3" parent="." instance=ExtResource("4_o73ea")] +position = Vector2(255, 235) + +[node name="Slot4" parent="." instance=ExtResource("4_o73ea")] +position = Vector2(785, 235) diff --git a/Scenes/worker_card.tscn b/Scenes/worker_card.tscn index ff3a168..d39173b 100644 --- a/Scenes/worker_card.tscn +++ b/Scenes/worker_card.tscn @@ -31,7 +31,6 @@ font_size = 24 size = Vector2(250, 350) [node name="Card" type="Node2D"] -position = Vector2(125, 175) script = ExtResource("1_bry7w") spread_curve = SubResource("Curve_7kl8o") height_curve = SubResource("Curve_b6tcq") @@ -42,6 +41,7 @@ hand_rotation = 0.2 [node name="Sprite2D" type="Sprite2D" parent="."] texture_filter = 1 +position = Vector2(125, 175) texture = ExtResource("2_taqnr") [node name="Title" type="Label" parent="Sprite2D"] @@ -151,15 +151,16 @@ texture = ExtResource("5_a2bm7") region_rect = Rect2(0, 0, 32, 32) [node name="Area2D" type="Area2D" parent="." groups=["Card"]] +position = Vector2(125, 175) [node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] shape = SubResource("RectangleShape2D_awcy0") [node name="Label" type="Label" parent="."] -offset_left = 127.0 -offset_top = 153.0 -offset_right = 167.0 -offset_bottom = 179.0 +offset_left = 252.0 +offset_top = 328.0 +offset_right = 292.0 +offset_bottom = 354.0 text = "0" [connection signal="input_event" from="Area2D" to="." method="_on_area_2d_input_event"] diff --git a/Scenes/worker_slot.tscn b/Scenes/worker_slot.tscn index 3a1c54b..5b9a5bf 100644 --- a/Scenes/worker_slot.tscn +++ b/Scenes/worker_slot.tscn @@ -1,25 +1,32 @@ -[gd_scene load_steps=3 format=3 uid="uid://baoec8cqmedf6"] +[gd_scene load_steps=5 format=3 uid="uid://baoec8cqmedf6"] -[ext_resource type="Script" path="res://Scripts/slot_button.gd" id="1_fras1"] +[ext_resource type="Script" path="res://Scripts/worker_slot.gd" id="1_0xyh3"] +[ext_resource type="Texture2D" uid="uid://cpitf556hf0g" path="res://Assets/worker_slot.png" id="1_fxq0t"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_1gv0f"] -size = Vector2(152, 214) +size = Vector2(250, 350) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_27hn2"] +size = Vector2(350, 250) [node name="Worker Slot" type="Node2D"] -script = ExtResource("1_fras1") +script = ExtResource("1_0xyh3") -[node name="Label" type="Label" parent="."] -offset_left = -72.0 -offset_top = -14.0 -offset_right = 72.0 -offset_bottom = 12.0 -text = "Empty Worker Slot" +[node name="Sprite2D" type="Sprite2D" parent="."] +texture = ExtResource("1_fxq0t") -[node name="Area2D" type="Area2D" parent="."] -position = Vector2(-76, -103) +[node name="Worker" type="Area2D" parent="."] +position = Vector2(-225, -175) -[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] -position = Vector2(76, 107) +[node name="CollisionShape2D" type="CollisionShape2D" parent="Worker"] +visible = false +position = Vector2(125, 175) shape = SubResource("RectangleShape2D_1gv0f") -[connection signal="input_event" from="Area2D" to="." method="_on_area_2d_input_event"] +[node name="Client" type="Area2D" parent="."] +position = Vector2(-125, -175) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Client"] +visible = false +position = Vector2(175, 125) +shape = SubResource("RectangleShape2D_27hn2") diff --git a/Scripts/PlayerStateMachine/bot_controller.gd b/Scripts/PlayerStateMachine/bot_controller.gd new file mode 100644 index 0000000..44fef53 --- /dev/null +++ b/Scripts/PlayerStateMachine/bot_controller.gd @@ -0,0 +1,2 @@ +class_name BotController +extends PlayerController diff --git a/Scripts/PlayerStateMachine/draft_state.gd b/Scripts/PlayerStateMachine/draft_state.gd new file mode 100644 index 0000000..13c3522 --- /dev/null +++ b/Scripts/PlayerStateMachine/draft_state.gd @@ -0,0 +1,48 @@ +class_name DraftState +extends State + + +func confirm_draft(): + if player.selected_for_draft.size() != player.draft_limit: + return + match(player.draft): + player.DraftType.HIRE_WORKER, player.DraftType.STARTING_HAND: + for card in player.selected_for_draft: + player.add_to_hand(card) + player.workers.append(card) + player.shown_for_draft.remove_at(player.shown_for_draft.find(card)) + for card in player.shown_for_draft: + card.position = Vector2(9999, 9999) + player.board.discard_worker(card) + match(fsm.history[-1]): + fsm.FSMState.SETUP, fsm.FSMState.MANAGEMENT: + fsm.change_state(fsm.FSMState.MANAGEMENT) + player.draft_completed.emit() + + +func cancel_draft(): + match(player.draft): + player.DraftType.HIRE_WORKER, player.DraftType.STARTING_HAND: + for card in player.shown_for_draft: + card.visible = false + card.set_process(false) + player.board.discard_worker(player.board.search_and_draw_worker(card)) + match(fsm.history[-1]): + fsm.FSMState.SETUP, fsm.FSMState.MANAGEMENT: + fsm.change_state(fsm.FSMState.MANAGEMENT) + player.draft_completed.emit() + + +func enter(): + self.visible = true + $Label.text = "Choose " + str(player.draft_limit) + " cards" + match(player.draft): + player.DraftType.HIRE_WORKER: + $CancelDraft.visible = true + player.DraftType.STARTING_HAND: + $CancelDraft.visible = false + + +func exit(): + self.visible = false + diff --git a/Scripts/PlayerStateMachine/holding_client_state.gd b/Scripts/PlayerStateMachine/holding_client_state.gd new file mode 100644 index 0000000..7b07410 --- /dev/null +++ b/Scripts/PlayerStateMachine/holding_client_state.gd @@ -0,0 +1,49 @@ +class_name HoldingClientState +extends State + +func _ready(): + player = get_parent().get_parent().get_parent() as Player + fsm = get_parent().get_parent() as StateMachine + + +func assign_task_to_worker(): + player.client_assignment = player.active_workers.find(player.selected_worker) + if player.active_clients[player.client_assignment] != null: + return + player.current_client.slide_to_position(player.selected_worker.position.x - 100, player.selected_worker.position.y - 100, 0.0, 0.3) + player.current_client.show_time_selector() + await player.current_client.time_slots_selected + player.payout = 0 + player.payout += player.current_client.turns_left * 2 + for service in player.current_client.services: + if player.selected_worker.services.has(service): + player.payout += Data.service_prices[service] + $Payout.text = "$" + str(player.payout) + $EndTurn.visible = true + + +func move_to_poor_discard(_button): + player.current_client.slide_to_position(player.pile_poor.position.x, player.pile_poor.position.y, 0.0, 0.2) + player.client_assignment = -1 + $EndTurn.visible = true + player.payout = 0 + $Payout.text = "" + + +func enter(): + self.visible = true + $Payout.text = "" + player.current_client = player.shift_deck.pop_back() + player.current_client.position = Vector2(494, -414) + player.current_client.visible = true + player.current_client.z_index = 1 + player.current_client.slide_to_position($PreviewTask.position.x, $PreviewTask.position.y, 0.0, 0.3) + player.task_drawn = true + player.pile_draw.disabled = true + player.pile_poor.disabled = false + player.clients_left = str(player.shift_deck.size()) + + +func exit(): + self.visible = false + diff --git a/Scripts/PlayerStateMachine/holding_worker_state.gd b/Scripts/PlayerStateMachine/holding_worker_state.gd new file mode 100644 index 0000000..915ac49 --- /dev/null +++ b/Scripts/PlayerStateMachine/holding_worker_state.gd @@ -0,0 +1,14 @@ +class_name HoldingWorkerState +extends State + +func _ready(): + player = get_parent().get_parent().get_parent() as Player + fsm = get_parent().get_parent() as StateMachine + +func enter(): + self.visible = true + + +func exit(): + self.visible = false + diff --git a/Scripts/PlayerStateMachine/human_controller.gd b/Scripts/PlayerStateMachine/human_controller.gd new file mode 100644 index 0000000..1dfbfce --- /dev/null +++ b/Scripts/PlayerStateMachine/human_controller.gd @@ -0,0 +1,3 @@ +class_name HumanController +extends PlayerController + diff --git a/Scripts/PlayerStateMachine/management_state.gd b/Scripts/PlayerStateMachine/management_state.gd new file mode 100644 index 0000000..c767bcd --- /dev/null +++ b/Scripts/PlayerStateMachine/management_state.gd @@ -0,0 +1,38 @@ +class_name ManagementState +extends State + +func _on_hire_button_pressed(): + if player.money >= player.hire_costs[player.workers.size()]: + player.money -= player.hire_costs[player.workers.size()] + $Money.text = "$" + str(player.money) + player.draft = player.DraftType.HIRE_WORKER + player.draft_workers(3, 1) + await player.draft_completed + $HireWorkerButton.text = "Hire Worker: $" + str(player.hire_costs[player.workers.size()]) + + +func _on_start_round_pressed() -> void: + player + fsm.change_state(fsm.FSMState.SHIFT) + + +func enter(): + self.visible = true + for worker in player.active_workers: + if worker != null: + worker.decrease_stress(worker.stress) + $RoundCounter.text = "Round: " + str(player.board.round_num) + $RosterButton/CollisionShape2D.disabled = false + player.hand_showing = true + player.selected_worker = null + player.camera.position.y = 0 + #TODO: Figure out what this loop is for + for x in player.hand.size(): + player.hand[x].in_hand = true + player.process_discard_decks() + + +func exit(): + self.visible = false + $RosterButton/CollisionShape2D.disabled = true + diff --git a/Scripts/PlayerStateMachine/player_controller.gd b/Scripts/PlayerStateMachine/player_controller.gd new file mode 100644 index 0000000..294a2a1 --- /dev/null +++ b/Scripts/PlayerStateMachine/player_controller.gd @@ -0,0 +1,2 @@ +class_name PlayerController +extends Node diff --git a/Scripts/PlayerStateMachine/setup_state.gd b/Scripts/PlayerStateMachine/setup_state.gd new file mode 100644 index 0000000..80d140c --- /dev/null +++ b/Scripts/PlayerStateMachine/setup_state.gd @@ -0,0 +1,12 @@ +class_name SetupState +extends State + + +func enter(): + self.visible = true + player.draft = player.DraftType.STARTING_HAND + player.draft_workers(4, 2) + + +func exit(): + self.visible = false diff --git a/Scripts/PlayerStateMachine/shift_state.gd b/Scripts/PlayerStateMachine/shift_state.gd new file mode 100644 index 0000000..b6d937e --- /dev/null +++ b/Scripts/PlayerStateMachine/shift_state.gd @@ -0,0 +1,56 @@ +class_name ShiftState +extends State + + +func enter(): + player.pad_shift_deck() + self.visible = true + $TurnCounter.text = "Turn: " + str(player.board.turn_num) + player.camera.position.y = 0 + for x in player.hand.size(): + player.hand[x].in_hand = true + if player.hand_hidden == false: + player.hand_hiding = true + player.pile_draw.disabled = false + player.task_drawn = false + player.clients_left.text = str(player.shift_deck.size()) + player.money += player.payout + player.payout = 0 + if player.client_assignment != null and player.current_client != null: + player.active_clients[player.client_assignment] = player.current_client + if player.active_workers[player.client_assignment].increase_stress(player.current_client.initial_stress): + player.worker_exceeded_capacity(player.client_assignment) + player.client_assignment = -1 + player.current_client = null + elif player.client_assignment == -1 and player.current_client != null: + player.poor_discard.append(player.current_client) + player.current_client = null + $Money.text = "$" + str(player.money) + player.pile_poor.disabled = true + #Pretty sure these are done in the right order even though it looks the wrong way around + for x in player.active_workers.size(): + if player.active_workers[x] != null and player.active_clients[x] == null: + player.active_workers[x].decrease_stress(1) + if player.active_workers[x] != null and player.active_clients[x] != null: + if player.active_workers[x].increase_stress(1): + player.worker_exceeded_capacity(x) + player.active_clients[x].turns_left -= 1 + player.active_clients[x].update_counter() + if player.active_clients[x].turns_left == 0: + player.evaluate_task_success(x) + var tasks_done = true + for client in player.active_clients: + if client != null: + tasks_done = false + if player.shift_deck.size() == 0: + if tasks_done: + player.round_completed = true + #enter_management_overview_state() + else: + $HoldingClient/EndTurn.visible = true + player.pile_draw.disabled = true + + +func exit(): + self.visible = false + diff --git a/Scripts/PlayerStateMachine/state.gd b/Scripts/PlayerStateMachine/state.gd new file mode 100644 index 0000000..7f959b3 --- /dev/null +++ b/Scripts/PlayerStateMachine/state.gd @@ -0,0 +1,17 @@ +class_name State +extends Node2D + +@export var player : Player +@export var fsm : StateMachine + +func _ready() -> void: + player = get_parent().get_parent() as Player + fsm = get_parent() as StateMachine + + +func enter(): + pass + + +func exit(): + pass diff --git a/Scripts/PlayerStateMachine/state_machine.gd b/Scripts/PlayerStateMachine/state_machine.gd new file mode 100644 index 0000000..c4fa8a4 --- /dev/null +++ b/Scripts/PlayerStateMachine/state_machine.gd @@ -0,0 +1,29 @@ +class_name StateMachine +extends Node + +enum FSMState {DRAFT, SETUP, MANAGEMENT, WORKER, H_WORKER, SHIFT, H_CLIENT} + +@export var state_nodes : Array[State] = [] + +var state : FSMState +var history : Array[FSMState] = [] + + +func _ready() -> void: + #TODO: Bug in 4.0.3.stable requires this + state_nodes.append($Draft) + state_nodes.append($Setup) + state_nodes.append($Management) + state_nodes.append($Worker) + state_nodes.append($Worker/HoldingWorker) + state_nodes.append($Shift) + state_nodes.append($Shift/HoldingClient) + + +func change_state(new_state : FSMState) -> void: + history.append(state) + state = new_state + state_nodes[history[-1]].exit() + state_nodes[state].enter() + + diff --git a/Scripts/PlayerStateMachine/worker_state.gd b/Scripts/PlayerStateMachine/worker_state.gd new file mode 100644 index 0000000..1eb5e76 --- /dev/null +++ b/Scripts/PlayerStateMachine/worker_state.gd @@ -0,0 +1,18 @@ +class_name WorkerState +extends State + + +func enter(): + self.visible = true + player.selected_worker = null + $ReturnButton/CollisionShape2D.disabled = false + player.camera.position.y = 640 + for x in player.hand.size(): + player.hand[x].in_hand = false + player.hand[x].slide_to_position(player.roster_positions[x].position.x, player.roster_positions[x].position.y, 0.0, 0.2) + + +func exit(): + self.visible = false + $ReturnButton/CollisionShape2D.disabled = true + diff --git a/Scripts/board.gd b/Scripts/board.gd index 9bb0e0a..7f1e3ec 100644 --- a/Scripts/board.gd +++ b/Scripts/board.gd @@ -1,22 +1,10 @@ class_name Board extends Node2D -signal turn_started -signal round_started - -const WORKER_DECK_SAVE_PATH = "user://worker_deck.json" -const CLIENT_DECK_SAVE_PATH = "user://client_deck.json" - var round_num : int = 0 var turn_num : int = 0 var _players : Array[Player] = [] var _readied_players -var _worker_deck : Array[Worker] = [] -var _worker_discard_deck : Array[Worker] = [] -var _client_deck : Array[Client] = [] -var _client_discard_deck : Array[Client] = [] -var _worker_scene = preload("res://Scenes/worker_card.tscn") -var _client_scene = preload("res://Scenes/client_card.tscn") func add_player(player : Player) -> void: @@ -77,52 +65,6 @@ func discard_client(card : Client) -> void: _client_discard_deck.append(card) -func _load_workers(): - if !FileAccess.file_exists(WORKER_DECK_SAVE_PATH): - return - var save_game = FileAccess.open(WORKER_DECK_SAVE_PATH, FileAccess.READ) - var card_dict = JSON.parse_string(save_game.get_line()) - for key in card_dict: - var value = card_dict[key] - var card_instance = _worker_scene.instantiate() - #JSON only returns floats so we have to get ints out of the dict - var bonuses = [] - for x in value.slice(1, value.size()): - bonuses.append(int(x)) - card_instance.setup(key, int(value[0]), bonuses) - card_instance.position = Vector2(9999, 9999) - #card_instance.scale = Vector2(1, 1) - #card_instance.visible = false - #card_instance.set_process(false) - #card_instance.card_clicked.connect(select_card) - _worker_deck.append(card_instance) - add_child(card_instance) - _worker_deck.shuffle() - - -func _load_clients(): - if !FileAccess.file_exists(CLIENT_DECK_SAVE_PATH): - return - var save_game = FileAccess.open(CLIENT_DECK_SAVE_PATH, FileAccess.READ) - var card_dict = JSON.parse_string(save_game.get_line()) - for key in card_dict: - var value = card_dict[key] - var card_instance = _client_scene.instantiate() - #JSON only returns floats so we have to get ints out of the dict - var bool_array = [] - var int_array = [] - for x in value.slice(1, 5): - bool_array.append(bool(x)) - for x in value.slice(5, value.size()): - int_array.append(int(x)) - card_instance.setup(key, int(value[0]), bool_array, int_array) - card_instance.position = Vector2(9999, 9999) - #card_instance.scale = Vector2(1, 1) - _client_deck.append(card_instance) - add_child(card_instance) - _client_deck.shuffle() - - func _draw_card(amount : int, deck, discard): var array = [] for x in amount: @@ -136,13 +78,4 @@ func _draw_card(amount : int, deck, discard): array.append(deck.pop_back()) return array -#Ideas okay? -#Make the client cards have a little progress track thats like how much they like their service right, -#put the poor/good/great blocks along that track, and instead of the services having that each service -#contributes a different number of points along that other track, so the money you recieve for making -#the match can be the same across all clients, but it shows how some clients value one more over the other -#without actually requiring you to have any specific one as long as you have enough turns to get them along -#the track, so a short session with all the perks can be a great service but a less special or less -#stress inducing session needs to be longer so the same worker needs to remain occupied longer, and it gives -#you more to do on your turn because you get to decide what all your little workers do rather than them only -#being interacted with when you're placing down a client card + diff --git a/Scripts/card_crafter.gd b/Scripts/card_crafter.gd index 043bcfd..f8790be 100644 --- a/Scripts/card_crafter.gd +++ b/Scripts/card_crafter.gd @@ -1,6 +1,6 @@ extends Node2D -var card_scene = preload("res://Scenes/card.tscn") +var card_scene = preload("res://Scenes/worker_card.tscn") var icon_order = [0, 1, 3, 5, 7, 8, 6, 4, 2] var symbol_buttons : Array[TextureButton] = [] var symbol_count_labels : Array[LineEdit] = [] diff --git a/Scripts/chat.gd b/Scripts/chat.gd new file mode 100644 index 0000000..3cb6439 --- /dev/null +++ b/Scripts/chat.gd @@ -0,0 +1,5 @@ +extends RichTextLabel + +@rpc("any_peer", "call_local") +func add_line(username, message): + text += "[" + username + "] " + message + "\n" diff --git a/Scripts/deck.gd b/Scripts/deck.gd new file mode 100644 index 0000000..3d7fef7 --- /dev/null +++ b/Scripts/deck.gd @@ -0,0 +1,53 @@ +class_name Deck +extends Node2D + +signal clicked +signal mouse_entered +signal mouse_exited + +enum Type {WORKER, CLIENT} + +@export var type: Type +var cards: Array[Card] = [] + +@onready var _w_pos = $Worker.global_position +@onready var _c_pos = $Client.global_position + +func _ready() -> void: + match type: + Type.WORKER: + $Area2D/WorkerShape.disabled = false + $Area2D/ClientSprite.visible = false + Type.CLIENT: + $Area2D/ClientShape.disabled = false + $Area2D/WorkerSprite.visible = false + + +func _on_area_2d_input_event(_viewport, event, _shape_idx) -> void: + if event is InputEventMouseButton and event.pressed: + clicked.emit() + + +func _on_area_2d_mouse_entered() -> void: + mouse_entered.emit() + + +func _on_area_2d_mouse_exited() -> void: + mouse_exited.emit() + + +func draw() -> Card: + return cards.pop_back() + + +func place(card: Card) -> void: + cards.append(card) + match type: + Type.WORKER: + card.slide_to_position(_w_pos.x, _w_pos.y, 0.0, 0.2) + Type.CLIENT: + card.slide_to_position(_c_pos.x, _c_pos.y, 0.0, 0.2) + + +func shuffle() -> void: + cards.shuffle() diff --git a/Scripts/game.gd b/Scripts/game.gd new file mode 100644 index 0000000..d186744 --- /dev/null +++ b/Scripts/game.gd @@ -0,0 +1,103 @@ +class_name Game +extends Node2D + +signal game_paused +signal game_resumed +signal turn_started +signal round_started + +enum PlayerType {HUMAN, BOT} + +const WORKER_DECK_SAVE_PATH = "user://worker_deck.json" +const CLIENT_DECK_SAVE_PATH = "user://client_deck.json" + +@export var worker_deck: Deck +@export var client_deck: Deck +@export var worker_discard: Deck +@export var client_discard: Deck +@export var seat1: Node2D +@export var seat2: Node2D +@export var seat3: Node2D +@export var seat4: Node2D + +var players = 0 + +var _worker_scene = preload("res://Scenes/worker_card.tscn") +var _client_scene = preload("res://Scenes/client_card.tscn") +var _player_scene = preload("res://Scenes/player_board.tscn") +var _human_scene = preload("res://Scenes/human_player.tscn") +var _bot_scene = preload("res://Scenes/bot_player.tscn") + +func _ready() -> void: + _load_workers() + _load_clients() + + +func _load_workers(): + if !FileAccess.file_exists(WORKER_DECK_SAVE_PATH): + return + var save_game = FileAccess.open(WORKER_DECK_SAVE_PATH, FileAccess.READ) + var card_dict = JSON.parse_string(save_game.get_line()) + for key in card_dict: + var value = card_dict[key] + var card_instance = _worker_scene.instantiate() + #JSON only returns floats so we have to get ints out of the dict + var bonuses = [] + for x in value.slice(1, value.size()): + bonuses.append(int(x)) + card_instance.setup(key, int(value[0]), bonuses) + add_child(card_instance) + worker_deck.place(card_instance) + worker_deck.shuffle() + + +func _load_clients(): + if !FileAccess.file_exists(CLIENT_DECK_SAVE_PATH): + return + var save_game = FileAccess.open(CLIENT_DECK_SAVE_PATH, FileAccess.READ) + var card_dict = JSON.parse_string(save_game.get_line()) + for key in card_dict: + var value = card_dict[key] + var card_instance = _client_scene.instantiate() + #JSON only returns floats so we have to get ints out of the dict + var bool_array = [] + var int_array = [] + for x in value.slice(1, 5): + bool_array.append(bool(x)) + for x in value.slice(5, value.size()): + int_array.append(int(x)) + card_instance.setup(key, int(value[0]), bool_array, int_array) + add_child(card_instance) + client_deck.place(card_instance) + client_deck.shuffle() + + +@rpc +func add_player(id: int, username: String, type: PlayerType) -> void: + if players >= 4: + return + if type == null: + type = PlayerType.HUMAN + var board = _player_scene.instantiate() + match players: + 0: + board.position = seat1.position + 1: + board.position = seat2.position + 2: + board.position = seat3.position + 3: + board.position = seat4.position + $Players.add_child(board) + var controller + match type: + PlayerType.HUMAN: + controller = _human_scene.instantiate() + PlayerType.BOT: + controller = _bot_scene.instantiate() + controller.name = str(id) + controller.set_multiplayer_authority(id) + controller.get_node("UI/Label").text = str(username) + board.add_child(controller) + players += 1 + diff --git a/Scripts/network_lobby.gd b/Scripts/network_lobby.gd new file mode 100644 index 0000000..ee875fe --- /dev/null +++ b/Scripts/network_lobby.gd @@ -0,0 +1,72 @@ +extends Node2D + +const SERVER_PORT := 58008 +const MAX_PLAYERS := 4 + +var game_scene = preload("res://Scenes/Table.tscn") + +var connected_players = {} +var player_info = {} + +@export var seats : Array[Node2D] = [null, null, null, null] +var enet_peer = ENetMultiplayerPeer.new() +var game : Game +var players_connected = 0 + +func _ready() -> void: + game = game_scene.instantiate() as Game + + + +func host_server() -> void: + if $UI/Username.text == "": + return + $UI.visible = false + enet_peer.create_server(SERVER_PORT, MAX_PLAYERS) + multiplayer.multiplayer_peer = enet_peer + add_child(game) + + player_info[1] = $UI/Username.text + add_player(1, player_info[1]) + game.get_node("LobbyCamera/LineEdit").text_submitted.connect(text_message) + + multiplayer.peer_connected.connect( + func(new_peer_id): + rpc_id(new_peer_id, "add_previous_players", connected_players) + #rpc("add_new_player", new_peer_id) + ) + + +func connect_to_server() -> void: + if $UI/Username.text == "": + return + $UI.visible = false + var ip = $UI/IPField.text if $UI/IPField.text != "" else $UI/IPField.placeholder_text + var port = $UI/PortField.text if $UI/PortField.text != "" else $UI/PortField.placeholder_text + enet_peer.create_client(ip, int(port)) + multiplayer.multiplayer_peer = enet_peer + add_child(game) + player_info[multiplayer.get_unique_id()] = $UI/Username.text + +func add_player(peer_id, username): + connected_players[peer_id] = username + game.add_player(peer_id, username, game.PlayerType.HUMAN) + + +@rpc("any_peer") +func add_new_player(peer_id, username): + add_player(peer_id, username) + + +func text_message(new_text): + game.get_node("LobbyCamera/RichTextLabel").rpc("add_line", player_info[multiplayer.get_unique_id()], new_text) + game.get_node("LobbyCamera/LineEdit").text = "" + + +@rpc +func add_previous_players(players): + for key in players: + add_player(key, players[key]) + rpc_id(key, "add_new_player", multiplayer.get_unique_id(), player_info[multiplayer.get_unique_id()]) + add_player(multiplayer.get_unique_id(), player_info[multiplayer.get_unique_id()]) + game.get_node("LobbyCamera/LineEdit").text_submitted.connect(text_message) diff --git a/Scripts/player.gd b/Scripts/player.gd index 75f2b60..ef35da6 100644 --- a/Scripts/player.gd +++ b/Scripts/player.gd @@ -4,13 +4,12 @@ extends Node2D signal draft_completed signal board_attached -enum FSMState {DRAFT, SETUP, MANAGEMENT, WORKER, H_WORKER, SHIFT, H_CLIENT} -enum DraftType {HIRE_WORKER} +enum DraftType {STARTING_HAND, HIRE_WORKER} +@export var fsm : StateMachine @export var roster_positions : Array[Node2D] = [] @export var slot_buttons : Array[Node2D] = [] -@export var seconds_to_hide_hand := 2.0 -@export var seconds_to_show_hand := 2.0 +@export var hand_slide_anim_time := 0.3 var money := 0 var payout := 0 var cost := 0 @@ -23,8 +22,6 @@ var active_clients : Array[Client] = [null, null, null, null, null] var poor_discard : Array[Client] = [] var good_discard : Array[Client] = [] var great_discard : Array[Client] = [] -var last_fsm_state := FSMState.SETUP -var current_fsm_state := FSMState.SETUP var draft := DraftType.HIRE_WORKER var hand_hiding := false var hand_hidden := false @@ -42,6 +39,13 @@ var board : Board = null var turn_completed = false var round_completed = false +@onready var pile_draw = $TaskDrawDeck/Area2D/CollisionShape2D +@onready var pile_poor = $PoorDiscardPile/Area2D/CollisionShape2D + +@onready var clients_left = $TaskDrawDeck/Count + +@onready var camera = $Camera2D + func _ready() -> void: #Bug in Godot 4.0.3.stable makes it nessesary to add these manually @@ -60,11 +64,11 @@ func _ready() -> void: roster_positions.append($RosterSection/Position13) roster_positions.append($RosterSection/Position14) roster_positions.append($RosterSection/Position15) - slot_buttons.append($WorkerPlaySlots/Slot1) - slot_buttons.append($WorkerPlaySlots/Slot2) - slot_buttons.append($WorkerPlaySlots/Slot3) - slot_buttons.append($WorkerPlaySlots/Slot4) - slot_buttons.append($WorkerPlaySlots/Slot5) + slot_buttons.append($StateMachine/Worker/WorkerPlaySlots/Slot1) + slot_buttons.append($StateMachine/Worker/WorkerPlaySlots/Slot2) + slot_buttons.append($StateMachine/Worker/WorkerPlaySlots/Slot3) + slot_buttons.append($StateMachine/Worker/WorkerPlaySlots/Slot4) + slot_buttons.append($StateMachine/Worker/WorkerPlaySlots/Slot5) for button in slot_buttons: button.button_pushed.connect(select_slot) $PoorDiscardPile/Label.text = "No / Poor service" @@ -73,14 +77,14 @@ func _ready() -> void: $TaskDrawDeck/Label.text = "Click to draw task card" $Camera2D.make_current() await board_attached - enter_setup_state() + fsm.change_state(fsm.FSMState.SETUP) func _process(delta) -> void: if (hand_hiding): - if hand_hiding_progress < seconds_to_hide_hand: + if hand_hiding_progress < hand_slide_anim_time: hand_hiding_progress += delta - var percent = clampf(hand_hiding_progress / seconds_to_hide_hand, 0.0, 1.0) + var percent = clampf(hand_hiding_progress / hand_slide_anim_time, 0.0, 1.0) for card in hand: card.hand_position.y = lerpf($Hand.position.y, $Hand.position.y + 300.0, percent) else: @@ -88,9 +92,9 @@ func _process(delta) -> void: hand_hidden = true hand_hiding_progress = 0.0 if (hand_showing): - if hand_showing_progress < seconds_to_show_hand: + if hand_showing_progress < hand_slide_anim_time: hand_showing_progress += delta - var percent = clampf(hand_showing_progress / seconds_to_show_hand, 0.0, 1.0) + var percent = clampf(hand_showing_progress / hand_slide_anim_time, 0.0, 1.0) for card in hand: card.hand_position.y = lerpf($Hand.position.y + 300.0, $Hand.position.y, percent) else: @@ -137,41 +141,8 @@ func drop_hand(): card.hovered = false -func _on_hire_button_pressed(): - if money >= hire_costs[workers.size()]: - money -= hire_costs[workers.size()] - $Camera2D/Money.text = "$" + str(money) - draft_workers(3, 1, true) - await draft_completed - $Button.text = "Hire Worker: $" + str(hire_costs[workers.size()]) - - -func assign_task_to_worker(): - client_assignment = active_workers.find(selected_worker) - if active_clients[client_assignment] != null: - return - current_client.slide_to_position(selected_worker.position.x - 100, selected_worker.position.y - 100, 0.0, 0.3) - current_client.show_time_selector() - await current_client.time_slots_selected - payout = 0 - payout += current_client.turns_left * 2 - for service in current_client.services: - if selected_worker.services.has(service): - payout += Data.service_prices[service] - $Camera2D/Payout.text = "$" + str(payout) - $"Camera2D/EndTurn".visible = true - - -func move_to_poor_discard(_button): - current_client.slide_to_position($PoorDiscardPile.position.x, $PoorDiscardPile.position.y, 0.0, 0.2) - client_assignment = -1 - $Camera2D/EndTurn.visible = true - payout = 0 - $Camera2D/Payout.text = "" - - func select_card(card): - if current_fsm_state == FSMState.DRAFT: + if fsm.state == fsm.FSMState.DRAFT: if selected_for_draft.size() <= draft_limit: if selected_for_draft.has(card): selected_for_draft.remove_at(selected_for_draft.find(card)) @@ -182,8 +153,8 @@ func select_card(card): card.slide_to_position(card.position.x, card.position.y - 40, 0.0, 0.1) return selected_worker = card - if current_client != null: - assign_task_to_worker() + if fsm.state == fsm.FSMState.H_CLIENT: + fsm.state_nodes[fsm.FSMState.H_CLIENT].assign_task_to_worker() func select_slot(slot): @@ -216,16 +187,16 @@ func select_slot(slot): func _on_area_2d_input_event(_viewport, event, _shape_idx): if event is InputEventMouseButton and event.pressed: - enter_workers_view_state() + fsm.change_state(fsm.FSMState.WORKER) func _on_area_2d_2_input_event(_viewport, event, _shape_idx): if event is InputEventMouseButton and event.pressed: - enter_management_overview_state() + fsm.change_state(fsm.FSMState.MANAGEMENT) func _on_task_draw_deck_button_pushed(_button): - enter_holding_task_state() + fsm.change_state(fsm.FSMState.H_CLIENT) func evaluate_task_success(num): @@ -279,8 +250,7 @@ func worker_exceeded_capacity(num): active_workers[num] = null -func draft_workers(_draw, pick, cancelable): - draft = DraftType.HIRE_WORKER +func draft_workers(_draw, pick): draft_limit = pick shown_for_draft = [] selected_for_draft = [] @@ -295,7 +265,7 @@ func draft_workers(_draw, pick, cancelable): var ratio = float(i) / float(_draw - 1) var xx = lerpf(-1 * x, x, ratio) card.slide_to_position(xx, y, 0.0, 0.3) - enter_draft_state(cancelable) + fsm.change_state(fsm.FSMState.DRAFT) func pad_shift_deck(): @@ -332,189 +302,3 @@ func process_discard_decks(): great_discard[x].visible = false great_discard.remove_at(x) - -func confirm_draft(): - if selected_for_draft.size() != draft_limit: - return - $Camera2D/EndDraft.visible = false - $Camera2D/CancelDraft.visible = false - match(draft): - DraftType.HIRE_WORKER: - for card in selected_for_draft: - add_to_hand(card) - workers.append(card) - shown_for_draft.remove_at(shown_for_draft.find(card)) - for card in shown_for_draft: - card.position = Vector2(9999, 9999) - board.discard_worker(card) - match(last_fsm_state): - FSMState.SETUP, FSMState.MANAGEMENT: - enter_management_overview_state() - draft_completed.emit() - - -func cancel_draft(): - $Camera2D/EndDraft.visible = false - $Camera2D/CancelDraft.visible = false - match(draft): - DraftType.HIRE_WORKER: - for card in shown_for_draft: - card.visible = false - card.set_process(false) - board.discard_worker(board.search_and_draw_worker(card)) - match(last_fsm_state): - FSMState.SETUP, FSMState.MANAGEMENT: - enter_management_overview_state() - draft_completed.emit() - - -func enter_draft_state(cancelable): - last_fsm_state = current_fsm_state - current_fsm_state = FSMState.DRAFT - $Camera2D/PhaseLabel.text = "Choose " + str(draft_limit) + " cards" - $Camera2D/EndManagement.visible = false - $RosterButton/CollisionShape2D.disabled = true - $ReturnButton.visible = false - $ReturnButton/CollisionShape2D.disabled = true - $Camera2D/EndDraft.visible = true - if cancelable: - $Camera2D/CancelDraft.visible = true - - -func enter_setup_state(): - last_fsm_state = current_fsm_state - current_fsm_state = FSMState.SETUP - #money = 100 - $Camera2D/Money.text = "$" + str(money) - draft_workers(4, 2, false) - - -func enter_management_overview_state(): - last_fsm_state = current_fsm_state - current_fsm_state = FSMState.MANAGEMENT - for worker in active_workers: - if worker != null: - worker.decrease_stress(worker.stress) - $Camera2D/RoundCounter.text = "Round: " + str(board.round_num) - $Camera2D/PhaseLabel.text = "Management Phase" - $Camera2D/EndManagement.visible = true - $Camera2D/Cost.visible = true - $Camera2D/EndShift.visible = false - $Camera2D/EndTurn.visible = false - $RosterButton/CollisionShape2D.disabled = false - $WorkerPlaySlots/Slot1.visible = true - $WorkerPlaySlots/Slot2.visible = true - $WorkerPlaySlots/Slot3.visible = true - $WorkerPlaySlots/Slot4.visible = true - $WorkerPlaySlots/Slot5.visible = true - $HireWorkerButton.visible = true - $Camera2D/TurnCounter.visible = false - hand_showing = true - selected_worker = null - $RosterButton/CollisionShape2D.disabled = false - $ReturnButton.visible = false - $ReturnButton/CollisionShape2D.disabled = true - $Camera2D.position.y = 0 - for x in hand.size(): - hand[x].in_hand = true - $TaskDrawDeck/Area2D/CollisionShape2D.disabled = true - $PoorDiscardPile/Area2D/CollisionShape2D.disabled = true - process_discard_decks() - pad_shift_deck() - $TaskDrawDeck/Count.text = str(shift_deck.size()) - - -func enter_workers_view_state(): - last_fsm_state = current_fsm_state - current_fsm_state = FSMState.WORKER - selected_worker = null - $RosterButton/CollisionShape2D.disabled = true - $ReturnButton.visible = true - $ReturnButton/CollisionShape2D.disabled = false - $Camera2D.position.y = 640 - for x in hand.size(): - hand[x].in_hand = false - hand[x].slide_to_position(roster_positions[x].position.x, roster_positions[x].position.y, 0.0, 0.2) - - -func enter_holding_worker_state(): - last_fsm_state = current_fsm_state - current_fsm_state = FSMState.H_WORKER - - -func enter_shift_overview_state(): - last_fsm_state = current_fsm_state - current_fsm_state = FSMState.SHIFT - $Camera2D/TurnCounter.visible = true - $Camera2D/TurnCounter.text = "Turn: " + str(board.turn_num) - $Camera2D/PhaseLabel.text = "Shift Phase" - $Camera2D/EndManagement.visible = false - $RosterButton/CollisionShape2D.disabled = true - $WorkerPlaySlots/Slot1.visible = false - $WorkerPlaySlots/Slot2.visible = false - $WorkerPlaySlots/Slot3.visible = false - $WorkerPlaySlots/Slot4.visible = false - $WorkerPlaySlots/Slot5.visible = false - $ReturnButton.visible = false - $ReturnButton/CollisionShape2D.disabled = true - $Camera2D.position.y = 0 - $Camera2D/Cost.visible = false - $HireWorkerButton.visible = false - for x in hand.size(): - hand[x].in_hand = true - if hand_hidden == false: - hand_hiding = true - $TaskDrawDeck/Area2D/CollisionShape2D.disabled = false - task_drawn = false - money += payout - payout = 0 - if client_assignment != null and current_client != null: - active_clients[client_assignment] = current_client - if active_workers[client_assignment].increase_stress(current_client.initial_stress): - worker_exceeded_capacity(client_assignment) - client_assignment = -1 - current_client = null - elif client_assignment == -1 and current_client != null: - poor_discard.append(current_client) - current_client = null - $Camera2D/Payout.text = "" - $Camera2D/Money.text = "$" + str(money) - $Camera2D/EndTurn.visible = false - $PoorDiscardPile/Area2D/CollisionShape2D.disabled = true - #Pretty sure these are done in the right order even though it looks the wrong way around - for x in active_workers.size(): - if active_workers[x] != null and active_clients[x] == null: - active_workers[x].decrease_stress(1) - if active_workers[x] != null and active_clients[x] != null: - if active_workers[x].increase_stress(1): - worker_exceeded_capacity(x) - active_clients[x].turns_left -= 1 - active_clients[x].update_counter() - if active_clients[x].turns_left == 0: - evaluate_task_success(x) - var tasks_done = true - for client in active_clients: - if client != null: - tasks_done = false - if shift_deck.size() == 0: - if tasks_done: - round_completed = true - #enter_management_overview_state() - else: - $Camera2D/EndTurn.visible = true - $TaskDrawDeck/Area2D/CollisionShape2D.disabled = true - - -func enter_holding_task_state(): - last_fsm_state = current_fsm_state - current_fsm_state = FSMState.H_CLIENT - current_client = shift_deck.pop_back() - current_client.position = Vector2(494, -414) - current_client.visible = true - current_client.z_index = 1 - current_client.slide_to_position($PreviewTask.position.x, $PreviewTask.position.y, 0.0, 0.3) - task_drawn = true - $TaskDrawDeck/Area2D/CollisionShape2D.disabled = true - $PoorDiscardPile/Area2D/CollisionShape2D.disabled = false - $TaskDrawDeck/Count.text = str(shift_deck.size()) - diff --git a/Scripts/slot_button.gd b/Scripts/slot_button.gd deleted file mode 100644 index 9b407d4..0000000 --- a/Scripts/slot_button.gd +++ /dev/null @@ -1,7 +0,0 @@ -extends Node2D - -signal button_pushed(button) - -func _on_area_2d_input_event(_viewport, event, _shape_idx): - if event is InputEventMouseButton and event.pressed: - emit_signal("button_pushed", self) diff --git a/Scripts/worker_slot.gd b/Scripts/worker_slot.gd new file mode 100644 index 0000000..c80d183 --- /dev/null +++ b/Scripts/worker_slot.gd @@ -0,0 +1,22 @@ +extends Node2D + +var worker: Worker +var client: Client + +@onready var _w_pos = $Worker.global_position +@onready var _c_pos = $Client.global_position + +func add_worker(card: Worker) -> bool: + if worker != null: + return false + worker = card + worker.slide_to_position(_w_pos.x, _w_pos.y, 0, 0.2) + return true + + +func add_client(card: Client) -> bool: + if client != null: + return false + client = card + client.slide_to_position(_c_pos.x, _c_pos.y, 0, 0.2) + return true diff --git a/UI_Theme.tres b/UI_Theme.tres new file mode 100644 index 0000000..0184072 --- /dev/null +++ b/UI_Theme.tres @@ -0,0 +1,3 @@ +[gd_resource type="Theme" format=3 uid="uid://d26ldkm1br1bo"] + +[resource] diff --git a/ideas.txt b/ideas.txt new file mode 100644 index 0000000..6fbf33c --- /dev/null +++ b/ideas.txt @@ -0,0 +1,10 @@ +#Ideas okay? +#Make the client cards have a little progress track thats like how much they like their service right, +#put the poor/good/great blocks along that track, and instead of the services having that each service +#contributes a different number of points along that other track, so the money you recieve for making +#the match can be the same across all clients, but it shows how some clients value one more over the other +#without actually requiring you to have any specific one as long as you have enough turns to get them along +#the track, so a short session with all the perks can be a great service but a less special or less +#stress inducing session needs to be longer so the same worker needs to remain occupied longer, and it gives +#you more to do on your turn because you get to decide what all your little workers do rather than them only +#being interacted with when you're placing down a client card diff --git a/project.godot b/project.godot index 2961619..98fed1b 100644 --- a/project.godot +++ b/project.godot @@ -23,9 +23,7 @@ Data="*res://Scripts/data.gd" [display] -window/size/viewport_width=1920 -window/size/viewport_height=1080 -window/stretch/mode="viewport" +window/stretch/mode="canvas_items" [editor] @@ -39,3 +37,7 @@ click={ "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"pressed":false,"double_click":false,"script":null) ] } + +[rendering] + +textures/canvas_textures/default_texture_filter=0 diff --git a/script_templates/.gdignore b/script_templates/.gdignore new file mode 100644 index 0000000..e69de29 diff --git a/script_templates/State/default.gd b/script_templates/State/default.gd new file mode 100644 index 0000000..fe4ff88 --- /dev/null +++ b/script_templates/State/default.gd @@ -0,0 +1,9 @@ +extends State + + +func enter(): + pass + + +func exit(): + pass