Compare commits

..

3 Commits

Author SHA1 Message Date
Nao db05f6eb9a Randomization Problem Wwise - Godot 2024-09-29 15:04:25 +02:00
Nao c1b0b0fd05 Test for Wwise 2024-09-04 14:24:23 +02:00
cblech e3ea51b354 Added wwise integration 2024-09-04 13:49:13 +02:00
835 changed files with 2076 additions and 47749 deletions
-4
View File
@@ -1,7 +1,3 @@
# Godot 4+ specific ignores
.godot/
/android/
# temporary files
**/*.tmp
**/*.translation
Binary file not shown.
+23
View File
@@ -0,0 +1,23 @@
Game Parameter ID Name Wwise Object Path Notes
504532776 Brick \Factory Acoustic Textures\Textures\Brick
513139656 Mountain \Factory Acoustic Textures\Textures\Mountain
841620460 Concrete \Factory Acoustic Textures\Textures\Concrete
1755085759 Wood_Deep \Factory Acoustic Textures\Textures\Wood_Deep
1873957695 Anechoic \Factory Acoustic Textures\Textures\Anechoic
1970351858 Fabric \Factory Acoustic Textures\Textures\Fabric
2058049674 Wood \Factory Acoustic Textures\Textures\Wood
2412606308 Carpet \Factory Acoustic Textures\Textures\Carpet
2637588553 Tile \Factory Acoustic Textures\Textures\Tile
2928161104 Curtains \Factory Acoustic Textures\Textures\Curtains
3195498748 Cork_Tiles \Factory Acoustic Textures\Textures\Cork_Tiles
3670307564 Drywall \Factory Acoustic Textures\Textures\Drywall
4168643977 Acoustic_Banner \Factory Acoustic Textures\Textures\Acoustic_Banner
4262522749 Wood_Bright \Factory Acoustic Textures\Textures\Wood_Bright
Audio Bus ID Name Wwise Object Path Notes
3803692087 Master Audio Bus \Default Work Unit\Master Audio Bus
Audio Devices ID Name Type Notes
2317455096 No_Output No Output
3859886410 System System
Binary file not shown.
+11
View File
@@ -0,0 +1,11 @@
Event ID Name Wwise Object Path Notes
3157003241 Test \Default Work Unit\Test
3833651337 Jump \Default Work Unit\Jump
In Memory Audio ID Name Audio source file Wwise Object Path Notes Data Size
143687057 SFX_Jump_02 D:\Game Projects\Babushka\Babushka_Wwise\Babushka\.cache\Windows\SFX\SFX_Jump_02_818F3B66.wem \Actor-Mixer Hierarchy\Default Work Unit\Jump\SFX_Jump_02 183312
190522504 SFX_Error D:\Game Projects\Babushka\Babushka_Wwise\Babushka\.cache\Windows\SFX\SFX_Error_818F3B66.wem \Actor-Mixer Hierarchy\Default Work Unit\SFX_Error 29040
260161493 SFX_Jump_03 D:\Game Projects\Babushka\Babushka_Wwise\Babushka\.cache\Windows\SFX\SFX_Jump_03_818F3B66.wem \Actor-Mixer Hierarchy\Default Work Unit\Jump\SFX_Jump_03 159880
413062689 SFX_Jump_05 D:\Game Projects\Babushka\Babushka_Wwise\Babushka\.cache\Windows\SFX\SFX_Jump_05_818F3B66.wem \Actor-Mixer Hierarchy\Default Work Unit\Jump\SFX_Jump_05 179052
963898419 SFX_Jump_04 D:\Game Projects\Babushka\Babushka_Wwise\Babushka\.cache\Windows\SFX\SFX_Jump_04_818F3B66.wem \Actor-Mixer Hierarchy\Default Work Unit\Jump\SFX_Jump_04 174792
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<PlatformInfo>
<Platform Name="Windows" BasePlatform="Windows" Generator="2023.1.6.8555"/>
<RootPaths>
<ProjectRoot>../../../Babushka_Wwise/Babushka</ProjectRoot>
<SourceFilesRoot>../../../Babushka_Wwise/Babushka/.cache/Windows</SourceFilesRoot>
<SoundBanksRoot>.</SoundBanksRoot>
<ExternalSourcesInputFile></ExternalSourcesInputFile>
<ExternalSourcesOutputRoot>../../../Babushka_Wwise/Babushka/GeneratedSoundBanks/Windows</ExternalSourcesOutputRoot>
</RootPaths>
<DefaultAlign>16</DefaultAlign>
<Settings>
<AutoSoundBankDefinition>false</AutoSoundBankDefinition>
<CopyLooseStreamedMediaFiles>true</CopyLooseStreamedMediaFiles>
<SubFoldersForGeneratedFiles>false</SubFoldersForGeneratedFiles>
<RemoveUnusedGeneratedFiles>true</RemoveUnusedGeneratedFiles>
<SourceControlGeneratedFiles>false</SourceControlGeneratedFiles>
<GenerateHeaderFile>false</GenerateHeaderFile>
<GenerateContentTxtFile>true</GenerateContentTxtFile>
<GenerateMetadataXML>true</GenerateMetadataXML>
<GenerateMetadataJSON>false</GenerateMetadataJSON>
<GenerateAllBanksMetadata>true</GenerateAllBanksMetadata>
<GeneratePerBankMetadata>false</GeneratePerBankMetadata>
<UseSoundBankNames>true</UseSoundBankNames>
<AllowExceedingMaxSize>false</AllowExceedingMaxSize>
<MaxAttenuationInfo>false</MaxAttenuationInfo>
<EstimatedDurationInfo>false</EstimatedDurationInfo>
<PrintObjectGuid>false</PrintObjectGuid>
<PrintObjectPath>false</PrintObjectPath>
</Settings>
<FileHash>{0D5998DA-3744-A3F7-BE47-D3829537549B}</FileHash>
</PlatformInfo>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<PluginInfo Platform="Windows" BasePlatform="Windows">
<PluginLibs>
<PluginLib LibName="System" LibId="11403271" Type="AudioDevice"/>
<PluginLib LibName="No Output" LibId="11862023" Type="AudioDevice"/>
</PluginLibs>
<FileHash>{0A13F4BA-B100-584C-1D1C-B9267B7D267A}</FileHash>
</PluginInfo>
@@ -0,0 +1,208 @@
<?xml version="1.0" encoding="utf-8"?>
<SoundBanksInfo Platform="Windows" BasePlatform="Windows" SchemaVersion="16" SoundBankVersion="150">
<RootPaths>
<ProjectRoot>../../../Babushka_Wwise/Babushka</ProjectRoot>
<SourceFilesRoot>../../../Babushka_Wwise/Babushka/.cache/Windows</SourceFilesRoot>
<SoundBanksRoot>.</SoundBanksRoot>
<ExternalSourcesInputFile></ExternalSourcesInputFile>
<ExternalSourcesOutputRoot>../../../Babushka_Wwise/Babushka/GeneratedSoundBanks/Windows</ExternalSourcesOutputRoot>
</RootPaths>
<DialogueEvents/>
<SoundBanks>
<SoundBank Id="1355168291" Type="User" Language="SFX" Hash="{AB9F0343-CD85-AB9E-58D8-B63D74A50185}">
<ShortName>Init</ShortName>
<Path>Init.bnk</Path>
<Plugins>
<AudioDevices>
<Plugin Id="2317455096" Name="No_Output" LibName="No Output" LibId="11862023"/>
<Plugin Id="3859886410" Name="System" LibName="System" LibId="11403271"/>
</AudioDevices>
</Plugins>
<Busses>
<Bus Id="3803692087" Name="Master Audio Bus"/>
</Busses>
<GameParameters>
<GameParameter Id="822163944" Name="SS_Air_RPM"/>
<GameParameter Id="1029930033" Name="SS_Air_Fury"/>
<GameParameter Id="1351367891" Name="SS_Air_Fear"/>
<GameParameter Id="2648548617" Name="SS_Air_Month"/>
<GameParameter Id="3002758120" Name="SS_Air_Freefall"/>
<GameParameter Id="3074696722" Name="SS_Air_Size"/>
<GameParameter Id="3203397129" Name="SS_Air_TimeOfDay"/>
<GameParameter Id="3715662592" Name="SS_Air_Storm"/>
<GameParameter Id="3847924954" Name="SS_Air_Presence"/>
<GameParameter Id="4160247818" Name="SS_Air_Turbulence"/>
</GameParameters>
<AcousticTextures>
<AcousticTexture Id="504532776" Name="Brick">
<Properties>
<Property Name="AbsorptionLow" Type="Real32" Value="12"/>
<Property Name="AbsorptionMidLow" Type="Real32" Value="18"/>
<Property Name="AbsorptionMidHigh" Type="Real32" Value="23"/>
<Property Name="AbsorptionHigh" Type="Real32" Value="35"/>
<Property Name="Scattering" Type="Real32" Value="0"/>
</Properties>
</AcousticTexture>
<AcousticTexture Id="513139656" Name="Mountain">
<Properties>
<Property Name="AbsorptionLow" Type="Real32" Value="0"/>
<Property Name="AbsorptionMidLow" Type="Real32" Value="0"/>
<Property Name="AbsorptionMidHigh" Type="Real32" Value="0"/>
<Property Name="AbsorptionHigh" Type="Real32" Value="0"/>
<Property Name="Scattering" Type="Real32" Value="0"/>
</Properties>
</AcousticTexture>
<AcousticTexture Id="841620460" Name="Concrete">
<Properties>
<Property Name="AbsorptionLow" Type="Real32" Value="6"/>
<Property Name="AbsorptionMidLow" Type="Real32" Value="6"/>
<Property Name="AbsorptionMidHigh" Type="Real32" Value="6"/>
<Property Name="AbsorptionHigh" Type="Real32" Value="14"/>
<Property Name="Scattering" Type="Real32" Value="0"/>
</Properties>
</AcousticTexture>
<AcousticTexture Id="1755085759" Name="Wood_Deep">
<Properties>
<Property Name="AbsorptionLow" Type="Real32" Value="1"/>
<Property Name="AbsorptionMidLow" Type="Real32" Value="8"/>
<Property Name="AbsorptionMidHigh" Type="Real32" Value="20"/>
<Property Name="AbsorptionHigh" Type="Real32" Value="35"/>
<Property Name="Scattering" Type="Real32" Value="0"/>
</Properties>
</AcousticTexture>
<AcousticTexture Id="1873957695" Name="Anechoic">
<Properties>
<Property Name="AbsorptionLow" Type="Real32" Value="100"/>
<Property Name="AbsorptionMidLow" Type="Real32" Value="100"/>
<Property Name="AbsorptionMidHigh" Type="Real32" Value="100"/>
<Property Name="AbsorptionHigh" Type="Real32" Value="100"/>
<Property Name="Scattering" Type="Real32" Value="0"/>
</Properties>
</AcousticTexture>
<AcousticTexture Id="1970351858" Name="Fabric">
<Properties>
<Property Name="AbsorptionLow" Type="Real32" Value="3"/>
<Property Name="AbsorptionMidLow" Type="Real32" Value="13"/>
<Property Name="AbsorptionMidHigh" Type="Real32" Value="48"/>
<Property Name="AbsorptionHigh" Type="Real32" Value="72"/>
<Property Name="Scattering" Type="Real32" Value="0"/>
</Properties>
</AcousticTexture>
<AcousticTexture Id="2058049674" Name="Wood">
<Properties>
<Property Name="AbsorptionLow" Type="Real32" Value="32"/>
<Property Name="AbsorptionMidLow" Type="Real32" Value="25"/>
<Property Name="AbsorptionMidHigh" Type="Real32" Value="20"/>
<Property Name="AbsorptionHigh" Type="Real32" Value="35"/>
<Property Name="Scattering" Type="Real32" Value="0"/>
</Properties>
</AcousticTexture>
<AcousticTexture Id="2412606308" Name="Carpet">
<Properties>
<Property Name="AbsorptionLow" Type="Real32" Value="46"/>
<Property Name="AbsorptionMidLow" Type="Real32" Value="45"/>
<Property Name="AbsorptionMidHigh" Type="Real32" Value="76"/>
<Property Name="AbsorptionHigh" Type="Real32" Value="100"/>
<Property Name="Scattering" Type="Real32" Value="0"/>
</Properties>
</AcousticTexture>
<AcousticTexture Id="2637588553" Name="Tile">
<Properties>
<Property Name="AbsorptionLow" Type="Real32" Value="67"/>
<Property Name="AbsorptionMidLow" Type="Real32" Value="41"/>
<Property Name="AbsorptionMidHigh" Type="Real32" Value="12"/>
<Property Name="AbsorptionHigh" Type="Real32" Value="0"/>
<Property Name="Scattering" Type="Real32" Value="0"/>
</Properties>
</AcousticTexture>
<AcousticTexture Id="2928161104" Name="Curtains">
<Properties>
<Property Name="AbsorptionLow" Type="Real32" Value="7"/>
<Property Name="AbsorptionMidLow" Type="Real32" Value="60"/>
<Property Name="AbsorptionMidHigh" Type="Real32" Value="0"/>
<Property Name="AbsorptionHigh" Type="Real32" Value="84"/>
<Property Name="Scattering" Type="Real32" Value="0"/>
</Properties>
</AcousticTexture>
<AcousticTexture Id="3195498748" Name="Cork_Tiles">
<Properties>
<Property Name="AbsorptionLow" Type="Real32" Value="14"/>
<Property Name="AbsorptionMidLow" Type="Real32" Value="30"/>
<Property Name="AbsorptionMidHigh" Type="Real32" Value="73"/>
<Property Name="AbsorptionHigh" Type="Real32" Value="100"/>
<Property Name="Scattering" Type="Real32" Value="0"/>
</Properties>
</AcousticTexture>
<AcousticTexture Id="3670307564" Name="Drywall">
<Properties>
<Property Name="AbsorptionLow" Type="Real32" Value="2"/>
<Property Name="AbsorptionMidLow" Type="Real32" Value="2"/>
<Property Name="AbsorptionMidHigh" Type="Real32" Value="2"/>
<Property Name="AbsorptionHigh" Type="Real32" Value="2"/>
<Property Name="Scattering" Type="Real32" Value="0"/>
</Properties>
</AcousticTexture>
<AcousticTexture Id="4168643977" Name="Acoustic_Banner">
<Properties>
<Property Name="AbsorptionLow" Type="Real32" Value="37"/>
<Property Name="AbsorptionMidLow" Type="Real32" Value="100"/>
<Property Name="AbsorptionMidHigh" Type="Real32" Value="100"/>
<Property Name="AbsorptionHigh" Type="Real32" Value="100"/>
<Property Name="Scattering" Type="Real32" Value="0"/>
</Properties>
</AcousticTexture>
<AcousticTexture Id="4262522749" Name="Wood_Bright">
<Properties>
<Property Name="AbsorptionLow" Type="Real32" Value="32"/>
<Property Name="AbsorptionMidLow" Type="Real32" Value="25"/>
<Property Name="AbsorptionMidHigh" Type="Real32" Value="10"/>
<Property Name="AbsorptionHigh" Type="Real32" Value="9"/>
<Property Name="Scattering" Type="Real32" Value="0"/>
</Properties>
</AcousticTexture>
</AcousticTextures>
</SoundBank>
<SoundBank Id="3161908922" Type="User" Language="SFX" Hash="{9878BE72-4D56-F2EF-127E-6C071B346441}">
<ShortName>Main</ShortName>
<Path>Main.bnk</Path>
<Media>
<File Id="143687057" Language="SFX" Streaming="false" Location="Memory">
<ShortName>SFX_Jump_02.wav</ShortName>
<CachePath>SFX/SFX_Jump_02_818F3B66.wem</CachePath>
</File>
<File Id="190522504" Language="SFX" Streaming="false" Location="Memory">
<ShortName>SFX_Error.wav</ShortName>
<CachePath>SFX/SFX_Error_818F3B66.wem</CachePath>
</File>
<File Id="260161493" Language="SFX" Streaming="false" Location="Memory">
<ShortName>SFX_Jump_03.wav</ShortName>
<CachePath>SFX/SFX_Jump_03_818F3B66.wem</CachePath>
</File>
<File Id="413062689" Language="SFX" Streaming="false" Location="Memory">
<ShortName>SFX_Jump_05.wav</ShortName>
<CachePath>SFX/SFX_Jump_05_818F3B66.wem</CachePath>
</File>
<File Id="963898419" Language="SFX" Streaming="false" Location="Memory">
<ShortName>SFX_Jump_04.wav</ShortName>
<CachePath>SFX/SFX_Jump_04_818F3B66.wem</CachePath>
</File>
</Media>
<Events>
<Event Id="3833651337" Name="Jump">
<MediaRefs>
<MediaRef Id="143687057"/>
<MediaRef Id="260161493"/>
<MediaRef Id="413062689"/>
<MediaRef Id="963898419"/>
</MediaRefs>
</Event>
<Event Id="3157003241" Name="Test">
<MediaRefs>
<MediaRef Id="190522504"/>
</MediaRefs>
</Event>
</Events>
</SoundBank>
</SoundBanks>
<FileHash>{EC2B4A58-41D2-3263-26FD-0EC5819FA29C}</FileHash>
</SoundBanksInfo>
+86
View File
@@ -0,0 +1,86 @@
class_name AK
class EVENTS:
const JUMP = 3833651337
const TEST = 3157003241
const _dict = {
"Jump": JUMP,
"Test": TEST
}
class STATES:
const _dict = {}
class SWITCHES:
const _dict = {}
class GAME_PARAMETERS:
const SS_AIR_TIMEOFDAY = 3203397129
const SS_AIR_TURBULENCE = 4160247818
const SS_AIR_MONTH = 2648548617
const SS_AIR_PRESENCE = 3847924954
const SS_AIR_FURY = 1029930033
const SS_AIR_STORM = 3715662592
const SS_AIR_FREEFALL = 3002758120
const SS_AIR_RPM = 822163944
const SS_AIR_SIZE = 3074696722
const SS_AIR_FEAR = 1351367891
const _dict = {
"SS_Air_TimeOfDay": SS_AIR_TIMEOFDAY,
"SS_Air_Turbulence": SS_AIR_TURBULENCE,
"SS_Air_Month": SS_AIR_MONTH,
"SS_Air_Presence": SS_AIR_PRESENCE,
"SS_Air_Fury": SS_AIR_FURY,
"SS_Air_Storm": SS_AIR_STORM,
"SS_Air_Freefall": SS_AIR_FREEFALL,
"SS_Air_RPM": SS_AIR_RPM,
"SS_Air_Size": SS_AIR_SIZE,
"SS_Air_Fear": SS_AIR_FEAR
}
class TRIGGERS:
const _dict = {}
class BANKS:
const INIT = 1355168291
const MAIN = 3161908922
const _dict = {
"Init": INIT,
"Main": MAIN
}
class BUSSES:
const MASTER_AUDIO_BUS = 3803692087
const _dict = {
"Master Audio Bus": MASTER_AUDIO_BUS
}
class AUX_BUSSES:
const _dict = {}
class AUDIO_DEVICES:
const SYSTEM = 3859886410
const NO_OUTPUT = 2317455096
const _dict = {
"System": SYSTEM,
"No_Output": NO_OUTPUT
}
class EXTERNAL_SOURCES:
const _dict = {}
+47
View File
@@ -0,0 +1,47 @@
[gd_scene format=3 uid="uid://bc0hrnjouuhb4"]
[node name="Node2D" type="Node2D"]
[node name="Button" type="Button" parent="."]
offset_left = 266.0
offset_top = 141.0
offset_right = 844.0
offset_bottom = 391.0
[node name="Button2" type="Button" parent="."]
offset_left = 58.0
offset_top = 29.0
offset_right = 220.0
offset_bottom = 210.0
[node name="AkBank_Init" type="AkBank" parent="."]
bank = {
"id": 1355168291,
"name": "Init"
}
load_on = 1
[node name="AkBank_Main" type="AkBank" parent="AkBank_Init"]
bank = {
"id": 3161908922,
"name": "Main"
}
load_on = 1
[node name="AkEvent_TestEvent" type="AkEvent2D" parent="AkBank_Init/AkBank_Main"]
event = {
"id": 3157003241,
"name": "Test"
}
position = Vector2(266, 141)
[node name="AkEvent_Jump" type="AkEvent2D" parent="AkBank_Init/AkBank_Main"]
event = {
"id": 3833651337,
"name": "Jump"
}
[node name="AkListener2D" type="AkListener2D" parent="."]
[connection signal="pressed" from="Button" to="AkBank_Init/AkBank_Main/AkEvent_TestEvent" method="post_event"]
[connection signal="pressed" from="Button2" to="AkBank_Init/AkBank_Main/AkEvent_Jump" method="post_event"]
+2
View File
@@ -0,0 +1,2 @@
class AkBuildExport:
extends AkEditorExportPlugin
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
<g transform="matrix(1,0,0,1,-140,-285)">
<g transform="matrix(1,0,0,1,140,285)">
<g id="ObjectIcons_AcousticTexture_nor">
<g id="Icons">
<g transform="matrix(1,0,0,1,-40,-25)">
<g id="Base-Block" serif:id="Base Block">
<path d="M55,27.1C55,25.941 54.059,25 52.9,25L42.1,25C40.941,25 40,25.941 40,27.1L40,37.9C40,39.059 40.941,40 42.1,40L52.9,40C54.059,40 55,39.059 55,37.9L55,27.1Z" style="fill-opacity:0;"/>
</g>
</g>
<path d="M9,5.086L9,2.5C9,1.672 9.672,1 10.5,1C11.328,1 12,1.672 12,2.5L12,3.086C12.156,3.03 12.325,3 12.5,3C13.328,3 14,3.672 14,4.5L14,12.5C14,13.328 13.328,14 12.5,14C12.5,14 2.5,14 2.5,14C1.672,14 1,13.328 1,12.5L1,6.5C1,5.672 1.672,5 2.5,5C3.328,5 4,5.672 4,6.5L4,9.086C4.156,9.03 4.325,9 4.5,9C4.675,9 4.844,9.03 5,9.086L5,8.5C5,7.672 5.672,7 6.5,7C6.675,7 6.844,7.03 7,7.086L7,6.5C7,5.672 7.672,5 8.5,5C8.675,5 8.844,5.03 9,5.086ZM11,13L11,2L10,2L10,13L11,13ZM7,13L7,8L6,8L6,13L7,13ZM3,13L3,6L2,6L2,13L3,13ZM9,13L9,6L8,6L8,13L9,13ZM13,13L13,4L12,4L12,13L13,13ZM5,13L5,10L4,10L4,13L5,13Z" style="fill:rgb(34,34,34);"/>
<g transform="matrix(-1,0,0,1.75,5,2.5)">
<rect x="2" y="2" width="1" height="4" style="fill:rgb(216,216,216);"/>
</g>
<g transform="matrix(-1,0,0,1.5,9,7)">
<rect x="4" y="2" width="1" height="2" style="fill:rgb(216,216,216);"/>
</g>
<g transform="matrix(-1,0,0,1.66667,13,4.66667)">
<rect x="6" y="2" width="1" height="3" style="fill:rgb(216,216,216);"/>
</g>
<g transform="matrix(-1,0,0,1.75,17,2.5)">
<rect x="8" y="2" width="1" height="4" style="fill:rgb(216,216,216);"/>
</g>
<g transform="matrix(-1,0,0,1.83333,21,-1.66667)">
<rect x="10" y="2" width="1" height="6" style="fill:rgb(216,216,216);"/>
</g>
<g transform="matrix(-1,0,0,1.8,25,0.4)">
<rect x="12" y="2" width="1" height="5" style="fill:rgb(216,216,216);"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

@@ -2,25 +2,24 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://2fkk71l86stl"
path="res://.godot/imported/DNextIndicator_icon.svg-d8f962ed97aa9f929346c153ee39c52b.ctex"
uid="uid://dtl5m1faegd7c"
path="res://.godot/imported/AcousticTexture_nor.svg-7052446467938c70bece44de02fa6583.ctex"
metadata={
"editor_scale": 1.25,
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/dialogic/Events/Text/DNextIndicator_icon.svg"
dest_files=["res://.godot/imported/DNextIndicator_icon.svg-d8f962ed97aa9f929346c153ee39c52b.ctex"]
source_file="res://addons/Wwise/editor/images/AcousticTexture_nor.svg"
dest_files=["res://.godot/imported/AcousticTexture_nor.svg-7052446467938c70bece44de02fa6583.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><g id="ObjectIcons_AuxBus_nor"><path id="AuxBus" d="M15,2.1c0,-1.159 -0.941,-2.1 -2.1,-2.1l-10.8,0c-1.159,0 -2.1,0.941 -2.1,2.1l0,10.8c0,1.159 0.941,2.1 2.1,2.1l10.8,0c1.159,0 2.1,-0.941 2.1,-2.1l0,-10.8Z" style="fill-opacity:0;"/><g id="AuxBus1" serif:id="AuxBus"><path d="M12,4.409c0,-0.778 -0.631,-1.409 -1.409,-1.409c0,0 -8.182,0 -8.182,0c-0.778,0 -1.409,0.631 -1.409,1.409c0,0 0,6.005 0,6.005l3.586,3.586l6.005,0c0.778,0 1.409,-0.631 1.409,-1.409l0,-8.182Z" style="fill:#212121;"/><path d="M4.5,0c-0.828,0 -1.5,0.672 -1.5,1.5l0,1c0,0.828 0.672,1.5 1.5,1.5c0.828,0 1.5,-0.672 1.5,-1.5l0,-1c0,-0.828 -0.672,-1.5 -1.5,-1.5Z" style="fill:#212121;"/><path d="M6.5,0c-0.828,0 -1.5,0.672 -1.5,1.5l0,1c0,0.828 0.672,1.5 1.5,1.5c0.828,0 1.5,-0.672 1.5,-1.5l0,-1c0,-0.828 -0.672,-1.5 -1.5,-1.5Z" style="fill:#212121;"/><path d="M8.5,0c-0.828,0 -1.5,0.672 -1.5,1.5l0,1c0,0.828 0.672,1.5 1.5,1.5c0.828,0 1.5,-0.672 1.5,-1.5l0,-1c0,-0.828 -0.672,-1.5 -1.5,-1.5Z" style="fill:#212121;"/><path d="M4,1l0,2l1,0l0,-2l-1,0Z" style="fill:#c8c8c8;"/><path d="M6,1l0,2l1,0l0,-2l-1,0Z" style="fill:#c8c8c8;"/><path d="M8,1l0,2l1,0l0,-2l-1,0Z" style="fill:#c8c8c8;"/><path d="M15,6.5c0,-0.828 -0.672,-1.5 -1.5,-1.5l-1,0c-0.828,0 -1.5,0.672 -1.5,1.5c0,0.828 0.672,1.5 1.5,1.5l1,0c0.828,0 1.5,-0.672 1.5,-1.5Z" style="fill:#212121;"/><path d="M15,8.5c0,-0.828 -0.672,-1.5 -1.5,-1.5l-1,0c-0.828,0 -1.5,0.672 -1.5,1.5c0,0.828 0.672,1.5 1.5,1.5l1,0c0.828,0 1.5,-0.672 1.5,-1.5Z" style="fill:#212121;"/><path d="M15,10.5c0,-0.828 -0.672,-1.5 -1.5,-1.5l-1,0c-0.828,0 -1.5,0.672 -1.5,1.5c0,0.828 0.672,1.5 1.5,1.5l1,0c0.828,0 1.5,-0.672 1.5,-1.5Z" style="fill:#212121;"/><rect x="12" y="6" width="2" height="1" style="fill:#c8c8c8;"/><rect x="12" y="8" width="2" height="1" style="fill:#c8c8c8;"/><rect x="12" y="10" width="2" height="1" style="fill:#c8c8c8;"/><path d="M11,4.409c0,-0.226 -0.183,-0.409 -0.409,-0.409l-8.182,0c-0.226,0 -0.409,0.183 -0.409,0.409l0,5.591l3,3l5.591,0c0.226,0 0.409,-0.183 0.409,-0.409l0,-8.182Z" style="fill:#c8c8c8;"/><rect x="8" y="3" width="1" height="1" style="fill:#919191;"/><rect x="6" y="3" width="1" height="1" style="fill:#919191;"/><rect x="4" y="3" width="1" height="1" style="fill:#919191;"/><rect x="11" y="6" width="1" height="1" style="fill:#919191;"/><rect x="11" y="8" width="1" height="1" style="fill:#919191;"/><rect x="11" y="10" width="1" height="1" style="fill:#919191;"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

@@ -2,8 +2,8 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://b7j220k0ewh35"
path="res://.godot/imported/join.svg-2f0d7b9e8e01cf0e62b8c3a85aff6213.ctex"
uid="uid://brb20yxmqs8ns"
path="res://.godot/imported/AuxBus_nor.svg-1ed6d09f61a4b44ca5939327fb4d9f5c.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
@@ -11,8 +11,8 @@ metadata={
[deps]
source_file="res://addons/dialogic/Editor/Images/Dropdown/join.svg"
dest_files=["res://.godot/imported/join.svg-2f0d7b9e8e01cf0e62b8c3a85aff6213.ctex"]
source_file="res://addons/Wwise/editor/images/AuxBus_nor.svg"
dest_files=["res://.godot/imported/AuxBus_nor.svg-1ed6d09f61a4b44ca5939327fb4d9f5c.ctex"]
[params]
@@ -35,4 +35,4 @@ process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
editor/convert_colors_with_editor_theme=false
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><g id="ObjectIcons_BusSimple_nor"><g id="Base-Block" serif:id="Base Block"><path d="M15,2.1c0,-1.159 -0.941,-2.1 -2.1,-2.1l-10.8,0c-1.159,0 -2.1,0.941 -2.1,2.1l0,10.8c0,1.159 0.941,2.1 2.1,2.1l10.8,0c1.159,0 2.1,-0.941 2.1,-2.1l0,-10.8Z" style="fill-opacity:0;"/></g><g id="Bus"><path d="M15,2c0,-0.552 -0.448,-1 -1,-1l-11,0c-0.552,0 -1,0.448 -1,1l0,11c0,0.552 0.448,1 1,1l11,0c0.552,0 1,-0.448 1,-1l0,-11Z" style="fill:#212121;"/><path d="M4,5.5c0,-0.828 -0.672,-1.5 -1.5,-1.5l-1,0c-0.828,0 -1.5,0.672 -1.5,1.5c0,0.828 0.672,1.5 1.5,1.5l1,0c0.828,0 1.5,-0.672 1.5,-1.5Z" style="fill:#212121;"/><path d="M4,7.5c0,-0.828 -0.672,-1.5 -1.5,-1.5l-1,0c-0.828,0 -1.5,0.672 -1.5,1.5c0,0.828 0.672,1.5 1.5,1.5l1,0c0.828,0 1.5,-0.672 1.5,-1.5Z" style="fill:#212121;"/><path d="M4,9.5c0,-0.828 -0.672,-1.5 -1.5,-1.5l-1,0c-0.828,0 -1.5,0.672 -1.5,1.5c0,0.828 0.672,1.5 1.5,1.5l1,0c0.828,0 1.5,-0.672 1.5,-1.5Z" style="fill:#212121;"/><path d="M14,2.5c0,-0.276 -0.224,-0.5 -0.5,-0.5l-10,0c-0.276,0 -0.5,0.224 -0.5,0.5l0,10c0,0.276 0.224,0.5 0.5,0.5l10,0c0.276,0 0.5,-0.224 0.5,-0.5l0,-10Z" style="fill:#c8c8c8;"/><rect x="1" y="5" width="1" height="1" style="fill:#c8c8c8;"/><rect x="1" y="7" width="1" height="1" style="fill:#c8c8c8;"/><rect x="1" y="9" width="1" height="1" style="fill:#c8c8c8;"/><path d="M3,10l-1,0l0,-1l1,0l0,1Zm0,-2l-1,0l0,-1l1,0l0,1Zm0,-2l-1,0l0,-1l1,0l0,1Z" style="fill:#919191;"/></g><g id="Parameters"><rect x="4" y="4" width="3" height="1" style="fill:#222;fill-opacity:0.41;"/><rect x="4" y="4" width="3" height="1" style="fill:#919191;"/><rect x="5" y="4" width="2" height="1" style="fill:#222;fill-opacity:0.73;"/><rect x="5" y="4" width="2" height="1" style="fill:#434343;"/><rect x="4" y="6" width="3" height="1" style="fill:#222;fill-opacity:0.41;"/><rect x="4" y="6" width="3" height="1" style="fill:#222;fill-opacity:0.73;"/><rect x="4" y="6" width="3" height="1" style="fill:#434343;"/><rect x="8" y="6" width="4" height="1" style="fill:#222;"/><rect x="8" y="6" width="4" height="1" style="fill:#212121;"/><rect x="8" y="4" width="4" height="1" style="fill:#222;"/><rect x="8" y="4" width="4" height="1" style="fill:#212121;"/><rect x="5" y="8" width="2" height="1" style="fill:#222;fill-opacity:0.41;"/><rect x="5" y="8" width="2" height="1" style="fill:#919191;"/><rect x="7" y="4" width="1" height="1" style="fill:#222;fill-opacity:0.3;"/><rect x="7" y="4" width="1" height="1" style="fill:#919191;"/><rect x="7" y="6" width="1" height="1" style="fill:#222;fill-opacity:0.3;"/><path d="M7,6l1,0l0,1l-1,0l0,-1Zm0.5,0.5c0,0 0,0 0,0Z" style="fill:#919191;"/><rect x="7" y="8" width="1" height="1" style="fill:#222;fill-opacity:0.3;"/><path d="M7,8l1,0l0,1l-1,0l0,-1Zm0.5,0.5c0,0 0,0 0,0Z" style="fill:#919191;"/><rect x="6" y="8" width="1" height="1" style="fill:#222;fill-opacity:0.73;"/><rect x="6" y="8" width="1" height="1" style="fill:#434343;"/><rect x="8" y="8" width="4" height="1" style="fill:#222;"/><rect x="8" y="8" width="4" height="1" style="fill:#212121;"/><rect x="12" y="8" width="1" height="1" style="fill:#222;fill-opacity:0.6;"/><path d="M12,8l1,0l0,1l-1,0l0,-1Zm0.5,0.5c0,0 0,0 0,0Z" style="fill:#717171;"/><rect x="12" y="6" width="1" height="1" style="fill:#222;fill-opacity:0.6;"/><path d="M12,6l1,0l0,1l-1,0l0,-1Zm0.5,0.5c0,0 0,0 0,0Z" style="fill:#717171;"/><rect x="12" y="4" width="1" height="1" style="fill:#222;fill-opacity:0.6;"/><rect x="12" y="4" width="1" height="1" style="fill:#717171;"/></g></g></svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

@@ -2,8 +2,8 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://kwk8ola23icj"
path="res://.godot/imported/icon_return.svg-dc7fb704ff391638f73cbbc2b30b32fa.ctex"
uid="uid://bberivmnwa7b7"
path="res://.godot/imported/BusSimple_nor.svg-2a7d7eb1bbea7edeae1f09d1fd0259dc.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
@@ -11,8 +11,8 @@ metadata={
[deps]
source_file="res://addons/dialogic/Modules/Jump/icon_return.svg"
dest_files=["res://.godot/imported/icon_return.svg-dc7fb704ff391638f73cbbc2b30b32fa.ctex"]
source_file="res://addons/Wwise/editor/images/BusSimple_nor.svg"
dest_files=["res://.godot/imported/BusSimple_nor.svg-2a7d7eb1bbea7edeae1f09d1fd0259dc.ctex"]
[params]
@@ -35,4 +35,4 @@ process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
editor/convert_colors_with_editor_theme=false
+45
View File
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
<g transform="matrix(1,0,0,1,-20,-45)">
<g transform="matrix(1,0,0,1,20,45)">
<g id="ObjectIcons_Event_nor">
<g id="Icons">
<g transform="matrix(1,0,0,1,-40,-25)">
<g id="Base-Block" serif:id="Base Block">
<path d="M55,27.1C55,25.941 54.059,25 52.9,25L42.1,25C40.941,25 40,25.941 40,27.1L40,37.9C40,39.059 40.941,40 42.1,40L52.9,40C54.059,40 55,39.059 55,37.9L55,27.1Z" style="fill-opacity:0;"/>
</g>
</g>
<path d="M4.86,6L2.14,6C1.511,6 1,5.489 1,4.86L1,4.14C1,3.512 1.509,3.001 2.14,3L4.86,3L4.976,3.006L5,3.009L5,2.56C5,1.7 5.698,1.001 6.56,1L9.44,1C10.302,1.001 11,1.7 11,2.56L11,5L12.86,5C13.495,5.006 14,5.515 14,6.14L14,6.86C14,7.488 13.491,7.999 12.86,8C13.491,8.001 14,8.512 14,9.14L14,9.86C14,10.485 13.495,10.994 12.86,11L11,11L12.86,11C13.491,11.001 14,11.512 14,12.14L14,12.86C14,13.486 13.494,13.995 12.86,14L10.14,14C10.028,14 9.919,13.984 9.816,13.952C9.7,13.983 9.578,13.999 9.44,14L6.56,14C5.699,14 5,13.301 5,12.44L5,5.991L4.976,5.994L4.86,6ZM10,6L10,2L6,2L6,4L2,4L2,5L6,5L6,13L13,13L13,12L10,12L10,10L13,10L13,9L10,9L10,7L13,7L13,6L10,6Z" style="fill:rgb(34,34,34);"/>
<g transform="matrix(0.5,0,0,1,6,2)">
<rect x="10" y="7" width="4" height="1" style="fill:rgb(200,200,200);"/>
</g>
<g transform="matrix(0.5,0,0,1,6,-3)">
<rect x="10" y="9" width="4" height="1" style="fill:rgb(200,200,200);"/>
</g>
<g transform="matrix(0.5,0,0,1,6,7)">
<rect x="10" y="5" width="4" height="1" style="fill:rgb(200,200,200);"/>
</g>
<g transform="matrix(0.75,0,0,1,1.25,-5)">
<rect x="1" y="9" width="4" height="1" style="fill:rgb(200,200,200);"/>
</g>
<g transform="matrix(0.8,0,0,1.57143,2,-4.28571)">
<rect x="5" y="4" width="5" height="7" style="fill:rgb(200,200,200);"/>
</g>
<g transform="matrix(-1,-0,0,1,21,-3)">
<rect x="10" y="9" width="1" height="1" style="fill:rgb(113,113,113);"/>
</g>
<g transform="matrix(-1,-0,0,1,21,2)">
<rect x="10" y="7" width="1" height="1" style="fill:rgb(113,113,113);"/>
</g>
<g transform="matrix(-1,-0,0,1,21,7)">
<rect x="10" y="5" width="1" height="1" style="fill:rgb(113,113,113);"/>
</g>
<g transform="matrix(-1,-0,0,1,10,-5)">
<rect x="4" y="9" width="1" height="1" style="fill:rgb(113,113,113);"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

@@ -2,8 +2,8 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://cspjyvye6c0r6"
path="res://.godot/imported/leave.svg-c936f6e3d601b8c12c23f205a765084e.ctex"
uid="uid://c6320wx4uohhj"
path="res://.godot/imported/Event_nor.svg-cca1b541d543badefe73ca9210414ad3.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
@@ -11,8 +11,8 @@ metadata={
[deps]
source_file="res://addons/dialogic/Editor/Images/Dropdown/leave.svg"
dest_files=["res://.godot/imported/leave.svg-c936f6e3d601b8c12c23f205a765084e.ctex"]
source_file="res://addons/Wwise/editor/images/Event_nor.svg"
dest_files=["res://.godot/imported/Event_nor.svg-cca1b541d543badefe73ca9210414ad3.ctex"]
[params]
@@ -35,4 +35,4 @@ process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
editor/convert_colors_with_editor_theme=false
+23
View File
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
<g transform="matrix(1,0,0,1,-40,-85)">
<g transform="matrix(1,0,0,1,40,86.0003)">
<g id="ObjectIcons_Folder_nor">
<g id="Icons">
<g transform="matrix(1,0,0,1,-40,-26.0003)">
<g id="Base-Block" serif:id="Base Block">
<path d="M55,27.1C55,25.941 54.059,25 52.9,25L42.1,25C40.941,25 40,25.941 40,27.1L40,37.9C40,39.059 40.941,40 42.1,40L52.9,40C54.059,40 55,39.059 55,37.9L55,27.1Z" style="fill-opacity:0;"/>
</g>
</g>
<path d="M0,0L0,13L15,13L15,2L8,1.999L8,-0.001L0,0ZM7,3L7,1L1,1L1,12L14,12L14,3L7,3Z" style="fill:rgb(34,34,34);"/>
<path d="M7,3L14,3L14,12L1,12L1,3L1,1L7,1L7,3ZM6,4L6,2L2,2L2,11L13,11L13,4L6,4Z" style="fill:rgb(200,200,200);"/>
<path d="M6,4L13,4L13,11L2,11L2,4L2,2L6,2L6,4ZM5,5L5,3L3,3L3,10L12,10L12,5L5,5Z" style="fill:rgb(67,67,67);"/>
<g transform="matrix(1,0,0,1,-60,-46.0003)">
<path d="M65,51L72,51L72,56L63,56L63,51L63,49L65,49L65,51Z" style="fill:rgb(145,145,145);"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -2,16 +2,17 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://bxvjpd6uwhaw7"
path="res://.godot/imported/node_dialog_text_icon.svg-3cf845e99d76137d8156865c09f39e3e.ctex"
uid="uid://ip6ktdm4yldl"
path="res://.godot/imported/Folder_nor.svg-bcc9eb4105339dfc40b4fabeac9d5ceb.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/dialogic/Modules/Text/node_dialog_text_icon.svg"
dest_files=["res://.godot/imported/node_dialog_text_icon.svg-3cf845e99d76137d8156865c09f39e3e.ctex"]
source_file="res://addons/Wwise/editor/images/Folder_nor.svg"
dest_files=["res://.godot/imported/Folder_nor.svg-bcc9eb4105339dfc40b4fabeac9d5ceb.ctex"]
[params]
@@ -33,5 +34,5 @@ process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=false
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
<g transform="matrix(1,0,0,1,-20,-165)">
<g transform="matrix(1,0,0,1,20,165)">
<g id="ObjectIcons_GameParameter_nor">
<g id="Icons">
<g transform="matrix(1,0,0,1,-40,-25)">
<g id="Base-Block" serif:id="Base Block">
<path d="M55,27.1C55,25.941 54.059,25 52.9,25L42.1,25C40.941,25 40,25.941 40,27.1L40,37.9C40,39.059 40.941,40 42.1,40L52.9,40C54.059,40 55,39.059 55,37.9L55,27.1Z" style="fill-opacity:0;"/>
</g>
</g>
<path d="M9.802,6C9.589,6.323 9.317,6.594 9,6.8L9,9.205C9.753,9.695 10.25,10.544 10.25,11.508C10.25,13.025 9.019,14.256 7.502,14.256C6.536,14.256 5.685,13.756 5.196,13L0.75,13C0.336,13 0,12.664 0,12.25L0,10.75C0,10.337 0.335,10.001 0.75,10L5.206,10C5.413,9.685 5.684,9.415 6,9.208L6,6.797C5.25,6.307 4.754,5.459 4.754,4.497C4.754,2.98 5.986,1.749 7.502,1.749C8.464,1.749 9.311,2.244 9.806,3L14.25,3C14.67,3.007 15,3.34 15,3.75L15,5.25C15,5.66 14.67,5.993 14.25,6L9.802,6ZM14,5L14,4L9.177,4C8.962,3.277 8.292,2.75 7.5,2.75C6.534,2.75 5.75,3.534 5.75,4.5C5.75,5.292 6.277,5.962 7,6.177L7,9.823C6.436,9.991 5.991,10.436 5.823,11L1,11L1,12L5.823,12C6.038,12.723 6.708,13.25 7.5,13.25C8.466,13.25 9.25,12.466 9.25,11.5C9.25,10.708 8.723,10.038 8,9.823L8,6.177C8.561,6.01 9.004,5.57 9.177,5L14,5Z" style="fill:rgb(34,34,34);"/>
<g transform="matrix(1,0,0,1,-80,-45)">
<path d="M87,51.177C86.277,50.962 85.75,50.292 85.75,49.5C85.75,48.534 86.534,47.75 87.5,47.75C88.292,47.75 88.962,48.277 89.177,49C89.264,49.363 89.261,49.695 89.177,50C89.009,50.564 88.564,51.009 88,51.177L88,54.823C88.723,55.038 89.25,55.708 89.25,56.5C89.25,57.466 88.466,58.25 87.5,58.25C86.708,58.25 86.038,57.723 85.823,57C85.727,56.693 85.721,56.361 85.823,56C85.991,55.436 86.436,54.991 87,54.823L87,51.177Z" style="fill:rgb(216,216,216);"/>
</g>
<g transform="matrix(3.31388e-17,-0.138727,-1,-4.66124e-16,15,7.54407)">
<path d="M10,7L4,7L4,8L10,8C9.35,7.679 9.37,7.345 10,7Z" style="fill:rgb(113,113,113);"/>
</g>
<g transform="matrix(-5.86225e-17,0.138727,1,4.83287e-16,2.45137e-13,7.44509)">
<path d="M17.208,7L15.764,7L15.586,7L11.208,7L11.208,8L17.208,8C16.559,7.679 16.579,7.345 17.208,7Z" style="fill:rgb(113,113,113);"/>
</g>
<g transform="matrix(-0.138727,0,0,1,10.5549,-3)">
<path d="M10,7L4,7L4,8L10,8C9.35,7.679 9.37,7.345 10,7Z" style="fill:rgb(113,113,113);"/>
</g>
<g transform="matrix(1,0,0,1,-80,-45)">
<rect x="90" y="49" width="4" height="1" style="fill:rgb(226,226,226);"/>
</g>
<g transform="matrix(-0.166667,0,0,1,6.66667,3)">
<path d="M10,8L5.128,8C5.632,8.311 5.691,8.642 5.128,9L10,9L10,8Z" style="fill:rgb(113,113,113);"/>
</g>
<g transform="matrix(1,0,0,1,-89,-38)">
<rect x="90" y="49" width="4" height="1" style="fill:rgb(226,226,226);"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

@@ -2,8 +2,8 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://d4n3j4lvatwxb"
path="res://.godot/imported/warning.svg-a48ae93c4663637f2aca88d055604495.ctex"
uid="uid://tqoikjxbffrh"
path="res://.godot/imported/GameParameter_nor.svg-6a742992ddee792a08392182410a7099.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
@@ -11,8 +11,8 @@ metadata={
[deps]
source_file="res://addons/dialogic/Editor/Images/Pieces/warning.svg"
dest_files=["res://.godot/imported/warning.svg-a48ae93c4663637f2aca88d055604495.ctex"]
source_file="res://addons/Wwise/editor/images/GameParameter_nor.svg"
dest_files=["res://.godot/imported/GameParameter_nor.svg-6a742992ddee792a08392182410a7099.ctex"]
[params]
@@ -35,4 +35,4 @@ process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
editor/convert_colors_with_editor_theme=false
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.7 KiB

@@ -2,8 +2,8 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://bsx8dtqf3vych"
path="res://.godot/imported/default.svg-3f34de5e45bef5de4d9c15ef78c00c6c.ctex"
uid="uid://5lleamn0de73"
path="res://.godot/imported/Project_nor.svg-58e5690f105d9fa4cc5677e77b09a4c1.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
@@ -11,8 +11,8 @@ metadata={
[deps]
source_file="res://addons/dialogic/Editor/Images/Dropdown/default.svg"
dest_files=["res://.godot/imported/default.svg-3f34de5e45bef5de4d9c15ef78c00c6c.ctex"]
source_file="res://addons/Wwise/editor/images/Project_nor.svg"
dest_files=["res://.godot/imported/Project_nor.svg-58e5690f105d9fa4cc5677e77b09a4c1.ctex"]
[params]
@@ -35,4 +35,4 @@ process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
editor/convert_colors_with_editor_theme=false
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><g id="ObjectIcons_SoundbankInit_nor"><g id="Icons"><g id="Base-Block" serif:id="Base Block"><path d="M15,2.1c-0,-1.159 -0.941,-2.1 -2.1,-2.1l-10.8,0c-1.159,0 -2.1,0.941 -2.1,2.1l-0,10.8c-0,1.159 0.941,2.1 2.1,2.1l10.8,0c1.159,0 2.1,-0.941 2.1,-2.1l-0,-10.8Z" style="fill-opacity:0;"/></g><path d="M2,4l-0.25,0c-0.966,0 -1.75,0.784 -1.75,1.75l-0,3.5c-0,0.966 0.784,1.75 1.75,1.75l0.25,0l-0,0.58c-0,1.336 1.084,2.42 2.42,2.42l6.16,0c1.336,0 2.42,-1.084 2.42,-2.42l-0,-0.58l0.25,0c0.966,0 1.75,-0.784 1.75,-1.75l-0,-3.5c-0,-0.966 -0.784,-1.75 -1.75,-1.75l-0.25,0l-0,-0.58c-0,-1.336 -1.084,-2.42 -2.42,-2.42l-6.16,0c-1.336,0 -2.42,1.084 -2.42,2.42l-0,0.58Zm10,1l-0,-1.74c-0,-0.695 -0.565,-1.26 -1.26,-1.26l-6.48,0c-0.695,0 -1.26,0.565 -1.26,1.26l-0,1.74l-2,0l-0,1l2,0l-0,1l-2,0l-0,1l2,0l-0,1l-2,0l-0,1l2,0l-0,1.74c-0,0.695 0.565,1.26 1.26,1.26l6.48,0c0.695,0 1.26,-0.565 1.26,-1.26l-0,-1.74l2,0l-0,-1l-2,0l-0,-1l2,0l-0,-1l-2,0l-0,-1l2,0l-0,-1l-2,0Z" style="fill:#222;"/><rect x="13" y="7" width="1" height="1" style="fill:#e2e2e2;"/><rect x="13" y="5" width="1" height="1" style="fill:#e2e2e2;"/><rect x="13" y="9" width="1" height="1" style="fill:#e2e2e2;"/><rect x="1" y="7" width="1" height="1" style="fill:#e2e2e2;"/><rect x="1" y="5" width="1" height="1" style="fill:#e2e2e2;"/><rect x="1" y="9" width="1" height="1" style="fill:#e2e2e2;"/><path d="M12,3.26c-0,-0.695 -0.565,-1.26 -1.26,-1.26l-6.48,0c-0.695,0 -1.26,0.565 -1.26,1.26l-0,8.48c-0,0.695 0.565,1.26 1.26,1.26l6.48,0c0.695,0 1.26,-0.565 1.26,-1.26l-0,-8.48Z" style="fill:#c8c8c8;"/><path d="M5,11l0,-0.977l2,-0.023l-0,-5l-2,-0l0,-1l5,0l0,1l-2,-0l-0,5l2,-0l0,1l-5,0Z" style="fill:#222;fill-rule:nonzero;"/><rect x="12" y="5" width="1" height="1" style="fill:#919191;"/><rect x="12" y="7" width="1" height="1" style="fill:#919191;"/><rect x="12" y="9" width="1" height="1" style="fill:#919191;"/><rect x="2" y="5" width="1" height="1" style="fill:#919191;"/><rect x="2" y="7" width="1" height="1" style="fill:#919191;"/><rect x="2" y="9" width="1" height="1" style="fill:#919191;"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

@@ -0,0 +1,38 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c6henbtgmply7"
path="res://.godot/imported/SoundbankInit_nor.svg-9fa97e168e627235d3e772b3183b27fd.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/Wwise/editor/images/SoundbankInit_nor.svg"
dest_files=["res://.godot/imported/SoundbankInit_nor.svg-9fa97e168e627235d3e772b3183b27fd.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
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=false
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
<g transform="matrix(1,0,0,1,-100,-85)">
<g transform="matrix(1,0,0,1,100,85)">
<g id="ObjectIcons_Soundbank_nor">
<g id="Icons">
<g transform="matrix(1,0,0,1,-40,-25)">
<g id="Base-Block" serif:id="Base Block">
<path d="M55,27.1C55,25.941 54.059,25 52.9,25L42.1,25C40.941,25 40,25.941 40,27.1L40,37.9C40,39.059 40.941,40 42.1,40L52.9,40C54.059,40 55,39.059 55,37.9L55,27.1Z" style="fill-opacity:0;"/>
</g>
</g>
<path d="M10.58,14L4.42,14C3.084,14 2,12.916 2,11.58L2,11L1.75,11C0.784,11 0,10.216 0,9.25L0,5.75C0,4.786 0.781,4.003 1.75,4L2,4L2,3.42C2,2.086 3.081,1.003 4.42,1L10.58,1C11.919,1.003 13,2.086 13,3.42L13,4L13.25,4C14.219,4.003 15,4.786 15,5.75L15,9.25C15,10.216 14.216,11 13.25,11L13,11L13,11.58C13,12.915 11.916,14 10.58,14ZM10.74,2L4.26,2C3.564,2.001 3,2.565 3,3.26L3,5L1,5L1,6L3,6L3,7L1,7L1,8L3,8L3,9L1,9L1,10L3,10L3,11.74C3,12.435 3.565,13 4.26,13L10.74,13C11.435,13 12,12.435 12,11.74L12,10L14,10L14,9L12,9L12,8L14,8L14,7L12,7L12,6L14,6L14,5L12,5L12,3.26C12,2.565 11.436,2.001 10.74,2Z" style="fill:rgb(34,34,34);"/>
<g transform="matrix(0.333333,0,0,1,9.33333,0)">
<rect x="11" y="7" width="3" height="1" style="fill:rgb(226,226,226);"/>
</g>
<g transform="matrix(0.333333,0,0,1,9.33333,-4)">
<rect x="11" y="9" width="3" height="1" style="fill:rgb(226,226,226);"/>
</g>
<g transform="matrix(0.333333,0,0,1,9.33333,4)">
<rect x="11" y="5" width="3" height="1" style="fill:rgb(226,226,226);"/>
</g>
<g transform="matrix(0.333333,0,0,1,0.666667,0)">
<rect x="1" y="7" width="3" height="1" style="fill:rgb(226,226,226);"/>
</g>
<g transform="matrix(0.333333,0,0,1,0.666667,-4)">
<rect x="1" y="9" width="3" height="1" style="fill:rgb(226,226,226);"/>
</g>
<g transform="matrix(0.333333,0,0,1,0.666667,4)">
<rect x="1" y="5" width="3" height="1" style="fill:rgb(226,226,226);"/>
</g>
<path d="M10.74,2C11.438,2.003 12,2.566 12,3.26L12,11.74C12,12.435 11.435,13 10.74,13L4.26,13C3.565,13 3,12.435 3,11.74L3,3.26C3,2.566 3.562,2.003 4.26,2L10.74,2ZM10,6C9.984,4.653 9.505,3.898 7.527,3.898C5.409,3.898 4.883,4.772 4.883,6C4.883,7.228 5.478,8.083 7.508,8.06C8.724,8.047 9,8.279 9,9C9,9.721 8.718,10 7.522,10C6.15,10 6.012,9.698 6,9L5,9C4.985,10.256 5.361,11.106 7.578,11.106C9.794,11.106 10.102,10.303 10.102,9C10.102,7.42 9.628,6.962 7.557,6.953C6.62,6.949 6.011,6.947 6,6C5.99,5.179 6.716,5 7.573,5C8.752,5 8.996,5.125 9,6L10,6Z" style="fill:rgb(200,200,200);"/>
<g transform="matrix(-1,-0,0,1,24,-4)">
<rect x="11" y="9" width="1" height="1" style="fill:rgb(145,145,145);"/>
</g>
<g transform="matrix(0.842382,0,0,0.774249,-117.591,-64.2877)">
<path d="M148.589,97.376C145.958,97.376 145.511,96.278 145.529,94.656L146.716,94.656C146.731,95.558 146.894,95.948 148.523,95.948C149.943,95.948 150.278,95.587 150.278,94.656C150.278,93.726 149.949,93.425 148.506,93.443C146.097,93.472 145.391,92.368 145.391,90.782C145.391,89.196 146.014,88.067 148.529,88.067C150.88,88.067 151.447,89.044 151.465,90.782L150.278,90.782C150.273,89.651 149.983,89.49 148.584,89.49C147.566,89.49 146.705,89.721 146.716,90.782C146.73,92.005 147.453,92.008 148.564,92.013C151.023,92.025 151.586,92.616 151.586,94.656C151.586,96.339 151.221,97.376 148.589,97.376Z" style="fill:rgb(34,34,34);"/>
</g>
<g transform="matrix(-1,-0,0,1,24,0)">
<rect x="11" y="7" width="1" height="1" style="fill:rgb(145,145,145);"/>
</g>
<g transform="matrix(-1,-0,0,1,24,4)">
<rect x="11" y="5" width="1" height="1" style="fill:rgb(145,145,145);"/>
</g>
<g transform="matrix(-1,-0,0,1,6,-4)">
<rect x="3" y="9" width="1" height="1" style="fill:rgb(145,145,145);"/>
</g>
<g transform="matrix(-1,-0,0,1,6,0)">
<rect x="3" y="7" width="1" height="1" style="fill:rgb(145,145,145);"/>
</g>
<g transform="matrix(-1,-0,0,1,6,4)">
<rect x="3" y="5" width="1" height="1" style="fill:rgb(145,145,145);"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.2 KiB

@@ -0,0 +1,38 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bx6kmkkhf8uiu"
path="res://.godot/imported/Soundbank_nor.svg-4156d1b612ac06ebcfe2b9efac7ddcc1.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/Wwise/editor/images/Soundbank_nor.svg"
dest_files=["res://.godot/imported/Soundbank_nor.svg-4156d1b612ac06ebcfe2b9efac7ddcc1.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
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=false
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
<g transform="matrix(1,0,0,1,-40,-165)">
<g transform="matrix(1,0,0,1,40,165)">
<g id="ObjectIcons_StateGroup_nor">
<g id="Icons">
<g transform="matrix(1,0,0,1,-40,-25)">
<g id="Base-Block" serif:id="Base Block">
<path d="M55,27.1C55,25.941 54.059,25 52.9,25L42.1,25C40.941,25 40,25.941 40,27.1L40,37.9C40,39.059 40.941,40 42.1,40L52.9,40C54.059,40 55,39.059 55,37.9L55,27.1Z" style="fill-opacity:0;"/>
</g>
</g>
<path d="M4.346,6.008C4.123,5.554 4,5.041 4,4.5C4,2.568 5.568,1 7.5,1C9.432,1 11,2.568 11,4.5C11,5.041 10.877,5.554 10.654,6.008C12.514,6.084 14,7.62 14,9.5C14,11.432 12.432,13 10.5,13C9.225,13 8.108,12.317 7.5,11.295C6.892,12.317 5.775,13 4.5,13C2.568,13 1,11.432 1,9.5C1,7.62 2.486,6.084 4.346,6.008ZM7.183,9.48C7.183,10.923 5.991,12.092 4.52,12.092C3.05,12.092 1.858,10.923 1.858,9.48C1.858,8.037 3.05,6.867 4.52,6.867C5.991,6.867 7.183,8.037 7.183,9.48ZM13.183,9.48C13.183,10.923 11.991,12.092 10.52,12.092C9.05,12.092 7.858,10.923 7.858,9.48C7.858,8.037 9.05,6.867 10.52,6.867C11.991,6.867 13.183,8.037 13.183,9.48ZM4,11C5.414,11 5.96,10.345 5.96,9.48C5.96,8.613 5.414,8 4,8L4,11ZM10,11C11.414,11 11.96,10.345 11.96,9.48C11.96,8.613 11.414,8 10,8L10,11ZM10.183,4.48C10.183,5.923 8.991,7.092 7.52,7.092C6.05,7.092 4.858,5.923 4.858,4.48C4.858,3.037 6.05,1.867 7.52,1.867C8.991,1.867 10.183,3.037 10.183,4.48ZM7,6C8.414,6 8.96,5.345 8.96,4.48C8.96,3.613 8.414,3 7,3L7,6Z" style="fill:rgb(34,34,34);"/>
<g transform="matrix(1.06499,0,0,1.04499,6.98777,2.70325)">
<path d="M0.011,3.155C1.339,3.155 1.852,2.528 1.852,1.7C1.852,0.871 1.339,0.284 0.011,0.284L0.011,3.155ZM3,1.7C3,3.081 1.881,4.2 0.5,4.2C-0.881,4.2 -2,3.081 -2,1.7C-2,0.319 -0.881,-0.8 0.5,-0.8C1.881,-0.8 3,0.319 3,1.7" style="fill:rgb(226,226,226);"/>
</g>
<g transform="matrix(1.06499,0,0,1.04499,6.12999,8.83599)">
<path d="M-2,2.071C-0.672,2.071 -0.159,1.444 -0.159,0.616C-0.159,-0.213 -0.672,-0.8 -2,-0.8L-2,2.071ZM0.989,0.616C0.989,1.997 -0.13,3.116 -1.511,3.116C-2.892,3.116 -4.011,1.997 -4.011,0.616C-4.011,-0.765 -2.892,-1.884 -1.511,-1.884C-0.13,-1.884 0.989,-0.765 0.989,0.616" style="fill:rgb(226,226,226);"/>
</g>
<g transform="matrix(1.06499,0,0,1.04499,6.98777,2.70325)">
<path d="M2.828,7.94C4.156,7.94 4.669,7.313 4.669,6.485C4.669,5.656 4.156,5.069 2.828,5.069L2.828,7.94ZM5.817,6.485C5.817,7.866 4.698,8.985 3.317,8.985C1.936,8.985 0.817,7.866 0.817,6.485C0.817,5.104 1.936,3.985 3.317,3.985C4.698,3.985 5.817,5.104 5.817,6.485" style="fill:rgb(226,226,226);"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

@@ -2,8 +2,8 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://dybg3l5pwetne"
path="res://.godot/imported/plugin-icon.svg-aa6701e8ed73f5fe5d177dfddce3a0e3.ctex"
uid="uid://ca0gg6latn4r3"
path="res://.godot/imported/StateGroup_nor.svg-08ec4b01a2266ce15e42db24ee690161.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
@@ -11,8 +11,8 @@ metadata={
[deps]
source_file="res://addons/dialogic/Editor/Images/plugin-icon.svg"
dest_files=["res://.godot/imported/plugin-icon.svg-aa6701e8ed73f5fe5d177dfddce3a0e3.ctex"]
source_file="res://addons/Wwise/editor/images/StateGroup_nor.svg"
dest_files=["res://.godot/imported/StateGroup_nor.svg-08ec4b01a2266ce15e42db24ee690161.ctex"]
[params]
@@ -35,4 +35,4 @@ process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
editor/convert_colors_with_editor_theme=false
+21
View File
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
<g transform="matrix(1,0,0,1,-60,-165)">
<g transform="matrix(1,0,0,1,60,165)">
<g id="ObjectIcons_State_nor">
<g id="Icons">
<g transform="matrix(1,0,0,1,-40,-25)">
<g id="Base-Block" serif:id="Base Block">
<path d="M55,27.1C55,25.941 54.059,25 52.9,25L42.1,25C40.941,25 40,25.941 40,27.1L40,37.9C40,39.059 40.941,40 42.1,40L52.9,40C54.059,40 55,39.059 55,37.9L55,27.1Z" style="fill-opacity:0;"/>
</g>
</g>
<path d="M7.5,1C11.087,1 14,3.913 14,7.5C14,11.087 11.087,14 7.5,14C3.913,14 1,11.087 1,7.5C1,3.913 3.913,1 7.5,1ZM13,7.5C13,10.538 10.537,13 7.5,13C4.463,13 2,10.538 2,7.5C2,4.462 4.463,2 7.5,2C10.537,2 13,4.462 13,7.5ZM7,11C9.709,11 11.175,9.709 11.175,7.5C11.175,5.291 9.709,4 7,4L7,11Z" style="fill:rgb(34,34,34);"/>
<g transform="matrix(1,0,0,1,7,3.5)">
<path d="M0,7.5C2.709,7.5 4.175,6.209 4.175,4C4.175,1.791 2.709,0.5 0,0.5L0,7.5ZM6,4C6,7.038 3.537,9.5 0.5,9.5C-2.537,9.5 -5,7.038 -5,4C-5,0.962 -2.537,-1.5 0.5,-1.5C3.537,-1.5 6,0.962 6,4" style="fill:rgb(200,200,200);"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -2,8 +2,8 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://dwy14qrkfoeb"
path="res://.godot/imported/minus.svg-29f22d1aa24635bae2c03057c07be8bc.ctex"
uid="uid://billu2uub7dyo"
path="res://.godot/imported/State_nor.svg-367952294445cb37b2ffc0af50a35618.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
@@ -11,8 +11,8 @@ metadata={
[deps]
source_file="res://addons/dialogic/Editor/Images/Dropdown/minus.svg"
dest_files=["res://.godot/imported/minus.svg-29f22d1aa24635bae2c03057c07be8bc.ctex"]
source_file="res://addons/Wwise/editor/images/State_nor.svg"
dest_files=["res://.godot/imported/State_nor.svg-367952294445cb37b2ffc0af50a35618.ctex"]
[params]
@@ -35,4 +35,4 @@ process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
editor/convert_colors_with_editor_theme=false
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
<g transform="matrix(1,0,0,1,-80,-165)">
<g transform="matrix(1,0,0,1,80,165)">
<g id="ObjectIcons_SwitchGroup_nor">
<g id="Icons">
<g transform="matrix(1,0,0,1,-40,-25)">
<g id="Base-Block" serif:id="Base Block">
<path d="M55,27.1C55,25.941 54.059,25 52.9,25L42.1,25C40.941,25 40,25.941 40,27.1L40,37.9C40,39.059 40.941,40 42.1,40L52.9,40C54.059,40 55,39.059 55,37.9L55,27.1Z" style="fill-opacity:0;"/>
</g>
</g>
<g transform="matrix(1,0,0,1,-80,-105)">
<path d="M84.65,106C85.395,106 86,106.605 86,107.35L86,117.65C86,118.395 85.395,119 84.65,119L84.35,119C83.605,119 83,118.395 83,117.65L83,107.35C83,106.605 83.605,106 84.35,106L84.65,106ZM85,107L84,107L84,118L85,118L85,107Z" style="fill:rgb(34,34,34);"/>
</g>
<path d="M6.558,5.5C6.214,5.173 6,4.711 6,4.2L6,2.8C6,1.807 6.807,1 7.8,1L9.2,1C10.193,1 11,1.807 11,2.8L11,4.2C11,4.711 10.786,5.173 10.442,5.5C10.786,5.827 11,6.289 11,6.8L11,8.2C11,8.711 10.786,9.173 10.442,9.5C10.786,9.827 11,10.289 11,10.8L11,12.2C11,13.192 10.196,13.998 9.2,14L7.8,14C6.807,14 6,13.193 6,12.2L6,10.8C6,10.289 6.214,9.827 6.558,9.5C6.214,9.173 6,8.711 6,8.2L6,6.8C6,6.289 6.214,5.827 6.558,5.5ZM10,10L9.2,10C9.2,10 7.8,10 7.8,10C7.8,10 7,10 7,10L7,13L10,13L10,10ZM7.8,6L7,6L7,9L10,9L10,6L9.2,6L7.8,6ZM10,2L7,2L7,5L10,5L10,2Z" style="fill:rgb(34,34,34);"/>
<g transform="matrix(1,0,0,1,-3,-8)">
<rect x="10" y="10" width="3" height="3" style="fill:rgb(200,200,200);"/>
</g>
<g transform="matrix(1,0,0,1,-3,-4)">
<rect x="10" y="10" width="3" height="3" style="fill:rgb(200,200,200);"/>
</g>
<g transform="matrix(1,0,0,1,-3,-1.42109e-13)">
<rect x="10" y="10" width="3" height="3" style="fill:rgb(200,200,200);"/>
</g>
<g transform="matrix(6.12323e-17,-1,1,5.72119e-18,2,7)">
<rect x="-6" y="2" width="11" height="1" style="fill:rgb(200,200,200);"/>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

@@ -2,8 +2,8 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://ddcfl67v0r1lw"
path="res://.godot/imported/set.svg-f100fad003be2285d5d0da5c58417203.ctex"
uid="uid://di2p281eymr6"
path="res://.godot/imported/SwitchGroup_nor.svg-4b8ec47f9b0f2d0ad35f4b4c39823197.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
@@ -11,8 +11,8 @@ metadata={
[deps]
source_file="res://addons/dialogic/Editor/Images/Dropdown/set.svg"
dest_files=["res://.godot/imported/set.svg-f100fad003be2285d5d0da5c58417203.ctex"]
source_file="res://addons/Wwise/editor/images/SwitchGroup_nor.svg"
dest_files=["res://.godot/imported/SwitchGroup_nor.svg-4b8ec47f9b0f2d0ad35f4b4c39823197.ctex"]
[params]
@@ -35,4 +35,4 @@ process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
editor/convert_colors_with_editor_theme=false
+19
View File
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
<g transform="matrix(1,0,0,1,-100,-165)">
<g transform="matrix(1,0,0,1,100,165)">
<g id="ObjectIcons_Switch_nor">
<g id="Icons">
<g transform="matrix(1,0,0,1,-40,-25)">
<g id="Base-Block" serif:id="Base Block">
<path d="M55,27.1C55,25.941 54.059,25 52.9,25L42.1,25C40.941,25 40,25.941 40,27.1L40,37.9C40,39.059 40.941,40 42.1,40L52.9,40C54.059,40 55,39.059 55,37.9L55,27.1Z" style="fill-opacity:0;"/>
</g>
</g>
<path d="M4.2,13L3.8,13C2.807,13 2,12.193 2,11.2L2,3.8C2,2.808 2.805,2.002 3.8,2L4.2,2L4.384,2.009L4.5,2.027L4.616,2.009L4.8,2L10.2,2L10.384,2.009L10.5,2.027L10.616,2.009L10.8,2L11.2,2C12.195,2.002 13,2.808 13,3.8L13,11.2C13,12.191 12.197,12.996 11.2,13L10.8,13C10.698,13 10.597,12.991 10.5,12.973L10.384,12.991L10.2,13L4.8,13C4.698,13 4.597,12.991 4.5,12.973L4.384,12.991L4.2,13ZM12,12L12,3L3,3L3,12L12,12ZM10,5L10,10L5,10L5,5L10,5ZM9,6L6,6L6,9L9,9L9,6Z" style="fill:rgb(34,34,34);"/>
<path d="M10,5L5,5L5,10L10,10L10,5ZM12,12L3,12L3,3L12,3L12,12Z" style="fill:rgb(200,200,200);"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -2,8 +2,8 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://c5laykjsxaxtl"
path="res://.godot/imported/divide.svg-4928f878a07ba93ebc44d8ae73ad4c1f.ctex"
uid="uid://1r1vuey5c32k"
path="res://.godot/imported/Switch_nor.svg-8d49f8fe707baf8c0ac91b5a53c494a7.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
@@ -11,8 +11,8 @@ metadata={
[deps]
source_file="res://addons/dialogic/Editor/Images/Dropdown/divide.svg"
dest_files=["res://.godot/imported/divide.svg-4928f878a07ba93ebc44d8ae73ad4c1f.ctex"]
source_file="res://addons/Wwise/editor/images/Switch_nor.svg"
dest_files=["res://.godot/imported/Switch_nor.svg-8d49f8fe707baf8c0ac91b5a53c494a7.ctex"]
[params]
@@ -35,4 +35,4 @@ process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=true
editor/convert_colors_with_editor_theme=false
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
<g transform="matrix(1,0,0,1,-60,-85)">
<g id="ObjectIcons_Workunit_nor" transform="matrix(1,0,0,1,-160,-40)">
<g transform="matrix(1,0,0,1,180,100)">
<g id="Base-Block" serif:id="Base Block">
<path d="M55,27.1C55,25.941 54.059,25 52.9,25L42.1,25C40.941,25 40,25.941 40,27.1L40,37.9C40,39.059 40.941,40 42.1,40L52.9,40C54.059,40 55,39.059 55,37.9L55,27.1Z" style="fill-opacity:0;"/>
</g>
</g>
<path d="M227.5,125.735L221,128.926L221,136.062L227.5,139.63L234,136.062L234,128.926L227.5,125.735ZM227.5,126.817L222,129.5L222,135.5L227.5,138.5L233,135.5L233,129.5L227.5,126.817Z" style="fill:rgb(34,34,34);"/>
<path d="M227.5,126.817L222,129.5L222,135.5L227.5,138.5L233,135.5L233,129.5L227.5,126.817ZM226,130L224,130L224,132.553C223.97,134.358 225.313,136.008 227.54,136C229.778,135.992 231.013,134.238 231,132.856L231,130L229,130L229,132.769C229.003,133.482 228.282,133.997 227.527,134C226.762,134.001 225.996,133.509 226,132.683L226,130Z" style="fill:rgb(200,200,200);"/>
<g transform="matrix(1,0,0,1,60,20)">
<path d="M166,110L164,110L164,112.553C163.97,114.358 165.313,116.008 167.54,116C169.778,115.992 171.013,114.238 171,112.856L171,110L169,110L169,112.769C169.003,113.482 168.282,113.997 167.527,114C166.762,114.001 165.996,113.509 166,112.683L166,110Z" style="fill:rgb(34,34,34);"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

@@ -0,0 +1,38 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://pc88x388tcsm"
path="res://.godot/imported/Workunit_nor.svg-e25848aba6a8174e5430bbb0701de596.ctex"
metadata={
"has_editor_variant": true,
"vram_texture": false
}
[deps]
source_file="res://addons/Wwise/editor/images/Workunit_nor.svg"
dest_files=["res://.godot/imported/Workunit_nor.svg-e25848aba6a8174e5430bbb0701de596.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
svg/scale=1.0
editor/scale_with_editor_scale=true
editor/convert_colors_with_editor_theme=false
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64" xml:space="preserve" version="1.1" viewBox="0 0 64 64">
<image width="64" height="64" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAADXElEQVR4Xu2aTa7aMBDHyWurqk/qphU7hNi8FZfgEnAeuA5cgkuw6wIhdkjt5kmtqtemThpbjjP2zPgjJCQsiTPM/Pz3319kk4F/soHXPxkBjAoYOIFxCAxcAKMJdmEI5JoKQ/ORschxyA0TDBVVeJ7nkyxTqfjmpIOU6aKx0AYJCi9ClskWheufCoJPTo141Fg+PxbKBCy+CEpNGkhAsARhlmFdCbcNwFp8KACHopwQ2gTgLD4QQFV/0wYwVbUBoGZ2Tjn+N0JKTtDM4fIVa1zKj4WMeZnUXxHkCQuE9Vb1vioUmDnY5poSACp5EwgVgG54EASOIaYCwC6e4QGY47NUkAKAV/EhAIB3MUhKfLEBeBfPAUCY8sgqiAkgqHgLANs+gVIgSQUmAGg9jZm3em6aD/nFqqFhgi63B+d9wxApkGpzbnAPcgtGZoFaD3pOeTYVgDuvRuPQgrjvmwogbJawArHndQWESphbMEcBmkfoqzpsnGPPuw3A4fZSwtg4x553GoDL6HTzxmTufO4MFCpp7vvAUth20EEZBkolLi/pOgCKCh5aASMAQSCoh7H3xyGgGVXXFkIytSQKWK/X7w+Hw5/BKkBQfRKzTv6wAPb7/ctms/k2WA9YLpcfT6fT774DQJeytgKlxHsPgHDAGWSSXfcAsLjVavXheDy+VdPEwwIgyd/cMXJPhbqsAHQvbxvf8/n8y+Vy+eEY/2oz1UcA1LMA6z5CM8jmmSB3C6st13xfVe+5jsQ8boAoQ4h0EUkpLMqBKnQqbPw42vvT6fTz7XZ7pchfP1SgFIm1CYYA3Q0KuWa73S7bbrfFBSu2P0APShaLxafz+fxLBop5MVKOuZAhQb0cNZ2/rFpcrevLX1uboqnek7EBqPqhBDAJUQEELI4aqk8FQKmBc9QeAmA2mz1fr9efUoWEO4WyP1ICYEPwAcBY+ID1pgbAgkAFAAwl6wmw9Ad97m/DA8wcSTMEEUAZG5gdOvkfIR0EOkNwABiEvYpvwwMg47eqIQQAZLZFPGGOX4U5frfNQG14ABlCTADU/x7fC0DDHKkJW3qypipOrHsCUBBkUcZBB7ZuAo1WfimWzu+M5TMY794AuEVGbz8CiI60ZwFHBfSsw6KnOyogOtKeBRy8Av4BmuykXyL1kYAAAAAASUVORK5CYII="/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

@@ -2,16 +2,16 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://bt87p6qlso0ya"
path="res://.godot/imported/dialogic-logo.svg-e43201cabc9573eeb3f78fd91ea9d909.ctex"
uid="uid://bvltdosfhfsrt"
path="res://.godot/imported/wwise_audio_speaker.svg-c8bbeea5359204d3be2da0640c91add2.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/dialogic/Editor/Images/dialogic-logo.svg"
dest_files=["res://.godot/imported/dialogic-logo.svg-e43201cabc9573eeb3f78fd91ea9d909.ctex"]
source_file="res://addons/Wwise/editor/images/wwise_audio_speaker.svg"
dest_files=["res://.godot/imported/wwise_audio_speaker.svg-c8bbeea5359204d3be2da0640c91add2.ctex"]
[params]
@@ -31,7 +31,7 @@ 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
detect_3d/compress_to=0
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
@@ -0,0 +1,46 @@
[gd_scene format=3 uid="uid://bomvl5s3ftk53"]
[node name="WwisePickerControl" type="VBoxContainer"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="ParentVBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 2
size_flags_vertical = 3
[node name="TopVBoxContainer" type="VBoxContainer" parent="ParentVBoxContainer"]
layout_mode = 2
[node name="ButtonsHContainer" type="HBoxContainer" parent="ParentVBoxContainer/TopVBoxContainer"]
layout_mode = 2
[node name="RefreshProjectButton" type="Button" parent="ParentVBoxContainer/TopVBoxContainer/ButtonsHContainer"]
layout_mode = 2
text = "Refresh Project"
[node name="ExportSoundbanksButton" type="Button" parent="ParentVBoxContainer/TopVBoxContainer/ButtonsHContainer"]
layout_mode = 2
text = "Generate Soundbanks"
[node name="GenerateIdsButton" type="Button" parent="ParentVBoxContainer/TopVBoxContainer/ButtonsHContainer"]
layout_mode = 2
text = "Generate Wwise IDs"
[node name="ConnectionText" type="Label" parent="ParentVBoxContainer/TopVBoxContainer/ButtonsHContainer"]
layout_mode = 2
[node name="SearchText" type="LineEdit" parent="ParentVBoxContainer/TopVBoxContainer"]
layout_mode = 2
placeholder_text = "Search Wwise project..."
caret_blink = true
caret_blink_interval = 0.5
[node name="ProjectObjectsTree" type="Tree" parent="ParentVBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
allow_reselect = true
+161
View File
@@ -0,0 +1,161 @@
<?xml version="1.0" encoding="UTF-8"?>
<class name="Waapi" inherits="Node" version="4.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<methods>
<method name="client_call">
<return type="Dictionary" />
<param index="0" name="uri" type="String" />
<param index="1" name="args" type="String" />
<param index="2" name="options" type="String" />
<description>
Calls the Waapi client with a given [param uri], [param arguments] and [param
options]. Example of usage:
[gdscript]
var json: JSON = JSON.new()
var connectResult = Waapi.connect_client("127.0.0.1", 8080)
if connectResult:
var args = {"from": {"ofType": ["Project", "Bus", "Switch", "State", "Event",
"SoundBank"]}}
var options = {"return": ["name", "type", "workunit", "path", "shortId"]}
var dict = Waapi.client_call("ak.wwise.core.object.get", JSON.stringify(args),
JSON.stringify(options))
var json_document = json.parse(dict["result_string"])
if json_document == OK:
if json.data.has("return"):
print(json.data["return"])
if Waapi.is_client_connected():
Waapi.disconnect_client()
[/gdscript]
Returns a Dictionary with keys [code]call_result[/code], [code]result_string[/code].
</description>
</method>
<method name="client_call_with_timeout">
<return type="Dictionary" />
<param index="0" name="uri" type="String" />
<param index="1" name="args" type="String" />
<param index="2" name="options" type="String" />
<param index="3" name="timeout_ms" type="int" />
<description>
Calls the Waapi client with a given [param uri], [param args] and [param options], specifying a timeout in
milliseconds.[br][br]
Returns a Dictionary with keys [code]call_result[/code], [code]result_string[/code].
</description>
</method>
<method name="connect_client">
<return type="bool" />
<param index="0" name="uri" type="String" />
<param index="1" name="port" type="int" />
<description>
Connects the Waapi client at the given [param uri] and [param port]. The Wwise
authoring application
should be open and available at the given location and port in order for this call
to succeed. Example:
[gdscript]
var connect_result = Waapi.connect_client("127.0.0.1", 8080)
if connect_result:
# Do something...
[/gdscript]
Returns [code]true[/code] if the connection succeeded.
</description>
</method>
<method name="disconnect_client">
<return type="void" />
<description>
Disconnects the client.
</description>
</method>
<method name="get_last_string">
<return type="String" />
<description>
Gets the last string result from [method subscribe], [method unsubscribe] or [method client_call]. Useful for
debugging.[br][br]
Returns a [code]result[/code] String.
</description>
</method>
<method name="is_client_connected">
<return type="bool" />
<description>
Checks the connection status of the Waapi client.[br][br]
Returns [code]true[/code] if the client is connected, [code]false[/code] otherwise.
</description>
</method>
<method name="process_callbacks">
<return type="void" />
<description>
</description>
</method>
<method name="subscribe">
<return type="Dictionary" />
<param index="0" name="uri" type="String" />
<param index="1" name="options" type="String" />
<description>
Subscribes the Waapi client to changes to the Wwise project in the authoring
app. In order to get the data dictionary with keys [code]subscription_id[/code], [code]subscribe_result[/code]
and [code]result_string.[br]
The signal wamp_event should be connected in GDScripts, e.g.
[gdscript]
Waapi.connect("wamp_event", Callable(self, "_on_wamp_event"))
func _on_wamp_event(data):
print(data)
[/gdscript]
Return a dictionary with keys [code]subscription_id[/code], [code]subscribe_result[/code]
and [code]result_string.
</description>
</method>
<method name="subscribe_with_timeout">
<return type="Dictionary" />
<param index="0" name="uri" type="String" />
<param index="1" name="options" type="String" />
<param index="2" name="timeout_ms" type="int" />
<description>
Subscribes the Waapi client to changes to the Wwise project in the authoring
app and returns after some timeout in milliseconds has passed. Works similarly to
[method subscribe] but with a timeout.[br][br]
Return a dictionary with keys [code]subscription_id[/code],
[code]subscribe_result[/code]
and [code]result_string.
</description>
</method>
<method name="unsubscribe">
<return type="Dictionary" />
<param index="0" name="subscription_id" type="int" />
<description>
Unsubscribes the Waapi client to changes to the Wwise project in the authoring app,
given a subscription ID.[br][br]
Returns a Dictionary with keys [code]unsubscribe_result[/code],
[code]result_string[/code].
</description>
</method>
<method name="unsubscribe_with_timeout">
<return type="Dictionary" />
<param index="0" name="subscription_id" type="int" />
<param index="1" name="timeout_ms" type="int" />
<description>
Unsubscribes the Waapi client to changes to the Wwise project in the authoring app
with a timeout in milliseconds. Works similarly to [method unsubscribe] but with a
timeout.[br][br]
Returns a Dictionary with keys [code]unsubscribe_result[/code],
[code]result_string[/code].
</description>
</method>
</methods>
<signals>
<signal name="wamp_event">
<param index="0" name="data" type="Dictionary" />
<description>
</description>
</signal>
</signals>
</class>
+754
View File
@@ -0,0 +1,754 @@
<?xml version="1.0" encoding="UTF-8"?>
<class name="Wwise" inherits="Object" version="4.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
</brief_description>
<description>
</description>
<tutorials>
<link title="Wwise Integration for Godot Wiki">
https://github.com/alessandrofama/wwise-godot-integration/wiki</link>
</tutorials>
<methods>
<method name="add_output">
<return type="bool" />
<param index="0" name="share_set" type="String" />
<param index="1" name="output_id" type="int" />
<description>
Adds an output to with the given [param share_set] and [param output_id] to the
sound engine. Calls [code]AK::SoundEngine::AddOutput[/code].[br][br]
Returns [code]true[/code] if adding the output succeeded.
</description>
</method>
<method name="get_playing_segment_info">
<return type="Dictionary" />
<param index="0" name="playing_id" type="int" />
<param index="1" name="extrapolate" type="bool" />
<description>
Queries information on the active segment of a music object that is playing,
associated with the given [param playing_id], obtained from [method
post_event_callback] or
[method post_event_id_callback]. You need to pass the
[code]AK_EnableGetMusicPlayPosition[/code]
[code]AkCallbackType[/code] flag defined in the [AkUtils] class to use this method.
Calls
[code]AK::MusicEngine::GetPlayingSegmentInfo[/code].[br][br]
Returns a Dictionary with the segment info.
</description>
</method>
<method name="get_rtpc_value">
<return type="float" />
<param index="0" name="name" type="String" />
<param index="1" name="game_object" type="Object" />
<description>
Gets the RTPC value with the given [param name] of the [param game_object]. Pass
[code]null[/code] to
[param game_object] to get a global RTPC value. Calls
[code]AK::SoundEngine::Query::GetRTPCValue[/code].[br][br]
Returns the RTPC value if succeeded, 1.0f (INVALID_RTPC_VALUE) if failed.
</description>
</method>
<method name="get_rtpc_value_id">
<return type="float" />
<param index="0" name="id" type="int" />
<param index="1" name="game_object" type="Object" />
<description>
Gets the RTPC value with the given [param id] of the [param game_object]. Pass
[code]null[/code] to
[param game_object] to get a global RTPC value. Calls
[code]AK::SoundEngine::Query::GetRTPCValue[/code].[br][br]
Returns the RTPC value if succeeded, 1.0f (INVALID_RTPC_VALUE) if failed.
</description>
</method>
<method name="get_source_play_position">
<return type="int" />
<param index="0" name="playing_id" type="int" />
<param index="1" name="extrapolate" type="bool" />
<description>
Gets the current position of the source associated with the given [param
playing_id],
obtained from [method post_event_callback] or [method post_event_id_callback]. You
need to
pass
the [code]AK_EnableGetSourcePlayPosition[/code] [code]AkCallbackType[/code] flag
defined in the [AkUtils] class
to use this method. Calls
[code]AK::SoundEngine::GetSourcePlayPosition[/code].[br][br]
Returns the current position of the source if succeeded, 0 if failed.
</description>
</method>
<method name="init">
<return type="void" />
<description>
Initializes the Wwise Soundengine. This is called automatically by the Wwise Runtime
autoload singleton at each game start.
</description>
</method>
<method name="load_bank">
<return type="bool" />
<param index="0" name="bank_name" type="String" />
<description>
Loads a bank with the given [param bank_name]. Calls
[code]AK::SoundEngine::LoadBank[/code].[br][br]
Returns [code]true[/code] if bank loading succeeded.
</description>
</method>
<method name="load_bank_async">
<return type="bool" />
<param index="0" name="bank_name" type="String" />
<param index="1" name="cookie" type="CookieWrapper" />
<description>
Loads a bank with the given [param bank_name]. The [param cookie] Object should be a
[CookieWrapper]
instance variable. Set the [param cookie] property of the wrapper to a [Callable] of
your
choice. Calls [code]AK::SoundEngine::LoadBank[/code].[br][br]
Returns [code]true[/code] if bank loading succeeded.
</description>
</method>
<method name="load_bank_async_id">
<return type="bool" />
<param index="0" name="bank_id" type="int" />
<param index="1" name="cookie" type="CookieWrapper" />
<description>
Loads a bank with the given [param bank_id]. The [param cookie] Object should be a
[CookieWrapper]
instance variable. Set the [param cookie] property of the wrapper to a [Callable] of
your
choice. Calls [code]AK::SoundEngine::LoadBank[/code].[br][br]
Returns [code]true[/code] if bank loading succeeded.
</description>
</method>
<method name="load_bank_id">
<return type="bool" />
<param index="0" name="bank_id" type="int" />
<description>
Loads a bank with the given [param bank:id]. Calls
[code]AK::SoundEngine::LoadBank[/code].[br][br]
Returns [code]true[/code] if bank loading succeeded.
</description>
</method>
<method name="post_event">
<return type="int" />
<param index="0" name="event_name" type="String" />
<param index="1" name="game_object" type="Object" />
<description>
Posts an Event with the given [param event_name] on the given [param game_object] to
the sound
engine. Calls [code]AK::SoundEngine::PostEvent[/code].[br][br]
Returns the [code]playing ID[/code] of the Event launched, or [code]0[/code] if
posting the Event failed.
</description>
</method>
<method name="post_event_callback">
<return type="int" />
<param index="0" name="event_name" type="String" />
<param index="1" name="flags" type="int" enum="AkUtils.AkCallbackType" />
<param index="2" name="game_object" type="Object" />
<param index="3" name="cookie" type="CookieWrapper" />
<description>
Posts an Event with the given [param event_name] on the given [param game_object] to
the sound
engine. Pass the [code]AkCallbackType[/code] flag defined in the [AkUtils] class to
[param flags]. The
[param cookie] Object should be a [CookieWrapper] instance variable. Set the [param
cookie] property of the wrapper to a [Callable] of your choice.
Calls [code]AK::SoundEngine::PostEvent[/code].[br][br]
Returns the [code]playing ID[/code] of the Event launched, or [code]0[/code] if
posting the Event failed.
</description>
</method>
<method name="post_event_id">
<return type="int" />
<param index="0" name="event_id" type="int" />
<param index="1" name="game_object" type="Object" />
<description>
Posts an Event with the given [param event_id] on the given [param game_object] to
the sound
engine. Calls [code]AK::SoundEngine::PostEvent[/code].[br][br]
Returns the [code]playing ID[/code] of the Event launched, or [code]0[/code] if
posting the Event failed.
</description>
</method>
<method name="post_event_id_callback">
<return type="int" />
<param index="0" name="event_id" type="int" />
<param index="1" name="flags" type="int" enum="AkUtils.AkCallbackType" />
<param index="2" name="game_object" type="Object" />
<param index="3" name="cookie" type="CookieWrapper" />
<description>
Posts an Event with the given [param event_id] on the given [param game_object] to
the sound
engine. Pass the [code]AkCallbackType[/code] flag defined in the [AkUtils] class to
[param flags]. The
[param cookie] Object should be a [CookieWrapper] instance variable. Set the [param
cookie] property of the wrapper to a [Callable] of your choice.
Calls [code]AK::SoundEngine::PostEvent[/code].[br][br]
Returns the [code]playing ID[/code] of the Event launched, or [code]0[/code] if
posting the Event failed.
</description>
</method>
<method name="post_external_source">
<return type="int" />
<param index="0" name="event_name" type="String" />
<param index="1" name="game_object" type="Object" />
<param index="2" name="source_object_name" type="String" />
<param index="3" name="filename" type="String" />
<param index="4" name="id_codec" type="int" enum="AkUtils.AkCodecID" />
<description>
Posts an Event with the given [param event_name] with an External Source on the
[param game_object].
[param source_object_name] is the Wwise External Source SFX name added through the
Contents
Editor in the authoring application. [param file_path] refers to the relative file
path of
the external source specified in the Output Path of the External Sources settings in
the authoring application. Pass the [code]AkCodecID[/code] value defined in
[AkUtils] class to
[param id_codec]. Calls [code]AK::SoundEngine::PostEvent[/code].[br][br]
Returns the [code]playing ID[/code] of the Event launched, or [code]0[/code] if
posting the Event failed.
</description>
</method>
<method name="post_external_source_id">
<return type="int" />
<param index="0" name="event_id" type="int" />
<param index="1" name="game_object" type="Object" />
<param index="2" name="source_object_id" type="int" />
<param index="3" name="filename" type="String" />
<param index="4" name="id_codec" type="int" enum="AkUtils.AkCodecID" />
<description>
Posts an Event with the given [param event_id] with an External Source on the [param
game_object].
[param source_object_id] is the Wwise External Source SFX ID added through the
Contents
Editor in the authoring application. [param file_path] refers to the relative file
path of
the external source specified in the Output Path of the External Sources settings in
the authoring application. Pass the [code]AkCodecID[/code] value defined in
[AkUtils] class to
[param id_codec]. Calls [code]AK::SoundEngine::PostEvent[/code].[br][br]
Returns the [code]playing ID[/code] of the Event launched, or [code]0[/code] if
posting the Event failed.
</description>
</method>
<method name="post_trigger">
<return type="bool" />
<param index="0" name="name" type="String" />
<param index="1" name="game_object" type="Object" />
<description>
Posts a trigger with the given [param name] on the given [param game_object]. Calls
[code]AK::SoundEngine::PostTrigger[/code].[br][br]
Returns [code]true[/code] if posting the trigger succeeded.
</description>
</method>
<method name="post_trigger_id">
<return type="bool" />
<param index="0" name="id" type="int" />
<param index="1" name="game_object" type="Object" />
<description>
Posts a trigger with the given [param id] on the given [param game_object]. Calls
[code]AK::SoundEngine::PostTrigger[/code].[br][br]
Returns [code]true[/code] if posting the trigger succeeded.
</description>
</method>
<method name="register_game_obj">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<param index="1" name="name" type="String" />
<description>
Registers a game object with the given [param game_object] and [param name].
Calls [code]AK::SoundEngine::RegisterGameObj[/code].[br][br]
Returns [code]true[/code] if registering the game object succeeded.
</description>
</method>
<method name="register_listener">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<description>
Registers a listener with the given [param game_object].
Returns [code]true[/code] if registering the listener succeeded.
</description>
</method>
<method name="register_spatial_listener">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<description>
Registers a spatial audio listener with the given [param game_object].Calls
[code]AK::SpatialAudio::RegisterListener[/code].[br][br]
Returns [code]true[/code] if registering the listener succeeded.[br][br]
Note: There can be only one Spatial Audio listener registered at any given time.
</description>
</method>
<method name="remove_game_object_from_room">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<description>
Removes the given [param game_object] from any room. Calls
[code]AK::SpatialAudio::SetGameObjectInRoom[/code].[br][br]
Returns [code]true[/code] if removing the game_object from a room succeeded.
</description>
</method>
<method name="remove_geometry">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<description>
Removes a geometry set. Pass the [param game_object] that was
used to register the geometry. Calls
[code]AK::SpatialAudio::RemoveGeometry[/code].[br][br]
Returns [code]true[/code] if removing the geometry set succeeded.
</description>
</method>
<method name="remove_output">
<return type="bool" />
<param index="0" name="output_id" type="int" />
<description>
Removes an output with the given [param output_id]. Calls
[code]AK::SoundEngine::RemoveOutput[/code].[br][br]
Returns [code]true[/code] if removing the output succeeded.
</description>
</method>
<method name="remove_portal">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<description>
Removes a portal created previously with [param set_portal]. Calls
[code]AK::SpatialAudio::RemovePortal[/code].[br][br]
Returns [code]true[/code] if removing the portal succeeded.
</description>
</method>
<method name="remove_room">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<description>
Removes a room with the given [param game_object]. Calls
[code]AK::SpatialAudio::RemoveRoom[/code].[br][br]
Returns [code]true[/code] if removing the room succeeded.
</description>
</method>
<method name="render_audio">
<return type="void" />
<description>
Processes all commands in the sound engine's command queue. This is called
automatically by the Wwise Runtime autoload singleton. Calls
[code]AK::SoundEngine::RenderAudio[/code].
</description>
</method>
<method name="set_2d_position">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<param index="1" name="transform_2d" type="Transform2D" />
<param index="2" name="z_depth" type="float" />
<description>
Sets the 3D position of the given [param game_object] with the given [param
transform_2d]
and [param z_depth]. Use the [param z_depth] parameter to position the game object
on the z-axis. Calls [code]AK::SoundEngine::SetPosition[/code].[br][br]
Returns [code]true[/code] if setting the position succeeded.
</description>
</method>
<method name="set_3d_position">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<param index="1" name="transform_3d" type="Transform3D" />
<description>
Sets the 3D position of the given [param game_object] with the given [param
transform_3d]. Calls [code]AK::SoundEngine::SetPosition[/code].[br][br]
Returns [code]true[/code] if setting the position succeeded.
</description>
</method>
<method name="set_base_path">
<return type="bool" />
<param index="0" name="base_path" type="String" />
<description>
Configures the root path for the generated soundbanks. This feature proves
beneficial when loading soundbanks from external sources beyond Godot's virtual
filesystem.
</description>
</method>
<method name="set_current_language">
<return type="void" />
<param index="0" name="language" type="String" />
<description>
Sets the current language. This is done automatically based on the
[code]startup_language[/code] setting in the Common User Wwise settings (Project
Settings).
</description>
</method>
<method name="set_early_reflections_aux_send">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<param index="1" name="aux_id" type="int" />
<description>
Set the given early reflections auxiliary bus [param aux_id] for the particular
[param game_object]. Calls
[code]AK::SpatialAudio::SetEarlyReflectionsAuxSend[/code].[br][br]
Returns [code]true[/code] if setting the early reflections auxiliary bus succeeded.
</description>
</method>
<method name="set_early_reflections_volume">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<param index="1" name="volume" type="float" />
<description>
Set the given early reflections send [param volume] for the particular [param
game_object].
Calls [code]AK::SpatialAudio::SetEarlyReflectionsVolume[/code].[br][br]
Returns [code]true[/code] if setting the early reflections send volume succeeded.
</description>
</method>
<method name="set_game_object_aux_send_values">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<param index="1" name="ak_aux_send_values" type="Array" />
<param index="2" name="num_send_values" type="int" />
<description>
Sets the Auxiliary Busses to route the specified [param game_object]. Pass an Array
of
Dictionaries to [param ak_aux_send_values] representing environments. The
Dictionaries
should contain the keys [code]aux_bus_id[/code] (the Aux Bus ID) and
[code]control_value[/code] (float
representing the attenuation or amplification factor applied to the volume of the
sound going through the auxiliary bus). Pass the number of environments to
[param num_send_values], 0 to clear the game object's auxiliary send. Calls
[code]AK::SoundEngine::SetGameObjectAuxSendValues[/code].[br][br]
Returns [code]true[/code] if succeeded.
</description>
</method>
<method name="set_game_object_in_room">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<param index="1" name="room" type="Object" />
<description>
Sets the room that the game object is currently located in. Pass a previously
registered game object to [param game_object] and the room to [param room]. Calls
[code]AK::SpatialAudio::SetGameObjectInRoom[/code].[br][br]
Returns [code]true[/code] if setting the game object in a room succeeded.
</description>
</method>
<method name="set_game_object_output_bus_volume">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<param index="1" name="listener" type="Object" />
<param index="2" name="f_control_value" type="float" />
<description>
Sets the Output Bus Volume of the given [param game_object]. Calls
[code]AK::SoundEngine::SetGameObjectOutputBusVolume[/code].[br][br]
Returns [code]true[/code] if setting the Output Bus Volume succeeded.
</description>
</method>
<method name="set_game_object_radius">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<param index="1" name="outer_radius" type="float" />
<param index="2" name="inner_radius" type="float" />
<description>
Sets the outer and inner radius for the specified [param game_object]. Calls
[code]AK::SpatialAudio::SetGameObjectRadius[/code].
</description>
</method>
<method name="set_game_object_to_portal_obstruction">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<param index="1" name="portal" type="Object" />
<param index="2" name="obstruction_value" type="float" />
<description>
</description>
</method>
<method name="set_geometry">
<return type="bool" />
<param index="0" name="vertices" type="Array" />
<param index="1" name="triangles" type="Array" />
<param index="2" name="acoustic_texture" type="Resource" />
<param index="3" name="transission_loss_value" type="float" />
<param index="4" name="game_object" type="Object" />
<param index="5" name="enable_diffraction" type="bool" />
<param index="6" name="enable_diffraction_on_boundary_edges" type="bool" />
<description>
Adds a set of geometry from the SpatialAudio module for geometric reflection and
diffaction processing on the given [param game_object]. [param vertices] should be
an Array
containing Vertices (Vector3), pass an Array of triangles (int) to [param
triangles].
[param enable_diffraction] enables or disables geometric diffraction for this
geometry,
[param enable_diffraction_on_boundary_edges] enables or disables geometric
diffraction on
boundary edges for this geometry. [param acoustic_texture] is a AkAcousticTexture
resource (currently not supported). Pass
null here if you don't use acoustic textures. Calls
[code]AK::SpatialAudio::SetGeometry[/code].
</description>
</method>
<method name="set_listeners">
<return type="bool" />
<param index="0" name="emtter" type="Object" />
<param index="1" name="listener" type="Object" />
<description>
Associates the game object [param emitter] with a [param listener] object.[br][br]
Returns [code]true[/code] if succeeded.
</description>
</method>
<method name="set_multiple_positions_2d">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<param index="1" name="positions" type="Transform2D[]" />
<param index="2" name="z_depths" type="float[]" />
<param index="3" name="num_positions" type="int" />
<param index="4" name="multi_position_type" type="int" enum="AkUtils.MultiPositionType" />
<description>
Sets the 2D position of the given [param game_object] with the given [param
positions] array.
Specify the number of position with [param num_positions] and the position type with
[enum AkUtils.MultiPositionType]. Calls
[code]AK::SoundEngine::SetMultiplePositions[/code].
</description>
</method>
<method name="set_multiple_positions_3d">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<param index="1" name="positions" type="Transform3D[]" />
<param index="2" name="num_positions" type="int" />
<param index="3" name="multi_position_type" type="int" enum="AkUtils.MultiPositionType" />
<description>
Sets the 3D position of the given [param game_object] with the given [param
positions] array.
Specify the number of position with [param num_positions] and the position type with
[enum AkUtils.MultiPositionType]. Calls
[code]AK::SoundEngine::SetMultiplePositions[/code].
</description>
</method>
<method name="set_object_obstruction_and_occlusion">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<param index="1" name="listener" type="Object" />
<param index="2" name="calculated_obs" type="float" />
<param index="3" name="calculated_occ" type="float" />
<description>
Sets the obstruction and occlusion levels of the given [param game_object]. It's up
to you
to calculate the [param calculated_obs] and [param calculated_occ] values. Calls
[code]AK::SoundEngine::SetObjectObstructionAndOcclusion[/code].[br][br]
Returns [code]true[/code] if succeeded.
</description>
</method>
<method name="set_portal">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<param index="1" name="transform" type="Transform3D" />
<param index="2" name="extent" type="Vector3" />
<param index="3" name="front_room" type="Object" />
<param index="4" name="back_room" type="Object" />
<param index="5" name="enabled" type="bool" />
<description>
Adds an acoustic portal with the given [param game_object] at the [param transform]
position. [param extent]
defines the dimensions of the portal relative to its center. Pass room objects
created with [method set_room] to [param front_room] and [param back_room]. [param
enabled] defines wheter the portal
is active or enabled. [code]Calls AK::SpatialAudio::SetPortal[/code].[br][br]
Returns [code]true[/code] if setting the portal succeeded.
</description>
</method>
<method name="set_portal_obstruction_and_occlusion">
<return type="bool" />
<param index="0" name="portal" type="Object" />
<param index="1" name="obstruction_value" type="float" />
<param index="2" name="occlusion_value" type="float" />
<description>
</description>
</method>
<method name="set_portal_to_portal_obstruction">
<return type="bool" />
<param index="0" name="portal0" type="Object" />
<param index="1" name="portal1" type="Object" />
<param index="2" name="obstruction_value" type="float" />
<description>
</description>
</method>
<method name="set_random_seed">
<return type="void" />
<param index="0" name="seed" type="int" />
<description>
Sets the random seed value. Can be used to synchronize randomness across instances
of the Soundengine. Calls [code]AK::SoundEngine::SetRandomSeed[/code].
</description>
</method>
<method name="set_room">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<param index="1" name="aux_bus_id" type="int" />
<param index="2" name="reverb_level" type="float" />
<param index="3" name="transmission_loss" type="float" />
<param index="4" name="front_vector" type="Vector3" />
<param index="5" name="up_vector" type="Vector3" />
<param index="6" name="keep_registered" type="bool" />
<param index="7" name="associated_geometry" type="Object" />
<description>
Adds a room with the given [param game_object]. Pass the reverb aux bus that is
associated
with the room to [param aux_bus_id].
Calls [code]AK::SpatialAudio::SetRoom[/code].[br][br]
Returns [code]true[/code] if setting the room succeeded.
</description>
</method>
<method name="set_rtpc_value">
<return type="bool" />
<param index="0" name="name" type="String" />
<param index="1" name="value" type="float" />
<param index="2" name="game_object" type="Object" />
<description>
Sets the RTPC [param name] with the given [param value] on the [param game_object].
Pass [code]null[/code] to [param game_object] to set a global RTPC value. Calls
[code]AK::SoundEngine::SetRTPCValue[/code].[br][br]
Returns [code]true[/code] if setting the RTPC succeeded.
</description>
</method>
<method name="set_rtpc_value_id">
<return type="bool" />
<param index="0" name="id" type="int" />
<param index="1" name="value" type="float" />
<param index="2" name="game_object" type="Object" />
<description>
Sets the RTPC [param id] with the given [param value] on the [param game_object].
Pass [code]null[/code] to [param game_object] to set a global RTPC value. Calls
[code]AK::SoundEngine::SetRTPCValue[/code].[br][br]
Returns [code]true[/code] if setting the RTPC succeeded.
</description>
</method>
<method name="set_state">
<return type="bool" />
<param index="0" name="state_group" type="String" />
<param index="1" name="state_value" type="String" />
<description>
Sets the given [param state_value] of the [param state_group]. Calls
[code]AK::SoundEngine::SetState[/code].[br][br]
Returns [code]true[/code] if setting the state succeeded.
</description>
</method>
<method name="set_state_id">
<return type="bool" />
<param index="0" name="state_group_id" type="int" />
<param index="1" name="state_value_id" type="int" />
<description>
Sets the given [param state_value_id] of the [param state_group_id]. Calls
[code]AK::SoundEngine::SetState[/code].[br][br]
Returns [code]true[/code] if setting the state succeeded.
</description>
</method>
<method name="set_switch">
<return type="bool" />
<param index="0" name="switch_group" type="String" />
<param index="1" name="switch_value" type="String" />
<param index="2" name="game_object" type="Object" />
<description>
Sets the given [param switch_value] of the [param switch_group] on the given [param
game_object]. Calls [code]AK::SoundEngine::SetSwitch[/code].[br][br]
Returns [code]true[/code] if setting the switch succeeded.
</description>
</method>
<method name="set_switch_id">
<return type="bool" />
<param index="0" name="switch_group_id" type="int" />
<param index="1" name="switch_value_id" type="int" />
<param index="2" name="game_object" type="Object" />
<description>
Sets the given [param switch_value_id] of the [param switch_group_id] on the given
[param
game_object]. Calls [code]AK::SoundEngine::SetSwitch[/code].[br][br]
Returns [code]true[/code] if setting the switch succeeded.
</description>
</method>
<method name="shutdown">
<return type="void" />
<description>
Shuts down the Wwise sound engine. This is called automatically by the Wwise Runtime
autoload singleton.
</description>
</method>
<method name="stop_event">
<return type="void" />
<param index="0" name="playing_id" type="int" />
<param index="1" name="fade_time" type="int" />
<param index="2" name="interpolation" type="int" enum="AkUtils.AkCurveInterpolation" />
<description>
Stops an Event with the given [param playing_id]. [param fade_time] describes the
fade time duration
in milliseconds. Pass the [enum AkUtils.AkCurveInterpolation] value to
[param interpolation]. Calls [code]AK::SoundEngine::ExecuteActionOnPlayingID[/code].
</description>
</method>
<method name="suspend">
<return type="bool" />
<param index="0" name="render_anyway" type="bool" />
<description>
Suspends the sound engine. Set [param render_anyway] to true if your game still runs
in
backround. Calls [code]AK::SoundEngine::Suspend[/code].[br][br]
Returns [code]true[/code] if suspending the sound engine succeeded.
</description>
</method>
<method name="unload_bank">
<return type="bool" />
<param index="0" name="bank_name" type="String" />
<description>
Unloads a bank with the given [param bank_name]. Calls
[code]AK::SoundEngine::UnloadBank[/code].[br][br]
Returns [code]true[/code] if bank unloading succeeded.
</description>
</method>
<method name="unload_bank_async">
<return type="bool" />
<param index="0" name="bank_name" type="String" />
<param index="1" name="cookie" type="CookieWrapper" />
<description>
Unloads a bank with the given [param bank_name]. The [param cookie] Object should be
a
[CookieWrapper] instance variable. Set the [param cookie] property of the wrapper to
a [Callable] of
your choice. Calls [code]AK::SoundEngine::UnloadBank[/code].[br][br]
Returns [code]true[/code] if bank unloading succeeded.
</description>
</method>
<method name="unload_bank_async_id">
<return type="bool" />
<param index="0" name="bank_id" type="int" />
<param index="1" name="cookie" type="CookieWrapper" />
<description>
Unloads a bank with the given [param bank_id]. The [param cookie] Object should be a
[CookieWrapper] instance variable. Set the [param cookie] property of the wrapper to
a [Callable] of
your choice. Calls [code]AK::SoundEngine::UnloadBank[/code].[br][br]
Returns [code]true[/code] if bank unloading succeeded.
</description>
</method>
<method name="unload_bank_id">
<return type="bool" />
<param index="0" name="bank_id" type="int" />
<description>
Unloads a bank with the given [param bank_id]. Calls
[code]AK::SoundEngine::UnloadBank[/code].[br][br]
Returns [code]true[/code] if bank unloading succeeded.
</description>
</method>
<method name="unregister_game_obj">
<return type="bool" />
<param index="0" name="game_object" type="Object" />
<description>
Unregisters a game object with the given [param game_object]. Calls
[code]AK::SoundEngine::UnregisterGameObj[/code].
</description>
</method>
<method name="wakeup_from_suspend">
<return type="bool" />
<description>
Wakes up the sound engine and starts processing audio again. Calls
[code]AK::SoundEngine::WakeupFromSuspend[/code].[br][br]
Returns [code]true[/code] if waking up the sound engine succeeded.
</description>
</method>
</methods>
</class>
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleIdentifier</key>
<string>com.gdextension.framework.libwwise.ios.template_debug</string>
<key>CFBundleName</key>
<string>libwwise.ios.template_debug</string>
<key>CFBundleExecutable</key>
<string>libwwise.ios.template_debug</string>
<key>DTPlatformName</key>
<string>iphoneos</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>MinimumOSVersion</key>
<string>11.0</string>
</dict>
</plist>
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleIdentifier</key>
<string>com.gdextension.framework.libwwise.ios.template_release</string>
<key>CFBundleName</key>
<string>libwwise.ios.template_release</string>
<key>CFBundleExecutable</key>
<string>libwwise.ios.template_release</string>
<key>DTPlatformName</key>
<string>iphoneos</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>MinimumOSVersion</key>
<string>11.0</string>
</dict>
</plist>
+43
View File
@@ -0,0 +1,43 @@
[configuration]
entry_symbol = "wwise_library_init"
compatibility_minimum = "4.2"
reloadable = false
android_aar_plugin = true
[libraries]
windows.editor = "res://addons/Wwise/native/lib/win64/debug/libwwise.windows.template_debug.dll"
windows.debug = "res://addons/Wwise/native/lib/win64/debug/libwwise.windows.template_debug.dll"
windows.release = "res://addons/Wwise/native/lib/win64/release/libwwise.windows.template_release.dll"
macos.editor = "res://addons/Wwise/native/lib/macos/debug/libwwise.macos.template_debug.framework"
macos.debug = "res://addons/Wwise/native/lib/macos/debug/libwwise.macos.template_debug.framework"
macos.release = "res://addons/Wwise/native/lib/macos/release/libwwise.macos.template_release.framework"
linux.editor = "res://addons/Wwise/native/lib/linux/debug/libwwise.linux.template_debug.so"
linux.debug = "res://addons/Wwise/native/lib/linux/debug/libwwise.linux.template_debug.so"
linux.release = "res://addons/Wwise/native/lib/linux/release/libwwise.linux.template_release.so"
ios.debug = "res://addons/Wwise/native/lib/ios/arm64/debug/libwwise.ios.template_debug.framework"
ios.release = "res://addons/Wwise/native/lib/ios/arm64/release/libwwise.ios.template_release.framework"
android.debug.arm64 = "res://addons/Wwise/native/lib/android/debug/arm64-v8a/libWwiseAndroidPlugin.so"
android.release.arm64 = "res://addons/Wwise/native/lib/android/release/arm64-v8a/libWwiseAndroidPlugin.so"
android.debug.arm32 = "res://addons/Wwise/native/lib/android/debug/armeabi-v7a/libWwiseAndroidPlugin.so"
android.release.arm32 = "res://addons/Wwise/native/lib/android/release/armeabi-v7a/libWwiseAndroidPlugin.so"
[icons]
Wwise = "res://addons/Wwise/editor/images/Project_nor.svg"
Waapi = "res://addons/Wwise/editor/images/Project_nor.svg"
WwiseSettings = "res://addons/Wwise/editor/images/Project_nor.svg"
AkListener2D = "res://addons/Wwise/editor/images/Project_nor.svg"
AkListener3D = "res://addons/Wwise/editor/images/Project_nor.svg"
AkEvent2D = "res://addons/Wwise/editor/images/Project_nor.svg"
AkEvent3D = "res://addons/Wwise/editor/images/Project_nor.svg"
AkState = "res://addons/Wwise/editor/images/Project_nor.svg"
AkSwitch = "res://addons/Wwise/editor/images/Project_nor.svg"
AkBank = "res://addons/Wwise/editor/images/Project_nor.svg"
AkEnvironment = "res://addons/Wwise/editor/images/Project_nor.svg"
AkEnvironmentData = "res://addons/Wwise/editor/images/Project_nor.svg"
AkGeometry = "res://addons/Wwise/editor/images/Project_nor.svg"
AkPortal = "res://addons/Wwise/editor/images/Project_nor.svg"
AkRoom = "res://addons/Wwise/editor/images/Project_nor.svg"
AkEarlyReflections = "res://addons/Wwise/editor/images/Project_nor.svg"
+7
View File
@@ -0,0 +1,7 @@
[plugin]
name="Wwise"
description="Wwise Integration for the Godot Engine"
author="Alessandro Famà"
version="2.0.3"
script="wwise.gd"
@@ -0,0 +1,44 @@
extends Node
var suspend_on_focus_loss:bool = false;
func _init() -> void:
suspend_on_focus_loss = ProjectSettings.get_setting("wwise/common_user_settings/suspend_on_focus_loss", false)
process_mode = Node.PROCESS_MODE_ALWAYS
Wwise.init()
func _process(_delta: float) -> void:
if Wwise.is_initialized():
Wwise.render_audio()
func _notification(what: int) -> void:
if suspend_on_focus_loss:
# Handling pause state on desktop platforms
if what == NOTIFICATION_APPLICATION_FOCUS_OUT:
pause()
elif what == NOTIFICATION_APPLICATION_FOCUS_IN:
resume()
# Handling pause state on Android
if what == NOTIFICATION_APPLICATION_PAUSED:
pause()
elif what == NOTIFICATION_APPLICATION_RESUMED:
resume()
# Handling shutdown
if what == NOTIFICATION_EXIT_TREE || what == NOTIFICATION_CRASH:
if !Wwise.is_initialized():
return
Wwise.shutdown()
func pause():
if Wwise.is_initialized():
Wwise.suspend(false)
func resume():
if Wwise.is_initialized():
Wwise.wakeup_from_suspend()
+2
View File
@@ -0,0 +1,2 @@
@tool
extends EditorPlugin
-433
View File
@@ -1,433 +0,0 @@
class_name DialogicGameHandler
extends Node
## Class that is used as the Dialogic autoload.
## Autoload script that allows you to interact with all of Dialogic's systems:[br]
## - Holds all important information about the current state of Dialogic.[br]
## - Provides access to all the subsystems.[br]
## - Has methods to start/end timelines.[br]
## States indicating different phases of dialog.
enum States {
IDLE, ## Dialogic is awaiting input to advance.
REVEALING_TEXT, ## Dialogic is currently revealing text.
ANIMATING, ## Some animation is happening.
AWAITING_CHOICE, ## Dialogic awaits the selection of a choice
WAITING ## Dialogic is currently awaiting something.
}
## Flags indicating what to clear when calling [method clear].
enum ClearFlags {
FULL_CLEAR = 0, ## Clears all subsystems
KEEP_VARIABLES = 1, ## Clears all subsystems and info except for variables
TIMELINE_INFO_ONLY = 2 ## Doesn't clear subsystems but current timeline and index
}
## Reference to the currently executed timeline.
var current_timeline: DialogicTimeline = null
## Copy of the [member current_timeline]'s events.
var current_timeline_events: Array = []
## Index of the event the timeline handling is currently at.
var current_event_idx: int = 0
## Contains all information that subsystems consider relevant for
## the current situation
var current_state_info: Dictionary = {}
## Current state (see [member States] enum).
var current_state := States.IDLE:
get:
return current_state
set(new_state):
current_state = new_state
state_changed.emit(new_state)
## Emitted when [member current_state] change.
signal state_changed(new_state:States)
## When `true`, many dialogic processes won't continue until it's `false` again.
var paused := false:
set(value):
paused = value
if paused:
for subsystem in get_children():
if subsystem is DialogicSubsystem:
(subsystem as DialogicSubsystem).pause()
dialogic_paused.emit()
else:
for subsystem in get_children():
if subsystem is DialogicSubsystem:
(subsystem as DialogicSubsystem).resume()
dialogic_resumed.emit()
## Emitted when [member paused] changes to `true`.
signal dialogic_paused
## Emitted when [member paused] changes to `false`.
signal dialogic_resumed
## Emitted when the timeline ends.
## This can be a timeline ending or [method end_timeline] being called.
signal timeline_ended
## Emitted when a timeline starts by calling either [method start]
## or [method start_timeline].
signal timeline_started
## Emitted when an event starts being executed.
## The event may not have finished executing yet.
signal event_handled(resource: DialogicEvent)
## Emitted when a [class SignalEvent] event was reached.
signal signal_event(argument: Variant)
## Emitted when a signal event gets fired from a [class TextEvent] event.
signal text_signal(argument: String)
# Careful, this section is repopulated automatically at certain moments.
#region SUBSYSTEMS
var Audio := preload("res://addons/dialogic/Modules/Audio/subsystem_audio.gd").new():
get: return get_subsystem("Audio")
var Backgrounds := preload("res://addons/dialogic/Modules/Background/subsystem_backgrounds.gd").new():
get: return get_subsystem("Backgrounds")
var Portraits := preload("res://addons/dialogic/Modules/Character/subsystem_portraits.gd").new():
get: return get_subsystem("Portraits")
var PortraitContainers := preload("res://addons/dialogic/Modules/Character/subsystem_containers.gd").new():
get: return get_subsystem("PortraitContainers")
var Choices := preload("res://addons/dialogic/Modules/Choice/subsystem_choices.gd").new():
get: return get_subsystem("Choices")
var Expressions := preload("res://addons/dialogic/Modules/Core/subsystem_expression.gd").new():
get: return get_subsystem("Expressions")
var Animations := preload("res://addons/dialogic/Modules/Core/subsystem_animation.gd").new():
get: return get_subsystem("Animations")
var Inputs := preload("res://addons/dialogic/Modules/Core/subsystem_input.gd").new():
get: return get_subsystem("Inputs")
var Glossary := preload("res://addons/dialogic/Modules/Glossary/subsystem_glossary.gd").new():
get: return get_subsystem("Glossary")
var History := preload("res://addons/dialogic/Modules/History/subsystem_history.gd").new():
get: return get_subsystem("History")
var Jump := preload("res://addons/dialogic/Modules/Jump/subsystem_jump.gd").new():
get: return get_subsystem("Jump")
var Save := preload("res://addons/dialogic/Modules/Save/subsystem_save.gd").new():
get: return get_subsystem("Save")
var Settings := preload("res://addons/dialogic/Modules/Settings/subsystem_settings.gd").new():
get: return get_subsystem("Settings")
var Styles := preload("res://addons/dialogic/Modules/Style/subsystem_styles.gd").new():
get: return get_subsystem("Styles")
var Text := preload("res://addons/dialogic/Modules/Text/subsystem_text.gd").new():
get: return get_subsystem("Text")
var TextInput := preload("res://addons/dialogic/Modules/TextInput/subsystem_text_input.gd").new():
get: return get_subsystem("TextInput")
var VAR := preload("res://addons/dialogic/Modules/Variable/subsystem_variables.gd").new():
get: return get_subsystem("VAR")
var Voice := preload("res://addons/dialogic/Modules/Voice/subsystem_voice.gd").new():
get: return get_subsystem("Voice")
#endregion
## Autoloads are added first, so this happens REALLY early on game startup.
func _ready() -> void:
_collect_subsystems()
clear()
#region TIMELINE & EVENT HANDLING
################################################################################
## Method to start a timeline AND ensure that a layout scene is present.
## For argument info, checkout [method start_timeline].
## -> returns the layout node
func start(timeline:Variant, label:Variant="") -> Node:
# If we don't have a style subsystem, default to just start_timeline()
if not has_subsystem('Styles'):
printerr("[Dialogic] You called Dialogic.start() but the Styles subsystem is missing!")
clear(ClearFlags.KEEP_VARIABLES)
start_timeline(timeline, label)
return null
# Otherwise make sure there is a style active.
var scene: Node = null
if !self.Styles.has_active_layout_node():
scene = self.Styles.load_style()
else:
scene = self.Styles.get_layout_node()
scene.show()
if not scene.is_node_ready():
scene.ready.connect(clear.bind(ClearFlags.KEEP_VARIABLES))
scene.ready.connect(start_timeline.bind(timeline, label))
else:
start_timeline(timeline, label)
return scene
## Method to start a timeline without adding a layout scene.
## @timeline can be either a loaded timeline resource or a path to a timeline file.
## @label_or_idx can be a label (string) or index (int) to skip to immediatly.
func start_timeline(timeline:Variant, label_or_idx:Variant = "") -> void:
# load the resource if only the path is given
if typeof(timeline) == TYPE_STRING:
#check the lookup table if it's not a full file name
if (timeline as String).contains("res://"):
timeline = load((timeline as String))
else:
timeline = DialogicResourceUtil.get_timeline_resource((timeline as String))
if timeline == null:
printerr("[Dialogic] There was an error loading this timeline. Check the filename, and the timeline for errors")
return
(timeline as DialogicTimeline).process()
current_timeline = timeline
current_timeline_events = current_timeline.events
for event in current_timeline_events:
event.dialogic = self
current_event_idx = -1
if typeof(label_or_idx) == TYPE_STRING:
if label_or_idx:
if has_subsystem('Jump'):
Jump.jump_to_label((label_or_idx as String))
elif typeof(label_or_idx) == TYPE_INT:
if label_or_idx >-1:
current_event_idx = label_or_idx -1
timeline_started.emit()
handle_next_event()
## Preloader function, prepares a timeline and returns an object to hold for later
## [param timeline_resource] can be either a path (string) or a loaded timeline (resource)
func preload_timeline(timeline_resource:Variant) -> Variant:
# I think ideally this should be on a new thread, will test
if typeof(timeline_resource) == TYPE_STRING:
timeline_resource = load((timeline_resource as String))
if timeline_resource == null:
printerr("[Dialogic] There was an error preloading this timeline. Check the filename, and the timeline for errors")
return null
(timeline_resource as DialogicTimeline).process()
return timeline_resource
## Clears and stops the current timeline.
func end_timeline() -> void:
await clear(ClearFlags.TIMELINE_INFO_ONLY)
_on_timeline_ended()
timeline_ended.emit()
## Handles the next event.
func handle_next_event(_ignore_argument: Variant = "") -> void:
handle_event(current_event_idx+1)
## Handles the event at the given index [param event_index].
## You can call this manually, but if another event is still executing, it might have unexpected results.
func handle_event(event_index:int) -> void:
if not current_timeline:
return
_cleanup_previous_event()
if paused:
await dialogic_resumed
if event_index >= len(current_timeline_events):
end_timeline()
return
#actually process the event now, since we didnt earlier at runtime
#this needs to happen before we create the copy DialogicEvent variable, so it doesn't throw an error if not ready
if current_timeline_events[event_index].event_node_ready == false:
current_timeline_events[event_index]._load_from_string(current_timeline_events[event_index].event_node_as_text)
current_event_idx = event_index
if not current_timeline_events[event_index].event_finished.is_connected(handle_next_event):
current_timeline_events[event_index].event_finished.connect(handle_next_event)
set_meta('previous_event', current_timeline_events[event_index])
current_timeline_events[event_index].execute(self)
event_handled.emit(current_timeline_events[event_index])
## Resets Dialogic's state fully or partially.
## By using the clear flags from the [member ClearFlags] enum you can specify
## what info should be kept.
## For example, at timeline end usually it doesn't clear node or subsystem info.
func clear(clear_flags := ClearFlags.FULL_CLEAR) -> void:
_cleanup_previous_event()
if !clear_flags & ClearFlags.TIMELINE_INFO_ONLY:
for subsystem in get_children():
if subsystem is DialogicSubsystem:
(subsystem as DialogicSubsystem).clear_game_state(clear_flags)
var timeline := current_timeline
current_timeline = null
current_event_idx = -1
current_timeline_events = []
current_state = States.IDLE
# Resetting variables
if timeline:
await timeline.clean()
## Cleanup after previous event (if any).
func _cleanup_previous_event():
if has_meta('previous_event') and get_meta('previous_event') is DialogicEvent:
var event := get_meta('previous_event') as DialogicEvent
if event.event_finished.is_connected(handle_next_event):
event.event_finished.disconnect(handle_next_event)
event._clear_state()
remove_meta("previous_event")
#endregion
#region SAVING & LOADING
################################################################################
## Returns a dictionary containing all necessary information to later recreate the same state with load_full_state.
## The [subsystem Save] subsystem might be more useful for you.
## However, this can be used to integrate the info into your own save system.
func get_full_state() -> Dictionary:
if current_timeline:
current_state_info['current_event_idx'] = current_event_idx
current_state_info['current_timeline'] = current_timeline.resource_path
else:
current_state_info['current_event_idx'] = -1
current_state_info['current_timeline'] = null
for subsystem in get_children():
(subsystem as DialogicSubsystem).save_game_state()
return current_state_info.duplicate(true)
## This method tries to load the state from the given [param state_info].
## Will automatically start a timeline and add a layout if a timeline was running when
## the dictionary was retrieved with [method get_full_state].
func load_full_state(state_info:Dictionary) -> void:
clear()
current_state_info = state_info
## The Style subsystem needs to run first for others to load correctly.
var scene: Node = null
if has_subsystem('Styles'):
get_subsystem('Styles').load_game_state()
scene = self.Styles.get_layout_node()
var load_subsystems := func() -> void:
for subsystem in get_children():
if subsystem.name == 'Styles':
continue
(subsystem as DialogicSubsystem).load_game_state()
if null != scene and not scene.is_node_ready():
scene.ready.connect(load_subsystems)
else:
await get_tree().process_frame
load_subsystems.call()
if current_state_info.get('current_timeline', null):
start_timeline(current_state_info.current_timeline, current_state_info.get('current_event_idx', 0))
else:
end_timeline.call_deferred()
#endregion
#region SUB-SYTSEMS
################################################################################
func _collect_subsystems() -> void:
var subsystem_nodes := [] as Array[DialogicSubsystem]
for indexer in DialogicUtil.get_indexers():
for subsystem in indexer._get_subsystems():
var subsystem_node := add_subsystem(str(subsystem.name), str(subsystem.script))
subsystem_nodes.push_back(subsystem_node)
for subsystem in subsystem_nodes:
subsystem.post_install()
## Returns `true` if a subystem with the given [param subsystem_name] exists.
func has_subsystem(subsystem_name:String) -> bool:
return has_node(subsystem_name)
## Returns the subsystem node of the given [param subsystem_name] or null if it doesn't exist.
func get_subsystem(subsystem_name:String) -> DialogicSubsystem:
return get_node(subsystem_name)
## Adds a subsystem node with the given [param subsystem_name] and [param script_path].
func add_subsystem(subsystem_name:String, script_path:String) -> DialogicSubsystem:
var node: Node = Node.new()
node.name = subsystem_name
node.set_script(load(script_path))
node = node as DialogicSubsystem
node.dialogic = self
add_child(node)
return node
#endregion
#region HELPERS
################################################################################
## This handles the `Layout End Behaviour` setting that can be changed in the Dialogic settings.
func _on_timeline_ended() -> void:
if self.Styles.has_active_layout_node() and self.Styles.get_layout_node().is_inside_tree():
match ProjectSettings.get_setting('dialogic/layout/end_behaviour', 0):
0:
self.Styles.get_layout_node().get_parent().remove_child(self.Styles.get_layout_node())
self.Styles.get_layout_node().queue_free()
1:
@warning_ignore("unsafe_method_access")
self.Styles.get_layout_node().hide()
func print_debug_moment() -> void:
if not current_timeline:
return
printerr("\tAt event ", current_event_idx+1, " (",current_timeline_events[current_event_idx].event_name, ' Event) in timeline "', DialogicResourceUtil.get_unique_identifier(current_timeline.resource_path), '" (',current_timeline.resource_path,').')
print("\n")
#endregion
@@ -1,291 +0,0 @@
@tool
class_name DialogicResourceUtil
static var label_cache := {}
static var event_cache: Array[DialogicEvent] = []
static var special_resources := {}
static func update() -> void:
update_directory('.dch')
update_directory('.dtl')
update_label_cache()
#region RESOURCE DIRECTORIES
################################################################################
static func get_directory(extension:String) -> Dictionary:
extension = extension.trim_prefix('.')
if Engine.has_meta(extension+'_directory'):
return Engine.get_meta(extension+'_directory', {})
var directory: Dictionary = ProjectSettings.get_setting("dialogic/directories/"+extension+'_directory', {})
Engine.set_meta(extension+'_directory', directory)
return directory
static func set_directory(extension:String, directory:Dictionary) -> void:
extension = extension.trim_prefix('.')
if Engine.is_editor_hint():
ProjectSettings.set_setting("dialogic/directories/"+extension+'_directory', directory)
ProjectSettings.save()
Engine.set_meta(extension+'_directory', directory)
static func update_directory(extension:String) -> void:
var directory := get_directory(extension)
for resource in list_resources_of_type(extension):
if not resource in directory.values():
directory = add_resource_to_directory(resource, directory)
var keys_to_remove := []
for key in directory:
if not ResourceLoader.exists(directory[key]):
keys_to_remove.append(key)
for key in keys_to_remove:
directory.erase(key)
set_directory(extension, directory)
static func add_resource_to_directory(file_path:String, directory:Dictionary) -> Dictionary:
var suggested_name := file_path.get_file().trim_suffix("."+file_path.get_extension())
while suggested_name in directory:
suggested_name = file_path.trim_suffix("/"+suggested_name+"."+file_path.get_extension()).get_file().path_join(suggested_name)
directory[suggested_name] = file_path
return directory
## Returns the unique identifier for the given resource path.
## Returns an empty string if no identifier was found.
static func get_unique_identifier(file_path:String) -> String:
var identifier: String = get_directory(file_path.get_extension()).find_key(file_path)
if typeof(identifier) == TYPE_STRING:
return identifier
return ""
## Returns the resource associated with the given unique identifier.
## The expected extension is needed to use the right directory.
static func get_resource_from_identifier(identifier:String, extension:String) -> Resource:
var path: String = get_directory(extension).get(identifier, '')
if ResourceLoader.exists(path):
return load(path)
return null
static func change_unique_identifier(file_path:String, new_identifier:String) -> void:
var directory := get_directory(file_path.get_extension())
var key: String = directory.find_key(file_path)
while key != null:
if key == new_identifier:
break
directory.erase(key)
directory[new_identifier] = file_path
key = directory.find_key(file_path)
set_directory(file_path.get_extension(), directory)
static func change_resource_path(old_path:String, new_path:String) -> void:
var directory := get_directory(new_path.get_extension())
var key: String = directory.find_key(old_path)
while key != null:
directory[key] = new_path
key = directory.find_key(old_path)
set_directory(new_path.get_extension(), directory)
static func remove_resource(file_path:String) -> void:
var directory := get_directory(file_path.get_extension())
var key: String = directory.find_key(file_path)
while key != null:
directory.erase(key)
key = directory.find_key(file_path)
set_directory(file_path.get_extension(), directory)
static func is_identifier_unused(extension:String, identifier:String) -> bool:
return not identifier in get_directory(extension)
#endregion
#region LABEL CACHE
################################################################################
# The label cache is only for the editor so we don't have to scan all timelines
# whenever we want to suggest labels. This has no use in game and is not always perfect.
static func get_label_cache() -> Dictionary:
if not label_cache.is_empty():
return label_cache
label_cache = DialogicUtil.get_editor_setting('label_ref', {})
return label_cache
static func set_label_cache(cache:Dictionary) -> void:
label_cache = cache
static func update_label_cache() -> void:
var cache := get_label_cache()
var timelines := get_timeline_directory().values()
for timeline in cache:
if !timeline in timelines:
cache.erase(timeline)
set_label_cache(cache)
#endregion
#region EVENT CACHE
################################################################################
## Dialogic keeps a list that has each event once. This allows retrieval of that list.
static func get_event_cache() -> Array:
if not event_cache.is_empty():
return event_cache
event_cache = update_event_cache()
return event_cache
static func update_event_cache() -> Array:
event_cache = []
for indexer in DialogicUtil.get_indexers():
# build event cache
for event in indexer._get_events():
if not ResourceLoader.exists(event):
continue
if not 'event_end_branch.gd' in event and not 'event_text.gd' in event:
event_cache.append(load(event).new())
# Events are checked in order while testing them. EndBranch needs to be first, Text needs to be last
event_cache.push_front(DialogicEndBranchEvent.new())
event_cache.push_back(DialogicTextEvent.new())
return event_cache
#endregion
#region SPECIAL RESOURCES
################################################################################
static func update_special_resources() -> void:
special_resources.clear()
for indexer in DialogicUtil.get_indexers():
var additions := indexer._get_special_resources()
for resource_type in additions:
if not resource_type in special_resources:
special_resources[resource_type] = {}
special_resources[resource_type].merge(additions[resource_type])
static func list_special_resources(type:String, filter := {}) -> Dictionary:
if special_resources.is_empty():
update_special_resources()
if type in special_resources:
if filter.is_empty():
return special_resources[type]
else:
var results := {}
for i in special_resources[type]:
if match_resource_filter(special_resources[type][i], filter):
results[i] = special_resources[type][i]
return results
return {}
static func match_resource_filter(dict:Dictionary, filter:Dictionary) -> bool:
for i in filter:
if not i in dict:
return false
if typeof(filter[i]) == TYPE_ARRAY:
if not dict[i] in filter[i]:
return false
else:
if not dict[i] == filter[i]:
return false
return true
static func guess_special_resource(type: String, string: String, default := {}, filter := {}, ignores:PackedStringArray=[]) -> Dictionary:
if string.is_empty():
return default
if special_resources.is_empty():
update_special_resources()
var resources := list_special_resources(type, filter)
if resources.is_empty():
printerr("[Dialogic] No ", type, "s found, but attempted to use one.")
return default
if string.begins_with('res://'):
for i in resources.values():
if i.path == string:
return i
printerr("[Dialogic] Unable to find ", type, " at path '", string, "'.")
return default
string = string.to_lower()
if string in resources:
return resources[string]
if not ignores.is_empty():
var regex := RegEx.create_from_string(r" ?\b(" + "|".join(ignores) + r")\b")
for name in resources:
if regex.sub(name, "") == regex.sub(string, ""):
return resources[name]
## As a last effort check against the unfiltered list
if string in special_resources[type]:
push_warning("[Dialogic] Using ", type, " '", string,"' when not supposed to.")
return special_resources[type][string]
printerr("[Dialogic] Unable to identify ", type, " based on string '", string, "'.")
return default
#endregion
#region HELPERS
################################################################################
static func get_character_directory() -> Dictionary:
return get_directory('dch')
static func get_timeline_directory() -> Dictionary:
return get_directory('dtl')
static func get_timeline_resource(timeline_identifier:String) -> DialogicTimeline:
return get_resource_from_identifier(timeline_identifier, 'dtl')
static func get_character_resource(character_identifier:String) -> DialogicCharacter:
return get_resource_from_identifier(character_identifier, 'dch')
static func list_resources_of_type(extension:String) -> Array:
var all_resources := scan_folder('res://', extension)
return all_resources
static func scan_folder(path:String, extension:String) -> Array:
var list: Array = []
if DirAccess.dir_exists_absolute(path):
var dir := DirAccess.open(path)
dir.list_dir_begin()
var file_name := dir.get_next()
while file_name != "":
if dir.current_is_dir() and not file_name.begins_with("."):
list += scan_folder(path.path_join(file_name), extension)
else:
if file_name.ends_with(extension):
list.append(path.path_join(file_name))
file_name = dir.get_next()
return list
#endregion
-676
View File
@@ -1,676 +0,0 @@
@tool
class_name DialogicUtil
## Script that container helper methods for both editor and game execution.
## Used whenever the same thing is needed in different parts of the plugin.
#region EDITOR
## This method should be used instead of EditorInterface.get_editor_scale(), because if you use that
## it will run perfectly fine from the editor, but crash when the game is exported.
static func get_editor_scale() -> float:
return get_dialogic_plugin().get_editor_interface().get_editor_scale()
## Although this does in fact always return a EditorPlugin node,
## that class is apparently not present in export and referencing it here creates a crash.
static func get_dialogic_plugin() -> Node:
for child in Engine.get_main_loop().get_root().get_children():
if child.get_class() == "EditorNode":
return child.get_node('DialogicPlugin')
return null
#endregion
## Returns the autoload when in-game.
static func autoload() -> DialogicGameHandler:
if Engine.is_editor_hint():
return null
if not Engine.get_main_loop().root.has_node("Dialogic"):
return null
return Engine.get_main_loop().root.get_node("Dialogic")
#region FILE SYSTEM
################################################################################
static func listdir(path: String, files_only:= true, _throw_error:= true, full_file_path:= false, include_imports := false) -> Array:
var files: Array = []
if path.is_empty(): path = "res://"
if DirAccess.dir_exists_absolute(path):
var dir := DirAccess.open(path)
dir.list_dir_begin()
var file_name := dir.get_next()
while file_name != "":
if not file_name.begins_with("."):
if files_only:
if not dir.current_is_dir() and (not file_name.ends_with('.import') or include_imports):
if full_file_path:
files.append(path.path_join(file_name))
else:
files.append(file_name)
else:
if full_file_path:
files.append(path.path_join(file_name))
else:
files.append(file_name)
file_name = dir.get_next()
dir.list_dir_end()
return files
static func get_module_path(name:String, builtin:=true) -> String:
if builtin:
return "res://addons/dialogic/Modules".path_join(name)
else:
return ProjectSettings.get_setting('dialogic/extensions_folder', 'res://addons/dialogic_additions').path_join(name)
## This is a private and editor-only function.
##
## Populates the [class DialogicGameHandler] with new custom subsystems by
## directly manipulating the file's content and then importing the file.
static func _update_autoload_subsystem_access() -> void:
if not Engine.is_editor_hint():
printerr("[Dialogic] This function is only available in the editor.")
return
var script: Script = load("res://addons/dialogic/Core/DialogicGameHandler.gd")
var new_subsystem_access_list := "#region SUBSYSTEMS\n"
for indexer: DialogicIndexer in get_indexers(true, true):
for subsystem: Dictionary in indexer._get_subsystems().duplicate(true):
new_subsystem_access_list += '\nvar {name} := preload("{script}").new():\n\tget: return get_subsystem("{name}")\n'.format(subsystem)
new_subsystem_access_list += "\n#endregion"
script.source_code = RegEx.create_from_string(r"#region SUBSYSTEMS\n#*\n((?!#endregion)(.*\n))*#endregion").sub(script.source_code, new_subsystem_access_list)
ResourceSaver.save(script)
Engine.get_singleton("EditorInterface").get_resource_filesystem().reimport_files(["res://addons/dialogic/Core/DialogicGameHandler.gd"])
static func get_indexers(include_custom := true, force_reload := false) -> Array[DialogicIndexer]:
if Engine.get_main_loop().has_meta('dialogic_indexers') and !force_reload:
return Engine.get_main_loop().get_meta('dialogic_indexers')
var indexers: Array[DialogicIndexer] = []
for file in listdir(DialogicUtil.get_module_path(''), false):
var possible_script: String = DialogicUtil.get_module_path(file).path_join("index.gd")
if ResourceLoader.exists(possible_script):
indexers.append(load(possible_script).new())
if include_custom:
var extensions_folder: String = ProjectSettings.get_setting('dialogic/extensions_folder', "res://addons/dialogic_additions/")
for file in listdir(extensions_folder, false, false):
var possible_script: String = extensions_folder.path_join(file + "/index.gd")
if ResourceLoader.exists(possible_script):
indexers.append(load(possible_script).new())
Engine.get_main_loop().set_meta('dialogic_indexers', indexers)
return indexers
## Turns a [param file_path] from `some_file.png` to `Some File`.
static func pretty_name(file_path: String) -> String:
var _name := file_path.get_file().trim_suffix("." + file_path.get_extension())
_name = _name.replace('_', ' ')
_name = _name.capitalize()
return _name
#endregion
#region EDITOR SETTINGS & COLORS
################################################################################
static func set_editor_setting(setting:String, value:Variant) -> void:
var cfg := ConfigFile.new()
if FileAccess.file_exists('user://dialogic/editor_settings.cfg'):
cfg.load('user://dialogic/editor_settings.cfg')
cfg.set_value('DES', setting, value)
if !DirAccess.dir_exists_absolute('user://dialogic'):
DirAccess.make_dir_absolute('user://dialogic')
cfg.save('user://dialogic/editor_settings.cfg')
static func get_editor_setting(setting:String, default:Variant=null) -> Variant:
var cfg := ConfigFile.new()
if !FileAccess.file_exists('user://dialogic/editor_settings.cfg'):
return default
if !cfg.load('user://dialogic/editor_settings.cfg') == OK:
return default
return cfg.get_value('DES', setting, default)
static func get_color_palette(default:bool = false) -> Dictionary:
var defaults := {
'Color1': Color('#3b8bf2'), # Blue
'Color2': Color('#00b15f'), # Green
'Color3': Color('#e868e2'), # Pink
'Color4': Color('#9468e8'), # Purple
'Color5': Color('#574fb0'), # DarkPurple
'Color6': Color('#1fa3a3'), # Aquamarine
'Color7': Color('#fa952a'), # Orange
'Color8': Color('#de5c5c'), # Red
'Color9': Color('#7c7c7c'), # Gray
}
if default:
return defaults
return get_editor_setting('color_palette', defaults)
static func get_color(value:String) -> Color:
var colors := get_color_palette()
return colors[value]
#endregion
#region TIMER PROCESS MODE
################################################################################
static func is_physics_timer() -> bool:
return ProjectSettings.get_setting('dialogic/timer/process_in_physics', false)
static func update_timer_process_callback(timer:Timer) -> void:
timer.process_callback = Timer.TIMER_PROCESS_PHYSICS if is_physics_timer() else Timer.TIMER_PROCESS_IDLE
#endregion
#region MULTITWEEN
################################################################################
static func multitween(tweened_value:Variant, item:Node, property:String, part:String) -> void:
var parts: Dictionary = item.get_meta(property+'_parts', {})
parts[part] = tweened_value
if not item.has_meta(property+'_base_value') and not 'base' in parts:
item.set_meta(property+'_base_value', item.get(property))
var final_value: Variant = parts.get('base', item.get_meta(property+'_base_value', item.get(property)))
for key in parts:
if key == 'base':
continue
else:
final_value += parts[key]
item.set(property, final_value)
item.set_meta(property+'_parts', parts)
#endregion
#region TRANSLATIONS
################################################################################
static func get_next_translation_id() -> String:
ProjectSettings.set_setting('dialogic/translation/id_counter', ProjectSettings.get_setting('dialogic/translation/id_counter', 16)+1)
return '%x' % ProjectSettings.get_setting('dialogic/translation/id_counter', 16)
#endregion
#region VARIABLES
################################################################################
enum VarTypes {ANY, STRING, FLOAT, INT, BOOL}
static func get_default_variables() -> Dictionary:
return ProjectSettings.get_setting('dialogic/variables', {})
# helper that converts a nested variable dictionary into an array with paths
static func list_variables(dict:Dictionary, path := "", type:=VarTypes.ANY) -> Array:
var array := []
for key in dict.keys():
if typeof(dict[key]) == TYPE_DICTIONARY:
array.append_array(list_variables(dict[key], path+key+".", type))
else:
if type == VarTypes.ANY or get_variable_value_type(dict[key]) == type:
array.append(path+key)
return array
static func get_variable_value_type(value:Variant) -> VarTypes:
match typeof(value):
TYPE_STRING:
return VarTypes.STRING
TYPE_FLOAT:
return VarTypes.FLOAT
TYPE_INT:
return VarTypes.INT
TYPE_BOOL:
return VarTypes.BOOL
return VarTypes.ANY
static func get_variable_type(path:String, dict:Dictionary={}) -> VarTypes:
if dict.is_empty():
dict = get_default_variables()
return get_variable_value_type(_get_value_in_dictionary(path, dict))
## This will set a value in a dictionary (or a sub-dictionary based on the path)
## e.g. it could set "Something.Something.Something" in {'Something':{'Something':{'Someting':"value"}}}
static func _set_value_in_dictionary(path:String, dictionary:Dictionary, value):
if '.' in path:
var from := path.split('.')[0]
if from in dictionary.keys():
dictionary[from] = _set_value_in_dictionary(path.trim_prefix(from+"."), dictionary[from], value)
else:
if path in dictionary.keys():
dictionary[path] = value
return dictionary
## This will get a value in a dictionary (or a sub-dictionary based on the path)
## e.g. it could get "Something.Something.Something" in {'Something':{'Something':{'Someting':"value"}}}
static func _get_value_in_dictionary(path:String, dictionary:Dictionary, default= null) -> Variant:
if '.' in path:
var from := path.split('.')[0]
if from in dictionary.keys():
return _get_value_in_dictionary(path.trim_prefix(from+"."), dictionary[from], default)
else:
if path in dictionary.keys():
return dictionary[path]
return default
#endregion
#region STYLES
################################################################################
static func get_default_layout_base() -> PackedScene:
return load(DialogicUtil.get_module_path('DefaultLayoutParts').path_join("Base_Default/default_layout_base.tscn"))
static func get_fallback_style() -> DialogicStyle:
return load(DialogicUtil.get_module_path('DefaultLayoutParts').path_join("Style_VN_Default/default_vn_style.tres"))
static func get_default_style() -> DialogicStyle:
var default: String = ProjectSettings.get_setting('dialogic/layout/default_style', '')
if !ResourceLoader.exists(default):
return get_fallback_style()
return load(default)
static func get_style_by_name(name:String) -> DialogicStyle:
if name.is_empty():
return get_default_style()
var styles: Array = ProjectSettings.get_setting('dialogic/layout/style_list', [])
for style in styles:
if not ResourceLoader.exists(style):
continue
if load(style).name == name:
return load(style)
return get_default_style()
#endregion
#region SCENE EXPORT OVERRIDES
################################################################################
static func apply_scene_export_overrides(node:Node, export_overrides:Dictionary, apply := true) -> void:
var default_info := get_scene_export_defaults(node)
if !node.script:
return
var property_info: Array[Dictionary] = node.script.get_script_property_list()
for i in property_info:
if i['usage'] & PROPERTY_USAGE_EDITOR:
if i['name'] in export_overrides:
if str_to_var(export_overrides[i['name']]) == null and typeof(node.get(i['name'])) == TYPE_STRING:
node.set(i['name'], export_overrides[i['name']])
else:
node.set(i['name'], str_to_var(export_overrides[i['name']]))
elif i['name'] in default_info:
node.set(i['name'], default_info.get(i['name']))
if apply:
if node.has_method('apply_export_overrides'):
node.apply_export_overrides()
static func get_scene_export_defaults(node:Node) -> Dictionary:
if !node.script:
return {}
if Engine.get_main_loop().has_meta('dialogic_scene_export_defaults') and \
node.script.resource_path in Engine.get_main_loop().get_meta('dialogic_scene_export_defaults'):
return Engine.get_main_loop().get_meta('dialogic_scene_export_defaults')[node.script.resource_path]
if !Engine.get_main_loop().has_meta('dialogic_scene_export_defaults'):
Engine.get_main_loop().set_meta('dialogic_scene_export_defaults', {})
var defaults := {}
var property_info: Array[Dictionary] = node.script.get_script_property_list()
for i in property_info:
if i['usage'] & PROPERTY_USAGE_EDITOR:
defaults[i['name']] = node.get(i['name'])
Engine.get_main_loop().get_meta('dialogic_scene_export_defaults')[node.script.resource_path] = defaults
return defaults
#endregion
#region MAKE CUSTOM
static func make_file_custom(original_file:String, target_folder:String, new_file_name := "", new_folder_name := "") -> String:
if not ResourceLoader.exists(original_file):
push_error("[Dialogic] Unable to make file with invalid path custom!")
return ""
if new_folder_name:
target_folder = target_folder.path_join(new_folder_name)
DirAccess.make_dir_absolute(target_folder)
if new_file_name.is_empty():
new_file_name = "custom_" + original_file.get_file()
if not new_file_name.ends_with(original_file.get_extension()):
new_file_name += "." + original_file.get_extension()
var target_file := target_folder.path_join(new_file_name)
customize_file(original_file, target_file)
get_dialogic_plugin().get_editor_interface().get_resource_filesystem().scan_sources()
return target_file
static func customize_file(original_file:String, target_file:String) -> String:
#print("\nCUSTOMIZE FILE")
#printt(original_file, "->", target_file)
DirAccess.copy_absolute(original_file, target_file)
var file := FileAccess.open(target_file, FileAccess.READ)
var file_text := file.get_as_text()
file.close()
# If we are customizing a scene, we check for any resources used in that scene that are in the same folder.
# Those will be copied as well and the scene will be modified to point to them.
if file_text.begins_with('[gd_'):
var base_path: String = original_file.get_base_dir()
var remove_uuid_regex := r'\[gd_.* (?<uid>uid="uid:[^"]*")'
var result := RegEx.create_from_string(remove_uuid_regex).search(file_text)
if result:
file_text = file_text.replace(result.get_string("uid"), "")
# This regex also removes the UID referencing the original resource
var file_regex := r'(uid="[^"]*" )?\Qpath="'+base_path+r'\E(?<file>[^"]*)"'
result = RegEx.create_from_string(file_regex).search(file_text)
while result:
var found_file_name := result.get_string('file')
var found_file_path := base_path.path_join(found_file_name)
var target_file_path := target_file.get_base_dir().path_join(found_file_name)
# Files found in this file will ALSO be customized.
customize_file(found_file_path, target_file_path)
file_text = file_text.replace(found_file_path, target_file_path)
result = RegEx.create_from_string(file_regex).search(file_text)
file = FileAccess.open(target_file, FileAccess.WRITE)
file.store_string(file_text)
file.close()
return target_file
#endregion
#region INSPECTOR FIELDS
################################################################################
static func setup_script_property_edit_node(property_info: Dictionary, value:Variant, property_changed:Callable) -> Control:
var input: Control = null
match property_info['type']:
TYPE_BOOL:
input = CheckBox.new()
if value != null:
input.button_pressed = value
input.toggled.connect(DialogicUtil._on_export_bool_submitted.bind(property_info.name, property_changed))
TYPE_COLOR:
input = ColorPickerButton.new()
if value != null:
input.color = value
input.color_changed.connect(DialogicUtil._on_export_color_submitted.bind(property_info.name, property_changed))
input.custom_minimum_size.x = get_editor_scale() * 50
TYPE_INT:
if property_info['hint'] & PROPERTY_HINT_ENUM:
input = OptionButton.new()
for x in property_info['hint_string'].split(','):
input.add_item(x.split(':')[0])
if value != null:
input.select(value)
input.item_selected.connect(DialogicUtil._on_export_int_enum_submitted.bind(property_info.name, property_changed))
else:
input = SpinBox.new()
input.value_changed.connect(DialogicUtil._on_export_number_submitted.bind(property_info.name, property_changed))
if property_info.hint_string == 'int':
input.step = 1
input.allow_greater = true
input.allow_lesser = true
elif ',' in property_info.hint_string:
input.min_value = int(property_info.hint_string.get_slice(',', 0))
input.max_value = int(property_info.hint_string.get_slice(',', 1))
if property_info.hint_string.count(',') > 1:
input.step = int(property_info.hint_string.get_slice(',', 2))
if value != null:
input.value = value
TYPE_FLOAT:
input = SpinBox.new()
input.step = 0.01
if ',' in property_info.hint_string:
input.min_value = float(property_info.hint_string.get_slice(',', 0))
input.max_value = float(property_info.hint_string.get_slice(',', 1))
if property_info.hint_string.count(',') > 1:
input.step = float(property_info.hint_string.get_slice(',', 2))
input.value_changed.connect(DialogicUtil._on_export_number_submitted.bind(property_info.name, property_changed))
if value != null:
input.value = value
TYPE_VECTOR2, TYPE_VECTOR3, TYPE_VECTOR4:
var vectorSize: String = type_string(typeof(value))[-1]
input = load("res://addons/dialogic/Editor/Events/Fields/field_vector" + vectorSize + ".tscn").instantiate()
input.property_name = property_info['name']
input.set_value(value)
input.value_changed.connect(DialogicUtil._on_export_vector_submitted.bind(property_changed))
TYPE_STRING:
if property_info['hint'] & PROPERTY_HINT_FILE or property_info['hint'] & PROPERTY_HINT_DIR:
input = load("res://addons/dialogic/Editor/Events/Fields/field_file.tscn").instantiate()
input.file_filter = property_info['hint_string']
input.file_mode = FileDialog.FILE_MODE_OPEN_FILE
if property_info['hint'] == PROPERTY_HINT_DIR:
input.file_mode = FileDialog.FILE_MODE_OPEN_DIR
input.property_name = property_info['name']
input.placeholder = "Default"
input.hide_reset = true
if value != null:
input.set_value(value)
input.value_changed.connect(DialogicUtil._on_export_file_submitted.bind(property_changed))
elif property_info['hint'] & PROPERTY_HINT_ENUM:
input = OptionButton.new()
var options: PackedStringArray = []
for x in property_info['hint_string'].split(','):
options.append(x.split(':')[0].strip_edges())
input.add_item(options[-1])
if value != null:
input.select(options.find(value))
input.item_selected.connect(DialogicUtil._on_export_string_enum_submitted.bind(property_info.name, options, property_changed))
else:
input = LineEdit.new()
if value != null:
input.text = value
input.text_submitted.connect(DialogicUtil._on_export_input_text_submitted.bind(property_info.name, property_changed))
TYPE_DICTIONARY:
input = load("res://addons/dialogic/Editor/Events/Fields/field_dictionary.tscn").instantiate()
input.property_name = property_info["name"]
input.value_changed.connect(_on_export_dict_submitted.bind(property_changed))
TYPE_OBJECT:
input = load("res://addons/dialogic/Editor/Common/hint_tooltip_icon.tscn").instantiate()
input.hint_text = "Objects/Resources as settings are currently not supported. \nUse @export_file('*.extension') instead and load the resource once needed."
_:
input = LineEdit.new()
if value != null:
input.text = value
input.text_submitted.connect(_on_export_input_text_submitted.bind(property_info.name, property_changed))
return input
static func _on_export_input_text_submitted(text:String, property_name:String, callable: Callable) -> void:
callable.call(property_name, var_to_str(text))
static func _on_export_bool_submitted(value:bool, property_name:String, callable: Callable) -> void:
callable.call(property_name, var_to_str(value))
static func _on_export_color_submitted(color:Color, property_name:String, callable: Callable) -> void:
callable.call(property_name, var_to_str(color))
static func _on_export_int_enum_submitted(item:int, property_name:String, callable: Callable) -> void:
callable.call(property_name, var_to_str(item))
static func _on_export_number_submitted(value:float, property_name:String, callable: Callable) -> void:
callable.call(property_name, var_to_str(value))
static func _on_export_file_submitted(property_name:String, value:String, callable: Callable) -> void:
callable.call(property_name, var_to_str(value))
static func _on_export_string_enum_submitted(value:int, property_name:String, list:PackedStringArray, callable: Callable):
callable.call(property_name, var_to_str(list[value]))
static func _on_export_vector_submitted(property_name:String, value:Variant, callable: Callable) -> void:
callable.call(property_name, var_to_str(value))
static func _on_export_dict_submitted(property_name:String, value:Variant, callable: Callable) -> void:
callable.call(property_name, var_to_str(value))
#endregion
#region EVENT DEFAULTS
################################################################################
static func get_custom_event_defaults(event_name:String) -> Dictionary:
if Engine.is_editor_hint():
return ProjectSettings.get_setting('dialogic/event_default_overrides', {}).get(event_name, {})
else:
if !Engine.get_main_loop().has_meta('dialogic_event_defaults'):
Engine.get_main_loop().set_meta('dialogic_event_defaults', ProjectSettings.get_setting('dialogic/event_default_overrides', {}))
return Engine.get_main_loop().get_meta('dialogic_event_defaults').get(event_name, {})
#endregion
#region CONVERSION
################################################################################
static func str_to_bool(boolstring:String) -> bool:
return true if boolstring == "true" else false
static func logical_convert(value:Variant) -> Variant:
if typeof(value) == TYPE_STRING:
if value.is_valid_int():
return value.to_int()
if value.is_valid_float():
return value.to_float()
if value == 'true':
return true
if value == 'false':
return false
return value
## Takes [param source] and builds a dictionary of keys only.
## The values are `null`.
static func str_to_hash_set(source: String) -> Dictionary:
var dictionary := Dictionary()
for character in source:
dictionary[character] = null
return dictionary
#endregion
static func get_character_suggestions(_search_text:String, current_value:DialogicCharacter = null, allow_none := true, allow_all:= false, editor_node:Node = null) -> Dictionary:
var suggestions := {}
var icon := load("res://addons/dialogic/Editor/Images/Resources/character.svg")
if allow_none and current_value:
suggestions['(No one)'] = {'value':'', 'editor_icon':["GuiRadioUnchecked", "EditorIcons"]}
if allow_all:
suggestions['ALL'] = {'value':'--All--', 'tooltip':'All currently joined characters leave', 'editor_icon':["GuiEllipsis", "EditorIcons"]}
# Get characters in the current timeline and place them at the top of suggestions.
if editor_node:
var recent_characters := []
var timeline_node := editor_node.get_parent().find_parent("Timeline") as DialogicEditor
for event_node in timeline_node.find_child("Timeline").get_children():
if event_node == editor_node:
break
if event_node.resource is DialogicCharacterEvent or event_node.resource is DialogicTextEvent:
recent_characters.append(event_node.resource.character)
recent_characters.reverse()
for character in recent_characters:
if character and not character.get_character_name() in suggestions:
suggestions[character.get_character_name()] = {'value': character.get_character_name(), 'tooltip': character.resource_path, 'icon': icon.duplicate()}
var character_directory := DialogicResourceUtil.get_character_directory()
for resource in character_directory.keys():
suggestions[resource] = {'value': resource, 'tooltip': character_directory[resource], 'icon': icon}
return suggestions
static func get_portrait_suggestions(search_text:String, character:DialogicCharacter, allow_empty := false, empty_text := "Don't Change") -> Dictionary:
var icon := load("res://addons/dialogic/Editor/Images/Resources/portrait.svg")
var suggestions := {}
if allow_empty:
suggestions[empty_text] = {'value':'', 'editor_icon':["GuiRadioUnchecked", "EditorIcons"]}
if "{" in search_text:
suggestions[search_text] = {'value':search_text, 'editor_icon':["Variant", "EditorIcons"]}
if character != null:
for portrait in character.portraits:
suggestions[portrait] = {'value':portrait, 'icon':icon}
return suggestions
static func get_portrait_position_suggestions(search_text := "") -> Dictionary:
var icon := load(DialogicUtil.get_module_path("Character").path_join('portrait_position.svg'))
var setting: String = ProjectSettings.get_setting('dialogic/portraits/position_suggestion_names', 'leftmost, left, center, right, rightmost')
var suggestions := {}
if not search_text.is_empty():
suggestions[search_text] = {'value':search_text.strip_edges(), 'editor_icon':["GuiScrollArrowRight", "EditorIcons"]}
for position_id in setting.split(','):
suggestions[position_id.strip_edges()] = {'value':position_id.strip_edges(), 'icon':icon}
if not search_text.is_empty() and position_id.strip_edges().begins_with(search_text):
suggestions.erase(search_text)
return suggestions
@@ -1,41 +0,0 @@
class_name DialogicSubsystem
extends Node
var dialogic: DialogicGameHandler = null
enum LoadFlags {FULL_LOAD, ONLY_DNODES}
# To be overriden by sub-classes
# Called once after every subsystem has been added to the tree
func post_install() -> void:
pass
# To be overriden by sub-classes
# Fill in everything that should be cleared (for example before loading a different state)
func clear_game_state(_clear_flag:=DialogicGameHandler.ClearFlags.FULL_CLEAR) -> void:
pass
# To be overriden by sub-classes
# Fill in everything that should be loaded using the dialogic_game_handler.current_state_info
# This is called when a save is loaded
func load_game_state(_load_flag:=LoadFlags.FULL_LOAD) -> void:
pass
# To be overriden by sub-classes
# Fill in everything that should be saved into the dialogic_game_handler.current_state_info
# This is called when a save is saved
func save_game_state() -> void:
pass
# To be overriden by sub-classes
func pause() -> void:
pass
# To be overriden by sub-classes
func resume() -> void:
pass
-152
View File
@@ -1,152 +0,0 @@
@tool
class_name DialogicIndexer
extends RefCounted
## Script that indexes events, subsystems, settings pages and more. [br]
## Place a script of this type in every folder in "addons/Events". [br]
## Overwrite the methods to return the contents of that folder.
var this_folder: String = get_script().resource_path.get_base_dir()
## Overwrite if this module contains any events. [br]
## Return an array with all the paths to the event scripts.[br]
## You can use the [property this_folder].path_join('my_event.gd')
func _get_events() -> Array:
if ResourceLoader.exists(this_folder.path_join('event.gd')):
return [this_folder.path_join('event.gd')]
return []
## Overwrite if this module contains any subsystems.
## Should return an array of dictionaries each with the following keys: [br]
## "name" -> name for this subsystem[br]
## "script" -> array of preview images[br]
func _get_subsystems() -> Array[Dictionary]:
return []
func _get_editors() -> Array[String]:
return []
func _get_settings_pages() -> Array:
return []
func _get_character_editor_sections() -> Array:
return []
#region TEXT EFFECTS & MODIFIERS
## Should return array of dictionaries with the following keys:[br]
## "command" -> the text e.g. "speed"[br]
## "node_path" or "subsystem" -> whichever contains your effect method[br]
## "method" -> name of the effect method[br]
func _get_text_effects() -> Array[Dictionary]:
return []
## Should return array of dictionaries with the same arguments as _get_text_effects()
func _get_text_modifiers() -> Array[Dictionary]:
return []
#endregion
## Return a list of resources, scripts, etc.
## These can later be retrieved with DialogicResourceUtil.
## Each dictionary should contain (at least "type" and "path").
## E.g. {"type":"Animation", "path": "res://..."}
func _get_special_resources() -> Dictionary:
return {}
## Return a list of dictionaries, each
func _get_portrait_scene_presets() -> Array[Dictionary]:
return []
#region HELPERS
################################################################################
func list_dir(subdir:='') -> Array:
return Array(DirAccess.get_files_at(this_folder.path_join(subdir))).map(func(file):return this_folder.path_join(subdir).path_join(file))
func list_special_resources(subdir:='', extension:="") -> Dictionary:
var dict := {}
for i in list_dir(subdir):
if extension.is_empty() or i.ends_with(extension):
dict[DialogicUtil.pretty_name(i).to_lower()] = {"path":i}
return dict
func list_animations(subdir := "") -> Dictionary:
var full_animation_list := {}
for path in list_dir(subdir):
if not path.ends_with(".gd") and not path.ends_with(".gdc"):
continue
var anim_object: DialogicAnimation = load(path).new()
var versions := anim_object._get_named_variations()
for version_name in versions:
full_animation_list[version_name] = versions[version_name]
full_animation_list[version_name]["path"] = path
anim_object.queue_free()
return full_animation_list
#endregion
#region STYLES & LAYOUTS
################################################################################
func _get_style_presets() -> Array[Dictionary]:
return []
## Should return an array of dictionaries with the following keys:[br]
## "path" -> the path to the scene[br]
## "name" -> name for this layout[br]
## "description"-> description of this layout. list what features/events are supported[br]
## "preview_image"-> array of preview images[br]
func _get_layout_parts() -> Array[Dictionary]:
return []
## Helper that allows scanning sub directories that might be layout parts or styles
func scan_for_layout_parts() -> Array[Dictionary]:
var dir := DirAccess.open(this_folder)
var style_list: Array[Dictionary] = []
if !dir:
return style_list
dir.list_dir_begin()
var dir_name := dir.get_next()
while dir_name != "":
if !dir.current_is_dir() or !dir.file_exists(dir_name.path_join('part_config.cfg')):
dir_name = dir.get_next()
continue
var config := ConfigFile.new()
config.load(this_folder.path_join(dir_name).path_join('part_config.cfg'))
var default_image_path: String = this_folder.path_join(dir_name).path_join('preview.png')
style_list.append(
{
'type': config.get_value('style', 'type', 'Unknown type'),
'name': config.get_value('style', 'name', 'Unnamed Layout'),
'path': this_folder.path_join(dir_name).path_join(config.get_value('style', 'scene', '')),
'author': config.get_value('style', 'author', 'Anonymous'),
'description': config.get_value('style', 'description', 'No description'),
'preview_image': [config.get_value('style', 'image', default_image_path)],
'style_path':config.get_value('style', 'style_path', ''),
'icon':this_folder.path_join(dir_name).path_join(config.get_value('style', 'icon', '')),
})
if not style_list[-1].style_path.begins_with('res://'):
style_list[-1].style_path = this_folder.path_join(dir_name).path_join(style_list[-1].style_path)
dir_name = dir.get_next()
return style_list
#endregion
@@ -1,91 +0,0 @@
@tool
extends DialogicCharacterEditorPortraitSection
## Section that allows setting values of exported scene variables
## for custom portrait scenes
var current_portrait_data := {}
var last_scene := ""
func _get_title() -> String:
return "Settings"
func _load_portrait_data(data:Dictionary) -> void:
_recheck(data, true)
## Recheck section visibility and reload export fields.
## This allows reacting to changes of the portrait_scene setting.
func _recheck(data: Dictionary, force:=false):
if last_scene == data.get("scene", "") and not force:
current_portrait_data = data
last_scene = data.get("scene", "")
return
last_scene = data.get("scene", "")
current_portrait_data = data
for child in $Grid.get_children():
child.get_parent().remove_child(child)
child.queue_free()
var scene: Variant = null
if current_portrait_data.get('scene', '').is_empty():
if ProjectSettings.get_setting('dialogic/portraits/default_portrait', '').is_empty():
scene = load(character_editor.def_portrait_path)
else:
scene = load(ProjectSettings.get_setting('dialogic/portraits/default_portrait', ''))
else:
scene = load(current_portrait_data.get('scene'))
if not scene:
return
scene = scene.instantiate()
var skip := false
for i in scene.script.get_script_property_list():
if i['usage'] & PROPERTY_USAGE_EDITOR and !skip:
var label := Label.new()
label.text = i['name'].capitalize()
$Grid.add_child(label)
var current_value: Variant = scene.get(i['name'])
if current_portrait_data.has('export_overrides') and current_portrait_data['export_overrides'].has(i['name']):
current_value = str_to_var(current_portrait_data.export_overrides[i['name']])
if current_value == null and typeof(scene.get(i['name'])) == TYPE_STRING:
current_value = current_portrait_data['export_overrides'][i['name']]
var input: Node = DialogicUtil.setup_script_property_edit_node(i, current_value, set_export_override)
input.size_flags_horizontal = SIZE_EXPAND_FILL
$Grid.add_child(input)
if i['usage'] & PROPERTY_USAGE_GROUP:
if i['name'] == 'Main' or i["name"] == "Private":
skip = true
continue
else:
skip = false
if $Grid.get_child_count():
get_parent().get_child(get_index()-1).show()
show()
else:
hide()
get_parent().get_child(get_index()-1).hide()
get_parent().get_child(get_index()+1).hide()
## On any change, save the export override to the portrait items metadata.
func set_export_override(property_name:String, value:String = "") -> void:
var data: Dictionary = selected_item.get_metadata(0)
if !data.has('export_overrides'):
data['export_overrides'] = {}
if !value.is_empty():
data.export_overrides[property_name] = value
else:
data.export_overrides.erase(property_name)
changed.emit()
update_preview.emit()
@@ -1,16 +0,0 @@
[gd_scene load_steps=2 format=3 uid="uid://cfcs7lb6gqnmd"]
[ext_resource type="Script" path="res://addons/dialogic/Editor/CharacterEditor/char_edit_p_section_exports.gd" id="1_isys8"]
[node name="Settings" type="VBoxContainer"]
custom_minimum_size = Vector2(0, 35)
offset_right = 367.0
offset_bottom = 82.0
script = ExtResource("1_isys8")
[node name="Grid" type="GridContainer" parent="."]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
theme_override_constants/h_separation = 10
columns = 2
@@ -1,44 +0,0 @@
@tool
extends DialogicCharacterEditorPortraitSection
## Tab that allows setting size, offset and mirror of a portrait.
func _get_title() -> String:
return "Scale, Offset & Mirror"
func _load_portrait_data(data:Dictionary) -> void:
%IgnoreScale.set_pressed_no_signal(data.get('ignore_char_scale', false))
%PortraitScale.value = data.get('scale', 1.0)*100
%PortraitOffset.set_value(data.get('offset', Vector2()))
%PortraitOffset._load_display_info({'step':1})
%PortraitMirror.set_pressed_no_signal(data.get('mirror', false))
func _on_portrait_scale_value_changed(value:float) -> void:
var data: Dictionary = selected_item.get_metadata(0)
data['scale'] = value/100.0
update_preview.emit()
changed.emit()
func _on_portrait_mirror_toggled(button_pressed:bool)-> void:
var data: Dictionary = selected_item.get_metadata(0)
data['mirror'] = button_pressed
update_preview.emit()
changed.emit()
func _on_ignore_scale_toggled(button_pressed:bool) -> void:
var data: Dictionary = selected_item.get_metadata(0)
data['ignore_char_scale'] = button_pressed
update_preview.emit()
changed.emit()
func _on_portrait_offset_value_changed(property:String, value:Vector2) -> void:
var data: Dictionary = selected_item.get_metadata(0)
data['offset'] = value
update_preview.emit()
changed.emit()
@@ -1,64 +0,0 @@
[gd_scene load_steps=3 format=3 uid="uid://crke8suvv52c6"]
[ext_resource type="Script" path="res://addons/dialogic/Editor/CharacterEditor/char_edit_p_section_layout.gd" id="1_76vf2"]
[ext_resource type="PackedScene" uid="uid://dtimnsj014cu" path="res://addons/dialogic/Editor/Events/Fields/field_vector2.tscn" id="2_c8kyi"]
[node name="Layout" type="HFlowContainer"]
offset_right = 428.0
offset_bottom = 128.0
size_flags_horizontal = 3
script = ExtResource("1_76vf2")
[node name="Label3" type="Label" parent="."]
layout_mode = 2
text = "Ignore Main Scale: "
[node name="IgnoreScale" type="CheckBox" parent="."]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "This portrait will ignore the main scale."
[node name="HBoxContainer" type="HBoxContainer" parent="."]
layout_mode = 2
[node name="Label" type="Label" parent="HBoxContainer"]
layout_mode = 2
text = "Scale:"
[node name="PortraitScale" type="SpinBox" parent="HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "A scale to be applied on top of the main scale
(unless ignore main scale is pressed)."
value = 100.0
allow_greater = true
suffix = "%"
[node name="HBoxContainer2" type="HBoxContainer" parent="."]
layout_mode = 2
[node name="Label2" type="Label" parent="HBoxContainer2"]
layout_mode = 2
text = "Offset:"
[node name="PortraitOffset" parent="HBoxContainer2" instance=ExtResource("2_c8kyi")]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "Offset that is applied on top of the main portrait offset."
[node name="MirrorOption" type="HBoxContainer" parent="."]
layout_mode = 2
[node name="Label" type="Label" parent="MirrorOption"]
layout_mode = 2
text = "Mirror:"
[node name="PortraitMirror" type="CheckBox" parent="MirrorOption"]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "Mirroring that is applied on top of the main portrait mirror."
[connection signal="toggled" from="IgnoreScale" to="." method="_on_ignore_scale_toggled"]
[connection signal="value_changed" from="HBoxContainer/PortraitScale" to="." method="_on_portrait_scale_value_changed"]
[connection signal="value_changed" from="HBoxContainer2/PortraitOffset" to="." method="_on_portrait_offset_value_changed"]
[connection signal="toggled" from="MirrorOption/PortraitMirror" to="." method="_on_portrait_mirror_toggled"]
@@ -1,101 +0,0 @@
@tool
extends DialogicCharacterEditorPortraitSection
## Tab that allows setting a custom scene for a portrait.
func _get_title() -> String:
return "Scene"
func _init() -> void:
hint_text = "You can use a custom scene for this portrait."
func _start_opened() -> bool:
return true
func _ready() -> void:
%ChangeSceneButton.icon = get_theme_icon("Loop", "EditorIcons")
%ScenePicker.file_filter = "*.tscn, *.scn; Scenes"
%ScenePicker.resource_icon = get_theme_icon('PackedScene', 'EditorIcons')
%ScenePicker.placeholder = 'Default scene'
%OpenSceneButton.icon = get_theme_icon("ExternalLink", "EditorIcons")
func _load_portrait_data(data:Dictionary) -> void:
reload_ui(data)
func _on_open_scene_button_pressed() -> void:
var data: Dictionary = selected_item.get_metadata(0)
if ResourceLoader.exists(data.get("scene", "")):
DialogicUtil.get_dialogic_plugin().get_editor_interface().open_scene_from_path(data.get("scene", ""))
await get_tree().process_frame
EditorInterface.set_main_screen_editor("2D")
func _on_change_scene_button_pressed() -> void:
%PortraitSceneBrowserWindow.popup_centered_ratio(0.6)
func _on_portrait_scene_browser_activate_part(part_info: Dictionary) -> void:
%PortraitSceneBrowserWindow.hide()
match part_info.type:
"General":
set_scene_path(part_info.path)
"Preset":
find_parent("EditorView").godot_file_dialog(
create_new_portrait_scene.bind(part_info),
'*.tscn,*.scn',
EditorFileDialog.FILE_MODE_SAVE_FILE,
"Select where to save the new scene",
part_info.path.get_file().trim_suffix("."+part_info.path.get_extension())+"_"+character_editor.current_resource.get_character_name().to_lower())
"Custom":
find_parent("EditorView").godot_file_dialog(
set_scene_path,
'*.tscn, *.scn',
EditorFileDialog.FILE_MODE_OPEN_FILE,
"Select custom portrait scene",)
"Default":
set_scene_path("")
func create_new_portrait_scene(target_file: String, info: Dictionary) -> void:
var path := make_portrait_preset_custom(target_file, info)
set_scene_path(path)
func make_portrait_preset_custom(target_file:String, info: Dictionary) -> String:
var previous_file: String = info.path
var result_path := DialogicUtil.make_file_custom(previous_file, target_file.get_base_dir(), target_file.get_file())
return result_path
func set_scene_path(path:String) -> void:
var data: Dictionary = selected_item.get_metadata(0)
data['scene'] = path
update_preview.emit()
changed.emit()
reload_ui(data)
func reload_ui(data: Dictionary) -> void:
var path: String = data.get('scene', '')
%OpenSceneButton.hide()
if path.is_empty():
%SceneLabel.text = "Default Portrait Scene"
%SceneLabel.tooltip_text = "Can be changed in the settings."
%SceneLabel.add_theme_color_override("font_color", get_theme_color("readonly_color", "Editor"))
elif %PortraitSceneBrowser.is_premade_portrait_scene(path):
%SceneLabel.text = %PortraitSceneBrowser.portrait_scenes_info[path].name
%SceneLabel.tooltip_text = path
%SceneLabel.add_theme_color_override("font_color", get_theme_color("accent_color", "Editor"))
else:
%SceneLabel.text = path.get_file()
%SceneLabel.tooltip_text = path
%SceneLabel.add_theme_color_override("font_color", get_theme_color("property_color_x", "Editor"))
%OpenSceneButton.show()
@@ -1,72 +0,0 @@
[gd_scene load_steps=6 format=3 uid="uid://djq4aasoihexj"]
[ext_resource type="Script" path="res://addons/dialogic/Editor/CharacterEditor/char_edit_p_section_main.gd" id="1_ht8lu"]
[ext_resource type="PackedScene" uid="uid://7mvxuaulctcq" path="res://addons/dialogic/Editor/Events/Fields/field_file.tscn" id="2_k8xs0"]
[ext_resource type="PackedScene" uid="uid://b1wn8r84uh11b" path="res://addons/dialogic/Editor/CharacterEditor/portrait_scene_browser.tscn" id="3_ngvgq"]
[sub_resource type="Image" id="Image_tg5pd"]
data = {
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
"format": "RGBA8",
"height": 16,
"mipmaps": false,
"width": 16
}
[sub_resource type="ImageTexture" id="ImageTexture_f5xt2"]
image = SubResource("Image_tg5pd")
[node name="Scene" type="GridContainer"]
offset_right = 298.0
offset_bottom = 86.0
size_flags_horizontal = 3
script = ExtResource("1_ht8lu")
[node name="HBox" type="HBoxContainer" parent="."]
layout_mode = 2
size_flags_horizontal = 3
[node name="ChangeSceneButton" type="Button" parent="HBox"]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "Change Scene"
icon = SubResource("ImageTexture_f5xt2")
[node name="SceneLabel" type="Label" parent="HBox"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
mouse_filter = 0
theme_override_colors/font_color = Color(0, 0, 0, 1)
text = "asdsdasdasd"
clip_text = true
[node name="ScenePicker" parent="HBox" instance=ExtResource("2_k8xs0")]
unique_name_in_owner = true
visible = false
layout_mode = 2
size_flags_horizontal = 3
file_filter = "*.tscn, *.scn; Scenes"
placeholder = "Default scene"
[node name="OpenSceneButton" type="Button" parent="HBox"]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "Open/Edit Scene"
icon = SubResource("ImageTexture_f5xt2")
[node name="PortraitSceneBrowserWindow" type="Window" parent="."]
unique_name_in_owner = true
title = "Portrait Scene Browser"
position = Vector2i(0, 36)
visible = false
wrap_controls = true
transient = true
popup_window = true
[node name="PortraitSceneBrowser" parent="PortraitSceneBrowserWindow" instance=ExtResource("3_ngvgq")]
unique_name_in_owner = true
[connection signal="pressed" from="HBox/ChangeSceneButton" to="." method="_on_change_scene_button_pressed"]
[connection signal="pressed" from="HBox/OpenSceneButton" to="." method="_on_open_scene_button_pressed"]
[connection signal="activate_part" from="PortraitSceneBrowserWindow/PortraitSceneBrowser" to="." method="_on_portrait_scene_browser_activate_part"]
@@ -1,80 +0,0 @@
@tool
extends DialogicCharacterEditorPortraitSection
## Portrait Settings Section that only shows the MAIN settings of a portrait scene.
var current_portrait_data := {}
var last_scene := ""
func _show_title() -> bool:
return false
func _load_portrait_data(data:Dictionary) -> void:
_recheck(data, true)
func _recheck(data:Dictionary, force := false) -> void:
get_parent().get_child(get_index()+1).hide()
if last_scene == data.get("scene", "") and not force:
current_portrait_data = data
last_scene = data.get("scene", "")
return
last_scene = data.get("scene", "")
current_portrait_data = data
load_portrait_scene_export_variables()
func load_portrait_scene_export_variables() -> void:
for child in $Grid.get_children():
child.queue_free()
var scene: Variant = null
if current_portrait_data.get('scene', '').is_empty():
if ProjectSettings.get_setting('dialogic/portraits/default_portrait', '').is_empty():
scene = load(character_editor.def_portrait_path)
else:
scene = load(ProjectSettings.get_setting('dialogic/portraits/default_portrait', ''))
else:
scene = load(current_portrait_data.get('scene'))
if not scene:
return
scene = scene.instantiate()
var skip := true
for i in scene.script.get_script_property_list():
if i['usage'] & PROPERTY_USAGE_EDITOR and !skip:
var label := Label.new()
label.text = i['name'].capitalize()
$Grid.add_child(label)
var current_value: Variant = scene.get(i['name'])
if current_portrait_data.has('export_overrides') and current_portrait_data['export_overrides'].has(i['name']):
current_value = str_to_var(current_portrait_data['export_overrides'][i['name']])
if current_value == null and typeof(scene.get(i['name'])) == TYPE_STRING:
current_value = current_portrait_data['export_overrides'][i['name']]
var input: Node = DialogicUtil.setup_script_property_edit_node(i, current_value, set_export_override)
input.size_flags_horizontal = SIZE_EXPAND_FILL
$Grid.add_child(input)
if i['usage'] & PROPERTY_USAGE_GROUP:
if i['name'] == 'Main':
skip = false
else:
skip = true
continue
func set_export_override(property_name:String, value:String = "") -> void:
var data: Dictionary = selected_item.get_metadata(0)
if !data.has('export_overrides'):
data['export_overrides'] = {}
if !value.is_empty():
data['export_overrides'][property_name] = value
else:
data['export_overrides'].erase(property_name)
changed.emit()
update_preview.emit()
@@ -1,15 +0,0 @@
[gd_scene load_steps=2 format=3 uid="uid://ba5w02lm3ewkj"]
[ext_resource type="Script" path="res://addons/dialogic/Editor/CharacterEditor/char_edit_p_section_main_exports.gd" id="1_mttrr"]
[node name="MainExports" type="VBoxContainer"]
offset_right = 374.0
offset_bottom = 82.0
script = ExtResource("1_mttrr")
[node name="Grid" type="GridContainer" parent="."]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
theme_override_constants/h_separation = 10
columns = 2
@@ -1,53 +0,0 @@
@tool
extends DialogicCharacterEditorMainSection
var min_width := 200
## The general character settings tab
func _get_title() -> String:
return "General"
func _start_opened() -> bool:
return true
func _ready() -> void:
# Connecting all necessary signals
%ColorPickerButton.custom_minimum_size.x = DialogicUtil.get_editor_scale() * 30
%ColorPickerButton.color_changed.connect(character_editor.something_changed)
%DisplayNameLineEdit.text_changed.connect(character_editor.something_changed)
%NicknameLineEdit.text_changed.connect(character_editor.something_changed)
%DescriptionTextEdit.text_changed.connect(character_editor.something_changed)
min_width = get_minimum_size().x
resized.connect(_on_resized)
func _load_character(resource:DialogicCharacter) -> void:
%DisplayNameLineEdit.text = resource.display_name
%ColorPickerButton.color = resource.color
%NicknameLineEdit.text = ""
for nickname in resource.nicknames:
%NicknameLineEdit.text += nickname +", "
%NicknameLineEdit.text = %NicknameLineEdit.text.trim_suffix(', ')
%DescriptionTextEdit.text = resource.description
func _save_changes(resource:DialogicCharacter) -> DialogicCharacter:
resource.display_name = %DisplayNameLineEdit.text
resource.color = %ColorPickerButton.color
var nicknames := []
for n_name in %NicknameLineEdit.text.split(','):
nicknames.append(n_name.strip_edges())
resource.nicknames = nicknames
resource.description = %DescriptionTextEdit.text
return resource
func _on_resized() -> void:
if size.x > min_width+20:
self.columns = 2
else:
self.columns = 1
@@ -1,114 +0,0 @@
[gd_scene load_steps=5 format=3 uid="uid://bnkck3hocbkk5"]
[ext_resource type="Script" path="res://addons/dialogic/Editor/CharacterEditor/char_edit_section_general.gd" id="1_3e1i1"]
[ext_resource type="PackedScene" uid="uid://dbpkta2tjsqim" path="res://addons/dialogic/Editor/Common/hint_tooltip_icon.tscn" id="2_cxfqm"]
[sub_resource type="Image" id="Image_yiygw"]
data = {
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
"format": "RGBA8",
"height": 16,
"mipmaps": false,
"width": 16
}
[sub_resource type="ImageTexture" id="ImageTexture_hx3oq"]
image = SubResource("Image_yiygw")
[node name="General" type="GridContainer"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 7.5
offset_top = 38.5
offset_right = -7.5
offset_bottom = -7.5
grow_horizontal = 2
grow_vertical = 2
theme_override_constants/h_separation = 6
theme_override_constants/v_separation = 6
columns = 2
script = ExtResource("1_3e1i1")
[node name="HBox" type="HBoxContainer" parent="."]
layout_mode = 2
size_flags_vertical = 0
[node name="Label2" type="Label" parent="HBox"]
layout_mode = 2
size_flags_vertical = 0
text = "Display Name"
[node name="HintTooltip" parent="HBox" instance=ExtResource("2_cxfqm")]
layout_mode = 2
tooltip_text = "This name will be displayed on the name label. You can use a dialogic variable. E.g. :{Player.name}"
texture = SubResource("ImageTexture_hx3oq")
hint_text = "This name will be displayed on the name label. You can use a dialogic variable. E.g. :{Player.name}"
[node name="DisplayName" type="HBoxContainer" parent="."]
layout_mode = 2
size_flags_horizontal = 3
[node name="DisplayNameLineEdit" type="LineEdit" parent="DisplayName"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
caret_blink = true
caret_blink_interval = 0.5
[node name="HintTooltip4" parent="DisplayName" instance=ExtResource("2_cxfqm")]
layout_mode = 2
tooltip_text = "This color can be used on the name label and for occurences of the characters name in text (autocolor names)."
texture = SubResource("ImageTexture_hx3oq")
hint_text = "This color can be used on the name label and for occurences of the characters name in text (autocolor names)."
[node name="ColorPickerButton" type="ColorPickerButton" parent="DisplayName"]
unique_name_in_owner = true
custom_minimum_size = Vector2(30, 0)
layout_mode = 2
color = Color(1, 1, 1, 1)
edit_alpha = false
[node name="HBox2" type="HBoxContainer" parent="."]
layout_mode = 2
size_flags_vertical = 0
[node name="Label3" type="Label" parent="HBox2"]
layout_mode = 2
size_flags_vertical = 0
text = "Nicknames"
[node name="HintTooltip2" parent="HBox2" instance=ExtResource("2_cxfqm")]
layout_mode = 2
tooltip_text = "If autocolor names is enabled, these will be colored in the characters color as well."
texture = SubResource("ImageTexture_hx3oq")
hint_text = "If autocolor names is enabled, these will be colored in the characters color as well."
[node name="NicknameLineEdit" type="LineEdit" parent="."]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
caret_blink = true
caret_blink_interval = 0.5
[node name="HBox3" type="HBoxContainer" parent="."]
layout_mode = 2
size_flags_vertical = 0
[node name="Label4" type="Label" parent="HBox3"]
layout_mode = 2
size_flags_vertical = 0
text = "Description"
[node name="HintTooltip3" parent="HBox3" instance=ExtResource("2_cxfqm")]
layout_mode = 2
tooltip_text = "No effect, just for you."
texture = SubResource("ImageTexture_hx3oq")
hint_text = "No effect, just for you."
[node name="DescriptionTextEdit" type="TextEdit" parent="."]
unique_name_in_owner = true
custom_minimum_size = Vector2(0, 65)
layout_mode = 2
size_flags_horizontal = 3
wrap_mode = 1
@@ -1,77 +0,0 @@
@tool
extends DialogicCharacterEditorMainSection
## The general portrait settings section
var loading := false
func _get_title() -> String:
return "Portraits"
func _ready() -> void:
# Connecting all necessary signals
%DefaultPortraitPicker.value_changed.connect(default_portrait_changed)
%MainScale.value_changed.connect(main_portrait_settings_update)
%MainOffset._load_display_info({'step':1})
%MainOffset.value_changed.connect(main_portrait_settings_update)
%MainMirror.toggled.connect(main_portrait_settings_update)
# Setting up Default Portrait Picker
%DefaultPortraitPicker.resource_icon = load("res://addons/dialogic/Editor/Images/Resources/portrait.svg")
%DefaultPortraitPicker.get_suggestions_func = suggest_portraits
## Make sure preview get's updated when portrait settings change
func main_portrait_settings_update(_something=null, _value=null) -> void:
if loading:
return
character_editor.current_resource.scale = %MainScale.value/100.0
character_editor.current_resource.offset = %MainOffset.current_value
character_editor.current_resource.mirror = %MainMirror.button_pressed
character_editor.update_preview()
character_editor.something_changed()
func default_portrait_changed(property:String, value:String) -> void:
character_editor.current_resource.default_portrait = value
character_editor.update_default_portrait_star(value)
func set_default_portrait(portrait_name:String) -> void:
%DefaultPortraitPicker.set_value(portrait_name)
default_portrait_changed("", portrait_name)
func _load_character(resource:DialogicCharacter) -> void:
loading = true
%DefaultPortraitPicker.set_value(resource.default_portrait)
%MainScale.value = 100*resource.scale
%MainOffset.set_value(resource.offset)
%MainMirror.button_pressed = resource.mirror
loading = false
func _save_changes(resource:DialogicCharacter) -> DialogicCharacter:
# Portrait settings
if %DefaultPortraitPicker.current_value in resource.portraits.keys():
resource.default_portrait = %DefaultPortraitPicker.current_value
elif !resource.portraits.is_empty():
resource.default_portrait = resource.portraits.keys()[0]
else:
resource.default_portrait = ""
resource.scale = %MainScale.value/100.0
resource.offset = %MainOffset.current_value
resource.mirror = %MainMirror.button_pressed
return resource
## Get suggestions for DefaultPortraitPicker
func suggest_portraits(search:String) -> Dictionary:
var suggestions := {}
for portrait in character_editor.get_updated_portrait_dict().keys():
suggestions[portrait] = {'value':portrait}
return suggestions
@@ -1,59 +0,0 @@
[gd_scene load_steps=4 format=3 uid="uid://cmrgbo8qi145o"]
[ext_resource type="Script" path="res://addons/dialogic/Editor/CharacterEditor/char_edit_section_portraits.gd" id="1_6sxsl"]
[ext_resource type="PackedScene" uid="uid://dpwhshre1n4t6" path="res://addons/dialogic/Editor/Events/Fields/field_options_dynamic.tscn" id="2_birla"]
[ext_resource type="PackedScene" uid="uid://dtimnsj014cu" path="res://addons/dialogic/Editor/Events/Fields/field_vector2.tscn" id="3_vcvin"]
[node name="Portraits" type="GridContainer"]
offset_right = 453.0
offset_bottom = 141.0
theme_override_constants/h_separation = 1
theme_override_constants/v_separation = 6
columns = 2
script = ExtResource("1_6sxsl")
[node name="Label5" type="Label" parent="."]
layout_mode = 2
size_flags_vertical = 0
text = "Default"
[node name="DefaultPortraitPicker" parent="." instance=ExtResource("2_birla")]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
placeholder_text = "Select Default Portrait"
fit_text_length = false
[node name="Label" type="Label" parent="."]
layout_mode = 2
size_flags_vertical = 0
text = "Main Scale"
[node name="MainScale" type="SpinBox" parent="."]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 8
value = 100.0
allow_greater = true
alignment = 1
suffix = "%"
[node name="Label2" type="Label" parent="."]
layout_mode = 2
size_flags_vertical = 0
text = "Main Offset"
[node name="MainOffset" parent="." instance=ExtResource("3_vcvin")]
unique_name_in_owner = true
layout_mode = 2
alignment = 2
[node name="Label3" type="Label" parent="."]
layout_mode = 2
size_flags_vertical = 0
text = "Main Mirror"
[node name="MainMirror" type="CheckBox" parent="."]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 8
@@ -1,688 +0,0 @@
@tool
extends DialogicEditor
## Editor for editing character resources.
signal character_loaded(resource_path:String)
signal portrait_selected()
# Current state
var loading := false
var current_previewed_scene: Variant = null
var current_scene_path: String = ""
# References
var selected_item: TreeItem
var def_portrait_path: String = DialogicUtil.get_module_path('Character').path_join('default_portrait.tscn')
######### EDITOR STUFF and LOADING/SAVING ######################################
#region Resource Logic
## Method is called once editors manager is ready to accept registers.
func _register() -> void:
## Makes the editor open this when a .dch file is selected.
## Then _open_resource() is called.
editors_manager.register_resource_editor("dch", self)
## Add an "add character" button
var add_character_button: Button = editors_manager.add_icon_button(
load("res://addons/dialogic/Editor/Images/Toolbar/add-character.svg"),
'Add Character',
self)
add_character_button.pressed.connect(_on_create_character_button_pressed)
add_character_button.shortcut = Shortcut.new()
add_character_button.shortcut.events.append(InputEventKey.new())
add_character_button.shortcut.events[0].keycode = KEY_2
add_character_button.shortcut.events[0].ctrl_pressed = true
## By default show the no character screen
$NoCharacterScreen.show()
func _get_title() -> String:
return "Character"
func _get_icon() -> Texture:
return load("res://addons/dialogic/Editor/Images/Resources/character.svg")
## Called when a character is opened somehow
func _open_resource(resource:Resource) -> void:
if resource == null:
$NoCharacterScreen.show()
return
## Update resource
current_resource = (resource as DialogicCharacter)
## Make sure changes in the ui won't trigger saving
loading = true
## Load other main tabs
for child in %MainSettingsSections.get_children():
if child is DialogicCharacterEditorMainSection:
child._load_character(current_resource)
## Clear and then load Portrait section
%PortraitSearch.text = ""
load_portrait_tree()
loading = false
character_loaded.emit(resource.resource_path)
%CharacterName.text = DialogicResourceUtil.get_unique_identifier(resource.resource_path)
$NoCharacterScreen.hide()
%PortraitChangeInfo.hide()
## Called when the character is opened.
func _open(extra_info:Variant="") -> void:
if !ProjectSettings.get_setting('dialogic/portraits/default_portrait', '').is_empty():
def_portrait_path = ProjectSettings.get_setting('dialogic/portraits/default_portrait', '')
else:
def_portrait_path = DialogicUtil.get_module_path('Character').path_join('default_portrait.tscn')
if current_resource == null:
$NoCharacterScreen.show()
return
update_preview(true)
%PortraitChangeInfo.hide()
func _clear() -> void:
current_resource = null
current_resource_state = ResourceStates.SAVED
$NoCharacterScreen.show()
func _save() -> void:
if ! visible or not current_resource:
return
## Portrait list
current_resource.portraits = get_updated_portrait_dict()
## Main tabs
for child in %MainSettingsSections.get_children():
if child is DialogicCharacterEditorMainSection:
current_resource = child._save_changes(current_resource)
ResourceSaver.save(current_resource, current_resource.resource_path)
current_resource_state = ResourceStates.SAVED
DialogicResourceUtil.update_directory('dch')
## Saves a new empty character to the given path
func new_character(path: String) -> void:
var resource := DialogicCharacter.new()
resource.resource_path = path
resource.display_name = path.get_file().trim_suffix("."+path.get_extension())
resource.color = Color(1,1,1,1)
resource.default_portrait = ""
resource.custom_info = {}
ResourceSaver.save(resource, path)
EditorInterface.get_resource_filesystem().update_file(path)
DialogicResourceUtil.update_directory('dch')
editors_manager.edit_resource(resource)
#endregion
######### INTERFACE ############################################################
#region Interface
func _ready() -> void:
if get_parent() is SubViewport:
return
DialogicUtil.get_dialogic_plugin().resource_saved.connect(_on_some_resource_saved)
# NOTE: This check is required because up to 4.2 this signal is not exposed.
if DialogicUtil.get_dialogic_plugin().has_signal("scene_saved"):
DialogicUtil.get_dialogic_plugin().scene_saved.connect(_on_some_resource_saved)
$NoCharacterScreen.color = get_theme_color("dark_color_2", "Editor")
$NoCharacterScreen.show()
setup_portrait_list_tab()
_on_fit_preview_toggle_toggled(DialogicUtil.get_editor_setting('character_preview_fit', true))
%PreviewLabel.add_theme_color_override("font_color", get_theme_color("readonly_color", "Editor"))
%PortraitChangeWarning.add_theme_color_override("font_color", get_theme_color("warning_color", "Editor"))
%RealPreviewPivot.texture = get_theme_icon("EditorPivot", "EditorIcons")
%MainSettingsCollapse.icon = get_theme_icon("GuiVisibilityVisible", "EditorIcons")
set_portrait_settings_position(DialogicUtil.get_editor_setting('portrait_settings_position', true))
await find_parent('EditorView').ready
## Add general tabs
add_settings_section(load("res://addons/dialogic/Editor/CharacterEditor/char_edit_section_general.tscn").instantiate(), %MainSettingsSections)
add_settings_section(load("res://addons/dialogic/Editor/CharacterEditor/char_edit_section_portraits.tscn").instantiate(), %MainSettingsSections)
add_settings_section(load("res://addons/dialogic/Editor/CharacterEditor/char_edit_p_section_main_exports.tscn").instantiate(), %PortraitSettingsSection)
add_settings_section(load("res://addons/dialogic/Editor/CharacterEditor/char_edit_p_section_exports.tscn").instantiate(), %PortraitSettingsSection)
add_settings_section(load("res://addons/dialogic/Editor/CharacterEditor/char_edit_p_section_main.tscn").instantiate(), %PortraitSettingsSection)
add_settings_section(load("res://addons/dialogic/Editor/CharacterEditor/char_edit_p_section_layout.tscn").instantiate(), %PortraitSettingsSection)
## Load custom sections from modules
for indexer in DialogicUtil.get_indexers():
for path in indexer._get_character_editor_sections():
var scene: Control = load(path).instantiate()
if scene is DialogicCharacterEditorMainSection:
add_settings_section(scene, %MainSettingsSections)
elif scene is DialogicCharacterEditorPortraitSection:
add_settings_section(scene, %PortraitSettingsSection)
## Add a section (a control) either to the given settings section (Main or Portraits)
## - sets up the title of the section
## - connects to various signals
func add_settings_section(edit:Control, parent:Node) -> void:
edit.changed.connect(something_changed)
edit.character_editor = self
if edit.has_signal('update_preview'):
edit.update_preview.connect(update_preview)
var button: Button
if edit._show_title():
var hbox := HBoxContainer.new()
hbox.name = edit._get_title()+"BOX"
button = Button.new()
button.flat = true
button.theme_type_variation = "DialogicSection"
button.alignment = HORIZONTAL_ALIGNMENT_LEFT
button.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
button.text = edit._get_title()
button.icon_alignment = HORIZONTAL_ALIGNMENT_RIGHT
button.pressed.connect(_on_section_button_pressed.bind(button))
button.focus_mode = Control.FOCUS_NONE
button.icon = get_theme_icon("CodeFoldDownArrow", "EditorIcons")
button.add_theme_color_override('icon_normal_color', get_theme_color("font_color", "DialogicSection"))
hbox.size_flags_horizontal = Control.SIZE_EXPAND_FILL
hbox.add_child(button)
if !edit.hint_text.is_empty():
var hint: Node = load("res://addons/dialogic/Editor/Common/hint_tooltip_icon.tscn").instantiate()
hint.hint_text = edit.hint_text
hbox.add_child(hint)
parent.add_child(hbox)
parent.add_child(edit)
parent.add_child(HSeparator.new())
if button and !edit._start_opened():
_on_section_button_pressed(button)
func get_settings_section_by_name(name:String, main:=true) -> Node:
var parent := %MainSettingsSections
if not main:
parent = %PortraitSettingsSection
if parent.has_node(name):
return parent.get_node(name)
elif parent.has_node(name+"BOX/"+name):
return parent.get_node(name+"BOX/"+name)
else:
return null
func _on_section_button_pressed(button:Button) -> void:
var section_header := button.get_parent()
var section := section_header.get_parent().get_child(section_header.get_index()+1)
if section.visible:
button.icon = get_theme_icon("CodeFoldedRightArrow", "EditorIcons")
section.visible = false
else:
button.icon = get_theme_icon("CodeFoldDownArrow", "EditorIcons")
section.visible = true
if section_header.get_parent().get_child_count() > section_header.get_index()+2 and section_header.get_parent().get_child(section_header.get_index()+2) is Separator:
section_header.get_parent().get_child(section_header.get_index()+2).visible = section_header.get_parent().get_child(section_header.get_index()+1).visible
func something_changed(fake_argument = "", fake_arg2 = null) -> void:
if not loading:
current_resource_state = ResourceStates.UNSAVED
func _on_main_settings_collapse_toggled(button_pressed:bool) -> void:
%MainSettingsTitle.visible = !button_pressed
%MainSettingsScroll.visible = !button_pressed
if button_pressed:
%MainSettings.hide()
%MainSettingsCollapse.icon = get_theme_icon("GuiVisibilityHidden", "EditorIcons")
else:
%MainSettings.show()
%MainSettingsCollapse.icon = get_theme_icon("GuiVisibilityVisible", "EditorIcons")
func _on_switch_portrait_settings_position_pressed() -> void:
set_portrait_settings_position(!%RightSection.vertical)
func set_portrait_settings_position(is_below:bool) -> void:
%RightSection.vertical = is_below
DialogicUtil.set_editor_setting('portrait_settings_position', is_below)
if is_below:
%SwitchPortraitSettingsPosition.icon = get_theme_icon("ControlAlignRightWide", "EditorIcons")
else:
%SwitchPortraitSettingsPosition.icon = get_theme_icon("ControlAlignBottomWide", "EditorIcons")
#endregion
########## PORTRAIT SECTION ####################################################
#region Portrait Section
func setup_portrait_list_tab() -> void:
%PortraitTree.editor = self
## Portrait section styling/connections
%AddPortraitButton.icon = get_theme_icon("Add", "EditorIcons")
%AddPortraitButton.pressed.connect(add_portrait)
%AddPortraitGroupButton.icon = load("res://addons/dialogic/Editor/Images/Pieces/add-folder.svg")
%AddPortraitGroupButton.pressed.connect(add_portrait_group)
%ImportPortraitsButton.icon = get_theme_icon("Load", "EditorIcons")
%ImportPortraitsButton.pressed.connect(open_portrait_folder_select)
%PortraitSearch.right_icon = get_theme_icon("Search", "EditorIcons")
%PortraitSearch.text_changed.connect(filter_portrait_list)
%PortraitTree.item_selected.connect(load_selected_portrait)
%PortraitTree.item_edited.connect(_on_item_edited)
%PortraitTree.item_activated.connect(_on_item_activated)
func open_portrait_folder_select() -> void:
find_parent("EditorView").godot_file_dialog(
import_portraits_from_folder, "*.svg, *.png",
EditorFileDialog.FILE_MODE_OPEN_DIR)
func import_portraits_from_folder(path:String) -> void:
var parent: TreeItem = %PortraitTree.get_root()
if %PortraitTree.get_selected() and %PortraitTree.get_selected() != parent and %PortraitTree.get_selected().get_metadata(0).has('group'):
parent = %PortraitTree.get_selected()
var dir := DirAccess.open(path)
dir.list_dir_begin()
var file_name: String = dir.get_next()
var files := []
while file_name != "":
if not dir.current_is_dir():
var file_lower := file_name.to_lower()
if '.svg' in file_lower or '.png' in file_lower:
if not '.import' in file_lower:
files.append(file_name)
file_name = dir.get_next()
var prefix: String = files[0]
for file in files:
while true:
if file.begins_with(prefix):
break
if prefix.is_empty():
break
prefix = prefix.substr(0, len(prefix)-1)
for file in files:
%PortraitTree.add_portrait_item(file.trim_prefix(prefix).trim_suffix('.'+file.get_extension()),
{'scene':"",'export_overrides':{'image':var_to_str(path.path_join(file))}, 'scale':1, 'offset':Vector2(), 'mirror':false}, parent)
## Handle selection
if parent.get_child_count():
parent.get_first_child().select(0)
else:
# Call anyways to clear preview and hide portrait settings section
load_selected_portrait()
something_changed()
func add_portrait(portrait_name:String='New portrait', portrait_data:Dictionary={'scene':"", 'export_overrides':{'image':''}, 'scale':1, 'offset':Vector2(), 'mirror':false}) -> void:
var parent: TreeItem = %PortraitTree.get_root()
if %PortraitTree.get_selected():
if %PortraitTree.get_selected().get_metadata(0) and %PortraitTree.get_selected().get_metadata(0).has('group'):
parent = %PortraitTree.get_selected()
else:
parent = %PortraitTree.get_selected().get_parent()
var item: TreeItem = %PortraitTree.add_portrait_item(portrait_name, portrait_data, parent)
item.set_meta('new', true)
item.set_editable(0, true)
item.select(0)
%PortraitTree.call_deferred('edit_selected')
something_changed()
func add_portrait_group() -> void:
var parent_item: TreeItem = %PortraitTree.get_root()
if %PortraitTree.get_selected() and %PortraitTree.get_selected().get_metadata(0).has('group'):
parent_item = %PortraitTree.get_selected()
var item: TreeItem = %PortraitTree.add_portrait_group("Group", parent_item)
item.set_meta('new', true)
item.set_editable(0, true)
item.select(0)
%PortraitTree.call_deferred('edit_selected')
func load_portrait_tree() -> void:
%PortraitTree.clear_tree()
var root: TreeItem = %PortraitTree.create_item()
for portrait in current_resource.portraits.keys():
var portrait_label: String = portrait
var parent: TreeItem = %PortraitTree.get_root()
if '/' in portrait:
parent = %PortraitTree.create_necessary_group_items(portrait)
portrait_label = portrait.split('/')[-1]
%PortraitTree.add_portrait_item(portrait_label, current_resource.portraits[portrait], parent)
update_default_portrait_star(current_resource.default_portrait)
if root.get_child_count():
root.get_first_child().select(0)
while %PortraitTree.get_selected().get_child_count():
%PortraitTree.get_selected().get_child(0).select(0)
else:
# Call anyways to clear preview and hide portrait settings section
load_selected_portrait()
func filter_portrait_list(filter_term := "") -> void:
filter_branch(%PortraitTree.get_root(), filter_term)
func filter_branch(parent: TreeItem, filter_term: String) -> bool:
var anything_visible := false
for item in parent.get_children():
if item.get_metadata(0).has('group'):
item.visible = filter_branch(item, filter_term)
anything_visible = item.visible
elif filter_term.is_empty() or filter_term.to_lower() in item.get_text(0).to_lower():
item.visible = true
anything_visible = true
else:
item.visible = false
return anything_visible
## This is used to save the portrait data
func get_updated_portrait_dict() -> Dictionary:
return list_portraits(%PortraitTree.get_root().get_children())
func list_portraits(tree_items: Array[TreeItem], dict := {}, path_prefix := "") -> Dictionary:
for item in tree_items:
if item.get_metadata(0).has('group'):
dict = list_portraits(item.get_children(), dict, path_prefix+item.get_text(0)+"/")
else:
dict[path_prefix +item.get_text(0)] = item.get_metadata(0)
return dict
func load_selected_portrait() -> void:
if selected_item and is_instance_valid(selected_item):
selected_item.set_editable(0, false)
selected_item = %PortraitTree.get_selected()
if selected_item and selected_item.get_metadata(0) != null and !selected_item.get_metadata(0).has('group'):
%PortraitSettingsSection.show()
var current_portrait_data: Dictionary = selected_item.get_metadata(0)
portrait_selected.emit(%PortraitTree.get_full_item_name(selected_item), current_portrait_data)
update_preview()
for child in %PortraitSettingsSection.get_children():
if child is DialogicCharacterEditorPortraitSection:
child.selected_item = selected_item
child._load_portrait_data(current_portrait_data)
else:
%PortraitSettingsSection.hide()
update_preview()
func delete_portrait_item(item: TreeItem) -> void:
if item.get_next_visible(true) and item.get_next_visible(true) != item:
item.get_next_visible(true).select(0)
else:
selected_item = null
load_selected_portrait()
item.free()
something_changed()
func duplicate_item(item: TreeItem) -> void:
var new_item: TreeItem = %PortraitTree.add_portrait_item(item.get_text(0)+'_duplicated', item.get_metadata(0).duplicate(true), item.get_parent())
new_item.set_meta('new', true)
new_item.select(0)
func _input(event: InputEvent) -> void:
if !is_visible_in_tree() or (get_viewport().gui_get_focus_owner()!= null and !name+'/' in str(get_viewport().gui_get_focus_owner().get_path())):
return
if event is InputEventKey and event.pressed:
if event.keycode == KEY_F2 and %PortraitTree.get_selected():
%PortraitTree.get_selected().set_editable(0, true)
%PortraitTree.edit_selected()
get_viewport().set_input_as_handled()
elif event.keycode == KEY_DELETE and get_viewport().gui_get_focus_owner() is Tree and %PortraitTree.get_selected():
delete_portrait_item(%PortraitTree.get_selected())
get_viewport().set_input_as_handled()
func _on_portrait_right_click_menu_index_pressed(id: int) -> void:
# RENAME BUTTON
if id == 0:
_on_item_activated()
# DELETE BUTTON
if id == 2:
delete_portrait_item(%PortraitTree.get_selected())
# DUPLICATE ITEM
elif id == 1:
duplicate_item(%PortraitTree.get_selected())
elif id == 4:
get_settings_section_by_name("Portraits").set_default_portrait(%PortraitTree.get_full_item_name(%PortraitTree.get_selected()))
## This removes/and adds the DEFAULT star on the portrait list
func update_default_portrait_star(default_portrait_name: String) -> void:
var item_list: Array = %PortraitTree.get_root().get_children()
if item_list.is_empty() == false:
while true:
var item: TreeItem = item_list.pop_back()
if item.get_button_by_id(0, 2) != -1:
item.erase_button(0, item.get_button_by_id(0, 2))
if %PortraitTree.get_full_item_name(item) == default_portrait_name:
item.add_button(0, get_theme_icon("Favorites", "EditorIcons"), 2, true, "Default")
item_list.append_array(item.get_children())
if item_list.is_empty():
break
func _on_item_edited() -> void:
selected_item = %PortraitTree.get_selected()
something_changed()
if selected_item:
if %PreviewLabel.text.trim_prefix('Preview of "').trim_suffix('"') == current_resource.default_portrait:
current_resource.default_portrait = %PortraitTree.get_full_item_name(selected_item)
selected_item.set_editable(0, false)
if !selected_item.has_meta('new') and %PortraitTree.get_full_item_name(selected_item) != selected_item.get_meta('previous_name'):
report_name_change(selected_item)
%PortraitChangeInfo.show()
update_preview()
func _on_item_activated() -> void:
if %PortraitTree.get_selected() == null:
return
%PortraitTree.get_selected().set_editable(0, true)
%PortraitTree.edit_selected()
func report_name_change(item: TreeItem) -> void:
if item.get_metadata(0).has('group'):
for s_item in item.get_children():
if s_item.get_metadata(0).has('group') or !s_item.has_meta('new'):
report_name_change(s_item)
else:
if item.get_meta('previous_name') == %PortraitTree.get_full_item_name(item):
return
editors_manager.reference_manager.add_portrait_ref_change(
item.get_meta('previous_name'),
%PortraitTree.get_full_item_name(item),
[DialogicResourceUtil.get_unique_identifier(current_resource.resource_path)])
item.set_meta('previous_name', %PortraitTree.get_full_item_name(item))
%PortraitChangeInfo.show()
#endregion
########### PREVIEW ############################################################
#region Preview
func update_preview(force := false, ignore_settings_reload := false) -> void:
%ScenePreviewWarning.hide()
if selected_item and is_instance_valid(selected_item) and selected_item.get_metadata(0) != null and !selected_item.get_metadata(0).has('group'):
%PreviewLabel.text = 'Preview of "'+%PortraitTree.get_full_item_name(selected_item)+'"'
var current_portrait_data: Dictionary = selected_item.get_metadata(0)
if not force and current_previewed_scene != null \
and scene_file_path == current_portrait_data.get('scene') \
and current_previewed_scene.has_method('_should_do_portrait_update') \
and is_instance_valid(current_previewed_scene.get_script()) \
and current_previewed_scene._should_do_portrait_update(current_resource, selected_item.get_text(0)):
# We keep the same scene.
pass
else:
for node in %RealPreviewPivot.get_children():
node.queue_free()
current_previewed_scene = null
current_scene_path = ""
var scene_path := def_portrait_path
if not current_portrait_data.get('scene', '').is_empty():
scene_path = current_portrait_data.get('scene')
if ResourceLoader.exists(scene_path):
current_previewed_scene = load(scene_path).instantiate()
current_scene_path = scene_path
if not current_previewed_scene == null:
%RealPreviewPivot.add_child(current_previewed_scene)
if not current_previewed_scene == null:
var scene: Node = current_previewed_scene
scene.show_behind_parent = true
DialogicUtil.apply_scene_export_overrides(scene, current_portrait_data.get('export_overrides', {}))
var mirror: bool = current_portrait_data.get('mirror', false) != current_resource.mirror
var scale: float = current_portrait_data.get('scale', 1) * current_resource.scale
if current_portrait_data.get('ignore_char_scale', false):
scale = current_portrait_data.get('scale', 1)
var offset: Vector2 = current_portrait_data.get('offset', Vector2()) + current_resource.offset
if is_instance_valid(scene.get_script()) and scene.script.is_tool():
if scene.has_method('_update_portrait'):
## Create a fake duplicate resource that has all the portrait changes applied already
var preview_character := current_resource.duplicate()
preview_character.portraits = get_updated_portrait_dict()
scene._update_portrait(preview_character, %PortraitTree.get_full_item_name(selected_item))
if scene.has_method('_set_mirror'):
scene._set_mirror(mirror)
if !%FitPreview_Toggle.button_pressed:
scene.position = Vector2() + offset
scene.scale = Vector2(1,1)*scale
else:
if not scene.get_script() == null and scene.script.is_tool() and scene.has_method('_get_covered_rect'):
var rect: Rect2 = scene._get_covered_rect()
var available_rect: Rect2 = %FullPreviewAvailableRect.get_rect()
scene.scale = Vector2(1,1) * min(available_rect.size.x/rect.size.x, available_rect.size.y/rect.size.y)
%RealPreviewPivot.position = (rect.position)*-1*scene.scale
%RealPreviewPivot.position.x = %FullPreviewAvailableRect.size.x/2
scene.position = Vector2()
else:
%ScenePreviewWarning.show()
else:
%PreviewLabel.text = 'Nothing to preview'
if not ignore_settings_reload:
for child in %PortraitSettingsSection.get_children():
if child is DialogicCharacterEditorPortraitSection:
child._recheck(current_portrait_data)
else:
%PreviewLabel.text = 'No portrait to preview.'
for node in %RealPreviewPivot.get_children():
node.queue_free()
current_previewed_scene = null
current_scene_path = ""
func _on_some_resource_saved(file:Variant) -> void:
if current_previewed_scene == null:
return
if file is Resource and file == current_previewed_scene.script:
update_preview(true)
if typeof(file) == TYPE_STRING and file == current_previewed_scene.get_meta("path", ""):
update_preview(true)
func _on_full_preview_available_rect_resized() -> void:
if %FitPreview_Toggle.button_pressed:
update_preview(false, true)
func _on_create_character_button_pressed() -> void:
editors_manager.show_add_resource_dialog(
new_character,
'*.dch; DialogicCharacter',
'Create new character',
'character',
)
func _on_fit_preview_toggle_toggled(button_pressed):
%FitPreview_Toggle.set_pressed_no_signal(button_pressed)
if button_pressed:
%FitPreview_Toggle.icon = get_theme_icon("ScrollContainer", "EditorIcons")
%FitPreview_Toggle.tooltip_text = "Real scale"
else:
%FitPreview_Toggle.tooltip_text = "Fit into preview"
%FitPreview_Toggle.icon = get_theme_icon("CenterContainer", "EditorIcons")
DialogicUtil.set_editor_setting('character_preview_fit', button_pressed)
update_preview(false, true)
#endregion
## Open the reference manager
func _on_reference_manger_button_pressed() -> void:
editors_manager.reference_manager.open()
%PortraitChangeInfo.hide()
@@ -1,456 +0,0 @@
[gd_scene load_steps=11 format=3 uid="uid://dlskc36c5hrwv"]
[ext_resource type="Script" path="res://addons/dialogic/Editor/CharacterEditor/character_editor.gd" id="2"]
[ext_resource type="PackedScene" uid="uid://dbpkta2tjsqim" path="res://addons/dialogic/Editor/Common/hint_tooltip_icon.tscn" id="2_uhhqs"]
[ext_resource type="Script" path="res://addons/dialogic/Editor/CharacterEditor/character_editor_portrait_tree.gd" id="2_vad0i"]
[ext_resource type="Texture2D" uid="uid://babwe22dqjta" path="res://addons/dialogic/Editor/Images/Pieces/add-folder.svg" id="3_v1qnr"]
[sub_resource type="Image" id="Image_s4mcg"]
data = {
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
"format": "RGBA8",
"height": 16,
"mipmaps": false,
"width": 16
}
[sub_resource type="ImageTexture" id="ImageTexture_oab13"]
image = SubResource("Image_s4mcg")
[sub_resource type="Image" id="Image_fnxud"]
data = {
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
"format": "RGBA8",
"height": 16,
"mipmaps": false,
"width": 16
}
[sub_resource type="ImageTexture" id="ImageTexture_u1a6g"]
image = SubResource("Image_fnxud")
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_es2rd"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_4xgdx"]
[node name="CharacterEditor" type="Control"]
self_modulate = Color(0, 0, 0, 1)
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("2")
[node name="Scroll" type="ScrollContainer" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="VBox" type="VBoxContainer" parent="Scroll"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
size_flags_stretch_ratio = 0.3
theme_override_constants/separation = 0
[node name="TopSection" type="HBoxContainer" parent="Scroll/VBox"]
layout_mode = 2
[node name="NameContainer" type="HBoxContainer" parent="Scroll/VBox/TopSection"]
layout_mode = 2
[node name="CharacterName" type="Label" parent="Scroll/VBox/TopSection/NameContainer"]
unique_name_in_owner = true
layout_mode = 2
theme_type_variation = &"DialogicTitle"
text = "My Character"
[node name="NameTooltip" parent="Scroll/VBox/TopSection/NameContainer" instance=ExtResource("2_uhhqs")]
layout_mode = 2
tooltip_text = "This unique identifier is based on the file name. You can change it in the Reference Manager.
Use this name in timelines to reference this character."
texture = SubResource("ImageTexture_oab13")
hint_text = "This unique identifier is based on the file name. You can change it in the Reference Manager.
Use this name in timelines to reference this character."
[node name="MainSettingsCollapse" type="Button" parent="Scroll/VBox/TopSection"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 10
size_flags_vertical = 4
toggle_mode = true
text = "Main Settings"
icon = SubResource("ImageTexture_u1a6g")
[node name="MainHSplit" type="HSplitContainer" parent="Scroll/VBox"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="MainSettings" type="VBoxContainer" parent="Scroll/VBox/MainHSplit"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_stretch_ratio = 0.2
[node name="MainSettingsTitle" type="Label" parent="Scroll/VBox/MainHSplit/MainSettings"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme_type_variation = &"DialogicSubTitle"
text = "Main Settings"
[node name="MainSettingsScroll" type="ScrollContainer" parent="Scroll/VBox/MainHSplit/MainSettings"]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 3
theme_override_styles/panel = SubResource("StyleBoxEmpty_es2rd")
horizontal_scroll_mode = 0
[node name="MainSettingsSections" type="VBoxContainer" parent="Scroll/VBox/MainHSplit/MainSettings/MainSettingsScroll"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="Split" type="HSplitContainer" parent="Scroll/VBox/MainHSplit"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="HBoxContainer" type="HBoxContainer" parent="Scroll/VBox/MainHSplit/Split"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_stretch_ratio = 0.2
theme_override_constants/separation = 0
[node name="MarginContainer" type="MarginContainer" parent="Scroll/VBox/MainHSplit/Split/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_stretch_ratio = 0.2
theme_override_constants/margin_bottom = 10
[node name="PortraitListSection" type="PanelContainer" parent="Scroll/VBox/MainHSplit/Split/HBoxContainer/MarginContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme_type_variation = &"DialogicPanelA"
[node name="Portraits" type="VBoxContainer" parent="Scroll/VBox/MainHSplit/Split/HBoxContainer/MarginContainer/PortraitListSection"]
layout_mode = 2
[node name="PortraitsTitle" type="Label" parent="Scroll/VBox/MainHSplit/Split/HBoxContainer/MarginContainer/PortraitListSection/Portraits"]
layout_mode = 2
theme_type_variation = &"DialogicSubTitle"
text = "Portraits"
[node name="PortraitListTools" type="HBoxContainer" parent="Scroll/VBox/MainHSplit/Split/HBoxContainer/MarginContainer/PortraitListSection/Portraits"]
layout_mode = 2
[node name="AddPortraitButton" type="Button" parent="Scroll/VBox/MainHSplit/Split/HBoxContainer/MarginContainer/PortraitListSection/Portraits/PortraitListTools"]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "Add portrait"
icon = SubResource("ImageTexture_u1a6g")
[node name="AddPortraitGroupButton" type="Button" parent="Scroll/VBox/MainHSplit/Split/HBoxContainer/MarginContainer/PortraitListSection/Portraits/PortraitListTools"]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "Add Group"
icon = ExtResource("3_v1qnr")
[node name="ImportPortraitsButton" type="Button" parent="Scroll/VBox/MainHSplit/Split/HBoxContainer/MarginContainer/PortraitListSection/Portraits/PortraitListTools"]
unique_name_in_owner = true
layout_mode = 2
tooltip_text = "Import images from folder"
icon = SubResource("ImageTexture_u1a6g")
[node name="PortraitSearch" type="LineEdit" parent="Scroll/VBox/MainHSplit/Split/HBoxContainer/MarginContainer/PortraitListSection/Portraits/PortraitListTools"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 4
placeholder_text = "Search"
expand_to_text_length = true
clear_button_enabled = true
right_icon = SubResource("ImageTexture_u1a6g")
caret_blink = true
caret_blink_interval = 0.5
[node name="PortraitTreePanel" type="PanelContainer" parent="Scroll/VBox/MainHSplit/Split/HBoxContainer/MarginContainer/PortraitListSection/Portraits"]
layout_mode = 2
size_flags_vertical = 3
theme_override_styles/panel = SubResource("StyleBoxEmpty_4xgdx")
[node name="PortraitTree" type="Tree" parent="Scroll/VBox/MainHSplit/Split/HBoxContainer/MarginContainer/PortraitListSection/Portraits/PortraitTreePanel"]
unique_name_in_owner = true
layout_mode = 2
allow_rmb_select = true
hide_root = true
drop_mode_flags = 3
script = ExtResource("2_vad0i")
[node name="PortraitRightClickMenu" type="PopupMenu" parent="Scroll/VBox/MainHSplit/Split/HBoxContainer/MarginContainer/PortraitListSection/Portraits/PortraitTreePanel/PortraitTree"]
size = Vector2i(118, 100)
item_count = 5
item_0/text = "Rename"
item_0/icon = SubResource("ImageTexture_oab13")
item_0/id = 2
item_1/text = "Duplicate"
item_1/icon = SubResource("ImageTexture_oab13")
item_1/id = 0
item_2/text = "Delete"
item_2/icon = SubResource("ImageTexture_oab13")
item_2/id = 1
item_3/text = ""
item_3/id = 3
item_3/separator = true
item_4/text = "Make Default"
item_4/icon = SubResource("ImageTexture_oab13")
item_4/id = 4
[node name="PortraitChangeInfo" type="HBoxContainer" parent="Scroll/VBox/MainHSplit/Split/HBoxContainer/MarginContainer/PortraitListSection/Portraits"]
unique_name_in_owner = true
layout_mode = 2
[node name="PortraitChangeWarning" type="Label" parent="Scroll/VBox/MainHSplit/Split/HBoxContainer/MarginContainer/PortraitListSection/Portraits/PortraitChangeInfo"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme_override_colors/font_color = Color(0, 0, 0, 1)
text = "Some portraits were renamed. Make sure no references broke!"
autowrap_mode = 3
[node name="ReferenceMangerButton" type="Button" parent="Scroll/VBox/MainHSplit/Split/HBoxContainer/MarginContainer/PortraitListSection/Portraits/PortraitChangeInfo"]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 4
text = "Reference
Manager"
[node name="RightSection2" type="VBoxContainer" parent="Scroll/VBox/MainHSplit/Split"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
size_flags_stretch_ratio = 0.5
[node name="Spacer" type="Control" parent="Scroll/VBox/MainHSplit/Split/RightSection2"]
custom_minimum_size = Vector2(0, 10)
layout_mode = 2
[node name="RightSection" type="SplitContainer" parent="Scroll/VBox/MainHSplit/Split/RightSection2"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
size_flags_stretch_ratio = 0.5
vertical = true
[node name="PortraitPreviewSection" type="Panel" parent="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection"]
unique_name_in_owner = true
show_behind_parent = true
custom_minimum_size = Vector2(100, 0)
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
theme_type_variation = &"DialogicPanelB"
[node name="ClipRect" type="Control" parent="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/PortraitPreviewSection"]
clip_contents = true
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="Node2D" type="Node2D" parent="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/PortraitPreviewSection/ClipRect"]
position = Vector2(13, 17)
[node name="RealPreviewPivot" type="Sprite2D" parent="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/PortraitPreviewSection/ClipRect/Node2D"]
unique_name_in_owner = true
position = Vector2(326.5, 267)
texture = SubResource("ImageTexture_u1a6g")
[node name="ScenePreviewWarning" type="Label" parent="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/PortraitPreviewSection"]
unique_name_in_owner = true
visible = false
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -143.0
offset_top = -44.5
offset_right = 143.0
offset_bottom = 85.5
grow_horizontal = 2
grow_vertical = 2
text = "Custom scenes can only be viewed in \"Full mode\" if they are in @tool mode and override _get_covered_rect"
horizontal_alignment = 1
vertical_alignment = 1
autowrap_mode = 3
metadata/_edit_layout_mode = 1
[node name="PreviewReal" type="CenterContainer" parent="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/PortraitPreviewSection"]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 7
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = -302.0
offset_top = -80.0
offset_right = 302.0
grow_horizontal = 2
grow_vertical = 0
mouse_filter = 2
metadata/_edit_layout_mode = 1
[node name="Control" type="Control" parent="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/PortraitPreviewSection/PreviewReal"]
layout_mode = 2
[node name="RealSizeRemotePivotTransform" type="RemoteTransform2D" parent="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/PortraitPreviewSection/PreviewReal/Control"]
unique_name_in_owner = true
remote_path = NodePath("../../../ClipRect/Node2D/RealPreviewPivot")
update_rotation = false
update_scale = false
[node name="FullPreviewAvailableRect" type="Control" parent="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/PortraitPreviewSection"]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 10.0
offset_top = 28.0
offset_right = -10.0
offset_bottom = -16.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
metadata/_edit_layout_mode = 1
[node name="HBoxContainer" type="HBoxContainer" parent="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/PortraitPreviewSection"]
layout_mode = 1
anchors_preset = 10
anchor_right = 1.0
offset_left = 6.0
offset_top = 7.0
offset_right = -6.0
offset_bottom = 43.0
grow_horizontal = 2
mouse_filter = 2
[node name="PreviewLabel" type="Label" parent="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/PortraitPreviewSection/HBoxContainer"]
unique_name_in_owner = true
show_behind_parent = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 0
theme_override_colors/font_color = Color(0, 0, 0, 1)
text = "No portrait to preview."
text_overrun_behavior = 1
[node name="FitPreview_Toggle" type="Button" parent="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/PortraitPreviewSection/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 0
tooltip_text = "Real scale"
focus_mode = 0
toggle_mode = true
button_pressed = true
icon = SubResource("ImageTexture_u1a6g")
flat = true
metadata/_edit_layout_mode = 1
[node name="VBox" type="VBoxContainer" parent="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
size_flags_stretch_ratio = 0.75
[node name="Hbox" type="HBoxContainer" parent="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/VBox"]
layout_mode = 2
[node name="PortraitSettingsTitle" type="Label" parent="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/VBox/Hbox"]
unique_name_in_owner = true
layout_mode = 2
theme_type_variation = &"DialogicSubTitle"
text = "Portrait Settings"
[node name="SwitchPortraitSettingsPosition" type="Button" parent="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/VBox/Hbox"]
unique_name_in_owner = true
modulate = Color(1, 1, 1, 0.647059)
layout_mode = 2
tooltip_text = "Switch position"
focus_mode = 0
icon = SubResource("ImageTexture_u1a6g")
flat = true
[node name="Scroll" type="ScrollContainer" parent="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/VBox"]
layout_mode = 2
size_flags_vertical = 3
size_flags_stretch_ratio = 0.4
[node name="PortraitSettingsSection" type="VBoxContainer" parent="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/VBox/Scroll"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
size_flags_stretch_ratio = 0.3
[node name="Spacer2" type="Control" parent="Scroll/VBox/MainHSplit/Split/RightSection2"]
custom_minimum_size = Vector2(0, 20)
layout_mode = 2
[node name="NoCharacterScreen" type="ColorRect" parent="."]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
color = Color(0, 0, 0, 1)
[node name="CenterContainer" type="CenterContainer" parent="NoCharacterScreen"]
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="NoCharacterScreen/CenterContainer"]
custom_minimum_size = Vector2(250, 0)
layout_mode = 2
[node name="Label" type="Label" parent="NoCharacterScreen/CenterContainer/VBoxContainer"]
layout_mode = 2
text = "No character opened.
Create a character or double-click one in the file system dock."
horizontal_alignment = 1
autowrap_mode = 3
[node name="CreateCharacterButton" type="Button" parent="NoCharacterScreen/CenterContainer/VBoxContainer"]
layout_mode = 2
text = "Create New Character"
[connection signal="toggled" from="Scroll/VBox/TopSection/MainSettingsCollapse" to="." method="_on_main_settings_collapse_toggled"]
[connection signal="item_mouse_selected" from="Scroll/VBox/MainHSplit/Split/HBoxContainer/MarginContainer/PortraitListSection/Portraits/PortraitTreePanel/PortraitTree" to="Scroll/VBox/MainHSplit/Split/HBoxContainer/MarginContainer/PortraitListSection/Portraits/PortraitTreePanel/PortraitTree" method="_on_item_mouse_selected"]
[connection signal="index_pressed" from="Scroll/VBox/MainHSplit/Split/HBoxContainer/MarginContainer/PortraitListSection/Portraits/PortraitTreePanel/PortraitTree/PortraitRightClickMenu" to="." method="_on_portrait_right_click_menu_index_pressed"]
[connection signal="pressed" from="Scroll/VBox/MainHSplit/Split/HBoxContainer/MarginContainer/PortraitListSection/Portraits/PortraitChangeInfo/ReferenceMangerButton" to="." method="_on_reference_manger_button_pressed"]
[connection signal="resized" from="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/PortraitPreviewSection/FullPreviewAvailableRect" to="." method="_on_full_preview_available_rect_resized"]
[connection signal="toggled" from="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/PortraitPreviewSection/HBoxContainer/FitPreview_Toggle" to="." method="_on_fit_preview_toggle_toggled"]
[connection signal="pressed" from="Scroll/VBox/MainHSplit/Split/RightSection2/RightSection/VBox/Hbox/SwitchPortraitSettingsPosition" to="." method="_on_switch_portrait_settings_position_pressed"]
[connection signal="pressed" from="NoCharacterScreen/CenterContainer/VBoxContainer/CreateCharacterButton" to="." method="_on_create_character_button_pressed"]
@@ -1,41 +0,0 @@
@tool
class_name DialogicCharacterEditorMainSection
extends Control
## Base class for all character editor main sections. Methods should be overriden.
## Emit this, if something changed
signal changed
## Reference to the character editor, set when instantiated
var character_editor: Control
## If not empty, a hint icon is added to the section title.
var hint_text := ""
## Overwrite to set the title of this section
func _get_title() -> String:
return "MainSection"
## Overwrite to set the visibility of the section title
func _show_title() -> bool:
return true
## Overwrite to set whether this should initially be opened.
func _start_opened() -> bool:
return false
## Overwrite to load all the information from the character into this section.
func _load_character(resource:DialogicCharacter) -> void:
pass
## Overwrite to save all changes made in this section to the resource.
## In custom sections you will mostly likely save to the [resource.custom_info]
## dictionary.
func _save_changes(resource:DialogicCharacter) -> DialogicCharacter:
return resource
@@ -1,48 +0,0 @@
@tool
class_name DialogicCharacterEditorPortraitSection
extends Control
## Base class for all portrait settings sections. Methods should be overriden.
## Changes made through fields in such a section should instantly be "saved"
## to the portrait_items metadata from where they will be saved to the resource.
## Emit this, if something changed
signal changed
## Emit this if the preview should reload
signal update_preview
## Reference to the character editor, set when instantiated
var character_editor: Control
## Reference to the selected portrait item.
## `selected_item.get_metadata(0)` can access the portraits data
var selected_item: TreeItem = null
## If not empty a hint icon is added to the section title
var hint_text := ""
## Overwrite to set the title of this section
func _get_title() -> String:
return "CustomSection"
## Overwrite to set the visibility of the section title
func _show_title() -> bool:
return true
## Overwrite to set whether this should initially be opened.
func _start_opened() -> bool:
return false
## Overwrite to load all the information from the character into this section.
func _load_portrait_data(data:Dictionary) -> void:
pass
## Overwrite to recheck visibility of your section and the content of your fields.
## This is called whenever the preview is updated so it allows reacting to major
## changes in other portrait sections.
func _recheck(data:Dictionary) -> void:
pass
@@ -1,142 +0,0 @@
@tool
extends Tree
## Tree that displays the portrait list as a hirarchy
var editor := find_parent('Character Editor')
var current_group_nodes := {}
func _ready() -> void:
$PortraitRightClickMenu.set_item_icon(0, get_theme_icon('Rename', 'EditorIcons'))
$PortraitRightClickMenu.set_item_icon(1, get_theme_icon('Duplicate', 'EditorIcons'))
$PortraitRightClickMenu.set_item_icon(2, get_theme_icon('Remove', 'EditorIcons'))
$PortraitRightClickMenu.set_item_icon(4, get_theme_icon("Favorites", "EditorIcons"))
func clear_tree() -> void:
clear()
current_group_nodes = {}
func add_portrait_item(portrait_name: String, portrait_data: Dictionary, parent_item: TreeItem, previous_name := "") -> TreeItem:
var item: TreeItem = %PortraitTree.create_item(parent_item)
item.set_text(0, portrait_name)
item.set_metadata(0, portrait_data)
if previous_name.is_empty():
item.set_meta('previous_name', get_full_item_name(item))
else:
item.set_meta('previous_name', previous_name)
if portrait_name == editor.current_resource.default_portrait:
item.add_button(0, get_theme_icon('Favorites', 'EditorIcons'), 2, true, 'Default')
return item
func add_portrait_group(goup_name := "Group", parent_item: TreeItem = get_root(), previous_name := "") -> TreeItem:
var item: TreeItem = %PortraitTree.create_item(parent_item)
item.set_icon(0, get_theme_icon("Folder", "EditorIcons"))
item.set_text(0, goup_name)
item.set_metadata(0, {'group':true})
if previous_name.is_empty():
item.set_meta('previous_name', get_full_item_name(item))
else:
item.set_meta('previous_name', previous_name)
return item
func get_full_item_name(item: TreeItem) -> String:
var item_name := item.get_text(0)
while item.get_parent() != get_root() and item != get_root():
item_name = item.get_parent().get_text(0)+"/"+item_name
item = item.get_parent()
return item_name
## Will create all not yet existing folders in the given path.
## Returns the last folder (the parent of the portrait item of this path).
func create_necessary_group_items(path: String) -> TreeItem:
var last_item := get_root()
var item_path := ""
for i in Array(path.split('/')).slice(0, -1):
item_path += "/"+i
item_path = item_path.trim_prefix('/')
if current_group_nodes.has(item_path+"/"+i):
last_item = current_group_nodes[item_path+"/"+i]
else:
var new_item: TreeItem = add_portrait_group(i, last_item)
current_group_nodes[item_path+"/"+i] = new_item
last_item = new_item
return last_item
func _on_item_mouse_selected(pos: Vector2, mouse_button_index: int) -> void:
if mouse_button_index == MOUSE_BUTTON_RIGHT:
$PortraitRightClickMenu.set_item_disabled(1, get_selected().get_metadata(0).has('group'))
$PortraitRightClickMenu.popup_on_parent(Rect2(get_global_mouse_position(),Vector2()))
################################################################################
## DRAG AND DROP
################################################################################
func _get_drag_data(at_position: Vector2) -> Variant:
var drag_item := get_item_at_position(at_position)
if not drag_item:
return null
drop_mode_flags = DROP_MODE_INBETWEEN
var preview := Label.new()
preview.text = " "+drag_item.get_text(0)
preview.add_theme_stylebox_override('normal', get_theme_stylebox("Background", "EditorStyles"))
set_drag_preview(preview)
return drag_item
func _can_drop_data(_at_position: Vector2, data: Variant) -> bool:
return data is TreeItem
func _drop_data(at_position: Vector2, item: Variant) -> void:
var to_item := get_item_at_position(at_position)
if to_item:
var test_item := to_item
while true:
if test_item == item:
return
test_item = test_item.get_parent()
if test_item == get_root():
break
var drop_section := get_drop_section_at_position(at_position)
var parent := get_root()
if to_item:
parent = to_item.get_parent()
if to_item and to_item.get_metadata(0).has('group') and drop_section == 1:
parent = to_item
var new_item := copy_branch_or_item(item, parent)
if to_item and !to_item.get_metadata(0).has('group') and drop_section == 1:
new_item.move_after(to_item)
if drop_section == -1:
new_item.move_before(to_item)
editor.report_name_change(new_item)
item.free()
func copy_branch_or_item(item: TreeItem, new_parent: TreeItem) -> TreeItem:
var new_item: TreeItem = null
if item.get_metadata(0).has('group'):
new_item = add_portrait_group(item.get_text(0), new_parent, item.get_meta('previous_name'))
else:
new_item = add_portrait_item(item.get_text(0), item.get_metadata(0), new_parent, item.get_meta('previous_name'))
for child in item.get_children():
copy_branch_or_item(child, new_item)
return new_item
@@ -1,126 +0,0 @@
@tool
extends Control
var ListItem := load("res://addons/dialogic/Editor/Common/BrowserItem.tscn")
enum Types {ALL, GENERAL, PRESET}
var current_type := Types.ALL
var current_info := {}
var portrait_scenes_info := {}
signal activate_part(part_info:Dictionary)
func _ready() -> void:
collect_portrait_scenes()
%Search.right_icon = get_theme_icon("Search", "EditorIcons")
%CloseButton.icon = get_theme_icon("Close", "EditorIcons")
get_parent().close_requested.connect(_on_close_button_pressed)
get_parent().visibility_changed.connect(func():if get_parent().visible: open())
func collect_portrait_scenes() -> void:
for indexer in DialogicUtil.get_indexers():
for element in indexer._get_portrait_scene_presets():
portrait_scenes_info[element.get('path', '')] = element
func open() -> void:
collect_portrait_scenes()
load_parts()
func is_premade_portrait_scene(scene_path:String) -> bool:
return scene_path in portrait_scenes_info
func load_parts() -> void:
for i in %PartGrid.get_children():
i.queue_free()
%Search.placeholder_text = "Search for "
%Search.text = ""
match current_type:
Types.GENERAL: %Search.placeholder_text += "general portrait scenes"
Types.PRESET: %Search.placeholder_text += "portrait scene presets"
Types.ALL: %Search.placeholder_text += "general portrait scenes and presets"
for info in portrait_scenes_info.values():
var type: String = info.get('type', '_')
if (current_type == Types.GENERAL and type != "General") or (current_type == Types.PRESET and type != "Preset"):
continue
var item: Node = ListItem.instantiate()
item.load_info(info)
%PartGrid.add_child(item)
item.set_meta('info', info)
item.clicked.connect(_on_item_clicked.bind(item, info))
item.focused.connect(_on_item_clicked.bind(item, info))
item.double_clicked.connect(emit_signal.bind('activate_part', info))
await get_tree().process_frame
if %PartGrid.get_child_count() > 0:
%PartGrid.get_child(0).clicked.emit()
%PartGrid.get_child(0).grab_focus()
func _on_item_clicked(item: Node, info:Dictionary) -> void:
load_part_info(info)
func load_part_info(info:Dictionary) -> void:
current_info = info
%PartTitle.text = info.get('name', 'Unknown Part')
%PartAuthor.text = "by "+info.get('author', 'Anonymus')
%PartDescription.text = info.get('description', '')
if info.get('preview_image', null) and ResourceLoader.exists(info.preview_image[0]):
%PreviewImage.texture = load(info.preview_image[0])
%PreviewImage.show()
else:
%PreviewImage.hide()
match info.type:
"General":
%ActivateButton.text = "Use this scene"
%TypeDescription.text = "This is a general use scene, it can be used directly."
"Preset":
%ActivateButton.text = "Customize this scene"
%TypeDescription.text = "This is a preset you can use for a custom portrait scene. Dialogic will promt you to save a copy of this scene that you can then use and customize."
"Default":
%ActivateButton.text = "Use default scene"
%TypeDescription.text = ""
"Custom":
%ActivateButton.text = "Select a custom scene"
%TypeDescription.text = ""
if info.get("documentation", ""):
%DocumentationButton.show()
%DocumentationButton.uri = info.documentation
else:
%DocumentationButton.hide()
func _on_activate_button_pressed() -> void:
activate_part.emit(current_info)
func _on_close_button_pressed() -> void:
get_parent().hide()
func _on_search_text_changed(new_text: String) -> void:
for item in %PartGrid.get_children():
if new_text.is_empty():
item.show()
continue
if new_text.to_lower() in item.get_meta('info').name.to_lower():
item.show()
continue
item.hide()
@@ -1,260 +0,0 @@
[gd_scene load_steps=11 format=3 uid="uid://b1wn8r84uh11b"]
[ext_resource type="Script" path="res://addons/dialogic/Editor/CharacterEditor/portrait_scene_browser.gd" id="1_an6nc"]
[sub_resource type="Gradient" id="Gradient_0o1u0"]
colors = PackedColorArray(0.100572, 0.303996, 0.476999, 1, 0.296448, 0.231485, 0.52887, 1)
[sub_resource type="GradientTexture2D" id="GradientTexture2D_gxpvv"]
gradient = SubResource("Gradient_0o1u0")
fill = 2
fill_from = Vector2(0.478632, 1)
fill_to = Vector2(0, 0)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_we8bq"]
content_margin_left = 6.0
content_margin_top = 3.0
content_margin_right = 6.0
content_margin_bottom = 3.0
draw_center = false
border_width_left = 2
border_width_top = 2
border_width_right = 2
border_width_bottom = 2
border_color = Color(1, 1, 1, 0.615686)
corner_radius_top_left = 5
corner_radius_top_right = 5
corner_radius_bottom_right = 5
corner_radius_bottom_left = 5
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_3x0xw"]
content_margin_left = 6.0
content_margin_top = 3.0
content_margin_right = 6.0
content_margin_bottom = 3.0
draw_center = false
border_width_left = 3
border_width_top = 3
border_width_right = 3
border_width_bottom = 3
border_color = Color(1, 1, 1, 1)
corner_radius_top_left = 5
corner_radius_top_right = 5
corner_radius_bottom_right = 5
corner_radius_bottom_left = 5
expand_margin_left = 2.0
expand_margin_top = 2.0
expand_margin_right = 2.0
expand_margin_bottom = 2.0
[sub_resource type="Image" id="Image_lwe0k"]
data = {
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 94, 94, 127, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 231, 255, 94, 94, 54, 255, 94, 94, 57, 255, 93, 93, 233, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 93, 93, 41, 255, 255, 255, 0, 255, 255, 255, 0, 255, 97, 97, 42, 255, 93, 93, 233, 255, 93, 93, 232, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 44, 255, 255, 255, 0, 255, 97, 97, 42, 255, 97, 97, 42, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 96, 96, 45, 255, 93, 93, 235, 255, 94, 94, 234, 255, 95, 95, 43, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 93, 93, 235, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 233, 255, 95, 95, 59, 255, 96, 96, 61, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 93, 93, 255, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0),
"format": "RGBA8",
"height": 16,
"mipmaps": false,
"width": 16
}
[sub_resource type="ImageTexture" id="ImageTexture_d2gam"]
image = SubResource("Image_lwe0k")
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_lf1ht"]
bg_color = Color(0.0588235, 0.0313726, 0.0980392, 1)
border_width_left = 5
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_a5iyu"]
bg_color = Color(1, 1, 1, 1)
draw_center = false
corner_radius_top_left = 10
corner_radius_top_right = 10
corner_radius_bottom_right = 10
corner_radius_bottom_left = 10
shadow_color = Color(0.992157, 0.992157, 0.992157, 0.101961)
shadow_size = 10
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_htwsp"]
bg_color = Color(1, 1, 1, 1)
corner_radius_top_left = 10
corner_radius_top_right = 10
corner_radius_bottom_right = 10
corner_radius_bottom_left = 10
[node name="PortraitSceneBrowser" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_an6nc")
[node name="BGColor" type="TextureRect" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
texture = SubResource("GradientTexture2D_gxpvv")
[node name="HSplitContainer" type="HSplitContainer" parent="."]
clip_contents = true
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_vertical = 3
[node name="Margin" type="MarginContainer" parent="HSplitContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_stretch_ratio = 1.5
theme_override_constants/margin_left = 10
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
[node name="VBox" type="VBoxContainer" parent="HSplitContainer/Margin"]
layout_mode = 2
size_flags_horizontal = 3
[node name="BrowserTitle" type="Label" parent="HSplitContainer/Margin/VBox"]
layout_mode = 2
theme_type_variation = &"DialogicSubTitle"
theme_override_font_sizes/font_size = 25
text = "Dialogic Portrait Scene Browser"
[node name="HBox" type="HBoxContainer" parent="HSplitContainer/Margin/VBox"]
layout_mode = 2
[node name="Search" type="LineEdit" parent="HSplitContainer/Margin/VBox/HBox"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme_override_styles/normal = SubResource("StyleBoxFlat_we8bq")
theme_override_styles/focus = SubResource("StyleBoxFlat_3x0xw")
placeholder_text = "Search"
right_icon = SubResource("ImageTexture_d2gam")
[node name="ScrollContainer" type="ScrollContainer" parent="HSplitContainer/Margin/VBox"]
layout_mode = 2
size_flags_vertical = 3
[node name="PartGrid" type="HFlowContainer" parent="HSplitContainer/Margin/VBox/ScrollContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="Buttons" type="HBoxContainer" parent="HSplitContainer/Margin/VBox"]
layout_mode = 2
alignment = 1
[node name="CloseButton" type="Button" parent="HSplitContainer/Margin/VBox/Buttons"]
unique_name_in_owner = true
layout_mode = 2
text = "Close"
icon = SubResource("ImageTexture_d2gam")
[node name="PanelContainer" type="PanelContainer" parent="HSplitContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_styles/panel = SubResource("StyleBoxFlat_lf1ht")
[node name="Control" type="Control" parent="HSplitContainer/PanelContainer"]
layout_mode = 2
[node name="Panel" type="Panel" parent="HSplitContainer/PanelContainer/Control"]
layout_mode = 1
anchors_preset = 9
anchor_bottom = 1.0
offset_left = -4.0
offset_right = 40.0
offset_bottom = 71.0
grow_vertical = 2
rotation = 0.0349066
theme_override_styles/panel = SubResource("StyleBoxFlat_lf1ht")
[node name="MarginContainer" type="MarginContainer" parent="HSplitContainer/PanelContainer"]
layout_mode = 2
theme_override_constants/margin_left = 5
theme_override_constants/margin_top = 10
theme_override_constants/margin_right = 10
theme_override_constants/margin_bottom = 10
[node name="VBox" type="VBoxContainer" parent="HSplitContainer/PanelContainer/MarginContainer"]
layout_mode = 2
alignment = 1
[node name="Panel" type="PanelContainer" parent="HSplitContainer/PanelContainer/MarginContainer/VBox"]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_a5iyu")
[node name="Panel" type="PanelContainer" parent="HSplitContainer/PanelContainer/MarginContainer/VBox/Panel"]
clip_children = 1
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_htwsp")
[node name="PreviewImage" type="TextureRect" parent="HSplitContainer/PanelContainer/MarginContainer/VBox/Panel/Panel"]
unique_name_in_owner = true
layout_mode = 2
expand_mode = 5
stretch_mode = 6
[node name="HFlowContainer" type="HFlowContainer" parent="HSplitContainer/PanelContainer/MarginContainer/VBox"]
layout_mode = 2
[node name="PartTitle" type="Label" parent="HSplitContainer/PanelContainer/MarginContainer/VBox/HFlowContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 8
theme_type_variation = &"DialogicTitle"
text = "Cool Style Part"
[node name="PartAuthor" type="Label" parent="HSplitContainer/PanelContainer/MarginContainer/VBox/HFlowContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 8
theme_type_variation = &"DialogicHintText"
text = "by Jowan"
[node name="PartType" type="Label" parent="HSplitContainer/PanelContainer/MarginContainer/VBox/HFlowContainer"]
visible = false
layout_mode = 2
size_flags_vertical = 8
theme_type_variation = &"DialogicHintText"
text = "a style"
[node name="PartDescription" type="Label" parent="HSplitContainer/PanelContainer/MarginContainer/VBox"]
unique_name_in_owner = true
layout_mode = 2
theme_type_variation = &"DialogicHintText2"
text = "A cool textbox layer"
autowrap_mode = 3
[node name="DocumentationButton" type="LinkButton" parent="HSplitContainer/PanelContainer/MarginContainer/VBox"]
unique_name_in_owner = true
layout_mode = 2
text = "Learn more"
[node name="HSeparator" type="HSeparator" parent="HSplitContainer/PanelContainer/MarginContainer/VBox"]
layout_mode = 2
[node name="ActivateButton" type="Button" parent="HSplitContainer/PanelContainer/MarginContainer/VBox"]
unique_name_in_owner = true
layout_mode = 2
text = "Use"
[node name="TypeDescription" type="Label" parent="HSplitContainer/PanelContainer/MarginContainer/VBox"]
unique_name_in_owner = true
layout_mode = 2
theme_type_variation = &"DialogicHintText"
text = "A cool textbox layer"
autowrap_mode = 3
[connection signal="text_changed" from="HSplitContainer/Margin/VBox/HBox/Search" to="." method="_on_search_text_changed"]
[connection signal="pressed" from="HSplitContainer/Margin/VBox/Buttons/CloseButton" to="." method="_on_close_button_pressed"]
[connection signal="pressed" from="HSplitContainer/PanelContainer/MarginContainer/VBox/ActivateButton" to="." method="_on_activate_button_pressed"]
@@ -1,86 +0,0 @@
@tool
extends Container
signal clicked
signal middle_clicked
signal double_clicked
signal focused
var base_size := 1
func _ready() -> void:
if get_parent() is SubViewport:
return
%Name.add_theme_font_override("font", get_theme_font("bold", "EditorFonts"))
custom_minimum_size = base_size * Vector2(200, 150) * DialogicUtil.get_editor_scale()
%CurrentIcon.texture = get_theme_icon("Favorites", "EditorIcons")
if %Image.texture == null:
%Image.texture = get_theme_icon("ImportFail", "EditorIcons")
%Image.stretch_mode = TextureRect.STRETCH_KEEP_CENTERED
func load_info(info:Dictionary) -> void:
%Name.text = info.name
if not info.has("preview_image"):
pass
elif info.preview_image[0] == 'custom':
await ready
%Image.texture = get_theme_icon("CreateNewSceneFrom", "EditorIcons")
%Image.stretch_mode = TextureRect.STRETCH_KEEP_CENTERED
%Panel.self_modulate = get_theme_color("property_color_z", "Editor")
elif info.preview_image[0].ends_with('scn'):
DialogicUtil.get_dialogic_plugin().get_editor_interface().get_resource_previewer().queue_resource_preview(info.preview_image[0], self, 'set_scene_preview', null)
elif ResourceLoader.exists(info.preview_image[0]):
%Image.texture = load(info.preview_image[0])
elif info.preview_image[0].is_valid_html_color():
%Image.texture = null
%Panel.self_modulate = Color(info.preview_image[0])
if ResourceLoader.exists(info.get('icon', '')):
%Icon.get_parent().show()
%Icon.texture = load(info.get('icon'))
else:
%Icon.get_parent().hide()
tooltip_text = info.description
func set_scene_preview(path:String, preview:Texture2D, thumbnail:Texture2D, userdata:Variant) -> void:
if preview:
%Image.texture = preview
else:
%Image.texture = get_theme_icon("PackedScene", "EditorIcons")
func set_current(current:bool):
%CurrentIcon.visible = current
func _on_mouse_entered() -> void:
%HoverBG.show()
func _on_mouse_exited() -> void:
%HoverBG.hide()
func _on_gui_input(event):
if event.is_action_pressed('ui_accept') or event.is_action_pressed("ui_select") or (
event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT):
clicked.emit()
if not event is InputEventMouseButton or event.double_click:
double_clicked.emit()
elif event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_MIDDLE:
middle_clicked.emit()
func _on_focus_entered() -> void:
$FocusFG.show()
focused.emit()
func _on_focus_exited() -> void:
$FocusFG.hide()
@@ -1,154 +0,0 @@
[gd_scene load_steps=6 format=3 uid="uid://ddlxjde1cx035"]
[ext_resource type="Script" path="res://addons/dialogic/Editor/Common/BrowserItem.gd" id="1_s3kf0"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_pfw08"]
bg_color = Color(1, 1, 1, 0.32549)
corner_radius_top_left = 10
corner_radius_top_right = 10
corner_radius_bottom_right = 10
corner_radius_bottom_left = 10
expand_margin_left = 4.0
expand_margin_top = 4.0
expand_margin_right = 4.0
expand_margin_bottom = 4.0
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ab24c"]
bg_color = Color(1, 1, 1, 1)
corner_radius_top_left = 10
corner_radius_top_right = 10
corner_radius_bottom_right = 10
corner_radius_bottom_left = 10
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qnehp"]
bg_color = Color(0, 0, 0, 1)
corner_radius_top_left = 10
corner_radius_top_right = 10
corner_radius_bottom_right = 10
corner_radius_bottom_left = 10
shadow_color = Color(0.847059, 0.847059, 0.847059, 0.384314)
shadow_size = 5
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_nxx8t"]
bg_color = Color(0.435294, 0.435294, 0.435294, 0.211765)
draw_center = false
border_width_left = 2
border_width_top = 2
border_width_right = 2
border_width_bottom = 2
corner_radius_top_left = 10
corner_radius_top_right = 10
corner_radius_bottom_right = 10
corner_radius_bottom_left = 10
expand_margin_left = 4.0
expand_margin_top = 4.0
expand_margin_right = 4.0
expand_margin_bottom = 4.0
[node name="BrowserItem" type="MarginContainer"]
custom_minimum_size = Vector2(200, 150)
offset_left = 1.0
offset_top = 1.0
offset_right = 128.0
offset_bottom = 102.0
size_flags_horizontal = 0
focus_mode = 2
theme_override_constants/margin_left = 4
theme_override_constants/margin_top = 4
theme_override_constants/margin_right = 4
theme_override_constants/margin_bottom = 4
script = ExtResource("1_s3kf0")
[node name="HoverBG" type="Panel" parent="."]
unique_name_in_owner = true
visible = false
layout_mode = 2
mouse_filter = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_pfw08")
[node name="VBox" type="VBoxContainer" parent="."]
layout_mode = 2
mouse_filter = 2
theme_override_constants/separation = 0
alignment = 1
[node name="Panel" type="PanelContainer" parent="VBox"]
unique_name_in_owner = true
self_modulate = Color(0.0705882, 0.0705882, 0.0705882, 1)
clip_children = 2
layout_mode = 2
size_flags_vertical = 3
mouse_filter = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_ab24c")
[node name="Image" type="TextureRect" parent="VBox/Panel"]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 3
mouse_filter = 2
expand_mode = 1
stretch_mode = 6
[node name="CurrentIcon" type="TextureRect" parent="VBox/Panel/Image"]
unique_name_in_owner = true
visible = false
layout_mode = 1
anchors_preset = 1
anchor_left = 1.0
anchor_right = 1.0
offset_left = -22.0
offset_top = 5.0
offset_right = -6.0
offset_bottom = 21.0
grow_horizontal = 0
tooltip_text = "Currently in use"
stretch_mode = 2
[node name="Panel" type="Panel" parent="VBox/Panel/Image"]
layout_mode = 1
anchors_preset = 3
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -37.0
offset_top = -36.0
offset_right = -7.0
offset_bottom = -6.0
grow_horizontal = 0
grow_vertical = 0
theme_override_styles/panel = SubResource("StyleBoxFlat_qnehp")
[node name="Icon" type="TextureRect" parent="VBox/Panel/Image/Panel"]
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 4.0
offset_top = 4.0
offset_right = -4.0
offset_bottom = -4.0
grow_horizontal = 2
grow_vertical = 2
expand_mode = 1
stretch_mode = 5
[node name="Name" type="Label" parent="VBox"]
unique_name_in_owner = true
layout_mode = 2
text = "Dialogic Theme"
horizontal_alignment = 1
[node name="FocusFG" type="Panel" parent="."]
unique_name_in_owner = true
visible = false
layout_mode = 2
mouse_filter = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_nxx8t")
[connection signal="focus_entered" from="." to="." method="_on_focus_entered"]
[connection signal="focus_exited" from="." to="." method="_on_focus_exited"]
[connection signal="gui_input" from="." to="." method="_on_gui_input"]
[connection signal="mouse_entered" from="." to="." method="_on_mouse_entered"]
[connection signal="mouse_exited" from="." to="." method="_on_mouse_exited"]
-47
View File
@@ -1,47 +0,0 @@
@tool
class_name DCSS
static func inline(style: Dictionary) -> StyleBoxFlat:
var scale: float = DialogicUtil.get_editor_scale()
var s := StyleBoxFlat.new()
for property in style.keys():
match property:
'border-left':
s.set('border_width_left', style[property] * scale)
'border-radius':
var radius: float = style[property] * scale
s.set('corner_radius_top_left', radius)
s.set('corner_radius_top_right', radius)
s.set('corner_radius_bottom_left', radius)
s.set('corner_radius_bottom_right', radius)
'background':
if typeof(style[property]) == TYPE_STRING and style[property] == "none":
s.set('draw_center', false)
else:
s.set('bg_color', style[property])
'border':
var width: float = style[property] * scale
s.set('border_width_left', width)
s.set('border_width_right', width)
s.set('border_width_top', width)
s.set('border_width_bottom', width)
'border-color':
s.set('border_color', style[property])
'padding':
var value_v: float = 0.0
var value_h: float = 0.0
if style[property] is int:
value_v = style[property] * scale
value_h = value_v
else:
value_v = style[property][0] * scale
value_h = style[property][1] * scale
s.set('content_margin_top', value_v)
s.set('content_margin_bottom', value_v)
s.set('content_margin_left', value_h)
s.set('content_margin_right', value_h)
'padding-right':
s.set('content_margin_right', style[property] * scale)
'padding-left':
s.set('content_margin_left', style[property] * scale)
return s
@@ -1,119 +0,0 @@
@tool
extends PanelContainer
enum Modes {EDIT, ADD}
var mode := Modes.EDIT
var item: TreeItem = null
func _ready() -> void:
hide()
%Character.resource_icon = load("res://addons/dialogic/Editor/Images/Resources/character.svg")
%Character.get_suggestions_func = get_character_suggestions
%WholeWords.icon = get_theme_icon("FontItem", "EditorIcons")
%MatchCase.icon = get_theme_icon("MatchCase", "EditorIcons")
func _on_add_pressed() -> void:
if visible:
if mode == Modes.ADD:
hide()
return
elif mode == Modes.EDIT:
save()
%AddButton.text = "Add"
mode = Modes.ADD
show()
%Type.selected = 0
_on_type_item_selected(0)
%Where.selected = 2
_on_where_item_selected(2)
%Old.text = ""
%New.text = ""
func open_existing(_item:TreeItem, info:Dictionary):
mode = Modes.EDIT
item = _item
show()
%AddButton.text = "Update"
%Type.selected = info.type
_on_type_item_selected(info.type)
if !info.character_names.is_empty():
%Where.selected = 1
%Character.set_value(info.character_names[0])
else:
%Where.selected = 0
_on_where_item_selected(%Where.selected)
%Old.text = info.what
%New.text = info.forwhat
func _on_type_item_selected(index:int) -> void:
match index:
0:
%Where.select(0)
%Where.set_item_disabled(0, false)
%Where.set_item_disabled(1, false)
%Where.set_item_disabled(2, true)
1:
%Where.select(0)
%Where.set_item_disabled(0, false)
%Where.set_item_disabled(1, false)
%Where.set_item_disabled(2, true)
2:
%Where.select(1)
%Where.set_item_disabled(0, true)
%Where.set_item_disabled(1, false)
%Where.set_item_disabled(2, true)
3,4:
%Where.select(0)
%Where.set_item_disabled(0, false)
%Where.set_item_disabled(1, true)
%Where.set_item_disabled(2, true)
%PureTextFlags.visible = index == 0
_on_where_item_selected(%Where.selected)
func _on_where_item_selected(index:int) -> void:
%Character.visible = index == 1
func get_character_suggestions(search_text:String) -> Dictionary:
var suggestions := {}
#override the previous _character_directory with the meta, specifically for searching otherwise new nodes wont work
var _character_directory := DialogicResourceUtil.get_character_directory()
var icon := load("res://addons/dialogic/Editor/Images/Resources/character.svg")
suggestions['(No one)'] = {'value':null, 'editor_icon':["GuiRadioUnchecked", "EditorIcons"]}
for resource in _character_directory.keys():
suggestions[resource] = {
'value' : resource,
'tooltip' : _character_directory[resource],
'icon' : icon.duplicate()}
return suggestions
func save() -> void:
if %Old.text.is_empty() or %New.text.is_empty():
return
if %Where.selected == 1 and %Character.current_value == null:
return
var previous := {}
if mode == Modes.EDIT:
previous = item.get_metadata(0)
item.get_parent()
item.free()
var ref_manager := find_parent('ReferenceManager')
var character_names := []
if %Character.current_value != null:
character_names = [%Character.current_value]
ref_manager.add_ref_change(%Old.text, %New.text, %Type.selected, %Where.selected, character_names, %WholeWords.button_pressed, %MatchCase.button_pressed, previous)
hide()
@@ -1,8 +0,0 @@
[gd_resource type="StyleBoxFlat" format=3 uid="uid://dmsjhgv22dns8"]
[resource]
content_margin_left = 5.0
content_margin_top = 5.0
content_margin_right = 5.0
content_margin_bottom = 5.0
bg_color = Color(0.545098, 0.545098, 0.545098, 0.211765)
@@ -1,363 +0,0 @@
@tool
extends VSplitContainer
## This manager shows a list of changed references and allows searching for them and replacing them.
var reference_changes: Array[Dictionary] = []:
set(changes):
reference_changes = changes
update_indicator()
var search_regexes: Array[Array]
var finder_thread: Thread
var progress_mutex: Mutex
var progress_percent: float = 0.0
var progress_message: String = ""
func _ready() -> void:
if owner.get_parent() is SubViewport:
return
%TabA.text = "Broken References"
%TabA.icon = get_theme_icon("Unlinked", "EditorIcons")
owner.get_parent().visibility_changed.connect(func(): if is_visible_in_tree(): open())
%ReplacementSection.hide()
%CheckButton.icon = get_theme_icon("Search", "EditorIcons")
%Replace.icon = get_theme_icon("ArrowRight", "EditorIcons")
%State.add_theme_color_override("font_color", get_theme_color("warning_color", "Editor"))
visibility_changed.connect(func(): if !visible: close())
await get_parent().ready
var tab_button: Control = %TabA
var dot := Sprite2D.new()
dot.texture = get_theme_icon("GuiGraphNodePort", "EditorIcons")
dot.scale = Vector2(0.8, 0.8)
dot.z_index = 10
dot.position = Vector2(tab_button.size.x, tab_button.size.y*0.25)
dot.modulate = get_theme_color("warning_color", "Editor").lightened(0.5)
tab_button.add_child(dot)
update_indicator()
func open() -> void:
%ReplacementEditPanel.hide()
%ReplacementSection.hide()
%ChangeTree.clear()
%ChangeTree.create_item()
%ChangeTree.set_column_expand(0, false)
%ChangeTree.set_column_expand(2, false)
%ChangeTree.set_column_custom_minimum_width(2, 50)
var categories := {null:%ChangeTree.get_root()}
for i in reference_changes:
var parent: TreeItem = null
if !i.get('category', null) in categories:
parent = %ChangeTree.create_item()
parent.set_text(1, i.category)
parent.set_custom_color(1, get_theme_color("disabled_font_color", "Editor"))
categories[i.category] = parent
else:
parent = categories[i.get('category')]
var item: TreeItem = %ChangeTree.create_item(parent)
item.set_text(1, i.what+" -> "+i.forwhat)
item.add_button(1, get_theme_icon("Edit", "EditorIcons"), 1, false, 'Edit')
item.add_button(1, get_theme_icon("Remove", "EditorIcons"), 0, false, 'Remove Change from List')
item.set_cell_mode(0, TreeItem.CELL_MODE_CHECK)
item.set_checked(0, true)
item.set_editable(0, true)
item.set_metadata(0, i)
%CheckButton.disabled = reference_changes.is_empty()
func _on_change_tree_button_clicked(item:TreeItem, column:int, id:int, mouse_button_index:int) -> void:
if id == 0:
reference_changes.erase(item.get_metadata(0))
if item.get_parent().get_child_count() == 1:
item.get_parent().free()
else:
item.free()
update_indicator()
%CheckButton.disabled = reference_changes.is_empty()
if id == 1:
%ReplacementEditPanel.open_existing(item, item.get_metadata(0))
%ReplacementSection.hide()
func _on_change_tree_item_edited() -> void:
if !%ChangeTree.get_selected():
return
%CheckButton.disabled = false
func _on_check_button_pressed() -> void:
var to_be_checked: Array[Dictionary]= []
var item: TreeItem = %ChangeTree.get_root()
while item.get_next_visible():
item = item.get_next_visible()
if item.get_child_count():
continue
if item.is_checked(0):
to_be_checked.append(item.get_metadata(0))
to_be_checked[-1]['item'] = item
to_be_checked[-1]['count'] = 0
open_finder(to_be_checked)
%CheckButton.disabled = true
func open_finder(replacements:Array[Dictionary]) -> void:
%ReplacementSection.show()
%Progress.show()
%ReferenceTree.hide()
search_regexes = []
for i in replacements:
if i.has('character_names') and !i.character_names.is_empty():
i['character_regex'] = RegEx.create_from_string("(?m)^(join|update|leave)?\\s*("+str(i.character_names).replace('"', '').replace(', ', '|').trim_suffix(']').trim_prefix('[').replace('/', '\\/')+")(?(1).*|.*:)")
for regex_string in i.regex:
var regex := RegEx.create_from_string(regex_string)
search_regexes.append([regex, i])
finder_thread = Thread.new()
progress_mutex = Mutex.new()
finder_thread.start(search_timelines.bind(search_regexes))
func _process(delta: float) -> void:
if finder_thread and finder_thread.is_started():
if finder_thread.is_alive():
progress_mutex.lock()
%State.text = progress_message
%Progress.value = progress_percent
progress_mutex.unlock()
else:
var finds: Variant = finder_thread.wait_to_finish()
display_search_results(finds)
func display_search_results(finds:Array[Dictionary]) -> void:
%Progress.hide()
%ReferenceTree.show()
for regex_info in search_regexes:
regex_info[1]['item'].set_text(2, str(regex_info[1]['count']))
update_count_coloring()
%State.text = str(len(finds))+ " occurrences found"
%ReferenceTree.clear()
%ReferenceTree.set_column_expand(0, false)
%ReferenceTree.create_item()
var timelines := {}
var height := 0
for i in finds:
var parent: TreeItem = null
if !i.timeline in timelines:
parent = %ReferenceTree.create_item()
parent.set_text(1, i.timeline)
parent.set_custom_color(1, get_theme_color("disabled_font_color", "Editor"))
timelines[i.timeline] = parent
height += %ReferenceTree.get_item_area_rect(parent).size.y+10
else:
parent = timelines[i.timeline]
var item: TreeItem = %ReferenceTree.create_item(parent)
item.set_text(1, 'Line '+str(i.line_number)+': '+i.line)
item.set_tooltip_text(1, i.info.what+' -> '+i.info.forwhat)
item.set_cell_mode(0, TreeItem.CELL_MODE_CHECK)
item.set_checked(0, true)
item.set_editable(0, true)
item.set_metadata(0, i)
height += %ReferenceTree.get_item_area_rect(item).size.y+10
var change_item: TreeItem = i.info.item
change_item.set_meta('found_items', change_item.get_meta('found_items', [])+[item])
%ReferenceTree.custom_minimum_size.y = min(height, 200)
%ReferenceTree.visible = !finds.is_empty()
%Replace.disabled = finds.is_empty()
if finds.is_empty():
%State.text = "Nothing found"
else:
%Replace.grab_focus()
func search_timelines(regexes:Array[Array]) -> Array[Dictionary]:
var finds: Array[Dictionary] = []
var timeline_paths := DialogicResourceUtil.list_resources_of_type('.dtl')
var progress := 0
var progress_max: float = len(timeline_paths)*len(regexes)
for timeline_path:String in timeline_paths:
var timeline_file := FileAccess.open(timeline_path, FileAccess.READ)
var timeline_text: String = timeline_file.get_as_text()
var timeline_event: PackedStringArray = timeline_text.split('\n')
timeline_file.close()
for regex_info in regexes:
progress += 1
progress_mutex.lock()
progress_percent = 1/progress_max*progress
progress_message = "Searching '"+timeline_path+"' for "+regex_info[1].what+' -> '+regex_info[1].forwhat
progress_mutex.unlock()
for i in regex_info[0].search_all(timeline_text):
if regex_info[1].has('character_regex'):
if regex_info[1].character_regex.search(get_line(timeline_text, i.get_start()+1)) == null:
continue
var line_number := timeline_text.count('\n', 0, i.get_start()+1)+1
var line := timeline_text.get_slice('\n', line_number-1)
finds.append({
'match':i,
'timeline':timeline_path,
'info': regex_info[1],
'line_number': line_number,
'line': line,
'line_start': timeline_text.rfind('\n', i.get_start())
})
regex_info[1]['count'] += 1
return finds
func _exit_tree() -> void:
# Shutting of
if finder_thread and finder_thread.is_alive():
finder_thread.wait_to_finish()
func get_line(string:String, at_index:int) -> String:
return string.substr(max(string.rfind('\n', at_index), 0), string.find('\n', at_index)-string.rfind('\n', at_index))
func update_count_coloring() -> void:
var item: TreeItem = %ChangeTree.get_root()
while item.get_next_visible():
item = item.get_next_visible()
if item.get_child_count():
continue
if int(item.get_text(2)) > 0:
item.set_custom_bg_color(1, get_theme_color("warning_color", "Editor").darkened(0.8))
item.set_custom_color(1, get_theme_color("warning_color", "Editor"))
item.set_custom_color(2, get_theme_color("warning_color", "Editor"))
else:
item.set_custom_color(2, get_theme_color("success_color", "Editor"))
item.set_custom_color(1, get_theme_color("readonly_font_color", "Editor"))
if item.get_button_count(1):
item.erase_button(1, 1)
item.add_button(1, get_theme_icon("Eraser", "EditorIcons"), -1, true, "This reference was not found anywhere and will be removed from this list.")
func _on_replace_pressed() -> void:
var to_be_replaced: Array[Dictionary]= []
var item: TreeItem = %ReferenceTree.get_root()
var affected_timelines: Array[String]= []
while item.get_next_visible():
item = item.get_next_visible()
if item.get_child_count():
continue
if item.is_checked(0):
to_be_replaced.append(item.get_metadata(0))
to_be_replaced[-1]['f_item'] = item
if !item.get_metadata(0).timeline in affected_timelines:
affected_timelines.append(item.get_metadata(0).timeline)
replace(affected_timelines, to_be_replaced)
func replace(timelines:Array[String], replacement_info:Array[Dictionary]) -> void:
var reopen_timeline := ""
var timeline_editor: DialogicEditor = find_parent('EditorView').editors_manager.editors['Timeline'].node
if timeline_editor.current_resource != null and timeline_editor.current_resource.resource_path in timelines:
reopen_timeline = timeline_editor.current_resource.resource_path
find_parent('EditorView').editors_manager.clear_editor(timeline_editor)
replacement_info.sort_custom(func(a,b): return a.match.get_start() < b.match.get_start())
for timeline_path in timelines:
%State.text = "Loading '"+timeline_path+"'"
var timeline_file := FileAccess.open(timeline_path, FileAccess.READ_WRITE)
var timeline_text: String = timeline_file.get_as_text()
var timeline_events := timeline_text.split('\n')
timeline_file.close()
var idx := 1
var offset_correction := 0
for replacement in replacement_info:
if replacement.timeline != timeline_path:
continue
%State.text = "Replacing in '"+timeline_path + "' ("+str(idx)+"/"+str(len(replacement_info))+")"
var group := 'replace'
if not 'replace' in replacement.match.names:
group = ''
timeline_text = timeline_text.substr(0, replacement.match.get_start(group) + offset_correction) + \
replacement.info.regex_replacement + \
timeline_text.substr(replacement.match.get_end(group) + offset_correction)
offset_correction += len(replacement.info.regex_replacement)-len(replacement.match.get_string(group))
replacement.info.count -= 1
replacement.info.item.set_text(2, str(replacement.info.count))
replacement.f_item.set_custom_bg_color(1, get_theme_color("success_color", "Editor").darkened(0.8))
timeline_file = FileAccess.open(timeline_path, FileAccess.WRITE)
timeline_file.store_string(timeline_text.strip_edges(false, true))
timeline_file.close()
if ResourceLoader.has_cached(timeline_path):
var tml := load(timeline_path)
tml.from_text(timeline_text)
if !reopen_timeline.is_empty():
find_parent('EditorView').editors_manager.edit_resource(load(reopen_timeline), false, true)
update_count_coloring()
%Replace.disabled = true
%CheckButton.disabled = false
%State.text = "Done Replacing"
func update_indicator() -> void:
%TabA.get_child(0).visible = !reference_changes.is_empty()
func close() -> void:
var item: TreeItem = %ChangeTree.get_root()
if item:
while item.get_next_visible():
item = item.get_next_visible()
if item.get_child_count():
continue
if item.get_text(2) != "" and int(item.get_text(2)) == 0:
reference_changes.erase(item.get_metadata(0))
for i in reference_changes:
i.item = null
DialogicUtil.set_editor_setting('reference_changes', reference_changes)
update_indicator()
find_parent("ReferenceManager").update_indicator()
func _on_add_button_pressed() -> void:
%ReplacementEditPanel._on_add_pressed()

Some files were not shown because too many files have changed in this diff Show More