private void Awake() { CharacterApi.RegisterExtraBehaviour <InvisibleBodyCharaController>("KK_InvisibleBody"); MakerAPI.RegisterCustomSubCategories += MakerAPI_RegisterCustomSubCategories; }
private static CharacterApi.ControllerRegistration GetControllerRegistration() { return(CharacterApi.GetRegisteredBehaviour(KoiClothesOverlayMgr.GUID)); }
internal void Main() { CharacterApi.RegisterExtraBehaviour <BetterPenetrationController>(BEHAVIOR); harmony = new Harmony("KK_Studio_BetterPenetration"); harmony.PatchAll(typeof(KK_Studio_BetterPenetration)); Chainloader.PluginInfos.TryGetValue("com.deathweasel.bepinex.uncensorselector", out PluginInfo pluginInfo); if (pluginInfo == null || pluginInfo.Instance == null) { return; } Type nestedType = pluginInfo.Instance.GetType().GetNestedType("UncensorSelectorController", AccessTools.all); if (nestedType == null) { return; } MethodInfo methodInfo = AccessTools.Method(nestedType, "ReloadCharacterPenis", null, null); if (methodInfo == null) { return; } harmony.Patch(methodInfo, prefix: new HarmonyMethod(typeof(KK_Studio_BetterPenetration), "BeforeDanCharacterReload"), postfix: new HarmonyMethod(typeof(KK_Studio_BetterPenetration), "AfterDanCharacterReload")); Debug.Log("Studio_BetterPenetration: patched UncensorSelectorController::ReloadCharacterPenis correctly"); methodInfo = AccessTools.Method(nestedType, "ReloadCharacterBalls", null, null); if (methodInfo == null) { return; } harmony.Patch(methodInfo, prefix: new HarmonyMethod(typeof(KK_Studio_BetterPenetration), "BeforeTamaCharacterReload"), postfix: new HarmonyMethod(typeof(KK_Studio_BetterPenetration), "AfterTamaCharacterReload")); Debug.Log("Studio_BetterPenetration: patched UncensorSelectorController::ReloadCharacterBalls correctly"); Chainloader.PluginInfos.TryGetValue("com.joan6694.illusionplugins.nodesconstraints", out pluginInfo); if (pluginInfo == null || pluginInfo.Instance == null) { return; } nodeConstraintPlugin = pluginInfo.Instance; Type nodeConstraintType = nodeConstraintPlugin.GetType(); if (nodeConstraintType == null) { return; } methodInfo = AccessTools.Method(nodeConstraintType, "AddConstraint", null, null); if (methodInfo == null) { return; } harmony.Patch(methodInfo, postfix: new HarmonyMethod(typeof(KK_Studio_BetterPenetration), "AfterAddConstraint")); Debug.Log("Studio_BetterPenetration: patched NodeConstraints::AddConstraint correctly"); methodInfo = AccessTools.Method(nodeConstraintType, "ApplyNodesConstraints", null, null); if (methodInfo == null) { return; } harmony.Patch(methodInfo, postfix: new HarmonyMethod(typeof(KK_Studio_BetterPenetration), "AfterApplyNodesConstraints")); Debug.Log("Studio_BetterPenetration: patched NodeConstraints::ApplyNodesConstraints correctly"); methodInfo = AccessTools.Method(nodeConstraintType, "ApplyConstraints", null, null); if (methodInfo == null) { return; } harmony.Patch(methodInfo, postfix: new HarmonyMethod(typeof(KK_Studio_BetterPenetration), "AfterApplyConstraints")); Debug.Log("Studio_BetterPenetration: patched NodeConstraints::ApplyConstraints correctly"); }
public void Awake() { WindowIDSleep = Config.Bind(SECTION_GENERAL, "__Window ID (Sleep Hours)", 83464); WindowIDDead = Config.Bind(SECTION_GENERAL, "__Window ID (Dead)", 83465); StatusKey = Config.Bind(SECTION_SURVIVAL, "Status UI Key", new KeyboardShortcut(KeyCode.T)); (PlayerStats = Config.Bind(SECTION_SURVIVAL, "Player Life Stats", true, DESCRIPTION_PLAYER_LIFE)).SettingChanged += (s, e) => { playerController.statusHUD.SetVisible(Status.visibileHUD, PlayerDeath.Value != DeathType.None, PlayerStats.Value); Status.UpdateCellPhoneVisibility(PlayerDeath.Value != DeathType.None, PlayerStats.Value, AgentDeath.Value != DeathType.None); }; (PlayerDeath = Config.Bind(SECTION_SURVIVAL, "Player Death", DeathType.Incapacitated, DESCRIPTION_PLAYER_DEATH)).SettingChanged += (s, e) => { playerController.statusHUD.SetVisible(Status.visibileHUD, PlayerDeath.Value != DeathType.None, PlayerStats.Value); Status.UpdateCellPhoneVisibility(PlayerDeath.Value != DeathType.None, PlayerStats.Value, AgentDeath.Value != DeathType.None); }; (AgentDeath = Config.Bind(SECTION_SURVIVAL, "Agent Death", DeathType.Incapacitated, DESCRIPTION_AGENT_DEATH)).SettingChanged += (s, e) => { foreach (var controller in agentControllers.Where(n => n != null)) { controller.statusHUD.SetVisible(Status.visibileHUD, AgentDeath.Value != DeathType.None, AgentDeath.Value != DeathType.None); } Status.UpdateCellPhoneVisibility(PlayerDeath.Value != DeathType.None, PlayerStats.Value, AgentDeath.Value != DeathType.None); }; SleepAnytime = Config.Bind(SECTION_SLEEP, "Sleep Anytime", true); SetHoursAsleep = Config.Bind(SECTION_SLEEP, "Set Hours Asleep", true, DESCRIPTION_SET_HOURS_ASLEEP); WakeHour = Config.Bind(SECTION_SLEEP, "Wake Up Hour", 8, new ConfigDescription(DESCRIPTION_WAKE_HOUR, new AcceptableValueRange <int>(0, 23))); AgentHealthLoss = Config.Bind(SECTION_LOSS, "Agent Health Loss - Collapsed", 2f, new ConfigDescription(DESCRIPTION_AGENT_HEALTH_LOSS, new AcceptableValueRange <float>(0, 100))); AgentHealthLossCold = Config.Bind(SECTION_LOSS, "Agent Health Loss - Cold", 1f, new ConfigDescription(DESCRIPTION_AGENT_HEALTH_LOSS_COLD, new AcceptableValueRange <float>(0, 100))); AgentHealthLossHeat = Config.Bind(SECTION_LOSS, "Agent Health Loss - Heatstroke", 4f, new ConfigDescription(DESCRIPTION_AGENT_HEALTH_LOSS_HEAT, new AcceptableValueRange <float>(0, 100))); AgentHealthLossHurt = Config.Bind(SECTION_LOSS, "Agent Health Loss - Hurt", 6f, new ConfigDescription(DESCRIPTION_AGENT_HEALTH_LOSS_HURT, new AcceptableValueRange <float>(0, 100))); AgentHealthLossHunger = Config.Bind(SECTION_LOSS, "Agent Health Loss - Hunger", 2f, new ConfigDescription(DESCRIPTION_AGENT_HEALTH_LOSS_HUNGER, new AcceptableValueRange <float>(0, 100))); AgentHealthLossThirst = Config.Bind(SECTION_LOSS, "Agent Health Loss - Thirst", 2f, new ConfigDescription(DESCRIPTION_AGENT_HEALTH_LOSS_THIRST, new AcceptableValueRange <float>(0, 100))); AgentFoodLossStomachache = Config.Bind(SECTION_LOSS, "Agent Food Loss - Stomachache", 2f, new ConfigDescription(DESCRIPTION_AGENT_FOOD_LOSS_STOMACHACHE, new AcceptableValueRange <float>(0, 100))); AgentStaminaLossOverwork = Config.Bind(SECTION_LOSS, "Agent Stamina Loss - Overwork", 4f, new ConfigDescription(DESCRIPTION_AGENT_STAMINA_LOSS_OVERWORK, new AcceptableValueRange <float>(0, 100))); HealthLoss = Config.Bind(SECTION_LOSS, "Player Health Loss", 2.5f, new ConfigDescription(DESCRIPTION_HEALTH_LOSS, new AcceptableValueRange <float>(0, 100))); StaminaLoss = Config.Bind(SECTION_LOSS, "Player Stamina Loss", 4f, new ConfigDescription(DESCRIPTION_STAMINA_LOSS, new AcceptableValueRange <float>(0, 100))); CaloriePool = Config.Bind(SECTION_LOSS, "Player Calorie Pool", 7500f, new ConfigDescription(DESCRIPTION_CALORIE_POOL, new AcceptableValueRange <float>(2500, 25000))); CalorieLoss = Config.Bind(SECTION_LOSS, "Player Calorie Loss Per Day", 2500f, new ConfigDescription(DESCRIPTION_CALORIE_LOSS, new AcceptableValueRange <float>(0, 10000))); WaterPool = Config.Bind(SECTION_LOSS, "Player Water Pool", 4000f, new ConfigDescription(DESCRIPTION_WATER_POOL, new AcceptableValueRange <float>(2000, 20000))); WaterLoss = Config.Bind(SECTION_LOSS, "Player Water Loss Per Day", 2000f, new ConfigDescription(DESCRIPTION_WATER_LOSS, new AcceptableValueRange <float>(0, 8000))); AgentHealthRate = Config.Bind(SECTION_RECOVER, "Agent Health Recovery (per Game-Hour)", 1f, new ConfigDescription(DESCRIPTION_AGENT_HEALTH_RATE, new AcceptableValueRange <float>(0, 100))); HealthRate = Config.Bind(SECTION_RECOVER, "Player Health Recovery (per Game-Hour)", 1f, new ConfigDescription(DESCRIPTION_HEALTH_RATE, new AcceptableValueRange <float>(0, 100))); StaminaRate = Config.Bind(SECTION_RECOVER, "Player Stamina Recovery (per Game-Hour)", 10f, new ConfigDescription(DESCRIPTION_STAMINA_RATE, new AcceptableValueRange <float>(0, 100))); CalorieEfficiency = Config.Bind(SECTION_RECOVER, "Restore Food Efficiency", 100f, new ConfigDescription(DESCRIPTION_FOOD_EFFICIENCY, new AcceptableValueRange <float>(0, 500))); WaterEfficiency = Config.Bind(SECTION_RECOVER, "Restore Water Efficiency", 100f, new ConfigDescription(DESCRIPTION_WATER_EFFICIENCY, new AcceptableValueRange <float>(0, 500))); AgentLowFood = Config.Bind(SECTION_PENALTY, "Agent Low Food Threshold", 0f, new ConfigDescription(DESCRIPTION_AGENT_LOW_FOOD, new AcceptableValueRange <float>(0, 100))); AgentLowWater = Config.Bind(SECTION_PENALTY, "Agent Low Water Threshold", 0f, new ConfigDescription(DESCRIPTION_AGENT_LOW_WATER, new AcceptableValueRange <float>(0, 100))); LowFood = Config.Bind(SECTION_PENALTY, "Player Low Food Threshold", 0f, new ConfigDescription(DESCRIPTION_LOW_FOOD, new AcceptableValueRange <float>(0, 100))); LowWater = Config.Bind(SECTION_PENALTY, "Player Low Water Threshold", 0f, new ConfigDescription(DESCRIPTION_LOW_WATER, new AcceptableValueRange <float>(0, 100))); LowStamina = Config.Bind(SECTION_PENALTY, "Player Low Stamina Threshold", 0f, new ConfigDescription(DESCRIPTION_LOW_STAMINA, new AcceptableValueRange <float>(0, 100))); AgentRevivePenalty = Config.Bind(SECTION_PENALTY, "Agent Revive Penalty", RevivePenalty.StatLoss, DESCRIPTION_AGENT_REVIVE_PENALTY); PlayerDeathReset = Config.Bind(SECTION_PENALTY, "Player Death Agent Reset", true, DESCRIPTION_PLAYER_DEATH_RESET); HealthWarn = Config.Bind(SECTION_WARN, "Health Warning", 30, new ConfigDescription(DESCRIPTION_HEALTH_WARN, new AcceptableValueRange <int>(0, 100))); AgentWarn = Config.Bind(SECTION_WARN, "Agent Health Warning", 30, new ConfigDescription(DESCRIPTION_AGENT_WARN, new AcceptableValueRange <int>(0, 100))); FoodWarn = Config.Bind(SECTION_WARN, "Food Warning", 20, new ConfigDescription(DESCRIPTION_FOOD_WARN, new AcceptableValueRange <int>(0, 100))); WaterWarn = Config.Bind(SECTION_WARN, "Water Warning", 20, new ConfigDescription(DESCRIPTION_WATER_WARN, new AcceptableValueRange <int>(0, 100))); StaminaWarn = Config.Bind(SECTION_WARN, "Stamina Warning", 20, new ConfigDescription(DESCRIPTION_STAMINA_WARN, new AcceptableValueRange <int>(0, 100))); CharacterApi.RegisterExtraBehaviour <LifeStatsController>(BEHAVIOR); HarmonyLib.Harmony.CreateAndPatchAll(typeof(HardcoreMode)); }
private void Main() { AnimationControllerHotkey = new SavedKeyboardShortcut(nameof(AnimationControllerHotkey), nameof(KK_AnimationController), new KeyboardShortcut(KeyCode.Minus)); CharacterApi.RegisterExtraBehaviour <AnimationControllerCharaController>(GUID); StudioSaveLoadApi.RegisterExtraBehaviour <AnimationControllerSceneController>(GUID); }
internal void Start() { Logger = base.Logger; ConfigEnablePushup = Config.Bind("Config", "Enable Pushup By Default", false, new ConfigDescription("Whether the pushup effect is enabled by default when a bra is worn.", null, new ConfigurationManagerAttributes { Order = 10 })); ConfigFirmnessDefault = Config.Bind("Config", "Firmness Default Value", 0.9f, new ConfigDescription("Firmness of the breasts. More firm means less bounce.", new AcceptableValueRange <float>(0f, 1f), new ConfigurationManagerAttributes { Order = 9 })); ConfigLiftDefault = Config.Bind("Config", "Lift Default Value", 0.6f, new ConfigDescription("Lift of the breasts. Lift is the minimum height position of the breasts when a bra is worn.", new AcceptableValueRange <float>(0f, 1f), new ConfigurationManagerAttributes { Order = 8 })); ConfigPushTogetherDefault = Config.Bind("Config", "Push Together Default Value", 0.55f, new ConfigDescription("How much the breasts will be pushed together when a bra is worn, if they are set far apart.", new AcceptableValueRange <float>(0f, 1f), new ConfigurationManagerAttributes { Order = 7 })); ConfigSqueezeDefault = Config.Bind("Config", "Squeeze Default Value", 0.6f, new ConfigDescription("Long breasts will be flattened by this amount.", new AcceptableValueRange <float>(0f, 1f), new ConfigurationManagerAttributes { Order = 6 })); ConfigNippleCenteringDefault = Config.Bind("Config", "Nipple Centering Default Value", 0.5f, new ConfigDescription("If the nipples point up or down, wearing a bra will make them point forwards.", new AcceptableValueRange <float>(0f, 1f), new ConfigurationManagerAttributes { Order = 5 })); ConfigFlattenNipplesDefault = Config.Bind("Config", "Flatten Nipples Default", true, new ConfigDescription("Flatten nipples while a bra is worn.", null, new ConfigurationManagerAttributes { Order = 4 })); ConfigSliderMin = Config.Bind("Config", "Advanced Mode Slider Minimum", -100, new ConfigDescription("Minimum value of advanced mode sliders.", new AcceptableValueRange <int>(-500, 0), new ConfigurationManagerAttributes { Order = 3 })); ConfigSliderMax = Config.Bind("Config", "Advanced Mode Slider Maximum", 200, new ConfigDescription("Maximum value of advanced mode sliders.", new AcceptableValueRange <int>(100, 500), new ConfigurationManagerAttributes { Order = 2 })); CharacterApi.RegisterExtraBehaviour <PushupController>(GUID); MakerAPI.RegisterCustomSubCategories += RegisterCustomSubCategories; MakerAPI.ReloadCustomInterface += ReloadCustomInterface; MakerAPI.MakerExiting += MakerExiting; MakerAPI.MakerFinishedLoading += MakerFinishedLoading; RegisterStudioControls(); var harmony = HarmonyWrapper.PatchAll(typeof(Hooks)); //Patch all the slider onValueChanged events to return false and cancel original code //Pushup adds its own onValueChanged event that manages this stuff foreach (var anonType in typeof(ChaCustom.CvsBreast).GetNestedTypes(AccessTools.all).Where(x => x.Name.Contains("<Start>"))) { foreach (var anonTypeMethod in anonType.GetMethods(AccessTools.all).Where(x => x.Name.Contains("<>m"))) { if (anonTypeMethod.GetParameters().Any(x => x.ParameterType == typeof(float))) { harmony.Patch(anonTypeMethod, new HarmonyMethod(typeof(Hooks).GetMethod(nameof(Hooks.SliderHook), AccessTools.all))); } } } var sliders = typeof(ChaCustom.CvsBreast).GetMethods(AccessTools.all).Where(x => x.Name.Contains("<Start>") && x.GetParameters().Any(y => y.ParameterType == typeof(float))).ToList(); //Don't patch areola size or nipple gloss since they are not managed by this plugin foreach (var slider in sliders) { if (Application.productName == Constants.MainGameProcessName) { if (slider.Name == "<Start>m__E") { } //areola size else if (slider.Name == "<Start>m__14") { } //nipple gloss else { harmony.Patch(slider, new HarmonyMethod(typeof(Hooks).GetMethod(nameof(Hooks.SliderHook), AccessTools.all))); } } else if (Application.productName == Constants.MainGameProcessNameSteam) { if (slider.Name == "<Start>m__10") { } //areola size else if (slider.Name == "<Start>m__17") { } //nipple gloss else { harmony.Patch(slider, new HarmonyMethod(typeof(Hooks).GetMethod(nameof(Hooks.SliderHook), AccessTools.all))); } } } }
internal void Main() { CharacterApi.RegisterExtraBehaviour <ProfileController>(PluginNameInternal); MakerAPI.RegisterCustomSubCategories += MakerAPI_RegisterCustomSubCategories; MakerAPI.MakerFinishedLoading += MakerAPI_MakerFinishedLoading; }
private void Start() { Logger = base.Logger; #if KK PregnancyProgressionSpeed = Config.Bind("General", "Pregnancy progression speed", 4, new ConfigDescription("How much faster does the in-game pregnancy progresses than the standard 40 weeks. " + "It also reduces the time characters leave school for after birth.\n\n" + "x1 is 40 weeks, x2 is 20 weeks, x4 is 10 weeks, x10 is 4 weeks.", new AcceptableValueList <int>(1, 2, 4, 10))); #elif AI PregnancyProgressionSpeed = Config.Bind("General", "Pregnancy progression speed", 4, new ConfigDescription("How much faster does the in-game pregnancy progresses than the standard 4 weeks. \n\n" + "x1 is 4 weeks, x2 is 2 weeks, x4 is 1 week, x10 is ~4 days.", new AcceptableValueList <int>(1, 2, 4, 10))); #endif ConceptionEnabled = Config.Bind("General", "Enable conception", true, "Allows characters to get pregnant from vaginal sex. Doesn't affect already pregnant characters."); FertilityOverride = Config.Bind("General", "Minimum fertility level", 0f, new ConfigDescription("If a character has a lower fertility level than this set, this level will be used instead. \n\n" + "0 - The value saved in the character card is used (30% by default)\n" + "30%, 50%, 75%, 100% - If the character card's saved value is lower, it will be raised to this level in HScenes.", new AcceptableValueList <float>(0f, 0.3f, 0.5f, 0.75f, 1f))); AnalConceptionEnabled = Config.Bind("General", "Enable anal conception", false, "Allows characters to get pregnant from anal sex. Doesn't affect already pregnant characters."); ShowPregnancyIconEarly = Config.Bind("General", "Show pregnancy icon early", false, "By default pregnancy status icon in class roster is shown after a few days or weeks (the character had a chance to do the test or noticed something is wrong).\n" + "Turning this on will always make the icon show up at the end of the current day."); HSceneMenstrIconOverride = Config.Bind("General", "Use custom safe/risky icons in H Scenes", true, "Replaces the standard safe/risky indicators with custom indicators that can also show pregnancy and unknown status. " + "If the status is unknown you will have to listen for the voice cues instead.\nChanges take effect after game restart."); InflationEnable = Config.Bind("Inflation", "Enable inflation", true, "Turn on the inflation effect."); InflationSpeed = Config.Bind("Inflation", "Inflation speed modifier", 1, new ConfigDescription("How quickly the belly will inflate/deflate compared to normal (1x, 2x, 3x as fast).", new AcceptableValueList <int>(1, 2, 3))); InflationOpenClothAtMax = Config.Bind("Inflation", "Open clothes at max inflation", true, "If clothes are fully on, open them when inflation reaches the max value (they 'burst' open)."); InflationMaxCount = Config.Bind("Inflation", "Cum count until full", 8, new ConfigDescription("How many times you have to let out inside to reach the maximum belly size.", new AcceptableValueRange <int>(2, 15))); #if KK LactationEnabled = Config.Bind("Lactation", "Enable lactation", true, "Enable the lactation effect. For the effect to work the character has to be pregnant, or the override setting has to be enabled."); LactationFillTime = Config.Bind("Lactation", "Time to fully refill", 5, new ConfigDescription("How many minutes it takes to fully refill the milk. 0 is always fully refilled.", new AcceptableValueRange <int>(0, 10))); LactationForceMaxCapacity = Config.Bind("Lactation", "Force max milk capacity", false, "If enabled, all characters will lactate and have full capacity. If off, capacity depends on the pregnancy progress."); #endif CharacterApi.RegisterExtraBehaviour <PregnancyCharaController>(GUID); GameAPI.RegisterExtraBehaviour <PregnancyGameController>(GUID); var hi = new Harmony(GUID); Hooks.InitHooks(hi); PregnancyGui.Init(hi, this); }
private void Awake() { CharacterApi.RegisterExtraBehaviour <KoiClothesOverlayController>(GUID); KoiClothesOverlayController.Hooks.Init(GUID); }
void Awake() { instance = this; }
private void Awake() { CharacterApi.RegisterExtraBehaviour <CharaController>(GUID); StudioSaveLoadApi.RegisterExtraBehaviour <SceneController>(GUID); SceneManager.sceneLoaded += OnSceneLoaded; }
private void Start() { CharacterApi.RegisterExtraBehaviour <MaterialRouterController>(GUID); HooksInstance = Harmony.CreateAndPatchAll(typeof(Hooks)); BepInEx.Bootstrap.Chainloader.PluginInfos.TryGetValue("com.deathweasel.bepinex.materialeditor", out PluginInfo PluginInfo); Type MaterialEditorCharaController = PluginInfo.Instance.GetType().Assembly.GetType("KK_Plugins.MaterialEditor.MaterialEditorCharaController"); HooksInstance.Patch(MaterialEditorCharaController.GetMethod("OnReload", AccessTools.all, null, new[] { typeof(GameMode), typeof(bool) }, null), prefix: new HarmonyMethod(typeof(Hooks), nameof(Hooks.MaterialEditorCharaController_OnReload_Prefix))); HooksInstance.Patch(MaterialEditorCharaController.GetMethod("OnCoordinateBeingLoaded", AccessTools.all, null, new[] { typeof(ChaFileCoordinate), typeof(bool) }, null), prefix: new HarmonyMethod(typeof(Hooks), nameof(Hooks.MaterialEditorCharaController_OnCoordinateBeingLoaded_Prefix))); HooksInstance.Patch(MaterialEditorCharaController.GetMethod("CorrectTongue", AccessTools.all, null, new Type[0], null), prefix: new HarmonyMethod(typeof(Hooks), nameof(Hooks.MaterialEditorCharaController_CorrectTongue_Prefix))); Type MaterialEditorMaterialAPI = PluginInfo.Instance.GetType().Assembly.GetType("MaterialEditorAPI.MaterialAPI"); if (MaterialEditorMaterialAPI.GetMethods().Single(x => x.Name == "SetTexture").GetParameters().ElementAtOrDefault(3)?.ParameterType == typeof(Texture)) { HooksInstance.Patch(MaterialEditorMaterialAPI.GetMethod("SetTexture", AccessTools.all, null, new[] { typeof(GameObject), typeof(string), typeof(string), typeof(Texture) }, null), prefix: new HarmonyMethod(typeof(Hooks), nameof(Hooks.MaterialAPI_SetTexture_Prefix))); } else { HooksInstance.Patch(MaterialEditorMaterialAPI.GetMethod("SetTexture", AccessTools.all, null, new[] { typeof(GameObject), typeof(string), typeof(string), typeof(Texture2D) }, null), prefix: new HarmonyMethod(typeof(Hooks), nameof(Hooks.MaterialAPI_SetTexture_Prefix))); } MakerAPI.MakerBaseLoaded += (object sender, RegisterCustomControlsEvent ev) => { HooksMakerInstance = Harmony.CreateAndPatchAll(typeof(HooksMaker)); }; MakerAPI.MakerFinishedLoading += (object sender, EventArgs ev) => { btmGetTemplate.Visible.OnNext(false); btmImportSetting.Visible.OnNext(false); btmRemoveSetting.Visible.OnNext(false); }; AccessoriesApi.SelectedMakerAccSlotChanged += (object sender, AccessorySlotEventArgs ev) => { InitCurrentSlot(); }; MakerAPI.MakerExiting += (object sender, EventArgs ev) => { HooksMakerInstance.UnpatchAll(HooksMakerInstance.Id); HooksMakerInstance = null; }; AccessoriesApi.AccessoryTransferred += (object sender, AccessoryTransferEventArgs ev) => { MaterialRouterController pluginCtrl = GetController(MakerAPI.GetCharacterControl()); pluginCtrl.AccessoryTransferEvent(ev); }; AccessoriesApi.AccessoriesCopied += (object sender, AccessoryCopyEventArgs ev) => { MaterialRouterController pluginCtrl = GetController(MakerAPI.GetCharacterControl()); pluginCtrl.AccessoryCopyEvent(ev); }; MakerAPI.RegisterCustomSubCategories += (object sender, RegisterSubCategoriesEvent ev) => { ChaControl chaCtrl = MakerAPI.GetCharacterControl(); MaterialRouterController pluginCtrl = GetController(chaCtrl); MakerCategory category = new MakerCategory("05_ParameterTop", "tglMaterialRouter", MakerConstants.Parameter.Attribute.Position + 1, "Router"); ev.AddSubCategory(category); ev.AddControl(new MakerText("BodyTrigger", category, this)); ev.AddControl(new MakerButton("Export", category, this)).OnClick.AddListener(delegate { pluginCtrl.ExportBodyTrigger(); }); ev.AddControl(new MakerButton("Import", category, this)).OnClick.AddListener(delegate { pluginCtrl.ImportBodyTrigger(); }); ev.AddControl(new MakerButton("Reset", category, this)).OnClick.AddListener(delegate { pluginCtrl.ResetBodyTrigger(); }); ev.AddControl(new MakerSeparator(category, this)); ev.AddControl(new MakerText("OutfitTriggers", category, this)); ev.AddControl(new MakerButton("Export", category, this)).OnClick.AddListener(delegate { pluginCtrl.ExportOutfitTrigger(); }); ev.AddControl(new MakerButton("Import", category, this)).OnClick.AddListener(delegate { pluginCtrl.ImportOutfitTrigger(); }); ev.AddControl(new MakerButton("Reset", category, this)).OnClick.AddListener(delegate { pluginCtrl.ResetOutfitTrigger(); }); ev.AddControl(new MakerSeparator(category, this)); ev.AddControl(new MakerText("Config", category, this)); tglSkipCloned = ev.AddControl(new MakerToggle(category, "Get Template Skip Cloned", CfgSkipCloned.Value, this)); tglSkipCloned.ValueChanged.Subscribe(value => CfgSkipCloned.Value = value); ev.AddControl(new MakerSeparator(category, this)); ev.AddControl(new MakerText("Tools", category, this)); ev.AddControl(new MakerButton("Reload", category, Instance)).OnClick.AddListener(delegate { string CardPath = Path.Combine(Path.GetTempPath(), Path.GetFileNameWithoutExtension(Paths.ExecutablePath) + "_MaterialRouter.png"); chaCtrl.chaFile.SaveCharaFile(CardPath, byte.MaxValue, false); chaCtrl.chaFile.LoadFileLimited(CardPath); if (chaCtrl.chaFile.GetLastErrorCode() != 0) { throw new Exception("LoadFileLimited failed"); } chaCtrl.ChangeCoordinateType(true); chaCtrl.Reload(); CustomBase.Instance.updateCustomUI = true; }); ev.AddControl(new MakerButton("Info", category, Instance)).OnClick.AddListener(delegate { Logger.LogInfo($"[BodyTrigger][{pluginCtrl?.BodyTrigger?.Count}]"); for (int i = 0; i < chaCtrl.chaFile.coordinate.Length; i++) { Logger.LogInfo($"[OutfitTriggers][{i}][{pluginCtrl?.OutfitTriggers?[i].Count}]"); } }); ev.AddControl(new MakerButton("Head Get Template", MakerConstants.Face.All, this)).OnClick.AddListener(() => PrintRendererInfo(chaCtrl, chaCtrl.objHead, true)); ev.AddControl(new MakerButton("Body Get Template", MakerConstants.Face.All, this)).OnClick.AddListener(() => PrintRendererInfo(chaCtrl, chaCtrl.objBody, true)); const string labelConsolePrint = "Console Output"; const string labelGenerateSetting = "Generate Setting"; const string labelRemoveSetting = "Remove Setting"; ev.AddControl(new MakerButton(labelConsolePrint, MakerConstants.Clothes.Top, this)).OnClick.AddListener(() => PrintRendererInfo(chaCtrl, chaCtrl.objClothes[0])); ev.AddControl(new MakerButton(labelConsolePrint, MakerConstants.Clothes.Bottom, this)).OnClick.AddListener(() => PrintRendererInfo(chaCtrl, chaCtrl.objClothes[1])); ev.AddControl(new MakerButton(labelConsolePrint, MakerConstants.Clothes.Bra, this)).OnClick.AddListener(() => PrintRendererInfo(chaCtrl, chaCtrl.objClothes[2])); ev.AddControl(new MakerButton(labelConsolePrint, MakerConstants.Clothes.Shorts, this)).OnClick.AddListener(() => PrintRendererInfo(chaCtrl, chaCtrl.objClothes[3])); ev.AddControl(new MakerButton(labelConsolePrint, MakerConstants.Clothes.Gloves, this)).OnClick.AddListener(() => PrintRendererInfo(chaCtrl, chaCtrl.objClothes[4])); ev.AddControl(new MakerButton(labelConsolePrint, MakerConstants.Clothes.Panst, this)).OnClick.AddListener(() => PrintRendererInfo(chaCtrl, chaCtrl.objClothes[5])); ev.AddControl(new MakerButton(labelConsolePrint, MakerConstants.Clothes.Socks, this)).OnClick.AddListener(() => PrintRendererInfo(chaCtrl, chaCtrl.objClothes[6])); ev.AddControl(new MakerButton(labelConsolePrint, MakerConstants.Clothes.InnerShoes, this)).OnClick.AddListener(() => PrintRendererInfo(chaCtrl, chaCtrl.objClothes[7])); ev.AddControl(new MakerButton(labelConsolePrint, MakerConstants.Clothes.OuterShoes, this)).OnClick.AddListener(() => PrintRendererInfo(chaCtrl, chaCtrl.objClothes[8])); btmGetTemplate = MakerAPI.AddAccessoryWindowControl(new MakerButton(labelConsolePrint, null, this)); btmGetTemplate.OnClick.AddListener(() => PrintRendererInfo(chaCtrl, chaCtrl.GetAccessoryObject(AccessoriesApi.SelectedMakerAccSlot))); btmImportSetting = MakerAPI.AddAccessoryWindowControl(new MakerButton(labelGenerateSetting, null, this)); btmImportSetting.OnClick.AddListener(() => pluginCtrl.ImportFromRendererInfo(AccessoriesApi.SelectedMakerAccSlot)); btmRemoveSetting = MakerAPI.AddAccessoryWindowControl(new MakerButton(labelRemoveSetting, null, this)); btmRemoveSetting.OnClick.AddListener(() => pluginCtrl.RemoveAccSlotInfo(AccessoriesApi.SelectedMakerAccSlot)); ev.AddControl(new MakerButton(labelConsolePrint, MakerConstants.Hair.Back, this)).OnClick.AddListener(() => PrintRendererInfo(chaCtrl, chaCtrl.objHair[0], true)); ev.AddControl(new MakerButton(labelConsolePrint, MakerConstants.Hair.Front, this)).OnClick.AddListener(() => PrintRendererInfo(chaCtrl, chaCtrl.objHair[1], true)); ev.AddControl(new MakerButton(labelConsolePrint, MakerConstants.Hair.Side, this)).OnClick.AddListener(() => PrintRendererInfo(chaCtrl, chaCtrl.objHair[2], true)); ev.AddControl(new MakerButton(labelConsolePrint, MakerConstants.Hair.Extension, this)).OnClick.AddListener(() => PrintRendererInfo(chaCtrl, chaCtrl.objHair[3], true)); }; }