diff options
author | bd <bdunahu@operationnull.com> | 2025-05-24 14:08:17 -0400 |
---|---|---|
committer | bd <bdunahu@operationnull.com> | 2025-05-24 14:08:17 -0400 |
commit | c38a303aad3c3c0d8114524e664da6ad721e21c4 (patch) | |
tree | 6fb27d2ff142e73bf59c3a0e5f7bed2fab49f844 | |
parent | 4948e4e35dadc749026a83d0a8402436a4b2ac44 (diff) |
Add logic to perform basic stat upgrades
-rw-r--r-- | scripts/base_defender.gd | 38 | ||||
-rw-r--r-- | scripts/game_stats_config.gd | 24 | ||||
-rw-r--r-- | scripts/player.gd | 28 | ||||
-rw-r--r-- | scripts/tower_manager.gd | 68 | ||||
-rw-r--r-- | scripts/warlock.gd | 19 | ||||
-rw-r--r-- | scripts/warlock_projectile.gd | 2 | ||||
-rw-r--r-- | scripts/wyvern.gd | 21 |
7 files changed, 122 insertions, 78 deletions
diff --git a/scripts/base_defender.gd b/scripts/base_defender.gd index 424ce96..06ac34f 100644 --- a/scripts/base_defender.gd +++ b/scripts/base_defender.gd @@ -2,25 +2,30 @@ extends StaticBody2D @onready var sprite_node = $Sprite2D @onready var util = preload("res://scripts/util.gd") +@onready var game_stats_config = preload("res://resources/game_stats_config.tres") + +var tower_data : Dictionary +var tower_key : String -var defender_range : float -var fire_rate : float -var damage : float var target : CharacterBody2D -var idle_atlas_coords : Vector2i -var attack_atlas_coords : Vector2i var _idle_texture : Texture var _attack_texture : Texture -func _ready() -> void: - _idle_texture = util.get_tile_texture(idle_atlas_coords) - _attack_texture = util.get_tile_texture(attack_atlas_coords) +func set_tower_stats(tower_name : String): + tower_key = tower_name + tower_data = game_stats_config.defenders[tower_key] + +func reset_tower_range(): + $Tower/CollisionShape2D.shape.radius = tower_data["range"] + +func reset_tower_sprite(): + _idle_texture = util.get_tile_texture(tower_data["sprite_idle"]) + _attack_texture = util.get_tile_texture(tower_data["sprite_attacking"]) _idle_state() -func _on_fire_timer_timeout() -> void: - # extending classes override here - pass +func get_tower_key() -> String: + return tower_key func select_target() -> void: var targets : Array = _find_targets() @@ -56,7 +61,7 @@ func _on_tower_body_entered(_body: Node2D) -> void: var old_target : CharacterBody2D = target select_target() if old_target == null && old_target != target: - $FireTimer.start(fire_rate) + $FireTimer.start(tower_data["fire_rate"]) _on_fire_timer_timeout() func _attack_state(): @@ -64,3 +69,12 @@ func _attack_state(): func _idle_state(): sprite_node.texture = _idle_texture + +func apply_upgrade(effects: Dictionary): + for key in effects.keys(): + if key in tower_data: + tower_data[key] += effects[key] + +# extending classes should override below +func _on_fire_timer_timeout() -> void: + pass diff --git a/scripts/game_stats_config.gd b/scripts/game_stats_config.gd index 4e0a3e6..873312d 100644 --- a/scripts/game_stats_config.gd +++ b/scripts/game_stats_config.gd @@ -21,7 +21,29 @@ class_name GameStatsConfig "sprite_panel": Vector2i(32, 4), "sprite_attacking": Vector2i(31, 2), "sprite_idle": Vector2i(31, 1), - "cost": 10 + "cost": 10, + "projectile_speed" : 100, + "upgrades": { + "tower_action_one": { + "cost": 7, + "effects": { + "damage": 3.0, + } + }, + "tower_action_two": { + "cost": 7, + "effects": { + "fire_rate": 0.5 + } + }, + "tower_action_three": { + "cost": 30, + "effects": { + "projectile_speed": 300.0, + "range": 200.0 + } + }, + }, }, "wyvern": { "damage" : 1.0, diff --git a/scripts/player.gd b/scripts/player.gd index c890542..45b2b61 100644 --- a/scripts/player.gd +++ b/scripts/player.gd @@ -1,6 +1,5 @@ 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") @@ -10,26 +9,8 @@ var _max_y : int var dirs = {"move_right": Vector2.RIGHT, "move_left": Vector2.LEFT, "move_up": Vector2.UP, - "move_down": Vector2.DOWN} - -var towers : Dictionary[String, Dictionary] = { - "place_warlock": { - "scene": preload("res://scenes/warlock.tscn"), - "cost": game_stats_config.defenders["warlock"]["cost"], - }, - "place_wyvern": { - "scene": preload("res://scenes/wyvern.tscn"), - "cost": game_stats_config.defenders["wyvern"]["cost"], - }, - #"place_werewolf": { - #"scene": preload("res://scenes/werewolf.tscn"), - #"cost": game_stats_config.defenders["werewolf"]["cost"], - #}, - #"place_wellspring": { - #"scene": preload("res://scenes/wellspring.tscn"), - #"cost": game_stats_config.defenders["werewolf"]["cost"], - #}, -} + "move_down": Vector2.DOWN + } func _ready(): _max_x = map_config.grid_width * map_config.tile_size @@ -42,10 +23,7 @@ func _unhandled_input(event): if event.is_action_pressed(dir): handle_move(dirs[dir]) return - for tower in towers.keys(): - if event.is_action_pressed(tower): - _tm.place_tower(towers[tower], position) - return + _tm.handle_tower_key(event, position) func handle_move(dir): position += dir * map_config.tile_size diff --git a/scripts/tower_manager.gd b/scripts/tower_manager.gd index 250b66b..9682dd9 100644 --- a/scripts/tower_manager.gd +++ b/scripts/tower_manager.gd @@ -1,30 +1,78 @@ extends Node +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": { + "scene": preload("res://scenes/warlock.tscn"), + "cost": game_stats_config.defenders["warlock"]["cost"], + }, + "tower_action_two": { + "scene": preload("res://scenes/wyvern.tscn"), + "cost": game_stats_config.defenders["wyvern"]["cost"], + }, + # TODO -- space reserved for last two towers + "tower_action_three": { + "scene": preload("res://scenes/warlock.tscn"), + "cost": game_stats_config.defenders["warlock"]["cost"], + }, + "tower_action_four": { + "scene": preload("res://scenes/warlock.tscn"), + "cost": game_stats_config.defenders["warlock"]["cost"], + }, +} + func _ready(): _towers = {} -func place_tower(tower : Dictionary, tile_position : Vector2i): +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_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"] + + if GameData.get_life() >= upgrade_cost: + GameData.subtract_life(upgrade_cost) + tower.apply_upgrade(upgrade_data["effects"]) + +func _handle_place_tower(tower : Dictionary, tile_position : Vector2i): var tower_cost = tower["cost"] - if is_valid_placement_tile(tile_position) && GameData.get_life() >= tower_cost: + if GameData.get_life() >= tower_cost: + GameData.subtract_life(tower_cost) var tmp = tower["scene"].instantiate() - var path = get_tree().get_root().get_node("Main/Defenders") - path.add_child(tmp) + add_child(tmp) tmp.global_position = tile_position - occupy_tile(tile_position) - GameData.subtract_life(tower_cost) + _occupy_tile(tile_position, tmp) -func is_valid_placement_tile(tile_position : Vector2i): +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 is_tile_occupied(tile_position : Vector2i): return _towers.has(tile_position) -func occupy_tile(tile_position): - _towers[tile_position] = true +func _occupy_tile(tile_position, tower): + _towers[tile_position] = tower -func free_tile(tile_position): +func _free_tile(tile_position): _towers.erase(tile_position) diff --git a/scripts/warlock.gd b/scripts/warlock.gd index bad20d3..9e3cd98 100644 --- a/scripts/warlock.gd +++ b/scripts/warlock.gd @@ -1,28 +1,19 @@ extends "res://scripts/base_defender.gd" -@onready var game_stats_config = preload("res://resources/game_stats_config.tres") - var projectile: PackedScene = preload("res://scenes/warlock_projectile.tscn") -var range_collision : CollisionShape2D func _ready(): - damage = game_stats_config.defenders["warlock"]["damage"] - fire_rate = game_stats_config.defenders["warlock"]["fire_rate"] - defender_range = game_stats_config.defenders["warlock"]["range"] - idle_atlas_coords = game_stats_config.defenders["warlock"]["sprite_idle"] - attack_atlas_coords = game_stats_config.defenders["warlock"]["sprite_attacking"] - - range_collision = $Tower/CollisionShape2D - range_collision.shape.radius = defender_range - - super() + set_tower_stats("warlock") + reset_tower_range() + reset_tower_sprite() func _on_fire_timer_timeout(): select_target() if (target != null): var tmp_projectile = projectile.instantiate() tmp_projectile.target = target - tmp_projectile.projectile_damage = damage + tmp_projectile.speed = tower_data["projectile_speed"] + tmp_projectile.projectile_damage = tower_data["damage"] get_node("ProjectileContainer").call_deferred("add_child", tmp_projectile) tmp_projectile.global_position = $Aim.global_position else: diff --git a/scripts/warlock_projectile.gd b/scripts/warlock_projectile.gd index 060a27d..326dfba 100644 --- a/scripts/warlock_projectile.gd +++ b/scripts/warlock_projectile.gd @@ -1,7 +1,7 @@ extends CharacterBody2D var target : CharacterBody2D -var speed : int = 100 +var speed : int var projectile_damage : int func _physics_process(_delta: float): diff --git a/scripts/wyvern.gd b/scripts/wyvern.gd index d0bf91e..1e1e2ff 100644 --- a/scripts/wyvern.gd +++ b/scripts/wyvern.gd @@ -1,23 +1,14 @@ extends "res://scripts/base_defender.gd" -var game_stats_config = preload("res://resources/game_stats_config.tres") var projectile: PackedScene = preload("res://scenes/wyvern_projectile.tscn") var damage_tick_rate: float var range_collision : CollisionShape2D var firing : bool = false func _ready(): - damage = game_stats_config.defenders["wyvern"]["damage"] - fire_rate = game_stats_config.defenders["wyvern"]["fire_rate"] - damage_tick_rate = game_stats_config.defenders["wyvern"]["damage_tick_rate"] - defender_range = game_stats_config.defenders["wyvern"]["range"] - idle_atlas_coords = game_stats_config.defenders["wyvern"]["sprite_idle"] - attack_atlas_coords = game_stats_config.defenders["wyvern"]["sprite_attacking"] - - range_collision = $Tower/CollisionShape2D - range_collision.shape.radius = defender_range - - super() + set_tower_stats("wyvern") + reset_tower_range() + reset_tower_sprite() func _process(_delta): select_target() @@ -33,14 +24,14 @@ func _on_tower_body_entered(_body: Node2D) -> void: var old_target : CharacterBody2D = target select_target() if old_target == null && old_target != target: - $FireTimer.start(fire_rate) + $FireTimer.start(tower_data["fire_rate"]) func _on_fire_timer_timeout(): if (target != null): var tmp_projectile = projectile.instantiate() tmp_projectile.target = target - tmp_projectile.projectile_damage = damage - tmp_projectile.damage_tick_rate = 0.25 + tmp_projectile.projectile_damage = tower_data["damage"] + tmp_projectile.damage_tick_rate = tower_data["damage_tick_rate"] add_child(tmp_projectile) tmp_projectile.global_position = $Aim.global_position firing = true |