diff --git a/NewHorizons/AssetBundle/AssetBundle b/NewHorizons/AssetBundle/AssetBundle deleted file mode 100644 index b0ee6978..00000000 Binary files a/NewHorizons/AssetBundle/AssetBundle and /dev/null differ diff --git a/NewHorizons/AssetBundle/AssetBundle.manifest b/NewHorizons/AssetBundle/AssetBundle.manifest deleted file mode 100644 index 3edbdeeb..00000000 --- a/NewHorizons/AssetBundle/AssetBundle.manifest +++ /dev/null @@ -1,7 +0,0 @@ -ManifestFileVersion: 0 -CRC: 920416521 -AssetBundleManifest: - AssetBundleInfos: - Info_0: - Name: shader - Dependencies: {} diff --git a/NewHorizons/AssetBundle/shader b/NewHorizons/AssetBundle/shader deleted file mode 100644 index 4eea1968..00000000 Binary files a/NewHorizons/AssetBundle/shader and /dev/null differ diff --git a/NewHorizons/AssetBundle/shader.manifest b/NewHorizons/AssetBundle/shader.manifest deleted file mode 100644 index dd99a585..00000000 --- a/NewHorizons/AssetBundle/shader.manifest +++ /dev/null @@ -1,21 +0,0 @@ -ManifestFileVersion: 0 -CRC: 1131808909 -Hashes: - AssetFileHash: - serializedVersion: 2 - Hash: 183a5bb48d2c1afa94657b52eb300f40 - TypeTreeHash: - serializedVersion: 2 - Hash: 55d48f4ad9c3b13330b9eb5ee5686477 -HashAppended: 0 -ClassTypes: -- Class: 48 - Script: {instanceID: 0} -SerializeReferenceClassIdentifiers: [] -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/AssetBundle/xen.newhorizons b/NewHorizons/AssetBundle/xen.newhorizons new file mode 100644 index 00000000..8424b800 Binary files /dev/null and b/NewHorizons/AssetBundle/xen.newhorizons differ diff --git a/NewHorizons/Builder/Atmosphere/CloudsBuilder.cs b/NewHorizons/Builder/Atmosphere/CloudsBuilder.cs index 5289156e..5c968483 100644 --- a/NewHorizons/Builder/Atmosphere/CloudsBuilder.cs +++ b/NewHorizons/Builder/Atmosphere/CloudsBuilder.cs @@ -11,6 +11,7 @@ namespace NewHorizons.Builder.Atmosphere public static class CloudsBuilder { private static Shader _sphereShader = null; + private static Material[] _gdCloudMaterials; public static void Make(GameObject planetGO, Sector sector, AtmosphereModule atmo, IModBehaviour mod) { Texture2D image, cap, ramp; @@ -45,26 +46,31 @@ namespace NewHorizons.Builder.Atmosphere topMF.mesh = GameObject.Find("CloudsTopLayer_GD").GetComponent().mesh; MeshRenderer topMR = cloudsTopGO.AddComponent(); - if (!atmo.UseBasicCloudShader) + + if (_sphereShader == null) _sphereShader = Main.NHAssetBundle.LoadAsset("Assets/Shaders/SphereTextureWrapper.shader"); + if (_gdCloudMaterials == null) _gdCloudMaterials = GameObject.Find("CloudsTopLayer_GD").GetComponent().sharedMaterials; + var tempArray = new Material[2]; + + if (atmo.UseBasicCloudShader) { - var tempArray = new Material[2]; - for (int i = 0; i < 2; i++) - { - var mat = new Material(GameObject.Find("CloudsTopLayer_GD").GetComponent().sharedMaterials[i]); - if (!atmo.ShadowsOnClouds) mat.renderQueue = 2550; - mat.name = atmo.ShadowsOnClouds ? "AdvancedShadowCloud" : "AdvancedCloud"; - tempArray[i] = mat; - } - topMR.sharedMaterials = tempArray; + var material = new Material(_sphereShader); + if (!atmo.ShadowsOnClouds) material.renderQueue = 2550; + material.name = atmo.ShadowsOnClouds ? "BasicShadowCloud" : "BasicCloud"; + + tempArray[0] = material; } else { - if (_sphereShader == null) _sphereShader = Main.ShaderBundle.LoadAsset("Assets/Shaders/SphereTextureWrapper.shader"); - topMR.material = new Material(_sphereShader); - if (!atmo.ShadowsOnClouds) topMR.material.renderQueue = 2550; - topMR.material.name = atmo.ShadowsOnClouds ? "BasicShadowCloud" : "BasicCloud"; + var material = new Material(_gdCloudMaterials[0]); + if (!atmo.ShadowsOnClouds) material.renderQueue = 2550; + material.name = atmo.ShadowsOnClouds ? "AdvancedShadowCloud" : "AdvancedCloud"; + tempArray[0] = material; } + // This is the stencil material for the fog under the clouds + tempArray[1] = new Material(_gdCloudMaterials[1]); + topMR.sharedMaterials = tempArray; + foreach (var material in topMR.sharedMaterials) { material.SetColor("_Color", cloudTint); @@ -80,7 +86,6 @@ namespace NewHorizons.Builder.Atmosphere cloudsTopGO.layer = LayerMask.NameToLayer("IgnoreSun"); } - RotateTransform topRT = cloudsTopGO.AddComponent(); // Idk why but the axis is weird topRT._localAxis = atmo.UseBasicCloudShader ? Vector3.forward : Vector3.up; diff --git a/NewHorizons/Builder/Atmosphere/VolumesBuilder.cs b/NewHorizons/Builder/Atmosphere/VolumesBuilder.cs index 2fb722fc..bb27a514 100644 --- a/NewHorizons/Builder/Atmosphere/VolumesBuilder.cs +++ b/NewHorizons/Builder/Atmosphere/VolumesBuilder.cs @@ -8,8 +8,11 @@ namespace NewHorizons.Builder.Atmosphere { public static class VolumesBuilder { - public static void Make(GameObject planetGO, float innerRadius, float outerRadius, bool useMiniMap) + public static void Make(GameObject planetGO, IPlanetConfig config, float sphereOfInfluence) { + var innerRadius = config.Base.SurfaceSize; + var useMiniMap = config.Base.IsSatellite; + GameObject volumesGO = new GameObject("Volumes"); volumesGO.SetActive(false); volumesGO.transform.parent = planetGO.transform; @@ -23,20 +26,28 @@ namespace NewHorizons.Builder.Atmosphere SS.SetLayer(Shape.Layer.Sector); SS.layerMask = -1; SS.pointChecksOnly = true; - SS.radius = outerRadius; + SS.radius = sphereOfInfluence; rulesetGO.AddComponent(); PlanetoidRuleset PR = rulesetGO.AddComponent(); PR._altitudeFloor = innerRadius; - PR._altitudeCeiling = outerRadius; + PR._altitudeCeiling = sphereOfInfluence; PR._useMinimap = useMiniMap; PR._useAltimeter = useMiniMap; EffectRuleset ER = rulesetGO.AddComponent(); ER._type = EffectRuleset.BubbleType.Underwater; - ER._material = GameObject.Find("RulesetVolumes_GD").GetComponent().GetValue("_material"); - ER._cloudMaterial = GameObject.Find("RulesetVolumes_GD").GetComponent().GetValue("_cloudMaterial"); + var gdRuleset = GameObject.Find("GiantsDeep_Body/Sector_GD/Volumes_GD/RulesetVolumes_GD").GetComponent(); + + ER._material = gdRuleset._material; + + var cloudMaterial = new Material(gdRuleset._cloudMaterial); + if (config.Atmosphere?.CloudTint != null) + { + cloudMaterial.SetColor("_FogColor", config.Atmosphere.CloudTint.ToColor32()); + } + ER._cloudMaterial = cloudMaterial; volumesGO.transform.position = planetGO.transform.position; rulesetGO.SetActive(true); diff --git a/NewHorizons/Builder/Body/CloakBuilder.cs b/NewHorizons/Builder/Body/CloakBuilder.cs index 8080bddb..9a509517 100644 --- a/NewHorizons/Builder/Body/CloakBuilder.cs +++ b/NewHorizons/Builder/Body/CloakBuilder.cs @@ -11,7 +11,7 @@ namespace NewHorizons.Builder.Body { public static class CloakBuilder { - public static void Make(GameObject planetGO, Sector sector, float radius) + public static void Make(GameObject planetGO, Sector sector, OWRigidbody OWRB, float radius) { var cloak = SearchUtilities.Find("RingWorld_Body/CloakingField_IP"); @@ -28,7 +28,7 @@ namespace NewHorizons.Builder.Body cloakFieldController._innerCloakRadius = radius * 900 / 3000f; cloakFieldController._nearCloakRadius = radius * 800 / 3000f; - cloakFieldController._referenceFrameVolume = planetGO.GetAttachedOWRigidbody()._attachedRFVolume; + cloakFieldController._referenceFrameVolume = OWRB._attachedRFVolume; cloakFieldController._exclusionSector = null; var cloakSectorController = newCloak.AddComponent(); diff --git a/NewHorizons/Builder/Body/HeightMapBuilder.cs b/NewHorizons/Builder/Body/HeightMapBuilder.cs index 5fa0e752..88d02e83 100644 --- a/NewHorizons/Builder/Body/HeightMapBuilder.cs +++ b/NewHorizons/Builder/Body/HeightMapBuilder.cs @@ -38,13 +38,14 @@ namespace NewHorizons.Builder.Body cubeSphere.transform.parent = sector?.transform ?? planetGO.transform; cubeSphere.transform.rotation = Quaternion.Euler(90, 0, 0); - Mesh mesh = CubeSphere.Build(51, heightMap, module.MinHeight, module.MaxHeight, module.Stretch); + Vector3 stretch = module.Stretch != null ? (Vector3)module.Stretch : Vector3.one; + Mesh mesh = CubeSphere.Build(51, heightMap, module.MinHeight, module.MaxHeight, stretch); cubeSphere.AddComponent(); cubeSphere.GetComponent().mesh = mesh; // TODO: fix UVs so we can switch to the default shader - if (PlanetShader == null) PlanetShader = Main.ShaderBundle.LoadAsset("Assets/Shaders/SphereTextureWrapper.shader"); + if (PlanetShader == null) PlanetShader = Main.NHAssetBundle.LoadAsset("Assets/Shaders/SphereTextureWrapper.shader"); //if (PlanetShader == null) PlanetShader = Shader.Find("Standard"); var cubeSphereMR = cubeSphere.AddComponent(); diff --git a/NewHorizons/Builder/Body/ProcGenBuilder.cs b/NewHorizons/Builder/Body/ProcGenBuilder.cs index af7222c7..77f38d84 100644 --- a/NewHorizons/Builder/Body/ProcGenBuilder.cs +++ b/NewHorizons/Builder/Body/ProcGenBuilder.cs @@ -12,8 +12,15 @@ namespace NewHorizons.Builder.Body { public static class ProcGenBuilder { + private static Material quantumMaterial; + private static Material iceMaterial; + public static void Make(GameObject planetGO, Sector sector, ProcGenModule module) { + if(quantumMaterial == null) quantumMaterial = SearchUtilities.FindResourceOfTypeAndName("Rock_QM_EyeRock_mat"); + if(iceMaterial == null) iceMaterial = SearchUtilities.FindResourceOfTypeAndName("Rock_BH_IceSpike_mat"); + + GameObject icosphere = new GameObject("Icosphere"); icosphere.transform.parent = sector?.transform ?? planetGO.transform; icosphere.transform.rotation = Quaternion.Euler(90, 0, 0); diff --git a/NewHorizons/Builder/Body/RingBuilder.cs b/NewHorizons/Builder/Body/RingBuilder.cs index c52d102c..a88ddb27 100644 --- a/NewHorizons/Builder/Body/RingBuilder.cs +++ b/NewHorizons/Builder/Body/RingBuilder.cs @@ -49,10 +49,10 @@ namespace NewHorizons.Builder.Body var ringMR = ringGO.AddComponent(); var texture = ringTexture; - if (RingShader == null) RingShader = Main.ShaderBundle.LoadAsset("Assets/Shaders/Ring.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"); + if (RingShader == null) RingShader = Main.NHAssetBundle.LoadAsset("Assets/Shaders/Ring.shader"); + if (UnlitRingShader == null) UnlitRingShader = Main.NHAssetBundle.LoadAsset("Assets/Shaders/UnlitTransparent.shader"); + if (RingShader1Pixel == null) RingShader1Pixel = Main.NHAssetBundle.LoadAsset("Assets/Shaders/Ring1Pixel.shader"); + if (UnlitRingShader1Pixel == null) UnlitRingShader1Pixel = Main.NHAssetBundle.LoadAsset("Assets/Shaders/UnlitRing1Pixel.shader"); var mat = new Material(ring.Unlit ? UnlitRingShader : RingShader); if (texture.width == 1) diff --git a/NewHorizons/Builder/Props/DetailBuilder.cs b/NewHorizons/Builder/Props/DetailBuilder.cs index 5343557d..d2a1b179 100644 --- a/NewHorizons/Builder/Props/DetailBuilder.cs +++ b/NewHorizons/Builder/Props/DetailBuilder.cs @@ -22,7 +22,7 @@ namespace NewHorizons.Builder.Props if (detail.assetBundle != null) { - var prefab = PropBuildManager.LoadPrefab(detail.assetBundle, detail.path, uniqueModName, mod); + var prefab = AssetBundleUtilities.LoadPrefab(detail.assetBundle, detail.path, mod); detailGO = MakeDetail(go, sector, prefab, detail.position, detail.rotation, detail.scale, detail.alignToNormal); } @@ -31,7 +31,7 @@ namespace NewHorizons.Builder.Props try { var prefab = mod.ModHelper.Assets.Get3DObject(detail.objFilePath, detail.mtlFilePath); - PropBuildManager.ReplaceShaders(prefab); + AssetBundleUtilities.ReplaceShaders(prefab); prefab.SetActive(false); detailGO = MakeDetail(go, sector, prefab, detail.position, detail.rotation, detail.scale, detail.alignToNormal); } @@ -51,6 +51,26 @@ namespace NewHorizons.Builder.Props else Logger.LogWarning($"Couldn't find {childPath}"); } } + + if(detailGO != null && detail.removeComponents) + { + // Just swap all the children to a new game object + var newDetailGO = new GameObject(detailGO.name); + newDetailGO.transform.position = detailGO.transform.position; + newDetailGO.transform.parent = detailGO.transform.parent; + // Can't modify parents while looping through children bc idk + var children = new List(); + foreach(Transform child in detailGO.transform) + { + children.Add(child); + } + foreach(var child in children) + { + child.parent = newDetailGO.transform; + } + GameObject.Destroy(detailGO); + detailGO = newDetailGO; + } } public static GameObject MakeDetail(GameObject go, Sector sector, string propToClone, MVector3 position, MVector3 rotation, float scale, bool alignWithNormal) @@ -153,12 +173,11 @@ namespace NewHorizons.Builder.Props prop.transform.position = position == null ? planetGO.transform.position : planetGO.transform.TransformPoint((Vector3)position); Quaternion rot = rotation == null ? Quaternion.identity : Quaternion.Euler((Vector3)rotation); - prop.transform.rotation = planetGO.transform.TransformRotation(Quaternion.identity); if (alignWithNormal) { // Apply the rotation after aligning it with normal var up = planetGO.transform.InverseTransformPoint(prop.transform.position).normalized; - prop.transform.rotation = Quaternion.FromToRotation(prop.transform.up, up) * prop.transform.rotation; + prop.transform.rotation = Quaternion.FromToRotation(Vector3.up, up); prop.transform.rotation *= rot; } else diff --git a/NewHorizons/Builder/Props/PropBuildManager.cs b/NewHorizons/Builder/Props/PropBuildManager.cs index 7bd2a39f..0c45045f 100644 --- a/NewHorizons/Builder/Props/PropBuildManager.cs +++ b/NewHorizons/Builder/Props/PropBuildManager.cs @@ -13,6 +13,7 @@ using NewHorizons.Utility; using OWML.Common; using NewHorizons.Builder.ShipLog; using NewHorizons.External.Configs; +using System.IO; namespace NewHorizons.Builder.Props { @@ -174,59 +175,5 @@ namespace NewHorizons.Builder.Props } } } - - public static GameObject LoadPrefab(string assetBundle, string path, string uniqueModName, IModBehaviour mod) - { - string key = uniqueModName + "." + assetBundle; - AssetBundle bundle; - GameObject prefab; - - try - { - if (Main.AssetBundles.ContainsKey(key)) bundle = Main.AssetBundles[key]; - else - { - bundle = mod.ModHelper.Assets.LoadBundle(assetBundle); - Main.AssetBundles[key] = bundle; - } - } - catch (Exception e) - { - Logger.LogError($"Couldn't load AssetBundle {assetBundle} : {e.Message}"); - return null; - } - - try - { - prefab = bundle.LoadAsset(path); - prefab.SetActive(false); - } - catch (Exception e) - { - Logger.Log($"Couldn't load asset {path} from AssetBundle {assetBundle} : {e.Message}"); - return null; - } - - ReplaceShaders(prefab); - - return prefab; - } - - public static void ReplaceShaders(GameObject prefab) - { - foreach (var renderer in prefab.GetComponentsInChildren(true)) - { - foreach (var material in renderer.sharedMaterials) - { - if (material == null) - { - continue; - } - - var replacementShader = Shader.Find(material.shader.name); - if (replacementShader != null) material.shader = replacementShader; - } - } - } } } diff --git a/NewHorizons/Builder/Props/ScatterBuilder.cs b/NewHorizons/Builder/Props/ScatterBuilder.cs index 4a979455..2df47932 100644 --- a/NewHorizons/Builder/Props/ScatterBuilder.cs +++ b/NewHorizons/Builder/Props/ScatterBuilder.cs @@ -46,7 +46,7 @@ namespace NewHorizons.Builder.Props Random.InitState(propInfo.seed); GameObject prefab; - if (propInfo.assetBundle != null) prefab = PropBuildManager.LoadPrefab(propInfo.assetBundle, propInfo.path, uniqueModName, mod); + if (propInfo.assetBundle != null) prefab = AssetBundleUtilities.LoadPrefab(propInfo.assetBundle, propInfo.path, mod); else prefab = GameObject.Find(propInfo.path); for (int i = 0; i < propInfo.count; i++) { diff --git a/NewHorizons/Builder/StarSystem/SkyboxBuilder.cs b/NewHorizons/Builder/StarSystem/SkyboxBuilder.cs index f3557854..6c69fd82 100644 --- a/NewHorizons/Builder/StarSystem/SkyboxBuilder.cs +++ b/NewHorizons/Builder/StarSystem/SkyboxBuilder.cs @@ -8,46 +8,12 @@ using Object = System.Object; namespace NewHorizons.Builder.StarSystem { - internal class SkyboxBuilder + public class SkyboxBuilder { - public static Material LoadMaterial(string assetBundle, string path, string uniqueModName, IModBehaviour mod) - { - string key = uniqueModName + "." + assetBundle; - AssetBundle bundle; - Material cubemap; - - try - { - if (Main.AssetBundles.ContainsKey(key)) bundle = Main.AssetBundles[key]; - else - { - bundle = mod.ModHelper.Assets.LoadBundle(assetBundle); - Main.AssetBundles[key] = bundle; - } - } - catch (Exception e) - { - Logger.LogError($"Couldn't load AssetBundle {assetBundle} : {e.Message}"); - return null; - } - - try - { - cubemap = bundle.LoadAsset(path); - } - catch (Exception e) - { - Logger.Log($"Couldn't load asset {path} from AssetBundle {assetBundle} : {e.Message}"); - return null; - } - - return cubemap; - } - public static void Make(StarSystemConfig.SkyboxConfig info, IModBehaviour mod) { Logger.Log("Building Skybox"); - Material skyBoxMaterial = LoadMaterial(info.assetBundle, info.path, mod.ModHelper.Manifest.UniqueName, mod); + var skyBoxMaterial = AssetBundleUtilities.Load(info.assetBundle, info.path, mod); RenderSettings.skybox = skyBoxMaterial; DynamicGI.UpdateEnvironment(); Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => diff --git a/NewHorizons/Components/TimeLoopController.cs b/NewHorizons/Components/TimeLoopController.cs new file mode 100644 index 00000000..0ad6a7ef --- /dev/null +++ b/NewHorizons/Components/TimeLoopController.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NewHorizons.Components +{ + public class TimeLoopController : MonoBehaviour + { + private float _supernovaTime; + private bool _supernovaHappened; + + public void Start() + { + GlobalMessenger.AddListener("TriggerSupernova", OnTriggerSupernova); + } + + public void Update() + { + // Stock gives like 33 seconds after the sun collapses + // Gonna assume it takes like 7 seconds to collapse after the supernova trigger + if(_supernovaHappened && Time.time > _supernovaTime + 40f) + { + Locator.GetDeathManager().KillPlayer(DeathType.TimeLoop); + } + } + + public void OnTriggerSupernova() + { + _supernovaHappened = true; + _supernovaTime = Time.time; + } + } +} diff --git a/NewHorizons/External/Configs/StarSystemConfig.cs b/NewHorizons/External/Configs/StarSystemConfig.cs index f0c2be3a..1447dd8d 100644 --- a/NewHorizons/External/Configs/StarSystemConfig.cs +++ b/NewHorizons/External/Configs/StarSystemConfig.cs @@ -13,6 +13,7 @@ namespace NewHorizons.External.Configs public bool startHere = false; public bool destroyStockPlanets = true; public string factRequiredForWarp; + public bool enableTimeLoop = true; public NomaiCoordinates coords; public SkyboxConfig skybox; diff --git a/NewHorizons/External/HeightMapModule.cs b/NewHorizons/External/HeightMapModule.cs index ea81c16e..f859e949 100644 --- a/NewHorizons/External/HeightMapModule.cs +++ b/NewHorizons/External/HeightMapModule.cs @@ -9,6 +9,6 @@ namespace NewHorizons.External public string TextureMap { get; set; } public float MinHeight { get; set; } public float MaxHeight { get; set; } - public MVector3 Stretch { get; set; } = (MVector3)Vector3.one; + public MVector3 Stretch { get; set; } } } diff --git a/NewHorizons/External/PropModule.cs b/NewHorizons/External/PropModule.cs index 80b982e2..2bf7cbc3 100644 --- a/NewHorizons/External/PropModule.cs +++ b/NewHorizons/External/PropModule.cs @@ -43,6 +43,7 @@ namespace NewHorizons.External public float scale { get; set; } = 1f; public bool alignToNormal; public string[] removeChildren; + public bool removeComponents; } public class RaftInfo diff --git a/NewHorizons/Handlers/PlanetCreationHandler.cs b/NewHorizons/Handlers/PlanetCreationHandler.cs index 5ae66008..fbd1f0ab 100644 --- a/NewHorizons/Handlers/PlanetCreationHandler.cs +++ b/NewHorizons/Handlers/PlanetCreationHandler.cs @@ -318,7 +318,7 @@ namespace NewHorizons.Handlers MarkerBuilder.Make(go, body.Config.Name, body.Config); } - VolumesBuilder.Make(go, body.Config.Base.SurfaceSize, sphereOfInfluence, !body.Config.Base.IsSatellite); + VolumesBuilder.Make(go, body.Config, sphereOfInfluence); if (body.Config.FocalPoint != null) { @@ -498,7 +498,7 @@ namespace NewHorizons.Handlers // Has to go last probably if (body.Config.Base.CloakRadius != 0f) { - CloakBuilder.Make(go, sector, body.Config.Base.CloakRadius); + CloakBuilder.Make(go, sector, rb, body.Config.Base.CloakRadius); } return go; @@ -586,6 +586,7 @@ namespace NewHorizons.Handlers { foreach (var childChild in AstroObjectLocator.GetChildren(childAO)) { + if (childChild == null) continue; var dPos = childChild.transform.position - child.transform.position; childChild.transform.position = go.transform.position + relativeMoonPositions[i] + dPos; } diff --git a/NewHorizons/Handlers/PlanetDestructionHandler.cs b/NewHorizons/Handlers/PlanetDestructionHandler.cs index 44a63647..9b79631d 100644 --- a/NewHorizons/Handlers/PlanetDestructionHandler.cs +++ b/NewHorizons/Handlers/PlanetDestructionHandler.cs @@ -80,6 +80,7 @@ namespace NewHorizons.Handlers else if (ao.GetAstroObjectName() == AstroObject.Name.CaveTwin || ao.GetAstroObjectName() == AstroObject.Name.TowerTwin) { DisableBody(GameObject.Find("FocalBody"), delete); + DisableBody(GameObject.Find("SandFunnel_Body"), delete); } else if (ao.GetAstroObjectName() == AstroObject.Name.MapSatellite) { @@ -132,6 +133,9 @@ namespace NewHorizons.Handlers Logger.Log($"Destroying SunProxy {sunProxy.gameObject.name}"); GameObject.Destroy(sunProxy.gameObject); } + + // Stop the sun from breaking stuff when the supernova gets triggered + GlobalMessenger.RemoveListener("TriggerSupernova", ao.GetComponent().OnTriggerSupernova); } // Just delete the children diff --git a/NewHorizons/Handlers/SystemCreationHandler.cs b/NewHorizons/Handlers/SystemCreationHandler.cs index ad50a626..60208699 100644 --- a/NewHorizons/Handlers/SystemCreationHandler.cs +++ b/NewHorizons/Handlers/SystemCreationHandler.cs @@ -9,6 +9,7 @@ using NewHorizons.Builder.StarSystem; using UnityEngine; using Logger = NewHorizons.Utility.Logger; using Object = UnityEngine.Object; +using NewHorizons.Components; namespace NewHorizons.Handlers { @@ -16,8 +17,6 @@ namespace NewHorizons.Handlers { public static void LoadSystem(NewHorizonsSystem system) { - - var skybox = GameObject.Find("Skybox/Starfield"); if (system.Config.skybox?.destroyStarField ?? false) @@ -30,6 +29,11 @@ namespace NewHorizons.Handlers SkyboxBuilder.Make(system.Config.skybox, system.Mod); } + if(system.Config.enableTimeLoop) + { + var timeLoopController = new GameObject("TimeLoopController"); + timeLoopController.AddComponent(); + } } } } diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index ba857f29..f3636d43 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -31,19 +31,21 @@ namespace NewHorizons { public class Main : ModBehaviour { - public static AssetBundle ShaderBundle; + public static AssetBundle NHAssetBundle { get; private set; } public static Main Instance { get; private set; } // Settings - public static bool Debug; + public static bool Debug { get; private set; } private static bool _useCustomTitleScreen; private static bool _wasConfigured = false; + private static string _defaultSystemOverride; public static Dictionary SystemDict = new Dictionary(); public static Dictionary> BodyDict = new Dictionary>(); - public static Dictionary AssetBundles = new Dictionary(); public static List MountedAddons = new List(); + public static float SecondsLeftInLoop = -1; + public static bool IsSystemReady { get; private set; } public static float FurthestOrbit { get; set; } = 50000f; @@ -82,6 +84,8 @@ namespace NewHorizons DebugReload.UpdateReloadButton(); Logger.UpdateLogLevel(Debug ? Logger.LogType.Log : Logger.LogType.Error); + _defaultSystemOverride = config.GetSettingsValue("Default System Override"); + var wasUsingCustomTitleScreen = _useCustomTitleScreen; _useCustomTitleScreen = config.GetSettingsValue("Custom title screen"); // Reload the title screen if this was updated on it @@ -109,11 +113,7 @@ namespace NewHorizons destroyStockPlanets = false } }; - foreach (AssetBundle bundle in AssetBundles.Values) - { - bundle.Unload(true); - } - AssetBundles.Clear(); + if (!resetTranslation) return; TranslationHandler.ClearTables(); TextTranslation.Get().SetLanguage(TextTranslation.Get().GetLanguage()); @@ -133,10 +133,10 @@ namespace NewHorizons Instance = this; GlobalMessenger.AddListener("PlayerDeath", OnDeath); GlobalMessenger.AddListener("WakeUp", new Callback(OnWakeUp)); - ShaderBundle = Main.Instance.ModHelper.Assets.LoadBundle("AssetBundle/shader"); - + NHAssetBundle = ModHelper.Assets.LoadBundle("AssetBundle/xen.newhorizons"); + ResetConfigs(resetTranslation: false); - + Logger.Log("Begin load of config files...", Logger.LogType.Log); try @@ -151,7 +151,7 @@ namespace NewHorizons Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => OnSceneLoaded(SceneManager.GetActiveScene(), LoadSceneMode.Single)); Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => _firstLoad = false); Instance.ModHelper.Menus.PauseMenu.OnInit += DebugReload.InitializePauseMenu; - } + } public void OnDestroy() { @@ -172,6 +172,7 @@ namespace NewHorizons SearchUtilities.ClearCache(); ImageUtilities.ClearCache(); AudioUtilities.ClearCache(); + AssetBundleUtilities.ClearCache(); IsSystemReady = false; } @@ -179,6 +180,28 @@ namespace NewHorizons { Logger.Log($"Scene Loaded: {scene.name} {mode}"); + // Set time loop stuff if its enabled and if we're warping to a new place + if (_isChangingStarSystem && (SystemDict[_currentStarSystem].Config.enableTimeLoop || _currentStarSystem == "SolarSystem") && SecondsLeftInLoop > 0f) + { + TimeLoop.SetSecondsRemaining(SecondsLeftInLoop); + // Prevent the OPC from firing + var launchController = GameObject.FindObjectOfType(); + if (launchController != null) + { + GlobalMessenger.RemoveListener("StartOfTimeLoop", launchController.OnStartOfTimeLoop); + foreach (var fakeDebris in launchController._fakeDebrisBodies) + { + fakeDebris.gameObject.SetActive(false); + } + launchController.enabled = false; + } + var nomaiProbe = GameObject.Find("NomaiProbe_Body"); + if (nomaiProbe != null) nomaiProbe.gameObject.SetActive(false); + } + + // Reset this + SecondsLeftInLoop = -1; + _isChangingStarSystem = false; if (scene.name == "TitleScreen" && _useCustomTitleScreen) @@ -186,21 +209,21 @@ namespace NewHorizons TitleSceneHandler.DisplayBodyOnTitleScreen(BodyDict.Values.ToList().SelectMany(x => x).ToList()); } - if(scene.name == "EyeOfTheUniverse" && IsWarping) + if (scene.name == "EyeOfTheUniverse" && IsWarping) { - if(_ship != null) SceneManager.MoveGameObjectToScene(_ship, SceneManager.GetActiveScene()); + if (_ship != null) SceneManager.MoveGameObjectToScene(_ship, SceneManager.GetActiveScene()); _ship.transform.position = new Vector3(50, 0, 0); _ship.SetActive(true); } - if(scene.name == "SolarSystem") + if (scene.name == "SolarSystem") { - foreach(var body in GameObject.FindObjectsOfType()) + foreach (var body in GameObject.FindObjectsOfType()) { Logger.Log($"{body.name}, {body.transform.rotation}"); } - if(_ship != null) + if (_ship != null) { _ship = GameObject.Find("Ship_Body").InstantiateInactive(); DontDestroyOnLoad(_ship); @@ -228,14 +251,14 @@ namespace NewHorizons if (IsWarping && _shipWarpController) { Instance.ModHelper.Events.Unity.RunWhen( - () => IsSystemReady, + () => IsSystemReady, () => _shipWarpController.WarpIn(WearingSuit) ); } else { Instance.ModHelper.Events.Unity.RunWhen( - () => IsSystemReady, + () => IsSystemReady, () => FindObjectOfType().DebugWarp(SystemDict[_currentStarSystem].SpawnPoint) ); } @@ -250,7 +273,16 @@ namespace NewHorizons else { // Reset back to original solar system after going to main menu. - _currentStarSystem = _defaultStarSystem; + // If the override is a valid system then we go there + if (SystemDict.Keys.Contains(_defaultSystemOverride)) + { + _currentStarSystem = _defaultSystemOverride; + IsWarping = true; // always do this else sometimes the spawn gets messed up + } + else + { + _currentStarSystem = _defaultStarSystem; + } } } @@ -285,6 +317,12 @@ namespace NewHorizons var relativePath = file.Replace(folder, ""); var starSystemConfig = mod.ModHelper.Storage.Load(relativePath); + if (starSystemConfig.startHere) + { + // We always want to allow mods to overwrite setting the main SolarSystem as default but not the other way around + if (name != "SolarSystem") SetDefaultSystem(name); + } + var system = new NewHorizonsSystem(name, starSystemConfig, mod); SystemDict[name] = system; } @@ -312,7 +350,7 @@ namespace NewHorizons LoadTranslations(folder, mod); } } - catch(Exception ex) + catch (Exception ex) { Logger.LogError($"{ex.Message}, {ex.StackTrace}"); } @@ -356,15 +394,13 @@ namespace NewHorizons if (config.Base.CenterOfSolarSystem) config.Orbit.IsStatic = true; if (!SystemDict.ContainsKey(config.StarSystem)) { - // See if theres a star system config + // Since we didn't load it earlier there shouldn't be a star system config var starSystemConfig = mod.ModHelper.Storage.Load($"systems/{config.StarSystem}.json"); if (starSystemConfig == null) starSystemConfig = new StarSystemConfig(null); - else Logger.Log($"Loaded system config for {config.StarSystem}"); + else Logger.LogWarning($"Loaded system config for {config.StarSystem}. Why wasn't this loaded earlier?"); var system = new NewHorizonsSystem(config.StarSystem, starSystemConfig, mod); - if (system.Config.startHere) SetDefaultSystem(system.Name); - SystemDict.Add(config.StarSystem, system); BodyDict.Add(config.StarSystem, new List()); @@ -396,8 +432,7 @@ namespace NewHorizons OnChangeStarSystem?.Invoke(newStarSystem); Logger.Log($"Warping to {newStarSystem}"); - if(warp && _shipWarpController) _shipWarpController.WarpOut(); - _currentStarSystem = newStarSystem; + if (warp && _shipWarpController) _shipWarpController.WarpOut(); _isChangingStarSystem = true; IsWarping = warp; WearingSuit = PlayerState.IsWearingSuit(); @@ -405,15 +440,24 @@ namespace NewHorizons // We kill them so they don't move as much Locator.GetDeathManager().KillPlayer(DeathType.Meditation); - if(newStarSystem == "EyeOfTheUniverse") + OWScene sceneToLoad; + + if (newStarSystem == "EyeOfTheUniverse") { - PlayerData.SaveWarpedToTheEye(60); - LoadManager.LoadSceneAsync(OWScene.EyeOfTheUniverse, true, LoadManager.FadeType.ToBlack, 0.1f, true); + PlayerData.SaveWarpedToTheEye(TimeLoop.GetSecondsRemaining()); + sceneToLoad = OWScene.EyeOfTheUniverse; } else { - LoadManager.LoadSceneAsync(OWScene.SolarSystem, true, LoadManager.FadeType.ToBlack, 0.1f, true); + if (SystemDict[_currentStarSystem].Config.enableTimeLoop) SecondsLeftInLoop = TimeLoop.GetSecondsRemaining(); + else SecondsLeftInLoop = -1; + + sceneToLoad = OWScene.SolarSystem; } + + _currentStarSystem = newStarSystem; + + LoadManager.LoadSceneAsync(sceneToLoad, true, LoadManager.FadeType.ToBlack, 0.1f, true); } void OnDeath(DeathType _) @@ -421,7 +465,17 @@ namespace NewHorizons // We reset the solar system on death (unless we just killed the player) if (!_isChangingStarSystem) { - _currentStarSystem = _defaultStarSystem; + // If the override is a valid system then we go there + if (SystemDict.Keys.Contains(_defaultSystemOverride)) + { + _currentStarSystem = _defaultSystemOverride; + IsWarping = true; // always do this else sometimes the spawn gets messed up + } + else + { + _currentStarSystem = _defaultStarSystem; + } + IsWarping = false; } } diff --git a/NewHorizons/Utility/AssetBundleUtilities.cs b/NewHorizons/Utility/AssetBundleUtilities.cs new file mode 100644 index 00000000..fc4cd0ed --- /dev/null +++ b/NewHorizons/Utility/AssetBundleUtilities.cs @@ -0,0 +1,91 @@ +using OWML.Common; +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 AssetBundleUtilities + { + public static Dictionary AssetBundles = new Dictionary(); + + public static void ClearCache() + { + foreach (var pair in AssetBundles) + { + if (pair.Value == null) Logger.LogError($"The asset bundle for {pair.Key} was null when trying to unload"); + else pair.Value.Unload(true); + } + AssetBundles.Clear(); + } + + public static T Load(string assetBundleRelativeDir, string pathInBundle, IModBehaviour mod) where T : UnityEngine.Object + { + string key = Path.GetFileName(assetBundleRelativeDir); + T obj; + + try + { + AssetBundle bundle; + + if (AssetBundles.ContainsKey(key)) + { + bundle = AssetBundles[key]; + } + else + { + var completePath = mod.ModHelper.Manifest.ModFolderPath + assetBundleRelativeDir; + bundle = AssetBundle.LoadFromFile(completePath); + if (bundle == null) + { + Logger.LogError($"Couldn't load AssetBundle at [{completePath}] for [{mod.ModHelper.Manifest.Name}]"); + return null; + } + + AssetBundles[key] = bundle; + } + + obj = bundle.LoadAsset(pathInBundle); + } + catch (Exception e) + { + Logger.LogError($"Couldn't load asset {pathInBundle} from AssetBundle {assetBundleRelativeDir} : {e.Message}"); + return null; + } + + return obj; + } + + public static GameObject LoadPrefab(string assetBundleRelativeDir, string pathInBundle, IModBehaviour mod) + { + var prefab = Load(assetBundleRelativeDir, pathInBundle, mod); + + prefab.SetActive(false); + + ReplaceShaders(prefab); + + return prefab; + } + + public static void ReplaceShaders(GameObject prefab) + { + foreach (var renderer in prefab.GetComponentsInChildren(true)) + { + foreach (var material in renderer.sharedMaterials) + { + if (material == null) + { + continue; + } + + var replacementShader = Shader.Find(material.shader.name); + if (replacementShader != null) material.shader = replacementShader; + } + } + } + } +} diff --git a/NewHorizons/Utility/AstroObjectLocator.cs b/NewHorizons/Utility/AstroObjectLocator.cs index b46bec43..76c5e579 100644 --- a/NewHorizons/Utility/AstroObjectLocator.cs +++ b/NewHorizons/Utility/AstroObjectLocator.cs @@ -111,9 +111,6 @@ namespace NewHorizons.Utility otherChildren.Add(GameObject.Find("FakeCannonBarrel_Body (1)")); otherChildren.Add(GameObject.Find("Debris_Body (1)")); break; - case AstroObject.Name.SunStation: - otherChildren.Add(GameObject.Find("SS_Debris_Body")); - break; case AstroObject.Name.GiantsDeep: otherChildren.Add(GameObject.Find("BrambleIsland_Body")); otherChildren.Add(GameObject.Find("GabbroIsland_Body")); @@ -134,6 +131,10 @@ namespace NewHorizons.Utility otherChildren.Add(GameObject.Find("BackRaft_Body")); otherChildren.Add(GameObject.Find("SealRaft_Body")); break; + // For some dumb reason the sun station doesn't use AstroObject.Name.SunStation + case AstroObject.Name.CustomString: + if(primary._customName.Equals("Sun Station")) otherChildren.Add(GameObject.Find("SS_Debris_Body")); + break; default: break; } diff --git a/NewHorizons/Utility/DebugReload.cs b/NewHorizons/Utility/DebugReload.cs index ecbfb00d..2dc0a2cc 100644 --- a/NewHorizons/Utility/DebugReload.cs +++ b/NewHorizons/Utility/DebugReload.cs @@ -50,6 +50,8 @@ namespace NewHorizons.Utility GameObject.Find("/PauseMenu/PauseMenuManagers").GetComponent().OnSkipToNextTimeLoop(); Main.Instance.ChangeCurrentStarSystem(Main.Instance.CurrentStarSystem); + + Main.SecondsLeftInLoop = -1f; } } } \ No newline at end of file diff --git a/NewHorizons/default-config.json b/NewHorizons/default-config.json index 75790651..f5200a8d 100644 --- a/NewHorizons/default-config.json +++ b/NewHorizons/default-config.json @@ -2,6 +2,7 @@ "enabled": true, "settings": { "Debug": false, - "Custom title screen": true + "Custom title screen": true, + "Default System Override": "" } } \ No newline at end of file diff --git a/NewHorizons/manifest.json b/NewHorizons/manifest.json index b0fc9dd3..80f0af97 100644 --- a/NewHorizons/manifest.json +++ b/NewHorizons/manifest.json @@ -3,7 +3,7 @@ "author": "xen, Bwc9876, & Book", "name": "New Horizons", "uniqueName": "xen.NewHorizons", - "version": "0.15.2", + "version": "0.16.0", "owmlVersion": "2.1.0", "conflicts": [ "Raicuparta.QuantumSpaceBuddies", "Vesper.AutoResume", "PacificEngine.OW_Randomizer" ], "pathsToPreserve": [ "planets", "systems", "translations" ] diff --git a/NewHorizons/schema.json b/NewHorizons/schema.json index c70c6faa..9ef93fd7 100644 --- a/NewHorizons/schema.json +++ b/NewHorizons/schema.json @@ -666,6 +666,11 @@ "items": { "type": "string" } + }, + "removeComponents": { + "type": "boolean", + "description": "Do we reset all the components on this object? Useful for certain props that have dialogue components attached to them.", + "default": false } } } diff --git a/NewHorizons/star_system_schema.json b/NewHorizons/star_system_schema.json index be3573b1..b8557a98 100644 --- a/NewHorizons/star_system_schema.json +++ b/NewHorizons/star_system_schema.json @@ -20,6 +20,11 @@ "type": "bool", "description": "Do you want a clean slate for this star system? Or will it be a modified version of the original." }, + "enableTimeLoop": { + "type": "bool", + "description": "Should the player be sent back in time after 22 minutes?", + "default": true + }, "skybox": { "type": "object", "description": "Options for the skybox of your system", diff --git a/NewHorizons/text_schema.xsd b/NewHorizons/text_schema.xsd new file mode 100644 index 00000000..19cc2392 --- /dev/null +++ b/NewHorizons/text_schema.xsd @@ -0,0 +1,112 @@ + + + + + + + + + + + The different text blocks of this object + + + + + + + The conditions for unlocking ship log facts + + + + + + + + + + + + + + + + + The id of this text block + + + + + + + The id of the parent text block + + + + + + + + + + + + + + + + + + + The text to show for this option + + + + + + + + + + + + + + + + + + + + + + + + + Facts to reveal when the player goes through this dialogue node + + + + + + + + + + + + + The ID of a fact to reveal + + + + + + + The text block ids (separated by commas) that need to be read to reveal that fact + + + + + + \ No newline at end of file