fixed double drawing on round 2

This commit is contained in:
Lexi Quinn 2023-07-07 17:46:11 +10:00
parent 613c89bea6
commit 01eb4e494f
21 changed files with 87 additions and 710 deletions

View File

@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://gxofrq3ug6qe"] [gd_scene load_steps=2 format=3 uid="uid://gxofrq3ug6qe"]
[ext_resource type="Script" path="res://Scripts/PlayerStateMachine/bot_controller.gd" id="1_rr26g"] [ext_resource type="Script" path="res://Scripts/bot_controller.gd" id="1_rr26g"]
[node name="BotPlayer" type="Node2D"] [node name="BotPlayer" type="Node2D"]
script = ExtResource("1_rr26g") script = ExtResource("1_rr26g")

View File

@ -37,6 +37,15 @@ position = Vector2(-125, -175)
[node name="Client" type="Node2D" parent="."] [node name="Client" type="Node2D" parent="."]
position = Vector2(-175, -125) position = Vector2(-175, -125)
[node name="Label" type="Label" parent="."]
offset_left = 145.0
offset_top = 145.0
offset_right = 185.0
offset_bottom = 171.0
text = "0"
horizontal_alignment = 1
vertical_alignment = 1
[connection signal="input_event" from="Area2D" to="." method="_on_area_2d_input_event"] [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_entered" from="Area2D" to="." method="_on_area_2d_mouse_entered"]
[connection signal="mouse_exited" from="Area2D" to="." method="_on_area_2d_mouse_exited"] [connection signal="mouse_exited" from="Area2D" to="." method="_on_area_2d_mouse_exited"]

View File

@ -1,10 +1,10 @@
[gd_scene load_steps=3 format=3 uid="uid://cpl32lvhwd5da"] [gd_scene load_steps=3 format=3 uid="uid://cpl32lvhwd5da"]
[ext_resource type="Script" path="res://Scripts/PlayerStateMachine/human_controller.gd" id="1_4thxs"] [ext_resource type="Script" path="res://Scripts/human_controller.gd" id="1_qtukm"]
[ext_resource type="Theme" uid="uid://d26ldkm1br1bo" path="res://UI_Theme.tres" id="2_ja0q8"] [ext_resource type="Theme" uid="uid://d26ldkm1br1bo" path="res://UI_Theme.tres" id="2_ja0q8"]
[node name="HumanPlayer" type="Node2D" node_paths=PackedStringArray("hand_position", "player_cam")] [node name="HumanPlayer" type="Node2D" node_paths=PackedStringArray("hand_position", "player_cam")]
script = ExtResource("1_4thxs") script = ExtResource("1_qtukm")
hand_position = NodePath("Node2D") hand_position = NodePath("Node2D")
player_cam = NodePath("Camera2D") player_cam = NodePath("Camera2D")

View File

@ -1,48 +0,0 @@
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

View File

@ -1,49 +0,0 @@
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

View File

@ -1,14 +0,0 @@
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

View File

@ -1,38 +0,0 @@
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

View File

@ -1,12 +0,0 @@
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

View File

@ -1,56 +0,0 @@
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

View File

@ -1,17 +0,0 @@
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

View File

@ -1,29 +0,0 @@
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()

View File

@ -1,18 +0,0 @@
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

View File

@ -1,81 +0,0 @@
class_name Board
extends Node2D
var round_num : int = 0
var turn_num : int = 0
var _players : Array[Player] = []
var _readied_players
func add_player(player : Player) -> void:
if not _players.has(player):
_players.append(player)
turn_started.connect(player.start_turn)
round_started.connect(player.start_round)
func end_turn():
var ready = true
for x in _players:
if x.turn_completed == false:
ready = false
if ready:
turn_num += 1
turn_started.emit()
#========== TODO ==============
#All this shit should be refactored into awaits and signals so each player goes one at a time
#The players camera should be set to the currently acting player when its not their own turn
func end_round():
turn_num = 0
pass
func _ready() -> void:
_load_workers()
_load_clients()
func draw_worker(amount : int):
return _draw_card(amount, _worker_deck, _worker_discard_deck)
func search_and_draw_worker(card : Worker) -> Worker:
var worker = _worker_deck[_worker_deck.find(card)]
_worker_deck.remove_at(_worker_deck.find(card))
return worker
func draw_client(amount):
return _draw_card(amount, _client_deck, _client_discard_deck)
func search_and_draw_client(card : Client) -> Client:
var client = _client_deck[_client_deck.find(card)]
_client_deck.remove_at(_client_deck.find(card))
return client
func discard_worker(card : Worker) -> void:
_worker_discard_deck.append(card)
func discard_client(card : Client) -> void:
_client_discard_deck.append(card)
func _draw_card(amount : int, deck, discard):
var array = []
for x in amount:
if deck.size() == 0:
if discard.size() > 0:
deck.append_array(discard)
discard = []
deck.shuffle()
else:
break
array.append(deck.pop_back())
return array

View File

@ -36,10 +36,16 @@ func _on_area_2d_mouse_exited() -> void:
mouse_exited.emit() mouse_exited.emit()
func update_label() -> void:
$Label.text = str(cards.size())
func draw_card() -> Card: func draw_card() -> Card:
if cards.size() == 0: if cards.size() == 0:
return null return null
return cards.pop_back() var card = cards.pop_back()
update_label()
return card
func draw_cards(num) -> Array[Card]: func draw_cards(num) -> Array[Card]:
@ -51,6 +57,7 @@ func draw_cards(num) -> Array[Card]:
array.append(cards[i]) array.append(cards[i])
cards.remove_at(i) cards.remove_at(i)
x += 1 x += 1
update_label()
return array return array
@ -61,6 +68,7 @@ func place(card: Card) -> void:
card.slide_to_position(_w_pos.x, _w_pos.y, 0.0, 0.2) card.slide_to_position(_w_pos.x, _w_pos.y, 0.0, 0.2)
Type.CLIENT: Type.CLIENT:
card.slide_to_position(_c_pos.x, _c_pos.y, 0.0, 0.2) card.slide_to_position(_c_pos.x, _c_pos.y, 0.0, 0.2)
update_label()
func shuffle() -> void: func shuffle() -> void:
@ -71,3 +79,4 @@ func order(node_paths) -> void:
cards = [] cards = []
for path in node_paths: for path in node_paths:
cards.append(get_node(path)) cards.append(get_node(path))
update_label()

View File

@ -5,6 +5,7 @@ signal game_paused
signal game_resumed signal game_resumed
signal turn_started signal turn_started
signal round_started signal round_started
signal shuffle_sync_recieved
enum PlayerType {HUMAN, BOT} enum PlayerType {HUMAN, BOT}
@ -25,7 +26,8 @@ var current_player := 0
var players: Array[PlayerController] = [] var players: Array[PlayerController] = []
var player_boards: Array[PlayerBoard] = [] var player_boards: Array[PlayerBoard] = []
var readied_players: Array[int] = [] var readied_players: Array[int] = []
var round_number := 0 var finished_players: Array[int] = []
var round_number := -1
var turn_number := 0 var turn_number := 0
var _worker_scene = preload("res://Scenes/worker_card.tscn") var _worker_scene = preload("res://Scenes/worker_card.tscn")
@ -101,6 +103,7 @@ func add_player(id: int, username: String, type: PlayerType) -> void:
controller = _human_scene.instantiate() controller = _human_scene.instantiate()
networked_controllers.append(controller) networked_controllers.append(controller)
controller.ready_button_pressed.connect(ready_player) controller.ready_button_pressed.connect(ready_player)
controller.round_finished.connect(finish_player)
controller.chat_message_submitted.connect(message) controller.chat_message_submitted.connect(message)
controller.workers_discarded.connect(discard_workers) controller.workers_discarded.connect(discard_workers)
controller.workers_kept.connect(board.add_to_roster) controller.workers_kept.connect(board.add_to_roster)
@ -139,17 +142,24 @@ func message(msg):
rpc("relay_chat_message", msg) rpc("relay_chat_message", msg)
func finish_player(id):
if not finished_players.has(id):
finished_players.append(id)
func are_all_finished() -> bool:
return finished_players.size() == players.size()
func ready_player(id): func ready_player(id):
if not readied_players.has(id): if not readied_players.has(id):
readied_players.append(id) readied_players.append(id)
for player in networked_controllers: for player in networked_controllers:
player.rpc("update_ready_label", readied_players.size(), players.size()) player.rpc("update_ready_label", readied_players.size(), players.size())
if readied_players.size() == players.size() and is_multiplayer_authority(): if readied_players.size() == players.size() and is_multiplayer_authority():
if round_number == 0: if round_number < 0:
rpc("start_game") rpc("start_game")
else: else:
for player in players:
player.ready_button_pressed.disconnect(ready_player)
rpc("start_round") rpc("start_round")
@ -157,28 +167,54 @@ func ready_player(id):
func start_game(): func start_game():
#Only the host should shuffle the decks #Only the host should shuffle the decks
readied_players = [] readied_players = []
finished_players = []
round_number += 1 round_number += 1
if is_multiplayer_authority(): if is_multiplayer_authority():
randomize() randomize()
var deck_order = [] shuffle_and_sync_workers()
for card in worker_deck.cards: shuffle_and_sync_clients()
deck_order.append(card.get_path())
rpc("send_worker_order", deck_order)
deck_order = []
for card in client_deck.cards:
deck_order.append(card.get_path())
rpc("send_client_order", deck_order)
for player in players: for player in players:
rpc("draft_workers", player.player_info["username"], 4, 2) rpc("draft_workers", player.player_info["username"], 4, 2)
rpc("draft_clients", player.player_info["username"])
func shuffle_and_sync_workers():
if not is_multiplayer_authority():
await shuffle_sync_recieved
return
for x in worker_discard.cards.size():
worker_deck.append(worker_discard.draw_card())
worker_deck.shuffle()
var deck_order = []
for card in worker_deck.cards:
deck_order.append(card.get_path())
rpc("send_worker_order", deck_order)
func shuffle_and_sync_clients():
if not is_multiplayer_authority():
await shuffle_sync_recieved
return
for x in client_discard.cards.size():
client_deck.append(client_discard.draw_card())
client_deck.shuffle()
var deck_order = []
for card in client_deck.cards:
deck_order.append(card.get_path())
rpc("send_client_order", deck_order)
@rpc("call_local", "reliable") @rpc("call_local", "reliable")
func start_round(): func start_round():
readied_players = [] readied_players = []
finished_players = []
round_number += 1 round_number += 1
turn_number = 0 turn_number = 0
if is_multiplayer_authority(): if is_multiplayer_authority():
for player in networked_controllers:
player.rpc("update_ready_label", readied_players.size(), players.size())
for player in players:
rpc("draft_clients", player.player_info["username"])
#await clients_drafted
rpc("start_turn") rpc("start_turn")
@ -186,23 +222,24 @@ func start_round():
func start_turn(): func start_turn():
turn_number += 1 turn_number += 1
for x in players.size(): for x in players.size():
#players[x].rpc("start_turn")
for other_player in players: for other_player in players:
other_player.spectate_player(players[x].get_path()) other_player.spectate_player(players[x].get_path())
players[x].start_turn() players[x].start_turn()
await players[x].turn_finished await players[x].turn_finished
if is_multiplayer_authority(): if is_multiplayer_authority() and not are_all_finished():
rpc("start_turn") rpc("start_turn")
@rpc("reliable") @rpc("reliable")
func send_worker_order(node_paths): func send_worker_order(node_paths):
worker_deck.order(node_paths) worker_deck.order(node_paths)
shuffle_sync_recieved.emit()
@rpc("reliable") @rpc("reliable")
func send_client_order(node_paths): func send_client_order(node_paths):
client_deck.order(node_paths) client_deck.order(node_paths)
shuffle_sync_recieved.emit()
@rpc("call_local", "reliable") @rpc("call_local", "reliable")
@ -234,6 +271,8 @@ func draft_clients(player):
if controller.reputation_points >= 60: if controller.reputation_points >= 60:
cards_to_draw += 4 cards_to_draw += 4
for x in cards_to_draw - controller.board.shift_deck.cards.size(): for x in cards_to_draw - controller.board.shift_deck.cards.size():
if client_deck.cards.size() == 0:
shuffle_and_sync_clients()
controller.board.shift_deck.place(client_deck.draw_card()) controller.board.shift_deck.place(client_deck.draw_card())

View File

@ -110,6 +110,9 @@ func end_turn():
func end_of_round(): func end_of_round():
super() super()
$CanvasLayer/UI/Reputation.text = str(reputation_points) + " / 100 Reputation" $CanvasLayer/UI/Reputation.text = str(reputation_points) + " / 100 Reputation"
game_started = 1
ready_button.visible = true
ready_label.visible = true
func update_money(): func update_money():

View File

@ -1,288 +0,0 @@
class_name Player
extends Node2D
signal draft_completed
signal board_attached
enum DraftType {STARTING_HAND, HIRE_WORKER}
@export var fsm : StateMachine
@export var roster_positions : Array[Node2D] = []
@export var slot_buttons : Array[Node2D] = []
@export var hand_slide_anim_time := 0.3
var money := 0
var payout := 0
var cost := 0
var hire_costs := [40, 50, 60, 70, 80]
var shift_deck : Array[Client] = []
var workers : Array[Worker] = []
var hand : Array[Worker] = []
var active_workers : Array[Worker] = [null, null, null, null, null]
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 draft := DraftType.HIRE_WORKER
var hand_hiding := false
var hand_hidden := false
var hand_hiding_progress := 0.0
var hand_showing := false
var hand_showing_progress := 0.0
var shown_for_draft : Array[Worker] = []
var selected_for_draft : Array[Worker] = []
var draft_limit := 0
var current_client : Client
var selected_worker : Worker
var task_drawn := false
var client_assignment : int = -1
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
roster_positions.append($RosterSection/Position1)
roster_positions.append($RosterSection/Position2)
roster_positions.append($RosterSection/Position3)
roster_positions.append($RosterSection/Position4)
roster_positions.append($RosterSection/Position5)
roster_positions.append($RosterSection/Position6)
roster_positions.append($RosterSection/Position7)
roster_positions.append($RosterSection/Position8)
roster_positions.append($RosterSection/Position9)
roster_positions.append($RosterSection/Position10)
roster_positions.append($RosterSection/Position11)
roster_positions.append($RosterSection/Position12)
roster_positions.append($RosterSection/Position13)
roster_positions.append($RosterSection/Position14)
roster_positions.append($RosterSection/Position15)
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"
$GoodDiscardPile/Label.text = "Good service"
$GreatDiscardPile/Label.text = "Great service"
$TaskDrawDeck/Label.text = "Click to draw task card"
$Camera2D.make_current()
await board_attached
fsm.change_state(fsm.FSMState.SETUP)
func _process(delta) -> void:
if (hand_hiding):
if hand_hiding_progress < hand_slide_anim_time:
hand_hiding_progress += delta
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:
hand_hiding = false
hand_hidden = true
hand_hiding_progress = 0.0
if (hand_showing):
if hand_showing_progress < hand_slide_anim_time:
hand_showing_progress += delta
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:
hand_showing = false
hand_showing_progress = 0.0
func start_turn():
pass
func start_round():
pass
@rpc("call_local")
func attach_board(board_path : NodePath):
board = get_node(board_path) as Board
board_attached.emit()
func add_to_hand(card):
hand.append(card)
for x in hand.size():
var hand_ratio = 0.5
if hand.size() > 1:
hand_ratio = float(x) / float(hand.size() - 1)
hand[x].position = $Hand.position
hand[x].hand_ratio = hand_ratio
hand[x].in_hand = true
hand[x].hand_position = $Hand.position
hand[x].visible = true
hand[x].set_process(true)
func lift_hand():
for card in hand:
card.hovered = true
func drop_hand():
for card in hand:
card.hovered = false
func select_card(card):
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))
card.slide_to_position(card.position.x, card.position.y + 40, 0.0, 0.1)
else:
if selected_for_draft.size() < draft_limit:
selected_for_draft.append(card)
card.slide_to_position(card.position.x, card.position.y - 40, 0.0, 0.1)
return
selected_worker = card
if fsm.state == fsm.FSMState.H_CLIENT:
fsm.state_nodes[fsm.FSMState.H_CLIENT].assign_task_to_worker()
func select_slot(slot):
if selected_worker == null:
return
if active_workers.has(selected_worker):
active_workers[active_workers.find(selected_worker)] = null
if hand.has(selected_worker):
hand.remove_at(hand.find(selected_worker))
active_workers[slot_buttons.find(slot)] = selected_worker
selected_worker.slide_to_position(slot.position.x, slot.position.y, 0.0, 0.3)
selected_worker = null
func _on_area_2d_input_event(_viewport, event, _shape_idx):
if event is InputEventMouseButton and event.pressed:
fsm.change_state(fsm.FSMState.WORKER)
func _on_area_2d_2_input_event(_viewport, event, _shape_idx):
if event is InputEventMouseButton and event.pressed:
fsm.change_state(fsm.FSMState.MANAGEMENT)
func _on_task_draw_deck_button_pushed(_button):
fsm.change_state(fsm.FSMState.H_CLIENT)
func evaluate_task_success(num):
var successfulness = 0
var worker = active_workers[num]
var client = active_clients[num]
match client.services.size():
2, 3:
successfulness = 2
4:
successfulness = 1
if worker.services.has(client.services[3]):
successfulness = 2
5:
successfulness = 1
if worker.services.has(client.services[4]):
successfulness = 2
6:
successfulness = 0
if worker.services.has(client.services[3]) or worker.services.has(client.services[4]):
successfulness = 1
if worker.services.has(client.services[5]):
successfulness = 2
7:
successfulness = 0
if worker.services.has(client.services[3]) or worker.services.has(client.services[4]):
successfulness = 1
if worker.services.has(client.services[5]) or worker.services.has(client.services[6]):
successfulness = 2
var slide_destination : Vector2
match successfulness:
0:
poor_discard.append(client)
slide_destination = $PoorDiscardPile.position
1:
good_discard.append(client)
slide_destination = $GoodDiscardPile.position
2:
great_discard.append(client)
slide_destination = $GreatDiscardPile.position
client.slide_to_position(slide_destination.x, slide_destination.y, 0.0, 0.2)
client.z_index = 0
active_clients[num] = null
func worker_exceeded_capacity(num):
active_workers[num].stress = 0
active_workers[num].set_process(false)
active_workers[num].visible = false
workers.remove_at(workers.find(active_workers[num]))
active_workers[num] = null
func draft_workers(_draw, pick):
draft_limit = pick
shown_for_draft = []
selected_for_draft = []
var y = 0
var x = (250.0 * _draw) / 2.0
shown_for_draft.append_array(board.draw_worker(_draw))
for i in shown_for_draft.size():
var card = shown_for_draft[i]
card.visible = true
card.set_process(true)
card.card_clicked.connect(select_card)
var ratio = float(i) / float(_draw - 1)
var xx = lerpf(-1 * x, x, ratio)
card.slide_to_position(xx, y, 0.0, 0.3)
fsm.change_state(fsm.FSMState.DRAFT)
func pad_shift_deck():
var padding = (2 + (2 * board.round_num)) - shift_deck.size()
shift_deck.append_array(board.draw_client(padding))
func process_discard_decks():
poor_discard.shuffle()
good_discard.shuffle()
great_discard.shuffle()
for x in range(poor_discard.size() - 1, -1, -1):
if x == 0:
shift_deck.append(poor_discard[x])
else:
board.discard_client(poor_discard[x])
poor_discard[x].position = Vector2(9999, 9999)
poor_discard[x].visible = false
poor_discard.remove_at(x)
for x in range(good_discard.size() - 1, -1, -1):
if x <= int(good_discard.size() / 2.0):
shift_deck.append(good_discard[x])
else:
board.discard_client(good_discard[x])
good_discard[x].position = Vector2(9999, 9999)
good_discard[x].visible = false
good_discard.remove_at(x)
for x in range(great_discard.size() - 1, -1, -1):
if x < great_discard.size() - 1:
shift_deck.append(great_discard[x])
else:
board.discard_client(great_discard[x])
great_discard[x].position = Vector2(9999, 9999)
great_discard[x].visible = false
great_discard.remove_at(x)

View File

@ -4,7 +4,7 @@ extends Node
signal workers_discarded signal workers_discarded
signal workers_kept signal workers_kept
signal turn_finished signal turn_finished
signal round_finished signal round_finished(int)
var player_info var player_info
@export var hand_position: Node2D @export var hand_position: Node2D
@ -113,11 +113,8 @@ func confirm_draft():
func start_turn(): func start_turn():
current_client = board.shift_deck.draw_card() current_client = board.shift_deck.draw_card()
if current_client == null: current_client.slide_to_position(board.global_position.x, board.global_position.y, 0.0, 0.3)
end_of_round() current_client.turn_front()
else:
current_client.slide_to_position(board.global_position.x, board.global_position.y, 0.0, 0.3)
current_client.turn_front()
func end_of_round(): func end_of_round():
@ -125,7 +122,7 @@ func end_of_round():
reputation_points += board.process_decks() reputation_points += board.process_decks()
if reputation_points < 0: if reputation_points < 0:
reputation_points = 0 reputation_points = 0
round_finished.emit() round_finished.emit(player_info["id"])
@rpc("call_local", "reliable") @rpc("call_local", "reliable")
@ -137,4 +134,6 @@ func end_turn():
current_workspace = null current_workspace = null
money += money_delta money += money_delta
money_delta = 0 money_delta = 0
if board.shift_deck.cards.size() == 0:
end_of_round()
turn_finished.emit() turn_finished.emit()

View File

@ -1,32 +0,0 @@
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
yeah there should be a system for doing something with ur workers each turn, like u do a service and it gives
u some client happiness with determines which deck they discard to, and gives u overall reputation points
the roster system is kind of fucked if you start with 2/4 cards and dont get new ones often
like, you would never have any in reserve, but do u need any? idk figure it out
Shift Phase
1. Swap 1 time token on each worker over to the stress side
2. Pick up the next client card in the deck, and either assign it to
a worker or place it in the no service pile
3. If a worker both has no client, and at least one stress token, remove
a stress token
Management Phase
Market Research
Look at the 10 clients, and place them back in the same order
Targeted Advertising
Search through the client discard deck, and add all clients
with one extra type to your shift deck
Roster Worker
Add 1 worker from your hand into the next open slot on your board

View File

@ -12,7 +12,7 @@ config_version=5
config/name="card test" config/name="card test"
run/main_scene="res://Scenes/main_menu.tscn" run/main_scene="res://Scenes/main_menu.tscn"
config/features=PackedStringArray("4.0", "Forward Plus") config/features=PackedStringArray("4.1", "Forward Plus")
boot_splash/bg_color=Color(0, 0, 0, 1) boot_splash/bg_color=Color(0, 0, 0, 1)
boot_splash/show_image=false boot_splash/show_image=false
config/icon="res://icon.svg" config/icon="res://icon.svg"
@ -34,7 +34,7 @@ version_control/autoload_on_startup=true
click={ click={
"deadzone": 0.5, "deadzone": 0.5,
"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) "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,"canceled":false,"pressed":false,"double_click":false,"script":null)
] ]
} }