This commit is contained in:
2026-03-27 00:21:40 +01:00
parent 2743fd314a
commit ebc9325b53
13 changed files with 26 additions and 34 deletions

View File

@@ -7,7 +7,7 @@ extends Node
#1: GEMS_CURRENCY_ID,
#}
const CURRENCY_DIRECTORY_PATH: String = "res://idles/currencies"
const CURRENCY_DIRECTORY_PATH: String = "res://sandbox/currencies"
const CURRENCY_RESOURCE_EXTENSIONS: PackedStringArray = ["tres", "res"]
var _currency_by_id: Dictionary = {}

View File

@@ -37,7 +37,7 @@ const HUGE_COST_EXPONENT: int = 1000000
@export var run_multiplier: float = 1.0
## Reference to generator UI
@onready var info_generator_container: GeneratorPanel = $GeneratorPanel
@export var info_generator_container: GeneratorPanel
## True while the pointer is inside the generator Area2D.
var _mouse_entered: bool = false

View File

@@ -3,32 +3,8 @@
[ext_resource type="Script" uid="uid://dtbxopw6ulhl8" path="res://core/generator/currency_generator.gd" id="1_4n4ca"]
[ext_resource type="Resource" uid="uid://brqaojindcxa5" path="res://idles/currencies/magic.tres" id="2_5tmvy"]
[ext_resource type="Resource" uid="uid://co0mcc2kvcpo5" path="res://idles/generators/orb.tres" id="3_wx13b"]
[ext_resource type="Texture2D" uid="uid://bgtt3wu43tajh" path="res://icon.svg" id="4_ruf1h"]
[ext_resource type="PackedScene" uid="uid://ckos7f22pnmyh" path="res://generator_container.tscn" id="5_bb14m"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_y5m1q"]
size = Vector2(128, 128)
[node name="CurrencyGenerator" type="Node2D" unique_id=967969064]
script = ExtResource("1_4n4ca")
currency = ExtResource("2_5tmvy")
data = ExtResource("3_wx13b")
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=807584513]
texture = ExtResource("4_ruf1h")
[node name="Area2D" type="Area2D" parent="." unique_id=707349247]
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D" unique_id=1572620025]
shape = SubResource("RectangleShape2D_y5m1q")
[node name="GeneratorPanel" parent="." unique_id=1129190041 node_paths=PackedStringArray("_generator") instance=ExtResource("5_bb14m")]
visible = false
offset_left = 33.0
offset_top = -65.0
offset_right = 474.0
offset_bottom = 200.5
_generator = NodePath("..")
[connection signal="mouse_entered" from="Area2D" to="." method="_on_area_2d_mouse_entered"]
[connection signal="mouse_exited" from="Area2D" to="." method="_on_area_2d_mouse_exited"]

View File

@@ -0,0 +1,173 @@
class_name GeneratorPanel
extends Container
const GENERATOR_BUFF_TILE_SCENE: PackedScene = preload("res://generator_buff_tile.tscn")
class BuffRow extends RefCounted:
var buff: GeneratorBuffData
var tile: GeneratorBuffTile
func _init(row_buff: GeneratorBuffData, row_tile: GeneratorBuffTile) -> void:
buff = row_buff
tile = row_tile
@export var _generator: CurrencyGenerator
@onready var _buy_button: Button = $PanelContainer/VBoxContainer/HBoxContainerGenerators/BuyOneButton
@onready var _buy_max_button: Button = $PanelContainer/VBoxContainer/HBoxContainerGenerators/BuyMaxButton
@onready var _name_label: Label = $PanelContainer/VBoxContainer/Label
@onready var _owned_value: Label = $PanelContainer/VBoxContainer/GeneratorStatsGrid/OwnedValue
@onready var _next_cost_value: Label = $PanelContainer/VBoxContainer/GeneratorStatsGrid/NextCostValue
@onready var _production_value: Label = $PanelContainer/VBoxContainer/GeneratorStatsGrid/ProductionValue
@onready var _buffs_section: VBoxContainer = $PanelContainer/VBoxContainer/BuffsSection
@onready var _buffs_list: VBoxContainer = $PanelContainer/VBoxContainer/BuffsSection/BuffsList
var _buff_rows: Array[BuffRow] = []
var _generator_id: StringName = &""
func _ready() -> void:
if _generator == null:
push_warning("GeneratorContainer '%s' has no generator assigned." % String(name))
return
_generator_id = _generator.get_generator_id()
_generator.purchase_completed.connect(_on_generator_updated)
_generator.production_tick.connect(_on_generator_updated)
_generator.purchase_failed.connect(_on_generator_updated)
_generator.buff_purchased.connect(_on_generator_updated)
_generator.buff_purchase_failed.connect(_on_generator_updated)
GameState.currency_changed.connect(_on_currency_changed)
GameState.generator_state_changed.connect(_on_generator_state_changed)
GameState.generator_buff_level_changed.connect(_on_generator_buff_level_changed)
GameState.generator_buff_unlocked_changed.connect(_on_generator_buff_unlocked_changed)
_name_label.text = _generator.data.name if _generator.data != null else "Generator"
_build_buff_rows()
_refresh_generator_ui()
func _on_buy_pressed() -> void:
_generator.buy(1)
_refresh_generator_ui()
func _on_buy_max_pressed() -> void:
_generator.buy_max()
_refresh_generator_ui()
func _on_debug_income_pressed() -> void:
_generator.grant_currency(BigNumber.from_float(100.0))
_refresh_generator_ui()
func _on_currency_changed(_changed_currency_id: StringName, _new_value: BigNumber) -> void:
_refresh_generator_ui()
func _on_generator_updated(_a = null, _b = null, _c = null, _d = null) -> void:
_refresh_generator_ui()
func _on_generator_state_changed(generator_id: StringName, _state: Dictionary) -> void:
if generator_id == _generator_id:
visible = true
_refresh_generator_ui()
func _on_generator_buff_level_changed(generator_id: StringName, _buff_id: StringName, _new_level: int) -> void:
if generator_id != _generator_id:
return
_refresh_generator_ui()
func _on_generator_buff_unlocked_changed(generator_id: StringName, _buff_id: StringName, _unlocked: bool) -> void:
if generator_id != _generator_id:
return
_refresh_generator_ui()
func _on_buy_buff_pressed(buff_id: StringName) -> void:
_generator.buy_buff(buff_id)
_refresh_generator_ui()
func _build_buff_rows() -> void:
_buff_rows.clear()
for child in _buffs_list.get_children():
child.queue_free()
for buff in _generator.get_buffs():
if buff == null:
continue
var buff_id_text: String = String(buff.id).strip_edges()
if buff_id_text.is_empty():
continue
var tile: GeneratorBuffTile = GENERATOR_BUFF_TILE_SCENE.instantiate() as GeneratorBuffTile
if tile == null:
push_warning("Failed to instantiate GeneratorBuffTile for buff '%s'." % buff_id_text)
continue
_buffs_list.add_child(tile)
tile.set_buff(buff)
tile.buy_pressed.connect(_on_buy_buff_pressed)
_buff_rows.append(BuffRow.new(buff, tile))
func _refresh_buff_rows(can_interact: bool) -> void:
_buffs_section.visible = not _buff_rows.is_empty()
if _buff_rows.is_empty():
return
for row in _buff_rows:
if row == null or row.buff == null or row.tile == null:
continue
var buff: GeneratorBuffData = row.buff
var buff_unlocked: bool = _generator.is_buff_unlocked(buff.id)
if not buff_unlocked:
var locked_hint: String = "Locked"
var unlock_goal_currency: Resource = buff.get_unlock_goal_currency()
if buff.has_unlock_goal() and unlock_goal_currency != null:
var goal_currency_id: StringName = GameState.get_currency_id(unlock_goal_currency)
var currency_name: String = GameState.get_currency_name(goal_currency_id)
var required_text: String = buff.get_unlock_goal_amount().to_string_suffix(2)
locked_hint = "Unlock at %s %s" % [required_text, currency_name]
row.tile.set_runtime(0, "Locked", locked_hint, false, false)
continue
var level: int = _generator.get_buff_level(buff.id)
var effect_text: String = buff.get_effect_description(level)
if _generator.is_buff_maxed(buff.id):
row.tile.set_runtime(level, effect_text, "", false, true)
continue
var cost: BigNumber = _generator.get_buff_cost(buff.id)
var cost_currency_id: StringName = _generator.get_buff_cost_currency_id(buff.id)
var currency_label: String = GameState.get_currency_name(cost_currency_id)
var cost_text: String = "%s %s" % [cost.to_string_suffix(2), currency_label]
var can_buy: bool = can_interact and _generator.can_buy_buff(buff.id)
row.tile.set_runtime(level, effect_text, cost_text, can_buy, false)
func _refresh_generator_ui() -> void:
var can_interact: bool = _generator.is_available_to_player()
_buy_button.disabled = not can_interact
_buy_max_button.disabled = not can_interact
_owned_value.text = str(_generator.owned)
if can_interact:
var purchase_currency_id: StringName = _generator.get_purchase_currency_id()
var purchase_currency_name: String = GameState.get_currency_name(purchase_currency_id)
if purchase_currency_name.is_empty():
purchase_currency_name = "Unconfigured"
_next_cost_value.text = "%s %s" % [_generator.get_next_cost().to_string_suffix(2), purchase_currency_name]
else:
_next_cost_value.text = "-"
var production_per_second: float = 0.0
if _generator.data != null and can_interact:
production_per_second = _generator.data.production_per_second(
_generator.owned,
_generator.get_effective_auto_run_multiplier(),
_generator.purchased_count
)
_production_value.text = BigNumber.from_float(production_per_second).to_string_suffix(2)
_refresh_buff_rows(can_interact)

View File

@@ -0,0 +1 @@
uid://es14nqk6vrrk

View File

@@ -0,0 +1,85 @@
[gd_scene format=3 uid="uid://ckos7f22pnmyh"]
[ext_resource type="Script" uid="uid://es14nqk6vrrk" path="res://core/generator/generator_container.gd" id="1_8wouw"]
[node name="GeneratorContainer" type="PanelContainer" unique_id=1451609580]
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -132.0
offset_top = -82.5
offset_right = 132.0
offset_bottom = 87.5
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_8wouw")
[node name="PanelContainer" type="MarginContainer" parent="." unique_id=370221865]
layout_mode = 2
theme_override_constants/margin_left = 20
theme_override_constants/margin_top = 20
theme_override_constants/margin_right = 20
theme_override_constants/margin_bottom = 20
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer" unique_id=1139263929]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer" unique_id=1867673612]
layout_mode = 2
text = "Generator"
[node name="HBoxContainerGenerators" type="HBoxContainer" parent="PanelContainer/VBoxContainer" unique_id=2033456807]
layout_mode = 2
theme_override_constants/separation = 8
[node name="BuyOneButton" type="Button" parent="PanelContainer/VBoxContainer/HBoxContainerGenerators" unique_id=1171095139]
layout_mode = 2
text = "Buy x1"
[node name="BuyMaxButton" type="Button" parent="PanelContainer/VBoxContainer/HBoxContainerGenerators" unique_id=871628534]
layout_mode = 2
text = "Buy Max"
[node name="GeneratorStatsGrid" type="GridContainer" parent="PanelContainer/VBoxContainer" unique_id=745078076]
layout_mode = 2
columns = 2
[node name="OwnedTitle" type="Label" parent="PanelContainer/VBoxContainer/GeneratorStatsGrid" unique_id=891417119]
layout_mode = 2
text = "Owned"
[node name="OwnedValue" type="Label" parent="PanelContainer/VBoxContainer/GeneratorStatsGrid" unique_id=549086894]
layout_mode = 2
text = "0"
[node name="NextCostTitle" type="Label" parent="PanelContainer/VBoxContainer/GeneratorStatsGrid" unique_id=303459589]
layout_mode = 2
text = "Next Cost"
[node name="NextCostValue" type="Label" parent="PanelContainer/VBoxContainer/GeneratorStatsGrid" unique_id=50480604]
layout_mode = 2
text = "0"
[node name="ProductionTitle" type="Label" parent="PanelContainer/VBoxContainer/GeneratorStatsGrid" unique_id=2139535774]
layout_mode = 2
text = "Production / sec"
[node name="ProductionValue" type="Label" parent="PanelContainer/VBoxContainer/GeneratorStatsGrid" unique_id=938669936]
layout_mode = 2
text = "0"
[node name="BuffsSection" type="VBoxContainer" parent="PanelContainer/VBoxContainer" unique_id=640102105]
layout_mode = 2
[node name="BuffsTitle" type="Label" parent="PanelContainer/VBoxContainer/BuffsSection" unique_id=1169271241]
layout_mode = 2
text = "Buffs"
[node name="BuffsList" type="VBoxContainer" parent="PanelContainer/VBoxContainer/BuffsSection" unique_id=1221547661]
layout_mode = 2
theme_override_constants/separation = 4
[connection signal="pressed" from="PanelContainer/VBoxContainer/HBoxContainerGenerators/BuyOneButton" to="." method="_on_buy_pressed"]
[connection signal="pressed" from="PanelContainer/VBoxContainer/HBoxContainerGenerators/BuyMaxButton" to="." method="_on_buy_max_pressed"]

View File

@@ -32,7 +32,7 @@ var last_reset_time: int = 0
func _ready() -> void:
if config == null:
config = load("res://idles/prestige/primary_prestige.tres") as Resource
config = load("res://sandbox/prestige/primary_prestige.tres") as Resource
if not _is_config_valid():
push_warning("PrestigeManager has invalid or missing config; prestige is disabled.")