202 lines
6.4 KiB
GDScript
202 lines
6.4 KiB
GDScript
class_name GameManager extends Node2D
|
|
|
|
@export var audience_manager: AudienceManager
|
|
@export var desk: Desk
|
|
@export var turn_manager: TurnManager
|
|
|
|
enum bidding_state {CLOSED, READY, ASKING, BID}
|
|
|
|
signal lost
|
|
signal won
|
|
|
|
var paintings_sold := 0
|
|
const PAINTINGS_TOTAL := 7
|
|
|
|
var paintings: Array[PaintingInfo] = []
|
|
var current_painting_idx := 0
|
|
|
|
# tracker variables for bid markers, proposing bids happens between numpad and audience
|
|
var current_bid := 0:
|
|
set(value):
|
|
if is_instance_valid(going_price_label):
|
|
going_price_label.display_caption("Bid: $%sk" % [floor(value / 1000.0)])
|
|
var starting_price := 0:
|
|
set(value):
|
|
if is_instance_valid(starting_price_label):
|
|
if value == 0:
|
|
starting_price_label.display_caption("Starting Price: ")
|
|
else:
|
|
starting_price_label.display_caption("Starting Price: $%sk" % [floor(value / 1000.0)])
|
|
var final_bid := 0:
|
|
set(value):
|
|
if is_instance_valid(going_price_label):
|
|
going_price_label.display_caption("Sold for $%sk!" % [floor(value / 1000.0)])
|
|
@export var current_bid_display: RichTextLabel
|
|
|
|
var target_sales := 0:
|
|
set(value):
|
|
if is_instance_valid(quota_label):
|
|
quota_label.display_caption("Quota: $%sk Progress: 0%%" % [floor(value / 1000.0)])
|
|
#var total_sales: int = 0
|
|
@export var sales_magnitude := 100000
|
|
@export var single_painting_magnitude := 1000
|
|
@export var initial_value_reduction := 0.6
|
|
|
|
# state tracker for a given painting's auction
|
|
var bidding_open := false
|
|
var state := bidding_state.CLOSED
|
|
|
|
@export var quota_label: CaptionLabel
|
|
@export var starting_price_label: CaptionLabel
|
|
@export var going_price_label: CaptionLabel
|
|
|
|
func _ready() -> void:
|
|
audience_manager.ask_accepted.connect(_handle_ask_accepted)
|
|
desk.gavel.gavel_hit.connect(_handle_gavel_hit)
|
|
|
|
# Associate collectors with their collections
|
|
var collectors: Array[Node] = get_tree().get_nodes_in_group("ArtCollectors")
|
|
assert(%PaintingPiles.get_child_count() == collectors.size())
|
|
for idx in collectors.size(): collectors[idx].painting_pile = %PaintingPiles.get_child(idx)
|
|
|
|
|
|
randomize_auction()
|
|
for idx in PAINTINGS_TOTAL:
|
|
var pd: PaintingDisplay = %Paintings.get_child(idx)
|
|
pd.configure_painting(paintings[idx].id)
|
|
|
|
|
|
next_painting()
|
|
|
|
var intro_msg := "You have %s paintings. Sell them fast for at least $%s or face the consequences!" % [PAINTINGS_TOTAL, target_sales]
|
|
intro_msg += "\nHit the gavel and input the starting price to begin!"
|
|
turn_manager.speak_sentence(intro_msg)
|
|
|
|
#build out the initialization process, which should:
|
|
# -- generate paintings and assign values
|
|
# -- start the turn timer/auction timer
|
|
# ---- also add an auction timer
|
|
# -- have tts announcement of starting bid and start of auction
|
|
|
|
|
|
func _handle_gavel_hit():
|
|
match state:
|
|
bidding_state.CLOSED:
|
|
state = bidding_state.READY
|
|
#starting_price_label.display_caption("Starting price: $%s" % [starting_price])
|
|
#current_bid_display.set_text("Starting price: $%s" % [starting_price])
|
|
bidding_state.ASKING:
|
|
if current_bid != 0:
|
|
sell_painting()
|
|
if next_painting():
|
|
print("The next painting is valued at $%s (should be $%s)" % [starting_price, paintings[current_painting_idx].value])
|
|
else:
|
|
end_auction()
|
|
|
|
|
|
func destroy_painting():
|
|
$FailedPainting.play()
|
|
if get_painting_display().damage_deal():
|
|
cancel_bidding()
|
|
get_painting_display().move_painting_to_pile(%PaintingPileDiscard)
|
|
next_painting()
|
|
turn_manager.speak_sentence("Oh nooooooo! Took too long!\nTry to make it up on the next painting!")
|
|
else:
|
|
turn_manager.restart_turn()
|
|
turn_manager.speak_sentence("Oops! Took too long! Quickly, try again!")
|
|
|
|
|
|
func sell_painting():
|
|
cancel_bidding()
|
|
move_painting_to_bidders_pile()
|
|
paintings[current_painting_idx].sold_for = current_bid
|
|
#current_bid_display.set_text("Sold for $%s!" % [current_bid])
|
|
var total_sold = 0
|
|
for painting in paintings:
|
|
total_sold += painting.sold_for
|
|
turn_manager.speak_sentence("Sold for $%s!" % [current_bid])
|
|
@warning_ignore("integer_division")
|
|
quota_label.display_caption("Quota: $%sk Progress: %s%%" % [floor(target_sales / 1000.0), floor((total_sold / target_sales) * 100.0)])
|
|
print("Congrats on selling your painting for $%s! You have made $%s so far." % [current_bid, get_total_sales()])
|
|
|
|
|
|
func move_painting_to_bidders_pile() -> void:
|
|
get_painting_display().move_painting_to_pile(audience_manager.latest_bidder.painting_pile)
|
|
|
|
|
|
func get_painting_display() -> PaintingDisplay:
|
|
return %Paintings.get_child(current_painting_idx)
|
|
|
|
|
|
func next_painting() -> bool:
|
|
current_painting_idx += 1
|
|
if current_painting_idx >= PAINTINGS_TOTAL: return false
|
|
var info := paintings[current_painting_idx]
|
|
starting_price = info.value
|
|
current_bid = 0
|
|
#going_price_label.display_caption("Current bid: $%s" % [current_bid])
|
|
$NextPainting.play()
|
|
get_painting_display().animate_show_painting()
|
|
return true
|
|
|
|
|
|
func _handle_ask_accepted():
|
|
pass
|
|
#current_bid_display.set_text("Current bid: $" + str(current_bid))
|
|
|
|
|
|
func end_auction():
|
|
#add in logic for displaying/transitioning to score screen
|
|
if get_total_sales() >= target_sales:
|
|
#add context specific score text?
|
|
turn_manager.speak_sentence("Congratulations! The auction house will run another day.")
|
|
emit_signal("won")
|
|
else:
|
|
#add context specific score text?
|
|
turn_manager.speak_sentence("You have failed. We must find a new auctioneer.")
|
|
emit_signal("lost")
|
|
|
|
|
|
func sum_total_sales(acculator: int, info: PaintingInfo) -> int:
|
|
return acculator + info.sold_for
|
|
|
|
|
|
func get_total_sales() -> int:
|
|
return paintings.reduce(sum_total_sales, 0)
|
|
|
|
|
|
func randomize_auction() -> void:
|
|
#paintings_total = randi_range(7,10)
|
|
target_sales = randi_range(2, 5) * sales_magnitude
|
|
var custom_ids: Array[int] = %PaintingDisplay1.get_n_unique_custom_paintings(3)
|
|
for idx in PAINTINGS_TOTAL:
|
|
var info := PaintingInfo.new()
|
|
info.id = custom_ids.pop_back() if not custom_ids.is_empty() else -absi(randi())
|
|
@warning_ignore('integer_division')
|
|
info.value = target_sales / randi_range(PAINTINGS_TOTAL - 2, PAINTINGS_TOTAL + 2)
|
|
info.value = snappedi(info.value, single_painting_magnitude)
|
|
paintings.append(info)
|
|
paintings.shuffle()
|
|
|
|
|
|
class PaintingInfo:
|
|
var id := 0
|
|
var value := 0
|
|
var sold_for := 0
|
|
var is_sold: bool:
|
|
get(): return sold_for > 0
|
|
|
|
# OTHER THINGS TO ADD:
|
|
# UI elements for score
|
|
# Bark manager
|
|
|
|
|
|
func _on_turn_manager_timer_timeout() -> void:
|
|
destroy_painting()
|
|
|
|
|
|
func cancel_bidding() -> void:
|
|
if not (state == bidding_state.ASKING or state == bidding_state.BID):
|
|
push_error('bidding state should not be ', state)
|
|
state = bidding_state.CLOSED
|
|
desk.numpad.reminder_timer.stop()
|