mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
Merge branch 'dev' into hawkbar-colliders
This commit is contained in:
commit
4e9ec84427
@ -100,6 +100,15 @@ namespace NewHorizons.Builder.Atmosphere
|
||||
atmoGO.transform.position = planetGO.transform.TransformPoint(Vector3.zero);
|
||||
atmoGO.SetActive(true);
|
||||
|
||||
// CullGroups have already set up their renderers when this is done so we need to add ourself to it
|
||||
// TODO: There are probably other builders where this is relevant
|
||||
// This in particular was a bug affecting hazy dreams
|
||||
if (sector != null && sector.gameObject.GetComponent<CullGroup>() is CullGroup cullGroup)
|
||||
{
|
||||
cullGroup.RecursivelyAddRenderers(atmoGO.transform, true);
|
||||
cullGroup.SetVisible(cullGroup.IsVisible());
|
||||
}
|
||||
|
||||
return atmoGO;
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,14 +60,22 @@ namespace NewHorizons.Builder.Body
|
||||
}
|
||||
}
|
||||
|
||||
public static void Make(GameObject planetGO, Sector sector, CometTailModule cometTailModule, PlanetConfig config)
|
||||
public static void Make(GameObject planetGO, Sector sector, CometTailModule cometTailModule, PlanetConfig config, AstroObject ao)
|
||||
{
|
||||
if (config.Orbit.primaryBody == null)
|
||||
var primaryBody = ao.GetPrimaryBody();
|
||||
|
||||
if (!string.IsNullOrEmpty(config.Orbit.primaryBody)) primaryBody = AstroObjectLocator.GetAstroObject(config.Orbit.primaryBody);
|
||||
|
||||
if (primaryBody == null)
|
||||
{
|
||||
NHLogger.LogError($"Comet {planetGO.name} does not orbit anything. That makes no sense");
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(cometTailModule.primaryBody))
|
||||
cometTailModule.primaryBody = !string.IsNullOrEmpty(config.Orbit.primaryBody) ? config.Orbit.primaryBody
|
||||
: primaryBody.GetKey();
|
||||
|
||||
var rootObj = new GameObject("CometRoot");
|
||||
rootObj.SetActive(false);
|
||||
rootObj.transform.parent = sector?.transform ?? planetGO.transform;
|
||||
@ -79,13 +87,11 @@ namespace NewHorizons.Builder.Body
|
||||
|
||||
if (cometTailModule.rotationOverride != null) controller.SetRotationOverride(cometTailModule.rotationOverride);
|
||||
|
||||
if (string.IsNullOrEmpty(cometTailModule.primaryBody)) cometTailModule.primaryBody = config.Orbit.primaryBody;
|
||||
|
||||
Delay.FireOnNextUpdate(() =>
|
||||
{
|
||||
controller.SetPrimaryBody(
|
||||
AstroObjectLocator.GetAstroObject(cometTailModule.primaryBody).transform,
|
||||
AstroObjectLocator.GetAstroObject(config.Orbit.primaryBody).GetAttachedOWRigidbody()
|
||||
AstroObjectLocator.GetAstroObject(cometTailModule.primaryBody).transform,
|
||||
primaryBody.GetAttachedOWRigidbody()
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@ -203,7 +203,7 @@ namespace NewHorizons.Builder.Body
|
||||
|
||||
if (body.Config.CometTail != null)
|
||||
{
|
||||
CometTailBuilder.Make(proxy, null, body.Config.CometTail, body.Config);
|
||||
CometTailBuilder.Make(proxy, null, body.Config.CometTail, body.Config, planetGO.GetComponent<AstroObject>());
|
||||
}
|
||||
|
||||
if (body.Config.Props?.proxyDetails != null)
|
||||
|
||||
@ -473,10 +473,14 @@ namespace NewHorizons.Builder.Props
|
||||
{
|
||||
// These flood toggles are to disable flooded docks on the Stranger
|
||||
// Presumably the user isn't making one of those
|
||||
foreach (var toggle in dock.GetComponents<FloodToggle>())
|
||||
foreach (var toggle in dock.GetComponents<FloodToggle>().Concat(dock.GetComponentsInChildren<FloodToggle>()))
|
||||
{
|
||||
Component.DestroyImmediate(toggle);
|
||||
}
|
||||
foreach (var floodSensor in dock.GetComponents<RingRiverFloodSensor>().Concat(dock.GetComponentsInChildren<RingRiverFloodSensor>()))
|
||||
{
|
||||
Component.DestroyImmediate(floodSensor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -43,6 +43,7 @@ namespace NewHorizons.Builder.Props
|
||||
private static GameObject _autoPrefab;
|
||||
private static GameObject _visionTorchDetectorPrefab;
|
||||
private static GameObject _standingVisionTorchPrefab;
|
||||
private static GameObject _standingVisionTorchCleanPrefab;
|
||||
private static readonly int EmissionMap = Shader.PropertyToID("_EmissionMap");
|
||||
|
||||
private static bool _isInit;
|
||||
@ -90,13 +91,28 @@ namespace NewHorizons.Builder.Props
|
||||
_visionTorchDetectorPrefab.AddComponent<DestroyOnDLC>()._destroyOnDLCNotOwned = true;
|
||||
}
|
||||
|
||||
if (_standingVisionTorchCleanPrefab == null)
|
||||
{
|
||||
_standingVisionTorchCleanPrefab = SearchUtilities.Find("DreamWorld_Body/Sector_DreamWorld/Sector_DreamZone_4/Interactibles_DreamZone_4_Upper/Prefab_IP_VisionTorchProjector")?.gameObject?.InstantiateInactive()?.Rename("Prefab_DW_VisionTorchProjector")?.DontDestroyOnLoad();
|
||||
if (_standingVisionTorchCleanPrefab == null)
|
||||
NHLogger.LogWarning($"Tried to make standing vision torch prefab but couldn't. Do you have the DLC installed?");
|
||||
else
|
||||
{
|
||||
_standingVisionTorchCleanPrefab.AddComponent<DestroyOnDLC>()._destroyOnDLCNotOwned = true;
|
||||
GameObject.DestroyImmediate(_standingVisionTorchCleanPrefab.FindChild("Prefab_IP_Reel_PrisonPeephole_Vision"));
|
||||
}
|
||||
}
|
||||
|
||||
if (_standingVisionTorchPrefab == null)
|
||||
{
|
||||
_standingVisionTorchPrefab = SearchUtilities.Find("RingWorld_Body/Sector_RingWorld/Sector_SecretEntrance/Interactibles_SecretEntrance/Experiment_1/VisionTorchApparatus/VisionTorchRoot/Prefab_IP_VisionTorchProjector")?.gameObject?.InstantiateInactive()?.Rename("Prefab_IP_VisionTorchProjector")?.DontDestroyOnLoad();
|
||||
if (_standingVisionTorchPrefab == null)
|
||||
NHLogger.LogWarning($"Tried to make standing vision torch prefab but couldn't. Do you have the DLC installed?");
|
||||
else
|
||||
{
|
||||
_standingVisionTorchPrefab.AddComponent<DestroyOnDLC>()._destroyOnDLCNotOwned = true;
|
||||
GameObject.Instantiate(_standingVisionTorchCleanPrefab.FindChild("Effects_IP_SIM_VisionTorch"), _standingVisionTorchPrefab.transform, false).Rename("Effects_IP_SIM_VisionTorch");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -446,10 +462,11 @@ namespace NewHorizons.Builder.Props
|
||||
{
|
||||
InitPrefabs();
|
||||
|
||||
if (_standingVisionTorchPrefab == null) return null;
|
||||
if (_standingVisionTorchPrefab == null || _standingVisionTorchCleanPrefab == null) return null;
|
||||
|
||||
// Spawn the torch itself
|
||||
var standingTorch = DetailBuilder.Make(planetGO, sector, mod, _standingVisionTorchPrefab, new DetailInfo(info));
|
||||
var prefab = info.reelCondition == ProjectionInfo.SlideReelCondition.Pristine ? _standingVisionTorchCleanPrefab : _standingVisionTorchPrefab;
|
||||
var standingTorch = DetailBuilder.Make(planetGO, sector, mod, prefab, new DetailInfo(info));
|
||||
|
||||
if (standingTorch == null)
|
||||
{
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using NewHorizons.Components.Volumes;
|
||||
using NewHorizons.External.Modules.Volumes.VolumeInfos;
|
||||
using OWML.Common;
|
||||
using OWML.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
@ -7,12 +8,13 @@ namespace NewHorizons.Builder.Volumes
|
||||
{
|
||||
internal static class CreditsVolumeBuilder
|
||||
{
|
||||
public static LoadCreditsVolume Make(GameObject planetGO, Sector sector, LoadCreditsVolumeInfo info)
|
||||
public static LoadCreditsVolume Make(GameObject planetGO, Sector sector, LoadCreditsVolumeInfo info, IModBehaviour mod)
|
||||
{
|
||||
var volume = VolumeBuilder.Make<LoadCreditsVolume>(planetGO, sector, info);
|
||||
|
||||
volume.gameOver = info.gameOver;
|
||||
volume.deathType = info.deathType == null ? null : EnumUtils.Parse(info.deathType.ToString(), DeathType.Default);
|
||||
volume.mod = mod;
|
||||
|
||||
volume.gameObject.SetActive(true);
|
||||
|
||||
|
||||
@ -247,7 +247,7 @@ namespace NewHorizons.Builder.Volumes
|
||||
{
|
||||
foreach (var creditsVolume in config.Volumes.creditsVolume)
|
||||
{
|
||||
CreditsVolumeBuilder.Make(go, sector, creditsVolume);
|
||||
CreditsVolumeBuilder.Make(go, sector, creditsVolume, mod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
using NewHorizons.External.Modules;
|
||||
using NewHorizons.External.SerializableEnums;
|
||||
using NewHorizons.Handlers;
|
||||
using NewHorizons.Patches.CreditsScenePatches;
|
||||
using NewHorizons.Utility.Files;
|
||||
using NewHorizons.Utility.OWML;
|
||||
using OWML.Common;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -15,14 +19,14 @@ namespace NewHorizons.Components
|
||||
/// Mod unique id to game over module list
|
||||
/// Done as a dictionary so that Reload Configs can overwrite entries per mod
|
||||
/// </summary>
|
||||
public static Dictionary<string, GameOverModule[]> gameOvers = new();
|
||||
public static Dictionary<IModBehaviour, GameOverModule[]> gameOvers = new();
|
||||
|
||||
public static NHGameOverManager Instance { get; private set; }
|
||||
|
||||
private GameOverController _gameOverController;
|
||||
private PlayerCameraEffectController _playerCameraEffectController;
|
||||
|
||||
private GameOverModule[] _gameOvers;
|
||||
private (IModBehaviour mod, GameOverModule gameOver)[] _gameOvers;
|
||||
|
||||
private bool _gameOverSequenceStarted;
|
||||
|
||||
@ -36,25 +40,35 @@ namespace NewHorizons.Components
|
||||
_gameOverController = FindObjectOfType<GameOverController>();
|
||||
_playerCameraEffectController = FindObjectOfType<PlayerCameraEffectController>();
|
||||
|
||||
_gameOvers = gameOvers.SelectMany(x => x.Value).ToArray();
|
||||
var gameOverList = new List<(IModBehaviour, GameOverModule)>();
|
||||
foreach (var gameOverPair in gameOvers)
|
||||
{
|
||||
var mod = gameOverPair.Key;
|
||||
foreach (var gameOver in gameOverPair.Value)
|
||||
{
|
||||
gameOverList.Add((mod, gameOver));
|
||||
}
|
||||
}
|
||||
_gameOvers = gameOverList.ToArray();
|
||||
}
|
||||
|
||||
public void TryHijackDeathSequence()
|
||||
{
|
||||
var gameOver = _gameOvers.FirstOrDefault(x => !string.IsNullOrEmpty(x.condition) && DialogueConditionManager.SharedInstance.GetConditionState(x.condition));
|
||||
if (!_gameOverSequenceStarted && gameOver != null && !Locator.GetDeathManager()._finishedDLC)
|
||||
var gameOver = _gameOvers.FirstOrDefault(x => !string.IsNullOrEmpty(x.gameOver.condition)
|
||||
&& DialogueConditionManager.SharedInstance.GetConditionState(x.gameOver.condition));
|
||||
if (!_gameOverSequenceStarted && gameOver != default && !Locator.GetDeathManager()._finishedDLC)
|
||||
{
|
||||
StartGameOverSequence(gameOver, null);
|
||||
StartGameOverSequence(gameOver.gameOver, null, gameOver.mod);
|
||||
}
|
||||
}
|
||||
|
||||
public void StartGameOverSequence(GameOverModule gameOver, DeathType? deathType)
|
||||
public void StartGameOverSequence(GameOverModule gameOver, DeathType? deathType, IModBehaviour mod)
|
||||
{
|
||||
_gameOverSequenceStarted = true;
|
||||
Delay.StartCoroutine(GameOver(gameOver, deathType));
|
||||
Delay.StartCoroutine(GameOver(gameOver, deathType, mod));
|
||||
}
|
||||
|
||||
private IEnumerator GameOver(GameOverModule gameOver, DeathType? deathType)
|
||||
private IEnumerator GameOver(GameOverModule gameOver, DeathType? deathType, IModBehaviour mod)
|
||||
{
|
||||
OWInput.ChangeInputMode(InputMode.None);
|
||||
ReticleController.Hide();
|
||||
@ -104,12 +118,12 @@ namespace NewHorizons.Components
|
||||
yield return new WaitUntil(ReadytoLoadCreditsScene);
|
||||
}
|
||||
|
||||
LoadCreditsScene(gameOver);
|
||||
LoadCreditsScene(gameOver, mod);
|
||||
}
|
||||
|
||||
private bool ReadytoLoadCreditsScene() => _gameOverController._fadedOutText && _gameOverController._textAnimator.IsComplete();
|
||||
|
||||
private void LoadCreditsScene(GameOverModule gameOver)
|
||||
private void LoadCreditsScene(GameOverModule gameOver, IModBehaviour mod)
|
||||
{
|
||||
NHLogger.LogVerbose($"Load credits {gameOver.creditsType}");
|
||||
|
||||
@ -125,6 +139,9 @@ namespace NewHorizons.Components
|
||||
TimelineObliterationController.s_hasRealityEnded = true;
|
||||
LoadManager.LoadScene(OWScene.Credits_Fast, LoadManager.FadeType.ToBlack);
|
||||
break;
|
||||
case NHCreditsType.Custom:
|
||||
LoadCustomCreditsScene(gameOver, mod);
|
||||
break;
|
||||
default:
|
||||
// GameOverController disables post processing
|
||||
_gameOverController._flashbackCamera.postProcessing.enabled = true;
|
||||
@ -134,5 +151,42 @@ namespace NewHorizons.Components
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadCustomCreditsScene(GameOverModule gameOver, IModBehaviour mod)
|
||||
{
|
||||
LoadManager.LoadScene(OWScene.Credits_Fast, LoadManager.FadeType.ToBlack);
|
||||
|
||||
// Unfortunately we can't make this a private method, as EventArgs/EventHandler enforces the (sender, e) parameters, which prevents us from passing in gameOver and mod, which we need.
|
||||
EventHandler onCreditsBuilt = null; // needs to be done so we can unsubscribe from within the lambda.
|
||||
onCreditsBuilt = (sender, e) =>
|
||||
{
|
||||
// Unsubscribe first, playing it safe in case it NREs
|
||||
CreditsPatches.CreditsBuilt -= onCreditsBuilt;
|
||||
|
||||
// Patch new music clip
|
||||
var musicSource = Locator.FindObjectsOfType<OWAudioSource>().Where(x => x.name == "AudioSource").Single(); // AudioSource that plays the credits music is literally called "AudioSource", luckily it's the only one called that. Lazy OW devs do be lazy.
|
||||
if (!string.IsNullOrEmpty(gameOver.audio)) // string.Empty is default value for "audio" in GameOverModule, means no audio is specified.
|
||||
{
|
||||
AudioUtilities.SetAudioClip(musicSource, gameOver.audio, mod); // Load audio if specified
|
||||
}
|
||||
else
|
||||
{
|
||||
musicSource.AssignAudioLibraryClip(AudioType.PLACEHOLDER); // Otherwise default custom credits are silent - AudioType.PLACEHOLDER is silence (apparently)
|
||||
}
|
||||
|
||||
musicSource.loop = gameOver.audioLooping;
|
||||
musicSource._maxSourceVolume = gameOver.audioVolume;
|
||||
|
||||
// Override fade in
|
||||
musicSource.Stop();
|
||||
musicSource.Play();
|
||||
|
||||
// Patch scroll duration
|
||||
var creditsScroll = Locator.FindObjectOfType<CreditsScrollSection>();
|
||||
creditsScroll._scrollDuration = gameOver.length;
|
||||
};
|
||||
|
||||
CreditsPatches.CreditsBuilt += onCreditsBuilt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using NewHorizons.External.Modules;
|
||||
using OWML.Common;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
@ -8,12 +9,13 @@ namespace NewHorizons.Components.Volumes
|
||||
{
|
||||
public GameOverModule gameOver;
|
||||
public DeathType? deathType;
|
||||
public IModBehaviour mod;
|
||||
|
||||
public override void OnTriggerVolumeEntry(GameObject hitObj)
|
||||
{
|
||||
if (hitObj.CompareTag("PlayerDetector") && enabled && (string.IsNullOrEmpty(gameOver.condition) || DialogueConditionManager.SharedInstance.GetConditionState(gameOver.condition)))
|
||||
{
|
||||
NHGameOverManager.Instance.StartGameOverSequence(gameOver, deathType);
|
||||
NHGameOverManager.Instance.StartGameOverSequence(gameOver, deathType, mod);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
25
NewHorizons/External/Modules/GameOverModule.cs
vendored
25
NewHorizons/External/Modules/GameOverModule.cs
vendored
@ -24,6 +24,31 @@ namespace NewHorizons.External.Modules
|
||||
/// </summary>
|
||||
public string condition;
|
||||
|
||||
/// <summary>
|
||||
/// The audio to use for the credits music. Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list.
|
||||
/// Credits will be silent unless this attribute is specified.
|
||||
/// Note: only applies when creditsType is set to "custom".
|
||||
/// </summary>
|
||||
public string audio;
|
||||
|
||||
/// <summary>
|
||||
/// The length of the fade in and out for the credits music.
|
||||
/// Note: only applies when creditsType is set to "custom".
|
||||
/// </summary>
|
||||
[DefaultValue(1f)] public float audioVolume = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the credits music should loop.
|
||||
/// Note: only applies when creditsType is set to "custom".
|
||||
/// </summary>
|
||||
[DefaultValue(false)] public bool audioLooping = false;
|
||||
|
||||
/// <summary>
|
||||
/// Duration of the credits scroll in seconds.
|
||||
/// Note: only applies when creditsType is set to "custom".
|
||||
/// </summary>
|
||||
[DefaultValue(120f)] public float length = 120f;
|
||||
|
||||
/// <summary>
|
||||
/// The type of credits that will run after the game over message is shown
|
||||
/// </summary>
|
||||
|
||||
@ -82,7 +82,7 @@ namespace NewHorizons.External.Modules.Props.EchoesOfTheEye
|
||||
[DefaultValue("sevenSlides")] public SlideReelType reelModel = SlideReelType.SevenSlides;
|
||||
|
||||
/// <summary>
|
||||
/// Exclusive to the slide reel type. Condition/material of the reel. Antique is the Stranger, Pristine is the Dreamworld, Rusted is a burned reel.
|
||||
/// Exclusive to the slide reel and standing vision torch type. Condition/material of the reel. Antique is the Stranger, Pristine is the Dreamworld, Rusted (exclusive to slide reels) is a burned reel.
|
||||
/// </summary>
|
||||
[DefaultValue("antique")] public SlideReelCondition reelCondition = SlideReelCondition.Antique;
|
||||
|
||||
|
||||
@ -13,6 +13,8 @@ namespace NewHorizons.External.SerializableEnums
|
||||
|
||||
[EnumMember(Value = @"kazoo")] Kazoo = 2,
|
||||
|
||||
[EnumMember(Value = @"none")] None = 3
|
||||
[EnumMember(Value = @"custom")] Custom = 3,
|
||||
|
||||
[EnumMember(Value = @"none")] None = 4
|
||||
}
|
||||
}
|
||||
|
||||
@ -657,7 +657,7 @@ namespace NewHorizons.Handlers
|
||||
|
||||
if (body.Config.CometTail != null)
|
||||
{
|
||||
CometTailBuilder.Make(go, sector, body.Config.CometTail, body.Config);
|
||||
CometTailBuilder.Make(go, sector, body.Config.CometTail, body.Config, go.GetComponent<AstroObject>());
|
||||
}
|
||||
|
||||
if (body.Config.Lava != null)
|
||||
|
||||
@ -849,7 +849,7 @@ namespace NewHorizons
|
||||
}
|
||||
if (addonConfig.gameOver != null)
|
||||
{
|
||||
NHGameOverManager.gameOvers[mod.ModHelper.Manifest.UniqueName] = addonConfig.gameOver;
|
||||
NHGameOverManager.gameOvers[mod] = addonConfig.gameOver;
|
||||
}
|
||||
|
||||
AddonConfigs[mod] = addonConfig;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<Project>
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<OutputPath>$(AppData)\OuterWildsModManager\OWML\Mods\xen.NewHorizons</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
@ -1,17 +1,30 @@
|
||||
using HarmonyLib;
|
||||
using NewHorizons.Handlers;
|
||||
using System;
|
||||
|
||||
namespace NewHorizons.Patches.CreditsScenePatches
|
||||
{
|
||||
[HarmonyPatch(typeof(Credits))]
|
||||
public static class CreditsPatches
|
||||
{
|
||||
public static event EventHandler CreditsBuilt; // Used in NHGameOverManager to patch credits music and scroll speed
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(Credits.Start))]
|
||||
public static void Credits_Start(Credits __instance)
|
||||
{
|
||||
CreditsHandler.AddCredits(__instance);
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(nameof(Credits.BuildCredits))]
|
||||
public static void Credits_BuildCredits_Post(Credits __instance)
|
||||
{
|
||||
// Do things BuildCredits() normally does
|
||||
|
||||
// Fire event once finished
|
||||
CreditsBuilt?.Invoke(__instance, new EventArgs());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -27,23 +27,34 @@ namespace NewHorizons.Utility.Files
|
||||
source._clipArrayLength = 0;
|
||||
source._clipSelectionOnPlay = OWAudioSource.ClipSelectionOnPlay.MANUAL;
|
||||
source.clip = clip;
|
||||
NHLogger.LogVerbose($"[{nameof(AudioUtilities)}] : Audio {audio} was loaded from a file");
|
||||
return;
|
||||
}
|
||||
catch
|
||||
{
|
||||
NHLogger.LogError($"Could not load file {audio}");
|
||||
NHLogger.LogError($"[{nameof(AudioUtilities)}] : Could not load file {audio}");
|
||||
}
|
||||
}
|
||||
|
||||
if (EnumUtils.TryParse(audio, out AudioType type))
|
||||
{
|
||||
source._audioLibraryClip = type;
|
||||
NHLogger.LogVerbose($"[{nameof(AudioUtilities)}] : Audio {audio} was an AudioType enum");
|
||||
}
|
||||
else
|
||||
{
|
||||
var audioClip = SearchUtilities.FindResourceOfTypeAndName<AudioClip>(audio);
|
||||
if (audioClip == null) NHLogger.Log($"Couldn't find audio clip {audio}");
|
||||
else source.clip = audioClip;
|
||||
if (audioClip == null)
|
||||
{
|
||||
NHLogger.LogError($"[{nameof(AudioUtilities)}] : Couldn't find audio clip {audio}");
|
||||
}
|
||||
else
|
||||
{
|
||||
NHLogger.LogVerbose($"[{nameof(AudioUtilities)}] : Audio {audio} was an AudioClip resource");
|
||||
// Else if this is set it will try to change the clip back when it starts playing
|
||||
source._audioLibraryClip = AudioType.None;
|
||||
source.clip = audioClip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -445,6 +445,11 @@ namespace NewHorizons.Utility
|
||||
return globalMusicController._endTimesSource.clip.length;
|
||||
}
|
||||
|
||||
public static string GetKey(this AstroObject ao)
|
||||
{
|
||||
return ao._name == AstroObject.Name.CustomString ? ao.GetCustomName() : ao._name.ToString();
|
||||
}
|
||||
|
||||
public static CodeMatcher LogInstructions(this CodeMatcher matcher, string prefix)
|
||||
{
|
||||
matcher.InstructionEnumeration().LogInstructions(prefix);
|
||||
|
||||
@ -65,7 +65,7 @@ namespace NewHorizons.Utility.OuterWilds
|
||||
|
||||
public static void RegisterCustomAstroObject(AstroObject ao)
|
||||
{
|
||||
var key = ao._name == AstroObject.Name.CustomString ? ao.GetCustomName() : ao._name.ToString();
|
||||
var key = ao.GetKey();
|
||||
|
||||
if (_customAstroObjectDictionary.ContainsKey(key))
|
||||
{
|
||||
@ -81,7 +81,7 @@ namespace NewHorizons.Utility.OuterWilds
|
||||
|
||||
public static void DeregisterCustomAstroObject(AstroObject ao)
|
||||
{
|
||||
var key = ao._name == AstroObject.Name.CustomString ? ao.GetCustomName() : ao._name.ToString();
|
||||
var key = ao.GetKey();
|
||||
_customAstroObjectDictionary.Remove(key);
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
"author": "xen, Bwc9876, JohnCorby, MegaPiggy, and friends",
|
||||
"name": "New Horizons",
|
||||
"uniqueName": "xen.NewHorizons",
|
||||
"version": "1.27.3",
|
||||
"version": "1.27.4",
|
||||
"owmlVersion": "2.12.1",
|
||||
"dependencies": [ "JohnCorby.VanillaFix", "xen.CommonCameraUtility", "dgarro.CustomShipLogModes" ],
|
||||
"conflicts": [ "PacificEngine.OW_CommonResources" ],
|
||||
|
||||
@ -20,12 +20,12 @@ You can use [Unity Explorer](https://outerwildsmods.com/mods/unityexplorer) to t
|
||||
|
||||
## Asset Bundles
|
||||
|
||||
There is an [old unity template](https://github.com/xen-42/outer-wilds-unity-template) and a [new one](https://github.com/ow-mods/outer-wilds-unity-wiki/wiki#outer-wilds-unity-assets)
|
||||
There is an [old unity template](https://github.com/xen-42/outer-wilds-unity-template) and a [new one](https://github.com/ow-mods/outer-wilds-unity-wiki/wiki/Tools-%E2%80%90-Outer-Wilds-Unity-Assets-repository)
|
||||
|
||||
The project contains ripped versions of all the game scripts, meaning you can put things like DirectionalForceVolumes in your Unity project to have artificial gravity volumes loaded right into the game.\
|
||||
Either one works, but the new one has more tools and better versions of the scripts (in exchange for being invite-only).
|
||||
|
||||
Read [this guide](https://github.com/ow-mods/outer-wilds-unity-wiki/wiki/Tutorials-%E2%80%90-Using-asset-bundles) on how to work with asset bundles in editor.
|
||||
Read [this guide](https://github.com/ow-mods/outer-wilds-unity-wiki/wiki/Tutorials-%E2%80%90-Using-AssetBundles) on how to work with asset bundles in editor.
|
||||
|
||||
## Importing a planet's surface from Unity
|
||||
|
||||
|
||||
@ -19,5 +19,5 @@ which interact poorly with the fluid detector and can mess up the movement of th
|
||||
Either clear the .nhcache files or enable Debug mode to always regenerate the text cache.
|
||||
|
||||
## Prop placer is gone!
|
||||
This is not a bug, actually. We removed prop placer because it was inconsistent and buggy, and no one in years cared enough to fix it.
|
||||
Use the debug raycast button and Unity Explorer to place your props, or otherwise work in unity editor.
|
||||
It has been moved to a [separate mod](https://outerwildsmods.com/mods/propplacer/).
|
||||
Use it in addition to the debug raycast button and Unity Explorer to place your props, or otherwise work in unity editor.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user