First work on dialogic, resized guild, and started implementing portraits.
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
[style]
|
||||
type = "Layer"
|
||||
name = "Textbubble Layer"
|
||||
author = "Dialogic"
|
||||
description = "A simple textbubble layer. Expects a textbubble base. Each textbubble provides a name label, dialog text and choices."
|
||||
scene = "text_bubble_layer.tscn"
|
||||
icon = "text_bubble_layer_icon.svg"
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 7.1 KiB |
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://x0kxo1qd4jqf"
|
||||
path="res://.godot/imported/preview.png-136e526350ab989f1e1d2ba13d756aaa.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/dialogic/Modules/DefaultLayoutParts/Layer_Textbubble/preview.png"
|
||||
dest_files=["res://.godot/imported/preview.png-136e526350ab989f1e1d2ba13d756aaa.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
@@ -0,0 +1,17 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform sampler2D deformation_sampler : filter_linear, repeat_enable;
|
||||
uniform float radius :hint_range(1.0, 200, 0.01)= 25;
|
||||
uniform vec2 box_size = vec2(100, 100);
|
||||
uniform float box_padding = 15;
|
||||
uniform float wobble_amount : hint_range(0.0, 1.0, 0.01) = 0.2;
|
||||
uniform float wobble_speed : hint_range(0.0, 10.0, 0.01) = 1;
|
||||
uniform float wobble_detail : hint_range(0.01, 1, 0.01) = 0.5;
|
||||
|
||||
void fragment() {
|
||||
float adjusted_radius = min(min(radius, box_size.x/2.0), box_size.y/2.0);
|
||||
vec2 deformation_sample = texture(deformation_sampler, UV*wobble_detail+TIME*wobble_speed*0.05).xy*(vec2(box_padding)/box_size)*0.9;
|
||||
vec2 deformed_UV = UV+((deformation_sample)-vec2(0.5)*vec2(box_padding)/box_size)*wobble_amount;
|
||||
float rounded_box = length(max(abs(deformed_UV*(box_size+vec2(box_padding))-vec2(0.5)*(box_size+vec2(box_padding)))+adjusted_radius-vec2(0.5)*box_size,0))-adjusted_radius;
|
||||
COLOR.a = min(smoothstep(0.0, -1, rounded_box), COLOR.a);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://fevg6633ljkf
|
||||
@@ -0,0 +1,202 @@
|
||||
extends Control
|
||||
|
||||
@onready var tail: Line2D = ($Group/Tail as Line2D)
|
||||
@onready var bubble: Control = ($Group/Background as Control)
|
||||
@onready var text: DialogicNode_DialogText = (%DialogText as DialogicNode_DialogText)
|
||||
# The choice container is added by the TextBubble layer
|
||||
@onready var choice_container: Container = null
|
||||
@onready var name_label: Label = (%NameLabel as Label)
|
||||
@onready var name_label_box: PanelContainer = (%NameLabelPanel as PanelContainer)
|
||||
@onready var name_label_holder: HBoxContainer = $DialogText/NameLabelPositioner
|
||||
|
||||
var node_to_point_at: Node = null
|
||||
var current_character: DialogicCharacter = null
|
||||
|
||||
var max_width := 300
|
||||
|
||||
var bubble_rect: Rect2 = Rect2(0.0, 0.0, 2.0, 2.0)
|
||||
var base_position := Vector2.ZERO
|
||||
|
||||
var base_direction := Vector2(1.0, -1.0).normalized()
|
||||
var safe_zone := 50.0
|
||||
var padding := Vector2()
|
||||
|
||||
var name_label_alignment := HBoxContainer.ALIGNMENT_BEGIN
|
||||
var name_label_offset := Vector2()
|
||||
var force_choices_on_separate_lines := false
|
||||
|
||||
# Sets the padding shader paramter.
|
||||
# It's the amount of spacing around the background to allow some wobbeling.
|
||||
var bg_padding := 30
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
reset()
|
||||
DialogicUtil.autoload().Choices.question_shown.connect(_on_question_shown)
|
||||
|
||||
|
||||
func reset() -> void:
|
||||
scale = Vector2.ZERO
|
||||
modulate.a = 0.0
|
||||
|
||||
tail.points = []
|
||||
bubble_rect = Rect2(0,0,2,2)
|
||||
|
||||
base_position = get_speaker_canvas_position()
|
||||
position = base_position
|
||||
|
||||
|
||||
func _process(delta:float) -> void:
|
||||
base_position = get_speaker_canvas_position()
|
||||
|
||||
var center := get_viewport_rect().size / 2.0
|
||||
|
||||
var dist_x := absf(base_position.x - center.x)
|
||||
var dist_y := absf(base_position.y - center.y)
|
||||
var x_e := center.x - bubble_rect.size.x
|
||||
var y_e := center.y - bubble_rect.size.y
|
||||
var influence_x := remap(clamp(dist_x, x_e, center.x), x_e, center.x * 0.8, 0.0, 1.0)
|
||||
var influence_y := remap(clamp(dist_y, y_e, center.y), y_e, center.y * 0.8, 0.0, 1.0)
|
||||
if base_position.x > center.x: influence_x = -influence_x
|
||||
if base_position.y > center.y: influence_y = -influence_y
|
||||
var edge_influence := Vector2(influence_x, influence_y)
|
||||
|
||||
var direction := (base_direction + edge_influence).normalized()
|
||||
|
||||
var p: Vector2 = base_position + direction * (
|
||||
safe_zone + lerp(bubble_rect.size.y, bubble_rect.size.x, abs(direction.x)) * 0.4
|
||||
)
|
||||
p = p.clamp(bubble_rect.size / 2.0, get_viewport_rect().size - bubble_rect.size / 2.0)
|
||||
|
||||
position = position.lerp(p, 5 * delta)
|
||||
|
||||
var point_a: Vector2 = Vector2.ZERO
|
||||
var point_b: Vector2 = (base_position - position) * 0.75
|
||||
|
||||
var offset: Vector2 = Vector2.from_angle(point_a.angle_to_point(point_b)) * bubble_rect.size * abs(direction.x) * 0.4
|
||||
|
||||
point_a += offset
|
||||
point_b += offset * 0.5
|
||||
|
||||
var curve := Curve2D.new()
|
||||
var direction_point := Vector2(0, (point_b.y - point_a.y))
|
||||
curve.add_point(point_a, Vector2.ZERO, direction_point * 0.5)
|
||||
curve.add_point(point_b)
|
||||
tail.points = curve.tessellate(5)
|
||||
tail.width = bubble_rect.size.x * 0.15
|
||||
|
||||
|
||||
func open() -> void:
|
||||
set_process(true)
|
||||
show()
|
||||
text.enabled = true
|
||||
var open_tween := create_tween().set_parallel(true)
|
||||
open_tween.tween_property(self, "scale", Vector2.ONE, 0.1).from(Vector2.ZERO)
|
||||
open_tween.tween_property(self, "modulate:a", 1.0, 0.1).from(0.0)
|
||||
|
||||
|
||||
func close() -> void:
|
||||
text.enabled = false
|
||||
var close_tween := create_tween().set_parallel(true)
|
||||
close_tween.tween_property(self, "scale", Vector2.ONE * 0.8, 0.2)
|
||||
close_tween.tween_property(self, "modulate:a", 0.0, 0.2)
|
||||
await close_tween.finished
|
||||
hide()
|
||||
set_process(false)
|
||||
|
||||
|
||||
func _on_dialog_text_started_revealing_text() -> void:
|
||||
_resize_bubble(get_base_content_size(), true)
|
||||
|
||||
|
||||
func _resize_bubble(content_size:Vector2, popup:=false) -> void:
|
||||
var bubble_size: Vector2 = content_size+(padding*2)+Vector2.ONE*bg_padding
|
||||
var half_size: Vector2= (bubble_size / 2.0)
|
||||
bubble.pivot_offset = half_size
|
||||
bubble_rect = Rect2(position, bubble_size * Vector2(1.1, 1.1))
|
||||
bubble.position = -half_size
|
||||
bubble.size = bubble_size
|
||||
|
||||
text.size = content_size
|
||||
text.position = -(content_size/2.0)
|
||||
|
||||
if popup:
|
||||
var t := create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK)
|
||||
t.tween_property(bubble, "scale", Vector2.ONE, 0.2).from(Vector2.ZERO)
|
||||
else:
|
||||
bubble.scale = Vector2.ONE
|
||||
|
||||
bubble.material.set(&"shader_parameter/box_size", bubble_size)
|
||||
name_label_holder.position = Vector2(0, bubble.position.y - text.position.y - name_label_holder.size.y/2.0)
|
||||
name_label_holder.position += name_label_offset
|
||||
name_label_holder.alignment = name_label_alignment
|
||||
name_label_holder.size.x = text.size.x
|
||||
|
||||
|
||||
func _on_question_shown(info:Dictionary) -> void:
|
||||
if !is_visible_in_tree():
|
||||
return
|
||||
|
||||
await get_tree().process_frame
|
||||
|
||||
var content_size := get_base_content_size()
|
||||
content_size.y += choice_container.size.y
|
||||
content_size.x = max(content_size.x, choice_container.size.x)
|
||||
_resize_bubble(content_size)
|
||||
|
||||
|
||||
func get_base_content_size() -> Vector2:
|
||||
var font: Font = text.get_theme_font(&"normal_font")
|
||||
return font.get_multiline_string_size(
|
||||
text.get_parsed_text(),
|
||||
HORIZONTAL_ALIGNMENT_LEFT,
|
||||
max_width,
|
||||
text.get_theme_font_size(&"normal_font_size")
|
||||
)
|
||||
|
||||
|
||||
func add_choice_container(node:Container, alignment:=FlowContainer.ALIGNMENT_BEGIN) -> void:
|
||||
if choice_container:
|
||||
choice_container.get_parent().remove_child(choice_container)
|
||||
choice_container.queue_free()
|
||||
|
||||
node.name = "ChoiceContainer"
|
||||
choice_container = node
|
||||
node.set_anchors_preset(LayoutPreset.PRESET_BOTTOM_WIDE)
|
||||
node.grow_vertical = Control.GROW_DIRECTION_BEGIN
|
||||
text.add_child(node)
|
||||
|
||||
if node is HFlowContainer:
|
||||
(node as HFlowContainer).alignment = alignment
|
||||
|
||||
for i:int in range(5):
|
||||
choice_container.add_child(DialogicNode_ChoiceButton.new())
|
||||
if node is HFlowContainer:
|
||||
continue
|
||||
match alignment:
|
||||
HBoxContainer.ALIGNMENT_BEGIN:
|
||||
(choice_container.get_child(-1) as Control).size_flags_horizontal = SIZE_SHRINK_BEGIN
|
||||
HBoxContainer.ALIGNMENT_CENTER:
|
||||
(choice_container.get_child(-1) as Control).size_flags_horizontal = SIZE_SHRINK_CENTER
|
||||
HBoxContainer.ALIGNMENT_END:
|
||||
(choice_container.get_child(-1) as Control).size_flags_horizontal = SIZE_SHRINK_END
|
||||
|
||||
for child:Button in choice_container.get_children():
|
||||
var prev := child.get_parent().get_child(wrap(child.get_index()-1, 0, choice_container.get_child_count()-1)).get_path()
|
||||
var next := child.get_parent().get_child(wrap(child.get_index()+1, 0, choice_container.get_child_count()-1)).get_path()
|
||||
child.focus_next = next
|
||||
child.focus_previous = prev
|
||||
child.focus_neighbor_left = prev
|
||||
child.focus_neighbor_top = prev
|
||||
child.focus_neighbor_right = next
|
||||
child.focus_neighbor_bottom = next
|
||||
|
||||
|
||||
func get_speaker_canvas_position() -> Vector2:
|
||||
if is_instance_valid(node_to_point_at):
|
||||
if node_to_point_at is Node3D:
|
||||
base_position = get_viewport().get_camera_3d().unproject_position(
|
||||
(node_to_point_at as Node3D).global_position)
|
||||
if node_to_point_at is CanvasItem:
|
||||
base_position = (node_to_point_at as CanvasItem).get_global_transform_with_canvas().origin
|
||||
return base_position
|
||||
@@ -0,0 +1 @@
|
||||
uid://dxmbq8y6byxip
|
||||
@@ -0,0 +1,17 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform sampler2D deformation_sampler : filter_linear, repeat_enable;
|
||||
uniform float radius : hint_range(1.0, 200, 0.01) = 25;
|
||||
uniform vec2 box_size = vec2(100, 100);
|
||||
uniform float box_padding = 15;
|
||||
uniform float wobble_amount : hint_range(0.0, 1.0, 0.01) = 0.2;
|
||||
uniform float wobble_speed : hint_range(0.0, 10.0, 0.01) = 1;
|
||||
uniform float wobble_detail : hint_range(0.01, 1, 0.01) = 0.5;
|
||||
|
||||
void fragment() {
|
||||
float adjusted_radius = min(min(radius, box_size.x/2.0), box_size.y/2.0);
|
||||
vec2 deformation_sample = texture(deformation_sampler, UV*wobble_detail+TIME*wobble_speed*0.05).xy*(vec2(box_padding)/box_size)*0.9;
|
||||
vec2 deformed_UV = UV+((deformation_sample)-vec2(0.5)*vec2(box_padding)/box_size)*wobble_amount;
|
||||
float rounded_box = length(max(abs(deformed_UV*(box_size+vec2(box_padding))-vec2(0.5)*(box_size+vec2(box_padding)))+adjusted_radius-vec2(0.5)*box_size,0))-adjusted_radius;
|
||||
COLOR.a = min(smoothstep(0.0, -1, rounded_box), COLOR.a);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://dl6kcmkb7sjil
|
||||
@@ -0,0 +1,111 @@
|
||||
[gd_scene load_steps=11 format=3 uid="uid://dlx7jcvm52tyw"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/dialogic/Modules/DefaultLayoutParts/Layer_Textbubble/text_bubble.gd" id="1_jdhpk"]
|
||||
[ext_resource type="Shader" path="res://addons/dialogic/Modules/DefaultLayoutParts/Layer_Textbubble/text_bubble.gdshader" id="2_1mhvf"]
|
||||
[ext_resource type="Script" path="res://addons/dialogic/Modules/Text/node_dialog_text.gd" id="3_syv35"]
|
||||
[ext_resource type="Script" path="res://addons/dialogic/Modules/Text/node_type_sound.gd" id="4_7bm4b"]
|
||||
[ext_resource type="Script" path="res://addons/dialogic/Modules/Text/node_name_label.gd" id="6_5gd03"]
|
||||
|
||||
[sub_resource type="Curve" id="Curve_0j8nu"]
|
||||
_data = [Vector2(0, 1), 0.0, -1.0, 0, 1, Vector2(1, 0), -1.0, 0.0, 1, 0]
|
||||
point_count = 2
|
||||
|
||||
[sub_resource type="FastNoiseLite" id="FastNoiseLite_lsfnp"]
|
||||
noise_type = 0
|
||||
fractal_type = 0
|
||||
cellular_jitter = 0.15
|
||||
|
||||
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_kr7hw"]
|
||||
seamless = true
|
||||
noise = SubResource("FastNoiseLite_lsfnp")
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_60xbe"]
|
||||
resource_local_to_scene = true
|
||||
shader = ExtResource("2_1mhvf")
|
||||
shader_parameter/radius = 200.0
|
||||
shader_parameter/box_size = Vector2(100, 100)
|
||||
shader_parameter/box_padding = 10.0
|
||||
shader_parameter/wobble_amount = 0.75
|
||||
shader_parameter/wobble_speed = 10.0
|
||||
shader_parameter/wobble_detail = 0.51
|
||||
shader_parameter/deformation_sampler = SubResource("NoiseTexture2D_kr7hw")
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_h6ls0"]
|
||||
content_margin_left = 5.0
|
||||
content_margin_right = 5.0
|
||||
bg_color = Color(1, 1, 1, 1)
|
||||
corner_radius_top_left = 10
|
||||
corner_radius_top_right = 10
|
||||
corner_radius_bottom_right = 10
|
||||
corner_radius_bottom_left = 10
|
||||
shadow_color = Color(0.152941, 0.152941, 0.152941, 0.12549)
|
||||
shadow_size = 5
|
||||
|
||||
[node name="TextBubble" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
script = ExtResource("1_jdhpk")
|
||||
|
||||
[node name="Group" type="CanvasGroup" parent="."]
|
||||
|
||||
[node name="Tail" type="Line2D" parent="Group"]
|
||||
unique_name_in_owner = true
|
||||
points = PackedVector2Array(-9, 7, -29, 118, -95, 174, -193, 195)
|
||||
width = 96.0
|
||||
width_curve = SubResource("Curve_0j8nu")
|
||||
|
||||
[node name="Background" type="ColorRect" parent="Group"]
|
||||
unique_name_in_owner = true
|
||||
material = SubResource("ShaderMaterial_60xbe")
|
||||
offset_left = -115.0
|
||||
offset_top = -69.0
|
||||
offset_right = 108.0
|
||||
offset_bottom = 83.0
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="DialogText" type="RichTextLabel" parent="." node_paths=PackedStringArray("textbox_root")]
|
||||
unique_name_in_owner = true
|
||||
clip_contents = false
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -53.0
|
||||
offset_top = -13.0
|
||||
offset_right = 53.0
|
||||
offset_bottom = 12.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_colors/default_color = Color(0, 0, 0, 1)
|
||||
scroll_active = false
|
||||
visible_characters_behavior = 1
|
||||
script = ExtResource("3_syv35")
|
||||
textbox_root = NodePath("..")
|
||||
|
||||
[node name="DialogicNode_TypeSounds" type="AudioStreamPlayer" parent="DialogText"]
|
||||
script = ExtResource("4_7bm4b")
|
||||
|
||||
[node name="NameLabelPositioner" type="HBoxContainer" parent="DialogText"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 10
|
||||
anchor_right = 1.0
|
||||
offset_bottom = 23.0
|
||||
grow_horizontal = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="NameLabelPanel" type="PanelContainer" parent="DialogText/NameLabelPositioner"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_h6ls0")
|
||||
|
||||
[node name="NameLabel" type="Label" parent="DialogText/NameLabelPositioner/NameLabelPanel" node_paths=PackedStringArray("name_label_root")]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
horizontal_alignment = 1
|
||||
script = ExtResource("6_5gd03")
|
||||
name_label_root = NodePath("..")
|
||||
use_character_color = false
|
||||
|
||||
[connection signal="started_revealing_text" from="DialogText" to="." method="_on_dialog_text_started_revealing_text"]
|
||||
@@ -0,0 +1,185 @@
|
||||
@tool
|
||||
extends DialogicLayoutLayer
|
||||
|
||||
## This layout won't do anything on its own
|
||||
|
||||
@export_group("Main")
|
||||
@export_subgroup("Text")
|
||||
@export var text_size: int = 15
|
||||
@export var text_color: Color = Color.BLACK
|
||||
@export_file('*.ttf') var normal_font: String = ""
|
||||
@export_file('*.ttf') var bold_font: String = ""
|
||||
@export_file('*.ttf') var italic_font: String = ""
|
||||
@export_file('*.ttf') var bold_italic_font: String = ""
|
||||
@export var text_max_width: int = 300
|
||||
|
||||
@export_subgroup('Box')
|
||||
@export var box_modulate: Color = Color.WHITE
|
||||
@export var box_modulate_by_character_color: bool = false
|
||||
@export var box_padding: Vector2 = Vector2(10,10)
|
||||
@export_range(1, 999) var box_corner_radius: int = 25
|
||||
@export_range(0.1, 5) var box_wobble_speed: float = 1
|
||||
@export_range(0, 1) var box_wobble_amount: float = 0.5
|
||||
@export_range(0, 1) var box_wobble_detail: float = 0.2
|
||||
|
||||
@export_subgroup('Behaviour')
|
||||
@export var behaviour_distance: int = 50
|
||||
@export var behaviour_direction: Vector2 = Vector2(1, -1)
|
||||
|
||||
@export_group('Name Label')
|
||||
@export_subgroup("Name Label")
|
||||
@export var name_label_enabled: bool = true
|
||||
@export var name_label_font_size: int = 15
|
||||
@export_file('*.ttf') var name_label_font: String = ""
|
||||
@export var name_label_use_character_color: bool = true
|
||||
@export var name_label_color: Color = Color.BLACK
|
||||
@export_subgroup("Name Label Box")
|
||||
@export var name_label_box_modulate: Color = Color.WHITE
|
||||
@export var name_label_box_modulate_use_character_color: bool = false
|
||||
@export var name_label_padding: Vector2 = Vector2(5,0)
|
||||
@export var name_label_offset: Vector2 = Vector2(0,0)
|
||||
@export var name_label_alignment := HBoxContainer.ALIGNMENT_BEGIN
|
||||
|
||||
|
||||
@export_group('Choices')
|
||||
@export_subgroup('Choices Text')
|
||||
@export var choices_text_size: int = 15
|
||||
@export_file('*.ttf') var choices_text_font: String = ""
|
||||
@export var choices_text_color: Color = Color.DARK_SLATE_GRAY
|
||||
@export var choices_text_color_hover: Color = Color.DARK_MAGENTA
|
||||
@export var choices_text_color_focus: Color = Color.DARK_MAGENTA
|
||||
@export var choices_text_color_disabled: Color = Color.DARK_GRAY
|
||||
|
||||
@export_subgroup('Choices Layout')
|
||||
@export var choices_layout_alignment := FlowContainer.ALIGNMENT_END
|
||||
@export var choices_layout_force_lines: bool = false
|
||||
@export_file('*.tres', "*.res") var choices_base_theme: String = ""
|
||||
|
||||
const TextBubble := preload("res://addons/dialogic/Modules/DefaultLayoutParts/Layer_Textbubble/text_bubble.gd")
|
||||
|
||||
var bubbles: Array[TextBubble] = []
|
||||
var fallback_bubble: TextBubble = null
|
||||
|
||||
const textbubble_scene: PackedScene = preload("res://addons/dialogic/Modules/DefaultLayoutParts/Layer_Textbubble/text_bubble.tscn")
|
||||
|
||||
|
||||
func add_bubble() -> TextBubble:
|
||||
var new_bubble: TextBubble = textbubble_scene.instantiate()
|
||||
add_child(new_bubble)
|
||||
bubbles.append(new_bubble)
|
||||
return new_bubble
|
||||
|
||||
|
||||
## Called by dialogic whenever export overrides might change
|
||||
func _apply_export_overrides() -> void:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
## Called by the base layer before opening the bubble
|
||||
func bubble_apply_overrides(bubble:TextBubble) -> void:
|
||||
## TEXT FONT AND COLOR
|
||||
var rtl: RichTextLabel = bubble.text
|
||||
rtl.add_theme_font_size_override(&'normal_font', text_size)
|
||||
rtl.add_theme_font_size_override(&"normal_font_size", text_size)
|
||||
rtl.add_theme_font_size_override(&"bold_font_size", text_size)
|
||||
rtl.add_theme_font_size_override(&"italics_font_size", text_size)
|
||||
rtl.add_theme_font_size_override(&"bold_italics_font_size", text_size)
|
||||
|
||||
rtl.add_theme_color_override(&"default_color", text_color)
|
||||
|
||||
if !normal_font.is_empty():
|
||||
rtl.add_theme_font_override(&"normal_font", load(normal_font) as Font)
|
||||
if !bold_font.is_empty():
|
||||
rtl.add_theme_font_override(&"bold_font", load(bold_font) as Font)
|
||||
if !italic_font.is_empty():
|
||||
rtl.add_theme_font_override(&"italitc_font", load(italic_font) as Font)
|
||||
if !bold_italic_font.is_empty():
|
||||
rtl.add_theme_font_override(&"bold_italics_font", load(bold_italic_font) as Font)
|
||||
bubble.set(&'max_width', text_max_width)
|
||||
|
||||
|
||||
## BOX & TAIL COLOR
|
||||
var tail_and_bg_group := (bubble.get_node("Group") as CanvasGroup)
|
||||
tail_and_bg_group.self_modulate = box_modulate
|
||||
if box_modulate_by_character_color and bubble.current_character != null:
|
||||
tail_and_bg_group.self_modulate = bubble.current_character.color
|
||||
|
||||
var background := (bubble.get_node('%Background') as ColorRect)
|
||||
var bg_material: ShaderMaterial = (background.material as ShaderMaterial)
|
||||
bg_material.set_shader_parameter(&'radius', box_corner_radius)
|
||||
bg_material.set_shader_parameter(&'wobble_amount', box_wobble_amount)
|
||||
bg_material.set_shader_parameter(&'wobble_speed', box_wobble_speed)
|
||||
bg_material.set_shader_parameter(&'wobble_detail', box_wobble_detail)
|
||||
|
||||
bubble.padding = box_padding
|
||||
|
||||
|
||||
## BEHAVIOUR
|
||||
bubble.safe_zone = behaviour_distance
|
||||
bubble.base_direction = behaviour_direction
|
||||
|
||||
|
||||
## NAME LABEL SETTINGS
|
||||
var nl: DialogicNode_NameLabel = bubble.name_label
|
||||
nl.add_theme_font_size_override(&"font_size", name_label_font_size)
|
||||
|
||||
if !name_label_font.is_empty():
|
||||
nl.add_theme_font_override(&'font', load(name_label_font) as Font)
|
||||
|
||||
|
||||
if name_label_use_character_color and bubble.current_character:
|
||||
nl.add_theme_color_override(&"font_color", bubble.current_character.color)
|
||||
else:
|
||||
nl.add_theme_color_override(&"font_color", name_label_color)
|
||||
|
||||
var nlp: PanelContainer = bubble.name_label_box
|
||||
nlp.self_modulate = name_label_box_modulate
|
||||
if name_label_box_modulate_use_character_color and bubble.current_character:
|
||||
nlp.self_modulate = bubble.current_character.color
|
||||
nlp.get_theme_stylebox(&'panel').content_margin_left = name_label_padding.x
|
||||
nlp.get_theme_stylebox(&'panel').content_margin_right = name_label_padding.x
|
||||
nlp.get_theme_stylebox(&'panel').content_margin_top = name_label_padding.y
|
||||
nlp.get_theme_stylebox(&'panel').content_margin_bottom = name_label_padding.y
|
||||
bubble.name_label_offset = name_label_offset
|
||||
bubble.name_label_alignment = name_label_alignment
|
||||
|
||||
nlp.get_parent().visible = name_label_enabled
|
||||
|
||||
## CHOICE SETTINGS
|
||||
if choices_layout_force_lines:
|
||||
bubble.add_choice_container(VBoxContainer.new(), choices_layout_alignment)
|
||||
else:
|
||||
bubble.add_choice_container(HFlowContainer.new(), choices_layout_alignment)
|
||||
|
||||
var choice_theme: Theme = null
|
||||
if choices_base_theme.is_empty() or not ResourceLoader.exists(choices_base_theme):
|
||||
choice_theme = Theme.new()
|
||||
var base_style := StyleBoxFlat.new()
|
||||
base_style.draw_center = false
|
||||
base_style.border_width_bottom = 2
|
||||
base_style.border_color = choices_text_color
|
||||
choice_theme.set_stylebox(&'normal', &'Button', base_style)
|
||||
var focus_style := (base_style.duplicate() as StyleBoxFlat)
|
||||
focus_style.border_color = choices_text_color_focus
|
||||
choice_theme.set_stylebox(&'focus', &'Button', focus_style)
|
||||
var hover_style := (base_style.duplicate() as StyleBoxFlat)
|
||||
hover_style.border_color = choices_text_color_hover
|
||||
choice_theme.set_stylebox(&'hover', &'Button', hover_style)
|
||||
var disabled_style := (base_style.duplicate() as StyleBoxFlat)
|
||||
disabled_style.border_color = choices_text_color_disabled
|
||||
choice_theme.set_stylebox(&'disabled', &'Button', disabled_style)
|
||||
choice_theme.set_stylebox(&'pressed', &'Button', base_style)
|
||||
else:
|
||||
choice_theme = (load(choices_base_theme) as Theme)
|
||||
|
||||
if !choices_text_font.is_empty():
|
||||
choice_theme.default_font = (load(choices_text_font) as Font)
|
||||
|
||||
choice_theme.set_font_size(&'font_size', &'Button', choices_text_size)
|
||||
choice_theme.set_color(&'font_color', &'Button', choices_text_color)
|
||||
choice_theme.set_color(&'font_pressed_color', &'Button', choices_text_color)
|
||||
choice_theme.set_color(&'font_hover_color', &'Button', choices_text_color_hover)
|
||||
choice_theme.set_color(&'font_focus_color', &'Button', choices_text_color_focus)
|
||||
choice_theme.set_color(&'font_disabled_color', &'Button', choices_text_color_disabled)
|
||||
bubble.choice_container.theme = choice_theme
|
||||
@@ -0,0 +1 @@
|
||||
uid://bnveym4ubsn3g
|
||||
@@ -0,0 +1,9 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://d2it0xiap3gnt"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/dialogic/Modules/DefaultLayoutParts/Layer_Textbubble/text_bubble_layer.gd" id="1_b37je"]
|
||||
|
||||
[node name="TextBubbleLayer" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
mouse_filter = 2
|
||||
script = ExtResource("1_b37je")
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg width="100" height="100" viewBox="0 0 26.458333 26.458333" version="1.1" id="svg13076" inkscape:export-filename="input_layer_icon.svg" inkscape:export-xdpi="96" inkscape:export-ydpi="96" inkscape:version="1.2.2 (732a01da63, 2022-12-09)" sodipodi:docname="text_bubble_layer_icon.svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview id="namedview13078" pagecolor="#505050" bordercolor="#eeeeee" borderopacity="1" inkscape:showpageshadow="0" inkscape:pageopacity="0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#505050" inkscape:document-units="mm" showgrid="true" inkscape:zoom="5.9184838" inkscape:cx="61.502239" inkscape:cy="68.598651" inkscape:window-width="1920" inkscape:window-height="1017" inkscape:window-x="-8" inkscape:window-y="-8" inkscape:window-maximized="1" inkscape:current-layer="layer1">
|
||||
<inkscape:grid type="xygrid" id="grid14286" />
|
||||
</sodipodi:namedview>
|
||||
<defs id="defs13073" />
|
||||
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1">
|
||||
<rect x="4.0595255" y="7.3477197" width="18.477333" height="10.384831" rx="1.759746" stroke="#ffffff" stroke-width="1.46627" id="rect30126" style="fill:#ffffff;fill-opacity:1" />
|
||||
<rect x="4.4799924" y="3.1119337" width="6.9150147" height="2.1797333" rx="0.65857279" stroke="#ffffff" stroke-width="0.410954" id="rect1570" style="fill:#ffffff;fill-opacity:1" />
|
||||
<path style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke-width:1.88;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.2" d="m 5.8208333,22.489583 c 2.507191,-1.706008 3.833717,-3.283474 4.7624997,-5.291666 l 5.820833,-1e-6 c 0.106809,2.563666 -4.892406,4.003771 -10.5833327,5.291667" id="path1626" sodipodi:nodetypes="cccc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,44 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dgpyaea4qw8a5"
|
||||
path="res://.godot/imported/text_bubble_layer_icon.svg-d46d5806bbf83c1dc50f8d7fc8dac67d.ctex"
|
||||
metadata={
|
||||
"has_editor_variant": true,
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/dialogic/Modules/DefaultLayoutParts/Layer_Textbubble/text_bubble_layer_icon.svg"
|
||||
dest_files=["res://.godot/imported/text_bubble_layer_icon.svg-d46d5806bbf83c1dc50f8d7fc8dac67d.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
svg/scale=0.3
|
||||
editor/scale_with_editor_scale=true
|
||||
editor/convert_colors_with_editor_theme=true
|
||||
Reference in New Issue
Block a user