From 8de9323a6e7e35d1f92e64e9453fab9f5efa97d2 Mon Sep 17 00:00:00 2001 From: ManlyMarco <39247311+ManlyMarco@users.noreply.github.com> Date: Wed, 17 Jan 2024 23:34:54 +0100 Subject: [PATCH] [KK/KKS] Add HairShadowColorControl plugin (#219) Convenient controls for changing the shadow color of character hair in maker. Uses ME underneath. --- KK_Plugins.sln | 22 +++ .../AssemblyInfo.cs | 14 ++ .../Core.HairShadowColorControl.shproj | 13 ++ .../HairShadowColorControl.Core.projitems | 15 ++ .../HairShadowColorControlPlugin.cs | 147 +++++++++++++++ .../KK.HairShadowColorControl.csproj | 111 ++++++++++++ src/HairShadowColorControl.KK/packages.config | 12 ++ .../KKS.HairShadowColorControl.csproj | 169 ++++++++++++++++++ .../packages.config | 16 ++ 9 files changed, 519 insertions(+) create mode 100644 src/HairShadowColorControl.Core/AssemblyInfo.cs create mode 100644 src/HairShadowColorControl.Core/Core.HairShadowColorControl.shproj create mode 100644 src/HairShadowColorControl.Core/HairShadowColorControl.Core.projitems create mode 100644 src/HairShadowColorControl.Core/HairShadowColorControlPlugin.cs create mode 100644 src/HairShadowColorControl.KK/KK.HairShadowColorControl.csproj create mode 100644 src/HairShadowColorControl.KK/packages.config create mode 100644 src/HairShadowColorControl.KKS/KKS.HairShadowColorControl.csproj create mode 100644 src/HairShadowColorControl.KKS/packages.config diff --git a/KK_Plugins.sln b/KK_Plugins.sln index 27f23b67..54d32226 100644 --- a/KK_Plugins.sln +++ b/KK_Plugins.sln @@ -565,6 +565,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AI.AccessoriesToStudioItems EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HS2.AccessoriesToStudioItems", "src\AccessoriesToStudioItems.HS2\HS2.AccessoriesToStudioItems.csproj", "{D6B32AEB-1431-432E-932D-AF0E30D2EB9F}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "HairShadowColorControl", "HairShadowColorControl", "{267C92B3-1324-448C-A699-B0A3A4D6A1A7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KKS.HairShadowColorControl", "src\HairShadowColorControl.KKS\KKS.HairShadowColorControl.csproj", "{0FF15905-4A4E-43EE-9853-F410F0A63876}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KK.HairShadowColorControl", "src\HairShadowColorControl.KK\KK.HairShadowColorControl.csproj", "{25C47673-7B6A-4127-9E47-237B3CA991FB}" +EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Core.HairShadowColorControl", "src\HairShadowColorControl.Core\Core.HairShadowColorControl.shproj", "{30F7FDB4-A1B8-41B9-8D74-E82E3099E555}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1263,6 +1271,14 @@ Global {D6B32AEB-1431-432E-932D-AF0E30D2EB9F}.Debug|Any CPU.Build.0 = Debug|Any CPU {D6B32AEB-1431-432E-932D-AF0E30D2EB9F}.Release|Any CPU.ActiveCfg = Release|Any CPU {D6B32AEB-1431-432E-932D-AF0E30D2EB9F}.Release|Any CPU.Build.0 = Release|Any CPU + {0FF15905-4A4E-43EE-9853-F410F0A63876}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0FF15905-4A4E-43EE-9853-F410F0A63876}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0FF15905-4A4E-43EE-9853-F410F0A63876}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0FF15905-4A4E-43EE-9853-F410F0A63876}.Release|Any CPU.Build.0 = Release|Any CPU + {25C47673-7B6A-4127-9E47-237B3CA991FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {25C47673-7B6A-4127-9E47-237B3CA991FB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {25C47673-7B6A-4127-9E47-237B3CA991FB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {25C47673-7B6A-4127-9E47-237B3CA991FB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1492,6 +1508,9 @@ Global {DC93DDEC-8CD0-42F4-905E-6550659CCA85} = {F4AD3F74-B97B-40BF-AD1B-92FFE7A428FC} {BE3DEE42-3526-42F9-9C2F-9D57BD43A078} = {F4AD3F74-B97B-40BF-AD1B-92FFE7A428FC} {D6B32AEB-1431-432E-932D-AF0E30D2EB9F} = {F4AD3F74-B97B-40BF-AD1B-92FFE7A428FC} + {0FF15905-4A4E-43EE-9853-F410F0A63876} = {267C92B3-1324-448C-A699-B0A3A4D6A1A7} + {25C47673-7B6A-4127-9E47-237B3CA991FB} = {267C92B3-1324-448C-A699-B0A3A4D6A1A7} + {30F7FDB4-A1B8-41B9-8D74-E82E3099E555} = {267C92B3-1324-448C-A699-B0A3A4D6A1A7} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D0F79985-4CB7-46CB-BEC2-FF89C476ED20} @@ -1512,6 +1531,7 @@ Global src\AccessoryQuickRemove.Core\AccessoryQuickRemove.Core.projitems*{0cd64f6f-4e15-4c9c-a990-4616a8a8ea82}*SharedItemsImports = 4 src\Shared\Shared.projitems*{0cd64f6f-4e15-4c9c-a990-4616a8a8ea82}*SharedItemsImports = 4 src\ClothingUnlocker.Core\Core.ClothingUnlocker.projitems*{0f7181c7-8d52-4576-9bff-d4b7d08f42a2}*SharedItemsImports = 13 + src\HairShadowColorControl.Core\HairShadowColorControl.Core.projitems*{0ff15905-4a4e-43ee-9853-f410f0a63876}*SharedItemsImports = 4 src\MaleJuice.Core\MaleJuice.Core.projitems*{11112067-cfa0-4522-be2e-0c4d1cf9e36a}*SharedItemsImports = 4 src\Shared\Shared.projitems*{11112067-cfa0-4522-be2e-0c4d1cf9e36a}*SharedItemsImports = 4 src\ForceHighPoly.Core\ForceHighPoly.Core.projitems*{123d12ea-5526-4d07-ab26-7ab9459b4aeb}*SharedItemsImports = 4 @@ -1563,6 +1583,7 @@ Global src\Shared\Shared.projitems*{255b5bf8-80ff-49ea-b4fb-7b535e8c6062}*SharedItemsImports = 4 src\Shared\Shared.projitems*{2566acd4-b07d-4feb-aa9c-4cd1751e97fc}*SharedItemsImports = 4 src\StudioSceneLoadedSound.Core\Core.StudioSceneLoadedSound.projitems*{2566acd4-b07d-4feb-aa9c-4cd1751e97fc}*SharedItemsImports = 4 + src\HairShadowColorControl.Core\HairShadowColorControl.Core.projitems*{25c47673-7b6a-4127-9e47-237b3ca991fb}*SharedItemsImports = 4 src\MaterialEditor.Base\MaterialEditor.Base.projitems*{25e45f23-4d1d-4cd0-b0bc-653c8ae1c561}*SharedItemsImports = 4 src\MaterialEditor.Core.Maker\Core.MaterialEditor.Maker.projitems*{25e45f23-4d1d-4cd0-b0bc-653c8ae1c561}*SharedItemsImports = 4 src\MaterialEditor.Core\Core.MaterialEditor.projitems*{25e45f23-4d1d-4cd0-b0bc-653c8ae1c561}*SharedItemsImports = 4 @@ -1574,6 +1595,7 @@ Global src\ItemBlacklist.Core\ItemBlacklist.Core.projitems*{3078a5da-7330-469c-ad65-7f6f2619fad7}*SharedItemsImports = 4 src\Shared\Shared.projitems*{3078a5da-7330-469c-ad65-7f6f2619fad7}*SharedItemsImports = 4 src\UIUtility\UIUtility.projitems*{3078a5da-7330-469c-ad65-7f6f2619fad7}*SharedItemsImports = 4 + src\HairShadowColorControl.Core\HairShadowColorControl.Core.projitems*{30f7fdb4-a1b8-41b9-8d74-e82e3099e555}*SharedItemsImports = 13 src\PoseQuickLoad.Core\Core.PoseQuickLoad.projitems*{35366d0f-99f5-47a4-bc14-db50b58e7ef7}*SharedItemsImports = 4 src\Shared\Shared.projitems*{35366d0f-99f5-47a4-bc14-db50b58e7ef7}*SharedItemsImports = 4 src\MakerDefaults.Core.AIHS2\MakerDefaults.Core.projitems*{35cf8f9c-ec35-49b6-b9e1-c1691771a49e}*SharedItemsImports = 4 diff --git a/src/HairShadowColorControl.Core/AssemblyInfo.cs b/src/HairShadowColorControl.Core/AssemblyInfo.cs new file mode 100644 index 00000000..d0ac68fe --- /dev/null +++ b/src/HairShadowColorControl.Core/AssemblyInfo.cs @@ -0,0 +1,14 @@ +using System.Reflection; +using System.Runtime.InteropServices; +using HairShadowColorControl; + +[assembly: AssemblyTitle(HairShadowColorControlPlugin.GUID)] +[assembly: AssemblyDescription(HairShadowColorControlPlugin.DisplayName)] +[assembly: AssemblyCompany("https://github.com/IllusionMods/KK_Plugins/")] +[assembly: AssemblyProduct(HairShadowColorControlPlugin.DisplayName)] +[assembly: AssemblyCopyright("Copyright © 2024")] + +[assembly: ComVisible(false)] +[assembly: Guid("0ff15905-4a4e-43ee-9853-f410f0a63876")] + +[assembly: AssemblyVersion(HairShadowColorControlPlugin.Version)] diff --git a/src/HairShadowColorControl.Core/Core.HairShadowColorControl.shproj b/src/HairShadowColorControl.Core/Core.HairShadowColorControl.shproj new file mode 100644 index 00000000..ed678f5f --- /dev/null +++ b/src/HairShadowColorControl.Core/Core.HairShadowColorControl.shproj @@ -0,0 +1,13 @@ + + + + 30f7fdb4-a1b8-41b9-8d74-e82e3099e555 + 14.0 + + + + + + + + diff --git a/src/HairShadowColorControl.Core/HairShadowColorControl.Core.projitems b/src/HairShadowColorControl.Core/HairShadowColorControl.Core.projitems new file mode 100644 index 00000000..fee33380 --- /dev/null +++ b/src/HairShadowColorControl.Core/HairShadowColorControl.Core.projitems @@ -0,0 +1,15 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + 30f7fdb4-a1b8-41b9-8d74-e82e3099e555 + + + HairShadowColorControl.Core + + + + + + \ No newline at end of file diff --git a/src/HairShadowColorControl.Core/HairShadowColorControlPlugin.cs b/src/HairShadowColorControl.Core/HairShadowColorControlPlugin.cs new file mode 100644 index 00000000..c08c1bd2 --- /dev/null +++ b/src/HairShadowColorControl.Core/HairShadowColorControlPlugin.cs @@ -0,0 +1,147 @@ +using System; +using BepInEx; +using ChaCustom; +using HarmonyLib; +using KK_Plugins.MaterialEditor; +using KKAPI.Maker; +using KKAPI.Maker.UI; +using UniRx; +using UnityEngine; + +namespace HairShadowColorControl +{ + [BepInPlugin(GUID, DisplayName, Version)] + [BepInDependency(KKAPI.KoikatuAPI.GUID, KKAPI.KoikatuAPI.VersionConst)] + public class HairShadowColorControlPlugin : BaseUnityPlugin + { + public const string GUID = "HairShadowColorControl"; + public const string Version = "1.0"; + internal const string DisplayName = "HairShadowColorControl"; + + private const string ShadowColorPropertyName = "ShadowColor"; + private static readonly Color _DefaultColor = new Color(0.83f, 0.87f, 0.94f); + + private static MakerColor[] _customControls; + private static ChaControl _charaController; + private static MaterialEditorCharaController _meController; + + private void Awake() + { + MakerAPI.MakerStartedLoading += MakerLoading; + MakerAPI.ReloadCustomInterface += MakerRefresh; + + Harmony.CreateAndPatchAll(typeof(Hooks), GUID); + } + + private void MakerLoading(object sender, RegisterCustomControlsEvent args) + { + var makerBase = MakerAPI.GetMakerBase(); + + _charaController = MakerAPI.GetCharacterControl(); + _meController = _charaController.GetComponent(); + + // Lines up with how hair parts are indexed + var hairKinds = new[] { MakerConstants.Hair.Back, MakerConstants.Hair.Front, MakerConstants.Hair.Side, MakerConstants.Hair.Extension }; + _customControls = new MakerColor[hairKinds.Length]; + for (var hairKind = 0; hairKind < hairKinds.Length; hairKind++) + { + var makerCategory = hairKinds[hairKind]; + var hairType = (CvsHair.HairType)hairKind; + var control = args.AddControl(new MakerColor("Hair shadow color", false, makerCategory, _DefaultColor, this) { GroupingID = null }); + control.ValueChanged.Subscribe(color => + { + if (!MakerAPI.InsideAndLoaded) return; + + var chaCtrl = MakerAPI.GetCharacterControl(); + + if (makerBase.customSettingSave.hairSameSetting) + { + for (var i = 0; i < _customControls.Length; i++) + { + SetShadowColor(chaCtrl, color, (CvsHair.HairType)i); + _customControls[i].SetValue(color, false); + } + } + else + { + SetShadowColor(chaCtrl, color, hairType); + } + }); + _customControls[hairKind] = control; + } + } + + private static void SetShadowColor(ChaControl chaCtrl, Color color, CvsHair.HairType kind) + { + var me = chaCtrl.GetComponent(); + + var rend = chaCtrl.GetCustomHairComponent((int)kind); + if (rend != null && rend.rendHair != null) + { + foreach (var r in rend.rendHair) + me.SetMaterialColorProperty((int)kind, MaterialEditorCharaController.ObjectType.Hair, r.material, ShadowColorPropertyName, color, rend.gameObject); + } + } + + private static void MakerRefresh(object sender, EventArgs e) + { + for (var hairPart = 0; hairPart < _customControls.Length; hairPart++) + UpdateSliderValue(hairPart); + } + + private static void UpdateSliderValue(int hairPart) + { + if (!MakerAPI.InsideMaker) return; + + // Figure out current color to show in the color control + Color? setColor = null, originColor = null, currentColor = null; + var any = false; + var rendHair = _charaController.GetCustomHairComponent(hairPart)?.rendHair; + if (rendHair != null) + { + foreach (var renderer in rendHair) + { + if (renderer == null) continue; + any = true; + + setColor = _meController.GetMaterialColorPropertyValue(hairPart, MaterialEditorCharaController.ObjectType.Hair, renderer.material, ShadowColorPropertyName, renderer.gameObject); + if (setColor.HasValue) break; + + if (originColor.HasValue) continue; + originColor = _meController.GetMaterialColorPropertyValueOriginal(hairPart, MaterialEditorCharaController.ObjectType.Hair, renderer.material, ShadowColorPropertyName, renderer.gameObject); + + if (currentColor.HasValue) continue; + currentColor = renderer.material.GetColor("_" + ShadowColorPropertyName); + } + } + var color = setColor ?? originColor ?? currentColor ?? _DefaultColor; + // Alpha is ignored by shaders and can be 0 making it invisible in the color picker + color.a = 1; + + var customControl = _customControls[hairPart]; + customControl.SetValue(color, false); + + // If there are no renderers then the control should be hidden like base game color controls + if (customControl.Visible.Value != any) + customControl.Visible.OnNext(any); + } + + private static class Hooks + { + [HarmonyPostfix] + [HarmonyPatch(typeof(CvsHair), nameof(CvsHair.UpdateSelectHair))] + private static void UpdateHairUi(CvsHair __instance) + { + // Problem is that if user changes hair type then shadow color is lost + // Update the slider to show the color of the newly loaded hair type + UpdateSliderValue(__instance.hairType); + + // doesn't work, no obvious way to tell if this is a card load or user ui click (breaks card load) + //var makerColor = _customControls[__instance.hairType]; + //var value = makerColor.Value; + //makerColor.SetValue(Color.magenta, false); + //makerColor.SetValue(value, true); + } + } + } +} diff --git a/src/HairShadowColorControl.KK/KK.HairShadowColorControl.csproj b/src/HairShadowColorControl.KK/KK.HairShadowColorControl.csproj new file mode 100644 index 00000000..553099ae --- /dev/null +++ b/src/HairShadowColorControl.KK/KK.HairShadowColorControl.csproj @@ -0,0 +1,111 @@ + + + + + Debug + AnyCPU + {25C47673-7B6A-4127-9E47-237B3CA991FB} + Library + Properties + HairShadowColorControl + KK_HairShadowColorControl + v3.5 + 512 + true + + + + + true + embedded + false + ..\..\bin\ + TRACE;DEBUG;KK + prompt + 4 + true + + + embedded + true + ..\..\bin\ + TRACE;KK + prompt + 4 + true + true + + + + ..\..\packages\IllusionLibs.BepInEx.Harmony.2.9.0\lib\net35\0Harmony.dll + False + + + ..\..\packages\IllusionLibs.Koikatu.Assembly-CSharp.2019.4.27.4\lib\net35\Assembly-CSharp.dll + False + + + ..\..\packages\IllusionLibs.Koikatu.Assembly-CSharp-firstpass.2019.4.27.4\lib\net35\Assembly-CSharp-firstpass.dll + False + + + ..\..\packages\IllusionLibs.BepInEx.5.4.20\lib\net35\BepInEx.dll + False + + + ..\..\packages\ExtensibleSaveFormat.Koikatu.16.8.1\lib\net35\ExtensibleSaveFormat.dll + False + + + ..\..\packages\IllusionModdingAPI.KKAPI.1.38.0\lib\net35\KKAPI.dll + False + + + + + + + + + ..\..\packages\IllusionLibs.Koikatu.UnityEngine.5.6.2.4\lib\net35\UnityEngine.dll + False + + + ..\..\packages\IllusionLibs.Koikatu.UnityEngine.UI.5.6.2.4\lib\net35\UnityEngine.UI.dll + False + + + + + + + + + + + + + + {b743e048-5913-4dec-9067-8afd1293a211} + KK.MaterialEditor + False + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + \ No newline at end of file diff --git a/src/HairShadowColorControl.KK/packages.config b/src/HairShadowColorControl.KK/packages.config new file mode 100644 index 00000000..e8f13db8 --- /dev/null +++ b/src/HairShadowColorControl.KK/packages.config @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/HairShadowColorControl.KKS/KKS.HairShadowColorControl.csproj b/src/HairShadowColorControl.KKS/KKS.HairShadowColorControl.csproj new file mode 100644 index 00000000..1850c1c7 --- /dev/null +++ b/src/HairShadowColorControl.KKS/KKS.HairShadowColorControl.csproj @@ -0,0 +1,169 @@ + + + + + Debug + AnyCPU + {0FF15905-4A4E-43EE-9853-F410F0A63876} + Library + Properties + HairShadowColorControl + KKS_HairShadowColorControl + v4.6 + 512 + true + + + + + true + embedded + false + ..\..\bin\ + TRACE;DEBUG;KKS + prompt + 4 + true + + + embedded + true + ..\..\bin\ + TRACE;KKS + prompt + 4 + true + true + + + + ..\..\packages\IllusionLibs.BepInEx.Harmony.2.9.0\lib\net35\0Harmony.dll + False + + + ..\..\packages\IllusionLibs.KoikatsuSunshine.Assembly-CSharp.2021.9.17\lib\net46\Assembly-CSharp.dll + False + + + ..\..\packages\IllusionLibs.KoikatsuSunshine.Assembly-CSharp-firstpass.2021.9.17\lib\net46\Assembly-CSharp-firstpass.dll + False + + + ..\..\packages\IllusionLibs.BepInEx.5.4.22\lib\net35\BepInEx.dll + False + + + ..\..\packages\IllusionModdingAPI.KKSAPI.1.38.0\lib\net46\KKSAPI.dll + False + + + ..\..\packages\ExtensibleSaveFormat.KoikatsuSunshine.16.8.1\lib\net46\KKS_ExtensibleSaveFormat.dll + False + + + ..\..\packages\IllusionLibs.KoikatsuSunshine.UnityEngine.CoreModule.2019.4.9\lib\net46\Sirenix.Serialization.dll + False + + + + + + + + + + + ..\..\packages\IllusionLibs.KoikatsuSunshine.UniRx.2021.9.17\lib\net46\UniRx.dll + False + + + ..\..\packages\IllusionLibs.KoikatsuSunshine.UniTask.2021.9.17\lib\net46\UniTask.dll + False + + + ..\..\packages\IllusionLibs.KoikatsuSunshine.UniTask.2021.9.17\lib\net46\UniTask.Addressables.dll + False + + + ..\..\packages\IllusionLibs.KoikatsuSunshine.UniTask.2021.9.17\lib\net46\UniTask.DOTween.dll + False + + + ..\..\packages\IllusionLibs.KoikatsuSunshine.UniTask.2021.9.17\lib\net46\UniTask.Linq.dll + False + + + ..\..\packages\IllusionLibs.KoikatsuSunshine.UniTask.2021.9.17\lib\net46\UniTask.TextMeshPro.dll + False + + + ..\..\packages\IllusionLibs.KoikatsuSunshine.UnityEngine.CoreModule.2019.4.9\lib\net46\UnityEngine.dll + False + + + ..\..\packages\IllusionLibs.KoikatsuSunshine.UnityEngine.CoreModule.2019.4.9\lib\net46\UnityEngine.CoreModule.dll + False + + + ..\..\packages\IllusionLibs.KoikatsuSunshine.UnityEngine.IMGUIModule.2019.4.9\lib\net46\UnityEngine.IMGUIModule.dll + False + + + ..\..\packages\IllusionLibs.KoikatsuSunshine.UnityEngine.InputLegacyModule.2019.4.9\lib\net46\UnityEngine.InputLegacyModule.dll + False + + + ..\..\packages\IllusionLibs.KoikatsuSunshine.UnityEngine.UI.2019.4.9\lib\net46\UnityEngine.UI.dll + False + + + ..\..\packages\IllusionLibs.KoikatsuSunshine.UnityEngine.UIModule.2019.4.9\lib\net46\UnityEngine.UIModule.dll + False + + + + + + + + {a6d41927-0f12-485c-afd5-5158439e48d0} + KKS.MaterialEditor + False + + + + + + + + + IF EXIST "$(TargetDir)$(TargetName).pdb" IF EXIST "$(SolutionDir)pdb2mdb.exe" CALL "$(SolutionDir)pdb2mdb.exe" "$(TargetPath)" +IF EXIST "$(SolutionDir)PostBuild.bat" CALL "$(SolutionDir)PostBuild.bat" "$(TargetPath)" KKS + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/HairShadowColorControl.KKS/packages.config b/src/HairShadowColorControl.KKS/packages.config new file mode 100644 index 00000000..1e2a0c0d --- /dev/null +++ b/src/HairShadowColorControl.KKS/packages.config @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file