straywild/messages/beach_bottle_presentation.gd

68 lines
1.7 KiB
GDScript

class_name BeachBottlePresentation
extends Node3D
const VISIBLE_BASE_TUCK_PIXELS: float = 1.0
const AUTHORED_VISIBLE_BOTTOM_PIXEL: float = 48.0
@onready var _sprite: Sprite3D = %BottleSprite
var message_id: StringName
var _collecting: bool = false
func _ready() -> void:
_anchor_sprite_visible_bottom()
func configure(
reserved_message_id: StringName,
world_position: Vector3,
phase: float = 0.0,
) -> void:
message_id = reserved_message_id
global_position = world_position
rotation.y = phase
func _anchor_sprite_visible_bottom() -> void:
if _sprite == null or _sprite.texture == null:
return
var texture_height: float = float(_sprite.texture.get_height())
if texture_height <= 0.0:
return
var texture_center_pixel: float = texture_height * 0.5
# VRAM-compressed textures do not expose reliable alpha bounds at runtime.
# The authored 64px sand sprite ends at pixel 48; sink that visible baseline
# one source pixel into the sampled terrain so it cannot visibly hover.
_sprite.position.y = maxf(
(
AUTHORED_VISIBLE_BOTTOM_PIXEL
- texture_center_pixel
- VISIBLE_BASE_TUCK_PIXELS
) * _sprite.pixel_size,
0.0,
)
func get_collect_position() -> Vector3:
return global_position
func play_collected() -> void:
if _collecting:
return
_collecting = true
var tween := create_tween()
tween.set_parallel(true)
tween.set_trans(Tween.TRANS_QUAD)
tween.set_ease(Tween.EASE_IN)
tween.tween_property(self, "scale", Vector3(0.35, 0.35, 0.35), 0.22)
tween.tween_property(self, "position:y", position.y + 0.35, 0.22)
if _sprite != null:
tween.tween_property(
_sprite,
"modulate",
Color(1.0, 1.0, 1.0, 0.0),
0.22,
)
tween.chain().tween_callback(queue_free)