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

View File

@ -8,8 +8,11 @@ namespace NewHorizons.Builder.Atmosphere
{
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");
volumesGO.SetActive(false);
volumesGO.transform.parent = planetGO.transform;
@ -23,20 +26,28 @@ namespace NewHorizons.Builder.Atmosphere
SS.SetLayer(Shape.Layer.Sector);
SS.layerMask = -1;
SS.pointChecksOnly = true;
SS.radius = outerRadius;
SS.radius = sphereOfInfluence;
rulesetGO.AddComponent<OWTriggerVolume>();
PlanetoidRuleset PR = rulesetGO.AddComponent<PlanetoidRuleset>();
PR._altitudeFloor = innerRadius;
PR._altitudeCeiling = outerRadius;
PR._altitudeCeiling = sphereOfInfluence;
PR._useMinimap = useMiniMap;
PR._useAltimeter = useMiniMap;
EffectRuleset ER = rulesetGO.AddComponent<EffectRuleset>();
ER._type = EffectRuleset.BubbleType.Underwater;
ER._material = GameObject.Find("RulesetVolumes_GD").GetComponent<RulesetVolume>().GetValue<Material>("_material");
ER._cloudMaterial = GameObject.Find("RulesetVolumes_GD").GetComponent<RulesetVolume>().GetValue<Material>("_cloudMaterial");
var gdRuleset = GameObject.Find("GiantsDeep_Body/Sector_GD/Volumes_GD/RulesetVolumes_GD").GetComponent<EffectRuleset>();
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;
rulesetGO.SetActive(true);

View File

@ -11,7 +11,7 @@ namespace NewHorizons.Builder.Body
{
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");
@ -28,7 +28,7 @@ namespace NewHorizons.Builder.Body
cloakFieldController._innerCloakRadius = radius * 900 / 3000f;
cloakFieldController._nearCloakRadius = radius * 800 / 3000f;
cloakFieldController._referenceFrameVolume = planetGO.GetAttachedOWRigidbody()._attachedRFVolume;
cloakFieldController._referenceFrameVolume = OWRB._attachedRFVolume;
cloakFieldController._exclusionSector = null;
var cloakSectorController = newCloak.AddComponent<CloakSectorController>();

View File

@ -38,13 +38,14 @@ namespace NewHorizons.Builder.Body
cubeSphere.transform.parent = sector?.transform ?? planetGO.transform;
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.GetComponent<MeshFilter>().mesh = mesh;
// 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");
var cubeSphereMR = cubeSphere.AddComponent<MeshRenderer>();

View File

@ -12,8 +12,15 @@ namespace NewHorizons.Builder.Body
{
public static class ProcGenBuilder
{
private static Material quantumMaterial;
private static Material iceMaterial;
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");
icosphere.transform.parent = sector?.transform ?? planetGO.transform;
icosphere.transform.rotation = Quaternion.Euler(90, 0, 0);

View File

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

View File

@ -22,7 +22,7 @@ namespace NewHorizons.Builder.Props
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);
}
@ -31,7 +31,7 @@ namespace NewHorizons.Builder.Props
try
{
var prefab = mod.ModHelper.Assets.Get3DObject(detail.objFilePath, detail.mtlFilePath);
PropBuildManager.ReplaceShaders(prefab);
AssetBundleUtilities.ReplaceShaders(prefab);
prefab.SetActive(false);
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}");
}
}
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)
@ -153,12 +173,11 @@ namespace NewHorizons.Builder.Props
prop.transform.position = position == null ? planetGO.transform.position : planetGO.transform.TransformPoint((Vector3)position);
Quaternion rot = rotation == null ? Quaternion.identity : Quaternion.Euler((Vector3)rotation);
prop.transform.rotation = planetGO.transform.TransformRotation(Quaternion.identity);
if (alignWithNormal)
{
// Apply the rotation after aligning it with normal
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;
}
else

View File

@ -13,6 +13,7 @@ using NewHorizons.Utility;
using OWML.Common;
using NewHorizons.Builder.ShipLog;
using NewHorizons.External.Configs;
using System.IO;
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);
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);
for (int i = 0; i < propInfo.count; i++)
{

View File

@ -8,46 +8,12 @@ using Object = System.Object;
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)
{
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;
DynamicGI.UpdateEnvironment();
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 destroyStockPlanets = true;
public string factRequiredForWarp;
public bool enableTimeLoop = true;
public NomaiCoordinates coords;
public SkyboxConfig skybox;

View File

@ -9,6 +9,6 @@ namespace NewHorizons.External
public string TextureMap { get; set; }
public float MinHeight { 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 bool alignToNormal;
public string[] removeChildren;
public bool removeComponents;
}
public class RaftInfo

View File

@ -318,7 +318,7 @@ namespace NewHorizons.Handlers
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)
{
@ -498,7 +498,7 @@ namespace NewHorizons.Handlers
// Has to go last probably
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;
@ -586,6 +586,7 @@ namespace NewHorizons.Handlers
{
foreach (var childChild in AstroObjectLocator.GetChildren(childAO))
{
if (childChild == null) continue;
var dPos = childChild.transform.position - child.transform.position;
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)
{
DisableBody(GameObject.Find("FocalBody"), delete);
DisableBody(GameObject.Find("SandFunnel_Body"), delete);
}
else if (ao.GetAstroObjectName() == AstroObject.Name.MapSatellite)
{
@ -132,6 +133,9 @@ namespace NewHorizons.Handlers
Logger.Log($"Destroying SunProxy {sunProxy.gameObject.name}");
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

View File

@ -9,6 +9,7 @@ using NewHorizons.Builder.StarSystem;
using UnityEngine;
using Logger = NewHorizons.Utility.Logger;
using Object = UnityEngine.Object;
using NewHorizons.Components;
namespace NewHorizons.Handlers
{
@ -16,8 +17,6 @@ namespace NewHorizons.Handlers
{
public static void LoadSystem(NewHorizonsSystem system)
{
var skybox = GameObject.Find("Skybox/Starfield");
if (system.Config.skybox?.destroyStarField ?? false)
@ -30,6 +29,11 @@ namespace NewHorizons.Handlers
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 static AssetBundle ShaderBundle;
public static AssetBundle NHAssetBundle { get; private set; }
public static Main Instance { get; private set; }
// Settings
public static bool Debug;
public static bool Debug { get; private set; }
private static bool _useCustomTitleScreen;
private static bool _wasConfigured = false;
private static string _defaultSystemOverride;
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, AssetBundle> AssetBundles = new Dictionary<string, AssetBundle>();
public static List<IModBehaviour> MountedAddons = new List<IModBehaviour>();
public static float SecondsLeftInLoop = -1;
public static bool IsSystemReady { get; private set; }
public static float FurthestOrbit { get; set; } = 50000f;
@ -82,6 +84,8 @@ namespace NewHorizons
DebugReload.UpdateReloadButton();
Logger.UpdateLogLevel(Debug ? Logger.LogType.Log : Logger.LogType.Error);
_defaultSystemOverride = config.GetSettingsValue<string>("Default System Override");
var wasUsingCustomTitleScreen = _useCustomTitleScreen;
_useCustomTitleScreen = config.GetSettingsValue<bool>("Custom title screen");
// Reload the title screen if this was updated on it
@ -109,11 +113,7 @@ namespace NewHorizons
destroyStockPlanets = false
}
};
foreach (AssetBundle bundle in AssetBundles.Values)
{
bundle.Unload(true);
}
AssetBundles.Clear();
if (!resetTranslation) return;
TranslationHandler.ClearTables();
TextTranslation.Get().SetLanguage(TextTranslation.Get().GetLanguage());
@ -133,7 +133,7 @@ namespace NewHorizons
Instance = this;
GlobalMessenger<DeathType>.AddListener("PlayerDeath", OnDeath);
GlobalMessenger.AddListener("WakeUp", new Callback(OnWakeUp));
ShaderBundle = Main.Instance.ModHelper.Assets.LoadBundle("AssetBundle/shader");
NHAssetBundle = ModHelper.Assets.LoadBundle("AssetBundle/xen.newhorizons");
ResetConfigs(resetTranslation: false);
@ -172,6 +172,7 @@ namespace NewHorizons
SearchUtilities.ClearCache();
ImageUtilities.ClearCache();
AudioUtilities.ClearCache();
AssetBundleUtilities.ClearCache();
IsSystemReady = false;
}
@ -179,6 +180,28 @@ namespace NewHorizons
{
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;
if (scene.name == "TitleScreen" && _useCustomTitleScreen)
@ -186,21 +209,21 @@ namespace NewHorizons
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.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}");
}
if(_ship != null)
if (_ship != null)
{
_ship = GameObject.Find("Ship_Body").InstantiateInactive();
DontDestroyOnLoad(_ship);
@ -250,7 +273,16 @@ namespace NewHorizons
else
{
// 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 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);
SystemDict[name] = system;
}
@ -312,7 +350,7 @@ namespace NewHorizons
LoadTranslations(folder, mod);
}
}
catch(Exception ex)
catch (Exception ex)
{
Logger.LogError($"{ex.Message}, {ex.StackTrace}");
}
@ -356,15 +394,13 @@ namespace NewHorizons
if (config.Base.CenterOfSolarSystem) config.Orbit.IsStatic = true;
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");
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);
if (system.Config.startHere) SetDefaultSystem(system.Name);
SystemDict.Add(config.StarSystem, system);
BodyDict.Add(config.StarSystem, new List<NewHorizonsBody>());
@ -396,8 +432,7 @@ namespace NewHorizons
OnChangeStarSystem?.Invoke(newStarSystem);
Logger.Log($"Warping to {newStarSystem}");
if(warp && _shipWarpController) _shipWarpController.WarpOut();
_currentStarSystem = newStarSystem;
if (warp && _shipWarpController) _shipWarpController.WarpOut();
_isChangingStarSystem = true;
IsWarping = warp;
WearingSuit = PlayerState.IsWearingSuit();
@ -405,15 +440,24 @@ namespace NewHorizons
// We kill them so they don't move as much
Locator.GetDeathManager().KillPlayer(DeathType.Meditation);
if(newStarSystem == "EyeOfTheUniverse")
OWScene sceneToLoad;
if (newStarSystem == "EyeOfTheUniverse")
{
PlayerData.SaveWarpedToTheEye(60);
LoadManager.LoadSceneAsync(OWScene.EyeOfTheUniverse, true, LoadManager.FadeType.ToBlack, 0.1f, true);
PlayerData.SaveWarpedToTheEye(TimeLoop.GetSecondsRemaining());
sceneToLoad = OWScene.EyeOfTheUniverse;
}
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 _)
@ -421,7 +465,17 @@ namespace NewHorizons
// We reset the solar system on death (unless we just killed the player)
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;
}
}

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("Debris_Body (1)"));
break;
case AstroObject.Name.SunStation:
otherChildren.Add(GameObject.Find("SS_Debris_Body"));
break;
case AstroObject.Name.GiantsDeep:
otherChildren.Add(GameObject.Find("BrambleIsland_Body"));
otherChildren.Add(GameObject.Find("GabbroIsland_Body"));
@ -134,6 +131,10 @@ namespace NewHorizons.Utility
otherChildren.Add(GameObject.Find("BackRaft_Body"));
otherChildren.Add(GameObject.Find("SealRaft_Body"));
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:
break;
}

View File

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

View File

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

View File

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

View File

@ -666,6 +666,11 @@
"items": {
"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",
"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": {
"type": "object",
"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>