feat: add cube upgrade

This commit is contained in:
Varylios 2025-09-07 19:48:58 +02:00
parent e6e1221ba5
commit 3452c943a5
22 changed files with 240 additions and 53 deletions

View file

@ -2,8 +2,13 @@
extends Node
@warning_ignore_start("unused_signal")
## [b]Emitter[/b] : [method GuiButton][br]
## [b]Subscriber[/b] : [method TowerManager]
## [b]Emitter[/b] : [param gui.gd], [br]
## [b]Subscriber[/b] : [TowerManager]
signal cube_selected
## [b]Emitter[/b] : [GuiButton][br]
## [b]Subscriber[/b] : [TowerManager]
signal tower_selected(towerType : Tower.TYPE)
@ -32,6 +37,11 @@ signal projectile_shooted(projectile: Projectile, startPosition: Vector3)
signal player_has_won
## [b]Emitter[/b] : [WorldManager][br]
## [b]Subscriber[/b] : [Game]
signal wave_finished
## [b]Emitter[/b] : [WorldManager][br]
## [b]Subscriber[/b] : gui.gd
signal wave_has_change(waveNumber : int, timeRemaining : float)

View file

@ -9,15 +9,21 @@ signal loose
signal allowed_tower_has_change
var upgrades : Array[CubeUpgrade] = load("res://Upgrades/cube_upgrades.tres").upgrades
var towerPackedScenes : Dictionary
var enmies : Dictionary
var towers : Dictionary
var max_health : int = 50
var max_health : int = 50 :
set(value):
var diff : int = value - max_health
max_health = value
health += diff
var health : int = max_health :
set(value):
health = value
health = clampi(value, 0, max_health)
cube_integrity_changed.emit()
if health <= 0:
death()
@ -29,9 +35,17 @@ var money : int = 0:
money_changed.emit()
var tier : int = 0
var maxTier : int = 3
var wave_health_regen : int = 0
var wave_money : int = 0
var energy_boost : int = 0
func _ready() -> void:
process_mode = Node.PROCESS_MODE_ALWAYS
EventBus.player_has_won.connect(win)
EventBus.wave_finished.connect(getWaveEndIncom)
Helper.preloadSceneInGlobal(towerPackedScenes, Helper.RESOURCE_TYPE.TOWER)
#Helper.preloadSceneInGlobal(towerPackedScenes, Helper.RESOURCE_TYPE.ENEMY)
@ -44,6 +58,11 @@ func _input(event: InputEvent) -> void:
get_tree().paused = not get_tree().paused
func getWaveEndIncom() -> void:
health += wave_health_regen
money += wave_money
func initTowers(allowedTowers : Array[Tower.TYPE]) -> void:
towers.clear()
for towerType in allowedTowers:

View file

@ -114,6 +114,7 @@ troops = Array[ExtResource("3_ub8wd")]([SubResource("Resource_7vcps"), SubResour
script = ExtResource("1_ftl6b")
auto_start = false
auto_launch_wave = false
tier_max = 1
allowedTowers = Array[int]([1, 2, 3])
laneCount = 1
startingMoney = 110

View file

@ -10,6 +10,8 @@ var shouldMove : bool = true
func _ready() -> void:
curve.bake()
rotation.x = deg_to_rad(curve.min_value)
position.y = curve.max_domain
func _process(_delta: float) -> void:

View file

@ -5,6 +5,7 @@ class_name Level
@export var auto_start : bool = false
@export var auto_launch_wave : bool = false
@export var tier_max : int = 1
@export var allowedTowers : Array[Tower.TYPE]
@export var laneCount : int = 1
@export var startingMoney : int = 0

View file

@ -40,6 +40,7 @@ func _process(_delta: float) -> void:
state = STATE.FIGHT
STATE.FIGHT when enemiesAlive == 0:
$SFX/SFXWinner.play()
EventBus.wave_finished.emit()
state = STATE.WAVE_END
STATE.WAVE_END when wave == level.waves.size():
EventBus.player_has_won.emit()
@ -127,6 +128,7 @@ func addMap(mapScene : PackedScene) -> void:
level = map.level
paths = map.paths.get_children()
Game.money = level.startingMoney
Game.maxTier = level.tier_max
Game.initTowers(level.allowedTowers)
state = STATE.SPAWN if level.auto_start else STATE.IDLE

View file

@ -28,6 +28,7 @@ text = "Max energy"
baseCost = 20
value = 10.0
maxLevel = 3
tierLock = Array[int]([1, 3, 4, 5])
upgradeDirection = 1
upgradeScaleType = 0
costScaleType = 0
@ -42,6 +43,7 @@ text = "Energy regen"
baseCost = 50
value = 2.0
maxLevel = 3
tierLock = Array[int]([1, 3, 4, 5])
upgradeDirection = 1
upgradeScaleType = 0
costScaleType = 0
@ -56,6 +58,7 @@ text = "Damage"
baseCost = 50
value = 2.0
maxLevel = 3
tierLock = Array[int]([1, 3, 4, 5])
upgradeDirection = 1
upgradeScaleType = 0
costScaleType = 0
@ -69,6 +72,7 @@ text = "Cooldown"
baseCost = 2000
value = 0.2
maxLevel = 2
tierLock = Array[int]([1, 3, 4, 5])
upgradeDirection = 1
upgradeScaleType = 0
costScaleType = 0

View file

@ -29,8 +29,10 @@ var projectileScene : PackedScene = preload("res://Towers/Projectiles/projectile
@export_group("Energy")
@export var max_energy : float = 100.0 :
set(value):
var diff : int = value - max_energy
max_energy = value
if not Engine.is_editor_hint() && is_node_ready():
energy += diff
energyBar.max_value = max_energy
changed.emit()
@export var energy_regen : float = 10.0
@ -70,7 +72,7 @@ func _ready() -> void:
energy = max_energy
# WARNING : Prevent .tscn file to be modified by the load of the scene in editor
if not Engine.is_editor_hint():
energyRecoveryCooldown.timeout.connect(func(): energy += energy_regen)
energyRecoveryCooldown.timeout.connect(func(): energy += energy_regen + Game.energy_boost)
collision_layer = 0
collision_mask = 0
$PriceTag.text = str(price) + ""

View file

@ -52,7 +52,7 @@ func handle_player_controls() -> Node3D:
#If the player has the mouse on the GUI, player can't place tower
if is_on_gui:
return
var space_state : PhysicsDirectSpaceState3D = get_world_3d().direct_space_state
var mouse_pos : Vector2 = get_viewport().get_mouse_position()

View file

@ -3,12 +3,26 @@ extends HBoxContainer
const upgradeBtnScene : PackedScene = preload("res://UI/upgrade_button.tscn")
var tower : Tower
func _ready() -> void:
EventBus.tower_selected.connect(onTowerSelected)
EventBus.cube_selected.connect(onCubeSelected)
func onCubeSelected() -> void:
if tower:
EventBus.tower_selected.emit(Tower.TYPE.NONE)
tower = null
visible = true
$PanelContainer2.visible = false
%UpgradeContainer.visible = true
%UpgradeContainer.get_children().map(func(btn): btn.queue_free())
for upgrade in Game.upgrades:
var btn : UpgradeButton = upgradeBtnScene.instantiate()
%UpgradeContainer.add_child(btn)
btn.setUpgrade(upgrade)
func onTowerSelected(towerType : Tower.TYPE) -> void:
@ -17,10 +31,11 @@ func onTowerSelected(towerType : Tower.TYPE) -> void:
tower.changed.disconnect(onTowerChange)
if towerType == Tower.TYPE.NONE:
visible = false
tower = null
visible = false
return
$PanelContainer2.visible = true
tower = Game.towers.get(towerType)
tower.energy_changed.connect(onEnergyChange)
tower.changed.connect(onTowerChange)
@ -52,4 +67,5 @@ func createTowerUpgradeButton() -> void:
for upgrade in tower.upgrades:
var btn : UpgradeButton = upgradeBtnScene.instantiate()
%UpgradeContainer.add_child(btn)
btn.setData(tower, upgrade)
btn.setUpgrade(upgrade)
btn.setTower(tower)

View file

@ -3,7 +3,7 @@ class_name UpgradeButton
var tower: Tower
var upgrade: TowerUpgrade
var upgrade: Upgrade
@onready var upgradeBtn : Button = $UpgradeButton
@ -14,12 +14,16 @@ func _ready() -> void:
upgradeBtn.pressed.connect(upgradeTower)
func setData(_tower: Tower, _upgrade: TowerUpgrade) -> void:
tower = _tower
func setUpgrade(_upgrade: Upgrade) -> void:
upgrade = _upgrade
updateVisuals()
func setTower(_tower: Tower) -> void:
tower = _tower
updateVisuals()
func upgradeTower() -> void:
if upgrade.upgrade(tower):
updateVisuals()

View file

@ -7,25 +7,31 @@ const guiButton : PackedScene = preload("res://UI/gui_button.tscn")
@onready var buttonContainer = %ButtonContainer
@onready var cubeIntegrity = %CubeIntegrity
@onready var cubeBtn = %CubeBtn
var waveCooldown : float
func _ready() -> void:
EventBus.team_in_rest_changed.connect(func(count): %LabelTowerInCube.text = "Zzz : %d" % count)
EventBus.team_in_action_changed.connect(func(count): %LabelTowerOnTerrain.text = " In action : %d" % count)
EventBus.wave_has_change.connect(onWaveChange)
EventBus.tower_selected.connect(
func(_type): cubeBtn.set_pressed_no_signal(cubeBtn.button_pressed && _type == Tower.TYPE.NONE))
Game.allowed_tower_has_change.connect(addTowerButtonNodes)
Game.cube_integrity_changed.connect(func(): cubeIntegrity.value = Game.health)
cubeIntegrity.max_value = Game.max_health
cubeIntegrity.value = Game.health
Game.money_changed.connect(func(): %LabelMoney.text = "%d" % Game.money)
EventBus.wave_has_change.connect(onWaveChange)
%NextWaveBtn.pressed.connect(EventBus.lauch_next_wave.emit)
$WaveCooldown/Timer.timeout.connect(updateWaveCooldownLabel)
%QuitLevelBtn.pressed.connect(Helper.showConfirmPopup.bind("Quit level ?", self, Game.quitLevel))
%QuitGameBtn.pressed.connect(Helper.showConfirmPopup.bind("Quit game ?", self, Game.quitGame))
$TowerInfoPanel.visible = false
$TowerInfoPanel.mouse_entered.connect(onMouseEnteredGui)
$TowerInfoPanel.mouse_exited.connect(onMouseExitedGui)
cubeBtn.toggled.connect(onCubeBtnPressed)
$InfoPanel.visible = false
$InfoPanel.mouse_entered.connect(onMouseEnteredGui)
$InfoPanel.mouse_exited.connect(onMouseExitedGui)
$TowerButtonPanel.mouse_entered.connect(onMouseEnteredGui)
$TowerButtonPanel.mouse_exited.connect(onMouseExitedGui)
@ -35,8 +41,12 @@ func _ready() -> void:
Game.initTowers(allowedTowers)
func _on_button_cube_pressed() -> void:
pass # Replace with function body.
func onCubeBtnPressed(state : bool) -> void:
if state:
EventBus.cube_selected.emit()
else:
EventBus.tower_selected.emit(Tower.TYPE.NONE)
func onWaveChange(waveNumber : int, timeRemaining : float) -> void:

View file

@ -7,7 +7,7 @@
[ext_resource type="PackedScene" uid="uid://dqb5o8w7u50hc" path="res://UI/gui_button.tscn" id="7_parkk"]
[ext_resource type="Texture2D" uid="uid://dfnf26suc8yb6" path="res://Assets/Icones/sideswipe.svg" id="8_ay13l"]
[ext_resource type="Texture2D" uid="uid://dootdihg7gkoj" path="res://Assets/Icones/exit-door.svg" id="8_decjp"]
[ext_resource type="Script" uid="uid://s4t3oa4v87xe" path="res://UI/TowerPanel.gd" id="9_3lugd"]
[ext_resource type="Script" uid="uid://s4t3oa4v87xe" path="res://UI/InfoPanel.gd" id="9_3lugd"]
[ext_resource type="Texture2D" uid="uid://b4m5ejfdrm8s0" path="res://Assets/Icones/power-button.svg" id="9_reygo"]
[ext_resource type="Texture2D" uid="uid://uptdcefxlv4c" path="res://Assets/Icones/ppdf_bio_image_placeholder_2.png" id="10_parkk"]
@ -153,6 +153,7 @@ size_flags_vertical = 0
columns = 4
[node name="CubeBtn" parent="TowerButtonPanel/ControlPanelBase/MarginContainer/ButtonContainer" instance=ExtResource("7_parkk")]
unique_name_in_owner = true
layout_mode = 2
texture = ExtResource("7_fffne")
@ -171,7 +172,7 @@ unique_name_in_owner = true
layout_mode = 2
texture = ExtResource("8_ay13l")
[node name="TowerInfoPanel" type="HBoxContainer" parent="."]
[node name="InfoPanel" type="HBoxContainer" parent="."]
visible = false
layout_mode = 1
anchors_preset = 2
@ -183,30 +184,30 @@ grow_vertical = 0
theme_override_constants/separation = 0
script = ExtResource("9_3lugd")
[node name="InfoPanel" type="PanelContainer" parent="TowerInfoPanel"]
[node name="PanelContainer2" type="PanelContainer" parent="InfoPanel"]
custom_minimum_size = Vector2(200, 0)
layout_mode = 2
mouse_filter = 1
theme_override_styles/panel = SubResource("StyleBoxFlat_h4fn5")
[node name="MarginContainer" type="MarginContainer" parent="TowerInfoPanel/InfoPanel"]
[node name="MarginContainer" type="MarginContainer" parent="InfoPanel/PanelContainer2"]
layout_mode = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
[node name="VBoxContainer" type="VBoxContainer" parent="TowerInfoPanel/InfoPanel/MarginContainer"]
[node name="VBoxContainer" type="VBoxContainer" parent="InfoPanel/PanelContainer2/MarginContainer"]
layout_mode = 2
[node name="HBoxContainer" type="HBoxContainer" parent="TowerInfoPanel/InfoPanel/MarginContainer/VBoxContainer"]
[node name="HBoxContainer" type="HBoxContainer" parent="InfoPanel/PanelContainer2/MarginContainer/VBoxContainer"]
layout_mode = 2
theme_override_constants/separation = 20
[node name="VBoxContainer" type="VBoxContainer" parent="TowerInfoPanel/InfoPanel/MarginContainer/VBoxContainer/HBoxContainer"]
[node name="VBoxContainer" type="VBoxContainer" parent="InfoPanel/PanelContainer2/MarginContainer/VBoxContainer/HBoxContainer"]
layout_mode = 2
[node name="TowerName" type="Label" parent="TowerInfoPanel/InfoPanel/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer"]
[node name="TowerName" type="Label" parent="InfoPanel/PanelContainer2/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 1
@ -217,7 +218,7 @@ text = "Name"
horizontal_alignment = 2
vertical_alignment = 2
[node name="TowerEnergy" type="Label" parent="TowerInfoPanel/InfoPanel/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer"]
[node name="TowerEnergy" type="Label" parent="InfoPanel/PanelContainer2/MarginContainer/VBoxContainer/HBoxContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "Le nombre de héros en action sur le terrain !"
@ -226,14 +227,14 @@ theme_override_colors/font_color = Color(0.2, 0.2, 0.2, 1)
text = "0/0"
horizontal_alignment = 2
[node name="TowerIcon" type="TextureRect" parent="TowerInfoPanel/InfoPanel/MarginContainer/VBoxContainer/HBoxContainer"]
[node name="TowerIcon" type="TextureRect" parent="InfoPanel/PanelContainer2/MarginContainer/VBoxContainer/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
theme = ExtResource("5_wpcnu")
texture = ExtResource("10_parkk")
expand_mode = 3
[node name="TowerDamage" type="Label" parent="TowerInfoPanel/InfoPanel/MarginContainer/VBoxContainer"]
[node name="TowerDamage" type="Label" parent="InfoPanel/PanelContainer2/MarginContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "Le nombre de héros disponible dans le cube !"
@ -242,7 +243,7 @@ theme_override_colors/font_color = Color(0.2, 0.2, 0.2, 1)
text = "0"
horizontal_alignment = 2
[node name="TowerCooldown" type="Label" parent="TowerInfoPanel/InfoPanel/MarginContainer/VBoxContainer"]
[node name="TowerCooldown" type="Label" parent="InfoPanel/PanelContainer2/MarginContainer/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "Le nombre de héros en action sur le terrain !"
@ -251,7 +252,7 @@ theme_override_colors/font_color = Color(0.2, 0.2, 0.2, 1)
text = "0"
horizontal_alignment = 2
[node name="TowerBio" type="Label" parent="TowerInfoPanel/InfoPanel/MarginContainer/VBoxContainer"]
[node name="TowerBio" type="Label" parent="InfoPanel/PanelContainer2/MarginContainer/VBoxContainer"]
unique_name_in_owner = true
visible = false
layout_mode = 2
@ -261,22 +262,20 @@ mouse_filter = 1
theme_override_colors/font_color = Color(0.2, 0.2, 0.2, 1)
horizontal_alignment = 2
[node name="PanelContainer" type="PanelContainer" parent="TowerInfoPanel"]
[node name="PanelContainer" type="PanelContainer" parent="InfoPanel"]
layout_mode = 2
mouse_filter = 1
theme_override_styles/panel = SubResource("StyleBoxFlat_3lugd")
[node name="MarginContainer" type="MarginContainer" parent="TowerInfoPanel/PanelContainer"]
[node name="MarginContainer" type="MarginContainer" parent="InfoPanel/PanelContainer"]
layout_mode = 2
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
[node name="UpgradeContainer" type="GridContainer" parent="TowerInfoPanel/PanelContainer/MarginContainer"]
[node name="UpgradeContainer" type="GridContainer" parent="InfoPanel/PanelContainer/MarginContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
size_flags_vertical = 0
[connection signal="pressed" from="TowerButtonPanel/ControlPanelBase/MarginContainer/ButtonContainer/CubeBtn" to="." method="_on_button_cube_pressed"]

View file

@ -5,13 +5,10 @@ extends Control
var levels : Array[String]
func _on_quit_button_pressed() -> void:
get_tree().quit()
func _ready() -> void:
%LevelContainer.get_children().map(%LevelContainer.remove_child)
levels = Helper.getPackedScenesPaths(Helper.RESOURCE_TYPE.LEVEL)
%QuitGame.pressed.connect(Helper.showConfirmPopup.bind("Quit game ?", self, Game.quitGame))
for i in levels.size():
var levelButton : Button = Button.new()
levelButton.text = "Level " + str(i + 1)

View file

@ -211,9 +211,8 @@ unique_name_in_owner = true
layout_mode = 2
columns = 6
[node name="QuitButton" type="Button" parent="Middleground/VBoxContainer"]
[node name="QuitGame" type="Button" parent="Middleground/VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
theme = ExtResource("6_rcgl7")
text = "Quit"
[connection signal="pressed" from="Middleground/VBoxContainer/QuitButton" to="." method="_on_quit_button_pressed"]

View file

@ -1,13 +1,34 @@
extends Node
extends Upgrade
class_name CubeUpgrade
enum TYPE {
HEALTH,
HEALTH_REGEN
TIER,
MAX_HEALTH,
WAVE_HEALTH_REGEN,
WAVE_MONEY,
BOOST_REGEN_ENERGY,
}
@export var type : TYPE
func upgrade() -> void:
pass
func canUpgrade() -> bool:
return super.canUpgrade() && (type != TYPE.TIER || Game.maxTier < Game.tier)
func upgrade(_subject = null) -> bool:
if not canUpgrade():
return false
match type:
TYPE.TIER: upgradeProperty(Game, "tier")
TYPE.MAX_HEALTH: upgradeProperty(Game, "max_health")
TYPE.WAVE_HEALTH_REGEN: upgradeProperty(Game, "wave_health_regen")
TYPE.WAVE_MONEY: upgradeProperty(Game, "wave_money")
TYPE.BOOST_REGEN_ENERGY: upgradeProperty(Game, "energy_boost")
upgradeUpgrade()
#Game.changed.emit()
return true

View file

@ -0,0 +1,7 @@
@tool
extends EnhancedResource
class_name CubeUpgradeList
@export var upgrades : Array[CubeUpgrade] :
set(value):
upgrades = arrayValueChanged(value, CubeUpgrade.new)

View file

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

View file

@ -15,7 +15,7 @@ enum TYPE {
@export var type : TYPE
func upgrade(tower: Tower) -> bool:
func upgrade(tower: Tower = null) -> bool:
if not canUpgrade():
return false

View file

@ -13,7 +13,10 @@ enum UPGRADE_DIRECTION { INCREASE = 1, DECREASE = -1 }
baseCost = value
cost = value
@export_range(0.001, 999, 0.001, "hide_slider") var value : float
@export_group("Restrictions")
@export_range(-1, 100, 1, "hide_slider") var maxLevel : int = -1 ##[param -1] for infinite leveling
@export var tierLock : Array[int]
@export_group("Upgrade Scaling")
@export var upgradeDirection : UPGRADE_DIRECTION = UPGRADE_DIRECTION.INCREASE
@ -25,7 +28,11 @@ enum UPGRADE_DIRECTION { INCREASE = 1, DECREASE = -1 }
var cost : int
var level : int = 0
var isLevelMax : bool :
get(): return maxLevel == level
get(): return maxLevel == level && (tierLock.is_empty() || level == tierLock[Game.maxTier])
func upgrade(_subject = null) -> bool:
return false
func upgradeProperty(subject: Variant, property: String) -> void:
@ -39,12 +46,12 @@ func upgradeUpgrade() -> void:
func canUpgrade():
return not isLevelMax && Game.money >= cost
return not isLevelMax && Game.money >= cost && (tierLock.is_empty() || tierLock[Game.tier] > level)
func getNextValue(oldValue, baseValue, scaleType : SCALE_TYPE):
match scaleType:
SCALE_TYPE.LINEAR: return oldValue + value
SCALE_TYPE.LINEAR: return oldValue + baseValue
_:
push_warning("Upgrade scale type not defined !")
return oldValue

View file

@ -0,0 +1,85 @@
[gd_resource type="Resource" script_class="CubeUpgradeList" load_steps=9 format=3 uid="uid://py454tq2ghgx"]
[ext_resource type="Script" uid="uid://dh4khyteo1mlt" path="res://Upgrades/CubeUpgradeList.gd" id="1_deiuh"]
[ext_resource type="Script" uid="uid://djhstur8ci655" path="res://Upgrades/CubeUpgrade.gd" id="2_lmxhg"]
[ext_resource type="Texture2D" uid="uid://dqvou7t7o1t5d" path="res://Assets/Icones/medal2.png" id="3_lmxhg"]
[sub_resource type="Resource" id="Resource_u6dkh"]
script = ExtResource("2_lmxhg")
type = 0
icon = ExtResource("3_lmxhg")
text = "Tier"
baseCost = 50
value = 1.0
maxLevel = 3
tierLock = Array[int]([])
upgradeDirection = 1
upgradeScaleType = 0
costScaleType = 0
costModificator = 50.0
metadata/_custom_type_script = "uid://djhstur8ci655"
[sub_resource type="Resource" id="Resource_wtnco"]
script = ExtResource("2_lmxhg")
type = 1
icon = ExtResource("3_lmxhg")
text = "Max Health"
baseCost = 100
value = 50.0
maxLevel = 5
tierLock = Array[int]([1, 3, 4, 5])
upgradeDirection = 1
upgradeScaleType = 0
costScaleType = 0
costModificator = 100.0
metadata/_custom_type_script = "uid://djhstur8ci655"
[sub_resource type="Resource" id="Resource_651hy"]
script = ExtResource("2_lmxhg")
type = 2
icon = ExtResource("3_lmxhg")
text = "Wave Health Regen"
baseCost = 200
value = 20.0
maxLevel = 3
tierLock = Array[int]([0, 1, 2, 3])
upgradeDirection = 1
upgradeScaleType = 0
costScaleType = 0
costModificator = 100.0
metadata/_custom_type_script = "uid://djhstur8ci655"
[sub_resource type="Resource" id="Resource_mimkt"]
script = ExtResource("2_lmxhg")
type = 3
icon = ExtResource("3_lmxhg")
text = "Wave Money"
baseCost = 300
value = 100.0
maxLevel = 3
tierLock = Array[int]([0, 0, 2, 3])
upgradeDirection = 1
upgradeScaleType = 0
costScaleType = 0
costModificator = 200.0
metadata/_custom_type_script = "uid://djhstur8ci655"
[sub_resource type="Resource" id="Resource_2b4ll"]
script = ExtResource("2_lmxhg")
type = 4
icon = ExtResource("3_lmxhg")
text = "Boost Energy Regen"
baseCost = 150
value = 5.0
maxLevel = 2
tierLock = Array[int]([])
upgradeDirection = 1
upgradeScaleType = 0
costScaleType = 0
costModificator = 0.0
metadata/_custom_type_script = "uid://djhstur8ci655"
[resource]
script = ExtResource("1_deiuh")
upgrades = Array[ExtResource("2_lmxhg")]([SubResource("Resource_u6dkh"), SubResource("Resource_wtnco"), SubResource("Resource_651hy"), SubResource("Resource_mimkt"), SubResource("Resource_2b4ll")])
metadata/_custom_type_script = "uid://dh4khyteo1mlt"