├── doc ├── studio icon template.png ├── KKAPI.Maker.UI.Sidebar.md └── KoiSkinOverlayX.md ├── src ├── Shared.Core │ ├── UI │ │ ├── local-back.png │ │ ├── local-check.png │ │ └── local-frame.png │ ├── Utilities │ │ ├── IMGUI │ │ │ ├── guisharp-box.png │ │ │ ├── guisharp-window.png │ │ │ ├── guisharp-box-light.png │ │ │ ├── guisharp-window-light.png │ │ │ └── InterfaceMaker.cs │ │ ├── TextUtils.cs │ │ ├── IgnoreCaseEqualityComparer.cs │ │ ├── WindowsStringComparer.cs │ │ ├── ObservableExtensions.cs │ │ └── ImageTypeIdentifier.cs │ ├── Constants.cs │ ├── Maker │ │ ├── UI │ │ │ └── Sidebar │ │ │ │ └── ISidebarControl.cs │ │ ├── CharaTextureSaveType.cs │ │ ├── CharaTextureSaveTypeChangedEventArgs.cs │ │ ├── Events │ │ │ ├── RegisterSubCategoriesEvent.cs │ │ │ ├── CharacterChangedEventArgs.cs │ │ │ └── RegisterCustomControlsEvent.cs │ │ ├── CharacterLoadFlags.cs │ │ └── MakerCategory.cs │ ├── Chara │ │ ├── Events │ │ │ ├── CharaReloadEventArgs.cs │ │ │ └── CoordinateEventArgs.cs │ │ └── CharacterApi.ControllerRegistration.cs │ ├── GameMode.cs │ ├── Shared.Core.shproj │ └── SceneApi.cs ├── KKAPI │ ├── MainGame │ │ ├── ActionIcons │ │ │ ├── Action_Icon_On_Template.png │ │ │ └── Action_Icon_Off_Template.png │ │ ├── TouchIcons │ │ │ ├── Touch_Icon_Selected_Template.png │ │ │ └── Touch_Icon_Deselected_Template.png │ │ ├── TalkScene │ │ │ └── TalkSceneActionKind.cs │ │ ├── Events │ │ │ └── GameSaveLoadEventArgs.cs │ │ └── TestGameFunctionController.cs │ ├── KKAPI.nuspec │ ├── Maker │ │ └── AccessoryCopyEventArgs.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── packages.config │ └── KKAPI.csproj.DotSettings ├── KKSAPI │ ├── MainGame │ │ ├── ActionIcons │ │ │ └── Action_Icon_Template.png │ │ ├── TalkScene │ │ │ └── TalkSceneActionKind.cs │ │ ├── Events │ │ │ └── GameSaveLoadEventArgs.cs │ │ └── TestGameFunctionController.cs │ ├── KKSAPI.nuspec │ ├── Maker │ │ └── AccessoryCopyEventArgs.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config ├── PHAPI │ ├── Maker │ │ ├── UI │ │ │ ├── Sidebar │ │ │ │ ├── ISidebarControl.cs │ │ │ │ ├── SidebarSeparator.cs │ │ │ │ └── SidebarToggle.cs │ │ │ ├── MakerSeparator.cs │ │ │ ├── MakerButton.cs │ │ │ ├── MakerText.cs │ │ │ ├── MakerDropdown.cs │ │ │ ├── MakerToggle.cs │ │ │ ├── MakerColor.cs │ │ │ └── MakerSlider.cs │ │ ├── Events │ │ │ ├── CharaTextureSaveTypeChangedEventArgs.cs │ │ │ ├── RegisterSubCategoriesEvent.cs │ │ │ ├── AccessoryTransferEventArgs.cs │ │ │ ├── AccessoryWindowControlValueChangedEventArgs.cs │ │ │ ├── AccessorySlotEventArgs.cs │ │ │ ├── CharacterChangedEventArgs.cs │ │ │ └── RegisterCustomControlsEvent.cs │ │ ├── CharacterLoadFlags.cs │ │ ├── AccessoriesApi.Hooks.PH.cs │ │ └── MakerCategory.cs │ ├── CharaTextureSaveType.cs │ ├── PHAPI.csproj.DotSettings │ ├── PHAPI.nuspec │ ├── Chara │ │ ├── Events │ │ │ ├── CharaReloadEventArgs.cs │ │ │ └── CoordinateEventArgs.cs │ │ ├── TestCharaCustomFunctionController.cs │ │ └── CharacterApi.ControllerRegistration.cs │ ├── GameMode.cs │ ├── packages.config │ ├── Properties │ │ └── AssemblyInfo.cs │ └── KoikatuAPI.cs ├── install.ps1 ├── .editorconfig ├── AIAPI │ ├── AIAPI.csproj.DotSettings │ ├── AIAPI.nuspec │ ├── MainGame │ │ ├── Events │ │ │ └── GameSaveLoadEventArgs.cs │ │ ├── TestGameFunctionController.cs │ │ └── GameAPI.Hooks.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── packages.config │ └── KoikatuAPI.cs ├── nuget.config ├── ECAPI │ ├── ECAPI.nuspec │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── KoikatuAPI.cs │ ├── KKAPI.csproj.DotSettings │ └── packages.config ├── HS2API │ ├── HS2API.nuspec │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config ├── Shared.KKalike │ ├── Maker │ │ ├── Events │ │ │ ├── AccessoryContolVisibilityArgs.cs │ │ │ ├── AccessoryTransferEventArgs.cs │ │ │ ├── AccessoryWindowControlValueChangedEventArgs.cs │ │ │ └── AccessorySlotEventArgs.cs │ │ └── UI │ │ │ ├── Sidebar │ │ │ ├── SidebarSeparator.cs │ │ │ └── SidebarToggle.cs │ │ │ ├── MakerSeparator.cs │ │ │ ├── MakerText.cs │ │ │ └── MakerButton.cs │ ├── Shared.KKalike.shproj │ └── Shared.KKalike.projitems ├── Shared.CharaStudio │ ├── Studio │ │ ├── Events │ │ │ ├── SceneTextureSaveTypeChangedEventArgs.cs │ │ │ ├── ObjectDeletedEventArgs.cs │ │ │ ├── ObjectsSelectedEventArgs.cs │ │ │ ├── ObjectsCopiedEventArgs.cs │ │ │ ├── ObjectVisibilityToggledEventArgs.cs │ │ │ └── SceneLoadEventArgs.cs │ │ ├── SceneTextureSaveType.cs │ │ ├── SaveLoad │ │ │ ├── SceneOperationKind.cs │ │ │ └── TestSceneFunctionController.cs │ │ ├── StudioAPI.Hooks.cs │ │ └── UI │ │ │ ├── SceneEffectsCategoryLabel.cs │ │ │ ├── Toolbars │ │ │ ├── ToolbarPosition.cs │ │ │ ├── SimpleToolbarButton.cs │ │ │ ├── SimpleToolbarToggle.cs │ │ │ └── ToolbarControlAdapter.cs │ │ │ ├── BaseCurrentStateEditableGuiEntry.cs │ │ │ ├── CustomStateCategorySwitch.cs │ │ │ └── CurrentStateCategorySubItemBase.cs │ └── Shared.CharaStudio.shproj ├── Shared.AIalike │ ├── Maker │ │ ├── Events │ │ │ ├── AccessoryTransferEventArgs.cs │ │ │ ├── AccessoryWindowControlValueChangedEventArgs.cs │ │ │ └── AccessorySlotEventArgs.cs │ │ ├── AccessoriesApi.Hooks.AI.cs │ │ └── UI │ │ │ ├── MakerSeparator.cs │ │ │ ├── Sidebar │ │ │ └── SidebarToggle.cs │ │ │ ├── MakerCoordinateLoadToggle.cs │ │ │ ├── MakerToggle.cs │ │ │ ├── MakerColor.cs │ │ │ ├── MakerText.cs │ │ │ └── MakerButton.cs │ ├── Shared.AIalike.shproj │ └── Shared.AIalike.projitems ├── Helper │ └── Helper.vcxproj.filters └── Directory.Build.props ├── .github └── workflows │ └── nuget.yml └── release.ps1 /doc/studio icon template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IllusionMods/IllusionModdingAPI/HEAD/doc/studio icon template.png -------------------------------------------------------------------------------- /src/Shared.Core/UI/local-back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IllusionMods/IllusionModdingAPI/HEAD/src/Shared.Core/UI/local-back.png -------------------------------------------------------------------------------- /src/Shared.Core/UI/local-check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IllusionMods/IllusionModdingAPI/HEAD/src/Shared.Core/UI/local-check.png -------------------------------------------------------------------------------- /src/Shared.Core/UI/local-frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IllusionMods/IllusionModdingAPI/HEAD/src/Shared.Core/UI/local-frame.png -------------------------------------------------------------------------------- /src/Shared.Core/Utilities/IMGUI/guisharp-box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IllusionMods/IllusionModdingAPI/HEAD/src/Shared.Core/Utilities/IMGUI/guisharp-box.png -------------------------------------------------------------------------------- /src/Shared.Core/Utilities/IMGUI/guisharp-window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IllusionMods/IllusionModdingAPI/HEAD/src/Shared.Core/Utilities/IMGUI/guisharp-window.png -------------------------------------------------------------------------------- /src/Shared.Core/Utilities/IMGUI/guisharp-box-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IllusionMods/IllusionModdingAPI/HEAD/src/Shared.Core/Utilities/IMGUI/guisharp-box-light.png -------------------------------------------------------------------------------- /src/KKAPI/MainGame/ActionIcons/Action_Icon_On_Template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IllusionMods/IllusionModdingAPI/HEAD/src/KKAPI/MainGame/ActionIcons/Action_Icon_On_Template.png -------------------------------------------------------------------------------- /src/KKSAPI/MainGame/ActionIcons/Action_Icon_Template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IllusionMods/IllusionModdingAPI/HEAD/src/KKSAPI/MainGame/ActionIcons/Action_Icon_Template.png -------------------------------------------------------------------------------- /src/Shared.Core/Utilities/IMGUI/guisharp-window-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IllusionMods/IllusionModdingAPI/HEAD/src/Shared.Core/Utilities/IMGUI/guisharp-window-light.png -------------------------------------------------------------------------------- /src/KKAPI/MainGame/ActionIcons/Action_Icon_Off_Template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IllusionMods/IllusionModdingAPI/HEAD/src/KKAPI/MainGame/ActionIcons/Action_Icon_Off_Template.png -------------------------------------------------------------------------------- /src/KKAPI/MainGame/TouchIcons/Touch_Icon_Selected_Template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IllusionMods/IllusionModdingAPI/HEAD/src/KKAPI/MainGame/TouchIcons/Touch_Icon_Selected_Template.png -------------------------------------------------------------------------------- /src/KKAPI/MainGame/TouchIcons/Touch_Icon_Deselected_Template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IllusionMods/IllusionModdingAPI/HEAD/src/KKAPI/MainGame/TouchIcons/Touch_Icon_Deselected_Template.png -------------------------------------------------------------------------------- /src/Shared.Core/Constants.cs: -------------------------------------------------------------------------------- 1 | namespace KKAPI 2 | { 3 | internal static class Constants 4 | { 5 | public const string Version = "1.45.1"; 6 | 7 | public const string GUID = "marco.kkapi"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/UI/Sidebar/ISidebarControl.cs: -------------------------------------------------------------------------------- 1 | namespace KKAPI.Maker.UI.Sidebar 2 | { 3 | /// 4 | /// Marks the control as being intended for use on Control Panel sidebar in chara maker 5 | /// 6 | public interface ISidebarControl { } 7 | } 8 | -------------------------------------------------------------------------------- /src/Shared.Core/Maker/UI/Sidebar/ISidebarControl.cs: -------------------------------------------------------------------------------- 1 | namespace KKAPI.Maker.UI.Sidebar 2 | { 3 | /// 4 | /// Marks the control as being intended for use on Control Panel sidebar in chara maker 5 | /// 6 | public interface ISidebarControl { } 7 | } 8 | -------------------------------------------------------------------------------- /src/install.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | $asms = $package.AssemblyReferences | %{$_.Name} 3 | foreach ($reference in $project.Object.References) 4 | { 5 | if ($asms -contains $reference.Name + ".dll") 6 | { 7 | $reference.CopyLocal = $false; 8 | } 9 | } -------------------------------------------------------------------------------- /src/.editorconfig: -------------------------------------------------------------------------------- 1 | # Top-level EditorConfig file. Root applies to all subdirectories 2 | root = true 3 | 4 | [*.{cs,vb}] 5 | 6 | # IDE0041: Use 'is null' check 7 | dotnet_style_prefer_is_null_check_over_reference_equality_method = false:suggestion 8 | [*.cs] 9 | indent_style = space 10 | indent_size = 4 -------------------------------------------------------------------------------- /src/AIAPI/AIAPI.csproj.DotSettings: -------------------------------------------------------------------------------- 1 | 2 | True -------------------------------------------------------------------------------- /src/nuget.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/PHAPI/CharaTextureSaveType.cs: -------------------------------------------------------------------------------- 1 | namespace KKAPI.Maker 2 | { 3 | /// 4 | /// Options for the type of texture saving that plugins should use in Maker. 5 | /// 6 | public enum CharaTextureSaveType 7 | { 8 | /// 9 | /// Textures should be bundled with the card. 10 | /// 11 | Bundled = 0, 12 | /// 13 | /// Textures should be saved separately from the card in a local folder. 14 | /// 15 | Local = 2, 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Shared.Core/Maker/CharaTextureSaveType.cs: -------------------------------------------------------------------------------- 1 | namespace KKAPI.Maker 2 | { 3 | /// 4 | /// Options for the type of texture saving that plugins should use in Maker. 5 | /// 6 | public enum CharaTextureSaveType 7 | { 8 | /// 9 | /// Textures should be bundled with the card. 10 | /// 11 | Bundled = 0, 12 | /// 13 | /// Textures should be saved separately from the card in a local folder. 14 | /// 15 | Local = 2, 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/PHAPI/PHAPI.csproj.DotSettings: -------------------------------------------------------------------------------- 1 | 2 | True 3 | True -------------------------------------------------------------------------------- /src/PHAPI/PHAPI.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | IllusionModdingAPI.PHAPI 5 | $version$ 6 | ManlyMarco 7 | https://github.com/IllusionMods/IllusionModdingAPI 8 | false 9 | Modding API for PlayHome 10 | true 11 | PlayHome 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/ECAPI/ECAPI.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | IllusionModdingAPI.ECAPI 5 | $version$ 6 | ManlyMarco 7 | https://github.com/IllusionMods/IllusionModdingAPI 8 | false 9 | Modding API for Emotion Creators 10 | true 11 | EmotionCreators 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/HS2API/HS2API.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | IllusionModdingAPI.HS2API 5 | $version$ 6 | ManlyMarco 7 | https://github.com/IllusionMods/IllusionModdingAPI 8 | false 9 | Modding API for HoneySelect2 10 | true 11 | HoneySelect2 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/KKAPI/KKAPI.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | IllusionModdingAPI.KKAPI 5 | $version$ 6 | ManlyMarco 7 | https://github.com/IllusionMods/IllusionModdingAPI 8 | false 9 | Modding API for Koikatu 10 | true 11 | Koikatu KoikatsuParty 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/AIAPI/AIAPI.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | IllusionModdingAPI.AIAPI 5 | $version$ 6 | ManlyMarco 7 | https://github.com/IllusionMods/IllusionModdingAPI 8 | false 9 | Modding API for AI Girl 10 | true 11 | AIGirl AIShoujo AISyoujyo 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/KKSAPI/KKSAPI.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | IllusionModdingAPI.KKSAPI 5 | $version$ 6 | ManlyMarco 7 | https://github.com/IllusionMods/IllusionModdingAPI 8 | false 9 | Modding API for Koikatsu Sunshine 10 | true 11 | Koikatu Sunshine 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/PHAPI/Chara/Events/CharaReloadEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | #pragma warning disable 1591 4 | 5 | namespace KKAPI.Chara 6 | { 7 | /// 8 | /// Event arguments used by character reload events 9 | /// 10 | public sealed class CharaReloadEventArgs : EventArgs 11 | { 12 | public CharaReloadEventArgs(Human reloadedCharacter) 13 | { 14 | ReloadedCharacter = reloadedCharacter; 15 | } 16 | 17 | /// 18 | /// Can be null when all characters in a scene are reloaded 19 | /// 20 | public Human ReloadedCharacter { get; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/Events/CharaTextureSaveTypeChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | #pragma warning disable 1591 4 | 5 | namespace KKAPI.Maker 6 | { 7 | /// 8 | /// Event argument used for when save type for cards is toggled 9 | /// 10 | public sealed class CharaTextureSaveTypeChangedEventArgs : EventArgs 11 | { 12 | public CharaTextureSaveTypeChangedEventArgs(CharaTextureSaveType saveType) 13 | { 14 | NewSetting = saveType; 15 | } 16 | 17 | /// 18 | /// The new state of the setting 19 | /// 20 | public CharaTextureSaveType NewSetting { get; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Shared.Core/Utilities/TextUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace KKAPI.Utilities 5 | { 6 | /// 7 | /// Utility methods for working with text. 8 | /// 9 | public static class TextUtils 10 | { 11 | /// 12 | /// Convert PascalCase to Sentence case. 13 | /// 14 | public static string PascalCaseToSentenceCase(this string str) 15 | { 16 | if (str == null) throw new ArgumentNullException(nameof(str)); 17 | return Regex.Replace(str, "[a-z][A-Z]", m => $"{m.Value[0]} {char.ToLower(m.Value[1])}"); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Shared.KKalike/Maker/Events/AccessoryContolVisibilityArgs.cs: -------------------------------------------------------------------------------- 1 | using ChaCustom; 2 | using System; 3 | #pragma warning disable 612 4 | 5 | namespace KKAPI.Maker 6 | { 7 | /// 8 | /// Event args for events that are related to accessory control visibility. 9 | /// 10 | public class AccessoryContolVisibilityArgs : EventArgs 11 | { 12 | /// 13 | public AccessoryContolVisibilityArgs(bool _show) 14 | { 15 | Show = _show; 16 | } 17 | 18 | /// 19 | /// Visibility state of accessory control 20 | /// 21 | public bool Show { get; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Shared.Core/Maker/CharaTextureSaveTypeChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | #pragma warning disable 1591 4 | 5 | namespace KKAPI.Maker 6 | { 7 | /// 8 | /// Event argument used for when texture save type for cards is changed 9 | /// 10 | public sealed class CharaTextureSaveTypeChangedEventArgs : EventArgs 11 | { 12 | public CharaTextureSaveTypeChangedEventArgs(CharaTextureSaveType saveType) 13 | { 14 | NewSetting = saveType; 15 | } 16 | 17 | /// 18 | /// The new state of the setting 19 | /// 20 | public CharaTextureSaveType NewSetting { get; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/Events/RegisterSubCategoriesEvent.cs: -------------------------------------------------------------------------------- 1 | namespace KKAPI.Maker 2 | { 3 | /// 4 | /// Event fired when character maker is starting and plugins are given an opportunity to register custom categories and controls 5 | /// 6 | public class RegisterSubCategoriesEvent : RegisterCustomControlsEvent 7 | { 8 | /// 9 | /// Add custom sub categories. They need to be added before maker starts loading, 10 | /// or in the RegisterCustomSubCategories event. 11 | /// 12 | public void AddSubCategory(MakerCategory category) 13 | { 14 | MakerAPI.AddSubCategory(category); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Shared.CharaStudio/Studio/Events/SceneTextureSaveTypeChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | #pragma warning disable 1591 4 | 5 | namespace KKAPI.Studio 6 | { 7 | /// 8 | /// Event argument used for when texture save type for scenes is changed 9 | /// 10 | public sealed class SceneTextureSaveTypeChangedEventArgs : EventArgs 11 | { 12 | public SceneTextureSaveTypeChangedEventArgs(SceneTextureSaveType saveType) 13 | { 14 | NewSetting = saveType; 15 | } 16 | 17 | /// 18 | /// The new state of the setting 19 | /// 20 | public SceneTextureSaveType NewSetting { get; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Shared.Core/Maker/Events/RegisterSubCategoriesEvent.cs: -------------------------------------------------------------------------------- 1 | namespace KKAPI.Maker 2 | { 3 | /// 4 | /// Event fired when character maker is starting and plugins are given an opportunity to register custom categories and controls 5 | /// 6 | public class RegisterSubCategoriesEvent : RegisterCustomControlsEvent 7 | { 8 | /// 9 | /// Add custom sub categories. They need to be added before maker starts loading, 10 | /// or in the RegisterCustomSubCategories event. 11 | /// 12 | public void AddSubCategory(MakerCategory category) 13 | { 14 | MakerAPI.AddSubCategory(category); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Shared.Core/Chara/Events/CharaReloadEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | #if AI || HS2 3 | using AIChara; 4 | #endif 5 | 6 | #pragma warning disable 1591 7 | 8 | namespace KKAPI.Chara 9 | { 10 | /// 11 | /// Event arguments used by character reload events 12 | /// 13 | public sealed class CharaReloadEventArgs : EventArgs 14 | { 15 | public CharaReloadEventArgs(ChaControl reloadedCharacter) 16 | { 17 | ReloadedCharacter = reloadedCharacter; 18 | } 19 | 20 | /// 21 | /// Can be null when all characters in a scene are reloaded 22 | /// 23 | public ChaControl ReloadedCharacter { get; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/UI/Sidebar/SidebarSeparator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BepInEx; 3 | using UnityEngine; 4 | 5 | namespace KKAPI.Maker.UI.Sidebar 6 | { 7 | /// 8 | [Obsolete("Not supported")] 9 | public class SidebarSeparator : BaseGuiEntry, ISidebarControl 10 | { 11 | /// 12 | public SidebarSeparator(BaseUnityPlugin owner) : base(null, owner) { } 13 | 14 | /// 15 | protected internal override void Initialize() { } 16 | 17 | /// 18 | protected override GameObject OnCreateControl(Transform subCategoryList) 19 | { 20 | throw new NotImplementedException(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Shared.CharaStudio/Studio/SceneTextureSaveType.cs: -------------------------------------------------------------------------------- 1 | namespace KKAPI.Studio 2 | { 3 | /// 4 | /// Options for the type of texture saving that plugins should use in Studio. 5 | /// 6 | public enum SceneTextureSaveType 7 | { 8 | /// 9 | /// Textures should be bundled with the scene. 10 | /// 11 | Bundled = 0, 12 | /// 13 | /// Textures should be deduped between different Chara and SceneControllers. 14 | /// 15 | Deduped = 1, 16 | /// 17 | /// Textures should be saved separately from the scene in a local folder. 18 | /// 19 | Local = 2, 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Shared.CharaStudio/Studio/Events/ObjectDeletedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using Studio; 2 | using System; 3 | 4 | namespace KKAPI.Studio.SaveLoad 5 | { 6 | /// 7 | /// Arguments used in object deleted events 8 | /// 9 | /// 10 | public sealed class ObjectDeletedEventArgs : EventArgs 11 | { 12 | /// 13 | /// Object being deleted 14 | public ObjectDeletedEventArgs(ObjectCtrlInfo deletedObject) 15 | { 16 | DeletedObject = deletedObject; 17 | } 18 | 19 | /// 20 | /// Object deleted by the event 21 | /// 22 | public ObjectCtrlInfo DeletedObject { get; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/KKAPI/MainGame/TalkScene/TalkSceneActionKind.cs: -------------------------------------------------------------------------------- 1 | namespace KKAPI.MainGame 2 | { 3 | /// 4 | /// Specifies the 3 buttons on the right when talking to a girl (the ones that you click to get a list of conversation topics) 5 | /// 6 | public enum TalkSceneActionKind 7 | { 8 | /// 9 | /// Top button, speak to the character about something. 10 | /// 11 | Talk, 12 | /// 13 | /// Middle button, listen to the character. Warning: You can't add custom buttons to this! 14 | /// 15 | Listen, 16 | /// 17 | /// Bottom button, ask the character to do something together, e.g. go exercise. 18 | /// 19 | Event 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/KKSAPI/MainGame/TalkScene/TalkSceneActionKind.cs: -------------------------------------------------------------------------------- 1 | namespace KKAPI.MainGame 2 | { 3 | /// 4 | /// Specifies the 3 buttons on the right when talking to a girl (the ones that you click to get a list of conversation topics) 5 | /// 6 | public enum TalkSceneActionKind 7 | { 8 | /// 9 | /// Top button, speak to the character about something. 10 | /// 11 | Talk, 12 | /// 13 | /// Middle button, listen to the character. Warning: You can't add custom buttons to this! 14 | /// 15 | Listen, 16 | /// 17 | /// Bottom button, ask the character to do something together, e.g. go exercise. 18 | /// 19 | Event 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Shared.CharaStudio/Studio/Events/ObjectsSelectedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using Studio; 2 | using System; 3 | using System.Collections.Generic; 4 | 5 | namespace KKAPI.Studio.SaveLoad 6 | { 7 | /// 8 | /// Arguments used in object deleted events 9 | /// 10 | /// 11 | public sealed class ObjectsSelectedEventArgs : EventArgs 12 | { 13 | /// 14 | /// Objects being selected 15 | public ObjectsSelectedEventArgs(List selectedObjects) 16 | { 17 | SelectedObjects = selectedObjects; 18 | } 19 | 20 | /// 21 | /// Object modified by the event 22 | /// 23 | public List SelectedObjects { get; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Shared.CharaStudio/Studio/Events/ObjectsCopiedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using KKAPI.Utilities; 3 | using Studio; 4 | 5 | namespace KKAPI.Studio.SaveLoad 6 | { 7 | /// 8 | /// Arguments used in objects copied events 9 | /// 10 | /// 11 | public sealed class ObjectsCopiedEventArgs : EventArgs 12 | { 13 | /// 14 | /// Objects copied by the event 15 | public ObjectsCopiedEventArgs(ReadOnlyDictionary loadedObjects) 16 | { 17 | LoadedObjects = loadedObjects; 18 | } 19 | 20 | /// 21 | /// Objects copied by the event and their original IDs 22 | /// 23 | public ReadOnlyDictionary LoadedObjects { get; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/Events/AccessoryTransferEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace KKAPI.Maker 4 | { 5 | /// 6 | /// Event args for accessory transfer events. 7 | /// 8 | public class AccessoryTransferEventArgs : EventArgs 9 | { 10 | /// 11 | public AccessoryTransferEventArgs(int sourceSlotIndex, int destinationSlotIndex) 12 | { 13 | SourceSlotIndex = sourceSlotIndex; 14 | DestinationSlotIndex = destinationSlotIndex; 15 | } 16 | 17 | /// 18 | /// Index of the source accessory. 19 | /// 20 | public int SourceSlotIndex { get; } 21 | 22 | /// 23 | /// Index the source accessory is copied to. 24 | /// 25 | public int DestinationSlotIndex { get; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Shared.Core/Maker/CharacterLoadFlags.cs: -------------------------------------------------------------------------------- 1 | #pragma warning disable 1591 2 | namespace KKAPI.Maker 3 | { 4 | /// 5 | /// Specifies which parts of the character will be loaded when loading a card in character maker. 6 | /// (It's the toggles at the bottom of load window) Only includes stock toggles. 7 | /// 8 | public sealed class CharacterLoadFlags 9 | { 10 | public bool Clothes; 11 | public bool Face; 12 | public bool Hair; 13 | public bool Body; 14 | public bool Parameters; 15 | } 16 | 17 | /// 18 | /// Specifies which parts of the coordinate will be loaded when loading a clothing card in character maker. 19 | /// 20 | public sealed class CoordinateLoadFlags 21 | { 22 | public bool Clothes; 23 | public bool Accessories; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Shared.AIalike/Maker/Events/AccessoryTransferEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace KKAPI.Maker 4 | { 5 | /// 6 | /// Event args for accessory transfer events. 7 | /// 8 | public class AccessoryTransferEventArgs : EventArgs 9 | { 10 | /// 11 | public AccessoryTransferEventArgs(int sourceSlotIndex, int destinationSlotIndex) 12 | { 13 | SourceSlotIndex = sourceSlotIndex; 14 | DestinationSlotIndex = destinationSlotIndex; 15 | } 16 | 17 | /// 18 | /// Index of the source accessory. 19 | /// 20 | public int SourceSlotIndex { get; } 21 | 22 | /// 23 | /// Index the source accessory is copied to. 24 | /// 25 | public int DestinationSlotIndex { get; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Shared.KKalike/Maker/Events/AccessoryTransferEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace KKAPI.Maker 4 | { 5 | /// 6 | /// Event args for accessory transfer events. 7 | /// 8 | public class AccessoryTransferEventArgs : EventArgs 9 | { 10 | /// 11 | public AccessoryTransferEventArgs(int sourceSlotIndex, int destinationSlotIndex) 12 | { 13 | SourceSlotIndex = sourceSlotIndex; 14 | DestinationSlotIndex = destinationSlotIndex; 15 | } 16 | 17 | /// 18 | /// Index of the source accessory. 19 | /// 20 | public int SourceSlotIndex { get; } 21 | 22 | /// 23 | /// Index the source accessory is copied to. 24 | /// 25 | public int DestinationSlotIndex { get; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/Events/AccessoryWindowControlValueChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace KKAPI.Maker 4 | { 5 | /// 6 | /// Event args used in . 7 | /// 8 | public sealed class AccessoryWindowControlValueChangedEventArgs : EventArgs 9 | { 10 | /// 11 | public AccessoryWindowControlValueChangedEventArgs(TVal newValue, int slotIndex) 12 | { 13 | NewValue = newValue; 14 | SlotIndex = slotIndex; 15 | } 16 | 17 | /// 18 | /// Newly assigned value. 19 | /// 20 | public TVal NewValue { get; } 21 | 22 | /// 23 | /// Index of the accessory the value was assigned to. 24 | /// 25 | public int SlotIndex { get; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Shared.AIalike/Maker/Events/AccessoryWindowControlValueChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace KKAPI.Maker 4 | { 5 | /// 6 | /// Event args used in . 7 | /// 8 | public sealed class AccessoryWindowControlValueChangedEventArgs : EventArgs 9 | { 10 | /// 11 | public AccessoryWindowControlValueChangedEventArgs(TVal newValue, int slotIndex) 12 | { 13 | NewValue = newValue; 14 | SlotIndex = slotIndex; 15 | } 16 | 17 | /// 18 | /// Newly assigned value. 19 | /// 20 | public TVal NewValue { get; } 21 | 22 | /// 23 | /// Index of the accessory the value was assigned to. 24 | /// 25 | public int SlotIndex { get; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Shared.KKalike/Maker/Events/AccessoryWindowControlValueChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace KKAPI.Maker 4 | { 5 | /// 6 | /// Event args used in . 7 | /// 8 | public sealed class AccessoryWindowControlValueChangedEventArgs : EventArgs 9 | { 10 | /// 11 | public AccessoryWindowControlValueChangedEventArgs(TVal newValue, int slotIndex) 12 | { 13 | NewValue = newValue; 14 | SlotIndex = slotIndex; 15 | } 16 | 17 | /// 18 | /// Newly assigned value. 19 | /// 20 | public TVal NewValue { get; } 21 | 22 | /// 23 | /// Index of the accessory the value was assigned to. 24 | /// 25 | public int SlotIndex { get; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/CharacterLoadFlags.cs: -------------------------------------------------------------------------------- 1 | #pragma warning disable 1591 2 | namespace KKAPI.Maker 3 | { 4 | /// 5 | /// Specifies which parts of the character will be loaded when loading a card in character maker. 6 | /// (It's the toggles at the bottom of load window) Only includes stock toggles. 7 | /// 8 | public sealed class CharacterLoadFlags 9 | { 10 | public bool Clothes; 11 | public bool Face; 12 | public bool Hair; 13 | public bool Body; 14 | //public bool Parameters; 15 | public bool Accessories; 16 | } 17 | 18 | /// 19 | /// Specifies which parts of the coordinate will be loaded when loading a clothing card in character maker. 20 | /// 21 | public sealed class CoordinateLoadFlags 22 | { 23 | public bool Clothes; 24 | public bool Accessories; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Shared.Core/Utilities/IgnoreCaseEqualityComparer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace KKAPI.MainGame 5 | { 6 | /// 7 | /// An equality comparer that uses StringComparison.OrdinalIgnoreCase rule 8 | /// 9 | public class IgnoreCaseEqualityComparer : IEqualityComparer 10 | { 11 | /// 12 | public bool Equals(string x, string y) 13 | { 14 | if (x == null || y == null) return false; 15 | return x.Equals(y, StringComparison.OrdinalIgnoreCase); 16 | } 17 | 18 | /// 19 | public int GetHashCode(string obj) 20 | { 21 | return obj.GetHashCode(); 22 | } 23 | 24 | /// 25 | /// Instance of the comparer for use in linq and such 26 | /// 27 | public static readonly IgnoreCaseEqualityComparer Instance = new IgnoreCaseEqualityComparer(); 28 | } 29 | } -------------------------------------------------------------------------------- /src/Shared.KKalike/Maker/UI/Sidebar/SidebarSeparator.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using UnityEngine; 3 | 4 | namespace KKAPI.Maker.UI.Sidebar 5 | { 6 | /// 7 | /// A separator to be used in the right "Control Panel" sidebar in character maker. 8 | /// The space is limited so use sparingly. 9 | /// 10 | public class SidebarSeparator : BaseGuiEntry, ISidebarControl 11 | { 12 | /// 13 | public SidebarSeparator(BaseUnityPlugin owner) : base(null, owner) { } 14 | 15 | /// 16 | protected internal override void Initialize() { } 17 | 18 | /// 19 | protected override GameObject OnCreateControl(Transform subCategoryList) 20 | { 21 | var orig = GetExistingControl("CustomScene/CustomRoot/FrontUIGroup/CvsDraw/Top", "Separate"); 22 | var copy = Object.Instantiate(orig.gameObject, orig.transform.parent); 23 | return copy; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Shared.CharaStudio/Studio/SaveLoad/SceneOperationKind.cs: -------------------------------------------------------------------------------- 1 | namespace KKAPI.Studio.SaveLoad 2 | { 3 | /// 4 | /// Scene load/change operations 5 | /// 6 | public enum SceneOperationKind 7 | { 8 | /// 9 | /// Scene is being loaded and will replace what's currently loaded. 10 | /// 11 | Load, 12 | 13 | /// 14 | /// Scene is being loaded and will be added to what's currently loaded. 15 | /// IDs in the scene will be different from the IDs in the file of the scene being imported, 16 | /// use to get IDs from the scene file. 17 | /// 18 | Import, 19 | 20 | /// 21 | /// Scene is being cleared of all state (by default, only user clicking the "Reset" button can trigger this). 22 | /// This is not triggered when studio starts. 23 | /// 24 | Clear 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Helper/Helper.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/AIAPI/MainGame/Events/GameSaveLoadEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace KKAPI.MainGame 4 | { 5 | /// 6 | /// Arguments used with main game save/load events. 7 | /// 8 | public sealed class GameSaveLoadEventArgs : EventArgs 9 | { 10 | /// 11 | /// Create a new instance 12 | /// 13 | public GameSaveLoadEventArgs(string path, string fileName) 14 | { 15 | Path = path; 16 | FileName = fileName; 17 | } 18 | 19 | /// 20 | /// Name of the safe file. 21 | /// 22 | public string FileName { get; } 23 | 24 | /// 25 | /// Full filename of the save file. 26 | /// 27 | public string FullFilename => System.IO.Path.Combine(Path, FileName); 28 | 29 | /// 30 | /// Path to which the save file will be written. 31 | /// 32 | public string Path { get; } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/KKAPI/MainGame/Events/GameSaveLoadEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace KKAPI.MainGame 4 | { 5 | /// 6 | /// Arguments used with main game save/load events. 7 | /// 8 | public sealed class GameSaveLoadEventArgs : EventArgs 9 | { 10 | /// 11 | /// Create a new instance 12 | /// 13 | public GameSaveLoadEventArgs(string path, string fileName) 14 | { 15 | Path = path; 16 | FileName = fileName; 17 | } 18 | 19 | /// 20 | /// Name of the safe file. 21 | /// 22 | public string FileName { get; } 23 | 24 | /// 25 | /// Full filename of the save file. 26 | /// 27 | public string FullFilename => System.IO.Path.Combine(Path, FileName); 28 | 29 | /// 30 | /// Path to which the save file will be written. 31 | /// 32 | public string Path { get; } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/KKSAPI/MainGame/Events/GameSaveLoadEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace KKAPI.MainGame 4 | { 5 | /// 6 | /// Arguments used with main game save/load events. 7 | /// 8 | public sealed class GameSaveLoadEventArgs : EventArgs 9 | { 10 | /// 11 | /// Create a new instance 12 | /// 13 | public GameSaveLoadEventArgs(string path, string fileName) 14 | { 15 | Path = path; 16 | FileName = fileName; 17 | } 18 | 19 | /// 20 | /// Name of the safe file. 21 | /// 22 | public string FileName { get; } 23 | 24 | /// 25 | /// Full filename of the save file. 26 | /// 27 | public string FullFilename => System.IO.Path.Combine(Path, FileName); 28 | 29 | /// 30 | /// Path to which the save file will be written. 31 | /// 32 | public string Path { get; } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Shared.CharaStudio/Studio/Events/ObjectVisibilityToggledEventArgs.cs: -------------------------------------------------------------------------------- 1 | using Studio; 2 | using System; 3 | 4 | namespace KKAPI.Studio.SaveLoad 5 | { 6 | /// 7 | /// Arguments used in object deleted events 8 | /// 9 | /// 10 | public sealed class ObjectVisibilityToggledEventArgs : EventArgs 11 | { 12 | /// 13 | /// Object being toggled 14 | /// Visibility of the object 15 | public ObjectVisibilityToggledEventArgs(ObjectCtrlInfo toggledObject, bool visible) 16 | { 17 | ToggledObject = toggledObject; 18 | Visible = visible; 19 | } 20 | 21 | /// 22 | /// Object being toggled 23 | /// 24 | public ObjectCtrlInfo ToggledObject { get; } 25 | 26 | /// 27 | /// Visibility of the object 28 | /// 29 | public bool Visible { get; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/Events/AccessorySlotEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace KKAPI.Maker 4 | { 5 | /// 6 | /// Event args for events that are related to accessory slot indexes. 7 | /// 8 | public class AccessorySlotEventArgs : EventArgs 9 | { 10 | /// 11 | public AccessorySlotEventArgs(int slotIndex) 12 | { 13 | SlotIndex = slotIndex; 14 | } 15 | 16 | /// 17 | /// Currently opened accessory slot index. 0-indexed. 18 | /// 19 | public int SlotIndex { get; } 20 | 21 | ///// 22 | ///// Get accessory UI entry in maker. 23 | ///// 24 | //public CvsAccessory CvsAccessory => AccessoriesApi.GetCvsAccessory(SlotIndex); 25 | // 26 | ///// 27 | ///// Get accessory component. 28 | ///// 29 | //public ChaAccessoryComponent AccessoryComponent => MakerAPI.GetCharacterControl().GetAccessory(SlotIndex); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/PHAPI/GameMode.cs: -------------------------------------------------------------------------------- 1 | namespace KKAPI 2 | { 3 | /// 4 | /// Current gameplay mode the game is in 5 | /// 6 | public enum GameMode 7 | { 8 | /// 9 | /// Anywhere else, including main menu 10 | /// 11 | Unknown, 12 | 13 | /// 14 | /// Inside character maker (can be started from main menu or from class roster) 15 | /// 16 | Maker, 17 | 18 | /// 19 | /// Anywhere inside CharaStudio.exe 20 | /// 21 | Studio, 22 | 23 | /// 24 | /// Anywhere inside the main game. 25 | /// Includes everything after starting a new game from title screen and after loading a saved game. 26 | /// This means this includes story scenes, night menu, roaming around and h scenes inside story mode. 27 | /// This does not hoverwer include the character maker launched from within the class menu. 28 | /// 29 | MainGame 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Shared.CharaStudio/Studio/SaveLoad/TestSceneFunctionController.cs: -------------------------------------------------------------------------------- 1 | using KKAPI.Utilities; 2 | using Studio; 3 | 4 | namespace KKAPI.Studio.SaveLoad 5 | { 6 | internal class TestSceneFunctionController : SceneCustomFunctionController 7 | { 8 | protected internal override void OnSceneLoad(SceneOperationKind operation, ReadOnlyDictionary loadedItems) 9 | { 10 | KoikatuAPI.Logger.Log(BepInEx.Logging.LogLevel.Warning | BepInEx.Logging.LogLevel.Message, $"OnSceneLoad {operation} - {loadedItems.Count}"); 11 | } 12 | 13 | protected internal override void OnSceneSave() 14 | { 15 | KoikatuAPI.Logger.Log(BepInEx.Logging.LogLevel.Warning | BepInEx.Logging.LogLevel.Message, "OnSceneSave"); 16 | } 17 | 18 | protected internal override void OnObjectsCopied(ReadOnlyDictionary copiedItems) 19 | { 20 | KoikatuAPI.Logger.Log(BepInEx.Logging.LogLevel.Warning | BepInEx.Logging.LogLevel.Message, "OnObjectsCopied"); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Shared.Core/GameMode.cs: -------------------------------------------------------------------------------- 1 | namespace KKAPI 2 | { 3 | /// 4 | /// Current gameplay mode the game is in 5 | /// 6 | public enum GameMode 7 | { 8 | /// 9 | /// Anywhere else, including main menu 10 | /// 11 | Unknown, 12 | 13 | /// 14 | /// Inside character maker (can be started from main menu or from class roster) 15 | /// 16 | Maker, 17 | 18 | /// 19 | /// Anywhere inside CharaStudio.exe 20 | /// 21 | Studio, 22 | 23 | /// 24 | /// Anywhere inside the main game. 25 | /// Includes everything after starting a new game from title screen and after loading a saved game. 26 | /// This means this includes story scenes, night menu, roaming around and h scenes inside story mode. 27 | /// This does not hoverwer include the character maker launched from within the class menu. 28 | /// 29 | MainGame 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Shared.Core/Shared.Core.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bd697c6c-a7d7-4307-a227-ccafc95c8744 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Shared.AIalike/Shared.AIalike.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bed55866-7531-4cc4-ba58-f406d901d3e8 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Shared.KKalike/Shared.KKalike.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16441a78-1945-4d7c-b3f4-333bab848211 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Shared.AIalike/Maker/Events/AccessorySlotEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using AIChara; 3 | using CharaCustom; 4 | #pragma warning disable 612 5 | 6 | namespace KKAPI.Maker 7 | { 8 | /// 9 | /// Event args for events that are related to accessory slot indexes. 10 | /// 11 | public class AccessorySlotEventArgs : EventArgs 12 | { 13 | /// 14 | public AccessorySlotEventArgs(int slotIndex) 15 | { 16 | SlotIndex = slotIndex; 17 | } 18 | 19 | /// 20 | /// Currently opened accessory slot index. 0-indexed. 21 | /// 22 | public int SlotIndex { get; } 23 | 24 | /// 25 | /// Get accessory UI entry in maker. 26 | /// 27 | public CustomAcsCorrectSet CvsAccessory => AccessoriesApi.GetCvsAccessory(); 28 | 29 | /// 30 | /// Get accessory component. 31 | /// 32 | public CmpAccessory AccessoryComponent => MakerAPI.GetCharacterControl().GetAccessory(SlotIndex); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/UI/MakerSeparator.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using UnityEngine; 3 | 4 | namespace KKAPI.Maker.UI 5 | { 6 | /// 7 | /// Custom control that draws a simple horizontal separator 8 | /// 9 | public class MakerSeparator : BaseGuiEntry 10 | { 11 | /// 12 | protected override GameObject OnCreateControl(Transform subCategoryList) 13 | { 14 | return MakerAPI.GetMakerBase().CreateSpace(subCategoryList.gameObject).gameObject; 15 | } 16 | 17 | /// 18 | protected internal override void Initialize() 19 | { 20 | } 21 | 22 | /// 23 | /// Create a new custom control. Create and register it in . 24 | /// 25 | /// Category the control will be created under 26 | /// Plugin that owns the control 27 | public MakerSeparator(MakerCategory category, BaseUnityPlugin owner) : base(category, owner) { } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Shared.CharaStudio/Shared.CharaStudio.shproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | a4b901df-f460-4510-8e04-8b3666990222 5 | 14.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Shared.KKalike/Maker/Events/AccessorySlotEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ChaCustom; 3 | #pragma warning disable 612 4 | 5 | namespace KKAPI.Maker 6 | { 7 | /// 8 | /// Event args for events that are related to accessory slot indexes. 9 | /// 10 | public class AccessorySlotEventArgs : EventArgs 11 | { 12 | /// 13 | public AccessorySlotEventArgs(int slotIndex) 14 | { 15 | SlotIndex = slotIndex; 16 | } 17 | 18 | /// 19 | /// Currently opened accessory slot index. 0-indexed. 20 | /// 21 | public int SlotIndex { get; } 22 | 23 | /// 24 | /// Get accessory UI entry in maker. 25 | /// 26 | [Obsolete] 27 | public CvsAccessory CvsAccessory => AccessoriesApi.GetCvsAccessory(SlotIndex); 28 | 29 | /// 30 | /// Get accessory component. 31 | /// 32 | [Obsolete] 33 | public ChaAccessoryComponent AccessoryComponent => MakerAPI.GetCharacterControl().GetAccessory(SlotIndex); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Shared.CharaStudio/Studio/Events/SceneLoadEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using KKAPI.Utilities; 3 | using Studio; 4 | 5 | namespace KKAPI.Studio.SaveLoad 6 | { 7 | /// 8 | /// Arguments used in scene loaded/imported events 9 | /// 10 | /// 11 | public sealed class SceneLoadEventArgs : EventArgs 12 | { 13 | /// 14 | /// Operation that caused the event 15 | /// Objects loaded by the event 16 | public SceneLoadEventArgs(SceneOperationKind operation, ReadOnlyDictionary loadedObjects) 17 | { 18 | Operation = operation; 19 | LoadedObjects = loadedObjects; 20 | } 21 | 22 | /// 23 | /// Operation that caused the event 24 | /// 25 | public SceneOperationKind Operation { get; } 26 | 27 | /// 28 | /// Objects loaded by the event and their original IDs (from the time the scene was saved) 29 | /// 30 | public ReadOnlyDictionary LoadedObjects { get; } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Shared.Core/Utilities/WindowsStringComparer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | 5 | namespace KKAPI.Utilities 6 | { 7 | /// 8 | /// String comparer that is equivalent to the one used by Windows Explorer to sort files (e.g. 2 will go before 10, unlike normal compare). 9 | /// 10 | /// 11 | public class WindowsStringComparer : IComparer 12 | { 13 | [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] 14 | private static extern int StrCmpLogicalW(String x, String y); 15 | 16 | /// 17 | /// Compare two strings with rules used by Windows Explorer to logically sort files. 18 | /// 19 | public int Compare(string x, string y) 20 | { 21 | return StrCmpLogicalW(x, y); 22 | } 23 | 24 | /// 25 | /// Compare two strings with rules used by Windows Explorer to logically sort files. 26 | /// 27 | public static int LogicalCompare(string x, string y) 28 | { 29 | return StrCmpLogicalW(x, y); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | $(IntermediateOutputPath)GeneratedConstantsFile.cs 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/KKAPI/Maker/AccessoryCopyEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace KKAPI.Maker 5 | { 6 | /// 7 | /// Event args for accessory copy events. 8 | /// 9 | public class AccessoryCopyEventArgs : EventArgs 10 | { 11 | /// 12 | public AccessoryCopyEventArgs(IEnumerable copiedSlotIndexes, 13 | ChaFileDefine.CoordinateType copySource, ChaFileDefine.CoordinateType copyDestination) 14 | { 15 | CopiedSlotIndexes = copiedSlotIndexes ?? throw new ArgumentNullException(nameof(copiedSlotIndexes)); 16 | CopySource = copySource; 17 | CopyDestination = copyDestination; 18 | } 19 | 20 | /// 21 | /// Indexes of accessories that were selected to be copied. 22 | /// 23 | public IEnumerable CopiedSlotIndexes { get; } 24 | 25 | /// 26 | /// Coordinate the accessories are copied from. 27 | /// 28 | public ChaFileDefine.CoordinateType CopySource { get; } 29 | 30 | /// 31 | /// Coordinate the accessories are copied into. 32 | /// 33 | public ChaFileDefine.CoordinateType CopyDestination { get; } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/KKSAPI/Maker/AccessoryCopyEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace KKAPI.Maker 5 | { 6 | /// 7 | /// Event args for accessory copy events. 8 | /// 9 | public class AccessoryCopyEventArgs : EventArgs 10 | { 11 | /// 12 | public AccessoryCopyEventArgs(IEnumerable copiedSlotIndexes, 13 | ChaFileDefine.CoordinateType copySource, ChaFileDefine.CoordinateType copyDestination) 14 | { 15 | CopiedSlotIndexes = copiedSlotIndexes ?? throw new ArgumentNullException(nameof(copiedSlotIndexes)); 16 | CopySource = copySource; 17 | CopyDestination = copyDestination; 18 | } 19 | 20 | /// 21 | /// Indexes of accessories that were selected to be copied. 22 | /// 23 | public IEnumerable CopiedSlotIndexes { get; } 24 | 25 | /// 26 | /// Coordinate the accessories are copied from. 27 | /// 28 | public ChaFileDefine.CoordinateType CopySource { get; } 29 | 30 | /// 31 | /// Coordinate the accessories are copied into. 32 | /// 33 | public ChaFileDefine.CoordinateType CopyDestination { get; } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/PHAPI/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/Shared.Core/Maker/Events/CharacterChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | #if AI || HS2 3 | using AIChara; 4 | #endif 5 | 6 | #pragma warning disable 1591 7 | 8 | namespace KKAPI.Maker 9 | { 10 | public sealed class ChaFileLoadedEventArgs : EventArgs 11 | { 12 | public ChaFileLoadedEventArgs(string filename, byte sex, bool face, bool body, bool hair, bool parameter, bool coordinate, ChaFileControl characterInstance, ChaFile loadedChaFile) 13 | { 14 | Filename = filename; 15 | Sex = sex; 16 | Face = face; 17 | Body = body; 18 | Hair = hair; 19 | Parameter = parameter; 20 | Coordinate = coordinate; 21 | CharacterInstance = characterInstance; 22 | LoadedChaFile = loadedChaFile; 23 | } 24 | 25 | public string Filename { get; } 26 | public byte Sex { get; } 27 | public bool Face { get; } 28 | public bool Body { get; } 29 | public bool Hair { get; } 30 | public bool Parameter { get; } 31 | public bool Coordinate { get; } 32 | public ChaFileControl CharacterInstance { get; } 33 | 34 | /// 35 | /// Use this to get extended data on the character 36 | /// 37 | public ChaFile LoadedChaFile { get; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Shared.CharaStudio/Studio/StudioAPI.Hooks.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using KKAPI.Utilities; 3 | using Studio; 4 | using System.Collections; 5 | 6 | namespace KKAPI.Studio 7 | { 8 | public static partial class StudioAPI 9 | { 10 | private static class Hooks 11 | { 12 | public static void SetupHooks() 13 | { 14 | Harmony.CreateAndPatchAll(typeof(Hooks)); 15 | } 16 | 17 | [HarmonyPostfix] 18 | [HarmonyPatch(typeof(MPCharCtrl), nameof(MPCharCtrl.OnClickRoot), typeof(int))] 19 | public static void OnClickRoot(int _idx, OCIChar ___m_OCIChar) 20 | { 21 | IEnumerator DelayedUpdateTrigger() 22 | { 23 | // Need to wait for the selected character to change or we risk overwriting current character with new character's data 24 | yield return CoroutineUtils.WaitForEndOfFrame; 25 | 26 | if (_idx == 0) 27 | { 28 | foreach (var stateCategory in _customCurrentStateCategories) 29 | stateCategory.UpdateInfo(___m_OCIChar); 30 | } 31 | } 32 | 33 | KoikatuAPI.Instance.StartCoroutine(DelayedUpdateTrigger()); 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /doc/KKAPI.Maker.UI.Sidebar.md: -------------------------------------------------------------------------------- 1 | ## `ISidebarControl` 2 | 3 | Marks the control as being intended for use on Control Panel sidebar in chara maker 4 | ```csharp 5 | public interface KKAPI.Maker.UI.Sidebar.ISidebarControl 6 | 7 | ``` 8 | 9 | ## `SidebarSeparator` 10 | 11 | A separator to be used in the right "Control Panel" sidebar in character maker. The space is limited so use sparingly. 12 | ```csharp 13 | public class KKAPI.Maker.UI.Sidebar.SidebarSeparator 14 | : BaseGuiEntry, IDisposable, ISidebarControl 15 | 16 | ``` 17 | 18 | Methods 19 | 20 | | Type | Name | Summary | 21 | | --- | --- | --- | 22 | | `void` | Initialize() | | 23 | | `GameObject` | OnCreateControl(`Transform` subCategoryList) | | 24 | 25 | 26 | ## `SidebarToggle` 27 | 28 | A toggle to be used in the right "Control Panel" sidebar in character maker. The space is limited so use sparingly. 29 | ```csharp 30 | public class KKAPI.Maker.UI.Sidebar.SidebarToggle 31 | : BaseEditableGuiEntry, IDisposable, ISidebarControl 32 | 33 | ``` 34 | 35 | Properties 36 | 37 | | Type | Name | Summary | 38 | | --- | --- | --- | 39 | | `String` | Text | Text displayed next to the checkbox | 40 | 41 | 42 | Methods 43 | 44 | | Type | Name | Summary | 45 | | --- | --- | --- | 46 | | `void` | Initialize() | | 47 | | `GameObject` | OnCreateControl(`Transform` subCategoryList) | | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/Events/CharacterChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Character; 3 | 4 | #if AI || HS2 5 | using AIChara; 6 | #endif 7 | 8 | #pragma warning disable 1591 9 | 10 | namespace KKAPI.Maker 11 | { 12 | public sealed class ChaFileLoadedEventArgs : EventArgs 13 | { 14 | public ChaFileLoadedEventArgs(string filename, byte sex, bool face, bool body, bool hair, bool parameter, bool coordinate, Human characterInstance, CustomParameter loadedChaFile) 15 | { 16 | Filename = filename; 17 | Sex = sex; 18 | Face = face; 19 | Body = body; 20 | Hair = hair; 21 | Parameter = parameter; 22 | Coordinate = coordinate; 23 | CharacterInstance = characterInstance; 24 | LoadedChaFile = loadedChaFile; 25 | } 26 | 27 | public string Filename { get; } 28 | public byte Sex { get; } 29 | public bool Face { get; } 30 | public bool Body { get; } 31 | public bool Hair { get; } 32 | public bool Parameter { get; } 33 | public bool Coordinate { get; } 34 | public Human CharacterInstance { get; } 35 | 36 | /// 37 | /// Use this to get extended data on the character 38 | /// 39 | public CustomParameter LoadedChaFile { get; } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/PHAPI/Chara/TestCharaCustomFunctionController.cs: -------------------------------------------------------------------------------- 1 | using Character; 2 | 3 | namespace KKAPI.Chara 4 | { 5 | internal sealed class TestCharaCustomFunctionController : CharaCustomFunctionController 6 | { 7 | protected override void OnCardBeingSaved(GameMode currentGameMode) 8 | { 9 | KoikatuAPI.Logger.LogWarning($"CharaController - OnCardBeingSaved - name:{ChaControl.GetCharacterName()}; currentGameMode:{currentGameMode}"); 10 | } 11 | 12 | protected override void OnReload(GameMode currentGameMode, bool maintainState) 13 | { 14 | KoikatuAPI.Logger.LogWarning($"CharaController - OnReload - name:{ChaControl.GetCharacterName()}; currentGameMode:{currentGameMode}; maintainState:{maintainState}"); 15 | } 16 | 17 | protected override void OnCoordinateBeingLoaded(CustomParameter coordinate, bool maintainState) 18 | { 19 | KoikatuAPI.Logger.LogWarning($"CharaController - OnCoordinateBeingLoaded - name:{ChaControl.GetCharacterName()}; sex:{coordinate?.Sex}; maintainState:{maintainState}"); 20 | } 21 | 22 | protected override void OnCoordinateBeingSaved(CustomParameter coordinate) 23 | { 24 | KoikatuAPI.Logger.LogWarning($"CharaController - OnCoordinateBeingSaved - name:{ChaControl.GetCharacterName()}; sex:{coordinate?.Sex}"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Shared.CharaStudio/Studio/UI/SceneEffectsCategoryLabel.cs: -------------------------------------------------------------------------------- 1 | #if KK || KKS || AI || HS2 2 | #define TMP 3 | #endif 4 | 5 | using UnityEngine.UI; 6 | #if TMP 7 | using Text = TMPro.TextMeshProUGUI; 8 | #endif 9 | 10 | namespace KKAPI.Studio.UI 11 | { 12 | /// 13 | /// A container for the value of a ColorPicker, associated label and button, and the setter method that triggers on value change. 14 | /// 15 | public class SceneEffectsLabelSet 16 | { 17 | /// 18 | /// Label UI element. 19 | /// 20 | public Text Label { get; set; } 21 | /// 22 | /// Get or set the text of the label. 23 | /// 24 | public string Text 25 | { 26 | get => Label.text; 27 | set => Label.text = value; 28 | } 29 | 30 | /// 31 | /// Create a new Label. Typically, you want to use SceneEffectsCategory.AddLabel instead of creating these manually. 32 | /// 33 | /// Label UI element 34 | /// Label text 35 | public SceneEffectsLabelSet(Text label, string text) 36 | { 37 | Label = label; 38 | Text = text; 39 | 40 | Label.gameObject.name = $"Label {Text}"; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/AIAPI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | using KKAPI; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("AIAPI")] 9 | [assembly: AssemblyDescription("Modding API for AI-Shoujo!")] 10 | [assembly: AssemblyCompany("ManlyMarco")] 11 | [assembly: AssemblyProduct("AIAPI")] 12 | [assembly: AssemblyCopyright("Copyright © 2018")] 13 | 14 | // Setting ComVisible to false makes the types in this assembly not visible 15 | // to COM components. If you need to access a type in this assembly from 16 | // COM, set the ComVisible attribute to true on that type. 17 | [assembly: ComVisible(false)] 18 | 19 | // The following GUID is for the ID of the typelib if this project is exposed to COM 20 | [assembly: Guid("601f5cca-63fa-4e77-a7c5-16591977578f")] 21 | 22 | // Version information for an assembly consists of the following four values: 23 | // 24 | // Major Version 25 | // Minor Version 26 | // Build Number 27 | // Revision 28 | // 29 | // You can specify all the values or you can default the Build and Revision Numbers 30 | // by using the '*' as shown below: 31 | // [assembly: AssemblyVersion("1.0.*")] 32 | [assembly: AssemblyFileVersion(KoikatuAPI.VersionConst)] 33 | [assembly: AssemblyVersion(KoikatuAPI.VersionConst)] 34 | -------------------------------------------------------------------------------- /src/KKAPI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | using KKAPI; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("KKAPI")] 9 | [assembly: AssemblyDescription("Modding API for Koikatsu!")] 10 | [assembly: AssemblyCompany("ManlyMarco")] 11 | [assembly: AssemblyProduct("KKAPI")] 12 | [assembly: AssemblyCopyright("Copyright © 2018")] 13 | 14 | // Setting ComVisible to false makes the types in this assembly not visible 15 | // to COM components. If you need to access a type in this assembly from 16 | // COM, set the ComVisible attribute to true on that type. 17 | [assembly: ComVisible(false)] 18 | 19 | // The following GUID is for the ID of the typelib if this project is exposed to COM 20 | [assembly: Guid("74c2db86-55bb-47b4-9805-51b5b992ef35")] 21 | 22 | // Version information for an assembly consists of the following four values: 23 | // 24 | // Major Version 25 | // Minor Version 26 | // Build Number 27 | // Revision 28 | // 29 | // You can specify all the values or you can default the Build and Revision Numbers 30 | // by using the '*' as shown below: 31 | // [assembly: AssemblyVersion("1.0.*")] 32 | [assembly: AssemblyFileVersion(KoikatuAPI.VersionConst)] 33 | [assembly: AssemblyVersion(KoikatuAPI.VersionConst)] 34 | -------------------------------------------------------------------------------- /src/PHAPI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | using KKAPI; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("PHAPI")] 9 | [assembly: AssemblyDescription("Modding API for PlayHome")] 10 | [assembly: AssemblyCompany("ManlyMarco")] 11 | [assembly: AssemblyProduct("PHAPI")] 12 | [assembly: AssemblyCopyright("Copyright © 2018")] 13 | 14 | // Setting ComVisible to false makes the types in this assembly not visible 15 | // to COM components. If you need to access a type in this assembly from 16 | // COM, set the ComVisible attribute to true on that type. 17 | [assembly: ComVisible(false)] 18 | 19 | // The following GUID is for the ID of the typelib if this project is exposed to COM 20 | [assembly: Guid("74c2db86-55bb-47b4-9805-51b5b992ef35")] 21 | 22 | // Version information for an assembly consists of the following four values: 23 | // 24 | // Major Version 25 | // Minor Version 26 | // Build Number 27 | // Revision 28 | // 29 | // You can specify all the values or you can default the Build and Revision Numbers 30 | // by using the '*' as shown below: 31 | // [assembly: AssemblyVersion("1.0.*")] 32 | [assembly: AssemblyFileVersion(KoikatuAPI.VersionConst)] 33 | [assembly: AssemblyVersion(KoikatuAPI.VersionConst)] 34 | -------------------------------------------------------------------------------- /src/KKSAPI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | using KKAPI; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("KKSAPI")] 9 | [assembly: AssemblyDescription("Modding API for Koikatsu Sunshine")] 10 | [assembly: AssemblyCompany("ManlyMarco")] 11 | [assembly: AssemblyProduct("KKSAPI")] 12 | [assembly: AssemblyCopyright("Copyright © 2021")] 13 | 14 | // Setting ComVisible to false makes the types in this assembly not visible 15 | // to COM components. If you need to access a type in this assembly from 16 | // COM, set the ComVisible attribute to true on that type. 17 | [assembly: ComVisible(false)] 18 | 19 | // The following GUID is for the ID of the typelib if this project is exposed to COM 20 | [assembly: Guid("74c2db86-55bb-47b4-9805-51b5b992ef35")] 21 | 22 | // Version information for an assembly consists of the following four values: 23 | // 24 | // Major Version 25 | // Minor Version 26 | // Build Number 27 | // Revision 28 | // 29 | // You can specify all the values or you can default the Build and Revision Numbers 30 | // by using the '*' as shown below: 31 | // [assembly: AssemblyVersion("1.0.*")] 32 | [assembly: AssemblyFileVersion(KoikatuAPI.VersionConst)] 33 | [assembly: AssemblyVersion(KoikatuAPI.VersionConst)] -------------------------------------------------------------------------------- /src/ECAPI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | using KKAPI; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ECAPI")] 9 | [assembly: AssemblyDescription("Modding API for EmotionCreators!")] 10 | [assembly: AssemblyCompany("ManlyMarco")] 11 | [assembly: AssemblyProduct("ECAPI")] 12 | [assembly: AssemblyCopyright("Copyright © 2018")] 13 | 14 | // Setting ComVisible to false makes the types in this assembly not visible 15 | // to COM components. If you need to access a type in this assembly from 16 | // COM, set the ComVisible attribute to true on that type. 17 | [assembly: ComVisible(false)] 18 | 19 | // The following GUID is for the ID of the typelib if this project is exposed to COM 20 | [assembly: Guid("74c2db86-55bb-47b4-9805-51b5b992ef35")] 21 | 22 | // Version information for an assembly consists of the following four values: 23 | // 24 | // Major Version 25 | // Minor Version 26 | // Build Number 27 | // Revision 28 | // 29 | // You can specify all the values or you can default the Build and Revision Numbers 30 | // by using the '*' as shown below: 31 | // [assembly: AssemblyVersion("1.0.*")] 32 | [assembly: AssemblyFileVersion(KoikatuAPI.VersionConst)] 33 | [assembly: AssemblyVersion(KoikatuAPI.VersionConst)] 34 | -------------------------------------------------------------------------------- /src/HS2API/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | using KKAPI; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("HS2API")] 9 | [assembly: AssemblyDescription("Modding API for HoneySelect2!")] 10 | [assembly: AssemblyCompany("ManlyMarco")] 11 | [assembly: AssemblyProduct("HS2API")] 12 | [assembly: AssemblyCopyright("Copyright © 2020")] 13 | 14 | // Setting ComVisible to false makes the types in this assembly not visible 15 | // to COM components. If you need to access a type in this assembly from 16 | // COM, set the ComVisible attribute to true on that type. 17 | [assembly: ComVisible(false)] 18 | 19 | // The following GUID is for the ID of the typelib if this project is exposed to COM 20 | [assembly: Guid("601f5cca-63fa-4e77-a7c5-16591977578f")] 21 | 22 | // Version information for an assembly consists of the following four values: 23 | // 24 | // Major Version 25 | // Minor Version 26 | // Build Number 27 | // Revision 28 | // 29 | // You can specify all the values or you can default the Build and Revision Numbers 30 | // by using the '*' as shown below: 31 | // [assembly: AssemblyVersion("1.0.*")] 32 | [assembly: AssemblyFileVersion(KoikatuAPI.VersionConst)] 33 | [assembly: AssemblyVersion(KoikatuAPI.VersionConst)] 34 | -------------------------------------------------------------------------------- /src/Shared.CharaStudio/Studio/UI/Toolbars/ToolbarPosition.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace KKAPI.Studio.UI.Toolbars 4 | { 5 | /// 6 | /// Represents the position of a toolbar in a grid layout, defined by its row and column indices. 7 | /// 8 | public readonly struct ToolbarPosition : IEquatable 9 | { 10 | /// 11 | /// Vertical position (row index). 12 | /// 13 | public readonly int Row; 14 | 15 | /// 16 | /// Horizontal position (column index). 17 | /// 18 | public readonly int Column; 19 | 20 | /// 21 | /// Initializes a new instance of the class with the specified row and column. 22 | /// 23 | public ToolbarPosition(int row, int column) 24 | { 25 | Row = row; 26 | Column = column; 27 | } 28 | 29 | /// 30 | public bool Equals(ToolbarPosition other) => Row == other.Row && Column == other.Column; 31 | 32 | /// 33 | public override bool Equals(object obj) => obj is ToolbarPosition other && Equals(other); 34 | 35 | /// 36 | public override int GetHashCode() 37 | { 38 | unchecked 39 | { 40 | return (Row * 397) ^ Column; 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /.github/workflows/nuget.yml: -------------------------------------------------------------------------------- 1 | name: Push to nuget feed on release 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | workflow_dispatch: 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: windows-latest 13 | 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v1 17 | 18 | - name: Setup Nuget 19 | uses: nuget/setup-nuget@v1 20 | 21 | - name: Setup MSBuild # Needed by Build NativeHelper 22 | uses: microsoft/setup-msbuild@v1 23 | 24 | - name: Build NativeHelper # Need to build this separately first because nuget pack doesn't seem to handle vcxproj 25 | working-directory: ./src/Helper 26 | run: | 27 | msbuild Helper.vcxproj /p:Configuration=Release /p:Platform=x64 28 | 29 | - name: Nuget pack 30 | working-directory: ./src 31 | run: | 32 | nuget restore 33 | gci -Recurse -Filter *.nuspec | foreach { nuget pack "$($_.DirectoryName)\$($_.BaseName).csproj" -build -properties Configuration=Release } 34 | 35 | - name: Nuget push 36 | working-directory: ./src 37 | env: 38 | NUGET_URL: https://pkgs.dev.azure.com/IllusionMods/Nuget/_packaging/IllusionMods/nuget/v3/index.json 39 | NUGET_TOKEN: ${{ secrets.NUGET_TOKEN }} 40 | run: | 41 | nuget sources update -name "IllusionMods" -username "token" -password ${env:NUGET_TOKEN} 42 | nuget push *.nupkg -apikey key -noninteractive -skipduplicate -src ${env:NUGET_URL} 43 | -------------------------------------------------------------------------------- /src/KKAPI/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/ECAPI/KoikatuAPI.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BepInEx; 3 | using KKAPI.Chara; 4 | using KKAPI.Maker; 5 | using Manager; 6 | using UnityEngine; 7 | 8 | namespace KKAPI 9 | { 10 | [BepInPlugin(GUID, "Modding API", VersionConst)] 11 | public partial class KoikatuAPI : BaseUnityPlugin 12 | { 13 | /// 14 | /// The game process name for use with attributes. 15 | /// 16 | public const string GameProcessName = "EmotionCreators"; 17 | 18 | private void Awake() 19 | { 20 | BaseAwake(); 21 | 22 | var insideStudio = Application.productName == "CharaStudio"; 23 | MakerAPI.Init(insideStudio); 24 | CharacterApi.Init(); 25 | } 26 | 27 | private void Start() 28 | { 29 | // Needs to be called after moreaccessories has a chance to load 30 | AccessoriesApi.Init(); 31 | } 32 | 33 | /// 34 | /// Get current game mode. 35 | /// 36 | public static GameMode GetCurrentGameMode() 37 | { 38 | if (MakerAPI.InsideMaker) return GameMode.Maker; 39 | return GameMode.Unknown; 40 | } 41 | 42 | /// 43 | /// Get current version of the game. 44 | /// 45 | public static Version GetGameVersion() 46 | { 47 | return new Version(GameSystem.GameSystemVersion); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Shared.AIalike/Maker/AccessoriesApi.Hooks.AI.cs: -------------------------------------------------------------------------------- 1 | using CharaCustom; 2 | using HarmonyLib; 3 | 4 | namespace KKAPI.Maker 5 | { 6 | public static partial class AccessoriesApi 7 | { 8 | private static class Hooks 9 | { 10 | [HarmonyPostfix] 11 | [HarmonyPatch(typeof(CvsA_Slot), nameof(CvsA_Slot.ChangeMenuFunc))] 12 | public static void ChangeMenuFuncPostfix(CvsA_Slot __instance) 13 | { 14 | OnSelectedMakerSlotChanged(__instance, __instance.SNo); 15 | } 16 | 17 | [HarmonyPostfix] 18 | [HarmonyPatch(typeof(CvsA_Slot), nameof(CvsA_Slot.ChangeAcsId), typeof(int))] 19 | public static void ChangeAcsIdPostfix(CvsA_Slot __instance, int id) 20 | { 21 | OnAccessoryKindChanged(__instance, __instance.SNo); 22 | } 23 | 24 | [HarmonyPostfix] 25 | [HarmonyPatch(typeof(CvsA_Slot), nameof(CvsA_Slot.ChangeAcsType), typeof(int))] 26 | public static void ChangeAcsTypePostfix(CvsA_Slot __instance) 27 | { 28 | OnAccessoryKindChanged(__instance, __instance.SNo); 29 | } 30 | 31 | [HarmonyPostfix] 32 | [HarmonyPatch(typeof(CvsA_Copy), "CopyAccessory")] 33 | public static void CopyAccessory(CvsA_Copy __instance) 34 | { 35 | OnChangeAcs(__instance, __instance.selSrc, __instance.selDst); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/AIAPI/MainGame/TestGameFunctionController.cs: -------------------------------------------------------------------------------- 1 | namespace KKAPI.MainGame 2 | { 3 | internal sealed class TestGameFunctionController : GameCustomFunctionController 4 | { 5 | protected internal override void OnEndH(HScene proc, bool freeH) 6 | { 7 | KoikatuAPI.Logger.LogDebug("GameController - OnEndH - FreeH:" + freeH); 8 | } 9 | 10 | protected internal override void OnGameLoad(GameSaveLoadEventArgs args) 11 | { 12 | KoikatuAPI.Logger.LogDebug("GameController - OnGameLoad - Path:" + args.FullFilename); 13 | } 14 | 15 | protected internal override void OnGameSave(GameSaveLoadEventArgs args) 16 | { 17 | KoikatuAPI.Logger.LogDebug("GameController - OnGameSave - Path:" + args.FullFilename); 18 | } 19 | 20 | protected internal override void OnStartH(HScene proc, bool freeH) 21 | { 22 | KoikatuAPI.Logger.LogDebug("GameController - OnStartH - FreeH:" + freeH); 23 | } 24 | 25 | protected internal override void OnDayChange(int day) 26 | { 27 | KoikatuAPI.Logger.LogDebug("GameController - OnDayChange - day:" + day); 28 | } 29 | 30 | protected internal override void OnPeriodChange(AIProject.TimeZone period) 31 | { 32 | KoikatuAPI.Logger.LogDebug("GameController - OnPeriodChange - period:" + period); 33 | } 34 | 35 | protected internal override void OnNewGame() 36 | { 37 | KoikatuAPI.Logger.LogDebug("GameController - OnNewGame"); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/PHAPI/Chara/Events/CoordinateEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Character; 4 | using ExtensibleSaveFormat; 5 | 6 | #pragma warning disable 1591 7 | 8 | namespace KKAPI.Chara 9 | { 10 | /// 11 | /// Fired in events that deal with coordinate cards 12 | /// 13 | public sealed class CoordinateEventArgs : EventArgs 14 | { 15 | public CoordinateEventArgs(Human character, CustomParameter loadedCoordinate) 16 | { 17 | Character = character; 18 | LoadedCoordinate = loadedCoordinate; 19 | } 20 | 21 | /// 22 | /// Character the coordinate was loaded to 23 | /// 24 | public Human Character { get; } 25 | 26 | /// 27 | /// The loaded coordinate 28 | /// 29 | public CustomParameter LoadedCoordinate { get; } 30 | 31 | /// 32 | /// Get all exrtended data assigned to this coordinate card 33 | /// 34 | public Dictionary GetCoordinateExtData() => ExtendedSave.GetAllExtendedData(LoadedCoordinate); 35 | 36 | /// 37 | /// Set extended data for this coordinate card 38 | /// 39 | /// Key to save the data under (usually plugin GUID) 40 | /// Data to set 41 | public void SetCoordinateExtData(string dataId, PluginData data) => ExtendedSave.SetExtendedDataById(LoadedCoordinate, dataId, data); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Shared.Core/Chara/Events/CoordinateEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using ExtensibleSaveFormat; 4 | #if AI || HS2 5 | using AIChara; 6 | #endif 7 | 8 | #pragma warning disable 1591 9 | 10 | namespace KKAPI.Chara 11 | { 12 | /// 13 | /// Fired in events that deal with coordinate cards 14 | /// 15 | public sealed class CoordinateEventArgs : EventArgs 16 | { 17 | public CoordinateEventArgs(ChaControl character, ChaFileCoordinate loadedCoordinate) 18 | { 19 | Character = character; 20 | LoadedCoordinate = loadedCoordinate; 21 | } 22 | 23 | /// 24 | /// Character the coordinate was loaded to 25 | /// 26 | public ChaControl Character { get; } 27 | 28 | /// 29 | /// The loaded coordinate 30 | /// 31 | public ChaFileCoordinate LoadedCoordinate { get; } 32 | 33 | /// 34 | /// Get all exrtended data assigned to this coordinate card 35 | /// 36 | public Dictionary GetCoordinateExtData() => ExtendedSave.GetAllExtendedData(LoadedCoordinate); 37 | 38 | /// 39 | /// Set extended data for this coordinate card 40 | /// 41 | /// Key to save the data under (usually plugin GUID) 42 | /// Data to set 43 | public void SetCoordinateExtData(string dataId, PluginData data) => ExtendedSave.SetExtendedDataById(LoadedCoordinate, dataId, data); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Shared.CharaStudio/Studio/UI/BaseCurrentStateEditableGuiEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Studio; 3 | using UniRx; 4 | 5 | namespace KKAPI.Studio.UI 6 | { 7 | /// 8 | /// Base class of controls that hold a value. 9 | /// Subscribe to to update your control's state whenever the value changes. 10 | /// 11 | /// Type of the held value 12 | public abstract class BaseCurrentStateEditableGuiEntry : CurrentStateCategorySubItemBase 13 | { 14 | private readonly Func _updateValue; 15 | 16 | /// 17 | /// Create a new control that holds a value 18 | /// 19 | /// Name of the control 20 | /// Function called every time current character changes and the value needs to be updated 21 | /// Initial value used before first updateValue call 22 | protected BaseCurrentStateEditableGuiEntry(string name, Func updateValue, T initialValue = default(T)) : base(name) 23 | { 24 | _updateValue = updateValue ?? throw new ArgumentNullException(nameof(updateValue)); 25 | Value = new BehaviorSubject(initialValue); 26 | } 27 | 28 | /// 29 | /// Current value of this control 30 | /// 31 | public BehaviorSubject Value { get; } 32 | 33 | /// 34 | protected internal override void OnUpdateInfo(OCIChar ociChar) 35 | { 36 | Value.OnNext(_updateValue.Invoke(ociChar)); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /doc/KoiSkinOverlayX.md: -------------------------------------------------------------------------------- 1 | ## `TextureStorage` 2 | 3 | A class for storing textures that should be saved and loaded from extended data's `ExtensibleSaveFormat.PluginData` (e.g. to character cards and scenes). Duplicate textures are automatically handled so that only one copy of the texture is held in memory and saved. 4 | ```csharp 5 | public class KoiSkinOverlayX.TextureStorage 6 | : IDisposable 7 | 8 | ``` 9 | 10 | Methods 11 | 12 | | Type | Name | Summary | 13 | | --- | --- | --- | 14 | | `void` | Clear(`Boolean` destroy = True) | Clear the texture list and optionally destroy all textures. | 15 | | `Int32[]` | GetAllTextureIDs() | Get IDs of all textures stored in this object. | 16 | | `Texture2D` | GetSharedTexture(`Int32` id) | Get a texture based on texture ID. The same texture is returned every time, so it shouldn't be destroyed. | 17 | | `void` | Load(`PluginData` data) | Load textures from extended data that were stored with `KoiSkinOverlayX.TextureStorage.Save(ExtensibleSaveFormat.PluginData)`. | 18 | | `void` | PurgeUnused(`IEnumerable` usedIDs) | Remove unused textures based on a list of used IDs. Textures with IDs not in the list will be removed. | 19 | | `void` | Save(`PluginData` data) | Save textures stored in this object to extended data. Can be loaded later with `KoiSkinOverlayX.TextureStorage.Load(ExtensibleSaveFormat.PluginData)`. | 20 | | `Int32` | StoreTexture(`Byte[]` tex) | Store a texture and get an ID representing it. The ID can be used to get the texture with `KoiSkinOverlayX.TextureStorage.GetSharedTexture(System.Int32)`. If you try to store a texture that was already stored before, the ID of the previous texture is returned so there are no multiple identical textures stored. | 21 | | `void` | System.IDisposable.Dispose() | | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/Shared.AIalike/Maker/UI/MakerSeparator.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using UnityEngine; 3 | 4 | namespace KKAPI.Maker.UI 5 | { 6 | /// 7 | /// Custom control that draws a simple horizontal separator 8 | /// 9 | public class MakerSeparator : BaseGuiEntry 10 | { 11 | private static Transform _sourceSeparator; 12 | 13 | /// 14 | protected override GameObject OnCreateControl(Transform subCategoryList) 15 | { 16 | var s = Object.Instantiate(SourceSeparator, subCategoryList, false); 17 | s.name = "Separate"; 18 | return s.gameObject; 19 | } 20 | 21 | /// 22 | protected internal override void Initialize() 23 | { 24 | if (_sourceSeparator == null) 25 | MakeCopy(); 26 | } 27 | 28 | private static Transform SourceSeparator 29 | { 30 | get 31 | { 32 | if (_sourceSeparator == null) 33 | MakeCopy(); 34 | 35 | return _sourceSeparator; 36 | } 37 | } 38 | 39 | private static void MakeCopy() 40 | { 41 | _sourceSeparator = GameObject.Find("SettingWindow/WinFace/F_ShapeEar/separate").transform; 42 | } 43 | 44 | /// 45 | /// Create a new custom control. Create and register it in . 46 | /// 47 | /// Category the control will be created under 48 | /// Plugin that owns the control 49 | public MakerSeparator(MakerCategory category, BaseUnityPlugin owner) : base(category, owner) { } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/UI/Sidebar/SidebarToggle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BepInEx; 3 | using KKAPI.Utilities; 4 | using UniRx; 5 | using UnityEngine; 6 | using UnityEngine.UI; 7 | using Object = UnityEngine.Object; 8 | 9 | namespace KKAPI.Maker.UI.Sidebar 10 | { 11 | /// 12 | /// A toggle to be used in the right "Control Panel" sidebar in character maker. 13 | /// The space is limited so use sparingly. 14 | /// 15 | public class SidebarToggle : BaseEditableGuiEntry, ISidebarControl 16 | { 17 | /// 18 | public SidebarToggle(string text, bool initialValue, BaseUnityPlugin owner) : base(null, initialValue, owner) 19 | { 20 | Text = text; 21 | } 22 | 23 | /// 24 | protected internal override void Initialize() { } 25 | 26 | /// 27 | protected override GameObject OnCreateControl(Transform child) 28 | { 29 | child.name = "Toggle custom PHAPI"; 30 | 31 | Object.DestroyImmediate(child.GetComponent()); 32 | Object.DestroyImmediate(child.GetComponent()); 33 | 34 | var tgl = child.GetComponent(); 35 | tgl.SetText(Text, Text); 36 | foreach (var image in tgl.GetComponentsInChildren()) image.raycastTarget = true; 37 | tgl.action.ActuallyRemoveAllListeners(); 38 | 39 | ValueChanged.Subscribe(b => tgl.Value = b); 40 | tgl.action.AddListener(SetValue); 41 | 42 | return child.gameObject; 43 | } 44 | 45 | /// 46 | /// Text displayed next to the checkbox 47 | /// 48 | public string Text { get; } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/ECAPI/KKAPI.csproj.DotSettings: -------------------------------------------------------------------------------- 1 | 2 | False 3 | True 4 | True 5 | True 6 | True 7 | True 8 | False 9 | False 10 | True 11 | False 12 | False -------------------------------------------------------------------------------- /release.ps1: -------------------------------------------------------------------------------- 1 | # Env setup --------------- 2 | if ($PSScriptRoot -match '.+?\\bin\\?') { 3 | $dir = $PSScriptRoot + "\" 4 | } 5 | else { 6 | $dir = $PSScriptRoot + "\bin\" 7 | } 8 | 9 | $copy = $dir + "\copy\BepInEx\plugins" 10 | 11 | if ((Get-ChildItem -Path $dir -Filter *.dll).Length -gt 0) 12 | { 13 | 14 | $pluginDir = $dir 15 | } 16 | else 17 | { 18 | $pluginDir = $dir + "\BepInEx\plugins" 19 | } 20 | Write-Information -MessageData ("Using " + $pluginDir + " as plugin directory") 21 | 22 | New-Item -ItemType Directory -Force -Path ($dir + "\out\") 23 | 24 | # Create releases --------- 25 | function CreateZip ($pluginFile) 26 | { 27 | Remove-Item -Force -Path ($dir + "\copy") -Recurse -ErrorAction SilentlyContinue 28 | New-Item -ItemType Directory -Force -Path $copy 29 | 30 | # copy the dll and any accompanying files 31 | Copy-Item -Path ($pluginFile.DirectoryName + "\" + $pluginFile.BaseName + ".*") -Destination $copy -Recurse -Force -ErrorAction Ignore 32 | 33 | # 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) 34 | $ver = (Get-ChildItem -Path ($copy) -Filter "*.dll" -Recurse -Force)[0].VersionInfo.FileVersion.ToString() -replace "^([\d+\.]+?\d+)[\.0]*$", '${1}' 35 | 36 | Compress-Archive -Path ($copy + "\..\") -Force -CompressionLevel "Optimal" -DestinationPath ($dir + "\out\" + $pluginFile.BaseName.Replace("API", "_ModdingAPI") + "_" + "v" + $ver + ".zip") 37 | } 38 | 39 | foreach ($pluginFile in Get-ChildItem -Path $pluginDir -Filter *API.dll) 40 | { 41 | try 42 | { 43 | CreateZip ($pluginFile) 44 | } 45 | catch 46 | { 47 | # retry 48 | CreateZip ($pluginFile) 49 | } 50 | } 51 | 52 | 53 | Remove-Item -Force -Path ($dir + "\copy") -Recurse 54 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/Events/RegisterCustomControlsEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using KKAPI.Maker.UI; 3 | using KKAPI.Maker.UI.Sidebar; 4 | 5 | #pragma warning disable CS0618 // Type or member is obsolete 6 | 7 | namespace KKAPI.Maker 8 | { 9 | /// 10 | /// Event fired when character maker is starting and plugins are given an opportunity to register custom controls 11 | /// 12 | public class RegisterCustomControlsEvent : EventArgs 13 | { 14 | /// 15 | /// Add custom controls. If you want to use custom sub categories, register them by calling AddSubCategory. 16 | /// 17 | public T AddControl(T control) where T : BaseGuiEntry 18 | { 19 | return MakerAPI.AddControl(control); 20 | } 21 | 22 | /// 23 | /// Add a control to the right sidebar in chara maker (the "Control Panel" where you set eye blinking, mouth expressions etc.) 24 | /// 25 | public T AddSidebarControl(T control) where T : BaseGuiEntry, ISidebarControl 26 | { 27 | return MakerAPI.AddSidebarControl(control); 28 | } 29 | 30 | /// 31 | /// Add a toggle to the bottom of the "Load character" window that allows for partial loading of characters. 32 | /// 33 | public MakerLoadToggle AddLoadToggle(MakerLoadToggle toggle) 34 | { 35 | return MakerLoadToggle.AddLoadToggle(toggle); 36 | } 37 | 38 | /// 39 | /// Add a toggle to the bottom of the "Load coordinate/clothes" window that allows for partial loading of coordinate cards. 40 | /// 41 | public MakerCoordinateLoadToggle AddCoordinateLoadToggle(MakerCoordinateLoadToggle toggle) 42 | { 43 | return MakerCoordinateLoadToggle.AddLoadToggle(toggle); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Shared.Core/Maker/Events/RegisterCustomControlsEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using KKAPI.Maker.UI; 3 | using KKAPI.Maker.UI.Sidebar; 4 | 5 | #pragma warning disable CS0618 // Type or member is obsolete 6 | 7 | namespace KKAPI.Maker 8 | { 9 | /// 10 | /// Event fired when character maker is starting and plugins are given an opportunity to register custom controls 11 | /// 12 | public class RegisterCustomControlsEvent : EventArgs 13 | { 14 | /// 15 | /// Add custom controls. If you want to use custom sub categories, register them by calling AddSubCategory. 16 | /// 17 | public T AddControl(T control) where T : BaseGuiEntry 18 | { 19 | return MakerAPI.AddControl(control); 20 | } 21 | 22 | /// 23 | /// Add a control to the right sidebar in chara maker (the "Control Panel" where you set eye blinking, mouth expressions etc.) 24 | /// 25 | public T AddSidebarControl(T control) where T : BaseGuiEntry, ISidebarControl 26 | { 27 | return MakerAPI.AddSidebarControl(control); 28 | } 29 | 30 | /// 31 | /// Add a toggle to the bottom of the "Load character" window that allows for partial loading of characters. 32 | /// 33 | public MakerLoadToggle AddLoadToggle(MakerLoadToggle toggle) 34 | { 35 | return MakerLoadToggle.AddLoadToggle(toggle); 36 | } 37 | 38 | /// 39 | /// Add a toggle to the bottom of the "Load coordinate/clothes" window that allows for partial loading of coordinate cards. 40 | /// 41 | public MakerCoordinateLoadToggle AddCoordinateLoadToggle(MakerCoordinateLoadToggle toggle) 42 | { 43 | return MakerCoordinateLoadToggle.AddLoadToggle(toggle); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Shared.KKalike/Maker/UI/Sidebar/SidebarToggle.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using TMPro; 3 | using UniRx; 4 | using UnityEngine; 5 | using UnityEngine.UI; 6 | 7 | namespace KKAPI.Maker.UI.Sidebar 8 | { 9 | /// 10 | /// A toggle to be used in the right "Control Panel" sidebar in character maker. 11 | /// The space is limited so use sparingly. 12 | /// 13 | public class SidebarToggle : BaseEditableGuiEntry, ISidebarControl 14 | { 15 | /// 16 | public SidebarToggle(string text, bool initialValue, BaseUnityPlugin owner) : base(null, initialValue, owner) 17 | { 18 | Text = text; 19 | } 20 | 21 | /// 22 | protected internal override void Initialize() { } 23 | 24 | /// 25 | protected override GameObject OnCreateControl(Transform subCategoryList) 26 | { 27 | var origTgl = GetExistingControl("CustomScene/CustomRoot/FrontUIGroup/CvsDraw/Top", "tglBlink"); 28 | var copy = Object.Instantiate(origTgl.gameObject, origTgl.transform.parent); 29 | 30 | RemoveLocalisation(copy); 31 | 32 | var tgl = copy.GetComponentInChildren(); 33 | tgl.graphic.raycastTarget = true; 34 | tgl.onValueChanged.RemoveAllListeners(); 35 | 36 | tgl.onValueChanged.AddListener(SetValue); 37 | BufferedValueChanged.Subscribe(val => tgl.isOn = val); 38 | 39 | var txt = copy.GetComponentInChildren(); 40 | txt.text = Text; 41 | txt.color = TextColor; 42 | txt.GetComponent().SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 145); 43 | 44 | return copy; 45 | } 46 | 47 | /// 48 | /// Text displayed next to the checkbox 49 | /// 50 | public string Text { get; } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Shared.KKalike/Maker/UI/MakerSeparator.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using UnityEngine; 3 | using UnityEngine.UI; 4 | 5 | namespace KKAPI.Maker.UI 6 | { 7 | /// 8 | /// Custom control that draws a simple horizontal separator 9 | /// 10 | public class MakerSeparator : BaseGuiEntry 11 | { 12 | private static Transform _sourceSeparator; 13 | 14 | /// 15 | protected override GameObject OnCreateControl(Transform subCategoryList) 16 | { 17 | var s = Object.Instantiate(SourceSeparator, subCategoryList, false); 18 | s.name = "Separate"; 19 | return s.gameObject; 20 | } 21 | 22 | /// 23 | protected internal override void Initialize() 24 | { 25 | if (_sourceSeparator == null) 26 | MakeCopy(); 27 | } 28 | 29 | private static Transform SourceSeparator 30 | { 31 | get 32 | { 33 | if (_sourceSeparator == null) 34 | MakeCopy(); 35 | 36 | return _sourceSeparator; 37 | } 38 | } 39 | 40 | private static void MakeCopy() 41 | { 42 | _sourceSeparator = GetExistingControl("CustomScene/CustomRoot/FrontUIGroup/CustomUIGroup/CvsMenuTree/00_FaceTop/tglAll", "Separate").transform; 43 | var layout = _sourceSeparator.GetComponent(); 44 | layout.flexibleWidth = 1; 45 | } 46 | 47 | /// 48 | /// Create a new custom control. Create and register it in . 49 | /// 50 | /// Category the control will be created under 51 | /// Plugin that owns the control 52 | public MakerSeparator(MakerCategory category, BaseUnityPlugin owner) : base(category, owner) { } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/UI/MakerButton.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using UnityEngine; 3 | using UnityEngine.UI; 4 | 5 | namespace KKAPI.Maker.UI 6 | { 7 | /// 8 | /// Custom control that draws a simple blue button. 9 | /// 10 | public class MakerButton : BaseGuiEntry 11 | { 12 | /// 13 | /// Create a new custom control. Create and register it in . 14 | /// 15 | /// Text displayed on the button 16 | /// Category the control will be created under 17 | /// Plugin that owns the control 18 | public MakerButton(string text, MakerCategory category, BaseUnityPlugin owner) : base(category, owner) 19 | { 20 | Text = text; 21 | OnClick = new Button.ButtonClickedEvent(); 22 | } 23 | 24 | /// 25 | /// Fired when user clicks on the button 26 | /// 27 | public Button.ButtonClickedEvent OnClick { get; } 28 | 29 | /// 30 | /// Text displayed on the button 31 | /// 32 | public string Text { get; } 33 | 34 | /// 35 | protected internal override void Initialize() 36 | { 37 | } 38 | 39 | /// 40 | public override void Dispose() 41 | { 42 | OnClick.RemoveAllListeners(); 43 | base.Dispose(); 44 | } 45 | 46 | /// 47 | protected override GameObject OnCreateControl(Transform subCategoryList) 48 | { 49 | var button = MakerAPI.GetMakerBase().CreateButton(subCategoryList.gameObject, Text, OnClick.Invoke); 50 | var text = button.GetComponentInChildren(); 51 | text.color = TextColor; 52 | SetTextAutosize(text); 53 | return button.gameObject; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Shared.CharaStudio/Studio/UI/Toolbars/SimpleToolbarButton.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BepInEx; 3 | using UniRx; 4 | using UniRx.Triggers; 5 | using UnityEngine; 6 | using UnityEngine.EventSystems; 7 | 8 | #pragma warning disable CS1573 // Necessary because inheritdoc doesn't count as having a param tag for the compiler, even though the tag is indeed added 9 | 10 | namespace KKAPI.Studio.UI.Toolbars 11 | { 12 | /// 13 | /// Simple toolbar button that triggers an action when clicked. 14 | /// 15 | public class SimpleToolbarButton : ToolbarControlBase 16 | { 17 | /// 18 | /// Observable triggered when the button is clicked. 19 | /// 20 | public Subject OnClicked { get; } 21 | 22 | /// 23 | /// Initializes a new instance of the class. 24 | /// 25 | /// 26 | /// Action to invoke when clicked. 27 | public SimpleToolbarButton(string buttonID, string hoverText, Func iconGetter, BaseUnityPlugin owner, Action onClicked = null) 28 | : base(buttonID, hoverText, iconGetter, owner) 29 | { 30 | OnClicked = new Subject(); 31 | if (onClicked != null) OnClicked.Subscribe(onClicked); 32 | } 33 | 34 | /// 35 | protected internal override void CreateControl() 36 | { 37 | if (ButtonObject) return; 38 | base.CreateControl(); 39 | // Do this instead of ButtonObject.onClick to support right and middle clicks too 40 | ButtonObject.image.OnPointerClickAsObservable().Subscribe(data => 41 | { 42 | // Recreate Button.onClick behavior 43 | if (ButtonObject.IsActive() && ButtonObject.IsInteractable()) 44 | OnClicked.OnNext(data.button); 45 | }); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/UI/MakerText.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using HarmonyLib; 3 | using UnityEngine; 4 | using UnityEngine.UI; 5 | 6 | namespace KKAPI.Maker.UI 7 | { 8 | /// 9 | /// Custom control that displays a simple text 10 | /// 11 | public class MakerText : BaseGuiEntry 12 | { 13 | /// 14 | /// Light gray color best used for text explaining another setting 15 | /// 16 | public static Color ExplanationGray => new Color(0.7f, 0.7f, 0.7f); 17 | 18 | private string _text; 19 | private Text _instance; 20 | 21 | /// 22 | /// Create a new custom control. Create and register it in . 23 | /// 24 | /// Displayed text 25 | /// Category the control will be created under 26 | /// Plugin that owns the control 27 | public MakerText(string text, MakerCategory category, BaseUnityPlugin owner) : base(category, owner) 28 | { 29 | Text = text; 30 | } 31 | 32 | /// 33 | /// Displayed text 34 | /// 35 | public string Text 36 | { 37 | get => _text; 38 | set 39 | { 40 | _text = value; 41 | 42 | if (_instance != null) 43 | _instance.text = value; 44 | } 45 | } 46 | 47 | /// 48 | protected internal override void Initialize() 49 | { 50 | } 51 | 52 | /// 53 | protected override GameObject OnCreateControl(Transform subCategoryList) 54 | { 55 | _instance = MakerAPI.GetMakerBase().CreateLabel(subCategoryList.gameObject, Text); 56 | var text = _instance.GetComponentInChildren(); 57 | text.color = TextColor; 58 | SetTextAutosize(text); 59 | return _instance.gameObject; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/KKAPI/MainGame/TestGameFunctionController.cs: -------------------------------------------------------------------------------- 1 | using ActionGame; 2 | using BepInEx.Logging; 3 | using UnityEngine; 4 | 5 | namespace KKAPI.MainGame 6 | { 7 | internal sealed class TestGameFunctionController : GameCustomFunctionController 8 | { 9 | protected internal override void OnEndH(MonoBehaviour proc, HFlag hFlag, bool vr) 10 | { 11 | KoikatuAPI.Logger.Log(LogLevel.Warning | LogLevel.Message, "GameController - OnEndH - FreeH:" + hFlag.isFreeH); 12 | } 13 | 14 | protected internal override void OnEnterNightMenu() 15 | { 16 | KoikatuAPI.Logger.Log(LogLevel.Warning | LogLevel.Message, "GameController - OnEnterNightMenu"); 17 | } 18 | 19 | protected internal override void OnGameLoad(GameSaveLoadEventArgs args) 20 | { 21 | KoikatuAPI.Logger.Log(LogLevel.Warning | LogLevel.Message, "GameController - OnGameLoad - Path:" + args.FullFilename); 22 | } 23 | 24 | protected internal override void OnGameSave(GameSaveLoadEventArgs args) 25 | { 26 | KoikatuAPI.Logger.Log(LogLevel.Warning | LogLevel.Message, "GameController - OnGameSave - Path:" + args.FullFilename); 27 | } 28 | 29 | protected internal override void OnStartH(MonoBehaviour proc, HFlag hFlag, bool vr) 30 | { 31 | KoikatuAPI.Logger.Log(LogLevel.Warning | LogLevel.Message, "GameController - OnStartH - FreeH:" + hFlag.isFreeH); 32 | } 33 | 34 | protected internal override void OnDayChange(Cycle.Week day) 35 | { 36 | KoikatuAPI.Logger.Log(LogLevel.Warning | LogLevel.Message, "GameController - OnDayChange - day:" + day); 37 | } 38 | 39 | protected internal override void OnPeriodChange(Cycle.Type period) 40 | { 41 | KoikatuAPI.Logger.Log(LogLevel.Warning | LogLevel.Message, "GameController - OnPeriodChange - period:" + period); 42 | } 43 | 44 | protected internal override void OnNewGame() 45 | { 46 | KoikatuAPI.Logger.Log(LogLevel.Warning | LogLevel.Message, "GameController - OnNewGame"); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/KKSAPI/MainGame/TestGameFunctionController.cs: -------------------------------------------------------------------------------- 1 | using ActionGame; 2 | using BepInEx.Logging; 3 | using UnityEngine; 4 | 5 | namespace KKAPI.MainGame 6 | { 7 | internal sealed class TestGameFunctionController : GameCustomFunctionController 8 | { 9 | protected internal override void OnEndH(MonoBehaviour proc, HFlag hFlag, bool vr) 10 | { 11 | KoikatuAPI.Logger.Log(LogLevel.Warning | LogLevel.Message, $"GameController - OnEndH - proc={proc} HFlag={hFlag} vr={vr}"); 12 | } 13 | 14 | protected internal override void OnEnterHotelMyroomMenu() 15 | { 16 | KoikatuAPI.Logger.Log(LogLevel.Warning | LogLevel.Message, "GameController - OnEnterHotelMyroomMenu"); 17 | } 18 | 19 | protected internal override void OnGameLoad(GameSaveLoadEventArgs args) 20 | { 21 | KoikatuAPI.Logger.Log(LogLevel.Warning | LogLevel.Message, "GameController - OnGameLoad - Path=" + args.FullFilename); 22 | } 23 | 24 | protected internal override void OnGameSave(GameSaveLoadEventArgs args) 25 | { 26 | KoikatuAPI.Logger.Log(LogLevel.Warning | LogLevel.Message, "GameController - OnGameSave - Path=" + args.FullFilename); 27 | } 28 | 29 | protected internal override void OnStartH(MonoBehaviour proc, HFlag hFlag, bool vr) 30 | { 31 | KoikatuAPI.Logger.Log(LogLevel.Warning | LogLevel.Message, $"GameController - OnStartH - proc={proc} HFlag={hFlag} vr={vr}"); 32 | } 33 | 34 | protected internal override void OnDayChange(Cycle.Week day) 35 | { 36 | KoikatuAPI.Logger.Log(LogLevel.Warning | LogLevel.Message, "GameController - OnDayChange - day=" + day); 37 | } 38 | 39 | protected internal override void OnPeriodChange(Cycle.Type period) 40 | { 41 | KoikatuAPI.Logger.Log(LogLevel.Warning | LogLevel.Message, "GameController - OnPeriodChange - period=" + period); 42 | } 43 | 44 | protected internal override void OnNewGame() 45 | { 46 | KoikatuAPI.Logger.Log(LogLevel.Warning | LogLevel.Message, "GameController - OnNewGame"); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/ECAPI/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/Shared.Core/Utilities/ObservableExtensions.cs: -------------------------------------------------------------------------------- 1 | #if HS2 || AI || KKS 2 | using System; 3 | #endif 4 | using UniRx; 5 | using UniRx.Triggers; 6 | using UnityEngine; 7 | 8 | namespace KKAPI.Utilities 9 | { 10 | /// 11 | /// Additions to the UniRx IObservable extension methods 12 | /// 13 | public static class ObservableExtensions 14 | { 15 | /// 16 | /// Get an observable that triggers on every OnGUI call on this gameObject 17 | /// 18 | public static IObservable OnGUIAsObservable(this Component component) => component == null ? Observable.Empty() : component.GetOrAddComponent().OnGUIAsObservable(); 19 | /// 20 | public static IObservable OnGUIAsObservable(this Transform transform) => transform == null ? Observable.Empty() : transform.GetOrAddComponent().OnGUIAsObservable(); 21 | /// 22 | public static IObservable OnGUIAsObservable(this GameObject gameObject) => gameObject == null ? Observable.Empty() : gameObject.GetOrAddComponent().OnGUIAsObservable(); 23 | } 24 | 25 | /// 26 | /// Trigger component that implements 27 | /// 28 | [DisallowMultipleComponent] 29 | public class ObservableOnGUITrigger : ObservableTriggerBase 30 | { 31 | private void OnGUI() 32 | { 33 | _onGui?.OnNext(Unit.Default); 34 | } 35 | 36 | /// 37 | /// Get observable that triggers every time this component's OnGUI is called 38 | /// 39 | public IObservable OnGUIAsObservable() 40 | { 41 | return _onGui ?? (_onGui = new Subject()); 42 | } 43 | 44 | /// 45 | public override void RaiseOnCompletedOnDestroy() 46 | { 47 | _onGui?.OnCompleted(); 48 | } 49 | 50 | private Subject _onGui; 51 | } 52 | } -------------------------------------------------------------------------------- /src/AIAPI/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/AccessoriesApi.Hooks.PH.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using HarmonyLib; 4 | using KKAPI.Utilities; 5 | using UnityEngine; 6 | using UnityEngine.UI; 7 | 8 | namespace KKAPI.Maker 9 | { 10 | public static partial class AccessoriesApi 11 | { 12 | private static class Hooks 13 | { 14 | [HarmonyPostfix] 15 | [HarmonyPatch(typeof(AccessoryCustomEdit), "ChangeTab")] 16 | public static void ChangeSlotPostfix(AccessoryCustomEdit __instance, int newTab) 17 | { 18 | OnSelectedMakerSlotChanged(__instance, newTab); 19 | } 20 | 21 | [HarmonyPostfix] 22 | [HarmonyPatch(typeof(AccessoryCustomEdit), "OnChangeAcceItem")] 23 | public static void OnAccessoryChangedHook(AccessoryCustomEdit __instance, int slot, CustomSelectSet set) 24 | { 25 | OnAccessoryChanged(__instance, slot); 26 | } 27 | 28 | #if KK 29 | [HarmonyPostfix] 30 | [HarmonyPatch(typeof(CvsAccessoryCopy), "CopyAcs")] 31 | public static void CopyCopyAcsPostfix(CvsAccessoryCopy __instance) 32 | { 33 | OnCopyAcs(__instance); 34 | } 35 | #endif 36 | 37 | [HarmonyPostfix] 38 | [HarmonyPatch(typeof(AcceCopyHelperUI), "Button_CopySlot")] 39 | //todo These only copy positions, so don't trigger? 40 | //[HarmonyPatch(typeof(AcceCopyHelperUI), "Button_CopyPos")] 41 | //[HarmonyPatch(typeof(AcceCopyHelperUI), "Button_CopyPosRev_H")] 42 | //[HarmonyPatch(typeof(AcceCopyHelperUI), "Button_CopyPosRev_V")] 43 | public static void CopyAcsPostfix(AcceCopyHelperUI __instance, Toggle[] ___dstSlots, Toggle[] ___srcSlots) 44 | { 45 | var selDst = -1; 46 | var selSrc = -1; 47 | for (var i = 0; i < ___dstSlots.Length; i++) 48 | { 49 | if (___srcSlots[i].isOn) selSrc = i; 50 | if (___dstSlots[i].isOn) selDst = i; 51 | } 52 | 53 | OnChangeAcs(__instance, selSrc, selDst); 54 | } 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /src/HS2API/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/UI/MakerDropdown.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using BepInEx; 3 | using HarmonyLib; 4 | using UniRx; 5 | using UnityEngine; 6 | using UnityEngine.UI; 7 | 8 | namespace KKAPI.Maker.UI 9 | { 10 | /// 11 | /// Custom control that draws a dropdown list 12 | /// 13 | public class MakerDropdown : BaseEditableGuiEntry 14 | { 15 | /// 16 | /// Create a new custom control. Create and register it in . 17 | /// 18 | /// Text displayed next to the dropdown 19 | /// Items for the dropdown menu 20 | /// Category the control will be created under 21 | /// Initially selected item in the dropdown menu 22 | /// Plugin that owns the control 23 | public MakerDropdown(string settingName, string[] options, MakerCategory category, int initialValue, BaseUnityPlugin owner) 24 | : base(category, initialValue, owner) 25 | { 26 | SettingName = settingName; 27 | Options = options; 28 | } 29 | 30 | /// 31 | /// List of all options in the dropdown 32 | /// 33 | public string[] Options { get; } 34 | 35 | /// 36 | /// Name displayed next to the dropdown 37 | /// 38 | public string SettingName { get; } 39 | 40 | /// 41 | protected internal override void Initialize() 42 | { 43 | } 44 | 45 | /// 46 | protected override GameObject OnCreateControl(Transform subCategoryList) 47 | { 48 | var dd = MakerAPI.GetMakerBase().CreateDropDownUI(subCategoryList.gameObject, SettingName, Options.Select(x => new Dropdown.OptionData(x)).ToList(), SetValue); 49 | BufferedValueChanged.Subscribe(dd.SetValue); 50 | var text = Traverse.Create(dd).Field("title").Value; 51 | text.color = TextColor; 52 | foreach (var txt in dd.GetComponentsInChildren(true)) 53 | SetTextAutosize(txt); 54 | return dd.gameObject; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/KKAPI/KKAPI.csproj.DotSettings: -------------------------------------------------------------------------------- 1 | 2 | False 3 | True 4 | True 5 | True 6 | True 7 | True 8 | True 9 | True 10 | True 11 | True 12 | False 13 | False 14 | True 15 | False 16 | False -------------------------------------------------------------------------------- /src/Shared.AIalike/Maker/UI/Sidebar/SidebarToggle.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using KKAPI.Utilities; 3 | using UniRx; 4 | using UnityEngine; 5 | using UnityEngine.UI; 6 | 7 | namespace KKAPI.Maker.UI.Sidebar 8 | { 9 | /// 10 | /// A toggle to be used in the right "Control Panel" sidebar in character maker. 11 | /// The space is limited so use sparingly. 12 | /// 13 | public class SidebarToggle : BaseEditableGuiEntry, ISidebarControl 14 | { 15 | /// 16 | public SidebarToggle(string text, bool initialValue, BaseUnityPlugin owner) : base(null, initialValue, owner) 17 | { 18 | Text = text; 19 | } 20 | 21 | private static GameObject _cachedToggle; 22 | 23 | /// 24 | protected internal override void Initialize() 25 | { 26 | if(_cachedToggle != null) return; 27 | 28 | var orig = GameObject.Find("CharaCustom/CustomControl/CanvasDraw/DrawWindow/dwCoorde/clothes/items/tgl01"); 29 | var copy = Object.Instantiate(orig, GuiCacheTransfrom, false); 30 | copy.name = "plugTgl_AIAPI"; 31 | 32 | var t = copy.transform.GetComponentInChildren(); 33 | t.lineSpacing = 0.65f; 34 | SetTextAutosize(t); 35 | 36 | var tgl = copy.GetComponent(); 37 | tgl.group = null; 38 | tgl.onValueChanged.ActuallyRemoveAllListeners(); 39 | tgl.graphic.raycastTarget = true; 40 | 41 | copy.SetActive(false); 42 | 43 | _cachedToggle = copy; 44 | } 45 | 46 | /// 47 | protected override GameObject OnCreateControl(Transform subCategoryList) 48 | { 49 | var copy = Object.Instantiate(_cachedToggle, subCategoryList); 50 | 51 | RemoveLocalisation(copy); 52 | 53 | var tgl = copy.GetComponent(); 54 | tgl.onValueChanged.AddListener(SetValue); 55 | BufferedValueChanged.Subscribe(val => tgl.isOn = val); 56 | 57 | var txt = copy.GetComponentInChildren(); 58 | txt.text = Text; 59 | txt.color = TextColor; 60 | 61 | return copy; 62 | } 63 | 64 | /// 65 | /// Text displayed next to the checkbox 66 | /// 67 | public string Text { get; } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/UI/MakerToggle.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using UniRx; 3 | using UnityEngine; 4 | using UnityEngine.UI; 5 | 6 | namespace KKAPI.Maker.UI 7 | { 8 | /// 9 | /// Custom control that displays a toggle 10 | /// 11 | public class MakerToggle : BaseEditableGuiEntry 12 | { 13 | /// 14 | /// Create a new custom control. Create and register it in . 15 | /// 16 | /// Text shown next to the checkbox 17 | /// Category the control will be created under 18 | /// Plugin that owns the control 19 | public MakerToggle(MakerCategory category, string displayName, BaseUnityPlugin owner) : this(category, displayName, false, owner) { } 20 | 21 | /// 22 | /// Create a new custom control. Create and register it in . 23 | /// 24 | /// Text shown next to the checkbox 25 | /// Category the control will be created under 26 | /// Initial value of the toggle 27 | /// Plugin that owns the control 28 | public MakerToggle(MakerCategory category, string displayName, bool initialValue, BaseUnityPlugin owner) : base(category, initialValue, owner) 29 | { 30 | DisplayName = displayName; 31 | } 32 | 33 | /// 34 | /// Text shown next to the checkbox 35 | /// 36 | public string DisplayName { get; } 37 | 38 | /// 39 | protected internal override void Initialize() 40 | { 41 | } 42 | 43 | /// 44 | protected override GameObject OnCreateControl(Transform subCategoryList) 45 | { 46 | var sw = MakerAPI.GetMakerBase().CreateSwitchUI(subCategoryList.gameObject, DisplayName, Value, SetValue); 47 | BufferedValueChanged.Subscribe(sw.SetValue); 48 | var text = sw.title; 49 | text.color = TextColor; 50 | foreach (var txt in sw.GetComponentsInChildren(true)) 51 | SetTextAutosize(txt); 52 | return sw.gameObject; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Shared.Core/SceneApi.cs: -------------------------------------------------------------------------------- 1 | namespace KKAPI 2 | { 3 | /// 4 | /// Game-agnostic version of Manager.Scene. It allows using the same code in all games without any #if directives. 5 | /// 6 | public static class SceneApi 7 | { 8 | /// 9 | /// Get name of the currently loaded overlay scene (eg. exit game box, config, confirmation dialogs). 10 | /// 11 | public static string GetAddSceneName() 12 | { 13 | #if HS2 || KKS 14 | return Manager.Scene.AddSceneName; 15 | #else 16 | return Manager.Scene.Instance.AddSceneName; 17 | #endif 18 | } 19 | 20 | /// 21 | /// Get name of the currently loaded game scene (eg. maker, h, adv). 22 | /// 23 | public static string GetLoadSceneName() 24 | { 25 | #if HS2 || KKS 26 | return Manager.Scene.LoadSceneName; 27 | #else 28 | return Manager.Scene.Instance.LoadSceneName; 29 | #endif 30 | } 31 | 32 | /// 33 | /// True if loading screen is being displayed, or if screen is currently fading in or out. 34 | /// 35 | public static bool GetIsNowLoadingFade() 36 | { 37 | #if HS2 || KKS 38 | return Manager.Scene.IsNowLoadingFade; 39 | #else 40 | return Manager.Scene.Instance.IsNowLoadingFade; 41 | #endif 42 | } 43 | 44 | /// 45 | /// True if loading screen is being displayed. 46 | /// 47 | public static bool GetIsNowLoading() 48 | { 49 | #if HS2 || KKS 50 | return Manager.Scene.IsNowLoading; 51 | #else 52 | return Manager.Scene.Instance.IsNowLoading; 53 | #endif 54 | } 55 | 56 | /// 57 | /// True if screen is currently fading in or out. 58 | /// 59 | public static bool GetIsFadeNow() 60 | { 61 | #if HS2 || KKS 62 | return Manager.Scene.IsFadeNow; 63 | #else 64 | return Manager.Scene.Instance.IsFadeNow; 65 | #endif 66 | } 67 | 68 | /// 69 | /// True if a dialog box or some other overlapping menu is shown (e.g. exit dialog after pressing esc). 70 | /// 71 | public static bool GetIsOverlap() 72 | { 73 | #if HS2 || KKS 74 | return Manager.Scene.IsOverlap; 75 | #else 76 | return Manager.Scene.Instance.IsOverlap; 77 | #endif 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /src/AIAPI/KoikatuAPI.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BepInEx; 3 | using KKAPI.Chara; 4 | using KKAPI.Maker; 5 | using KKAPI.Studio; 6 | using KKAPI.MainGame; 7 | using Manager; 8 | using UnityEngine; 9 | 10 | namespace KKAPI 11 | { 12 | [BepInPlugin(GUID, "Modding API", VersionConst)] 13 | [BepInDependency(ExtensibleSaveFormat.ExtendedSave.GUID, "12.2")] 14 | public partial class KoikatuAPI : BaseUnityPlugin 15 | { 16 | /// 17 | /// The studio process name for use with attributes. 18 | /// 19 | public const string StudioProcessName = "StudioNEOV2"; 20 | /// 21 | /// The game process name for use with attributes. 22 | /// It's the same for jp and steam releases. 23 | /// 24 | public const string GameProcessName = "AI-Syoujyo"; 25 | 26 | private void Awake() 27 | { 28 | BaseAwake(); 29 | 30 | var insideStudio = Application.productName == "StudioNEOV2"; 31 | MakerAPI.Init(insideStudio); 32 | StudioAPI.Init(insideStudio); 33 | CharacterApi.Init(); 34 | GameAPI.Init(insideStudio); 35 | } 36 | 37 | private void Start() 38 | { 39 | // Needs to be called after moreaccessories has a chance to load 40 | AccessoriesApi.Init(); 41 | } 42 | 43 | /// 44 | /// Get current game mode. 45 | /// 46 | public static GameMode GetCurrentGameMode() 47 | { 48 | if (MakerAPI.InsideMaker) return GameMode.Maker; 49 | if (StudioAPI.InsideStudio) return GameMode.Studio; 50 | if (Map.IsInstance() && Map.Instance.MapRoot != null) return GameMode.MainGame; 51 | return GameMode.Unknown; 52 | } 53 | 54 | /// 55 | /// Get current version of the game. 56 | /// 57 | public static Version GetGameVersion() 58 | { 59 | return Game.Version; 60 | } 61 | 62 | /// 63 | /// Check if the game is the Steam release instead of the original Japanese release. 64 | /// It's best to not rely on this and instead make the same code work in both versions (if possible). 65 | /// 66 | public static bool IsSteamRelease() 67 | { 68 | // The jp version only has Japanese listed 69 | return GameSystem.Instance.cultureNames.Length > 1; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/PHAPI/KoikatuAPI.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BepInEx; 3 | using HarmonyLib; 4 | using KKAPI.Chara; 5 | using KKAPI.Maker; 6 | using KKAPI.Studio; 7 | using Manager; 8 | using UnityEngine; 9 | 10 | namespace KKAPI 11 | { 12 | [BepInPlugin(GUID, "Modding API", VersionConst)] 13 | public partial class KoikatuAPI : BaseUnityPlugin 14 | { 15 | /// 16 | /// The game process name for use with attributes. 17 | /// This is for the 64 bit version. In almost all cases should be used together with the 32 bit version. 18 | /// 19 | public const string GameProcessName = "PlayHome64bit"; 20 | /// 21 | /// The game process name for use with attributes. 22 | /// This is for the 32 bit version. In almost all cases should be used together with the 64 bit version. 23 | /// 24 | public const string GameProcessName32bit = "PlayHome32bit"; 25 | /// 26 | /// The studio process name for use with attributes. 27 | /// This is for the 64 bit version. In almost all cases should be used together with the 32 bit version. 28 | /// 29 | public const string StudioProcessName = "PlayHomeStudio64bit"; 30 | /// 31 | /// The studio process name for use with attributes. 32 | /// This is for the 32 bit version. In almost all cases should be used together with the 64 bit version. 33 | /// 34 | public const string StudioProcessName32bit = "PlayHomeStudio32bit"; 35 | 36 | private void Awake() 37 | { 38 | BaseAwake(); 39 | 40 | var insideStudio = Application.productName.StartsWith("PlayHomeStudio"); 41 | MakerAPI.Init(insideStudio); 42 | StudioAPI.Init(insideStudio); 43 | CharacterApi.Init(); 44 | AccessoriesApi.Init(); 45 | } 46 | 47 | /// 48 | /// Get current game mode. 49 | /// 50 | public static GameMode GetCurrentGameMode() 51 | { 52 | if (StudioAPI.InsideStudio) return GameMode.Studio; 53 | if (MakerAPI.InsideMaker) return GameMode.Maker; 54 | //todo implement 55 | //if (Game.IsInstance()) return GameMode.MainGame; 56 | return GameMode.Unknown; 57 | } 58 | 59 | /// 60 | /// Get current version of the game. 61 | /// 62 | public static Version GetGameVersion() 63 | { 64 | //todo implement 65 | return new Version(1, 4); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Shared.AIalike/Maker/UI/MakerCoordinateLoadToggle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using UnityEngine; 5 | 6 | namespace KKAPI.Maker.UI 7 | { 8 | /// 9 | /// Adds a toggle to the bottom of the coordinate/clothes card load window in character maker. 10 | /// Use to allow user to not load data related to your mod. 11 | /// Use with 12 | /// 13 | [Obsolete("Not implemented")] 14 | public class MakerCoordinateLoadToggle : BaseEditableGuiEntry 15 | { 16 | private static readonly List Toggles = new List(); 17 | 18 | /// 19 | /// Create a new coordinate load toggle. Create and register it in 20 | /// with . 21 | /// 22 | /// Text displayed next to the checkbox 23 | /// Initial value of the toggle 24 | public MakerCoordinateLoadToggle(string text, bool initialValue = true) : base(null, initialValue, null) 25 | { 26 | Text = text; 27 | } 28 | 29 | /// 30 | /// Text displayed next to the toggle 31 | /// 32 | public string Text { get; } 33 | 34 | /// 35 | /// Check if any of the custom toggles are checked 36 | /// 37 | public static bool AnyEnabled => Toggles.Any(x => x.Value); 38 | 39 | internal static void CreateCustomToggles() 40 | { 41 | } 42 | 43 | /// 44 | protected override GameObject OnCreateControl(Transform loadBoxTransform) 45 | { 46 | KoikatuAPI.Logger.LogWarning("MakerCoordinateLoadToggles are not implemented yet"); 47 | Value = true; 48 | return null; 49 | } 50 | 51 | /// 52 | protected internal override void Initialize() { } 53 | 54 | internal static MakerCoordinateLoadToggle AddLoadToggle(MakerCoordinateLoadToggle toggle) 55 | { 56 | if (toggle == null) throw new ArgumentNullException(nameof(toggle)); 57 | toggle.ThrowIfDisposed(nameof(toggle)); 58 | 59 | Toggles.Add(toggle); 60 | return toggle; 61 | } 62 | 63 | internal static void Reset() 64 | { 65 | foreach (var toggle in Toggles) 66 | toggle.Dispose(); 67 | Toggles.Clear(); 68 | } 69 | 70 | internal static void Setup() 71 | { 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Shared.AIalike/Maker/UI/MakerToggle.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using KKAPI.Utilities; 3 | using UniRx; 4 | using UnityEngine; 5 | using UnityEngine.UI; 6 | 7 | namespace KKAPI.Maker.UI 8 | { 9 | /// 10 | /// Custom control that displays a toggle 11 | /// 12 | public class MakerToggle : BaseEditableGuiEntry 13 | { 14 | /// 15 | /// Create a new custom control. Create and register it in . 16 | /// 17 | /// Text shown next to the checkbox 18 | /// Category the control will be created under 19 | /// Plugin that owns the control 20 | public MakerToggle(MakerCategory category, string displayName, BaseUnityPlugin owner) : this(category, displayName, false, owner) { } 21 | 22 | /// 23 | /// Create a new custom control. Create and register it in . 24 | /// 25 | /// Text shown next to the checkbox 26 | /// Category the control will be created under 27 | /// Initial value of the toggle 28 | /// Plugin that owns the control 29 | public MakerToggle(MakerCategory category, string displayName, bool initialValue, BaseUnityPlugin owner) : base(category, initialValue, owner) 30 | { 31 | DisplayName = displayName; 32 | } 33 | 34 | /// 35 | /// Text shown next to the checkbox 36 | /// 37 | public string DisplayName { get; } 38 | 39 | /// 40 | protected internal override void Initialize() 41 | { 42 | } 43 | 44 | /// 45 | protected override GameObject OnCreateControl(Transform subCategoryList) 46 | { 47 | var tr = Object.Instantiate(GameObject.Find("CharaCustom/CustomControl/CanvasMain/SubMenu/SubMenuFace/Scroll View/Viewport/Content/Category/CategoryTop/SameSettingEyes"), subCategoryList, false); 48 | 49 | var tgl = tr.GetComponentInChildren(); 50 | tgl.onValueChanged.ActuallyRemoveAllListeners(); 51 | tgl.onValueChanged.AddListener(SetValue); 52 | 53 | BufferedValueChanged.Subscribe(b => tgl.isOn = b); 54 | 55 | var text = tr.GetComponentInChildren(); 56 | text.text = DisplayName; 57 | text.color = TextColor; 58 | SetTextAutosize(text); 59 | 60 | return tr.gameObject; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Shared.AIalike/Shared.AIalike.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | bed55866-7531-4cc4-ba58-f406d901d3e8 7 | 8 | 9 | KKAPI 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/Shared.CharaStudio/Studio/UI/Toolbars/SimpleToolbarToggle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BepInEx; 3 | using UniRx; 4 | using UnityEngine; 5 | using UnityEngine.EventSystems; 6 | 7 | #pragma warning disable CS1573 // Necessary because inheritdoc doesn't count as having a param tag for the compiler, even though the tag is indeed added 8 | 9 | namespace KKAPI.Studio.UI.Toolbars 10 | { 11 | /// 12 | /// Toolbar button that acts as a toggle (on/off). 13 | /// 14 | public class SimpleToolbarToggle : SimpleToolbarButton 15 | { 16 | /// 17 | /// Observable value representing the toggle state. 18 | /// 19 | public BehaviorSubject Toggled { get; } 20 | 21 | /// 22 | /// Initializes a new instance of the class. 23 | /// 24 | /// 25 | /// Initial toggle value. 26 | /// Action to invoke when value changes. 27 | public SimpleToolbarToggle(string buttonID, string hoverText, Func iconGetter, bool initialValue, BaseUnityPlugin owner, Action onValueChanged = null) 28 | : base(buttonID, hoverText, iconGetter, owner) 29 | { 30 | Toggled = new BehaviorSubject(initialValue); 31 | Toggled.Subscribe(_ => UpdateVisualState()); 32 | 33 | if (onValueChanged != null) 34 | { 35 | var firstSkipped = false; 36 | Toggled.Subscribe(b => 37 | { 38 | if (firstSkipped) onValueChanged(b); 39 | else firstSkipped = true; 40 | }); 41 | } 42 | } 43 | 44 | /// 45 | protected internal override void CreateControl() 46 | { 47 | if (ButtonObject) return; 48 | 49 | base.CreateControl(); 50 | 51 | OnClicked.Subscribe(button => 52 | { 53 | if (button == PointerEventData.InputButton.Left) 54 | Toggled.OnNext(!Toggled.Value); 55 | }); 56 | 57 | UpdateVisualState(); 58 | } 59 | 60 | private void UpdateVisualState() 61 | { 62 | if (IsDisposed) throw new ObjectDisposedException(nameof(SimpleToolbarToggle)); 63 | var button = ButtonObject; 64 | if (!button) return; 65 | var btnIcon = button.image; 66 | btnIcon.color = Toggled.Value ? Color.green : Color.white; 67 | } 68 | 69 | /// 70 | public override void Dispose() 71 | { 72 | base.Dispose(); 73 | Toggled?.Dispose(); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/MakerCategory.cs: -------------------------------------------------------------------------------- 1 | namespace KKAPI.Maker 2 | { 3 | /// 4 | /// Specifies a category inside character maker. 5 | /// 6 | public sealed class MakerCategory 7 | { 8 | private bool Equals(MakerCategory other) 9 | { 10 | return string.Equals(CategoryName, other.CategoryName) && string.Equals(SubCategoryName, other.SubCategoryName); 11 | } 12 | 13 | /// 14 | public override bool Equals(object obj) 15 | { 16 | if (ReferenceEquals(null, obj)) return false; 17 | if (ReferenceEquals(this, obj)) return true; 18 | return obj is MakerCategory mc && Equals(mc); 19 | } 20 | 21 | /// 22 | public override int GetHashCode() 23 | { 24 | unchecked 25 | { 26 | return ((CategoryName != null ? CategoryName.GetHashCode() : 0) * 397) ^ (SubCategoryName != null ? SubCategoryName.GetHashCode() : 0); 27 | } 28 | } 29 | 30 | /// 31 | /// Make a new custom subcategory. 32 | /// 33 | public MakerCategory(string categoryName, string subCategoryName, 34 | int position = int.MaxValue, string displayName = null) 35 | { 36 | CategoryName = categoryName; 37 | SubCategoryName = subCategoryName; 38 | Position = position; 39 | DisplayName = displayName; 40 | } 41 | 42 | /// 43 | /// Main category gameObject name. Main categories are the square buttons at the top-left edge of the screen. 44 | /// They contain multiple subcategories (tabs on the left edge of the screen). 45 | /// 46 | public string CategoryName { get; } 47 | 48 | /// 49 | /// Sub category gameObject name. Sub categories are the named tabs on the left edge of the screen. 50 | /// They contain the actual controls (inside the window on the right of the tabs). 51 | /// 52 | public string SubCategoryName { get; } 53 | 54 | /// 55 | /// Numeric position of the subcategory. 56 | /// When making new subcategories you can set this value to be in-between stock subcategories. 57 | /// 58 | public int Position { get; } 59 | 60 | /// 61 | /// The text displayed on the subcategory tab on the left edge of the screen. 62 | /// 63 | public string DisplayName { get; } 64 | 65 | /// 66 | /// Get combined name for logging etc. 67 | /// 68 | public override string ToString() 69 | { 70 | return $"{CategoryName} / {SubCategoryName}"; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Shared.Core/Maker/MakerCategory.cs: -------------------------------------------------------------------------------- 1 | namespace KKAPI.Maker 2 | { 3 | /// 4 | /// Specifies a category inside character maker. 5 | /// 6 | public sealed class MakerCategory 7 | { 8 | private bool Equals(MakerCategory other) 9 | { 10 | return string.Equals(CategoryName, other.CategoryName) && string.Equals(SubCategoryName, other.SubCategoryName); 11 | } 12 | 13 | /// 14 | public override bool Equals(object obj) 15 | { 16 | if (ReferenceEquals(null, obj)) return false; 17 | if (ReferenceEquals(this, obj)) return true; 18 | return obj is MakerCategory mc && Equals(mc); 19 | } 20 | 21 | /// 22 | public override int GetHashCode() 23 | { 24 | unchecked 25 | { 26 | return ((CategoryName != null ? CategoryName.GetHashCode() : 0) * 397) ^ (SubCategoryName != null ? SubCategoryName.GetHashCode() : 0); 27 | } 28 | } 29 | 30 | /// 31 | /// Make a new custom subcategory. 32 | /// 33 | public MakerCategory(string categoryName, string subCategoryName, 34 | int position = int.MaxValue, string displayName = null) 35 | { 36 | CategoryName = categoryName; 37 | SubCategoryName = subCategoryName; 38 | Position = position; 39 | DisplayName = displayName; 40 | } 41 | 42 | /// 43 | /// Main category gameObject name. Main categories are the square buttons at the top-left edge of the screen. 44 | /// They contain multiple subcategories (tabs on the left edge of the screen). 45 | /// 46 | public string CategoryName { get; } 47 | 48 | /// 49 | /// Sub category gameObject name. Sub categories are the named tabs on the left edge of the screen. 50 | /// They contain the actual controls (inside the window on the right of the tabs). 51 | /// 52 | public string SubCategoryName { get; } 53 | 54 | /// 55 | /// Numeric position of the subcategory. 56 | /// When making new subcategories you can set this value to be in-between stock subcategories. 57 | /// 58 | public int Position { get; } 59 | 60 | /// 61 | /// The text displayed on the subcategory tab on the left edge of the screen. 62 | /// 63 | public string DisplayName { get; } 64 | 65 | /// 66 | /// Get combined name for logging etc. 67 | /// 68 | public override string ToString() 69 | { 70 | return $"{CategoryName} / {SubCategoryName}"; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/UI/MakerColor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BepInEx; 3 | using UniRx; 4 | using UnityEngine; 5 | using UnityEngine.UI; 6 | 7 | namespace KKAPI.Maker.UI 8 | { 9 | /// 10 | /// Control that allows user to change a in a separate color selector window 11 | /// 12 | public class MakerColor : BaseEditableGuiEntry 13 | { 14 | /// 15 | /// Create a new custom control. Create and register it in . 16 | /// 17 | /// Text displayed next to the control 18 | /// 19 | /// If true, the color selector will allow the user to change alpha of the color. 20 | /// If false, no color slider is shown and alpha is always 1f. 21 | /// 22 | /// Category the control will be created under 23 | /// Color set to the control when it is created 24 | /// Plugin that owns the control 25 | public MakerColor(string settingName, bool useAlpha, MakerCategory category, Color initialValue, BaseUnityPlugin owner) : base(category, initialValue, owner) 26 | { 27 | SettingName = settingName; 28 | UseAlpha = useAlpha; 29 | } 30 | 31 | /// 32 | /// Name of the setting 33 | /// 34 | public string SettingName { get; } 35 | 36 | /// 37 | /// If true, the color selector will allow the user to change alpha of the color. 38 | /// If false, no color slider is shown and alpha is always 1f. 39 | /// 40 | public bool UseAlpha { get; } 41 | 42 | /// 43 | /// Width of the color box. Can adjust this to allow for longer label text. 44 | /// Default width is 276 and might need to get lowered to allow longer labels. 45 | /// The default color boxes in accessory window are 230 wide. 46 | /// 47 | [Obsolete] 48 | public int ColorBoxWidth { get; set; } 49 | 50 | /// 51 | protected internal override void Initialize() 52 | { 53 | } 54 | 55 | /// 56 | protected override GameObject OnCreateControl(Transform subCategoryList) 57 | { 58 | var dd = MakerAPI.GetMakerBase().CreateColorChangeButton(subCategoryList.gameObject, SettingName, Value, UseAlpha, SetValue); 59 | BufferedValueChanged.Subscribe(dd.SetColor); 60 | var text = dd.GetComponentInChildren(); 61 | text.color = TextColor; 62 | SetTextAutosize(text); 63 | return dd.gameObject; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Shared.Core/Utilities/IMGUI/InterfaceMaker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using Object = UnityEngine.Object; 4 | 5 | namespace KKAPI.Utilities 6 | { 7 | internal static class InterfaceMaker 8 | { 9 | // These all need to be held as static properties, including textures, to prevent UnloadUnusedAssets from destroying them 10 | private static Texture2D _boxBackground; 11 | private static Texture2D _winBackground; 12 | private static GUISkin _customSkin; 13 | 14 | public static GUISkin CustomSkin 15 | { 16 | get 17 | { 18 | if (_customSkin == null) 19 | { 20 | try 21 | { 22 | KoikatuAPI.Logger.LogDebug("Instantiating custom GUISkin"); 23 | _customSkin = CreateSkin(IMGUIUtils.ColorFilterAffectsImgui); 24 | } 25 | catch (Exception ex) 26 | { 27 | KoikatuAPI.Logger.LogWarning("Could not load custom GUISkin - " + ex.Message); 28 | _customSkin = GUI.skin; 29 | } 30 | } 31 | 32 | return _customSkin; 33 | } 34 | } 35 | 36 | private static GUISkin CreateSkin(bool lightVersion) 37 | { 38 | // Reflection because unity 4.x refuses to instantiate if built with newer versions of UnityEngine 39 | var newSkin = Object.Instantiate(GUI.skin); 40 | Object.DontDestroyOnLoad(newSkin); 41 | 42 | // Load the custom skin from resources 43 | _boxBackground = ResourceUtils.GetEmbeddedResource(lightVersion ? "guisharp-box-light.png" : "guisharp-box.png").LoadTexture(); 44 | Object.DontDestroyOnLoad(_boxBackground); 45 | newSkin.box.onNormal.background = null; 46 | newSkin.box.normal.background = _boxBackground; 47 | newSkin.box.normal.textColor = Color.white; 48 | 49 | _winBackground = ResourceUtils.GetEmbeddedResource(lightVersion ? "guisharp-window-light.png" : "guisharp-window.png").LoadTexture(); 50 | Object.DontDestroyOnLoad(_winBackground); 51 | newSkin.window.onNormal.background = null; 52 | newSkin.window.normal.background = _winBackground; 53 | newSkin.window.padding = new RectOffset(6, 6, 22, 6); 54 | newSkin.window.border = new RectOffset(10, 10, 20, 10); 55 | newSkin.window.normal.textColor = Color.white; 56 | 57 | newSkin.button.padding = new RectOffset(4, 4, 3, 3); 58 | newSkin.button.normal.textColor = Color.white; 59 | 60 | newSkin.textField.normal.textColor = Color.white; 61 | 62 | newSkin.label.normal.textColor = Color.white; 63 | 64 | return newSkin; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Shared.AIalike/Maker/UI/MakerColor.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using CharaCustom; 3 | using KKAPI.Utilities; 4 | using UnityEngine; 5 | using Object = UnityEngine.Object; 6 | 7 | namespace KKAPI.Maker.UI 8 | { 9 | /// 10 | /// Control that allows user to change a in a separate color selector window 11 | /// 12 | public class MakerColor : BaseEditableGuiEntry 13 | { 14 | /// 15 | /// Create a new custom control. Create and register it in . 16 | /// 17 | /// Text displayed next to the control 18 | /// 19 | /// If true, the color selector will allow the user to change alpha of the color. 20 | /// If false, no color slider is shown and alpha is always 1f. 21 | /// 22 | /// Category the control will be created under 23 | /// Color set to the control when it is created 24 | /// Plugin that owns the control 25 | public MakerColor(string settingName, bool useAlpha, MakerCategory category, Color initialValue, BaseUnityPlugin owner) : base(category, initialValue, owner) 26 | { 27 | SettingName = settingName; 28 | UseAlpha = useAlpha; 29 | } 30 | 31 | /// 32 | /// Name of the setting 33 | /// 34 | public string SettingName { get; } 35 | 36 | /// 37 | /// If true, the color selector will allow the user to change alpha of the color. 38 | /// If false, no color slider is shown and alpha is always 1f. 39 | /// 40 | public bool UseAlpha { get; } 41 | 42 | /// 43 | protected internal override void Initialize() 44 | { 45 | } 46 | 47 | /// 48 | protected override GameObject OnCreateControl(Transform subCategoryList) 49 | { 50 | var tr = Object.Instantiate(GameObject.Find("SettingWindow/WinFace/F_Mole/Setting/Setting02/Scroll View/Viewport/Content/ColorSet"), subCategoryList, false); 51 | tr.name = "ColorSet"; 52 | 53 | var ccs = tr.GetComponent(); 54 | var settingName = ccs.title; 55 | settingName.text = SettingName; 56 | settingName.color = TextColor; 57 | SetTextAutosize(settingName); 58 | 59 | var button = ccs.button; 60 | button.onClick.ActuallyRemoveAllListeners(); 61 | button.targetGraphic.raycastTarget = true; 62 | 63 | ccs.image.color = Value; 64 | 65 | ccs.actUpdateColor = SetValue; 66 | 67 | return tr.gameObject; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/KKSAPI/packages.config: -------------------------------------------------------------------------------- 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 | 27 | -------------------------------------------------------------------------------- /src/Shared.CharaStudio/Studio/UI/CustomStateCategorySwitch.cs: -------------------------------------------------------------------------------- 1 | #if AI || HS2 2 | #define TMP 3 | #endif 4 | 5 | using Studio; 6 | using System; 7 | using UniRx; 8 | using UnityEngine; 9 | using UnityEngine.UI; 10 | using Object = UnityEngine.Object; 11 | #if TMP 12 | using Text = TMPro.TextMeshProUGUI; 13 | #endif 14 | 15 | namespace KKAPI.Studio.UI 16 | { 17 | /// 18 | /// Custom control that draws a single, circular button with an on/off state in the Chara > CurrentState studio menu. 19 | /// 20 | public class CurrentStateCategorySwitch : BaseCurrentStateEditableGuiEntry 21 | { 22 | private static GameObject _originalObject; 23 | #if TMP 24 | private const float LineSpacing = -20; 25 | #else 26 | private const float LineSpacing = 0.5f; 27 | #endif 28 | 29 | /// 30 | /// A single button for the Chara > CurrentState studio menu. 31 | /// 32 | /// Name of the button, shown on left 33 | /// Function called when the current character changes and the on/off state needs to be updated. 34 | /// OCIChar is the newly selected character. Return the new state. Can't be null. 35 | public CurrentStateCategorySwitch(string name, Func updateValue) : base(name, updateValue) { } 36 | 37 | /// 38 | protected override GameObject CreateItem(GameObject categoryObject) 39 | { 40 | if (_originalObject == null) 41 | _originalObject = GameObject.Find("StudioScene/Canvas Main Menu/02_Manipulate/00_Chara/01_State/Viewport/Content/Etc/Son"); 42 | 43 | var copy = Object.Instantiate(_originalObject, categoryObject.transform, true); 44 | copy.gameObject.SetActive(true); 45 | copy.transform.localScale = Vector3.one; 46 | copy.name = "CustomSwitch " + Name; 47 | 48 | var text = copy.GetComponentInChildren(true); 49 | text.lineSpacing = LineSpacing; 50 | text.gameObject.SetActive(true); 51 | text.gameObject.name = "Text " + Name; 52 | text.text = Name; 53 | 54 | var trt = text.rectTransform; 55 | trt.offsetMin = new Vector2(0, -20); 56 | trt.offsetMax = new Vector2(100, 0); 57 | 58 | var toggle = copy.GetComponentInChildren(true); 59 | toggle.gameObject.SetActive(true); 60 | toggle.gameObject.name = $"Button {Name}"; 61 | #if PH 62 | toggle.transform.localPosition = new Vector3(100, 0, 0); 63 | #endif 64 | 65 | toggle.isOn = Value.Value; 66 | 67 | toggle.onValueChanged.RemoveAllListeners(); 68 | toggle.onValueChanged.AddListener(Value.OnNext); 69 | Value.Subscribe(newSet => toggle.isOn = newSet); 70 | 71 | return copy; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/AIAPI/MainGame/GameAPI.Hooks.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using HarmonyLib; 3 | using AIProject.SaveData; 4 | using AIProject; 5 | using AIProject.Scene; 6 | 7 | namespace KKAPI.MainGame 8 | { 9 | public static partial class GameAPI 10 | { 11 | private class Hooks 12 | { 13 | private static bool _isNewGame; 14 | private static int _day = 0; 15 | 16 | public static void SetupHooks() 17 | { 18 | Harmony.CreateAndPatchAll(typeof(Hooks)); 19 | } 20 | 21 | [HarmonyPostfix] 22 | [HarmonyPatch(typeof(SaveData), nameof(SaveData.Load), typeof(string))] 23 | public static void LoadHook(string fileName) 24 | { 25 | OnGameBeingLoaded("", fileName); 26 | } 27 | 28 | [HarmonyPrefix] 29 | [HarmonyPatch(typeof(SaveData), nameof(SaveData.SaveFile), typeof(string))] 30 | public static void SaveHook(string path) 31 | { 32 | GameBeingSaved = true; 33 | OnGameBeingSaved(path, ""); 34 | } 35 | 36 | [HarmonyFinalizer] 37 | [HarmonyPatch(typeof(SaveData), nameof(SaveData.SaveFile), typeof(string))] 38 | public static void SaveHookPost() 39 | { 40 | GameBeingSaved = false; 41 | } 42 | 43 | [HarmonyPrefix] 44 | [HarmonyPatch(typeof(TitleLoadScene), "SetWorldData", typeof(WorldData), typeof(bool))] 45 | public static void TitleLoadScene_SetWorldData(WorldData _worldData, bool isAuto) 46 | { 47 | _isNewGame = _worldData?.SaveTime == new DateTime(0); 48 | } 49 | 50 | [HarmonyPostfix] 51 | [HarmonyPatch(typeof(MapScene), "OnLoaded")] 52 | public static void MapScene_OnLoaded(MapScene __instance) 53 | { 54 | if (_isNewGame) OnNewGame(); 55 | } 56 | 57 | [HarmonyPostfix] 58 | [HarmonyPatch(typeof(HScene), "SetStartVoice")] 59 | public static void HScene_SetStartVoice(HScene __instance) 60 | { 61 | OnHStart(__instance); 62 | } 63 | 64 | [HarmonyPostfix] 65 | [HarmonyPatch(typeof(HScene), "EndProc")] 66 | public static void HScene_EndProc(HScene __instance) 67 | { 68 | OnHEnd(__instance); 69 | } 70 | 71 | [HarmonyPostfix] 72 | [HarmonyPatch(typeof(EnvironmentSimulator), nameof(EnvironmentSimulator.SetTimeZone), typeof(AIProject.TimeZone))] 73 | public static void EnvironmentChangeTypeHook(AIProject.TimeZone zone) 74 | { 75 | if (zone == AIProject.TimeZone.Morning) 76 | { 77 | OnDayChange(_day); 78 | _day++; 79 | } 80 | 81 | OnPeriodChange(zone);//morning, day, evening 82 | } 83 | 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/Shared.KKalike/Shared.KKalike.projitems: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | 16441a78-1945-4d7c-b3f4-333bab848211 7 | 8 | 9 | KKAPI 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/Shared.CharaStudio/Studio/UI/CurrentStateCategorySubItemBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Studio; 3 | using UniRx; 4 | using UnityEngine; 5 | 6 | namespace KKAPI.Studio.UI 7 | { 8 | /// 9 | /// Base of custom controls created under CurrentState category 10 | /// 11 | public abstract class CurrentStateCategorySubItemBase 12 | { 13 | /// 14 | /// Create a new custom CurrentState control 15 | /// 16 | /// Name of the setting displayed on the left 17 | protected CurrentStateCategorySubItemBase(string name) 18 | { 19 | Name = name ?? throw new ArgumentNullException(nameof(name)); 20 | 21 | Visible = new BehaviorSubject(true); 22 | Visible.Subscribe( 23 | b => 24 | { 25 | if (RootGameObject != null) 26 | RootGameObject.SetActive(b); 27 | }); 28 | } 29 | 30 | /// 31 | /// Name of the setting, displayed to the left 32 | /// 33 | public string Name { get; } 34 | 35 | /// 36 | /// Fired when API wants to create the control. Should return the control's root GameObject 37 | /// 38 | /// Parent object of the control to be created 39 | protected abstract GameObject CreateItem(GameObject categoryObject); 40 | 41 | internal void CreateItemInt(GameObject categoryObject) 42 | { 43 | if (categoryObject == null) throw new ArgumentNullException(nameof(categoryObject)); 44 | if (!StudioAPI.StudioLoaded) throw new InvalidOperationException("Called before studio was loaded"); 45 | 46 | if (Created) return; 47 | 48 | var rootGameObject = CreateItem(categoryObject); 49 | if (rootGameObject == null) throw new ArgumentException("CreateItem has to return a GameObject, check its overload in " + GetType().FullName); 50 | RootGameObject = rootGameObject; 51 | 52 | rootGameObject.SetActive(Visible.Value); 53 | } 54 | 55 | /// 56 | /// Fired when currently selected character changes and the control need to be updated 57 | /// 58 | /// Newly selected character 59 | protected internal abstract void OnUpdateInfo(OCIChar ociChar); 60 | 61 | /// 62 | /// The control's root gameobject. null if the control was not created yet. 63 | /// 64 | public GameObject RootGameObject { get; private set; } 65 | 66 | /// 67 | /// The control was created and still exists. 68 | /// 69 | public bool Created => RootGameObject != null; 70 | 71 | /// 72 | /// The control is visible to the user (usually the same as it's GameObject being active). 73 | /// 74 | public BehaviorSubject Visible { get; } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Shared.AIalike/Maker/UI/MakerText.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using UnityEngine; 3 | using UnityEngine.UI; 4 | 5 | namespace KKAPI.Maker.UI 6 | { 7 | /// 8 | /// Custom control that displays a simple text 9 | /// 10 | public class MakerText : BaseGuiEntry 11 | { 12 | /// 13 | /// Light gray color best used for text explaining another setting 14 | /// 15 | public static Color ExplanationGray => new Color(0.7f, 0.7f, 0.7f); 16 | 17 | private static Transform _textCopy; 18 | 19 | private string _text; 20 | private Text _instance; 21 | 22 | /// 23 | /// Create a new custom control. Create and register it in . 24 | /// 25 | /// Displayed text 26 | /// Category the control will be created under 27 | /// Plugin that owns the control 28 | public MakerText(string text, MakerCategory category, BaseUnityPlugin owner) : base(category, owner) 29 | { 30 | Text = text; 31 | } 32 | 33 | /// 34 | /// Displayed text 35 | /// 36 | public string Text 37 | { 38 | get => _text; 39 | set 40 | { 41 | _text = value; 42 | 43 | if (_instance != null) 44 | _instance.text = value; 45 | } 46 | } 47 | 48 | private static Transform TextCopy 49 | { 50 | get 51 | { 52 | if (_textCopy == null) 53 | MakeCopy(); 54 | return _textCopy; 55 | } 56 | } 57 | 58 | private static void MakeCopy() 59 | { 60 | _textCopy = Object.Instantiate(GameObject.Find("SettingWindow/WinFace/F_FaceType/Setting/Setting01/title"), GuiCacheTransfrom).transform; 61 | _textCopy.gameObject.SetActive(false); 62 | _textCopy.name = "txtCustom"; 63 | 64 | _textCopy.gameObject.AddComponent().minHeight = 40; 65 | 66 | var textCmp = _textCopy.GetComponentInChildren(); 67 | textCmp.lineSpacing = 0.75f; 68 | textCmp.fontSize = 24; 69 | SetTextAutosize(textCmp); 70 | 71 | RemoveLocalisation(_textCopy.gameObject); 72 | } 73 | 74 | /// 75 | protected internal override void Initialize() 76 | { 77 | if (_textCopy == null) 78 | MakeCopy(); 79 | } 80 | 81 | /// 82 | protected override GameObject OnCreateControl(Transform subCategoryList) 83 | { 84 | var tr = Object.Instantiate(TextCopy, subCategoryList, false); 85 | 86 | _instance = tr.GetComponentInChildren(); 87 | _instance.text = Text; 88 | _instance.color = TextColor; 89 | 90 | return tr.gameObject; 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/PHAPI/Chara/CharacterApi.ControllerRegistration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | #if KK || EC 5 | using UniRx; 6 | #elif AI 7 | using AIChara; 8 | #endif 9 | 10 | namespace KKAPI.Chara 11 | { 12 | public static partial class CharacterApi 13 | { 14 | /// 15 | /// Information about a single kind of a . New kind is created every time 16 | /// you call . 17 | /// 18 | public sealed class ControllerRegistration 19 | { 20 | private readonly List _instances = new List(); 21 | 22 | /// 23 | /// All currently existing instances of this kind of controller. 24 | /// 25 | public IEnumerable Instances => _instances.Where(x => x != null); 26 | 27 | /// 28 | /// Type of the custom controller kind. 29 | /// 30 | public Type ControllerType { get; } 31 | 32 | /// 33 | /// ID of the extended data used by this controller kind. 34 | /// 35 | public string ExtendedDataId { get; } 36 | 37 | /// 38 | /// Method used to copy extended data used by this controller in case that's necessary. 39 | /// 40 | public CopyExtendedDataFunc ExtendedDataCopier { get; } 41 | 42 | /// 43 | /// If true, the current state of all controllers of this kind should be preserved inside . 44 | /// New extended data will not be read, instead currently data will be reused, or the reload will not happen at all. 45 | /// 46 | public bool MaintainState { get; set; } 47 | 48 | /// 49 | /// If true, the current state of all controllers of this kind should be preserved inside . 50 | /// New extended data will not be read, instead currently data will be reused, or the load will not happen at all. 51 | /// 52 | public bool MaintainCoordinateState { get; set; } 53 | 54 | internal ControllerRegistration(Type controllerType, string extendedDataId, CopyExtendedDataFunc extendedDataCopier) 55 | { 56 | ControllerType = controllerType; 57 | ExtendedDataId = extendedDataId; 58 | ExtendedDataCopier = extendedDataCopier; 59 | } 60 | 61 | internal void CreateInstance(Human target) 62 | { 63 | var newBehaviour = (CharaCustomFunctionController) target.gameObject.AddComponent(ControllerType); 64 | newBehaviour.ControllerRegistration = this; 65 | 66 | _instances.Add(newBehaviour); 67 | _instances.RemoveAll(x => x == null); 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/PHAPI/Maker/UI/MakerSlider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BepInEx; 3 | using HarmonyLib; 4 | using UniRx; 5 | using UnityEngine; 6 | using UnityEngine.UI; 7 | 8 | namespace KKAPI.Maker.UI 9 | { 10 | /// 11 | /// Custom control that draws a slider and a text box (both are used to edit the same value) 12 | /// 13 | public class MakerSlider : BaseEditableGuiEntry 14 | { 15 | private readonly string _settingName; 16 | 17 | private readonly float _maxValue; 18 | private readonly float _minValue; 19 | private readonly float _defaultValue; 20 | 21 | /// 22 | /// Create a new custom control. Create and register it in . 23 | /// 24 | /// Text displayed next to the slider 25 | /// Category the control will be created under 26 | /// Plugin that owns the control 27 | /// Lowest allowed value (inclusive) 28 | /// Highest allowed value (inclusive) 29 | /// Value the slider will be set to after creation 30 | public MakerSlider(MakerCategory category, string settingName, float minValue, float maxValue, float defaultValue, BaseUnityPlugin owner) : base(category, defaultValue, owner) 31 | { 32 | _settingName = settingName; 33 | 34 | _minValue = minValue; 35 | _maxValue = maxValue; 36 | _defaultValue = defaultValue; 37 | } 38 | 39 | /// 40 | /// Custom converter from text in the textbox to the slider value. 41 | /// If not set, float.Parse(txt) / 100f is used. 42 | /// 43 | [Obsolete] 44 | public Func StringToValue { get; set; } 45 | 46 | /// 47 | /// Custom converter from the slider value to what's displayed in the textbox. 48 | /// If not set, Mathf.RoundToInt(f * 100).ToString() is used. 49 | /// 50 | [Obsolete] 51 | public Func ValueToString { get; set; } 52 | 53 | /// 54 | /// Custom converter from the slider value to what's displayed in the textbox. 55 | /// By default it's set to 0.00 56 | /// 57 | public string TextFormat { get; set; } = "0.00"; 58 | 59 | /// 60 | protected internal override void Initialize() 61 | { 62 | } 63 | 64 | /// 65 | protected override GameObject OnCreateControl(Transform subCategoryList) 66 | { 67 | var sliderUi = MakerAPI.GetMakerBase().CreateInputSliderUI(subCategoryList.gameObject, _settingName, _minValue, _maxValue, true, _defaultValue, SetValue); 68 | BufferedValueChanged.Subscribe(sliderUi.SetValue); 69 | var text = sliderUi.title; 70 | text.color = TextColor; 71 | SetTextAutosize(text); 72 | sliderUi.textFormat = TextFormat; 73 | return sliderUi.gameObject; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Shared.Core/Chara/CharacterApi.ControllerRegistration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | #if KK || KKS || EC 5 | using UniRx; 6 | #elif AI || HS2 7 | using AIChara; 8 | #endif 9 | 10 | namespace KKAPI.Chara 11 | { 12 | public static partial class CharacterApi 13 | { 14 | /// 15 | /// Information about a single kind of a . New kind is created every time 16 | /// you call . 17 | /// 18 | public sealed class ControllerRegistration 19 | { 20 | private readonly List _instances = new List(); 21 | 22 | /// 23 | /// All currently existing instances of this kind of controller. 24 | /// 25 | public IEnumerable Instances => _instances.Where(x => x != null); 26 | 27 | /// 28 | /// Type of the custom controller kind. 29 | /// 30 | public Type ControllerType { get; } 31 | 32 | /// 33 | /// ID of the extended data used by this controller kind. 34 | /// 35 | public string ExtendedDataId { get; } 36 | 37 | /// 38 | /// Method used to copy extended data used by this controller in case that's necessary. 39 | /// 40 | public CopyExtendedDataFunc ExtendedDataCopier { get; } 41 | 42 | /// 43 | /// If true, the current state of all controllers of this kind should be preserved inside . 44 | /// New extended data will not be read, instead currently data will be reused, or the reload will not happen at all. 45 | /// 46 | public bool MaintainState { get; set; } 47 | 48 | /// 49 | /// If true, the current state of all controllers of this kind should be preserved inside . 50 | /// New extended data will not be read, instead currently data will be reused, or the load will not happen at all. 51 | /// 52 | public bool MaintainCoordinateState { get; set; } 53 | 54 | internal ControllerRegistration(Type controllerType, string extendedDataId, CopyExtendedDataFunc extendedDataCopier) 55 | { 56 | ControllerType = controllerType; 57 | ExtendedDataId = extendedDataId; 58 | ExtendedDataCopier = extendedDataCopier; 59 | } 60 | 61 | internal void CreateInstance(ChaControl target) 62 | { 63 | var newBehaviour = (CharaCustomFunctionController) target.gameObject.AddComponent(ControllerType); 64 | newBehaviour.ControllerRegistration = this; 65 | 66 | _instances.Add(newBehaviour); 67 | _instances.RemoveAll(x => x == null); 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/Shared.KKalike/Maker/UI/MakerText.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using TMPro; 3 | using UnityEngine; 4 | using UnityEngine.UI; 5 | 6 | namespace KKAPI.Maker.UI 7 | { 8 | /// 9 | /// Custom control that displays a simple text 10 | /// 11 | public class MakerText : BaseGuiEntry 12 | { 13 | /// 14 | /// Light gray color best used for text explaining another setting 15 | /// 16 | public static Color ExplanationGray => new Color(0.7f, 0.7f, 0.7f); 17 | 18 | private static Transform _textCopy; 19 | 20 | private string _text; 21 | private TextMeshProUGUI _instance; 22 | 23 | /// 24 | /// Create a new custom control. Create and register it in . 25 | /// 26 | /// Displayed text 27 | /// Category the control will be created under 28 | /// Plugin that owns the control 29 | public MakerText(string text, MakerCategory category, BaseUnityPlugin owner) : base(category, owner) 30 | { 31 | Text = text; 32 | } 33 | 34 | /// 35 | /// Displayed text 36 | /// 37 | public string Text 38 | { 39 | get => _text; 40 | set 41 | { 42 | _text = value; 43 | 44 | if (_instance != null) 45 | _instance.text = value; 46 | } 47 | } 48 | 49 | private static Transform TextCopy 50 | { 51 | get 52 | { 53 | if (_textCopy == null) 54 | MakeCopy(); 55 | return _textCopy; 56 | } 57 | } 58 | 59 | private static void MakeCopy() 60 | { 61 | #if KKS 62 | var original = GetExistingControl("CustomScene/CustomRoot/FrontUIGroup/CustomUIGroup/CvsMenuTree/06_SystemTop/tglVisualSettings", "txtExplanation"); 63 | #else 64 | var original = GetExistingControl("CustomScene/CustomRoot/FrontUIGroup/CustomUIGroup/CvsMenuTree/06_SystemTop/tglConfig", "txtExplanation"); 65 | #endif 66 | 67 | _textCopy = Object.Instantiate(original, GuiCacheTransfrom, false); 68 | _textCopy.gameObject.SetActive(false); 69 | _textCopy.name = "txtCustom"; 70 | 71 | RemoveLocalisation(_textCopy.gameObject); 72 | } 73 | 74 | /// 75 | protected internal override void Initialize() 76 | { 77 | if (_textCopy == null) 78 | MakeCopy(); 79 | } 80 | 81 | /// 82 | protected override GameObject OnCreateControl(Transform subCategoryList) 83 | { 84 | var tr = Object.Instantiate(TextCopy, subCategoryList, false); 85 | 86 | _instance = tr.GetComponentInChildren(); 87 | _instance.text = Text; 88 | _instance.color = TextColor; 89 | 90 | var layout = tr.GetComponent(); 91 | layout.flexibleWidth = 1; 92 | 93 | return tr.gameObject; 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/Shared.AIalike/Maker/UI/MakerButton.cs: -------------------------------------------------------------------------------- 1 | using BepInEx; 2 | using UnityEngine; 3 | using UnityEngine.UI; 4 | 5 | namespace KKAPI.Maker.UI 6 | { 7 | /// 8 | /// Custom control that draws a simple blue button. 9 | /// 10 | public class MakerButton : BaseGuiEntry 11 | { 12 | private static Transform _buttonCopy; 13 | 14 | /// 15 | /// Create a new custom control. Create and register it in . 16 | /// 17 | /// Text displayed on the button 18 | /// Category the control will be created under 19 | /// Plugin that owns the control 20 | public MakerButton(string text, MakerCategory category, BaseUnityPlugin owner) : base(category, owner) 21 | { 22 | Text = text; 23 | OnClick = new Button.ButtonClickedEvent(); 24 | 25 | TextColor = new Color(0.090f, 0.118f, 0.141f); 26 | } 27 | 28 | /// 29 | /// Fired when user clicks on the button 30 | /// 31 | public Button.ButtonClickedEvent OnClick { get; } 32 | 33 | /// 34 | /// Text displayed on the button 35 | /// 36 | public string Text { get; } 37 | 38 | private static Transform ButtonCopy 39 | { 40 | get 41 | { 42 | if (_buttonCopy == null) 43 | MakeCopy(); 44 | return _buttonCopy; 45 | } 46 | } 47 | 48 | private static void MakeCopy() 49 | { 50 | var original = GameObject.Find("DefaultColor").transform; 51 | 52 | _buttonCopy = Object.Instantiate(original, GuiCacheTransfrom, false); 53 | _buttonCopy.gameObject.SetActive(false); 54 | _buttonCopy.name = "btnCustom"; 55 | 56 | var button = _buttonCopy.GetComponentInChildren