Trap explosions with damage and health bar depletion.

This commit is contained in:
2025-12-29 15:03:05 -05:00
parent e632e54cba
commit 84bf495d11
16 changed files with 149 additions and 30 deletions

View File

@@ -47,9 +47,8 @@ var disarming : bool
var difficulty : int = 1
func _process(delta: float) -> void:
timer_label.text = "%02d.3" % timer.time_left
timer_label.text = "%02f.3" % timer.time_left
func start_disarming() -> void:
disarming = true

15
scripts/healthbar.gd Normal file
View File

@@ -0,0 +1,15 @@
class_name HealthBar extends TextureProgressBar
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass
func _on_health_changed(current : int, max : int) -> void:
max_value = max
value = current

1
scripts/healthbar.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://bolw6n14ocxt3

View File

@@ -1,11 +1,12 @@
class_name HUD extends Control
@onready var trap_display : TrapDisplay = %TrapDisplay
@onready var p1_healthbar : HealthBar = %P1HealthBar
func _ready() -> void:
Game.hud = self
func register_player(player : Player) -> void:
player.health_changed.connect(p1_healthbar._on_health_changed)
trap_display._on_trap_list_changed(player.data.traps, player.data.active_trap)
player.trap_cycled.connect(trap_display._on_trap_cycled)
player.trap_quantity_changed.connect(trap_display._on_trap_quantity_changed)

View File

@@ -9,6 +9,8 @@ const disarm_trap_modal = preload("res://templates/disarm_trap_modal.tscn")
@onready var data : PlayerData = $Data
@onready var trap_sound : AudioStreamPlayer3D = $TrapSound
var id : int = 1
var button_actions : Dictionary[int, String]
var current_square : Vector3i
var detecting : bool = false
@@ -22,7 +24,7 @@ var modal = null
signal trap_cycled(trap_index)
signal trap_quantity_changed(trap_index, quantity)
signal trap_list_changed(traps)
signal health_changed(current : int, max : int)
func _physics_process(delta: float) -> void:
var dir = Input.get_vector("west", "east", "north", "south")
@@ -156,6 +158,9 @@ func show_disarm_trap_modal() -> void:
modal = disarm_trap_modal.instantiate()
modal.difficulty = Game.level.difficulty
modal.square = current_square
var trap = Game.level.traps[current_square]
trap.disarming = true
trap.disarm_id = Multiplayer.id
Game.level.add_child(modal)
func start_detecting() -> void:
@@ -216,6 +221,10 @@ func cycle_active_trap(dir) -> void:
if prev != data.active_trap:
trap_cycled.emit(data.active_trap)
func hurt(damage : int) -> void:
data.life = max(0, data.life - damage)
health_changed.emit(data.life, data.max_life)
func _on_trap_disarmed(type : Trap.Type) -> void:
for i in range(len(data.traps)):
var d = data.traps[i]

View File

@@ -59,6 +59,10 @@ func is_valid_trap_square(crd : Vector3i) -> bool:
return false
return true
func add_vfx(vfx, crd : Vector3i) -> void:
vfx.global_position = Vector3(crd) #+ Vector3(0.5, 0, 0.5)
add_child(vfx)
func activate_trap(crd : Vector3i) -> void:
var trap = traps[crd]
#if trap:

View File

@@ -9,6 +9,14 @@ enum Type{
PITFALL
}
const range_shapes : Dictionary = {
Trap.Type.BOMB : Vector3(5,1,5),
Trap.Type.GAS : Vector3(1,1,1),
Trap.Type.PITFALL : Vector3(1,1,1),
Trap.Type.FORCE_PANEL : Vector3(1,1,1),
Trap.Type.SWITCH : Vector3(3,1,3),
Trap.Type.MINE : Vector3(5,1,5),
}
const trap_icons : Dictionary = {
Trap.Type.BOMB : preload("res://visuals/images/icons/t-bomb.png"),
Trap.Type.GAS : preload("res://visuals/images/icons/t-gas.png"),
@@ -18,6 +26,10 @@ const trap_icons : Dictionary = {
Trap.Type.MINE : preload("res://visuals/images/icons/t-mine.png"),
}
const explosion_template = preload("res://templates/explosion.tscn")
@onready var range_area : Area3D = %RangeArea
@onready var range_shape : BoxShape3D = %RangeShape.shape
@onready var model : MeshInstance3D = %Model
@onready var icon : Sprite3D = %Icon
@onready var material : StandardMaterial3D = model.get_surface_override_material(0)
@@ -25,6 +37,12 @@ const trap_icons : Dictionary = {
var type : Type
var square : Vector3i
var trap_owner : int
var disarming : bool
var disarm_id : int
var damage : int = 10
signal disarmed(type : Trap.Type)
@@ -51,4 +69,17 @@ func _ready() -> void:
icon.texture = trap_icons[type]
model.visible = owns_trap
icon.visible = owns_trap
range_shape.size = range_shapes[type]
material.albedo_color = Color.YELLOW if owns_trap else Color.RED
func activate() -> void:
var exp = explosion_template.instantiate()
Game.level.add_vfx(exp, square)
for body in range_area.get_overlapping_bodies():
body.hurt(damage)
#match(type):
func _on_body_entered(body: Node3D) -> void:
if !disarming or body.id != disarm_id:
if !body.detecting:
activate()

View File

@@ -9,3 +9,12 @@ func _ready() -> void:
func _on_timer_timeout() -> void:
print("Done")
queue_free()
func proximal_shake(distance : float) -> void:
print(Input.get_connected_joypads())
if !Game.player:
return
var d = global_position.distance_squared_to(Game.player.global_position)
if d <= distance * distance:
Input.start_joy_vibration(0, 1,1,1000)