186 lines
4.7 KiB
GDScript3
186 lines
4.7 KiB
GDScript3
|
extends Node2D
|
||
|
|
||
|
# Signals
|
||
|
signal game_energy_changed
|
||
|
signal game_deck_changed
|
||
|
signal game_discard_changed
|
||
|
signal game_hand_changed
|
||
|
signal game_state_changed
|
||
|
|
||
|
var DEBUG = true
|
||
|
# class member variables go here, for example:
|
||
|
# var a = 2
|
||
|
# var b = "textvar"
|
||
|
var energy = 100
|
||
|
const ENERGY_MAX = 100
|
||
|
const ENERGY_MIN = 0
|
||
|
const SHUFFLE_REPEATS = 3
|
||
|
const STARTING_DECK_SIZE = 10
|
||
|
|
||
|
# Card piles: hand, deck, discard
|
||
|
var max_hand_size = 5
|
||
|
var hand = []
|
||
|
# Index 0 = bottom for deck and discard
|
||
|
var deck = []
|
||
|
var discard = []
|
||
|
|
||
|
# Game state machine ish
|
||
|
var actions_per_round = 1
|
||
|
var actions_remaining = 1
|
||
|
var round_counter = 0
|
||
|
var game_state = -2
|
||
|
var game_win = false
|
||
|
var game_over_message = ''
|
||
|
var game_states = {
|
||
|
-2: "initializing",
|
||
|
-1: "round_start",
|
||
|
0: "waiting_player_action",
|
||
|
1: "playing_action",
|
||
|
2: "round_done",
|
||
|
3: "waiting", # Generic let something else finish
|
||
|
4: "event", # Some out of player control event
|
||
|
5: "over",
|
||
|
}
|
||
|
|
||
|
# Cards
|
||
|
var cards = {
|
||
|
"card_repair": preload("res://cards/card_repair.tscn"),
|
||
|
}
|
||
|
|
||
|
func _ready():
|
||
|
# Called every time the node is added to the scene.
|
||
|
# Initialization here
|
||
|
randomize()
|
||
|
var bar = get_node("ui/EnergyHolder/ProgressBar")
|
||
|
bar.set_min(ENERGY_MIN)
|
||
|
bar.set_max(ENERGY_MAX)
|
||
|
set_process(true)
|
||
|
if self.DEBUG:
|
||
|
get_node('ui/debug').show()
|
||
|
init_game()
|
||
|
|
||
|
func init_game():
|
||
|
# Popuplate deck
|
||
|
var card_keys = self.cards.keys()
|
||
|
while self.deck.size() < STARTING_DECK_SIZE:
|
||
|
var node = self.cards[card_keys[rand_range(0, card_keys.size() - 1)]].instance()
|
||
|
node.add_to_group('cards')
|
||
|
get_node('cards').add_child(node)
|
||
|
node.hide()
|
||
|
self.deck.append(node)
|
||
|
self.shuffle()
|
||
|
emit_signal('game_deck_changed', self.deck.size())
|
||
|
self.update_game_state(-1)
|
||
|
|
||
|
func update_game_state(new_state_idx):
|
||
|
if ! self.game_states.has(new_state_idx):
|
||
|
print("Error: trying to change game_state to unknown index: %d" % new_state_idx)
|
||
|
return
|
||
|
var old_state = self.game_state
|
||
|
self.game_state = new_state_idx
|
||
|
print("Changed game state from %d to %d" % [old_state, new_state_idx])
|
||
|
emit_signal('game_state_changed', old_state, new_state_idx)
|
||
|
|
||
|
func _process():
|
||
|
pass
|
||
|
|
||
|
func update_energy(diff = 0):
|
||
|
self.energy += diff
|
||
|
emit_signal("game_energy_changed", self.energy)
|
||
|
if self.energy <= 0:
|
||
|
self.game_win = false
|
||
|
self.game_over_message = 'Ran out of energy.... your ship is floating useless and dead in space'
|
||
|
self.update_game_state(5)
|
||
|
return true
|
||
|
return false
|
||
|
|
||
|
func draw_hand(cmax = null):
|
||
|
if not cmax:
|
||
|
cmax = self.max_hand_size
|
||
|
var success = false
|
||
|
while self.hand.size() < cmax:
|
||
|
success = self.draw_card()
|
||
|
if not success:
|
||
|
break
|
||
|
|
||
|
func draw_card():
|
||
|
"""
|
||
|
returns bool: true if a card was drawn
|
||
|
"""
|
||
|
if self.hand.size() >= self.max_hand_size:
|
||
|
return false # Can't exceed max hand size
|
||
|
print(self.deck.size())
|
||
|
if self.deck.size() == 0:
|
||
|
self.shuffle_in_discard()
|
||
|
if self.deck.empty():
|
||
|
return false # Deck + Discard is milled out
|
||
|
var c = self.deck[-1]
|
||
|
self.deck.pop_back()
|
||
|
self.hand.push_back(c)
|
||
|
emit_signal("game_deck_changed", self.deck.size())
|
||
|
emit_signal("game_hand_changed", self.hand.size())
|
||
|
return true
|
||
|
|
||
|
func shuffle_in_discard():
|
||
|
while not self.discard.empty():
|
||
|
self.deck.push_back(self.discard[-1])
|
||
|
self.discard.pop_back()
|
||
|
emit_signal("game_discard_changed", self.discard.size())
|
||
|
self.shuffle()
|
||
|
|
||
|
func shuffle():
|
||
|
if self.DEBUG:
|
||
|
print("--- start shuffle ---")
|
||
|
print(self.deck)
|
||
|
for i in range(1, SHUFFLE_REPEATS):
|
||
|
var new_deck = []
|
||
|
var x
|
||
|
while not self.deck.empty():
|
||
|
x = rand_range(0, self.deck.size()-1)
|
||
|
new_deck.append(self.deck[x])
|
||
|
self.deck.remove(x)
|
||
|
self.deck = new_deck
|
||
|
if self.DEBUG:
|
||
|
print(self.deck)
|
||
|
print("--- end shuffle ---")
|
||
|
|
||
|
func _on_game_game_state_changed(old_state, new_state):
|
||
|
if new_state == -1:
|
||
|
# New Round
|
||
|
self.round_counter += 1
|
||
|
self.actions_remaining = self.actions_per_round
|
||
|
self.draw_hand()
|
||
|
emit_signal("game_round_start", self.round_counter)
|
||
|
self.update_game_state(0) # Waiting for player action
|
||
|
if new_state == 3: # Round done
|
||
|
var state_changed = self.update_energy(-get_round_energy_cost())
|
||
|
if not state_changed:
|
||
|
self.update_game_state(-1)
|
||
|
if new_state == 5: # Game finish
|
||
|
get_node('ui/help').set_text(self.game_over_message)
|
||
|
|
||
|
func play_card(card):
|
||
|
if self.game_state != 0:
|
||
|
return
|
||
|
card.hide()
|
||
|
card.set_global_pos(Vector2(-200,-200))
|
||
|
var p = self.hand.find(card)
|
||
|
print(p)
|
||
|
if p != -1:
|
||
|
self.hand.remove(p)
|
||
|
self.discard.append(card)
|
||
|
print(self.hand)
|
||
|
print(self.discard)
|
||
|
emit_signal('game_hand_changed', self.hand.size())
|
||
|
emit_signal('game_discard_changed', self.discard.size())
|
||
|
card.proc_effects(self, 'on_card_play_done')
|
||
|
self.update_game_state(1) # playing action
|
||
|
|
||
|
func on_card_play_done(card):
|
||
|
self.actions_remaining -= 1
|
||
|
if self.actions_remaining <= 0:
|
||
|
self.update_game_state(3)
|
||
|
|
||
|
func get_round_energy_cost():
|
||
|
# @TODO base on enabled areas
|
||
|
return 10
|