mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
1.20.3 (#880)
## Minor features - Added `parentPath` to scatter. This parent should be at the position where you'd like to scatter (which would usually be zero). ## Improvements - Now avoiding unnecessary EndConversation calls. (Fix #859) ## Bug fixes - Prevents a softlock when at the eye (JohnCorby's fault) (Fix #865) - Pause on load like in base game (Fix #783) - Fixed disabled reference frames not being disabled (for the third time) - Fixed sectors being rotated on tidally locked bodies - Fixed scatter not working properly on tidally locked bodies - Fixed returning to solar system radius not being calculated correctly - Supposedly fixed rafts but didn't actually (wtf Hawkbar!) - Stop popups spamming your entire save file potentially.
This commit is contained in:
commit
d87b2d0a0a
@ -13,7 +13,7 @@ namespace NewHorizons.Builder.General
|
||||
// We can't not build a reference frame volume, Cloak requires one to be there
|
||||
module.maxTargetDistance = 0f;
|
||||
module.targetWhenClose = true;
|
||||
module.targetColliderRadius = 0f;
|
||||
module.targetColliderRadius = 0.001f;
|
||||
module.hideInMap = true;
|
||||
owrb.SetIsTargetable(false);
|
||||
}
|
||||
|
||||
@ -11,8 +11,8 @@ namespace NewHorizons.Builder.General
|
||||
{
|
||||
var sectorGO = new GameObject("Sector");
|
||||
sectorGO.SetActive(false);
|
||||
sectorGO.transform.parent = planetBody.transform;
|
||||
sectorGO.transform.localPosition = Vector3.zero;
|
||||
// Have to use set parent method without keeping world position to Fix sectors being rotated on tidally locked bodies #870
|
||||
sectorGO.transform.SetParent(planetBody.transform, false);
|
||||
|
||||
var SS = sectorGO.AddComponent<SphereShape>();
|
||||
SS.SetCollisionMode(Shape.CollisionMode.Volume);
|
||||
|
||||
@ -47,17 +47,6 @@ namespace NewHorizons.Builder.Props
|
||||
}
|
||||
}
|
||||
}
|
||||
if (config.Props.scatter != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
ScatterBuilder.Make(go, sector, config, mod);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
NHLogger.LogError($"Couldn't make planet scatter for [{go.name}]:\n{ex}");
|
||||
}
|
||||
}
|
||||
if (config.Props.details != null)
|
||||
{
|
||||
foreach (var detail in config.Props.details)
|
||||
@ -72,6 +61,17 @@ namespace NewHorizons.Builder.Props
|
||||
}
|
||||
}
|
||||
}
|
||||
if (config.Props.scatter != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
ScatterBuilder.Make(go, sector, config, mod);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
NHLogger.LogError($"Couldn't make planet scatter for [{go.name}]:\n{ex}");
|
||||
}
|
||||
}
|
||||
if (config.Props.geysers != null)
|
||||
{
|
||||
foreach (var geyserInfo in config.Props.geysers)
|
||||
|
||||
@ -3,6 +3,7 @@ using NewHorizons.External.Modules.Props;
|
||||
using NewHorizons.Utility;
|
||||
using NewHorizons.Utility.Files;
|
||||
using NewHorizons.Utility.Geometry;
|
||||
using NewHorizons.Utility.OWML;
|
||||
using OWML.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -120,10 +121,28 @@ namespace NewHorizons.Builder.Props
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var parent = sector?.transform ?? go.transform;
|
||||
|
||||
if (go != null && !string.IsNullOrEmpty(propInfo.parentPath))
|
||||
{
|
||||
var newParent = go.transform.Find(propInfo.parentPath);
|
||||
if (newParent != null)
|
||||
{
|
||||
parent = newParent;
|
||||
sector = newParent.GetComponentInParent<Sector>();
|
||||
}
|
||||
else
|
||||
{
|
||||
NHLogger.LogError($"Cannot find parent object at path: {go.name}/{propInfo.parentPath}");
|
||||
}
|
||||
}
|
||||
|
||||
var prop = scatterPrefab.InstantiateInactive();
|
||||
prop.transform.SetParent(sector?.transform ?? go.transform);
|
||||
prop.transform.localPosition = go.transform.TransformPoint(point * height);
|
||||
var up = go.transform.InverseTransformPoint(prop.transform.position).normalized;
|
||||
// Have to use SetParent method to work with tidally locked bodies #872
|
||||
prop.transform.SetParent(parent, false);
|
||||
prop.transform.localPosition = point * height;
|
||||
var up = (prop.transform.position - go.transform.position).normalized;
|
||||
prop.transform.rotation = Quaternion.FromToRotation(Vector3.up, up);
|
||||
|
||||
if (propInfo.offset != null) prop.transform.localPosition += prop.transform.TransformVector(propInfo.offset);
|
||||
|
||||
@ -66,5 +66,10 @@ namespace NewHorizons.External.Modules.Props
|
||||
/// Should this detail stay loaded even if you're outside the sector (good for very large props)
|
||||
/// </summary>
|
||||
public bool keepLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// The relative path from the planet to the parent of this object. Optional (will default to the root sector). This parent should be at the position where you'd like to scatter (which would usually be zero).
|
||||
/// </summary>
|
||||
public string parentPath;
|
||||
}
|
||||
}
|
||||
|
||||
6
NewHorizons/External/NewHorizonsData.cs
vendored
6
NewHorizons/External/NewHorizonsData.cs
vendored
@ -187,7 +187,11 @@ namespace NewHorizons.External
|
||||
|
||||
public static void ReadOneTimePopup(string id)
|
||||
{
|
||||
_activeProfile?.PopupsRead.Add(id);
|
||||
// else it re-adds it each time
|
||||
if (_activeProfile != null && !_activeProfile.PopupsRead.Contains(id))
|
||||
{
|
||||
_activeProfile.PopupsRead.Add(id);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool HasReadOneTimePopup(string id)
|
||||
|
||||
@ -928,7 +928,7 @@ namespace NewHorizons.Handlers
|
||||
}
|
||||
|
||||
// Uses the ratio of the interlopers furthest point to what the base game considers the edge of the solar system
|
||||
var distanceToCenter = go.transform.position.magnitude * (24000 / 30000f);
|
||||
var distanceToCenter = go.transform.position.magnitude / (24000 / 30000f);
|
||||
if (distanceToCenter > SolarSystemRadius)
|
||||
{
|
||||
SolarSystemRadius = distanceToCenter;
|
||||
|
||||
@ -387,9 +387,10 @@ namespace NewHorizons
|
||||
else if (IsWarpingBackToEye)
|
||||
{
|
||||
IsWarpingBackToEye = false;
|
||||
OWTime.Pause(OWTime.PauseType.Loading);
|
||||
LoadManager.LoadScene(OWScene.EyeOfTheUniverse); // LoadScene loads one frame later in Update. will this break since we unpause before that in the next line?
|
||||
OWTime.Unpause(OWTime.PauseType.Loading);
|
||||
// OWTime.Pause(OWTime.PauseType.Loading); // loading already pauses
|
||||
ManualOnStartSceneLoad(OWScene.EyeOfTheUniverse);
|
||||
LoadManager.LoadSceneImmediate(OWScene.EyeOfTheUniverse);
|
||||
// OWTime.Unpause(OWTime.PauseType.Loading); // changing active scenes already unpauses
|
||||
return;
|
||||
}
|
||||
|
||||
@ -627,6 +628,39 @@ namespace NewHorizons
|
||||
HasWarpDrive = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sometimes we call LoadSceneImmediate, which doesnt do the required event firing for mods to be happy.
|
||||
/// this method emulates that via copying parts of LoadManager.
|
||||
/// </summary>
|
||||
public static void ManualOnStartSceneLoad(OWScene scene)
|
||||
{
|
||||
LoadManager.s_loadSceneJob = new LoadManager.LoadSceneJob();
|
||||
LoadManager.s_loadSceneJob.sceneToLoad = scene;
|
||||
LoadManager.s_loadSceneJob.fadeType = LoadManager.FadeType.None;
|
||||
LoadManager.s_loadSceneJob.fadeLength = 0;
|
||||
LoadManager.s_loadSceneJob.pauseDuringFade = true;
|
||||
LoadManager.s_loadSceneJob.asyncOperation = false;
|
||||
LoadManager.s_loadSceneJob.skipPreLoadMemoryDump = false;
|
||||
LoadManager.s_loadSceneJob.skipVsyncChange = false;
|
||||
|
||||
LoadManager.s_loadingScene = LoadManager.s_loadSceneJob.sceneToLoad;
|
||||
LoadManager.s_fadeType = LoadManager.s_loadSceneJob.fadeType;
|
||||
LoadManager.s_fadeStartTime = Time.unscaledTime;
|
||||
LoadManager.s_fadeLength = LoadManager.s_loadSceneJob.fadeLength;
|
||||
LoadManager.s_pauseDuringFade = LoadManager.s_loadSceneJob.pauseDuringFade;
|
||||
LoadManager.s_skipVsyncChange = LoadManager.s_loadSceneJob.skipVsyncChange;
|
||||
|
||||
// cant fire events from outside of class without reflection
|
||||
((Delegate)AccessTools.Field(typeof(LoadManager), nameof(LoadManager.OnStartSceneLoad)).GetValue(null))
|
||||
.DynamicInvoke(LoadManager.s_currentScene, LoadManager.s_loadingScene);
|
||||
|
||||
if (LoadManager.s_pauseDuringFade)
|
||||
{
|
||||
OWTime.Pause(OWTime.PauseType.Loading);
|
||||
}
|
||||
|
||||
LoadManager.s_loadSceneJob = null;
|
||||
}
|
||||
|
||||
#region Load
|
||||
public void LoadStarSystemConfig(string starSystemName, StarSystemConfig starSystemConfig, string relativePath, IModBehaviour mod)
|
||||
@ -936,11 +970,12 @@ namespace NewHorizons
|
||||
OWInput.ChangeInputMode(InputMode.None);
|
||||
|
||||
// Hide unloading
|
||||
ManualOnStartSceneLoad(sceneToLoad);
|
||||
FadeHandler.FadeThen(1f, () =>
|
||||
{
|
||||
// Slide reel unloading is tied to being removed from the sector, so we do that here to prevent a softlock
|
||||
Locator.GetPlayerSectorDetector().RemoveFromAllSectors();
|
||||
LoadManager.LoadScene(sceneToLoad); // this used to be LoadSceneImmediate, but that breaks with qsb. hopefully it doesnt break nh
|
||||
LoadManager.LoadSceneImmediate(sceneToLoad);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,10 @@ public static class CharacterDialogueTreePatches
|
||||
|
||||
private static void OnAttachPlayerToPoint(this CharacterDialogueTree characterDialogueTree, OWRigidbody rigidbody)
|
||||
{
|
||||
characterDialogueTree.EndConversation();
|
||||
if (characterDialogueTree.InConversation())
|
||||
{
|
||||
characterDialogueTree.EndConversation();
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
using HarmonyLib;
|
||||
using NewHorizons.Utility;
|
||||
using OWML.Utils;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
@ -2046,6 +2046,10 @@
|
||||
"keepLoaded": {
|
||||
"type": "boolean",
|
||||
"description": "Should this detail stay loaded even if you're outside the sector (good for very large props)"
|
||||
},
|
||||
"parentPath": {
|
||||
"type": "string",
|
||||
"description": "The relative path from the planet to the parent of this object. Optional (will default to the root sector). This parent should be at the position where you'd like to scatter (which would usually be zero)."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Dialogue Tree -->
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- Empty Type -->
|
||||
@ -8,7 +8,7 @@
|
||||
<xs:element name="DialogueTree">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="NameField" type="xs:string">
|
||||
<xs:element name="NameField" type="xs:string" minOccurs="1" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The name of the character, used for the interaction prompt. Set to `SIGN` for the prompt
|
||||
@ -16,7 +16,7 @@
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="DialogueNode" type="DialogueNode" maxOccurs="unbounded">
|
||||
<xs:element name="DialogueNode" type="DialogueNode" minOccurs="1" maxOccurs="unbounded">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The different nodes of this dialogue tree
|
||||
@ -30,7 +30,7 @@
|
||||
<!-- Dialogue Node Info -->
|
||||
<xs:complexType name="DialogueNode">
|
||||
<xs:sequence>
|
||||
<xs:element name="Name" type="xs:string">
|
||||
<xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The name of this dialogue node
|
||||
@ -45,34 +45,35 @@
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="Randomize" type="empty" minOccurs="0">
|
||||
<xs:element name="Randomize" type="empty" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
When used with multiple Dialogues, the node will choose a random one to show
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="Dialogue" type="Dialogue" maxOccurs="unbounded">
|
||||
<xs:element name="Dialogue" type="Dialogue" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The dialogue to show to the player
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="DialogueOptionsList" type="DialogueOptionsList" minOccurs="0">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
A list of options to show to the player once the character is done talking
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="RevealFacts" type="RevealFacts" minOccurs="0">
|
||||
<xs:element name="RevealFacts" type="RevealFacts" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Facts to reveal when the player goes through this dialogue node
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="SetPersistentCondition" type="xs:string" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Set a new persistent condition that will last indefinitely in the current save, unless cancelled
|
||||
or deleted
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="SetCondition" type="xs:string" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
@ -80,11 +81,10 @@
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="SetPersistentCondition" type="xs:string" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="DisablePersistentCondition" type="xs:string" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Set a new persistent condition that will last indefinitely in the current save, unless cancelled
|
||||
or deleted
|
||||
Disable a set persistent condition from the current save
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
@ -95,7 +95,7 @@
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="DialogueTarget" type="xs:string" minOccurs="0">
|
||||
<xs:element name="DialogueTarget" type="xs:string" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The name of the `DialogueNode` to go to after this node. Mutually exclusive with
|
||||
@ -103,13 +103,20 @@
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="DialogueOptionsList" type="DialogueOptionsList" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
A list of options to show to the player once the character is done talking
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Dialogue Info -->
|
||||
<xs:complexType name="Dialogue">
|
||||
<xs:sequence>
|
||||
<xs:element name="Page" type="xs:string" maxOccurs="unbounded">
|
||||
<xs:element name="Page" type="xs:string" minOccurs="1" maxOccurs="unbounded">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
A page of dialogue to show to the player
|
||||
@ -122,7 +129,7 @@
|
||||
<!-- Reveal Facts Info -->
|
||||
<xs:complexType name="RevealFacts">
|
||||
<xs:sequence>
|
||||
<xs:element name="FactID" type="xs:string" maxOccurs="unbounded">
|
||||
<xs:element name="FactID" type="xs:string" minOccurs="1" maxOccurs="unbounded">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The ID of a fact to reveal
|
||||
@ -135,19 +142,33 @@
|
||||
<!-- Dialogue Options List Info -->
|
||||
<xs:complexType name="DialogueOptionsList">
|
||||
<xs:sequence>
|
||||
<xs:element name="DialogueOption" type="DialogueOption" maxOccurs="unbounded">
|
||||
<xs:element name="DialogueOption" type="DialogueOption" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Options the player can select from
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="ReuseDialogueOptionsListFrom" type="xs:string" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Name of another DialogueNode whose options you want to repeat to avoid having to copy paste
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
<!-- Dialogue Option Info -->
|
||||
<xs:complexType name="DialogueOption">
|
||||
<xs:sequence>
|
||||
<xs:element name="RequiredLogCondition" type="xs:string" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Require a ship log fact to be known to show this option
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="RequiredPersistentCondition" type="xs:string" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
@ -162,55 +183,48 @@
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="RequiredCondition" type="xs:string" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="RequiredCondition" type="xs:string" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Require a (single-loop) condition to be met to show this option
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="CancelledCondition" type="xs:string" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="CancelledCondition" type="xs:string" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Hide this option if a (single-loop) condition has been met
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="RequiredLogCondition" type="xs:string" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Require a ship log fact to be known to show this option
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="Text" type="xs:string">
|
||||
<xs:element name="Text" type="xs:string" minOccurs="1" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The text to show for this option
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="ConditionToSet" type="xs:string" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Set a condition when this option is chosen
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="ConditionToCancel" type="xs:string" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Cancel a condition when this option is chosen
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="DialogueTarget" type="xs:string" minOccurs="0">
|
||||
<xs:element name="DialogueTarget" type="xs:string" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The name of the `DialogueNode` to go to when this option is selected
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="ConditionToSet" type="xs:string" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Set a condition when this option is chosen
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="ConditionToCancel" type="xs:string" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Cancel a condition when this option is chosen
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:schema>
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Ship Log Entries -->
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- Astro Object Entry Info -->
|
||||
<xs:element name="AstroObjectEntry">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="ID" type="xs:string">
|
||||
<xs:element name="ID" type="xs:string" minOccurs="1" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
ID of the planet these entries are for
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="Entry" type="Entry" maxOccurs="unbounded">
|
||||
<xs:element name="Entry" type="Entry" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
A set of entries that belong to this planet
|
||||
@ -29,49 +29,56 @@
|
||||
<!-- Entry Info -->
|
||||
<xs:complexType name="Entry">
|
||||
<xs:sequence>
|
||||
<xs:element name="ID" type="xs:string">
|
||||
<xs:element name="ID" type="xs:string" minOccurs="1" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The ID of this entry
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="Name" type="xs:string">
|
||||
<xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Name of this entry
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="Curiosity" type="xs:string" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="Curiosity" type="xs:string" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The curiosity this entry belongs to
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="IsCuriosity" type="empty" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="IsCuriosity" type="empty" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Whether this entry is a curiosity
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="IgnoreMoreToExplore" type="empty" minOccurs="0">
|
||||
<xs:element name="IgnoreMoreToExplore" type="empty" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Whether to hide the "More To Explore" text on this entry
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="IgnoreMoreToExploreCondition" type="xs:string" minOccurs="0">
|
||||
<xs:element name="ParentIgnoreNotRevealed" type="empty" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
When the parent of this entry is determining whether its "More To Explore" text should appear, this child entry will be ignored.
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="IgnoreMoreToExploreCondition" type="xs:string" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Ignore more to explore if a persistent condition is `true`
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="AltPhotoCondition" type="xs:string" minOccurs="0">
|
||||
<xs:element name="AltPhotoCondition" type="xs:string" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
If this fact is revealed, show the Alt picture
|
||||
@ -105,35 +112,35 @@
|
||||
<!-- Rumor Fact Info -->
|
||||
<xs:complexType name="RumorFact">
|
||||
<xs:sequence>
|
||||
<xs:element name="ID" type="xs:string">
|
||||
<xs:element name="ID" type="xs:string" minOccurs="1" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The ID of this rumor fact
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="SourceID" type="xs:string" minOccurs="0">
|
||||
<xs:element name="SourceID" type="xs:string" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The source of this rumor, this draws a line in detective mode
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="RumorName" type="xs:string" minOccurs="0">
|
||||
<xs:element name="RumorName" type="xs:string" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Displays on the card in detective mode if no ExploreFacts have been revealed on the parent entry
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="RumorNamePriority" type="xs:int" minOccurs="0">
|
||||
<xs:element name="RumorNamePriority" type="xs:int" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Priority over other RumorFacts to appear as the entry card's title
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="IgnoreMoreToExplore" type="empty" minOccurs="0">
|
||||
<xs:element name="IgnoreMoreToExplore" type="empty" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Whether to hide the "More to explore" on this rumor fact
|
||||
@ -147,14 +154,14 @@
|
||||
<!-- Explore Fact Info -->
|
||||
<xs:complexType name="ExploreFact">
|
||||
<xs:sequence>
|
||||
<xs:element name="ID" type="xs:string">
|
||||
<xs:element name="ID" type="xs:string" minOccurs="1" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The ID of this explore fact
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="IgnoreMoreToExplore" type="empty" minOccurs="0">
|
||||
<xs:element name="IgnoreMoreToExplore" type="empty" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Whether to hide the "More to explore" text for this fact
|
||||
@ -168,14 +175,14 @@
|
||||
<!-- Text Data Group -->
|
||||
<xs:group name="TextData">
|
||||
<xs:sequence>
|
||||
<xs:element name="Text" type="xs:string">
|
||||
<xs:element name="Text" type="xs:string" minOccurs="1" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The text content for this fact
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="AltText" minOccurs="0">
|
||||
<xs:element name="AltText" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
Display alt-text given a certain fact is revealed
|
||||
@ -183,14 +190,14 @@
|
||||
</xs:annotation>
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="Text" type="xs:string">
|
||||
<xs:element name="Text" type="xs:string" minOccurs="1" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The text to display if the condition is met
|
||||
</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="Condition" type="xs:string">
|
||||
<xs:element name="Condition" type="xs:string" minOccurs="1" maxOccurs="unbounded">
|
||||
<xs:annotation>
|
||||
<xs:documentation>
|
||||
The condition that needs to be fulfilled to have the alt text be displayed
|
||||
|
||||
@ -27,27 +27,27 @@
|
||||
<!-- Text Block Info -->
|
||||
<xs:complexType name="TextBlock">
|
||||
<xs:sequence>
|
||||
<xs:element name="ID" type="xs:positiveInteger">
|
||||
<xs:element name="ID" type="xs:positiveInteger" minOccurs="1" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation> The id of this text block </xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="ParentID" type="xs:positiveInteger" minOccurs="0">
|
||||
<xs:element name="ParentID" type="xs:positiveInteger" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation> The id of the parent text block </xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="LocationA" type="empty" minOccurs="0">
|
||||
<xs:element name="LocationA" type="empty" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation> </xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="LocationB" type="empty" minOccurs="0">
|
||||
<xs:element name="LocationB" type="empty" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation> </xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="Text" type="xs:string">
|
||||
<xs:element name="Text" type="xs:string" minOccurs="1" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation> The text to show for this option </xs:documentation>
|
||||
</xs:annotation>
|
||||
@ -58,17 +58,17 @@
|
||||
<!-- Ship Log Conditions Info -->
|
||||
<xs:complexType name="ShipLogConditions">
|
||||
<xs:sequence>
|
||||
<xs:element name="LocationA" type="empty" minOccurs="0">
|
||||
<xs:element name="LocationA" type="empty" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation> </xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="LocationB" type="empty" minOccurs="0">
|
||||
<xs:element name="LocationB" type="empty" minOccurs="0" maxOccurs="1">
|
||||
<xs:annotation>
|
||||
<xs:documentation> </xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="RevealFact" type="RevealFact" minOccurs="0">
|
||||
<xs:element name="RevealFact" type="RevealFact" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:annotation>
|
||||
<xs:documentation> Facts to reveal when the player goes through this dialogue
|
||||
node </xs:documentation>
|
||||
|
||||
@ -372,40 +372,6 @@ namespace NewHorizons.Utility
|
||||
return curve;
|
||||
}
|
||||
|
||||
// From QSB
|
||||
public static void RaiseEvent<T>(this T instance, string eventName, params object[] args)
|
||||
{
|
||||
const BindingFlags flags = BindingFlags.Instance
|
||||
| BindingFlags.Static
|
||||
| BindingFlags.Public
|
||||
| BindingFlags.NonPublic
|
||||
| BindingFlags.DeclaredOnly;
|
||||
if (typeof(T)
|
||||
.GetField(eventName, flags)?
|
||||
.GetValue(instance) is not MulticastDelegate multiDelegate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
multiDelegate.SafeInvoke(args);
|
||||
}
|
||||
|
||||
// From QSB
|
||||
public static void SafeInvoke(this MulticastDelegate multicast, params object[] args)
|
||||
{
|
||||
foreach (var del in multicast.GetInvocationList())
|
||||
{
|
||||
try
|
||||
{
|
||||
del.DynamicInvoke(args);
|
||||
}
|
||||
catch (TargetInvocationException ex)
|
||||
{
|
||||
NHLogger.LogError($"Error invoking delegate! {ex.InnerException}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<XmlNode> GetChildNodes(this XmlNode parentNode, string tagName)
|
||||
{
|
||||
return parentNode.ChildNodes.Cast<XmlNode>().Where(node => node.LocalName == tagName).ToList();
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
"author": "xen, Bwc9876, JohnCorby, MegaPiggy, Clay, Trifid, and friends",
|
||||
"name": "New Horizons",
|
||||
"uniqueName": "xen.NewHorizons",
|
||||
"version": "1.20.2",
|
||||
"version": "1.20.3",
|
||||
"owmlVersion": "2.10.3",
|
||||
"dependencies": [ "JohnCorby.VanillaFix", "xen.CommonCameraUtility", "dgarro.CustomShipLogModes" ],
|
||||
"conflicts": [ "PacificEngine.OW_CommonResources" ],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user