Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,50 +7,38 @@ extends FillingBarrel
## Emitted when [member current_health] reaches 0.
signal barrel_destroyed(barrel_instance: FragileBarrel)

## Maximum hits the barrel can take before breaking.
@export_range(1, 100) var max_health: int = 4

var current_health: int

@onready var crack_overlay_node: AnimatedSprite2D = %CrackOverlay
@onready var crack_sound: AudioStreamPlayer2D = %CrackSound
@onready var shatter_sound: AudioStreamPlayer2D = %ShatterSound
@onready var health_component: HealthComponent = %HealthComponent


func _ready() -> void:
super._ready()
current_health = max_health
crack_overlay_node.visible = false


# Logic called by Projectile when it hits this object
func hit_by_droplet(droplet_label: String) -> void:
# Ignore if already full or destroyed
if _amount >= needed_amount or current_health <= 0:
if _amount >= needed_amount or health_component.has_depleted_health:
return

if droplet_label == self.label:
increment()
else:
take_damage()
health_component.damage(1)


func take_damage() -> void:
current_health -= 1

if current_health <= 0:
break_barrel()
else:
crack_sound.play()
update_cracks()
crack_sound.play()
update_cracks()


func update_cracks() -> void:
var damage_taken: int = max_health - current_health

# IMPROVEMENT: Calculate frame index proportionally based on damage percentage.
var total_frames: int = crack_overlay_node.sprite_frames.get_frame_count("default")
var frame_index: int = int(floor((float(damage_taken) / max_health) * total_frames))
var frame_index: int = int(floor((health_component.damage_taken_percentage) * total_frames))

# Clamp to ensure we don't exceed available frames (0-based index)
frame_index = clamp(frame_index, 0, total_frames - 1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
[ext_resource type="Script" uid="uid://d05hp7ascndlr" path="res://scenes/game_elements/props/filling_barrel/components/fragile_barrel.gd" id="2_wal8y"]
[ext_resource type="AudioStream" uid="uid://bknpb07lvbded" path="res://scenes/game_elements/props/filling_barrel/components/sfx_barrel_crack.tres" id="4_sdj6j"]
[ext_resource type="AudioStream" uid="uid://c3iuv5ax8i78v" path="res://scenes/game_elements/props/filling_barrel/components/sfx_barrel_breaking.tres" id="5_v7k7g"]
[ext_resource type="Script" uid="uid://b0qrfv6upnqtu" path="res://scenes/game_logic/health_component.gd" id="6_v7k7g"]

[node name="FragileBarrel" unique_id=2064522120 instance=ExtResource("1_ab25j")]
script = ExtResource("2_wal8y")
max_health = 4

[node name="CrackOverlay" type="AnimatedSprite2D" parent="." index="1" unique_id=473951260]
unique_name_in_owner = true
Expand All @@ -25,3 +25,11 @@ bus = &"SFX"
unique_name_in_owner = true
stream = ExtResource("5_v7k7g")
bus = &"SFX"

[node name="HealthComponent" type="Node2D" parent="." index="10" unique_id=1654759649]
unique_name_in_owner = true
script = ExtResource("6_v7k7g")
metadata/_custom_type_script = "uid://b0qrfv6upnqtu"

[connection signal="health_changed" from="HealthComponent" to="." method="take_damage" unbinds=1]
[connection signal="health_depleted" from="HealthComponent" to="." method="break_barrel"]
40 changes: 40 additions & 0 deletions scenes/game_logic/health_component.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# SPDX-FileCopyrightText: The Threadbare Authors
# SPDX-License-Identifier: MPL-2.0
class_name HealthComponent
extends Node2D

signal health_depleted
signal health_changed(current_health: int)

@export_range(1, 100) var max_health: int = 4

var current_health: int = max_health:
set(value):
if value == current_health:
pass

current_health = value
if current_health <= 0:
health_depleted.emit()
else:
health_changed.emit(current_health)

var damage_taken: int:
get:
return max_health - current_health

var damage_taken_percentage: float:
get:
return float(damage_taken) / max_health

var has_depleted_health: bool:
get:
return current_health <= 0


func damage(amount: int) -> void:
current_health -= amount


func heal(amount: int) -> void:
current_health += amount
1 change: 1 addition & 0 deletions scenes/game_logic/health_component.gd.uid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uid://b0qrfv6upnqtu