Wire all twelve levels with billboard prefabs, autoload systems (inventory, achievements, mock shop, DE/EN/BY), and satire audio locks so the Title→End flow is playable with placeholder assets.
43 lines
1,014 B
GDScript
43 lines
1,014 B
GDScript
extends Node3D
|
|
class_name HittableEntity
|
|
## Generic enemy / boss stub with hit points.
|
|
|
|
signal defeated
|
|
signal hit(remaining_hp: int)
|
|
|
|
@export var max_hp: int = 4
|
|
@export var texture_path: String = "res://assets/sprites/placeholders/enemy.png"
|
|
@export var defeat_flag: String = ""
|
|
@export var achievement_on_defeat: String = ""
|
|
|
|
var hp: int = 4
|
|
var _alive: bool = true
|
|
|
|
@onready var _billboard: BillboardSprite = $BillboardSprite
|
|
|
|
func _ready() -> void:
|
|
hp = max_hp
|
|
add_to_group("enemy")
|
|
add_to_group("interactable")
|
|
if _billboard:
|
|
var tex: Texture2D = load(texture_path)
|
|
if tex:
|
|
_billboard.set_texture(tex)
|
|
|
|
func take_hit(amount: int = 1) -> void:
|
|
if not _alive:
|
|
return
|
|
hp = max(0, hp - amount)
|
|
hit.emit(hp)
|
|
AudioDirector.play_hit()
|
|
if hp <= 0:
|
|
_alive = false
|
|
if defeat_flag != "":
|
|
GameState.set_flag(defeat_flag, true)
|
|
if achievement_on_defeat != "":
|
|
Achievements.unlock(achievement_on_defeat)
|
|
defeated.emit()
|
|
queue_free()
|
|
|
|
func on_interact(_player: Node) -> void:
|
|
take_hit(1)
|