1 class_name DialogicPortrait
4 ## Default portrait class. Should be extended by custom portraits.
6 ## Stores the character that this scene displays.
7 var character: DialogicCharacter
8 ## Stores the name of the current portrait.
11 #region MAIN OVERRIDES
12 ################################################################################
14 ## This function can be overridden.
15 ## If this returns true, it won't instance a new scene, but call
16 ## [method _update_portrait] on this one.
17 ## This is only relevant if the next portrait uses the same scene.
18 ## This allows implementing transitions between portraits that use the same scene.
19 func _should_do_portrait_update(_character: DialogicCharacter, _portrait: String) -> bool:
23 ## If the custom portrait accepts a change, then accept it here
24 ## You should position your portrait so that the root node is at the pivot point*.
25 ## For example for a simple sprite this code would work:
26 ## >>> $Sprite.position = $Sprite.get_rect().size * Vector2(-0.5, -1)
28 ## * this depends on the portrait containers, but it will most likely be the bottom center (99% of cases)
29 func _update_portrait(_passed_character: DialogicCharacter, _passed_portrait: String) -> void:
33 ## This should be implemented. It is used for sizing in the
34 ## character editor preview and in portrait containers.
35 ## Scale and offset will be applied by Dialogic.
36 ## For example, a simple sprite:
37 ## >>> return Rect2($Sprite.position, $Sprite.get_rect().size)
39 ## This will only work as expected if the portrait is positioned so that the
40 ## root is at the pivot point.
42 ## If you've used apply_texture this should work automatically.
43 func _get_covered_rect() -> Rect2:
44 if has_meta('texture_holder_node') and get_meta('texture_holder_node', null) != null and is_instance_valid(get_meta('texture_holder_node')):
45 var node: Node = get_meta('texture_holder_node')
46 if node is Sprite2D or node is TextureRect:
47 return Rect2(node.position, node.get_rect().size)
51 ## If implemented, this is called when the mirror changes
52 func _set_mirror(mirror:bool) -> void:
53 if has_meta('texture_holder_node') and get_meta('texture_holder_node', null) != null and is_instance_valid(get_meta('texture_holder_node')):
54 var node: Node = get_meta('texture_holder_node')
55 if node is Sprite2D or node is TextureRect:
59 ## Function to accept and use the extra data, if the custom portrait wants to accept it
60 func _set_extra_data(_data: String) -> void:
65 #region HIGHLIGHT OVERRIDES
66 ################################################################################
68 ## Called when this becomes the active speaker
69 func _highlight() -> void:
73 ## Called when this stops being the active speaker
74 func _unhighlight() -> void:
80 ################################################################################
82 ## Helper that quickly setups and checks the character and portrait.
83 func apply_character_and_portrait(passed_character:DialogicCharacter, passed_portrait:String) -> void:
84 if passed_portrait == "" or not passed_portrait in passed_character.portraits.keys():
85 passed_portrait = passed_character.default_portrait
87 portrait = passed_portrait
88 character = passed_character
91 func apply_texture(node:Node, texture_path:String) -> void:
92 if not character or not character.portraits.has(portrait):
95 if not "texture" in node:
100 if not ResourceLoader.exists(texture_path):
101 # This is a leftover from alpha.
102 # Removing this will break any portraits made before alpha-10
103 if ResourceLoader.exists(character.portraits[portrait].get('image', '')):
104 texture_path = character.portraits[portrait].get('image', '')
108 node.texture = load(texture_path)
110 if node is Sprite2D or node is TextureRect:
112 node.centered = false
113 node.scale = Vector2.ONE
114 if node is TextureRect:
115 if !is_inside_tree():
117 node.position = node.get_rect().size * Vector2(-0.5, -1)
119 set_meta('texture_holder_node', node)