-
-
Notifications
You must be signed in to change notification settings - Fork 123
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[KK/KKS] Add HairShadowColorControl plugin (#219)
Convenient controls for changing the shadow color of character hair in maker. Uses ME underneath.
- Loading branch information
1 parent
33a48c1
commit 8de9323
Showing
9 changed files
with
519 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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)] |
13 changes: 13 additions & 0 deletions
13
src/HairShadowColorControl.Core/Core.HairShadowColorControl.shproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<PropertyGroup Label="Globals"> | ||
<ProjectGuid>30f7fdb4-a1b8-41b9-8d74-e82e3099e555</ProjectGuid> | ||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion> | ||
</PropertyGroup> | ||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> | ||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" /> | ||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" /> | ||
<PropertyGroup /> | ||
<Import Project="HairShadowColorControl.Core.projitems" Label="Shared" /> | ||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" /> | ||
</Project> |
15 changes: 15 additions & 0 deletions
15
src/HairShadowColorControl.Core/HairShadowColorControl.Core.projitems
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<PropertyGroup> | ||
<MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' < '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects> | ||
<HasSharedItems>true</HasSharedItems> | ||
<SharedGUID>30f7fdb4-a1b8-41b9-8d74-e82e3099e555</SharedGUID> | ||
</PropertyGroup> | ||
<PropertyGroup Label="Configuration"> | ||
<Import_RootNamespace>HairShadowColorControl.Core</Import_RootNamespace> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Compile Include="$(MSBuildThisFileDirectory)AssemblyInfo.cs" /> | ||
<Compile Include="$(MSBuildThisFileDirectory)HairShadowColorControlPlugin.cs" /> | ||
</ItemGroup> | ||
</Project> |
147 changes: 147 additions & 0 deletions
147
src/HairShadowColorControl.Core/HairShadowColorControlPlugin.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<MaterialEditorCharaController>(); | ||
|
||
// 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<MaterialEditorCharaController>(); | ||
|
||
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); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.