]> Untitled Git - wolf-seeking-sheep.git/blob - addons/dialogic/Modules/Character/dialogic_portrait.gd
Squashed commit of the following:
[wolf-seeking-sheep.git] / addons / dialogic / Modules / Character / dialogic_portrait.gd
1 class_name DialogicPortrait
2 extends Node
3
4 ## Default portrait class. Should be extended by custom portraits.
5
6 ## Stores the character that this scene displays.
7 var character: DialogicCharacter
8 ## Stores the name of the current portrait.
9 var portrait: String
10
11 #region MAIN OVERRIDES
12 ################################################################################
13
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:
20         return false
21
22
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)
27 ##
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:
30         pass
31
32
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)
38 ##
39 ## This will only work as expected if the portrait is positioned so that the
40 ## root is at the pivot point.
41 ##
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)
48         return Rect2()
49
50
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:
56                         node.flip_h = mirror
57
58
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:
61         pass
62
63 #endregion
64
65 #region HIGHLIGHT OVERRIDES
66 ################################################################################
67
68 ## Called when this becomes the active speaker
69 func _highlight() -> void:
70         pass
71
72
73 ## Called when this stops being the active speaker
74 func _unhighlight() -> void:
75         pass
76 #endregion
77
78
79 #region HELPERS
80 ################################################################################
81
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
86
87         portrait = passed_portrait
88         character = passed_character
89
90
91 func apply_texture(node:Node, texture_path:String) -> void:
92         if not character or not character.portraits.has(portrait):
93                 return
94
95         if not "texture" in node:
96                 return
97
98         node.texture = null
99
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', '')
105                 else:
106                         return
107
108         node.texture = load(texture_path)
109
110         if node is Sprite2D or node is TextureRect:
111                 if node is Sprite2D:
112                         node.centered = false
113                 node.scale = Vector2.ONE
114                 if node is TextureRect:
115                         if !is_inside_tree():
116                                 await ready
117                 node.position = node.get_rect().size * Vector2(-0.5, -1)
118
119         set_meta('texture_holder_node', node)
120
121 #endregion