Skip to content

Commit

Permalink
1.18.4 (#771)
Browse files Browse the repository at this point in the history
## Minor features
- Can now set `preloadBundles` in the addon config file. This will load
asset bundles on the main menu and keep them loaded. Will improve
initial load times at the cost of more memory usage. (#749)
- Can now set `subtitlePath` in the addon config file for displaying a
subtitle for your mod on the main menu.

## Improvements
- Will show a warning popup if you have addons requiring the DLC
installed but not the DLC itself (#728).

## Bug fixes
- Fixes a bug where the ship was not removed from volumes when being
repositioned. Affected INSANE people who had stars larger than 8000m
wide.
- Probably fixes a bug where the ship would think it is grounded when
spawned in zero-g (#748).
- Fixed a bug where using system override to spawn in a ship-less system
would break (#738).
  • Loading branch information
xen-42 committed Feb 4, 2024
2 parents c5847b4 + 4f0998a commit fb28b1e
Show file tree
Hide file tree
Showing 12 changed files with 205 additions and 19 deletions.
3 changes: 2 additions & 1 deletion NewHorizons/Assets/translations/english.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
"DEBUG_PLACE_TEXT": "Place Nomai Text",
"DEBUG_UNDO": "Undo",
"DEBUG_REDO": "Redo",
"Vessel": "Vessel"
"Vessel": "Vessel",
"DLC_REQUIRED": "WARNING\n\nYou have addons (like {0}) installed which require the DLC but it is not enabled.\n\nYour mods may not function as intended."
},
"OtherDictionary": {
"NOMAI_SHUTTLE_COMPUTER": "The <![CDATA[<color=orange>shuttle</color>]]> is currently resting at <![CDATA[<color=lightblue>{0}</color>]]>."
Expand Down
3 changes: 2 additions & 1 deletion NewHorizons/Assets/translations/french.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"RICH_PRESENCE_WARPING": "En route vers {0}.",
"OUTDATED_VERSION_WARNING": "AVERTISSEMENT\n\nNew Horizons fonctionne seulement sur la version {0} ou plus récente. Vous êtes sur la version {1}.\n\nVeuillez mettre à jour votre jeu ou désinstaller NH.",
"JSON_FAILED_TO_LOAD": "Fichier(s) invalide(s): {0}",
"Vessel": "Vaisseau"
"Vessel": "Vaisseau",
"DLC_REQUIRED": "AVERTISSEMENT\n\nVous avez installé des addons (par exemple, {0}) qui nécessitent le DLC mais il n'est pas activé.\n\nVos mods peuvent ne pas fonctionner."
},
"AchievementTranslations": {
"NH_EATEN_OUTSIDE_BRAMBLE": {
Expand Down
12 changes: 12 additions & 0 deletions NewHorizons/External/Configs/AddonConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,17 @@ public class AddonConfig
/// If popupMessage is set, should it repeat every time the game starts or only once
/// </summary>
public bool repeatPopup;

/// <summary>
/// These asset bundles will be loaded on the title screen and stay loaded. Will improve initial load time at the cost of increased memory use.
/// The path is the relative directory of the asset bundle in the mod folder.
/// </summary>
public string[] preloadAssetBundles;

/// <summary>
/// The path to the addons subtitle for the main menu.
/// Defaults to "subtitle.png".
/// </summary>
public string subtitlePath = "subtitle.png";
}
}
9 changes: 9 additions & 0 deletions NewHorizons/External/NewHorizonBody.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ public NewHorizonsBody(PlanetConfig config, IModBehaviour mod, string relativePa

public GameObject Object;

public bool RequiresDLC()
{
var detailPaths = Config.Props.details.Select(x => x.path);
return Config.Cloak != null
|| Config.Props?.rafts != null
|| Config.Props?.slideShows != null
|| detailPaths.Any(x => x.StartsWith("Ringworld") || x.StartsWith("Dreamworld"));
}

#region Cache
public void LoadCache()
{
Expand Down
38 changes: 38 additions & 0 deletions NewHorizons/Handlers/PlayerSpawnHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using NewHorizons.Utility;
using NewHorizons.Utility.OWML;
using System.Collections;
using System.Linq;
using UnityEngine;

namespace NewHorizons.Handlers
Expand Down Expand Up @@ -76,7 +77,44 @@ public static void SpawnShip()
pos += SpawnPointBuilder.ShipSpawn.transform.TransformDirection(SpawnPointBuilder.ShipSpawnOffset);
}

// #748 Before moving the ship, reset all its landing pad sensors
// Else they might think its still touching TH
// Doing this before moving the ship so that if they start contacting in the new spawn point then that gets preserved
foreach (var landingPadSensor in ship.GetComponentsInChildren<LandingPadSensor>())
{
landingPadSensor._contactBody = null;
}

SpawnBody(ship.GetAttachedOWRigidbody(), SpawnPointBuilder.ShipSpawn, pos);

// Bug affecting mods with massive stars (8600m+ radius)
// TH has an orbital radius of 8600m, meaning the base game ship spawn ends up inside the star
// This places the ship into the star's fluid volumes (destruction volume and atmosphere)
// When the ship is teleported out, it doesn't update it's detected fluid volumes and gets affected by drag forever
// Can fix by turning the volumes off and on again
// Done after re-positioning else it'd just get re-added to the old volumes

// .ToList is because it makes a copy of the array, else it errors:
// "InvalidOperationException: Collection was modified; enumeration operation may not execute."
foreach (var volume in ship.GetComponentInChildren<ShipFluidDetector>()._activeVolumes.ToList())
{
if (volume.gameObject.activeInHierarchy)
{
volume.gameObject.SetActive(false);
volume.gameObject.SetActive(true);
}
}
// Also applies to force volumes
foreach (var volume in ship.GetComponentInChildren<AlignmentForceDetector>()._activeVolumes.ToList())
{
if (volume.gameObject.activeInHierarchy)
{
volume.gameObject.SetActive(false);
volume.gameObject.SetActive(true);
}
}
// For some reason none of this seems to apply to the Player.
// If somebody ever makes a sound volume thats somehow always applying to the player tho then itd probably be this
}
}
else if (Main.Instance.CurrentStarSystem != "SolarSystem" && !Main.Instance.IsWarpingFromShip)
Expand Down
12 changes: 10 additions & 2 deletions NewHorizons/Handlers/SubtitlesHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,17 @@ public void Start()

private void AddSubtitles()
{
foreach (var mod in Main.MountedAddons.Where(mod => File.Exists($"{mod.ModHelper.Manifest.ModFolderPath}subtitle.png")))
foreach (var mod in Main.MountedAddons)
{
AddSubtitle(mod, "subtitle.png");
if (Main.AddonConfigs.TryGetValue(mod, out var addonConfig) && File.Exists(Path.Combine(mod.ModHelper.Manifest.ModFolderPath, addonConfig.subtitlePath)))
{
AddSubtitle(mod, addonConfig.subtitlePath);
}
// Else default to subtitle.png
else if (File.Exists(Path.Combine(mod.ModHelper.Manifest.ModFolderPath, "subtitle.png")))
{
AddSubtitle(mod, "subtitle.png");
}
}
}

Expand Down
37 changes: 32 additions & 5 deletions NewHorizons/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ public class Main : ModBehaviour
private static bool _wasConfigured = false;
private static string _defaultSystemOverride;

public static Dictionary<string, NewHorizonsSystem> SystemDict = new Dictionary<string, NewHorizonsSystem>();
public static Dictionary<string, List<NewHorizonsBody>> BodyDict = new Dictionary<string, List<NewHorizonsBody>>();
public static List<IModBehaviour> MountedAddons = new List<IModBehaviour>();
public static Dictionary<string, NewHorizonsSystem> SystemDict = new();
public static Dictionary<string, List<NewHorizonsBody>> BodyDict = new();
public static List<IModBehaviour> MountedAddons = new();
public static Dictionary<IModBehaviour, AddonConfig> AddonConfigs = new();

public static float SecondsElapsedInLoop = -1;

Expand Down Expand Up @@ -99,6 +100,8 @@ public string CurrentStarSystem
public bool PlayerSpawned { get; set; }
public bool ForceClearCaches { get; set; } // for reloading configs

public bool FlagDLCRequired { get; set; }

public ShipWarpController ShipWarpController { get; private set; }

// API events
Expand Down Expand Up @@ -690,6 +693,14 @@ public void LoadConfigs(IModBehaviour mod)
var relativeDirectory = file.Replace(folder, "");
var body = LoadConfig(mod, relativeDirectory);

// Only bother checking if they need the DLC if they don't have it
if (!HasDLC && !FlagDLCRequired && body.RequiresDLC())
{
FlagDLCRequired = true;
var popupText = TranslationHandler.GetTranslation("DLC_REQUIRED", TranslationHandler.TextType.UI).Replace("{0}", mod.ModHelper.Manifest.Name);
MenuHandler.RegisterOneTimePopup(this, popupText, true);
}

if (body != null)
{
// Wanna track the spawn point of each system
Expand Down Expand Up @@ -737,6 +748,15 @@ private void LoadAddonManifest(string file, IModBehaviour mod)
{
MenuHandler.RegisterOneTimePopup(mod, TranslationHandler.GetTranslation(addonConfig.popupMessage, TranslationHandler.TextType.UI), addonConfig.repeatPopup);
}
if (addonConfig.preloadAssetBundles != null)
{
foreach (var bundle in addonConfig.preloadAssetBundles)
{
AssetBundleUtilities.PreloadBundle(bundle, mod);
}
}

AddonConfigs[mod] = addonConfig;
}

private void LoadTranslations(string folder, IModBehaviour mod)
Expand Down Expand Up @@ -921,8 +941,15 @@ private void ResetCurrentStarSystem()
{
CurrentStarSystem = _defaultSystemOverride;

// Sometimes the override will not support spawning regularly, so always warp in
IsWarpingFromShip = true;
if (BodyDict.TryGetValue(_defaultSystemOverride, out var bodies) && bodies.Any(x => x.Config?.Spawn?.shipSpawn != null))
{
// #738 - Sometimes the override will not support spawning regularly, so always warp in if possible
IsWarpingFromShip = true;
}
else
{
IsWarpingFromShip = false;
}
}
else
{
Expand Down
1 change: 0 additions & 1 deletion NewHorizons/NewHorizonsApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@

namespace NewHorizons
{

public class NewHorizonsApi : INewHorizons
{
[Obsolete("Create(Dictionary<string, object> config) is deprecated, please use LoadConfigs(IModBehaviour mod) instead")]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,69 @@
using HarmonyLib;
using NewHorizons.Utility.Files;
using NewHorizons.Utility.OWML;

namespace NewHorizons.Patches.EyeScenePatches
{
[HarmonyPatch(typeof(SubmitActionLoadScene))]
public static class SubmitActionLoadScenePatches
{
// To call the base method
[HarmonyReversePatch]
[HarmonyPatch(typeof(SubmitActionConfirm), nameof(SubmitActionConfirm.ConfirmSubmit))]
public static void SubmitActionConfirm_ConfirmSubmit(SubmitActionConfirm instance) { }


[HarmonyPrefix]
[HarmonyPatch(nameof(SubmitActionLoadScene.ConfirmSubmit))]
public static void SubmitActionLoadScene_ConfirmSubmit(SubmitActionLoadScene __instance)
public static bool SubmitActionLoadScene_ConfirmSubmit(SubmitActionLoadScene __instance)
{
if (__instance._receivedSubmitAction) return false;

// Title screen can warp you to eye and cause problems.
if (__instance._sceneToLoad == SubmitActionLoadScene.LoadableScenes.EYE)
{
NHLogger.LogWarning("Warping to solar system and then back to eye");
Main.Instance.IsWarpingBackToEye = true;
__instance._sceneToLoad = SubmitActionLoadScene.LoadableScenes.GAME;
}

// modified from patched function
SubmitActionConfirm_ConfirmSubmit(__instance);
__instance._receivedSubmitAction = true;
Locator.GetMenuInputModule().DisableInputs();

Delay.RunWhen(() =>
{
// update text. just use 0%
__instance.ResetStringBuilder();
__instance._nowLoadingSB.Append(UITextLibrary.GetString(UITextType.LoadingMessage));
__instance._nowLoadingSB.Append(0.ToString("P0"));
__instance._loadingText.text = __instance._nowLoadingSB.ToString();
return AssetBundleUtilities.AreRequiredAssetsLoaded();
}, () =>
{
switch (__instance._sceneToLoad)
{
case SubmitActionLoadScene.LoadableScenes.GAME:
LoadManager.LoadSceneAsync(OWScene.SolarSystem, false, LoadManager.FadeType.ToBlack, 1f, false);
__instance.ResetStringBuilder();
__instance._waitingOnStreaming = true;
break;
case SubmitActionLoadScene.LoadableScenes.EYE:
LoadManager.LoadSceneAsync(OWScene.EyeOfTheUniverse, true, LoadManager.FadeType.ToBlack, 1f, false);
__instance.ResetStringBuilder();
break;
case SubmitActionLoadScene.LoadableScenes.TITLE:
LoadManager.LoadScene(OWScene.TitleScreen, LoadManager.FadeType.ToBlack, 2f, true);
break;
case SubmitActionLoadScene.LoadableScenes.CREDITS:
LoadManager.LoadScene(OWScene.Credits_Fast, LoadManager.FadeType.ToBlack, 1f, false);
break;
}
});

return false;
}
}
}
11 changes: 11 additions & 0 deletions NewHorizons/Schemas/addon_manifest_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@
"type": "boolean",
"description": "If popupMessage is set, should it repeat every time the game starts or only once"
},
"preloadAssetBundles": {
"type": "array",
"description": "These asset bundles will be loaded on the title screen and stay loaded. Will improve initial load time at the cost of increased memory use.\nThe path is the relative directory of the asset bundle in the mod folder.",
"items": {
"type": "string"
}
},
"subtitlePath": {
"type": "string",
"description": "The path to the addons subtitle for the main menu.\nDefaults to \"subtitle.png\"."
},
"$schema": {
"type": "string",
"description": "The schema to validate with"
Expand Down
47 changes: 40 additions & 7 deletions NewHorizons/Utility/Files/AssetBundleUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,57 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;

namespace NewHorizons.Utility.Files
{
public static class AssetBundleUtilities
{
public static Dictionary<string, AssetBundle> AssetBundles = new Dictionary<string, AssetBundle>();
public static Dictionary<string, (AssetBundle bundle, bool keepLoaded)> AssetBundles = new();

private static readonly List<AssetBundleCreateRequest> _loadingBundles = new();

public static void ClearCache()
{
foreach (var pair in AssetBundles)
{
if (pair.Value == null) NHLogger.LogError($"The asset bundle for {pair.Key} was null when trying to unload");
else pair.Value.Unload(true);
if (!pair.Value.keepLoaded)
{
if (pair.Value.bundle == null)
{
NHLogger.LogError($"The asset bundle for {pair.Key} was null when trying to unload");
}
else
{
pair.Value.bundle.Unload(true);
}
}

}
AssetBundles.Clear();
AssetBundles = AssetBundles.Where(x => x.Value.keepLoaded).ToDictionary(x => x.Key, x => x.Value);
}

public static void PreloadBundle(string assetBundleRelativeDir, IModBehaviour mod)
{
string key = Path.GetFileName(assetBundleRelativeDir);
var completePath = Path.Combine(mod.ModHelper.Manifest.ModFolderPath, assetBundleRelativeDir);
var request = AssetBundle.LoadFromFileAsync(completePath);
_loadingBundles.Add(request);
NHLogger.Log($"Preloading bundle {assetBundleRelativeDir} - {_loadingBundles.Count} left");
request.completed += _ =>
{
_loadingBundles.Remove(request);
NHLogger.Log($"Finshed preloading bundle {assetBundleRelativeDir} - {_loadingBundles.Count} left");
AssetBundles[key] = (request.assetBundle, true);
};
}

/// <summary>
/// are preloaded bundles done loading?
/// </summary>
public static bool AreRequiredAssetsLoaded() => _loadingBundles.Count == 0;

public static T Load<T>(string assetBundleRelativeDir, string pathInBundle, IModBehaviour mod) where T : UnityEngine.Object
{
string key = Path.GetFileName(assetBundleRelativeDir);
Expand All @@ -32,7 +65,7 @@ public static void ClearCache()

if (AssetBundles.ContainsKey(key))
{
bundle = AssetBundles[key];
bundle = AssetBundles[key].bundle;
}
else
{
Expand All @@ -44,7 +77,7 @@ public static void ClearCache()
return null;
}

AssetBundles[key] = bundle;
AssetBundles[key] = (bundle, false);
}

obj = bundle.LoadAsset<T>(pathInBundle);
Expand Down Expand Up @@ -124,4 +157,4 @@ public static void ReplaceShaders(GameObject prefab)
}
}
}
}
}
2 changes: 1 addition & 1 deletion NewHorizons/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"author": "xen, Bwc9876, clay, MegaPiggy, John, Trifid, Hawkbar, Book",
"name": "New Horizons",
"uniqueName": "xen.NewHorizons",
"version": "1.18.3",
"version": "1.18.4",
"owmlVersion": "2.9.8",
"dependencies": [ "JohnCorby.VanillaFix", "_nebula.MenuFramework", "xen.CommonCameraUtility", "dgarro.CustomShipLogModes" ],
"conflicts": [ "Raicuparta.QuantumSpaceBuddies", "PacificEngine.OW_CommonResources" ],
Expand Down

0 comments on commit fb28b1e

Please sign in to comment.