Broke everything but the multiplayer lobby
This commit is contained in:
2
Scripts/PlayerStateMachine/bot_controller.gd
Normal file
2
Scripts/PlayerStateMachine/bot_controller.gd
Normal file
@ -0,0 +1,2 @@
|
||||
class_name BotController
|
||||
extends PlayerController
|
48
Scripts/PlayerStateMachine/draft_state.gd
Normal file
48
Scripts/PlayerStateMachine/draft_state.gd
Normal file
@ -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
|
||||
|
49
Scripts/PlayerStateMachine/holding_client_state.gd
Normal file
49
Scripts/PlayerStateMachine/holding_client_state.gd
Normal file
@ -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
|
||||
|
14
Scripts/PlayerStateMachine/holding_worker_state.gd
Normal file
14
Scripts/PlayerStateMachine/holding_worker_state.gd
Normal file
@ -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
|
||||
|
3
Scripts/PlayerStateMachine/human_controller.gd
Normal file
3
Scripts/PlayerStateMachine/human_controller.gd
Normal file
@ -0,0 +1,3 @@
|
||||
class_name HumanController
|
||||
extends PlayerController
|
||||
|
38
Scripts/PlayerStateMachine/management_state.gd
Normal file
38
Scripts/PlayerStateMachine/management_state.gd
Normal file
@ -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
|
||||
|
2
Scripts/PlayerStateMachine/player_controller.gd
Normal file
2
Scripts/PlayerStateMachine/player_controller.gd
Normal file
@ -0,0 +1,2 @@
|
||||
class_name PlayerController
|
||||
extends Node
|
12
Scripts/PlayerStateMachine/setup_state.gd
Normal file
12
Scripts/PlayerStateMachine/setup_state.gd
Normal file
@ -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
|
56
Scripts/PlayerStateMachine/shift_state.gd
Normal file
56
Scripts/PlayerStateMachine/shift_state.gd
Normal file
@ -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
|
||||
|
17
Scripts/PlayerStateMachine/state.gd
Normal file
17
Scripts/PlayerStateMachine/state.gd
Normal file
@ -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
|
29
Scripts/PlayerStateMachine/state_machine.gd
Normal file
29
Scripts/PlayerStateMachine/state_machine.gd
Normal file
@ -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()
|
||||
|
||||
|
18
Scripts/PlayerStateMachine/worker_state.gd
Normal file
18
Scripts/PlayerStateMachine/worker_state.gd
Normal file
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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] = []
|
||||
|
5
Scripts/chat.gd
Normal file
5
Scripts/chat.gd
Normal file
@ -0,0 +1,5 @@
|
||||
extends RichTextLabel
|
||||
|
||||
@rpc("any_peer", "call_local")
|
||||
func add_line(username, message):
|
||||
text += "[" + username + "] " + message + "\n"
|
53
Scripts/deck.gd
Normal file
53
Scripts/deck.gd
Normal file
@ -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()
|
103
Scripts/game.gd
Normal file
103
Scripts/game.gd
Normal file
@ -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
|
||||
|
72
Scripts/network_lobby.gd
Normal file
72
Scripts/network_lobby.gd
Normal file
@ -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)
|
@ -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())
|
||||
|
||||
|
@ -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)
|
22
Scripts/worker_slot.gd
Normal file
22
Scripts/worker_slot.gd
Normal file
@ -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
|
Reference in New Issue
Block a user