From 4e7330ce09371b0a9416e24b7b5288f9d2bf9f95 Mon Sep 17 00:00:00 2001 From: FreezeDriedMangoes Date: Wed, 1 Jun 2022 22:23:45 -0400 Subject: [PATCH] implemented basic UI skeleton for the text placer along with basic raycast-based placing functionality --- NewHorizons/Builder/Props/NomaiTextBuilder.cs | 20 ++ NewHorizons/Main.cs | 3 +- NewHorizons/Utility/DebugMenu/DebugMenu.cs | 13 +- .../DebugMenu/DebugMenuDummySubmenu.cs | 10 + .../Utility/DebugMenu/DebugMenuNomaiText.cs | 276 ++++++++++++++---- .../Utility/DebugMenu/DebugMenuPropPlacer.cs | 10 + NewHorizons/Utility/DebugMenu/DebugSubmenu.cs | 4 + .../DebugUtilities/DebugNomaiTextPlacer.cs | 35 +++ .../DebugUtilities/DebugRaycastData.cs | 4 +- .../Utility/DebugUtilities/DebugRaycaster.cs | 4 +- 10 files changed, 310 insertions(+), 69 deletions(-) create mode 100644 NewHorizons/Utility/DebugUtilities/DebugNomaiTextPlacer.cs diff --git a/NewHorizons/Builder/Props/NomaiTextBuilder.cs b/NewHorizons/Builder/Props/NomaiTextBuilder.cs index ee28ddf2..087323eb 100644 --- a/NewHorizons/Builder/Props/NomaiTextBuilder.cs +++ b/NewHorizons/Builder/Props/NomaiTextBuilder.cs @@ -19,6 +19,22 @@ namespace NewHorizons.Builder.Props private static GameObject _computerPrefab; private static GameObject _cairnPrefab; private static GameObject _recorderPrefab; + + private static Dictionary arcInfoToCorrespondingSpawnedGameObject = new Dictionary(); + public static GameObject GetSpawnedGameObjectByNomaiTextArcInfo(PropModule.NomaiTextArcInfo arc) + { + if (!arcInfoToCorrespondingSpawnedGameObject.ContainsKey(arc)) return null; + return arcInfoToCorrespondingSpawnedGameObject[arc]; + } + + private static Dictionary conversationInfoToCorrespondingSpawnedGameObject = new Dictionary(); + public static GameObject GetSpawnedGameObjectByNomaiTextInfo(PropModule.NomaiTextInfo convo) + { + Logger.Log("retrieving wall text obj for " + convo); + if (!conversationInfoToCorrespondingSpawnedGameObject.ContainsKey(convo)) return null; + return conversationInfoToCorrespondingSpawnedGameObject[convo]; + } + private static void InitPrefabs() { @@ -283,6 +299,9 @@ namespace NewHorizons.Builder.Props nomaiWallText.SetTextAsset(text); + Logger.Log("adding to wall text dict: "+info + ", " + nomaiWallTextObj); + conversationInfoToCorrespondingSpawnedGameObject[info] = nomaiWallTextObj; + return nomaiWallText; } @@ -372,6 +391,7 @@ namespace NewHorizons.Builder.Props arc.SetActive(true); arcsByID.Add(textEntryID, arc); + arcInfoToCorrespondingSpawnedGameObject[arcInfo] = arc; } } diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index e685759d..6264a5b7 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -273,7 +273,8 @@ namespace NewHorizons private void OnSystemReady(bool shouldWarpIn) { Locator.GetPlayerBody().gameObject.AddComponent(); - Locator.GetPlayerBody().gameObject.AddComponent(); + Locator.GetPlayerBody().gameObject.AddComponent(); + Locator.GetPlayerBody().gameObject.AddComponent(); Locator.GetPlayerBody().gameObject.AddComponent(); if (shouldWarpIn) _shipWarpController.WarpIn(WearingSuit); diff --git a/NewHorizons/Utility/DebugMenu/DebugMenu.cs b/NewHorizons/Utility/DebugMenu/DebugMenu.cs index f3aa3c61..c0add5af 100644 --- a/NewHorizons/Utility/DebugMenu/DebugMenu.cs +++ b/NewHorizons/Utility/DebugMenu/DebugMenu.cs @@ -20,9 +20,9 @@ namespace NewHorizons.Utility.DebugMenu { private static IModButton pauseMenuButton; - GUIStyle _editorMenuStyle; - GUIStyle _tabBarStyle; - GUIStyle _submenuStyle; + public GUIStyle _editorMenuStyle; + public GUIStyle _tabBarStyle; + public GUIStyle _submenuStyle; internal Vector2 EditorMenuSize = new Vector2(600, 900); bool menuOpen = false; static bool openMenuOnPause; @@ -125,6 +125,7 @@ namespace NewHorizons.Utility.DebugMenu if (GUILayout.Button(mod.ModHelper.Manifest.UniqueName)) { LoadMod(mod); + submenus[activeSubmenu].GainActive(); } } @@ -167,7 +168,13 @@ namespace NewHorizons.Utility.DebugMenu GUI.enabled = i != activeSubmenu; var style = i == activeSubmenu ? _submenuStyle : _tabBarStyle; if (GUILayout.Button(" "+submenus[i].SubmenuName()+" ", style, GUILayout.ExpandWidth(false))) + { + GUI.enabled = true; + submenus[activeSubmenu].LoseActive(); activeSubmenu = i; + submenus[activeSubmenu].GainActive(); + + } GUI.enabled = true; // if (i < submenus.Count-1) GUILayout.Label("|", GUILayout.ExpandWidth(false)); diff --git a/NewHorizons/Utility/DebugMenu/DebugMenuDummySubmenu.cs b/NewHorizons/Utility/DebugMenu/DebugMenuDummySubmenu.cs index 6d0eb404..fab7091f 100644 --- a/NewHorizons/Utility/DebugMenu/DebugMenuDummySubmenu.cs +++ b/NewHorizons/Utility/DebugMenu/DebugMenuDummySubmenu.cs @@ -9,11 +9,21 @@ namespace NewHorizons.Utility.DebugMenu { class DebugMenuDummySubmenu : DebugSubmenu { + internal override void GainActive() + { + + } + internal override void LoseActive() + { + + } + internal override void LoadConfigFile(DebugMenu menu, PlanetConfig config) { } + internal override void OnAwake(DebugMenu menu) { } diff --git a/NewHorizons/Utility/DebugMenu/DebugMenuNomaiText.cs b/NewHorizons/Utility/DebugMenu/DebugMenuNomaiText.cs index f9fb8442..b648d6d9 100644 --- a/NewHorizons/Utility/DebugMenu/DebugMenuNomaiText.cs +++ b/NewHorizons/Utility/DebugMenu/DebugMenuNomaiText.cs @@ -1,3 +1,4 @@ +using NewHorizons.Builder.Props; using NewHorizons.External.Configs; using NewHorizons.External.Modules; using NewHorizons.Utility.DebugUtilities; @@ -7,6 +8,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; +using static NewHorizons.External.Modules.PropModule; namespace NewHorizons.Utility.DebugMenu { @@ -20,19 +22,35 @@ namespace NewHorizons.Utility.DebugMenu class DebugMenuNomaiText : DebugSubmenu { internal DebugRaycaster _drc; + internal DebugNomaiTextPlacer _dnp; - class NomaiTextTree + class ConversationMetadata { - public GameObject text; - public int variation; - public float arcLengthLocationOnParent; + public NomaiTextInfo conversation; + public GameObject conversationGo; + public PlanetConfig planetConfig; - public List children = new List(); + public List spirals; + + public bool collapsed; } - List textTrees = new List(); - NomaiTextTree currentTree; + class SpiralMetadata + { + public NomaiTextArcInfo spiral; + public GameObject spiralGo; + public NomaiTextInfo conversation; + public PlanetConfig planetConfig; + + public string planetName; + public int id; + } + + List conversations = new List(); + + // menu stuff + Vector2 conversationsScrollPosition = new Vector2(); internal override string SubmenuName() { @@ -42,87 +60,223 @@ namespace NewHorizons.Utility.DebugMenu internal override void OnInit(DebugMenu menu) { _drc = menu.GetComponent(); + _dnp = menu.GetComponent(); } internal override void OnAwake(DebugMenu menu) { _drc = menu.GetComponent(); + _dnp = menu.GetComponent(); } - internal override void OnBeginLoadMod(DebugMenu debugMenu) + internal override void OnBeginLoadMod(DebugMenu debugMenu) {} + + internal override void GainActive() {} // intentionally blank. do not set `DebugNomaiTextPlacer.active = true;` here + + internal override void LoseActive() { - DebugPropPlacer.active = true; + DebugNomaiTextPlacer.active = false; } internal override void LoadConfigFile(DebugMenu menu, PlanetConfig config) { - // TODO: populate textTrees + if (config?.Props?.nomaiText == null) return; + + foreach(NomaiTextInfo conversation in config.Props.nomaiText) + { + ConversationMetadata conversationMetadata = new ConversationMetadata() + { + conversation = conversation, + conversationGo = NomaiTextBuilder.GetSpawnedGameObjectByNomaiTextInfo(conversation), + planetConfig = config, + spirals = new List(), + collapsed = true + }; + + Logger.Log("adding go " + conversationMetadata.conversationGo); + + conversations.Add(conversationMetadata); + + var numArcs = conversation.arcInfo == null + ? 0 + : conversation.arcInfo.Length; + for(int id = 0; id < numArcs; id++) + { + NomaiTextArcInfo arcInfo = conversation.arcInfo[id]; + + SpiralMetadata metadata = new SpiralMetadata() + { + spiral = arcInfo, + spiralGo = NomaiTextBuilder.GetSpawnedGameObjectByNomaiTextArcInfo(arcInfo), + conversation = conversation, + planetConfig = config, + planetName = config.name, + id = id + }; + + conversationMetadata.spirals.Add(metadata); + } + } } + + /* + Conversations: + +---------------------------+ + |1) comment | + | |o Visible| |Place| | // replace is greyed out if the user is currently replacing this plane (replacing is done after the user presses G + |2) ... | + +---------------------------+ + + Spirals: + +---------------------------+ + | v Planet - Comment | + | +----------------------+ | + | | v ID | | + | | | | + | | | > Surface 2 | | | + | | x: 5 ---o--- | | + | | y: 2 ---o--- | | + | | theta: 45 ---o--- | | + | | | | + | | o Child o Adult o ...| | + | | variation: o1 o2 o3..| | + | +----------------------+ | + | | + | +----------------------+ | + | | > ID | | + | +----------------------+ | + | | + | ... | + +---------------------------+ + + +---------------------------+ + | > Planet - Comment | + +---------------------------+ + ... + + */ internal override void OnGUI(DebugMenu menu) { - GUILayout.Space(5); + conversationsScrollPosition = GUILayout.BeginScrollView(conversationsScrollPosition); + + for(int i = 0; i < conversations.Count(); i++) + { + ConversationMetadata conversationMeta = conversations[i]; - GUILayout.Space(5); + GUILayout.BeginHorizontal(); + GUILayout.Space(5); + + GUILayout.BeginVertical(menu._editorMenuStyle); + + var arrow = conversationMeta.collapsed ? " > " : " v "; + if (GUILayout.Button(arrow + conversationMeta.planetConfig.name + " - " + i)) + { + conversationMeta.collapsed = !conversationMeta.collapsed; + Logger.Log("BUTTON " + i); + } + + if (!conversationMeta.collapsed) + { + GUILayout.Space(5); + // button to set this one to place with a raycast + GUILayout.Label("Conversation"); + + // only show the button if this conversation is a wall text, do not show it if it is a scroll text or something + if ( + conversationMeta.conversation.type == PropModule.NomaiTextInfo.NomaiTextType.Wall && + GUILayout.Button("Place conversation with G") + ) { + Logger.Log(conversationMeta.conversationGo+" 0"); + DebugNomaiTextPlacer.active = true; + _dnp.onRaycast = (DebugRaycastData data) => + { + var sectorObject = data.hitBodyGameObject.GetComponentInChildren()?.gameObject; + if (sectorObject == null) sectorObject = data.hitBodyGameObject.GetComponentInParent()?.gameObject; + + conversationMeta.conversation.position = data.pos; + conversationMeta.conversation.normal = data.norm; + conversationMeta.conversation.rotation = null; + + DebugNomaiTextPlacer.active = false; + UpdateConversationTransform(conversationMeta, sectorObject); + }; + } + + // + // spirals + // + + for(int j = 0; j < conversationMeta.spirals.Count(); j++) + { + GUILayout.BeginHorizontal(); + GUILayout.Space(5); + GUILayout.BeginVertical(menu._submenuStyle); + + // spiral controls + GUILayout.Label("Spiral"); + + GUILayout.EndVertical(); + GUILayout.Space(5); + GUILayout.EndHorizontal(); + + GUILayout.Space(10); + } + } + + GUILayout.EndVertical(); + + GUILayout.Space(5); + GUILayout.EndHorizontal(); + + GUILayout.Space(10); + } + + GUILayout.EndScrollView(); } - void DrawSpiralControls(int indentationLevel, NomaiTextTree tree) + void UpdateConversationTransform(ConversationMetadata conversationMetadata, GameObject sectorParent) { - GUILayout.BeginHorizontal(); - GUILayout.Space(5*indentationLevel); + var nomaiWallTextObj = conversationMetadata.conversationGo; + var planetGO = sectorParent; + var info = conversationMetadata.conversation; + + Logger.Log(nomaiWallTextObj + " 1"); + Logger.Log(nomaiWallTextObj?.transform + " 2"); + Logger.Log(planetGO + " 3"); + Logger.Log(planetGO?.transform + " 4"); + Logger.Log(info + " 5"); + Logger.Log(info?.position + " 6"); + nomaiWallTextObj.transform.position = planetGO.transform.TransformPoint(info.position); + if (info.normal != null) + { + // In global coordinates (normal was in local coordinates) + var up = (nomaiWallTextObj.transform.position - planetGO.transform.position).normalized; + var forward = planetGO.transform.TransformDirection(info.normal).normalized; - GUILayout.EndHorizontal(); - - tree.children.ForEach(child => DrawSpiralControls(indentationLevel+1, child)); + nomaiWallTextObj.transform.up = up; + nomaiWallTextObj.transform.forward = forward; + } + if (info.rotation != null) + { + nomaiWallTextObj.transform.rotation = planetGO.transform.TransformRotation(Quaternion.Euler(info.rotation)); + } } internal override void PreSave(DebugMenu menu) { - UpdateLoadedConfigsForRecentSystem(menu); - } + conversations.ForEach(metadata => + { + metadata.conversation.position = metadata.conversationGo.transform.localPosition; + metadata.conversation.rotation = metadata.conversationGo.transform.localEulerAngles; + }); - private void UpdateLoadedConfigsForRecentSystem(DebugMenu menu) - { - //var newDetails = _dpp.GetPropsConfigByBody(); - - //Logger.Log("Updating config files. New Details Counts by planet: " + string.Join(", ", newDetails.Keys.Select(x => x + $" ({newDetails[x].Length})"))); - - //Dictionary planetToConfigPath = new Dictionary(); - - //// Get all configs - //foreach (var filePath in menu.loadedConfigFiles.Keys) + // Spirals' configs do not need to be updated. They are always up to date + //spirals.ForEach(metadata => //{ - // Logger.Log("potentially updating copy of config at " + filePath); - - // if (menu.loadedConfigFiles[filePath].starSystem != Main.Instance.CurrentStarSystem) return; - // if (menu.loadedConfigFiles[filePath].name == null || AstroObjectLocator.GetAstroObject(menu.loadedConfigFiles[filePath].name) == null) { Logger.Log("Failed to update copy of config at " + filePath); continue; } - - // var astroObjectName = DebugPropPlacer.GetAstroObjectName(menu.loadedConfigFiles[filePath].name); - // planetToConfigPath[astroObjectName] = filePath; - - // if (!newDetails.ContainsKey(astroObjectName)) continue; - - // if (menu.loadedConfigFiles[filePath].Props == null) menu.loadedConfigFiles[filePath].Props = new External.Modules.PropModule(); - // menu.loadedConfigFiles[filePath].Props.details = newDetails[astroObjectName]; - - // Logger.Log("successfully updated copy of config file for " + astroObjectName); - //} - - //// find all new planets that do not yet have config paths - //var planetsThatDoNotHaveConfigFiles = newDetails.Keys.Where(x => !planetToConfigPath.ContainsKey(x)).ToList(); - //foreach (var astroObjectName in planetsThatDoNotHaveConfigFiles) - //{ - // Logger.Log("Fabricating new config file for " + astroObjectName); - - // var filepath = "planets/" + Main.Instance.CurrentStarSystem + "/" + astroObjectName + ".json"; - // PlanetConfig c = new PlanetConfig(); - // c.starSystem = Main.Instance.CurrentStarSystem; - // c.name = astroObjectName; - // c.Props = new PropModule(); - // c.Props.details = newDetails[astroObjectName]; - - // menu.loadedConfigFiles[filepath] = c; - //} + // metadata.spiral.position = metadata.spiral.position; + // metadata.spiral.zRotation = metadata.spiral.zRotation; + //}); } } } diff --git a/NewHorizons/Utility/DebugMenu/DebugMenuPropPlacer.cs b/NewHorizons/Utility/DebugMenu/DebugMenuPropPlacer.cs index 9c20e146..d98fd8ba 100644 --- a/NewHorizons/Utility/DebugMenu/DebugMenuPropPlacer.cs +++ b/NewHorizons/Utility/DebugMenu/DebugMenuPropPlacer.cs @@ -39,9 +39,19 @@ namespace NewHorizons.Utility.DebugMenu } internal override void OnBeginLoadMod(DebugMenu debugMenu) + { + + } + + internal override void GainActive() { DebugPropPlacer.active = true; } + + internal override void LoseActive() + { + DebugPropPlacer.active = false; + } internal override void LoadConfigFile(DebugMenu menu, PlanetConfig config) { diff --git a/NewHorizons/Utility/DebugMenu/DebugSubmenu.cs b/NewHorizons/Utility/DebugMenu/DebugSubmenu.cs index 0f7e6f5f..a3faceb6 100644 --- a/NewHorizons/Utility/DebugMenu/DebugSubmenu.cs +++ b/NewHorizons/Utility/DebugMenu/DebugSubmenu.cs @@ -18,5 +18,9 @@ namespace NewHorizons.Utility.DebugMenu internal abstract string SubmenuName(); + internal abstract void GainActive(); + internal abstract void LoseActive(); + + } } diff --git a/NewHorizons/Utility/DebugUtilities/DebugNomaiTextPlacer.cs b/NewHorizons/Utility/DebugUtilities/DebugNomaiTextPlacer.cs new file mode 100644 index 00000000..9bf781e8 --- /dev/null +++ b/NewHorizons/Utility/DebugUtilities/DebugNomaiTextPlacer.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using UnityEngine.InputSystem; + +namespace NewHorizons.Utility.DebugUtilities +{ + class DebugNomaiTextPlacer : MonoBehaviour + { + public static bool active; + public Action onRaycast; + + private DebugRaycaster _rc; + + private void Awake() + { + _rc = this.GetComponent(); + } + + void Update() + { + if (!Main.Debug) return; + if (!active) return; + + if (Keyboard.current[Key.G].wasReleasedThisFrame) + { + DebugRaycastData data = _rc.Raycast(); + if (onRaycast != null) onRaycast.Invoke(data); + } + } + } +} diff --git a/NewHorizons/Utility/DebugUtilities/DebugRaycastData.cs b/NewHorizons/Utility/DebugUtilities/DebugRaycastData.cs index e38bcd84..fe8d0e51 100644 --- a/NewHorizons/Utility/DebugUtilities/DebugRaycastData.cs +++ b/NewHorizons/Utility/DebugUtilities/DebugRaycastData.cs @@ -12,7 +12,7 @@ namespace NewHorizons.Utility.DebugUtilities public bool hit; public Vector3 pos; public Vector3 norm; - public Plane plane; + public DebugRaycastPlane plane; public string bodyName; public string bodyPath; @@ -20,7 +20,7 @@ namespace NewHorizons.Utility.DebugUtilities public GameObject hitObject; } - struct Plane + struct DebugRaycastPlane { public Vector3 origin; public Vector3 normal; diff --git a/NewHorizons/Utility/DebugUtilities/DebugRaycaster.cs b/NewHorizons/Utility/DebugUtilities/DebugRaycaster.cs index 6592397c..b2d353c5 100644 --- a/NewHorizons/Utility/DebugUtilities/DebugRaycaster.cs +++ b/NewHorizons/Utility/DebugUtilities/DebugRaycaster.cs @@ -103,7 +103,7 @@ namespace NewHorizons.Utility.DebugUtilities } - internal Plane ConstructPlane(DebugRaycastData data) + internal DebugRaycastPlane ConstructPlane(DebugRaycastData data) { var U = data.pos - Vector3.zero; // U is the local "up" direction. the direction directly away from the center of the planet at this point. // pos is always relative to the body, so the body is considered to be at 0,0,0. var R = data.pos; // R is our origin point for the plane @@ -123,7 +123,7 @@ namespace NewHorizons.Utility.DebugUtilities var u = Vector3.Cross(N, v); - Plane p = new Plane() + DebugRaycastPlane p = new DebugRaycastPlane() { origin = R, normal = N,