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 dockedRafts
This commit is contained in:
commit
4a6d3cfcf6
7
.github/workflows/build.yaml
vendored
7
.github/workflows/build.yaml
vendored
@ -62,7 +62,8 @@ jobs:
|
|||||||
name: NewHorizons-Schemas-${{ inputs.build_type }}
|
name: NewHorizons-Schemas-${{ inputs.build_type }}
|
||||||
path: .\NewHorizons\Schemas
|
path: .\NewHorizons\Schemas
|
||||||
|
|
||||||
- name: Check Changed Schemas
|
- name: Verify Changed Schemas
|
||||||
|
uses: tj-actions/verify-changed-files@v20
|
||||||
id: changed_files
|
id: changed_files
|
||||||
run: |
|
with:
|
||||||
echo "files_changed=$(git diff --exit-code NewHorizons/Schemas 2>&1>$null && echo false || echo true)" >> $Env:GITHUB_OUTPUT
|
files: NewHorizons/Schemas/**
|
||||||
@ -473,10 +473,14 @@ namespace NewHorizons.Builder.Props
|
|||||||
{
|
{
|
||||||
// These flood toggles are to disable flooded docks on the Stranger
|
// These flood toggles are to disable flooded docks on the Stranger
|
||||||
// Presumably the user isn't making one of those
|
// 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);
|
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 _autoPrefab;
|
||||||
private static GameObject _visionTorchDetectorPrefab;
|
private static GameObject _visionTorchDetectorPrefab;
|
||||||
private static GameObject _standingVisionTorchPrefab;
|
private static GameObject _standingVisionTorchPrefab;
|
||||||
|
private static GameObject _standingVisionTorchCleanPrefab;
|
||||||
private static readonly int EmissionMap = Shader.PropertyToID("_EmissionMap");
|
private static readonly int EmissionMap = Shader.PropertyToID("_EmissionMap");
|
||||||
|
|
||||||
private static bool _isInit;
|
private static bool _isInit;
|
||||||
@ -90,13 +91,28 @@ namespace NewHorizons.Builder.Props
|
|||||||
_visionTorchDetectorPrefab.AddComponent<DestroyOnDLC>()._destroyOnDLCNotOwned = true;
|
_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)
|
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();
|
_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)
|
if (_standingVisionTorchPrefab == null)
|
||||||
NHLogger.LogWarning($"Tried to make standing vision torch prefab but couldn't. Do you have the DLC installed?");
|
NHLogger.LogWarning($"Tried to make standing vision torch prefab but couldn't. Do you have the DLC installed?");
|
||||||
else
|
else
|
||||||
|
{
|
||||||
_standingVisionTorchPrefab.AddComponent<DestroyOnDLC>()._destroyOnDLCNotOwned = true;
|
_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();
|
InitPrefabs();
|
||||||
|
|
||||||
if (_standingVisionTorchPrefab == null) return null;
|
if (_standingVisionTorchPrefab == null || _standingVisionTorchCleanPrefab == null) return null;
|
||||||
|
|
||||||
// Spawn the torch itself
|
// 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)
|
if (standingTorch == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using NewHorizons.Components.Volumes;
|
using NewHorizons.Components.Volumes;
|
||||||
using NewHorizons.External.Modules.Volumes.VolumeInfos;
|
using NewHorizons.External.Modules.Volumes.VolumeInfos;
|
||||||
|
using OWML.Common;
|
||||||
using OWML.Utils;
|
using OWML.Utils;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@ -7,12 +8,13 @@ namespace NewHorizons.Builder.Volumes
|
|||||||
{
|
{
|
||||||
internal static class CreditsVolumeBuilder
|
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);
|
var volume = VolumeBuilder.Make<LoadCreditsVolume>(planetGO, sector, info);
|
||||||
|
|
||||||
volume.gameOver = info.gameOver;
|
volume.gameOver = info.gameOver;
|
||||||
volume.deathType = info.deathType == null ? null : EnumUtils.Parse(info.deathType.ToString(), DeathType.Default);
|
volume.deathType = info.deathType == null ? null : EnumUtils.Parse(info.deathType.ToString(), DeathType.Default);
|
||||||
|
volume.mod = mod;
|
||||||
|
|
||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -216,7 +216,7 @@ namespace NewHorizons.Builder.Volumes
|
|||||||
{
|
{
|
||||||
foreach (var creditsVolume in config.Volumes.creditsVolume)
|
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.Modules;
|
||||||
using NewHorizons.External.SerializableEnums;
|
using NewHorizons.External.SerializableEnums;
|
||||||
using NewHorizons.Handlers;
|
using NewHorizons.Handlers;
|
||||||
|
using NewHorizons.Patches.CreditsScenePatches;
|
||||||
|
using NewHorizons.Utility.Files;
|
||||||
using NewHorizons.Utility.OWML;
|
using NewHorizons.Utility.OWML;
|
||||||
|
using OWML.Common;
|
||||||
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -15,14 +19,14 @@ namespace NewHorizons.Components
|
|||||||
/// Mod unique id to game over module list
|
/// Mod unique id to game over module list
|
||||||
/// Done as a dictionary so that Reload Configs can overwrite entries per mod
|
/// Done as a dictionary so that Reload Configs can overwrite entries per mod
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Dictionary<string, GameOverModule[]> gameOvers = new();
|
public static Dictionary<IModBehaviour, GameOverModule[]> gameOvers = new();
|
||||||
|
|
||||||
public static NHGameOverManager Instance { get; private set; }
|
public static NHGameOverManager Instance { get; private set; }
|
||||||
|
|
||||||
private GameOverController _gameOverController;
|
private GameOverController _gameOverController;
|
||||||
private PlayerCameraEffectController _playerCameraEffectController;
|
private PlayerCameraEffectController _playerCameraEffectController;
|
||||||
|
|
||||||
private GameOverModule[] _gameOvers;
|
private (IModBehaviour mod, GameOverModule gameOver)[] _gameOvers;
|
||||||
|
|
||||||
private bool _gameOverSequenceStarted;
|
private bool _gameOverSequenceStarted;
|
||||||
|
|
||||||
@ -36,25 +40,35 @@ namespace NewHorizons.Components
|
|||||||
_gameOverController = FindObjectOfType<GameOverController>();
|
_gameOverController = FindObjectOfType<GameOverController>();
|
||||||
_playerCameraEffectController = FindObjectOfType<PlayerCameraEffectController>();
|
_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()
|
public void TryHijackDeathSequence()
|
||||||
{
|
{
|
||||||
var gameOver = _gameOvers.FirstOrDefault(x => !string.IsNullOrEmpty(x.condition) && DialogueConditionManager.SharedInstance.GetConditionState(x.condition));
|
var gameOver = _gameOvers.FirstOrDefault(x => !string.IsNullOrEmpty(x.gameOver.condition)
|
||||||
if (!_gameOverSequenceStarted && gameOver != null && !Locator.GetDeathManager()._finishedDLC)
|
&& 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;
|
_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);
|
OWInput.ChangeInputMode(InputMode.None);
|
||||||
ReticleController.Hide();
|
ReticleController.Hide();
|
||||||
@ -104,12 +118,12 @@ namespace NewHorizons.Components
|
|||||||
yield return new WaitUntil(ReadytoLoadCreditsScene);
|
yield return new WaitUntil(ReadytoLoadCreditsScene);
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadCreditsScene(gameOver);
|
LoadCreditsScene(gameOver, mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ReadytoLoadCreditsScene() => _gameOverController._fadedOutText && _gameOverController._textAnimator.IsComplete();
|
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}");
|
NHLogger.LogVerbose($"Load credits {gameOver.creditsType}");
|
||||||
|
|
||||||
@ -125,6 +139,9 @@ namespace NewHorizons.Components
|
|||||||
TimelineObliterationController.s_hasRealityEnded = true;
|
TimelineObliterationController.s_hasRealityEnded = true;
|
||||||
LoadManager.LoadScene(OWScene.Credits_Fast, LoadManager.FadeType.ToBlack);
|
LoadManager.LoadScene(OWScene.Credits_Fast, LoadManager.FadeType.ToBlack);
|
||||||
break;
|
break;
|
||||||
|
case NHCreditsType.Custom:
|
||||||
|
LoadCustomCreditsScene(gameOver, mod);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// GameOverController disables post processing
|
// GameOverController disables post processing
|
||||||
_gameOverController._flashbackCamera.postProcessing.enabled = true;
|
_gameOverController._flashbackCamera.postProcessing.enabled = true;
|
||||||
@ -134,5 +151,42 @@ namespace NewHorizons.Components
|
|||||||
break;
|
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 NewHorizons.External.Modules;
|
||||||
|
using OWML.Common;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
|
||||||
@ -8,12 +9,13 @@ namespace NewHorizons.Components.Volumes
|
|||||||
{
|
{
|
||||||
public GameOverModule gameOver;
|
public GameOverModule gameOver;
|
||||||
public DeathType? deathType;
|
public DeathType? deathType;
|
||||||
|
public IModBehaviour mod;
|
||||||
|
|
||||||
public override void OnTriggerVolumeEntry(GameObject hitObj)
|
public override void OnTriggerVolumeEntry(GameObject hitObj)
|
||||||
{
|
{
|
||||||
if (hitObj.CompareTag("PlayerDetector") && enabled && (string.IsNullOrEmpty(gameOver.condition) || DialogueConditionManager.SharedInstance.GetConditionState(gameOver.condition)))
|
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>
|
/// </summary>
|
||||||
public string condition;
|
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>
|
/// <summary>
|
||||||
/// The type of credits that will run after the game over message is shown
|
/// The type of credits that will run after the game over message is shown
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -82,7 +82,7 @@ namespace NewHorizons.External.Modules.Props.EchoesOfTheEye
|
|||||||
[DefaultValue("sevenSlides")] public SlideReelType reelModel = SlideReelType.SevenSlides;
|
[DefaultValue("sevenSlides")] public SlideReelType reelModel = SlideReelType.SevenSlides;
|
||||||
|
|
||||||
/// <summary>
|
/// <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>
|
/// </summary>
|
||||||
[DefaultValue("antique")] public SlideReelCondition reelCondition = SlideReelCondition.Antique;
|
[DefaultValue("antique")] public SlideReelCondition reelCondition = SlideReelCondition.Antique;
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,8 @@ namespace NewHorizons.External.SerializableEnums
|
|||||||
|
|
||||||
[EnumMember(Value = @"kazoo")] Kazoo = 2,
|
[EnumMember(Value = @"kazoo")] Kazoo = 2,
|
||||||
|
|
||||||
[EnumMember(Value = @"none")] None = 3
|
[EnumMember(Value = @"custom")] Custom = 3,
|
||||||
|
|
||||||
|
[EnumMember(Value = @"none")] None = 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -850,7 +850,7 @@ namespace NewHorizons
|
|||||||
}
|
}
|
||||||
if (addonConfig.gameOver != null)
|
if (addonConfig.gameOver != null)
|
||||||
{
|
{
|
||||||
NHGameOverManager.gameOvers[mod.ModHelper.Manifest.UniqueName] = addonConfig.gameOver;
|
NHGameOverManager.gameOvers[mod] = addonConfig.gameOver;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddonConfigs[mod] = addonConfig;
|
AddonConfigs[mod] = addonConfig;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputPath>$(AppData)\OuterWildsModManager\OWML\Mods\xen.NewHorizons</OutputPath>
|
<OutputPath>$(AppData)\OuterWildsModManager\OWML\Mods\xen.NewHorizons</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@ -1,17 +1,30 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using NewHorizons.Handlers;
|
using NewHorizons.Handlers;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace NewHorizons.Patches.CreditsScenePatches
|
namespace NewHorizons.Patches.CreditsScenePatches
|
||||||
{
|
{
|
||||||
[HarmonyPatch(typeof(Credits))]
|
[HarmonyPatch(typeof(Credits))]
|
||||||
public static class CreditsPatches
|
public static class CreditsPatches
|
||||||
{
|
{
|
||||||
|
public static event EventHandler CreditsBuilt; // Used in NHGameOverManager to patch credits music and scroll speed
|
||||||
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(nameof(Credits.Start))]
|
[HarmonyPatch(nameof(Credits.Start))]
|
||||||
public static void Credits_Start(Credits __instance)
|
public static void Credits_Start(Credits __instance)
|
||||||
{
|
{
|
||||||
CreditsHandler.AddCredits(__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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -103,6 +103,27 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Condition that must be true for this game over to trigger. If this is on a LoadCreditsVolume, leave empty to always trigger this game over.\nNote this is a regular dialogue condition, not a persistent condition."
|
"description": "Condition that must be true for this game over to trigger. If this is on a LoadCreditsVolume, leave empty to always trigger this game over.\nNote this is a regular dialogue condition, not a persistent condition."
|
||||||
},
|
},
|
||||||
|
"audio": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The audio to use for the credits music. Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list.\nCredits will be silent unless this attribute is specified.\nNote: only applies when creditsType is set to \"custom\"."
|
||||||
|
},
|
||||||
|
"audioVolume": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "The length of the fade in and out for the credits music.\nNote: only applies when creditsType is set to \"custom\".",
|
||||||
|
"format": "float",
|
||||||
|
"default": 1.0
|
||||||
|
},
|
||||||
|
"audioLooping": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Determines if the credits music should loop.\nNote: only applies when creditsType is set to \"custom\".",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "Duration of the credits scroll in seconds.\nNote: only applies when creditsType is set to \"custom\".",
|
||||||
|
"format": "float",
|
||||||
|
"default": 120.0
|
||||||
|
},
|
||||||
"creditsType": {
|
"creditsType": {
|
||||||
"description": "The type of credits that will run after the game over message is shown",
|
"description": "The type of credits that will run after the game over message is shown",
|
||||||
"default": "fast",
|
"default": "fast",
|
||||||
@ -152,12 +173,14 @@
|
|||||||
"Fast",
|
"Fast",
|
||||||
"Final",
|
"Final",
|
||||||
"Kazoo",
|
"Kazoo",
|
||||||
|
"Custom",
|
||||||
"None"
|
"None"
|
||||||
],
|
],
|
||||||
"enum": [
|
"enum": [
|
||||||
"fast",
|
"fast",
|
||||||
"final",
|
"final",
|
||||||
"kazoo",
|
"kazoo",
|
||||||
|
"custom",
|
||||||
"none"
|
"none"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2964,7 +2964,7 @@
|
|||||||
"$ref": "#/definitions/SlideReelType"
|
"$ref": "#/definitions/SlideReelType"
|
||||||
},
|
},
|
||||||
"reelCondition": {
|
"reelCondition": {
|
||||||
"description": "Exclusive to the slide reel type. Condition/material of the reel. Antique is the Stranger, Pristine is the Dreamworld, Rusted is a burned reel.",
|
"description": "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.",
|
||||||
"default": "antique",
|
"default": "antique",
|
||||||
"$ref": "#/definitions/SlideReelCondition"
|
"$ref": "#/definitions/SlideReelCondition"
|
||||||
},
|
},
|
||||||
@ -6529,6 +6529,27 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Condition that must be true for this game over to trigger. If this is on a LoadCreditsVolume, leave empty to always trigger this game over.\nNote this is a regular dialogue condition, not a persistent condition."
|
"description": "Condition that must be true for this game over to trigger. If this is on a LoadCreditsVolume, leave empty to always trigger this game over.\nNote this is a regular dialogue condition, not a persistent condition."
|
||||||
},
|
},
|
||||||
|
"audio": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The audio to use for the credits music. Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list.\nCredits will be silent unless this attribute is specified.\nNote: only applies when creditsType is set to \"custom\"."
|
||||||
|
},
|
||||||
|
"audioVolume": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "The length of the fade in and out for the credits music.\nNote: only applies when creditsType is set to \"custom\".",
|
||||||
|
"format": "float",
|
||||||
|
"default": 1.0
|
||||||
|
},
|
||||||
|
"audioLooping": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Determines if the credits music should loop.\nNote: only applies when creditsType is set to \"custom\".",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "Duration of the credits scroll in seconds.\nNote: only applies when creditsType is set to \"custom\".",
|
||||||
|
"format": "float",
|
||||||
|
"default": 120.0
|
||||||
|
},
|
||||||
"creditsType": {
|
"creditsType": {
|
||||||
"description": "The type of credits that will run after the game over message is shown",
|
"description": "The type of credits that will run after the game over message is shown",
|
||||||
"default": "fast",
|
"default": "fast",
|
||||||
@ -6543,12 +6564,14 @@
|
|||||||
"Fast",
|
"Fast",
|
||||||
"Final",
|
"Final",
|
||||||
"Kazoo",
|
"Kazoo",
|
||||||
|
"Custom",
|
||||||
"None"
|
"None"
|
||||||
],
|
],
|
||||||
"enum": [
|
"enum": [
|
||||||
"fast",
|
"fast",
|
||||||
"final",
|
"final",
|
||||||
"kazoo",
|
"kazoo",
|
||||||
|
"custom",
|
||||||
"none"
|
"none"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@ -27,23 +27,34 @@ namespace NewHorizons.Utility.Files
|
|||||||
source._clipArrayLength = 0;
|
source._clipArrayLength = 0;
|
||||||
source._clipSelectionOnPlay = OWAudioSource.ClipSelectionOnPlay.MANUAL;
|
source._clipSelectionOnPlay = OWAudioSource.ClipSelectionOnPlay.MANUAL;
|
||||||
source.clip = clip;
|
source.clip = clip;
|
||||||
|
NHLogger.LogVerbose($"[{nameof(AudioUtilities)}] : Audio {audio} was loaded from a file");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
NHLogger.LogError($"Could not load file {audio}");
|
NHLogger.LogError($"[{nameof(AudioUtilities)}] : Could not load file {audio}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EnumUtils.TryParse(audio, out AudioType type))
|
if (EnumUtils.TryParse(audio, out AudioType type))
|
||||||
{
|
{
|
||||||
source._audioLibraryClip = type;
|
source._audioLibraryClip = type;
|
||||||
|
NHLogger.LogVerbose($"[{nameof(AudioUtilities)}] : Audio {audio} was an AudioType enum");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var audioClip = SearchUtilities.FindResourceOfTypeAndName<AudioClip>(audio);
|
var audioClip = SearchUtilities.FindResourceOfTypeAndName<AudioClip>(audio);
|
||||||
if (audioClip == null) NHLogger.Log($"Couldn't find audio clip {audio}");
|
if (audioClip == null)
|
||||||
else source.clip = audioClip;
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
"author": "xen, Bwc9876, JohnCorby, MegaPiggy, and friends",
|
"author": "xen, Bwc9876, JohnCorby, MegaPiggy, and friends",
|
||||||
"name": "New Horizons",
|
"name": "New Horizons",
|
||||||
"uniqueName": "xen.NewHorizons",
|
"uniqueName": "xen.NewHorizons",
|
||||||
"version": "1.27.3",
|
"version": "1.27.4",
|
||||||
"owmlVersion": "2.12.1",
|
"owmlVersion": "2.12.1",
|
||||||
"dependencies": [ "JohnCorby.VanillaFix", "xen.CommonCameraUtility", "dgarro.CustomShipLogModes" ],
|
"dependencies": [ "JohnCorby.VanillaFix", "xen.CommonCameraUtility", "dgarro.CustomShipLogModes" ],
|
||||||
"conflicts": [ "PacificEngine.OW_CommonResources" ],
|
"conflicts": [ "PacificEngine.OW_CommonResources" ],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user