Fix dialogue manager plugin, lower resolution

This commit is contained in:
2025-06-27 18:53:08 -07:00
parent 338e303fbb
commit 39f791e2b4
43 changed files with 1565 additions and 856 deletions

View File

@@ -5,219 +5,219 @@ namespace DialogueManagerRuntime
{
public partial class ExampleBalloon : CanvasLayer
{
[Export] public string NextAction = "ui_accept";
[Export] public string SkipAction = "ui_cancel";
[Export] public string NextAction = "ui_accept";
[Export] public string SkipAction = "ui_cancel";
Control balloon;
RichTextLabel characterLabel;
RichTextLabel dialogueLabel;
VBoxContainer responsesMenu;
Control balloon;
RichTextLabel characterLabel;
RichTextLabel dialogueLabel;
VBoxContainer responsesMenu;
Resource resource;
Array<Variant> temporaryGameStates = new Array<Variant>();
bool isWaitingForInput = false;
bool willHideBalloon = false;
Resource resource;
Array<Variant> temporaryGameStates = new Array<Variant>();
bool isWaitingForInput = false;
bool willHideBalloon = false;
DialogueLine dialogueLine;
DialogueLine DialogueLine
{
get => dialogueLine;
set
{
if (value == null)
{
QueueFree();
return;
}
DialogueLine dialogueLine;
DialogueLine DialogueLine
{
get => dialogueLine;
set
{
if (value == null)
{
QueueFree();
return;
}
dialogueLine = value;
ApplyDialogueLine();
}
}
dialogueLine = value;
ApplyDialogueLine();
}
}
Timer MutationCooldown = new Timer();
Timer MutationCooldown = new Timer();
public override void _Ready()
{
balloon = GetNode<Control>("%Balloon");
characterLabel = GetNode<RichTextLabel>("%CharacterLabel");
dialogueLabel = GetNode<RichTextLabel>("%DialogueLabel");
responsesMenu = GetNode<VBoxContainer>("%ResponsesMenu");
public override void _Ready()
{
balloon = GetNode<Control>("%Balloon");
characterLabel = GetNode<RichTextLabel>("%CharacterLabel");
dialogueLabel = GetNode<RichTextLabel>("%DialogueLabel");
responsesMenu = GetNode<VBoxContainer>("%ResponsesMenu");
balloon.Hide();
balloon.Hide();
balloon.GuiInput += (@event) =>
{
if ((bool)dialogueLabel.Get("is_typing"))
{
bool mouseWasClicked = @event is InputEventMouseButton && (@event as InputEventMouseButton).ButtonIndex == MouseButton.Left && @event.IsPressed();
bool skipButtonWasPressed = @event.IsActionPressed(SkipAction);
if (mouseWasClicked || skipButtonWasPressed)
{
GetViewport().SetInputAsHandled();
dialogueLabel.Call("skip_typing");
return;
}
}
balloon.GuiInput += (@event) =>
{
if ((bool)dialogueLabel.Get("is_typing"))
{
bool mouseWasClicked = @event is InputEventMouseButton && (@event as InputEventMouseButton).ButtonIndex == MouseButton.Left && @event.IsPressed();
bool skipButtonWasPressed = @event.IsActionPressed(SkipAction);
if (mouseWasClicked || skipButtonWasPressed)
{
GetViewport().SetInputAsHandled();
dialogueLabel.Call("skip_typing");
return;
}
}
if (!isWaitingForInput) return;
if (dialogueLine.Responses.Count > 0) return;
if (!isWaitingForInput) return;
if (dialogueLine.Responses.Count > 0) return;
GetViewport().SetInputAsHandled();
GetViewport().SetInputAsHandled();
if (@event is InputEventMouseButton && @event.IsPressed() && (@event as InputEventMouseButton).ButtonIndex == MouseButton.Left)
{
Next(dialogueLine.NextId);
}
else if (@event.IsActionPressed(NextAction) && GetViewport().GuiGetFocusOwner() == balloon)
{
Next(dialogueLine.NextId);
}
};
if (@event is InputEventMouseButton && @event.IsPressed() && (@event as InputEventMouseButton).ButtonIndex == MouseButton.Left)
{
Next(dialogueLine.NextId);
}
else if (@event.IsActionPressed(NextAction) && GetViewport().GuiGetFocusOwner() == balloon)
{
Next(dialogueLine.NextId);
}
};
if (string.IsNullOrEmpty((string)responsesMenu.Get("next_action")))
{
responsesMenu.Set("next_action", NextAction);
}
responsesMenu.Connect("response_selected", Callable.From((DialogueResponse response) =>
{
Next(response.NextId);
}));
if (string.IsNullOrEmpty((string)responsesMenu.Get("next_action")))
{
responsesMenu.Set("next_action", NextAction);
}
responsesMenu.Connect("response_selected", Callable.From((DialogueResponse response) =>
{
Next(response.NextId);
}));
// Hide the balloon when a mutation is running
MutationCooldown.Timeout += () =>
{
if (willHideBalloon)
{
willHideBalloon = false;
balloon.Hide();
}
};
AddChild(MutationCooldown);
// Hide the balloon when a mutation is running
MutationCooldown.Timeout += () =>
{
if (willHideBalloon)
{
willHideBalloon = false;
balloon.Hide();
}
};
AddChild(MutationCooldown);
DialogueManager.Mutated += OnMutated;
}
DialogueManager.Mutated += OnMutated;
}
public override void _ExitTree()
{
DialogueManager.Mutated -= OnMutated;
}
public override void _ExitTree()
{
DialogueManager.Mutated -= OnMutated;
}
public override void _UnhandledInput(InputEvent @event)
{
// Only the balloon is allowed to handle input while it's showing
GetViewport().SetInputAsHandled();
}
public override void _UnhandledInput(InputEvent @event)
{
// Only the balloon is allowed to handle input while it's showing
GetViewport().SetInputAsHandled();
}
public override async void _Notification(int what)
{
// Detect a change of locale and update the current dialogue line to show the new language
if (what == NotificationTranslationChanged && IsInstanceValid(dialogueLabel))
{
float visibleRatio = dialogueLabel.VisibleRatio;
DialogueLine = await DialogueManager.GetNextDialogueLine(resource, DialogueLine.Id, temporaryGameStates);
if (visibleRatio < 1.0f)
{
dialogueLabel.Call("skip_typing");
}
}
}
public override async void _Notification(int what)
{
// Detect a change of locale and update the current dialogue line to show the new language
if (what == NotificationTranslationChanged && IsInstanceValid(dialogueLabel))
{
float visibleRatio = dialogueLabel.VisibleRatio;
DialogueLine = await DialogueManager.GetNextDialogueLine(resource, DialogueLine.Id, temporaryGameStates);
if (visibleRatio < 1.0f)
{
dialogueLabel.Call("skip_typing");
}
}
}
public async void Start(Resource dialogueResource, string title, Array<Variant> extraGameStates = null)
{
temporaryGameStates = new Array<Variant> { this } + (extraGameStates ?? new Array<Variant>());
isWaitingForInput = false;
resource = dialogueResource;
public async void Start(Resource dialogueResource, string title, Array<Variant> extraGameStates = null)
{
temporaryGameStates = new Array<Variant> { this } + (extraGameStates ?? new Array<Variant>());
isWaitingForInput = false;
resource = dialogueResource;
DialogueLine = await DialogueManager.GetNextDialogueLine(resource, title, temporaryGameStates);
}
DialogueLine = await DialogueManager.GetNextDialogueLine(resource, title, temporaryGameStates);
}
public async void Next(string nextId)
{
DialogueLine = await DialogueManager.GetNextDialogueLine(resource, nextId, temporaryGameStates);
}
public async void Next(string nextId)
{
DialogueLine = await DialogueManager.GetNextDialogueLine(resource, nextId, temporaryGameStates);
}
#region Helpers
#region Helpers
private async void ApplyDialogueLine()
{
MutationCooldown.Stop();
private async void ApplyDialogueLine()
{
MutationCooldown.Stop();
isWaitingForInput = false;
balloon.FocusMode = Control.FocusModeEnum.All;
balloon.GrabFocus();
isWaitingForInput = false;
balloon.FocusMode = Control.FocusModeEnum.All;
balloon.GrabFocus();
// Set up the character name
characterLabel.Visible = !string.IsNullOrEmpty(dialogueLine.Character);
characterLabel.Text = Tr(dialogueLine.Character, "dialogue");
// Set up the character name
characterLabel.Visible = !string.IsNullOrEmpty(dialogueLine.Character);
characterLabel.Text = Tr(dialogueLine.Character, "dialogue");
// Set up the dialogue
dialogueLabel.Hide();
dialogueLabel.Set("dialogue_line", dialogueLine);
// Set up the dialogue
dialogueLabel.Hide();
dialogueLabel.Set("dialogue_line", dialogueLine);
// Set up the responses
responsesMenu.Hide();
responsesMenu.Set("responses", dialogueLine.Responses);
// Set up the responses
responsesMenu.Hide();
responsesMenu.Set("responses", dialogueLine.Responses);
// Type out the text
balloon.Show();
willHideBalloon = false;
dialogueLabel.Show();
if (!string.IsNullOrEmpty(dialogueLine.Text))
{
dialogueLabel.Call("type_out");
await ToSignal(dialogueLabel, "finished_typing");
}
// Type out the text
balloon.Show();
willHideBalloon = false;
dialogueLabel.Show();
if (!string.IsNullOrEmpty(dialogueLine.Text))
{
dialogueLabel.Call("type_out");
await ToSignal(dialogueLabel, "finished_typing");
}
// Wait for input
if (dialogueLine.Responses.Count > 0)
{
balloon.FocusMode = Control.FocusModeEnum.None;
responsesMenu.Show();
}
else if (!string.IsNullOrEmpty(dialogueLine.Time))
{
float time = 0f;
if (!float.TryParse(dialogueLine.Time, out time))
{
time = dialogueLine.Text.Length * 0.02f;
}
await ToSignal(GetTree().CreateTimer(time), "timeout");
Next(dialogueLine.NextId);
}
else
{
isWaitingForInput = true;
balloon.FocusMode = Control.FocusModeEnum.All;
balloon.GrabFocus();
}
}
// Wait for input
if (dialogueLine.Responses.Count > 0)
{
balloon.FocusMode = Control.FocusModeEnum.None;
responsesMenu.Show();
}
else if (!string.IsNullOrEmpty(dialogueLine.Time))
{
float time = 0f;
if (!float.TryParse(dialogueLine.Time, out time))
{
time = dialogueLine.Text.Length * 0.02f;
}
await ToSignal(GetTree().CreateTimer(time), "timeout");
Next(dialogueLine.NextId);
}
else
{
isWaitingForInput = true;
balloon.FocusMode = Control.FocusModeEnum.All;
balloon.GrabFocus();
}
}
#endregion
#endregion
#region signals
#region signals
private void OnMutated(Dictionary _mutation)
{
isWaitingForInput = false;
willHideBalloon = true;
MutationCooldown.Start(0.1f);
}
private void OnMutated(Dictionary _mutation)
{
isWaitingForInput = false;
willHideBalloon = true;
MutationCooldown.Start(0.1f);
}
#endregion
#endregion
}
}

View File

@@ -40,7 +40,7 @@ corner_radius_top_right = 5
corner_radius_bottom_right = 5
corner_radius_bottom_left = 5
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_uy0d5"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qkmqt"]
bg_color = Color(0, 0, 0, 1)
border_width_left = 3
border_width_top = 3
@@ -61,7 +61,7 @@ MarginContainer/constants/margin_bottom = 15
MarginContainer/constants/margin_left = 30
MarginContainer/constants/margin_right = 30
MarginContainer/constants/margin_top = 15
Panel/styles/panel = SubResource("StyleBoxFlat_uy0d5")
PanelContainer/styles/panel = SubResource("StyleBoxFlat_qkmqt")
[node name="ExampleBalloon" type="CanvasLayer"]
layer = 100
@@ -77,33 +77,28 @@ grow_horizontal = 2
grow_vertical = 2
theme = SubResource("Theme_qq3yp")
[node name="Panel" type="Panel" parent="Balloon"]
clip_children = 2
[node name="MarginContainer" type="MarginContainer" parent="Balloon"]
layout_mode = 1
anchors_preset = 12
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 21.0
offset_top = -183.0
offset_right = -19.0
offset_bottom = -19.0
offset_top = -219.0
grow_horizontal = 2
grow_vertical = 0
[node name="PanelContainer" type="PanelContainer" parent="Balloon/MarginContainer"]
clip_children = 2
layout_mode = 2
mouse_filter = 1
[node name="Dialogue" type="MarginContainer" parent="Balloon/Panel"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="VBoxContainer" type="VBoxContainer" parent="Balloon/Panel/Dialogue"]
[node name="MarginContainer" type="MarginContainer" parent="Balloon/MarginContainer/PanelContainer"]
layout_mode = 2
[node name="CharacterLabel" type="RichTextLabel" parent="Balloon/Panel/Dialogue/VBoxContainer"]
[node name="VBoxContainer" type="VBoxContainer" parent="Balloon/MarginContainer/PanelContainer/MarginContainer"]
layout_mode = 2
[node name="CharacterLabel" type="RichTextLabel" parent="Balloon/MarginContainer/PanelContainer/MarginContainer/VBoxContainer"]
unique_name_in_owner = true
modulate = Color(1, 1, 1, 0.501961)
layout_mode = 2
@@ -113,37 +108,35 @@ text = "Character"
fit_content = true
scroll_active = false
[node name="DialogueLabel" parent="Balloon/Panel/Dialogue/VBoxContainer" instance=ExtResource("2_a8ve6")]
[node name="DialogueLabel" parent="Balloon/MarginContainer/PanelContainer/MarginContainer/VBoxContainer" instance=ExtResource("2_a8ve6")]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 3
text = "Dialogue..."
[node name="Responses" type="MarginContainer" parent="Balloon"]
layout_mode = 1
anchors_preset = 7
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = -147.0
offset_top = -558.0
offset_right = 494.0
offset_bottom = -154.0
grow_horizontal = 2
grow_vertical = 0
[node name="ResponsesMenu" type="VBoxContainer" parent="Balloon/Responses" node_paths=PackedStringArray("response_template")]
[node name="ResponsesMenu" type="VBoxContainer" parent="Balloon" node_paths=PackedStringArray("response_template")]
unique_name_in_owner = true
layout_mode = 2
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -290.5
offset_top = -35.0
offset_right = 290.5
offset_bottom = 35.0
grow_horizontal = 2
grow_vertical = 2
size_flags_vertical = 8
theme_override_constants/separation = 2
alignment = 1
script = ExtResource("3_72ixx")
response_template = NodePath("ResponseExample")
[node name="ResponseExample" type="Button" parent="Balloon/Responses/ResponsesMenu"]
[node name="ResponseExample" type="Button" parent="Balloon/ResponsesMenu"]
layout_mode = 2
text = "Response example"
[connection signal="gui_input" from="Balloon" to="." method="_on_balloon_gui_input"]
[connection signal="response_selected" from="Balloon/Responses/ResponsesMenu" to="." method="_on_responses_menu_response_selected"]
[connection signal="response_selected" from="Balloon/ResponsesMenu" to="." method="_on_responses_menu_response_selected"]

View File

@@ -66,7 +66,7 @@ corner_radius_top_right = 3
corner_radius_bottom_right = 3
corner_radius_bottom_left = 3
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_uy0d5"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_i6nbm"]
bg_color = Color(0, 0, 0, 1)
border_width_left = 1
border_width_top = 1
@@ -87,7 +87,7 @@ MarginContainer/constants/margin_bottom = 4
MarginContainer/constants/margin_left = 8
MarginContainer/constants/margin_right = 8
MarginContainer/constants/margin_top = 4
Panel/styles/panel = SubResource("StyleBoxFlat_uy0d5")
PanelContainer/styles/panel = SubResource("StyleBoxFlat_i6nbm")
[node name="ExampleBalloon" type="CanvasLayer"]
layer = 100
@@ -103,33 +103,28 @@ grow_horizontal = 2
grow_vertical = 2
theme = SubResource("Theme_qq3yp")
[node name="Panel" type="Panel" parent="Balloon"]
clip_children = 2
[node name="MarginContainer" type="MarginContainer" parent="Balloon"]
layout_mode = 1
anchors_preset = 12
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 3.0
offset_top = -62.0
offset_right = -4.0
offset_bottom = -4.0
offset_top = -71.0
grow_horizontal = 2
grow_vertical = 0
[node name="PanelContainer" type="PanelContainer" parent="Balloon/MarginContainer"]
clip_children = 2
layout_mode = 2
mouse_filter = 1
[node name="Dialogue" type="MarginContainer" parent="Balloon/Panel"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="VBoxContainer" type="VBoxContainer" parent="Balloon/Panel/Dialogue"]
[node name="MarginContainer" type="MarginContainer" parent="Balloon/MarginContainer/PanelContainer"]
layout_mode = 2
[node name="CharacterLabel" type="RichTextLabel" parent="Balloon/Panel/Dialogue/VBoxContainer"]
[node name="VBoxContainer" type="VBoxContainer" parent="Balloon/MarginContainer/PanelContainer/MarginContainer"]
layout_mode = 2
[node name="CharacterLabel" type="RichTextLabel" parent="Balloon/MarginContainer/PanelContainer/MarginContainer/VBoxContainer"]
unique_name_in_owner = true
modulate = Color(1, 1, 1, 0.501961)
layout_mode = 2
@@ -139,36 +134,33 @@ text = "Character"
fit_content = true
scroll_active = false
[node name="DialogueLabel" parent="Balloon/Panel/Dialogue/VBoxContainer" instance=ExtResource("2_hfvdi")]
[node name="DialogueLabel" parent="Balloon/MarginContainer/PanelContainer/MarginContainer/VBoxContainer" instance=ExtResource("2_hfvdi")]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 3
text = "Dialogue..."
[node name="Responses" type="MarginContainer" parent="Balloon"]
layout_mode = 1
anchors_preset = 7
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = -124.0
offset_top = -218.0
offset_right = 125.0
offset_bottom = -50.0
grow_horizontal = 2
grow_vertical = 0
[node name="ResponsesMenu" type="VBoxContainer" parent="Balloon/Responses"]
[node name="ResponsesMenu" type="VBoxContainer" parent="Balloon"]
unique_name_in_owner = true
layout_mode = 2
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -116.5
offset_top = -9.0
offset_right = 116.5
offset_bottom = 9.0
grow_horizontal = 2
grow_vertical = 2
size_flags_vertical = 8
theme_override_constants/separation = 2
script = ExtResource("3_1j1j0")
[node name="ResponseExample" type="Button" parent="Balloon/Responses/ResponsesMenu"]
[node name="ResponseExample" type="Button" parent="Balloon/ResponsesMenu"]
layout_mode = 2
text = "Response Example"
[connection signal="gui_input" from="Balloon" to="." method="_on_balloon_gui_input"]
[connection signal="response_selected" from="Balloon/Responses/ResponsesMenu" to="." method="_on_responses_menu_response_selected"]
[connection signal="response_selected" from="Balloon/ResponsesMenu" to="." method="_on_responses_menu_response_selected"]