extends Control var z_index = 0 var character_data = { 'name': 'Default', 'image': "res://addons/dialogic/Example Assets/portraits/df-3.png", 'color': Color(0.973511, 1, 0.152344), 'file': '', 'mirror_portraits': false } var single_portrait_mode = false var dim_time = 0.5 var direction = 'left' var debug = false var fading_out = false var custom_instance : Node2D = null var current_state := {'character':'', 'portrait':'', 'position':'', 'mirrored':false} signal animation_finished func init(expression: String = '') -> void: set_portrait(expression) func _ready(): if debug: print('Character data loaded: ', character_data) print(rect_position, $TextureRect.rect_size) $AnimationTween.connect('finished_animation', self, 'emit_signal', ['animation_finished']) func set_portrait(expression: String) -> void: if expression == "(Don't change)": return if expression == '': expression = 'Default' current_state['portrait'] = expression # Clearing old custom scenes for n in get_children(): if 'DialogicCustomPortraitScene' in n.name: n.queue_free() custom_instance = null var default for p in character_data['portraits']: if p['name'] == expression: if is_scene(p['path']): # Creating a scene portrait var custom_node = load(p['path']) custom_instance = custom_node.instance() custom_instance.name = 'DialogicCustomPortraitScene' add_child(custom_instance) $TextureRect.texture = ImageTexture.new() return else: # Creating an image portrait if ResourceLoader.exists(p['path']): $TextureRect.texture = load(p['path']) else: $TextureRect.texture = ImageTexture.new() return # Saving what the default is to fallback to it. if p['name'] == 'Default': default = p['path'] # Everything failed, go with the default one if is_scene(default): push_warning('[Dialogic] Portrait missing: "' + expression + '". Maybe you deleted it? Update your timeline.') # Creating a scene portrait var custom_node = load(default) custom_instance = custom_node.instance() custom_instance.name = 'DialogicCustomPortraitScene' add_child(custom_instance) $TextureRect.texture = ImageTexture.new() return else: # Creating an image portrait if ResourceLoader.exists(default): $TextureRect.texture = load(default) else: $TextureRect.texture = ImageTexture.new() return func set_mirror(value): current_state['mirrored'] = value if character_data["data"].has('mirror_portraits'): if character_data["data"]['mirror_portraits']: if custom_instance != null: custom_instance.scale.x *= get_mirror_scale(custom_instance.scale.x, !value) else: $TextureRect.flip_h = !value else: if custom_instance != null: custom_instance.scale.x *= get_mirror_scale(custom_instance.scale.x, value) else: $TextureRect.flip_h = value else: if custom_instance != null: custom_instance.scale.x *= get_mirror_scale(custom_instance.scale.x, value) else: $TextureRect.flip_h = value func move_to_position(position_offset): var positions = { 'left': Vector2(-400, 0), 'right': Vector2(+400, 0), 'center': Vector2(0, 0), 'center_right': Vector2(200, 0), 'center_left': Vector2(-200, 0)} direction = position_offset rect_position = positions[position_offset] # Setting the scale of the portrait var custom_scale = Vector2(1, 1) if character_data.has('data'): if character_data['data'].has('scale'): custom_scale = Vector2( float(character_data['data']['scale']) / 100, float(character_data['data']['scale']) / 100 ) rect_scale = custom_scale if character_data['data'].has('offset_x'): rect_position += Vector2( character_data['data']['offset_x'], character_data['data']['offset_y'] ) if $TextureRect.get('texture'): rect_position -= Vector2( $TextureRect.texture.get_width() * 0.5, $TextureRect.texture.get_height() ) * custom_scale func animate(animation_name = '[No Animation]', time = 1, loop = 1, delete = false ): if animation_name == "[No Animation]": return if '_in' in animation_name: if custom_instance != null: custom_instance.modulate.a = 0 else: $TextureRect.modulate = Color(1,1,1,0) $AnimationTween.loop = loop if custom_instance != null: $AnimationTween.play(custom_instance, animation_name, time) else: $AnimationTween.play($TextureRect, animation_name, time) if delete: if !$AnimationTween.is_connected("tween_all_completed", self, "queue_free"): $AnimationTween.connect("tween_all_completed", self, "queue_free") func focus(): if not fading_out: tween_modulate(modulate, Color(1,1,1, 1)) func focusout(dim_color = Color(0.5, 0.5, 0.5, 1.0)): if single_portrait_mode: dim_color.a = 0 if not fading_out: tween_modulate(modulate, dim_color) func tween_modulate(from_value, to_value): $ModulationTween.stop(self, 'modulation') $ModulationTween.interpolate_property( self, "modulate", from_value, to_value, dim_time, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT ) $ModulationTween.start() return $ModulationTween func is_scene(path) -> bool: if '.tscn' in path.to_lower(): return true return false func get_mirror_scale(current_scale:float, mirror_value:bool) -> int: if mirror_value and current_scale > 0: return -1 else: return 1