everything_has_a_price_jam/economy.gd
2026-09-27 16:02:02 -06:00

154 lines
4.1 KiB
GDScript

extends Node
signal productions_update(p: Array[Production])
@warning_ignore("unused_signal")
signal production_log(producer: Currency, p: Production)
@warning_ignore("unused_signal")
signal log(s: String)
@export var currencies: Array[Production]
@export var members: Array
signal census(p: Production)
@onready var events: Array[Event] = load_events()
func spawn_friendlies():
if GameState.spawns_good == null:
spawn_friendlies.call_deferred()
return
for currency in get_all_sentient_currencies():
var p := Production.new()
p.currency = currency
p.amount = 0
census.emit(p)
var delta := p.amount - get_currency_amount(currency)
if delta > 0:
for i in range(delta):
spawn_currency_avatar(currency)
func spawn_currency_avatar(currency):
var troup := preload("res://Troup.tscn").instantiate()
var spawn: Node2D = GameState.spawns_good.get_children().pick_random()
troup.top_level = true
troup.position = spawn.global_position
var sprite: CurrencyMemberSprite = troup.sprite()
sprite.currency = currency
sprite.allegiance = preload("res://allegiance/good.tres")
get_tree().root.add_child(troup)
func load_events() -> Array[Event]:
var dir := "res://random events"
var es: Array[Event] = []
for event_name in ResourceLoader.list_directory(dir):
var event: Event = load(dir + "/" + event_name)
es.push_back(event)
return es
func get_currency(c: Currency) -> Production:
sync_currency.call_deferred()
for p in currencies:
if c == p.currency:
return p
var p := Production.new()
p.currency = c
p.amount = 0
currencies.append(p)
return p
func do_bribing(p: Production) -> bool:
if get_currency_amount(p.currency) < p.amount:
return false
produce(negate_production(p))
return true
func negate_production(p: Production) -> Production:
var pp := p.duplicate()
pp.amount = -pp.amount
return pp
func sync_currency():
var did_remove := true
while did_remove:
did_remove = false
for i in range(len(currencies)):
var p: Production = currencies[i]
if p.amount == 0:
currencies.remove_at(i)
did_remove = true
break
productions_update.emit(currencies)
func get_currency_amount(currency: Currency) -> int:
var c := get_currency(currency)
return c.amount
func can_consume(production: Production) -> bool:
return get_currency_amount(production.currency) >= production.amount
func produce(production: Production):
sync_currency.call_deferred()
var c := get_currency(production.currency)
c.amount += production.amount
c.amount = clamp(c.amount, 0, 9999)
func update_currencies():
productions_update.emit.call_deferred(currencies)
for c in currencies:
for p in c.currency.production:
var pp := Production.new()
pp.currency = p.currency
pp.amount = c.amount * p.amount
produce(pp)
func simulate():
update_currencies()
for e in events:
if e.requirements_satisfied() and e.will_happen():
if e.game_over_timeline != null:
get_tree().change_scene_to_file("res://game_over.tscn")
Dialogic.start(e.game_over_timeline)
return
if e.log_message != "" and not e.skip_log:
Economy.log.emit(e.log_message)
var outcome := e.outcome()
for o in outcome:
if o == null:
continue
produce(o)
if e.log_message == "" and not e.skip_log:
production_log.emit(null, o)
if e.timeline != null:
GameState.add_letter.emit(e.into_letter())
if randf() < 0.01:
LetterGeneration.try_generate_offer()
func get_all_currencies_in(dir: StringName):
var reses := ResourceLoader.list_directory(dir)
var resources := []
for res in reses:
if res.ends_with(".tres"):
resources.append(load(dir + "/" + res))
return resources
func get_all_sentient_currencies() -> Array:
return get_all_currencies_in("res://currency/sentient")
func get_all_inanimate_currencies() -> Array:
return get_all_currencies_in("res://currency/inanimate")
func _ready() -> void:
%SimulateTickTimer.start()
update_currencies()
log.emit.call_deferred("Welcome to your kingdom!")
func _on_timer_timeout() -> void:
if get_tree().current_scene.scene_file_path != "res://game.tscn":
%SimulateTickTimer.start()
return
if Dialogic.current_timeline != null:
%SimulateTickTimer.start()
return
simulate()