Exemplo n.º 1
0
        private static void OnCopyAcs(CvsAccessoryCopy instance)
        {
            if (AccessoriesCopied == null)
            {
                return;
            }

            try
            {
                var selected = instance.GetComponentsInChildren <UnityEngine.UI.Toggle>()
                               .Where(x => x.isOn)
                               .Select(x => x.transform.parent.name)
                               .Select(n => int.Parse(n.Substring("kind".Length)))
                               .ToList();

                var dropdowns = Traverse.Create(instance).Field("ddCoordeType").GetValue <TMP_Dropdown[]>();

                var args = new AccessoryCopyEventArgs(selected, (ChaFileDefine.CoordinateType)dropdowns[1].value, (ChaFileDefine.CoordinateType)dropdowns[0].value);

                AccessoriesCopied(instance, args);
            }
            catch (Exception ex)
            {
                KoikatuAPI.Log(LogLevel.Error, "Crash in AccessoriesCopied event: " + ex);
            }
        }
Exemplo n.º 2
0
        private void LateUpdate()
        {
            if (NeedsFullRefresh)
            {
                OnReload(KoikatuAPI.GetCurrentGameMode(), true);
                NeedsFullRefresh = false;
                return;
            }

            if (_baselineKnown == true)
            {
                if (NeedsBaselineUpdate)
                {
                    UpdateBaseline();
                }

                foreach (var modifier in Modifiers)
                {
                    var additionalModifiers = _additionalBoneEffects
                                              .Select(x => x.GetEffect(modifier.BoneName, this, CurrentCoordinate.Value))
                                              .Where(x => x != null)
                                              .ToList();

                    modifier.Apply(CurrentCoordinate.Value, additionalModifiers, _isDuringHScene);
                }
            }
            else if (_baselineKnown == false)
            {
                _baselineKnown = null;
                CollectBaseline();
            }

            NeedsBaselineUpdate = false;
        }
Exemplo n.º 3
0
 public void UpdateHover()
 {
     if (KoikatuAPI.GetCurrentGameMode() != GameMode.Studio)
     {
         if (!isShoeActive || currentConfig == null || !GroundAnim)
         {
             DisableHover();
         }
         else
         {
             EnableHover();
         }
     }
     else
     {
         if (!isShoeActive || currentConfig == null)
         {
             DisableHover();
         }
         else
         {
             EnableHover();
         }
     }
 }
        /// <summary>
        /// Save your custom data to the character card under the ID you specified when registering this controller.
        /// This should be used inside the <see cref="OnCardBeingSaved"/> event.
        /// Consider using one of the other "Get___ExtData" and "Set___ExtData" methods instead since they are more reliable and handle copying and transferring outfits and they conform to built in maker load toggles.
        /// </summary>
        /// <param name="data">Your custom data to be written to the character card. Can be null to remove the data.</param>
        public void SetExtendedData(PluginData data)
        {
            if (ExtendedDataId == null)
            {
                throw new ArgumentException(nameof(ExtendedDataId));
            }
            ExtendedSave.SetExtendedDataById(ChaFileControl, ExtendedDataId, data);

#if KK //todo || KKS
            // Needed for propagating changes back to the original charFile since they don't get copied back.
            var heroine = ChaControl.GetHeroine();
            if (heroine != null)
            {
                ExtendedSave.SetExtendedDataById(heroine.charFile, ExtendedDataId, data);

                if (ChaControl != heroine.chaCtrl)
                {
                    ExtendedSave.SetExtendedDataById(heroine.chaCtrl.chaFile, ExtendedDataId, data);

                    // Update other instance to reflect the new ext data
                    var other = heroine.chaCtrl.GetComponent(GetType()) as CharaCustomFunctionController;
                    if (other != null)
                    {
                        other.OnReloadInternal(KoikatuAPI.GetCurrentGameMode());
                    }
                }

                var npc = heroine.GetNPC();
                if (npc != null && npc.chaCtrl != null && npc.chaCtrl != ChaControl)
                {
                    ExtendedSave.SetExtendedDataById(npc.chaCtrl.chaFile, ExtendedDataId, data);

                    // Update other instance to reflect the new ext data
                    var other = npc.chaCtrl.GetComponent(GetType()) as CharaCustomFunctionController;
                    if (other != null)
                    {
                        other.OnReloadInternal(KoikatuAPI.GetCurrentGameMode());
                    }
                }
            }

            var player = ChaControl.GetPlayer();
            if (player != null)
            {
                ExtendedSave.SetExtendedDataById(player.charFile, ExtendedDataId, data);

                if (ChaControl != player.chaCtrl)
                {
                    ExtendedSave.SetExtendedDataById(player.chaCtrl.chaFile, ExtendedDataId, data);

                    // Update other instance to reflect the new ext data
                    var other = player.chaCtrl.GetComponent(GetType()) as CharaCustomFunctionController;
                    if (other != null)
                    {
                        other.OnReloadInternal(KoikatuAPI.GetCurrentGameMode());
                    }
                }
            }
#endif
        }
Exemplo n.º 5
0
        public static Transform AddNewSubCategory(UI_ToggleGroupCtrl mainCategory, MakerCategory subCategory)
        {
            KoikatuAPI.Log(LogLevel.Debug, $"[MakerAPI] Adding custom subcategory {subCategory.SubCategoryName} to {mainCategory.transform.name}");

            var tr = Object.Instantiate(SubCategoryCopy.gameObject, mainCategory.transform, true).transform;

            tr.name = subCategory.SubCategoryName;
            var trTop = tr.Find("CustomSubcategoryTop");

            trTop.name = subCategory.SubCategoryName + "Top";

            foreach (Transform oldObj in trTop.transform)
            {
                Object.Destroy(oldObj.gameObject);
            }

            tr.GetComponentInChildren <TextMeshProUGUI>().text = GetSubcategoryDisplayName(subCategory);

            var tgl = tr.GetComponent <Toggle>();

            tgl.group = mainCategory.transform.GetComponent <ToggleGroup>();

            var cgroup = trTop.GetComponent <CanvasGroup>();

            mainCategory.items = mainCategory.items.AddToArray(new UI_ToggleGroupCtrl.ItemInfo {
                tglItem = tgl, cgItem = cgroup
            });

            KoikatuAPI.Instance.StartCoroutine(FinishInit(trTop));

            tr.gameObject.SetActive(true);

            return(tr);
        }
 /// <summary>
 /// Get extended data for character's face (face sliders, eye settings).
 /// Do not store this data because it might change without notice, for example when clothing is copied. Always call Get at the point where you need the data, not earlier.
 /// If you change any of the data, remember to call the corresponding Set method or the change might not be saved.
 /// This data is saved alongside game data, which means it is automatically copied and moved as necessary.
 /// If no extended data of this plugin was set yet, this method will return null.
 /// In maker, you can update controls that use this data in the <see cref="MakerAPI.ReloadCustomInterface"/> event.
 /// </summary>
 public PluginData GetFaceExtData()
 {
     KoikatuAPI.Assert(ChaFileControl.custom != null, "ChaFileControl.custom != null");
     KoikatuAPI.Assert(ChaFileControl.custom.face != null, "ChaFileControl.custom.face != null");
     ChaFileControl.custom.face.TryGetExtendedDataById(ExtendedDataId, out var data);
     return(data);
 }
Exemplo n.º 7
0
        private static void CreateCustomControlsInSubCategory(Transform subCategoryTransform, ICollection <BaseGuiEntry> entriesToAdd)
        {
            if (entriesToAdd.Count == 0)
            {
                return;
            }

            var contentParent = FindSubcategoryContentParent(subCategoryTransform);

            BaseUnityPlugin lastOwner = contentParent.childCount > 1 ? KoikatuAPI.Instance : null;

            foreach (var customControl in entriesToAdd)
            {
                if (lastOwner != customControl.Owner && lastOwner != null)
                {
                    new MakerSeparator(new MakerCategory(null, null), KoikatuAPI.Instance).CreateControl(contentParent);
                }

                customControl.CreateControl(contentParent);
                lastOwner = customControl.Owner;
            }

            var category = entriesToAdd.First().Category;

            KoikatuAPI.Log(LogLevel.Debug, $"[MakerAPI] Added {entriesToAdd.Count()} custom controls " +
                           $"to {category.CategoryName}/{category.SubCategoryName}");
        }
Exemplo n.º 8
0
        private static void OnMakerBaseLoaded()
        {
            if (MakerBaseLoaded != null)
            {
                var args = new RegisterCustomControlsEvent();
                foreach (var handler in MakerBaseLoaded.GetInvocationList())
                {
                    try
                    {
                        ((EventHandler <RegisterCustomControlsEvent>)handler).Invoke(KoikatuAPI.Instance, args);
                    }
                    catch (Exception e)
                    {
                        KoikatuAPI.Log(LogLevel.Error, e);
                    }
                }
            }

            DebugControls();

            foreach (var baseGuiEntry in _guiEntries)
            {
                baseGuiEntry.Initialize();
            }
        }
Exemplo n.º 9
0
        internal void UpdateCurrentCardTranslationMode()
        {
            var origMode = CurrentCardLoadTranslationMode;

            if (StudioAPI.InsideStudio)
            {
                CurrentCardLoadTranslationMode =
                    StudioTranslateCardNameOnLoad?.Value ?? CardLoadTranslationMode.Disabled;
                CurrentGameMode = GameMode.Studio;
            }

            else if (MakerAPI.InsideMaker)
            {
                CurrentCardLoadTranslationMode =
                    MakerTranslateCardNameOnLoad?.Value ?? CardLoadTranslationMode.Disabled;
                CurrentGameMode = GameMode.Maker;
            }
            else
            {
                CurrentGameMode = KoikatuAPI.GetCurrentGameMode();

                if (CurrentGameMode == GameMode.MainGame)
                {
                    CurrentCardLoadTranslationMode =
                        GameTranslateCardNameOnLoad?.Value ?? CardLoadTranslationMode.Disabled;
                }
                else
                {
                    CurrentCardLoadTranslationMode = CardLoadTranslationMode.Disabled;
                }
            }


            Logger.LogDebug($"UpdateCurrentCardTranslationMode: {origMode} => {CurrentCardLoadTranslationMode}");
        }
Exemplo n.º 10
0
        private void LateUpdate()
        {
            if (NeedsFullRefresh)
            {
                OnReload(KoikatuAPI.GetCurrentGameMode(), true);
                NeedsFullRefresh = false;
                return;
            }

            if (_baselineKnown == true)
            {
                if (NeedsBaselineUpdate)
                {
                    UpdateBaseline();
                }

                foreach (var modifier in Modifiers)
                {
                    modifier.Apply(CurrentCoordinate.Value);
                }
            }
            else if (_baselineKnown == false)
            {
                _baselineKnown = null;
                StartCoroutine(CollectBaselineCo());
            }

            NeedsBaselineUpdate = false;
        }
Exemplo n.º 11
0
        private void Start()
        {
            EnableBld         = new ConfigWrapper <bool>(nameof(EnableBld), this, true);
            EnableBldAlways   = new ConfigWrapper <bool>(nameof(EnableBldAlways), this, false);
            EnableCum         = new ConfigWrapper <bool>(nameof(EnableCum), this, true);
            EnableSwt         = new ConfigWrapper <bool>(nameof(EnableSwt), this, true);
            EnableTear        = new ConfigWrapper <bool>(nameof(EnableTear), this, true);
            EnableDrl         = new ConfigWrapper <bool>(nameof(EnableDrl), this, true);
            EnablePersistance = new ConfigWrapper <bool>(nameof(EnablePersistance), this, true);

            Hooks.InstallHook();

            CharacterApi.RegisterExtraBehaviour <SkinEffectsController>(GUID);
            GameAPI.RegisterExtraBehaviour <SkinEffectGameController>(GUID);

            SkinEffectsGui.Init(this);

            if (KoikatuAPI.GetCurrentGameMode() != GameMode.Studio)
            {
                SceneManager.sceneLoaded += (arg0, mode) =>
                {
                    // Preload effects for H scene in case they didn't get loaded yet to prevent freeze on first effect appearing
                    if (arg0.name == "H")
                    {
                        TextureLoader.InitializeTextures();
                    }
                };
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// Needs to run before UI_ToggleGroupCtrl.Start of the category runs, or it won't get added properly
        /// </summary>
        private static void AddMissingSubCategories(UI_ToggleGroupCtrl mainCategory)
        {
            var categoryTransfrom = mainCategory.transform;

            // Can break stuff, 06_SystemTop might be fine but needs testing
            if (categoryTransfrom.name == "04_AccessoryTop" || categoryTransfrom.name == "06_SystemTop")
            {
                return;
            }

            // Sorting breaks hair selector layout, too lazy to fix
            var noSorting = categoryTransfrom.name == "02_HairTop";

            var transformsToSort = new List <UniRx.Tuple <Transform, int> >();

            foreach (var category in _categories)
            {
                if (categoryTransfrom.name != category.CategoryName)
                {
                    continue;
                }

                var categorySubTransform = categoryTransfrom.Find(category.SubCategoryName)
                                           ?? SubCategoryCreator.AddNewSubCategory(mainCategory, category);

                transformsToSort.Add(new UniRx.Tuple <Transform, int>(categorySubTransform, category.Position));
            }

            if (noSorting)
            {
                return;
            }

            foreach (Transform subTransform in categoryTransfrom)
            {
                if (transformsToSort.Any(x => x.Item1 == subTransform))
                {
                    continue;
                }

                var builtInCategory = MakerConstants.GetBuiltInCategory(categoryTransfrom.name, subTransform.name);
                if (builtInCategory != null)
                {
                    transformsToSort.Add(new UniRx.Tuple <Transform, int>(subTransform, builtInCategory.Position));
                }
                else
                {
                    KoikatuAPI.Log(LogLevel.Warning, $"[MakerAPI] Missing MakerCategory for existing transfrom {categoryTransfrom.name} / {subTransform.name}");
                }
            }

            var index = 0;

            foreach (var tuple in transformsToSort.OrderBy(x => x.Item2))
            {
                tuple.Item1.SetSiblingIndex(index++);
            }

            KoikatuAPI.Instance.StartCoroutine(FixCategoryContentOffsets(mainCategory));
        }
Exemplo n.º 13
0
        internal static void Init()
        {
            DetectMoreAccessories();

            HarmonyPatcher.PatchAll(typeof(Hooks));

            MakerAPI.InsideMakerChanged   += MakerAPI_InsideMakerChanged;
            MakerAPI.MakerFinishedLoading += (sender, args) => OnSelectedMakerSlotChanged(sender, 0);

            if (MoreAccessoriesInstalled)
            {
                var getAccCmpM = AccessTools.Method(_moreAccessoriesType, "GetChaAccessoryComponent");
                _getChaAccessoryCmp = (control, componentIndex) => (ChaAccessoryComponent)getAccCmpM.Invoke(_moreAccessoriesInstance, new object[] { control, componentIndex });

                var getAccCmpIndexM = AccessTools.Method(_moreAccessoriesType, "GetChaAccessoryComponentIndex");
                _getChaAccessoryCmpIndex = (control, component) => (int)getAccCmpIndexM.Invoke(_moreAccessoriesInstance, new object[] { control, component });
            }
            else
            {
                _getChaAccessoryCmp      = (control, i) => control.cusAcsCmp[i];
                _getChaAccessoryCmpIndex = (control, component) => Array.IndexOf(control.cusAcsCmp, component);
            }

            if (KoikatuAPI.EnableDebugLogging)
            {
                SelectedMakerAccSlotChanged += (sender, args) => KoikatuAPI.Log(LogLevel.Message,
                                                                                $"SelectedMakerAccSlotChanged - id: {args.SlotIndex}, cvs: {args.CvsAccessory.transform.name}, component: {args.AccessoryComponent?.name ?? "null"}");
#if KK
                AccessoriesCopied += (sender, args) => KoikatuAPI.Log(LogLevel.Message,
                                                                      $"AccessoriesCopied - ids: {string.Join(", ", args.CopiedSlotIndexes.Select(x => x.ToString()).ToArray())}, src:{args.CopySource}, dst:{args.CopyDestination}");
#endif
                AccessoryTransferred += (sender, args) => KoikatuAPI.Log(LogLevel.Message,
                                                                         $"AccessoryTransferred - srcId:{args.SourceSlotIndex}, dstId:{args.DestinationSlotIndex}");
            }
        }
Exemplo n.º 14
0
        private void LateUpdate()
        {
            if (NeedsFullRefresh)
            {
                OnReload(KoikatuAPI.GetCurrentGameMode(), true);
                NeedsFullRefresh = false;
                return;
            }

            if (_baselineKnown == true)
            {
                if (NeedsBaselineUpdate)
                {
                    UpdateBaseline();
                }

                ApplyEffects();
            }
            else if (_baselineKnown == false)
            {
                _baselineKnown = null;
                CollectBaseline();
            }

            NeedsBaselineUpdate = false;
        }
Exemplo n.º 15
0
        public static bool GetFileNamePatch(ref string __result, string path)
        {
            // Should only work during main game
            var gmode = KoikatuAPI.GetCurrentGameMode();

            if (gmode != GameMode.MainGame && gmode != GameMode.Maker)
            {
                return(true);
            }

            try
            {
                if (File.Exists(UserData.Path + "chara/female/" + path))
                {
                    __result = path;
                    return(false);
                }

                var lookedAtPath     = new Uri(path);
                var basePathForChara = new Uri(UserData.Path + "chara/female/");
                if (basePathForChara.IsBaseOf(lookedAtPath))
                {
                    __result = MainGameFolders.GetRelativePath(path, UserData.Path + "chara/female/");
                    return(false);
                }

                return(true);
            }
            catch
            {
                return(true);
            }
        }
Exemplo n.º 16
0
        public static bool ConvertCharaFilePath(ref ChaFileControl __instance, ref string __result, string path)
        {
            // Should only work during main game
            var gmode = KoikatuAPI.GetCurrentGameMode();

            if (gmode != GameMode.MainGame && gmode != GameMode.Maker)
            {
                return(true);
            }
            if (path == null)
            {
                return(true);
            }

            if (!path.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
            {
                path += ".png";
            }

            if (File.Exists(path))
            {
                __result = path;
                return(false);
            }

            if (File.Exists(UserData.Path + "chara/female/" + path))
            {
                __result = UserData.Path + "chara/female/" + path;
                return(false);
            }

            return(true);
        }
Exemplo n.º 17
0
        private static void DetectMoreAccessories()
        {
            try
            {
                _moreAccessoriesType = Type.GetType("MoreAccessoriesKOI.MoreAccessories, MoreAccessories, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");

                if (_moreAccessoriesType != null)
                {
                    _moreAccessoriesInstance = Object.FindObjectOfType(_moreAccessoriesType);

                    var slotAddEvent = _moreAccessoriesType.GetEvent("onCharaMakerSlotAdded", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                    if (slotAddEvent != null)
                    {
                        slotAddEvent.AddEventHandler(_moreAccessoriesInstance,
                                                     new Action <int, Transform>((i, transform) => OnMakerAccSlotAdded(_moreAccessoriesInstance, i, transform)));
                    }
                    else
                    {
                        _moreAccessoriesType = null;
                        KoikatuAPI.Log(LogLevel.Message | LogLevel.Error, "[KKAPI] WARNING: Your MoreAccesories is outdated! Some features won't work correctly until you update to the latest version.");
                    }
                }
            }
            catch (Exception e)
            {
                _moreAccessoriesType = null;
                KoikatuAPI.Log(LogLevel.Warning, "Failed to detect MoreAccessories!");
                KoikatuAPI.Log(LogLevel.Debug, e);
            }
        }
Exemplo n.º 18
0
        public bool Install(Harmony instance, ConfigFile config)
        {
            if (KoikatuAPI.IsVR())
            {
                return(false);
            }

            _statDecay = config.Bind(KoikatuGameplayMod.ConfCatMainGame, "Player stats slowly decay overnight", true,
                                     "Player's stats slowly decrease every day to keep the training points relevant.");
            _changeLewdDaily = config.Bind(KoikatuGameplayMod.ConfCatMainGame, "Change lewdness overnight", false,
                                           "H bar of all heroines either increases or decreases overnight depending on their status.");

            SceneManager.sceneLoaded += (arg0, mode) =>
            {
                if (arg0.name != "MyRoom" || Singleton <Scene> .Instance.LoadSceneName == "H")
                {
                    _inNightMenu = false;
                }
                else
                {
                    if (!_inNightMenu && !_firstNightMenu)
                    {
                        try { OnNightStarted(); }
                        catch (Exception ex) { UnityEngine.Debug.LogException(ex); }
                    }

                    _inNightMenu    = true;
                    _firstNightMenu = false;
                }
            };

            return(true);
        }
Exemplo n.º 19
0
        private static void CreateCustomControls()
        {
            // Craete controls in tabs
            foreach (Transform categoryTransfrom in GameObject.Find("CvsMenuTree").transform)
            {
                CreateCustomControlsInCategory(categoryTransfrom);
            }

            // Create sidebar controls
            if (_sidebarEntries.Any())
            {
                var sidebarTop = GameObject.Find("CustomScene/CustomRoot/FrontUIGroup/CvsDraw/Top").transform;

                var sep = new SidebarSeparator(KoikatuAPI.Instance);
                sep.CreateControl(sidebarTop);

                foreach (var sidebarEntry in _sidebarEntries)
                {
                    sidebarEntry.CreateControl(sidebarTop);
                }

                KoikatuAPI.Log(LogLevel.Debug, $"[MakerAPI] Added {_sidebarEntries.Count} custom controls " +
                               "to Control Panel sidebar");
            }

            if (_accessoryWindowEntries.Any())
            {
                CreateCustomAccessoryWindowControls();
            }
        }
Exemplo n.º 20
0
        private static void OnSelectedMakerSlotChanged(object source, int newSlotIndex)
        {
            if (newSlotIndex == SelectedMakerAccSlot)
            {
                return;
            }
            SelectedMakerAccSlot = newSlotIndex;

            if (KoikatuAPI.EnableDebugLogging)
            {
                KoikatuAPI.Log(LogLevel.Message, "SelectedMakerSlotChanged - slot:" + newSlotIndex);
            }

            if (SelectedMakerAccSlotChanged == null)
            {
                return;
            }
            try
            {
                SelectedMakerAccSlotChanged(source, new AccessorySlotEventArgs(newSlotIndex));
            }
            catch (Exception ex)
            {
                KoikatuAPI.Log(LogLevel.Error, "Subscription to SelectedMakerSlot crashed: " + ex);
            }
        }
        private ChaFile GetExtDataTargetChaFile(bool setDirty)
        {
#if KK || KKS
            // In main game store ext data for the character inside of the main chaFile object (the one that gets saved to game saves) instead of its copies.
            // This allows saving ext data inside talk scenes and H scenes without losing it after exiting to main map.
            if (KoikatuAPI.GetCurrentGameMode() == GameMode.MainGame)
            {
                var heroine = ChaControl.GetHeroine();
                if (heroine != null)
                {
                    if (setDirty)
                    {
                        CharacterApi.Hooks.SetDirty(heroine, true);
                    }
                    return(heroine.charFile);
                }

                var player = ChaControl.GetPlayer();
                if (player != null)
                {
                    if (setDirty)
                    {
                        CharacterApi.Hooks.SetDirty(player, true);
                    }
                    return(player.charFile);
                }
            }
#endif
            return(ChaFileControl);
        }
 /// <summary>
 /// Warning: When overriding make sure to call the base method at the end of your logic!
 /// </summary>
 protected virtual void OnEnable()
 {
     // Order is Awake - OnEnable - Start, so need to check if we started yet
     if (Started)
     {
         OnReloadInternal(KoikatuAPI.GetCurrentGameMode());
     }
 }
Exemplo n.º 23
0
        private void Start()
        {
            KoikatuAPI.CheckRequiredPlugin(this, KoikatuAPI.GUID, new Version(KoikatuAPI.VersionConst));

            MakerAPI.RegisterCustomSubCategories += OnRegisterCustomSubCategories;
            MakerAPI.MakerBaseLoaded             += OnEarlyMakerFinishedLoading;
            MakerAPI.MakerExiting += OnMakerExiting;
        }
        /// <summary>
        /// Get extended data for character's parameters (personality, preferences, traits).
        /// Do not store this data because it might change without notice, for example when clothing is copied. Always call Get at the point where you need the data, not earlier.
        /// If you change any of the data, remember to call the corresponding Set method or the change might not be saved.
        /// This data is saved alongside game data, which means it is automatically copied and moved as necessary.
        /// If no extended data of this plugin was set yet, this method will return null.
        /// In maker, you can update controls that use this data in the <see cref="MakerAPI.ReloadCustomInterface"/> event.
        /// </summary>
        public PluginData GetParameterExtData()
        {
            var chafile = GetExtDataTargetChaFile(false);

            KoikatuAPI.Assert(chafile.parameter != null, "chafile.parameter != null");
            chafile.parameter.TryGetExtendedDataById(ExtendedDataId, out var data);
            return(data);
        }
        /// <summary>
        /// Get extended data for character's face (face sliders, eye settings).
        /// Do not store this data because it might change without notice, for example when clothing is copied. Always call Get at the point where you need the data, not earlier.
        /// If you change any of the data, remember to call the corresponding Set method or the change might not be saved.
        /// This data is saved alongside game data, which means it is automatically copied and moved as necessary.
        /// If no extended data of this plugin was set yet, this method will return null.
        /// In maker, you can update controls that use this data in the <see cref="MakerAPI.ReloadCustomInterface"/> event.
        /// </summary>
        public PluginData GetFaceExtData()
        {
            var chafile = GetExtDataTargetChaFile(false);

            KoikatuAPI.Assert(chafile.custom != null, "chafile.custom != null");
            KoikatuAPI.Assert(chafile.custom.face != null, "chafile.custom.face != null");
            chafile.custom.face.TryGetExtendedDataById(ExtendedDataId, out var data);
            return(data);
        }
Exemplo n.º 26
0
 internal static void ChaFile_SaveFile_Postfix(ChaFile __instance)
 {
     // ReSharper disable once UseNullPropagation
     if (__instance == null)
     {
         return;
     }
     __instance.GetTranslationHelperController()
     .SafeProcObject(c => c.OnCardSaveComplete(KoikatuAPI.GetCurrentGameMode()));
 }
Exemplo n.º 27
0
        private static void ChaControl_ChangeSettingEyelineUp(ChaControl __instance)
        {
            //Only care about maker and studio, other modes have problems that aren't worth the effort
            if (KoikatuAPI.GetCurrentGameMode() == GameMode.MainGame)
            {
                return;
            }

            EyebrowFix.SetEyeliners(__instance, __instance.chaFile.custom.face.foregroundEyes);
        }
        /// <summary>
        /// Set extended data for specific clothes.
        /// Always call Set right after changing any of the data, or the change might not be saved if the data is changed for whatever reason (clothing change, reload, etc.)
        /// This data is saved alongside game data, which means it is automatically copied and moved as necessary.
        /// </summary>
        /// <param name="data">Extended data to save.</param>
        /// <param name="coordinateId">The coordinate number to open extened data for if the game supports multiple coords (0-indexed). -1 will use the current coordinate.</param>
        public void SetClothesExtData(PluginData data, int coordinateId = -1)
        {
            var coord = GetCoordinate(coordinateId);

            KoikatuAPI.Assert(coord != null, nameof(coord) + " != null");
            KoikatuAPI.Assert(coord.clothes != null, "coord.clothes != null");
            var clothes = coord.clothes;

            clothes.SetExtendedDataById(ExtendedDataId, data);
        }
        /// <summary>
        /// Set extended data for a specific accessory.
        /// Always call Set right after changing any of the data, or the change might not be saved if the data is changed for whatever reason (clothing change, reload, etc.)
        /// This data is saved alongside game data, which means it is automatically copied and moved as necessary.
        /// </summary>
        /// <param name="data">Extended data to save.</param>
        /// <param name="accessoryPartId">The accessory part number to open extened data for (0-indexed).</param>
        /// <param name="coordinateId">The coordinate number to open extened data for if the game supports multiple coords (0-indexed). -1 will use the current coordinate.</param>
        public void SetAccessoryExtData(PluginData data, int accessoryPartId, int coordinateId = -1)
        {
            var coord = GetCoordinate(coordinateId);

            KoikatuAPI.Assert(coord != null, nameof(coord) + " != null");
            KoikatuAPI.Assert(coord.accessory != null, "coord.accessory != null");
            var accessoryPart = coord.accessory.parts[accessoryPartId];

            accessoryPart.SetExtendedDataById(ExtendedDataId, data);
        }
Exemplo n.º 30
0
 private static void NotBraShortsOverride(ChaControl __instance, ref bool value)
 {
     if (__instance.GetCurrentCrest() == CrestType.liberated)
     {
         if (KoikatuAPI.GetCurrentGameMode() == GameMode.MainGame || GameAPI.InsideHScene)
         {
             // Force underwear to be off
             value = true;
         }
     }
 }