Explosion_der_Spiele/scripts/combat/cheese_seller.gd

93 lines
2.9 KiB
GDScript3
Raw Permalink Normal View History

@tool
extends Node3D
class_name CheeseSeller
## Places a cheese table and periodically launches moldy cheese at the player.
## DESIGN: stab the cheese (projectile), not the seller — seller dies of grief when cheese destroyed.
## @tool: billboard look only in editor (no cheese firing).
@export var texture_path: String = "res://assets/sprites/placeholders/cheese_seller.png":
set(v):
texture_path = v
if Engine.is_editor_hint() and is_node_ready():
_apply_billboard_look()
@export var fire_interval: float = 2.8
@export var cheese_speed: float = 7.0
var _alive: bool = true
var _timer: float = 0.0
var _grief: int = 0
@onready var _billboard: BillboardSprite = $BillboardSprite
func _ready() -> void:
_apply_billboard_look()
if Engine.is_editor_hint():
set_process(false)
return
add_to_group("interactable")
add_to_group("cheese_seller")
_timer = randf() * fire_interval
func _apply_billboard_look() -> void:
if _billboard == null:
_billboard = get_node_or_null("BillboardSprite") as BillboardSprite
if _billboard == null:
return
_billboard.set_target_height(SpriteFit.WORLD_PROP_HEIGHT)
if texture_path != "" and ResourceLoader.exists(texture_path):
var tex: Texture2D = load(texture_path)
if tex:
_billboard.set_texture(tex)
func _process(delta: float) -> void:
if Engine.is_editor_hint() or not _alive:
return
_timer -= delta
if _timer <= 0.0:
_timer = fire_interval
_fire()
func _fire() -> void:
var player := get_tree().get_first_node_in_group("player")
if player == null:
return
var proj_scene: PackedScene = load("res://scenes/prefabs/cheese_projectile.tscn")
if proj_scene == null:
return
var proj: Node3D = proj_scene.instantiate()
get_tree().current_scene.add_child(proj)
proj.global_position = global_position + Vector3(0, 0.8, 0)
var dir: Vector3 = (player.global_position + Vector3(0, 0.8, 0) - proj.global_position).normalized()
proj.set("velocity", dir * cheese_speed)
proj.add_to_group("cheese_projectile")
proj.add_to_group("enemy")
proj.set_meta("seller", self)
func notify_cheese_destroyed() -> void:
_grief += 1
if _grief >= 2:
_alive = false
var ui := get_node_or_null("/root/UIRoot")
if ui and ui.has_method("show_dialog"):
ui.show_dialog_key("dialog_cheese")
queue_free()
func on_interact(_player: Node) -> void:
var ui := get_node_or_null("/root/UIRoot")
if ui and ui.has_method("show_dialog"):
ui.show_dialog_key("dialog_cheese")
func take_hit(_amount: int = 1) -> void:
## Hitting the seller does nothing useful (DESIGN).
var ui := get_node_or_null("/root/UIRoot")
if ui and ui.has_method("show_dialog"):
ui.show_dialog_key("dialog_cheese")
func get_interact_prompt() -> String:
return "%s — %s" % [Locale.tr_key("prompt_talk"), Locale.tr_key("dialog_cheese")]
func set_interaction_highlight(enabled: bool, color: Color = Color(1.4, 1.35, 0.4)) -> void:
if _billboard and _billboard.has_method("set_highlight"):
_billboard.set_highlight(enabled, color)