ld58-collector/game_manager.gd

177 lines
5.2 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
var starting_price := 0
var final_bid := 0
@export var current_bid_display: RichTextLabel
var target_sales := 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
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(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
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("Oh nooooooo! Took too long!\nTry to make it up on the next painting!")
else:
turn_manager.restart_turn()
turn_manager.speak("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])
turn_manager.speak("Sold for $%s!" % [current_bid])
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():
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("Congratulations! The auction house will run another day.")
emit_signal("won")
else:
#add context specific score text?
turn_manager.speak("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
>> >> >> > wip_astra137
# 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()