summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorbd <bdunahu@operationnull.com>2025-05-24 18:50:01 -0400
committerbd <bdunahu@operationnull.com>2025-05-24 18:50:01 -0400
commit2190d18d8d58f867927126829e7c0d7ef6fac372 (patch)
tree1dd88af4374a9105ef2c723c43a68a0fd67e390f /scripts
parentc38a303aad3c3c0d8114524e664da6ad721e21c4 (diff)
Add UI panel which displays actions/upgrades
Diffstat (limited to 'scripts')
-rw-r--r--scripts/base_defender.gd13
-rw-r--r--scripts/game_data.gd8
-rw-r--r--scripts/game_stats_config.gd62
-rw-r--r--scripts/life.gd11
-rw-r--r--scripts/life.gd.uid1
-rw-r--r--scripts/morale.gd11
-rw-r--r--scripts/morale.gd.uid1
-rw-r--r--scripts/player.gd37
-rw-r--r--scripts/tower_manager.gd67
-rw-r--r--scripts/ui.gd34
-rw-r--r--scripts/ui.gd.uid1
-rw-r--r--scripts/warlock.gd2
-rw-r--r--scripts/wyvern.gd2
13 files changed, 146 insertions, 104 deletions
diff --git a/scripts/base_defender.gd b/scripts/base_defender.gd
index 06ac34f..088f235 100644
--- a/scripts/base_defender.gd
+++ b/scripts/base_defender.gd
@@ -12,9 +12,9 @@ var target : CharacterBody2D
var _idle_texture : Texture
var _attack_texture : Texture
-func set_tower_stats(tower_name : String):
- tower_key = tower_name
- tower_data = game_stats_config.defenders[tower_key]
+func set_tower_stats(tower_index : int):
+ tower_data = game_stats_config.defenders[tower_index].duplicate()
+ tower_key = tower_data["desc"]
func reset_tower_range():
$Tower/CollisionShape2D.shape.radius = tower_data["range"]
@@ -24,9 +24,6 @@ func reset_tower_sprite():
_attack_texture = util.get_tile_texture(tower_data["sprite_attacking"])
_idle_state()
-func get_tower_key() -> String:
- return tower_key
-
func select_target() -> void:
var targets : Array = _find_targets()
@@ -73,7 +70,9 @@ func _idle_state():
func apply_upgrade(effects: Dictionary):
for key in effects.keys():
if key in tower_data:
- tower_data[key] += effects[key]
+ tower_data[key] = effects[key]
+ reset_tower_range()
+ reset_tower_sprite()
# extending classes should override below
func _on_fire_timer_timeout() -> void:
diff --git a/scripts/game_data.gd b/scripts/game_data.gd
index d2d1de7..0ed0f61 100644
--- a/scripts/game_data.gd
+++ b/scripts/game_data.gd
@@ -13,22 +13,22 @@ func get_life() -> int:
func add_life(amount: int):
_life += amount
- emit_signal("life_changed", _life)
+ emit_signal("life_changed")
func subtract_life(amount: int):
_life -= amount
- emit_signal("life_changed", _life)
+ emit_signal("life_changed")
func get_morale() -> int:
return _morale
func add_morale(amount: int):
_morale += amount
- emit_signal("morale_changed", _morale)
+ emit_signal("morale_changed")
func subtract_morale(amount: int):
_morale -= amount
- emit_signal("morale_changed", _morale)
+ emit_signal("morale_changed")
func get_current_wave() -> int:
return _current_wave
diff --git a/scripts/game_stats_config.gd b/scripts/game_stats_config.gd
index 873312d..89d265c 100644
--- a/scripts/game_stats_config.gd
+++ b/scripts/game_stats_config.gd
@@ -2,7 +2,7 @@ extends Resource
class_name GameStatsConfig
# game stats
-@export var starting_life : int = 15
+@export var starting_life : int = 20
@export var starting_morale : int = 10
# waves
@@ -13,39 +13,49 @@ class_name GameStatsConfig
]
# defenders
-@export var defenders : Dictionary[String, Dictionary] = {
- "warlock": {
+@export var defenders : Array[Dictionary] = [
+ {
+ "desc": "Warlock",
"damage" : 4.0,
"fire_rate" : 1.2,
"range": 75.0,
"sprite_panel": Vector2i(32, 4),
- "sprite_attacking": Vector2i(31, 2),
- "sprite_idle": Vector2i(31, 1),
+ "sprite_attacking": Vector2i(28, 1),
+ "sprite_idle": Vector2i(29, 1),
"cost": 10,
"projectile_speed" : 100,
- "upgrades": {
- "tower_action_one": {
- "cost": 7,
+ "upgrades": [
+ {
+ "desc": "Phoenix (DMG)",
+ "sprite_panel": Vector2i(32, 5),
+ "cost": 12,
"effects": {
- "damage": 3.0,
- }
+ "damage": 9.0,
+ },
},
- "tower_action_two": {
+ {
+ "desc": "Sparrow (DUP)",
+ "sprite_panel": Vector2i(35, 5),
"cost": 7,
"effects": {
- "fire_rate": 0.5
+ "fire_rate": 1.7
}
},
- "tower_action_three": {
- "cost": 30,
+ {
+ "desc": "Falcon (RNGE)",
+ "sprite_panel": Vector2i(34, 4),
+ "cost": 20,
"effects": {
- "projectile_speed": 300.0,
- "range": 200.0
+ "projectile_speed": 200.0,
+ "range": 275.0,
+ "sprite_attacking": Vector2i(31, 2),
+ "sprite_idle": Vector2i(31, 1),
}
},
- },
+ ],
},
- "wyvern": {
+ {
+ "desc": "Wyvern",
"damage" : 1.0,
"fire_rate" : 1.0,
"range": 35.0,
@@ -54,27 +64,33 @@ class_name GameStatsConfig
"sprite_idle": Vector2i(24, 10),
"cost": 15,
"damage_tick_rate": 0.25,
+ # TODO
+ "upgrades": [],
},
# TODO
- "werewolf": {
+ {
+ "desc": "Werewolf",
"damage": 1.0,
"fire_rate": 1.0,
"range": 1.0,
"sprite_panel": Vector2i(26, 11),
"sprite_attacking": Vector2i(26, 11),
"sprite_idle": Vector2i(26, 11),
- "cost": 1
+ "cost": 1,
+ "upgrades": [],
},
- "wellspring": {
+ {
+ "desc": "Wellspring",
"damage": 1.0,
"fire_rate": 1.0,
"range": 1.0,
"sprite_panel": Vector2i(38, 11),
"sprite_attacking": Vector2i(38, 11),
"sprite_idle": Vector2i(38, 11),
- "cost": 1
+ "cost": 1,
+ "upgrades": [],
}
-}
+]
# crawlers
@export var crawlers : Dictionary[String, Dictionary] = {
diff --git a/scripts/life.gd b/scripts/life.gd
deleted file mode 100644
index b185cda..0000000
--- a/scripts/life.gd
+++ /dev/null
@@ -1,11 +0,0 @@
-extends Label
-
-func _ready():
- GameData.connect("life_changed", Callable(self, "_on_life_changed"))
- update_label(GameData.get_life())
-
-func _on_life_changed(new_life: int) -> void:
- update_label(new_life)
-
-func update_label(new_life: int) -> void:
- text = "Life:" + str(new_life)
diff --git a/scripts/life.gd.uid b/scripts/life.gd.uid
deleted file mode 100644
index 6666d8d..0000000
--- a/scripts/life.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://dtj2opmwvh4y1
diff --git a/scripts/morale.gd b/scripts/morale.gd
deleted file mode 100644
index 613c7f5..0000000
--- a/scripts/morale.gd
+++ /dev/null
@@ -1,11 +0,0 @@
-extends Label
-
-func _ready():
- GameData.connect("morale_changed", Callable(self, "_on_morale_changed"))
- update_label(GameData.get_morale())
-
-func _on_morale_changed(new_morale: int) -> void:
- update_label(new_morale)
-
-func update_label(new_morale: int) -> void:
- text = "Morale:" + str(new_morale)
diff --git a/scripts/morale.gd.uid b/scripts/morale.gd.uid
deleted file mode 100644
index 2424396..0000000
--- a/scripts/morale.gd.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://b8urrbmynk327
diff --git a/scripts/player.gd b/scripts/player.gd
index 45b2b61..d9ee0bd 100644
--- a/scripts/player.gd
+++ b/scripts/player.gd
@@ -1,16 +1,27 @@
extends Node2D
+var game_stats_config = preload("res://resources/game_stats_config.tres")
@onready var map_config = preload("res://resources/map_generator_resource.tres")
@onready var _tm = get_node("../Defenders")
var _max_x : int
var _max_y : int
-var dirs = {"move_right": Vector2.RIGHT,
- "move_left": Vector2.LEFT,
- "move_up": Vector2.UP,
- "move_down": Vector2.DOWN
- }
+var dirs = {
+ "move_right": Vector2.RIGHT,
+ "move_left": Vector2.LEFT,
+ "move_up": Vector2.UP,
+ "move_down": Vector2.DOWN
+}
+
+var tower_ids = {
+ "tower_action_one": 0,
+ "tower_action_two": 1,
+ "tower_action_three": 2,
+ "tower_action_four": 3,
+}
+
+signal curr_tile(tile_state)
func _ready():
_max_x = map_config.grid_width * map_config.tile_size
@@ -23,7 +34,10 @@ func _unhandled_input(event):
if event.is_action_pressed(dir):
handle_move(dirs[dir])
return
- _tm.handle_tower_key(event, position)
+ for id in tower_ids.keys():
+ if event.is_action_pressed(id):
+ _tm.handle_tower_key(tower_ids[id], global_position)
+ emit_signal("curr_tile", _get_tile_state())
func handle_move(dir):
position += dir * map_config.tile_size
@@ -31,3 +45,14 @@ func handle_move(dir):
position.y = max(position.y, map_config.tile_size / 2)
position.x = min(position.x, _max_x - (map_config.tile_size / 2))
position.y = min(position.y, _max_y - (map_config.tile_size / 2))
+
+# this method of getting uniform menu for the panel
+# was specifically designed that way in game stats config
+# it may be inefficient and is somewhat messy
+func _get_tile_state():
+ var tile_info = null
+ if _tm.is_tile_occupied(position):
+ tile_info = _tm.get_upgrades_at(position)
+ elif _tm.is_valid_placement_tile(position):
+ tile_info = game_stats_config.defenders
+ return tile_info
diff --git a/scripts/tower_manager.gd b/scripts/tower_manager.gd
index 9682dd9..7440a9a 100644
--- a/scripts/tower_manager.gd
+++ b/scripts/tower_manager.gd
@@ -4,56 +4,42 @@ var game_stats_config = preload("res://resources/game_stats_config.tres")
@onready var _tiles : TileMapLayer = get_node("../Map/TileMapLayer")
var _towers : Dictionary
-var _tower_actions : Array[String] = [
- "tower_action_one",
- "tower_action_two",
- "tower_action_three",
- "tower_action_four"
-]
-
-var _tower_data : Dictionary[String, Dictionary] = {
- "tower_action_one": {
+var _tower_data : Array[Dictionary] = [
+ {
"scene": preload("res://scenes/warlock.tscn"),
- "cost": game_stats_config.defenders["warlock"]["cost"],
+ "cost": game_stats_config.defenders[0]["cost"],
},
- "tower_action_two": {
+ {
"scene": preload("res://scenes/wyvern.tscn"),
- "cost": game_stats_config.defenders["wyvern"]["cost"],
+ "cost": game_stats_config.defenders[1]["cost"],
},
# TODO -- space reserved for last two towers
- "tower_action_three": {
+ {
"scene": preload("res://scenes/warlock.tscn"),
- "cost": game_stats_config.defenders["warlock"]["cost"],
+ "cost": game_stats_config.defenders[0]["cost"],
},
- "tower_action_four": {
+ {
"scene": preload("res://scenes/warlock.tscn"),
- "cost": game_stats_config.defenders["warlock"]["cost"],
+ "cost": game_stats_config.defenders[0]["cost"],
},
-}
+]
func _ready():
_towers = {}
-func handle_tower_key(event, tile_position : Vector2i):
- for action in _tower_actions:
- if event.is_action_pressed(action):
- if is_tile_occupied(tile_position):
- _handle_upgrade(action, _towers[tile_position])
- elif _is_valid_placement_tile(tile_position):
- _handle_place_tower(_tower_data[action], tile_position)
+func handle_tower_key(tower_index : int, tile_position : Vector2i):
+ if is_tile_occupied(tile_position):
+ _handle_upgrade(tower_index, _towers[tile_position])
+ elif is_valid_placement_tile(tile_position):
+ _handle_place_tower(_tower_data[tower_index], tile_position)
-func _handle_upgrade(action : String, tower : StaticBody2D):
- var tower_key : String = tower.get_tower_key()
- var upgrades = game_stats_config.defenders[tower_key]["upgrades"]
-
- print("foo: ", GameData.get_life(), " ", action, " ", tower_key, " ", upgrades)
- if upgrades.has(action):
- var upgrade_data = upgrades[action]
- var upgrade_cost = upgrade_data["cost"]
+func _handle_upgrade(upgrade_index : int, tower : StaticBody2D):
+ var upgrades = tower.tower_data["upgrades"]
+ var upgrade_cost = upgrades[upgrade_index]["cost"]
- if GameData.get_life() >= upgrade_cost:
- GameData.subtract_life(upgrade_cost)
- tower.apply_upgrade(upgrade_data["effects"])
+ if GameData.get_life() >= upgrade_cost:
+ GameData.subtract_life(upgrade_cost)
+ tower.apply_upgrade(upgrades[upgrade_index]["effects"])
func _handle_place_tower(tower : Dictionary, tile_position : Vector2i):
var tower_cost = tower["cost"]
@@ -64,9 +50,14 @@ func _handle_place_tower(tower : Dictionary, tile_position : Vector2i):
tmp.global_position = tile_position
_occupy_tile(tile_position, tmp)
-func _is_valid_placement_tile(tile_position : Vector2i):
- var tile_coords = _tiles.get_cell_atlas_coords(tile_position)
- return (tile_coords == (Vector2i(-1, -1))) && (!is_tile_occupied(tile_position))
+func get_upgrades_at(tile_position : Vector2i) -> Array:
+ if _towers.has(tile_position):
+ return _towers[tile_position].tower_data["upgrades"]
+ return []
+
+func is_valid_placement_tile(tile_position : Vector2i):
+ var tile_coords = _tiles.get_cell_atlas_coords(_tiles.local_to_map(tile_position))
+ return (tile_coords == (Vector2i(-1, -1)))
func is_tile_occupied(tile_position : Vector2i):
return _towers.has(tile_position)
diff --git a/scripts/ui.gd b/scripts/ui.gd
new file mode 100644
index 0000000..031236b
--- /dev/null
+++ b/scripts/ui.gd
@@ -0,0 +1,34 @@
+extends PanelContainer
+
+@onready var morale : Label = $MarginContainer/HBoxContainer/VBoxContainer/Life
+@onready var life : Label = $MarginContainer/HBoxContainer/VBoxContainer/Morale
+@onready var options_container : HBoxContainer = $MarginContainer/HBoxContainer/HBoxContainer
+
+var ui_option = preload("res://scenes/ui_option.tscn")
+
+func _ready():
+ var player = get_node("../Player")
+ player.connect("curr_tile", Callable(self, "_update_options"))
+
+ GameData.connect("morale_changed", Callable(self, "_update_morale"))
+ GameData.connect("life_changed", Callable(self, "_update_life"))
+ _update_morale()
+ _update_life()
+
+func _update_morale() -> void:
+ morale.text = "Morale:" + str(GameData.get_morale())
+
+func _update_life() -> void:
+ life.text = "Life:" + str(GameData.get_life())
+
+func _update_options(data):
+ for i in options_container.get_children():
+ i.queue_free()
+
+ if data != null:
+ for i in data:
+ var option = ui_option.instantiate()
+ option.desc = i["desc"]
+ option.cost = i["cost"]
+ option.sprite_atlas = i["sprite_panel"]
+ options_container.add_child(option)
diff --git a/scripts/ui.gd.uid b/scripts/ui.gd.uid
new file mode 100644
index 0000000..d709bc5
--- /dev/null
+++ b/scripts/ui.gd.uid
@@ -0,0 +1 @@
+uid://biw5cwtetstux
diff --git a/scripts/warlock.gd b/scripts/warlock.gd
index 9e3cd98..a3174d8 100644
--- a/scripts/warlock.gd
+++ b/scripts/warlock.gd
@@ -3,7 +3,7 @@ extends "res://scripts/base_defender.gd"
var projectile: PackedScene = preload("res://scenes/warlock_projectile.tscn")
func _ready():
- set_tower_stats("warlock")
+ set_tower_stats(0)
reset_tower_range()
reset_tower_sprite()
diff --git a/scripts/wyvern.gd b/scripts/wyvern.gd
index 1e1e2ff..e9a1efe 100644
--- a/scripts/wyvern.gd
+++ b/scripts/wyvern.gd
@@ -6,7 +6,7 @@ var range_collision : CollisionShape2D
var firing : bool = false
func _ready():
- set_tower_stats("wyvern")
+ set_tower_stats(1)
reset_tower_range()
reset_tower_sprite()