diff options
Diffstat (limited to 'Towers/Components')
-rw-r--r-- | Towers/Components/AttackComponent.gd | 77 | ||||
-rw-r--r-- | Towers/Components/BurnComponent.gd | 2 | ||||
-rw-r--r-- | Towers/Components/FrostComponent.gd | 2 | ||||
-rw-r--r-- | Towers/Components/RangeComponent.gd | 52 | ||||
-rw-r--r-- | Towers/Components/TowerComponent.gd | 48 |
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 |