You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
4.0 KiB
120 lines
4.0 KiB
6 months ago
|
class_name DialogicPortrait
|
||
|
extends Node
|
||
|
|
||
|
## Default portrait class. Should be extended by custom portraits.
|
||
|
|
||
|
## Stores the character that this scene displays.
|
||
|
var character: DialogicCharacter
|
||
|
## Stores the name of the current portrait.
|
||
|
var portrait: String
|
||
|
|
||
|
#region MAIN OVERRIDES
|
||
|
################################################################################
|
||
|
|
||
|
## This function can be overridden.
|
||
|
## If this returns true, it won't insatnce a new scene, but call _update_portrait on this one.
|
||
|
## This is only relevant if the next portrait uses the same scene.
|
||
|
## This allows implmenting transitions between portraits that use the same scene.
|
||
|
func _should_do_portrait_update(character:DialogicCharacter, portrait:String) -> bool:
|
||
|
return true
|
||
|
|
||
|
|
||
|
## If the custom portrait accepts a change, then accept it here
|
||
|
## You should position your portrait so that the root node is at the pivot point*.
|
||
|
## For example for a simple sprite this code would work:
|
||
|
## >>> $Sprite.position = $Sprite.get_rect().size * Vector2(-0.5, -1)
|
||
|
##
|
||
|
## * this depends on the portrait containers, but it will most likely be the bottom center (99% of cases)
|
||
|
func _update_portrait(passed_character:DialogicCharacter, passed_portrait:String) -> void:
|
||
|
pass
|
||
|
|
||
|
|
||
|
## This should be implemented. It is used for sizing in the
|
||
|
## character editor preview and in portrait containers.
|
||
|
## Scale and offset will be applied by dialogic.
|
||
|
## For example for a simple sprite this should work:
|
||
|
## >>> return Rect2($Sprite.position, $Sprite.get_rect().size)
|
||
|
##
|
||
|
## This will only work as expected if the portrait is positioned so that the root is at the pivot point.
|
||
|
##
|
||
|
## If you've used apply_texture this should work automatically.
|
||
|
func _get_covered_rect() -> Rect2:
|
||
|
if has_meta('texture_holder_node') and get_meta('texture_holder_node', null) != null and is_instance_valid(get_meta('texture_holder_node')):
|
||
|
var node: Node = get_meta('texture_holder_node')
|
||
|
if node is Sprite2D or node is TextureRect:
|
||
|
return Rect2(node.position, node.get_rect().size)
|
||
|
return Rect2()
|
||
|
|
||
|
|
||
|
## If implemented, this is called when the mirror changes
|
||
|
func _set_mirror(mirror:bool) -> void:
|
||
|
if has_meta('texture_holder_node') and get_meta('texture_holder_node', null) != null and is_instance_valid(get_meta('texture_holder_node')):
|
||
|
var node: Node = get_meta('texture_holder_node')
|
||
|
if node is Sprite2D or node is TextureRect:
|
||
|
node.flip_h = mirror
|
||
|
|
||
|
|
||
|
## Function to accept and use the extra data, if the custom portrait wants to accept it
|
||
|
func _set_extra_data(data: String) -> void:
|
||
|
pass
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region HIGHLIGHT OVERRIDES
|
||
|
################################################################################
|
||
|
|
||
|
## Called when this becomes the active speaker
|
||
|
func _highlight() -> void:
|
||
|
pass
|
||
|
|
||
|
|
||
|
## Called when this stops being the active speaker
|
||
|
func _unhighlight() -> void:
|
||
|
pass
|
||
|
#endregion
|
||
|
|
||
|
|
||
|
#region HELPERS
|
||
|
################################################################################
|
||
|
|
||
|
## Helper that quickly setups and checks the character and portrait.
|
||
|
func apply_character_and_portrait(passed_character:DialogicCharacter, passed_portrait:String) -> void:
|
||
|
if passed_portrait == "" or not passed_portrait in passed_character.portraits.keys():
|
||
|
passed_portrait = passed_character.default_portrait
|
||
|
|
||
|
portrait = passed_portrait
|
||
|
character = passed_character
|
||
|
|
||
|
|
||
|
func apply_texture(node:Node, texture_path:String) -> void:
|
||
|
if not character or not character.portraits.has(portrait):
|
||
|
return
|
||
|
|
||
|
if not "texture" in node:
|
||
|
return
|
||
|
|
||
|
node.texture = null
|
||
|
|
||
|
if not ResourceLoader.exists(texture_path):
|
||
|
# This is a leftover from alpha.
|
||
|
# Removing this will break any portraits made before alpha-10
|
||
|
if ResourceLoader.exists(character.portraits[portrait].get('image', '')):
|
||
|
texture_path = character.portraits[portrait].get('image', '')
|
||
|
else:
|
||
|
return
|
||
|
|
||
|
node.texture = load(texture_path)
|
||
|
|
||
|
if node is Sprite2D or node is TextureRect:
|
||
|
if node is Sprite2D:
|
||
|
node.centered = false
|
||
|
node.scale = Vector2.ONE
|
||
|
if node is TextureRect:
|
||
|
if !is_inside_tree():
|
||
|
await ready
|
||
|
node.position = node.get_rect().size * Vector2(-0.5, -1)
|
||
|
|
||
|
set_meta('texture_holder_node', node)
|
||
|
|
||
|
#endregion
|