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.text = "Bid: $%sk" % [int(floor(value / 1000.0))] current_bid = value var starting_price := 0: set(value): if is_instance_valid(starting_price_label): if value == 0 or state == bidding_state.CLOSED: starting_price_label.text = "Starting Price: Pending" else: starting_price_label.text = "Starting Price: $%sk" % [int(floor(value / 1000.0))] starting_price = value var final_bid := 0: set(value): if is_instance_valid(going_price_label): going_price_label.text = "Sold for $%sk!" % [int(floor(value / 1000.0))] final_bid = value var target_sales := 0: set(value): if is_instance_valid(quota_label): quota_label.text = "Quota: $%sk Progress: 0%%" % [int(floor(value / 1000.0))] target_sales = value #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: Label @export var starting_price_label: Label @export var going_price_label: Label 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 = 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 turn_manager.speak_sentence("Sold for $%s!" % [current_bid]) quota_label.text = "Quota: $%sk Progress: %s%%" % [floor(target_sales / 1000.0), floor((float(get_total_sales()) / float(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 $NextPainting.play() get_painting_display().animate_show_painting() return true func _handle_ask_accepted(): pass 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()