diff --git a/NewHorizons/AssetBundle/hearthian system.png b/NewHorizons/AssetBundle/hearthian system.png new file mode 100644 index 00000000..2cb78552 Binary files /dev/null and b/NewHorizons/AssetBundle/hearthian system.png differ diff --git a/NewHorizons/AssetBundle/shader b/NewHorizons/AssetBundle/shader index 148eca35..7f913501 100644 Binary files a/NewHorizons/AssetBundle/shader and b/NewHorizons/AssetBundle/shader differ diff --git a/NewHorizons/AssetBundle/shader.manifest b/NewHorizons/AssetBundle/shader.manifest index cb6d8e25..29c8e572 100644 --- a/NewHorizons/AssetBundle/shader.manifest +++ b/NewHorizons/AssetBundle/shader.manifest @@ -1,9 +1,9 @@ ManifestFileVersion: 0 -CRC: 3597037522 +CRC: 2524157958 Hashes: AssetFileHash: serializedVersion: 2 - Hash: 33678ea445c06b269454371064cc3a5c + Hash: 882ab688c937b5592f590a313cfc0529 TypeTreeHash: serializedVersion: 2 Hash: 6370d3f9de9eca57f523bce048404a46 @@ -14,5 +14,7 @@ ClassTypes: Assets: - Assets/Shaders/SphereTextureWrapper.shader - Assets/Shaders/Ring.shader +- Assets/Shaders/UnlitRing1Pixel.shader - Assets/Shaders/UnlitTransparent.shader +- Assets/Shaders/Ring1Pixel.shader Dependencies: [] diff --git a/NewHorizons/Builder/Atmosphere/CloudsBuilder.cs b/NewHorizons/Builder/Atmosphere/CloudsBuilder.cs index c948ff6e..0dfcaeb7 100644 --- a/NewHorizons/Builder/Atmosphere/CloudsBuilder.cs +++ b/NewHorizons/Builder/Atmosphere/CloudsBuilder.cs @@ -10,6 +10,7 @@ namespace NewHorizons.Atmosphere { static class CloudsBuilder { + private static Shader _sphereShader = null; public static void Make(GameObject body, Sector sector, AtmosphereModule atmo, IModAssets assets) { Texture2D image, cap, ramp; @@ -20,10 +21,10 @@ namespace NewHorizons.Atmosphere if (atmo.CloudCap == null) cap = ImageUtilities.ClearTexture(128, 128); else cap = assets.GetTexture(atmo.CloudCap); - if(atmo.CloudRamp == null) ramp = ImageUtilities.CanvasScaled(image, 1, image.height); + if (atmo.CloudRamp == null) ramp = ImageUtilities.CanvasScaled(image, 1, image.height); else ramp = assets.GetTexture(atmo.CloudRamp); } - catch(Exception e) + catch (Exception e) { Logger.LogError($"Couldn't load Cloud textures, {e.Message}, {e.StackTrace}"); return; @@ -45,15 +46,22 @@ namespace NewHorizons.Atmosphere MeshFilter topMF = cloudsTopGO.AddComponent(); topMF.mesh = GameObject.Find("CloudsTopLayer_GD").GetComponent().mesh; - var tempArray = new Material[2]; MeshRenderer topMR = cloudsTopGO.AddComponent(); - for (int i = 0; i < 2; i++) + if (!atmo.UseBasicCloudShader) { - tempArray[i] = GameObject.Instantiate(GameObject.Find("CloudsTopLayer_GD").GetComponent().sharedMaterials[i]); + var tempArray = new Material[2]; + for (int i = 0; i < 2; i++) + { + tempArray[i] = new Material(GameObject.Find("CloudsTopLayer_GD").GetComponent().sharedMaterials[i]); + } + topMR.sharedMaterials = tempArray; + } + else + { + if (_sphereShader == null) _sphereShader = Main.ShaderBundle.LoadAsset("Assets/Shaders/SphereTextureWrapper.shader"); + topMR.material = new Material(_sphereShader); } - topMR.sharedMaterials = tempArray; - foreach (var material in topMR.sharedMaterials) { material.SetColor("_Color", cloudTint); @@ -63,7 +71,7 @@ namespace NewHorizons.Atmosphere material.SetTexture("_RampTex", ramp); material.SetTexture("_CapTex", cap); } - + RotateTransform topRT = cloudsTopGO.AddComponent(); topRT.SetValue("_localAxis", Vector3.up); @@ -78,20 +86,23 @@ namespace NewHorizons.Atmosphere TessellatedSphereRenderer bottomTSR = cloudsBottomGO.AddComponent(); bottomTSR.tessellationMeshGroup = GameObject.Find("CloudsBottomLayer_GD").GetComponent().tessellationMeshGroup; - bottomTSR.sharedMaterials = GameObject.Find("CloudsBottomLayer_GD").GetComponent().sharedMaterials; + var bottomTSRMaterials = GameObject.Find("CloudsBottomLayer_GD").GetComponent().sharedMaterials; + var bottomTSRTempArray = new Material[bottomTSRMaterials.Length]; + + // It's a bit too green + var bottomColor = atmo.CloudTint.ToColor32(); + bottomColor.g = (byte)(bottomColor.g * 0.5f); + for (int i = 0; i < bottomTSRMaterials.Length; i++) + { + bottomTSRTempArray[i] = new Material(bottomTSRMaterials[i]); + bottomTSRTempArray[i].SetColor("_Color", bottomColor); + bottomTSRTempArray[i].SetColor("_TintColor", bottomColor); + } + bottomTSR.sharedMaterials = bottomTSRTempArray; bottomTSR.maxLOD = 6; bottomTSR.LODBias = 0; bottomTSR.LODRadius = 1f; - // It's always more green than expected - var bottomCloudTint = cloudTint; - bottomCloudTint.g = (byte)(bottomCloudTint.g * 0.8f); - foreach (Material material in bottomTSR.sharedMaterials) - { - material.SetColor("_Color", bottomCloudTint); - material.SetColor("_TintColor", bottomCloudTint); - } - TessSphereSectorToggle bottomTSST = cloudsBottomGO.AddComponent(); bottomTSST.SetValue("_sector", sector); @@ -118,6 +129,8 @@ namespace NewHorizons.Atmosphere // Fix the rotations once the rest is done cloudsMainGO.transform.localRotation = Quaternion.Euler(0, 0, 0); + // For the base shader it has to be rotated idk + if(atmo.UseBasicCloudShader) cloudsMainGO.transform.localRotation = Quaternion.Euler(90, 0, 0); cloudsMainGO.transform.localPosition = Vector3.zero; cloudsBottomGO.transform.localPosition = Vector3.zero; diff --git a/NewHorizons/Builder/Body/AsteroidBeltBuilder.cs b/NewHorizons/Builder/Body/AsteroidBeltBuilder.cs index 868ec3b8..ab2b20ce 100644 --- a/NewHorizons/Builder/Body/AsteroidBeltBuilder.cs +++ b/NewHorizons/Builder/Body/AsteroidBeltBuilder.cs @@ -14,7 +14,7 @@ namespace NewHorizons.Builder.Body { static class AsteroidBeltBuilder { - public static void Make(string bodyName, IPlanetConfig parentConfig, IModAssets assets, string uniqueName) + public static void Make(string bodyName, IPlanetConfig parentConfig, IModHelper mod) { var belt = parentConfig.AsteroidBelt; @@ -62,7 +62,7 @@ namespace NewHorizons.Builder.Body var asteroidConfig = new PlanetConfig(config); if (belt.ProcGen != null) asteroidConfig.ProcGen = belt.ProcGen; - var asteroid = new NewHorizonsBody(new PlanetConfig(config), assets, uniqueName); + var asteroid = new NewHorizonsBody(new PlanetConfig(config), mod); Main.NextPassBodies.Add(asteroid); } } diff --git a/NewHorizons/Builder/Body/RingBuilder.cs b/NewHorizons/Builder/Body/RingBuilder.cs index af987b42..ef2c6b56 100644 --- a/NewHorizons/Builder/Body/RingBuilder.cs +++ b/NewHorizons/Builder/Body/RingBuilder.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; +using NewHorizons.Utility; using Logger = NewHorizons.Utility.Logger; namespace NewHorizons.Builder.Body @@ -13,10 +14,15 @@ namespace NewHorizons.Builder.Body static class RingBuilder { public static Shader RingShader; - public static Shader UnlitShader; + public static Shader RingShader1Pixel; + public static Shader UnlitRingShader; + public static Shader UnlitRingShader1Pixel; public static GameObject Make(GameObject body, RingModule ring, IModAssets assets) { + // Properly lit shader doesnt work yet + ring.Unlit = true; + Texture2D ringTexture; try { @@ -41,20 +47,77 @@ namespace NewHorizons.Builder.Body var texture = ringTexture; if (RingShader == null) RingShader = Main.ShaderBundle.LoadAsset("Assets/Shaders/Ring.shader"); - if (UnlitShader == null) UnlitShader = Main.ShaderBundle.LoadAsset("Assets/Shaders/UnlitTransparent.shader"); + if (UnlitRingShader == null) UnlitRingShader = Main.ShaderBundle.LoadAsset("Assets/Shaders/UnlitTransparent.shader"); + if (RingShader1Pixel == null) RingShader1Pixel = Main.ShaderBundle.LoadAsset("Assets/Shaders/Ring1Pixel.shader"); + if (UnlitRingShader1Pixel == null) UnlitRingShader1Pixel = Main.ShaderBundle.LoadAsset("Assets/Shaders/UnlitRing1Pixel.shader"); + + var mat = new Material(ring.Unlit ? UnlitRingShader : RingShader); + if(texture.width == 1) + { + mat = new Material(ring.Unlit ? UnlitRingShader1Pixel : RingShader1Pixel); + mat.SetFloat("_InnerRadius", 0); + } + ringMR.receiveShadows = !ring.Unlit; - var mat = new Material(ring.Unlit ? UnlitShader : RingShader); mat.mainTexture = texture; - mat.renderQueue = 2895; + mat.renderQueue = 3000; ringMR.material = mat; // Make mesh - var segments = (int)Mathf.Clamp(ring.OuterRadius, 20, 2000); + var segments = (int)Mathf.Clamp(ring.OuterRadius, 20, 2000); BuildRingMesh(ringMesh, segments, ring.InnerRadius, ring.OuterRadius); + if(ring.RotationSpeed != 0) + { + var rot = ringGO.AddComponent(); + rot._degreesPerSecond = ring.RotationSpeed; + rot._localAxis = Vector3.down; + } + return ringGO; } + public static void BuildQuadMesh(Mesh mesh, float width) + { + Vector3[] vertices; + int[] tri; + Vector3[] normals; + Vector2[] uv; + + vertices = new Vector3[4]; + tri = new int[6]; + normals = new Vector3[4]; + uv = new Vector2[4]; + + vertices[0] = new Vector3(-width / 2, 0, -width / 2); + vertices[1] = new Vector3(width / 2, 0, -width / 2); + vertices[2] = new Vector3(-width / 2, 0, width / 2); + vertices[3] = new Vector3(width / 2, 0, width / 2); + + tri[0] = 0; + tri[1] = 2; + tri[2] = 1; + + tri[3] = 2; + tri[4] = 3; + tri[5] = 1; + + normals[0] = Vector3.up; + normals[1] = Vector3.up; + normals[2] = Vector3.up; + normals[3] = Vector3.up; + + uv[0] = new Vector2(0, 0); + uv[1] = new Vector2(1, 0); + uv[2] = new Vector2(0, 1); + uv[3] = new Vector2(1, 1); + + mesh.vertices = vertices; + mesh.triangles = tri; + mesh.normals = normals; + mesh.uv = uv; + } + // Thank you https://github.com/boardtobits/planet-ring-mesh/blob/master/PlanetRing.cs public static void BuildRingMesh(Mesh ringMesh, int segments, float innerRadius, float outerRadius) { @@ -72,8 +135,10 @@ namespace NewHorizons.Builder.Body vertices[i * 2] = vertices[i * 2 + halfway] = new Vector3(x, 0f, z) * outerRadius; vertices[i * 2 + 1] = vertices[i * 2 + 1 + halfway] = new Vector3(x, 0f, z) * innerRadius; - uv[i * 2] = uv[i * 2 + halfway] = new Vector2(progress, 0f); - uv[i * 2 + 1] = uv[i * 2 + 1 + halfway] = new Vector2(progress, 1f); + //uv[i * 2] = uv[i * 2 + halfway] = new Vector2(progress, 0f); + //uv[i * 2 + 1] = uv[i * 2 + 1 + halfway] = new Vector2(progress, 1f); + uv[i * 2] = uv[i * 2 + halfway] = (new Vector2(x, z) / 2f) + Vector2.one * 0.5f; + uv[i * 2 + 1] = uv[i * 2 + 1 + halfway] = new Vector2(0.5f, 0.5f); if (i != segments) { @@ -95,5 +160,40 @@ namespace NewHorizons.Builder.Body ringMesh.uv = uv; ringMesh.RecalculateNormals(); } - } + + public static void BuildCircleMesh(Mesh mesh, int segments, float outerRadius) + { + float angleStep = 360.0f / (float)segments; + List vertexList = new List(); + List triangleList = new List(); + List uv = new List(); + Quaternion quaternion = Quaternion.Euler(0.0f, angleStep, 0f); + // Make first triangle. + vertexList.Add(new Vector3(0.0f, 0.0f, 0.0f)); // 1. Circle center. + vertexList.Add(new Vector3(0.0f, 0f, outerRadius)); // 2. First vertex on circle outline (radius = 0.5f) + vertexList.Add(quaternion * vertexList[1]); // 3. First vertex on circle outline rotated by angle) + // Add triangle indices. + uv.Add(new Vector2(0.5f, 0.5f)); + uv.Add(new Vector2(0.5f, 1f)); + uv.Add(quaternion * uv[1]); + + triangleList.Add(0); + triangleList.Add(1); + triangleList.Add(2); + for (int i = 0; i < segments - 1; i++) + { + triangleList.Add(0); // Index of circle center. + triangleList.Add(vertexList.Count - 1); + triangleList.Add(vertexList.Count); + vertexList.Add(quaternion * vertexList[vertexList.Count - 1]); + uv.Add(quaternion * (uv[uv.Count - 1] - Vector2.one * 0.5f) + Vector3.one * 0.5f); + } + + mesh.vertices = vertexList.ToArray(); + mesh.triangles = triangleList.ToArray(); + mesh.uv = uv.ToArray(); + mesh.RecalculateNormals(); + + } + } } diff --git a/NewHorizons/Builder/Body/SingularityBuilder.cs b/NewHorizons/Builder/Body/SingularityBuilder.cs index 7386a983..0012f695 100644 --- a/NewHorizons/Builder/Body/SingularityBuilder.cs +++ b/NewHorizons/Builder/Body/SingularityBuilder.cs @@ -211,7 +211,7 @@ namespace NewHorizons.Builder.Body whiteHoleVolume._fluidVolume = whiteHoleFluidVolume; whiteHoleVolume._whiteHoleBody = OWRB; whiteHoleVolume._whiteHoleProxyShadowSuperGroup = body.GetComponent(); - + whiteHoleVolumeGO.GetComponent().radius = size; whiteHoleVolume.enabled = true; diff --git a/NewHorizons/Builder/Body/WaterBuilder.cs b/NewHorizons/Builder/Body/WaterBuilder.cs index 8a529135..b72a89f0 100644 --- a/NewHorizons/Builder/Body/WaterBuilder.cs +++ b/NewHorizons/Builder/Body/WaterBuilder.cs @@ -16,12 +16,24 @@ namespace NewHorizons.Builder.Body waterGO.transform.localScale = new Vector3(waterSize, waterSize, waterSize); waterGO.DestroyAllComponents(); + var GDTSR = GameObject.Find("Ocean_GD").GetComponent(); + TessellatedSphereRenderer TSR = waterGO.AddComponent(); - TSR.tessellationMeshGroup = GameObject.Find("Ocean_GD").GetComponent().tessellationMeshGroup; - TSR.sharedMaterials = GameObject.Find("Ocean_GD").GetComponent().sharedMaterials; - TSR.maxLOD = 7; - TSR.LODBias = 2; - TSR.LODRadius = 2f; + TSR.tessellationMeshGroup = GDTSR.tessellationMeshGroup; + + var GDSharedMaterials = GameObject.Find("Ocean_GD").GetComponent()._lowAltitudeMaterials; + var tempArray = new Material[GDSharedMaterials.Length]; + for(int i = 0; i < GDSharedMaterials.Length; i++) + { + tempArray[i] = new Material(GDSharedMaterials[i]); + } + // TODO: Make water module + //tempArray[1].color = Color.red; + + TSR.sharedMaterials = tempArray; + TSR.maxLOD = GDTSR.maxLOD; + TSR.LODBias = GDTSR.LODBias; + TSR.LODRadius = GDTSR.LODRadius; OceanEffectController OEC = waterGO.AddComponent(); OEC.SetValue("_sector", sector); @@ -53,16 +65,15 @@ namespace NewHorizons.Builder.Body fluidVolume.SetValue("_layer", LayerMask.NameToLayer("BassicEffectVolume")); // Because assetbundles were a bitch... - /* GameObject fog1 = new GameObject(); - fog1.transform.parent = waterBase.transform; + fog1.transform.parent = waterGO.transform; fog1.transform.localScale = new Vector3(1, 1, 1); fog1.AddComponent().mesh = GameObject.Find("CloudsTopLayer_GD").GetComponent().mesh; fog1.AddComponent().material = new Material(Shader.Find("Sprites/Default")); fog1.GetComponent().material.color = new Color32(0, 75, 50, 5); GameObject fog2 = new GameObject(); - fog2.transform.parent = waterBase.transform; + fog2.transform.parent = waterGO.transform; fog2.transform.localScale = new Vector3(1.001f, 1.001f, 1.001f); fog2.AddComponent().mesh = GameObject.Find("CloudsTopLayer_GD").GetComponent().mesh; fog2.AddComponent().material = new Material(Shader.Find("Sprites/Default")); @@ -74,7 +85,6 @@ namespace NewHorizons.Builder.Body fog3.AddComponent().mesh = GameObject.Find("CloudsTopLayer_GD").GetComponent().mesh; fog3.AddComponent().material = new Material(Shader.Find("Sprites/Default")); fog3.GetComponent().material.color = new Color32(0, 75, 50, 5); - */ waterGO.transform.localPosition = Vector3.zero; waterGO.SetActive(true); diff --git a/NewHorizons/Builder/General/ShipLogBuilder.cs b/NewHorizons/Builder/General/ShipLogBuilder.cs index 1502b5e6..8d38d135 100644 --- a/NewHorizons/Builder/General/ShipLogBuilder.cs +++ b/NewHorizons/Builder/General/ShipLogBuilder.cs @@ -1,40 +1,53 @@ -using System; +using NewHorizons.Components; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; +using Logger = NewHorizons.Utility.Logger; namespace NewHorizons.Builder.General { public static class ShipLogBuilder { - public static ShipLogDetectiveMode StarChartMode; + public static ShipLogStarChartMode ShipLogStarChartMode; public static void Init() { - /* var shipLogRoot = GameObject.Find("Ship_Body/Module_Cabin/Systems_Cabin/ShipLogPivot/ShipLog/ShipLogPivot/ShipLogCanvas"); - var starChartLog = GameObject.Instantiate(shipLogRoot.transform.Find("DetectiveMode"), shipLogRoot.transform); - starChartLog.transform.name = "StarChartMode"; + + var starChartLog = new GameObject("StarChartMode"); + starChartLog.SetActive(false); + starChartLog.transform.parent = shipLogRoot.transform; + starChartLog.transform.localScale = Vector3.one * 1f; + starChartLog.transform.localPosition = Vector3.zero; + starChartLog.transform.localRotation = Quaternion.Euler(0, 0, 0); + + ShipLogStarChartMode = starChartLog.AddComponent(); + + var reticleImage = GameObject.Instantiate(GameObject.Find("Ship_Body/Module_Cabin/Systems_Cabin/ShipLogPivot/ShipLog/ShipLogPivot/ShipLogCanvas/DetectiveMode/ReticleImage (1)/"), starChartLog.transform); + + var scaleRoot = new GameObject("ScaleRoot"); + scaleRoot.transform.parent = starChartLog.transform; + scaleRoot.transform.localScale = Vector3.one; + scaleRoot.transform.localPosition = Vector3.zero; + scaleRoot.transform.localRotation = Quaternion.Euler(0, 0, 0); - var cardRoot = starChartLog.transform.Find("ScaleRoot").Find("PanRoot"); - foreach(Transform child in cardRoot) - { - GameObject.Destroy(child.gameObject); - } + var panRoot = new GameObject("PanRoot"); + panRoot.transform.parent = scaleRoot.transform; + panRoot.transform.localScale = Vector3.one; + panRoot.transform.localPosition = Vector3.zero; + panRoot.transform.localRotation = Quaternion.Euler(0,0,0); - var cardPrefab = GameObject.Find("Ship_Body/Module_Cabin/Systems_Cabin/ShipLogPivot/ShipLog/ShipLogPivot/ShipLogCanvas/DetectiveMode/ScaleRoot/PanRoot/TH_VILLAGE"); + var centerPromptList = shipLogRoot.transform.Find("ScreenPromptListScaleRoot/ScreenPromptList_Center")?.GetComponent(); + var upperRightPromptList = shipLogRoot.transform.Find("ScreenPromptListScaleRoot/ScreenPromptList_UpperRight")?.GetComponent(); + var oneShotSource = GameObject.Find("Ship_Body/Module_Cabin/Systems_Cabin/ShipLogPivot/ShipLog/OneShotAudio_ShipLog")?.GetComponent(); - var detectiveMode = GameObject.Find("Ship_Body/Module_Cabin/Systems_Cabin/ShipLogPivot/ShipLog/ShipLogPivot/ShipLogCanvas/DetectiveMode/"); - var mapMode = GameObject.Find("Ship_Body/Module_Cabin/Systems_Cabin/ShipLogPivot/ShipLog/ShipLogPivot/ShipLogCanvas/MapMode/"); - - StarChartMode = starChartLog.GetComponent(); - - StarChartMode._cardDict = new Dictionary(); - StarChartMode._cardList = new List(); - StarChartMode._centerPromptList = detectiveMode.GetComponent()._centerPromptList; - */ + ShipLogStarChartMode.Initialize( + centerPromptList, + upperRightPromptList, + oneShotSource); } } } diff --git a/NewHorizons/Builder/General/SpawnPointBuilder.cs b/NewHorizons/Builder/General/SpawnPointBuilder.cs index 0104ea8e..2aec79a5 100644 --- a/NewHorizons/Builder/General/SpawnPointBuilder.cs +++ b/NewHorizons/Builder/General/SpawnPointBuilder.cs @@ -12,7 +12,7 @@ namespace NewHorizons.Builder.General public static SpawnPoint Make(GameObject body, SpawnModule module, OWRigidbody rb) { SpawnPoint playerSpawn = null; - if(module.PlayerSpawnPoint != null) + if(!Main.IsWarping && module.PlayerSpawnPoint != null) { GameObject spawnGO = new GameObject("PlayerSpawnPoint"); spawnGO.transform.parent = body.transform; @@ -44,8 +44,22 @@ namespace NewHorizons.Builder.General ship.transform.position = ship.transform.position + ship.transform.TransformDirection(Vector3.up) * 5f; ship.GetRequiredComponent().SetBodyToMatch(rb); + + if(Main.IsWarping) + { + GameObject playerSpawnGO = new GameObject("PlayerSpawnPoint"); + playerSpawnGO.transform.parent = ship.transform; + playerSpawnGO.layer = 8; + + playerSpawnGO.transform.localPosition = Vector3.zero; + + playerSpawn = playerSpawnGO.AddComponent(); + playerSpawnGO.transform.localRotation = Quaternion.Euler(0,0,0); + + GameObject.FindObjectOfType().SetInitialSpawnPoint(playerSpawn); + } } - if(module.StartWithSuit && !suitUpQueued) + if(!Main.IsWarping && module.StartWithSuit && !suitUpQueued) { suitUpQueued = true; Main.Instance.ModHelper.Events.Unity.FireInNUpdates(() => SuitUp(), 4); @@ -55,9 +69,10 @@ namespace NewHorizons.Builder.General return playerSpawn; } - private static void SuitUp() + public static void SuitUp() { suitUpQueued = false; + if (Locator.GetPlayerController()._isWearingSuit) return; try { var spv = GameObject.Find("Ship_Body/Module_Supplies/Systems_Supplies/ExpeditionGear").GetComponent(); diff --git a/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs b/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs index 039e0ddb..ff5691d9 100644 --- a/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs +++ b/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs @@ -26,7 +26,7 @@ namespace NewHorizons.Builder.Orbital // Rotation initialMotion.SetValue("_initAngularSpeed", orbit.SiderealPeriod == 0 ? 0f : 1.0f / orbit.SiderealPeriod); - var rotationAxis = Quaternion.AngleAxis(orbit.AxialTilt + orbit.Inclination + 90f, Vector3.right) * Vector3.up; + var rotationAxis = Quaternion.AngleAxis(orbit.AxialTilt + 90f, Vector3.right) * Vector3.up; body.transform.rotation = Quaternion.FromToRotation(Vector3.up, rotationAxis); initialMotion._orbitImpulseScalar = 0f; diff --git a/NewHorizons/Builder/Props/SignalBuilder.cs b/NewHorizons/Builder/Props/SignalBuilder.cs index 48f26fca..1aef7f33 100644 --- a/NewHorizons/Builder/Props/SignalBuilder.cs +++ b/NewHorizons/Builder/Props/SignalBuilder.cs @@ -21,6 +21,8 @@ namespace NewHorizons.Builder.Props public static Dictionary SignalFrequencyOverrides; + private static int _nextCustomSignalName; + public static void Reset() { _customSignalNames = new Dictionary(); @@ -66,18 +68,17 @@ namespace NewHorizons.Builder.Props { SignalFrequency.Default, "???" }, { SignalFrequency.WarpCore, "ANTI-GRAVITON FLUX" } }; + _nextCustomSignalName = 200; } public static SignalName AddSignalName(string str) { - if (_availableSignalNames.Count == 0) - { - Logger.LogWarning($"There are no more available SignalName spots. Cannot use name [{str}]."); - return SignalName.Default; - } - Logger.Log($"Registering new signal name [{str}]"); - var newName = _availableSignalNames.Pop(); + SignalName newName; + + if (_availableSignalNames.Count == 0) newName = (SignalName)_nextCustomSignalName++; + else newName = _availableSignalNames.Pop(); + _customSignalNames.Add(newName, str.ToUpper()); return newName; } @@ -88,15 +89,15 @@ namespace NewHorizons.Builder.Props return name; } - public static void Make(GameObject body, Sector sector, SignalModule module, IModAssets assets) + public static void Make(GameObject body, Sector sector, SignalModule module, IModHelper mod) { foreach(var info in module.Signals) { - Make(body, sector, info, assets); + Make(body, sector, info, mod); } } - public static void Make(GameObject body, Sector sector, SignalModule.SignalInfo info, IModAssets assets) + public static void Make(GameObject body, Sector sector, SignalModule.SignalInfo info, IModHelper mod) { var signalGO = new GameObject($"Signal_{info.Name}"); signalGO.SetActive(false); @@ -120,8 +121,7 @@ namespace NewHorizons.Builder.Props { try { - clip = assets.GetAudio(info.AudioFilePath); - + clip = mod.Assets.GetAudio(info.AudioFilePath); } catch(Exception e) { diff --git a/NewHorizons/Components/ShipLogStarChartMode.cs b/NewHorizons/Components/ShipLogStarChartMode.cs new file mode 100644 index 00000000..daf49013 --- /dev/null +++ b/NewHorizons/Components/ShipLogStarChartMode.cs @@ -0,0 +1,278 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using NewHorizons.Utility; +using Logger = NewHorizons.Utility.Logger; +using UnityEngine.UI; +using OWML.Common; + +namespace NewHorizons.Components +{ + public class ShipLogStarChartMode : ShipLogMode + { + private List _starSystemCards = new List(); + private GameObject _cardTemplate = null; + private int _cardIndex = 0; + private OWAudioSource _oneShotSource; + + private float _startPanTime; + private float _panDuration; + private Transform root; + private Vector2 _panRootPos = Vector2.zero; + private Vector2 _startPanPos; + + private ScreenPromptList _upperRightPromptList; + private ScreenPromptList _centerPromptList; + + private ScreenPrompt _detectiveModePrompt; + private ScreenPrompt _targetSystemPrompt; + + private ShipLogEntryCard _target = null; + private NotificationData _warpNotificationData = null; + + public override void Initialize(ScreenPromptList centerPromptList, ScreenPromptList upperRightPromptList, OWAudioSource oneShotSource) + { + root = base.transform.Find("ScaleRoot/PanRoot"); + _oneShotSource = oneShotSource; + + _centerPromptList = centerPromptList; + _upperRightPromptList = upperRightPromptList; + + _detectiveModePrompt = new ScreenPrompt(InputLibrary.swapShipLogMode, "Rumor Mode", 0, ScreenPrompt.DisplayState.Normal, false); + _targetSystemPrompt = new ScreenPrompt(InputLibrary.markEntryOnHUD, "Target", 0, ScreenPrompt.DisplayState.Normal, false); + + GlobalMessenger.AddListener("TargetReferenceFrame", new Callback(OnTargetReferenceFrame)); + GlobalMessenger.AddListener("EnterFlightConsole", new Callback(OnEnterFlightConsole)); + + var x = 0; + foreach (var starSystem in Main.BodyDict.Keys) + { + // Conditions to allow warping into that system (either no planets (stock system) or has a ship spawn point) + var flag = false; + if (starSystem.Equals("SolarSystem")) flag = true; + else + { + foreach(var body in Main.BodyDict[starSystem]) + { + if(body.Config?.Spawn?.ShipSpawnPoint != null) + { + flag = true; + break; + } + } + } + + if(flag) + { + var card = CreateCard(starSystem, root.transform, new Vector2(x++ * 200, 0)); + _starSystemCards.Add(card); + } + } + } + + public void OnDestroy() + { + GlobalMessenger.RemoveListener("TargetReferenceFrame", new Callback(OnTargetReferenceFrame)); + GlobalMessenger.RemoveListener("EnterFlightConsole", new Callback(OnEnterFlightConsole)); + } + + private void OnEnterFlightConsole(OWRigidbody _) + { + if (_target == null) GlobalMessenger.FireEvent("UntargetReferenceFrame"); + } + + public GameObject CreateCard(string uniqueName, Transform parent, Vector2 position) + { + if (_cardTemplate == null) + { + var panRoot = GameObject.Find("Ship_Body/Module_Cabin/Systems_Cabin/ShipLogPivot/ShipLog/ShipLogPivot/ShipLogCanvas/DetectiveMode/ScaleRoot/PanRoot"); + _cardTemplate = GameObject.Instantiate(panRoot.GetComponentInChildren().gameObject); + _cardTemplate.SetActive(false); + } + + var newCard = GameObject.Instantiate(_cardTemplate, parent); + newCard.transform.Find("EntryCardRoot/NameBackground/Name").GetComponent().text = UniqueNameToString(uniqueName); + newCard.SetActive(true); + newCard.transform.name = uniqueName; + newCard.transform.localPosition = new Vector3(position.x, position.y, 40); + newCard.transform.localRotation = Quaternion.Euler(0, 0, 0); + + var shipLogEntryCard = newCard.GetComponent(); + + Texture texture = null; + try + { + if (uniqueName.Equals("SolarSystem")) + { + IModAssets assets = Main.Instance.ModHelper.Assets; + texture = assets.GetTexture("AssetBundle/hearthian system.png"); + } + else + { + IModAssets assets = Main.BodyDict[uniqueName][0].Mod.Assets; + var path = $"planets/{uniqueName}.png"; + Logger.Log($"Trying to load {path}"); + texture = assets.GetTexture(path); + } + } + catch (Exception) { } + + if(texture != null) + { + shipLogEntryCard._photo.sprite = MakeSprite((Texture2D)texture); + newCard.transform.Find("EntryCardRoot/EntryCardBackground/PhotoImage").gameObject.SetActive(true); + } + + shipLogEntryCard._hudMarkerIcon.gameObject.SetActive(false); + shipLogEntryCard._moreToExploreIcon.gameObject.SetActive(false); + shipLogEntryCard._unreadIcon.gameObject.SetActive(false); + + return newCard; + } + + public override bool AllowCancelInput() + { + return true; + } + + public override bool AllowModeSwap() + { + return true; + } + + public override void EnterMode(string entryID = "", List revealQueue = null) + { + base.gameObject.SetActive(true); + + Locator.GetPromptManager().AddScreenPrompt(_detectiveModePrompt, _upperRightPromptList, TextAnchor.MiddleRight, -1, true); + Locator.GetPromptManager().AddScreenPrompt(_targetSystemPrompt, _centerPromptList, TextAnchor.MiddleCenter, -1, true); + } + + public override void ExitMode() + { + base.gameObject.SetActive(false); + + Locator.GetPromptManager().RemoveScreenPrompt(_detectiveModePrompt); + Locator.GetPromptManager().RemoveScreenPrompt(_targetSystemPrompt); + } + + public override string GetFocusedEntryID() + { + return ""; + } + + public override void OnEnterComputer() + { + + } + + public override void OnExitComputer() + { + + } + + public override void UpdateMode() + { + UpdateMapCamera(); + UpdateMapNavigation(); + UpdatePrompts(); + } + + private void UpdateMapCamera() + { + Vector2 b = -_starSystemCards[_cardIndex].transform.localPosition; + float num = Mathf.InverseLerp(_startPanTime, _startPanTime + _panDuration, Time.unscaledTime); + num = 1f - (num - 1f) * (num - 1f); + _panRootPos = Vector2.Lerp(_startPanPos, b, num); + root.transform.localPosition = new Vector3(_panRootPos.x, _panRootPos.y, 0); + } + + private void UpdateMapNavigation() + { + var oldIndex = _cardIndex; + if (OWInput.IsNewlyPressed(InputLibrary.right, InputMode.All) || OWInput.IsNewlyPressed(InputLibrary.right2, InputMode.All)) + { + _cardIndex = Posmod(_cardIndex + 1, _starSystemCards.Count()); + } + else if (OWInput.IsNewlyPressed(InputLibrary.left, InputMode.All) || OWInput.IsNewlyPressed(InputLibrary.left2, InputMode.All)) + { + _cardIndex = Posmod(_cardIndex - 1, _starSystemCards.Count()); + } + + if (oldIndex != _cardIndex) + { + Logger.Log($"Moving to {_cardIndex}"); + _oneShotSource.PlayOneShot(global::AudioType.ShipLogMoveBetweenPlanets, 1f); + _startPanTime = Time.unscaledTime; + _startPanPos = _panRootPos; + _panDuration = 0.25f; + } + } + + private void UpdatePrompts() + { + if (OWInput.IsNewlyPressed(InputLibrary.markEntryOnHUD, InputMode.All)) + { + var shipLogEntryCard = _starSystemCards[_cardIndex].GetComponent(); + + if (_target == shipLogEntryCard) RemoveWarpTarget(); + else SetWarpTarget(shipLogEntryCard); + } + } + + public string UniqueNameToString(string uniqueName) + { + if (uniqueName.Equals("SolarSystem")) return "Hearthian System"; + + var splitString = uniqueName.Split('.'); + if (splitString.Length > 1) splitString = splitString.Skip(1).ToArray(); + var name = string.Join("", splitString).SplitCamelCase(); + return name; + } + + private int Posmod(int a, int b) + { + return (a % b + b) % b; + } + + private Sprite MakeSprite(Texture2D texture) + { + var rect = new Rect(0, 0, texture.width, texture.height); + var pivot = new Vector2(texture.width / 2, texture.height / 2); + return Sprite.Create(texture, rect, pivot); + } + + private void OnTargetReferenceFrame(ReferenceFrame referenceFrame) + { + RemoveWarpTarget(); + } + + private void SetWarpTarget(ShipLogEntryCard shipLogEntryCard) + { + RemoveWarpTarget(false); + _oneShotSource.PlayOneShot(global::AudioType.ShipLogUnmarkLocation, 1f); + _target = shipLogEntryCard; + _target.SetMarkedOnHUD(true); + GlobalMessenger.FireEvent("UntargetReferenceFrame"); + _warpNotificationData = new NotificationData($"AUTOPILOT LOCKED TO:\n{UniqueNameToString(shipLogEntryCard.name).ToUpper()}"); + NotificationManager.SharedInstance.PostNotification(_warpNotificationData, true); + } + + private void RemoveWarpTarget(bool playSound = false) + { + if(_warpNotificationData != null) NotificationManager.SharedInstance.UnpinNotification(_warpNotificationData); + if (_target == null) return; + if(playSound) _oneShotSource.PlayOneShot(global::AudioType.ShipLogMarkLocation, 1f); + _target.SetMarkedOnHUD(false); + _target = null; + } + + public string GetTargetStarSystem() + { + return _target?.name; + } + } +} diff --git a/NewHorizons/Components/ShipWarpController.cs b/NewHorizons/Components/ShipWarpController.cs new file mode 100644 index 00000000..15fa3ebb --- /dev/null +++ b/NewHorizons/Components/ShipWarpController.cs @@ -0,0 +1,160 @@ +using NewHorizons.Builder.General; +using PacificEngine.OW_CommonResources.Game.Player; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NewHorizons.Components +{ + public class ShipWarpController : MonoBehaviour + { + private SingularityController _blackhole; + private SingularityController _whitehole; + private OWAudioSource _oneShotSource; + + private bool _isWarpingIn; + private bool _waitingToBeSeated; + private bool _eyesOpen = false; + + private float _impactDeathSpeed; + + private const float size = 14f; + + public void Start() + { + MakeBlackHole(); + MakeWhiteHole(); + + _oneShotSource = base.gameObject.AddComponent(); + + GlobalMessenger.AddListener("FinishOpenEyes", new Callback(OnFinishOpenEyes)); + } + + private void MakeBlackHole() + { + var blackHoleShader = GameObject.Find("TowerTwin_Body/Sector_TowerTwin/Sector_Tower_HGT/Interactables_Tower_HGT/Interactables_Tower_TT/Prefab_NOM_WarpTransmitter (1)/BlackHole/BlackHoleSingularity").GetComponent().material.shader; + + var blackHoleRender = new GameObject("BlackHoleRender"); + blackHoleRender.transform.parent = base.transform; + blackHoleRender.transform.localPosition = new Vector3(0, 1, 0); + blackHoleRender.transform.localScale = Vector3.one * size; + + var meshFilter = blackHoleRender.AddComponent(); + meshFilter.mesh = GameObject.Find("BrittleHollow_Body/BlackHole_BH/BlackHoleRenderer").GetComponent().mesh; + + var meshRenderer = blackHoleRender.AddComponent(); + if (blackHoleShader == null) blackHoleShader = GameObject.Find("BrittleHollow_Body/BlackHole_BH/BlackHoleRenderer").GetComponent().sharedMaterial.shader; + meshRenderer.material = new Material(blackHoleShader); + meshRenderer.material.SetFloat("_Radius", size * 0.4f); + meshRenderer.material.SetFloat("_MaxDistortRadius", size * 0.95f); + meshRenderer.material.SetFloat("_MassScale", 1); + meshRenderer.material.SetFloat("_DistortFadeDist", size * 0.55f); + + _blackhole = blackHoleRender.AddComponent(); + blackHoleRender.SetActive(true); + } + + private void MakeWhiteHole() + { + var whiteHoleShader = GameObject.Find("TowerTwin_Body/Sector_TowerTwin/Sector_Tower_HGT/Interactables_Tower_HGT/Interactables_Tower_CT/Prefab_NOM_WarpTransmitter/WhiteHole/WhiteHoleSingularity").GetComponent().material.shader; + + var whiteHoleRenderer = new GameObject("WhiteHoleRenderer"); + whiteHoleRenderer.transform.parent = base.transform; + whiteHoleRenderer.transform.localPosition = new Vector3(0, 1, 0); + whiteHoleRenderer.transform.localScale = Vector3.one * size * 2.8f; + + var meshFilter = whiteHoleRenderer.AddComponent(); + meshFilter.mesh = GameObject.Find("WhiteHole_Body/WhiteHoleVisuals/Singularity").GetComponent().mesh; + + var meshRenderer = whiteHoleRenderer.AddComponent(); + if (whiteHoleShader == null) whiteHoleShader = GameObject.Find("WhiteHole_Body/WhiteHoleVisuals/Singularity").GetComponent().sharedMaterial.shader; + meshRenderer.material = new Material(whiteHoleShader); + meshRenderer.sharedMaterial.SetFloat("_Radius", size * 0.4f); + meshRenderer.sharedMaterial.SetFloat("_DistortFadeDist", size); + meshRenderer.sharedMaterial.SetFloat("_MaxDistortRadius", size * 2.8f); + meshRenderer.sharedMaterial.SetColor("_Color", new Color(1.88f, 1.88f, 1.88f, 1f)); + + _whitehole = whiteHoleRenderer.AddComponent(); + whiteHoleRenderer.SetActive(true); + } + + public void OnDestroy() + { + GlobalMessenger.RemoveListener("FinishOpenEyes", new Callback(OnFinishOpenEyes)); + } + + public void WarpIn() + { + // Trying really hard to stop the player from dying while warping in + _impactDeathSpeed = Locator.GetDeathManager()._impactDeathSpeed; + Locator.GetDeathManager()._impactDeathSpeed = Mathf.Infinity; + Locator.GetDeathManager()._invincible = true; + + _isWarpingIn = true; + _whitehole.Create(); + } + + public void WarpOut() + { + _oneShotSource.PlayOneShot(global::AudioType.VesselSingularityCreate, 1f); + _blackhole.Create(); + } + + public void Update() + { + if(_isWarpingIn && LateInitializerManager.isDoneInitializing) + { + _oneShotSource.PlayOneShot(global::AudioType.VesselSingularityCollapse, 1f); + Locator.GetDeathManager()._invincible = true; + if (Main.Instance.CurrentStarSystem.Equals("SolarSystem")) Teleportation.teleportPlayerToShip(); + _whitehole.Create(); + _isWarpingIn = false; + _waitingToBeSeated = true; + if (!Locator.GetPlayerController()._isWearingSuit) + { + SpawnPointBuilder.SuitUp(); + } + } + // Idk whats making this work but now it works and idc + if(_waitingToBeSeated + && PlayerState.IsInsideShip() + && PlayerState.IsWearingSuit() + && base.GetComponentInChildren()?._playerAttachPoint?.GetAttachedOWRigidbody() != null + && !Locator.GetPlayerController()._isMovementLocked + && !Locator.GetPlayerController()._isTurningLocked + && _eyesOpen) + { + Main.Instance.ModHelper.Events.Unity.FireInNUpdates(() => FinishWarp(), 4); + _waitingToBeSeated = false; + } + if (_waitingToBeSeated) + { + if (Player.getResources()._currentHealth < 100f) + { + // Means the player was killed meaning they weren't teleported in + Player.getResources()._currentHealth = 100f; + Teleportation.teleportPlayerToShip(); + } + } + } + + private void OnFinishOpenEyes() + { + _eyesOpen = true; + } + + public void FinishWarp() + { + Locator.GetShipBody().GetComponentInChildren().OnPressInteract(); + _waitingToBeSeated = false; + Main.Instance.ModHelper.Events.Unity.FireInNUpdates(() => _whitehole.Collapse(), 30); + + Locator.GetDeathManager()._impactDeathSpeed = _impactDeathSpeed; + Player.getResources()._currentHealth = 100f; + Locator.GetDeathManager()._invincible = false; + } + } +} diff --git a/NewHorizons/Utility/StarController.cs b/NewHorizons/Components/StarController.cs similarity index 100% rename from NewHorizons/Utility/StarController.cs rename to NewHorizons/Components/StarController.cs diff --git a/NewHorizons/Utility/StarLightController.cs b/NewHorizons/Components/StarLightController.cs similarity index 100% rename from NewHorizons/Utility/StarLightController.cs rename to NewHorizons/Components/StarLightController.cs diff --git a/NewHorizons/External/AtmosphereModule.cs b/NewHorizons/External/AtmosphereModule.cs index 229f9d5b..16ee6e71 100644 --- a/NewHorizons/External/AtmosphereModule.cs +++ b/NewHorizons/External/AtmosphereModule.cs @@ -14,6 +14,7 @@ namespace NewHorizons.External public string Cloud { get; set; } public string CloudCap { get; set; } public string CloudRamp { get; set; } + public bool UseBasicCloudShader { get; set; } public MColor32 FogTint { get; set; } public float FogDensity { get; set; } public float FogSize { get; set; } diff --git a/NewHorizons/External/RingModule.cs b/NewHorizons/External/RingModule.cs index bcb35531..91b22c33 100644 --- a/NewHorizons/External/RingModule.cs +++ b/NewHorizons/External/RingModule.cs @@ -13,6 +13,7 @@ namespace NewHorizons.External public float Inclination { get; set; } public float LongitudeOfAscendingNode { get; set; } public string Texture { get; set; } - public bool Unlit { get; set; } = true; + public bool Unlit { get; set; } = false; + public float RotationSpeed { get; set; } = 0f; } } diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 4c9c3d55..53e41732 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -11,6 +11,7 @@ using NewHorizons.Utility; using OWML.Common; using OWML.ModHelper; using OWML.Utils; +using PacificEngine.OW_CommonResources.Game.Player; using System; using System.Collections.Generic; using System.IO; @@ -28,14 +29,20 @@ namespace NewHorizons public static AssetBundle ShaderBundle; public static Main Instance { get; private set; } - public static List BodyList = new List(); + public static Dictionary> BodyDict = new Dictionary>(); public static List NextPassBodies = new List(); public static Dictionary AssetBundles = new Dictionary(); public static float FurthestOrbit { get; set; } = 50000f; public StarLightController StarLightController { get; private set; } private string _currentStarSystem = "SolarSystem"; + public string CurrentStarSystem { get { return Instance._currentStarSystem; } } + private bool _isChangingStarSystem = false; + private bool _isWarping = false; + public static bool IsWarping { get { return Instance._isWarping; } } + + private ShipWarpController _shipWarpController; public override object GetApi() { @@ -48,6 +55,7 @@ namespace NewHorizons Instance = this; GlobalMessenger.AddListener("PlayerDeath", OnDeath); ShaderBundle = Main.Instance.ModHelper.Assets.LoadBundle("AssetBundle/shader"); + BodyDict["SolarSystem"] = new List(); Utility.Patches.Apply(); @@ -73,12 +81,6 @@ namespace NewHorizons GlobalMessenger.RemoveListener("PlayerDeath", OnDeath); } - void OnDeath(DeathType _) - { - // We reset the solar system on death (unless we just killed the player) - if (!_isChangingStarSystem) _currentStarSystem = "SolarSystem"; - } - void OnSceneLoaded(Scene scene, LoadSceneMode mode) { Logger.Log($"Scene Loaded: {scene.name} {mode}"); @@ -142,8 +144,7 @@ namespace NewHorizons } // Order by stars then planets then moons (not necessary but probably speeds things up, maybe) ALSO only include current star system - var toLoad = BodyList - .Where(b => b.Config.StarSystem.Equals(_currentStarSystem)) + var toLoad = BodyDict[_currentStarSystem] .OrderBy(b => (b.Config.BuildPriority != -1 ? b.Config.BuildPriority : (b.Config.FocalPoint != null ? 0 : @@ -190,18 +191,24 @@ namespace NewHorizons Logger.Log("Done loading bodies"); // I don't know what these do but they look really weird from a distance - Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => PlanetDestroyer.RemoveDistantProxyClones()); + //Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => PlanetDestroyer.RemoveDistantProxyClones()); if(!_currentStarSystem.Equals("SolarSystem")) Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => PlanetDestroyer.RemoveSolarSystem()); var map = GameObject.FindObjectOfType(); if (map != null) map._maxPanDistance = FurthestOrbit * 1.5f; + + _shipWarpController = GameObject.Find("Ship_Body").AddComponent(); + if (_isWarping) Instance.ModHelper.Events.Unity.FireInNUpdates(() => _shipWarpController.WarpIn(), 1); + _isWarping = false; } + #region TitleScreen + public void DisplayBodyOnTitleScreen() { //Try loading one planet why not - var eligible = BodyList.Where(b => b.Config.HeightMap != null || b.Config.Atmosphere?.Cloud != null).ToArray(); + var eligible = BodyDict.Values.SelectMany(x => x).ToList().Where(b => b.Config.HeightMap != null || b.Config.Atmosphere?.Cloud != null).ToArray(); var eligibleCount = eligible.Count(); if (eligibleCount == 0) return; @@ -267,7 +274,7 @@ namespace NewHorizons heightMap.TextureMap = body.Config.Atmosphere.Cloud; } - HeightMapBuilder.Make(titleScreenGO, heightMap, body.Assets); + HeightMapBuilder.Make(titleScreenGO, heightMap, body.Mod.Assets); GameObject pivot = GameObject.Instantiate(GameObject.Find("Scene/Background/PlanetPivot"), GameObject.Find("Scene/Background").transform); pivot.GetComponent()._degreesPerSecond = 10f; @@ -283,7 +290,7 @@ namespace NewHorizons newRing.InnerRadius = size * 1.2f; newRing.OuterRadius = size * 2f; newRing.Texture = body.Config.Ring.Texture; - var ring = RingBuilder.Make(titleScreenGO, newRing, body.Assets); + var ring = RingBuilder.Make(titleScreenGO, newRing, body.Mod.Assets); titleScreenGO.transform.localScale = Vector3.one * 0.8f; } @@ -293,6 +300,29 @@ namespace NewHorizons return titleScreenGO; } + #endregion TitleScreen + + #region Load + public void LoadConfigs(IModBehaviour mod) + { + var folder = mod.ModHelper.Manifest.ModFolderPath; + foreach (var file in Directory.GetFiles(folder + @"planets\", "*.json", SearchOption.AllDirectories)) + { + try + { + var config = mod.ModHelper.Storage.Load(file.Replace(folder, "")); + Logger.Log($"Loaded {config.Name}"); + if (config.Base.CenterOfSolarSystem) config.Orbit.IsStatic = true; + if (!BodyDict.ContainsKey(config.StarSystem)) BodyDict.Add(config.StarSystem, new List()); + BodyDict[config.StarSystem].Add(new NewHorizonsBody(config, mod.ModHelper)); + } + catch (Exception e) + { + Logger.LogError($"Couldn't load {file}: {e.Message}, is your Json formatted correctly?"); + } + } + } + private bool LoadBody(NewHorizonsBody body, bool defaultPrimaryToSun = false) { var stringID = body.Config.Name.ToUpper().Replace(" ", "_").Replace("'", ""); @@ -348,25 +378,6 @@ namespace NewHorizons return true; } - public void LoadConfigs(IModBehaviour mod) - { - var folder = mod.ModHelper.Manifest.ModFolderPath; - foreach (var file in Directory.GetFiles(folder + @"planets\", "*.json", SearchOption.AllDirectories)) - { - try - { - var config = mod.ModHelper.Storage.Load(file.Replace(folder, "")); - Logger.Log($"Loaded {config.Name}"); - if (config.Base.CenterOfSolarSystem) config.Orbit.IsStatic = true; - BodyList.Add(new NewHorizonsBody(config, mod.ModHelper.Assets, mod.ModHelper.Manifest.UniqueName)); - } - catch (Exception e) - { - Logger.LogError($"Couldn't load {file}: {e.Message}, is your Json formatted correctly?"); - } - } - } - public GameObject UpdateBody(NewHorizonsBody body, GameObject go) { Logger.Log($"Updating existing Object {go.name}"); @@ -378,6 +389,10 @@ namespace NewHorizons return SharedGenerateBody(body, go, sector, rb); } + #endregion Load + + #region Body generation + public GameObject GenerateBody(NewHorizonsBody body, bool defaultPrimaryToSun = false) { AstroObject primaryBody; @@ -436,7 +451,7 @@ namespace NewHorizons VolumesBuilder.Make(go, body.Config.Base.SurfaceSize, sphereOfInfluence); if (body.Config.HeightMap != null) - HeightMapBuilder.Make(go, body.Config.HeightMap, body.Assets); + HeightMapBuilder.Make(go, body.Config.HeightMap, body.Mod.Assets); if (body.Config.ProcGen != null) ProcGenBuilder.Make(go, body.Config.ProcGen); @@ -483,10 +498,10 @@ namespace NewHorizons private GameObject SharedGenerateBody(NewHorizonsBody body, GameObject go, Sector sector, OWRigidbody rb) { if (body.Config.Ring != null) - RingBuilder.Make(go, body.Config.Ring, body.Assets); + RingBuilder.Make(go, body.Config.Ring, body.Mod.Assets); if (body.Config.AsteroidBelt != null) - AsteroidBeltBuilder.Make(body.Config.Name, body.Config, body.Assets, body.ModUniqueName); + AsteroidBeltBuilder.Make(body.Config.Name, body.Config, body.Mod); if (body.Config.Base.HasCometTail) CometTailBuilder.Make(go, body.Config.Base, go.GetComponent().GetPrimaryBody()); @@ -502,7 +517,7 @@ namespace NewHorizons if (body.Config.Atmosphere.Cloud != null) { - CloudsBuilder.Make(go, sector, body.Config.Atmosphere, body.Assets); + CloudsBuilder.Make(go, sector, body.Config.Atmosphere, body.Mod.Assets); SunOverrideBuilder.Make(go, sector, body.Config.Base.SurfaceSize, body.Config.Atmosphere); } @@ -516,10 +531,10 @@ namespace NewHorizons } if (body.Config.Props != null) - PropBuilder.Make(go, sector, body.Config, body.Assets, body.ModUniqueName); + PropBuilder.Make(go, sector, body.Config, body.Mod.Assets, body.Mod.Manifest.UniqueName); if (body.Config.Signal != null) - SignalBuilder.Make(go, sector, body.Config.Signal, body.Assets); + SignalBuilder.Make(go, sector, body.Config.Signal, body.Mod); if (body.Config.Base.BlackHoleSize != 0 || body.Config.Singularity != null) SingularityBuilder.Make(go, sector, rb, body.Config); @@ -527,15 +542,29 @@ namespace NewHorizons return go; } - public void ChangeCurrentStarSystem(string newStarSystem) + #endregion Body generation + + #region Change star system + public void ChangeCurrentStarSystem(string newStarSystem, bool warp = false) { + _shipWarpController.WarpOut(); _currentStarSystem = newStarSystem; _isChangingStarSystem = true; - Locator.GetDeathManager().KillPlayer(DeathType.Meditation); + _isWarping = warp; + // If the player isn't in the ship we kill them so they don't move as much + if(!warp) Locator.GetDeathManager().KillPlayer(DeathType.Meditation); LoadManager.LoadSceneAsync(OWScene.SolarSystem, true, LoadManager.FadeType.ToBlack, 0.1f, true); } + + void OnDeath(DeathType _) + { + // We reset the solar system on death (unless we just killed the player) + if (!_isChangingStarSystem) _currentStarSystem = "SolarSystem"; + } + #endregion Change star system } + #region API public class NewHorizonsApi { [Obsolete("Create(Dictionary config) is deprecated, please use Create(Dictionary config, IModBehaviour mod) instead")] @@ -549,9 +578,10 @@ namespace NewHorizons Logger.Log("Recieved API request to create planet " + (string)config["Name"], Logger.LogType.Log); var planetConfig = new PlanetConfig(config); - var body = new NewHorizonsBody(planetConfig, mod != null ? mod.ModHelper.Assets : Main.Instance.ModHelper.Assets, mod.ModHelper.Manifest.UniqueName); + var body = new NewHorizonsBody(planetConfig, mod != null ? mod.ModHelper : Main.Instance.ModHelper); - Main.BodyList.Add(body); + if (!Main.BodyDict.ContainsKey(body.Config.StarSystem)) Main.BodyDict.Add(body.Config.StarSystem, new List()); + Main.BodyDict[body.Config.StarSystem].Add(body); } public void LoadConfigs(IModBehaviour mod) @@ -561,7 +591,8 @@ namespace NewHorizons public GameObject GetPlanet(string name) { - return Main.BodyList.FirstOrDefault(x => x.Config.Name == name).Object; + return Main.BodyDict.Values.SelectMany(x => x).ToList().FirstOrDefault(x => x.Config.Name == name).Object; } } + #endregion API } diff --git a/NewHorizons/Utility/AudioUtility.cs b/NewHorizons/Utility/AudioUtility.cs new file mode 100644 index 00000000..7e3ec22d --- /dev/null +++ b/NewHorizons/Utility/AudioUtility.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NewHorizons.Utility +{ + public static class AudioUtility + { + // Thank you https://answers.unity.com/questions/737002/wav-byte-to-audioclip.html?_ga=2.94866780.194866897.1641426110-1837936344.1635819725 + + // convert two bytes to one float in the range -1 to 1 + static float bytesToFloat(byte firstByte, byte secondByte) + { + // convert two bytes to one short (little endian) + short s = (short)((secondByte << 8) | firstByte); + // convert to range from -1 to (just below) 1 + return s / 32768.0F; + } + + static int bytesToInt(byte[] bytes, int offset = 0) + { + int value = 0; + for (int i = 0; i < 4; i++) + { + value |= ((int)bytes[offset + i]) << (i * 8); + } + return value; + } + + private static byte[] GetBytes(string filename) + { + return File.ReadAllBytes(filename); + } + + // Returns left and right double arrays. 'right' will be null if sound is mono. + public static AudioClip LoadWAV(string filename) + { + var wav = GetBytes(filename); + + // Determine if mono or stereo + var ChannelCount = wav[22]; // Forget byte 23 as 99.999% of WAVs are 1 or 2 channels + + // Get the frequency + var Frequency = bytesToInt(wav, 24); + + // Get past all the other sub chunks to get to the data subchunk: + int pos = 12; // First Subchunk ID from 12 to 16 + + // Keep iterating until we find the data chunk (i.e. 64 61 74 61 ...... (i.e. 100 97 116 97 in decimal)) + while (!(wav[pos] == 100 && wav[pos + 1] == 97 && wav[pos + 2] == 116 && wav[pos + 3] == 97)) + { + pos += 4; + int chunkSize = wav[pos] + wav[pos + 1] * 256 + wav[pos + 2] * 65536 + wav[pos + 3] * 16777216; + pos += 4 + chunkSize; + } + pos += 8; + + // Pos is now positioned to start of actual sound data. + var SampleCount = (wav.Length - pos) / 2; // 2 bytes per sample (16 bit sound mono) + if (ChannelCount == 2) SampleCount /= 2; // 4 bytes per sample (16 bit stereo) + + // Allocate memory (right will be null if only mono sound) + var LeftChannel = new float[SampleCount]; + float[] RightChannel; + if (ChannelCount == 2) RightChannel = new float[SampleCount]; + else RightChannel = null; + + // Write to double array/s: + int i = 0; + while (pos < wav.Length) + { + LeftChannel[i] = bytesToFloat(wav[pos], wav[pos + 1]); + pos += 2; + if (ChannelCount == 2) + { + RightChannel[i] = bytesToFloat(wav[pos], wav[pos + 1]); + pos += 2; + } + i++; + } + + AudioClip audioClip = AudioClip.Create("testSound", SampleCount, 1, Frequency, false); + audioClip.SetData(LeftChannel, 0); + return audioClip; + } + } +} diff --git a/NewHorizons/Utility/NewHorizonBody.cs b/NewHorizons/Utility/NewHorizonBody.cs index 73e494c1..c34786ee 100644 --- a/NewHorizons/Utility/NewHorizonBody.cs +++ b/NewHorizons/Utility/NewHorizonBody.cs @@ -6,16 +6,14 @@ namespace NewHorizons.Utility { public class NewHorizonsBody { - public NewHorizonsBody(IPlanetConfig config, IModAssets assets, string modUniqueName) + public NewHorizonsBody(IPlanetConfig config, IModHelper mod) { Config = config; - Assets = assets; - ModUniqueName = modUniqueName; + Mod = mod; } public IPlanetConfig Config; - public IModAssets Assets; - public string ModUniqueName; + public IModHelper Mod; public GameObject Object; } diff --git a/NewHorizons/Utility/NewHorizonExtensions.cs b/NewHorizons/Utility/NewHorizonExtensions.cs index cfc03a43..3c935dff 100644 --- a/NewHorizons/Utility/NewHorizonExtensions.cs +++ b/NewHorizons/Utility/NewHorizonExtensions.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Reflection; using System.Text; +using System.Text.RegularExpressions; using UnityEngine; namespace NewHorizons.Utility @@ -97,8 +98,20 @@ namespace NewHorizons.Utility { Logger.LogWarning($"Couldn't copy property {targetProperty.Name} from {source} to {destination}"); } - } } + + public static string SplitCamelCase(this string str) + { + return Regex.Replace( + Regex.Replace( + str, + @"(\P{Ll})(\P{Ll}\p{Ll})", + "$1 $2" + ), + @"(\p{Ll})(\P{Ll})", + "$1 $2" + ); + } } } diff --git a/NewHorizons/Utility/Patches.cs b/NewHorizons/Utility/Patches.cs index d8774483..ec86082a 100644 --- a/NewHorizons/Utility/Patches.cs +++ b/NewHorizons/Utility/Patches.cs @@ -51,9 +51,12 @@ namespace NewHorizons.Utility Main.Instance.ModHelper.HarmonyHelper.AddPrefix("Update", typeof(Patches), nameof(Patches.OnShipLogControllerUpdate)); + Main.Instance.ModHelper.HarmonyHelper.AddPrefix("Update", typeof(Patches), nameof(Patches.OnShipCockpitControllerUpdate)); + // Postfixes Main.Instance.ModHelper.HarmonyHelper.AddPostfix("Awake", typeof(Patches), nameof(Patches.OnMapControllerAwake)); Main.Instance.ModHelper.HarmonyHelper.AddPostfix("Awake", typeof(Patches), nameof(Patches.OnOWCameraAwake)); + Main.Instance.ModHelper.HarmonyHelper.AddPostfix("EnterMode", typeof(Patches), nameof(Patches.OnShipLogMapModeEnterMode)); } public static bool GetHUDDisplayName(ReferenceFrame __instance, ref string __result) @@ -347,7 +350,7 @@ namespace NewHorizons.Utility if (__instance._exiting || OWInput.GetInputMode() != InputMode.ShipComputer || __instance._currentMode.AllowCancelInput() && OWInput.IsNewlyPressed(InputLibrary.cancel, InputMode.All) - || ShipLogBuilder.StarChartMode == null) + || ShipLogBuilder.ShipLogStarChartMode == null) return true; __instance._exitPrompt.SetVisibility(__instance._currentMode.AllowCancelInput()); @@ -356,12 +359,14 @@ namespace NewHorizons.Utility { ShipLogMode currentMode = __instance._currentMode; string focusedEntryID = currentMode.GetFocusedEntryID(); + Logger.Log($"[{focusedEntryID}]"); + if (!focusedEntryID.Equals("")) return true; bool flag = currentMode.Equals(__instance._mapMode); __instance._currentMode = (flag ? __instance._detectiveMode : __instance._mapMode); if (currentMode.Equals(__instance._mapMode)) - __instance._currentMode = ShipLogBuilder.StarChartMode; - else if (currentMode.Equals(ShipLogBuilder.StarChartMode)) + __instance._currentMode = ShipLogBuilder.ShipLogStarChartMode; + else if (currentMode.Equals(ShipLogBuilder.ShipLogStarChartMode)) __instance._currentMode = __instance._detectiveMode; else __instance._currentMode = __instance._mapMode; @@ -385,5 +390,27 @@ namespace NewHorizons.Utility } return false; } + + public static bool OnShipCockpitControllerUpdate(ShipCockpitController __instance) + { + if(__instance._playerAtFlightConsole && OWInput.IsNewlyPressed(InputLibrary.autopilot, InputMode.ShipCockpit)) + { + var targetSystem = ShipLogBuilder.ShipLogStarChartMode.GetTargetStarSystem(); + if (targetSystem != null) + { + Main.Instance.ChangeCurrentStarSystem(targetSystem, true); + return false; + } + } + return true; + } + + public static void OnShipLogMapModeEnterMode(ShipLogMapMode __instance) + { + var newPrompt = "Interstellar Mode"; + __instance._detectiveModePrompt.SetText(newPrompt); + var text = GameObject.Find("Ship_Body/Module_Cabin/Systems_Cabin/ShipLogPivot/ShipLog/ShipLogPivot/ShipLogCanvas/ScreenPromptListScaleRoot/ScreenPromptList_UpperRight/ScreenPrompt/Text").GetComponent(); + text.text = newPrompt; + } } } diff --git a/NewHorizons/manifest.json b/NewHorizons/manifest.json index 2c46608f..12edea5e 100644 --- a/NewHorizons/manifest.json +++ b/NewHorizons/manifest.json @@ -3,7 +3,7 @@ "author": "xen", "name": "New Horizons", "uniqueName": "xen.NewHorizons", - "version": "0.5.3", + "version": "0.6.0", "owmlVersion": "2.1.0", "dependencies": [ "PacificEngine.OW_CommonResources" ] }