First commit 🎉

This commit is contained in:
Tony Bark 2025-07-17 01:49:18 -04:00
commit 43ea213f9b
728 changed files with 37080 additions and 0 deletions

View file

@ -0,0 +1,265 @@
@tool
@icon("res://addons/popochiu/icons/prop.png")
class_name PopochiuProp
extends PopochiuClickable
## Visual elements in the Room that can have interaction (i.e. the background, the foreground, a
## table, a cup).
##
## When selecting a Prop in the scene tree (Scene dock), Popochiu will enable three buttons in
## the Canvas Editor Menu: Baseline, Walk to, and Interaction. This can be used to select the child
## nodes that allow to modify the position of the [member PopochiuClickable.baseline],
## the position of the [member PopochiuClickable.walk_to_point], and the position and the polygon
## points of the [b]$InteractionPolygon[/b] child.
## Emitted when the [param item] linked to this object (by [member link_to_item]) is removed from
## the inventory. This may happen when the inventory item disappears forever from the game.
signal linked_item_removed(item: PopochiuInventoryItem)
## Emitted when the [param item] linked to this object (by [member link_to_item]) is discarded from
## the inventory. This may happen when the inventory item disappears forever from the game.
signal linked_item_discarded(item: PopochiuInventoryItem)
## The image to use as the [member Sprite2D.texture] of the [b]$Sprite2D[/b] child.
@export var texture: Texture2D : set = set_texture
## The number of horizontal frames this node's texture image has. Modifying this will change the
## value of the [member Sprite2D.hframes] property in the [b]$Sprite2D[/b] child.
@export var frames := 1 : set = set_frames
## The number of vertical frames this node's texture image has. Modifying this will change the
## value of the [member Sprite2D.vframes] property in the [b]$Sprite2D[/b] child.
@export var v_frames := 1 : set = set_v_frames
## The current frame to use as the texture of this node. Modifying this will change the value of the
## [member Sprite2D.frame] property in the [b]$Sprite2D[/b] child. Trying to assign a value lesser
## than 0 will roll over the value to the maximum frame ([code]frames * v_frames - 1[/code]) or
## setting the value greater than the number of frames will roll over the value to 0.
@export var current_frame := 0: set = set_current_frame
## Links the prop to a [PopochiuInventoryItem] by its [member PopochiuInventoryItem.script_name].
## This will make the prop disappear from the room, depending on whether or not said inventory item
## is inside the inventory.
@export var link_to_item := ""
## Total frames available the texture image has. [code](frames * vframes)[/code]
var total_frames: get = get_total_frames
@onready var _sprite: Sprite2D = $Sprite2D
#region Godot ######################################################################################
func _ready() -> void:
super()
add_to_group("props")
if Engine.is_editor_hint(): return
for c in get_children():
if c.get("position") is Vector2:
c.position.y -= baseline * c.scale.y
walk_to_point.y -= baseline * scale.y
look_at_point.y -= baseline * scale.y
position.y += baseline * scale.y
if always_on_top:
z_index += 1
if link_to_item:
PopochiuUtils.i.item_added.connect(_on_item_added)
PopochiuUtils.i.item_removed.connect(_on_item_removed)
PopochiuUtils.i.item_discarded.connect(_on_item_discarded)
if PopochiuUtils.i.is_item_in_inventory(link_to_item):
disable()
#endregion
#region Virtual ####################################################################################
## Called when the [PopochiuInventoryItem] linked to this prop is removed from the inventory.
## [i]Virtual[/i].
func _on_linked_item_removed() -> void:
pass
## Called when the [PopochiuInventoryItem] linked to this prop is discarded from the inventory.
## [i]Virtual[/i].
func _on_linked_item_discarded() -> void:
pass
#endregion
#region Public #####################################################################################
## Changes the value of the [member Sprite2D.frame] property to [param new_frame] in the
## [b]$Sprite2D[/b] child.[br][br]
## [i]This method is intended to be used inside a [method Popochiu.queue] of instructions.[/i]
func queue_change_frame(new_frame: int) -> Callable:
return func (): await change_frame(new_frame)
## Changes the value of the [member Sprite2D.frame] property to [param new_frame] in the
## [b]$Sprite2D[/b] child.
func change_frame(new_frame: int) -> void:
self.current_frame = new_frame
await get_tree().process_frame
#endregion
#region SetGet #####################################################################################
func set_texture(value: Texture2D) -> void:
texture = value
if not has_node("Sprite2D"): return
$Sprite2D.texture = value
func set_frames(value: int) -> void:
frames = value
if not has_node("Sprite2D"): return
$Sprite2D.hframes = value
func set_v_frames(value: int) -> void:
v_frames = value
if not has_node("Sprite2D"): return
$Sprite2D.vframes = value
func set_current_frame(value: int) -> void:
current_frame = value
if not has_node("Sprite2D"): return
var sprite := $Sprite2D as Sprite2D
current_frame = (total_frames + current_frame) % total_frames
sprite.frame = current_frame
func get_total_frames() -> int:
return frames * v_frames
#endregion
#region AnimationPlayer ############################################################################
## Will play the [param name] animation if it exists in this prop's [AnimationPlayer] node.
## Optionally you can use the other [method AnimationPlayer.play] parameters (see Godot's
## documentation for more details).
## [i]This method is intended to be used inside a [method Popochiu.queue] of instructions.[/i]
func queue_play_animation(
name: StringName = &"",
custom_blend: float = -1,
custom_speed: float = 1.0,
from_end: bool = false
) -> Callable:
return func (): await play_animation(name, custom_blend, custom_speed, from_end)
## Will play the [param name] animation if it exists in this prop's [AnimationPlayer] node.
## Optionally you can use the other [method AnimationPlayer.play] parameters (see Godot's
## documentation for more details).
func play_animation(
name: StringName = &"",
custom_blend: float = -1,
custom_speed: float = 1.0,
from_end: bool = false
) -> void:
if not has_node("AnimationPlayer"): return
$AnimationPlayer.play(name, custom_blend, custom_speed, from_end)
## Will play the [param name] animation in reverse if it exists in this prop's [AnimationPlayer]
## node.
## This method is a shorthand for [method play_animation] with [code]custom_speed = -1.0[/code]
## and [code]from_end = true[/code].
## [i]This method is intended to be used inside a [method Popochiu.queue] of instructions.[/i]
func queue_play_animation_backwards(name: StringName = &"", custom_blend: float = -1) -> Callable:
return func (): await play_animation_backwards(name, custom_blend)
## Will play the [param name] animation in reverse if it exists in this prop's [AnimationPlayer]
## node.
## This method is a shorthand for [method play_animation] with [code]custom_speed = -1.0[/code]
## and [code]from_end = true[/code].
func play_animation_backwards(name: StringName = &"", custom_blend: float = -1) -> void:
if not has_node("AnimationPlayer"): return
$AnimationPlayer.play_backwards(name, custom_blend)
## Will stop the animation that is currently playing.
## The animation position is reset to [code]0[/code] and the [code]custom_speed[/code] is reset to
## [code]1.0[/code]. Set [param keep_state] to [code]true[/code] to avoid the animation to be
## updated visually.
## [i]This method is intended to be used inside a [method Popochiu.queue] of instructions.[/i]
func queue_stop_animation(keep_state: bool = false) -> Callable:
return func (): await stop_animation(keep_state)
## Will stop the animation that is currently playing.
## The animation position is reset to [code]0[/code] and the [code]custom_speed[/code] is reset to
## [code]1.0[/code]. Set [param keep_state] to [code]true[/code] to avoid the animation to be
## updated visually.
func stop_animation(keep_state: bool = false) -> void:
if not has_node("AnimationPlayer"): return
$AnimationPlayer.stop(keep_state)
## Will pause the animation that is currently playing.
## Call [method play_animation] without any parameters to resume the animation.
## [i]This method is intended to be used inside a [method Popochiu.queue] of instructions.[/i]
func queue_pause_animation() -> Callable:
return func (): await pause_animation()
## Will pause the animation that is currently playing on the Popochiu Prop.
## Will pause the animation that is currently playing.
## Call [method play_animation] without any parameters to resume the animation.
func pause_animation() -> void:
if not has_node("AnimationPlayer"): return
$AnimationPlayer.pause()
## Return [code]true[/code] if an animation is playing, otherwise it will return [code]false[/code].
func is_animation_playing() -> bool:
if not has_node("AnimationPlayer"): return false
return $AnimationPlayer.is_playing()
## Returns the string name of the currently assigned animation in the [AnimationPlayer] node.
func get_assigned_animation() -> String:
if not has_node("AnimationPlayer"): return ""
return $AnimationPlayer.assigned_animation
## Sets the animation key name for the currently assigned animation in the [AnimationPlayer] node.
func set_assigned_animation(name: StringName) -> void:
if not has_node("AnimationPlayer"): return
$AnimationPlayer.assigned_animation = name
## Will return the current Popochiu Prop animation position in seconds.
## returns -1.0 if there is an error.
func get_current_animation_position() -> float:
if not has_node("AnimationPlayer"): return -1.0
return $AnimationPlayer.current_animation_position
#endregion
#region Private ####################################################################################
func _on_item_added(item: PopochiuInventoryItem, _animate: bool) -> void:
if item.script_name == link_to_item:
disable()
func _on_item_removed(item: PopochiuInventoryItem, _animate: bool) -> void:
if item.script_name == link_to_item:
_on_linked_item_removed()
linked_item_removed.emit(self)
func _on_item_discarded(item: PopochiuInventoryItem) -> void:
if item.script_name == link_to_item:
enable()
_on_linked_item_discarded()
linked_item_discarded.emit(self)
#endregion