From 0064e61389e6947dba04f96de494fdacc322c07b Mon Sep 17 00:00:00 2001 From: Michele Rossi Date: Thu, 23 Apr 2026 12:46:01 +0200 Subject: [PATCH] Fix alchemy tower --- AGENTS.md | 1 + core/level_game_state.gd | 12 +- .../buildings/alchemy_tower/Tower.png | Bin 0 -> 6496 bytes .../buildings/alchemy_tower/Tower.png.import | 40 ++++ .../alchemy_craftable_panel_tile.gd | 81 ++++++++ .../alchemy_craftable_panel_tile.gd.uid | 1 + .../alchemy_craftable_panel_tile.tscn | 31 +++ .../alchemy_tower/alchemy_currencies_panel.gd | 161 ++++++++++++++ .../alchemy_currencies_panel.gd.uid | 1 + .../alchemy_currencies_panel.tscn | 40 ++++ .../alchemy_currencies_panel_old.gd.uid | 1 + .../buildings/alchemy_tower/alchemy_tower.gd | 196 ++++++++++++++++++ .../alchemy_tower/alchemy_tower.gd.uid | 1 + .../alchemy_tower/alchemy_tower.tscn | 33 +++ .../alchemy_tower/alchemy_tower_data.gd | 23 ++ .../alchemy_tower/alchemy_tower_data.gd.uid | 1 + .../alchemy_tower/alchemy_tower_data.tres | 14 ++ .../recipes/alchemy_craft_catalogue.gd | 18 ++ .../recipes/alchemy_craft_catalogue.gd.uid | 1 + .../recipes/alchemy_craft_catalogue.tres | 9 + .../recipes/alchemy_craft_recipe.gd | 10 + .../recipes/alchemy_craft_recipe.gd.uid | 1 + .../alchemy_craft_recipes_catalogue.tres | 10 + .../recipes/cognite_cost_entry.tres | 10 + .../alchemy_tower/recipes/cognite_recipe.tres | 11 + .../recipes/currency_cost_entry.gd | 6 + .../recipes/currency_cost_entry.gd.uid | 1 + .../recipes/mana_stone_cost_entry.tres | 10 + .../recipes/mana_stone_recipe.tres | 13 ++ .../buildings/alchemy_tower/test_panel.gd.uid | 1 + docs/gyms/tiny_sword/currencies/cognite.tres | 11 + .../tiny_sword/currencies/magic_gold.tres | 11 + .../tiny_sword/currencies/mana_stone.tres | 11 + .../currencies/ts_currency_catalogue.tres | 5 +- docs/gyms/tiny_sword/tiny_sword.tscn | 35 ++-- 35 files changed, 792 insertions(+), 19 deletions(-) create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/Tower.png create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/Tower.png.import create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_craftable_panel_tile.gd create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_craftable_panel_tile.gd.uid create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_craftable_panel_tile.tscn create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_currencies_panel.gd create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_currencies_panel.gd.uid create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_currencies_panel.tscn create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_currencies_panel_old.gd.uid create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower.gd create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower.gd.uid create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower.tscn create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower_data.gd create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower_data.gd.uid create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower_data.tres create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_catalogue.gd create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_catalogue.gd.uid create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_catalogue.tres create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_recipe.gd create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_recipe.gd.uid create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_recipes_catalogue.tres create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/cognite_cost_entry.tres create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/cognite_recipe.tres create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/currency_cost_entry.gd create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/currency_cost_entry.gd.uid create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/mana_stone_cost_entry.tres create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/mana_stone_recipe.tres create mode 100644 docs/gyms/tiny_sword/buildings/alchemy_tower/test_panel.gd.uid create mode 100644 docs/gyms/tiny_sword/currencies/cognite.tres create mode 100644 docs/gyms/tiny_sword/currencies/magic_gold.tres create mode 100644 docs/gyms/tiny_sword/currencies/mana_stone.tres diff --git a/AGENTS.md b/AGENTS.md index e258761..f4a619f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -24,3 +24,4 @@ When reading files/JSON, always guard `FileAccess.open(...)` and validate parsed Use signals (already in `GameState`) for UI updates instead of polling or cross-node direct mutation. No Cursor/Claude/Windsurf/Cline/Goose/Copilot rule files were found in this repository, so this file is the canonical agent guidance. Avoid trivial one-line wrapper/helper functions that only forward or repack data. Inline the logic at the real call site unless the wrapper adds meaningful abstraction or is reused enough to justify it. +Resource type safety: Use the specific resource. Avoid as much as possible explicit `Resource` usage. diff --git a/core/level_game_state.gd b/core/level_game_state.gd index acf3502..af9aad0 100644 --- a/core/level_game_state.gd +++ b/core/level_game_state.gd @@ -150,7 +150,7 @@ func _ready() -> void: # CURRENCY API # ============================================================================== ## Returns the normalized ID from a Currency resource. -func get_currency_id(currency: Resource) -> StringName: +func get_currency_id(currency: Currency) -> StringName: return _normalize_currency_id(currency.id if currency else &"") ## Parses and normalizes a currency ID from raw input (handles special cases like "gem" -> "gems"). @@ -193,7 +193,7 @@ func get_currency_icon(currency_id: StringName) -> Texture2D: return null ## Adds currency from a Currency resource. Emits [signal currency_changed] on success. -func add_currency(currency: Resource, amount: BigNumber) -> void: +func add_currency(currency: Currency, amount: BigNumber) -> void: var currency_id: StringName = get_currency_id(currency) if currency_id == &"": push_warning("Attempted to add currency with an invalid Currency resource.") @@ -201,7 +201,7 @@ func add_currency(currency: Resource, amount: BigNumber) -> void: add_currency_by_id(currency_id, amount) ## Spends currency from a Currency resource. Returns false if insufficient funds. -func spend_currency(currency: Resource, cost: BigNumber) -> bool: +func spend_currency(currency: Currency, cost: BigNumber) -> bool: var currency_id: StringName = get_currency_id(currency) if currency_id == &"": push_warning("Attempted to spend currency with an invalid Currency resource.") @@ -237,7 +237,7 @@ func spend_currency_by_id(currency_id: StringName, cost: BigNumber) -> bool: return false ## Returns the current balance for a Currency resource. -func get_currency_amount(currency: Resource) -> BigNumber: +func get_currency_amount(currency: Currency) -> BigNumber: return get_currency_amount_by_id(get_currency_id(currency)) ## Returns the current balance for a currency ID. @@ -245,7 +245,7 @@ func get_currency_amount_by_id(currency_id: StringName) -> BigNumber: return _get_current_currency_ref(currency_id) ## Returns the total acquired this run for a Currency resource. -func get_total_currency_acquired(currency: Resource) -> BigNumber: +func get_total_currency_acquired(currency: Currency) -> BigNumber: return get_total_currency_acquired_by_id(get_currency_id(currency)) ## Returns the total acquired this run for a currency ID (resets on prestige). @@ -253,7 +253,7 @@ func get_total_currency_acquired_by_id(currency_id: StringName) -> BigNumber: return _get_total_currency_ref(currency_id) ## Returns the all-time total for a Currency resource. -func get_all_time_currency_acquired(currency: Resource) -> BigNumber: +func get_all_time_currency_acquired(currency: Currency) -> BigNumber: return get_all_time_currency_acquired_by_id(get_currency_id(currency)) ## Returns the all-time total for a currency ID (never resets). diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/Tower.png b/docs/gyms/tiny_sword/buildings/alchemy_tower/Tower.png new file mode 100644 index 0000000000000000000000000000000000000000..cf740f09f253bb49d7b36197cc3130dfa10ee1f0 GIT binary patch literal 6496 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 void: + _game_state = find_parent("LevelGameState") + _game_state.ready.connect(_on_game_state_ready) + + if not _button.pressed.is_connected(_on_button_pressed): + _button.pressed.connect(_on_button_pressed) + + _initialized = true + +func setup(recipe: AlchemyCraftRecipe) -> void: + _recipe = recipe + +func _on_game_state_ready() -> void: + # Validate labels before use + if _name_label == null: + push_error("AlchemyCraftableTile: _name_label is null in setup") + return + + # Set up display + _name_label.text = str(_recipe.output_currency.display_name) if _recipe.output_currency else "Unknown" + _update_cost_display() + + # Connect to currency changes for balance updates + if _game_state != null: + _game_state.currency_changed.connect(_on_currency_changed) + + # Initial balance update + _update_balance() + +func _update_cost_display() -> void: + if _cost_label == null or _recipe == null: + return + + if _recipe.cost_entries.is_empty(): + _cost_label.text = "No cost" + return + + var cost_text: String = "" + for entry in _recipe.cost_entries: + if entry == null: + continue + if not cost_text.is_empty(): + cost_text += " + " + cost_text += "%d %s" % [entry.amount, entry.currency.display_name] + + _cost_label.text = cost_text + +func _update_balance() -> void: + if _balance_label == null or _recipe == null or _game_state == null: + return + + var balance: BigNumber = _game_state.get_currency_amount(_recipe.output_currency) + _balance_label.text = balance.to_string_suffix(0) + +func _on_button_pressed() -> void: + if _recipe == null: + push_warning("AlchemyCraftableTile: No recipe configured") + return + + craft_button_pressed.emit(_recipe) + +func _on_currency_changed(currency_id: StringName, _amount: BigNumber) -> void: + # Update balance if this currency changed + if _recipe != null: + var output_currency_id: StringName = _recipe.output_currency.id if _recipe.output_currency else &"" + if currency_id == output_currency_id: + _update_balance() diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_craftable_panel_tile.gd.uid b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_craftable_panel_tile.gd.uid new file mode 100644 index 0000000..2ca7984 --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_craftable_panel_tile.gd.uid @@ -0,0 +1 @@ +uid://c63g772y4kxwm diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_craftable_panel_tile.tscn b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_craftable_panel_tile.tscn new file mode 100644 index 0000000..78c63f8 --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_craftable_panel_tile.tscn @@ -0,0 +1,31 @@ +[gd_scene format=3 uid="uid://cxusq0tunvjlb"] + +[ext_resource type="Script" uid="uid://c63g772y4kxwm" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_craftable_panel_tile.gd" id="1_hw1b0"] + +[node name="AlchemyCraftableTile" type="HBoxContainer" unique_id=1715275035] +offset_left = 10.0 +offset_top = 10.0 +offset_right = 280.0 +offset_bottom = 41.0 +script = ExtResource("1_hw1b0") + +[node name="NameLabel" type="Label" parent="." unique_id=2031343677] +layout_mode = 2 +size_flags_horizontal = 8 +text = "Currency" + +[node name="BalanceLabel" type="Label" parent="." unique_id=1367089480] +layout_mode = 2 +size_flags_horizontal = 8 +text = "0" + +[node name="CostLabel" type="Label" parent="." unique_id=1649255694] +layout_mode = 2 +size_flags_horizontal = 8 +text = "10 Magic Gold" + +[node name="Button" type="Button" parent="." unique_id=1649255693] +layout_mode = 2 +text = "Craft" + +[connection signal="pressed" from="Button" to="." method="_on_button_pressed"] diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_currencies_panel.gd b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_currencies_panel.gd new file mode 100644 index 0000000..6586c3f --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_currencies_panel.gd @@ -0,0 +1,161 @@ +class_name AlchemyCurrenciesPanel +extends PanelContainer + +signal craft_requested(recipe: Variant) +signal alchemy_workers_changed(count: int) + +# Currency used to pay crafts (magic gold) +@export var currency: Currency +# The list of crafts available to alchemy tower +@export var craft_recipes: AlchemyCraftCatalogue + +@onready var _tile_scene: PackedScene = preload("res://docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_craftable_panel_tile.tscn") +@onready var _craft_list: VBoxContainer = $VBoxContainer/CraftList +@onready var _currency_name_label: Label = $VBoxContainer/HBoxCurrency/NameLabel +@onready var _progress_bar: ProgressBar = $VBoxContainer/HBoxCurrency/ProgressBar +@onready var _balance_label: Label = $VBoxContainer/HBoxCurrency/AmountLabel +@onready var _worker_label: Label = $VBoxContainer/HBoxWorker/WorkerLabel +@onready var _assign_button: Button = $VBoxContainer/HBoxWorker/AssignButton + +var _alchemy_tower: AlchemyTower +var _game_state: LevelGameState +var _alchemy_worker_count: int = 0 + +func _ready() -> void: + assert(craft_recipes != null, "Craft recipes cannot be null") + + _game_state = find_parent("LevelGameState") + if _game_state == null: + push_error("AlchemyCurrenciesPanel: Could not find LevelGameState") + return + + # Find AlchemyTower in parent + _alchemy_tower = _find_alchemy_tower() + + # Set up UI labels + _currency_name_label.text = currency.display_name if currency else "Magic Gold" + + # Connect to tower signals + if _alchemy_tower: + _alchemy_tower.production_progress_updated.connect(_on_production_progress) + _alchemy_tower.magic_gold_balance_updated.connect(_on_magic_gold_changed) + _alchemy_tower.production_completed.connect(_on_production_completed) + + # Connect worker button + if _assign_button: + _assign_button.pressed.connect(_on_assign_button_pressed) + + # Initialize displays + _update_magic_gold_display() + _update_production_progress(0.0) + _update_worker_display() + + # Connect to worker currency changes + _game_state.currency_changed.connect(_on_currency_changed) + + # Clear and populate craft tiles + for child in _craft_list.get_children(): + child.queue_free() + + for recipe in craft_recipes.recipes: + var instance: AlchemyCraftableTile = _tile_scene.instantiate() as AlchemyCraftableTile + instance.setup(recipe) + instance.craft_button_pressed.connect(_on_craft_button_pressed) + _craft_list.add_child(instance) + +func _find_alchemy_tower() -> AlchemyTower: + var parent: Node = get_parent() + while parent != null: + if parent is AlchemyTower: + return parent as AlchemyTower + parent = parent.get_parent() + return null + +func _update_magic_gold_display() -> void: + if _alchemy_tower == null or _game_state == null: + return + + var magic_gold_currency: Currency = _get_magic_gold_currency() + if magic_gold_currency == null: + _balance_label.text = "0" + return + + var balance: BigNumber = _game_state.get_currency_amount(magic_gold_currency) + _balance_label.text = balance.to_string_suffix(2) + +func _update_production_progress(progress: float) -> void: + if _progress_bar == null: + return + _progress_bar.value = progress * 100.0 + +func _update_worker_display() -> void: + if _worker_label == null: + return + + _worker_label.text = "Alchemy Workers: %d" % _alchemy_worker_count + + if _assign_button != null: + var worker_currency: Currency = _get_worker_currency() + var can_assign: bool = false + + if worker_currency != null and _alchemy_worker_count < 10: + var worker_balance: BigNumber = _game_state.get_currency_amount(worker_currency) + can_assign = worker_balance.mantissa >= 1.0 + + _assign_button.disabled = not can_assign + _assign_button.text = "Assign Worker" if can_assign else "No Workers Available" + +func _get_magic_gold_currency() -> Currency: + if _game_state == null or _game_state.currency_catalogue == null: + return null + + for currency in _game_state.currency_catalogue.currencies: + if currency == null: + continue + if currency.id == &"magic_gold": + return currency + + return null + +func _get_worker_currency() -> Currency: + if _game_state == null or _game_state.currency_catalogue == null: + return null + + for currency in _game_state.currency_catalogue.currencies: + if currency == null: + continue + if currency.id == &"worker": + return currency + + return null + +func _on_production_progress(progress: float) -> void: + _update_production_progress(progress) + +func _on_magic_gold_changed(amount: BigNumber) -> void: + _update_magic_gold_display() + _update_worker_display() + +func _on_production_completed(_amount: BigNumber) -> void: + _update_magic_gold_display() + +func _on_currency_changed(currency_id: StringName, _amount: BigNumber) -> void: + if currency_id == &"worker": + _update_worker_display() + +func _on_assign_button_pressed() -> void: + if _alchemy_tower == null or _game_state == null: + return + + var worker_currency: Currency = _get_worker_currency() + if worker_currency == null: + return + + # Spend a worker + if _game_state.spend_currency(worker_currency, BigNumber.from_float(1.0)): + _alchemy_worker_count += 1 + _update_worker_display() + alchemy_workers_changed.emit(_alchemy_worker_count) + +func _on_craft_button_pressed(recipe: Variant) -> void: + craft_requested.emit(recipe) diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_currencies_panel.gd.uid b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_currencies_panel.gd.uid new file mode 100644 index 0000000..27e1f16 --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_currencies_panel.gd.uid @@ -0,0 +1 @@ +uid://do1i3hrd0ueb6 diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_currencies_panel.tscn b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_currencies_panel.tscn new file mode 100644 index 0000000..59627f1 --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_currencies_panel.tscn @@ -0,0 +1,40 @@ +[gd_scene format=3 uid="uid://cbp6vpth8x4rw"] + +[ext_resource type="Script" uid="uid://do1i3hrd0ueb6" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_currencies_panel.gd" id="1_script"] + +[node name="AlchemyCurrenciesPanel" type="PanelContainer" unique_id=1000001] +custom_minimum_size = Vector2(400, 300) +script = ExtResource("1_script") + +[node name="VBoxContainer" type="VBoxContainer" parent="." unique_id=1115194594] +layout_mode = 2 + +[node name="HBoxWorker" type="HBoxContainer" parent="VBoxContainer" unique_id=1415354976] +layout_mode = 2 + +[node name="WorkerLabel" type="Label" parent="VBoxContainer/HBoxWorker" unique_id=4000008] +layout_mode = 2 +text = "Alchemy Workers: 0" + +[node name="AssignButton" type="Button" parent="VBoxContainer/HBoxWorker" unique_id=4000009] +layout_mode = 2 +text = "Assign Worker" + +[node name="HBoxCurrency" type="HBoxContainer" parent="VBoxContainer" unique_id=1815331819] +layout_mode = 2 + +[node name="NameLabel" type="Label" parent="VBoxContainer/HBoxCurrency" unique_id=4000005] +layout_mode = 2 +text = "Magic Gold" + +[node name="ProgressBar" type="ProgressBar" parent="VBoxContainer/HBoxCurrency" unique_id=4000006] +custom_minimum_size = Vector2(200, 0) +layout_mode = 2 + +[node name="AmountLabel" type="Label" parent="VBoxContainer/HBoxCurrency" unique_id=4000007] +layout_mode = 2 +text = "0" + +[node name="CraftList" type="VBoxContainer" parent="VBoxContainer" unique_id=3000005] +layout_mode = 2 +size_flags_vertical = 8 diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_currencies_panel_old.gd.uid b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_currencies_panel_old.gd.uid new file mode 100644 index 0000000..3aedd89 --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_currencies_panel_old.gd.uid @@ -0,0 +1 @@ +uid://bsfgq4apkidak diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower.gd b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower.gd new file mode 100644 index 0000000..de947cd --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower.gd @@ -0,0 +1,196 @@ +class_name AlchemyTower +extends Node2D + +## Emitted when production progress changes (0.0 to 1.0) +signal production_progress_updated(progress: float) + +## Emitted when magic gold balance changes +signal magic_gold_balance_updated(amount: BigNumber) + +## Emitted when a production cycle completes +signal production_completed(amount: BigNumber) + +## Configuration data for this tower +@export var data: AlchemyTowerData + +## Available craft recipes +@export var craft_recipes: AlchemyCraftCatalogue + +## Reference to game state +@onready var game_state: LevelGameState = find_parent("LevelGameState") + +## Current production state +var production_time_elapsed: float = 0.0 +var current_production_time: float +var cycle_count: int = 0 + +## Number of workers assigned to this tower +var _worker_count: int = 0 + +## UI panel reference +@onready var alchemy_panel: AlchemyCurrenciesPanel = $AlchemyCurrenciesPanel + +func _ready() -> void: + assert(data != null, "AlchemyTowerData is required") + assert(craft_recipes != null, "Craft recipes catalogue is required") + assert(game_state != null, "LevelGameState is required") + + # Initialize production time + current_production_time = data.base_production_time_seconds + + # Register this tower as an available generator + game_state.set_generator_available(get_generator_id(), true) + + # Connect to magic gold balance changes + game_state.currency_changed.connect(_on_currency_changed) + + # Connect panel signals if available + if alchemy_panel: + alchemy_panel.craft_requested.connect(_on_craft_requested) + alchemy_panel.alchemy_workers_changed.connect(_on_alchemy_workers_changed) + + # Initial progress update + production_progress_updated.emit(0.0) + +func _process(delta: float) -> void: + if not _is_production_active(): + return + + var speed_multiplier: float = _get_worker_speed_multiplier() + + # Add elapsed time scaled by worker count + production_time_elapsed += delta * speed_multiplier + + # Update progress bar every frame + production_progress_updated.emit(_get_production_progress()) + + # Check if production is complete + if production_time_elapsed >= current_production_time: + _try_complete_production() + +func _is_production_active() -> bool: + if not game_state.is_generator_available(get_generator_id()): + return false + return _get_worker_count() > 0 + +func _try_complete_production() -> void: + # Calculate how many cycles completed + var completed_cycles: int = floori(production_time_elapsed / current_production_time) + + if completed_cycles <= 0: + return + + # Reset elapsed time + production_time_elapsed -= current_production_time * float(completed_cycles) + + # Calculate output + var output_per_cycle: BigNumber = BigNumber.from_float(data.magic_gold_per_cycle) + var total_output: BigNumber = output_per_cycle.multiply(BigNumber.from_float(float(completed_cycles))) + + # Apply worker speed bonus (affects output, not time) + var worker_multiplier: float = _get_worker_speed_multiplier() + if worker_multiplier > 1.0: + total_output = total_output.multiply(BigNumber.from_float(worker_multiplier)) + + # Add magic gold + _add_magic_gold(total_output) + + # Increment cycle count + cycle_count += completed_cycles + + # Increase production time (mild exponential growth) + current_production_time *= pow(data.production_time_growth_multiplier, float(completed_cycles)) + + # Emit signals + production_completed.emit(total_output) + production_progress_updated.emit(_get_production_progress()) + +func _add_magic_gold(amount: BigNumber) -> void: + if data == null or game_state == null: + return + + var magic_gold_currency: Currency = _get_magic_gold_currency() + if magic_gold_currency == null: + push_error("AlchemyTower: Could not find magic gold currency") + return + + game_state.add_currency(magic_gold_currency, amount) + +func _get_magic_gold_currency() -> Currency: + # Find magic gold in the currency catalogue + if game_state == null or game_state.currency_catalogue == null: + return null + + for currency in game_state.currency_catalogue.currencies: + if currency == null: + continue + if currency.id == &"magic_gold": + return currency + + return null + +func _get_worker_count() -> int: + return mini(_worker_count, data.max_workers) + +func _get_worker_speed_multiplier() -> float: + if game_state == null: + return 1.0 + + var worker_count: int = _get_worker_count() + var multiplier: float = 1.0 + (float(worker_count) * data.base_worker_speed_bonus) + + return multiplier + +func _get_worker_currency() -> Currency: + if game_state == null or game_state.currency_catalogue == null: + return null + + for currency in game_state.currency_catalogue.currencies: + if currency == null: + continue + if currency.id == &"worker": + return currency + + return null + +func _get_production_progress() -> float: + if current_production_time <= 0.0: + return 1.0 + + var progress: float = production_time_elapsed / current_production_time + return clampf(progress, 0.0, 1.0) + +func get_generator_id() -> StringName: + return data.id + +func craft_item(recipe: Variant) -> bool: + if recipe == null: + return false + + # Check and pay all costs + for entry in recipe.cost_entries: + if entry == null or entry.currency == null: + continue + if not game_state.spend_currency(entry.currency, BigNumber.from_float(float(entry.amount))): + return false + + # Success - add output + game_state.add_currency(recipe.output_currency, BigNumber.from_float(float(recipe.output_amount))) + + return true + +func _on_currency_changed(currency_id: StringName, _amount: BigNumber) -> void: + if currency_id == &"magic_gold": + magic_gold_balance_updated.emit(_amount) + +func _on_alchemy_workers_changed(count: int) -> void: + _worker_count = count + production_progress_updated.emit(_get_production_progress()) + +func _on_craft_requested(recipe: Variant) -> void: + if recipe == null: + return + + var success: bool = craft_item(recipe) + if not success: + push_warning("AlchemyTower: Failed to craft %s - insufficient funds" % recipe.output_currency.display_name) diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower.gd.uid b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower.gd.uid new file mode 100644 index 0000000..ae7c32e --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower.gd.uid @@ -0,0 +1 @@ +uid://bddaaj76msmvj diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower.tscn b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower.tscn new file mode 100644 index 0000000..ad9a758 --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower.tscn @@ -0,0 +1,33 @@ +[gd_scene format=3 uid="uid://bp5ng4vu4ot4a"] + +[ext_resource type="Texture2D" uid="uid://cieg8i3c8hca6" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/Tower.png" id="1_vbhae"] +[ext_resource type="PackedScene" uid="uid://cbp6vpth8x4rw" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_currencies_panel.tscn" id="2_8pntr"] +[ext_resource type="Script" uid="uid://bddaaj76msmvj" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower.gd" id="3_tower"] +[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower_data.tres" id="4_data"] +[ext_resource type="Resource" uid="uid://diboykfbbxpfs" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_catalogue.tres" id="5_recipes"] +[ext_resource type="Resource" uid="uid://dpbndqxvsffa0" path="res://docs/gyms/tiny_sword/currencies/magic_gold.tres" id="7_b8p5n"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_8pntr"] +size = Vector2(109, 182) + +[node name="AlchemyTower" type="Node2D" unique_id=51852160] +script = ExtResource("3_tower") +data = ExtResource("4_data") +craft_recipes = ExtResource("5_recipes") + +[node name="Sprite2D" type="Sprite2D" parent="." unique_id=1160485854] +texture = ExtResource("1_vbhae") + +[node name="Area2D" type="Area2D" parent="." unique_id=911128362] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D" unique_id=1059910507] +position = Vector2(0.5, 11) +shape = SubResource("RectangleShape2D_8pntr") + +[node name="AlchemyCurrenciesPanel" parent="." unique_id=731368154 instance=ExtResource("2_8pntr")] +offset_left = 65.0 +offset_top = -75.0 +offset_right = 65.0 +offset_bottom = -75.0 +currency = ExtResource("7_b8p5n") +craft_recipes = ExtResource("5_recipes") diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower_data.gd b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower_data.gd new file mode 100644 index 0000000..67172b1 --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower_data.gd @@ -0,0 +1,23 @@ +class_name AlchemyTowerData +extends Resource + +@export_group("Identification") +@export var id: StringName = &"alchemy_tower" +@export var name: String = "Alchemy Tower" + +@export_group("Production") +## Base time to produce one magic gold (first production) +@export var base_production_time_seconds: float = 5.0 + +## Multiplier applied to production time each cycle (1.2 = 20% increase) +@export var production_time_growth_multiplier: float = 1.2 + +## Amount of magic gold produced per cycle +@export var magic_gold_per_cycle: float = 1.0 + +@export_group("Workers") +## Speed bonus per alchemy worker (0.1 = +10% speed per worker) +@export var base_worker_speed_bonus: float = 0.1 + +## Maximum workers that can be assigned +@export var max_workers: int = 10 diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower_data.gd.uid b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower_data.gd.uid new file mode 100644 index 0000000..bc38cec --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower_data.gd.uid @@ -0,0 +1 @@ +uid://dxgpic67x08c6 diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower_data.tres b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower_data.tres new file mode 100644 index 0000000..8de1016 --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower_data.tres @@ -0,0 +1,14 @@ +[gd_resource type="Resource" script_class="AlchemyTowerData" format=3 uid="uid://alchemy_tower_data"] + +[ext_resource type="Script" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower_data.gd" id="1_data"] + +[resource] +script = ExtResource("1_data") +id = &"alchemy_tower" +name = "Alchemy Tower" +base_production_time_seconds = 5.0 +production_time_growth_multiplier = 1.2 +magic_gold_per_cycle = 1.0 +base_worker_speed_bonus = 0.1 +max_workers = 10 +metadata/_custom_type_script = "res://docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower_data.gd" diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_catalogue.gd b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_catalogue.gd new file mode 100644 index 0000000..a4b3d05 --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_catalogue.gd @@ -0,0 +1,18 @@ +class_name AlchemyCraftCatalogue +extends Resource + +## Catalogue of alchemy craft recipes +@export var recipes: Array = [] + +func get_recipe_by_id(id: StringName) -> Variant: + for recipe in recipes: + if recipe != null and recipe.id == id: + return recipe + return null + +func get_all_ids() -> Array[StringName]: + var ids: Array[StringName] = [] + for recipe in recipes: + if recipe != null and recipe.id != &"": + ids.append(recipe.id) + return ids diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_catalogue.gd.uid b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_catalogue.gd.uid new file mode 100644 index 0000000..c1f39e4 --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_catalogue.gd.uid @@ -0,0 +1 @@ +uid://biljlhsxr3rsc diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_catalogue.tres b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_catalogue.tres new file mode 100644 index 0000000..de35e76 --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_catalogue.tres @@ -0,0 +1,9 @@ +[gd_resource type="Resource" script_class="AlchemyCraftCatalogue" format=3 uid="uid://diboykfbbxpfs"] + +[ext_resource type="Script" uid="uid://biljlhsxr3rsc" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_catalogue.gd" id="1_cat"] +[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/mana_stone_recipe.tres" id="2_mana_recipe"] +[ext_resource type="Resource" uid="uid://dliibkgb2mom0" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/cognite_recipe.tres" id="3_cognite_recipe"] + +[resource] +script = ExtResource("1_cat") +recipes = [ExtResource("2_mana_recipe"), ExtResource("3_cognite_recipe")] diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_recipe.gd b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_recipe.gd new file mode 100644 index 0000000..e88f2de --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_recipe.gd @@ -0,0 +1,10 @@ +class_name AlchemyCraftRecipe +extends Resource + +## Recipe for crafting currencies at the Alchemy Tower +@export var id: StringName = &"" +@export var output_currency: Currency +@export var output_amount: int = 1 + +## Multi-currency cost to perform this craft +@export var cost_entries: Array = [] diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_recipe.gd.uid b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_recipe.gd.uid new file mode 100644 index 0000000..6d03f6d --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_recipe.gd.uid @@ -0,0 +1 @@ +uid://ddlnlpb0p750q diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_recipes_catalogue.tres b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_recipes_catalogue.tres new file mode 100644 index 0000000..879e500 --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_recipes_catalogue.tres @@ -0,0 +1,10 @@ +[gd_resource type="Resource" script_class="CurrencyCatalogue" format=3] + +[ext_resource type="Script" uid="uid://621tus0uvbrd" path="res://core/currency/currency_catalogue.gd" id="1_cat"] +[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/mana_stone_recipe.tres" id="2_mana_recipe"] +[ext_resource type="Resource" uid="uid://dliibkgb2mom0" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/cognite_recipe.tres" id="3_cognite_recipe"] + +[resource] +script = ExtResource("1_cat") +currencies = [ExtResource("2_mana_recipe"), ExtResource("3_cognite_recipe")] +metadata/_custom_type_script = "uid://catalogue_script" diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/cognite_cost_entry.tres b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/cognite_cost_entry.tres new file mode 100644 index 0000000..a4506cb --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/cognite_cost_entry.tres @@ -0,0 +1,10 @@ +[gd_resource type="Resource" script_class="CurrencyCostEntry" format=3] + +[ext_resource type="Script" uid="uid://ba8e403mb7hp0" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/currency_cost_entry.gd" id="1_cost"] +[ext_resource type="Resource" uid="uid://dpbndqxvsffa0" path="res://docs/gyms/tiny_sword/currencies/magic_gold.tres" id="2_magic_gold"] + +[resource] +script = ExtResource("1_cost") +currency = ExtResource("2_magic_gold") +amount = 25 +metadata/_custom_type_script = "res://docs/gyms/tiny_sword/buildings/alchemy_tower/currency_cost_entry.gd" diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/cognite_recipe.tres b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/cognite_recipe.tres new file mode 100644 index 0000000..82083d1 --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/cognite_recipe.tres @@ -0,0 +1,11 @@ +[gd_resource type="Resource" script_class="AlchemyCraftRecipe" format=3 uid="uid://dliibkgb2mom0"] + +[ext_resource type="Script" uid="uid://ddlnlpb0p750q" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_recipe.gd" id="1_recipe"] +[ext_resource type="Resource" uid="uid://t6du7gm2ywbi" path="res://docs/gyms/tiny_sword/currencies/cognite.tres" id="2_xltlj"] +[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/cognite_cost_entry.tres" id="3_cost"] + +[resource] +script = ExtResource("1_recipe") +id = &"cognite_recipe" +output_currency = ExtResource("2_xltlj") +cost_entries = [ExtResource("3_cost")] diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/currency_cost_entry.gd b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/currency_cost_entry.gd new file mode 100644 index 0000000..c5aedd5 --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/currency_cost_entry.gd @@ -0,0 +1,6 @@ +class_name CurrencyCostEntry +extends Resource + +## Entry for multi-currency cost in alchemy recipes +@export var currency: Currency +@export var amount: int = 1 diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/currency_cost_entry.gd.uid b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/currency_cost_entry.gd.uid new file mode 100644 index 0000000..7158d86 --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/currency_cost_entry.gd.uid @@ -0,0 +1 @@ +uid://ba8e403mb7hp0 diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/mana_stone_cost_entry.tres b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/mana_stone_cost_entry.tres new file mode 100644 index 0000000..6e7cc21 --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/mana_stone_cost_entry.tres @@ -0,0 +1,10 @@ +[gd_resource type="Resource" script_class="CurrencyCostEntry" format=3] + +[ext_resource type="Script" uid="uid://ba8e403mb7hp0" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/currency_cost_entry.gd" id="1_cost"] +[ext_resource type="Resource" uid="uid://dpbndqxvsffa0" path="res://docs/gyms/tiny_sword/currencies/magic_gold.tres" id="2_magic_gold"] + +[resource] +script = ExtResource("1_cost") +currency = ExtResource("2_magic_gold") +amount = 10 +metadata/_custom_type_script = "res://docs/gyms/tiny_sword/buildings/alchemy_tower/currency_cost_entry.gd" diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/mana_stone_recipe.tres b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/mana_stone_recipe.tres new file mode 100644 index 0000000..14f646f --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/mana_stone_recipe.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="AlchemyCraftRecipe" format=3] + +[ext_resource type="Script" uid="uid://ddlnlpb0p750q" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/alchemy_craft_recipe.gd" id="1_recipe"] +[ext_resource type="Resource" uid="uid://brctmnpmhjas6" path="res://docs/gyms/tiny_sword/currencies/mana_stone.tres" id="2_mana_stone"] +[ext_resource type="Resource" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/recipes/mana_stone_cost_entry.tres" id="3_cost"] + +[resource] +script = ExtResource("1_recipe") +id = &"mana_stone_recipe" +output_currency = ExtResource("2_mana_stone") +output_amount = 1 +cost_entries = [ExtResource("3_cost")] +metadata/_custom_type_script = "res://docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_craft_recipe.gd" diff --git a/docs/gyms/tiny_sword/buildings/alchemy_tower/test_panel.gd.uid b/docs/gyms/tiny_sword/buildings/alchemy_tower/test_panel.gd.uid new file mode 100644 index 0000000..77c0785 --- /dev/null +++ b/docs/gyms/tiny_sword/buildings/alchemy_tower/test_panel.gd.uid @@ -0,0 +1 @@ +uid://d5wkgk7kfrma diff --git a/docs/gyms/tiny_sword/currencies/cognite.tres b/docs/gyms/tiny_sword/currencies/cognite.tres new file mode 100644 index 0000000..c8d9cbd --- /dev/null +++ b/docs/gyms/tiny_sword/currencies/cognite.tres @@ -0,0 +1,11 @@ +[gd_resource type="Resource" script_class="Currency" format=3 uid="uid://t6du7gm2ywbi"] + +[ext_resource type="Texture2D" uid="uid://c1gnh8jgctrcx" path="res://sandbox/tiny_swords/UI Elements/UI Elements/Icons/Icon_07.png" id="1_axihf"] +[ext_resource type="Script" uid="uid://dtgqjf3bl7pm8" path="res://core/currency/currency.gd" id="2_fxby5"] + +[resource] +script = ExtResource("2_fxby5") +id = &"cognite" +display_name = "Cognite" +icon = ExtResource("1_axihf") +metadata/_custom_type_script = "uid://dtgqjf3bl7pm8" diff --git a/docs/gyms/tiny_sword/currencies/magic_gold.tres b/docs/gyms/tiny_sword/currencies/magic_gold.tres new file mode 100644 index 0000000..4565024 --- /dev/null +++ b/docs/gyms/tiny_sword/currencies/magic_gold.tres @@ -0,0 +1,11 @@ +[gd_resource type="Resource" script_class="Currency" format=3 uid="uid://dpbndqxvsffa0"] + +[ext_resource type="Script" uid="uid://dtgqjf3bl7pm8" path="res://core/currency/currency.gd" id="1_v6rd4"] +[ext_resource type="Texture2D" uid="uid://c1gnh8jgctrcx" path="res://sandbox/tiny_swords/UI Elements/UI Elements/Icons/Icon_07.png" id="1_wi1w3"] + +[resource] +script = ExtResource("1_v6rd4") +id = &"magic_gold" +display_name = "Magic Gold" +icon = ExtResource("1_wi1w3") +metadata/_custom_type_script = "uid://dtgqjf3bl7pm8" diff --git a/docs/gyms/tiny_sword/currencies/mana_stone.tres b/docs/gyms/tiny_sword/currencies/mana_stone.tres new file mode 100644 index 0000000..1e256c0 --- /dev/null +++ b/docs/gyms/tiny_sword/currencies/mana_stone.tres @@ -0,0 +1,11 @@ +[gd_resource type="Resource" script_class="Currency" format=3 uid="uid://brctmnpmhjas6"] + +[ext_resource type="Texture2D" uid="uid://c1gnh8jgctrcx" path="res://sandbox/tiny_swords/UI Elements/UI Elements/Icons/Icon_07.png" id="1_c7yxi"] +[ext_resource type="Script" uid="uid://dtgqjf3bl7pm8" path="res://core/currency/currency.gd" id="1_fahg0"] + +[resource] +script = ExtResource("1_fahg0") +id = &"mana_stone" +display_name = "Mana Stone" +icon = ExtResource("1_c7yxi") +metadata/_custom_type_script = "uid://dtgqjf3bl7pm8" diff --git a/docs/gyms/tiny_sword/currencies/ts_currency_catalogue.tres b/docs/gyms/tiny_sword/currencies/ts_currency_catalogue.tres index a5aa70a..ae7013c 100644 --- a/docs/gyms/tiny_sword/currencies/ts_currency_catalogue.tres +++ b/docs/gyms/tiny_sword/currencies/ts_currency_catalogue.tres @@ -7,8 +7,11 @@ [ext_resource type="Resource" uid="uid://bxg2au0ijp242" path="res://docs/gyms/tiny_sword/currencies/food.tres" id="4_c77gh"] [ext_resource type="Resource" uid="uid://bgsk8h4w80h45" path="res://docs/gyms/tiny_sword/currencies/wood.tres" id="5_gyp05"] [ext_resource type="Resource" uid="uid://bfrb0ayrljac2" path="res://docs/gyms/tiny_sword/currencies/ascension.tres" id="6_ascension"] +[ext_resource type="Resource" uid="uid://dpbndqxvsffa0" path="res://docs/gyms/tiny_sword/currencies/magic_gold.tres" id="7_vu05v"] +[ext_resource type="Resource" uid="uid://brctmnpmhjas6" path="res://docs/gyms/tiny_sword/currencies/mana_stone.tres" id="8_p3urk"] +[ext_resource type="Resource" uid="uid://t6du7gm2ywbi" path="res://docs/gyms/tiny_sword/currencies/cognite.tres" id="9_ejnoj"] [resource] script = ExtResource("2_hmju3") -currencies = Array[ExtResource("1_501l6")]([ExtResource("2_ucsji"), ExtResource("3_7hx6u"), ExtResource("4_c77gh"), ExtResource("5_gyp05"), ExtResource("6_ascension")]) +currencies = Array[ExtResource("1_501l6")]([ExtResource("2_ucsji"), ExtResource("3_7hx6u"), ExtResource("4_c77gh"), ExtResource("5_gyp05"), ExtResource("6_ascension"), ExtResource("7_vu05v"), ExtResource("8_p3urk"), ExtResource("9_ejnoj")]) metadata/_custom_type_script = "uid://621tus0uvbrd" diff --git a/docs/gyms/tiny_sword/tiny_sword.tscn b/docs/gyms/tiny_sword/tiny_sword.tscn index 503f8c0..500cbb1 100644 --- a/docs/gyms/tiny_sword/tiny_sword.tscn +++ b/docs/gyms/tiny_sword/tiny_sword.tscn @@ -19,7 +19,10 @@ [ext_resource type="Resource" uid="uid://bgsk8h4w80h45" path="res://docs/gyms/tiny_sword/currencies/wood.tres" id="12_l6a68"] [ext_resource type="PackedScene" uid="uid://bf8lqbexvnx6e" path="res://docs/gyms/tiny_sword/buildings/monastery/monastery.tscn" id="13_no27p"] [ext_resource type="PackedScene" uid="uid://rejxvjwybkll" path="res://sandbox/tiny_swords/Terrain/Resources/Wood/Trees/tree_1.tscn" id="14_0cs5o"] +[ext_resource type="PackedScene" uid="uid://bp5ng4vu4ot4a" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower.tscn" id="14_hum8s"] [ext_resource type="Resource" uid="uid://bfrb0ayrljac2" path="res://docs/gyms/tiny_sword/currencies/ascension.tres" id="15_ascension"] +[ext_resource type="Resource" uid="uid://dpbndqxvsffa0" path="res://docs/gyms/tiny_sword/currencies/magic_gold.tres" id="20_no27p"] +[ext_resource type="Resource" uid="uid://brctmnpmhjas6" path="res://docs/gyms/tiny_sword/currencies/mana_stone.tres" id="22_rbyxa"] [node name="TinySwords" type="Node" unique_id=498237642] @@ -58,18 +61,6 @@ position = Vector2(1568, 656) [node name="Tree6" parent="LevelGameState/World/ForestProps" unique_id=894701042 instance=ExtResource("14_0cs5o")] position = Vector2(1665, 650) -[node name="Tree7" parent="LevelGameState/World/ForestProps" unique_id=1661458508 instance=ExtResource("14_0cs5o")] -position = Vector2(1362, 792) - -[node name="Tree8" parent="LevelGameState/World/ForestProps" unique_id=2029836975 instance=ExtResource("14_0cs5o")] -position = Vector2(1452, 790) - -[node name="Tree9" parent="LevelGameState/World/ForestProps" unique_id=1580665442 instance=ExtResource("14_0cs5o")] -position = Vector2(1557, 793) - -[node name="Tree10" parent="LevelGameState/World/ForestProps" unique_id=1295721315 instance=ExtResource("14_0cs5o")] -position = Vector2(1644, 822) - [node name="GoldMine" parent="LevelGameState/World" unique_id=341660167 instance=ExtResource("2_2j2oc")] position = Vector2(274, 429) @@ -85,6 +76,9 @@ position = Vector2(825, 915) [node name="Monastery" parent="LevelGameState/World" unique_id=1545930496 instance=ExtResource("13_no27p")] position = Vector2(105, 920) +[node name="AlchemyTower" parent="LevelGameState/World" unique_id=51852160 instance=ExtResource("14_hum8s")] +position = Vector2(1239, 775) + [node name="UI" type="Control" parent="LevelGameState" unique_id=1299828389] layout_mode = 3 anchors_preset = 0 @@ -130,6 +124,23 @@ offset_bottom = 156.0 currency = ExtResource("15_ascension") game_state = NodePath("../..") +[node name="MagicGoldTile" parent="LevelGameState/UI" unique_id=707573446 node_paths=PackedStringArray("game_state") instance=ExtResource("7_0cs5o")] +layout_mode = 0 +offset_top = 152.0 +offset_right = 203.0 +offset_bottom = 183.0 +currency = ExtResource("20_no27p") +game_state = NodePath("../..") + +[node name="ManaStoneTile" parent="LevelGameState/UI" unique_id=1333819600 node_paths=PackedStringArray("game_state") instance=ExtResource("7_0cs5o")] +layout_mode = 0 +offset_left = 1.0 +offset_top = 178.0 +offset_right = 204.0 +offset_bottom = 209.0 +currency = ExtResource("22_rbyxa") +game_state = NodePath("../..") + [node name="GoalsDebugUI" parent="LevelGameState/UI" unique_id=1494700185 instance=ExtResource("10_qifrv")] layout_mode = 1 offset_left = 1275.0