|
@@ -1,504 +1,556 @@
|
|
|
using System;
|
|
|
-using System.IO;
|
|
|
using System.Collections;
|
|
|
-using System.Collections.Generic;
|
|
|
+using System.IO;
|
|
|
using System.Text;
|
|
|
+
|
|
|
+using BepInEx;
|
|
|
using UnityEngine;
|
|
|
using UnityEngine.SceneManagement;
|
|
|
-using BepInEx;
|
|
|
|
|
|
-namespace MeidoPhotoStudio.Plugin
|
|
|
+using Input = MeidoPhotoStudio.Plugin.InputManager;
|
|
|
+
|
|
|
+namespace MeidoPhotoStudio.Plugin;
|
|
|
+
|
|
|
+[BepInPlugin(PluginGuid, PluginName, PluginVersion)]
|
|
|
+[BepInDependency("org.bepinex.plugins.unityinjectorloader", BepInDependency.DependencyFlags.SoftDependency)]
|
|
|
+public class MeidoPhotoStudio : BaseUnityPlugin
|
|
|
{
|
|
|
- using Input = InputManager;
|
|
|
- [BepInPlugin(pluginGuid, pluginName, pluginVersion)]
|
|
|
- [BepInDependency("org.bepinex.plugins.unityinjectorloader", BepInDependency.DependencyFlags.SoftDependency)]
|
|
|
- public class MeidoPhotoStudio : BaseUnityPlugin
|
|
|
+ public const string PluginName = "MeidoPhotoStudio";
|
|
|
+ public const string PluginVersion = "1.0.0";
|
|
|
+ public const string PluginSubVersion = "beta.4.1";
|
|
|
+ public const short SceneVersion = 2;
|
|
|
+ public const int KankyoMagic = -765;
|
|
|
+
|
|
|
+ public static readonly byte[] SceneHeader = Encoding.UTF8.GetBytes("MPSSCENE");
|
|
|
+ public static readonly string PluginString = $"{PluginName} {PluginVersion}";
|
|
|
+
|
|
|
+ private const string PluginGuid = "com.habeebweeb.com3d2.meidophotostudio";
|
|
|
+
|
|
|
+ private static Constants.Scene currentScene;
|
|
|
+
|
|
|
+ private HarmonyLib.Harmony harmony;
|
|
|
+ private WindowManager windowManager;
|
|
|
+ private SceneManager sceneManager;
|
|
|
+ private MeidoManager meidoManager;
|
|
|
+ private EnvironmentManager environmentManager;
|
|
|
+ private MessageWindowManager messageWindowManager;
|
|
|
+ private LightManager lightManager;
|
|
|
+ private PropManager propManager;
|
|
|
+ private EffectManager effectManager;
|
|
|
+ private CameraManager cameraManager;
|
|
|
+ private bool initialized;
|
|
|
+ private bool active;
|
|
|
+ private bool uiActive;
|
|
|
+
|
|
|
+ static MeidoPhotoStudio()
|
|
|
{
|
|
|
- public static readonly byte[] SceneHeader = Encoding.UTF8.GetBytes("MPSSCENE");
|
|
|
- private static event EventHandler<ScreenshotEventArgs> ScreenshotEvent;
|
|
|
- private const string pluginGuid = "com.habeebweeb.com3d2.meidophotostudio";
|
|
|
- public const string pluginName = "MeidoPhotoStudio";
|
|
|
- public const string pluginVersion = "1.0.0";
|
|
|
- public const string pluginSubVersion = "beta.4.1";
|
|
|
- public const short sceneVersion = 2;
|
|
|
- public const int kankyoMagic = -765;
|
|
|
- public static readonly string pluginString = $"{pluginName} {pluginVersion}";
|
|
|
- public static bool EditMode => currentScene == Constants.Scene.Edit;
|
|
|
- public static event EventHandler<ScreenshotEventArgs> NotifyRawScreenshot;
|
|
|
- private HarmonyLib.Harmony harmony;
|
|
|
- private WindowManager windowManager;
|
|
|
- private SceneManager sceneManager;
|
|
|
- private MeidoManager meidoManager;
|
|
|
- private EnvironmentManager environmentManager;
|
|
|
- private MessageWindowManager messageWindowManager;
|
|
|
- private LightManager lightManager;
|
|
|
- private PropManager propManager;
|
|
|
- private EffectManager effectManager;
|
|
|
- private CameraManager cameraManager;
|
|
|
- private static Constants.Scene currentScene;
|
|
|
- private bool initialized;
|
|
|
- private bool active;
|
|
|
- private bool uiActive;
|
|
|
-
|
|
|
- static MeidoPhotoStudio()
|
|
|
- {
|
|
|
- Input.Register(MpsKey.Screenshot, KeyCode.S, "Take screenshot");
|
|
|
- Input.Register(MpsKey.Activate, KeyCode.F6, "Activate/deactivate MeidoPhotoStudio");
|
|
|
+ Input.Register(MpsKey.Screenshot, KeyCode.S, "Take screenshot");
|
|
|
+ Input.Register(MpsKey.Activate, KeyCode.F6, "Activate/deactivate MeidoPhotoStudio");
|
|
|
|
|
|
- if (!string.IsNullOrEmpty(pluginSubVersion)) pluginString += $"-{pluginSubVersion}";
|
|
|
- }
|
|
|
+ if (!string.IsNullOrEmpty(PluginSubVersion))
|
|
|
+ PluginString += $"-{PluginSubVersion}";
|
|
|
+ }
|
|
|
|
|
|
- private void Awake()
|
|
|
- {
|
|
|
- harmony = HarmonyLib.Harmony.CreateAndPatchAll(typeof(AllProcPropSeqStartPatcher));
|
|
|
- harmony.PatchAll(typeof(BgMgrPatcher));
|
|
|
- harmony.PatchAll(typeof(MeidoManager));
|
|
|
- ScreenshotEvent += OnScreenshotEvent;
|
|
|
- DontDestroyOnLoad(this);
|
|
|
- UnityEngine.SceneManagement.SceneManager.sceneLoaded += OnSceneLoaded;
|
|
|
- UnityEngine.SceneManagement.SceneManager.activeSceneChanged += OnSceneChanged;
|
|
|
- }
|
|
|
+ public static event EventHandler<ScreenshotEventArgs> NotifyRawScreenshot;
|
|
|
|
|
|
- private void Start()
|
|
|
- {
|
|
|
- Constants.Initialize();
|
|
|
- Translation.Initialize(Translation.CurrentLanguage);
|
|
|
- }
|
|
|
+ private static event EventHandler<ScreenshotEventArgs> ScreenshotEvent;
|
|
|
|
|
|
- private void OnSceneLoaded(Scene scene, LoadSceneMode sceneMode)
|
|
|
- {
|
|
|
- currentScene = (Constants.Scene)scene.buildIndex;
|
|
|
- }
|
|
|
+ public static bool EditMode =>
|
|
|
+ currentScene is Constants.Scene.Edit;
|
|
|
|
|
|
- private void OnSceneChanged(Scene current, Scene next)
|
|
|
- {
|
|
|
- if (active) Deactivate(true);
|
|
|
- CameraUtility.MainCamera.ResetCalcNearClip();
|
|
|
- }
|
|
|
+ public static void TakeScreenshot(ScreenshotEventArgs args) =>
|
|
|
+ ScreenshotEvent?.Invoke(null, args);
|
|
|
+
|
|
|
+ public static void TakeScreenshot(string path = "", int superSize = -1, bool hideMaids = false) =>
|
|
|
+ TakeScreenshot(new ScreenshotEventArgs() { Path = path, SuperSize = superSize, HideMaids = hideMaids });
|
|
|
|
|
|
- public byte[] SaveScene(bool environment = false)
|
|
|
+ public byte[] SaveScene(bool environment = false)
|
|
|
+ {
|
|
|
+ if (meidoManager.Busy)
|
|
|
+ return null;
|
|
|
+
|
|
|
+ try
|
|
|
{
|
|
|
- if (meidoManager.Busy) return null;
|
|
|
+ using var memoryStream = new MemoryStream();
|
|
|
+ using var headerWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
|
|
|
+
|
|
|
+ headerWriter.Write(SceneHeader);
|
|
|
|
|
|
- try
|
|
|
+ new SceneMetadata
|
|
|
{
|
|
|
- using var memoryStream = new MemoryStream();
|
|
|
- using var headerWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
|
|
|
+ Version = SceneVersion,
|
|
|
+ Environment = environment,
|
|
|
+ MaidCount = environment ? KankyoMagic : meidoManager.ActiveMeidoList.Count,
|
|
|
+ MMConverted = false,
|
|
|
+ }.WriteMetadata(headerWriter);
|
|
|
|
|
|
- headerWriter.Write(SceneHeader);
|
|
|
+ using var compressionStream = memoryStream.GetCompressionStream();
|
|
|
+ using var dataWriter = new BinaryWriter(compressionStream, Encoding.UTF8);
|
|
|
|
|
|
- new SceneMetadata
|
|
|
- {
|
|
|
- Version = sceneVersion,
|
|
|
- Environment = environment,
|
|
|
- MaidCount = environment ? kankyoMagic : meidoManager.ActiveMeidoList.Count
|
|
|
- }.WriteMetadata(headerWriter);
|
|
|
+ if (!environment)
|
|
|
+ {
|
|
|
+ Serialization.Get<MeidoManager>().Serialize(meidoManager, dataWriter);
|
|
|
+ Serialization.Get<MessageWindowManager>().Serialize(messageWindowManager, dataWriter);
|
|
|
+ Serialization.Get<CameraManager>().Serialize(cameraManager, dataWriter);
|
|
|
+ }
|
|
|
|
|
|
- using var compressionStream = memoryStream.GetCompressionStream();
|
|
|
- using var dataWriter = new BinaryWriter(compressionStream, Encoding.UTF8);
|
|
|
+ Serialization.Get<LightManager>().Serialize(lightManager, dataWriter);
|
|
|
+ Serialization.Get<EffectManager>().Serialize(effectManager, dataWriter);
|
|
|
+ Serialization.Get<EnvironmentManager>().Serialize(environmentManager, dataWriter);
|
|
|
+ Serialization.Get<PropManager>().Serialize(propManager, dataWriter);
|
|
|
|
|
|
- if (!environment)
|
|
|
- {
|
|
|
- Serialization.Get<MeidoManager>().Serialize(meidoManager, dataWriter);
|
|
|
- Serialization.Get<MessageWindowManager>().Serialize(messageWindowManager, dataWriter);
|
|
|
- Serialization.Get<CameraManager>().Serialize(cameraManager, dataWriter);
|
|
|
- }
|
|
|
+ dataWriter.Write("END");
|
|
|
|
|
|
- Serialization.Get<LightManager>().Serialize(lightManager, dataWriter);
|
|
|
- Serialization.Get<EffectManager>().Serialize(effectManager, dataWriter);
|
|
|
- Serialization.Get<EnvironmentManager>().Serialize(environmentManager, dataWriter);
|
|
|
- Serialization.Get<PropManager>().Serialize(propManager, dataWriter);
|
|
|
+ compressionStream.Close();
|
|
|
|
|
|
- dataWriter.Write("END");
|
|
|
+ var data = memoryStream.ToArray();
|
|
|
|
|
|
- compressionStream.Close();
|
|
|
+ return data;
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ Utility.LogError($"Failed to save scene because {e.Message}\n{e.StackTrace}");
|
|
|
|
|
|
- var data = memoryStream.ToArray();
|
|
|
- return data;
|
|
|
- }
|
|
|
- catch (Exception e)
|
|
|
- {
|
|
|
- Utility.LogError($"Failed to save scene because {e.Message}\n{e.StackTrace}");
|
|
|
- return null;
|
|
|
- }
|
|
|
+ return null;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- public void LoadScene(byte[] buffer)
|
|
|
+ public void LoadScene(byte[] buffer)
|
|
|
+ {
|
|
|
+ if (meidoManager.Busy)
|
|
|
{
|
|
|
- if (meidoManager.Busy)
|
|
|
- {
|
|
|
- Utility.LogMessage("Could not apply scene. Meidos are Busy");
|
|
|
- return;
|
|
|
- }
|
|
|
+ Utility.LogMessage("Could not apply scene. Meidos are Busy");
|
|
|
|
|
|
- using var memoryStream = new MemoryStream(buffer);
|
|
|
- using var headerReader = new BinaryReader(memoryStream, Encoding.UTF8);
|
|
|
-
|
|
|
- if (!Utility.BytesEqual(headerReader.ReadBytes(SceneHeader.Length), SceneHeader))
|
|
|
- {
|
|
|
- Utility.LogError("Not a MPS scene!");
|
|
|
- return;
|
|
|
- }
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- var metadata = SceneMetadata.ReadMetadata(headerReader);
|
|
|
+ using var memoryStream = new MemoryStream(buffer);
|
|
|
+ using var headerReader = new BinaryReader(memoryStream, Encoding.UTF8);
|
|
|
|
|
|
- if (metadata.Version > sceneVersion)
|
|
|
- {
|
|
|
- Utility.LogWarning("Cannot load scene. Scene is too new.");
|
|
|
- Utility.LogWarning($"Your version: {sceneVersion}, Scene version: {metadata.Version}");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- using var uncompressed = memoryStream.Decompress();
|
|
|
- using var dataReader = new BinaryReader(uncompressed, Encoding.UTF8);
|
|
|
+ if (!Utility.BytesEqual(headerReader.ReadBytes(SceneHeader.Length), SceneHeader))
|
|
|
+ {
|
|
|
+ Utility.LogError("Not a MPS scene!");
|
|
|
|
|
|
- var header = string.Empty;
|
|
|
- var previousHeader = string.Empty;
|
|
|
- try
|
|
|
- {
|
|
|
- while ((header = dataReader.ReadString()) != "END")
|
|
|
- {
|
|
|
- switch (header)
|
|
|
- {
|
|
|
- case MeidoManager.header:
|
|
|
- Serialization.Get<MeidoManager>().Deserialize(meidoManager, dataReader, metadata);
|
|
|
- break;
|
|
|
- case MessageWindowManager.header:
|
|
|
- Serialization.Get<MessageWindowManager>().Deserialize(messageWindowManager, dataReader, metadata);
|
|
|
- break;
|
|
|
- case CameraManager.header:
|
|
|
- Serialization.Get<CameraManager>().Deserialize(cameraManager, dataReader, metadata);
|
|
|
- break;
|
|
|
- case LightManager.header:
|
|
|
- Serialization.Get<LightManager>().Deserialize(lightManager, dataReader, metadata);
|
|
|
- break;
|
|
|
- case EffectManager.header:
|
|
|
- Serialization.Get<EffectManager>().Deserialize(effectManager, dataReader, metadata);
|
|
|
- break;
|
|
|
- case EnvironmentManager.header:
|
|
|
- Serialization.Get<EnvironmentManager>().Deserialize(environmentManager, dataReader, metadata);
|
|
|
- break;
|
|
|
- case PropManager.header:
|
|
|
- Serialization.Get<PropManager>().Deserialize(propManager, dataReader, metadata);
|
|
|
- break;
|
|
|
- default: throw new Exception($"Unknown header '{header}'");
|
|
|
- }
|
|
|
-
|
|
|
- previousHeader = header;
|
|
|
- }
|
|
|
- }
|
|
|
- catch (Exception e)
|
|
|
- {
|
|
|
- Utility.LogError(
|
|
|
- $"Failed to deserialize scene because {e.Message}"
|
|
|
- + $"\nCurrent header: '{header}'. Last header: '{previousHeader}'"
|
|
|
- );
|
|
|
- Utility.LogError(e.StackTrace);
|
|
|
- }
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- public static void TakeScreenshot(ScreenshotEventArgs args) => ScreenshotEvent?.Invoke(null, args);
|
|
|
+ var metadata = SceneMetadata.ReadMetadata(headerReader);
|
|
|
|
|
|
- public static void TakeScreenshot(string path = "", int superSize = -1, bool hideMaids = false)
|
|
|
+ if (metadata.Version > SceneVersion)
|
|
|
{
|
|
|
- TakeScreenshot(new ScreenshotEventArgs() { Path = path, SuperSize = superSize, HideMaids = hideMaids });
|
|
|
- }
|
|
|
+ Utility.LogWarning("Cannot load scene. Scene is too new.");
|
|
|
+ Utility.LogWarning($"Your version: {SceneVersion}, Scene version: {metadata.Version}");
|
|
|
|
|
|
- private void OnScreenshotEvent(object sender, ScreenshotEventArgs args)
|
|
|
- {
|
|
|
- StartCoroutine(Screenshot(args));
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- private void Update()
|
|
|
+ using var uncompressed = memoryStream.Decompress();
|
|
|
+ using var dataReader = new BinaryReader(uncompressed, Encoding.UTF8);
|
|
|
+
|
|
|
+ var header = string.Empty;
|
|
|
+ var previousHeader = string.Empty;
|
|
|
+
|
|
|
+ try
|
|
|
{
|
|
|
- if (currentScene == Constants.Scene.Daily || currentScene == Constants.Scene.Edit)
|
|
|
+ while ((header = dataReader.ReadString()) is not "END")
|
|
|
{
|
|
|
- if (Input.GetKeyDown(MpsKey.Activate))
|
|
|
+ switch (header)
|
|
|
{
|
|
|
- if (active) Deactivate();
|
|
|
- else Activate();
|
|
|
- }
|
|
|
+ case MeidoManager.Header:
|
|
|
+ Serialization.Get<MeidoManager>().Deserialize(meidoManager, dataReader, metadata);
|
|
|
|
|
|
- if (active)
|
|
|
- {
|
|
|
- if (!Input.Control && !Input.GetKey(MpsKey.CameraLayer) && Input.GetKeyDown(MpsKey.Screenshot))
|
|
|
- {
|
|
|
- TakeScreenshot();
|
|
|
- }
|
|
|
-
|
|
|
- meidoManager.Update();
|
|
|
- cameraManager.Update();
|
|
|
- windowManager.Update();
|
|
|
- effectManager.Update();
|
|
|
- sceneManager.Update();
|
|
|
+ break;
|
|
|
+ case MessageWindowManager.Header:
|
|
|
+ Serialization.Get<MessageWindowManager>()
|
|
|
+ .Deserialize(messageWindowManager, dataReader, metadata);
|
|
|
+
|
|
|
+ break;
|
|
|
+ case CameraManager.Header:
|
|
|
+ Serialization.Get<CameraManager>().Deserialize(cameraManager, dataReader, metadata);
|
|
|
+
|
|
|
+ break;
|
|
|
+ case LightManager.Header:
|
|
|
+ Serialization.Get<LightManager>().Deserialize(lightManager, dataReader, metadata);
|
|
|
+
|
|
|
+ break;
|
|
|
+ case EffectManager.Header:
|
|
|
+ Serialization.Get<EffectManager>().Deserialize(effectManager, dataReader, metadata);
|
|
|
+
|
|
|
+ break;
|
|
|
+ case EnvironmentManager.Header:
|
|
|
+ Serialization.Get<EnvironmentManager>().Deserialize(environmentManager, dataReader, metadata);
|
|
|
+
|
|
|
+ break;
|
|
|
+ case PropManager.Header:
|
|
|
+ Serialization.Get<PropManager>().Deserialize(propManager, dataReader, metadata);
|
|
|
+
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new Exception($"Unknown header '{header}'");
|
|
|
}
|
|
|
+
|
|
|
+ previousHeader = header;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- private IEnumerator Screenshot(ScreenshotEventArgs args)
|
|
|
+ catch (Exception e)
|
|
|
{
|
|
|
- // Hide UI and dragpoints
|
|
|
- GameObject gameMain = GameMain.Instance.gameObject;
|
|
|
- GameObject editUI = UTY.GetChildObject(GameObject.Find("UI Root"), "Camera");
|
|
|
- GameObject fpsViewer = UTY.GetChildObject(gameMain, "SystemUI Root/FpsCounter");
|
|
|
- GameObject sysDialog = UTY.GetChildObject(gameMain, "SystemUI Root/SystemDialog");
|
|
|
- GameObject sysShortcut = UTY.GetChildObject(gameMain, "SystemUI Root/SystemShortcut");
|
|
|
+ Utility.LogError(
|
|
|
+ $"Failed to deserialize scene because {e.Message}\nCurrent header: '{header}'. " +
|
|
|
+ $"Last header: '{previousHeader}'");
|
|
|
|
|
|
- // CameraUtility can hide the edit UI so keep its state for later
|
|
|
- bool editUIWasActive = editUI.activeSelf;
|
|
|
+ Utility.LogError(e.StackTrace);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- uiActive = false;
|
|
|
- editUI.SetActive(false);
|
|
|
- fpsViewer.SetActive(false);
|
|
|
- sysDialog.SetActive(false);
|
|
|
- sysShortcut.SetActive(false);
|
|
|
-
|
|
|
- // Hide maid dragpoints and maids
|
|
|
- List<Meido> activeMeidoList = meidoManager.ActiveMeidoList;
|
|
|
- bool[] isIK = new bool[activeMeidoList.Count];
|
|
|
- bool[] isVisible = new bool[activeMeidoList.Count];
|
|
|
- for (int i = 0; i < activeMeidoList.Count; i++)
|
|
|
- {
|
|
|
- Meido meido = activeMeidoList[i];
|
|
|
- isIK[i] = meido.IK;
|
|
|
- if (meido.IK) meido.IK = false;
|
|
|
+ private void OnSceneLoaded(Scene scene, LoadSceneMode sceneMode) =>
|
|
|
+ currentScene = (Constants.Scene)scene.buildIndex;
|
|
|
|
|
|
- // Hide the maid if needed
|
|
|
- if (args.HideMaids)
|
|
|
- {
|
|
|
- isVisible[i] = meido.Maid.Visible;
|
|
|
- meido.Maid.Visible = false;
|
|
|
- }
|
|
|
- }
|
|
|
+ private void OnSceneChanged(Scene current, Scene next)
|
|
|
+ {
|
|
|
+ if (active)
|
|
|
+ Deactivate(true);
|
|
|
|
|
|
- // Hide other drag points
|
|
|
- bool[] isCubeActive = {
|
|
|
- MeidoDragPointManager.CubeActive,
|
|
|
- PropManager.CubeActive,
|
|
|
- LightManager.CubeActive,
|
|
|
- EnvironmentManager.CubeActive
|
|
|
- };
|
|
|
+ CameraUtility.MainCamera.ResetCalcNearClip();
|
|
|
+ }
|
|
|
|
|
|
- MeidoDragPointManager.CubeActive = false;
|
|
|
- PropManager.CubeActive = false;
|
|
|
- LightManager.CubeActive = false;
|
|
|
- EnvironmentManager.CubeActive = false;
|
|
|
+ private void OnScreenshotEvent(object sender, ScreenshotEventArgs args) =>
|
|
|
+ StartCoroutine(Screenshot(args));
|
|
|
|
|
|
- // hide gizmos
|
|
|
- GizmoRender.UIVisible = false;
|
|
|
+ private void Awake()
|
|
|
+ {
|
|
|
+ harmony = HarmonyLib.Harmony.CreateAndPatchAll(typeof(AllProcPropSeqStartPatcher));
|
|
|
+ harmony.PatchAll(typeof(BgMgrPatcher));
|
|
|
+ harmony.PatchAll(typeof(MeidoManager));
|
|
|
|
|
|
- yield return new WaitForEndOfFrame();
|
|
|
+ ScreenshotEvent += OnScreenshotEvent;
|
|
|
|
|
|
- Texture2D rawScreenshot = null;
|
|
|
+ DontDestroyOnLoad(this);
|
|
|
|
|
|
- if (args.InMemory)
|
|
|
- {
|
|
|
- // Take a screenshot directly to a Texture2D for immediate processing
|
|
|
- RenderTexture renderTexture = new RenderTexture(Screen.width, Screen.height, 24);
|
|
|
- RenderTexture.active = renderTexture;
|
|
|
- CameraUtility.MainCamera.camera.targetTexture = renderTexture;
|
|
|
- CameraUtility.MainCamera.camera.Render();
|
|
|
-
|
|
|
- rawScreenshot = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
|
|
|
- rawScreenshot.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0, false);
|
|
|
- rawScreenshot.Apply();
|
|
|
-
|
|
|
- CameraUtility.MainCamera.camera.targetTexture = null;
|
|
|
- RenderTexture.active = null;
|
|
|
- DestroyImmediate(renderTexture);
|
|
|
- }
|
|
|
+ UnityEngine.SceneManagement.SceneManager.sceneLoaded += OnSceneLoaded;
|
|
|
+ UnityEngine.SceneManagement.SceneManager.activeSceneChanged += OnSceneChanged;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void Start()
|
|
|
+ {
|
|
|
+ Constants.Initialize();
|
|
|
+ Translation.Initialize(Translation.CurrentLanguage);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void Update()
|
|
|
+ {
|
|
|
+ if (currentScene is not Constants.Scene.Daily and not Constants.Scene.Edit)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (Input.GetKeyDown(MpsKey.Activate))
|
|
|
+ {
|
|
|
+ if (active)
|
|
|
+ Deactivate();
|
|
|
else
|
|
|
- {
|
|
|
- // Take Screenshot
|
|
|
- int[] defaultSuperSize = new[] { 1, 2, 4 };
|
|
|
- int selectedSuperSize = args.SuperSize < 1
|
|
|
- ? defaultSuperSize[(int)GameMain.Instance.CMSystem.ScreenShotSuperSize]
|
|
|
- : args.SuperSize;
|
|
|
+ Activate();
|
|
|
+ }
|
|
|
|
|
|
- string path = string.IsNullOrEmpty(args.Path)
|
|
|
- ? Utility.ScreenshotFilename()
|
|
|
- : args.Path;
|
|
|
+ if (!active)
|
|
|
+ return;
|
|
|
|
|
|
- Application.CaptureScreenshot(path, selectedSuperSize);
|
|
|
- }
|
|
|
- GameMain.Instance.SoundMgr.PlaySe("se022.ogg", false);
|
|
|
+ if (!Input.Control && !Input.GetKey(MpsKey.CameraLayer) && Input.GetKeyDown(MpsKey.Screenshot))
|
|
|
+ TakeScreenshot();
|
|
|
|
|
|
- yield return new WaitForEndOfFrame();
|
|
|
+ meidoManager.Update();
|
|
|
+ cameraManager.Update();
|
|
|
+ windowManager.Update();
|
|
|
+ effectManager.Update();
|
|
|
+ sceneManager.Update();
|
|
|
+ }
|
|
|
|
|
|
- // Show UI and dragpoints
|
|
|
- uiActive = true;
|
|
|
- editUI.SetActive(editUIWasActive);
|
|
|
- fpsViewer.SetActive(GameMain.Instance.CMSystem.ViewFps);
|
|
|
- sysDialog.SetActive(true);
|
|
|
- sysShortcut.SetActive(true);
|
|
|
+ private IEnumerator Screenshot(ScreenshotEventArgs args)
|
|
|
+ {
|
|
|
+ // Hide UI and dragpoints
|
|
|
+ var gameMain = GameMain.Instance.gameObject;
|
|
|
+ var editUI = UTY.GetChildObject(GameObject.Find("UI Root"), "Camera");
|
|
|
+ var fpsViewer = UTY.GetChildObject(gameMain, "SystemUI Root/FpsCounter");
|
|
|
+ var sysDialog = UTY.GetChildObject(gameMain, "SystemUI Root/SystemDialog");
|
|
|
+ var sysShortcut = UTY.GetChildObject(gameMain, "SystemUI Root/SystemShortcut");
|
|
|
+
|
|
|
+ // CameraUtility can hide the edit UI so keep its state for later
|
|
|
+ var editUIWasActive = editUI.activeSelf;
|
|
|
+
|
|
|
+ uiActive = false;
|
|
|
+ editUI.SetActive(false);
|
|
|
+ fpsViewer.SetActive(false);
|
|
|
+ sysDialog.SetActive(false);
|
|
|
+ sysShortcut.SetActive(false);
|
|
|
+
|
|
|
+ // Hide maid dragpoints and maids
|
|
|
+ var activeMeidoList = meidoManager.ActiveMeidoList;
|
|
|
+ var isIK = new bool[activeMeidoList.Count];
|
|
|
+ var isVisible = new bool[activeMeidoList.Count];
|
|
|
+
|
|
|
+ for (var i = 0; i < activeMeidoList.Count; i++)
|
|
|
+ {
|
|
|
+ var meido = activeMeidoList[i];
|
|
|
+
|
|
|
+ isIK[i] = meido.IK;
|
|
|
|
|
|
- for (int i = 0; i < activeMeidoList.Count; i++)
|
|
|
+ if (meido.IK)
|
|
|
+ meido.IK = false;
|
|
|
+
|
|
|
+ // Hide the maid if needed
|
|
|
+ if (args.HideMaids)
|
|
|
{
|
|
|
- Meido meido = activeMeidoList[i];
|
|
|
- if (isIK[i]) meido.IK = true;
|
|
|
- if (args.HideMaids && isVisible[i]) meido.Maid.Visible = true;
|
|
|
+ isVisible[i] = meido.Maid.Visible;
|
|
|
+ meido.Maid.Visible = false;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- MeidoDragPointManager.CubeActive = isCubeActive[0];
|
|
|
- PropManager.CubeActive = isCubeActive[1];
|
|
|
- LightManager.CubeActive = isCubeActive[2];
|
|
|
- EnvironmentManager.CubeActive = isCubeActive[3];
|
|
|
+ // Hide other drag points
|
|
|
+ var isCubeActive = new[]
|
|
|
+ {
|
|
|
+ MeidoDragPointManager.CubeActive,
|
|
|
+ PropManager.CubeActive,
|
|
|
+ LightManager.CubeActive,
|
|
|
+ EnvironmentManager.CubeActive,
|
|
|
+ };
|
|
|
|
|
|
- GizmoRender.UIVisible = true;
|
|
|
+ MeidoDragPointManager.CubeActive = false;
|
|
|
+ PropManager.CubeActive = false;
|
|
|
+ LightManager.CubeActive = false;
|
|
|
+ EnvironmentManager.CubeActive = false;
|
|
|
|
|
|
- if (args.InMemory && rawScreenshot)
|
|
|
- NotifyRawScreenshot?.Invoke(null, new ScreenshotEventArgs() { Screenshot = rawScreenshot });
|
|
|
- }
|
|
|
+ // hide gizmos
|
|
|
+ GizmoRender.UIVisible = false;
|
|
|
|
|
|
- private void OnGUI()
|
|
|
- {
|
|
|
- if (uiActive)
|
|
|
- {
|
|
|
- windowManager.DrawWindows();
|
|
|
+ yield return new WaitForEndOfFrame();
|
|
|
|
|
|
- if (DropdownHelper.Visible) DropdownHelper.HandleDropdown();
|
|
|
- if (Modal.Visible) Modal.Draw();
|
|
|
- }
|
|
|
- }
|
|
|
+ Texture2D rawScreenshot = null;
|
|
|
|
|
|
- private void Initialize()
|
|
|
+ if (args.InMemory)
|
|
|
{
|
|
|
- if (initialized) return;
|
|
|
- initialized = true;
|
|
|
+ // Take a screenshot directly to a Texture2D for immediate processing
|
|
|
+ var renderTexture = new RenderTexture(Screen.width, Screen.height, 24);
|
|
|
|
|
|
- meidoManager = new MeidoManager();
|
|
|
- environmentManager = new EnvironmentManager();
|
|
|
- messageWindowManager = new MessageWindowManager();
|
|
|
- messageWindowManager.Activate();
|
|
|
- lightManager = new LightManager();
|
|
|
- propManager = new PropManager(meidoManager);
|
|
|
- sceneManager = new SceneManager(this);
|
|
|
- cameraManager = new CameraManager();
|
|
|
+ RenderTexture.active = renderTexture;
|
|
|
+ CameraUtility.MainCamera.camera.targetTexture = renderTexture;
|
|
|
+ CameraUtility.MainCamera.camera.Render();
|
|
|
|
|
|
- effectManager = new EffectManager();
|
|
|
- effectManager.AddManager<BloomEffectManager>();
|
|
|
- effectManager.AddManager<DepthOfFieldEffectManager>();
|
|
|
- effectManager.AddManager<FogEffectManager>();
|
|
|
- effectManager.AddManager<VignetteEffectManager>();
|
|
|
- effectManager.AddManager<SepiaToneEffectManger>();
|
|
|
- effectManager.AddManager<BlurEffectManager>();
|
|
|
+ rawScreenshot = new(Screen.width, Screen.height, TextureFormat.RGB24, false);
|
|
|
+ rawScreenshot.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0, false);
|
|
|
+ rawScreenshot.Apply();
|
|
|
|
|
|
- meidoManager.BeginCallMeidos += (s, a) => uiActive = false;
|
|
|
- meidoManager.EndCallMeidos += (s, a) => uiActive = true;
|
|
|
+ CameraUtility.MainCamera.camera.targetTexture = null;
|
|
|
+ RenderTexture.active = null;
|
|
|
|
|
|
- MaidSwitcherPane maidSwitcherPane = new MaidSwitcherPane(meidoManager);
|
|
|
+ DestroyImmediate(renderTexture);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // Take Screenshot
|
|
|
+ var defaultSuperSize = new[] { 1, 2, 4 };
|
|
|
+ var selectedSuperSize = args.SuperSize < 1
|
|
|
+ ? defaultSuperSize[(int)GameMain.Instance.CMSystem.ScreenShotSuperSize]
|
|
|
+ : args.SuperSize;
|
|
|
|
|
|
- SceneWindow sceneWindow = new SceneWindow(sceneManager);
|
|
|
+ var path = string.IsNullOrEmpty(args.Path)
|
|
|
+ ? Utility.ScreenshotFilename()
|
|
|
+ : args.Path;
|
|
|
|
|
|
- windowManager = new WindowManager()
|
|
|
- {
|
|
|
- [Constants.Window.Main] = new MainWindow(meidoManager, propManager, lightManager)
|
|
|
- {
|
|
|
- [Constants.Window.Call] = new CallWindowPane(meidoManager),
|
|
|
- [Constants.Window.Pose] = new PoseWindowPane(meidoManager, maidSwitcherPane),
|
|
|
- [Constants.Window.Face] = new FaceWindowPane(meidoManager, maidSwitcherPane),
|
|
|
- [Constants.Window.BG] = new BGWindowPane(
|
|
|
- environmentManager, lightManager, effectManager, sceneWindow, cameraManager
|
|
|
- ),
|
|
|
- [Constants.Window.BG2] = new BG2WindowPane(meidoManager, propManager),
|
|
|
- [Constants.Window.Settings] = new SettingsWindowPane()
|
|
|
- },
|
|
|
- [Constants.Window.Message] = new MessageWindow(messageWindowManager),
|
|
|
- [Constants.Window.Save] = sceneWindow
|
|
|
- };
|
|
|
+ Application.CaptureScreenshot(path, selectedSuperSize);
|
|
|
}
|
|
|
|
|
|
- private void Activate()
|
|
|
- {
|
|
|
- if (!GameMain.Instance.SysDlg.IsDecided) return;
|
|
|
+ GameMain.Instance.SoundMgr.PlaySe("se022.ogg", false);
|
|
|
|
|
|
- if (!initialized) Initialize();
|
|
|
- else
|
|
|
- {
|
|
|
- meidoManager.Activate();
|
|
|
- environmentManager.Activate();
|
|
|
- cameraManager.Activate();
|
|
|
- propManager.Activate();
|
|
|
- lightManager.Activate();
|
|
|
- effectManager.Activate();
|
|
|
- messageWindowManager.Activate();
|
|
|
- windowManager.Activate();
|
|
|
- }
|
|
|
+ yield return new WaitForEndOfFrame();
|
|
|
|
|
|
- uiActive = true;
|
|
|
- active = true;
|
|
|
+ // Show UI and dragpoints
|
|
|
+ uiActive = true;
|
|
|
+ editUI.SetActive(editUIWasActive);
|
|
|
+ fpsViewer.SetActive(GameMain.Instance.CMSystem.ViewFps);
|
|
|
+ sysDialog.SetActive(true);
|
|
|
+ sysShortcut.SetActive(true);
|
|
|
|
|
|
- if (!EditMode)
|
|
|
- {
|
|
|
- GameObject dailyPanel = GameObject.Find("UI Root")?.transform.Find("DailyPanel")?.gameObject;
|
|
|
- if (dailyPanel) dailyPanel.SetActive(false);
|
|
|
- }
|
|
|
- else meidoManager.CallMeidos();
|
|
|
+ for (var i = 0; i < activeMeidoList.Count; i++)
|
|
|
+ {
|
|
|
+ var meido = activeMeidoList[i];
|
|
|
+
|
|
|
+ if (isIK[i])
|
|
|
+ meido.IK = true;
|
|
|
+
|
|
|
+ if (args.HideMaids && isVisible[i])
|
|
|
+ meido.Maid.Visible = true;
|
|
|
}
|
|
|
|
|
|
- private void Deactivate(bool force = false)
|
|
|
- {
|
|
|
- if (meidoManager.Busy || SceneManager.Busy) return;
|
|
|
+ MeidoDragPointManager.CubeActive = isCubeActive[0];
|
|
|
+ PropManager.CubeActive = isCubeActive[1];
|
|
|
+ LightManager.CubeActive = isCubeActive[2];
|
|
|
+ EnvironmentManager.CubeActive = isCubeActive[3];
|
|
|
+
|
|
|
+ GizmoRender.UIVisible = true;
|
|
|
+
|
|
|
+ if (args.InMemory && rawScreenshot)
|
|
|
+ NotifyRawScreenshot?.Invoke(null, new() { Screenshot = rawScreenshot });
|
|
|
+ }
|
|
|
|
|
|
- var sysDialog = GameMain.Instance.SysDlg;
|
|
|
+ private void OnGUI()
|
|
|
+ {
|
|
|
+ if (!uiActive)
|
|
|
+ return;
|
|
|
+
|
|
|
+ windowManager.DrawWindows();
|
|
|
|
|
|
- if (!sysDialog.IsDecided && !force) return;
|
|
|
+ if (DropdownHelper.Visible)
|
|
|
+ DropdownHelper.HandleDropdown();
|
|
|
|
|
|
+ if (Modal.Visible)
|
|
|
+ Modal.Draw();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void Initialize()
|
|
|
+ {
|
|
|
+ if (initialized)
|
|
|
+ return;
|
|
|
+
|
|
|
+ initialized = true;
|
|
|
+
|
|
|
+ meidoManager = new();
|
|
|
+ environmentManager = new();
|
|
|
+ messageWindowManager = new();
|
|
|
+ messageWindowManager.Activate();
|
|
|
+ lightManager = new();
|
|
|
+ propManager = new(meidoManager);
|
|
|
+ sceneManager = new(this);
|
|
|
+ cameraManager = new();
|
|
|
+
|
|
|
+ effectManager = new();
|
|
|
+ effectManager.AddManager<BloomEffectManager>();
|
|
|
+ effectManager.AddManager<DepthOfFieldEffectManager>();
|
|
|
+ effectManager.AddManager<FogEffectManager>();
|
|
|
+ effectManager.AddManager<VignetteEffectManager>();
|
|
|
+ effectManager.AddManager<SepiaToneEffectManager>();
|
|
|
+ effectManager.AddManager<BlurEffectManager>();
|
|
|
+
|
|
|
+ meidoManager.BeginCallMeidos += (_, _) =>
|
|
|
uiActive = false;
|
|
|
- active = false;
|
|
|
|
|
|
- if (force)
|
|
|
- {
|
|
|
- Exit();
|
|
|
- return;
|
|
|
- }
|
|
|
+ meidoManager.EndCallMeidos += (_, _) =>
|
|
|
+ uiActive = true;
|
|
|
|
|
|
- sysDialog.Show(
|
|
|
- string.Format(Translation.Get("systemMessage", "exitConfirm"), pluginName),
|
|
|
- SystemDialog.TYPE.OK_CANCEL,
|
|
|
- Exit,
|
|
|
- () =>
|
|
|
- {
|
|
|
- sysDialog.Close();
|
|
|
- uiActive = true;
|
|
|
- active = true;
|
|
|
- }
|
|
|
- );
|
|
|
+ var maidSwitcherPane = new MaidSwitcherPane(meidoManager);
|
|
|
+ var sceneWindow = new SceneWindow(sceneManager);
|
|
|
|
|
|
- void Exit()
|
|
|
+ windowManager = new()
|
|
|
+ {
|
|
|
+ [Constants.Window.Main] = new MainWindow(meidoManager, propManager, lightManager)
|
|
|
{
|
|
|
- sysDialog.Close();
|
|
|
-
|
|
|
- meidoManager.Deactivate();
|
|
|
- environmentManager.Deactivate();
|
|
|
- cameraManager.Deactivate();
|
|
|
- propManager.Deactivate();
|
|
|
- lightManager.Deactivate();
|
|
|
- effectManager.Deactivate();
|
|
|
- messageWindowManager.Deactivate();
|
|
|
- windowManager.Deactivate();
|
|
|
- Input.Deactivate();
|
|
|
+ [Constants.Window.Call] = new CallWindowPane(meidoManager),
|
|
|
+ [Constants.Window.Pose] = new PoseWindowPane(meidoManager, maidSwitcherPane),
|
|
|
+ [Constants.Window.Face] = new FaceWindowPane(meidoManager, maidSwitcherPane),
|
|
|
+ [Constants.Window.BG] =
|
|
|
+ new BGWindowPane(environmentManager, lightManager, effectManager, sceneWindow, cameraManager),
|
|
|
+ [Constants.Window.BG2] = new BG2WindowPane(meidoManager, propManager),
|
|
|
+ [Constants.Window.Settings] = new SettingsWindowPane(),
|
|
|
+ },
|
|
|
+ [Constants.Window.Message] = new MessageWindow(messageWindowManager),
|
|
|
+ [Constants.Window.Save] = sceneWindow,
|
|
|
+ };
|
|
|
+ }
|
|
|
|
|
|
- Modal.Close();
|
|
|
+ private void Activate()
|
|
|
+ {
|
|
|
+ if (!GameMain.Instance.SysDlg.IsDecided)
|
|
|
+ return;
|
|
|
|
|
|
- Configuration.Config.Save();
|
|
|
+ if (!initialized)
|
|
|
+ {
|
|
|
+ Initialize();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ meidoManager.Activate();
|
|
|
+ environmentManager.Activate();
|
|
|
+ cameraManager.Activate();
|
|
|
+ propManager.Activate();
|
|
|
+ lightManager.Activate();
|
|
|
+ effectManager.Activate();
|
|
|
+ messageWindowManager.Activate();
|
|
|
+ windowManager.Activate();
|
|
|
+ }
|
|
|
|
|
|
- if (EditMode) return;
|
|
|
+ uiActive = true;
|
|
|
+ active = true;
|
|
|
|
|
|
- var dailyPanel = GameObject.Find("UI Root")?.transform.Find("DailyPanel")?.gameObject;
|
|
|
+ if (EditMode)
|
|
|
+ {
|
|
|
+ meidoManager.CallMeidos();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // TODO: Rework this to not use null propagation (UNT008)
|
|
|
+ var dailyPanel = GameObject.Find("UI Root")?.transform.Find("DailyPanel")?.gameObject;
|
|
|
|
|
|
- if (dailyPanel != null)
|
|
|
- dailyPanel.SetActive(true);
|
|
|
- }
|
|
|
+ if (dailyPanel)
|
|
|
+ dailyPanel.SetActive(false);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public class ScreenshotEventArgs : EventArgs
|
|
|
+ private void Deactivate(bool force = false)
|
|
|
{
|
|
|
- public string Path { get; set; } = string.Empty;
|
|
|
- public int SuperSize { get; set; } = -1;
|
|
|
- public bool HideMaids { get; set; }
|
|
|
- public bool InMemory { get; set; } = false;
|
|
|
- public Texture2D Screenshot { get; set; }
|
|
|
+ if (meidoManager.Busy || SceneManager.Busy)
|
|
|
+ return;
|
|
|
+
|
|
|
+ var sysDialog = GameMain.Instance.SysDlg;
|
|
|
+
|
|
|
+ if (!sysDialog.IsDecided && !force)
|
|
|
+ return;
|
|
|
+
|
|
|
+ uiActive = false;
|
|
|
+ active = false;
|
|
|
+
|
|
|
+ if (force)
|
|
|
+ {
|
|
|
+ Exit();
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ sysDialog.Show(
|
|
|
+ string.Format(Translation.Get("systemMessage", "exitConfirm"), PluginName),
|
|
|
+ SystemDialog.TYPE.OK_CANCEL,
|
|
|
+ Exit,
|
|
|
+ Resume);
|
|
|
+
|
|
|
+ void Resume()
|
|
|
+ {
|
|
|
+ sysDialog.Close();
|
|
|
+ uiActive = true;
|
|
|
+ active = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ void Exit()
|
|
|
+ {
|
|
|
+ sysDialog.Close();
|
|
|
+
|
|
|
+ meidoManager.Deactivate();
|
|
|
+ environmentManager.Deactivate();
|
|
|
+ cameraManager.Deactivate();
|
|
|
+ propManager.Deactivate();
|
|
|
+ lightManager.Deactivate();
|
|
|
+ effectManager.Deactivate();
|
|
|
+ messageWindowManager.Deactivate();
|
|
|
+ windowManager.Deactivate();
|
|
|
+ Input.Deactivate();
|
|
|
+
|
|
|
+ Modal.Close();
|
|
|
+
|
|
|
+ Configuration.Config.Save();
|
|
|
+
|
|
|
+ if (EditMode)
|
|
|
+ return;
|
|
|
+
|
|
|
+ // TODO: Rework this to not use null propagation (UNT008)
|
|
|
+ var dailyPanel = GameObject.Find("UI Root")?.transform.Find("DailyPanel")?.gameObject;
|
|
|
+
|
|
|
+ // NOTE: using is (not) for null checks on UnityEngine.Object does not work
|
|
|
+ if (dailyPanel)
|
|
|
+ dailyPanel.SetActive(true);
|
|
|
+ }
|
|
|
}
|
|
|
}
|