summaryrefslogtreecommitdiff
path: root/Towers/Components
diff options
context:
space:
mode:
Diffstat (limited to 'Towers/Components')
-rw-r--r--Towers/Components/AttackComponent.gd77
-rw-r--r--Towers/Components/BurnComponent.gd2
-rw-r--r--Towers/Components/FrostComponent.gd2
-rw-r--r--Towers/Components/RangeComponent.gd52
-rw-r--r--Towers/Components/TowerComponent.gd48
5 files changed, 169 insertions, 12 deletions
diff --git a/Towers/Components/AttackComponent.gd b/Towers/Components/AttackComponent.gd
new file mode 100644
index 0000000..c7660cf
--- /dev/null
+++ b/Towers/Components/AttackComponent.gd
@@ -0,0 +1,77 @@
+class_name AttackTowerComponent
+extends TowerComponent
+
+
+var power := 1
+
+var speed_base := 1.0
+var speed := 1
+
+var shoot_cooldown := Timer.new()
+var shoot_sound := AudioStreamPlayer2D.new()
+
+@export var range_component: RangeTowerComponent:
+ get():
+ return current_tower.components[ComponentType.Range]
+
+
+func _init() -> void:
+ type = ComponentType.Attack
+ set_sprite(preload("res://Towers/Components/Assets/attack-component.png"))
+
+ update_power()
+ update_speed()
+ level_changed.connect(update_power)
+ level_changed.connect(update_speed)
+
+
+func update_power():
+ power = ceil(level / 2.0)
+
+func update_speed():
+ speed = level - ceil(level / 2.0)
+ shoot_cooldown.wait_time = speed_base / speed
+
+func update_range():
+ shoot_sound.max_distance = range_component.range * Client.current_stage.map.tile_set.tile_size.x
+
+
+func on_add(tower: Tower):
+ super.on_add(tower)
+
+ shoot_cooldown.one_shot = true
+ tower.add_child(shoot_cooldown)
+
+ shoot_sound.stream = preload("res://Towers/Assets/shoot.ogg")
+ tower.add_child(shoot_sound)
+
+ update_range()
+ range_component.range_changed.connect(update_range)
+
+
+func process(_delta: float):
+ if shoot_cooldown.is_stopped() and not range_component.units_in_range.is_empty():
+ shoot()
+ shoot_cooldown.start()
+
+
+func shoot():
+ var target = range_component.units_in_range[0]
+
+ for component in current_tower.components.values():
+ if component.has_method("on_shoot"):
+ component.on_shoot(target)
+
+ shoot_fx.rpc()
+
+ if is_melee_range():
+ target.set_hp(target.hp - 1)
+ else: # TODO
+ target.set_hp(target.hp - 1)
+
+@rpc("authority", "call_local")
+func shoot_fx():
+ shoot_sound.play()
+
+func is_melee_range():
+ return range_component.range <= (Client.current_stage.map.tile_set.tile_size.x * 2)
diff --git a/Towers/Components/BurnComponent.gd b/Towers/Components/BurnComponent.gd
index 96c24f7..d708d4f 100644
--- a/Towers/Components/BurnComponent.gd
+++ b/Towers/Components/BurnComponent.gd
@@ -2,7 +2,7 @@ extends TowerComponent
func _init() -> void:
- name = "Burn"
+ type = ComponentType.Burn
set_sprite(preload("res://Towers/Components/Assets/burn-component.png"))
diff --git a/Towers/Components/FrostComponent.gd b/Towers/Components/FrostComponent.gd
index 473baf6..2443b70 100644
--- a/Towers/Components/FrostComponent.gd
+++ b/Towers/Components/FrostComponent.gd
@@ -2,7 +2,7 @@ extends TowerComponent
func _init() -> void:
- name = "Frost"
+ type = ComponentType.Frost
set_sprite(preload("res://Towers/Components/Assets/frost-component.png"))
diff --git a/Towers/Components/RangeComponent.gd b/Towers/Components/RangeComponent.gd
new file mode 100644
index 0000000..a2f7ae7
--- /dev/null
+++ b/Towers/Components/RangeComponent.gd
@@ -0,0 +1,52 @@
+class_name RangeTowerComponent
+extends TowerComponent
+
+
+signal range_changed
+@warning_ignore("shadowed_global_identifier")
+var range := 0:
+ set(value):
+ range = value
+ range_changed.emit()
+
+var area := Area2D.new()
+var collision_shape := CollisionShape2D.new()
+var shape := CircleShape2D.new()
+
+var units_in_range: Array[Unit]
+
+
+func _init() -> void:
+ type = ComponentType.Range
+ set_sprite(preload("res://Towers/Components/Assets/range-component.png"))
+
+ update_range()
+ level_changed.connect(update_range)
+
+
+func update_range():
+ var tile_size = Client.current_stage.map.tile_set.tile_size.x
+ @warning_ignore("integer_division")
+ range = (tile_size * 2) + ((tile_size / 2) * level)
+ shape.radius = range
+
+
+func on_add(tower: Tower):
+ super.on_add(tower)
+
+ area.set_collision_layer_value(1, false)
+ area.set_collision_mask_value(1, true)
+
+ area.body_entered.connect(func(body: Node2D):
+ units_in_range.append(body)
+ )
+ area.body_exited.connect(func(body: Node2D):
+ units_in_range.erase(body)
+ )
+
+ area.position = tower.get_node("CenterAnchor").position
+
+ collision_shape.shape = shape
+ area.add_child(collision_shape)
+
+ tower.add_child(area)
diff --git a/Towers/Components/TowerComponent.gd b/Towers/Components/TowerComponent.gd
index 609f88c..7ca766a 100644
--- a/Towers/Components/TowerComponent.gd
+++ b/Towers/Components/TowerComponent.gd
@@ -1,30 +1,58 @@
class_name TowerComponent
-extends Resource
+extends Node
-var name: String
-var sprite: Sprite2D = Sprite2D.new()
-var level: int = 1
+var current_tower: Tower
+
+enum ComponentType {
+ Range,
+ Attack,
+ Speed,
+ Frost,
+ Burn,
+ Poison,
+}
+
+var type: ComponentType
+var sprite: TextureRect = TextureRect.new()
+
+var id: String:
+ get():
+ return get_type_name()
+
+signal level_changed
+var level: int = 1:
+ set(value):
+ level = value
+ level_changed.emit()
func set_sprite(texture: Texture2D):
sprite.texture = texture
sprite.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
- sprite.centered = false
- sprite.scale = Vector2(2, 2)
- sprite.name = name
+ #sprite.centered = false
+ sprite.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
+ #sprite.scale = Vector2(2, 2)
+ sprite.name = get_type_name()
+
+
+func get_type_name(component_type: ComponentType = type):
+ return ComponentType.keys()[component_type]
+
+func on_add(tower: Tower):
+ current_tower = tower
class NetworkData extends Resource:
- var name: String
+ var type: ComponentType
var level: int
func to_network_data() -> NetworkData:
var data = NetworkData.new()
- data.name = name
+ data.type = type
data.level = level
return data
@@ -35,7 +63,7 @@ func update_with_network_data(_data: NetworkData):
static func from_network_data(data: NetworkData) -> TowerComponent:
var component = preload("res://Towers/Components/TowerComponent.gd").new()
- component.name = data.name
+ component.type = data.type
component.level = data.level
return component