diff --git a/NewHorizons/Builder/Body/BrambleDimensionBuilder.cs b/NewHorizons/Builder/Body/BrambleDimensionBuilder.cs index 237335bb..4dce6bc3 100644 --- a/NewHorizons/Builder/Body/BrambleDimensionBuilder.cs +++ b/NewHorizons/Builder/Body/BrambleDimensionBuilder.cs @@ -10,117 +10,6 @@ using Logger = NewHorizons.Utility.Logger; namespace NewHorizons.Builder.Body { - [HarmonyPatch] - static class Patch - { - // SkinnedMeshRenderer.SetBlendShapeWeight - [HarmonyPrefix] - [HarmonyPatch(typeof(PlayerFogWarpDetector), nameof(PlayerFogWarpDetector.LateUpdate))] - public static bool LateUpdate(PlayerFogWarpDetector __instance) - { - // if (PlanetaryFogController.GetActiveFogSphere() == null) - //{ - // return false; - //} - float num = __instance._targetFogFraction; - if (PlayerState.IsInsideShip()) - { - num = Mathf.Max(__instance._shipFogDetector.GetTargetFogFraction(), num); - } - if (num < __instance._fogFraction) - { - float num2 = (__instance._closestFogWarp.UseFastFogFade() ? 1f : 0.2f); - __instance._fogFraction = Mathf.MoveTowards(__instance._fogFraction, num, Time.deltaTime * num2); - } - else - { - __instance._fogFraction = num; - } - if (__instance._targetFogColorWarpVolume != __instance._closestFogWarp) - { - __instance._targetFogColorWarpVolume = __instance._closestFogWarp; - __instance._startColorCrossfadeTime = Time.time; - __instance._startCrossfadeColor = __instance._fogColor; - } - if (__instance._targetFogColorWarpVolume != null) - { - Color fogColor = __instance._targetFogColorWarpVolume.GetFogColor(); - if (__instance._fogFraction <= 0f) - { - __instance._fogColor = fogColor; - } - else - { - float t = Mathf.InverseLerp(__instance._startColorCrossfadeTime, __instance._startColorCrossfadeTime + 1f, Time.time); - __instance._fogColor = Color.Lerp(__instance._startCrossfadeColor, fogColor, t); - } - __instance._fogColor = new Color(__instance._fogColor.r, __instance._fogColor.g, __instance._fogColor.b); - } - if (__instance._playerEffectBubbleController != null) - { - __instance._playerEffectBubbleController.SetFogFade(__instance._fogFraction, __instance._fogColor); - } - if (__instance._shipLandingCamEffectBubbleController != null) - { - __instance._shipLandingCamEffectBubbleController.SetFogFade(__instance._fogFraction, __instance._fogColor); - } - - return false; - } - - - // FogWarpBubbleController.SetFogFade - [HarmonyPrefix] - [HarmonyPatch(typeof(FogWarpEffectBubbleController), nameof(FogWarpEffectBubbleController.SetFogFade))] - public static bool FogWarpBubbleController_SetFogFade(FogWarpEffectBubbleController __instance, float fogAlpha, Color fogColor) - { - if (__instance._effectBubbleRenderer.sharedMaterial != null) - { - Color value = fogColor; - value.a = fogAlpha; - __instance._matPropBlock.SetColor(__instance._propID_Color, value); - __instance._effectBubbleRenderer.SetPropertyBlock(__instance._matPropBlock); - } - __instance._visible = __instance._effectBubbleRenderer.sharedMaterial != null && fogAlpha > 0f; - if (__instance._targetCamera == null) - { - __instance._effectBubbleRenderer.enabled = __instance._visible; - Logger.Log($"Setting camera effect renderer to {__instance._visible}"); - } - - // Logger.Log($"{__instance.gameObject.transform.GetPath()} _visible: {__instance._visible} set alpha to {fogAlpha} and set color ot {fogColor}"); - - return false; - } - - - // note: I would just make this a one line postfix function, but CheckWarpProximity() does extra stuff that we really don't want to run twice - // so we have to completely override this function to support scaling ;-; - [HarmonyPrefix] - [HarmonyPatch(typeof(FogWarpDetector), nameof(FogWarpDetector.FixedUpdate))] - public static void FixedUpdate(FogWarpDetector __instance) - { - __instance._targetFogFraction = 0f; - __instance._closestFogWarp = null; - float num = float.PositiveInfinity; - for (int i = 0; i < __instance._warpVolumes.Count; i++) - { - if (!__instance._warpVolumes[i].IsProbeOnly() || __instance._name == FogWarpDetector.Name.Probe) - { - FogWarpVolume fogWarpVolume = __instance._warpVolumes[i]; - float num2 = Mathf.Abs(fogWarpVolume.CheckWarpProximity(__instance)); - float b = Mathf.Clamp01(1f - Mathf.Abs(num2) / fogWarpVolume.GetFogThickness()); - __instance._targetFogFraction = Mathf.Max(__instance._targetFogFraction, b); - if (num2 < num) - { - num = num2; - __instance._closestFogWarp = fogWarpVolume; - } - } - } - } - } - // TODO: in order to fix fog screen effect for scaling nodes, I need to replace all InnerFogWarpVolume and OuterFogWarpVolume instances with NHInner/OuterFogWarpVolume and on those two classes, implement GetFogThickness(){ return 50*scale; }} // TODO: StreamingHandler.SetUpStreaming() for all FogWarpEffectBubbleController objects // TODO: add the "don't see me" effect @@ -194,6 +83,24 @@ namespace NewHorizons.Builder.Body repelVolume.transform.parent = sector.transform; repelVolume.transform.localPosition = Vector3.zero; + // remove default vines + var geoBatchedGroup = geometry.FindChild("BatchedGroup"); + var collider = geoBatchedGroup.FindChild("BatchedMeshColliders_1"); + collider.transform.parent = geometry.transform; + GameObject.Destroy(geoBatchedGroup); + + var geoOtherComponentsGroup = geometry.FindChild("OtherComponentsGroup"); + var dimensionWalls = geoOtherComponentsGroup.FindChild("Terrain_DB_BrambleSphere_Outer_v2"); + dimensionWalls.transform.parent = geometry.transform; + GameObject.Destroy(geoOtherComponentsGroup); + + // fix some cull groups + volumes.GetComponent()._sector = sector; + volumes.FindChild("SunOverrideVolume").GetComponent()._sector = sector; + effects.GetComponent()._sector = sector; + atmo.GetComponent()._sector = sector; + atmo.GetComponent()._sector = sector; + // Set up rulesets var thrustRuleset = sector.gameObject.AddComponent(); thrustRuleset._attachedBody = owRigidBody; @@ -224,6 +131,19 @@ namespace NewHorizons.Builder.Body PairExit(config.linksTo, outerFogWarpVolume); + // If the config says only certain entrances are allowed, enforce that + if (config.allowedEntrances != null) + { + var entrances = outerFogWarpVolume._exits; + var newEntrances = new List(); + foreach (var index in config.allowedEntrances) + { + if(index is < 0 or > 5) continue; + newEntrances.Add(entrances[index]); + } + outerFogWarpVolume._exits = newEntrances.ToArray(); + } + // Set the scale var scale = config.radius / BASE_DIMENSION_RADIUS; geometry.transform.localScale = Vector3.one * scale; @@ -255,10 +175,6 @@ namespace NewHorizons.Builder.Body cloak._sectors = new Sector[] { sector }; cloak.GetComponent().enabled = true; - // fix the fog backdrop - atmo.GetComponent()._sector = sector; - atmo.GetComponent()._sector = sector; - // finalize atmo.SetActive(true); volumes.SetActive(true); diff --git a/NewHorizons/Builder/Props/BrambleNodeBuilder.cs b/NewHorizons/Builder/Props/BrambleNodeBuilder.cs index 9b6e733a..811ccd05 100644 --- a/NewHorizons/Builder/Props/BrambleNodeBuilder.cs +++ b/NewHorizons/Builder/Props/BrambleNodeBuilder.cs @@ -214,14 +214,26 @@ namespace NewHorizons.Builder.Props fogLight._linkedLightData = new List(); sector.RegisterFogLight(fogLight); + + // If the config says only certain exits are allowed, enforce that + if (config.possibleExits != null) + { + var exits = innerFogWarpVolume._exits; + var newExits = new List(); + foreach (var index in config.possibleExits) + { + if(index is < 0 or > 5) continue; + newExits.Add(exits[index]); + } + innerFogWarpVolume._exits = newExits.ToArray(); + } // set up screen fog effect // (in the base game, any sector that contains a bramble node needs an EffectRuleset with type FogWarp) // (this isn't jank I swear, this is how it's supposed to work) var sectorHasFogEffectRuleset = sector .GetComponents() - .Where(effectRuleset => effectRuleset._type == EffectRuleset.BubbleType.FogWarp) - .Count() > 0; + .Any(effectRuleset => effectRuleset._type == EffectRuleset.BubbleType.FogWarp); if (!sectorHasFogEffectRuleset) { var fogEffectRuleset = sector.gameObject.AddComponent(); @@ -244,7 +256,7 @@ namespace NewHorizons.Builder.Props // Seed fog works differently, so it doesn't need to be fixed (it's also located on a different child path, so the below FindChild calls wouldn't work) if (!config.isSeed) { - var fog = brambleNode.FindChild("Effects").FindChild("InnerWarpFogSphere"); + var fog = brambleNode.FindChild("Effects/InnerWarpFogSphere"); var fogMaterial = fog.GetComponent().sharedMaterial; fog.transform.localScale /= config.scale; fogMaterial.SetFloat("_Radius", fogMaterial.GetFloat("_Radius") * config.scale); @@ -255,6 +267,13 @@ namespace NewHorizons.Builder.Props if (config.isSeed) SetSeedColors(brambleNode, config.fogTint?.ToColor(), config.lightTint?.ToColor()); else SetNodeColors(brambleNode, config.fogTint?.ToColor(), config.lightTint?.ToColor()); + innerFogWarpVolume._useFarFogColor = false; + if (config.farFogTint != null) + { + innerFogWarpVolume._useFarFogColor = true; + innerFogWarpVolume._farFogColor = config.farFogTint.ToColor(); + } + // Set up warps innerFogWarpVolume._sector = sector; innerFogWarpVolume._attachedBody = go.GetComponent(); // I don't think this is necessary, it seems to be set correctly on its own @@ -292,9 +311,8 @@ namespace NewHorizons.Builder.Props var fogRenderer = brambleNode.GetComponent(); fogRenderer._fogColor = fogTint.Value; - fogRenderer._useFarFogColor = false; - var fogBackdrop = brambleNode.FindChild("Terrain_DB_BrambleSphere_Inner_v2")?.FindChild("fogbackdrop_v2"); + var fogBackdrop = brambleNode.FindChild("Terrain_DB_BrambleSphere_Inner_v2/fogbackdrop_v2"); if (fogBackdrop != null) fogBackdrop.GetComponent().sharedMaterial.color = (Color)fogTint; } diff --git a/NewHorizons/Builder/Props/NomaiTextBuilder.cs b/NewHorizons/Builder/Props/NomaiTextBuilder.cs index 8f71830c..02cc532e 100644 --- a/NewHorizons/Builder/Props/NomaiTextBuilder.cs +++ b/NewHorizons/Builder/Props/NomaiTextBuilder.cs @@ -69,7 +69,7 @@ namespace NewHorizons.Builder.Props foreach (var existingArc in existingGhostArcs) { var arc = existingArc.InstantiateInactive(); - arc.name = "Arc"; + arc.name = "Arc (Ghost)"; _ghostArcPrefabs.Add(arc); } diff --git a/NewHorizons/Components/SizeControllers/StarEvolutionController.cs b/NewHorizons/Components/SizeControllers/StarEvolutionController.cs index 2da729c6..42398c2b 100644 --- a/NewHorizons/Components/SizeControllers/StarEvolutionController.cs +++ b/NewHorizons/Components/SizeControllers/StarEvolutionController.cs @@ -53,6 +53,7 @@ namespace NewHorizons.Components.SizeControllers public UnityEvent SupernovaStart = new UnityEvent(); private float maxScale; + private float minScale; private static readonly int ColorRamp = Shader.PropertyToID("_ColorRamp"); private Color _currentColour; @@ -121,10 +122,12 @@ namespace NewHorizons.Components.SizeControllers if (scaleCurve != null) { maxScale = scaleCurve.keys.Select(x => x.value).Max() * size; + minScale = scaleCurve.keys.Select(x => x.value).Min() * size; } else { maxScale = 0; + minScale = 0; scaleCurve = new AnimationCurve(); scaleCurve.AddKey(0, 1); } @@ -150,7 +153,8 @@ namespace NewHorizons.Components.SizeControllers { // Use the age if theres no resizing happening, else make it get redder the larger it is or wtv var t = _age / (lifespan * 60f); - if (maxScale > 0) t = CurrentScale / maxScale; + if (maxScale != minScale) t = Mathf.InverseLerp(minScale, maxScale, CurrentScale); + if (t < 1f) { _currentColour = Color.Lerp(_startColour, _endColour, t); @@ -268,9 +272,7 @@ namespace NewHorizons.Components.SizeControllers { lod.material.SetFloat("_InnerRadius", CurrentScale); lod.material.SetFloat("_OuterRadius", CurrentScale * StarBuilder.OuterRadiusRatio); - - // These break once it reaches endColour and I have no idea why - //lod.material.SetColor("_SkyColor", _currentColour); + lod.material.SetColor("_SkyColor", _currentColour); } } } diff --git a/NewHorizons/External/Configs/PlanetConfig.cs b/NewHorizons/External/Configs/PlanetConfig.cs index 7f662072..0eab39b6 100644 --- a/NewHorizons/External/Configs/PlanetConfig.cs +++ b/NewHorizons/External/Configs/PlanetConfig.cs @@ -181,6 +181,7 @@ namespace NewHorizons.External.Configs if (Base.centerOfSolarSystem) Orbit.isStatic = true; if (Atmosphere?.clouds?.lightningGradient != null) Atmosphere.clouds.hasLightning = true; if (Bramble?.dimension != null && Orbit?.staticPosition == null) throw new Exception($"Dimension {name} must have Orbit.staticPosition defined."); + if (Bramble?.dimension != null) canShowOnTitle = false; if (Orbit?.staticPosition != null) Orbit.isStatic = true; // For each quantum group, verify the following: diff --git a/NewHorizons/External/Modules/BrambleModule.cs b/NewHorizons/External/Modules/BrambleModule.cs index 4e499ac0..20400052 100644 --- a/NewHorizons/External/Modules/BrambleModule.cs +++ b/NewHorizons/External/Modules/BrambleModule.cs @@ -41,6 +41,11 @@ namespace NewHorizons.External.Modules /// The internal radius (in meters) of the dimension. The default is 1705. /// [DefaultValue(1705f)] public float radius = 1705f; + + /// + /// An array of integers from 0-5. By default, all entrances are allowed. To force this dimension to warp players in from only one point (like the anglerfish nest dimension in the base game) set this value to [3], [5], or similar. Values of 0-5 only. + /// + public int[] allowedEntrances; } @@ -86,6 +91,16 @@ namespace NewHorizons.External.Modules /// The color of the shafts of light coming from the entrances to the node. Leave blank for the default yellowish color: (131, 124, 105, 255) /// public MColor lightTint; + + /// + /// The color a dimension's background fog turns when you approach this node (if it's in a dimension). If this node is not in a dimension, this does nothing. Leave blank for the default yellowish white color: (255, 245, 217, 255) + /// + public MColor farFogTint; + + /// + /// An array of integers from 0-5. By default, all exits are allowed. To force this node to warp players out from only one hole set this value to [3], [5], or similar. Values of 0-5 only. + /// + public int[] possibleExits; } } } diff --git a/NewHorizons/Handlers/SubtitlesHandler.cs b/NewHorizons/Handlers/SubtitlesHandler.cs index 737c6b0b..d1cc0b00 100644 --- a/NewHorizons/Handlers/SubtitlesHandler.cs +++ b/NewHorizons/Handlers/SubtitlesHandler.cs @@ -26,8 +26,6 @@ namespace NewHorizons.Handlers public Sprite eoteSprite; public int subtitleIndex; - public System.Random randomizer; - public static readonly int PAUSE_TIMER_MAX = 50; public int pauseTimer = PAUSE_TIMER_MAX; @@ -45,8 +43,6 @@ namespace NewHorizons.Handlers public void Start() { - randomizer = new System.Random(); - GetComponent().alpha = 1; graphic = GetComponent(); image = GetComponent(); @@ -87,7 +83,7 @@ namespace NewHorizons.Handlers possibleSubtitles.Add(sprite); } - public void Update() + public void FixedUpdate() { CheckForEOTE(); @@ -132,14 +128,7 @@ namespace NewHorizons.Handlers public void ChangeSubtitle() { - // to pick a new random subtitle without requiring retries, we generate a random offset less than the length of the possible subtitles array - // we then add that offset to the current index, modulo NUMBER_OF_POSSIBLE_SUBTITLES - // since the offset can never be NUMBER_OF_POSSIBLE_SUBTITLES, it will never wrap all the way back around to the initial subtitleIndex - - // note, this makes the code more confusing, but Random.Next(min, max) generates a random number on the range [min, max) - // that is, the below code will generate numbers up to and including Count-1, not Count. - var newIndexOffset = randomizer.Next(1, possibleSubtitles.Count); - subtitleIndex = (subtitleIndex + newIndexOffset) % possibleSubtitles.Count; + subtitleIndex = (subtitleIndex + 1) % possibleSubtitles.Count; image.sprite = possibleSubtitles[subtitleIndex]; } diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index a6b2dc49..0aeb8004 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -388,6 +388,8 @@ namespace NewHorizons if (SystemDict.ContainsKey(name)) { + if (string.IsNullOrEmpty(SystemDict[name].Config.travelAudio)) + SystemDict[name].Mod = mod; SystemDict[name].Config.Merge(starSystemConfig); } else diff --git a/NewHorizons/Patches/BramblePatches.cs b/NewHorizons/Patches/BramblePatches.cs index bbd5e33b..2a721169 100644 --- a/NewHorizons/Patches/BramblePatches.cs +++ b/NewHorizons/Patches/BramblePatches.cs @@ -10,6 +10,12 @@ namespace NewHorizons.Patches [HarmonyPatch] public class BramblePatches { + // + // this file is not great. the real solution to the issues these patches address should be solved by replacing bramble nodes' InnerFogWarpVolume + // components with a custom NHInnerFogWarpVolume component, and implement the below functions as overrides in the NHInnerFogWarpVolume class + // that would fix the issue of seeds having inappropriate screen fog + // + [HarmonyPrefix] [HarmonyPatch(typeof(SphericalFogWarpVolume), nameof(SphericalFogWarpVolume.IsProbeOnly))] public static bool SphericalFogWarpVolume_IsProbeOnly(SphericalFogWarpVolume __instance, ref bool __result) diff --git a/NewHorizons/Schemas/body_schema.json b/NewHorizons/Schemas/body_schema.json index a28c26ca..5c920b62 100644 --- a/NewHorizons/Schemas/body_schema.json +++ b/NewHorizons/Schemas/body_schema.json @@ -530,6 +530,14 @@ "description": "The internal radius (in meters) of the dimension. The default is 1705.", "format": "float", "default": 1705.0 + }, + "allowedEntrances": { + "type": "array", + "description": "An array of integers from 0-5. By default, all entrances are allowed. To force this dimension to warp players in from only one point (like the anglerfish nest dimension in the base game) set this value to [3], [5], or similar. Values of 0-5 only.", + "items": { + "type": "integer", + "format": "int32" + } } } }, @@ -571,6 +579,18 @@ "lightTint": { "description": "The color of the shafts of light coming from the entrances to the node. Leave blank for the default yellowish color: (131, 124, 105, 255)", "$ref": "#/definitions/MColor" + }, + "farFogTint": { + "description": "The color a dimension's background fog turns when you approach this node (if it's in a dimension). If this node is not in a dimension, this does nothing. Leave blank for the default yellowish white color: (255, 245, 217, 255)", + "$ref": "#/definitions/MColor" + }, + "possibleExits": { + "type": "array", + "description": "An array of integers from 0-5. By default, all exits are allowed. To force this node to warp players out from only one hole set this value to [3], [5], or similar. Values of 0-5 only.", + "items": { + "type": "integer", + "format": "int32" + } } } }, diff --git a/NewHorizons/Utility/ImageUtilities.cs b/NewHorizons/Utility/ImageUtilities.cs index fbd1b3ac..13140976 100644 --- a/NewHorizons/Utility/ImageUtilities.cs +++ b/NewHorizons/Utility/ImageUtilities.cs @@ -20,12 +20,7 @@ namespace NewHorizons.Utility return _loadedTextures.ContainsKey(path); } - public static Texture2D GetTexture(IModBehaviour mod, string filename) - { - return GetTexture(mod, filename, true); - } - - public static Texture2D GetTexture(IModBehaviour mod, string filename, bool useMipmaps) + public static Texture2D GetTexture(IModBehaviour mod, string filename, bool useMipmaps = true) { // Copied from OWML but without the print statement lol var path = mod.ModHelper.Manifest.ModFolderPath + filename; @@ -41,6 +36,7 @@ namespace NewHorizons.Utility var data = File.ReadAllBytes(path); var texture = new Texture2D(2, 2, TextureFormat.RGBA32, useMipmaps); texture.name = Path.GetFileNameWithoutExtension(path); + texture.wrapMode = TextureWrapMode.Clamp; // this is apparently repeat by default texture.LoadImage(data); _loadedTextures.Add(path, texture);