## 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:
Will Corby 2024-06-03 21:00:01 -07:00 committed by GitHub
commit d87b2d0a0a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 192 additions and 135 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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)

View File

@ -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;

View File

@ -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);
});
}
}

View File

@ -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]

View File

@ -1,5 +1,5 @@
using HarmonyLib;
using NewHorizons.Utility;
using OWML.Utils;
using System.Collections.Generic;
using UnityEngine;

View File

@ -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)."
}
}
},

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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();

View File

@ -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" ],