mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
Merge branch 'main' into hawkbar-docs-updates
This commit is contained in:
commit
3d630b26fc
Binary file not shown.
|
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 128 KiB |
@ -10,7 +10,7 @@
|
|||||||
"Trifid#Tester\n#Programmer",
|
"Trifid#Tester\n#Programmer",
|
||||||
"Nageld#Programmer",
|
"Nageld#Programmer",
|
||||||
"Ernesto#Fish",
|
"Ernesto#Fish",
|
||||||
"With help from#Raicuparta\n#dgarroDC\n#jtsalomo\n#and the modding community",
|
"With help from#Raicuparta\n#dgarroDC\n#jtsalomo\n#coderCleric\n#TRSasasusu\n#and the modding community",
|
||||||
" ",
|
" ",
|
||||||
"Based off Marshmallow made by#_nebula",
|
"Based off Marshmallow made by#_nebula",
|
||||||
"With help from#AmazingAlek\n#Raicuparta\n#and the Outer Wilds discord server",
|
"With help from#AmazingAlek\n#Raicuparta\n#and the Outer Wilds discord server",
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
using NewHorizons.External.Modules;
|
using NewHorizons.External.Modules;
|
||||||
using NewHorizons.External.Modules.Props;
|
|
||||||
using NewHorizons.Utility;
|
using NewHorizons.Utility;
|
||||||
using NewHorizons.Utility.Files;
|
using NewHorizons.Utility.Files;
|
||||||
using OWML.Common;
|
using OWML.Common;
|
||||||
using System;
|
using System;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace NewHorizons.Builder.Atmosphere
|
namespace NewHorizons.Builder.Atmosphere
|
||||||
{
|
{
|
||||||
public static class FogBuilder
|
public static class FogBuilder
|
||||||
@ -26,7 +26,9 @@ namespace NewHorizons.Builder.Atmosphere
|
|||||||
|
|
||||||
internal static void InitPrefabs()
|
internal static void InitPrefabs()
|
||||||
{
|
{
|
||||||
if (_ramp == null) _ramp = ImageUtilities.GetTexture(Main.Instance, "Assets/textures/FogColorRamp.png");
|
// Checking null here it was getting destroyed and wouldnt reload and never worked outside of the first loop
|
||||||
|
// GetTexture caches itself anyway so it doesn't matter that this gets called multiple times
|
||||||
|
_ramp = ImageUtilities.GetTexture(Main.Instance, "Assets/textures/FogColorRamp.png");
|
||||||
|
|
||||||
if (_isInit) return;
|
if (_isInit) return;
|
||||||
|
|
||||||
@ -73,6 +75,7 @@ namespace NewHorizons.Builder.Atmosphere
|
|||||||
atmo.fogRampPath != null ? ImageUtilities.GetTexture(mod, atmo.fogRampPath) :
|
atmo.fogRampPath != null ? ImageUtilities.GetTexture(mod, atmo.fogRampPath) :
|
||||||
atmo.fogTint != null ? ImageUtilities.TintImage(_ramp, atmo.fogTint.ToColor()) :
|
atmo.fogTint != null ? ImageUtilities.TintImage(_ramp, atmo.fogTint.ToColor()) :
|
||||||
_ramp;
|
_ramp;
|
||||||
|
|
||||||
PFC.fogColorRampTexture = colorRampTexture;
|
PFC.fogColorRampTexture = colorRampTexture;
|
||||||
PFC.fogColorRampIntensity = 1f;
|
PFC.fogColorRampIntensity = 1f;
|
||||||
if (atmo.fogTint != null)
|
if (atmo.fogTint != null)
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using NewHorizons.External.Modules;
|
using NewHorizons.External.Modules;
|
||||||
using NewHorizons.External.Modules.VariableSize;
|
using NewHorizons.External.Modules.VariableSize;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace NewHorizons.Builder.Atmosphere
|
namespace NewHorizons.Builder.Atmosphere
|
||||||
{
|
{
|
||||||
public static class SunOverrideBuilder
|
public static class SunOverrideBuilder
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
using NewHorizons.Components;
|
using NewHorizons.Components;
|
||||||
using NewHorizons.Components.Orbital;
|
using NewHorizons.Components.Orbital;
|
||||||
using NewHorizons.External.Configs;
|
using NewHorizons.External;
|
||||||
using NewHorizons.Utility.OWML;
|
using NewHorizons.Utility.OWML;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@ -8,9 +8,13 @@ namespace NewHorizons.Builder.General
|
|||||||
{
|
{
|
||||||
public static class AstroObjectBuilder
|
public static class AstroObjectBuilder
|
||||||
{
|
{
|
||||||
public static NHAstroObject Make(GameObject body, AstroObject primaryBody, PlanetConfig config, bool isVanilla)
|
public static NHAstroObject Make(GameObject body, AstroObject primaryBody, NewHorizonsBody nhBody, bool isVanilla)
|
||||||
{
|
{
|
||||||
NHAstroObject astroObject = body.AddComponent<NHAstroObject>();
|
NHAstroObject astroObject = body.AddComponent<NHAstroObject>();
|
||||||
|
astroObject.modUniqueName = nhBody.Mod.ModHelper.Manifest.UniqueName;
|
||||||
|
|
||||||
|
var config = nhBody.Config;
|
||||||
|
|
||||||
astroObject.isVanilla = isVanilla;
|
astroObject.isVanilla = isVanilla;
|
||||||
astroObject.HideDisplayName = !config.Base.hasMapMarker;
|
astroObject.HideDisplayName = !config.Base.hasMapMarker;
|
||||||
astroObject.invulnerableToSun = config.Base.invulnerableToSun;
|
astroObject.invulnerableToSun = config.Base.invulnerableToSun;
|
||||||
|
|||||||
@ -12,6 +12,8 @@ namespace NewHorizons.Builder.General
|
|||||||
{
|
{
|
||||||
// We can't not build a reference frame volume, Cloak requires one to be there
|
// We can't not build a reference frame volume, Cloak requires one to be there
|
||||||
module.maxTargetDistance = 0f;
|
module.maxTargetDistance = 0f;
|
||||||
|
module.targetWhenClose = true;
|
||||||
|
module.targetColliderRadius = 0f;
|
||||||
module.hideInMap = true;
|
module.hideInMap = true;
|
||||||
owrb.SetIsTargetable(false);
|
owrb.SetIsTargetable(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
|
using NewHorizons.External;
|
||||||
using NewHorizons.External.Modules.Props.Audio;
|
using NewHorizons.External.Modules.Props.Audio;
|
||||||
using NewHorizons.Utility;
|
using NewHorizons.Utility;
|
||||||
using NewHorizons.Utility.OWML;
|
using NewHorizons.Utility.OWML;
|
||||||
using OWML.Common;
|
using OWML.Common;
|
||||||
using OWML.Utils;
|
using OWML.Utils;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -36,27 +38,16 @@ namespace NewHorizons.Builder.Props.Audio
|
|||||||
};
|
};
|
||||||
NumberOfFrequencies = EnumUtils.GetValues<SignalFrequency>().Length;
|
NumberOfFrequencies = EnumUtils.GetValues<SignalFrequency>().Length;
|
||||||
|
|
||||||
_qmSignals = new (){ SearchUtilities.Find("QuantumMoon_Body/Signal_Quantum").GetComponent<AudioSignal>() };
|
_qmSignals = new () { SearchUtilities.Find("QuantumMoon_Body/Signal_Quantum").GetComponent<AudioSignal>() };
|
||||||
_cloakedSignals = new();
|
_cloakedSignals = new();
|
||||||
|
|
||||||
Initialized = true;
|
Initialized = true;
|
||||||
|
|
||||||
SceneManager.sceneUnloaded -= OnSceneUnloaded;
|
SceneManager.sceneUnloaded -= OnSceneUnloaded;
|
||||||
SceneManager.sceneUnloaded += OnSceneUnloaded;
|
SceneManager.sceneUnloaded += OnSceneUnloaded;
|
||||||
Main.Instance.OnStarSystemLoaded.RemoveListener(OnStarSystemLoaded);
|
|
||||||
Main.Instance.OnStarSystemLoaded.AddListener(OnStarSystemLoaded);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static HashSet<SignalFrequency> _frequenciesInUse = new();
|
|
||||||
|
|
||||||
private static void OnSceneUnloaded(Scene _)
|
|
||||||
{
|
|
||||||
_frequenciesInUse.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void OnStarSystemLoaded(string starSystem)
|
|
||||||
{
|
|
||||||
// If its the base game solar system or eye we get all the main frequencies
|
// If its the base game solar system or eye we get all the main frequencies
|
||||||
|
var starSystem = Main.Instance.CurrentStarSystem;
|
||||||
if (starSystem == "SolarSystem" || starSystem == "EyeOfTheUniverse")
|
if (starSystem == "SolarSystem" || starSystem == "EyeOfTheUniverse")
|
||||||
{
|
{
|
||||||
_frequenciesInUse.Add(SignalFrequency.Quantum);
|
_frequenciesInUse.Add(SignalFrequency.Quantum);
|
||||||
@ -69,19 +60,43 @@ namespace NewHorizons.Builder.Props.Audio
|
|||||||
// We don't want a scenario where the player knows no frequencies
|
// We don't want a scenario where the player knows no frequencies
|
||||||
_frequenciesInUse.Add(SignalFrequency.Traveler);
|
_frequenciesInUse.Add(SignalFrequency.Traveler);
|
||||||
|
|
||||||
|
// Make sure the NH save file has all the right frequencies
|
||||||
|
// Skip "default"
|
||||||
|
for (int i = 1; i < PlayerData._currentGameSave.knownFrequencies.Length; i++)
|
||||||
|
{
|
||||||
|
if (PlayerData._currentGameSave.knownFrequencies[i])
|
||||||
|
{
|
||||||
|
NewHorizonsData.LearnFrequency(AudioSignal.IndexToFrequency(i).ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NHLogger.LogVerbose($"Frequencies in use in {starSystem}: {_frequenciesInUse.Join(x => x.ToString())}");
|
NHLogger.LogVerbose($"Frequencies in use in {starSystem}: {_frequenciesInUse.Join(x => x.ToString())}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static HashSet<SignalFrequency> _frequenciesInUse = new();
|
||||||
|
|
||||||
|
private static void OnSceneUnloaded(Scene _)
|
||||||
|
{
|
||||||
|
_frequenciesInUse.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
public static bool IsFrequencyInUse(SignalFrequency freq) => _frequenciesInUse.Contains(freq);
|
public static bool IsFrequencyInUse(SignalFrequency freq) => _frequenciesInUse.Contains(freq);
|
||||||
|
|
||||||
|
public static bool IsFrequencyInUse(string freqString)
|
||||||
|
{
|
||||||
|
if (Enum.TryParse<SignalFrequency>(freqString, out var freq))
|
||||||
|
{
|
||||||
|
return IsFrequencyInUse(freq);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static bool IsCloaked(this AudioSignal signal) => _cloakedSignals.Contains(signal);
|
public static bool IsCloaked(this AudioSignal signal) => _cloakedSignals.Contains(signal);
|
||||||
|
|
||||||
public static bool IsOnQuantumMoon(this AudioSignal signal) => _qmSignals.Contains(signal);
|
public static bool IsOnQuantumMoon(this AudioSignal signal) => _qmSignals.Contains(signal);
|
||||||
|
|
||||||
public static SignalFrequency AddFrequency(string str)
|
public static SignalFrequency AddFrequency(string str)
|
||||||
{
|
{
|
||||||
if (_customFrequencyNames == null) Init();
|
|
||||||
|
|
||||||
var freq = CollectionUtilities.KeyByValue(_customFrequencyNames, str);
|
var freq = CollectionUtilities.KeyByValue(_customFrequencyNames, str);
|
||||||
if (freq != default) return freq;
|
if (freq != default) return freq;
|
||||||
|
|
||||||
@ -99,23 +114,19 @@ namespace NewHorizons.Builder.Props.Audio
|
|||||||
NumberOfFrequencies = EnumUtils.GetValues<SignalFrequency>().Length;
|
NumberOfFrequencies = EnumUtils.GetValues<SignalFrequency>().Length;
|
||||||
|
|
||||||
// This stuff happens after the signalscope is Awake so we have to change the number of frequencies now
|
// This stuff happens after the signalscope is Awake so we have to change the number of frequencies now
|
||||||
Object.FindObjectOfType<Signalscope>()._strongestSignals = new AudioSignal[NumberOfFrequencies + 1];
|
GameObject.FindObjectOfType<Signalscope>()._strongestSignals = new AudioSignal[NumberOfFrequencies + 1];
|
||||||
|
|
||||||
return freq;
|
return freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetCustomFrequencyName(SignalFrequency frequencyName)
|
public static string GetCustomFrequencyName(SignalFrequency frequencyName)
|
||||||
{
|
{
|
||||||
if (_customFrequencyNames == null) Init();
|
|
||||||
|
|
||||||
_customFrequencyNames.TryGetValue(frequencyName, out string name);
|
_customFrequencyNames.TryGetValue(frequencyName, out string name);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SignalName AddSignalName(string str)
|
public static SignalName AddSignalName(string str)
|
||||||
{
|
{
|
||||||
if (_customSignalNames == null) Init();
|
|
||||||
|
|
||||||
var name = CollectionUtilities.KeyByValue(_customSignalNames, str);
|
var name = CollectionUtilities.KeyByValue(_customSignalNames, str);
|
||||||
if (name != default) return name;
|
if (name != default) return name;
|
||||||
|
|
||||||
@ -129,8 +140,6 @@ namespace NewHorizons.Builder.Props.Audio
|
|||||||
|
|
||||||
public static string GetCustomSignalName(SignalName signalName)
|
public static string GetCustomSignalName(SignalName signalName)
|
||||||
{
|
{
|
||||||
if (_customSignalNames == null) Init();
|
|
||||||
|
|
||||||
_customSignalNames.TryGetValue(signalName, out string name);
|
_customSignalNames.TryGetValue(signalName, out string name);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ using NewHorizons.Handlers;
|
|||||||
using NewHorizons.Utility;
|
using NewHorizons.Utility;
|
||||||
using NewHorizons.Utility.OuterWilds;
|
using NewHorizons.Utility.OuterWilds;
|
||||||
using NewHorizons.Utility.OWML;
|
using NewHorizons.Utility.OWML;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using OWML.Common;
|
using OWML.Common;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -414,7 +415,13 @@ namespace NewHorizons.Builder.Props
|
|||||||
{
|
{
|
||||||
foreach (var signalConfig in connectedSignals)
|
foreach (var signalConfig in connectedSignals)
|
||||||
{
|
{
|
||||||
var signalGO = SignalBuilder.Make(go, sector, signalConfig, mod);
|
// Have to ensure that this new signal doesn't use parent path, else it looks for a parent that only exists on the original body
|
||||||
|
// Have to make a copy of it as well to avoid modifying the old body's info
|
||||||
|
var signalConfigCopy = JsonConvert.DeserializeObject<SignalInfo>(JsonConvert.SerializeObject(signalConfig));
|
||||||
|
signalConfigCopy.parentPath = null;
|
||||||
|
signalConfigCopy.isRelativeToParent = false;
|
||||||
|
|
||||||
|
var signalGO = SignalBuilder.Make(go, sector, signalConfigCopy, mod);
|
||||||
signalGO.GetComponent<AudioSignal>()._identificationDistance = 0;
|
signalGO.GetComponent<AudioSignal>()._identificationDistance = 0;
|
||||||
signalGO.GetComponent<AudioSignal>()._sourceRadius = 1;
|
signalGO.GetComponent<AudioSignal>()._sourceRadius = 1;
|
||||||
signalGO.transform.position = brambleNode.transform.position;
|
signalGO.transform.position = brambleNode.transform.position;
|
||||||
|
|||||||
@ -101,6 +101,7 @@ namespace NewHorizons.Builder.Props
|
|||||||
GameObject prop;
|
GameObject prop;
|
||||||
bool isItem;
|
bool isItem;
|
||||||
bool invalidComponentFound = false;
|
bool invalidComponentFound = false;
|
||||||
|
bool isFromAssetBundle = !string.IsNullOrEmpty(detail.assetBundle);
|
||||||
|
|
||||||
// We save copies with all their components fixed, good if the user is placing the same detail more than once
|
// We save copies with all their components fixed, good if the user is placing the same detail more than once
|
||||||
if (detail?.path != null && _fixedPrefabCache.TryGetValue((sector, detail.path), out var storedPrefab))
|
if (detail?.path != null && _fixedPrefabCache.TryGetValue((sector, detail.path), out var storedPrefab))
|
||||||
@ -139,12 +140,21 @@ namespace NewHorizons.Builder.Props
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FixSectoredComponent(component, sector, existingSectors, detail.keepLoaded);
|
// Fix cull groups only when not from an asset bundle (because then they're there on purpose!)
|
||||||
|
// keepLoaded should remove existing groups
|
||||||
|
// renderers/colliders get enabled later so we dont have to do that here
|
||||||
|
if (detail.keepLoaded && !isFromAssetBundle && component is SectorCullGroup or SectorCollisionGroup or SectorLightsCullGroup)
|
||||||
|
{
|
||||||
|
UnityEngine.Object.DestroyImmediate(component);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FixSectoredComponent(component, sector, existingSectors);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Asset bundle is a real string -> Object loaded from unity
|
// Asset bundle is a real string -> Object loaded from unity
|
||||||
// If they're adding dialogue we have to manually register the xml text
|
// If they're adding dialogue we have to manually register the xml text
|
||||||
if (!string.IsNullOrEmpty(detail.assetBundle) && component is CharacterDialogueTree dialogue)
|
if (isFromAssetBundle && component is CharacterDialogueTree dialogue)
|
||||||
{
|
{
|
||||||
DialogueBuilder.AddTranslation(dialogue._xmlCharacterDialogueAsset.text, null);
|
DialogueBuilder.AddTranslation(dialogue._xmlCharacterDialogueAsset.text, null);
|
||||||
}
|
}
|
||||||
@ -278,16 +288,8 @@ namespace NewHorizons.Builder.Props
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fix components that have sectors. Has a specific fix if there is a VisionTorchItem on the object.
|
/// Fix components that have sectors. Has a specific fix if there is a VisionTorchItem on the object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static void FixSectoredComponent(Component component, Sector sector, HashSet<Sector> existingSectors, bool keepLoaded)
|
private static void FixSectoredComponent(Component component, Sector sector, HashSet<Sector> existingSectors)
|
||||||
{
|
{
|
||||||
// keepLoaded should remove existing groups
|
|
||||||
// renderers/colliders get enabled later so we dont have to do that here
|
|
||||||
if (keepLoaded && component is SectorCullGroup or SectorCollisionGroup or SectorLightsCullGroup)
|
|
||||||
{
|
|
||||||
UnityEngine.Object.DestroyImmediate(component);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fix Sector stuff, eg SectorCullGroup (without this, props that have a SectorCullGroup component will become invisible inappropriately)
|
// fix Sector stuff, eg SectorCullGroup (without this, props that have a SectorCullGroup component will become invisible inappropriately)
|
||||||
if (component is ISectorGroup sectorGroup && !existingSectors.Contains(sectorGroup.GetSector()))
|
if (component is ISectorGroup sectorGroup && !existingSectors.Contains(sectorGroup.GetSector()))
|
||||||
{
|
{
|
||||||
@ -295,15 +297,8 @@ namespace NewHorizons.Builder.Props
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Not doing else if here because idk if any of the classes below implement ISectorGroup
|
// Not doing else if here because idk if any of the classes below implement ISectorGroup
|
||||||
|
|
||||||
// Null check else shuttles controls break
|
|
||||||
// parent sector is always null before Awake so this code actually never runs lol
|
|
||||||
if (component is Sector s && s.GetParentSector() != null && !existingSectors.Contains(s.GetParentSector()))
|
|
||||||
{
|
|
||||||
s.SetParentSector(sector);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(component is SectoredMonoBehaviour behaviour && !existingSectors.Contains(behaviour._sector))
|
if(component is SectoredMonoBehaviour behaviour && !existingSectors.Contains(behaviour._sector))
|
||||||
{
|
{
|
||||||
// not using SetSector here because it registers the events twice
|
// not using SetSector here because it registers the events twice
|
||||||
// perhaps this happens with ISectorGroup.SetSector or Sector.SetParentSector too? idk and nothing seems to break because of it yet
|
// perhaps this happens with ISectorGroup.SetSector or Sector.SetParentSector too? idk and nothing seems to break because of it yet
|
||||||
|
|||||||
@ -102,10 +102,12 @@ namespace NewHorizons.Builder.Props
|
|||||||
// We just have to merge the dialogue options
|
// We just have to merge the dialogue options
|
||||||
var dialogueOptions = newDialogueNode.GetChildNode("DialogueOptionsList").GetChildNodes("DialogueOption");
|
var dialogueOptions = newDialogueNode.GetChildNode("DialogueOptionsList").GetChildNodes("DialogueOption");
|
||||||
var existingDialogueOptionsList = existingNode.GetChildNode("DialogueOptionsList");
|
var existingDialogueOptionsList = existingNode.GetChildNode("DialogueOptionsList");
|
||||||
|
var firstNode = existingDialogueOptionsList.ChildNodes[0];
|
||||||
foreach (XmlNode node in dialogueOptions)
|
foreach (XmlNode node in dialogueOptions)
|
||||||
{
|
{
|
||||||
var importedNode = existingDialogueOptionsList.OwnerDocument.ImportNode(node, true);
|
var importedNode = existingDialogueOptionsList.OwnerDocument.ImportNode(node, true);
|
||||||
existingDialogueOptionsList.AppendChild(importedNode);
|
// We add them to the start because normally the last option is to return to menu or exit
|
||||||
|
existingDialogueOptionsList.PrependChild(importedNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@ -51,6 +51,10 @@ namespace NewHorizons.Builder.Props
|
|||||||
item.DisplayName = itemName;
|
item.DisplayName = itemName;
|
||||||
item.ItemType = itemType;
|
item.ItemType = itemType;
|
||||||
item.Droppable = info.droppable;
|
item.Droppable = info.droppable;
|
||||||
|
item.HoldOffset = info.holdOffset ?? Vector3.zero;
|
||||||
|
item.HoldRotation = info.holdRotation ?? Vector3.zero;
|
||||||
|
item.SocketOffset = info.socketOffset ?? Vector3.zero;
|
||||||
|
item.SocketRotation = info.socketRotation ?? Vector3.zero;
|
||||||
if (!string.IsNullOrEmpty(info.pickupAudio))
|
if (!string.IsNullOrEmpty(info.pickupAudio))
|
||||||
{
|
{
|
||||||
item.PickupAudio = AudioTypeHandler.GetAudioType(info.pickupAudio, mod);
|
item.PickupAudio = AudioTypeHandler.GetAudioType(info.pickupAudio, mod);
|
||||||
|
|||||||
@ -476,7 +476,7 @@ namespace NewHorizons.Builder.Props.TranslatorText
|
|||||||
}
|
}
|
||||||
|
|
||||||
ArcCacheData[] cachedData = null;
|
ArcCacheData[] cachedData = null;
|
||||||
if (nhBody.Cache?.ContainsKey(cacheKey) ?? false)
|
if (nhBody?.Cache?.ContainsKey(cacheKey) ?? false)
|
||||||
cachedData = nhBody.Cache.Get<ArcCacheData[]>(cacheKey);
|
cachedData = nhBody.Cache.Get<ArcCacheData[]>(cacheKey);
|
||||||
|
|
||||||
var arranger = nomaiWallText.gameObject.AddComponent<NomaiTextArcArranger>();
|
var arranger = nomaiWallText.gameObject.AddComponent<NomaiTextArcArranger>();
|
||||||
|
|||||||
@ -30,7 +30,7 @@ namespace NewHorizons.Builder.ShipLog
|
|||||||
{
|
{
|
||||||
if (body.Config.ShipLog == null) continue;
|
if (body.Config.ShipLog == null) continue;
|
||||||
|
|
||||||
if (body.Config.ShipLog?.mapMode?.manualPosition == null)
|
if (body.Config.ShipLog.mapMode?.manualPosition == null)
|
||||||
{
|
{
|
||||||
flagAutoPositionUsed = true;
|
flagAutoPositionUsed = true;
|
||||||
}
|
}
|
||||||
@ -45,6 +45,12 @@ namespace NewHorizons.Builder.ShipLog
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If they're both false, just default to auto (this means that no planets even have ship log info)
|
||||||
|
if (!flagManualPositionUsed && !flagAutoPositionUsed)
|
||||||
|
{
|
||||||
|
flagAutoPositionUsed = true;
|
||||||
|
}
|
||||||
|
|
||||||
var isBaseSolarSystem = systemName == "SolarSystem";
|
var isBaseSolarSystem = systemName == "SolarSystem";
|
||||||
|
|
||||||
// Default to MANUAL in Base Solar System (we can't automatically fix them so it might just break, but AUTO breaks even more!)
|
// Default to MANUAL in Base Solar System (we can't automatically fix them so it might just break, but AUTO breaks even more!)
|
||||||
@ -142,6 +148,7 @@ namespace NewHorizons.Builder.ShipLog
|
|||||||
|
|
||||||
astroObject._imageObj = CreateImage(gameObject, image, body.Config.name + " Revealed", layer);
|
astroObject._imageObj = CreateImage(gameObject, image, body.Config.name + " Revealed", layer);
|
||||||
astroObject._outlineObj = CreateImage(gameObject, outline, body.Config.name + " Outline", layer);
|
astroObject._outlineObj = CreateImage(gameObject, outline, body.Config.name + " Outline", layer);
|
||||||
|
|
||||||
if (ShipLogHandler.BodyHasEntries(body))
|
if (ShipLogHandler.BodyHasEntries(body))
|
||||||
{
|
{
|
||||||
Image revealedImage = astroObject._imageObj.GetComponent<Image>();
|
Image revealedImage = astroObject._imageObj.GetComponent<Image>();
|
||||||
@ -156,6 +163,12 @@ namespace NewHorizons.Builder.ShipLog
|
|||||||
|
|
||||||
Rect imageRect = astroObject._imageObj.GetComponent<RectTransform>().rect;
|
Rect imageRect = astroObject._imageObj.GetComponent<RectTransform>().rect;
|
||||||
astroObject._unviewedObj.transform.localPosition = new Vector3(imageRect.width / 2 + unviewedIconOffset, imageRect.height / 2 + unviewedIconOffset, 0);
|
astroObject._unviewedObj.transform.localPosition = new Vector3(imageRect.width / 2 + unviewedIconOffset, imageRect.height / 2 + unviewedIconOffset, 0);
|
||||||
|
|
||||||
|
// Set all icons inactive, they will be conditionally activated when the map mode is opened for the first time
|
||||||
|
astroObject._unviewedObj.SetActive(false);
|
||||||
|
astroObject._imageObj.SetActive(false);
|
||||||
|
astroObject._outlineObj.SetActive(false);
|
||||||
|
|
||||||
return astroObject;
|
return astroObject;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -0,0 +1,33 @@
|
|||||||
|
using NewHorizons.Utility.OWML;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NewHorizons.Components.Fixers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fixes a bug where spawning into the ship would not trigger the hatch entryway, so the player could drown if the ship flew into water
|
||||||
|
/// </summary>
|
||||||
|
internal class PlayerShipAtmosphereDetectorFix : MonoBehaviour
|
||||||
|
{
|
||||||
|
private PlayerCameraFluidDetector _fluidDetector;
|
||||||
|
private SimpleFluidVolume _shipAtmosphereVolume;
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
_fluidDetector = Locator.GetPlayerCameraDetector().GetComponent<PlayerCameraFluidDetector>();
|
||||||
|
_shipAtmosphereVolume = Locator.GetShipBody().transform.Find("Volumes/ShipAtmosphereVolume").GetComponent<SimpleFluidVolume>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update()
|
||||||
|
{
|
||||||
|
if (PlayerState.IsInsideShip())
|
||||||
|
{
|
||||||
|
if (!_fluidDetector._activeVolumes.Contains(_shipAtmosphereVolume))
|
||||||
|
{
|
||||||
|
NHLogger.LogVerbose($"{nameof(PlayerShipAtmosphereDetectorFix)} had to add the ship atmosphere volume [{_shipAtmosphereVolume}] to the fluid detector");
|
||||||
|
_fluidDetector.AddVolume(_shipAtmosphereVolume);
|
||||||
|
}
|
||||||
|
NHLogger.LogVerbose($"{nameof(PlayerShipAtmosphereDetectorFix)} applied its fix");
|
||||||
|
Component.Destroy(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -14,6 +14,11 @@ namespace NewHorizons.Components.Orbital
|
|||||||
public bool invulnerableToSun;
|
public bool invulnerableToSun;
|
||||||
public bool isVanilla;
|
public bool isVanilla;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The unique name of the mod that created this body or, if it is an existing body being edited, the last mod to edit it
|
||||||
|
/// </summary>
|
||||||
|
public string modUniqueName;
|
||||||
|
|
||||||
public void SetOrbitalParametersFromConfig(OrbitModule orbit)
|
public void SetOrbitalParametersFromConfig(OrbitModule orbit)
|
||||||
{
|
{
|
||||||
SetOrbitalParametersFromTrueAnomaly(orbit.eccentricity, orbit.semiMajorAxis, orbit.inclination, orbit.argumentOfPeriapsis, orbit.longitudeOfAscendingNode, orbit.trueAnomaly);
|
SetOrbitalParametersFromTrueAnomaly(orbit.eccentricity, orbit.semiMajorAxis, orbit.inclination, orbit.argumentOfPeriapsis, orbit.longitudeOfAscendingNode, orbit.trueAnomaly);
|
||||||
|
|||||||
@ -19,6 +19,7 @@ namespace NewHorizons.Components.Props
|
|||||||
{
|
{
|
||||||
var conditionalObjectActivationGO = new GameObject($"{go.name}_{condition}");
|
var conditionalObjectActivationGO = new GameObject($"{go.name}_{condition}");
|
||||||
var component = conditionalObjectActivationGO.AddComponent<ConditionalObjectActivation>();
|
var component = conditionalObjectActivationGO.AddComponent<ConditionalObjectActivation>();
|
||||||
|
component.transform.parent = go.transform.parent;
|
||||||
component.GameObject = go;
|
component.GameObject = go;
|
||||||
component.DialogueCondition = condition;
|
component.DialogueCondition = condition;
|
||||||
component.CloseEyes = closeEyes;
|
component.CloseEyes = closeEyes;
|
||||||
|
|||||||
@ -19,6 +19,10 @@ namespace NewHorizons.Components.Props
|
|||||||
public AudioType DropAudio;
|
public AudioType DropAudio;
|
||||||
public AudioType SocketAudio;
|
public AudioType SocketAudio;
|
||||||
public AudioType UnsocketAudio;
|
public AudioType UnsocketAudio;
|
||||||
|
public Vector3 HoldOffset;
|
||||||
|
public Vector3 HoldRotation;
|
||||||
|
public Vector3 SocketOffset;
|
||||||
|
public Vector3 SocketRotation;
|
||||||
public string PickupCondition;
|
public string PickupCondition;
|
||||||
public bool ClearPickupConditionOnDrop;
|
public bool ClearPickupConditionOnDrop;
|
||||||
public string PickupFact;
|
public string PickupFact;
|
||||||
@ -42,6 +46,8 @@ namespace NewHorizons.Components.Props
|
|||||||
public override void PickUpItem(Transform holdTranform)
|
public override void PickUpItem(Transform holdTranform)
|
||||||
{
|
{
|
||||||
base.PickUpItem(holdTranform);
|
base.PickUpItem(holdTranform);
|
||||||
|
transform.localPosition = HoldOffset;
|
||||||
|
transform.localEulerAngles = HoldRotation;
|
||||||
TriggerPickupConditions();
|
TriggerPickupConditions();
|
||||||
PlayCustomSound(PickupAudio);
|
PlayCustomSound(PickupAudio);
|
||||||
}
|
}
|
||||||
@ -56,6 +62,8 @@ namespace NewHorizons.Components.Props
|
|||||||
public override void SocketItem(Transform socketTransform, Sector sector)
|
public override void SocketItem(Transform socketTransform, Sector sector)
|
||||||
{
|
{
|
||||||
base.SocketItem(socketTransform, sector);
|
base.SocketItem(socketTransform, sector);
|
||||||
|
transform.localPosition = SocketOffset;
|
||||||
|
transform.localEulerAngles = SocketRotation;
|
||||||
TriggerDropConditions();
|
TriggerDropConditions();
|
||||||
PlayCustomSound(SocketAudio);
|
PlayCustomSound(SocketAudio);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,13 +33,16 @@ namespace NewHorizons.Components.Sectored
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
|
{
|
||||||
|
DisableRenderers();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetRenderers()
|
||||||
{
|
{
|
||||||
_renderers = gameObject.GetComponentsInChildren<Renderer>();
|
_renderers = gameObject.GetComponentsInChildren<Renderer>();
|
||||||
_tessellatedRenderers = gameObject.GetComponentsInChildren<TessellatedRenderer>();
|
_tessellatedRenderers = gameObject.GetComponentsInChildren<TessellatedRenderer>();
|
||||||
_colliders = gameObject.GetComponentsInChildren<Collider>();
|
_colliders = gameObject.GetComponentsInChildren<Collider>();
|
||||||
_lights = gameObject.GetComponentsInChildren<Light>();
|
_lights = gameObject.GetComponentsInChildren<Light>();
|
||||||
|
|
||||||
DisableRenderers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnSectorOccupantsUpdated()
|
private void OnSectorOccupantsUpdated()
|
||||||
@ -54,54 +57,35 @@ namespace NewHorizons.Components.Sectored
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EnableRenderers()
|
private void EnableRenderers() => ToggleRenderers(true);
|
||||||
|
|
||||||
|
private void DisableRenderers() => ToggleRenderers(false);
|
||||||
|
|
||||||
|
private void ToggleRenderers(bool visible)
|
||||||
{
|
{
|
||||||
|
GetRenderers();
|
||||||
|
|
||||||
foreach (var renderer in _renderers)
|
foreach (var renderer in _renderers)
|
||||||
{
|
{
|
||||||
renderer.forceRenderingOff = false;
|
renderer.forceRenderingOff = !visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var tessellatedRenderer in _tessellatedRenderers)
|
foreach (var tessellatedRenderer in _tessellatedRenderers)
|
||||||
{
|
{
|
||||||
tessellatedRenderer.enabled = true;
|
tessellatedRenderer.enabled = visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var collider in _colliders)
|
foreach (var collider in _colliders)
|
||||||
{
|
{
|
||||||
collider.enabled = true;
|
collider.enabled = visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var light in _lights)
|
foreach (var light in _lights)
|
||||||
{
|
{
|
||||||
light.enabled = true;
|
light.enabled = visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderersShown = true;
|
_renderersShown = visible;
|
||||||
}
|
|
||||||
|
|
||||||
private void DisableRenderers()
|
|
||||||
{
|
|
||||||
foreach (var renderer in _renderers)
|
|
||||||
{
|
|
||||||
renderer.forceRenderingOff = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var tessellatedRenderer in _tessellatedRenderers)
|
|
||||||
{
|
|
||||||
tessellatedRenderer.enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var collider in _colliders)
|
|
||||||
{
|
|
||||||
collider.enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var light in _lights)
|
|
||||||
{
|
|
||||||
light.enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_renderersShown = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
NewHorizons/External/Configs/PlanetConfig.cs
vendored
1
NewHorizons/External/Configs/PlanetConfig.cs
vendored
@ -213,7 +213,6 @@ namespace NewHorizons.External.Configs
|
|||||||
// Always have to have a base module
|
// Always have to have a base module
|
||||||
if (Base == null) Base = new BaseModule();
|
if (Base == null) Base = new BaseModule();
|
||||||
if (Orbit == null) Orbit = new OrbitModule();
|
if (Orbit == null) Orbit = new OrbitModule();
|
||||||
if (ShipLog == null) ShipLog = new ShipLogModule();
|
|
||||||
if (ReferenceFrame == null) ReferenceFrame = new ReferenceFrameModule();
|
if (ReferenceFrame == null) ReferenceFrame = new ReferenceFrameModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -44,6 +44,22 @@ namespace NewHorizons.External.Modules.Props.Item
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public MVector3 dropNormal;
|
public MVector3 dropNormal;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// A relative offset to apply to the item's position when holding it. The initial position varies for vanilla item types.
|
||||||
|
/// </summary>
|
||||||
|
public MVector3 holdOffset;
|
||||||
|
/// <summary>
|
||||||
|
/// A relative offset to apply to the item's rotation when holding it.
|
||||||
|
/// </summary>
|
||||||
|
public MVector3 holdRotation;
|
||||||
|
/// <summary>
|
||||||
|
/// A relative offset to apply to the item's position when placing it into a socket.
|
||||||
|
/// </summary>
|
||||||
|
public MVector3 socketOffset;
|
||||||
|
/// <summary>
|
||||||
|
/// A relative offset to apply to the item's rotation when placing it into a socket.
|
||||||
|
/// </summary>
|
||||||
|
public MVector3 socketRotation;
|
||||||
|
/// <summary>
|
||||||
/// The audio to play when this item is picked up. Only applies to custom/non-vanilla item types.
|
/// The audio to play when this item is picked up. Only applies to custom/non-vanilla item types.
|
||||||
/// Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list.
|
/// Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
11
NewHorizons/External/NewHorizonsData.cs
vendored
11
NewHorizons/External/NewHorizonsData.cs
vendored
@ -1,5 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using NewHorizons.Builder.Props.Audio;
|
||||||
using NewHorizons.Utility.OWML;
|
using NewHorizons.Utility.OWML;
|
||||||
|
|
||||||
namespace NewHorizons.External
|
namespace NewHorizons.External
|
||||||
@ -124,7 +126,6 @@ namespace NewHorizons.External
|
|||||||
if (!KnowsFrequency(frequency))
|
if (!KnowsFrequency(frequency))
|
||||||
{
|
{
|
||||||
_activeProfile.KnownFrequencies.Add(frequency);
|
_activeProfile.KnownFrequencies.Add(frequency);
|
||||||
Save();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,13 +135,12 @@ namespace NewHorizons.External
|
|||||||
if (KnowsFrequency(frequency))
|
if (KnowsFrequency(frequency))
|
||||||
{
|
{
|
||||||
_activeProfile.KnownFrequencies.Remove(frequency);
|
_activeProfile.KnownFrequencies.Remove(frequency);
|
||||||
Save();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool KnowsMultipleFrequencies()
|
public static bool KnowsMultipleFrequencies()
|
||||||
{
|
{
|
||||||
return _activeProfile != null && _activeProfile.KnownFrequencies.Count > 0;
|
return _activeProfile?.KnownFrequencies != null && _activeProfile.KnownFrequencies.Count(SignalBuilder.IsFrequencyInUse) > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -159,7 +159,6 @@ namespace NewHorizons.External
|
|||||||
if (!KnowsSignal(signal))
|
if (!KnowsSignal(signal))
|
||||||
{
|
{
|
||||||
_activeProfile.KnownSignals.Add(signal);
|
_activeProfile.KnownSignals.Add(signal);
|
||||||
Save();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +169,6 @@ namespace NewHorizons.External
|
|||||||
public static void AddNewlyRevealedFactID(string id)
|
public static void AddNewlyRevealedFactID(string id)
|
||||||
{
|
{
|
||||||
_activeProfile?.NewlyRevealedFactIDs.Add(id);
|
_activeProfile?.NewlyRevealedFactIDs.Add(id);
|
||||||
Save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<string> GetNewlyRevealedFactIDs()
|
public static List<string> GetNewlyRevealedFactIDs()
|
||||||
@ -181,7 +179,6 @@ namespace NewHorizons.External
|
|||||||
public static void ClearNewlyRevealedFactIDs()
|
public static void ClearNewlyRevealedFactIDs()
|
||||||
{
|
{
|
||||||
_activeProfile?.NewlyRevealedFactIDs.Clear();
|
_activeProfile?.NewlyRevealedFactIDs.Clear();
|
||||||
Save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -191,7 +188,6 @@ namespace NewHorizons.External
|
|||||||
public static void ReadOneTimePopup(string id)
|
public static void ReadOneTimePopup(string id)
|
||||||
{
|
{
|
||||||
_activeProfile?.PopupsRead.Add(id);
|
_activeProfile?.PopupsRead.Add(id);
|
||||||
Save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool HasReadOneTimePopup(string id)
|
public static bool HasReadOneTimePopup(string id)
|
||||||
@ -208,7 +204,6 @@ namespace NewHorizons.External
|
|||||||
{
|
{
|
||||||
if (name == CharacterDialogueTree.RECORDING_NAME || name == CharacterDialogueTree.SIGN_NAME) return;
|
if (name == CharacterDialogueTree.RECORDING_NAME || name == CharacterDialogueTree.SIGN_NAME) return;
|
||||||
_activeProfile?.CharactersTalkedTo.SafeAdd(name);
|
_activeProfile?.CharactersTalkedTo.SafeAdd(name);
|
||||||
Save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool HasTalkedToFiveCharacters()
|
public static bool HasTalkedToFiveCharacters()
|
||||||
|
|||||||
@ -371,7 +371,7 @@ namespace NewHorizons.Handlers
|
|||||||
const float sphereOfInfluence = 2000f;
|
const float sphereOfInfluence = 2000f;
|
||||||
|
|
||||||
var owRigidBody = RigidBodyBuilder.Make(go, sphereOfInfluence, body.Config);
|
var owRigidBody = RigidBodyBuilder.Make(go, sphereOfInfluence, body.Config);
|
||||||
var ao = AstroObjectBuilder.Make(go, null, body.Config, false);
|
var ao = AstroObjectBuilder.Make(go, null, body, false);
|
||||||
|
|
||||||
var sector = SectorBuilder.Make(go, owRigidBody, sphereOfInfluence);
|
var sector = SectorBuilder.Make(go, owRigidBody, sphereOfInfluence);
|
||||||
ao._rootSector = sector;
|
ao._rootSector = sector;
|
||||||
@ -447,7 +447,7 @@ namespace NewHorizons.Handlers
|
|||||||
var sphereOfInfluence = GetSphereOfInfluence(body);
|
var sphereOfInfluence = GetSphereOfInfluence(body);
|
||||||
|
|
||||||
var owRigidBody = RigidBodyBuilder.Make(go, sphereOfInfluence, body.Config);
|
var owRigidBody = RigidBodyBuilder.Make(go, sphereOfInfluence, body.Config);
|
||||||
var ao = AstroObjectBuilder.Make(go, primaryBody, body.Config, false);
|
var ao = AstroObjectBuilder.Make(go, primaryBody, body, false);
|
||||||
|
|
||||||
var sector = SectorBuilder.Make(go, owRigidBody, sphereOfInfluence * 2f);
|
var sector = SectorBuilder.Make(go, owRigidBody, sphereOfInfluence * 2f);
|
||||||
ao._rootSector = sector;
|
ao._rootSector = sector;
|
||||||
@ -788,7 +788,7 @@ namespace NewHorizons.Handlers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Just destroy the existing AO after copying everything over
|
// Just destroy the existing AO after copying everything over
|
||||||
var newAO = AstroObjectBuilder.Make(go, primary, body.Config, true);
|
var newAO = AstroObjectBuilder.Make(go, primary, body, true);
|
||||||
newAO._gravityVolume = ao._gravityVolume;
|
newAO._gravityVolume = ao._gravityVolume;
|
||||||
newAO._moon = ao._moon;
|
newAO._moon = ao._moon;
|
||||||
newAO._name = ao._name;
|
newAO._name = ao._name;
|
||||||
|
|||||||
@ -115,6 +115,17 @@ namespace NewHorizons.Handlers
|
|||||||
}
|
}
|
||||||
// For some reason none of this seems to apply to the Player.
|
// 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
|
// If somebody ever makes a sound volume thats somehow always applying to the player tho then itd probably be this
|
||||||
|
|
||||||
|
// Sometimes the ship isn't added to the volumes it's meant to now be in
|
||||||
|
foreach (var volume in SpawnPointBuilder.ShipSpawn.GetAttachedOWRigidbody().GetComponentsInChildren<EffectVolume>())
|
||||||
|
{
|
||||||
|
if (volume.GetOWTriggerVolume().GetPenetrationDistance(ship.transform.position) > 0)
|
||||||
|
{
|
||||||
|
// Add ship to volume
|
||||||
|
// If it's already tracking it it will complain here but thats fine
|
||||||
|
volume.GetOWTriggerVolume().AddObjectToVolume(Locator.GetShipDetector());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Main.Instance.CurrentStarSystem != "SolarSystem" && !Main.Instance.IsWarpingFromShip)
|
else if (Main.Instance.CurrentStarSystem != "SolarSystem" && !Main.Instance.IsWarpingFromShip)
|
||||||
|
|||||||
@ -11,8 +11,8 @@ namespace NewHorizons.Handlers
|
|||||||
{
|
{
|
||||||
class SubtitlesHandler : MonoBehaviour
|
class SubtitlesHandler : MonoBehaviour
|
||||||
{
|
{
|
||||||
public static int SUBTITLE_HEIGHT = 97;
|
public static float SUBTITLE_HEIGHT = 97;
|
||||||
public static int SUBTITLE_WIDTH = 669; // nice
|
public static float SUBTITLE_WIDTH = 669; // nice
|
||||||
|
|
||||||
public float fadeSpeed = 0.005f;
|
public float fadeSpeed = 0.005f;
|
||||||
public float fade = 1;
|
public float fade = 1;
|
||||||
@ -45,7 +45,7 @@ namespace NewHorizons.Handlers
|
|||||||
if (eoteSprite != null)
|
if (eoteSprite != null)
|
||||||
{
|
{
|
||||||
// Don't make it appear first actually because we have mods to display!
|
// Don't make it appear first actually because we have mods to display!
|
||||||
possibleSubtitles.Add(eoteSprite);
|
possibleSubtitles.Add(eoteSprite);
|
||||||
}
|
}
|
||||||
eoteSubtitleHasBeenInserted = true;
|
eoteSubtitleHasBeenInserted = true;
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ namespace NewHorizons.Handlers
|
|||||||
CheckForEOTE();
|
CheckForEOTE();
|
||||||
|
|
||||||
// We add our subtitles as a child object so that their sizing doesnt shift the layout of the main menu
|
// We add our subtitles as a child object so that their sizing doesnt shift the layout of the main menu
|
||||||
_subtitleDisplay = new GameObject().AddComponent<Image>();
|
_subtitleDisplay = new GameObject("SubtitleDisplay").AddComponent<Image>();
|
||||||
_subtitleDisplay.transform.parent = transform;
|
_subtitleDisplay.transform.parent = transform;
|
||||||
_subtitleDisplay.transform.localPosition = new Vector3(0, 0, 0);
|
_subtitleDisplay.transform.localPosition = new Vector3(0, 0, 0);
|
||||||
_subtitleDisplay.transform.localScale = new Vector3(0.75f, 0.75f, 0.75f);
|
_subtitleDisplay.transform.localScale = new Vector3(0.75f, 0.75f, 0.75f);
|
||||||
@ -173,9 +173,12 @@ namespace NewHorizons.Handlers
|
|||||||
{
|
{
|
||||||
subtitleIndex = (subtitleIndex + 1) % possibleSubtitles.Count;
|
subtitleIndex = (subtitleIndex + 1) % possibleSubtitles.Count;
|
||||||
|
|
||||||
_subtitleDisplay.sprite = possibleSubtitles[subtitleIndex];
|
var subtitle = possibleSubtitles[subtitleIndex];
|
||||||
var ratio = SUBTITLE_WIDTH / _subtitleDisplay.sprite.texture.width;
|
_subtitleDisplay.sprite = subtitle;
|
||||||
_subtitleDisplay.rectTransform.sizeDelta = new Vector2(_subtitleDisplay.sprite.texture.width, _subtitleDisplay.sprite.texture.height) * ratio;
|
var width = subtitle.texture.width;
|
||||||
|
var height = subtitle.texture.height;
|
||||||
|
var ratio = SUBTITLE_WIDTH / width; // one of these needs to be a float so that compiler doesn't think "oh 2 integers! let's round to nearest whole"
|
||||||
|
_subtitleDisplay.rectTransform.sizeDelta = new Vector2(width, height) * ratio;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,9 +2,11 @@ using NewHorizons.External.Configs;
|
|||||||
using NewHorizons.Utility;
|
using NewHorizons.Utility;
|
||||||
using NewHorizons.Utility.OWML;
|
using NewHorizons.Utility.OWML;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using static TextTranslation;
|
||||||
|
|
||||||
namespace NewHorizons.Handlers
|
namespace NewHorizons.Handlers
|
||||||
{
|
{
|
||||||
@ -50,30 +52,46 @@ namespace NewHorizons.Handlers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the translated text
|
// Get the translated text
|
||||||
if (dictionary.TryGetValue(language, out var table))
|
if (TryGetTranslatedText(dictionary, language, text, out var translatedText))
|
||||||
{
|
{
|
||||||
if (table.TryGetValue(text, out var translatedText))
|
return translatedText;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (warn)
|
||||||
|
{
|
||||||
|
NHLogger.LogVerbose($"Defaulting to english for {text}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TryGetTranslatedText(dictionary, Language.ENGLISH, text, out translatedText))
|
||||||
|
{
|
||||||
|
return translatedText;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (warn)
|
||||||
|
{
|
||||||
|
NHLogger.LogVerbose($"Defaulting to key for {text}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryGetTranslatedText(Dictionary<Language, Dictionary<string, string>> dict, Language language, string text, out string translatedText)
|
||||||
|
{
|
||||||
|
if (dict.TryGetValue(language, out var table))
|
||||||
|
{
|
||||||
|
if (table.TryGetValue(text, out translatedText))
|
||||||
{
|
{
|
||||||
return translatedText;
|
return true;
|
||||||
}
|
}
|
||||||
// Try without whitespace if its missing
|
// Try without whitespace if its missing
|
||||||
else if (table.TryGetValue(text.TruncateWhitespaceAndToLower(), out translatedText))
|
else if (table.TryGetValue(text.TruncateWhitespaceAndToLower(), out translatedText))
|
||||||
{
|
{
|
||||||
return translatedText;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (warn) NHLogger.LogVerbose($"Defaulting to english for {text}");
|
translatedText = null;
|
||||||
|
return false;
|
||||||
// Try to default to English
|
|
||||||
if (dictionary.TryGetValue(TextTranslation.Language.ENGLISH, out var englishTable))
|
|
||||||
if (englishTable.TryGetValue(text, out var englishText))
|
|
||||||
return englishText;
|
|
||||||
|
|
||||||
if (warn) NHLogger.LogVerbose($"Defaulting to key for {text}");
|
|
||||||
|
|
||||||
// Default to the key
|
|
||||||
return text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RegisterTranslation(TextTranslation.Language language, TranslationConfig config)
|
public static void RegisterTranslation(TextTranslation.Language language, TranslationConfig config)
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
using NewHorizons.Handlers;
|
|
||||||
using OWML.Common;
|
using OWML.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|||||||
@ -263,7 +263,6 @@ namespace NewHorizons
|
|||||||
// Call this from the menu since we hadn't hooked onto the event yet
|
// Call this from the menu since we hadn't hooked onto the event yet
|
||||||
Delay.FireOnNextUpdate(() => OnSceneLoaded(SceneManager.GetActiveScene(), LoadSceneMode.Single));
|
Delay.FireOnNextUpdate(() => OnSceneLoaded(SceneManager.GetActiveScene(), LoadSceneMode.Single));
|
||||||
Delay.FireOnNextUpdate(() => _firstLoad = false);
|
Delay.FireOnNextUpdate(() => _firstLoad = false);
|
||||||
Instance.ModHelper.Menus.PauseMenu.OnInit += DebugReload.InitializePauseMenu;
|
|
||||||
|
|
||||||
MenuHandler.Init();
|
MenuHandler.Init();
|
||||||
AchievementHandler.Init();
|
AchievementHandler.Init();
|
||||||
@ -275,6 +274,13 @@ namespace NewHorizons
|
|||||||
LoadAddonManifest("Assets/addon-manifest.json", this);
|
LoadAddonManifest("Assets/addon-manifest.json", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void SetupPauseMenu(IPauseMenuManager pauseMenu)
|
||||||
|
{
|
||||||
|
base.SetupPauseMenu(pauseMenu);
|
||||||
|
DebugReload.InitializePauseMenu(pauseMenu);
|
||||||
|
DebugMenu.InitializePauseMenu(pauseMenu);
|
||||||
|
}
|
||||||
|
|
||||||
public void OnDestroy()
|
public void OnDestroy()
|
||||||
{
|
{
|
||||||
NHLogger.Log($"Destroying NewHorizons");
|
NHLogger.Log($"Destroying NewHorizons");
|
||||||
@ -512,8 +518,10 @@ namespace NewHorizons
|
|||||||
|
|
||||||
// We are in a custom system on the first loop -> The time loop isn't active, that's not very good
|
// We are in a custom system on the first loop -> The time loop isn't active, that's not very good
|
||||||
// TimeLoop uses the launch codes condition to know if the loop is active or not
|
// TimeLoop uses the launch codes condition to know if the loop is active or not
|
||||||
|
// We also skip them to loop 2, else if they enter a credits volume in this loop they get reset
|
||||||
if (CurrentStarSystem != "SolarSystem" && PlayerData.LoadLoopCount() == 1)
|
if (CurrentStarSystem != "SolarSystem" && PlayerData.LoadLoopCount() == 1)
|
||||||
{
|
{
|
||||||
|
PlayerData.SaveLoopCount(2);
|
||||||
PlayerData.SetPersistentCondition("LAUNCH_CODES_GIVEN", true);
|
PlayerData.SetPersistentCondition("LAUNCH_CODES_GIVEN", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -595,6 +603,7 @@ namespace NewHorizons
|
|||||||
Locator.GetPlayerBody().gameObject.AddComponent<DebugRaycaster>();
|
Locator.GetPlayerBody().gameObject.AddComponent<DebugRaycaster>();
|
||||||
Locator.GetPlayerBody().gameObject.AddComponent<DebugPropPlacer>();
|
Locator.GetPlayerBody().gameObject.AddComponent<DebugPropPlacer>();
|
||||||
Locator.GetPlayerBody().gameObject.AddComponent<DebugMenu>();
|
Locator.GetPlayerBody().gameObject.AddComponent<DebugMenu>();
|
||||||
|
Locator.GetPlayerBody().gameObject.AddComponent<PlayerShipAtmosphereDetectorFix>();
|
||||||
|
|
||||||
PlayerSpawnHandler.OnSystemReady(shouldWarpInFromShip, shouldWarpInFromVessel);
|
PlayerSpawnHandler.OnSystemReady(shouldWarpInFromShip, shouldWarpInFromVessel);
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="OuterWildsGameLibs" Version="1.1.14.768" />
|
<PackageReference Include="OuterWildsGameLibs" Version="1.1.14.768" />
|
||||||
<PackageReference Include="OWML" Version="2.9.8" />
|
<PackageReference Include="OWML" Version="2.11.1" />
|
||||||
<Reference Include="../Lib/System.ComponentModel.Annotations.dll" />
|
<Reference Include="../Lib/System.ComponentModel.Annotations.dll" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@ -1,20 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
|
|
||||||
namespace NewHorizons.OtherMods.MenuFramework
|
|
||||||
{
|
|
||||||
public interface IMenuAPI
|
|
||||||
{
|
|
||||||
GameObject TitleScreen_MakeMenuOpenButton(string name, int index, Menu menuToOpen);
|
|
||||||
GameObject TitleScreen_MakeSceneLoadButton(string name, int index, SubmitActionLoadScene.LoadableScenes sceneToLoad, PopupMenu confirmPopup = null);
|
|
||||||
Button TitleScreen_MakeSimpleButton(string name, int index);
|
|
||||||
GameObject PauseMenu_MakeMenuOpenButton(string name, Menu menuToOpen, Menu customMenu = null);
|
|
||||||
GameObject PauseMenu_MakeSceneLoadButton(string name, SubmitActionLoadScene.LoadableScenes sceneToLoad, PopupMenu confirmPopup = null, Menu customMenu = null);
|
|
||||||
Button PauseMenu_MakeSimpleButton(string name, Menu customMenu = null);
|
|
||||||
Menu PauseMenu_MakePauseListMenu(string title);
|
|
||||||
PopupMenu MakeTwoChoicePopup(string message, string confirmText, string cancelText);
|
|
||||||
PopupInputMenu MakeInputFieldPopup(string message, string placeholderMessage, string confirmText, string cancelText);
|
|
||||||
PopupMenu MakeInfoPopup(string message, string continueButtonText);
|
|
||||||
void RegisterStartupPopup(string message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -11,15 +11,11 @@ namespace NewHorizons.OtherMods.MenuFramework
|
|||||||
{
|
{
|
||||||
public static class MenuHandler
|
public static class MenuHandler
|
||||||
{
|
{
|
||||||
private static IMenuAPI _menuApi;
|
|
||||||
|
|
||||||
private static List<(IModBehaviour mod, string message, bool repeat)> _registeredPopups = new();
|
private static List<(IModBehaviour mod, string message, bool repeat)> _registeredPopups = new();
|
||||||
private static List<string> _failedFiles = new();
|
private static List<string> _failedFiles = new();
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
_menuApi = Main.Instance.ModHelper.Interaction.TryGetModApi<IMenuAPI>("_nebula.MenuFramework");
|
|
||||||
|
|
||||||
TextTranslation.Get().OnLanguageChanged += OnLanguageChanged;
|
TextTranslation.Get().OnLanguageChanged += OnLanguageChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,14 +31,14 @@ namespace NewHorizons.OtherMods.MenuFramework
|
|||||||
Application.version);
|
Application.version);
|
||||||
|
|
||||||
NHLogger.LogError(warning);
|
NHLogger.LogError(warning);
|
||||||
_menuApi.RegisterStartupPopup(warning);
|
Main.Instance.ModHelper.MenuHelper.PopupMenuManager.RegisterStartupPopup(warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(var (mod, message, repeat) in _registeredPopups)
|
foreach(var (mod, message, repeat) in _registeredPopups)
|
||||||
{
|
{
|
||||||
if (repeat || !NewHorizonsData.HasReadOneTimePopup(mod.ModHelper.Manifest.UniqueName))
|
if (repeat || !NewHorizonsData.HasReadOneTimePopup(mod.ModHelper.Manifest.UniqueName))
|
||||||
{
|
{
|
||||||
_menuApi.RegisterStartupPopup(TranslationHandler.GetTranslation(message, TranslationHandler.TextType.UI));
|
Main.Instance.ModHelper.MenuHelper.PopupMenuManager.RegisterStartupPopup(TranslationHandler.GetTranslation(message, TranslationHandler.TextType.UI));
|
||||||
NewHorizonsData.ReadOneTimePopup(mod.ModHelper.Manifest.UniqueName);
|
NewHorizonsData.ReadOneTimePopup(mod.ModHelper.Manifest.UniqueName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,7 +48,7 @@ namespace NewHorizons.OtherMods.MenuFramework
|
|||||||
var message = TranslationHandler.GetTranslation("JSON_FAILED_TO_LOAD", TranslationHandler.TextType.UI);
|
var message = TranslationHandler.GetTranslation("JSON_FAILED_TO_LOAD", TranslationHandler.TextType.UI);
|
||||||
var mods = string.Join(",", _failedFiles.Take(10));
|
var mods = string.Join(",", _failedFiles.Take(10));
|
||||||
if (_failedFiles.Count > 10) mods += "...";
|
if (_failedFiles.Count > 10) mods += "...";
|
||||||
_menuApi.RegisterStartupPopup(string.Format(message, mods));
|
Main.Instance.ModHelper.MenuHelper.PopupMenuManager.RegisterStartupPopup(string.Format(message, mods));
|
||||||
}
|
}
|
||||||
|
|
||||||
_registeredPopups.Clear();
|
_registeredPopups.Clear();
|
||||||
|
|||||||
26
NewHorizons/Patches/BrambleProjectionFixPatches.cs
Normal file
26
NewHorizons/Patches/BrambleProjectionFixPatches.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace NewHorizons.Patches;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Bug fix from the Outsider
|
||||||
|
/// </summary>
|
||||||
|
[HarmonyPatch]
|
||||||
|
internal class BrambleProjectionFixPatches
|
||||||
|
{
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(FogWarpVolume), nameof(FogWarpVolume.WarpDetector))]
|
||||||
|
public static bool FogWarpVolume_WarpDetector()
|
||||||
|
{
|
||||||
|
// Do not warp the player if they have entered the fog via a projection
|
||||||
|
return !PlayerState.UsingNomaiRemoteCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(FogWarpDetector), nameof(FogWarpDetector.FixedUpdate))]
|
||||||
|
public static bool FogWarpDetector_FixedUpdate()
|
||||||
|
{
|
||||||
|
// Do not warp the player if they have entered the fog via a projection
|
||||||
|
return !PlayerState.UsingNomaiRemoteCamera();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,6 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
|
using System.Collections;
|
||||||
|
using UnityEngine.InputSystem;
|
||||||
|
|
||||||
namespace NewHorizons.Patches.DialoguePatches
|
namespace NewHorizons.Patches.DialoguePatches
|
||||||
{
|
{
|
||||||
@ -7,6 +9,29 @@ namespace NewHorizons.Patches.DialoguePatches
|
|||||||
{
|
{
|
||||||
private static bool _wasLastDialogueInactive = false;
|
private static bool _wasLastDialogueInactive = false;
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(nameof(RemoteDialogueTrigger.Awake))]
|
||||||
|
public static void RemoteDialogueTrigger_Awake(RemoteDialogueTrigger __instance)
|
||||||
|
{
|
||||||
|
// Wait for player to be up and moving before allowing them to trigger remote dialogue
|
||||||
|
// Stops you getting locked into dialogue while waking up
|
||||||
|
if (OWInput.GetInputMode() != InputMode.Character)
|
||||||
|
{
|
||||||
|
__instance._collider.enabled = false;
|
||||||
|
__instance.StartCoroutine(AwakeCoroutine(__instance));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerator AwakeCoroutine(RemoteDialogueTrigger instance)
|
||||||
|
{
|
||||||
|
while (OWInput.GetInputMode() != InputMode.Character)
|
||||||
|
{
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance._collider.enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Should fix a bug where disabled a CharacterDialogueTree makes its related RemoteDialogueTriggers softlock your game
|
/// Should fix a bug where disabled a CharacterDialogueTree makes its related RemoteDialogueTriggers softlock your game
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using NewHorizons.Components.Sectored;
|
using NewHorizons.Components.Sectored;
|
||||||
using NewHorizons.Handlers;
|
using NewHorizons.Handlers;
|
||||||
|
using NewHorizons.Utility.OWML;
|
||||||
|
|
||||||
namespace NewHorizons.Patches.HUDPatches
|
namespace NewHorizons.Patches.HUDPatches
|
||||||
{
|
{
|
||||||
@ -27,15 +28,21 @@ namespace NewHorizons.Patches.HUDPatches
|
|||||||
[HarmonyPatch(nameof(ProbeHUDMarker.RefreshOwnVisibility))]
|
[HarmonyPatch(nameof(ProbeHUDMarker.RefreshOwnVisibility))]
|
||||||
public static bool ProbeHUDMarker_RefreshOwnVisibility(ProbeHUDMarker __instance)
|
public static bool ProbeHUDMarker_RefreshOwnVisibility(ProbeHUDMarker __instance)
|
||||||
{
|
{
|
||||||
|
// Probe marker seems to never appear in the eye or QM in base game (inside eye being past the vortex) ?? at least thats what its code implies
|
||||||
bool insideEYE = Locator.GetEyeStateManager() != null && Locator.GetEyeStateManager().IsInsideTheEye();
|
bool insideEYE = Locator.GetEyeStateManager() != null && Locator.GetEyeStateManager().IsInsideTheEye();
|
||||||
bool insideQM = __instance._quantumMoon != null && (__instance._quantumMoon.IsPlayerInside() || __instance._quantumMoon.IsProbeInside());
|
bool insideQM = __instance._quantumMoon != null && (__instance._quantumMoon.IsPlayerInside() || __instance._quantumMoon.IsProbeInside());
|
||||||
bool insideRW = Locator.GetRingWorldController() != null && Locator.GetRingWorldController().isPlayerInside == Locator.GetRingWorldController().isProbeInside;
|
|
||||||
bool insideIP = Locator.GetCloakFieldController() != null && Locator.GetCloakFieldController().isPlayerInsideCloak == Locator.GetCloakFieldController().isProbeInsideCloak;
|
// Either the controllers wtv are null or the player and probe state are the same
|
||||||
bool insideCloak = CloakSectorController.isPlayerInside == CloakSectorController.isProbeInside;
|
bool sameRW = Locator.GetRingWorldController() == null || Locator.GetRingWorldController().isPlayerInside == Locator.GetRingWorldController().isProbeInside;
|
||||||
|
bool sameIP = Locator.GetCloakFieldController() == null || Locator.GetCloakFieldController().isPlayerInsideCloak == Locator.GetCloakFieldController().isProbeInsideCloak;
|
||||||
|
bool sameCloak = CloakSectorController.isPlayerInside == CloakSectorController.isProbeInside;
|
||||||
bool sameInterference = InterferenceHandler.IsPlayerSameAsProbe();
|
bool sameInterference = InterferenceHandler.IsPlayerSameAsProbe();
|
||||||
|
|
||||||
bool isActive = __instance.gameObject.activeInHierarchy || __instance._isTLCDuplicate;
|
bool isActive = __instance.gameObject.activeInHierarchy || __instance._isTLCDuplicate;
|
||||||
|
|
||||||
__instance._isVisible = isActive && !insideEYE && !insideQM && !__instance._translatorEquipped && !__instance._inConversation && __instance._launched && (__instance._isWearingHelmet || __instance._atFlightConsole) && insideRW && insideIP && insideCloak && sameInterference;
|
__instance._isVisible = isActive && !insideEYE && !insideQM && !__instance._translatorEquipped
|
||||||
|
&& !__instance._inConversation && __instance._launched && (__instance._isWearingHelmet || __instance._atFlightConsole)
|
||||||
|
&& sameRW && sameIP && sameCloak && sameInterference;
|
||||||
|
|
||||||
if (__instance._canvasMarker != null) __instance._canvasMarker.SetVisibility(__instance._isVisible);
|
if (__instance._canvasMarker != null) __instance._canvasMarker.SetVisibility(__instance._isVisible);
|
||||||
|
|
||||||
|
|||||||
@ -85,12 +85,8 @@ namespace NewHorizons.Patches.PlayerPatches
|
|||||||
[HarmonyPatch(nameof(PlayerData.KnowsMultipleFrequencies))]
|
[HarmonyPatch(nameof(PlayerData.KnowsMultipleFrequencies))]
|
||||||
public static bool PlayerData_KnowsMultipleFrequencies(ref bool __result)
|
public static bool PlayerData_KnowsMultipleFrequencies(ref bool __result)
|
||||||
{
|
{
|
||||||
if (NewHorizonsData.KnowsMultipleFrequencies())
|
__result = NewHorizonsData.KnowsMultipleFrequencies();
|
||||||
{
|
return false;
|
||||||
__result = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
@ -140,5 +136,12 @@ namespace NewHorizons.Patches.PlayerPatches
|
|||||||
{
|
{
|
||||||
NewHorizonsData.Reset();
|
NewHorizonsData.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(nameof(PlayerData.SaveCurrentGame))]
|
||||||
|
public static void PlayerData_SaveCurrentGame()
|
||||||
|
{
|
||||||
|
NewHorizonsData.Save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,9 +25,32 @@ namespace NewHorizons.Patches.ShipLogPatches
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(nameof(ShipLogAstroObject.UpdateState))]
|
||||||
|
public static bool ShipLogAstroObject_UpdateState_Pre(ShipLogAstroObject __instance)
|
||||||
|
{
|
||||||
|
// Custom astro objects might have no entries, in this case they will be permanently hidden
|
||||||
|
// Just treat it as if it were revealed
|
||||||
|
if (__instance._entries.Count == 0)
|
||||||
|
{
|
||||||
|
__instance._state = ShipLogEntry.State.Explored;
|
||||||
|
__instance._imageObj.SetActive(true);
|
||||||
|
__instance._outlineObj?.SetActive(false);
|
||||||
|
if (__instance._image != null)
|
||||||
|
{
|
||||||
|
__instance.SetMaterialGreyscale(false);
|
||||||
|
__instance._image.color = Color.white;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(nameof(ShipLogAstroObject.UpdateState))]
|
[HarmonyPatch(nameof(ShipLogAstroObject.UpdateState))]
|
||||||
public static void ShipLogAstroObject_UpdateState(ShipLogAstroObject __instance)
|
public static void ShipLogAstroObject_UpdateState_Post(ShipLogAstroObject __instance)
|
||||||
{
|
{
|
||||||
Transform detailsParent = __instance.transform.Find("Details");
|
Transform detailsParent = __instance.transform.Find("Details");
|
||||||
if (detailsParent != null)
|
if (detailsParent != null)
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using NewHorizons.Builder.Props.Audio;
|
using NewHorizons.Builder.Props.Audio;
|
||||||
|
using NewHorizons.Utility.OWML;
|
||||||
|
|
||||||
namespace NewHorizons.Patches.SignalPatches
|
namespace NewHorizons.Patches.SignalPatches
|
||||||
{
|
{
|
||||||
@ -19,13 +20,18 @@ namespace NewHorizons.Patches.SignalPatches
|
|||||||
{
|
{
|
||||||
var count = SignalBuilder.NumberOfFrequencies;
|
var count = SignalBuilder.NumberOfFrequencies;
|
||||||
__instance._frequencyFilterIndex += increment;
|
__instance._frequencyFilterIndex += increment;
|
||||||
|
// Base game does 1 here but we use frequency index 0 as "default" or "???"
|
||||||
__instance._frequencyFilterIndex = __instance._frequencyFilterIndex >= count ? 0 : __instance._frequencyFilterIndex;
|
__instance._frequencyFilterIndex = __instance._frequencyFilterIndex >= count ? 0 : __instance._frequencyFilterIndex;
|
||||||
__instance._frequencyFilterIndex = __instance._frequencyFilterIndex < 0 ? count - 1 : __instance._frequencyFilterIndex;
|
__instance._frequencyFilterIndex = __instance._frequencyFilterIndex < 0 ? count - 1 : __instance._frequencyFilterIndex;
|
||||||
var signalFrequency = AudioSignal.IndexToFrequency(__instance._frequencyFilterIndex);
|
var signalFrequency = AudioSignal.IndexToFrequency(__instance._frequencyFilterIndex);
|
||||||
|
|
||||||
|
NHLogger.Log($"Changed freq to {signalFrequency} at {__instance._frequencyFilterIndex}");
|
||||||
|
|
||||||
// Skip over this frequency
|
// Skip over this frequency
|
||||||
var isUnknown = !PlayerData.KnowsFrequency(signalFrequency) && !(__instance._isUnknownFreqNearby && __instance._unknownFrequency == signalFrequency);
|
// Never skip traveler (always known)
|
||||||
if (isUnknown || !SignalBuilder.IsFrequencyInUse(signalFrequency))
|
var isTraveler = __instance._frequencyFilterIndex == 1;
|
||||||
|
var isUnknown = !PlayerData.KnowsFrequency(signalFrequency) && (!__instance._isUnknownFreqNearby || __instance._unknownFrequency != signalFrequency);
|
||||||
|
if (!isTraveler && (isUnknown || !SignalBuilder.IsFrequencyInUse(signalFrequency)))
|
||||||
{
|
{
|
||||||
__instance.SwitchFrequencyFilter(increment);
|
__instance.SwitchFrequencyFilter(increment);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,5 +26,25 @@ namespace NewHorizons.Patches.VolumePatches
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This method detects Nomai shuttles that are inactive
|
||||||
|
/// When active, it swaps the position of the NomaiShuttleController and the Rigidbody, so its not found as a child here and explodes continuously forever
|
||||||
|
/// Just ignore the shuttle if its inactive
|
||||||
|
/// </summary>
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(nameof(DestructionVolume.VanishNomaiShuttle))]
|
||||||
|
public static bool DestructionVolume_VanishNomaiShuttle(DestructionVolume __instance, OWRigidbody shuttleBody, RelativeLocationData entryLocation)
|
||||||
|
{
|
||||||
|
if (shuttleBody.GetComponentInChildren<NomaiShuttleController>() == null)
|
||||||
|
{
|
||||||
|
if (__instance._nomaiShuttleBody == shuttleBody)
|
||||||
|
{
|
||||||
|
__instance._nomaiShuttleBody = null;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1429,6 +1429,22 @@
|
|||||||
"description": "The direction the item will be oriented when dropping it on the ground. Defaults to up (0, 1, 0).",
|
"description": "The direction the item will be oriented when dropping it on the ground. Defaults to up (0, 1, 0).",
|
||||||
"$ref": "#/definitions/MVector3"
|
"$ref": "#/definitions/MVector3"
|
||||||
},
|
},
|
||||||
|
"holdOffset": {
|
||||||
|
"description": "A relative offset to apply to the item's position when holding it. The initial position varies for vanilla item types.",
|
||||||
|
"$ref": "#/definitions/MVector3"
|
||||||
|
},
|
||||||
|
"holdRotation": {
|
||||||
|
"description": "A relative offset to apply to the item's rotation when holding it.",
|
||||||
|
"$ref": "#/definitions/MVector3"
|
||||||
|
},
|
||||||
|
"socketOffset": {
|
||||||
|
"description": "A relative offset to apply to the item's position when placing it into a socket.",
|
||||||
|
"$ref": "#/definitions/MVector3"
|
||||||
|
},
|
||||||
|
"socketRotation": {
|
||||||
|
"description": "A relative offset to apply to the item's rotation when placing it into a socket.",
|
||||||
|
"$ref": "#/definitions/MVector3"
|
||||||
|
},
|
||||||
"pickupAudio": {
|
"pickupAudio": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The audio to play when this item is picked up. Only applies to custom/non-vanilla item types.\nCan be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list."
|
"description": "The audio to play when this item is picked up. Only applies to custom/non-vanilla item types.\nCan be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list."
|
||||||
|
|||||||
@ -3,6 +3,7 @@ using NewHorizons.Utility.Files;
|
|||||||
using NewHorizons.Utility.OWML;
|
using NewHorizons.Utility.OWML;
|
||||||
using OWML.Common;
|
using OWML.Common;
|
||||||
using OWML.Common.Menus;
|
using OWML.Common.Menus;
|
||||||
|
using OWML.Utils;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace NewHorizons.Utility.DebugTools
|
namespace NewHorizons.Utility.DebugTools
|
||||||
@ -10,22 +11,18 @@ namespace NewHorizons.Utility.DebugTools
|
|||||||
public static class DebugReload
|
public static class DebugReload
|
||||||
{
|
{
|
||||||
|
|
||||||
private static IModButton _reloadButton;
|
private static SubmitAction _reloadButton;
|
||||||
|
|
||||||
public static void InitializePauseMenu()
|
public static void InitializePauseMenu(IPauseMenuManager pauseMenu)
|
||||||
{
|
{
|
||||||
_reloadButton = Main.Instance.ModHelper.Menus.PauseMenu.OptionsButton.Duplicate(TranslationHandler.GetTranslation("Reload Configs", TranslationHandler.TextType.UI).ToUpper());
|
_reloadButton = pauseMenu.MakeSimpleButton(TranslationHandler.GetTranslation("Reload Configs", TranslationHandler.TextType.UI).ToUpper(), 3, true);
|
||||||
_reloadButton.OnClick += ReloadConfigs;
|
_reloadButton.OnSubmitAction += ReloadConfigs;
|
||||||
UpdateReloadButton();
|
UpdateReloadButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateReloadButton()
|
public static void UpdateReloadButton()
|
||||||
{
|
{
|
||||||
if (_reloadButton != null)
|
_reloadButton?.SetButtonVisible(Main.Debug);
|
||||||
{
|
|
||||||
if (Main.Debug) _reloadButton.Show();
|
|
||||||
else _reloadButton.Hide();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ReloadConfigs()
|
private static void ReloadConfigs()
|
||||||
|
|||||||
@ -5,6 +5,7 @@ using NewHorizons.Utility.OWML;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using OWML.Common;
|
using OWML.Common;
|
||||||
using OWML.Common.Menus;
|
using OWML.Common.Menus;
|
||||||
|
using OWML.Utils;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -15,7 +16,7 @@ namespace NewHorizons.Utility.DebugTools.Menu
|
|||||||
{
|
{
|
||||||
class DebugMenu : MonoBehaviour
|
class DebugMenu : MonoBehaviour
|
||||||
{
|
{
|
||||||
private static IModButton pauseMenuButton;
|
private static SubmitAction pauseMenuButton;
|
||||||
|
|
||||||
public GUIStyle _editorMenuStyle;
|
public GUIStyle _editorMenuStyle;
|
||||||
public GUIStyle _tabBarStyle;
|
public GUIStyle _tabBarStyle;
|
||||||
@ -23,7 +24,6 @@ namespace NewHorizons.Utility.DebugTools.Menu
|
|||||||
internal Vector2 EditorMenuSize = new Vector2(600, 900);
|
internal Vector2 EditorMenuSize = new Vector2(600, 900);
|
||||||
bool menuOpen = false;
|
bool menuOpen = false;
|
||||||
static bool openMenuOnPause;
|
static bool openMenuOnPause;
|
||||||
static bool staticInitialized;
|
|
||||||
|
|
||||||
// Menu params
|
// Menu params
|
||||||
internal static IModBehaviour loadedMod = null;
|
internal static IModBehaviour loadedMod = null;
|
||||||
@ -34,6 +34,8 @@ namespace NewHorizons.Utility.DebugTools.Menu
|
|||||||
// Submenus
|
// Submenus
|
||||||
private List<DebugSubmenu> submenus;
|
private List<DebugSubmenu> submenus;
|
||||||
private int activeSubmenu = 0;
|
private int activeSubmenu = 0;
|
||||||
|
|
||||||
|
private static DebugMenu _instance;
|
||||||
|
|
||||||
internal static JsonSerializerSettings jsonSettings = new JsonSerializerSettings
|
internal static JsonSerializerSettings jsonSettings = new JsonSerializerSettings
|
||||||
{
|
{
|
||||||
@ -55,28 +57,13 @@ namespace NewHorizons.Utility.DebugTools.Menu
|
|||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
if (!staticInitialized)
|
_instance = this;
|
||||||
{
|
|
||||||
staticInitialized = true;
|
|
||||||
|
|
||||||
Main.Instance.ModHelper.Menus.PauseMenu.OnInit += PauseMenuInitHook;
|
Main.Instance.ModHelper.MenuHelper.PauseMenuManager.PauseMenuOpened += OnOpenMenu;
|
||||||
Main.Instance.ModHelper.Menus.PauseMenu.OnClosed += CloseMenu;
|
Main.Instance.ModHelper.MenuHelper.PauseMenuManager.PauseMenuClosed += OnCloseMenu;
|
||||||
Main.Instance.ModHelper.Menus.PauseMenu.OnOpened += RestoreMenuOpennessState;
|
Main.Instance.OnChangeStarSystem.AddListener(OnChangeStarSystem);
|
||||||
|
|
||||||
PauseMenuInitHook();
|
InitMenu();
|
||||||
|
|
||||||
Main.Instance.OnChangeStarSystem.AddListener((string s) => {
|
|
||||||
if (saveButtonUnlocked)
|
|
||||||
{
|
|
||||||
SaveLoadedConfigsForRecentSystem();
|
|
||||||
saveButtonUnlocked = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
InitMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loadedMod != null)
|
if (loadedMod != null)
|
||||||
{
|
{
|
||||||
@ -84,26 +71,38 @@ namespace NewHorizons.Utility.DebugTools.Menu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PauseMenuInitHook()
|
public void OnDestroy()
|
||||||
{
|
{
|
||||||
pauseMenuButton = Main.Instance.ModHelper.Menus.PauseMenu.OptionsButton.Duplicate(TranslationHandler.GetTranslation("Toggle Dev Tools Menu", TranslationHandler.TextType.UI).ToUpper());
|
Main.Instance.ModHelper.MenuHelper.PauseMenuManager.PauseMenuOpened -= OnOpenMenu;
|
||||||
InitMenu();
|
Main.Instance.ModHelper.MenuHelper.PauseMenuManager.PauseMenuClosed -= OnCloseMenu;
|
||||||
|
Main.Instance.OnChangeStarSystem.RemoveListener(OnChangeStarSystem);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnChangeStarSystem(string _)
|
||||||
|
{
|
||||||
|
if (saveButtonUnlocked)
|
||||||
|
{
|
||||||
|
SaveLoadedConfigsForRecentSystem();
|
||||||
|
saveButtonUnlocked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void InitializePauseMenu(IPauseMenuManager pauseMenu)
|
||||||
|
{
|
||||||
|
pauseMenuButton = pauseMenu.MakeSimpleButton(TranslationHandler.GetTranslation("Toggle Dev Tools Menu", TranslationHandler.TextType.UI).ToUpper(), 3, true);
|
||||||
|
_instance?.InitMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdatePauseMenuButton()
|
public static void UpdatePauseMenuButton()
|
||||||
{
|
{
|
||||||
if (pauseMenuButton != null)
|
pauseMenuButton?.SetButtonVisible(Main.Debug);
|
||||||
{
|
|
||||||
if (Main.Debug) pauseMenuButton.Show();
|
|
||||||
else pauseMenuButton.Hide();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RestoreMenuOpennessState() { menuOpen = openMenuOnPause; }
|
private void OnOpenMenu() { menuOpen = openMenuOnPause; }
|
||||||
|
|
||||||
private void ToggleMenu() { menuOpen = !menuOpen; openMenuOnPause = !openMenuOnPause; }
|
private void ToggleMenu() { menuOpen = !menuOpen; openMenuOnPause = !openMenuOnPause; }
|
||||||
|
|
||||||
private void CloseMenu() { menuOpen = false; }
|
private void OnCloseMenu() { menuOpen = false; }
|
||||||
|
|
||||||
private void OnGUI()
|
private void OnGUI()
|
||||||
{
|
{
|
||||||
@ -284,7 +283,7 @@ namespace NewHorizons.Utility.DebugTools.Menu
|
|||||||
UpdatePauseMenuButton();
|
UpdatePauseMenuButton();
|
||||||
|
|
||||||
// TODO: figure out how to clear this event list so that we don't pile up useless instances of the DebugMenu that can't get garbage collected
|
// TODO: figure out how to clear this event list so that we don't pile up useless instances of the DebugMenu that can't get garbage collected
|
||||||
pauseMenuButton.OnClick += ToggleMenu;
|
pauseMenuButton.OnSubmitAction += ToggleMenu;
|
||||||
|
|
||||||
submenus.ForEach(submenu => submenu.OnInit(this));
|
submenus.ForEach(submenu => submenu.OnInit(this));
|
||||||
|
|
||||||
|
|||||||
@ -19,10 +19,17 @@ namespace NewHorizons.Utility.OWML
|
|||||||
Main.Instance.ModHelper.Console.WriteLine($"{Enum.GetName(typeof(LogType), type)} : {text}", LogTypeToMessageType(type));
|
Main.Instance.ModHelper.Console.WriteLine($"{Enum.GetName(typeof(LogType), type)} : {text}", LogTypeToMessageType(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void LogVerbose(params object[] obj) => LogVerbose(string.Join(", ", obj));
|
||||||
public static void LogVerbose(object text) => Log(text, LogType.Verbose);
|
public static void LogVerbose(object text) => Log(text, LogType.Verbose);
|
||||||
|
|
||||||
public static void Log(object text) => Log(text, LogType.Log);
|
public static void Log(object text) => Log(text, LogType.Log);
|
||||||
|
public static void Log(params object[] obj) => Log(string.Join(", ", obj));
|
||||||
|
|
||||||
public static void LogWarning(object text) => Log(text, LogType.Warning);
|
public static void LogWarning(object text) => Log(text, LogType.Warning);
|
||||||
|
public static void LogWarning(params object[] obj) => LogWarning(string.Join(", ", obj));
|
||||||
|
|
||||||
public static void LogError(object text) => Log(text, LogType.Error);
|
public static void LogError(object text) => Log(text, LogType.Error);
|
||||||
|
public static void LogError(params object[] obj) => LogError(string.Join(", ", obj));
|
||||||
|
|
||||||
public enum LogType
|
public enum LogType
|
||||||
{
|
{
|
||||||
|
|||||||
@ -4,9 +4,9 @@
|
|||||||
"author": "xen, Bwc9876, JohnCorby, MegaPiggy, Clay, Trifid, and friends",
|
"author": "xen, Bwc9876, JohnCorby, MegaPiggy, Clay, Trifid, and friends",
|
||||||
"name": "New Horizons",
|
"name": "New Horizons",
|
||||||
"uniqueName": "xen.NewHorizons",
|
"uniqueName": "xen.NewHorizons",
|
||||||
"version": "1.19.3",
|
"version": "1.19.9",
|
||||||
"owmlVersion": "2.9.8",
|
"owmlVersion": "2.10.3",
|
||||||
"dependencies": [ "JohnCorby.VanillaFix", "_nebula.MenuFramework", "xen.CommonCameraUtility", "dgarro.CustomShipLogModes" ],
|
"dependencies": [ "JohnCorby.VanillaFix", "xen.CommonCameraUtility", "dgarro.CustomShipLogModes" ],
|
||||||
"conflicts": [ "Raicuparta.QuantumSpaceBuddies", "PacificEngine.OW_CommonResources" ],
|
"conflicts": [ "Raicuparta.QuantumSpaceBuddies", "PacificEngine.OW_CommonResources" ],
|
||||||
"pathsToPreserve": [ "planets", "systems", "translations" ],
|
"pathsToPreserve": [ "planets", "systems", "translations" ],
|
||||||
"donateLink": "https://www.patreon.com/ownh"
|
"donateLink": "https://www.patreon.com/ownh"
|
||||||
|
|||||||
@ -30,7 +30,7 @@ Once in VSCode, paste this code into the file:
|
|||||||
```json title="wetrock.json"
|
```json title="wetrock.json"
|
||||||
{
|
{
|
||||||
"name": "Wetrock",
|
"name": "Wetrock",
|
||||||
"$schema": "https://raw.githubusercontent.com/Outer-Wilds-New-Horizons/new-horizons/main/NewHorizons/Schemas/body_schema.json",
|
"$schema": "https://raw.githubusercontent.com/Outer-Wilds-New-Horizons/new-horizons/main/NewHorizons/Schemas/body_schema.json",
|
||||||
"starSystem": "SolarSystem",
|
"starSystem": "SolarSystem",
|
||||||
"Base": {
|
"Base": {
|
||||||
"groundSize": 100,
|
"groundSize": 100,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user