├── src ├── Common.Core │ ├── BuildNumber.cs │ ├── Common.Core.projitems │ ├── Common.Core.shproj │ ├── Log.cs │ └── Constants.cs ├── BetterSceneLoader.Core │ ├── Resources │ │ ├── loadicon │ │ └── pluginicon │ ├── SortBy.cs │ ├── LoadingIcon.cs │ ├── BetterSceneLoader.Core.shproj │ ├── BetterSceneLoader.Core.projitems │ ├── AutoGridLayout.cs │ ├── SceneGrid.cs │ └── DropdownAutoScroll.cs ├── UIUtility │ ├── Resources │ │ ├── DefaultResourcesHS.unity3d │ │ └── DefaultResourcesKOI.unity3d │ ├── OneTimeVerticalLayoutGroup.cs │ ├── Extensions.cs │ ├── OneTimeHorizontalLayoutGroup.cs │ ├── UIUtility.shproj │ ├── UILibResource.cs │ ├── UIUtility.projitems │ └── MovableWindow.cs ├── BuildSettings.Patcher.props ├── SkipAllRefs.targets ├── BuildSettings.Koikatu.props ├── BuildSettings.PlayHome.props ├── BuildSettings.AISyoujyo.props ├── BuildSettings.KoikatsuSunshine.props ├── BuildSettings.HoneySelect2.props ├── Common.Utils │ ├── Tuple.cs │ ├── Lazy.cs │ ├── Common.Utils.projitems │ ├── Common.Utils.shproj │ └── Resource.cs ├── Common.Harmony │ ├── ReflectionExtensions.cs │ ├── HarmonyExtensions.cs │ ├── Common.Harmony.projitems │ ├── Common.Harmony.shproj │ ├── EventFactory.cs │ ├── HarmonyPatchExt.cs │ └── CoroutineExtensions.cs ├── ItemLayerEdit.Core │ ├── LayerData.cs │ ├── Extensions.cs │ ├── ItemLayerEdit.Core.projitems │ ├── ItemLayerEdit.Core.shproj │ ├── ItemLayerEdit.cs │ └── SceneDataController.cs ├── Common.Unity │ ├── UnityEventExtensions.cs │ ├── Common.Unity.projitems │ ├── Common.Unity.shproj │ └── UnityExtensions.cs ├── UnityLogFilter │ ├── UnityLogFilter.csproj │ └── UnityLogFilter.cs ├── AssOverride │ ├── AssOverride.csproj │ └── AssOverride.cs ├── RealPOV.Koikatu │ └── RealPOV.Koikatu.csproj ├── LockOnPlugin.Koikatu │ └── LockOnPlugin.Koikatu.csproj ├── FreeHDefaults.KoikatuSunshine │ └── FreeHDefaults.KoikatuSunshine.csproj ├── TitleShortcuts.Core │ ├── TitleShortcutsCore.cs │ ├── TitleShortcuts.Core.projitems │ └── TitleShortcuts.Core.shproj ├── RealPOV.Core │ ├── RealPOV.Core.projitems │ └── RealPOV.Core.shproj ├── MaterialLink.KoikatuSunshine │ ├── MaterialLink.KoikatuSunshine.csproj │ └── MaterialLink.cs ├── AltAutoMode.PlayHome │ └── AltAutoMode.PlayHome.csproj ├── LightManager.Core │ ├── TrackTransform.cs │ ├── LightManager.Core.projitems │ ├── LightManager.Core.shproj │ ├── LightManagerPlugin.cs │ └── SceneDataController.cs ├── SoundEffects.PlayHome │ ├── SoundEffects.PlayHome.csproj │ └── SoundEffects.cs ├── CameraFrameMask.Koikatu │ └── CameraFrameMask.Koikatu.csproj ├── FreeHDefaults.Koikatu │ └── FreeHDefaults.Koikatu.csproj ├── LockOnPlugin.KoikatuSunshine │ └── LockOnPlugin.KoikatuSunshine.csproj ├── AnimeAssAssistant.Core │ ├── AnimeAssAssistant.Core.projitems │ └── AnimeAssAssistant.Core.shproj ├── CharaStateX.Koikatu │ └── CharaStateX.Koikatu.csproj ├── DefaultStudioScene.Core │ ├── DefaultStudioScene.Core.projitems │ ├── DefaultStudioScene.Core.shproj │ └── DefaultStudioScene.cs ├── EyeLookEditor.Core │ ├── DefaultValue.cs │ ├── EyeLookEditor.Core.projitems │ └── EyeLookEditor.Core.shproj ├── ClothingStateMenuX.Core │ ├── ClothingStateMenuX.Core.projitems │ ├── ClothingStateMenuX.Core.shproj │ └── ClothingStateMenu.cs ├── StudioAddonLite.Koikatu │ └── StudioAddonLite.Koikatu.csproj ├── TitleShortcuts.AISyoujyo │ ├── TitleShortcuts.AISyoujyo.csproj │ └── TitleShortcuts.cs ├── TesselationSetting.KoikatuSunshine │ ├── TesselationSetting.KoikatuSunshine.csproj │ ├── CharaExtra.cs │ └── TesselationSetting.cs ├── FreeHDefaults.Core │ ├── FreeHDefaults.Core.projitems │ ├── FreeHDefaults.Core.shproj │ └── Savedata.cs ├── CameraFrameMask.Core │ ├── CameraFrameMask.Core.projitems │ ├── CameraFrameMask.Core.shproj │ ├── MaskComponent.cs │ └── CameraFrameMask.cs ├── CameraFrameMask.KoikatuSunshine │ └── CameraFrameMask.KoikatuSunshine.csproj ├── StudioAddonLite.Core │ ├── StudioAddonLite.Core.projitems │ └── StudioAddonLite.Core.shproj ├── RealPOV.PlayHome │ ├── RealPOV.PlayHome.csproj │ └── RealPOV.cs ├── EyeLookEditor.Koikatu │ └── EyeLookEditor.Koikatu.csproj ├── MakerBridge.Koikatu │ └── MakerBridge.Koikatu.csproj ├── StudioAddonLite.KoikatuSunshine │ └── StudioAddonLite.KoikatuSunshine.csproj ├── DefaultParamEditor.Koikatu │ └── DefaultParamEditor.Koikatu.csproj ├── DefaultStudioScene.Koikatu │ └── DefaultStudioScene.Koikatu.csproj ├── TitleShortcuts.Koikatu │ └── TitleShortcuts.Koikatu.csproj ├── RealPOV.Core.Koikatu │ ├── RealPOV.Core.Koikatu.projitems │ ├── RealPOV.Core.Koikatu.shproj │ ├── CharaUtils.cs │ └── SceneDataController.cs ├── EyeLookEditor.KoikatuSunshine │ └── EyeLookEditor.KoikatuSunshine.csproj ├── DefaultStudioScene.KoikatuSunshine │ └── DefaultStudioScene.KoikatuSunshine.csproj ├── RealPOV.KoikatsuSunshine │ └── RealPOV.KoikatsuSunshine.csproj ├── DefaultStudioScene.AISyoujyo │ └── DefaultStudioScene.AISyoujyo.csproj ├── MakerBridge.Core │ ├── MakerBridge.Core.projitems │ ├── MakerBridge.Core.shproj │ ├── HandlerCore.cs │ ├── CharaCardWatcher.cs │ ├── MakerBridge.cs │ ├── StudioHandler.cs │ └── MakerHandler.cs ├── DefaultParamEditor.Core │ ├── DefaultParamEditor.Core.projitems │ └── DefaultParamEditor.Core.shproj ├── DefaultStudioScene.HoneySelect2 │ └── DefaultStudioScene.HoneySelect2.csproj ├── BetterSceneLoader.Koikatu │ └── BetterSceneLoader.Koikatu.csproj ├── CharaStateX.Core │ ├── CharaStateX.cs │ ├── CharaStateX.Core.shproj │ ├── CharaStateX.Core.projitems │ ├── Utils.cs │ ├── HandInfoPatch.cs │ ├── NeckLookPatch.cs │ ├── FKIKPatch.cs │ └── AnimationPatch.cs ├── CharaStateX.KoikatuSunshine │ └── CharaStateX.KoikatuSunshine.csproj ├── MakerBridge.KoikatuSunshine │ └── MakerBridge.KoikatuSunshine.csproj ├── AnimeAssAssistant.KoikatuSunshine │ └── AnimeAssAssistant.KoikatuSunshine.csproj ├── LightManager.Koikatu │ └── LightManager.Koikatu.csproj ├── LockOnPlugin.Core │ ├── LockOnPlugin.Core.shproj │ ├── LockOnPlugin.Core.projitems │ ├── MakerMono.cs │ ├── LockOnPluginData.json │ ├── TargetData.cs │ ├── KeyboardShortcutHotkey.cs │ └── HSceneMono.cs ├── TitleShortcuts.HoneySelect2 │ ├── TitleShortcuts.HoneySelect2.csproj │ └── TitleShortcuts.cs ├── AnimeAssAssistant.Koikatu │ └── AnimeAssAssistant.Koikatu.csproj ├── TitleShortcuts.KoikatuSunshine │ └── TitleShortcuts.KoikatuSunshine.csproj ├── ClothingStateMenuX.Koikatu │ └── ClothingStateMenuX.Koikatu.csproj ├── BuildSettings.Common.props ├── ItemLayerEdit.Koikatu │ └── ItemLayerEdit.Koikatu.csproj ├── ClothingStateMenuX.KoikatuSunshine │ └── ClothingStateMenuX.KoikatuSunshine.csproj ├── DefaultParamEditor.KoikatuSunshine │ └── DefaultParamEditor.KoikatuSunshine.csproj ├── BetterSceneLoader.KoikatuSunshine │ └── BetterSceneLoader.KoikatuSunshine.csproj ├── ItemLayerEdit.AISyoujyo │ └── ItemLayerEdit.AISyoujyo.csproj ├── ItemLayerEdit.HoneySelect2 │ └── ItemLayerEdit.HoneySelect2.csproj ├── ItemLayerEdit.KoikatuSunshine │ └── ItemLayerEdit.KoikatuSunshine.csproj └── LightManager.KoikatuSunshine │ └── LightManager.KoikatuSunshine.csproj ├── nuget.config ├── .github └── workflows │ ├── ci.yaml │ └── release.yaml └── release.ps1 /src/Common.Core/BuildNumber.cs: -------------------------------------------------------------------------------- 1 | internal static class BuildNumber 2 | { 3 | public const string Version = "1"; 4 | } 5 | -------------------------------------------------------------------------------- /src/BetterSceneLoader.Core/Resources/loadicon: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IllusionMods/KeelPlugins/HEAD/src/BetterSceneLoader.Core/Resources/loadicon -------------------------------------------------------------------------------- /src/BetterSceneLoader.Core/Resources/pluginicon: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IllusionMods/KeelPlugins/HEAD/src/BetterSceneLoader.Core/Resources/pluginicon -------------------------------------------------------------------------------- /src/UIUtility/Resources/DefaultResourcesHS.unity3d: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IllusionMods/KeelPlugins/HEAD/src/UIUtility/Resources/DefaultResourcesHS.unity3d -------------------------------------------------------------------------------- /src/UIUtility/Resources/DefaultResourcesKOI.unity3d: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IllusionMods/KeelPlugins/HEAD/src/UIUtility/Resources/DefaultResourcesKOI.unity3d -------------------------------------------------------------------------------- /src/BuildSettings.Patcher.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | net35 4 | $(SolutionDir)bin\$(Configuration)\Patchers 5 | 6 | -------------------------------------------------------------------------------- /src/BetterSceneLoader.Core/SortBy.cs: -------------------------------------------------------------------------------- 1 | namespace BetterSceneLoader 2 | { 3 | public enum SortBy 4 | { 5 | DateDescending, 6 | DateAscending, 7 | SizeDescending, 8 | SizeAscending 9 | } 10 | } -------------------------------------------------------------------------------- /src/SkipAllRefs.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/BuildSettings.Koikatu.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | net35 4 | $(SolutionDir)bin\$(Configuration)\KeelPluginsKK 5 | KK 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/BuildSettings.PlayHome.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | net35 4 | $(SolutionDir)bin\$(Configuration)\KeelPluginsPH 5 | PH 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/BuildSettings.AISyoujyo.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | net46 4 | $(SolutionDir)bin\$(Configuration)\KeelPluginsAI 5 | AI 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/BuildSettings.KoikatsuSunshine.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | net46 4 | $(SolutionDir)bin\$(Configuration)\KeelPluginsKKS 5 | KKS 6 | 7 | -------------------------------------------------------------------------------- /src/BuildSettings.HoneySelect2.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | net46 4 | $(SolutionDir)bin\$(Configuration)\KeelPluginsHS2 5 | HS2 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Common.Utils/Tuple.cs: -------------------------------------------------------------------------------- 1 | namespace KeelPlugins.Utils 2 | { 3 | internal struct Tuple 4 | { 5 | public readonly T1 Item1; 6 | public readonly T2 Item2; 7 | public Tuple(T1 item1, T2 item2) { Item1 = item1; Item2 = item2; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Common.Harmony/ReflectionExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace System.Reflection 2 | { 3 | public static class ReflectionExtensions 4 | { 5 | public static T[] GetCustomAttributes(this MemberInfo memberInfo, bool inherit) where T : Attribute 6 | { 7 | return memberInfo.GetCustomAttributes(typeof(T), inherit) as T[]; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/ItemLayerEdit.Core/LayerData.cs: -------------------------------------------------------------------------------- 1 | using MessagePack; 2 | using UnityEngine; 3 | 4 | namespace ItemLayerEdit.Koikatu 5 | { 6 | internal class LayerDataContainer : MonoBehaviour 7 | { 8 | public int DefaultLayer; 9 | } 10 | 11 | [MessagePackObject(true)] 12 | public class LayerSaveData 13 | { 14 | public int DefaultLayer; 15 | public int NewLayer; 16 | public int ObjectId; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Common.Unity/UnityEventExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace UnityEngine.Events 2 | { 3 | internal static class UnityEventExtensions 4 | { 5 | public static void ActuallyRemoveAllListeners(this UnityEventBase evt) 6 | { 7 | evt.RemoveAllListeners(); 8 | for(var i = 0; i < evt.GetPersistentEventCount(); i++) 9 | evt.SetPersistentListenerState(i, UnityEventCallState.Off); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/ItemLayerEdit.Core/Extensions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace ItemLayerEdit.Koikatu 4 | { 5 | public static class Extensions 6 | { 7 | public static void SetAllLayers(this GameObject gameObject, int layer) 8 | { 9 | gameObject.layer = layer; 10 | foreach(var child in gameObject.GetComponentsInChildren()) 11 | child.gameObject.layer = layer; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/UnityLogFilter/UnityLogFilter.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/AssOverride/AssOverride.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/RealPOV.Koikatu/RealPOV.Koikatu.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/LockOnPlugin.Koikatu/LockOnPlugin.Koikatu.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: push 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | - uses: actions/setup-dotnet@v4 11 | - name: Update build number 12 | run: echo "internal static class BuildNumber{public const string Version = \"${{ github.run_number }}\";}" > src/Common.Core/BuildNumber.cs 13 | - run: dotnet build --configuration Release 14 | - uses: actions/upload-artifact@v4 15 | with: 16 | name: ${{ github.event.repository.name }}_${{ github.sha }} 17 | path: bin/Release 18 | -------------------------------------------------------------------------------- /src/FreeHDefaults.KoikatuSunshine/FreeHDefaults.KoikatuSunshine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/TitleShortcuts.Core/TitleShortcutsCore.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | 3 | namespace TitleShortcuts.Core 4 | { 5 | public abstract class TitleShortcutsCore : BaseUnityPlugin 6 | { 7 | public const string GUID = "keelhauled.titleshortcuts"; 8 | public const string PluginName = "Title Shortcuts"; 9 | 10 | protected const string SECTION_HOTKEYS = "Keyboard shortcuts"; 11 | 12 | protected static TitleShortcutsCore Plugin; 13 | 14 | protected virtual void Awake() 15 | { 16 | Plugin = this; 17 | Log.SetLogSource(Logger); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/UIUtility/OneTimeVerticalLayoutGroup.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | 4 | namespace UILib 5 | { 6 | public class OneTimeVerticalLayoutGroup : VerticalLayoutGroup 7 | { 8 | public override void OnEnable() 9 | { 10 | base.OnEnable(); 11 | if(Application.isEditor == false || Application.isPlaying) 12 | this.ExecuteDelayed(() => enabled = false, 3); 13 | } 14 | 15 | public override void OnDisable() 16 | { 17 | } 18 | 19 | public void UpdateLayout() 20 | { 21 | enabled = true; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/UIUtility/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using UnityEngine; 4 | 5 | namespace UILib 6 | { 7 | internal static class Extensions 8 | { 9 | internal static void ExecuteDelayed(this MonoBehaviour self, Action action, int waitCount = 1) 10 | { 11 | self.StartCoroutine(ExecuteDelayed_Routine(action, waitCount)); 12 | } 13 | 14 | private static IEnumerator ExecuteDelayed_Routine(Action action, int waitCount) 15 | { 16 | for(int i = 0; i < waitCount; ++i) 17 | yield return null; 18 | action(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/RealPOV.Core/RealPOV.Core.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | a52280cd-3cc4-452a-8c11-67e440e0262f 7 | 8 | 9 | RealPOV.Core 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/MaterialLink.KoikatuSunshine/MaterialLink.KoikatuSunshine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/UIUtility/OneTimeHorizontalLayoutGroup.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | 4 | namespace UILib 5 | { 6 | public class OneTimeHorizontalLayoutGroup : HorizontalLayoutGroup 7 | { 8 | public override void OnEnable() 9 | { 10 | base.OnEnable(); 11 | if (Application.isEditor == false || Application.isPlaying) 12 | this.ExecuteDelayed(() => enabled = false, 3); 13 | } 14 | 15 | public override void OnDisable() 16 | { 17 | } 18 | 19 | public void UpdateLayout() 20 | { 21 | enabled = true; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/AltAutoMode.PlayHome/AltAutoMode.PlayHome.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/LightManager.Core/TrackTransform.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace LightManager.Core 4 | { 5 | internal class TrackTransform : MonoBehaviour 6 | { 7 | public string targetName; 8 | public Transform target; 9 | public int targetKey; 10 | public float rotationSpeed = 1f; 11 | 12 | private void Update() 13 | { 14 | if(target) 15 | { 16 | var rotation = Quaternion.LookRotation(target.position - transform.position); 17 | transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * rotationSpeed); 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/SoundEffects.PlayHome/SoundEffects.PlayHome.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/TitleShortcuts.Core/TitleShortcuts.Core.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 4d175c74-23cc-45db-8225-537db7e33142 7 | 8 | 9 | TitleShortcuts.Core 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/CameraFrameMask.Koikatu/CameraFrameMask.Koikatu.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/FreeHDefaults.Koikatu/FreeHDefaults.Koikatu.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/LockOnPlugin.KoikatuSunshine/LockOnPlugin.KoikatuSunshine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/Common.Unity/Common.Unity.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 50994af9-8369-47a9-a33a-37650e4b454e 7 | 8 | 9 | KeelPlugins.Unity 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/Common.Harmony/HarmonyExtensions.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System; 3 | using System.Reflection; 4 | 5 | namespace KeelPlugins.Harmony 6 | { 7 | public static class HarmonyExtensions 8 | { 9 | public static HarmonyLib.Harmony CreateAndPatchAll(Type type) 10 | { 11 | var harmony = new HarmonyLib.Harmony(Guid.NewGuid().ToString()); 12 | harmony.PatchAll(type); 13 | 14 | foreach(var method in type.GetMethods(AccessTools.all)) 15 | { 16 | foreach(var attr in method.GetCustomAttributes(false)) 17 | attr.Patch(harmony, method); 18 | } 19 | 20 | return harmony; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/AnimeAssAssistant.Core/AnimeAssAssistant.Core.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | {EDF05826-3E16-414F-AD86-A9FAABAD63FB} 7 | 8 | 9 | AnimeAssAssistant.Core 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/CharaStateX.Koikatu/CharaStateX.Koikatu.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/DefaultStudioScene.Core/DefaultStudioScene.Core.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 45def5dd-3617-482e-842f-b53ed60f59b6 7 | 8 | 9 | DefaultStudioScene.Core 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/EyeLookEditor.Core/DefaultValue.cs: -------------------------------------------------------------------------------- 1 | namespace EyeLookEditor 2 | { 3 | public static class DefaultValue 4 | { 5 | public const float ThresholdAngleDifference = 0f; 6 | public const float BendingMultiplier = 0.4f; 7 | public const float MaxAngleDifference = 10f; 8 | public const float UpBendingAngle = -66f; 9 | public const float DownBendingAngle = 25f; 10 | public const float MinBendingAngle = -36f; 11 | public const float MaxBendingAngle = 23f; 12 | public const float LeapSpeed = 38f; 13 | public const float ForntTagDis = 50f; 14 | public const float NearDis = 2f; 15 | public const float HAngleLimit = 110f; 16 | public const float VAngleLimit = 80f; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/ClothingStateMenuX.Core/ClothingStateMenuX.Core.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | {4DD73961-C8A1-429D-A756-D382A4259EBD} 7 | 8 | 9 | ClothingStateMenuX.Core 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/StudioAddonLite.Koikatu/StudioAddonLite.Koikatu.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Common.Core/Common.Core.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | dd7d6945-54a6-4190-8f49-46a189ee32cd 7 | 8 | 9 | KeelPlugins.Core 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/TitleShortcuts.AISyoujyo/TitleShortcuts.AISyoujyo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/TesselationSetting.KoikatuSunshine/TesselationSetting.KoikatuSunshine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/FreeHDefaults.Core/FreeHDefaults.Core.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | d77a4720-b234-4a59-b7ef-7f9abea81cd3 7 | 8 | 9 | FreeHDefaults.Core 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/CameraFrameMask.Core/CameraFrameMask.Core.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 327037cf-62f6-46c0-9e7c-4d46bed9e56b 7 | 8 | 9 | CameraFrameMask.Core 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/CameraFrameMask.KoikatuSunshine/CameraFrameMask.KoikatuSunshine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/StudioAddonLite.Core/StudioAddonLite.Core.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 5a380f5e-debf-48e6-934f-593f20e93aa2 7 | 8 | 9 | StudioAddonLite.Core 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/RealPOV.PlayHome/RealPOV.PlayHome.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/EyeLookEditor.Core/EyeLookEditor.Core.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | {A8893D39-4731-4260-8FF9-E71033FFCED1} 7 | 8 | 9 | EyeLookEditor.Core 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/EyeLookEditor.Koikatu/EyeLookEditor.Koikatu.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/MakerBridge.Koikatu/MakerBridge.Koikatu.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/StudioAddonLite.KoikatuSunshine/StudioAddonLite.KoikatuSunshine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/DefaultParamEditor.Koikatu/DefaultParamEditor.Koikatu.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/DefaultStudioScene.Koikatu/DefaultStudioScene.Koikatu.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/TitleShortcuts.Koikatu/TitleShortcuts.Koikatu.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/RealPOV.Core.Koikatu/RealPOV.Core.Koikatu.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 5034d4dd-f7d2-45c7-893f-9955098bff4b 7 | 8 | 9 | RealPOV.Core.Koikatu 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/LightManager.Core/LightManager.Core.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | d2938a42-199f-4a5b-8c9b-6592e9e53424 7 | 8 | 9 | LightManager.Core 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/Common.Utils/Lazy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace KeelPlugins.Utils 4 | { 5 | internal class Lazy 6 | { 7 | private readonly Func initializer; 8 | private T value; 9 | 10 | public Lazy(Func initializer) 11 | { 12 | this.initializer = initializer ?? throw new ArgumentNullException(nameof(initializer)); 13 | } 14 | 15 | public T Value 16 | { 17 | get 18 | { 19 | if(value == null) 20 | value = initializer(); 21 | return value; 22 | } 23 | } 24 | 25 | public static implicit operator Lazy(Func func) 26 | { 27 | return new Lazy(func); 28 | } 29 | 30 | public static implicit operator T(Lazy lazy) 31 | { 32 | return lazy.Value; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/EyeLookEditor.KoikatuSunshine/EyeLookEditor.KoikatuSunshine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/DefaultStudioScene.KoikatuSunshine/DefaultStudioScene.KoikatuSunshine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/RealPOV.KoikatsuSunshine/RealPOV.KoikatsuSunshine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/DefaultStudioScene.AISyoujyo/DefaultStudioScene.AISyoujyo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/ItemLayerEdit.Core/ItemLayerEdit.Core.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 6af96840-64fa-43da-93ca-43d5af47fd60 7 | 8 | 9 | ItemLayerEdit.Core 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/MakerBridge.Core/MakerBridge.Core.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 3b6cd84f-6327-46b6-91e1-5eb972bc60fe 7 | 8 | 9 | MakerBridge 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/BetterSceneLoader.Core/LoadingIcon.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | 4 | namespace BetterSceneLoader 5 | { 6 | public class LoadingIcon : MonoBehaviour 7 | { 8 | public static void Init(GameObject parent, Image image, float speed) 9 | { 10 | var icon = parent.AddComponent(); 11 | icon.image = image; 12 | icon.speed = speed; 13 | } 14 | 15 | public static int loadingCount = 0; 16 | private Image image; 17 | private float speed; 18 | 19 | private void Update() 20 | { 21 | if(loadingCount > 0) 22 | { 23 | if(!image.enabled) image.enabled = true; 24 | image.rectTransform.rotation *= Quaternion.Euler(0f, 0f, speed); 25 | } 26 | else 27 | { 28 | if(image.enabled) image.enabled = false; 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/DefaultParamEditor.Core/DefaultParamEditor.Core.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 30236263-c659-45ec-9a6c-7947830bb343 7 | 8 | 9 | DefaultParamEditor.Core 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/Common.Utils/Common.Utils.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | afc4ee66-2891-439a-925a-baf22553e1ba 7 | 8 | 9 | KeelPlugins.Utils 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/DefaultStudioScene.HoneySelect2/DefaultStudioScene.HoneySelect2.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/EyeLookEditor.Core/EyeLookEditor.Core.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {A8893D39-4731-4260-8FF9-E71033FFCED1} 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/BetterSceneLoader.Koikatu/BetterSceneLoader.Koikatu.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/AnimeAssAssistant.Core/AnimeAssAssistant.Core.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {EDF05826-3E16-414F-AD86-A9FAABAD63FB} 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/CharaStateX.Core/CharaStateX.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using HarmonyLib; 3 | using KeelPlugins; 4 | 5 | [assembly: System.Reflection.AssemblyVersion(CharaStateX.Koikatu.CharaStateX.Version)] 6 | 7 | namespace CharaStateX.Koikatu 8 | { 9 | [BepInProcess(Constants.StudioProcessName)] 10 | [BepInPlugin(GUID, "CharaStateX", Version)] 11 | public class CharaStateX : BaseUnityPlugin 12 | { 13 | public const string GUID = "keelhauled.charastatex"; 14 | public const string Version = "1.1.2." + BuildNumber.Version; 15 | 16 | private void Awake() 17 | { 18 | var harmony = new Harmony("keelhauled.charastatex.harmony"); 19 | harmony.PatchAll(typeof(AnimationPatch)); 20 | StateInfoPatch.Patch(harmony); 21 | NeckLookPatch.Patch(harmony); 22 | EtcInfoPatch.Patch(harmony); 23 | HandInfoPatch.Patch(harmony); 24 | JointInfoPatch.Patch(harmony); 25 | FKIKPatch.Patch(harmony); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/CharaStateX.KoikatuSunshine/CharaStateX.KoikatuSunshine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/MakerBridge.KoikatuSunshine/MakerBridge.KoikatuSunshine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/ClothingStateMenuX.Core/ClothingStateMenuX.Core.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {4DD73961-C8A1-429D-A756-D382A4259EBD} 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/UIUtility/UIUtility.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7f30866a-1b8b-40f1-8960-0e203eede225 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Common.Core/Common.Core.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | dd7d6945-54a6-4190-8f49-46a189ee32cd 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Common.Harmony/Common.Harmony.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 81e73402-3a7e-4ed3-b990-33c1b31fc205 7 | 8 | 9 | KeelPlugins.Harmony 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Common.Unity/Common.Unity.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 50994af9-8369-47a9-a33a-37650e4b454e 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Common.Utils/Common.Utils.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | afc4ee66-2891-439a-925a-baf22553e1ba 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/RealPOV.Core/RealPOV.Core.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | a52280cd-3cc4-452a-8c11-67e440e0262f 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Common.Harmony/Common.Harmony.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 81e73402-3a7e-4ed3-b990-33c1b31fc205 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/AnimeAssAssistant.KoikatuSunshine/AnimeAssAssistant.KoikatuSunshine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/CharaStateX.Core/CharaStateX.Core.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 66ededb6-34f2-4613-a6ff-450341da94ce 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/LightManager.Koikatu/LightManager.Koikatu.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/MakerBridge.Core/MakerBridge.Core.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 3b6cd84f-6327-46b6-91e1-5eb972bc60fe 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/FreeHDefaults.Core/FreeHDefaults.Core.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | d77a4720-b234-4a59-b7ef-7f9abea81cd3 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/ItemLayerEdit.Core/ItemLayerEdit.Core.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6af96840-64fa-43da-93ca-43d5af47fd60 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/LightManager.Core/LightManager.Core.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | d2938a42-199f-4a5b-8c9b-6592e9e53424 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/LockOnPlugin.Core/LockOnPlugin.Core.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 073d65ba-9bb7-4386-9b01-f86fa6df6984 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/CameraFrameMask.Core/CameraFrameMask.Core.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 327037cf-62f6-46c0-9e7c-4d46bed9e56b 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/RealPOV.Core.Koikatu/RealPOV.Core.Koikatu.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5034d4dd-f7d2-45c7-893f-9955098bff4b 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/StudioAddonLite.Core/StudioAddonLite.Core.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5a380f5e-debf-48e6-934f-593f20e93aa2 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/TitleShortcuts.Core/TitleShortcuts.Core.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4d175c74-23cc-45db-8225-537db7e33142 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/BetterSceneLoader.Core/BetterSceneLoader.Core.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 65d1defc-6733-47f3-84f8-1609c596fa5b 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/DefaultParamEditor.Core/DefaultParamEditor.Core.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 30236263-c659-45ec-9a6c-7947830bb343 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/DefaultStudioScene.Core/DefaultStudioScene.Core.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 45def5dd-3617-482e-842f-b53ed60f59b6 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/TitleShortcuts.HoneySelect2/TitleShortcuts.HoneySelect2.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/AnimeAssAssistant.Koikatu/AnimeAssAssistant.Koikatu.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/TitleShortcuts.KoikatuSunshine/TitleShortcuts.KoikatuSunshine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/FreeHDefaults.Core/Savedata.cs: -------------------------------------------------------------------------------- 1 | using System.Xml.Serialization; 2 | 3 | namespace FreeHDefaults.Koikatu 4 | { 5 | [XmlRoot] 6 | public class Savedata 7 | { 8 | [XmlElement] 9 | public string HeroinePath; 10 | 11 | [XmlElement] 12 | public string PartnerPath; 13 | 14 | [XmlElement] 15 | public string PlayerPath; 16 | 17 | [XmlElement] 18 | public int map; 19 | 20 | [XmlElement] 21 | public int timeZone; 22 | 23 | [XmlElement] 24 | public int stageH1; 25 | 26 | [XmlElement] 27 | public int stageH2; 28 | 29 | [XmlElement] 30 | public int statusH; 31 | 32 | [XmlElement] 33 | public bool discovery; 34 | 35 | [XmlElement] 36 | public int category; 37 | 38 | [XmlElement] 39 | public bool isAibuSelect = true; 40 | 41 | [XmlElement] 42 | public float Fov = 23f; 43 | 44 | [XmlElement] 45 | public float LightX; 46 | [XmlElement] 47 | public float LightY; 48 | [XmlElement] 49 | public float LightZ; 50 | } 51 | } -------------------------------------------------------------------------------- /src/Common.Unity/UnityExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace UnityEngine 2 | { 3 | internal static class UnityExtensions 4 | { 5 | public static bool AddComponentIfNotExist(this GameObject gameObject, out T component) where T : MonoBehaviour 6 | { 7 | if(gameObject.GetComponent()) 8 | { 9 | component = null; 10 | return false; 11 | } 12 | else 13 | { 14 | component = gameObject.AddComponent(); 15 | return true; 16 | } 17 | } 18 | 19 | public static Transform FindRecursive(this Transform parent, string childName) 20 | { 21 | foreach(Transform child in parent) 22 | { 23 | if(child.name == childName) 24 | { 25 | return child; 26 | } 27 | else 28 | { 29 | var found = FindRecursive(child, childName); 30 | if (found != null) 31 | return found; 32 | } 33 | } 34 | return null; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/ClothingStateMenuX.Koikatu/ClothingStateMenuX.Koikatu.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/MakerBridge.Core/HandlerCore.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using UnityEngine; 3 | 4 | namespace MakerBridge 5 | { 6 | internal abstract class HandlerCore : MonoBehaviour 7 | { 8 | protected FileSystemWatcher watcher; 9 | 10 | protected abstract string WatchedFilePath { get; } 11 | protected abstract string OutputFilePath { get; } 12 | 13 | protected abstract void SaveCharacter(string path); 14 | protected abstract void LoadCharacter(string path); 15 | 16 | private void Start() 17 | { 18 | watcher = CharaCardWatcher.Watch(WatchedFilePath, LoadCharacter); 19 | watcher.EnableRaisingEvents = true; 20 | } 21 | 22 | private void Update() 23 | { 24 | if(MakerBridge.SendChara.Value.IsDown()) 25 | SaveCharacter(OutputFilePath); 26 | } 27 | 28 | private void OnEnable() 29 | { 30 | if(watcher != null) 31 | watcher.EnableRaisingEvents = true; 32 | } 33 | 34 | private void OnDisable() 35 | { 36 | if(watcher != null) 37 | watcher.EnableRaisingEvents = false; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/UIUtility/UILibResource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Reflection; 4 | 5 | namespace UILib 6 | { 7 | internal static class UILibResource 8 | { 9 | public static byte[] LoadEmbeddedResource(Assembly callingAssembly, string resourceName) 10 | { 11 | try 12 | { 13 | using(var stream = callingAssembly.GetManifestResourceStream(resourceName)) 14 | { 15 | return ReadFully(stream); 16 | } 17 | } 18 | catch(Exception) 19 | { 20 | Console.WriteLine($"Error accessing resources ({resourceName})"); 21 | throw; 22 | } 23 | } 24 | 25 | public static byte[] ReadFully(Stream input) 26 | { 27 | byte[] buffer = new byte[16 * 1024]; 28 | using(MemoryStream ms = new MemoryStream()) 29 | { 30 | int read; 31 | while((read = input.Read(buffer, 0, buffer.Length)) > 0) 32 | { 33 | ms.Write(buffer, 0, read); 34 | } 35 | return ms.ToArray(); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/AssOverride/AssOverride.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using Mono.Cecil; 5 | 6 | namespace AssOverride 7 | { 8 | public class AssOverride 9 | { 10 | public const string Version = "1.0.1." + BuildNumber.Version; 11 | 12 | private static readonly Dictionary asses = new Dictionary(); 13 | 14 | public static IEnumerable TargetDLLs => GetDLLs(); 15 | public static IEnumerable GetDLLs() 16 | { 17 | foreach(var file in Directory.GetFiles("blaablaa", "*.dll")) 18 | { 19 | var filename = Path.GetFileName(file); 20 | var filenameNoExtension = Path.GetFileNameWithoutExtension(file); 21 | asses.Add(filenameNoExtension, file); 22 | yield return filename; 23 | } 24 | } 25 | 26 | public static void Patch(ref AssemblyDefinition ass) 27 | { 28 | if(asses.TryGetValue(ass.Name.Name, out var path)) 29 | { 30 | ass = AssemblyDefinition.ReadAssembly(path); 31 | Console.Write($"Replacing {ass.Name.Name}"); 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/BuildSettings.Common.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | embedded 4 | false 5 | false 6 | false 7 | false 8 | $(SolutionDir)bin\$(Configuration) 9 | true 10 | https://gitgoon.dev/IllusionMods/KeelPlugins 11 | GPL-3.0 license, 2019 12 | preview 13 | true 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/LightManager.Core/LightManagerPlugin.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using HarmonyLib; 3 | using KeelPlugins; 4 | using KKAPI.Studio.SaveLoad; 5 | using UnityEngine; 6 | 7 | [assembly: System.Reflection.AssemblyVersion(LightManager.Koikatu.LightManagerPlugin.Version)] 8 | 9 | namespace LightManager.Koikatu 10 | { 11 | [BepInDependency(KKAPI.KoikatuAPI.GUID)] 12 | [BepInProcess(Constants.StudioProcessName)] 13 | [BepInPlugin(GUID, "Light Manager", Version)] 14 | public class LightManagerPlugin : BaseUnityPlugin 15 | { 16 | public const string GUID = "keelhauled.lightmanager"; 17 | public const string Version = "1.0.2." + BuildNumber.Version; 18 | 19 | private static GameObject bepinex; 20 | 21 | private void Awake() 22 | { 23 | bepinex = gameObject; 24 | Harmony.CreateAndPatchAll(typeof(Hooks)); 25 | StudioSaveLoadApi.RegisterExtraBehaviour(GUID); 26 | } 27 | 28 | private class Hooks 29 | { 30 | [HarmonyPrefix, HarmonyPatch(typeof(StudioScene), "Start")] 31 | public static void Entrypoint() 32 | { 33 | bepinex.GetOrAddComponent(); 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/UIUtility/UIUtility.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 7f30866a-1b8b-40f1-8960-0e203eede225 7 | 8 | 9 | UILib 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/ItemLayerEdit.Koikatu/ItemLayerEdit.Koikatu.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/LockOnPlugin.Core/LockOnPlugin.Core.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 073d65ba-9bb7-4386-9b01-f86fa6df6984 7 | 8 | 9 | LockOnPlugin 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/CharaStateX.Core/CharaStateX.Core.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 66ededb6-34f2-4613-a6ff-450341da94ce 7 | 8 | 9 | CharaStateX.Core 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/RealPOV.Core.Koikatu/CharaUtils.cs: -------------------------------------------------------------------------------- 1 | namespace RealPOV.Koikatu 2 | { 3 | internal static class CharaUtils 4 | { 5 | public static void SetNeckLook(this ChaControl chara, NECK_LOOK_TYPE_VER2 necktype) 6 | { 7 | for(int i = 0; i < chara.neckLookCtrl.neckLookScript.neckTypeStates.Length; i++) 8 | { 9 | if(chara.neckLookCtrl.neckLookScript.neckTypeStates[i].lookType == necktype) 10 | chara.neckLookCtrl.ptnNo = i; 11 | } 12 | } 13 | 14 | public static void SetEyeLook(this ChaControl chara, EYE_LOOK_TYPE eyetype) 15 | { 16 | for(int i = 0; i < chara.eyeLookCtrl.eyeLookScript.eyeTypeStates.Length; i++) 17 | { 18 | if(chara.eyeLookCtrl.eyeLookScript.eyeTypeStates[i].lookType == eyetype) 19 | chara.eyeLookCtrl.ptnNo = i; 20 | } 21 | } 22 | 23 | public static NECK_LOOK_TYPE_VER2 GetNeckLook(this ChaControl chara) 24 | { 25 | return chara.neckLookCtrl.neckLookScript.neckTypeStates[chara.neckLookCtrl.ptnNo].lookType; 26 | } 27 | 28 | public static EYE_LOOK_TYPE GetEyeLook(this ChaControl chara) 29 | { 30 | return chara.eyeLookCtrl.eyeLookScript.eyeTypeStates[chara.eyeLookCtrl.ptnNo].lookType; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Common.Core/Log.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using BepInEx.Logging; 4 | 5 | internal static class Log 6 | { 7 | private static ManualLogSource _logSource; 8 | 9 | public static void SetLogSource(ManualLogSource logSource) 10 | { 11 | _logSource = logSource; 12 | } 13 | 14 | public static void Info(object data) => CheckAndRunLogger(() => _logSource.LogInfo(data)); 15 | public static void Debug(object data) => CheckAndRunLogger(() => _logSource.LogDebug(data)); 16 | public static void Error(object data) => CheckAndRunLogger(() => _logSource.LogError(data)); 17 | public static void Fatal(object data) => CheckAndRunLogger(() => _logSource.LogFatal(data)); 18 | public static void Message(object data) => CheckAndRunLogger(() => _logSource.LogMessage(data)); 19 | public static void Warning(object data) => CheckAndRunLogger(() => _logSource.LogWarning(data)); 20 | public static void Level(BepInEx.Logging.LogLevel level, object data) => CheckAndRunLogger(() => _logSource.Log(level, data)); 21 | 22 | private static void CheckAndRunLogger(Action action) 23 | { 24 | if(_logSource == null) 25 | { 26 | Console.WriteLine($"Use {nameof(SetLogSource)} before logging. {new StackTrace().ToString()}"); 27 | return; 28 | } 29 | 30 | action(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/BetterSceneLoader.Core/BetterSceneLoader.Core.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 65d1defc-6733-47f3-84f8-1609c596fa5b 7 | 8 | 9 | BetterSceneLoader.Core 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/ClothingStateMenuX.KoikatuSunshine/ClothingStateMenuX.KoikatuSunshine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: workflow_dispatch 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Gather info 10 | id: info 11 | run: | 12 | DATE=$(date +'%Y-%m-%d') 13 | echo "date=$DATE" >> $GITHUB_OUTPUT 14 | echo "file=${{ github.event.repository.name }}_$DATE.zip" >> $GITHUB_OUTPUT 15 | 16 | - uses: actions/checkout@v4 17 | with: 18 | fetch-depth: 0 # for creating the changelog 19 | - uses: actions/setup-dotnet@v4 20 | - run: dotnet build --configuration Release 21 | 22 | - name: Create release notes 23 | continue-on-error: true 24 | run: | 25 | echo "## Changelog" >> body.md 26 | LATEST_TAG=$(git describe --tags --abbrev=0) 27 | git log $LATEST_TAG..HEAD --pretty=format:"* %s" >> body.md 28 | echo "" >> body.md 29 | echo "**Full Changelog**: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/compare/$LATEST_TAG...${{ steps.info.outputs.date }}" >> body.md 30 | 31 | - name: Create zip 32 | run: | 33 | cd bin/Release 34 | zip -r ${{ steps.info.outputs.file }} * 35 | - uses: softprops/action-gh-release@v2 36 | with: 37 | draft: true 38 | generate_release_notes: false 39 | files: bin/Release/${{ steps.info.outputs.file }} 40 | tag_name: ${{ steps.info.outputs.date }} 41 | body_path: body.md 42 | -------------------------------------------------------------------------------- /src/BetterSceneLoader.Core/AutoGridLayout.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | 4 | namespace BetterSceneLoader 5 | { 6 | public class AutoGridLayout : GridLayoutGroup 7 | { 8 | public bool m_IsColumn; 9 | public int m_Column = 1, m_Row = 1; 10 | public float aspectRatio = 16f / 9f; 11 | 12 | public override void CalculateLayoutInputHorizontal() 13 | { 14 | base.CalculateLayoutInputHorizontal(); 15 | if(m_IsColumn) 16 | { 17 | float iColumn = m_Column; 18 | if(iColumn <= 0) 19 | { 20 | iColumn = 1; 21 | } 22 | float fWidth = rectTransform.rect.width - (iColumn - 1) * spacing.x - (padding.right + padding.left); 23 | float width = fWidth / iColumn; 24 | cellSize = new Vector2(width, width / aspectRatio); 25 | } 26 | else 27 | { 28 | float iRow = m_Row; 29 | if(iRow <= 0) 30 | { 31 | iRow = 1; 32 | } 33 | float fHeight = rectTransform.rect.height - (iRow - 1) * spacing.y - (padding.top + padding.bottom); 34 | float height = fHeight / iRow; 35 | cellSize = new Vector2(height * aspectRatio, height); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/TesselationSetting.KoikatuSunshine/CharaExtra.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using KKAPI; 3 | using KKAPI.Chara; 4 | using UnityEngine; 5 | 6 | namespace TesselationSetting.Koikatu 7 | { 8 | public class CharaExtra : CharaCustomFunctionController 9 | { 10 | protected override void OnCardBeingSaved(GameMode currentGameMode) 11 | { 12 | 13 | } 14 | 15 | protected override void OnReload(GameMode currentGameMode) 16 | { 17 | StartCoroutine(Coroutine()); 18 | 19 | IEnumerator Coroutine() 20 | { 21 | for(int i = 0; i < 10; i++) 22 | yield return null; 23 | 24 | SetRendererTesselation(ChaControl.rendBody); 25 | SetRendererTesselation(ChaControl.rendFace); 26 | } 27 | } 28 | 29 | private static void SetRendererTesselation(Renderer rend) 30 | { 31 | if(rend.material && rend.material.shader.name == "xukmi/SkinPlusTess") 32 | { 33 | if(rend.material.HasProperty("_TessSmooth")) 34 | { 35 | Log.Info($"Set TessSmooth {TesselationSetting.TessSmooth.Value} '{rend.material.name}'"); 36 | rend.material.SetFloat("_TessSmooth", TesselationSetting.TessSmooth.Value); 37 | } 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/CharaStateX.Core/Utils.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using Studio; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | 7 | namespace CharaStateX.Koikatu 8 | { 9 | internal static class Utils 10 | { 11 | public static IEnumerable GetSelectedCharacters() 12 | { 13 | return GuideObjectManager.Instance.selectObjectKey.Select(x => Studio.Studio.GetCtrlInfo(x) as OCIChar).Where(x => x != null); 14 | } 15 | 16 | public static IEnumerable GetAllSelectedButMain(object __instance) 17 | { 18 | var mainChara = GetMainChara(__instance); 19 | return GetSelectedCharacters().Where(chara => chara != mainChara); 20 | } 21 | 22 | public static OCIChar GetMainChara(object __instance) 23 | { 24 | if(__instance == null) throw new ArgumentNullException(nameof(__instance)); 25 | var property = __instance.GetType().GetProperty("ociChar", AccessTools.all); 26 | if(property == null) throw new ArgumentException("Could not find property ociChar"); 27 | return (OCIChar)property.GetValue(__instance, null); 28 | } 29 | 30 | public static bool GetIsUpdateInfo(object __instance) 31 | { 32 | var propInfo = AccessTools.Property(__instance.GetType(), "isUpdateInfo"); 33 | return (bool)propInfo.GetValue(__instance, null); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/TesselationSetting.KoikatuSunshine/TesselationSetting.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using BepInEx; 3 | using BepInEx.Configuration; 4 | using KeelPlugins; 5 | using KKAPI; 6 | using UnityEngine; 7 | 8 | [assembly: System.Reflection.AssemblyVersion(TesselationSetting.Koikatu.TesselationSetting.Version)] 9 | 10 | namespace TesselationSetting.Koikatu 11 | { 12 | [BepInProcess(Constants.MainGameProcessName)] 13 | [BepInProcess(Constants.MainGameProcessNameSteam)] 14 | [BepInDependency(KoikatuAPI.GUID)] 15 | [BepInPlugin(GUID, PluginName, Version)] 16 | public class TesselationSetting : BaseUnityPlugin 17 | { 18 | public const string GUID = "keelhauled.tesselationsetting"; 19 | public const string PluginName = "TesselationSetting"; 20 | public const string Version = "1.0.0." + BuildNumber.Version; 21 | 22 | public static ConfigEntry TessSmooth { get; set; } 23 | 24 | private static TesselationSetting plugin; 25 | private static readonly List ManagedRenderers = new List(); 26 | 27 | private void Awake() 28 | { 29 | plugin = this; 30 | Log.SetLogSource(Logger); 31 | 32 | TessSmooth = Config.Bind("General", "TessSmooth", 0f, new ConfigDescription("", new AcceptableValueRange(0f, 1f))); 33 | 34 | KKAPI.Chara.CharacterApi.RegisterExtraBehaviour(GUID); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/CharaStateX.Core/HandInfoPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using Studio; 3 | 4 | namespace CharaStateX.Koikatu 5 | { 6 | internal static class HandInfoPatch 7 | { 8 | public static void Patch(Harmony harmony) 9 | { 10 | var type = typeof(MPCharCtrl).GetNestedType("HandInfo", AccessTools.all); 11 | 12 | { 13 | var target = AccessTools.Method(type, "ChangeLeftHandAnime"); 14 | var patch = AccessTools.Method(typeof(HandInfoPatch), nameof(Patch_ChangeLeftHandAnime)); 15 | harmony.Patch(target, null, new HarmonyMethod(patch)); 16 | } 17 | 18 | { 19 | var target = AccessTools.Method(type, "ChangeRightHandAnime"); 20 | var patch = AccessTools.Method(typeof(HandInfoPatch), nameof(Patch_ChangeRightHandAnime)); 21 | harmony.Patch(target, null, new HarmonyMethod(patch)); 22 | } 23 | } 24 | 25 | private static void Patch_ChangeLeftHandAnime(object __instance, ref int _no) 26 | { 27 | if(Utils.GetIsUpdateInfo(__instance)) return; 28 | 29 | foreach(var chara in Utils.GetAllSelectedButMain(__instance)) 30 | chara.ChangeHandAnime(0, _no); 31 | } 32 | 33 | private static void Patch_ChangeRightHandAnime(object __instance, ref int _no) 34 | { 35 | if(Utils.GetIsUpdateInfo(__instance)) return; 36 | 37 | foreach(var chara in Utils.GetAllSelectedButMain(__instance)) 38 | chara.ChangeHandAnime(1, _no); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/DefaultParamEditor.KoikatuSunshine/DefaultParamEditor.KoikatuSunshine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Common.Harmony/EventFactory.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System; 3 | using System.Reflection; 4 | using System.Runtime.CompilerServices; 5 | 6 | namespace KeelPlugins.Harmony 7 | { 8 | internal static class EventFactory 9 | { 10 | private static Harmony harmony = new Harmony("KeelPlugins.EventFactory"); 11 | private static MultiKeyDictionary methods = new MultiKeyDictionary(); 12 | 13 | [MethodImpl(MethodImplOptions.Synchronized)] 14 | public static void AddAccessor(Action e, Action value, Type type, string name, MethodInfo patch) 15 | { 16 | LazyPatch(type, name, patch); 17 | e += value; 18 | } 19 | 20 | [MethodImpl(MethodImplOptions.Synchronized)] 21 | public static void RemoveAccessor(Action e, Action value) 22 | { 23 | e -= value; 24 | } 25 | 26 | private static void LazyPatch(Type type, string name, MethodInfo patch) 27 | { 28 | if(!methods.TryGetValue(type, name, out _)) 29 | { 30 | var methodInfo = AccessTools.Method(type, name); 31 | harmony.Patch(methodInfo, new HarmonyMethod(patch)); 32 | methods.Add(type, name, methodInfo); 33 | } 34 | } 35 | 36 | public static void InvokeEvent(Action e) 37 | { 38 | if(e != null) 39 | { 40 | foreach(var @delegate in e.GetInvocationList()) 41 | ((Action)@delegate).Invoke(); 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/MakerBridge.Core/CharaCardWatcher.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using System; 3 | using System.IO; 4 | using System.Threading; 5 | 6 | namespace MakerBridge 7 | { 8 | internal static class CharaCardWatcher 9 | { 10 | public static FileSystemWatcher Watch(string filePath, Action fileChangeCompleted) 11 | { 12 | var watcher = new FileSystemWatcher 13 | { 14 | Path = Path.GetDirectoryName(filePath), 15 | Filter = $"{Path.GetFileNameWithoutExtension(filePath)}*{Path.GetExtension(filePath)}" 16 | }; 17 | 18 | void handler(object sender, FileSystemEventArgs e) => FileChanged(e, fileChangeCompleted); 19 | watcher.Created += handler; 20 | watcher.Changed += handler; 21 | 22 | return watcher; 23 | } 24 | 25 | private static void FileChanged(FileSystemEventArgs e, Action fileChangeCompleted) 26 | { 27 | bool fileIsBusy = true; 28 | while(fileIsBusy) 29 | { 30 | try 31 | { 32 | using(File.Open(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.Read)){ } 33 | fileIsBusy = false; 34 | } 35 | catch(IOException) 36 | { 37 | Thread.Sleep(100); 38 | } 39 | } 40 | 41 | ThreadingHelper.Instance.StartSyncInvoke(() => 42 | { 43 | fileChangeCompleted(e.FullPath); 44 | File.Delete(e.FullPath); 45 | }); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Common.Core/Constants.cs: -------------------------------------------------------------------------------- 1 | namespace KeelPlugins 2 | { 3 | public static class Constants 4 | { 5 | #if AI 6 | public const string MainGameProcessName = "AI-Syoujyo"; 7 | public const string MainGameProcessNameSteam = "AI-Shoujo"; 8 | public const string StudioProcessName = "StudioNEOV2"; 9 | #elif HS2 10 | public const string MainGameProcessName = "HoneySelect2"; 11 | public const string MainGameProcessNameSteam = MainGameProcessName; 12 | public const string VRProcessName = "HoneySelect2VR"; 13 | public const string StudioProcessName = "StudioNEOV2"; 14 | #elif KK 15 | public const string MainGameProcessName = "Koikatu"; 16 | public const string MainGameProcessNameSteam = "Koikatsu Party"; 17 | public const string VRProcessName = "KoikatsuVR"; 18 | public const string VRProcessNameSteam = "Koikatsu Party VR"; 19 | public const string StudioProcessName = "CharaStudio"; 20 | #elif KKS 21 | public const string MainGameProcessName = "KoikatsuSunshine"; 22 | public const string MainGameProcessNameSteam = MainGameProcessName; 23 | public const string VRProcessName = "KoikatsuSunshine_VR"; 24 | public const string VRProcessNameSteam = VRProcessName; 25 | public const string StudioProcessName = "CharaStudio"; 26 | #elif PH 27 | public const string MainGameProcessName64bit = "PlayHome64bit"; 28 | public const string MainGameProcessName32bit = "PlayHome32bit"; 29 | public const string StudioProcessName64bit = "PlayHomeStudio64bit"; 30 | public const string StudioProcessName32bit = "PlayHomeStudio32bit"; 31 | #endif 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/BetterSceneLoader.KoikatuSunshine/BetterSceneLoader.KoikatuSunshine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Common.Utils/Resource.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Reflection; 3 | 4 | namespace KeelPlugins.Utils 5 | { 6 | internal static class Resource 7 | { 8 | public static byte[] GetResourceAsBytes(Assembly assembly, string resourceName) 9 | { 10 | using(var stream = GetManifestResourceStream(assembly, resourceName)) 11 | using(var mem = new MemoryStream()) 12 | { 13 | CopyTo(stream, mem); 14 | return mem.ToArray(); 15 | } 16 | } 17 | 18 | public static string GetResourceAsString(Assembly assembly, string resourceName) 19 | { 20 | using(var stream = GetManifestResourceStream(assembly, resourceName)) 21 | using(var reader = new StreamReader(stream)) 22 | return reader.ReadToEnd(); 23 | } 24 | 25 | private static Stream GetManifestResourceStream(Assembly assembly, string resourceName) 26 | { 27 | var resourcePath = $"{assembly.GetName().Name}.{resourceName}"; 28 | var res = assembly.GetManifestResourceStream(resourcePath); 29 | 30 | if(res == null) 31 | throw new FileNotFoundException(resourcePath); 32 | 33 | return res; 34 | } 35 | 36 | private static void CopyTo(Stream input, Stream outputStream) 37 | { 38 | byte[] buffer = new byte[16 * 1024]; // Fairly arbitrary size 39 | int bytesRead; 40 | while((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0) 41 | { 42 | outputStream.Write(buffer, 0, bytesRead); 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/SoundEffects.PlayHome/SoundEffects.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using HarmonyLib; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using UnityEngine; 7 | 8 | [assembly: System.Reflection.AssemblyVersion(SoundEffects.PlayHome.SoundEffects.Version)] 9 | 10 | namespace SoundEffects.PlayHome 11 | { 12 | [BepInPlugin(GUID, PluginName, Version)] 13 | internal class SoundEffects : BaseUnityPlugin 14 | { 15 | public const string GUID = "keelhauled.soundeffects"; 16 | public const string PluginName = "SoundEffects"; 17 | public const string Version = "1.0.2." + BuildNumber.Version; 18 | 19 | private Harmony harmony; 20 | private static List slaps = new List(); 21 | 22 | private void Awake() 23 | { 24 | harmony = Harmony.CreateAndPatchAll(GetType()); 25 | var soundDir = Path.Combine(Path.GetDirectoryName(Info.Location), PluginName); 26 | slaps = Directory.GetFiles(soundDir, "*.wav").Select(ExternalAudioClip.Load).ToList(); 27 | } 28 | 29 | #if DEBUG 30 | private void OnDestroy() 31 | { 32 | harmony.UnpatchSelf(); 33 | } 34 | #endif 35 | 36 | [HarmonyPrefix, HarmonyPatch(typeof(H_SE), nameof(H_SE.Play_Piston))] 37 | private static bool CustomSound(H_SE __instance, Female female) 38 | { 39 | if(slaps.Count > 0) 40 | { 41 | var random = Random.Range(0, slaps.Count - 1); 42 | __instance.gameCtrl.audioCtrl.Play3DSE(slaps[random], female.CrotchTrans.position); 43 | return false; 44 | } 45 | 46 | return true; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/CharaStateX.Core/NeckLookPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using Studio; 3 | 4 | namespace CharaStateX.Koikatu 5 | { 6 | internal static class NeckLookPatch 7 | { 8 | public static void Patch(Harmony harmony) 9 | { 10 | { 11 | var type = typeof(MPCharCtrl).GetNestedType("LookAtInfo", AccessTools.all); 12 | var target = AccessTools.Method(type, "OnClick"); 13 | var patch = AccessTools.Method(typeof(NeckLookPatch), nameof(Patch_LookAtInfo_OnClick)); 14 | harmony.Patch(target, null, new HarmonyMethod(patch)); 15 | } 16 | 17 | { 18 | var type = typeof(MPCharCtrl).GetNestedType("NeckInfo", AccessTools.all); 19 | var target = AccessTools.Method(type, "OnClick"); 20 | var patch = AccessTools.Method(typeof(NeckLookPatch), nameof(Patch_NeckInfo_OnClick)); 21 | harmony.Patch(target, null, new HarmonyMethod(patch)); 22 | } 23 | } 24 | 25 | private static void Patch_LookAtInfo_OnClick(object __instance, ref int _no) 26 | { 27 | if(Utils.GetIsUpdateInfo(__instance)) return; 28 | 29 | foreach(var chara in Utils.GetAllSelectedButMain(__instance)) 30 | chara.ChangeLookEyesPtn(_no); 31 | } 32 | 33 | private static void Patch_NeckInfo_OnClick(object __instance, ref int _idx) 34 | { 35 | if(Utils.GetIsUpdateInfo(__instance)) return; 36 | var patterns = Traverse.Create(__instance).Field("patterns").GetValue(); 37 | 38 | foreach(var chara in Utils.GetAllSelectedButMain(__instance)) 39 | chara.ChangeLookNeckPtn(patterns[_idx]); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Common.Harmony/HarmonyPatchExt.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System; 3 | using System.Reflection; 4 | 5 | namespace KeelPlugins.Harmony 6 | { 7 | [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)] 8 | public sealed class HarmonyPatchExtAttribute : Attribute 9 | { 10 | private readonly MethodInfo targetMethod; 11 | private readonly bool firstRun = true; 12 | 13 | public HarmonyPatchExtAttribute(Type targetType, string targetMethodName, Type[] paramTypes = null, Type[] genericTypes = null) 14 | { 15 | if(firstRun) 16 | { 17 | firstRun = false; 18 | targetMethod = AccessTools.Method(targetType, targetMethodName, paramTypes, genericTypes); 19 | } 20 | } 21 | 22 | /// 23 | /// 24 | /// 25 | /// Fully qualified type name with assembly name 26 | /// 27 | /// 28 | /// 29 | public HarmonyPatchExtAttribute(string targetTypeName, string targetMethodName, Type[] paramTypes = null, Type[] genericTypes = null) 30 | { 31 | if(firstRun) 32 | { 33 | firstRun = false; 34 | var targetType = Type.GetType(targetTypeName); 35 | targetMethod = AccessTools.Method(targetType, targetMethodName, paramTypes, genericTypes); 36 | } 37 | } 38 | 39 | public void Patch(HarmonyLib.Harmony harmony, MethodInfo patchmethod) 40 | { 41 | harmony.Patch(targetMethod, new HarmonyMethod(patchmethod)); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/RealPOV.Core.Koikatu/SceneDataController.cs: -------------------------------------------------------------------------------- 1 | using ExtensibleSaveFormat; 2 | using KKAPI.Studio.SaveLoad; 3 | using KKAPI.Utilities; 4 | using MessagePack; 5 | using Studio; 6 | using UnityEngine; 7 | 8 | namespace RealPOV.Koikatu 9 | { 10 | public class SceneDataController : SceneCustomFunctionController 11 | { 12 | private const string DictID = "PovData"; 13 | 14 | protected override void OnSceneLoad(SceneOperationKind operation, ReadOnlyDictionary loadedItems) 15 | { 16 | var extData = GetExtendedData(); 17 | if(extData == null) 18 | return; 19 | 20 | if(operation == SceneOperationKind.Load && extData.data.TryGetValue(DictID, out var povRawData)) 21 | { 22 | var povData = MessagePackSerializer.Deserialize((byte[])povRawData); 23 | if(povData.FormatVersion < 1) 24 | povData.CharaPrevVisibleHeadAlways = true; 25 | RealPOV.EnablePov(povData); 26 | } 27 | } 28 | 29 | protected override void OnSceneSave() 30 | { 31 | var povData = RealPOV.GetPovData(); 32 | if(povData != null) 33 | { 34 | var pluginData = new PluginData(); 35 | pluginData.data.Add(DictID, MessagePackSerializer.Serialize(povData)); 36 | SetExtendedData(pluginData); 37 | } 38 | } 39 | } 40 | 41 | [MessagePackObject(true)] 42 | public class ScenePovData 43 | { 44 | public int FormatVersion = 1; 45 | public Vector3 Rotation; 46 | public int CharaId; 47 | public bool CharaPrevVisibleHeadAlways; 48 | public float Fov; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/CharaStateX.Core/FKIKPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using Studio; 3 | 4 | namespace CharaStateX.Koikatu 5 | { 6 | internal static class FKIKPatch 7 | { 8 | public static void Patch(Harmony harmony) 9 | { 10 | { 11 | var type = typeof(MPCharCtrl).GetNestedType("FKInfo", AccessTools.all); 12 | var target = AccessTools.Method(type, "OnChangeValueFunction"); 13 | var patch = AccessTools.Method(typeof(FKIKPatch), nameof(Patch_FKInfo_OnChangeValueFunction)); 14 | harmony.Patch(target, null, new HarmonyMethod(patch)); 15 | } 16 | 17 | { 18 | var type = typeof(MPCharCtrl).GetNestedType("IKInfo", AccessTools.all); 19 | var target = AccessTools.Method(type, "OnChangeValueFunction"); 20 | var patch = AccessTools.Method(typeof(FKIKPatch), nameof(Patch_IKInfo_OnChangeValueFunction)); 21 | harmony.Patch(target, null, new HarmonyMethod(patch)); 22 | } 23 | } 24 | 25 | private static void Patch_FKInfo_OnChangeValueFunction(object __instance, ref bool _value) 26 | { 27 | if(Utils.GetIsUpdateInfo(__instance)) return; 28 | 29 | foreach(var chara in Utils.GetAllSelectedButMain(__instance)) 30 | chara.ActiveKinematicMode(OICharInfo.KinematicMode.FK, _value, false); 31 | } 32 | 33 | private static void Patch_IKInfo_OnChangeValueFunction(object __instance, ref bool _value) 34 | { 35 | if(Utils.GetIsUpdateInfo(__instance)) return; 36 | 37 | foreach(var chara in Utils.GetAllSelectedButMain(__instance)) 38 | chara.ActiveKinematicMode(OICharInfo.KinematicMode.IK, _value, false); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/CameraFrameMask.Core/MaskComponent.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace CameraFrameMask.Koikatu 4 | { 5 | public class MaskComponent : MonoBehaviour 6 | { 7 | private int count; 8 | private RenderTexture lastFrame; 9 | private int lastWidth; 10 | private int lastHeight; 11 | 12 | private void Start() 13 | { 14 | lastWidth = Screen.width; 15 | lastHeight = Screen.height; 16 | lastFrame = RenderTexture.GetTemporary(lastWidth, lastHeight); 17 | } 18 | 19 | private void OnDestroy() 20 | { 21 | RenderTexture.ReleaseTemporary(lastFrame); 22 | } 23 | 24 | public void MaskFrames(int count) 25 | { 26 | Log.Debug($"Masking {count} frames"); 27 | 28 | if(this.count < count) 29 | this.count = count; 30 | } 31 | 32 | private void OnRenderImage(RenderTexture src, RenderTexture dest) 33 | { 34 | if(count > 0) 35 | { 36 | // Display the last frame again to hide the actual screen 37 | Graphics.Blit(lastFrame, dest); 38 | count--; 39 | } 40 | else 41 | { 42 | var newWidth = Screen.width; 43 | var newHeight = Screen.height; 44 | 45 | if(lastWidth != newWidth || lastHeight != newHeight) 46 | { 47 | RenderTexture.ReleaseTemporary(lastFrame); 48 | lastFrame = RenderTexture.GetTemporary(newWidth, newHeight); 49 | 50 | lastWidth = newWidth; 51 | lastHeight = newHeight; 52 | } 53 | 54 | // Need to keep a copy of the last frame since we don't know when MaskFrames will be used 55 | Graphics.Blit(src, lastFrame); 56 | 57 | Graphics.Blit(src, dest); 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/ItemLayerEdit.AISyoujyo/ItemLayerEdit.AISyoujyo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/LockOnPlugin.Core/MakerMono.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace LockOnPlugin 4 | { 5 | internal class MakerMono : LockOnBase 6 | { 7 | private readonly CameraControl_Ver2 camera = Singleton.Instance; 8 | 9 | protected override void Start() 10 | { 11 | base.Start(); 12 | currentCharaInfo = FindObjectOfType(); 13 | Guitime.pos = new Vector2(1f, 1f); 14 | } 15 | 16 | protected override void ResetModState() 17 | { 18 | base.ResetModState(); 19 | currentCharaInfo = FindObjectOfType(); 20 | } 21 | 22 | protected override float CameraMoveSpeed 23 | { 24 | get => camera.moveSpeed; 25 | set => camera.moveSpeed = value; 26 | } 27 | 28 | protected override Vector3 CameraTargetPos 29 | { 30 | get => camera.TargetPos; 31 | set => camera.TargetPos = value; 32 | } 33 | 34 | protected override Vector3 CameraAngle 35 | { 36 | get => camera.CameraAngle; 37 | set => camera.CameraAngle = value; 38 | } 39 | 40 | protected override float CameraFov 41 | { 42 | get => camera.CameraFov; 43 | set => camera.CameraFov = value; 44 | } 45 | 46 | protected override Vector3 CameraDir 47 | { 48 | get => camera.CameraDir; 49 | set => camera.CameraDir = value; 50 | } 51 | 52 | protected override bool CameraTargetTex 53 | { 54 | set => camera.isConfigTargetTex = value; 55 | } 56 | 57 | protected override float CameraZoomSpeed => defaultCameraSpeed; 58 | protected override Transform CameraTransform => camera.transform; 59 | protected override bool AllowTracking => true; 60 | protected override bool InputFieldSelected => base.InputFieldSelected; 61 | protected override bool CameraEnabled => camera.enabled; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/ItemLayerEdit.HoneySelect2/ItemLayerEdit.HoneySelect2.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/ItemLayerEdit.KoikatuSunshine/ItemLayerEdit.KoikatuSunshine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/BetterSceneLoader.Core/SceneGrid.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using System.Collections; 3 | using UnityEngine; 4 | using KeelPlugins.Utils; 5 | using KKAPI.Studio.UI.Toolbars; 6 | using Studio; 7 | 8 | namespace BetterSceneLoader 9 | { 10 | public class SceneGrid : ImageGrid 11 | { 12 | private SimpleToolbarToggle toolbarToggle; 13 | private AddButtonCtrl addButtonCtrl; 14 | 15 | public SceneGrid() : base( 16 | defaultPath: BepInEx.Utility.CombinePaths(Paths.GameRootPath, "UserData", "Studio", "scene"), 17 | onSaveButtonClick: () => Studio.Studio.Instance.systemButtonCtrl.OnClickSave(), 18 | onLoadButtonClick: x => Studio.Studio.Instance.StartCoroutine(Studio.Studio.Instance.LoadSceneCoroutine(x)), 19 | onImportButtonClick: x => Studio.Studio.Instance.ImportScene(x)) 20 | { } 21 | 22 | public override void ShowWindow(bool flag) 23 | { 24 | base.ShowWindow(flag); 25 | if(flag && (addButtonCtrl.select == 0 || addButtonCtrl.select == 1)) 26 | addButtonCtrl.OnClick(addButtonCtrl.select); 27 | } 28 | 29 | public override void HideWindow() 30 | { 31 | toolbarToggle.Toggled.OnNext(false); 32 | } 33 | 34 | public override void CreateUI(string name, int sortingOrder, string titleText) 35 | { 36 | base.CreateUI(name, sortingOrder, titleText); 37 | ThreadingHelper.Instance.StartCoroutine(AddToolbarButton()); 38 | addButtonCtrl = GameObject.Find("StudioScene/Canvas Main Menu/01_Add").GetComponent(); 39 | } 40 | 41 | private IEnumerator AddToolbarButton() 42 | { 43 | yield return null; 44 | toolbarToggle = new SimpleToolbarToggle(BetterSceneLoader.PluginName, null, GetTex, false, BetterSceneLoader.plugin, ShowWindow); 45 | ToolbarManager.AddLeftToolbarControl(toolbarToggle); 46 | Texture2D GetTex() => PngAssist.ChangeTextureFromByte(Resource.GetResourceAsBytes(typeof(ImageGrid).Assembly, "Resources.pluginicon")); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/LightManager.KoikatuSunshine/LightManager.KoikatuSunshine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/Common.Harmony/CoroutineExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using UnityEngine; 4 | 5 | namespace KeelPlugins.Harmony 6 | { 7 | public static class CoroutineExtensions 8 | { 9 | /// 10 | /// Create a coroutine that calls the appendCoroutine after base coroutine finishes 11 | /// 12 | public static IEnumerator AppendCo(this IEnumerator baseCoroutine, IEnumerator appendCoroutine) 13 | { 14 | return new[] { baseCoroutine, appendCoroutine }.GetEnumerator(); 15 | } 16 | 17 | /// 18 | /// Create a coroutine that calls the yieldInstruction after base coroutine finishes. 19 | /// Append further coroutines tu run after this. 20 | /// 21 | public static IEnumerator AppendCo(this IEnumerator baseCoroutine, YieldInstruction yieldInstruction) 22 | { 23 | return new object[] { baseCoroutine, yieldInstruction }.GetEnumerator(); 24 | } 25 | 26 | /// 27 | /// Create a coroutine that calls each of the actions in order after base coroutine finishes 28 | /// 29 | public static IEnumerator AppendCo(this IEnumerator baseCoroutine, params Action[] actions) 30 | { 31 | return new object[] { baseCoroutine, CreateCoroutine(actions) }.GetEnumerator(); 32 | } 33 | 34 | /// 35 | /// Create a coroutine that calls each of the action delegates on consecutive frames 36 | /// (yield return null is returned after each one of the actions) 37 | /// 38 | public static IEnumerator CreateCoroutine(params Action[] actions) 39 | { 40 | foreach (var action in actions) 41 | { 42 | action(); 43 | yield return null; 44 | } 45 | } 46 | 47 | /// 48 | /// Create a coroutine that calls each of the supplied coroutines in order 49 | /// 50 | public static IEnumerator ComposeCoroutine(params IEnumerator[] coroutine) 51 | { 52 | return coroutine.GetEnumerator(); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /src/UIUtility/MovableWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using UnityEngine.EventSystems; 4 | 5 | namespace UILib 6 | { 7 | public class MovableWindow : UIBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler 8 | { 9 | private Vector2 _cachedDragPosition; 10 | private Vector2 _cachedMousePosition; 11 | private bool _pointerDownCalled; 12 | private BaseCameraControl _cameraControl; 13 | private BaseCameraControl.NoCtrlFunc _noControlFunctionCached; 14 | 15 | public event Action PointerDown; 16 | public event Action Drag; 17 | public event Action PointerUp; 18 | 19 | public RectTransform toDrag; 20 | public bool preventCameraControl; 21 | 22 | public override void Awake() 23 | { 24 | base.Awake(); 25 | _cameraControl = FindObjectOfType(); 26 | } 27 | 28 | public void OnPointerDown(PointerEventData eventData) 29 | { 30 | if(preventCameraControl && _cameraControl) 31 | { 32 | _noControlFunctionCached = _cameraControl.NoCtrlCondition; 33 | _cameraControl.NoCtrlCondition = () => true; 34 | } 35 | _pointerDownCalled = true; 36 | _cachedDragPosition = toDrag.position; 37 | _cachedMousePosition = Input.mousePosition; 38 | PointerDown?.Invoke(eventData); 39 | } 40 | 41 | public void OnDrag(PointerEventData eventData) 42 | { 43 | if(_pointerDownCalled == false) 44 | return; 45 | toDrag.position = _cachedDragPosition + ((Vector2)Input.mousePosition - _cachedMousePosition); 46 | Drag?.Invoke(eventData); 47 | } 48 | 49 | public void OnPointerUp(PointerEventData eventData) 50 | { 51 | if(_pointerDownCalled == false) 52 | return; 53 | if(preventCameraControl && _cameraControl) 54 | _cameraControl.NoCtrlCondition = _noControlFunctionCached; 55 | _pointerDownCalled = false; 56 | PointerUp?.Invoke(eventData); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/LockOnPlugin.Core/LockOnPluginData.json: -------------------------------------------------------------------------------- 1 | { 2 | "quickTargets": 3 | [ 4 | "CenterPoint", 5 | "cf_J_FaceUp_tz", 6 | "cf_j_spine03", 7 | "cf_j_hips", 8 | "cf_d_kokan", 9 | "BetweenKnees", 10 | "BetweenFeet" 11 | ], 12 | 13 | "customTargets": 14 | [ 15 | { 16 | "target": "BetweenThighs", 17 | "point1": "cf_d_thigh02_R", 18 | "point2": "cf_d_thigh02_L", 19 | "midpoint": 0.5 20 | }, 21 | { 22 | "target": "BetweenKnees", 23 | "point1": "cf_j_leg01_R", 24 | "point2": "cf_j_leg01_L", 25 | "midpoint": 0.5 26 | }, 27 | { 28 | "target": "BetweenShins", 29 | "point1": "cf_hit_leg01_R", 30 | "point2": "cf_hit_leg01_L", 31 | "midpoint": 0.5 32 | }, 33 | { 34 | "target": "BetweenFeet", 35 | "point1": "cf_hit_leg02_R", 36 | "point2": "cf_hit_leg02_L", 37 | "midpoint": 0.5 38 | } 39 | ], 40 | 41 | "centerWeigths": 42 | [ 43 | { 44 | "bone": "cf_J_FaceUp_tz", 45 | "weigth": 1.1 46 | }, 47 | { 48 | "bone": "cf_j_spine03", 49 | "weigth": 1.1 50 | }, 51 | { 52 | "bone": "cf_j_hips", 53 | "weigth": 1.1 54 | }, 55 | { 56 | "bone": "cf_j_hand_R", 57 | "weigth": 0.4 58 | }, 59 | { 60 | "bone": "cf_j_hand_L", 61 | "weigth": 0.4 62 | }, 63 | { 64 | "bone": "cf_d_kokan", 65 | "weigth": 1.1 66 | }, 67 | { 68 | "bone": "cf_j_leg01_R", 69 | "weigth": 0.7 70 | }, 71 | { 72 | "bone": "cf_j_leg01_L", 73 | "weigth": 0.7 74 | }, 75 | { 76 | "bone": "cf_hit_leg02_R", 77 | "weigth": 0.4 78 | }, 79 | { 80 | "bone": "cf_hit_leg02_L", 81 | "weigth": 0.4 82 | } 83 | ], 84 | 85 | "presenceTargets": 86 | [ 87 | "cf_J_FaceUp_tz", 88 | "cf_j_spine03", 89 | "cf_j_hips", 90 | "cf_d_kokan" 91 | ] 92 | } 93 | -------------------------------------------------------------------------------- /src/ItemLayerEdit.Core/ItemLayerEdit.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using BepInEx.Configuration; 3 | using KeelPlugins; 4 | using KKAPI.Studio.SaveLoad; 5 | using Studio; 6 | using System.Linq; 7 | using UnityEngine; 8 | 9 | [assembly: System.Reflection.AssemblyVersion(ItemLayerEdit.Koikatu.ItemLayerEdit.Version)] 10 | 11 | namespace ItemLayerEdit.Koikatu 12 | { 13 | [BepInDependency(KKAPI.KoikatuAPI.GUID)] 14 | [BepInProcess(Constants.StudioProcessName)] 15 | [BepInPlugin(GUID, "Item Layer Edit", Version)] 16 | public class ItemLayerEdit : BaseUnityPlugin 17 | { 18 | public const string GUID = "keelhauled.itemlayeredit"; 19 | public const string Version = "1.1.3." + BuildNumber.Version; 20 | 21 | private ConfigEntry ChangeLayer { get; set; } 22 | 23 | private void Start() 24 | { 25 | StudioSaveLoadApi.RegisterExtraBehaviour(GUID); 26 | 27 | ChangeLayer = Config.Bind("General", "Change layer", new KeyboardShortcut(KeyCode.V), "Toggle the selected objects between character and map layers"); 28 | } 29 | 30 | private void Update() 31 | { 32 | if(ChangeLayer.Value.IsDown()) 33 | { 34 | var layer = GetSelectedObjectLayer(); 35 | if(layer == 11) 36 | SetSelectedObjectLayer(10); 37 | else if(layer == 10) 38 | SetSelectedObjectLayer(11); 39 | } 40 | } 41 | 42 | private static void SetSelectedObjectLayer(int layer) 43 | { 44 | var targetObjects = Studio.Studio.GetSelectObjectCtrl().OfType().Select(x => x.objectItem); 45 | 46 | foreach(var targetObject in targetObjects) 47 | { 48 | if(targetObject.AddComponentIfNotExist(out var data)) 49 | data.DefaultLayer = targetObject.layer; 50 | 51 | targetObject.SetAllLayers(layer); 52 | } 53 | } 54 | 55 | private static int GetSelectedObjectLayer() 56 | { 57 | var targetObject = Studio.Studio.GetSelectObjectCtrl().OfType().Select(x => x.objectItem).FirstOrDefault(); 58 | return targetObject != null ? targetObject.layer : -1; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/MakerBridge.Core/MakerBridge.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using BepInEx.Configuration; 3 | using BepInEx.Logging; 4 | using System.IO; 5 | using UnityEngine; 6 | using KKAPI.Maker; 7 | using KKAPI.Studio; 8 | 9 | [assembly: System.Reflection.AssemblyVersion(MakerBridge.MakerBridge.Version)] 10 | 11 | namespace MakerBridge 12 | { 13 | [BepInPlugin(GUID, PluginName, Version)] 14 | [BepInDependency(KKAPI.KoikatuAPI.GUID)] 15 | public class MakerBridge : BaseUnityPlugin 16 | { 17 | public const string GUID = "keelhauled.makerbridge"; 18 | public const string PluginName = "MakerBridge"; 19 | public const string Version = "1.0.5." + BuildNumber.Version; 20 | 21 | private const string DESCRIPTION_SENDCHARA = "Sends the selected character to the other open koikatu application."; 22 | private const string DESCRIPTION_SHOWMSG = "Show on screen messages about things the plugin is doing."; 23 | 24 | internal static string MakerCardPath; 25 | internal static string OtherCardPath; 26 | protected static GameObject bepinex; 27 | 28 | internal static ConfigEntry SendChara { get; set; } 29 | internal static ConfigEntry ShowMessages { get; set; } 30 | 31 | protected virtual void Awake() 32 | { 33 | Log.SetLogSource(Logger); 34 | bepinex = gameObject; 35 | 36 | SendChara = Config.Bind("Keyboard shortcuts", "Send character", new KeyboardShortcut(KeyCode.B), new ConfigDescription(DESCRIPTION_SENDCHARA)); 37 | ShowMessages = Config.Bind("General", "Show messages", true, new ConfigDescription(DESCRIPTION_SHOWMSG)); 38 | 39 | MakerCardPath = Path.Combine(Paths.CachePath, "makerbridge1.png"); 40 | OtherCardPath = Path.Combine(Paths.CachePath, "makerbridge2.png"); 41 | 42 | MakerAPI.MakerFinishedLoading += (sender, e) => bepinex.GetOrAddComponent(); 43 | MakerAPI.MakerExiting += (sender, e) => Destroy(bepinex.GetComponent()); 44 | StudioAPI.StudioLoadedChanged += (sender, e) => bepinex.GetOrAddComponent(); 45 | } 46 | 47 | internal static void LogMsg(object data) 48 | { 49 | Log.Level(ShowMessages.Value ? LogLevel.Message : LogLevel.Info, data); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/CameraFrameMask.Core/CameraFrameMask.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using HarmonyLib; 3 | using Studio; 4 | using UnityEngine; 5 | 6 | [assembly: System.Reflection.AssemblyVersion(CameraFrameMask.Koikatu.CameraFrameMask.Version)] 7 | 8 | namespace CameraFrameMask.Koikatu 9 | { 10 | [BepInPlugin(GUID, PluginName, Version)] 11 | public class CameraFrameMask : BaseUnityPlugin 12 | { 13 | public const string GUID = "keelhauled.cameraframemask"; 14 | public const string PluginName = "CameraFrameMask"; 15 | public const string Version = "1.1.1." + BuildNumber.Version; 16 | 17 | private static MaskComponent maskComponent; 18 | private static readonly bool inStudio = Paths.ProcessName == "CharaStudio"; 19 | 20 | private void Awake() 21 | { 22 | Log.SetLogSource(Logger); 23 | Harmony.CreateAndPatchAll(GetType()); 24 | } 25 | 26 | [HarmonyPrefix, HarmonyPatch(typeof(CustomScene), "Start")] 27 | private static void MakerEntrypoint() => maskComponent = Camera.main.GetOrAddComponent(); 28 | [HarmonyPrefix, HarmonyPatch(typeof(CustomScene), "OnDestroy")] 29 | private static void MakerEnd() => maskComponent = null; 30 | [HarmonyPrefix, HarmonyPatch(typeof(StudioScene), "Start")] 31 | private static void StudioEntrypoint() => maskComponent = Camera.main.GetOrAddComponent(); 32 | [HarmonyPrefix, HarmonyPatch(typeof(HSceneProc), "SetShortcutKey")] 33 | private static void HSceneEntrypoint() => maskComponent = Camera.main.GetOrAddComponent(); 34 | [HarmonyPrefix, HarmonyPatch(typeof(HSceneProc), "OnDestroy")] 35 | private static void HSceneEnd() => maskComponent = null; 36 | 37 | [HarmonyPrefix] 38 | [HarmonyPatch(typeof(ChaControl), nameof(ChaControl.ChangeCoordinateType), typeof(ChaFileDefine.CoordinateType), typeof(bool))] 39 | [HarmonyPatch(typeof(PauseCtrl), nameof(PauseCtrl.Load))] 40 | [HarmonyPatch(typeof(OCIChar), nameof(OCIChar.LoadAnime))] 41 | [HarmonyPatch(typeof(OCIChar), nameof(OCIChar.ActiveKinematicMode))] 42 | private static void MaskFramesPatch() 43 | { 44 | MaskFrames(inStudio ? 3 : 2); 45 | } 46 | 47 | public static void MaskFrames(int count) 48 | { 49 | if (maskComponent) 50 | maskComponent.MaskFrames(count); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/MakerBridge.Core/StudioHandler.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using Studio; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using UnityEngine; 7 | 8 | namespace MakerBridge 9 | { 10 | internal class StudioHandler : HandlerCore 11 | { 12 | protected override string WatchedFilePath => MakerBridge.MakerCardPath; 13 | protected override string OutputFilePath => MakerBridge.OtherCardPath; 14 | 15 | protected override void SaveCharacter(string path) 16 | { 17 | var characters = GetSelectedCharacters(); 18 | if(characters.Count > 0) 19 | { 20 | var empty = new Texture2D(1, 1, TextureFormat.ARGB32, false); 21 | empty.SetPixel(0, 0, Color.black); 22 | empty.Apply(); 23 | 24 | var charFile = characters[0].charInfo.chaFile; 25 | charFile.pngData = empty.EncodeToPNG(); 26 | charFile.facePngData = empty.EncodeToPNG(); 27 | 28 | using(var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write)) 29 | charFile.SaveCharaFile(fileStream, true); 30 | } 31 | else 32 | { 33 | MakerBridge.LogMsg("Select a character to send to maker"); 34 | } 35 | } 36 | 37 | protected override void LoadCharacter(string path) 38 | { 39 | var characters = GetSelectedCharacters(); 40 | if(characters.Count > 0) 41 | { 42 | MakerBridge.LogMsg("Character received"); 43 | 44 | foreach(var chara in characters) 45 | chara.ChangeChara(path); 46 | 47 | UpdateStateInfo(); 48 | } 49 | else 50 | { 51 | MakerBridge.LogMsg("Select a character before replacing it"); 52 | } 53 | } 54 | 55 | private List GetSelectedCharacters() 56 | { 57 | return GuideObjectManager.Instance.selectObjectKey.Select(x => Studio.Studio.GetCtrlInfo(x) as OCIChar).Where(x => x != null).ToList(); 58 | } 59 | 60 | private void UpdateStateInfo() 61 | { 62 | var mpCharCtrl = FindObjectOfType(); 63 | if(mpCharCtrl && (mpCharCtrl.select == 0 || mpCharCtrl.select == 1)) 64 | mpCharCtrl.OnClickRoot(mpCharCtrl.select); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/LockOnPlugin.Core/TargetData.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using ParadoxNotion.Serialization; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Text; 7 | using KKAPI.Utilities; 8 | 9 | namespace LockOnPlugin 10 | { 11 | internal class TargetData 12 | { 13 | private const string dataName = "LockOnPluginData.json"; 14 | 15 | private static TargetData _instance; 16 | public static TargetData Instance 17 | { 18 | get 19 | { 20 | if(_instance == null) 21 | { 22 | var dataPath = Path.Combine(Paths.ConfigPath, dataName); 23 | if(File.Exists(dataPath)) 24 | { 25 | try 26 | { 27 | var json = File.ReadAllText(dataPath); 28 | _instance = JSONSerializer.Deserialize(json); 29 | Log.Info("Loading custom target data."); 30 | } 31 | catch(Exception ex) 32 | { 33 | Log.Info($"Failed to deserialize custom target data. Loading default target data.\n{ex}"); 34 | _instance = GetEmbeddedData(); 35 | } 36 | } 37 | else 38 | { 39 | Log.Debug("Loading default target data."); 40 | _instance = GetEmbeddedData(); 41 | } 42 | } 43 | 44 | return _instance; 45 | } 46 | } 47 | 48 | private static TargetData GetEmbeddedData() 49 | { 50 | var json = Encoding.UTF8.GetString(ResourceUtils.GetEmbeddedResource(dataName, typeof(LockOnPluginCore).Assembly)); 51 | return JSONSerializer.Deserialize(json); 52 | } 53 | 54 | #pragma warning disable 649 // disable never assigned warning 55 | public List quickTargets; 56 | public List customTargets; 57 | public List centerWeigths; 58 | public List presenceTargets; 59 | 60 | public class CustomTarget 61 | { 62 | public string target; 63 | public string point1; 64 | public string point2; 65 | public float midpoint; 66 | } 67 | 68 | public class CenterWeigth 69 | { 70 | public string bone; 71 | public float weigth; 72 | } 73 | #pragma warning restore 649 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/CharaStateX.Core/AnimationPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using Studio; 3 | using System.Linq; 4 | using UnityEngine; 5 | 6 | namespace CharaStateX.Koikatu 7 | { 8 | internal static class AnimationPatch 9 | { 10 | [HarmonyPostfix, HarmonyPatch(typeof(PauseRegistrationList), "OnClickLoad")] 11 | public static void PoseLoadPatch(PauseRegistrationList __instance) 12 | { 13 | foreach(var chara in Utils.GetSelectedCharacters().Where(chara => chara != __instance.ociChar)) 14 | PauseCtrl.Load(chara, __instance.listPath[__instance.select]); 15 | } 16 | 17 | [HarmonyPrefix, HarmonyPatch(typeof(MPCharCtrl), "LoadAnime")] 18 | public static bool LoadAnimePrefix(MPCharCtrl __instance, ref int _group, ref int _category, ref int _no) 19 | { 20 | bool sexMatch = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl); 21 | 22 | foreach(var chara in Utils.GetSelectedCharacters()) 23 | { 24 | if(chara != __instance.ociChar) 25 | { 26 | float param1 = chara.animeOptionParam1; 27 | float param2 = chara.animeOptionParam2; 28 | 29 | var soup = sexMatch ? MatchCategory(chara.sex, _group) : _group; 30 | chara.LoadAnime(soup, _category, _no); 31 | 32 | chara.animeOptionParam1 = param1; 33 | chara.animeOptionParam2 = param2; 34 | } 35 | } 36 | 37 | float animeOptionParam1 = __instance.ociChar.animeOptionParam1; 38 | float animeOptionParam2 = __instance.ociChar.animeOptionParam2; 39 | 40 | int group = sexMatch ? MatchCategory(__instance.ociChar.sex, _group) : _group; 41 | __instance.ociChar.LoadAnime(group, _category, _no); 42 | __instance.animeControl.UpdateInfo(); 43 | 44 | __instance.ociChar.animeOptionParam1 = animeOptionParam1; 45 | __instance.ociChar.animeOptionParam2 = animeOptionParam2; 46 | 47 | return false; 48 | } 49 | 50 | private static int MatchCategory(int sex, int group) 51 | { 52 | if(sex == 1) 53 | { 54 | switch(group) 55 | { 56 | case 3: return 2; 57 | case 5: return 4; 58 | } 59 | } 60 | else if(sex == 0) 61 | { 62 | switch(group) 63 | { 64 | case 2: return 3; 65 | case 4: return 5; 66 | } 67 | } 68 | 69 | return group; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/LockOnPlugin.Core/KeyboardShortcutHotkey.cs: -------------------------------------------------------------------------------- 1 | using BepInEx.Configuration; 2 | using UnityEngine; 3 | using UnityEngine.Events; 4 | using UnityEngine.EventSystems; 5 | using UnityEngine.UI; 6 | 7 | namespace LockOnPlugin 8 | { 9 | internal class KeyboardShortcutHotkey 10 | { 11 | private KeyboardShortcut key; 12 | private float procTime; 13 | private float timeHeld; 14 | private bool released = true; 15 | private bool enabled = true; 16 | 17 | public KeyboardShortcutHotkey(KeyboardShortcut newKey, float newProcTime = 0f) 18 | { 19 | key = newKey; 20 | if(key.MainKey == KeyCode.None) 21 | enabled = false; 22 | 23 | if(newProcTime > 0f) 24 | procTime = newProcTime; 25 | } 26 | 27 | public void KeyDownAction(UnityAction action) 28 | { 29 | if(ResetIfShould()) return; 30 | 31 | if(enabled && key.IsDown()) 32 | { 33 | action(); 34 | released = false; 35 | } 36 | } 37 | 38 | /// 39 | /// This always needs at least KeyUpAction(null) after it. 40 | /// 41 | /// 42 | public void KeyHoldAction(UnityAction action) 43 | { 44 | if(ResetIfShould()) return; 45 | 46 | if(enabled && procTime > 0f && key.IsPressed()) 47 | { 48 | timeHeld += Time.deltaTime; 49 | if(timeHeld >= procTime && released) 50 | { 51 | action(); 52 | released = false; 53 | } 54 | } 55 | } 56 | 57 | public void KeyUpAction(UnityAction action) 58 | { 59 | if(ResetIfShould()) return; 60 | 61 | if(enabled && key.IsUp()) 62 | { 63 | if(released) 64 | action?.Invoke(); 65 | 66 | timeHeld = 0f; 67 | released = true; 68 | } 69 | } 70 | 71 | private bool ResetIfShould() 72 | { 73 | bool shouldReset = false; 74 | 75 | if(GUIUtility.keyboardControl > 0) 76 | shouldReset = true; 77 | 78 | if(EventSystem.current.currentSelectedGameObject != null && EventSystem.current.currentSelectedGameObject.GetComponent() != null) 79 | shouldReset = true; 80 | 81 | if(shouldReset) 82 | { 83 | timeHeld = 0f; 84 | released = true; 85 | return true; 86 | } 87 | 88 | return false; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/BetterSceneLoader.Core/DropdownAutoScroll.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | 4 | namespace BetterSceneLoader 5 | { 6 | /// 7 | /// Set the initial scroll position of the dropdown to the position of the selected item. 8 | /// 9 | internal class DropdownAutoScroll : MonoBehaviour 10 | { 11 | public static void Setup(Dropdown dropdown) 12 | { 13 | var scrollbar = dropdown.GetComponentInChildren(true); 14 | 15 | if (scrollbar == null) 16 | return; 17 | 18 | var assComp = scrollbar.GetOrAddComponent(); 19 | assComp._target = dropdown; 20 | } 21 | 22 | [SerializeField] 23 | private Dropdown _target; 24 | 25 | private bool _autoScrolled; 26 | 27 | private void OnEnable() 28 | { 29 | //No scrolling until LateUpdate when internal setup is complete 30 | _autoScrolled = false; 31 | } 32 | 33 | private void LateUpdate() 34 | { 35 | if (!_autoScrolled) 36 | { 37 | _autoScrolled = true; 38 | AutoScroll(); 39 | } 40 | } 41 | 42 | private void AutoScroll() 43 | { 44 | if (_target == null) 45 | return; 46 | 47 | int items = _target.options.Count; 48 | 49 | if (items <= 1) 50 | return; 51 | 52 | var scrollbar = GetComponent(); 53 | 54 | if (scrollbar == null) 55 | return; 56 | 57 | int axis = scrollbar.direction < Scrollbar.Direction.BottomToTop ? 0 : 1; 58 | 59 | var scrollRect = _target.template.GetComponent(); 60 | 61 | float viewSize = scrollRect.viewport.rect.size[axis]; 62 | float itemSize = 20f; 63 | 64 | if (_target.itemText != null) 65 | { 66 | var itemRect = (RectTransform)_target.itemText.transform.parent; 67 | itemSize = itemRect.rect.size[axis]; 68 | } 69 | else if (_target.itemImage != null) 70 | { 71 | var itemRect = (RectTransform)_target.itemImage.transform.parent; 72 | itemSize = itemRect.rect.size[axis]; 73 | } 74 | 75 | float viewAreaRatio = viewSize / itemSize / items; 76 | 77 | float scroll = (float)_target.value / items - viewAreaRatio * 0.5f; 78 | scroll = Mathf.Clamp(scroll, 0f, 1f - viewAreaRatio); 79 | scroll = Mathf.InverseLerp(0, 1f - viewAreaRatio, scroll); 80 | 81 | scrollbar.value = Mathf.Clamp01(1.0f - scroll); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/MakerBridge.Core/MakerHandler.cs: -------------------------------------------------------------------------------- 1 | using ChaCustom; 2 | using System; 3 | using System.Linq; 4 | using UnityEngine; 5 | 6 | namespace MakerBridge 7 | { 8 | internal class MakerHandler : HandlerCore 9 | { 10 | protected override string WatchedFilePath => MakerBridge.OtherCardPath; 11 | protected override string OutputFilePath => MakerBridge.MakerCardPath; 12 | 13 | protected override void SaveCharacter(string path) 14 | { 15 | var customBase = CustomBase.Instance; 16 | if(customBase) 17 | { 18 | var empty = new Texture2D(1, 1, TextureFormat.ARGB32, false); 19 | empty.SetPixel(0, 0, Color.black); 20 | empty.Apply(); 21 | 22 | var charFile = customBase.chaCtrl.chaFile; 23 | charFile.pngData = empty.EncodeToPNG(); 24 | charFile.facePngData = empty.EncodeToPNG(); 25 | 26 | customBase.chaCtrl.chaFile.SaveCharaFile(path); 27 | } 28 | } 29 | 30 | protected override void LoadCharacter(string path) 31 | { 32 | var cfw = FindObjectsOfType().FirstOrDefault(x => x.fwType == CustomFileWindow.FileWindowType.CharaLoad); 33 | var loadFace = true; 34 | var loadBody = true; 35 | var loadHair = true; 36 | var parameter = true; 37 | var loadCoord = true; 38 | 39 | if(cfw) 40 | { 41 | loadFace = cfw.tglChaLoadFace && cfw.tglChaLoadFace.isOn; 42 | loadBody = cfw.tglChaLoadBody && cfw.tglChaLoadBody.isOn; 43 | loadHair = cfw.tglChaLoadHair && cfw.tglChaLoadHair.isOn; 44 | parameter = cfw.tglChaLoadParam && cfw.tglChaLoadParam.isOn; 45 | loadCoord = cfw.tglChaLoadCoorde && cfw.tglChaLoadCoorde.isOn; 46 | } 47 | 48 | var chaCtrl = CustomBase.Instance.chaCtrl; 49 | var originalSex = chaCtrl.sex; 50 | 51 | chaCtrl.chaFile.LoadFileLimited(path, chaCtrl.sex, loadFace, loadBody, loadHair, parameter, loadCoord); 52 | if(chaCtrl.chaFile.GetLastErrorCode() != 0) 53 | throw new Exception("LoadFileLimited failed"); 54 | 55 | if(chaCtrl.chaFile.parameter.sex != originalSex) 56 | { 57 | chaCtrl.chaFile.parameter.sex = originalSex; 58 | MakerBridge.LogMsg("Warning: The character's sex has been changed to match the editor mode."); 59 | } 60 | 61 | chaCtrl.ChangeCoordinateType(); 62 | chaCtrl.Reload(!loadCoord, !loadFace && !loadCoord, !loadHair, !loadBody); 63 | CustomBase.Instance.updateCustomUI = true; 64 | 65 | MakerBridge.LogMsg("Character received"); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/DefaultStudioScene.Core/DefaultStudioScene.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using BepInEx.Configuration; 3 | using HarmonyLib; 4 | using System.Collections; 5 | using System.IO; 6 | using UnityEngine; 7 | using KKAPI.Utilities; 8 | using KeelPlugins; 9 | 10 | [assembly: System.Reflection.AssemblyVersion(DefaultStudioScene.Koikatu.DefaultStudioScene.Version)] 11 | 12 | namespace DefaultStudioScene.Koikatu 13 | { 14 | [BepInProcess(Constants.StudioProcessName)] 15 | [BepInPlugin(GUID, "DefaultStudioScene", Version)] 16 | [BepInDependency(KKAPI.KoikatuAPI.GUID)] 17 | public class DefaultStudioScene : BaseUnityPlugin 18 | { 19 | public const string GUID = "keelhauled.defaultstudioscene"; 20 | public const string Version = "1.0.4." + BuildNumber.Version; 21 | 22 | private static ConfigEntry DefaultScenePath { get; set; } 23 | private static DefaultStudioScene plugin; 24 | 25 | private const string fileExtension = ".png"; 26 | private const string filter = "Scenes (*.png)|*.png|All files|*.*"; 27 | private string defaultDir = Path.Combine(Paths.GameRootPath, @"userdata\studio\scene"); 28 | 29 | public void Awake() 30 | { 31 | plugin = this; 32 | Config.Bind("General", $"Default Scene Replacement", "", new ConfigDescription("", null, new ConfigurationManagerAttributes { Order = 2, HideDefaultButton = true, CustomDrawer = SceneButtonDrawer})); 33 | DefaultScenePath = Config.Bind("General", "Default Scene Path", "", new ConfigDescription("", null, new ConfigurationManagerAttributes { Order = 1 })); 34 | Harmony.CreateAndPatchAll(GetType()); 35 | } 36 | 37 | [HarmonyPostfix, HarmonyPatch(typeof(Studio.Studio), nameof(Studio.Studio.Init))] 38 | private static void LoadScene() 39 | { 40 | plugin.StartCoroutine(Coroutine()); 41 | 42 | IEnumerator Coroutine() 43 | { 44 | yield return new WaitUntil(() => Studio.Studio.Instance.rootButtonCtrl != null); 45 | 46 | if(!string.IsNullOrEmpty(DefaultScenePath.Value) && File.Exists(DefaultScenePath.Value)) 47 | plugin.StartCoroutine(Studio.Studio.Instance.LoadSceneCoroutine(DefaultScenePath.Value)); 48 | } 49 | } 50 | 51 | private void SceneButtonDrawer(ConfigEntryBase configEntry) 52 | { 53 | if(GUILayout.Button($"Select a scene", GUILayout.ExpandWidth(true))) 54 | OpenFileDialog.Show(OnAccept, "Select a scene", defaultDir, filter, fileExtension, OpenFileDialog.OpenSaveFileDialgueFlags.OFN_FILEMUSTEXIST); 55 | } 56 | 57 | private void OnAccept(string[] paths) 58 | { 59 | if(paths.IsNullOrEmpty()) return; 60 | DefaultScenePath.Value = paths[0]; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/ClothingStateMenuX.Core/ClothingStateMenu.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BepInEx; 3 | using BepInEx.Bootstrap; 4 | using BepInEx.Configuration; 5 | using HarmonyLib; 6 | using KeelPlugins; 7 | using KKAPI; 8 | using KKAPI.Maker; 9 | 10 | [assembly: System.Reflection.AssemblyVersion(ClothingStateMenuX.ClothingStateMenu.Version)] 11 | 12 | namespace ClothingStateMenuX 13 | { 14 | [BepInProcess(Constants.MainGameProcessName)] 15 | [BepInDependency(KoikatuAPI.GUID)] 16 | [BepInDependency(MoreOutfitsGUID, BepInDependency.DependencyFlags.SoftDependency)] 17 | [BepInPlugin("keelhauled.clothingstatemenux", "ClothingStateMenuX", Version)] 18 | public class ClothingStateMenu : BaseUnityPlugin 19 | { 20 | public const string Version = "1.1.0." + BuildNumber.Version; 21 | 22 | public static ConfigEntry ShowClothingSets { get; set; } 23 | 24 | private const string MoreOutfitsGUID = "com.deathweasel.bepinex.moreoutfits"; 25 | private Harmony harmony; 26 | 27 | private void Awake() 28 | { 29 | Log.SetLogSource(Logger); 30 | ShowClothingSets = Config.Bind("General", "Show Clothing Sets", true); 31 | ShowClothingSets.SettingChanged += (sender, args) => 32 | { 33 | if(ShowClothingSets.Value) 34 | { 35 | StartClothingSetEvents(); 36 | UI.ReloadClothingSets(); 37 | } 38 | else 39 | { 40 | harmony?.UnpatchSelf(); 41 | MakerAPI.ReloadCustomInterface -= OnReloadCustomInterface; 42 | UI.RemoveClothingSets(); 43 | } 44 | }; 45 | 46 | MakerAPI.MakerStartedLoading += (sender, args) => UI.Setup(); 47 | 48 | if(ShowClothingSets.Value) 49 | StartClothingSetEvents(); 50 | } 51 | 52 | private void StartClothingSetEvents() 53 | { 54 | if(Chainloader.PluginInfos.ContainsKey(MoreOutfitsGUID)) 55 | harmony = Harmony.CreateAndPatchAll(typeof(Hooks)); 56 | else 57 | MakerAPI.ReloadCustomInterface += OnReloadCustomInterface; 58 | } 59 | 60 | private void OnReloadCustomInterface(object sender, EventArgs args) 61 | { 62 | UI.ReloadClothingSets(); 63 | } 64 | 65 | private static class Hooks 66 | { 67 | #if KK 68 | [HarmonyPostfix, HarmonyPatch("KK_Plugins.MoreOutfits.MakerUI, KK_MoreOutfits", "UpdateMakerUI"), HarmonyWrapSafe] 69 | #else 70 | [HarmonyPostfix, HarmonyPatch("KK_Plugins.MoreOutfits.MakerUI, KKS_MoreOutfits", "UpdateMakerUI"), HarmonyWrapSafe] 71 | #endif 72 | private static void MoreOutfitsHook() 73 | { 74 | UI.ReloadClothingSets(); 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /release.ps1: -------------------------------------------------------------------------------- 1 | # Env setup --------------- 2 | if ($PSScriptRoot -match '.+?\\Release\\?') { 3 | $dir = $PSScriptRoot + "\" 4 | } 5 | else { 6 | $dir = $PSScriptRoot + "\bin\Release" 7 | } 8 | 9 | Remove-Item -Force -Path ($dir + "\copy") -Recurse -ErrorAction SilentlyContinue 10 | Remove-Item -Force -Path ($dir + "\out\") -Recurse -ErrorAction SilentlyContinue 11 | New-Item -ItemType Directory -Force -Path ($dir + "\out\") 12 | 13 | foreach ($subdir in Get-ChildItem -Path $dir -Directory -Exclude "Out") 14 | { 15 | if ((Get-ChildItem -Path $subdir -Filter *.dll).Length -gt 0) 16 | { 17 | $pluginDir = $subdir 18 | } 19 | else 20 | { 21 | $pluginDir = Get-Item ($subdir.FullName + "\BepInEx\plugins") 22 | } 23 | 24 | if (($subdir.BaseName.ToLower()) -eq "Patchers".ToLower()) 25 | { 26 | $copy = $dir + "\copy\BepInEx\patchers" 27 | } 28 | elseif ((Get-ChildItem -Path $subdir -Filter *.dll).Length -gt 0) 29 | { 30 | $copy = $dir + "\copy\BepInEx\plugins" 31 | } 32 | 33 | Write-Information -MessageData ("Using " + $pluginDir + " as plugin directory") 34 | 35 | $outdir = $dir + "\out\" + $subdir.BaseName 36 | New-Item -ItemType Directory -Force -Path $outdir 37 | 38 | # Create releases --------- 39 | function CreateZip ($pluginFile) 40 | { 41 | Remove-Item -Force -Path ($dir + "\copy") -Recurse -ErrorAction SilentlyContinue 42 | New-Item -ItemType Directory -Force -Path $copy 43 | 44 | # the actual dll 45 | Copy-Item -Path $pluginFile.FullName -Destination $copy -Recurse -Force 46 | # the docs xml if it exists 47 | Copy-Item -Path ($pluginFile.DirectoryName + "\" + $pluginFile.BaseName + ".xml") -Destination $copy -Recurse -Force -ErrorAction Ignore 48 | Copy-Item -Path ($pluginFile.DirectoryName + "\" + $pluginFile.BaseName) -Destination $copy -Recurse -Force -ErrorAction Ignore 49 | 50 | # the replace removes .0 from the end of version up until it hits a non-0 or there are only 2 version parts remaining (e.g. v1.0 v1.0.1) 51 | $ver = (Get-ChildItem -Path ($copy) -Filter "*.dll" -Recurse -Force)[0].VersionInfo.FileVersion.ToString() -replace "^([\d+\.]+?\d+)[\.0]*$", '${1}' 52 | 53 | Compress-Archive -Path ($dir + "\copy\*") -Force -CompressionLevel "Optimal" -DestinationPath ($outdir + "\" + $pluginFile.BaseName + "_" + "v" + $ver + ".zip") 54 | } 55 | 56 | foreach ($pluginFile in Get-ChildItem -Path $pluginDir -Filter *.dll) 57 | { 58 | try 59 | { 60 | CreateZip ($pluginFile) 61 | } 62 | catch 63 | { 64 | # retry 65 | CreateZip ($pluginFile) 66 | } 67 | } 68 | 69 | Compress-Archive -Path ($outdir + "\*") -Force -CompressionLevel "NoCompression" -DestinationPath ($dir + "\out\" + $subdir.BaseName + "_" + (Get-Date).ToString("yyyy.MM.dd") + ".zip") 70 | 71 | } 72 | 73 | Remove-Item -Force -Path ($dir + "\copy") -Recurse 74 | -------------------------------------------------------------------------------- /src/ItemLayerEdit.Core/SceneDataController.cs: -------------------------------------------------------------------------------- 1 | using ExtensibleSaveFormat; 2 | using KKAPI.Studio.SaveLoad; 3 | using KKAPI.Utilities; 4 | using MessagePack; 5 | using Studio; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | 9 | namespace ItemLayerEdit.Koikatu 10 | { 11 | internal class SceneDataController : SceneCustomFunctionController 12 | { 13 | private const string SaveId = "SavedLayers"; 14 | 15 | protected override void OnSceneLoad(SceneOperationKind operation, ReadOnlyDictionary loadedItems) 16 | { 17 | var data = GetExtendedData(); 18 | if(data == null) 19 | return; 20 | 21 | if((operation == SceneOperationKind.Load || operation == SceneOperationKind.Import) && data.data.TryGetValue(SaveId, out var saveDataBytes)) 22 | { 23 | var saveData = MessagePackSerializer.Deserialize>((byte[])saveDataBytes); 24 | foreach(var layerData in saveData) 25 | { 26 | if(loadedItems.TryGetValue(layerData.ObjectId, out var itemInfo) && itemInfo is OCIItem item) 27 | { 28 | item.objectItem.AddComponent().DefaultLayer = layerData.DefaultLayer; 29 | item.objectItem.SetAllLayers(layerData.NewLayer); 30 | } 31 | } 32 | } 33 | } 34 | 35 | protected override void OnSceneSave() 36 | { 37 | var saveData = new List(); 38 | foreach(var item in Studio.Studio.Instance.dicObjectCtrl.Values.OfType()) 39 | { 40 | var data = item.objectItem.GetComponent(); 41 | if(data && data.DefaultLayer != item.objectItem.layer) 42 | { 43 | saveData.Add(new LayerSaveData 44 | { 45 | DefaultLayer = data.DefaultLayer, 46 | NewLayer = item.objectItem.layer, 47 | ObjectId = item.objectInfo.dicKey 48 | }); 49 | } 50 | } 51 | 52 | if(saveData.Count > 0) 53 | { 54 | var data = new PluginData(); 55 | data.data.Add(SaveId, MessagePackSerializer.Serialize(saveData)); 56 | SetExtendedData(data); 57 | } 58 | } 59 | 60 | protected override void OnObjectsCopied(ReadOnlyDictionary copiedItems) { 61 | foreach (var kvp in copiedItems) 62 | { 63 | if ( 64 | Studio.Studio.Instance.dicObjectCtrl.TryGetValue(kvp.Key, out var oci) && 65 | oci is OCIItem original && 66 | original.objectItem.GetComponent() != null 67 | ) { 68 | OCIItem copy = kvp.Value as OCIItem; 69 | copy.objectItem.AddComponent().DefaultLayer = copy.objectItem.layer; 70 | copy.objectItem.SetAllLayers(original.objectItem.layer); 71 | } 72 | } 73 | 74 | base.OnObjectsCopied(copiedItems); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/UnityLogFilter/UnityLogFilter.cs: -------------------------------------------------------------------------------- 1 | using BepInEx.Bootstrap; 2 | using BepInEx.Logging; 3 | using HarmonyLib; 4 | using Mono.Cecil; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Text.RegularExpressions; 10 | 11 | [assembly: System.Reflection.AssemblyVersion(UnityLogFilter.UnityLogFilter.Version)] 12 | 13 | namespace UnityLogFilter 14 | { 15 | public class UnityLogFilter 16 | { 17 | public const string Version = "1.0.2." + BuildNumber.Version; 18 | 19 | public static IEnumerable TargetDLLs { get; } = new string[0]; 20 | public static void Patch(AssemblyDefinition ass) { } 21 | 22 | private static Harmony Harmony; 23 | private static readonly List filters = new List(); 24 | private static readonly string filterFilePath = Path.Combine(BepInEx.Paths.ConfigPath, "UnityLogFilter.txt"); 25 | 26 | public static void Finish() 27 | { 28 | Harmony = new Harmony(nameof(UnityLogFilter)); 29 | Log.SetLogSource(Logger.CreateLogSource(nameof(UnityLogFilter))); 30 | 31 | if(File.Exists(filterFilePath)) 32 | { 33 | foreach(var line in File.ReadAllLines(filterFilePath)) 34 | { 35 | if(VerifyRegex(line)) 36 | filters.Add(new Regex(line)); 37 | else 38 | Log.Warning($"'{line}' is not a valid regex pattern"); 39 | } 40 | 41 | Log.Info($"Loaded {filters.Count} filter{(filters.Count == 1 ? "" : "s")}"); 42 | } 43 | else 44 | { 45 | File.Create(filterFilePath); 46 | Log.Info($"{filterFilePath} created, add regular expressions to it."); 47 | } 48 | 49 | Harmony.Patch(AccessTools.Method(typeof(Chainloader), nameof(Chainloader.Initialize)), 50 | postfix: new HarmonyMethod(AccessTools.Method(typeof(UnityLogFilter), nameof(ChainloaderHook)))); 51 | } 52 | 53 | public static void ChainloaderHook() 54 | { 55 | Harmony.Patch(AccessTools.Method(typeof(UnityLogSource), "UnityLogMessageHandler"), 56 | prefix: new HarmonyMethod(AccessTools.Method(typeof(UnityLogFilter), nameof(LogPatch)))); 57 | } 58 | 59 | public static bool LogPatch(LogEventArgs eventArgs) 60 | { 61 | return !(eventArgs.Data is string msg && filters.Any(x => x.IsMatch(msg))); 62 | } 63 | 64 | public static bool VerifyRegex(string testPattern) 65 | { 66 | bool isValid = true; 67 | 68 | if(testPattern != null && testPattern.Trim().Length > 0) 69 | { 70 | try 71 | { 72 | Regex.Match("", testPattern); 73 | } 74 | catch(ArgumentException) 75 | { 76 | // BAD PATTERN: Syntax error 77 | isValid = false; 78 | } 79 | } 80 | else 81 | { 82 | //BAD PATTERN: Pattern is null or blank 83 | isValid = false; 84 | } 85 | 86 | return isValid; 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/TitleShortcuts.HoneySelect2/TitleShortcuts.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using BepInEx.Configuration; 3 | using KeelPlugins; 4 | using System.Collections; 5 | using HS2; 6 | using TitleShortcuts.Core; 7 | using UnityEngine; 8 | using UnityEngine.Events; 9 | using UnityEngine.SceneManagement; 10 | 11 | [assembly: System.Reflection.AssemblyVersion(TitleShortcuts.HoneySelect2.TitleShortcuts.Version)] 12 | 13 | namespace TitleShortcuts.HoneySelect2 14 | { 15 | [BepInProcess(Constants.MainGameProcessName)] 16 | [BepInPlugin(GUID, PluginName, Version)] 17 | public class TitleShortcuts : TitleShortcutsCore 18 | { 19 | public const string Version = "1.3.1." + BuildNumber.Version; 20 | 21 | private ConfigEntry StartFemaleMaker { get; set; } 22 | private ConfigEntry StartMaleMaker { get; set; } 23 | private ConfigEntry StartUploader { get; set; } 24 | private ConfigEntry StartDownloader { get; set; } 25 | private ConfigEntry StartGame { get; set; } 26 | 27 | private TitleScene titleScene; 28 | 29 | protected override void Awake() 30 | { 31 | base.Awake(); 32 | 33 | StartFemaleMaker = Config.Bind(SECTION_HOTKEYS, "Open female maker", new KeyboardShortcut(KeyCode.F)); 34 | StartMaleMaker = Config.Bind(SECTION_HOTKEYS, "Open male maker", new KeyboardShortcut(KeyCode.M)); 35 | StartUploader = Config.Bind(SECTION_HOTKEYS, "Open uploader", new KeyboardShortcut(KeyCode.U)); 36 | StartDownloader = Config.Bind(SECTION_HOTKEYS, "Open downloader", new KeyboardShortcut(KeyCode.D)); 37 | StartGame = Config.Bind(SECTION_HOTKEYS, "Open main game", new KeyboardShortcut(KeyCode.G)); 38 | 39 | SceneManager.sceneLoaded += StartInput; 40 | } 41 | 42 | private void StartInput(Scene scene, LoadSceneMode mode) 43 | { 44 | StopAllCoroutines(); 45 | 46 | titleScene = FindObjectOfType(); 47 | 48 | if (titleScene) StartCoroutine(InputCheck()); 49 | } 50 | 51 | private IEnumerator InputCheck() 52 | { 53 | while (titleScene) 54 | { 55 | if (!Manager.Scene.IsNowLoadingFade) 56 | { 57 | if (StartFemaleMaker.Value.IsPressed()) StartMode(titleScene.OnMakeFemale, "Starting female maker"); 58 | else if (StartMaleMaker.Value.IsPressed()) StartMode(titleScene.OnMakeMale, "Starting male maker"); 59 | else if (StartUploader.Value.IsPressed()) StartMode(titleScene.OnUpload, "Starting uploader"); 60 | else if (StartDownloader.Value.IsPressed()) StartMode(titleScene.OnDownload, "Starting downloader"); 61 | else if (StartGame.Value.IsPressed()) StartMode(titleScene.OnPlay, "Starting main game"); 62 | } 63 | 64 | yield return null; 65 | } 66 | 67 | void StartMode(UnityAction action, string msg) 68 | { 69 | var configWindow = FindObjectOfType(); 70 | if (!configWindow || !configWindow.active) 71 | { 72 | Log.Message(msg); 73 | action(); 74 | titleScene = null; 75 | } 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/LightManager.Core/SceneDataController.cs: -------------------------------------------------------------------------------- 1 | using ExtensibleSaveFormat; 2 | using KKAPI.Studio.SaveLoad; 3 | using KKAPI.Utilities; 4 | using LightManager.Core; 5 | using MessagePack; 6 | using Studio; 7 | using System.Collections.Generic; 8 | 9 | namespace LightManager.Koikatu 10 | { 11 | public class SceneDataController : SceneCustomFunctionController 12 | { 13 | private const string SavedLights = "SavedLights"; 14 | 15 | protected override void OnSceneLoad(SceneOperationKind operation, ReadOnlyDictionary loadedItems) 16 | { 17 | var data = GetExtendedData(); 18 | if(data == null) 19 | return; 20 | 21 | if(operation == SceneOperationKind.Load && data.data.TryGetValue(SavedLights, out var savedLightData)) 22 | { 23 | var savedLights = MessagePackSerializer.Deserialize>((byte[])savedLightData); 24 | foreach(var savedLight in savedLights) 25 | { 26 | if(loadedItems.TryGetValue(savedLight.LightId, out var lightInfo) && lightInfo is OCILight ocilight) 27 | { 28 | if(loadedItems.TryGetValue(savedLight.TargetId, out var targetInfo) && targetInfo is OCIChar targetChara) 29 | { 30 | var tracker = ocilight.light.gameObject.AddComponent(); 31 | tracker.target = targetChara.charInfo.objBody.transform; 32 | tracker.targetKey = targetInfo.objectInfo.dicKey; 33 | tracker.rotationSpeed = savedLight.RotationSpeed; 34 | tracker.targetName = savedLight.TargetName; 35 | } 36 | } 37 | } 38 | } 39 | } 40 | 41 | protected override void OnSceneSave() 42 | { 43 | var studio = Studio.Studio.Instance; 44 | var savedLights = new List(); 45 | 46 | foreach(var objectCtrlInfo in studio.dicObjectCtrl.Values) 47 | { 48 | if(objectCtrlInfo is OCILight light) 49 | { 50 | var tracker = light.light.gameObject.GetComponent(); 51 | if(tracker && studio.dicObjectCtrl.TryGetValue(tracker.targetKey, out _)) 52 | { 53 | savedLights.Add(new SavedLight 54 | { 55 | LightId = objectCtrlInfo.objectInfo.dicKey, 56 | TargetId = tracker.targetKey, 57 | RotationSpeed = tracker.rotationSpeed, 58 | TargetName = tracker.targetName 59 | }); 60 | } 61 | } 62 | } 63 | 64 | if(savedLights.Count > 0) 65 | { 66 | var data = new PluginData(); 67 | data.data.Add(SavedLights, MessagePackSerializer.Serialize(savedLights)); 68 | SetExtendedData(data); 69 | } 70 | } 71 | 72 | [MessagePackObject(true)] 73 | public class SavedLight 74 | { 75 | public int LightId; 76 | public int TargetId; 77 | public float RotationSpeed; 78 | public string TargetName; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/MaterialLink.KoikatuSunshine/MaterialLink.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using BepInEx; 4 | using HarmonyLib; 5 | using UnityEngine; 6 | 7 | [assembly: System.Reflection.AssemblyVersion(MaterialLink.KoikatuSunshine.MaterialLinkInfo.Version)] 8 | 9 | namespace MaterialLink.KoikatuSunshine 10 | { 11 | [BepInPlugin(GUID, PluginName, Version)] 12 | public class MaterialLinkInfo : BaseUnityPlugin 13 | { 14 | public const string GUID = "keelhauled.materiallink"; 15 | public const string PluginName = "MaterialLink"; 16 | public const string Version = "1.0.0." + BuildNumber.Version; 17 | 18 | private static MaterialLinkInfo plugin; 19 | private static readonly List ManagedRenderers = new List(); 20 | 21 | private void Awake() 22 | { 23 | plugin = this; 24 | Log.SetLogSource(Logger); 25 | Harmony.CreateAndPatchAll(typeof(MaterialLinkInfo)); 26 | } 27 | 28 | // color change 29 | [HarmonyPostfix, HarmonyPatch(typeof(ChaControl), nameof(ChaControl.ChangeCustomClothes)), HarmonyWrapSafe] 30 | private static void ChangeCustomClothes_Postfix(ChaControl __instance) 31 | { 32 | UpdateMaterials(__instance); 33 | } 34 | 35 | // coordinate change 36 | [HarmonyPostfix, HarmonyPatch(typeof(ChaControl), nameof(ChaControl.UpdateClothesStateAll))] 37 | private static void UpdateClothesStateAll_Postfix(ChaControl __instance) 38 | { 39 | UpdateMaterialsDelayed(__instance, 10); 40 | } 41 | 42 | // character start 43 | [HarmonyPostfix, HarmonyPatch(typeof(ChaControl), nameof(ChaControl.Initialize)), HarmonyWrapSafe] 44 | private static void Initialize_Postfix(ChaControl __instance) 45 | { 46 | UpdateMaterialsDelayed(__instance, 10); 47 | } 48 | 49 | private static void UpdateMaterialsDelayed(ChaControl chara, int framesToWait) 50 | { 51 | plugin.StartCoroutine(Coroutine()); 52 | 53 | IEnumerator Coroutine() 54 | { 55 | for(int i = 0; i < framesToWait; i++) 56 | yield return null; 57 | 58 | UpdateMaterials(chara); 59 | } 60 | } 61 | 62 | private static void UpdateMaterials(ChaControl chara) 63 | { 64 | if(!chara) 65 | return; 66 | 67 | // Find clothing that uses the skin shader 68 | foreach(var cloth in chara.gameObject.GetComponentsInChildren()) 69 | foreach(var rend in cloth.gameObject.GetComponentsInChildren()) 70 | { 71 | if(rend && rend.material.shader.name == "Shader Forge/main_skin" && !ManagedRenderers.Contains(rend)) 72 | { 73 | Log.Info($"Managing {cloth.name}"); 74 | ManagedRenderers.Add(rend); 75 | } 76 | } 77 | 78 | // Edit found renderers to use skin material 79 | if(chara.customMatBody) 80 | { 81 | foreach(var rend in ManagedRenderers) 82 | { 83 | if(rend && rend.material != chara.customMatBody) 84 | rend.material = chara.customMatBody; 85 | } 86 | } 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/TitleShortcuts.AISyoujyo/TitleShortcuts.cs: -------------------------------------------------------------------------------- 1 | using AIProject; 2 | using BepInEx; 3 | using BepInEx.Configuration; 4 | using KeelPlugins; 5 | using System.Collections; 6 | using TitleShortcuts.Core; 7 | using UnityEngine; 8 | using UnityEngine.Events; 9 | using UnityEngine.SceneManagement; 10 | 11 | [assembly: System.Reflection.AssemblyVersion(TitleShortcuts.AISyoujyo.TitleShortcuts.Version)] 12 | 13 | namespace TitleShortcuts.AISyoujyo 14 | { 15 | [BepInProcess(Constants.MainGameProcessName)] 16 | [BepInProcess(Constants.MainGameProcessNameSteam)] 17 | [BepInPlugin(GUID, PluginName, Version)] 18 | public class TitleShortcuts : TitleShortcutsCore 19 | { 20 | public const string Version = "1.3.1." + BuildNumber.Version; 21 | 22 | private ConfigEntry StartFemaleMaker { get; set; } 23 | private ConfigEntry StartMaleMaker { get; set; } 24 | private ConfigEntry StartUploader { get; set; } 25 | private ConfigEntry StartDownloader { get; set; } 26 | private ConfigEntry StartGame { get; set; } 27 | 28 | private TitleScene titleScene; 29 | 30 | protected override void Awake() 31 | { 32 | base.Awake(); 33 | 34 | StartFemaleMaker = Config.Bind(SECTION_HOTKEYS, "Open female maker", new KeyboardShortcut(KeyCode.F)); 35 | StartMaleMaker = Config.Bind(SECTION_HOTKEYS, "Open male maker", new KeyboardShortcut(KeyCode.M)); 36 | StartUploader = Config.Bind(SECTION_HOTKEYS, "Open uploader", new KeyboardShortcut(KeyCode.U)); 37 | StartDownloader = Config.Bind(SECTION_HOTKEYS, "Open downloader", new KeyboardShortcut(KeyCode.D)); 38 | StartGame = Config.Bind(SECTION_HOTKEYS, "Open main game", new KeyboardShortcut(KeyCode.G)); 39 | 40 | SceneManager.sceneLoaded += StartInput; 41 | } 42 | 43 | private void StartInput(Scene scene, LoadSceneMode mode) 44 | { 45 | StopAllCoroutines(); 46 | 47 | titleScene = FindObjectOfType(); 48 | 49 | if (titleScene) StartCoroutine(InputCheck()); 50 | } 51 | 52 | private IEnumerator InputCheck() 53 | { 54 | while (titleScene) 55 | { 56 | if (!Manager.Scene.Instance.IsNowLoadingFade) 57 | { 58 | if (StartFemaleMaker.Value.IsPressed()) StartMode(titleScene.OnCustomFemale, "Starting female maker"); 59 | else if (StartMaleMaker.Value.IsPressed()) StartMode(titleScene.OnCustomMale, "Starting male maker"); 60 | else if (StartUploader.Value.IsPressed()) StartMode(titleScene.OnUploader, "Starting uploader"); 61 | else if (StartDownloader.Value.IsPressed()) StartMode(titleScene.OnDownloader, "Starting downloader"); 62 | else if (StartGame.Value.IsPressed()) StartMode(titleScene.OnStart, "Starting main game"); 63 | } 64 | 65 | yield return null; 66 | } 67 | 68 | void StartMode(UnityAction action, string msg) 69 | { 70 | if (!FindObjectOfType()) 71 | { 72 | Log.Message(msg); 73 | action(); 74 | titleScene = null; 75 | } 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/LockOnPlugin.Core/HSceneMono.cs: -------------------------------------------------------------------------------- 1 | using IllusionUtility.GetUtility; 2 | using UnityEngine; 3 | 4 | namespace LockOnPlugin 5 | { 6 | internal class HSceneMono : LockOnBase 7 | { 8 | private readonly CameraControl_Ver2 camera = Singleton.Instance; 9 | 10 | protected override float CameraMoveSpeed 11 | { 12 | get => camera.moveSpeed; 13 | set => camera.moveSpeed = value; 14 | } 15 | 16 | protected override Vector3 CameraTargetPos 17 | { 18 | get => camera.TargetPos; 19 | set => camera.TargetPos = value; 20 | } 21 | 22 | protected override Vector3 CameraAngle 23 | { 24 | get => camera.CameraAngle; 25 | set => camera.CameraAngle = value; 26 | } 27 | 28 | protected override float CameraFov 29 | { 30 | get => camera.CameraFov; 31 | set => camera.CameraFov = value; 32 | } 33 | 34 | protected override Vector3 CameraDir 35 | { 36 | get => camera.CameraDir; 37 | set => camera.CameraDir = value; 38 | } 39 | 40 | protected override bool CameraTargetTex 41 | { 42 | set => camera.isConfigTargetTex = value; 43 | } 44 | 45 | protected override float CameraZoomSpeed => defaultCameraSpeed; 46 | protected override Transform CameraTransform => camera.transform; 47 | protected override bool AllowTracking => true; 48 | protected override bool InputFieldSelected => base.InputFieldSelected; 49 | protected override bool CameraEnabled => camera.enabled; 50 | protected override Vector3 CameraForward => camera.transBase.InverseTransformDirection(camera.transform.forward); 51 | protected override Vector3 CameraRight => camera.transBase.InverseTransformDirection(camera.transform.right); 52 | protected override Vector3 CameraUp => camera.transBase.InverseTransformDirection(camera.transform.up); 53 | protected override Vector3 LockOnTargetPos => camera.transBase.InverseTransformPoint(lockOnTarget.transform.position); 54 | 55 | private ChaInfo GetClosestChara() 56 | { 57 | ChaInfo closestChara = null; 58 | float smallestMagnitude = 0f; 59 | 60 | foreach(var chara in FindObjectsOfType()) 61 | { 62 | float magnitude = 0f; 63 | foreach(var targetname in TargetData.Instance.presenceTargets) 64 | { 65 | var target = chara.objBodyBone.transform.FindLoop(targetname); 66 | float distance = Vector3.Distance(camera.TargetPos, camera.transBase.InverseTransformPoint(target.transform.position)); 67 | magnitude += distance; 68 | } 69 | 70 | if(!closestChara) 71 | { 72 | closestChara = chara; 73 | smallestMagnitude = magnitude; 74 | } 75 | else 76 | { 77 | if(magnitude < smallestMagnitude) 78 | { 79 | closestChara = chara; 80 | smallestMagnitude = magnitude; 81 | } 82 | } 83 | } 84 | 85 | return closestChara; 86 | } 87 | 88 | protected override bool LockOn() 89 | { 90 | if(!lockedOn) currentCharaInfo = GetClosestChara(); 91 | return base.LockOn(); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/RealPOV.PlayHome/RealPOV.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using BepInEx.Bootstrap; 3 | using BepInEx.Configuration; 4 | using HarmonyLib; 5 | using KeelPlugins.Utils; 6 | using RealPOV.Core; 7 | using UnityEngine; 8 | 9 | [assembly: System.Reflection.AssemblyVersion(RealPOV.PlayHome.RealPOV.Version)] 10 | 11 | namespace RealPOV.PlayHome 12 | { 13 | [BepInPlugin(GUID, PluginName, Version)] 14 | public class RealPOV : RealPOVCore 15 | { 16 | public const string Version = "1.1.1." + BuildNumber.Version; 17 | 18 | private const string SECTION_OFFSETS = "Offsets"; 19 | 20 | internal static ConfigEntry FemaleOffsetX { get; set; } 21 | internal static ConfigEntry FemaleOffsetY { get; set; } 22 | internal static ConfigEntry FemaleOffsetZ { get; set; } 23 | internal static ConfigEntry MaleOffsetX { get; set; } 24 | internal static ConfigEntry MaleOffsetY { get; set; } 25 | internal static ConfigEntry MaleOffsetZ { get; set; } 26 | internal static ConfigEntry CycleNextHotkey { get; set; } 27 | internal static ConfigEntry CyclePrevHotkey { get; set; } 28 | internal static ConfigEntry IncludeFemalePOV { get; set; } 29 | internal static ConfigEntry DefaultNearClip { get; set; } 30 | 31 | protected static float defaultNearClip = 0.06f; 32 | 33 | protected override void Awake() 34 | { 35 | base.Awake(); 36 | 37 | FemaleOffsetX = Config.Bind(SECTION_OFFSETS, "Female offset X", 0f, new ConfigDescription("", null, new ConfigurationManagerAttributes { IsAdvanced = true })); 38 | FemaleOffsetY = Config.Bind(SECTION_OFFSETS, "Female offset Y", 0.0315f, new ConfigDescription("", null, new ConfigurationManagerAttributes { IsAdvanced = true })); 39 | FemaleOffsetZ = Config.Bind(SECTION_OFFSETS, "Female offset Z", 0f, new ConfigDescription("", null, new ConfigurationManagerAttributes { IsAdvanced = true })); 40 | 41 | MaleOffsetX = Config.Bind(SECTION_OFFSETS, "Male offset X", 0f, new ConfigDescription("", null, new ConfigurationManagerAttributes { IsAdvanced = true })); 42 | MaleOffsetY = Config.Bind(SECTION_OFFSETS, "Male offset Y", 0.092f, new ConfigDescription("", null, new ConfigurationManagerAttributes { IsAdvanced = true })); 43 | MaleOffsetZ = Config.Bind(SECTION_OFFSETS, "Male offset Z", 0.12f, new ConfigDescription("", null, new ConfigurationManagerAttributes { IsAdvanced = true })); 44 | 45 | CycleNextHotkey = Config.Bind(SECTION_HOTKEYS, "Cycle next character POV", new KeyboardShortcut(KeyCode.KeypadPlus)); 46 | CyclePrevHotkey = Config.Bind(SECTION_HOTKEYS, "Cycle previous character POV", new KeyboardShortcut(KeyCode.KeypadMinus)); 47 | IncludeFemalePOV = Config.Bind(SECTION_GENERAL, "Include female POV when cycling", false); 48 | DefaultNearClip = Config.Bind(SECTION_GENERAL, "Default camera near clip", defaultNearClip, new ConfigDescription("", new AcceptableValueRange(0.01f, 0.1f))); 49 | 50 | Harmony.CreateAndPatchAll(GetType()); 51 | } 52 | 53 | protected override void EnablePov() 54 | { 55 | 56 | } 57 | 58 | protected override void DisablePov() 59 | { 60 | 61 | } 62 | 63 | [HarmonyPostfix, HarmonyPatch(typeof(H_Scene), "Awake")] 64 | private static void HSceneInit() 65 | { 66 | Chainloader.ManagerObject.GetOrAddComponent(); 67 | } 68 | 69 | [HarmonyPostfix, HarmonyPatch(typeof(StudioScene), "Start")] 70 | private static void StudioSceneInit() 71 | { 72 | Chainloader.ManagerObject.GetOrAddComponent(); 73 | } 74 | 75 | [HarmonyPostfix, HarmonyPatch(typeof(H_Scene), "OnDestroy")] 76 | private static void HSceneDestroy() 77 | { 78 | Destroy(Chainloader.ManagerObject.GetComponent()); 79 | } 80 | } 81 | } 82 | --------------------------------------------------------------------------------