Merge pull request #114 from xen-42/dev

Dev
This commit is contained in:
Nick 2022-05-13 17:24:53 -04:00 committed by GitHub
commit f15583ba75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 439 additions and 193 deletions

Binary file not shown.

View File

@ -1,7 +0,0 @@
ManifestFileVersion: 0
CRC: 920416521
AssetBundleManifest:
AssetBundleInfos:
Info_0:
Name: shader
Dependencies: {}

Binary file not shown.

View File

@ -1,21 +0,0 @@
ManifestFileVersion: 0
CRC: 1131808909
Hashes:
AssetFileHash:
serializedVersion: 2
Hash: 183a5bb48d2c1afa94657b52eb300f40
TypeTreeHash:
serializedVersion: 2
Hash: 55d48f4ad9c3b13330b9eb5ee5686477
HashAppended: 0
ClassTypes:
- Class: 48
Script: {instanceID: 0}
SerializeReferenceClassIdentifiers: []
Assets:
- Assets/Shaders/SphereTextureWrapper.shader
- Assets/Shaders/Ring.shader
- Assets/Shaders/UnlitRing1Pixel.shader
- Assets/Shaders/UnlitTransparent.shader
- Assets/Shaders/Ring1Pixel.shader
Dependencies: []

Binary file not shown.

View File

@ -11,6 +11,7 @@ namespace NewHorizons.Builder.Atmosphere
public static class CloudsBuilder public static class CloudsBuilder
{ {
private static Shader _sphereShader = null; private static Shader _sphereShader = null;
private static Material[] _gdCloudMaterials;
public static void Make(GameObject planetGO, Sector sector, AtmosphereModule atmo, IModBehaviour mod) public static void Make(GameObject planetGO, Sector sector, AtmosphereModule atmo, IModBehaviour mod)
{ {
Texture2D image, cap, ramp; Texture2D image, cap, ramp;
@ -45,26 +46,31 @@ namespace NewHorizons.Builder.Atmosphere
topMF.mesh = GameObject.Find("CloudsTopLayer_GD").GetComponent<MeshFilter>().mesh; topMF.mesh = GameObject.Find("CloudsTopLayer_GD").GetComponent<MeshFilter>().mesh;
MeshRenderer topMR = cloudsTopGO.AddComponent<MeshRenderer>(); MeshRenderer topMR = cloudsTopGO.AddComponent<MeshRenderer>();
if (!atmo.UseBasicCloudShader)
if (_sphereShader == null) _sphereShader = Main.NHAssetBundle.LoadAsset<Shader>("Assets/Shaders/SphereTextureWrapper.shader");
if (_gdCloudMaterials == null) _gdCloudMaterials = GameObject.Find("CloudsTopLayer_GD").GetComponent<MeshRenderer>().sharedMaterials;
var tempArray = new Material[2];
if (atmo.UseBasicCloudShader)
{ {
var tempArray = new Material[2]; var material = new Material(_sphereShader);
for (int i = 0; i < 2; i++) if (!atmo.ShadowsOnClouds) material.renderQueue = 2550;
{ material.name = atmo.ShadowsOnClouds ? "BasicShadowCloud" : "BasicCloud";
var mat = new Material(GameObject.Find("CloudsTopLayer_GD").GetComponent<MeshRenderer>().sharedMaterials[i]);
if (!atmo.ShadowsOnClouds) mat.renderQueue = 2550; tempArray[0] = material;
mat.name = atmo.ShadowsOnClouds ? "AdvancedShadowCloud" : "AdvancedCloud";
tempArray[i] = mat;
}
topMR.sharedMaterials = tempArray;
} }
else else
{ {
if (_sphereShader == null) _sphereShader = Main.ShaderBundle.LoadAsset<Shader>("Assets/Shaders/SphereTextureWrapper.shader"); var material = new Material(_gdCloudMaterials[0]);
topMR.material = new Material(_sphereShader); if (!atmo.ShadowsOnClouds) material.renderQueue = 2550;
if (!atmo.ShadowsOnClouds) topMR.material.renderQueue = 2550; material.name = atmo.ShadowsOnClouds ? "AdvancedShadowCloud" : "AdvancedCloud";
topMR.material.name = atmo.ShadowsOnClouds ? "BasicShadowCloud" : "BasicCloud"; tempArray[0] = material;
} }
// This is the stencil material for the fog under the clouds
tempArray[1] = new Material(_gdCloudMaterials[1]);
topMR.sharedMaterials = tempArray;
foreach (var material in topMR.sharedMaterials) foreach (var material in topMR.sharedMaterials)
{ {
material.SetColor("_Color", cloudTint); material.SetColor("_Color", cloudTint);
@ -80,7 +86,6 @@ namespace NewHorizons.Builder.Atmosphere
cloudsTopGO.layer = LayerMask.NameToLayer("IgnoreSun"); cloudsTopGO.layer = LayerMask.NameToLayer("IgnoreSun");
} }
RotateTransform topRT = cloudsTopGO.AddComponent<RotateTransform>(); RotateTransform topRT = cloudsTopGO.AddComponent<RotateTransform>();
// Idk why but the axis is weird // Idk why but the axis is weird
topRT._localAxis = atmo.UseBasicCloudShader ? Vector3.forward : Vector3.up; topRT._localAxis = atmo.UseBasicCloudShader ? Vector3.forward : Vector3.up;

View File

@ -8,8 +8,11 @@ namespace NewHorizons.Builder.Atmosphere
{ {
public static class VolumesBuilder public static class VolumesBuilder
{ {
public static void Make(GameObject planetGO, float innerRadius, float outerRadius, bool useMiniMap) public static void Make(GameObject planetGO, IPlanetConfig config, float sphereOfInfluence)
{ {
var innerRadius = config.Base.SurfaceSize;
var useMiniMap = config.Base.IsSatellite;
GameObject volumesGO = new GameObject("Volumes"); GameObject volumesGO = new GameObject("Volumes");
volumesGO.SetActive(false); volumesGO.SetActive(false);
volumesGO.transform.parent = planetGO.transform; volumesGO.transform.parent = planetGO.transform;
@ -23,20 +26,28 @@ namespace NewHorizons.Builder.Atmosphere
SS.SetLayer(Shape.Layer.Sector); SS.SetLayer(Shape.Layer.Sector);
SS.layerMask = -1; SS.layerMask = -1;
SS.pointChecksOnly = true; SS.pointChecksOnly = true;
SS.radius = outerRadius; SS.radius = sphereOfInfluence;
rulesetGO.AddComponent<OWTriggerVolume>(); rulesetGO.AddComponent<OWTriggerVolume>();
PlanetoidRuleset PR = rulesetGO.AddComponent<PlanetoidRuleset>(); PlanetoidRuleset PR = rulesetGO.AddComponent<PlanetoidRuleset>();
PR._altitudeFloor = innerRadius; PR._altitudeFloor = innerRadius;
PR._altitudeCeiling = outerRadius; PR._altitudeCeiling = sphereOfInfluence;
PR._useMinimap = useMiniMap; PR._useMinimap = useMiniMap;
PR._useAltimeter = useMiniMap; PR._useAltimeter = useMiniMap;
EffectRuleset ER = rulesetGO.AddComponent<EffectRuleset>(); EffectRuleset ER = rulesetGO.AddComponent<EffectRuleset>();
ER._type = EffectRuleset.BubbleType.Underwater; ER._type = EffectRuleset.BubbleType.Underwater;
ER._material = GameObject.Find("RulesetVolumes_GD").GetComponent<RulesetVolume>().GetValue<Material>("_material"); var gdRuleset = GameObject.Find("GiantsDeep_Body/Sector_GD/Volumes_GD/RulesetVolumes_GD").GetComponent<EffectRuleset>();
ER._cloudMaterial = GameObject.Find("RulesetVolumes_GD").GetComponent<RulesetVolume>().GetValue<Material>("_cloudMaterial");
ER._material = gdRuleset._material;
var cloudMaterial = new Material(gdRuleset._cloudMaterial);
if (config.Atmosphere?.CloudTint != null)
{
cloudMaterial.SetColor("_FogColor", config.Atmosphere.CloudTint.ToColor32());
}
ER._cloudMaterial = cloudMaterial;
volumesGO.transform.position = planetGO.transform.position; volumesGO.transform.position = planetGO.transform.position;
rulesetGO.SetActive(true); rulesetGO.SetActive(true);

View File

@ -11,7 +11,7 @@ namespace NewHorizons.Builder.Body
{ {
public static class CloakBuilder public static class CloakBuilder
{ {
public static void Make(GameObject planetGO, Sector sector, float radius) public static void Make(GameObject planetGO, Sector sector, OWRigidbody OWRB, float radius)
{ {
var cloak = SearchUtilities.Find("RingWorld_Body/CloakingField_IP"); var cloak = SearchUtilities.Find("RingWorld_Body/CloakingField_IP");
@ -28,7 +28,7 @@ namespace NewHorizons.Builder.Body
cloakFieldController._innerCloakRadius = radius * 900 / 3000f; cloakFieldController._innerCloakRadius = radius * 900 / 3000f;
cloakFieldController._nearCloakRadius = radius * 800 / 3000f; cloakFieldController._nearCloakRadius = radius * 800 / 3000f;
cloakFieldController._referenceFrameVolume = planetGO.GetAttachedOWRigidbody()._attachedRFVolume; cloakFieldController._referenceFrameVolume = OWRB._attachedRFVolume;
cloakFieldController._exclusionSector = null; cloakFieldController._exclusionSector = null;
var cloakSectorController = newCloak.AddComponent<CloakSectorController>(); var cloakSectorController = newCloak.AddComponent<CloakSectorController>();

View File

@ -38,13 +38,14 @@ namespace NewHorizons.Builder.Body
cubeSphere.transform.parent = sector?.transform ?? planetGO.transform; cubeSphere.transform.parent = sector?.transform ?? planetGO.transform;
cubeSphere.transform.rotation = Quaternion.Euler(90, 0, 0); cubeSphere.transform.rotation = Quaternion.Euler(90, 0, 0);
Mesh mesh = CubeSphere.Build(51, heightMap, module.MinHeight, module.MaxHeight, module.Stretch); Vector3 stretch = module.Stretch != null ? (Vector3)module.Stretch : Vector3.one;
Mesh mesh = CubeSphere.Build(51, heightMap, module.MinHeight, module.MaxHeight, stretch);
cubeSphere.AddComponent<MeshFilter>(); cubeSphere.AddComponent<MeshFilter>();
cubeSphere.GetComponent<MeshFilter>().mesh = mesh; cubeSphere.GetComponent<MeshFilter>().mesh = mesh;
// TODO: fix UVs so we can switch to the default shader // TODO: fix UVs so we can switch to the default shader
if (PlanetShader == null) PlanetShader = Main.ShaderBundle.LoadAsset<Shader>("Assets/Shaders/SphereTextureWrapper.shader"); if (PlanetShader == null) PlanetShader = Main.NHAssetBundle.LoadAsset<Shader>("Assets/Shaders/SphereTextureWrapper.shader");
//if (PlanetShader == null) PlanetShader = Shader.Find("Standard"); //if (PlanetShader == null) PlanetShader = Shader.Find("Standard");
var cubeSphereMR = cubeSphere.AddComponent<MeshRenderer>(); var cubeSphereMR = cubeSphere.AddComponent<MeshRenderer>();

View File

@ -12,8 +12,15 @@ namespace NewHorizons.Builder.Body
{ {
public static class ProcGenBuilder public static class ProcGenBuilder
{ {
private static Material quantumMaterial;
private static Material iceMaterial;
public static void Make(GameObject planetGO, Sector sector, ProcGenModule module) public static void Make(GameObject planetGO, Sector sector, ProcGenModule module)
{ {
if(quantumMaterial == null) quantumMaterial = SearchUtilities.FindResourceOfTypeAndName<Material>("Rock_QM_EyeRock_mat");
if(iceMaterial == null) iceMaterial = SearchUtilities.FindResourceOfTypeAndName<Material>("Rock_BH_IceSpike_mat");
GameObject icosphere = new GameObject("Icosphere"); GameObject icosphere = new GameObject("Icosphere");
icosphere.transform.parent = sector?.transform ?? planetGO.transform; icosphere.transform.parent = sector?.transform ?? planetGO.transform;
icosphere.transform.rotation = Quaternion.Euler(90, 0, 0); icosphere.transform.rotation = Quaternion.Euler(90, 0, 0);

View File

@ -49,10 +49,10 @@ namespace NewHorizons.Builder.Body
var ringMR = ringGO.AddComponent<MeshRenderer>(); var ringMR = ringGO.AddComponent<MeshRenderer>();
var texture = ringTexture; var texture = ringTexture;
if (RingShader == null) RingShader = Main.ShaderBundle.LoadAsset<Shader>("Assets/Shaders/Ring.shader"); if (RingShader == null) RingShader = Main.NHAssetBundle.LoadAsset<Shader>("Assets/Shaders/Ring.shader");
if (UnlitRingShader == null) UnlitRingShader = Main.ShaderBundle.LoadAsset<Shader>("Assets/Shaders/UnlitTransparent.shader"); if (UnlitRingShader == null) UnlitRingShader = Main.NHAssetBundle.LoadAsset<Shader>("Assets/Shaders/UnlitTransparent.shader");
if (RingShader1Pixel == null) RingShader1Pixel = Main.ShaderBundle.LoadAsset<Shader>("Assets/Shaders/Ring1Pixel.shader"); if (RingShader1Pixel == null) RingShader1Pixel = Main.NHAssetBundle.LoadAsset<Shader>("Assets/Shaders/Ring1Pixel.shader");
if (UnlitRingShader1Pixel == null) UnlitRingShader1Pixel = Main.ShaderBundle.LoadAsset<Shader>("Assets/Shaders/UnlitRing1Pixel.shader"); if (UnlitRingShader1Pixel == null) UnlitRingShader1Pixel = Main.NHAssetBundle.LoadAsset<Shader>("Assets/Shaders/UnlitRing1Pixel.shader");
var mat = new Material(ring.Unlit ? UnlitRingShader : RingShader); var mat = new Material(ring.Unlit ? UnlitRingShader : RingShader);
if (texture.width == 1) if (texture.width == 1)

View File

@ -22,7 +22,7 @@ namespace NewHorizons.Builder.Props
if (detail.assetBundle != null) if (detail.assetBundle != null)
{ {
var prefab = PropBuildManager.LoadPrefab(detail.assetBundle, detail.path, uniqueModName, mod); var prefab = AssetBundleUtilities.LoadPrefab(detail.assetBundle, detail.path, mod);
detailGO = MakeDetail(go, sector, prefab, detail.position, detail.rotation, detail.scale, detail.alignToNormal); detailGO = MakeDetail(go, sector, prefab, detail.position, detail.rotation, detail.scale, detail.alignToNormal);
} }
@ -31,7 +31,7 @@ namespace NewHorizons.Builder.Props
try try
{ {
var prefab = mod.ModHelper.Assets.Get3DObject(detail.objFilePath, detail.mtlFilePath); var prefab = mod.ModHelper.Assets.Get3DObject(detail.objFilePath, detail.mtlFilePath);
PropBuildManager.ReplaceShaders(prefab); AssetBundleUtilities.ReplaceShaders(prefab);
prefab.SetActive(false); prefab.SetActive(false);
detailGO = MakeDetail(go, sector, prefab, detail.position, detail.rotation, detail.scale, detail.alignToNormal); detailGO = MakeDetail(go, sector, prefab, detail.position, detail.rotation, detail.scale, detail.alignToNormal);
} }
@ -51,6 +51,26 @@ namespace NewHorizons.Builder.Props
else Logger.LogWarning($"Couldn't find {childPath}"); else Logger.LogWarning($"Couldn't find {childPath}");
} }
} }
if(detailGO != null && detail.removeComponents)
{
// Just swap all the children to a new game object
var newDetailGO = new GameObject(detailGO.name);
newDetailGO.transform.position = detailGO.transform.position;
newDetailGO.transform.parent = detailGO.transform.parent;
// Can't modify parents while looping through children bc idk
var children = new List<Transform>();
foreach(Transform child in detailGO.transform)
{
children.Add(child);
}
foreach(var child in children)
{
child.parent = newDetailGO.transform;
}
GameObject.Destroy(detailGO);
detailGO = newDetailGO;
}
} }
public static GameObject MakeDetail(GameObject go, Sector sector, string propToClone, MVector3 position, MVector3 rotation, float scale, bool alignWithNormal) public static GameObject MakeDetail(GameObject go, Sector sector, string propToClone, MVector3 position, MVector3 rotation, float scale, bool alignWithNormal)
@ -153,12 +173,11 @@ namespace NewHorizons.Builder.Props
prop.transform.position = position == null ? planetGO.transform.position : planetGO.transform.TransformPoint((Vector3)position); prop.transform.position = position == null ? planetGO.transform.position : planetGO.transform.TransformPoint((Vector3)position);
Quaternion rot = rotation == null ? Quaternion.identity : Quaternion.Euler((Vector3)rotation); Quaternion rot = rotation == null ? Quaternion.identity : Quaternion.Euler((Vector3)rotation);
prop.transform.rotation = planetGO.transform.TransformRotation(Quaternion.identity);
if (alignWithNormal) if (alignWithNormal)
{ {
// Apply the rotation after aligning it with normal // Apply the rotation after aligning it with normal
var up = planetGO.transform.InverseTransformPoint(prop.transform.position).normalized; var up = planetGO.transform.InverseTransformPoint(prop.transform.position).normalized;
prop.transform.rotation = Quaternion.FromToRotation(prop.transform.up, up) * prop.transform.rotation; prop.transform.rotation = Quaternion.FromToRotation(Vector3.up, up);
prop.transform.rotation *= rot; prop.transform.rotation *= rot;
} }
else else

View File

@ -13,6 +13,7 @@ using NewHorizons.Utility;
using OWML.Common; using OWML.Common;
using NewHorizons.Builder.ShipLog; using NewHorizons.Builder.ShipLog;
using NewHorizons.External.Configs; using NewHorizons.External.Configs;
using System.IO;
namespace NewHorizons.Builder.Props namespace NewHorizons.Builder.Props
{ {
@ -174,59 +175,5 @@ namespace NewHorizons.Builder.Props
} }
} }
} }
public static GameObject LoadPrefab(string assetBundle, string path, string uniqueModName, IModBehaviour mod)
{
string key = uniqueModName + "." + assetBundle;
AssetBundle bundle;
GameObject prefab;
try
{
if (Main.AssetBundles.ContainsKey(key)) bundle = Main.AssetBundles[key];
else
{
bundle = mod.ModHelper.Assets.LoadBundle(assetBundle);
Main.AssetBundles[key] = bundle;
}
}
catch (Exception e)
{
Logger.LogError($"Couldn't load AssetBundle {assetBundle} : {e.Message}");
return null;
}
try
{
prefab = bundle.LoadAsset<GameObject>(path);
prefab.SetActive(false);
}
catch (Exception e)
{
Logger.Log($"Couldn't load asset {path} from AssetBundle {assetBundle} : {e.Message}");
return null;
}
ReplaceShaders(prefab);
return prefab;
}
public static void ReplaceShaders(GameObject prefab)
{
foreach (var renderer in prefab.GetComponentsInChildren<Renderer>(true))
{
foreach (var material in renderer.sharedMaterials)
{
if (material == null)
{
continue;
}
var replacementShader = Shader.Find(material.shader.name);
if (replacementShader != null) material.shader = replacementShader;
}
}
}
} }
} }

View File

@ -46,7 +46,7 @@ namespace NewHorizons.Builder.Props
Random.InitState(propInfo.seed); Random.InitState(propInfo.seed);
GameObject prefab; GameObject prefab;
if (propInfo.assetBundle != null) prefab = PropBuildManager.LoadPrefab(propInfo.assetBundle, propInfo.path, uniqueModName, mod); if (propInfo.assetBundle != null) prefab = AssetBundleUtilities.LoadPrefab(propInfo.assetBundle, propInfo.path, mod);
else prefab = GameObject.Find(propInfo.path); else prefab = GameObject.Find(propInfo.path);
for (int i = 0; i < propInfo.count; i++) for (int i = 0; i < propInfo.count; i++)
{ {

View File

@ -8,46 +8,12 @@ using Object = System.Object;
namespace NewHorizons.Builder.StarSystem namespace NewHorizons.Builder.StarSystem
{ {
internal class SkyboxBuilder public class SkyboxBuilder
{ {
public static Material LoadMaterial(string assetBundle, string path, string uniqueModName, IModBehaviour mod)
{
string key = uniqueModName + "." + assetBundle;
AssetBundle bundle;
Material cubemap;
try
{
if (Main.AssetBundles.ContainsKey(key)) bundle = Main.AssetBundles[key];
else
{
bundle = mod.ModHelper.Assets.LoadBundle(assetBundle);
Main.AssetBundles[key] = bundle;
}
}
catch (Exception e)
{
Logger.LogError($"Couldn't load AssetBundle {assetBundle} : {e.Message}");
return null;
}
try
{
cubemap = bundle.LoadAsset<Material>(path);
}
catch (Exception e)
{
Logger.Log($"Couldn't load asset {path} from AssetBundle {assetBundle} : {e.Message}");
return null;
}
return cubemap;
}
public static void Make(StarSystemConfig.SkyboxConfig info, IModBehaviour mod) public static void Make(StarSystemConfig.SkyboxConfig info, IModBehaviour mod)
{ {
Logger.Log("Building Skybox"); Logger.Log("Building Skybox");
Material skyBoxMaterial = LoadMaterial(info.assetBundle, info.path, mod.ModHelper.Manifest.UniqueName, mod); var skyBoxMaterial = AssetBundleUtilities.Load<Material>(info.assetBundle, info.path, mod);
RenderSettings.skybox = skyBoxMaterial; RenderSettings.skybox = skyBoxMaterial;
DynamicGI.UpdateEnvironment(); DynamicGI.UpdateEnvironment();
Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() =>

View File

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace NewHorizons.Components
{
public class TimeLoopController : MonoBehaviour
{
private float _supernovaTime;
private bool _supernovaHappened;
public void Start()
{
GlobalMessenger.AddListener("TriggerSupernova", OnTriggerSupernova);
}
public void Update()
{
// Stock gives like 33 seconds after the sun collapses
// Gonna assume it takes like 7 seconds to collapse after the supernova trigger
if(_supernovaHappened && Time.time > _supernovaTime + 40f)
{
Locator.GetDeathManager().KillPlayer(DeathType.TimeLoop);
}
}
public void OnTriggerSupernova()
{
_supernovaHappened = true;
_supernovaTime = Time.time;
}
}
}

View File

@ -13,6 +13,7 @@ namespace NewHorizons.External.Configs
public bool startHere = false; public bool startHere = false;
public bool destroyStockPlanets = true; public bool destroyStockPlanets = true;
public string factRequiredForWarp; public string factRequiredForWarp;
public bool enableTimeLoop = true;
public NomaiCoordinates coords; public NomaiCoordinates coords;
public SkyboxConfig skybox; public SkyboxConfig skybox;

View File

@ -9,6 +9,6 @@ namespace NewHorizons.External
public string TextureMap { get; set; } public string TextureMap { get; set; }
public float MinHeight { get; set; } public float MinHeight { get; set; }
public float MaxHeight { get; set; } public float MaxHeight { get; set; }
public MVector3 Stretch { get; set; } = (MVector3)Vector3.one; public MVector3 Stretch { get; set; }
} }
} }

View File

@ -43,6 +43,7 @@ namespace NewHorizons.External
public float scale { get; set; } = 1f; public float scale { get; set; } = 1f;
public bool alignToNormal; public bool alignToNormal;
public string[] removeChildren; public string[] removeChildren;
public bool removeComponents;
} }
public class RaftInfo public class RaftInfo

View File

@ -318,7 +318,7 @@ namespace NewHorizons.Handlers
MarkerBuilder.Make(go, body.Config.Name, body.Config); MarkerBuilder.Make(go, body.Config.Name, body.Config);
} }
VolumesBuilder.Make(go, body.Config.Base.SurfaceSize, sphereOfInfluence, !body.Config.Base.IsSatellite); VolumesBuilder.Make(go, body.Config, sphereOfInfluence);
if (body.Config.FocalPoint != null) if (body.Config.FocalPoint != null)
{ {
@ -498,7 +498,7 @@ namespace NewHorizons.Handlers
// Has to go last probably // Has to go last probably
if (body.Config.Base.CloakRadius != 0f) if (body.Config.Base.CloakRadius != 0f)
{ {
CloakBuilder.Make(go, sector, body.Config.Base.CloakRadius); CloakBuilder.Make(go, sector, rb, body.Config.Base.CloakRadius);
} }
return go; return go;
@ -586,6 +586,7 @@ namespace NewHorizons.Handlers
{ {
foreach (var childChild in AstroObjectLocator.GetChildren(childAO)) foreach (var childChild in AstroObjectLocator.GetChildren(childAO))
{ {
if (childChild == null) continue;
var dPos = childChild.transform.position - child.transform.position; var dPos = childChild.transform.position - child.transform.position;
childChild.transform.position = go.transform.position + relativeMoonPositions[i] + dPos; childChild.transform.position = go.transform.position + relativeMoonPositions[i] + dPos;
} }

View File

@ -80,6 +80,7 @@ namespace NewHorizons.Handlers
else if (ao.GetAstroObjectName() == AstroObject.Name.CaveTwin || ao.GetAstroObjectName() == AstroObject.Name.TowerTwin) else if (ao.GetAstroObjectName() == AstroObject.Name.CaveTwin || ao.GetAstroObjectName() == AstroObject.Name.TowerTwin)
{ {
DisableBody(GameObject.Find("FocalBody"), delete); DisableBody(GameObject.Find("FocalBody"), delete);
DisableBody(GameObject.Find("SandFunnel_Body"), delete);
} }
else if (ao.GetAstroObjectName() == AstroObject.Name.MapSatellite) else if (ao.GetAstroObjectName() == AstroObject.Name.MapSatellite)
{ {
@ -132,6 +133,9 @@ namespace NewHorizons.Handlers
Logger.Log($"Destroying SunProxy {sunProxy.gameObject.name}"); Logger.Log($"Destroying SunProxy {sunProxy.gameObject.name}");
GameObject.Destroy(sunProxy.gameObject); GameObject.Destroy(sunProxy.gameObject);
} }
// Stop the sun from breaking stuff when the supernova gets triggered
GlobalMessenger.RemoveListener("TriggerSupernova", ao.GetComponent<SunController>().OnTriggerSupernova);
} }
// Just delete the children // Just delete the children

View File

@ -9,6 +9,7 @@ using NewHorizons.Builder.StarSystem;
using UnityEngine; using UnityEngine;
using Logger = NewHorizons.Utility.Logger; using Logger = NewHorizons.Utility.Logger;
using Object = UnityEngine.Object; using Object = UnityEngine.Object;
using NewHorizons.Components;
namespace NewHorizons.Handlers namespace NewHorizons.Handlers
{ {
@ -16,8 +17,6 @@ namespace NewHorizons.Handlers
{ {
public static void LoadSystem(NewHorizonsSystem system) public static void LoadSystem(NewHorizonsSystem system)
{ {
var skybox = GameObject.Find("Skybox/Starfield"); var skybox = GameObject.Find("Skybox/Starfield");
if (system.Config.skybox?.destroyStarField ?? false) if (system.Config.skybox?.destroyStarField ?? false)
@ -30,6 +29,11 @@ namespace NewHorizons.Handlers
SkyboxBuilder.Make(system.Config.skybox, system.Mod); SkyboxBuilder.Make(system.Config.skybox, system.Mod);
} }
if(system.Config.enableTimeLoop)
{
var timeLoopController = new GameObject("TimeLoopController");
timeLoopController.AddComponent<TimeLoopController>();
}
} }
} }
} }

View File

@ -31,19 +31,21 @@ namespace NewHorizons
{ {
public class Main : ModBehaviour public class Main : ModBehaviour
{ {
public static AssetBundle ShaderBundle; public static AssetBundle NHAssetBundle { get; private set; }
public static Main Instance { get; private set; } public static Main Instance { get; private set; }
// Settings // Settings
public static bool Debug; public static bool Debug { get; private set; }
private static bool _useCustomTitleScreen; private static bool _useCustomTitleScreen;
private static bool _wasConfigured = false; private static bool _wasConfigured = false;
private static string _defaultSystemOverride;
public static Dictionary<string, NewHorizonsSystem> SystemDict = new Dictionary<string, NewHorizonsSystem>(); public static Dictionary<string, NewHorizonsSystem> SystemDict = new Dictionary<string, NewHorizonsSystem>();
public static Dictionary<string, List<NewHorizonsBody>> BodyDict = new Dictionary<string, List<NewHorizonsBody>>(); public static Dictionary<string, List<NewHorizonsBody>> BodyDict = new Dictionary<string, List<NewHorizonsBody>>();
public static Dictionary<string, AssetBundle> AssetBundles = new Dictionary<string, AssetBundle>();
public static List<IModBehaviour> MountedAddons = new List<IModBehaviour>(); public static List<IModBehaviour> MountedAddons = new List<IModBehaviour>();
public static float SecondsLeftInLoop = -1;
public static bool IsSystemReady { get; private set; } public static bool IsSystemReady { get; private set; }
public static float FurthestOrbit { get; set; } = 50000f; public static float FurthestOrbit { get; set; } = 50000f;
@ -82,6 +84,8 @@ namespace NewHorizons
DebugReload.UpdateReloadButton(); DebugReload.UpdateReloadButton();
Logger.UpdateLogLevel(Debug ? Logger.LogType.Log : Logger.LogType.Error); Logger.UpdateLogLevel(Debug ? Logger.LogType.Log : Logger.LogType.Error);
_defaultSystemOverride = config.GetSettingsValue<string>("Default System Override");
var wasUsingCustomTitleScreen = _useCustomTitleScreen; var wasUsingCustomTitleScreen = _useCustomTitleScreen;
_useCustomTitleScreen = config.GetSettingsValue<bool>("Custom title screen"); _useCustomTitleScreen = config.GetSettingsValue<bool>("Custom title screen");
// Reload the title screen if this was updated on it // Reload the title screen if this was updated on it
@ -109,11 +113,7 @@ namespace NewHorizons
destroyStockPlanets = false destroyStockPlanets = false
} }
}; };
foreach (AssetBundle bundle in AssetBundles.Values)
{
bundle.Unload(true);
}
AssetBundles.Clear();
if (!resetTranslation) return; if (!resetTranslation) return;
TranslationHandler.ClearTables(); TranslationHandler.ClearTables();
TextTranslation.Get().SetLanguage(TextTranslation.Get().GetLanguage()); TextTranslation.Get().SetLanguage(TextTranslation.Get().GetLanguage());
@ -133,7 +133,7 @@ namespace NewHorizons
Instance = this; Instance = this;
GlobalMessenger<DeathType>.AddListener("PlayerDeath", OnDeath); GlobalMessenger<DeathType>.AddListener("PlayerDeath", OnDeath);
GlobalMessenger.AddListener("WakeUp", new Callback(OnWakeUp)); GlobalMessenger.AddListener("WakeUp", new Callback(OnWakeUp));
ShaderBundle = Main.Instance.ModHelper.Assets.LoadBundle("AssetBundle/shader"); NHAssetBundle = ModHelper.Assets.LoadBundle("AssetBundle/xen.newhorizons");
ResetConfigs(resetTranslation: false); ResetConfigs(resetTranslation: false);
@ -172,6 +172,7 @@ namespace NewHorizons
SearchUtilities.ClearCache(); SearchUtilities.ClearCache();
ImageUtilities.ClearCache(); ImageUtilities.ClearCache();
AudioUtilities.ClearCache(); AudioUtilities.ClearCache();
AssetBundleUtilities.ClearCache();
IsSystemReady = false; IsSystemReady = false;
} }
@ -179,6 +180,28 @@ namespace NewHorizons
{ {
Logger.Log($"Scene Loaded: {scene.name} {mode}"); Logger.Log($"Scene Loaded: {scene.name} {mode}");
// Set time loop stuff if its enabled and if we're warping to a new place
if (_isChangingStarSystem && (SystemDict[_currentStarSystem].Config.enableTimeLoop || _currentStarSystem == "SolarSystem") && SecondsLeftInLoop > 0f)
{
TimeLoop.SetSecondsRemaining(SecondsLeftInLoop);
// Prevent the OPC from firing
var launchController = GameObject.FindObjectOfType<OrbitalProbeLaunchController>();
if (launchController != null)
{
GlobalMessenger<int>.RemoveListener("StartOfTimeLoop", launchController.OnStartOfTimeLoop);
foreach (var fakeDebris in launchController._fakeDebrisBodies)
{
fakeDebris.gameObject.SetActive(false);
}
launchController.enabled = false;
}
var nomaiProbe = GameObject.Find("NomaiProbe_Body");
if (nomaiProbe != null) nomaiProbe.gameObject.SetActive(false);
}
// Reset this
SecondsLeftInLoop = -1;
_isChangingStarSystem = false; _isChangingStarSystem = false;
if (scene.name == "TitleScreen" && _useCustomTitleScreen) if (scene.name == "TitleScreen" && _useCustomTitleScreen)
@ -186,21 +209,21 @@ namespace NewHorizons
TitleSceneHandler.DisplayBodyOnTitleScreen(BodyDict.Values.ToList().SelectMany(x => x).ToList()); TitleSceneHandler.DisplayBodyOnTitleScreen(BodyDict.Values.ToList().SelectMany(x => x).ToList());
} }
if(scene.name == "EyeOfTheUniverse" && IsWarping) if (scene.name == "EyeOfTheUniverse" && IsWarping)
{ {
if(_ship != null) SceneManager.MoveGameObjectToScene(_ship, SceneManager.GetActiveScene()); if (_ship != null) SceneManager.MoveGameObjectToScene(_ship, SceneManager.GetActiveScene());
_ship.transform.position = new Vector3(50, 0, 0); _ship.transform.position = new Vector3(50, 0, 0);
_ship.SetActive(true); _ship.SetActive(true);
} }
if(scene.name == "SolarSystem") if (scene.name == "SolarSystem")
{ {
foreach(var body in GameObject.FindObjectsOfType<AstroObject>()) foreach (var body in GameObject.FindObjectsOfType<AstroObject>())
{ {
Logger.Log($"{body.name}, {body.transform.rotation}"); Logger.Log($"{body.name}, {body.transform.rotation}");
} }
if(_ship != null) if (_ship != null)
{ {
_ship = GameObject.Find("Ship_Body").InstantiateInactive(); _ship = GameObject.Find("Ship_Body").InstantiateInactive();
DontDestroyOnLoad(_ship); DontDestroyOnLoad(_ship);
@ -250,7 +273,16 @@ namespace NewHorizons
else else
{ {
// Reset back to original solar system after going to main menu. // Reset back to original solar system after going to main menu.
_currentStarSystem = _defaultStarSystem; // If the override is a valid system then we go there
if (SystemDict.Keys.Contains(_defaultSystemOverride))
{
_currentStarSystem = _defaultSystemOverride;
IsWarping = true; // always do this else sometimes the spawn gets messed up
}
else
{
_currentStarSystem = _defaultStarSystem;
}
} }
} }
@ -285,6 +317,12 @@ namespace NewHorizons
var relativePath = file.Replace(folder, ""); var relativePath = file.Replace(folder, "");
var starSystemConfig = mod.ModHelper.Storage.Load<StarSystemConfig>(relativePath); var starSystemConfig = mod.ModHelper.Storage.Load<StarSystemConfig>(relativePath);
if (starSystemConfig.startHere)
{
// We always want to allow mods to overwrite setting the main SolarSystem as default but not the other way around
if (name != "SolarSystem") SetDefaultSystem(name);
}
var system = new NewHorizonsSystem(name, starSystemConfig, mod); var system = new NewHorizonsSystem(name, starSystemConfig, mod);
SystemDict[name] = system; SystemDict[name] = system;
} }
@ -312,7 +350,7 @@ namespace NewHorizons
LoadTranslations(folder, mod); LoadTranslations(folder, mod);
} }
} }
catch(Exception ex) catch (Exception ex)
{ {
Logger.LogError($"{ex.Message}, {ex.StackTrace}"); Logger.LogError($"{ex.Message}, {ex.StackTrace}");
} }
@ -356,15 +394,13 @@ namespace NewHorizons
if (config.Base.CenterOfSolarSystem) config.Orbit.IsStatic = true; if (config.Base.CenterOfSolarSystem) config.Orbit.IsStatic = true;
if (!SystemDict.ContainsKey(config.StarSystem)) if (!SystemDict.ContainsKey(config.StarSystem))
{ {
// See if theres a star system config // Since we didn't load it earlier there shouldn't be a star system config
var starSystemConfig = mod.ModHelper.Storage.Load<StarSystemConfig>($"systems/{config.StarSystem}.json"); var starSystemConfig = mod.ModHelper.Storage.Load<StarSystemConfig>($"systems/{config.StarSystem}.json");
if (starSystemConfig == null) starSystemConfig = new StarSystemConfig(null); if (starSystemConfig == null) starSystemConfig = new StarSystemConfig(null);
else Logger.Log($"Loaded system config for {config.StarSystem}"); else Logger.LogWarning($"Loaded system config for {config.StarSystem}. Why wasn't this loaded earlier?");
var system = new NewHorizonsSystem(config.StarSystem, starSystemConfig, mod); var system = new NewHorizonsSystem(config.StarSystem, starSystemConfig, mod);
if (system.Config.startHere) SetDefaultSystem(system.Name);
SystemDict.Add(config.StarSystem, system); SystemDict.Add(config.StarSystem, system);
BodyDict.Add(config.StarSystem, new List<NewHorizonsBody>()); BodyDict.Add(config.StarSystem, new List<NewHorizonsBody>());
@ -396,8 +432,7 @@ namespace NewHorizons
OnChangeStarSystem?.Invoke(newStarSystem); OnChangeStarSystem?.Invoke(newStarSystem);
Logger.Log($"Warping to {newStarSystem}"); Logger.Log($"Warping to {newStarSystem}");
if(warp && _shipWarpController) _shipWarpController.WarpOut(); if (warp && _shipWarpController) _shipWarpController.WarpOut();
_currentStarSystem = newStarSystem;
_isChangingStarSystem = true; _isChangingStarSystem = true;
IsWarping = warp; IsWarping = warp;
WearingSuit = PlayerState.IsWearingSuit(); WearingSuit = PlayerState.IsWearingSuit();
@ -405,15 +440,24 @@ namespace NewHorizons
// We kill them so they don't move as much // We kill them so they don't move as much
Locator.GetDeathManager().KillPlayer(DeathType.Meditation); Locator.GetDeathManager().KillPlayer(DeathType.Meditation);
if(newStarSystem == "EyeOfTheUniverse") OWScene sceneToLoad;
if (newStarSystem == "EyeOfTheUniverse")
{ {
PlayerData.SaveWarpedToTheEye(60); PlayerData.SaveWarpedToTheEye(TimeLoop.GetSecondsRemaining());
LoadManager.LoadSceneAsync(OWScene.EyeOfTheUniverse, true, LoadManager.FadeType.ToBlack, 0.1f, true); sceneToLoad = OWScene.EyeOfTheUniverse;
} }
else else
{ {
LoadManager.LoadSceneAsync(OWScene.SolarSystem, true, LoadManager.FadeType.ToBlack, 0.1f, true); if (SystemDict[_currentStarSystem].Config.enableTimeLoop) SecondsLeftInLoop = TimeLoop.GetSecondsRemaining();
else SecondsLeftInLoop = -1;
sceneToLoad = OWScene.SolarSystem;
} }
_currentStarSystem = newStarSystem;
LoadManager.LoadSceneAsync(sceneToLoad, true, LoadManager.FadeType.ToBlack, 0.1f, true);
} }
void OnDeath(DeathType _) void OnDeath(DeathType _)
@ -421,7 +465,17 @@ namespace NewHorizons
// We reset the solar system on death (unless we just killed the player) // We reset the solar system on death (unless we just killed the player)
if (!_isChangingStarSystem) if (!_isChangingStarSystem)
{ {
_currentStarSystem = _defaultStarSystem; // If the override is a valid system then we go there
if (SystemDict.Keys.Contains(_defaultSystemOverride))
{
_currentStarSystem = _defaultSystemOverride;
IsWarping = true; // always do this else sometimes the spawn gets messed up
}
else
{
_currentStarSystem = _defaultStarSystem;
}
IsWarping = false; IsWarping = false;
} }
} }

View File

@ -0,0 +1,91 @@
using OWML.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace NewHorizons.Utility
{
public static class AssetBundleUtilities
{
public static Dictionary<string, AssetBundle> AssetBundles = new Dictionary<string, AssetBundle>();
public static void ClearCache()
{
foreach (var pair in AssetBundles)
{
if (pair.Value == null) Logger.LogError($"The asset bundle for {pair.Key} was null when trying to unload");
else pair.Value.Unload(true);
}
AssetBundles.Clear();
}
public static T Load<T>(string assetBundleRelativeDir, string pathInBundle, IModBehaviour mod) where T : UnityEngine.Object
{
string key = Path.GetFileName(assetBundleRelativeDir);
T obj;
try
{
AssetBundle bundle;
if (AssetBundles.ContainsKey(key))
{
bundle = AssetBundles[key];
}
else
{
var completePath = mod.ModHelper.Manifest.ModFolderPath + assetBundleRelativeDir;
bundle = AssetBundle.LoadFromFile(completePath);
if (bundle == null)
{
Logger.LogError($"Couldn't load AssetBundle at [{completePath}] for [{mod.ModHelper.Manifest.Name}]");
return null;
}
AssetBundles[key] = bundle;
}
obj = bundle.LoadAsset<T>(pathInBundle);
}
catch (Exception e)
{
Logger.LogError($"Couldn't load asset {pathInBundle} from AssetBundle {assetBundleRelativeDir} : {e.Message}");
return null;
}
return obj;
}
public static GameObject LoadPrefab(string assetBundleRelativeDir, string pathInBundle, IModBehaviour mod)
{
var prefab = Load<GameObject>(assetBundleRelativeDir, pathInBundle, mod);
prefab.SetActive(false);
ReplaceShaders(prefab);
return prefab;
}
public static void ReplaceShaders(GameObject prefab)
{
foreach (var renderer in prefab.GetComponentsInChildren<Renderer>(true))
{
foreach (var material in renderer.sharedMaterials)
{
if (material == null)
{
continue;
}
var replacementShader = Shader.Find(material.shader.name);
if (replacementShader != null) material.shader = replacementShader;
}
}
}
}
}

View File

@ -111,9 +111,6 @@ namespace NewHorizons.Utility
otherChildren.Add(GameObject.Find("FakeCannonBarrel_Body (1)")); otherChildren.Add(GameObject.Find("FakeCannonBarrel_Body (1)"));
otherChildren.Add(GameObject.Find("Debris_Body (1)")); otherChildren.Add(GameObject.Find("Debris_Body (1)"));
break; break;
case AstroObject.Name.SunStation:
otherChildren.Add(GameObject.Find("SS_Debris_Body"));
break;
case AstroObject.Name.GiantsDeep: case AstroObject.Name.GiantsDeep:
otherChildren.Add(GameObject.Find("BrambleIsland_Body")); otherChildren.Add(GameObject.Find("BrambleIsland_Body"));
otherChildren.Add(GameObject.Find("GabbroIsland_Body")); otherChildren.Add(GameObject.Find("GabbroIsland_Body"));
@ -134,6 +131,10 @@ namespace NewHorizons.Utility
otherChildren.Add(GameObject.Find("BackRaft_Body")); otherChildren.Add(GameObject.Find("BackRaft_Body"));
otherChildren.Add(GameObject.Find("SealRaft_Body")); otherChildren.Add(GameObject.Find("SealRaft_Body"));
break; break;
// For some dumb reason the sun station doesn't use AstroObject.Name.SunStation
case AstroObject.Name.CustomString:
if(primary._customName.Equals("Sun Station")) otherChildren.Add(GameObject.Find("SS_Debris_Body"));
break;
default: default:
break; break;
} }

View File

@ -50,6 +50,8 @@ namespace NewHorizons.Utility
GameObject.Find("/PauseMenu/PauseMenuManagers").GetComponent<PauseMenuManager>().OnSkipToNextTimeLoop(); GameObject.Find("/PauseMenu/PauseMenuManagers").GetComponent<PauseMenuManager>().OnSkipToNextTimeLoop();
Main.Instance.ChangeCurrentStarSystem(Main.Instance.CurrentStarSystem); Main.Instance.ChangeCurrentStarSystem(Main.Instance.CurrentStarSystem);
Main.SecondsLeftInLoop = -1f;
} }
} }
} }

View File

@ -2,6 +2,7 @@
"enabled": true, "enabled": true,
"settings": { "settings": {
"Debug": false, "Debug": false,
"Custom title screen": true "Custom title screen": true,
"Default System Override": ""
} }
} }

View File

@ -3,7 +3,7 @@
"author": "xen, Bwc9876, & Book", "author": "xen, Bwc9876, & Book",
"name": "New Horizons", "name": "New Horizons",
"uniqueName": "xen.NewHorizons", "uniqueName": "xen.NewHorizons",
"version": "0.15.2", "version": "0.16.0",
"owmlVersion": "2.1.0", "owmlVersion": "2.1.0",
"conflicts": [ "Raicuparta.QuantumSpaceBuddies", "Vesper.AutoResume", "PacificEngine.OW_Randomizer" ], "conflicts": [ "Raicuparta.QuantumSpaceBuddies", "Vesper.AutoResume", "PacificEngine.OW_Randomizer" ],
"pathsToPreserve": [ "planets", "systems", "translations" ] "pathsToPreserve": [ "planets", "systems", "translations" ]

View File

@ -666,6 +666,11 @@
"items": { "items": {
"type": "string" "type": "string"
} }
},
"removeComponents": {
"type": "boolean",
"description": "Do we reset all the components on this object? Useful for certain props that have dialogue components attached to them.",
"default": false
} }
} }
} }

View File

@ -20,6 +20,11 @@
"type": "bool", "type": "bool",
"description": "Do you want a clean slate for this star system? Or will it be a modified version of the original." "description": "Do you want a clean slate for this star system? Or will it be a modified version of the original."
}, },
"enableTimeLoop": {
"type": "bool",
"description": "Should the player be sent back in time after 22 minutes?",
"default": true
},
"skybox": { "skybox": {
"type": "object", "type": "object",
"description": "Options for the skybox of your system", "description": "Options for the skybox of your system",

112
NewHorizons/text_schema.xsd Normal file
View File

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Nomai Text -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<!-- Nomai Text Info -->
<xs:element name="NomaiObject">
<xs:complexType>
<xs:sequence>
<xs:element name="TextBlock" type="TextBlock" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>
The different text blocks of this object
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="ShipLogConditions" type="ShipLogConditions" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>
The conditions for unlocking ship log facts
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="LocationA"></xs:complexType>
<xs:complexType name="LocationB"></xs:complexType>
<!-- Text Block Info -->
<xs:complexType name="TextBlock">
<xs:sequence>
<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" maxOccurs="1">
<xs:annotation>
<xs:documentation>
The id of the parent text block
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="LocationA" type="LocationA" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="LocationB" type="LocationB" minOccurs="0" maxOccurs="1" >
<xs:annotation>
<xs:documentation>
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="Text" type="xs:string">
<xs:annotation>
<xs:documentation>
The text to show for this option
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<!-- Ship Log Conditions Info -->
<xs:complexType name="ShipLogConditions">
<xs:sequence>
<xs:element name="LocationA" type="LocationA" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="LocationB" type="LocationB" minOccurs="0" maxOccurs="1" >
<xs:annotation>
<xs:documentation>
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="RevealFacts" type="RevealFacts" minOccurs="0">
<xs:annotation>
<xs:documentation>
Facts to reveal when the player goes through this dialogue node
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<!-- Reveal Facts Info -->
<xs:complexType name="RevealFacts">
<xs:sequence>
<xs:element name="FactID" type="xs:string" minOccurs="1" maxOccurs="1">
<xs:annotation>
<xs:documentation>
The ID of a fact to reveal
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="Condition" type="xs:string" minOccurs="1" maxOccurs="1">
<xs:annotation>
<xs:documentation>
The text block ids (separated by commas) that need to be read to reveal that fact
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>