Compare commits
	
		
			5 Commits 
		
	
	
		
			d63a93bb93
			...
			5be84f6b84
		
	
	| Author | SHA1 | Date | 
|---|---|---|
| 
							
							
								
									
								
								 | 
						5be84f6b84 | |
| 
							
							
								
									
								
								 | 
						78daa89ba6 | |
| 
							
							
								
									
								
								 | 
						71f14c5121 | |
| 
							
							
								
									
								
								 | 
						b13eb48b99 | |
| 
							
							
								
									
								
								 | 
						dde1d18bc5 | 
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
[remap]
 | 
					[remap]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
importer="dialogue_manager_compiler_11"
 | 
					importer="dialogue_manager_compiler_12"
 | 
				
			||||||
type="Resource"
 | 
					type="Resource"
 | 
				
			||||||
uid="uid://dilmuoilweoeh"
 | 
					uid="uid://dilmuoilweoeh"
 | 
				
			||||||
path="res://.godot/imported/books.dialogue-cc272ebae322ae3ca46820dca11a3437.tres"
 | 
					path="res://.godot/imported/books.dialogue-cc272ebae322ae3ca46820dca11a3437.tres"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
[remap]
 | 
					[remap]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
importer="dialogue_manager_compiler_11"
 | 
					importer="dialogue_manager_compiler_12"
 | 
				
			||||||
type="Resource"
 | 
					type="Resource"
 | 
				
			||||||
uid="uid://c2om4y0fm81yr"
 | 
					uid="uid://c2om4y0fm81yr"
 | 
				
			||||||
path="res://.godot/imported/clone-machine.dialogue-8810934a67eacdad52469e9ef5f970fb.tres"
 | 
					path="res://.godot/imported/clone-machine.dialogue-8810934a67eacdad52469e9ef5f970fb.tres"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
[remap]
 | 
					[remap]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
importer="dialogue_manager_compiler_11"
 | 
					importer="dialogue_manager_compiler_12"
 | 
				
			||||||
type="Resource"
 | 
					type="Resource"
 | 
				
			||||||
uid="uid://dntkvjjr8mrgf"
 | 
					uid="uid://dntkvjjr8mrgf"
 | 
				
			||||||
path="res://.godot/imported/doc.dialogue-8f95f6a09d3ac685b71d7e07c49df1c6.tres"
 | 
					path="res://.godot/imported/doc.dialogue-8f95f6a09d3ac685b71d7e07c49df1c6.tres"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								| 
		 After Width: | Height: | Size: 189 B  | 
| 
						 | 
					@ -0,0 +1,34 @@
 | 
				
			||||||
 | 
					[remap]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					importer="texture"
 | 
				
			||||||
 | 
					type="CompressedTexture2D"
 | 
				
			||||||
 | 
					uid="uid://dc1gcsbhkchvg"
 | 
				
			||||||
 | 
					path="res://.godot/imported/hotbar-active.png-7657e1b4001be05323aa0d0697509f58.ctex"
 | 
				
			||||||
 | 
					metadata={
 | 
				
			||||||
 | 
					"vram_texture": false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[deps]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					source_file="res://Assets/Sprites/UI/hotbar-active.png"
 | 
				
			||||||
 | 
					dest_files=["res://.godot/imported/hotbar-active.png-7657e1b4001be05323aa0d0697509f58.ctex"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[params]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					compress/mode=0
 | 
				
			||||||
 | 
					compress/high_quality=false
 | 
				
			||||||
 | 
					compress/lossy_quality=0.7
 | 
				
			||||||
 | 
					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/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
 | 
				
			||||||
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								| 
		 Before Width: | Height: | Size: 115 B After Width: | Height: | Size: 153 B  | 
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								| 
		 After Width: | Height: | Size: 832 B  | 
| 
						 | 
					@ -0,0 +1,34 @@
 | 
				
			||||||
 | 
					[remap]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					importer="texture"
 | 
				
			||||||
 | 
					type="CompressedTexture2D"
 | 
				
			||||||
 | 
					uid="uid://uhmowtsi3wfh"
 | 
				
			||||||
 | 
					path="res://.godot/imported/menu-rect-no-bg-white.png-5ea2d275879af97991070fb370031211.ctex"
 | 
				
			||||||
 | 
					metadata={
 | 
				
			||||||
 | 
					"vram_texture": false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[deps]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					source_file="res://Assets/Sprites/UI/menu-rect-no-bg-white.png"
 | 
				
			||||||
 | 
					dest_files=["res://.godot/imported/menu-rect-no-bg-white.png-5ea2d275879af97991070fb370031211.ctex"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[params]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					compress/mode=0
 | 
				
			||||||
 | 
					compress/high_quality=false
 | 
				
			||||||
 | 
					compress/lossy_quality=0.7
 | 
				
			||||||
 | 
					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/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
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
[remap]
 | 
					[remap]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
importer="dialogue_manager_compiler_11"
 | 
					importer="dialogue_manager_compiler_12"
 | 
				
			||||||
type="Resource"
 | 
					type="Resource"
 | 
				
			||||||
uid="uid://c4n7vhoxybu70"
 | 
					uid="uid://c4n7vhoxybu70"
 | 
				
			||||||
path="res://.godot/imported/snus-dealer.dialogue-69dbddee28632f18888364bae03f393d.tres"
 | 
					path="res://.godot/imported/snus-dealer.dialogue-69dbddee28632f18888364bae03f393d.tres"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,9 @@ public partial class Inventory : Node2D
 | 
				
			||||||
    [Signal]
 | 
					    [Signal]
 | 
				
			||||||
    public delegate void UsedItemEventHandler(Item item);
 | 
					    public delegate void UsedItemEventHandler(Item item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [Signal]
 | 
				
			||||||
 | 
					    public delegate void EquippedItemEventHandler(Item newItem, Item prevItem);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public const int MaxCapacity = 3;
 | 
					    public const int MaxCapacity = 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private Item _selectedItem;
 | 
					    private Item _selectedItem;
 | 
				
			||||||
| 
						 | 
					@ -87,7 +90,8 @@ public partial class Inventory : Node2D
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        _selectedItem?.Unequip(Character);
 | 
					        Item prevItem = _selectedItem;
 | 
				
			||||||
 | 
					        prevItem?.Unequip(Character);
 | 
				
			||||||
        _selectedIndex = index;
 | 
					        _selectedIndex = index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (index >= 0)
 | 
					        if (index >= 0)
 | 
				
			||||||
| 
						 | 
					@ -100,6 +104,8 @@ public partial class Inventory : Node2D
 | 
				
			||||||
            _selectedItem = null;
 | 
					            _selectedItem = null;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        EmitSignal(SignalName.EquippedItem, prevItem, _selectedItem);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        GD.Print($"Inventory: {index} is new selected index.");
 | 
					        GD.Print($"Inventory: {index} is new selected index.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,6 @@
 | 
				
			||||||
using Godot;
 | 
					using Godot;
 | 
				
			||||||
using SupaLidlGame.Items;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SupaLidlGame.UI;
 | 
					namespace SupaLidlGame.UI.Inventory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public partial class Hotbar : GridContainer
 | 
					public partial class Hotbar : GridContainer
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -13,7 +12,7 @@ public partial class Hotbar : GridContainer
 | 
				
			||||||
        Events.EventBus.Instance.PlayerInventoryUpdate += OnInventoryUpdate;
 | 
					        Events.EventBus.Instance.PlayerInventoryUpdate += OnInventoryUpdate;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void OnInventoryUpdate(Inventory inventory)
 | 
					    public void OnInventoryUpdate(Items.Inventory inventory)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        GD.Print($"UPDATE: {inventory.SelectedIndex} is selected index.");
 | 
					        GD.Print($"UPDATE: {inventory.SelectedIndex} is selected index.");
 | 
				
			||||||
        for (int i = 0; i < 3; i++)
 | 
					        for (int i = 0; i < 3; i++)
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
[gd_scene load_steps=3 format=3 uid="uid://sfs8dpfitpdu"]
 | 
					[gd_scene load_steps=3 format=3 uid="uid://sfs8dpfitpdu"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[ext_resource type="Script" path="res://UI/Hotbar.cs" id="1_2sak2"]
 | 
					[ext_resource type="Script" path="res://UI/Inventory/Hotbar.cs" id="1_2sak2"]
 | 
				
			||||||
[ext_resource type="PackedScene" uid="uid://ctad0dkoyw8ad" path="res://UI/InventorySlot.tscn" id="1_ct3cn"]
 | 
					[ext_resource type="PackedScene" uid="uid://dmvu2hjyrwc1y" path="res://UI/Inventory/HotbarSlot.tscn" id="2_3axfe"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[node name="Hotbar" type="GridContainer" node_paths=PackedStringArray("_slots")]
 | 
					[node name="Hotbar" type="GridContainer" node_paths=PackedStringArray("_slots")]
 | 
				
			||||||
anchors_preset = 1
 | 
					anchors_preset = 1
 | 
				
			||||||
| 
						 | 
					@ -15,11 +15,11 @@ columns = 3
 | 
				
			||||||
script = ExtResource("1_2sak2")
 | 
					script = ExtResource("1_2sak2")
 | 
				
			||||||
_slots = [NodePath("InventorySlot"), NodePath("InventorySlot2"), NodePath("InventorySlot3")]
 | 
					_slots = [NodePath("InventorySlot"), NodePath("InventorySlot2"), NodePath("InventorySlot3")]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[node name="InventorySlot" parent="." instance=ExtResource("1_ct3cn")]
 | 
					[node name="InventorySlot" parent="." instance=ExtResource("2_3axfe")]
 | 
				
			||||||
layout_mode = 2
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[node name="InventorySlot2" parent="." instance=ExtResource("1_ct3cn")]
 | 
					[node name="InventorySlot2" parent="." instance=ExtResource("2_3axfe")]
 | 
				
			||||||
layout_mode = 2
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[node name="InventorySlot3" parent="." instance=ExtResource("1_ct3cn")]
 | 
					[node name="InventorySlot3" parent="." instance=ExtResource("2_3axfe")]
 | 
				
			||||||
layout_mode = 2
 | 
					layout_mode = 2
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,32 @@
 | 
				
			||||||
 | 
					using Godot;
 | 
				
			||||||
 | 
					using GodotUtilities;
 | 
				
			||||||
 | 
					using GodotUtilities.SourceGenerators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace SupaLidlGame.UI.Inventory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Scene]
 | 
				
			||||||
 | 
					public partial class HotbarSlot : InventorySlot
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    [Node("TextureRect")]
 | 
				
			||||||
 | 
					    private TextureRect _textureRect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [Node("Selected")]
 | 
				
			||||||
 | 
					    private NinePatchRect _selected;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static Texture2D _placeholderTexture;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private Items.ItemMetadata _item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private bool _isSelected = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public bool IsSelected
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        get => _isSelected;
 | 
				
			||||||
 | 
					        set
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _isSelected = value;
 | 
				
			||||||
 | 
					            _selected.Visible = _isSelected;
 | 
				
			||||||
 | 
					            _frame.Visible = !_isSelected;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					[gd_scene load_steps=3 format=3 uid="uid://dmvu2hjyrwc1y"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[ext_resource type="PackedScene" uid="uid://ctad0dkoyw8ad" path="res://UI/Inventory/InventorySlot.tscn" id="1_fb62b"]
 | 
				
			||||||
 | 
					[ext_resource type="Texture2D" uid="uid://dc1gcsbhkchvg" path="res://Assets/Sprites/UI/hotbar-active.png" id="2_bcv71"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="InventorySlot" instance=ExtResource("1_fb62b")]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="SelectedFrame" type="NinePatchRect" parent="." index="2"]
 | 
				
			||||||
 | 
					visible = false
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					texture = ExtResource("2_bcv71")
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,59 @@
 | 
				
			||||||
 | 
					using Godot;
 | 
				
			||||||
 | 
					using GodotUtilities;
 | 
				
			||||||
 | 
					using SupaLidlGame.Items;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace SupaLidlGame.UI.Inventory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public partial class InventoryGrid : GridContainer
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    private SupaLidlGame.Items.Inventory _inventorySource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [Export]
 | 
				
			||||||
 | 
					    private PackedScene _slotScene;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public SupaLidlGame.Items.Inventory InventorySource
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        set
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _inventorySource = value;
 | 
				
			||||||
 | 
					            Redraw();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        get => _inventorySource;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void Redraw()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (_inventorySource is null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            this.QueueFreeChildren();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var children = GetChildren();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (int i = children.Count; i < _inventorySource.InventoryCapacity; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            AddChild(_slotScene.Instantiate<InventorySlot>());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (int i = children.Count - 1; i >= _inventorySource.InventoryCapacity; i--)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            children[i].QueueFree();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        children = GetChildren();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (int i = 0; i < children.Count; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            InventorySlot slot = children[i] as InventorySlot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (i >= _inventorySource.Items.Count)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                slot.Item = null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else if (slot.Item != _inventorySource.Items[i])
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                slot.Item = _inventorySource.Items[i];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,14 @@
 | 
				
			||||||
 | 
					[gd_scene load_steps=3 format=3 uid="uid://chmokkxsy5vas"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[ext_resource type="Script" path="res://UI/Inventory/InventoryGrid.cs" id="1_7128g"]
 | 
				
			||||||
 | 
					[ext_resource type="PackedScene" uid="uid://ctad0dkoyw8ad" path="res://UI/Inventory/InventorySlot.tscn" id="2_b6vp8"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="InventoryGrid" type="GridContainer"]
 | 
				
			||||||
 | 
					anchors_preset = 15
 | 
				
			||||||
 | 
					anchor_right = 1.0
 | 
				
			||||||
 | 
					anchor_bottom = 1.0
 | 
				
			||||||
 | 
					grow_horizontal = 2
 | 
				
			||||||
 | 
					grow_vertical = 2
 | 
				
			||||||
 | 
					columns = 5
 | 
				
			||||||
 | 
					script = ExtResource("1_7128g")
 | 
				
			||||||
 | 
					_slotScene = ExtResource("2_b6vp8")
 | 
				
			||||||
| 
						 | 
					@ -2,19 +2,31 @@ using Godot;
 | 
				
			||||||
using GodotUtilities;
 | 
					using GodotUtilities;
 | 
				
			||||||
using GodotUtilities.SourceGenerators;
 | 
					using GodotUtilities.SourceGenerators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SupaLidlGame.UI;
 | 
					namespace SupaLidlGame.UI.Inventory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Scene]
 | 
					public partial class InventorySlot : Container
 | 
				
			||||||
public partial class InventorySlot : ColorRect
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    [Node("TextureRect")]
 | 
					    private bool _isSelected = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public bool IsSelected
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        get => _isSelected;
 | 
				
			||||||
 | 
					        set
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _isSelected = value;
 | 
				
			||||||
 | 
					            if (_selectedFrame is not null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _selectedFrame.Visible = _isSelected;
 | 
				
			||||||
 | 
					                _frame.Visible = !_isSelected;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private TextureRect _textureRect;
 | 
					    private TextureRect _textureRect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Node("Selected")]
 | 
					    private NinePatchRect _frame;
 | 
				
			||||||
    private NinePatchRect _selected;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Node("Unselected")]
 | 
					    private NinePatchRect _selectedFrame;
 | 
				
			||||||
    private NinePatchRect _unselected;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static Texture2D _placeholderTexture;
 | 
					    private static Texture2D _placeholderTexture;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +41,6 @@ public partial class InventorySlot : ColorRect
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (_item is null)
 | 
					            if (_item is null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                //_textureRect.Texture = _placeholderTexture;
 | 
					 | 
				
			||||||
                _textureRect.Texture = null;
 | 
					                _textureRect.Texture = null;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
| 
						 | 
					@ -39,36 +50,16 @@ public partial class InventorySlot : ColorRect
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private bool _isSelected = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public bool IsSelected
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        get => _isSelected;
 | 
					 | 
				
			||||||
        set
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            _isSelected = value;
 | 
					 | 
				
			||||||
            _selected.Visible = _isSelected;
 | 
					 | 
				
			||||||
            _unselected.Visible = !_isSelected;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    static InventorySlot()
 | 
					    static InventorySlot()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        _placeholderTexture = ResourceLoader.Load<Texture2D>(
 | 
					        _placeholderTexture = ResourceLoader.Load<Texture2D>(
 | 
				
			||||||
            "res://Assets/Sprites/UI/hotbar-inactive.png");
 | 
					            "res://Assets/Sprites/UI/hotbar-inactive.png");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public override void _Notification(int what)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (what == NotificationSceneInstantiated)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            WireNodes();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        base._Notification(what);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public override void _Ready()
 | 
					    public override void _Ready()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        _textureRect = GetNode<TextureRect>("TextureRect");
 | 
				
			||||||
 | 
					        _frame = GetNode<NinePatchRect>("Frame");
 | 
				
			||||||
 | 
					        _selectedFrame = GetNode<NinePatchRect>("SelectedFrame");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					[gd_scene load_steps=4 format=3 uid="uid://ctad0dkoyw8ad"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[ext_resource type="Script" path="res://UI/Inventory/InventorySlot.cs" id="1_fju5i"]
 | 
				
			||||||
 | 
					[ext_resource type="Texture2D" uid="uid://dc1gcsbhkchvg" path="res://Assets/Sprites/UI/hotbar-active.png" id="2_m56j3"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_6jbma"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="InventorySlot" type="PanelContainer"]
 | 
				
			||||||
 | 
					custom_minimum_size = Vector2(32, 32)
 | 
				
			||||||
 | 
					theme_override_styles/panel = SubResource("StyleBoxEmpty_6jbma")
 | 
				
			||||||
 | 
					script = ExtResource("1_fju5i")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="TextureRect" type="TextureRect" parent="."]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					stretch_mode = 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="Frame" type="NinePatchRect" parent="."]
 | 
				
			||||||
 | 
					self_modulate = Color(1, 1, 1, 0.5)
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					texture = ExtResource("2_m56j3")
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,44 @@
 | 
				
			||||||
 | 
					[gd_scene load_steps=4 format=3 uid="uid://bsheehtfcdwhh"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[ext_resource type="Theme" uid="uid://cksjbu3vrup5" path="res://UI/Themes/supalidl.tres" id="1_elbte"]
 | 
				
			||||||
 | 
					[ext_resource type="Texture2D" uid="uid://dp7osg05ip5oo" path="res://Assets/Sprites/sword.png" id="2_5jpi0"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_idehr"]
 | 
				
			||||||
 | 
					bg_color = Color(0.976471, 0.956863, 0.956863, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="ShopItem" type="BoxContainer"]
 | 
				
			||||||
 | 
					offset_right = 67.0
 | 
				
			||||||
 | 
					offset_bottom = 16.0
 | 
				
			||||||
 | 
					theme = ExtResource("1_elbte")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="VBoxContainer" type="VBoxContainer" parent="."]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					theme_override_constants/separation = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="Item Margin" type="MarginContainer" parent="VBoxContainer"]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/Item Margin"]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="TextureRect" type="TextureRect" parent="VBoxContainer/Item Margin/HBoxContainer"]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					texture = ExtResource("2_5jpi0")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="Label" type="Label" parent="VBoxContainer/Item Margin/HBoxContainer"]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					text = "Your mom's Item"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="PanelContainer2" type="PanelContainer" parent="VBoxContainer"]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					theme_override_styles/panel = SubResource("StyleBoxFlat_idehr")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="DescriptionMargin" type="MarginContainer" parent="VBoxContainer/PanelContainer2"]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					theme_override_constants/margin_top = 2
 | 
				
			||||||
 | 
					theme_override_constants/margin_bottom = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="Label" type="Label" parent="VBoxContainer/PanelContainer2/DescriptionMargin"]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					theme_override_colors/font_color = Color(0, 0, 0, 1)
 | 
				
			||||||
 | 
					text = "250 Shillings"
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,78 @@
 | 
				
			||||||
 | 
					[gd_scene load_steps=6 format=3 uid="uid://cyggkyqosjk36"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[ext_resource type="Texture2D" uid="uid://uhmowtsi3wfh" path="res://Assets/Sprites/UI/menu-rect-no-bg-white.png" id="2_puklu"]
 | 
				
			||||||
 | 
					[ext_resource type="FontFile" uid="uid://cgwa8bjiyv534" path="res://Assets/Fonts/alagard.ttf" id="3_aj4jx"]
 | 
				
			||||||
 | 
					[ext_resource type="PackedScene" uid="uid://ctad0dkoyw8ad" path="res://UI/Inventory/InventorySlot.tscn" id="4_wawb8"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_gm1xk"]
 | 
				
			||||||
 | 
					bg_color = Color(0, 0, 0, 0.752941)
 | 
				
			||||||
 | 
					border_width_left = 16
 | 
				
			||||||
 | 
					border_width_top = 16
 | 
				
			||||||
 | 
					border_width_right = 16
 | 
				
			||||||
 | 
					border_width_bottom = 16
 | 
				
			||||||
 | 
					border_color = Color(0, 0, 0, 0)
 | 
				
			||||||
 | 
					border_blend = true
 | 
				
			||||||
 | 
					corner_radius_top_left = 16
 | 
				
			||||||
 | 
					corner_radius_top_right = 16
 | 
				
			||||||
 | 
					corner_radius_bottom_right = 16
 | 
				
			||||||
 | 
					corner_radius_bottom_left = 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[sub_resource type="StyleBoxTexture" id="StyleBoxTexture_bvu21"]
 | 
				
			||||||
 | 
					texture = ExtResource("2_puklu")
 | 
				
			||||||
 | 
					texture_margin_left = 32.0
 | 
				
			||||||
 | 
					texture_margin_top = 32.0
 | 
				
			||||||
 | 
					texture_margin_right = 32.0
 | 
				
			||||||
 | 
					texture_margin_bottom = 32.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="Panel" type="PanelContainer"]
 | 
				
			||||||
 | 
					anchors_preset = 6
 | 
				
			||||||
 | 
					anchor_left = 1.0
 | 
				
			||||||
 | 
					anchor_top = 0.5
 | 
				
			||||||
 | 
					anchor_right = 1.0
 | 
				
			||||||
 | 
					anchor_bottom = 0.5
 | 
				
			||||||
 | 
					offset_left = -236.0
 | 
				
			||||||
 | 
					offset_top = -175.5
 | 
				
			||||||
 | 
					offset_bottom = 175.5
 | 
				
			||||||
 | 
					grow_horizontal = 0
 | 
				
			||||||
 | 
					grow_vertical = 2
 | 
				
			||||||
 | 
					theme_override_styles/panel = SubResource("StyleBoxFlat_gm1xk")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="PanelContainer" type="PanelContainer" parent="."]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					theme_override_styles/panel = SubResource("StyleBoxTexture_bvu21")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer"]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="Label" type="Label" parent="PanelContainer/VBoxContainer"]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					theme_override_fonts/font = ExtResource("3_aj4jx")
 | 
				
			||||||
 | 
					text = "Snus Dealer"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="GridContainer" type="GridContainer" parent="PanelContainer/VBoxContainer"]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					columns = 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="InventorySlot" parent="PanelContainer/VBoxContainer/GridContainer" instance=ExtResource("4_wawb8")]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="InventorySlot2" parent="PanelContainer/VBoxContainer/GridContainer" instance=ExtResource("4_wawb8")]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="InventorySlot3" parent="PanelContainer/VBoxContainer/GridContainer" instance=ExtResource("4_wawb8")]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="InventorySlot4" parent="PanelContainer/VBoxContainer/GridContainer" instance=ExtResource("4_wawb8")]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="InventorySlot5" parent="PanelContainer/VBoxContainer/GridContainer" instance=ExtResource("4_wawb8")]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="InventorySlot6" parent="PanelContainer/VBoxContainer/GridContainer" instance=ExtResource("4_wawb8")]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="InventorySlot7" parent="PanelContainer/VBoxContainer/GridContainer" instance=ExtResource("4_wawb8")]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[node name="InventorySlot8" parent="PanelContainer/VBoxContainer/GridContainer" instance=ExtResource("4_wawb8")]
 | 
				
			||||||
 | 
					layout_mode = 2
 | 
				
			||||||
| 
						 | 
					@ -1,39 +0,0 @@
 | 
				
			||||||
[gd_scene load_steps=4 format=3 uid="uid://ctad0dkoyw8ad"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[ext_resource type="Script" path="res://UI/InventorySlot.cs" id="1_llonk"]
 | 
					 | 
				
			||||||
[ext_resource type="Texture2D" uid="uid://bd81g8aivb2ql" path="res://Assets/Sprites/UI/menu-rect-no-bg-32.png" id="2_vvog5"]
 | 
					 | 
				
			||||||
[ext_resource type="Texture2D" uid="uid://b16461tjso0j7" path="res://Assets/Sprites/UI/hotbar-inactive.png" id="3_jr23q"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[node name="InventorySlot" type="ColorRect"]
 | 
					 | 
				
			||||||
custom_minimum_size = Vector2(32, 32)
 | 
					 | 
				
			||||||
color = Color(1, 1, 1, 0)
 | 
					 | 
				
			||||||
script = ExtResource("1_llonk")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[node name="TextureRect" type="TextureRect" parent="."]
 | 
					 | 
				
			||||||
layout_mode = 1
 | 
					 | 
				
			||||||
anchors_preset = 15
 | 
					 | 
				
			||||||
anchor_right = 1.0
 | 
					 | 
				
			||||||
anchor_bottom = 1.0
 | 
					 | 
				
			||||||
grow_horizontal = 2
 | 
					 | 
				
			||||||
grow_vertical = 2
 | 
					 | 
				
			||||||
stretch_mode = 3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[node name="Selected" type="NinePatchRect" parent="."]
 | 
					 | 
				
			||||||
visible = false
 | 
					 | 
				
			||||||
layout_mode = 1
 | 
					 | 
				
			||||||
anchors_preset = 15
 | 
					 | 
				
			||||||
anchor_right = 1.0
 | 
					 | 
				
			||||||
anchor_bottom = 1.0
 | 
					 | 
				
			||||||
grow_horizontal = 2
 | 
					 | 
				
			||||||
grow_vertical = 2
 | 
					 | 
				
			||||||
texture = ExtResource("2_vvog5")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[node name="Unselected" type="NinePatchRect" parent="."]
 | 
					 | 
				
			||||||
self_modulate = Color(1, 1, 1, 0.5)
 | 
					 | 
				
			||||||
layout_mode = 1
 | 
					 | 
				
			||||||
anchors_preset = 15
 | 
					 | 
				
			||||||
anchor_right = 1.0
 | 
					 | 
				
			||||||
anchor_bottom = 1.0
 | 
					 | 
				
			||||||
grow_horizontal = 2
 | 
					 | 
				
			||||||
grow_vertical = 2
 | 
					 | 
				
			||||||
texture = ExtResource("3_jr23q")
 | 
					 | 
				
			||||||
| 
						 | 
					@ -206,6 +206,13 @@ namespace DialogueManagerRuntime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public partial class DialogueLine : RefCounted
 | 
					    public partial class DialogueLine : RefCounted
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        private string id = "";
 | 
				
			||||||
 | 
					        public string Id
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get => id;
 | 
				
			||||||
 | 
					            set => id = value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private string type = "dialogue";
 | 
					        private string type = "dialogue";
 | 
				
			||||||
        public string Type
 | 
					        public string Type
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,26 +70,28 @@ func _ready() -> void:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func _gui_input(event: InputEvent) -> void:
 | 
					func _gui_input(event: InputEvent) -> void:
 | 
				
			||||||
 | 
						# Handle shortcuts that come from the editor
 | 
				
			||||||
	if event is InputEventKey and event.is_pressed():
 | 
						if event is InputEventKey and event.is_pressed():
 | 
				
			||||||
		match event.as_text():
 | 
							var shortcut: String = Engine.get_meta("DialogueManagerPlugin").get_editor_shortcut(event)
 | 
				
			||||||
			"Ctrl+Equal", "Command+Equal":
 | 
							match shortcut:
 | 
				
			||||||
				self.font_size += 1
 | 
								"toggle_comment":
 | 
				
			||||||
				get_viewport().set_input_as_handled()
 | 
					 | 
				
			||||||
			"Ctrl+Minus", "Command+Minus":
 | 
					 | 
				
			||||||
				self.font_size -= 1
 | 
					 | 
				
			||||||
				get_viewport().set_input_as_handled()
 | 
					 | 
				
			||||||
			"Ctrl+0", "Command+0":
 | 
					 | 
				
			||||||
				self.font_size = theme_overrides.font_size
 | 
					 | 
				
			||||||
				get_viewport().set_input_as_handled()
 | 
					 | 
				
			||||||
			"Ctrl+K", "Command+K":
 | 
					 | 
				
			||||||
				toggle_comment()
 | 
									toggle_comment()
 | 
				
			||||||
				get_viewport().set_input_as_handled()
 | 
									get_viewport().set_input_as_handled()
 | 
				
			||||||
			"Alt+Up":
 | 
								"move_up":
 | 
				
			||||||
				move_line(-1)
 | 
									move_line(-1)
 | 
				
			||||||
				get_viewport().set_input_as_handled()
 | 
									get_viewport().set_input_as_handled()
 | 
				
			||||||
			"Alt+Down":
 | 
								"move_down":
 | 
				
			||||||
				move_line(1)
 | 
									move_line(1)
 | 
				
			||||||
				get_viewport().set_input_as_handled()
 | 
									get_viewport().set_input_as_handled()
 | 
				
			||||||
 | 
								"text_size_increase":
 | 
				
			||||||
 | 
									self.font_size += 1
 | 
				
			||||||
 | 
									get_viewport().set_input_as_handled()
 | 
				
			||||||
 | 
								"text_size_decrease":
 | 
				
			||||||
 | 
									self.font_size -= 1
 | 
				
			||||||
 | 
									get_viewport().set_input_as_handled()
 | 
				
			||||||
 | 
								"text_size_reset":
 | 
				
			||||||
 | 
									self.font_size = theme_overrides.font_size
 | 
				
			||||||
 | 
									get_viewport().set_input_as_handled()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	elif event is InputEventMouse:
 | 
						elif event is InputEventMouse:
 | 
				
			||||||
		match event.as_text():
 | 
							match event.as_text():
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,11 +26,11 @@ var regex_dict: RegEx = RegEx.create_from_string("^\\{((?>[^\\{\\}]+|(?R))*)\\}$
 | 
				
			||||||
var regex_kvdict: RegEx = RegEx.create_from_string("^\\s*(?<left>.*?)\\s*(?<colon>:|=)\\s*(?<right>[^\\/]+)$")
 | 
					var regex_kvdict: RegEx = RegEx.create_from_string("^\\s*(?<left>.*?)\\s*(?<colon>:|=)\\s*(?<right>[^\\/]+)$")
 | 
				
			||||||
var regex_commas: RegEx = RegEx.create_from_string("([^,]+)(?:\\s*,\\s*)?")
 | 
					var regex_commas: RegEx = RegEx.create_from_string("([^,]+)(?:\\s*,\\s*)?")
 | 
				
			||||||
var regex_assignment: RegEx = RegEx.create_from_string("^\\s*(?<var>[a-zA-Z_][a-zA-Z_0-9]*)(?:(?<attr>(?:\\.[a-zA-Z_][a-zA-Z_0-9]*)+)|(?:\\[(?<key>[^\\]]+)\\]))?\\s*(?<op>(?:\\/|\\*|-|\\+)?=)\\s*(?<val>.*)$")
 | 
					var regex_assignment: RegEx = RegEx.create_from_string("^\\s*(?<var>[a-zA-Z_][a-zA-Z_0-9]*)(?:(?<attr>(?:\\.[a-zA-Z_][a-zA-Z_0-9]*)+)|(?:\\[(?<key>[^\\]]+)\\]))?\\s*(?<op>(?:\\/|\\*|-|\\+)?=)\\s*(?<val>.*)$")
 | 
				
			||||||
var regex_varname: RegEx = RegEx.create_from_string("^\\s*(?!true|false|and|or|not|in|null)(?<var>[a-zA-Z_][a-zA-Z_0-9]*)(?:(?<attr>(?:\\.[a-zA-Z_][a-zA-Z_0-9]*)+)|(?:\\[(?<key>[^\\]]+)\\]))?\\s*$")
 | 
					var regex_varname: RegEx = RegEx.create_from_string("^\\s*(?!true|false|and|or|&&|\\|\\|not|in|null)(?<var>[a-zA-Z_][a-zA-Z_0-9]*)(?:(?<attr>(?:\\.[a-zA-Z_][a-zA-Z_0-9]*)+)|(?:\\[(?<key>[^\\]]+)\\]))?\\s*$")
 | 
				
			||||||
var regex_keyword: RegEx = RegEx.create_from_string("^\\s*(true|false|null)\\s*$")
 | 
					var regex_keyword: RegEx = RegEx.create_from_string("^\\s*(true|false|null)\\s*$")
 | 
				
			||||||
var regex_function: RegEx = RegEx.create_from_string("^\\s*([a-zA-Z_][a-zA-Z_0-9]*\\s*)\\(")
 | 
					var regex_function: RegEx = RegEx.create_from_string("^\\s*([a-zA-Z_][a-zA-Z_0-9]*\\s*)\\(")
 | 
				
			||||||
var regex_comparison: RegEx = RegEx.create_from_string("^(?<left>.*?)\\s*(?<op>==|>=|<=|<|>|!=)\\s*(?<right>.*)$")
 | 
					var regex_comparison: RegEx = RegEx.create_from_string("^(?<left>.*?)\\s*(?<op>==|>=|<=|<|>|!=)\\s*(?<right>.*)$")
 | 
				
			||||||
var regex_blogical: RegEx = RegEx.create_from_string("^(?<left>.*?)\\s+(?<op>and|or|in)\\s+(?<right>.*)$")
 | 
					var regex_blogical: RegEx = RegEx.create_from_string("^(?<left>.*?)\\s+(?<op>and|or|in|&&|\\|\\|)\\s+(?<right>.*)$")
 | 
				
			||||||
var regex_ulogical: RegEx = RegEx.create_from_string("^\\s*(?<op>not)\\s+(?<right>.*)$")
 | 
					var regex_ulogical: RegEx = RegEx.create_from_string("^\\s*(?<op>not)\\s+(?<right>.*)$")
 | 
				
			||||||
var regex_paren: RegEx = RegEx.create_from_string("\\((?<paren>((?:[^\\(\\)]*)|(?:\\((?1)\\)))*?)\\)")
 | 
					var regex_paren: RegEx = RegEx.create_from_string("\\((?<paren>((?:[^\\(\\)]*)|(?:\\((?1)\\)))*?)\\)")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -186,9 +186,9 @@ func _get_dialogue_syntax_highlighting(start_index: int, text: String) -> Dictio
 | 
				
			||||||
	for goto_match in goto_matches:
 | 
						for goto_match in goto_matches:
 | 
				
			||||||
		colors[start_index + goto_match.get_start(0)] = {"color": text_edit.theme_overrides.jumps_color}
 | 
							colors[start_index + goto_match.get_start(0)] = {"color": text_edit.theme_overrides.jumps_color}
 | 
				
			||||||
		if "file" in goto_match.names:
 | 
							if "file" in goto_match.names:
 | 
				
			||||||
			colors[start_index + goto_match.get_start("file")] = {"color": text_edit.theme_overrides.members_color}
 | 
								colors[start_index + goto_match.get_start("file")] = {"color": text_edit.theme_overrides.jumps_color}
 | 
				
			||||||
			colors[start_index + goto_match.get_end("file")] = {"color": text_edit.theme_overrides.symbols_color}
 | 
								colors[start_index + goto_match.get_end("file")] = {"color": text_edit.theme_overrides.symbols_color}
 | 
				
			||||||
		colors[start_index + goto_match.get_start("title")] = {"color": text_edit.theme_overrides.titles_color}
 | 
							colors[start_index + goto_match.get_start("title")] = {"color": text_edit.theme_overrides.jumps_color}
 | 
				
			||||||
		colors[start_index + goto_match.get_end("title")] = {"color": text_edit.theme_overrides.jumps_color}
 | 
							colors[start_index + goto_match.get_end("title")] = {"color": text_edit.theme_overrides.jumps_color}
 | 
				
			||||||
		colors[start_index + goto_match.get_end(0)] = {"color": text_edit.theme_overrides.text_color}
 | 
							colors[start_index + goto_match.get_end(0)] = {"color": text_edit.theme_overrides.text_color}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,7 +43,7 @@ var TOKEN_DEFINITIONS: Dictionary = {
 | 
				
			||||||
	DialogueConstants.TOKEN_DOT: RegEx.create_from_string("^\\."),
 | 
						DialogueConstants.TOKEN_DOT: RegEx.create_from_string("^\\."),
 | 
				
			||||||
	DialogueConstants.TOKEN_STRING: RegEx.create_from_string("^(\".*?\"|\'.*?\')"),
 | 
						DialogueConstants.TOKEN_STRING: RegEx.create_from_string("^(\".*?\"|\'.*?\')"),
 | 
				
			||||||
	DialogueConstants.TOKEN_NOT: RegEx.create_from_string("^(not( |$)|!)"),
 | 
						DialogueConstants.TOKEN_NOT: RegEx.create_from_string("^(not( |$)|!)"),
 | 
				
			||||||
	DialogueConstants.TOKEN_AND_OR: RegEx.create_from_string("^(and|or)( |$)"),
 | 
						DialogueConstants.TOKEN_AND_OR: RegEx.create_from_string("^(and|or|&&|\\|\\|)( |$)"),
 | 
				
			||||||
	DialogueConstants.TOKEN_VARIABLE: RegEx.create_from_string("^[a-zA-Z_][a-zA-Z_0-9]*"),
 | 
						DialogueConstants.TOKEN_VARIABLE: RegEx.create_from_string("^[a-zA-Z_][a-zA-Z_0-9]*"),
 | 
				
			||||||
	DialogueConstants.TOKEN_COMMENT: RegEx.create_from_string("^#.*"),
 | 
						DialogueConstants.TOKEN_COMMENT: RegEx.create_from_string("^#.*"),
 | 
				
			||||||
	DialogueConstants.TOKEN_CONDITION: RegEx.create_from_string("^(if|elif|else)"),
 | 
						DialogueConstants.TOKEN_CONDITION: RegEx.create_from_string("^(if|elif|else)"),
 | 
				
			||||||
| 
						 | 
					@ -230,6 +230,7 @@ func parse(text: String, path: String) -> Error:
 | 
				
			||||||
					line["character"] = first_child.character
 | 
										line["character"] = first_child.character
 | 
				
			||||||
					line["character_replacements"] = first_child.character_replacements
 | 
										line["character_replacements"] = first_child.character_replacements
 | 
				
			||||||
					line["text"] = first_child.text
 | 
										line["text"] = first_child.text
 | 
				
			||||||
 | 
										line["text_replacements"] = extract_dialogue_replacements(line.text, indent_size + 2)
 | 
				
			||||||
					line["translation_key"] = first_child.translation_key
 | 
										line["translation_key"] = first_child.translation_key
 | 
				
			||||||
					parsed_lines[str(id) + ".2"] = first_child
 | 
										parsed_lines[str(id) + ".2"] = first_child
 | 
				
			||||||
					line["next_id"] = str(id) + ".2"
 | 
										line["next_id"] = str(id) + ".2"
 | 
				
			||||||
| 
						 | 
					@ -691,11 +692,6 @@ func get_line_after_line(id: int, indent_size: int, line: Dictionary) -> String:
 | 
				
			||||||
	var next_nonempty_line_id = get_next_nonempty_line_id(id)
 | 
						var next_nonempty_line_id = get_next_nonempty_line_id(id)
 | 
				
			||||||
	if next_nonempty_line_id != DialogueConstants.ID_NULL \
 | 
						if next_nonempty_line_id != DialogueConstants.ID_NULL \
 | 
				
			||||||
		and indent_size <= get_indent(raw_lines[next_nonempty_line_id.to_int()]):
 | 
							and indent_size <= get_indent(raw_lines[next_nonempty_line_id.to_int()]):
 | 
				
			||||||
		# The next line is a title so we need the next nonempty line after that
 | 
					 | 
				
			||||||
		if is_title_line(raw_lines[next_nonempty_line_id.to_int()]):
 | 
					 | 
				
			||||||
			return get_next_nonempty_line_id(next_nonempty_line_id.to_int())
 | 
					 | 
				
			||||||
		# Otherwise it's a normal line
 | 
					 | 
				
			||||||
		else:
 | 
					 | 
				
			||||||
		return next_nonempty_line_id
 | 
							return next_nonempty_line_id
 | 
				
			||||||
	# Otherwise, we grab the ID from the parents next ID after children
 | 
						# Otherwise, we grab the ID from the parents next ID after children
 | 
				
			||||||
	elif line.has("parent_id") and parsed_lines.has(line.parent_id):
 | 
						elif line.has("parent_id") and parsed_lines.has(line.parent_id):
 | 
				
			||||||
| 
						 | 
					@ -927,8 +923,8 @@ func find_next_line_after_responses(line_number: int) -> String:
 | 
				
			||||||
			if get_indent(line) <= expected_indent:
 | 
								if get_indent(line) <= expected_indent:
 | 
				
			||||||
				return str(line_number)
 | 
									return str(line_number)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	# EOF so must be end of conversation
 | 
						# EOF so it's also the end of a block
 | 
				
			||||||
	return DialogueConstants.ID_END_CONVERSATION
 | 
						return DialogueConstants.ID_END
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Get the names of any autoloads in the project
 | 
					## Get the names of any autoloads in the project
 | 
				
			||||||
| 
						 | 
					@ -1529,10 +1525,15 @@ func build_token_tree(tokens: Array[Dictionary], line_type: String, expected_clo
 | 
				
			||||||
			DialogueConstants.TOKEN_ASSIGNMENT, \
 | 
								DialogueConstants.TOKEN_ASSIGNMENT, \
 | 
				
			||||||
			DialogueConstants.TOKEN_OPERATOR, \
 | 
								DialogueConstants.TOKEN_OPERATOR, \
 | 
				
			||||||
			DialogueConstants.TOKEN_AND_OR, \
 | 
								DialogueConstants.TOKEN_AND_OR, \
 | 
				
			||||||
			DialogueConstants.TOKEN_VARIABLE: \
 | 
								DialogueConstants.TOKEN_VARIABLE:
 | 
				
			||||||
 | 
									var value = token.value.strip_edges()
 | 
				
			||||||
 | 
									if value == "&&":
 | 
				
			||||||
 | 
										value = "and"
 | 
				
			||||||
 | 
									elif value == "||":
 | 
				
			||||||
 | 
										value = "or"
 | 
				
			||||||
				tree.append({
 | 
									tree.append({
 | 
				
			||||||
					type = token.type,
 | 
										type = token.type,
 | 
				
			||||||
					value = token.value.strip_edges()
 | 
										value = value
 | 
				
			||||||
				})
 | 
									})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			DialogueConstants.TOKEN_STRING:
 | 
								DialogueConstants.TOKEN_STRING:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -142,6 +142,7 @@ func get_resolved_line_data(data: Dictionary, extra_game_states: Array = []) ->
 | 
				
			||||||
    for replacement in data.text_replacements:
 | 
					    for replacement in data.text_replacements:
 | 
				
			||||||
        var value = await resolve(replacement.expression.duplicate(true), extra_game_states)
 | 
					        var value = await resolve(replacement.expression.duplicate(true), extra_game_states)
 | 
				
			||||||
        var index: int = text.find(replacement.value_in_text)
 | 
					        var index: int = text.find(replacement.value_in_text)
 | 
				
			||||||
 | 
					        if index > -1:
 | 
				
			||||||
            text = text.substr(0, index) + str(value) + text.substr(index + replacement.value_in_text.length())
 | 
					            text = text.substr(0, index) + str(value) + text.substr(index + replacement.value_in_text.length())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var parser: DialogueManagerParser = DialogueManagerParser.new()
 | 
					    var parser: DialogueManagerParser = DialogueManagerParser.new()
 | 
				
			||||||
| 
						 | 
					@ -218,6 +219,7 @@ func get_resolved_character(data: Dictionary, extra_game_states: Array = []) ->
 | 
				
			||||||
    for replacement in data.get(&"character_replacements", []):
 | 
					    for replacement in data.get(&"character_replacements", []):
 | 
				
			||||||
        var value = await resolve(replacement.expression.duplicate(true), extra_game_states)
 | 
					        var value = await resolve(replacement.expression.duplicate(true), extra_game_states)
 | 
				
			||||||
        var index: int = character.find(replacement.value_in_text)
 | 
					        var index: int = character.find(replacement.value_in_text)
 | 
				
			||||||
 | 
					        if index > -1:
 | 
				
			||||||
            character = character.substr(0, index) + str(value) + character.substr(index + replacement.value_in_text.length())
 | 
					            character = character.substr(0, index) + str(value) + character.substr(index + replacement.value_in_text.length())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Resolve random groups
 | 
					    # Resolve random groups
 | 
				
			||||||
| 
						 | 
					@ -359,6 +361,10 @@ func get_line(resource: DialogueResource, key: String, extra_game_states: Array)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var data: Dictionary = resource.lines.get(key)
 | 
					    var data: Dictionary = resource.lines.get(key)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # This title key points to another title key so we should jump there instead
 | 
				
			||||||
 | 
					    if data.type == DialogueConstants.TYPE_TITLE and data.next_id in resource.titles.values():
 | 
				
			||||||
 | 
					        return await get_line(resource, data.next_id + id_trail, extra_game_states)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Check for weighted random lines
 | 
					    # Check for weighted random lines
 | 
				
			||||||
    if data.has(&"siblings"):
 | 
					    if data.has(&"siblings"):
 | 
				
			||||||
        var target_weight: float = randf_range(0, data.siblings.reduce(func(total, sibling): return total + sibling.weight, 0))
 | 
					        var target_weight: float = randf_range(0, data.siblings.reduce(func(total, sibling): return total + sibling.weight, 0))
 | 
				
			||||||
| 
						 | 
					@ -454,7 +460,7 @@ func translate(data: Dictionary) -> String:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            TranslationSource.Guess:
 | 
					            TranslationSource.Guess:
 | 
				
			||||||
                var translation_files: Array = ProjectSettings.get_setting(&"internationalization/locale/translations")
 | 
					                var translation_files: Array = ProjectSettings.get_setting(&"internationalization/locale/translations")
 | 
				
			||||||
				if translation_files.filter(func(f: String): return f.get_extension() == &"po").size() > 0:
 | 
					                if translation_files.filter(func(f: String): return f.get_extension() in [&"po", &"mo"]).size() > 0:
 | 
				
			||||||
                    # Assume PO
 | 
					                    # Assume PO
 | 
				
			||||||
                    return tr(data.text, StringName(data.translation_key))
 | 
					                    return tr(data.text, StringName(data.translation_key))
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
| 
						 | 
					@ -745,6 +751,16 @@ func resolve(tokens: Array, extra_game_states: Array):
 | 
				
			||||||
                        token["type"] = "value"
 | 
					                        token["type"] = "value"
 | 
				
			||||||
                        token["value"] = Quaternion(args[0], args[1], args[2], args[3])
 | 
					                        token["value"] = Quaternion(args[0], args[1], args[2], args[3])
 | 
				
			||||||
                        found = true
 | 
					                        found = true
 | 
				
			||||||
 | 
					                    &"Callable":
 | 
				
			||||||
 | 
					                        token["type"] = "value"
 | 
				
			||||||
 | 
					                        match args.size():
 | 
				
			||||||
 | 
					                            0:
 | 
				
			||||||
 | 
					                                token["value"] = Callable()
 | 
				
			||||||
 | 
					                            1:
 | 
				
			||||||
 | 
					                                token["value"] = Callable(args[0])
 | 
				
			||||||
 | 
					                            2:
 | 
				
			||||||
 | 
					                                token["value"] = Callable(args[0], args[1])
 | 
				
			||||||
 | 
					                        found = true
 | 
				
			||||||
                    &"Color":
 | 
					                    &"Color":
 | 
				
			||||||
                        token["type"] = "value"
 | 
					                        token["type"] = "value"
 | 
				
			||||||
                        match args.size():
 | 
					                        match args.size():
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
@icon("./assets/responses_menu.svg")
 | 
					@icon("./assets/responses_menu.svg")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## A VBoxContainer for dialogue responses provided by [b]Dialogue Manager[/b].
 | 
					## A [Container] for dialogue responses provided by [b]Dialogue Manager[/b].
 | 
				
			||||||
class_name DialogueResponsesMenu extends VBoxContainer
 | 
					class_name DialogueResponsesMenu extends Container
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Emitted when a response is selected.
 | 
					## Emitted when a response is selected.
 | 
				
			||||||
| 
						 | 
					@ -14,8 +14,10 @@ signal response_selected(response)
 | 
				
			||||||
## The action for accepting a response (is possibly overridden by parent dialogue balloon).
 | 
					## The action for accepting a response (is possibly overridden by parent dialogue balloon).
 | 
				
			||||||
@export var next_action: StringName = &""
 | 
					@export var next_action: StringName = &""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# The list of dialogue responses.
 | 
					## The list of dialogue responses.
 | 
				
			||||||
var responses: Array = []:
 | 
					var responses: Array = []:
 | 
				
			||||||
 | 
						get:
 | 
				
			||||||
 | 
							return responses
 | 
				
			||||||
	set(value):
 | 
						set(value):
 | 
				
			||||||
		responses = value
 | 
							responses = value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,11 +66,25 @@ func _ready() -> void:
 | 
				
			||||||
		response_template.hide()
 | 
							response_template.hide()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# This is deprecated.
 | 
					## Get the selectable items in the menu.
 | 
				
			||||||
 | 
					func get_menu_items() -> Array:
 | 
				
			||||||
 | 
						var items: Array = []
 | 
				
			||||||
 | 
						for child in get_children():
 | 
				
			||||||
 | 
							if not child.visible: continue
 | 
				
			||||||
 | 
							if "Disallowed" in child.name: continue
 | 
				
			||||||
 | 
							items.append(child)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return items
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [b]DEPRECATED[/b]. Do not use.
 | 
				
			||||||
func set_responses(next_responses: Array) -> void:
 | 
					func set_responses(next_responses: Array) -> void:
 | 
				
			||||||
	self.responses = next_responses
 | 
						self.responses = next_responses
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#region Internal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Prepare the menu for keyboard and mouse navigation.
 | 
					# Prepare the menu for keyboard and mouse navigation.
 | 
				
			||||||
func _configure_focus() -> void:
 | 
					func _configure_focus() -> void:
 | 
				
			||||||
	var items = get_menu_items()
 | 
						var items = get_menu_items()
 | 
				
			||||||
| 
						 | 
					@ -100,18 +116,9 @@ func _configure_focus() -> void:
 | 
				
			||||||
	items[0].grab_focus()
 | 
						items[0].grab_focus()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Get the selectable items in the menu.
 | 
					#endregion
 | 
				
			||||||
func get_menu_items() -> Array:
 | 
					 | 
				
			||||||
	var items: Array = []
 | 
					 | 
				
			||||||
	for child in get_children():
 | 
					 | 
				
			||||||
		if not child.visible: continue
 | 
					 | 
				
			||||||
		if "Disallowed" in child.name: continue
 | 
					 | 
				
			||||||
		items.append(child)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return items
 | 
					#region Signals
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Signals
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func _on_response_mouse_entered(item: Control) -> void:
 | 
					func _on_response_mouse_entered(item: Control) -> void:
 | 
				
			||||||
| 
						 | 
					@ -129,3 +136,6 @@ func _on_response_gui_input(event: InputEvent, item: Control, response) -> void:
 | 
				
			||||||
		response_selected.emit(response)
 | 
							response_selected.emit(response)
 | 
				
			||||||
	elif event.is_action_pressed(&"ui_accept" if next_action.is_empty() else next_action) and item in get_menu_items():
 | 
						elif event.is_action_pressed(&"ui_accept" if next_action.is_empty() else next_action) and item in get_menu_items():
 | 
				
			||||||
		response_selected.emit(response)
 | 
							response_selected.emit(response)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endregion
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -105,6 +105,21 @@ namespace DialogueManagerRuntime
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        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)
 | 
					    public async void Start(Resource dialogueResource, string title, Array<Variant> extraGameStates = null)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      temporaryGameStates = extraGameStates ?? new Array<Variant>();
 | 
					      temporaryGameStates = extraGameStates ?? new Array<Variant>();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -89,6 +89,15 @@ func _unhandled_input(_event: InputEvent) -> void:
 | 
				
			||||||
	get_viewport().set_input_as_handled()
 | 
						get_viewport().set_input_as_handled()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func _notification(what: int) -> void:
 | 
				
			||||||
 | 
						# Detect a change of locale and update the current dialogue line to show the new language
 | 
				
			||||||
 | 
						if what == NOTIFICATION_TRANSLATION_CHANGED:
 | 
				
			||||||
 | 
							var visible_ratio = dialogue_label.visible_ratio
 | 
				
			||||||
 | 
							self.dialogue_line = await resource.get_next_dialogue_line(dialogue_line.id)
 | 
				
			||||||
 | 
							if visible_ratio < 1:
 | 
				
			||||||
 | 
								dialogue_label.skip_typing()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Start some dialogue
 | 
					## Start some dialogue
 | 
				
			||||||
func start(dialogue_resource: DialogueResource, title: String, extra_game_states: Array = []) -> void:
 | 
					func start(dialogue_resource: DialogueResource, title: String, extra_game_states: Array = []) -> void:
 | 
				
			||||||
	temporary_game_states =  [self] + extra_game_states
 | 
						temporary_game_states =  [self] + extra_game_states
 | 
				
			||||||
| 
						 | 
					@ -102,7 +111,7 @@ func next(next_id: String) -> void:
 | 
				
			||||||
	self.dialogue_line = await resource.get_next_dialogue_line(next_id, temporary_game_states)
 | 
						self.dialogue_line = await resource.get_next_dialogue_line(next_id, temporary_game_states)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Signals
 | 
					#region Signals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func _on_mutated(_mutation: Dictionary) -> void:
 | 
					func _on_mutated(_mutation: Dictionary) -> void:
 | 
				
			||||||
| 
						 | 
					@ -139,3 +148,6 @@ func _on_balloon_gui_input(event: InputEvent) -> void:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func _on_responses_menu_response_selected(response: DialogueResponse) -> void:
 | 
					func _on_responses_menu_response_selected(response: DialogueResponse) -> void:
 | 
				
			||||||
	next(response.next_id)
 | 
						next(response.next_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endregion
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,7 @@ signal compiled_resource(resource: Resource)
 | 
				
			||||||
const DialogueResource = preload("./dialogue_resource.gd")
 | 
					const DialogueResource = preload("./dialogue_resource.gd")
 | 
				
			||||||
const DialogueManagerParseResult = preload("./components/parse_result.gd")
 | 
					const DialogueManagerParseResult = preload("./components/parse_result.gd")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const compiler_version = 11
 | 
					const compiler_version = 12
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func _get_importer_name() -> String:
 | 
					func _get_importer_name() -> String:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@ msgstr ""
 | 
				
			||||||
"POT-Creation-Date: \n"
 | 
					"POT-Creation-Date: \n"
 | 
				
			||||||
"PO-Revision-Date: \n"
 | 
					"PO-Revision-Date: \n"
 | 
				
			||||||
"Last-Translator: \n"
 | 
					"Last-Translator: \n"
 | 
				
			||||||
"Language-Team: penghao123456、憨憨羊の宇航鸽鸽\n"
 | 
					"Language-Team: penghao123456、憨憨羊の宇航鸽鸽、ABShinri\n"
 | 
				
			||||||
"Language: zh\n"
 | 
					"Language: zh\n"
 | 
				
			||||||
"MIME-Version: 1.0\n"
 | 
					"MIME-Version: 1.0\n"
 | 
				
			||||||
"Content-Type: text/plain; charset=UTF-8\n"
 | 
					"Content-Type: text/plain; charset=UTF-8\n"
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,9 @@ msgstr "清空历史记录"
 | 
				
			||||||
msgid "save_all_files"
 | 
					msgid "save_all_files"
 | 
				
			||||||
msgstr "保存所有文件"
 | 
					msgstr "保存所有文件"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "find_in_files"
 | 
				
			||||||
 | 
					msgstr "在文件中查找"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "test_dialogue"
 | 
					msgid "test_dialogue"
 | 
				
			||||||
msgstr "测试对话"
 | 
					msgstr "测试对话"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,10 +54,10 @@ msgid "docs"
 | 
				
			||||||
msgstr "文档"
 | 
					msgstr "文档"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "insert.wave_bbcode"
 | 
					msgid "insert.wave_bbcode"
 | 
				
			||||||
msgstr "BBCode [lb]wave[rb]"
 | 
					msgstr "波浪效果"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "insert.shake_bbcode"
 | 
					msgid "insert.shake_bbcode"
 | 
				
			||||||
msgstr "BBCode [lb]wave[rb]"
 | 
					msgstr "抖动效果"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "insert.typing_pause"
 | 
					msgid "insert.typing_pause"
 | 
				
			||||||
msgstr "输入间隔"
 | 
					msgstr "输入间隔"
 | 
				
			||||||
| 
						 | 
					@ -95,6 +98,9 @@ msgstr "结束对话"
 | 
				
			||||||
msgid "generate_line_ids"
 | 
					msgid "generate_line_ids"
 | 
				
			||||||
msgstr "生成行 ID"
 | 
					msgstr "生成行 ID"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "save_characters_to_csv"
 | 
				
			||||||
 | 
					msgstr "保存角色到 CSV"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "save_to_csv"
 | 
					msgid "save_to_csv"
 | 
				
			||||||
msgstr "生成 CSV"
 | 
					msgstr "生成 CSV"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -134,6 +140,9 @@ msgstr "在 Godot 侧边栏中显示"
 | 
				
			||||||
msgid "settings.revert_to_default_test_scene"
 | 
					msgid "settings.revert_to_default_test_scene"
 | 
				
			||||||
msgstr "重置测试场景设定"
 | 
					msgstr "重置测试场景设定"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "settings.default_balloon_hint"
 | 
				
			||||||
 | 
					msgstr "设置调用 \"DialogueManager.show_balloon()\" 时使用的对话框"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "settings.autoload"
 | 
					msgid "settings.autoload"
 | 
				
			||||||
msgstr "Autoload"
 | 
					msgstr "Autoload"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -150,10 +159,10 @@ msgid "settings.missing_keys_hint"
 | 
				
			||||||
msgstr "如果你使用静态键,这将会帮助你寻找未添加至翻译文件的键。"
 | 
					msgstr "如果你使用静态键,这将会帮助你寻找未添加至翻译文件的键。"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "settings.characters_translations"
 | 
					msgid "settings.characters_translations"
 | 
				
			||||||
msgstr "在翻译文件中导出角色名。"
 | 
					msgstr "在翻译文件中导出角色名"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "settings.wrap_long_lines"
 | 
					msgid "settings.wrap_long_lines"
 | 
				
			||||||
msgstr "自动折行"
 | 
					msgstr "文本编辑器自动换行"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "settings.include_failed_responses"
 | 
					msgid "settings.include_failed_responses"
 | 
				
			||||||
msgstr "在判断条件失败时仍显示回复选项"
 | 
					msgstr "在判断条件失败时仍显示回复选项"
 | 
				
			||||||
| 
						 | 
					@ -176,9 +185,39 @@ msgstr "当一个 Autoload 在这里被勾选,他的所有成员会被映射
 | 
				
			||||||
msgid "settings.states_hint"
 | 
					msgid "settings.states_hint"
 | 
				
			||||||
msgstr "比如,当你开启对于“Foo”的映射时,你可以将“Foo.bar”简写成“bar”。"
 | 
					msgstr "比如,当你开启对于“Foo”的映射时,你可以将“Foo.bar”简写成“bar”。"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "settings.recompile_warning"
 | 
				
			||||||
 | 
					msgstr "更改这些选项会强制重新编译所有的对话框,当你清楚在做什么的时候更改。"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "settings.create_lines_for_responses_with_characters"
 | 
				
			||||||
 | 
					msgstr "回复项带角色名时(- char: response),会自动生成为选择后的下一句对话"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "settings.include_characters_in_translations"
 | 
				
			||||||
 | 
					msgstr "导出 CSV 时包括角色名"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "settings.include_notes_in_translations"
 | 
				
			||||||
 | 
					msgstr "导出 CSV 时包括注释(## comments)"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "settings.check_for_updates"
 | 
				
			||||||
 | 
					msgstr "检查升级"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "n_of_n"
 | 
					msgid "n_of_n"
 | 
				
			||||||
msgstr "第{index}个,共{total}个"
 | 
					msgstr "第{index}个,共{total}个"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "search.find"
 | 
				
			||||||
 | 
					msgstr "查找:"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "search.find_all"
 | 
				
			||||||
 | 
					msgstr "查找全部..."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "search.placeholder"
 | 
				
			||||||
 | 
					msgstr "请输入查找的内容"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "search.replace_placeholder"
 | 
				
			||||||
 | 
					msgstr "请输入替换的内容"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "search.replace_selected"
 | 
				
			||||||
 | 
					msgstr "替换勾选"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "search.previous"
 | 
					msgid "search.previous"
 | 
				
			||||||
msgstr "查找上一个"
 | 
					msgstr "查找上一个"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@ msgstr ""
 | 
				
			||||||
"POT-Creation-Date: \n"
 | 
					"POT-Creation-Date: \n"
 | 
				
			||||||
"PO-Revision-Date: \n"
 | 
					"PO-Revision-Date: \n"
 | 
				
			||||||
"Last-Translator: \n"
 | 
					"Last-Translator: \n"
 | 
				
			||||||
"Language-Team: 憨憨羊の宇航鴿鴿\n"
 | 
					"Language-Team: 憨憨羊の宇航鴿鴿、ABShinri\n"
 | 
				
			||||||
"Language: zh_TW\n"
 | 
					"Language: zh_TW\n"
 | 
				
			||||||
"MIME-Version: 1.0\n"
 | 
					"MIME-Version: 1.0\n"
 | 
				
			||||||
"Content-Type: text/plain; charset=UTF-8\n"
 | 
					"Content-Type: text/plain; charset=UTF-8\n"
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,9 @@ msgstr "清空歷史記錄"
 | 
				
			||||||
msgid "save_all_files"
 | 
					msgid "save_all_files"
 | 
				
			||||||
msgstr "儲存所有檔案"
 | 
					msgstr "儲存所有檔案"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "find_in_files"
 | 
				
			||||||
 | 
					msgstr "在檔案中查找"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "test_dialogue"
 | 
					msgid "test_dialogue"
 | 
				
			||||||
msgstr "測試對話"
 | 
					msgstr "測試對話"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,10 +54,10 @@ msgid "docs"
 | 
				
			||||||
msgstr "文檔"
 | 
					msgstr "文檔"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "insert.wave_bbcode"
 | 
					msgid "insert.wave_bbcode"
 | 
				
			||||||
msgstr "BBCode [lb]wave[rb]"
 | 
					msgstr "波浪特效"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "insert.shake_bbcode"
 | 
					msgid "insert.shake_bbcode"
 | 
				
			||||||
msgstr "BBCode [lb]wave[rb]"
 | 
					msgstr "震動特效"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "insert.typing_pause"
 | 
					msgid "insert.typing_pause"
 | 
				
			||||||
msgstr "輸入間隔"
 | 
					msgstr "輸入間隔"
 | 
				
			||||||
| 
						 | 
					@ -95,6 +98,9 @@ msgstr "結束對話"
 | 
				
			||||||
msgid "generate_line_ids"
 | 
					msgid "generate_line_ids"
 | 
				
			||||||
msgstr "生成行 ID"
 | 
					msgstr "生成行 ID"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "save_characters_to_csv"
 | 
				
			||||||
 | 
					msgstr "保存角色到 CSV"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "save_to_csv"
 | 
					msgid "save_to_csv"
 | 
				
			||||||
msgstr "生成 CSV"
 | 
					msgstr "生成 CSV"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -134,6 +140,9 @@ msgstr "在 Godot 側邊欄中顯示"
 | 
				
			||||||
msgid "settings.revert_to_default_test_scene"
 | 
					msgid "settings.revert_to_default_test_scene"
 | 
				
			||||||
msgstr "重置測試場景設定"
 | 
					msgstr "重置測試場景設定"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "settings.default_balloon_hint"
 | 
				
			||||||
 | 
					msgstr "設置使用 \"DialogueManager.show_balloon()\" 时的对话框"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "settings.autoload"
 | 
					msgid "settings.autoload"
 | 
				
			||||||
msgstr "Autoload"
 | 
					msgstr "Autoload"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -176,9 +185,39 @@ msgstr "當一個 Autoload 在這裏被勾選,他的所有成員會被映射
 | 
				
			||||||
msgid "settings.states_hint"
 | 
					msgid "settings.states_hint"
 | 
				
			||||||
msgstr "比如,當你開啓對於“Foo”的映射時,你可以將“Foo.bar”簡寫成“bar”。"
 | 
					msgstr "比如,當你開啓對於“Foo”的映射時,你可以將“Foo.bar”簡寫成“bar”。"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "settings.recompile_warning"
 | 
				
			||||||
 | 
					msgstr "更改這些選項會強制重新編譯所有的對話框,當你清楚在做什麼的時候更改。"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "settings.create_lines_for_responses_with_characters"
 | 
				
			||||||
 | 
					msgstr "回覆項目帶角色名稱時(- char: response),會自動產生為選擇後的下一句對話"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "settings.include_characters_in_translations"
 | 
				
			||||||
 | 
					msgstr "匯出 CSV 時包含角色名"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "settings.include_notes_in_translations"
 | 
				
			||||||
 | 
					msgstr "匯出 CSV 時包括註解(## comments)"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "settings.check_for_updates"
 | 
				
			||||||
 | 
					msgstr "檢查升級"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "n_of_n"
 | 
					msgid "n_of_n"
 | 
				
			||||||
msgstr "第{index}個,共{total}個"
 | 
					msgstr "第{index}個,共{total}個"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "search.find"
 | 
				
			||||||
 | 
					msgstr "搜尋:"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "search.find_all"
 | 
				
			||||||
 | 
					msgstr "搜尋全部..."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "search.placeholder"
 | 
				
			||||||
 | 
					msgstr "請輸入搜尋的內容"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "search.replace_placeholder"
 | 
				
			||||||
 | 
					msgstr "請輸入替換的內容"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					msgid "search.replace_selected"
 | 
				
			||||||
 | 
					msgstr "替換勾選"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
msgid "search.previous"
 | 
					msgid "search.previous"
 | 
				
			||||||
msgstr "搜尋上一個"
 | 
					msgstr "搜尋上一個"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,5 +3,5 @@
 | 
				
			||||||
name="Dialogue Manager"
 | 
					name="Dialogue Manager"
 | 
				
			||||||
description="A simple but powerful branching dialogue system"
 | 
					description="A simple but powerful branching dialogue system"
 | 
				
			||||||
author="Nathan Hoad"
 | 
					author="Nathan Hoad"
 | 
				
			||||||
version="2.38.0"
 | 
					version="2.39.1"
 | 
				
			||||||
script="plugin.gd"
 | 
					script="plugin.gd"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -145,6 +145,80 @@ func _build() -> bool:
 | 
				
			||||||
	return true
 | 
						return true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Get the shortcuts used by the plugin
 | 
				
			||||||
 | 
					func get_editor_shortcuts() -> Dictionary:
 | 
				
			||||||
 | 
						var shortcuts: Dictionary = {
 | 
				
			||||||
 | 
							toggle_comment = [
 | 
				
			||||||
 | 
								_create_event("Ctrl+K"),
 | 
				
			||||||
 | 
								_create_event("Ctrl+Slash")
 | 
				
			||||||
 | 
							],
 | 
				
			||||||
 | 
							move_up = [
 | 
				
			||||||
 | 
								_create_event("Alt+Up")
 | 
				
			||||||
 | 
							],
 | 
				
			||||||
 | 
							move_down = [
 | 
				
			||||||
 | 
								_create_event("Alt+Down")
 | 
				
			||||||
 | 
							],
 | 
				
			||||||
 | 
							save = [
 | 
				
			||||||
 | 
								_create_event("Ctrl+Alt+S")
 | 
				
			||||||
 | 
							],
 | 
				
			||||||
 | 
							close_file = [
 | 
				
			||||||
 | 
								_create_event("Ctrl+W")
 | 
				
			||||||
 | 
							],
 | 
				
			||||||
 | 
							find_in_files = [
 | 
				
			||||||
 | 
								_create_event("Ctrl+Shift+F")
 | 
				
			||||||
 | 
							],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							run_test_scene = [
 | 
				
			||||||
 | 
								_create_event("Ctrl+F5")
 | 
				
			||||||
 | 
							],
 | 
				
			||||||
 | 
							text_size_increase = [
 | 
				
			||||||
 | 
								_create_event("Ctrl+Equal")
 | 
				
			||||||
 | 
							],
 | 
				
			||||||
 | 
							text_size_decrease = [
 | 
				
			||||||
 | 
								_create_event("Ctrl+Minus")
 | 
				
			||||||
 | 
							],
 | 
				
			||||||
 | 
							text_size_reset = [
 | 
				
			||||||
 | 
								_create_event("Ctrl+0")
 | 
				
			||||||
 | 
							]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var paths = get_editor_interface().get_editor_paths()
 | 
				
			||||||
 | 
						var settings = load(paths.get_config_dir() + "/editor_settings-4.tres")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if not settings: return shortcuts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for s in settings.get("shortcuts"):
 | 
				
			||||||
 | 
							for key in shortcuts:
 | 
				
			||||||
 | 
								if s.name == "script_text_editor/%s" % key or s.name == "script_editor/%s" % key:
 | 
				
			||||||
 | 
									shortcuts[key] = []
 | 
				
			||||||
 | 
									for event in s.shortcuts:
 | 
				
			||||||
 | 
										if event is InputEventKey:
 | 
				
			||||||
 | 
											shortcuts[key].append(event)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return shortcuts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func _create_event(string: String) -> InputEventKey:
 | 
				
			||||||
 | 
						var event: InputEventKey = InputEventKey.new()
 | 
				
			||||||
 | 
						var bits = string.split("+")
 | 
				
			||||||
 | 
						event.keycode = OS.find_keycode_from_string(bits[bits.size() - 1])
 | 
				
			||||||
 | 
						event.shift_pressed = bits.has("Shift")
 | 
				
			||||||
 | 
						event.alt_pressed = bits.has("Alt")
 | 
				
			||||||
 | 
						if bits.has("Ctrl") or bits.has("Command"):
 | 
				
			||||||
 | 
							event.command_or_control_autoremap = true
 | 
				
			||||||
 | 
						return event
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Get the editor shortcut that matches an event
 | 
				
			||||||
 | 
					func get_editor_shortcut(event: InputEventKey) -> String:
 | 
				
			||||||
 | 
						var shortcuts: Dictionary = get_editor_shortcuts()
 | 
				
			||||||
 | 
						for key in shortcuts:
 | 
				
			||||||
 | 
							for shortcut in shortcuts.get(key, []):
 | 
				
			||||||
 | 
								if event.is_match(shortcut):
 | 
				
			||||||
 | 
									return key
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Get the current version
 | 
					## Get the current version
 | 
				
			||||||
func get_version() -> String:
 | 
					func get_version() -> String:
 | 
				
			||||||
	var config: ConfigFile = ConfigFile.new()
 | 
						var config: ConfigFile = ConfigFile.new()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -176,9 +176,5 @@ static func has_dotnet_solution() -> bool:
 | 
				
			||||||
		var has_dotnet_solution: bool = FileAccess.file_exists("res://%s/%s.sln" % [directory, file_name])
 | 
							var has_dotnet_solution: bool = FileAccess.file_exists("res://%s/%s.sln" % [directory, file_name])
 | 
				
			||||||
		set_user_value("has_dotnet_solution", has_dotnet_solution)
 | 
							set_user_value("has_dotnet_solution", has_dotnet_solution)
 | 
				
			||||||
		return has_dotnet_solution
 | 
							return has_dotnet_solution
 | 
				
			||||||
	else:
 | 
					 | 
				
			||||||
		var plugin_path: String = new().get_script().resource_path.get_base_dir()
 | 
					 | 
				
			||||||
		if not ResourceLoader.exists(plugin_path + "/DialogueManager.cs"): return false
 | 
					 | 
				
			||||||
		if load(plugin_path + "/DialogueManager.cs") == null: return false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return true
 | 
						return false
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,8 @@ const SUPPORTED_BUILTIN_TYPES = [
 | 
				
			||||||
	TYPE_DICTIONARY,
 | 
						TYPE_DICTIONARY,
 | 
				
			||||||
	TYPE_QUATERNION,
 | 
						TYPE_QUATERNION,
 | 
				
			||||||
	TYPE_COLOR,
 | 
						TYPE_COLOR,
 | 
				
			||||||
	TYPE_SIGNAL
 | 
						TYPE_SIGNAL,
 | 
				
			||||||
 | 
						TYPE_CALLABLE
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -181,19 +181,20 @@ func _unhandled_input(event: InputEvent) -> void:
 | 
				
			||||||
	if not visible: return
 | 
						if not visible: return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if event is InputEventKey and event.is_pressed():
 | 
						if event is InputEventKey and event.is_pressed():
 | 
				
			||||||
		match event.as_text():
 | 
							var shortcut: String = Engine.get_meta("DialogueManagerPlugin").get_editor_shortcut(event)
 | 
				
			||||||
			"Ctrl+Alt+S", "Command+Alt+S":
 | 
							match shortcut:
 | 
				
			||||||
				get_viewport().set_input_as_handled()
 | 
								"close_file":
 | 
				
			||||||
				save_file(current_file_path)
 | 
					 | 
				
			||||||
			"Ctrl+W", "Command+W":
 | 
					 | 
				
			||||||
				get_viewport().set_input_as_handled()
 | 
									get_viewport().set_input_as_handled()
 | 
				
			||||||
				close_file(current_file_path)
 | 
									close_file(current_file_path)
 | 
				
			||||||
			"Ctrl+F5", "Command+F5":
 | 
								"save":
 | 
				
			||||||
				get_viewport().set_input_as_handled()
 | 
									get_viewport().set_input_as_handled()
 | 
				
			||||||
				_on_test_button_pressed()
 | 
									save_file(current_file_path)
 | 
				
			||||||
			"Ctrl+Shift+F", "Command+Shift+F":
 | 
								"find_in_files":
 | 
				
			||||||
				get_viewport().set_input_as_handled()
 | 
									get_viewport().set_input_as_handled()
 | 
				
			||||||
				_on_find_in_files_button_pressed()
 | 
									_on_find_in_files_button_pressed()
 | 
				
			||||||
 | 
								"run_test_scene":
 | 
				
			||||||
 | 
									get_viewport().set_input_as_handled()
 | 
				
			||||||
 | 
									_on_test_button_pressed()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func apply_changes() -> void:
 | 
					func apply_changes() -> void:
 | 
				
			||||||
| 
						 | 
					@ -1044,9 +1045,11 @@ func _on_files_list_file_middle_clicked(path: String):
 | 
				
			||||||
func _on_files_popup_menu_about_to_popup() -> void:
 | 
					func _on_files_popup_menu_about_to_popup() -> void:
 | 
				
			||||||
	files_popup_menu.clear()
 | 
						files_popup_menu.clear()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	files_popup_menu.add_item(DialogueConstants.translate(&"buffer.save"), ITEM_SAVE, KEY_MASK_CTRL | KEY_MASK_ALT | KEY_S)
 | 
						var shortcuts: Dictionary = Engine.get_meta("DialogueManagerPlugin").get_editor_shortcuts()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						files_popup_menu.add_item(DialogueConstants.translate(&"buffer.save"), ITEM_SAVE, OS.find_keycode_from_string(shortcuts.get("save")[0].as_text_keycode()))
 | 
				
			||||||
	files_popup_menu.add_item(DialogueConstants.translate(&"buffer.save_as"), ITEM_SAVE_AS)
 | 
						files_popup_menu.add_item(DialogueConstants.translate(&"buffer.save_as"), ITEM_SAVE_AS)
 | 
				
			||||||
	files_popup_menu.add_item(DialogueConstants.translate(&"buffer.close"), ITEM_CLOSE, KEY_MASK_CTRL | KEY_W)
 | 
						files_popup_menu.add_item(DialogueConstants.translate(&"buffer.close"), ITEM_CLOSE, OS.find_keycode_from_string(shortcuts.get("close_file")[0].as_text_keycode()))
 | 
				
			||||||
	files_popup_menu.add_item(DialogueConstants.translate(&"buffer.close_all"), ITEM_CLOSE_ALL)
 | 
						files_popup_menu.add_item(DialogueConstants.translate(&"buffer.close_all"), ITEM_CLOSE_ALL)
 | 
				
			||||||
	files_popup_menu.add_item(DialogueConstants.translate(&"buffer.close_other_files"), ITEM_CLOSE_OTHERS)
 | 
						files_popup_menu.add_item(DialogueConstants.translate(&"buffer.close_other_files"), ITEM_CLOSE_OTHERS)
 | 
				
			||||||
	files_popup_menu.add_separator()
 | 
						files_popup_menu.add_separator()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue