Added description to all modules except translation

This commit is contained in:
Ben C 2022-05-21 13:28:04 -04:00
parent f5e02d3035
commit 0a061ecbcc
34 changed files with 1668 additions and 408 deletions

View File

@ -76,11 +76,11 @@ namespace NewHorizons.Builder.Atmosphere
fluidCLFV._density = 1.2f; fluidCLFV._density = 1.2f;
var fluidType = FluidVolume.Type.CLOUD; var fluidType = FluidVolume.Type.CLOUD;
if (!string.IsNullOrEmpty(atmo.Clouds.FluidType)) if (atmo.Clouds.FluidType != null)
{ {
try try
{ {
fluidType = (FluidVolume.Type)Enum.Parse(typeof(FluidVolume.Type), atmo.Clouds.FluidType.ToUpper()); fluidType = (FluidVolume.Type)Enum.Parse(typeof(FluidVolume.Type), Enum.GetName(typeof(CloudFluidType), atmo.Clouds.FluidType).ToUpper());
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -35,7 +35,7 @@ namespace NewHorizons.Builder.Body
SurfaceGravity = 1, SurfaceGravity = 1,
SurfaceSize = size, SurfaceSize = size,
HasReferenceFrame = false, HasReferenceFrame = false,
GravityFallOff = "inverseSquared" GravityFallOff = GravityFallOff.InverseSquared
}; };
config.Orbit = new OrbitModule() config.Orbit = new OrbitModule()

View File

@ -1,4 +1,5 @@
using NewHorizons.Components; using System.Runtime.Serialization;
using NewHorizons.Components;
using NewHorizons.Utility; using NewHorizons.Utility;
using UnityEngine; using UnityEngine;
using Logger = NewHorizons.Utility.Logger; using Logger = NewHorizons.Utility.Logger;
@ -8,26 +9,16 @@ namespace NewHorizons.Builder.Body
{ {
public static class FunnelBuilder public static class FunnelBuilder
{ {
private enum FunnelType
{
SAND,
WATER,
LAVA,
STAR
}
public static void Make(GameObject planetGO, ConstantForceDetector detector, OWRigidbody rigidbody, FunnelModule module) public static void Make(GameObject planetGO, ConstantForceDetector detector, OWRigidbody rigidbody, FunnelModule module)
{ {
var funnelType = FunnelType.SAND; var funnelType = module.Type;
if (module.Type.ToUpper().Equals("WATER")) funnelType = FunnelType.WATER;
else if (module.Type.ToUpper().Equals("LAVA")) funnelType = FunnelType.LAVA;
else if (module.Type.ToUpper().Equals("STAR")) funnelType = FunnelType.STAR;
var funnelGO = new GameObject($"{planetGO.name.Replace("_Body", "")}Funnel_Body"); var funnelGO = new GameObject($"{planetGO.name.Replace("_Body", "")}Funnel_Body");
funnelGO.SetActive(false); funnelGO.SetActive(false);
funnelGO.transform.parent = planetGO.transform; funnelGO.transform.parent = planetGO.transform;
var owrb = funnelGO.AddComponent<OWRigidbody>(); funnelGO.AddComponent<OWRigidbody>();
var matchMotion = funnelGO.AddComponent<MatchInitialMotion>(); var matchMotion = funnelGO.AddComponent<MatchInitialMotion>();
matchMotion.SetBodyToMatch(rigidbody); matchMotion.SetBodyToMatch(rigidbody);
@ -61,10 +52,10 @@ namespace NewHorizons.Builder.Body
var fluidVolume = sfv.gameObject; var fluidVolume = sfv.gameObject;
switch (funnelType) switch (funnelType)
{ {
case FunnelType.SAND: case FunnelType.Sand:
sfv._fluidType = FluidVolume.Type.SAND; sfv._fluidType = FluidVolume.Type.SAND;
break; break;
case FunnelType.WATER: case FunnelType.Water:
sfv._fluidType = FluidVolume.Type.WATER; sfv._fluidType = FluidVolume.Type.WATER;
GameObject.Destroy(geoGO.transform.Find("Effects_HT_SandColumn/SandColumn_Interior").gameObject); GameObject.Destroy(geoGO.transform.Find("Effects_HT_SandColumn/SandColumn_Interior").gameObject);
@ -111,8 +102,8 @@ namespace NewHorizons.Builder.Body
*/ */
break; break;
case FunnelType.LAVA: case FunnelType.Lava:
case FunnelType.STAR: case FunnelType.Star:
sfv._fluidType = FluidVolume.Type.PLASMA; sfv._fluidType = FluidVolume.Type.PLASMA;
GameObject.Destroy(geoGO.transform.Find("Effects_HT_SandColumn/SandColumn_Interior").gameObject); GameObject.Destroy(geoGO.transform.Find("Effects_HT_SandColumn/SandColumn_Interior").gameObject);
@ -129,12 +120,12 @@ namespace NewHorizons.Builder.Body
proxyGO.GetComponentInChildren<MeshRenderer>().material = lavaMaterial; proxyGO.GetComponentInChildren<MeshRenderer>().material = lavaMaterial;
geoGO.GetComponentInChildren<MeshRenderer>().material = lavaMaterial; geoGO.GetComponentInChildren<MeshRenderer>().material = lavaMaterial;
if (funnelType == FunnelType.LAVA) if (funnelType == FunnelType.Lava)
{ {
lavaMaterial.SetFloat("_HeightScale", 0); lavaMaterial.SetFloat("_HeightScale", 0);
AddDestructionVolumes(fluidVolume, DeathType.Lava); AddDestructionVolumes(fluidVolume, DeathType.Lava);
} }
else if (funnelType == FunnelType.STAR) else if (funnelType == FunnelType.Star)
{ {
lavaMaterial.renderQueue = 2999; lavaMaterial.renderQueue = 2999;
lavaMaterial.SetFloat("_HeightScale", 100000); lavaMaterial.SetFloat("_HeightScale", 100000);

View File

@ -89,7 +89,7 @@ namespace NewHorizons.Builder.Body
// Could improve this to actually use the proper renders and materials // Could improve this to actually use the proper renders and materials
if (body.Config.Singularity != null) if (body.Config.Singularity != null)
{ {
if (body.Config.Singularity.Type == "BlackHole") if (body.Config.Singularity.Type == SingularityModule.SingularityType.BlackHole)
{ {
MakeBlackHole(newProxy, body.Config.Singularity.Size); MakeBlackHole(newProxy, body.Config.Singularity.Size);
} }

View File

@ -4,6 +4,7 @@ using NewHorizons.Utility;
using OWML.Common; using OWML.Common;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using NewHorizons.External.Modules;
using UnityEngine; using UnityEngine;
using Logger = NewHorizons.Utility.Logger; using Logger = NewHorizons.Utility.Logger;
using NewHorizons.External.Modules.VariableSize; using NewHorizons.External.Modules.VariableSize;
@ -46,11 +47,11 @@ namespace NewHorizons.Builder.Body
var sfv = ringVolume.AddComponent<SimpleFluidVolume>(); var sfv = ringVolume.AddComponent<SimpleFluidVolume>();
var fluidType = FluidVolume.Type.NONE; var fluidType = FluidVolume.Type.NONE;
if (!string.IsNullOrEmpty(ring.FluidType)) if (ring.FluidType != null)
{ {
try try
{ {
fluidType = (FluidVolume.Type)Enum.Parse(typeof(FluidVolume.Type), ring.FluidType.ToUpper()); fluidType = (FluidVolume.Type)Enum.Parse(typeof(FluidVolume.Type), Enum.GetName(typeof(CloudFluidType), ring.FluidType).ToUpper());
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -2,17 +2,13 @@
using NewHorizons.External.Configs; using NewHorizons.External.Configs;
using NewHorizons.Utility; using NewHorizons.Utility;
using System; using System;
using NewHorizons.External.Modules.VariableSize;
using UnityEngine; using UnityEngine;
using Logger = NewHorizons.Utility.Logger; using Logger = NewHorizons.Utility.Logger;
namespace NewHorizons.Builder.Body namespace NewHorizons.Builder.Body
{ {
public static class SingularityBuilder public static class SingularityBuilder
{ {
enum Polarity
{
BlackHole,
WhiteHole
}
private static Shader blackHoleShader = null; private static Shader blackHoleShader = null;
private static Shader whiteHoleShader = null; private static Shader whiteHoleShader = null;
@ -22,11 +18,7 @@ namespace NewHorizons.Builder.Body
var size = config.Singularity.Size; var size = config.Singularity.Size;
var pairedSingularity = config.Singularity.PairedSingularity; var pairedSingularity = config.Singularity.PairedSingularity;
var polarity = Polarity.BlackHole; var polarity = config.Singularity.Type;
if (config.Singularity.Type != null && config.Singularity.Type.ToUpper().Equals("WHITEHOLE"))
{
polarity = Polarity.WhiteHole;
}
bool isWormHole = config.Singularity?.TargetStarSystem != null; bool isWormHole = config.Singularity?.TargetStarSystem != null;
bool hasHazardVolume = !isWormHole && (pairedSingularity == null); bool hasHazardVolume = !isWormHole && (pairedSingularity == null);
@ -38,10 +30,10 @@ namespace NewHorizons.Builder.Body
GameObject newSingularity = null; GameObject newSingularity = null;
switch (polarity) switch (polarity)
{ {
case Polarity.BlackHole: case SingularityModule.SingularityType.BlackHole:
newSingularity = MakeBlackHole(go, sector, localPosition, size, hasHazardVolume, config.Singularity.TargetStarSystem); newSingularity = MakeBlackHole(go, sector, localPosition, size, hasHazardVolume, config.Singularity.TargetStarSystem);
break; break;
case Polarity.WhiteHole: case SingularityModule.SingularityType.WhiteHole:
newSingularity = MakeWhiteHole(go, sector, OWRB, localPosition, size, makeZeroGVolume); newSingularity = MakeWhiteHole(go, sector, OWRB, localPosition, size, makeZeroGVolume);
break; break;
} }
@ -54,10 +46,10 @@ namespace NewHorizons.Builder.Body
{ {
switch (polarity) switch (polarity)
{ {
case Polarity.BlackHole: case SingularityModule.SingularityType.BlackHole:
PairSingularities(newSingularity, pairedSingularityAO.gameObject); PairSingularities(newSingularity, pairedSingularityAO.gameObject);
break; break;
case Polarity.WhiteHole: case SingularityModule.SingularityType.WhiteHole:
PairSingularities(pairedSingularityAO.gameObject, newSingularity); PairSingularities(pairedSingularityAO.gameObject, newSingularity);
break; break;
} }

View File

@ -1,4 +1,5 @@
using NewHorizons.External.Configs; using NewHorizons.External.Configs;
using NewHorizons.External.Modules;
using UnityEngine; using UnityEngine;
using Logger = NewHorizons.Utility.Logger; using Logger = NewHorizons.Utility.Logger;
namespace NewHorizons.Builder.General namespace NewHorizons.Builder.General
@ -7,7 +8,7 @@ namespace NewHorizons.Builder.General
{ {
public static GravityVolume Make(GameObject planetGO, AstroObject ao, PlanetConfig config) public static GravityVolume Make(GameObject planetGO, AstroObject ao, PlanetConfig config)
{ {
var exponent = config.Base.GravityFallOff.Equals("linear") ? 1f : 2f; var exponent = config.Base.GravityFallOff == GravityFallOff.Linear ? 1f : 2f;
var GM = config.Base.SurfaceGravity * Mathf.Pow(config.Base.SurfaceSize, exponent); var GM = config.Base.SurfaceGravity * Mathf.Pow(config.Base.SurfaceSize, exponent);
// Gravity limit will be when the acceleration it would cause is less than 0.1 m/s^2 // Gravity limit will be when the acceleration it would cause is less than 0.1 m/s^2
@ -37,10 +38,8 @@ namespace NewHorizons.Builder.General
var gravityVolume = gravityGO.AddComponent<GravityVolume>(); var gravityVolume = gravityGO.AddComponent<GravityVolume>();
gravityVolume._cutoffAcceleration = 0.1f; gravityVolume._cutoffAcceleration = 0.1f;
GravityVolume.FalloffType falloff = GravityVolume.FalloffType.linear; var falloff = config.Base.GravityFallOff == GravityFallOff.Linear? GravityVolume.FalloffType.linear : GravityVolume.FalloffType.inverseSquared;
if (config.Base.GravityFallOff.ToUpper().Equals("LINEAR")) falloff = GravityVolume.FalloffType.linear;
else if (config.Base.GravityFallOff.ToUpper().Equals("INVERSESQUARED")) falloff = GravityVolume.FalloffType.inverseSquared;
else Logger.LogError($"Couldn't set gravity type {config.Base.GravityFallOff}. Must be either \"linear\" or \"inverseSquared\". Defaulting to linear.");
gravityVolume._falloffType = falloff; gravityVolume._falloffType = falloff;
// Radius where your feet turn to the planet // Radius where your feet turn to the planet

View File

@ -71,7 +71,7 @@ namespace NewHorizons.Builder.Orbital
{ {
var surfaceAcceleration = config.Base.SurfaceGravity; var surfaceAcceleration = config.Base.SurfaceGravity;
var upperSurfaceRadius = config.Base.SurfaceSize; var upperSurfaceRadius = config.Base.SurfaceSize;
int falloffExponent = config.Base.GravityFallOff.ToUpper().Equals("LINEAR") ? 1 : 2; int falloffExponent = config.Base.GravityFallOff == GravityFallOff.Linear ? 1 : 2;
return surfaceAcceleration * Mathf.Pow(upperSurfaceRadius, falloffExponent) / GravityVolume.GRAVITATIONAL_CONSTANT; return surfaceAcceleration * Mathf.Pow(upperSurfaceRadius, falloffExponent) / GravityVolume.GRAVITATIONAL_CONSTANT;
} }

View File

@ -73,184 +73,191 @@ namespace NewHorizons.Builder.Props
var xmlPath = System.IO.File.ReadAllText(mod.ModHelper.Manifest.ModFolderPath + info.xmlFile); var xmlPath = System.IO.File.ReadAllText(mod.ModHelper.Manifest.ModFolderPath + info.xmlFile);
if (info.type == "wall") switch (info.type)
{ {
var nomaiWallTextObj = MakeWallText(planetGO, sector, info, xmlPath).gameObject; case PropModule.NomaiTextInfo.NomaiTextType.Wall:
nomaiWallTextObj.transform.parent = sector?.transform ?? planetGO.transform;
nomaiWallTextObj.transform.position = planetGO.transform.TransformPoint(info.position);
if (info.normal != null)
{ {
// In global coordinates (normal was in local coordinates) var nomaiWallTextObj = MakeWallText(planetGO, sector, info, xmlPath).gameObject;
var up = (nomaiWallTextObj.transform.position - planetGO.transform.position).normalized;
var forward = planetGO.transform.TransformDirection(info.normal).normalized;
nomaiWallTextObj.transform.up = up; nomaiWallTextObj.transform.parent = sector?.transform ?? planetGO.transform;
nomaiWallTextObj.transform.forward = forward; nomaiWallTextObj.transform.position = planetGO.transform.TransformPoint(info.position);
} if (info.normal != null)
if (info.rotation != null)
{
nomaiWallTextObj.transform.rotation = planetGO.transform.TransformRotation(Quaternion.Euler(info.rotation));
}
nomaiWallTextObj.SetActive(true);
}
else if (info.type == "scroll")
{
var customScroll = _scrollPrefab.InstantiateInactive();
var nomaiWallText = MakeWallText(planetGO, sector, info, xmlPath);
nomaiWallText.transform.parent = customScroll.transform;
nomaiWallText.transform.localPosition = Vector3.zero;
nomaiWallText.transform.localRotation = Quaternion.identity;
nomaiWallText._showTextOnStart = false;
// Don't want to be able to translate until its in a socket
nomaiWallText.GetComponent<Collider>().enabled = false;
nomaiWallText.gameObject.SetActive(true);
var scrollItem = customScroll.GetComponent<ScrollItem>();
// Idk why this thing is always around
GameObject.Destroy(customScroll.transform.Find("Arc_BH_City_Forum_2").gameObject);
// This variable is the bane of my existence i dont get it
scrollItem._nomaiWallText = nomaiWallText;
// Because the scroll was already awake it does weird shit in Awake and makes some of the entries in this array be null
scrollItem._colliders = new OWCollider[] { scrollItem.GetComponent<OWCollider>() };
// Else when you put them down you can't pick them back up
customScroll.GetComponent<OWCollider>()._physicsRemoved = false;
// Place scroll
customScroll.transform.parent = sector?.transform ?? planetGO.transform;
customScroll.transform.position = planetGO.transform.TransformPoint(info.position ?? Vector3.zero);
var up = planetGO.transform.InverseTransformPoint(customScroll.transform.position).normalized;
customScroll.transform.rotation = Quaternion.FromToRotation(customScroll.transform.up, up) * customScroll.transform.rotation;
customScroll.SetActive(true);
// Enable the collider and renderer
Main.Instance.ModHelper.Events.Unity.RunWhen(
() => Main.IsSystemReady,
() =>
{ {
Logger.Log("Fixing scroll!"); // In global coordinates (normal was in local coordinates)
scrollItem._nomaiWallText = nomaiWallText; var up = (nomaiWallTextObj.transform.position - planetGO.transform.position).normalized;
scrollItem.SetSector(sector); var forward = planetGO.transform.TransformDirection(info.normal).normalized;
customScroll.transform.Find("Props_NOM_Scroll/Props_NOM_Scroll_Geo").GetComponent<MeshRenderer>().enabled = true;
customScroll.transform.Find("Props_NOM_Scroll/Props_NOM_Scroll_Collider").gameObject.SetActive(true); nomaiWallTextObj.transform.up = up;
nomaiWallText.gameObject.GetComponent<Collider>().enabled = false; nomaiWallTextObj.transform.forward = forward;
customScroll.GetComponent<CapsuleCollider>().enabled = true; }
if (info.rotation != null)
{
nomaiWallTextObj.transform.rotation = planetGO.transform.TransformRotation(Quaternion.Euler(info.rotation));
} }
);
}
else if (info.type == "computer")
{
var computerObject = _computerPrefab.InstantiateInactive();
computerObject.transform.parent = sector?.transform ?? planetGO.transform; nomaiWallTextObj.SetActive(true);
computerObject.transform.position = planetGO.transform.TransformPoint(info?.position ?? Vector3.zero); break;
var up = computerObject.transform.position - planetGO.transform.position;
if (info.normal != null) up = planetGO.transform.TransformDirection(info.normal);
computerObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, up) * computerObject.transform.rotation;
var computer = computerObject.GetComponent<NomaiComputer>();
computer.SetSector(sector);
computer._dictNomaiTextData = MakeNomaiTextDict(xmlPath);
computer._nomaiTextAsset = new TextAsset(xmlPath);
AddTranslation(xmlPath);
// Make sure the computer model is loaded
OWAssetHandler.LoadObject(computerObject);
sector.OnOccupantEnterSector.AddListener((x) => OWAssetHandler.LoadObject(computerObject));
computerObject.SetActive(true);
}
else if (info.type == "cairn")
{
var cairnObject = _cairnPrefab.InstantiateInactive();
cairnObject.transform.parent = sector?.transform ?? planetGO.transform;
cairnObject.transform.position = planetGO.transform.TransformPoint(info?.position ?? Vector3.zero);
if (info.rotation != null)
{
cairnObject.transform.rotation = planetGO.transform.TransformRotation(Quaternion.Euler(info.rotation));
} }
else case PropModule.NomaiTextInfo.NomaiTextType.Scroll:
{ {
// By default align it to normal var customScroll = _scrollPrefab.InstantiateInactive();
var up = (cairnObject.transform.position - planetGO.transform.position).normalized;
cairnObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, up) * cairnObject.transform.rotation; var nomaiWallText = MakeWallText(planetGO, sector, info, xmlPath);
nomaiWallText.transform.parent = customScroll.transform;
nomaiWallText.transform.localPosition = Vector3.zero;
nomaiWallText.transform.localRotation = Quaternion.identity;
nomaiWallText._showTextOnStart = false;
// Don't want to be able to translate until its in a socket
nomaiWallText.GetComponent<Collider>().enabled = false;
nomaiWallText.gameObject.SetActive(true);
var scrollItem = customScroll.GetComponent<ScrollItem>();
// Idk why this thing is always around
GameObject.Destroy(customScroll.transform.Find("Arc_BH_City_Forum_2").gameObject);
// This variable is the bane of my existence i dont get it
scrollItem._nomaiWallText = nomaiWallText;
// Because the scroll was already awake it does weird shit in Awake and makes some of the entries in this array be null
scrollItem._colliders = new OWCollider[] { scrollItem.GetComponent<OWCollider>() };
// Else when you put them down you can't pick them back up
customScroll.GetComponent<OWCollider>()._physicsRemoved = false;
// Place scroll
customScroll.transform.parent = sector?.transform ?? planetGO.transform;
customScroll.transform.position = planetGO.transform.TransformPoint(info.position ?? Vector3.zero);
var up = planetGO.transform.InverseTransformPoint(customScroll.transform.position).normalized;
customScroll.transform.rotation = Quaternion.FromToRotation(customScroll.transform.up, up) * customScroll.transform.rotation;
customScroll.SetActive(true);
// Enable the collider and renderer
Main.Instance.ModHelper.Events.Unity.RunWhen(
() => Main.IsSystemReady,
() =>
{
Logger.Log("Fixing scroll!");
scrollItem._nomaiWallText = nomaiWallText;
scrollItem.SetSector(sector);
customScroll.transform.Find("Props_NOM_Scroll/Props_NOM_Scroll_Geo").GetComponent<MeshRenderer>().enabled = true;
customScroll.transform.Find("Props_NOM_Scroll/Props_NOM_Scroll_Collider").gameObject.SetActive(true);
nomaiWallText.gameObject.GetComponent<Collider>().enabled = false;
customScroll.GetComponent<CapsuleCollider>().enabled = true;
}
);
break;
} }
case PropModule.NomaiTextInfo.NomaiTextType.Computer:
// Idk do we have to set it active before finding things?
cairnObject.SetActive(true);
// Make it do the thing when it finishes being knocked over
foreach (var rock in cairnObject.GetComponent<NomaiCairn>()._rocks)
{ {
rock._returning = false; var computerObject = _computerPrefab.InstantiateInactive();
rock._owCollider.SetActivation(true);
rock.enabled = false; computerObject.transform.parent = sector?.transform ?? planetGO.transform;
computerObject.transform.position = planetGO.transform.TransformPoint(info?.position ?? Vector3.zero);
var up = computerObject.transform.position - planetGO.transform.position;
if (info.normal != null) up = planetGO.transform.TransformDirection(info.normal);
computerObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, up) * computerObject.transform.rotation;
var computer = computerObject.GetComponent<NomaiComputer>();
computer.SetSector(sector);
computer._dictNomaiTextData = MakeNomaiTextDict(xmlPath);
computer._nomaiTextAsset = new TextAsset(xmlPath);
AddTranslation(xmlPath);
// Make sure the computer model is loaded
OWAssetHandler.LoadObject(computerObject);
sector.OnOccupantEnterSector.AddListener((x) => OWAssetHandler.LoadObject(computerObject));
computerObject.SetActive(true);
break;
} }
case PropModule.NomaiTextInfo.NomaiTextType.Cairn:
// So we can actually knock it over
cairnObject.GetComponent<CapsuleCollider>().enabled = true;
var nomaiWallText = cairnObject.transform.Find("Props_TH_ClutterSmall/Arc_Short").GetComponent<NomaiWallText>();
nomaiWallText.SetSector(sector);
nomaiWallText._dictNomaiTextData = MakeNomaiTextDict(xmlPath);
nomaiWallText._nomaiTextAsset = new TextAsset(xmlPath);
AddTranslation(xmlPath);
// Make sure the computer model is loaded
OWAssetHandler.LoadObject(cairnObject);
sector.OnOccupantEnterSector.AddListener((x) => OWAssetHandler.LoadObject(cairnObject));
}
else if (info.type == "recorder")
{
var recorderObject = _recorderPrefab.InstantiateInactive();
recorderObject.transform.parent = sector?.transform ?? planetGO.transform;
recorderObject.transform.position = planetGO.transform.TransformPoint(info?.position ?? Vector3.zero);
if (info.rotation != null)
{ {
recorderObject.transform.rotation = planetGO.transform.TransformRotation(Quaternion.Euler(info.rotation)); var cairnObject = _cairnPrefab.InstantiateInactive();
cairnObject.transform.parent = sector?.transform ?? planetGO.transform;
cairnObject.transform.position = planetGO.transform.TransformPoint(info?.position ?? Vector3.zero);
if (info.rotation != null)
{
cairnObject.transform.rotation = planetGO.transform.TransformRotation(Quaternion.Euler(info.rotation));
}
else
{
// By default align it to normal
var up = (cairnObject.transform.position - planetGO.transform.position).normalized;
cairnObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, up) * cairnObject.transform.rotation;
}
// Idk do we have to set it active before finding things?
cairnObject.SetActive(true);
// Make it do the thing when it finishes being knocked over
foreach (var rock in cairnObject.GetComponent<NomaiCairn>()._rocks)
{
rock._returning = false;
rock._owCollider.SetActivation(true);
rock.enabled = false;
}
// So we can actually knock it over
cairnObject.GetComponent<CapsuleCollider>().enabled = true;
var nomaiWallText = cairnObject.transform.Find("Props_TH_ClutterSmall/Arc_Short").GetComponent<NomaiWallText>();
nomaiWallText.SetSector(sector);
nomaiWallText._dictNomaiTextData = MakeNomaiTextDict(xmlPath);
nomaiWallText._nomaiTextAsset = new TextAsset(xmlPath);
AddTranslation(xmlPath);
// Make sure the computer model is loaded
OWAssetHandler.LoadObject(cairnObject);
sector.OnOccupantEnterSector.AddListener((x) => OWAssetHandler.LoadObject(cairnObject));
break;
} }
else case PropModule.NomaiTextInfo.NomaiTextType.Recorder:
{ {
var up = recorderObject.transform.position - planetGO.transform.position; var recorderObject = _recorderPrefab.InstantiateInactive();
recorderObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, up) * recorderObject.transform.rotation;
recorderObject.transform.parent = sector?.transform ?? planetGO.transform;
recorderObject.transform.position = planetGO.transform.TransformPoint(info?.position ?? Vector3.zero);
if (info.rotation != null)
{
recorderObject.transform.rotation = planetGO.transform.TransformRotation(Quaternion.Euler(info.rotation));
}
else
{
var up = recorderObject.transform.position - planetGO.transform.position;
recorderObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, up) * recorderObject.transform.rotation;
}
var nomaiText = recorderObject.GetComponentInChildren<NomaiText>();
nomaiText.SetSector(sector);
nomaiText._dictNomaiTextData = MakeNomaiTextDict(xmlPath);
nomaiText._nomaiTextAsset = new TextAsset(xmlPath);
AddTranslation(xmlPath);
// Make sure the recorder model is loaded
OWAssetHandler.LoadObject(recorderObject);
sector.OnOccupantEnterSector.AddListener((x) => OWAssetHandler.LoadObject(recorderObject));
recorderObject.SetActive(true);
recorderObject.transform.Find("InteractSphere").gameObject.GetComponent<SphereShape>().enabled = true;
break;
} }
default:
var nomaiText = recorderObject.GetComponentInChildren<NomaiText>(); Logger.LogError($"Unsupported NomaiText type {info.type}");
nomaiText.SetSector(sector); break;
nomaiText._dictNomaiTextData = MakeNomaiTextDict(xmlPath);
nomaiText._nomaiTextAsset = new TextAsset(xmlPath);
AddTranslation(xmlPath);
// Make sure the recorder model is loaded
OWAssetHandler.LoadObject(recorderObject);
sector.OnOccupantEnterSector.AddListener((x) => OWAssetHandler.LoadObject(recorderObject));
recorderObject.SetActive(true);
recorderObject.transform.Find("InteractSphere").gameObject.GetComponent<SphereShape>().enabled = true;
}
else
{
Logger.LogError($"Unsupported NomaiText type {info.type}");
} }
} }
@ -304,18 +311,19 @@ namespace NewHorizons.Builder.Props
var parent = parentID == -1 ? null : arcsByID[parentID]; var parent = parentID == -1 ? null : arcsByID[parentID];
GameObject arc; GameObject arc;
var type = info.arcInfo != null ? info.arcInfo[i].type : "adult"; var type = info.arcInfo != null ? info.arcInfo[i].type : PropModule.NomaiTextArcInfo.NomaiTextArcType.Adult;
if (type == "child") switch (type)
{ {
arc = _childArcPrefabs[Random.Range(0, _childArcPrefabs.Count())].InstantiateInactive(); case PropModule.NomaiTextArcInfo.NomaiTextArcType.Child:
} arc = _childArcPrefabs[Random.Range(0, _childArcPrefabs.Count())].InstantiateInactive();
else if (type == "stranger" && _ghostArcPrefabs.Count() > 0) // It could be empty if they dont have the DLC break;
{ case PropModule.NomaiTextArcInfo.NomaiTextArcType.Stranger when _ghostArcPrefabs.Any():
arc = _ghostArcPrefabs[Random.Range(0, _ghostArcPrefabs.Count())].InstantiateInactive(); arc = _ghostArcPrefabs[Random.Range(0, _ghostArcPrefabs.Count())].InstantiateInactive();
} break;
else case PropModule.NomaiTextArcInfo.NomaiTextArcType.Adult:
{ default:
arc = _arcPrefabs[Random.Range(0, _arcPrefabs.Count())].InstantiateInactive(); arc = _arcPrefabs[Random.Range(0, _arcPrefabs.Count())].InstantiateInactive();
break;
} }
arc.transform.parent = conversationZone.transform; arc.transform.parent = conversationZone.transform;

View File

@ -14,9 +14,18 @@ namespace NewHorizons.Builder.Props
private static GameObject _autoPrefab; private static GameObject _autoPrefab;
public static void Make(GameObject go, Sector sector, PropModule.ProjectionInfo info, IModBehaviour mod) public static void Make(GameObject go, Sector sector, PropModule.ProjectionInfo info, IModBehaviour mod)
{ {
if (info.type == "autoProjector") MakeAutoProjector(go, sector, info, mod); switch (info.type)
else if (info.type == "slideReel") MakeSlideReel(go, sector, info, mod); {
else Logger.LogError($"Invalid projection type {info.type}"); case PropModule.ProjectionInfo.SlideShowType.AutoProjector:
MakeAutoProjector(go, sector, info, mod);
break;
case PropModule.ProjectionInfo.SlideShowType.SlideReel:
MakeSlideReel(go, sector, info, mod);
break;
default:
Logger.LogError($"Invalid projection type {info.type}");
break;
}
} }
private static void MakeSlideReel(GameObject planetGO, Sector sector, PropModule.ProjectionInfo info, IModBehaviour mod) private static void MakeSlideReel(GameObject planetGO, Sector sector, PropModule.ProjectionInfo info, IModBehaviour mod)

View File

@ -5,6 +5,7 @@ using NewHorizons.Utility;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NewHorizons.External.Modules.VariableSize;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using Logger = NewHorizons.Utility.Logger; using Logger = NewHorizons.Utility.Logger;
@ -511,8 +512,13 @@ namespace NewHorizons.Builder.ShipLog
{ {
try try
{ {
if (body.Config?.Singularity?.Type == "BlackHole") return Color.black; switch (body.Config?.Singularity?.Type)
if (body.Config?.Singularity?.Type == "WhiteHole") return Color.white; {
case SingularityModule.SingularityType.BlackHole:
return Color.black;
case SingularityModule.SingularityType.WhiteHole:
return Color.white;
}
var starColor = body.Config?.Star?.Tint; var starColor = body.Config?.Star?.Tint;
if (starColor != null) return starColor.ToColor(); if (starColor != null) return starColor.ToColor();

View File

@ -8,23 +8,22 @@ namespace NewHorizons.Builder.ShipLog
{ {
public static void Make(GameObject go, Sector sector, PropModule.RevealInfo info, IModBehaviour mod) public static void Make(GameObject go, Sector sector, PropModule.RevealInfo info, IModBehaviour mod)
{ {
GameObject newRevealGO = MakeGameObject(go, sector, info, mod); var newRevealGO = MakeGameObject(go, sector, info, mod);
switch (info.revealOn.ToLower()) switch (info.revealOn)
{ {
case "enter": case PropModule.RevealInfo.RevealVolumeType.Enter:
MakeTrigger(newRevealGO, sector, info, mod); MakeTrigger(newRevealGO, sector, info, mod);
break; break;
case "observe": case PropModule.RevealInfo.RevealVolumeType.Observe:
MakeObservable(newRevealGO, sector, info, mod); MakeObservable(newRevealGO, sector, info, mod);
break; break;
case "snapshot": case PropModule.RevealInfo.RevealVolumeType.Snapshot:
MakeSnapshot(newRevealGO, sector, info, mod); MakeSnapshot(newRevealGO, sector, info, mod);
break; break;
default: default:
Logger.LogError("Invalid revealOn: " + info.revealOn); Logger.LogError("Invalid revealOn: " + info.revealOn);
break; break;
} }
newRevealGO.SetActive(true); newRevealGO.SetActive(true);
} }

View File

@ -17,7 +17,7 @@ namespace NewHorizons.Components.Orbital
{ {
var surfaceAcceleration = module.SurfaceGravity; var surfaceAcceleration = module.SurfaceGravity;
var upperSurfaceRadius = module.SurfaceSize; var upperSurfaceRadius = module.SurfaceSize;
int falloffExponent = module.GravityFallOff.ToUpper().Equals("LINEAR") ? 1 : 2; int falloffExponent = module.GravityFallOff == GravityFallOff.Linear ? 1 : 2;
Mass = surfaceAcceleration * Mathf.Pow(upperSurfaceRadius, falloffExponent) / GravityVolume.GRAVITATIONAL_CONSTANT; Mass = surfaceAcceleration * Mathf.Pow(upperSurfaceRadius, falloffExponent) / GravityVolume.GRAVITATIONAL_CONSTANT;
Power = falloffExponent; Power = falloffExponent;

View File

@ -1,41 +1,150 @@
using NewHorizons.External.Modules; using NewHorizons.External.Modules;
using NewHorizons.External.Modules.VariableSize; using NewHorizons.External.Modules.VariableSize;
using NewHorizons.Utility; using Newtonsoft.Json;
using UnityEngine;
namespace NewHorizons.External.Configs namespace NewHorizons.External.Configs
{ {
/// <summary>
/// A planet or body to generate
/// </summary>
[JsonObject]
public class PlanetConfig public class PlanetConfig
{ {
public string Name { get; set; } /// <summary>
public string Version { get; set; } /// Unique name of your planet
public string StarSystem { get; set; } = "SolarSystem"; /// </summary>
public bool Destroy { get; set; } public string Name;
public string[] RemoveChildren { get; set; }
public int BuildPriority { get; set; } = -1; /// <summary>
public bool CanShowOnTitle { get; set; } = true; /// Version of New Horizons this config is using (Doesn't do anything)
public bool IsQuantumState { get; set; } /// </summary>
public BaseModule Base { get; set; } public string Version;
public AtmosphereModule Atmosphere { get; set; }
public OrbitModule Orbit { get; set; } /// <summary>
public RingModule Ring { get; set; } /// Unique star system containing your planet
public HeightMapModule HeightMap { get; set; } /// </summary>
public ProcGenModule ProcGen { get; set; } public string StarSystem = "SolarSystem";
public AsteroidBeltModule AsteroidBelt { get; set; }
public StarModule Star { get; set; } /// <summary>
public FocalPointModule FocalPoint { get; set; } /// `true` if you want to delete this planet
public PropModule Props { get; set; } /// </summary>
public ShipLogModule ShipLog { get; set; } public bool Destroy;
public SpawnModule Spawn { get; set; }
public SignalModule Signal { get; set; } /// <summary>
public SingularityModule Singularity { get; set; } /// A list of paths to child GameObjects to destroy on this planet
public LavaModule Lava { get; set; } /// </summary>
public WaterModule Water { get; set; } public string[] RemoveChildren;
public SandModule Sand { get; set; }
public FunnelModule Funnel { get; set; } /// <summary>
/// Set to a higher number if you wish for this body to be built sooner
/// </summary>
public int BuildPriority = -1;
/// <summary>
/// Should this planet ever be shown on the title screen?
/// </summary>
public bool CanShowOnTitle = true;
/// <summary>
/// Does this config describe a quantum state of a custom planet defined in another file?
/// </summary>
public bool IsQuantumState;
/// <summary>
/// Base Properties of this Body
/// </summary>
public BaseModule Base;
/// <summary>
/// Describes this Body's atmosphere
/// </summary>
public AtmosphereModule Atmosphere;
/// <summary>
/// Describes this Body's orbit (or lack there of)
/// </summary>
public OrbitModule Orbit;
/// <summary>
/// Creates a ring around the planet
/// </summary>
public RingModule Ring;
/// <summary>
/// Generate the surface of this planet using a heightmap
/// </summary>
public HeightMapModule HeightMap;
/// <summary>
/// Procedural Generation
/// </summary>
public ProcGenModule ProcGen;
/// <summary>
/// Generate asteroids around this body
/// </summary>
public AsteroidBeltModule AsteroidBelt;
/// <summary>
/// Make this body a star
/// </summary>
public StarModule Star;
/// <summary>
/// Make this body into a focal point (barycenter)
/// </summary>
public FocalPointModule FocalPoint;
/// <summary>
/// Spawn various objects on this body
/// </summary>
public PropModule Props;
/// <summary>
/// Add ship log entries to this planet and describe how it looks in map mode
/// </summary>
public ShipLogModule ShipLog;
/// <summary>
/// Spawn the player at this planet
/// </summary>
public SpawnModule Spawn;
/// <summary>
/// Add signals that can be heard via the signal-scope to this planet
/// </summary>
public SignalModule Signal;
/// <summary>
/// Add a black or white hole to this planet
/// </summary>
public SingularityModule Singularity;
/// <summary>
/// Add lava to this planet
/// </summary>
public LavaModule Lava;
/// <summary>
/// Add water to this planet
/// </summary>
public WaterModule Water;
/// <summary>
/// Add sand to this planet
/// </summary>
public SandModule Sand;
/// <summary>
/// Add funnel from this planet to another
/// </summary>
public FunnelModule Funnel;
#region Obsolete #region Obsolete
[System.Obsolete("ChildrenToDestroy is deprecated, please use RemoveChildren instead")] public string[] ChildrenToDestroy { get; set; }
[System.Obsolete("ChildrenToDestroy is deprecated, please use RemoveChildren instead")]
public string[] ChildrenToDestroy;
#endregion Obsolete #endregion Obsolete
public PlanetConfig() public PlanetConfig()
@ -57,22 +166,28 @@ namespace NewHorizons.External.Configs
#pragma warning disable 612, 618 #pragma warning disable 612, 618
if (Base.WaterSize != 0) if (Base.WaterSize != 0)
{ {
Water = new WaterModule(); Water = new WaterModule
Water.Size = Base.WaterSize; {
Water.Tint = Base.WaterTint; Size = Base.WaterSize,
Tint = Base.WaterTint
};
} }
if (Base.LavaSize != 0) if (Base.LavaSize != 0)
{ {
Lava = new LavaModule(); Lava = new LavaModule
Lava.Size = Base.LavaSize; {
Size = Base.LavaSize
};
} }
if (Base.BlackHoleSize != 0) if (Base.BlackHoleSize != 0)
{ {
Singularity = new SingularityModule(); Singularity = new SingularityModule
Singularity.Type = "BlackHole"; {
Singularity.Size = Base.BlackHoleSize; Type = SingularityModule.SingularityType.BlackHole,
Size = Base.BlackHoleSize
};
} }
if (Base.IsSatellite) if (Base.IsSatellite)
@ -102,7 +217,7 @@ namespace NewHorizons.External.Configs
TexturePath = Atmosphere.Cloud, TexturePath = Atmosphere.Cloud,
CapPath = Atmosphere.CloudCap, CapPath = Atmosphere.CloudCap,
RampPath = Atmosphere.CloudRamp, RampPath = Atmosphere.CloudRamp,
FluidType = Atmosphere.CloudFluidType, FluidType = Atmosphere.FluidType,
UseBasicCloudShader = Atmosphere.UseBasicCloudShader, UseBasicCloudShader = Atmosphere.UseBasicCloudShader,
Unlit = !Atmosphere.ShadowsOnClouds, Unlit = !Atmosphere.ShadowsOnClouds,
}; };
@ -123,4 +238,4 @@ namespace NewHorizons.External.Configs
#pragma warning restore 612, 618 #pragma warning restore 612, 618
} }
} }
} }

View File

@ -1,14 +1,51 @@
namespace NewHorizons.External.Configs using Newtonsoft.Json;
namespace NewHorizons.External.Configs
{ {
/// <summary>
/// Configuration for a specific star system
/// </summary>
[JsonObject]
public class StarSystemConfig public class StarSystemConfig
{ {
/// <summary>
/// Whether this system can be warped to via the warp drive
/// </summary>
public bool canEnterViaWarpDrive = true; public bool canEnterViaWarpDrive = true;
public bool startHere = false;
/// <summary>
/// Set to `true` if you want to spawn here after dying, not Timber Hearth. You can still warp back to the main star system.
/// </summary>
public bool startHere;
/// <summary>
/// Do you want a clean slate for this star system? Or will it be a modified version of the original.
/// </summary>
public bool destroyStockPlanets = true; public bool destroyStockPlanets = true;
/// <summary>
/// Set to the FactID that must be revealed before it can be warped to. Don't set `CanEnterViaWarpDrive` to `false` if you're using this, that would make no sense.
/// </summary>
public string factRequiredForWarp; public string factRequiredForWarp;
/// <summary>
/// Should the player be sent back in time after 22 minutes?
/// </summary>
public bool enableTimeLoop = true; public bool enableTimeLoop = true;
/// <summary>
/// Should the player be unable to use their map in this system?
/// </summary>
public bool mapRestricted; public bool mapRestricted;
/// <summary>
/// [DEPRECATED] Not implemented
/// </summary>
public NomaiCoordinates coords; public NomaiCoordinates coords;
/// <summary>
/// Customize the skybox for this system
/// </summary>
public SkyboxConfig skybox; public SkyboxConfig skybox;
public class NomaiCoordinates public class NomaiCoordinates
@ -18,11 +55,23 @@
public int[] z; public int[] z;
} }
[JsonObject]
public class SkyboxConfig public class SkyboxConfig
{ {
public string assetBundle = null; /// <summary>
public string path = null; /// Path to the Unity asset bundle to load the skybox material from
public bool destroyStarField = false; /// </summary>
public string assetBundle;
/// <summary>
/// Path to the material within the asset bundle specified by `assetBundle` to use for the skybox
/// </summary>
public string path;
/// <summary>
/// Whether to destroy the star field around the player
/// </summary>
public bool destroyStarField;
} }
} }
} }

View File

@ -1,15 +1,53 @@
namespace NewHorizons.External.Modules using Newtonsoft.Json;
namespace NewHorizons.External.Modules
{ {
[JsonObject]
public class AsteroidBeltModule public class AsteroidBeltModule
{ {
public float InnerRadius { get; set; } /// <summary>
public float OuterRadius { get; set; } /// Lowest distance from the planet asteroids can spawn
public float MinSize { get; set; } = 20; /// </summary>
public float MaxSize { get; set; } = 50; public float InnerRadius;
public int Amount { get; set; } = -1;
public float Inclination { get; set; } /// <summary>
public float LongitudeOfAscendingNode { get; set; } /// Greatest distance from the planet asteroids can spawn
public int RandomSeed { get; set; } /// </summary>
public ProcGenModule ProcGen { get; set; } public float OuterRadius;
/// <summary>
/// Minimum size of the asteroids.
/// </summary>
public float MinSize = 20f;
/// <summary>
/// Maximum size of the asteroids.
/// </summary>
public float MaxSize = 50f;
/// <summary>
/// Amount of asteroids to create.
/// </summary>
public int Amount = -1;
/// <summary>
/// Angle between the rings and the equatorial plane of the planet.
/// </summary>
public float Inclination;
/// <summary>
/// Angle defining the point where the rings rise up from the planet's equatorial plane if inclination is nonzero.
/// </summary>
public float LongitudeOfAscendingNode;
/// <summary>
/// Number used to randomize asteroid positions
/// </summary>
public int RandomSeed;
/// <summary>
/// How the asteroids are generated
/// </summary>
public ProcGenModule ProcGen;
} }
} }

View File

@ -1,54 +1,162 @@
using NewHorizons.Utility; using System.Runtime.Serialization;
using UnityEngine; using NewHorizons.Utility;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace NewHorizons.External.Modules namespace NewHorizons.External.Modules
{ {
public enum CloudFluidType
{
[EnumMember(Value = @"NONE")]
None = 0,
[EnumMember(Value = @"WATER")]
Water = 1,
[EnumMember(Value = @"CLOUD")]
Cloud = 2,
[EnumMember(Value = @"SAND")]
Sand = 3,
[EnumMember(Value = @"PLASMA")]
Plasma = 4
}
[JsonObject]
public class AtmosphereModule public class AtmosphereModule
{ {
public float Size { get; set; } /// <summary>
public MColor AtmosphereTint { get; set; } /// Scale height of the atmosphere
public MColor FogTint { get; set; } /// </summary>
public float FogDensity { get; set; } public float Size;
public float FogSize { get; set; }
public bool HasRain { get; set; } /// <summary>
public bool HasSnow { get; set; } /// Colour of atmospheric shader on the planet.
public bool HasOxygen { get; set; } /// </summary>
public bool UseAtmosphereShader { get; set; } public MColor AtmosphereTint;
public CloudInfo Clouds { get; set; }
/// <summary>
/// Colour of fog on the planet, if you put fog.
/// </summary>
public MColor FogTint;
/// <summary>
/// How dense the fog is, if you put fog.
/// </summary>
// FIXME: Min & Max Needed!
public float FogDensity;
/// <summary>
/// Radius of fog sphere, independent of the atmosphere. This has to be set for there to be fog.
/// </summary>
public float FogSize;
/// <summary>
/// Does this planet have rain?
/// </summary>
public bool HasRain;
/// <summary>
/// Does this planet have snow?
/// </summary>
public bool HasSnow;
/// <summary>
/// Lets you survive on the planet without a suit.
/// </summary>
public bool HasOxygen;
/// <summary>
/// Whether we use an atmospheric shader on the planet. Doesn't affect clouds, fog, rain, snow, oxygen, etc. Purely visual.
/// </summary>
public bool UseAtmosphereShader;
/// <summary>
/// Describes the clouds in the atmosphere
/// </summary>
public CloudInfo Clouds;
#region Obsolete #region Obsolete
[System.Obsolete("CloudTint is deprecated, please use CloudInfo instead")] public MColor CloudTint { get; set; } [System.Obsolete("CloudTint is deprecated, please use CloudInfo instead")] public MColor CloudTint;
[System.Obsolete("CloudTint is deprecated, please use CloudInfo instead")] public string Cloud { get; set; } [System.Obsolete("CloudTint is deprecated, please use CloudInfo instead")] public string Cloud;
[System.Obsolete("CloudCap is deprecated, please use CloudInfo instead")] public string CloudCap { get; set; } [System.Obsolete("CloudCap is deprecated, please use CloudInfo instead")] public string CloudCap;
[System.Obsolete("CloudRamp is deprecated, please use CloudInfo instead")] public string CloudRamp { get; set; } [System.Obsolete("CloudRamp is deprecated, please use CloudInfo instead")] public string CloudRamp;
[System.Obsolete("CloudFluidType is deprecated, please use CloudInfo instead")] public string CloudFluidType { get; set; } [System.Obsolete("CloudFluidType is deprecated, please use CloudInfo instead")]
[System.Obsolete("UseBasicCloudShader is deprecated, please use CloudInfo instead")] public bool UseBasicCloudShader { get; set; } [JsonConverter(typeof(StringEnumConverter))]
[System.Obsolete("ShadowsOnClouds is deprecated, please use CloudInfo instead")] public bool ShadowsOnClouds { get; set; } = true; public CloudFluidType? FluidType;
[System.Obsolete("HasAtmosphere is deprecated, please use UseAtmosphereShader instead")] public bool HasAtmosphere { get; set; } [System.Obsolete("UseBasicCloudShader is deprecated, please use CloudInfo instead")] public bool UseBasicCloudShader;
[System.Obsolete("ShadowsOnClouds is deprecated, please use CloudInfo instead")] public bool ShadowsOnClouds = true;
[System.Obsolete("HasAtmosphere is deprecated, please use UseAtmosphereShader instead")] public bool HasAtmosphere;
#endregion Obsolete #endregion Obsolete
public class AirInfo public class AirInfo
{ {
public float Scale { get; set; } public float Scale;
public bool HasOxygen { get; set; } public bool HasOxygen;
public bool IsRaining { get; set; } public bool IsRaining;
public bool IsSnowing { get; set; } public bool IsSnowing;
} }
[JsonObject]
public class CloudInfo public class CloudInfo
{ {
public float OuterCloudRadius { get; set; } /// <summary>
public float InnerCloudRadius { get; set; } /// Radius from the center to the outer layer of the clouds.
public MColor Tint { get; set; } /// </summary>
public string TexturePath { get; set; } public float OuterCloudRadius;
public string CapPath { get; set; }
public string RampPath { get; set; } /// <summary>
public string FluidType { get; set; } /// Radius from the center to the inner layer of the clouds.
public bool UseBasicCloudShader { get; set; } /// </summary>
public bool Unlit { get; set; } public float InnerCloudRadius;
public bool HasLightning { get; set; }
public MGradient[] LightningGradient { get; set; } /// <summary>
/// Colour of the inner cloud layer.
/// </summary>
public MColor Tint;
/// <summary>
/// Relative filepath to the cloud texture, if the planet has clouds.
/// </summary>
public string TexturePath;
/// <summary>
/// Relative filepath to the cloud cap texture, if the planet has clouds.
/// </summary>
public string CapPath;
/// <summary>
/// Relative filepath to the cloud ramp texture, if the planet has clouds. If you don't put anything here it will be auto-generated.
/// </summary>
public string RampPath;
/// <summary>
/// Fluid type for sounds/effects when colliding with this cloud.
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public CloudFluidType? FluidType = CloudFluidType.Cloud;
/// <summary>
/// Set to `false` in order to use Giant's deep shader. Set to `true` to just apply the cloud texture as is.
/// </summary>
public bool UseBasicCloudShader;
/// <summary>
/// If the top layer shouldn't have shadows. Set to true if you're making a brown dwarf for example.
/// </summary>
public bool Unlit;
/// <summary>
/// Add lightning to this planet like on Giant's Deep.
/// </summary>
public bool HasLightning;
/// <summary>
/// Colour gradient of the lightning, time is in seconds.
/// </summary>
public MGradient[] LightningGradient;
} }
} }
} }

View File

@ -1,30 +1,99 @@
using NewHorizons.Utility; using System.Runtime.Serialization;
using NewHorizons.Utility;
using Newtonsoft.Json;
namespace NewHorizons.External.Modules namespace NewHorizons.External.Modules
{ {
public enum GravityFallOff
{
[EnumMember(Value = @"linear")]
Linear = 0,
[EnumMember(Value = @"inverseSquared")]
InverseSquared = 1
}
[JsonObject]
public class BaseModule public class BaseModule
{ {
public bool HasMapMarker { get; set; } /// <summary>
public float AmbientLight { get; set; } /// If the body should have a marker on the map screen.
public float SurfaceGravity { get; set; } /// </summary>
public string GravityFallOff { get; set; } = "linear"; public bool HasMapMarker;
public float SurfaceSize { get; set; }
public float SphereOfInfluence { get; set; } /// <summary>
public float GroundSize { get; set; } /// The intensity of light the dark side of the body should have. Timber Hearth has `1.4` for reference
public bool HasCometTail { get; set; } /// </summary>
public MVector3 CometTailRotation { get; set; } public float AmbientLight;
public bool HasReferenceFrame { get; set; } = true;
public bool CenterOfSolarSystem { get; set; } = false; /// <summary>
public float CloakRadius { get; set; } = 0f; /// The acceleration due to gravity felt as the surfaceSize. Timber Hearth has 12 for reference
public bool InvulnerableToSun { get; set; } /// </summary>
public bool ShowMinimap { get; set; } = true; public float SurfaceGravity;
/// <summary>
/// How gravity falls off with distance. Most planets use linear but the sun and some moons use inverseSquared.
/// </summary>
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public GravityFallOff GravityFallOff = GravityFallOff.Linear;
/// <summary>
/// A scale height used for a number of things. Should be the approximate radius of the body.
/// </summary>
public float SurfaceSize;
/// <summary>
/// An override for the radius of the planet's gravitational sphere of influence. Optional
/// </summary>
public float SphereOfInfluence;
/// <summary>
/// Radius of a simple sphere used as the ground for the planet. If you want to use more complex terrain, leave this as 0.
/// </summary>
public float GroundSize;
/// <summary>
/// If you want the body to have a tail like the Interloper.
/// </summary>
public bool HasCometTail;
/// <summary>
/// If it has a comet tail, it'll be oriented according to these Euler angles.
/// </summary>
public MVector3 CometTailRotation;
/// <summary>
/// Allows the object to be targeted on the map.
/// </summary>
public bool HasReferenceFrame = true;
/// <summary>
/// Set this to true if you are replacing the sun with a different body. Only one object in a star system should ever have this set to true.
/// </summary>
public bool CenterOfSolarSystem = false;
/// <summary>
/// Radius of the cloaking field around the planet. It's a bit finicky so experiment with different values. If you don't want a cloak, leave this as 0.
/// </summary>
public float CloakRadius = 0f;
/// <summary>
/// Can this planet survive entering a star?
/// </summary>
public bool InvulnerableToSun;
/// <summary>
/// Do we show the minimap when walking around this planet?
/// </summary>
public bool ShowMinimap = true;
#region Obsolete #region Obsolete
[System.Obsolete("IsSatellite is deprecated, please use ShowMinimap instead")] public bool IsSatellite { get; set; } [System.Obsolete("IsSatellite is deprecated, please use ShowMinimap instead")] public bool IsSatellite;
[System.Obsolete("BlackHoleSize is deprecated, please use SingularityModule instead")] public float BlackHoleSize { get; set; } [System.Obsolete("BlackHoleSize is deprecated, please use SingularityModule instead")] public float BlackHoleSize;
[System.Obsolete("LavaSize is deprecated, please use LavaModule instead")] public float LavaSize { get; set; } [System.Obsolete("LavaSize is deprecated, please use LavaModule instead")] public float LavaSize;
[System.Obsolete("WaterTint is deprecated, please use WaterModule instead")] public float WaterSize { get; set; } [System.Obsolete("WaterTint is deprecated, please use WaterModule instead")] public float WaterSize;
[System.Obsolete("WaterTint is deprecated, please use WaterModule instead")] public MColor WaterTint { get; set; } [System.Obsolete("WaterTint is deprecated, please use WaterModule instead")] public MColor WaterTint;
[System.Obsolete("HasAmbientLight is deprecated, please use AmbientLight instead")] public bool HasAmbientLight { get; set; } [System.Obsolete("HasAmbientLight is deprecated, please use AmbientLight instead")] public bool HasAmbientLight;
#endregion Obsolete #endregion Obsolete
} }
} }

View File

@ -1,8 +1,18 @@
namespace NewHorizons.External.Modules using Newtonsoft.Json;
namespace NewHorizons.External.Modules
{ {
[JsonObject]
public class FocalPointModule public class FocalPointModule
{ {
public string Primary { get; set; } /// <summary>
public string Secondary { get; set; } /// Name of the primary planet in this binary system
/// </summary>
public string Primary;
/// <summary>
/// Name of the secondary planet in this binary system
/// </summary>
public string Secondary;
} }
} }

View File

@ -3,10 +3,29 @@ namespace NewHorizons.External.Modules
{ {
public class HeightMapModule public class HeightMapModule
{ {
public string HeightMap { get; set; } /// <summary>
public string TextureMap { get; set; } /// Relative filepath to the texture used for the terrain height.
public float MinHeight { get; set; } /// </summary>
public float MaxHeight { get; set; } public string HeightMap;
public MVector3 Stretch { get; set; }
/// <summary>
/// Relative filepath to the texture used for the terrain.
/// </summary>
public string TextureMap;
/// <summary>
/// The lowest points on your planet will be at this height.
/// </summary>
public float MinHeight;
/// <summary>
/// The highest points on your planet will be at this height.
/// </summary>
public float MaxHeight;
/// <summary>
/// The scale of the terrain.
/// </summary>
public MVector3 Stretch;
} }
} }

View File

@ -1,25 +1,96 @@
using NewHorizons.Components.Orbital; using NewHorizons.Components.Orbital;
using NewHorizons.Utility; using NewHorizons.Utility;
using Newtonsoft.Json;
using UnityEngine;
namespace NewHorizons.External.Modules namespace NewHorizons.External.Modules
{ {
public class OrbitModule : IOrbitalParameters public class OrbitModule : IOrbitalParameters
{ {
/// <summary>
/// The semi-major axis of the ellipse that is the body's orbit. For a circular orbit this is the radius.
/// </summary>
public float SemiMajorAxis { get; set; } public float SemiMajorAxis { get; set; }
/// <summary>
/// The angle (in degrees) between the body's orbit and the plane of the star system
/// </summary>
public float Inclination { get; set; } public float Inclination { get; set; }
/// <summary>
/// The name of the body this one will orbit around
/// </summary>
public string PrimaryBody { get; set; } public string PrimaryBody { get; set; }
/// <summary>
/// Is this the moon of a planet? Used for determining when its name is shown on the map.
/// </summary>
public bool IsMoon { get; set; } public bool IsMoon { get; set; }
/// <summary>
/// An angle (in degrees) defining the point where the orbit of the body rises above the orbital plane if it has nonzero inclination.
/// </summary>
public float LongitudeOfAscendingNode { get; set; } public float LongitudeOfAscendingNode { get; set; }
/// <summary>
/// At 0 the orbit is a circle. The closer to 1 it is, the more oval-shaped the orbit is.
/// </summary>
// FIXME: Needs Min & Max!
public float Eccentricity { get; set; } public float Eccentricity { get; set; }
/// <summary>
/// An angle (in degrees) defining the location of the periapsis (the closest distance to it's primary body) if it has nonzero eccentricity.
/// </summary>
public float ArgumentOfPeriapsis { get; set; } public float ArgumentOfPeriapsis { get; set; }
/// <summary>
/// Where the planet should start off in its orbit in terms of the central angle.
/// </summary>
public float TrueAnomaly { get; set; } public float TrueAnomaly { get; set; }
/// <summary>
/// The angle between the normal to the orbital plane and its axis of rotation.
/// </summary>
public float AxialTilt { get; set; } public float AxialTilt { get; set; }
/// <summary>
/// Rotation period in minutes.
/// </summary>
public float SiderealPeriod { get; set; } public float SiderealPeriod { get; set; }
/// <summary>
/// Should the body always have one side facing its primary?
/// </summary>
public bool IsTidallyLocked { get; set; } public bool IsTidallyLocked { get; set; }
/// <summary>
/// If it is tidally locked, this direction will face towards the primary. Ex: Interloper uses `0, -1, 0`. Most planets will want something like `-1, 0, 0`.
/// </summary>
public MVector3 AlignmentAxis { get; set; } public MVector3 AlignmentAxis { get; set; }
/// <summary>
/// Referring to the orbit line in the map screen.
/// </summary>
public bool ShowOrbitLine { get; set; } = true; public bool ShowOrbitLine { get; set; } = true;
/// <summary>
/// Should the orbit line be dotted?
/// </summary>
public bool DottedOrbitLine { get; set; } = false; public bool DottedOrbitLine { get; set; } = false;
/// <summary>
/// Is the body meant to stay in one place without moving?
/// </summary>
public bool IsStatic { get; set; } public bool IsStatic { get; set; }
/// <summary>
/// Colour of the orbit-line in the map view.
/// </summary>
public MColor Tint { get; set; } public MColor Tint { get; set; }
/// <summary>
/// Should we just draw a line behind its orbit instead of the entire circle/ellipse?
/// </summary>
public bool TrackingOrbitLine { get; set; } = false; public bool TrackingOrbitLine { get; set; } = false;
public OrbitalParameters GetOrbitalParameters(Gravity primaryGravity, Gravity secondaryGravity) public OrbitalParameters GetOrbitalParameters(Gravity primaryGravity, Gravity secondaryGravity)

View File

@ -1,10 +1,12 @@
using NewHorizons.Utility; using NewHorizons.Utility;
using Newtonsoft.Json;
namespace NewHorizons.External.Modules namespace NewHorizons.External.Modules
{ {
public class ProcGenModule [JsonObject]
public class ProcGenModule
{ {
public float Scale { get; set; } public float Scale;
public MColor Color { get; set; } public MColor Color;
} }
} }

View File

@ -1,161 +1,587 @@
using NewHorizons.Utility; using System.Runtime.Serialization;
using NewHorizons.Utility;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace NewHorizons.External.Modules namespace NewHorizons.External.Modules
{ {
[JsonObject]
public class PropModule public class PropModule
{ {
/// <summary>
/// Scatter props around this planet's surface
/// </summary>
public ScatterInfo[] Scatter; public ScatterInfo[] Scatter;
/// <summary>
/// Place props in predefined positions on the planet
/// </summary>
public DetailInfo[] Details; public DetailInfo[] Details;
/// <summary>
/// Add rafts to this planet
/// </summary>
public RaftInfo[] Rafts; public RaftInfo[] Rafts;
/// <summary>
/// Add Geysers to this planet
/// </summary>
public GeyserInfo[] Geysers; public GeyserInfo[] Geysers;
/// <summary>
/// Add tornadoes to this planet
/// </summary>
public TornadoInfo[] Tornados; public TornadoInfo[] Tornados;
/// <summary>
/// Add volcanoes to this planet
/// </summary>
public VolcanoInfo[] Volcanoes; public VolcanoInfo[] Volcanoes;
/// <summary>
/// Add dialogue triggers to this planet
/// </summary>
public DialogueInfo[] Dialogue; public DialogueInfo[] Dialogue;
/// <summary>
/// Add triggers that reveal parts of the ship log on this planet
/// </summary>
public RevealInfo[] Reveal; public RevealInfo[] Reveal;
/// <summary>
/// Add ship log entry locations on this planet
/// </summary>
public EntryLocationInfo[] EntryLocation; public EntryLocationInfo[] EntryLocation;
/// <summary>
/// Add translatable text to this planet
/// </summary>
public NomaiTextInfo[] NomaiText; public NomaiTextInfo[] NomaiText;
/// <summary>
/// Add slideshows (from the DLC) to the planet
/// </summary>
public ProjectionInfo[] SlideShows; public ProjectionInfo[] SlideShows;
/// <summary>
/// Details which will be shown from 50km away. Meant to be lower resolution.
/// </summary>
public DetailInfo[] ProxyDetails; public DetailInfo[] ProxyDetails;
[JsonObject]
public class ScatterInfo public class ScatterInfo
{ {
public int seed = 0; /// <summary>
/// The number used as entropy for scattering the props
/// </summary>
public int seed;
/// <summary>
/// Number of props to scatter
/// </summary>
public int count; public int count;
/// <summary>
/// Either the path in the scene hierarchy of the item to copy or the path to the object in the supplied asset bundle
/// </summary>
public string path; public string path;
/// <summary>
/// Relative filepath to an asset-bundle"
/// </summary>
public string assetBundle; public string assetBundle;
/// <summary>
/// Offset this prop once it is placed
/// </summary>
public MVector3 offset; public MVector3 offset;
/// <summary>
/// Rotate this prop once it is placed
/// </summary>
public MVector3 rotation; public MVector3 rotation;
public float scale { get; set; } = 1f;
/// <summary>
/// Scale this prop once it is placed
/// </summary>
public float scale = 1f;
} }
[JsonObject]
public class DetailInfo public class DetailInfo
{ {
/// <summary>
/// Either the path in the scene hierarchy of the item to copy or the path to the object in the supplied asset bundle
/// </summary>
public string path; public string path;
public string objFilePath; //obsolete DO NOT DOCUMENT
public string mtlFilePath; //obsolete /// <summary>
/// [DEPRECATED] Path to the .obj file to load a 3d model from
/// </summary>
public string objFilePath;
/// <summary>
/// [DEPRECATED] Path to the .mtl file to load a 3d model from
/// </summary>
public string mtlFilePath;
/// <summary>
/// Relative filepath to an asset-bundle to load the prefab defined in `path` from/
/// </summary>
public string assetBundle; public string assetBundle;
/// <summary>
/// Position of this prop relative to the body's center
/// </summary>
public MVector3 position; public MVector3 position;
/// <summary>
/// Rotate this prop
/// </summary>
public MVector3 rotation; public MVector3 rotation;
public float scale { get; set; } = 1f;
/// <summary>
/// Scale the prop
/// </summary>
public float scale = 1f;
/// <summary>
/// Do we override rotation and try to automatically align this object to stand upright on the body's surface?
/// </summary>
public bool alignToNormal; public bool alignToNormal;
/// <summary>
/// A list of children to remove from this detail
/// </summary>
public string[] removeChildren; public string[] removeChildren;
/// <summary>
/// Do we reset all the components on this object? Useful for certain props that have dialogue components attached to them.
/// </summary>
public bool removeComponents; public bool removeComponents;
} }
[JsonObject]
public class RaftInfo public class RaftInfo
{ {
/// <summary>
/// Position of the raft
/// </summary>
public MVector3 position; public MVector3 position;
} }
[JsonObject]
public class GeyserInfo public class GeyserInfo
{ {
/// <summary>
/// Position of the geyser
/// </summary>
public MVector3 position; public MVector3 position;
} }
[JsonObject]
public class TornadoInfo public class TornadoInfo
{ {
/// <summary>
/// Position of the tornado
/// </summary>
public MVector3 position; public MVector3 position;
/// <summary>
/// Alternative to setting the position. Will choose a random place at this elevation.
/// </summary>
public float elevation; public float elevation;
public float height = 30;
/// <summary>
/// The height of this tornado.
/// </summary>
public float height = 30f;
/// <summary>
/// The colour of the tornado.
/// </summary>
public MColor tint; public MColor tint;
/// <summary>
/// Should it pull things downwards? Will push them upwards by default.
/// </summary>
public bool downwards; public bool downwards;
/// <summary>
/// The rate at which the tornado will wander around the planet. Set to 0 for it to be stationary. Should be around 0.1.
/// </summary>
public float wanderRate; public float wanderRate;
public float wanderDegreesX = 45;
public float wanderDegreesZ = 45; /// <summary>
/// Angular distance from the starting position that it will wander, in terms of the angle around the x-axis.
/// </summary>
public float wanderDegreesX = 45f;
/// <summary>
/// Angular distance from the starting position that it will wander, in terms of the angle around the z-axis.
/// </summary>
public float wanderDegreesZ = 45f;
} }
[JsonObject]
public class VolcanoInfo public class VolcanoInfo
{ {
public MVector3 position = null; /// <summary>
/// Position of this volcano
/// </summary>
public MVector3 position;
/// <summary>
/// Scale of this volcano
/// </summary>
public float scale = 1; public float scale = 1;
public MColor stoneTint = null;
public MColor lavaTint = null; /// <summary>
/// The colour of the meteor's stone.
/// </summary>
public MColor stoneTint;
/// <summary>
/// The colour of the meteor's lava.
/// </summary>
public MColor lavaTint;
/// <summary>
/// Minimum random speed at which meteors are launched.
/// </summary>
public float minLaunchSpeed = 50f; public float minLaunchSpeed = 50f;
/// <summary>
/// Maximum random speed at which meteors are launched.
/// </summary>
public float maxLaunchSpeed = 150f; public float maxLaunchSpeed = 150f;
/// <summary>
/// Minimum time between meteor launches.
/// </summary>
public float minInterval = 5f; public float minInterval = 5f;
/// <summary>
/// Maximum time between meteor launches.
/// </summary>
public float maxInterval = 20f; public float maxInterval = 20f;
} }
[JsonObject]
public class DialogueInfo public class DialogueInfo
{ {
/// <summary>
/// When you enter into dialogue, you will look here.
/// </summary>
public MVector3 position; public MVector3 position;
/// <summary>
/// Radius of the spherical collision volume where you get the "talk to" prompt when looking at. If you use a remoteTriggerPosition, you can set this to 0 to make the dialogue only trigger remotely.
/// </summary>
public float radius = 1f; public float radius = 1f;
/// <summary>
/// The radius of the remote trigger volume.
/// </summary>
public float remoteTriggerRadius; public float remoteTriggerRadius;
/// <summary>
/// Relative path to the xml file defining the dialogue.
/// </summary>
public string xmlFile; public string xmlFile;
/// <summary>
/// Allows you to trigger dialogue from a distance when you walk into an area.
/// </summary>
public MVector3 remoteTriggerPosition; public MVector3 remoteTriggerPosition;
/// <summary>
/// Prevents the dialogue from being created after a specific persistent condition is set. Useful for remote dialogue triggers that you want to have happen only once.
/// </summary>
public string blockAfterPersistentCondition; public string blockAfterPersistentCondition;
/// <summary>
/// If this dialogue is meant for a character, this is the relative path from the planet to that character's CharacterAnimController or SolanumAnimController.
/// </summary>
public string pathToAnimController; public string pathToAnimController;
/// <summary>
/// If a pathToAnimController is supplied, if you are within this distance the character will look at you. If it is set to 0, they will only look at you when spoken to.
/// </summary>
public float lookAtRadius; public float lookAtRadius;
} }
[JsonObject]
public class RevealInfo public class RevealInfo
{ {
public string revealOn = "enter"; public enum RevealVolumeType
{
[EnumMember(Value = @"enter")]
Enter = 0,
[EnumMember(Value = @"observe")]
Observe = 1,
[EnumMember(Value = @"snapshot")]
Snapshot = 2
}
/// <summary>
/// What needs to be done to the volume to unlock the facts
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public RevealVolumeType revealOn = RevealVolumeType.Enter;
/// <summary>
/// A list of facts to reveal
/// </summary>
public string[] reveals; public string[] reveals;
/// <summary>
/// The position to place this volume at
/// </summary>
public MVector3 position; public MVector3 position;
/// <summary>
/// The radius of this reveal volume
/// </summary>
public float radius = 1f; public float radius = 1f;
/// <summary>
/// The max distance the user can be away from the volume to reveal the fact (`snapshot` and `observe` only)
/// </summary>
public float maxDistance = -1f; // Snapshot & Observe Only public float maxDistance = -1f; // Snapshot & Observe Only
/// <summary>
/// The max view angle (in degrees) the player can see the volume with to unlock the fact (`observe` only)
/// </summary>
public float maxAngle = 180f; // Observe Only public float maxAngle = 180f; // Observe Only
} }
[JsonObject]
public class EntryLocationInfo public class EntryLocationInfo
{ {
/// <summary>
/// ID of the entry this location relates to
/// </summary>
public string id; public string id;
/// <summary>
/// Whether this location is cloaked
/// </summary>
public bool cloaked; public bool cloaked;
/// <summary>
/// The position of this entry location
/// </summary>
public MVector3 position; public MVector3 position;
} }
[JsonObject]
public class NomaiTextInfo public class NomaiTextInfo
{ {
public enum NomaiTextType
{
[EnumMember(Value = @"wall")]
Wall = 0,
[EnumMember(Value = @"scroll")]
Scroll = 1,
[EnumMember(Value = @"Computer")]
Computer = 2,
[EnumMember(Value = @"Cairn")]
Cairn = 3,
[EnumMember(Value = @"Recorder")]
Recorder = 4
}
/// <summary>
/// Position of the root of this text
/// </summary>
public MVector3 position; public MVector3 position;
/// <summary>
/// The normal vector for this object. Used for writing on walls and positioning computers.
/// </summary>
public MVector3 normal; public MVector3 normal;
/// <summary>
/// The euler angle rotation of this object. Not required if setting the normal. Computers and cairns will orient themselves to the surface of the planet automatically.
/// </summary>
public MVector3 rotation; public MVector3 rotation;
public string type = "wall";
/// <summary>
/// The type of object this is.
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public NomaiTextType type = NomaiTextType.Wall;
/// <summary>
/// The relative path to the xml file for this object.
/// </summary>
public string xmlFile; public string xmlFile;
/// <summary>
/// The random seed used to pick what the text arcs will look like.
/// </summary>
public int seed; // For randomizing arcs public int seed; // For randomizing arcs
/// <summary>
/// Additional information about each arc in the text
/// </summary>
public NomaiTextArcInfo[] arcInfo; public NomaiTextArcInfo[] arcInfo;
} }
[JsonObject]
public class NomaiTextArcInfo public class NomaiTextArcInfo
{ {
public enum NomaiTextArcType
{
[EnumMember(Value = @"adult")]
Adult = 0,
[EnumMember(Value = @"child")]
Child = 1,
[EnumMember(Value = @"stranger")]
Stranger = 2
}
/// <summary>
/// The local position of this object on the wall.
/// </summary>
public MVector2 position; public MVector2 position;
/// <summary>
/// The z euler angle for this arc.
/// </summary>
public float zRotation; public float zRotation;
public string type = "adult";
/// <summary>
/// The type of text to display.
/// </summary>
public NomaiTextArcType type = NomaiTextArcType.Adult;
} }
[JsonObject]
public class ProjectionInfo public class ProjectionInfo
{ {
public enum SlideShowType
{
[EnumMember(Value = @"slideReel")]
SlideReel = 0,
[EnumMember(Value = @"autoProjector")]
AutoProjector = 1
}
/// <summary>
/// The position of this slideshow.
/// </summary>
public MVector3 position; public MVector3 position;
/// <summary>
/// The rotation of this slideshow.
/// </summary>
public MVector3 rotation; public MVector3 rotation;
/// <summary>
/// The type of object this is.
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public SlideShowType type = SlideShowType.SlideReel;
/// <summary>
/// The ship log entries revealed after finishing this slide reel.
/// </summary>
public string[] reveals; public string[] reveals;
/// <summary>
/// The list of slides for this object.
/// </summary>
public SlideInfo[] slides; public SlideInfo[] slides;
public string type = "SlideReel";
} }
[JsonObject]
public class SlideInfo public class SlideInfo
{ {
/// <summary>
/// The path to the image file for this slide.
/// </summary>
public string imagePath; public string imagePath;
// SlideBeatAudioModule // SlideBeatAudioModule
/// <summary>
/// The name of the AudioClip for a one-shot sound when opening the slide.
/// </summary>
public string beatAudio; public string beatAudio;
/// <summary>
/// The time delay until the one-shot audio
/// </summary>
public float beatDelay; public float beatDelay;
// SlideBackdropAudioModule // SlideBackdropAudioModule
/// <summary>
/// The name of the AudioClip that will continuously play while watching these slides
/// </summary>
public string backdropAudio; public string backdropAudio;
/// <summary>
/// The time to fade into the backdrop audio
/// </summary>
public float backdropFadeTime; public float backdropFadeTime;
// SlideAmbientLightModule // SlideAmbientLightModule
/// <summary>
/// Ambient light intensity when viewing this slide.
/// </summary>
public float ambientLightIntensity; public float ambientLightIntensity;
/// <summary>
/// Ambient light range when viewing this slide.
/// </summary>
public float ambientLightRange; public float ambientLightRange;
/// <summary>
/// Ambient light colour when viewing this slide.
/// </summary>
public MColor ambientLightColor; public MColor ambientLightColor;
/// <summary>
/// Spotlight intensity modifier when viewing this slide.
/// </summary>
public float spotIntensityMod; public float spotIntensityMod;
// SlidePlayTimeModule // SlidePlayTimeModule
/// <summary>
/// Play-time duration for auto-projector slides.
/// </summary>
public float playTimeDuration; public float playTimeDuration;
// SlideBlackFrameModule // SlideBlackFrameModule
/// <summary>
/// Before viewing this slide, there will be a black frame for this many seconds.
/// </summary>
public float blackFrameDuration; public float blackFrameDuration;
// SlideShipLogEntryModule // SlideShipLogEntryModule
/// <summary>
/// Ship log entry revealed when viewing this slide
/// </summary>
public string reveal; public string reveal;
} }
} }

View File

@ -1,48 +1,154 @@
using NewHorizons.Utility; using NewHorizons.Utility;
using Newtonsoft.Json;
namespace NewHorizons.External.Modules namespace NewHorizons.External.Modules
{ {
[JsonObject]
public class ShipLogModule public class ShipLogModule
{ {
/// <summary>
/// The relative path to the xml file to load ship log entries from.
/// </summary>
public string xmlFile; public string xmlFile;
/// <summary>
/// A path to the folder where entry sprites are stored.
/// </summary>
public string spriteFolder; public string spriteFolder;
/// <summary>
/// A list of fact IDs to reveal when the game starts.
/// </summary>
public string[] initialReveal; public string[] initialReveal;
/// <summary>
/// Describe what this planet looks and like in map mode
/// </summary>
public MapModeInfo mapMode = new MapModeInfo(); public MapModeInfo mapMode = new MapModeInfo();
/// <summary>
/// List colors of curiosity entries
/// </summary>
public CuriosityColorInfo[] curiosities; public CuriosityColorInfo[] curiosities;
/// <summary>
/// Manually layout entries in detective mode
/// </summary>
public EntryPositionInfo[] entryPositions; public EntryPositionInfo[] entryPositions;
[JsonObject]
public class MapModeInfo public class MapModeInfo
{ {
/// <summary>
/// The path to the sprite to show when the planet is revealed in map mode.
/// </summary>
public string revealedSprite; public string revealedSprite;
/// <summary>
/// The path to the sprite to show when the planet is unexplored in map mode.
/// </summary>
public string outlineSprite; public string outlineSprite;
/// <summary>
/// Scale to apply to the planet in map mode.
/// </summary>
public float scale = 1f; public float scale = 1f;
/// <summary>
/// Hide the planet completely if unexplored instead of showing an outline.
/// </summary>
public bool invisibleWhenHidden; public bool invisibleWhenHidden;
public float offset = 0f;
/// <summary>
/// Extra distance to apply to this object in map mode.
/// </summary>
public float offset;
/// <summary>
/// Manually place this planet at the specified position.
/// </summary>
public MVector2 manualPosition; public MVector2 manualPosition;
/// <summary>
/// Specify where this planet is in terms of navigation.
/// </summary>
public MVector2 manualNavigationPosition; public MVector2 manualNavigationPosition;
public bool remove = false;
/// <summary>
/// Completely remove this planet (and it's children) from map mode.
/// </summary>
public bool remove;
/// <summary>
/// Place non-selectable objects in map mode (like sand funnels).
/// </summary>
public ShipLogDetailInfo[] details; public ShipLogDetailInfo[] details;
} }
[JsonObject]
public class ShipLogDetailInfo public class ShipLogDetailInfo
{ {
/// <summary>
/// The sprite to show when the parent AstroBody is revealed.
/// </summary>
public string revealedSprite; public string revealedSprite;
/// <summary>
/// The sprite to show when the parent AstroBody is rumored/unexplored.
/// </summary>
public string outlineSprite; public string outlineSprite;
public float rotation = 0f;
/// <summary>
/// The angle in degrees to rotate the detail.
/// </summary>
public float rotation;
/// <summary>
/// Whether to completely hide this detail when the parent AstroBody is unexplored.
/// </summary>
public bool invisibleWhenHidden; public bool invisibleWhenHidden;
/// <summary>
/// The position (relative to the parent) to place the detail.
/// </summary>
public MVector2 position; public MVector2 position;
/// <summary>
/// The amount to scale the x and y-axis of the detail by.
/// </summary>
public MVector2 scale; public MVector2 scale;
} }
[JsonObject]
public class CuriosityColorInfo public class CuriosityColorInfo
{ {
/// <summary>
/// The ID of the curiosity to apply the color to.
/// </summary>
public string id; public string id;
/// <summary>
/// The color to apply to entries with this curiosity.
/// </summary>
public MColor color; public MColor color;
/// <summary>
/// The color to apply to highlighted entries with this curiosity.
/// </summary>
public MColor highlightColor; public MColor highlightColor;
} }
[JsonObject]
public class EntryPositionInfo public class EntryPositionInfo
{ {
/// <summary>
/// The name of the entry to apply the position to.
/// </summary>
public string id; public string id;
/// <summary>
/// Position of the entry
/// </summary>
public MVector2 position; public MVector2 position;
} }
} }

View File

@ -1,23 +1,73 @@
using NewHorizons.Utility; using NewHorizons.Utility;
using Newtonsoft.Json;
namespace NewHorizons.External.Modules namespace NewHorizons.External.Modules
{ {
[JsonObject]
public class SignalModule public class SignalModule
{ {
/// <summary>
/// List of signals to add (Why did xen do it like this)
/// </summary>
public SignalInfo[] Signals; public SignalInfo[] Signals;
[JsonObject]
public class SignalInfo public class SignalInfo
{ {
/// <summary>
/// Position of the signal's source
/// </summary>
public MVector3 Position; public MVector3 Position;
/// <summary>
/// The frequency ID of the signal. The built-in game values are `Default`, `Traveler`, `Quantum`, `EscapePod`, `Statue`, `WarpCore`, `HideAndSeek`, and `Radio`. You can also put a custom value.
/// </summary>
public string Frequency; public string Frequency;
/// <summary>
/// The unique ID of the signal.
/// </summary>
public string Name; public string Name;
public string AudioClip = null;
public string AudioFilePath = null; /// <summary>
/// Name of an existing AudioClip in the game that will player over the signal.
/// </summary>
public string AudioClip;
/// <summary>
/// Relative filepath to the .wav file to use as the audio. Mutually exclusive with audioClip.
/// </summary>
public string AudioFilePath;
/// <summary>
/// A ship log fact to reveal when the signal is identified.
/// </summary>
public string Reveals = ""; public string Reveals = "";
/// <summary>
/// Radius of the sphere giving off the signal.
/// </summary>
public float SourceRadius = 1f; public float SourceRadius = 1f;
public float DetectionRadius = 0f;
/// <summary>
/// How close the player must get to the signal to detect it. This is when you get the "Unknown Signal Detected" notification.
/// </summary>
public float DetectionRadius;
/// <summary>
/// How close the player must get to the signal to identify it. This is when you learn its name.
/// </summary>
public float IdentificationRadius = 10f; public float IdentificationRadius = 10f;
/// <summary>
/// `false` if the player can hear the signal without equipping the signal-scope.
/// </summary>
public bool OnlyAudibleToScope = true; public bool OnlyAudibleToScope = true;
public bool InsideCloak = false;
/// <summary>
/// Only set to `true` if you are putting this signal inside a cloaking field.
/// </summary>
public bool InsideCloak;
} }
} }
} }

View File

@ -1,12 +1,34 @@
using NewHorizons.Utility; using NewHorizons.Utility;
using Newtonsoft.Json;
namespace NewHorizons.External.Modules namespace NewHorizons.External.Modules
{ {
[JsonObject]
public class SpawnModule public class SpawnModule
{ {
public MVector3 PlayerSpawnPoint { get; set; } /// <summary>
public MVector3 PlayerSpawnRotation { get; set; } /// If you want the player to spawn on the new body, set a value for this. Press `P` in game with Debug mode on to have the game log the position you're looking at to find a good value for this.
public MVector3 ShipSpawnPoint { get; set; } /// </summary>
public MVector3 ShipSpawnRotation { get; set; } public MVector3 PlayerSpawnPoint;
public bool StartWithSuit { get; set; }
/// <summary>
/// Euler angles by which the player will be oriented.
/// </summary>
public MVector3 PlayerSpawnRotation;
/// <summary>
/// Required for the system to be accessible by warp drive.
/// </summary>
public MVector3 ShipSpawnPoint;
/// <summary>
/// Euler angles by which the ship will be oriented.
/// </summary>
public MVector3 ShipSpawnRotation;
/// <summary>
/// If you spawn on a planet with no oxygen, you probably want to set this to true ;;)
/// </summary>
public bool StartWithSuit;
} }
} }

View File

@ -1,10 +1,43 @@
using NewHorizons.Utility; using System.Runtime.Serialization;
using NewHorizons.Utility;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace NewHorizons.External.Modules.VariableSize namespace NewHorizons.External.Modules.VariableSize
{ {
public enum FunnelType
{
[EnumMember(Value = @"Sand")]
Sand = 0,
[EnumMember(Value = @"Water")]
Water = 1,
[EnumMember(Value = @"Lava")]
Lava = 2,
[EnumMember(Value = @"Star")]
Star = 3
}
[JsonObject]
public class FunnelModule : VariableSizeModule public class FunnelModule : VariableSizeModule
{ {
public string Target { get; set; }
public string Type { get; set; } = "Sand"; /// <summary>
public MColor Tint { get; set; } /// The planet the funnel will flow to
/// </summary>
public string Target;
/// <summary>
/// Type of fluid the funnel transfers
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public FunnelType Type = FunnelType.Sand;
/// <summary>
/// Tint of the funnel
/// </summary>
public MColor Tint;
} }
} }

View File

@ -1,9 +1,19 @@
using NewHorizons.Utility; using NewHorizons.Utility;
using Newtonsoft.Json;
namespace NewHorizons.External.Modules.VariableSize namespace NewHorizons.External.Modules.VariableSize
{ {
[JsonObject]
public class LavaModule : VariableSizeModule public class LavaModule : VariableSizeModule
{ {
public float Size { get; set; } /// <summary>
public MColor Tint { get; set; } /// Size of the lava sphere
/// </summary>
public float Size;
/// <summary>
/// Tint of the lava
/// </summary>
public MColor Tint;
} }
} }

View File

@ -1,14 +1,48 @@
namespace NewHorizons.External.Modules.VariableSize using Newtonsoft.Json;
namespace NewHorizons.External.Modules.VariableSize
{ {
[JsonObject]
public class RingModule : VariableSizeModule public class RingModule : VariableSizeModule
{ {
public float InnerRadius { get; set; } /// <summary>
public float OuterRadius { get; set; } /// Inner radius of the disk
public float Inclination { get; set; } /// </summary>
public float LongitudeOfAscendingNode { get; set; } public float InnerRadius;
public string Texture { get; set; }
public bool Unlit { get; set; } = false; /// <summary>
public float RotationSpeed { get; set; } = 0f; /// Outer radius of the disk
public string FluidType { get; set; } /// </summary>
public float OuterRadius;
/// <summary>
/// Angle between the rings and the equatorial plane of the planet.
/// </summary>
public float Inclination;
/// <summary>
/// Angle defining the point where the rings rise up from the planet's equatorial plane if inclination is nonzero.
/// </summary>
public float LongitudeOfAscendingNode;
/// <summary>
/// Relative filepath to the texture used for the rings.
/// </summary>
public string Texture;
/// <summary>
/// Should this ring be unlit?
/// </summary>
public bool Unlit;
/// <summary>
/// Allows the rings to rotate.
/// </summary>
public float RotationSpeed;
/// <summary>
/// Fluid type for sounds/effects when colliding with this ring.
/// </summary>
public CloudFluidType? FluidType = CloudFluidType.None;
} }
} }

View File

@ -3,7 +3,14 @@ namespace NewHorizons.External.Modules.VariableSize
{ {
public class SandModule : VariableSizeModule public class SandModule : VariableSizeModule
{ {
/// <summary>
/// Size of the sand
/// </summary>
public float Size { get; set; } public float Size { get; set; }
/// <summary>
/// Tint of the sand
/// </summary>
public MColor Tint { get; set; } public MColor Tint { get; set; }
} }
} }

View File

@ -1,13 +1,51 @@
using NewHorizons.Utility; using System.Runtime.Serialization;
using NewHorizons.Utility;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace NewHorizons.External.Modules.VariableSize namespace NewHorizons.External.Modules.VariableSize
{ {
[JsonObject]
public class SingularityModule : VariableSizeModule public class SingularityModule : VariableSizeModule
{ {
public enum SingularityType
{
[EnumMember(Value = @"BlackHole")]
BlackHole = 0,
[EnumMember(Value = @"WhiteHole")]
WhiteHole = 1
}
/// <summary>
/// Radius of the singularity. Note that this isn't the same as the event horizon, but includes the entire volume that has warped effects in it.
/// </summary>
public float Size; public float Size;
/// <summary>
/// The name of the white hole or black hole that is paired to this one. If you don't set a value, entering will kill the player
/// </summary>
public string PairedSingularity; public string PairedSingularity;
/// <summary>
/// If you want a black hole to load a new star system scene, put its name here.
/// </summary>
public string TargetStarSystem; public string TargetStarSystem;
public string Type; //BlackHole or WhiteHole
/// <summary>
/// Type of singularity (white hole or black hole)
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public SingularityType Type;
/// <summary>
/// Position of the singularity
/// </summary>
public MVector3 Position; public MVector3 Position;
/// <summary>
/// Only for White Holes. Should this white hole repel the player from it.
/// </summary>
public bool MakeZeroGVolume = true; public bool MakeZeroGVolume = true;
} }
} }

View File

@ -1,16 +1,49 @@
using NewHorizons.Utility; using NewHorizons.Utility;
using Newtonsoft.Json;
namespace NewHorizons.External.Modules.VariableSize namespace NewHorizons.External.Modules.VariableSize
{ {
[JsonObject]
public class StarModule : VariableSizeModule public class StarModule : VariableSizeModule
{ {
public float Size { get; set; } = 2000f; /// <summary>
public MColor Tint { get; set; } /// Radius of the star.
public MColor EndTint { get; set; } /// </summary>
public MColor SupernovaTint { get; set; } public float Size = 2000f;
public MColor LightTint { get; set; }
public float SolarLuminosity { get; set; } = 1f; /// <summary>
public bool HasAtmosphere { get; set; } = true; /// Colour of the star.
public bool GoSupernova { get; set; } = true; /// </summary>
public MColor Tint;
/// <summary>
/// Colour of the star at the end of its life.
/// </summary>
public MColor EndTint;
/// <summary>
/// The tint of the supernova this star creates when it dies.
/// </summary>
public MColor SupernovaTint;
/// <summary>
/// Colour of the light given off.
/// </summary>
public MColor LightTint;
/// <summary>
/// Relative strength of the light compared to the sun.
/// </summary>
public float SolarLuminosity = 1f;
/// <summary>
/// The default sun has its own atmosphere that is different from regular planets. If you want that, set this to `true`.
/// </summary>
public bool HasAtmosphere = true;
/// <summary>
/// Should this star explode after 22 minutes?
/// </summary>
public bool GoSupernova = true;
} }
} }

View File

@ -1,8 +1,13 @@
using UnityEngine; using Newtonsoft.Json;
using UnityEngine;
namespace NewHorizons.External.Modules.VariableSize namespace NewHorizons.External.Modules.VariableSize
{ {
[JsonObject]
public class VariableSizeModule public class VariableSizeModule
{ {
/// <summary>
/// Scale this module over time
/// </summary>
public TimeValuePair[] Curve { get; set; } public TimeValuePair[] Curve { get; set; }
public class TimeValuePair public class TimeValuePair

View File

@ -1,9 +1,19 @@
using NewHorizons.Utility; using NewHorizons.Utility;
using Newtonsoft.Json;
namespace NewHorizons.External.Modules.VariableSize namespace NewHorizons.External.Modules.VariableSize
{ {
[JsonObject]
public class WaterModule : VariableSizeModule public class WaterModule : VariableSizeModule
{ {
public float Size { get; set; } /// <summary>
public MColor Tint { get; set; } /// Size of the water sphere
/// </summary>
public float Size;
/// <summary>
/// Tint of the water
/// </summary>
public MColor Tint;
} }
} }