public static bool PoseLoadPatch(OCIChar _ociChar, ref string _path, ref bool __result) { if (Path.GetExtension(_path).ToLower() == PngExt) { var fileInfo = new PauseCtrl.FileInfo(null); using (var fileStream = new FileStream(_path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (var binaryReader = new BinaryReader(fileStream)) { PngFile.SkipPng(binaryReader); if (string.Compare(binaryReader.ReadString(), PauseCtrl.saveIdentifyingCode) != 0) { __result = false; return(false); } int ver = binaryReader.ReadInt32(); binaryReader.ReadInt32(); binaryReader.ReadString(); fileInfo.Load(binaryReader, ver); } fileInfo.Apply(_ociChar); __result = true; return(false); } return(true); }
private void ExtendedSave_PoseBeingSaved(string poseName, PauseCtrl.FileInfo fileInfo, OCIChar ociChar, ExtendedSave.GameNames gameName) { var data = new PluginData(); //Facial expression #if PH data.data.Add(EyesPatternData, ociChar.charStatus.eyesPtn); data.data.Add(MouthPatternData, ociChar.charStatus.mouthPtn); data.data.Add(EyeOpenData, ociChar.charStatus.eyesOpenMax); data.data.Add(MouthOpenData, ociChar.oiCharInfo.mouthOpen); #else data.data.Add(EyebrowPatternData, ociChar.charFileStatus.eyebrowPtn); data.data.Add(EyesPatternData, ociChar.charFileStatus.eyesPtn); data.data.Add(MouthPatternData, ociChar.charFileStatus.mouthPtn); data.data.Add(EyeOpenData, ociChar.charFileStatus.eyesOpenMax); data.data.Add(MouthOpenData, ociChar.oiCharInfo.mouthOpen); #endif //Only save skirt FK if enabled if (ociChar.oiCharInfo.activeFK[SkirtFKIndex]) { Dictionary <int, Vector3> skirtFK = new Dictionary <int, Vector3>(); foreach (KeyValuePair <int, OIBoneInfo> item2 in ociChar.oiCharInfo.bones.Where(b => (OIBoneInfo.BoneGroup.Skirt & b.Value.group) != 0)) { skirtFK.Add(item2.Key, item2.Value.changeAmount.rot); } data.data.Add(SkirtFKData, MessagePackSerializer.Serialize(skirtFK)); } //Joint correction data.data.Add(JointCorrectionData, MessagePackSerializer.Serialize(ociChar.oiCharInfo.expression)); ExtendedSave.SetPoseExtendedDataById(PoseToolsData, data); }
public static bool PoseSavePatch(OCIChar _ociChar, ref string _name) { var filename = $"{_name}_{DateTime.Now.ToString("yyyy_MMdd_HHmm_ss_fff")}{PngExt}"; var path = Path.Combine(SavePath.Value, filename); var fileInfo = new PauseCtrl.FileInfo(_ociChar); try { using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write)) using (var binaryWriter = new BinaryWriter(fileStream)) { var buffer = Studio.Studio.Instance.gameScreenShot.CreatePngScreen(320, 180, false, false); binaryWriter.Write(buffer); binaryWriter.Write(PauseCtrl.saveIdentifyingCode); binaryWriter.Write(PauseCtrl.saveVersion); binaryWriter.Write(_ociChar.oiCharInfo.sex); binaryWriter.Write(_name); fileInfo.Save(binaryWriter); } } catch (Exception ex) { Logger.Log(LogLevel.Message, "PosePng plugin save path has not been set properly"); Logger.Log(LogLevel.Error, ex); } return(false); }
internal static void Apply(PauseCtrl.FileInfo __instance, OCIChar _char) { if (__instance.enableFK && __instance.enableIK) { EnableFKIK(_char); } }
public static bool ApplyPrefix(OCIChar _char, PauseCtrl.FileInfo __instance) { _char.LoadAnime(__instance.group, __instance.category, __instance.no, __instance.normalizedTime); for (int i = 0; i < __instance.activeIK.Length; i++) { _char.ActiveIK((OIBoneInfo.BoneGroup)(1 << i), __instance.activeIK[i], false); } _char.ActiveKinematicMode(OICharInfo.KinematicMode.IK, __instance.enableIK, true); foreach (KeyValuePair <int, ChangeAmount> keyValuePair in __instance.dicIK) { _char.oiCharInfo.ikTarget[keyValuePair.Key].changeAmount.Copy(keyValuePair.Value, true, true, true); } for (int j = 0; j < __instance.activeFK.Length; j++) { _char.ActiveFK(FKCtrl.parts[j], __instance.activeFK[j], false); } _char.ActiveKinematicMode(OICharInfo.KinematicMode.FK, __instance.enableFK, true); foreach (KeyValuePair <int, ChangeAmount> keyValuePair2 in __instance.dicFK) { _char.oiCharInfo.bones.TryGetValue(keyValuePair2.Key, out OIBoneInfo value); value?.changeAmount.Copy(keyValuePair2.Value, true, true, true); } for (int k = 0; k < __instance.expression.Length; k++) { _char.EnableExpressionCategory(k, __instance.expression[k]); } return(false); }
private static bool PoseSavePatch(OCIChar _ociChar, ref string _name) { var filename = $"{DateTime.Now:yyyy_MMdd_HHmm_ss_fff}.png"; if (ConfigPoseNamePrefix.Value && !_name.IsNullOrEmpty()) { filename = $"{_name}_" + filename; } if (!ConfigSavePng.Value) { return(true); } var path = Path.Combine(UserData.Create(GetFolder()), filename); var fileInfo = new PauseCtrl.FileInfo(_ociChar); try { using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write)) using (var binaryWriter = new BinaryWriter(fileStream)) { #if PH var buffer = Studio.Studio.Instance.sceneInfo.CreatePngScreen(320, 180); #else var buffer = Studio.Studio.Instance.gameScreenShot.CreatePngScreen(320, 180); #endif Texture2D screenshot = TextureFromBytes(buffer, mipmaps: false); screenshot = OverwriteTexture(screenshot, Watermark, 0, screenshot.height - Watermark.height); buffer = screenshot.EncodeToPNG(); binaryWriter.Write(buffer); binaryWriter.Write(PauseCtrl.saveIdentifyingCode); binaryWriter.Write(PauseCtrl.saveVersion); binaryWriter.Write(_ociChar.oiCharInfo.sex); binaryWriter.Write(_name); fileInfo.Save(binaryWriter); } } catch (Exception ex) { Plugin.Logger.LogError("Failed to save pose .png, falling back to original game code."); Plugin.Logger.LogError(ex); return(true); } return(false); }
internal static bool Apply(PauseCtrl.FileInfo __instance, OCIChar _char) { //AI and KK pose files are apparently indistinguishable from each other //If the user is holding ctrl while loading the pose correct the right hand FK bool correctHand = false; if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) { correctHand = true; } //326 is a bone that exists in HS but not KK, check that to see if this is a loaded HS pose bool HSPose = __instance.dicFK.Keys.Any(x => x == 326); #if KK //Honey Select poses always need the right hand corrected in KK if (HSPose) { correctHand = true; } #endif if (!HSPose && !correctHand) { return(true); } #region Vanilla Code _char.LoadAnime(__instance.group, __instance.category, __instance.no, __instance.normalizedTime); for (int i = 0; i < __instance.activeIK.Length; i++) { _char.ActiveIK((OIBoneInfo.BoneGroup)(1 << i), __instance.activeIK[i]); } _char.ActiveKinematicMode(OICharInfo.KinematicMode.IK, __instance.enableIK, _force: true); foreach (KeyValuePair <int, ChangeAmount> item in __instance.dicIK) { _char.oiCharInfo.ikTarget[item.Key].changeAmount.Copy(item.Value); } for (int j = 0; j < __instance.activeFK.Length; j++) { _char.ActiveFK(FKCtrl.parts[j], __instance.activeFK[j]); } _char.ActiveKinematicMode(OICharInfo.KinematicMode.FK, __instance.enableFK, _force: true); #endregion foreach (KeyValuePair <int, ChangeAmount> item2 in __instance.dicFK) { int key = item2.Key; if (HSPose) { //Breasts translated from HS to KK/AI if (key == 326) { key = 53; } if (key == 327) { key = 54; } if (key == 328) { key = 55; } if (key == 329) { key = 56; } if (key == 330) { key = 57; } if (key == 332) { key = 59; } if (key == 333) { key = 60; } if (key == 334) { key = 61; } if (key == 335) { key = 62; } if (key == 336) { key = 63; } } if (_char.oiCharInfo.bones.TryGetValue(key, out var oIBoneInfo)) { if (correctHand) { //Correct the right hand if (key == 22 || key == 25 || key == 28 || key == 31 || key == 34) { item2.Value.rot = new Vector3(-item2.Value.rot.x, 180 + item2.Value.rot.y, 180 - item2.Value.rot.z); } if (key == 23 || key == 26 || key == 29 || key == 32 || key == 35) { item2.Value.rot = new Vector3(item2.Value.rot.x, -item2.Value.rot.y, -item2.Value.rot.z); } if (key == 24 || key == 27 || key == 30 || key == 33 || key == 36) { item2.Value.rot = new Vector3(item2.Value.rot.x, -item2.Value.rot.y, -item2.Value.rot.z); } } oIBoneInfo.changeAmount.Copy(item2.Value); } } #region Vanilla Code for (int k = 0; k < __instance.expression.Length; k++) { _char.EnableExpressionCategory(k, __instance.expression[k]); } #endregion return(false); }
private void ExtendedSave_PoseBeingLoaded(string poseName, PauseCtrl.FileInfo fileInfo, OCIChar ociChar, ExtendedSave.GameNames gameName) { bool loadSkirtFK = false; PluginData data = ExtendedSave.GetPoseExtendedDataById(PoseToolsData); if (data != null) { bool sameGame = false; //Only load expression data for the game this pose was created on, eye etc. patterns wouldn't match otherwise #if KK || KKS if (gameName == ExtendedSave.GameNames.Koikatsu || gameName == ExtendedSave.GameNames.KoikatsuSunshine) { sameGame = true; } #elif AI || HS2 if (gameName == ExtendedSave.GameNames.AIGirl || gameName == ExtendedSave.GameNames.HoneySelect2) { sameGame = true; } #elif PH if (gameName == ExtendedSave.GameNames.PlayHome) { sameGame = true; } #endif //Facial expression if (sameGame && ConfigLoadExpression.Value) { #if !PH if (data.data.TryGetValue(EyebrowPatternData, out var eyebrowPatternData)) { ociChar.charInfo.ChangeEyebrowPtn((int)eyebrowPatternData); } #endif if (data.data.TryGetValue(EyesPatternData, out var eyesPatternData)) { ociChar.charInfo.ChangeEyesPtn((int)eyesPatternData); } if (data.data.TryGetValue(MouthPatternData, out var mouthPatternData)) { ociChar.charInfo.ChangeMouthPtn((int)mouthPatternData); } if (data.data.TryGetValue(EyeOpenData, out var eyeOpenData)) { ociChar.ChangeEyesOpen((float)eyeOpenData); } if (data.data.TryGetValue(MouthOpenData, out var mouthOpenData)) { ociChar.ChangeMouthOpen((float)mouthOpenData); } } //Skirt FK if (sameGame && ConfigLoadSkirtFK.Value && data.data.TryGetValue(SkirtFKData, out var skirtFKData) && skirtFKData != null) { loadSkirtFK = true; Dictionary <int, Vector3> skirtFK = MessagePackSerializer.Deserialize <Dictionary <int, Vector3> >((byte[])skirtFKData); foreach (KeyValuePair <int, Vector3> item in skirtFK) { ociChar.oiCharInfo.bones[item.Key].changeAmount.rot = item.Value; } } //Joint correction if (data.data.TryGetValue(JointCorrectionData, out var jointCorrectionData) && jointCorrectionData != null) { bool[] expression = MessagePackSerializer.Deserialize <bool[]>((byte[])jointCorrectionData); //Skip the first 4 since those are handled by vanilla code for (int i = 4; i < expression.Length; i++) { ociChar.EnableExpressionCategory(i, expression[i]); } } } if (!loadSkirtFK) { //Disable skirt FK if there was none to load since it's worthless to have enabled StartCoroutine(DisableSkirtFK(ociChar)); ociChar.ActiveFK(OIBoneInfo.BoneGroup.Skirt, false); } }
private static void Apply(PauseCtrl.FileInfo __instance, OCIChar _char) { if (__instance.enableFK && __instance.enableIK) EnableFKIK(_char); }