diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..dd84ea78 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..bbcbbe7d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/NewHorizons/Builder/Atmosphere/VolumesBuilder.cs b/NewHorizons/Builder/Atmosphere/VolumesBuilder.cs index 569d8b14..f4128814 100644 --- a/NewHorizons/Builder/Atmosphere/VolumesBuilder.cs +++ b/NewHorizons/Builder/Atmosphere/VolumesBuilder.cs @@ -7,7 +7,7 @@ namespace NewHorizons.Atmosphere { static class VolumesBuilder { - public static void Make(GameObject body, float innerRadius, float outerRadius) + public static void Make(GameObject body, float innerRadius, float outerRadius, IPlanetConfig config) { GameObject volumesGO = new GameObject("Volumes"); volumesGO.SetActive(false); @@ -24,17 +24,18 @@ namespace NewHorizons.Atmosphere SS.pointChecksOnly = true; SS.radius = outerRadius; - /*OWTriggerVolume trigvol = */ rulesetGO.AddComponent(); PlanetoidRuleset PR = rulesetGO.AddComponent(); - PR.SetValue("_altitudeFloor", innerRadius); - PR.SetValue("_altitudeCeiling", outerRadius); + PR._altitudeFloor = innerRadius; + PR._altitudeCeiling = outerRadius; + PR._useMinimap = !config.Base.IsSatellite; + PR._useAltimeter = !config.Base.IsSatellite; EffectRuleset ER = rulesetGO.AddComponent(); - ER.SetValue("_type", EffectRuleset.BubbleType.Underwater); - ER.SetValue("_material", GameObject.Find("RulesetVolumes_GD").GetComponent().GetValue("_material")); - ER.SetValue("_cloudMaterial", GameObject.Find("RulesetVolumes_GD").GetComponent().GetValue("_cloudMaterial")); + ER._type = EffectRuleset.BubbleType.Underwater; + ER._material = GameObject.Find("RulesetVolumes_GD").GetComponent().GetValue("_material"); + ER._cloudMaterial = GameObject.Find("RulesetVolumes_GD").GetComponent().GetValue("_cloudMaterial"); volumesGO.transform.localPosition = Vector3.zero; rulesetGO.SetActive(true); diff --git a/NewHorizons/Builder/Body/WaterBuilder.cs b/NewHorizons/Builder/Body/WaterBuilder.cs index f7cccd41..bb155cf7 100644 --- a/NewHorizons/Builder/Body/WaterBuilder.cs +++ b/NewHorizons/Builder/Body/WaterBuilder.cs @@ -81,11 +81,11 @@ namespace NewHorizons.Builder.Body fogGO.name = "OceanFog"; fogGO.transform.localPosition = Vector3.zero; fogGO.transform.localScale = Vector3.one; - if(module.Tint != null) + + if (module.Tint != null) { var adjustedColour = module.Tint.ToColor() / 4f; - adjustedColour.a = 1f; - + adjustedColour.a = adjustedColour.a * 4f; fogGO.GetComponent().material.color = adjustedColour; } diff --git a/NewHorizons/Builder/General/RFVolumeBuilder.cs b/NewHorizons/Builder/General/RFVolumeBuilder.cs index c93811f9..4e17d11d 100644 --- a/NewHorizons/Builder/General/RFVolumeBuilder.cs +++ b/NewHorizons/Builder/General/RFVolumeBuilder.cs @@ -22,22 +22,22 @@ namespace NewHorizons.Builder.General ReferenceFrameVolume RFV = rfGO.AddComponent(); ReferenceFrame RV = new ReferenceFrame(rigidbody); - RV.SetValue("_minSuitTargetDistance", sphereOfInfluence); - RV.SetValue("_maxTargetDistance", 0); - RV.SetValue("_autopilotArrivalDistance", sphereOfInfluence * 2f); - RV.SetValue("_autoAlignmentDistance", sphereOfInfluence * 1.5f); + RV._minSuitTargetDistance = sphereOfInfluence; + RV._maxTargetDistance = 0; + RV._autopilotArrivalDistance = 2.0f * sphereOfInfluence; + RV._autoAlignmentDistance = sphereOfInfluence * 1.5f; + + RV._hideLandingModePrompt = false; + RV._matchAngularVelocity = true; + RV._minMatchAngularVelocityDistance = 70; + RV._maxMatchAngularVelocityDistance = 400; + RV._bracketsRadius = sphereOfInfluence; - RV.SetValue("_hideLandingModePrompt", false); - RV.SetValue("_matchAngularVelocity", true); - RV.SetValue("_minMatchAngularVelocityDistance", 70); - RV.SetValue("_maxMatchAngularVelocityDistance", 400); - RV.SetValue("_bracketsRadius", sphereOfInfluence); - - RFV.SetValue("_referenceFrame", RV); - RFV.SetValue("_minColliderRadius", sphereOfInfluence); - RFV.SetValue("_maxColliderRadius", sphereOfInfluence * 2f); - RFV.SetValue("_isPrimaryVolume", true); - RFV.SetValue("_isCloseRangeVolume", false); + RFV._referenceFrame = RV; + RFV._minColliderRadius = sphereOfInfluence; + RFV._maxColliderRadius = sphereOfInfluence * 2f; + RFV._isPrimaryVolume = true; + RFV._isCloseRangeVolume = false; rfGO.SetActive(true); } diff --git a/NewHorizons/Builder/General/SpawnPointBuilder.cs b/NewHorizons/Builder/General/SpawnPointBuilder.cs index 37b5a2d6..cd54f9a7 100644 --- a/NewHorizons/Builder/General/SpawnPointBuilder.cs +++ b/NewHorizons/Builder/General/SpawnPointBuilder.cs @@ -22,7 +22,7 @@ namespace NewHorizons.Builder.General playerSpawn = spawnGO.AddComponent(); spawnGO.transform.rotation = Quaternion.FromToRotation(Vector3.up, (playerSpawn.transform.position - body.transform.position).normalized); - spawnGO.transform.position = spawnGO.transform.position + spawnGO.transform.TransformDirection(Vector3.up) * 2f; + spawnGO.transform.position = spawnGO.transform.position + spawnGO.transform.TransformDirection(Vector3.up) * 4f; GameObject.FindObjectOfType().SetInitialSpawnPoint(playerSpawn); } @@ -41,7 +41,7 @@ namespace NewHorizons.Builder.General ship.transform.position = spawnPoint.transform.position; ship.transform.rotation = Quaternion.FromToRotation(Vector3.up, (spawnPoint.transform.position - body.transform.position).normalized); // Move it up a bit more - ship.transform.position = ship.transform.position + ship.transform.TransformDirection(Vector3.up) * 5f; + ship.transform.position = ship.transform.position + ship.transform.TransformDirection(Vector3.up) * 4f; ship.GetRequiredComponent().SetBodyToMatch(rb); diff --git a/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs b/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs index aa71f286..1f84fcee 100644 --- a/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs +++ b/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs @@ -21,10 +21,15 @@ namespace NewHorizons.Builder.Orbital return Update(initialMotion, body, primaryBody, OWRB, orbit); } + public static float SiderealPeriodToAngularSpeed(float siderealPeriod) + { + return siderealPeriod == 0 ? 0f : 2f * Mathf.PI / (siderealPeriod * 60f); + } + public static InitialMotion Update(InitialMotion initialMotion, GameObject body, AstroObject primaryBody, OWRigidbody OWRB, OrbitModule orbit) { // Rotation - initialMotion.SetValue("_initAngularSpeed", orbit.SiderealPeriod == 0 ? 0f : 2f * Mathf.PI / (orbit.SiderealPeriod * 60f)); + initialMotion.SetValue("_initAngularSpeed", SiderealPeriodToAngularSpeed(orbit.SiderealPeriod)); var rotationAxis = Quaternion.AngleAxis(orbit.AxialTilt + 90f, Vector3.right) * Vector3.up; body.transform.rotation = Quaternion.FromToRotation(Vector3.up, rotationAxis); diff --git a/NewHorizons/Builder/Props/DetailBuilder.cs b/NewHorizons/Builder/Props/DetailBuilder.cs index 7970b7e0..cbfc88ea 100644 --- a/NewHorizons/Builder/Props/DetailBuilder.cs +++ b/NewHorizons/Builder/Props/DetailBuilder.cs @@ -16,10 +16,12 @@ namespace NewHorizons.Builder.Props { public static void Make(GameObject go, Sector sector, IPlanetConfig config, IModAssets assets, string uniqueModName, PropModule.DetailInfo detail) { + GameObject detailGO = null; + if (detail.assetBundle != null) { var prefab = PropBuildManager.LoadPrefab(detail.assetBundle, detail.path, uniqueModName, assets); - MakeDetail(go, sector, prefab, detail.position, detail.rotation, detail.scale, detail.alignToNormal, detail.generateColliders); + detailGO = MakeDetail(go, sector, prefab, detail.position, detail.rotation, detail.scale, detail.alignToNormal); } else if (detail.objFilePath != null) { @@ -27,24 +29,33 @@ namespace NewHorizons.Builder.Props { var prefab = assets.Get3DObject(detail.objFilePath, detail.mtlFilePath); prefab.SetActive(false); - MakeDetail(go, sector, prefab, detail.position, detail.rotation, detail.scale, detail.alignToNormal, detail.generateColliders); + detailGO = MakeDetail(go, sector, prefab, detail.position, detail.rotation, detail.scale, detail.alignToNormal); } catch (Exception e) { Logger.LogError($"Could not load 3d object {detail.objFilePath} with texture {detail.mtlFilePath} : {e.Message}"); } } - else MakeDetail(go, sector, detail.path, detail.position, detail.rotation, detail.scale, detail.alignToNormal, detail.generateColliders); + else detailGO = MakeDetail(go, sector, detail.path, detail.position, detail.rotation, detail.scale, detail.alignToNormal); + + if(detailGO != null && detail.removeChildren != null) + { + foreach(var childPath in detail.removeChildren) + { + var childObj = SearchUtilities.Find(SearchUtilities.GetPath(detailGO.transform) + "/" + childPath); + childObj.gameObject.SetActive(false); + } + } } - public static GameObject MakeDetail(GameObject go, Sector sector, string propToClone, MVector3 position, MVector3 rotation, float scale, bool alignWithNormal, bool generateColliders) + public static GameObject MakeDetail(GameObject go, Sector sector, string propToClone, MVector3 position, MVector3 rotation, float scale, bool alignWithNormal) { var prefab = SearchUtilities.Find(propToClone); if (prefab == null) Logger.LogError($"Couldn't find detail {propToClone}"); - return MakeDetail(go, sector, prefab, position, rotation, scale, alignWithNormal, generateColliders); + return MakeDetail(go, sector, prefab, position, rotation, scale, alignWithNormal); } - public static GameObject MakeDetail(GameObject go, Sector sector, GameObject prefab, MVector3 position, MVector3 rotation, float scale, bool alignWithNormal, bool generateColliders) + public static GameObject MakeDetail(GameObject go, Sector sector, GameObject prefab, MVector3 position, MVector3 rotation, float scale, bool alignWithNormal) { if (prefab == null) return null; @@ -77,7 +88,11 @@ namespace NewHorizons.Builder.Props if (component is GhostIK) (component as GhostIK).enabled = false; if (component is GhostEffects) (component as GhostEffects).enabled = false; - if (component is Animator) Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => (component as Animator).enabled = true); + // If it's not a moving anglerfish make sure the anim controller is off + if(component is AnglerfishAnimController && component.GetComponentInParent() == null) + Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => (component as AnglerfishAnimController).enabled = false); + + if (component is Animator) Main.Instance.ModHelper.Events.Unity.FireInNUpdates(() => (component as Animator).enabled = true, 5); if (component is Collider) Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => (component as Collider).enabled = true); if(component is Shape) Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => (component as Shape).enabled = true); @@ -104,17 +119,6 @@ namespace NewHorizons.Builder.Props Logger.LogError($"Couldn't update AnglerFish chase speed: {e.Message}"); } } - - // Mesh colliders - if (generateColliders) - { - if (component is MeshFilter && component.gameObject.GetComponent() == null) - { - var mesh = (component as MeshFilter).mesh; - if (mesh.isReadable) component.gameObject.AddComponent(); - else Logger.LogError($"Couldn't change mesh for {component.gameObject.name} because it is not readable"); - } - } } prop.transform.position = position == null ? go.transform.position : go.transform.TransformPoint((Vector3)position); diff --git a/NewHorizons/Builder/Props/DialogueBuilder.cs b/NewHorizons/Builder/Props/DialogueBuilder.cs index 79ebaa44..3cc77e70 100644 --- a/NewHorizons/Builder/Props/DialogueBuilder.cs +++ b/NewHorizons/Builder/Props/DialogueBuilder.cs @@ -15,7 +15,6 @@ namespace NewHorizons.Builder.Props { public static void Make(GameObject go, Sector sector, PropModule.DialogueInfo info, IModHelper mod) { - if (info.blockAfterPersistentCondition != null && PlayerData._currentGameSave.GetPersistentCondition(info.blockAfterPersistentCondition)) return; var dialogue = MakeConversationZone(go, sector, info, mod); diff --git a/NewHorizons/Builder/Props/ScatterBuilder.cs b/NewHorizons/Builder/Props/ScatterBuilder.cs index 0538fee2..4990c867 100644 --- a/NewHorizons/Builder/Props/ScatterBuilder.cs +++ b/NewHorizons/Builder/Props/ScatterBuilder.cs @@ -71,7 +71,7 @@ namespace NewHorizons.Builder.Props height -= 0.2f; } - var prop = DetailBuilder.MakeDetail(go, sector, prefab, (MVector3)(point.normalized * height), null, propInfo.scale, true, propInfo.generateColliders); + var prop = DetailBuilder.MakeDetail(go, sector, prefab, (MVector3)(point.normalized * height), null, propInfo.scale, true); if (propInfo.offset != null) prop.transform.localPosition += prop.transform.TransformVector(propInfo.offset); if (propInfo.rotation != null) prop.transform.rotation *= Quaternion.Euler(propInfo.rotation); points.RemoveAt(randomInd); diff --git a/NewHorizons/Builder/Updater/OrbitUpdater.cs b/NewHorizons/Builder/Updater/OrbitUpdater.cs new file mode 100644 index 00000000..695d9c87 --- /dev/null +++ b/NewHorizons/Builder/Updater/OrbitUpdater.cs @@ -0,0 +1,69 @@ +using NewHorizons.Builder.Orbital; +using NewHorizons.OrbitalPhysics; +using NewHorizons.Utility; +using PacificEngine.OW_CommonResources.Game.Resource; +using PacificEngine.OW_CommonResources.Game.State; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Logger = NewHorizons.Utility.Logger; + +namespace NewHorizons.Builder.Updater +{ + public static class OrbitUpdater + { + public static void Update(NewHorizonsBody body, GameObject go) + { + var mapping = Planet.defaultMapping; + var heavenlyBody = CommonResourcesUtilities.HeavenlyBodyFromAstroObject(AstroObjectLocator.GetAstroObject(body.Config.Name)); + + Logger.Log($"Updating position of {body.Config.Name}/{heavenlyBody}"); + + if (heavenlyBody != HeavenlyBody.None) + { + var original = mapping[heavenlyBody]; + + var coords = OrbitalHelper.KeplerCoordinatesFromOrbitModule(body.Config.Orbit); + + var parent = original.state.parent; + if (body.Config.Orbit.PrimaryBody != null) + { + var parentAO = AstroObjectLocator.GetAstroObject(body.Config.Orbit.PrimaryBody); + var newParent = CommonResourcesUtilities.HeavenlyBodyFromAstroObject(parentAO); + if (newParent != HeavenlyBody.None) + { + Logger.LogWarning($"Sorry, can't change primary body for planets yet. You tried making {body.Config.Name} orbit {newParent}"); + /* + parent = newParent; + // Have to change the gravity stuff + go.GetComponentInChildren()._detectableFields = new ForceVolume[] { parentAO.GetGravityVolume() }; + go.GetComponent()._primaryBody = parentAO; + */ + } + else Logger.LogError($"Couldn't find new parent {body.Config.Orbit.PrimaryBody}"); + } + + var planetoid = new Planet.Plantoid( + original.size, + original.gravity, + go.transform.rotation, + InitialMotionBuilder.SiderealPeriodToAngularSpeed(body.Config.Orbit.SiderealPeriod), + parent, + coords + ); + + mapping[heavenlyBody] = planetoid; + + Planet.defaultMapping = mapping; + Planet.mapping = mapping; + } + else + { + Logger.LogError($"Couldn't find heavenlyBody for {body.Config.Name}"); + } + } + } +} diff --git a/NewHorizons/External/OrbitModule.cs b/NewHorizons/External/OrbitModule.cs index 5e005f2a..d8ec66b4 100644 --- a/NewHorizons/External/OrbitModule.cs +++ b/NewHorizons/External/OrbitModule.cs @@ -9,7 +9,7 @@ namespace NewHorizons.External { public class OrbitModule : Module { - public int SemiMajorAxis { get; set; } = 5000; + public int SemiMajorAxis { get; set; } public float Inclination { get; set; } public string PrimaryBody { get; set; } public bool IsMoon { get; set; } diff --git a/NewHorizons/External/PlanetConfig.cs b/NewHorizons/External/PlanetConfig.cs index 7539d0cf..f084011f 100644 --- a/NewHorizons/External/PlanetConfig.cs +++ b/NewHorizons/External/PlanetConfig.cs @@ -34,7 +34,7 @@ namespace NewHorizons.External public PlanetConfig(Dictionary dict) { - // Always have to have a base module and orbit module + // Always have to have a base module Base = new BaseModule(); Orbit = new OrbitModule(); diff --git a/NewHorizons/External/PropModule.cs b/NewHorizons/External/PropModule.cs index effb7d52..496c7f31 100644 --- a/NewHorizons/External/PropModule.cs +++ b/NewHorizons/External/PropModule.cs @@ -27,7 +27,6 @@ namespace NewHorizons.External public MVector3 offset; public MVector3 rotation; public float scale { get; set; } = 1f; - public bool generateColliders = false; } public class DetailInfo @@ -40,7 +39,7 @@ namespace NewHorizons.External public MVector3 rotation; public float scale { get; set; } = 1f; public bool alignToNormal; - public bool generateColliders = false; + public string[] removeChildren; } public class RaftInfo diff --git a/NewHorizons/Handlers/StarChartHandler.cs b/NewHorizons/Handlers/StarChartHandler.cs index d60d5bb0..6fafab15 100644 --- a/NewHorizons/Handlers/StarChartHandler.cs +++ b/NewHorizons/Handlers/StarChartHandler.cs @@ -49,4 +49,4 @@ namespace NewHorizons.Handlers oneShotSource); } } -} +} \ No newline at end of file diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index e9f6274f..a0ff7957 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -4,14 +4,19 @@ using NewHorizons.Builder.Body; using NewHorizons.Builder.General; using NewHorizons.Builder.Orbital; using NewHorizons.Builder.Props; +using NewHorizons.Builder.Updater; using NewHorizons.Components; using NewHorizons.External; using NewHorizons.External.VariableSize; +using NewHorizons.Handlers; using NewHorizons.OrbitalPhysics; using NewHorizons.Utility; using OWML.Common; using OWML.ModHelper; using OWML.Utils; +using PacificEngine.OW_CommonResources.Game.Player; +using PacificEngine.OW_CommonResources.Game.Resource; +using PacificEngine.OW_CommonResources.Game.State; using System; using System.Collections.Generic; using System.IO; @@ -423,7 +428,16 @@ namespace NewHorizons } // Do stuff that's shared between generating new planets and updating old ones - return SharedGenerateBody(body, go, sector, rb); + go = SharedGenerateBody(body, go, sector, rb); + + // Update a position using CommonResources + // Since orbits are always there just check if they set a semi major axis + if (body.Config.Orbit != null && body.Config.Orbit.SemiMajorAxis != 0f) + { + OrbitUpdater.Update(body, go); + } + + return go; } #endregion Load @@ -487,7 +501,7 @@ namespace NewHorizons var sector = MakeSector.Make(go, owRigidBody, sphereOfInfluence * 2f); ao.SetValue("_rootSector", sector); - VolumesBuilder.Make(go, body.Config.Base.SurfaceSize, sphereOfInfluence); + VolumesBuilder.Make(go, body.Config.Base.SurfaceSize, sphereOfInfluence, body.Config); if (body.Config.HeightMap != null) HeightMapBuilder.Make(go, body.Config.HeightMap, body.Mod.Assets); @@ -506,13 +520,7 @@ namespace NewHorizons body.Object = go; // Now that we're done move the planet into place - go.transform.parent = Locator.GetRootTransform(); - go.transform.position = OrbitalHelper.GetCartesian(new OrbitalHelper.Gravity(1, 100), body.Config.Orbit).Item1 + (primaryBody == null ? Vector3.zero : primaryBody.transform.position); - - if (go.transform.position.magnitude > FurthestOrbit) - { - FurthestOrbit = go.transform.position.magnitude + 30000f; - } + UpdatePosition(go, body, primaryBody); // Have to do this after setting position var initialMotion = InitialMotionBuilder.Make(go, primaryBody, owRigidBody, body.Config.Orbit); @@ -605,6 +613,17 @@ namespace NewHorizons return go; } + private void UpdatePosition(GameObject go, NewHorizonsBody body, AstroObject primaryBody) + { + go.transform.parent = Locator.GetRootTransform(); + go.transform.position = OrbitalHelper.GetCartesian(new OrbitalHelper.Gravity(1, 100), body.Config.Orbit).Item1 + (primaryBody == null ? Vector3.zero : primaryBody.transform.position); + + if (go.transform.position.magnitude > FurthestOrbit) + { + FurthestOrbit = go.transform.position.magnitude + 30000f; + } + } + #endregion Body generation #region Change star system diff --git a/NewHorizons/Tools/Patches.cs b/NewHorizons/Tools/Patches.cs index d9a92420..bd1fdf4c 100644 --- a/NewHorizons/Tools/Patches.cs +++ b/NewHorizons/Tools/Patches.cs @@ -77,9 +77,12 @@ namespace NewHorizons.Tools public static bool CheckShipOutersideSolarSystem(PlayerState __instance, ref bool __result) { + if (PlayerState._inBrambleDimension) return false; + Transform sunTransform = Locator.GetSunTransform(); OWRigidbody shipBody = Locator.GetShipBody(); - __result = sunTransform != null && shipBody != null && (sunTransform.position - shipBody.transform.position).sqrMagnitude > Main.FurthestOrbit * Main.FurthestOrbit * 4f; + var maxDist2 = Mathf.Max(900000000f, Main.FurthestOrbit * Main.FurthestOrbit * 2f); + __result = sunTransform != null && shipBody != null && (sunTransform.position - shipBody.transform.position).sqrMagnitude > maxDist2; return false; } diff --git a/NewHorizons/Utility/CommonResourcesUtilities.cs b/NewHorizons/Utility/CommonResourcesUtilities.cs new file mode 100644 index 00000000..b2da17f3 --- /dev/null +++ b/NewHorizons/Utility/CommonResourcesUtilities.cs @@ -0,0 +1,61 @@ +using PacificEngine.OW_CommonResources.Game.Resource; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NewHorizons.Utility +{ + public static class CommonResourcesUtilities + { + public static HeavenlyBody HeavenlyBodyFromAstroObject(AstroObject obj) + { + switch (obj.GetAstroObjectName()) + { + case AstroObject.Name.CustomString: + return HeavenlyBody.FromString(obj.GetCustomName()); + case AstroObject.Name.BrittleHollow: + return HeavenlyBodies.BrittleHollow; + case AstroObject.Name.CaveTwin: + return HeavenlyBodies.EmberTwin; + case AstroObject.Name.Comet: + return HeavenlyBodies.Interloper; + case AstroObject.Name.DarkBramble: + return HeavenlyBodies.DarkBramble; + case AstroObject.Name.DreamWorld: + return HeavenlyBodies.DreamWorld; + case AstroObject.Name.GiantsDeep: + return HeavenlyBodies.GiantsDeep; + case AstroObject.Name.HourglassTwins: + return HeavenlyBodies.HourglassTwins; + case AstroObject.Name.MapSatellite: + return HeavenlyBodies.SatiliteMapping; + case AstroObject.Name.ProbeCannon: + return HeavenlyBodies.ProbeCannon; + case AstroObject.Name.QuantumMoon: + return HeavenlyBodies.QuantumMoon; + case AstroObject.Name.RingWorld: + return HeavenlyBodies.Stranger; + case AstroObject.Name.Sun: + return HeavenlyBodies.Sun; + case AstroObject.Name.SunStation: + return HeavenlyBodies.SunStation; + case AstroObject.Name.TimberHearth: + return HeavenlyBodies.TimberHearth; + case AstroObject.Name.TimberMoon: + return HeavenlyBodies.Attlerock; + case AstroObject.Name.TowerTwin: + return HeavenlyBodies.AshTwin; + case AstroObject.Name.VolcanicMoon: + return HeavenlyBodies.HollowLantern; + case AstroObject.Name.WhiteHole: + return HeavenlyBodies.WhiteHole; + case AstroObject.Name.WhiteHoleTarget: + return HeavenlyBodies.WhiteHoleStation; + default: + return HeavenlyBodies.None; + } + } + } +} diff --git a/NewHorizons/Utility/DebugRaycaster.cs b/NewHorizons/Utility/DebugRaycaster.cs index 3d8e3116..fa7d4760 100644 --- a/NewHorizons/Utility/DebugRaycaster.cs +++ b/NewHorizons/Utility/DebugRaycaster.cs @@ -13,7 +13,7 @@ namespace NewHorizons.Utility public class DebugRaycaster : MonoBehaviour { private OWRigidbody _rb; - + private void Awake() { _rb = this.GetRequiredComponent(); diff --git a/NewHorizons/Utility/MColor.cs b/NewHorizons/Utility/MColor.cs index 228ac25a..e18e6b66 100644 --- a/NewHorizons/Utility/MColor.cs +++ b/NewHorizons/Utility/MColor.cs @@ -17,7 +17,7 @@ namespace NewHorizons.Utility public int B { get; } public int A { get; } - public Color32 ToColor32() => new Color(R, G, B, A); + public Color32 ToColor32() => new Color32((byte)R, (byte)G, (byte)B, (byte)A); public Color ToColor() => new Color(R / 255f, G / 255f, B / 255f, A / 255f); } diff --git a/NewHorizons/Utility/SearchUtilities.cs b/NewHorizons/Utility/SearchUtilities.cs index 370681bc..bd164b7b 100644 --- a/NewHorizons/Utility/SearchUtilities.cs +++ b/NewHorizons/Utility/SearchUtilities.cs @@ -99,60 +99,68 @@ namespace NewHorizons.Utility public static GameObject Find(string path) { - var go = GameObject.Find(path); - - var names = path.Split(new char[] { '\\', '/' }); - if (go == null) + try { + var go = GameObject.Find(path); - // Get the root object and hope its the right one - var root = GameObject.Find(names[0]); - if (root == null) root = FindObjectOfTypeAndName(names[0]); - - var t = root?.transform; - if (t == null) + var names = path.Split(new char[] { '\\', '/' }); + if (go == null) { - Logger.LogWarning($"Couldn't find root object in path ({names[0]})"); - return null; - } - for (int i = 1; i < names.Length; i++) - { - var child = t.transform.Find(names[i]); + // Get the root object and hope its the right one + var root = GameObject.Find(names[0]); + if (root == null) root = FindObjectOfTypeAndName(names[0]); - if(child == null) + var t = root?.transform; + if (t == null) { - foreach(Transform c in t.GetComponentsInChildren(true)) + Logger.LogWarning($"Couldn't find root object in path ({names[0]})"); + } + else + { + for (int i = 1; i < names.Length; i++) { - if(t.name.Equals(names[i])) + var child = t.transform.Find(names[i]); + + if (child == null) { - child = c; + foreach (Transform c in t.GetComponentsInChildren(true)) + { + if (t.name.Equals(names[i])) + { + child = c; + break; + } + } + } + + if (child == null) + { + Logger.LogWarning($"Couldn't find object in path ({names[i]})"); + t = null; break; } + + t = child; } } - if (child == null) - { - Logger.LogWarning($"Couldn't find object in path ({names[i]})"); - t = null; - break; - } - - t = child; + go = t?.gameObject; } - go = t?.gameObject; - } + if (go == null) + { + var name = names.Last(); + Logger.LogWarning($"Couldn't find object {path}, will look for potential matches for name {name}"); + go = FindObjectOfTypeAndName(name); + } - if(go == null) + return go; + } + catch(Exception) { - var name = names.Last(); - Logger.LogWarning($"Couldn't find object {path}, will look for potential matches for name {name}"); - go = FindObjectOfTypeAndName(name); + return null; } - - return go; } public static List GetAllChildren(GameObject parent) diff --git a/NewHorizons/manifest.json b/NewHorizons/manifest.json index 2e7a1f51..493970eb 100644 --- a/NewHorizons/manifest.json +++ b/NewHorizons/manifest.json @@ -3,7 +3,7 @@ "author": "xen", "name": "New Horizons", "uniqueName": "xen.NewHorizons", - "version": "0.8.1", + "version": "0.8.3", "owmlVersion": "2.1.0", "dependencies": [ "PacificEngine.OW_CommonResources" ], "conflicts": [ "Raicuparta.QuantumSpaceBuddies", "Vesper.OuterWildsMMO", "Vesper.AutoResume" ] diff --git a/README.md b/README.md index 4b4efbe0..8c267445 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![new horizons thumbnail](https://user-images.githubusercontent.com/22628069/146680547-bd815057-9f4e-42da-a6c4-84d3ff82ff2c.png) +![new horizons thumbnail 2](https://user-images.githubusercontent.com/22628069/154112130-b777f618-245f-44c9-9408-e11141fc5fde.png) ![Current version](https://img.shields.io/github/manifest-json/v/xen-42/outer-wilds-new-horizons?color=gree&filename=NewHorizons%2Fmanifest.json) ![Downloads](https://img.shields.io/github/downloads/xen-42/outer-wilds-new-horizons/total) @@ -62,29 +62,30 @@ Check the ship's log for how to use your warp drive to travel between star syste - Separate solar system scenes accessible via wormhole (done) - Warp drive with target set in ship's log (done) - Implement custom dialogue (done) +- Make a template Unity project to use with NH, including all game scripts recovered using UtinyRipper to make AssetBundle creation easier ([done](https://github.com/xen-42/outer-wilds-unity-template)) - Procedural terrain generation (started) - "Quantum" planet parameters - Better terrain and water LOD - Edit existing planet orbits - Implement all planet features: - - Tornados + floating islands - - Funnels (sand/water/lava/star) (done) + - Funnels (sand/water/lava/star) (done) - Variable surface height (sand/water/lava/star) (done) + - Zero-g volumes (done, with Unity template) + - Ghost matter (done, by copying props via game hierarchy) + - Tornados + floating islands - Let any star go supernova - Geysers - Meteors - - Ghost matter - Pocket dimensions - Timed position/velocity changes - - Zero-g volumes - Implement custom Nomai scrolls - Implement custom translatable writing -- Implement constant gravity volumes - Destroy planets that fall into a star -- Make a template Unity project to use with NH, including all game scripts recovered using UtinyRipper to make AssetBundle creation easier ## How to create your own planets using configs +**Note that I'm more than happy to help you debug your planet config files, but please don't just use notepad to edit them. Use something like Visual Studio Code that will check your .json file for errors. It will save both of us time.** + There is a template [here](https://github.com/xen-42/ow-new-horizons-config-template) if you want to release your own planet mod using configs. You can learn how the configs work by picking apart the [Real Solar System](https://github.com/xen-42/outer-wilds-real-solar-system) mod or the [New Horizons Examples](https://github.com/xen-42/ow-new-horizons-examples) mod. Planets are created using a JSON file format structure, and placed in a folder called `planets` (or in any sub-directory of it) in the location where New Horizons is installed (by default this folder doesn't exist, you have to create it within the `xen.NewHorizons` directory). @@ -96,7 +97,7 @@ To locate this directory, click the "..." symbol next to "New Horizons" in the O ![Create a planets folder in the mod directory](https://user-images.githubusercontent.com/22628069/149638007-26b872ab-f02e-455f-a7fd-99d0d2a96de8.png) Now that you have created your planets folder, this is where you will put your planet config files. A config file will look something like this: -``` +```json { "name" : "Wetrock", "$schema": "https://raw.githubusercontent.com/xen-42/outer-wilds-new-horizons/master/NewHorizons/schema.json", @@ -104,7 +105,6 @@ Now that you have created your planets folder, this is where you will put your p "Base" : { "groundSize" : 100, - "waterSize" : 101, "surfaceSize" : 101, "surfaceGravity" : 12, "hasMapMarker" : true, @@ -155,7 +155,7 @@ Each { must match up with a closing } to denote its section. If you don't know h Modules look like this: -``` +```json "Star" : { "size" : 3000, @@ -174,26 +174,26 @@ In this example the `Star` module has a `size` field and a `tint` field. Since t Most fields are either true/false, a decimal number, and integer number, or a string (word with quotation marks around it). There are also the following types of values: #### Colour: -``` +```json { - "r" : 200, - "g" : 255, - "b" : 255, - "a" : 255 + "r" : 200, + "g" : 255, + "b" : 255, + "a" : 255 } ``` #### Position: -``` +```json { - "x" : 182.4, - "y" : 227.4, - "z" : 62.7, + "x" : 182.4, + "y" : 227.4, + "z" : 62.7, } ``` #### Scale curve: -``` +```json [ {"time":0, "value":1}, {"time":5, "value":0}, @@ -271,7 +271,7 @@ Let's you put asteroids in orbit around a planet or star. Can probably negativel ### FocalPoint If you want to have binary planets or stars you have to do a few extra steps. First you make a focal point body. Here's an example (note the "..." means you'd be writing stuff there but it isn't important for the example. Don't literally put "..."): -``` +```json { "name" : "Alpha Centauri", "Base" : @@ -292,7 +292,7 @@ If you want to have binary planets or stars you have to do a few extra steps. Fi } ``` Then you would make config files for the two bodies in the binary pair. -``` +```json { "name" : "Alpha Centauri A", "Base" : @@ -312,7 +312,7 @@ Then you would make config files for the two bodies in the binary pair. } ``` and -``` +```json { "name" : "Alpha Centauri B", "Base" : @@ -346,7 +346,7 @@ The different things you can specify in the props section are: - "scatter" : (list) I'll just give an example. -``` +```json "scatter" : [ {"path" : "DreamWorld_Body/Sector_DreamWorld/Sector_DreamZone_1/Props_DreamZone_1/OtherComponentsGroup/Trees_Z1/DreamHouseIsland/Tree_DW_M_Var", "count" : 12} ] @@ -363,14 +363,22 @@ A detail info object can have the following parameters: - "rotation" : (x, y, z) the euler angle rotation from a 3d vector (in degrees) - "scale" : (decimal number) - "alignToNormal" : (true/false) If it should align with the normal vector of the surface its own (overwrites rotation) +- "removeChildren" : (list of strings) relative paths of children to get rid of You have three options: Load from the scene hierarchy by setting "path", load from an asset bundle by setting "path" and "assetBundle", or load an obj file by setting "objFilePath" and "mtlFilePath". Asset bundles give much better results than .obj's. #### Asset Bundles + +Here is a template project: [Outer Wilds Unity Template](https://github.com/xen-42/outer-wilds-unity-template) + +The template project contains ripped versions of all the game scripts, meaning you can put things like DirectionalForceVolumes in your Unity project to have artificial gravity volumes loaded right into the game. + +If for whatever reason you want to set up a Unity project manually instead of using the template, follow these instructions: + 1. Start up a Unity 2017 project (I use Unity 2017.4.40f1 (64-bit), so if you use something else I can't guarantee it will work). The DLC updated Outer Wilds to 2019.4.27 so that probably works but I personally haven't tried it. 2. In the "Assets" folder in Unity, create a new folder called "Editor". In it create a file called "CreateAssetBundle.cs" with the following code in it: -``` +```cs using UnityEditor; using UnityEngine; using System.IO; @@ -407,7 +415,7 @@ An array of object, each one has the following properties: #### XML Here's an example dialogue XML: -``` +```xml EXAMPLE NPC @@ -529,7 +537,7 @@ Signal info objects can then have the following values set: - "insideCloak" : (true/false) You have to set this to true if the signal is inside a cloaking field Here's an example of what all this looks like, for more check my [Signals+](https://github.com/xen-42/outer-wilds-signals-plus) add-on: -``` +```json "Signal" : { "Signals" : @@ -570,7 +578,7 @@ This allows you to make black holes and white holes, and to pair them. ### How to destroy existing planets You do this (but with the appropriate name) as it's own config. -``` +```json { "name" : "Ember Twin", "destroy" : true, @@ -585,11 +593,19 @@ Similar to above, make a config where "Name" is the name of the planet. The name Only some of the above modules are supported (currently) for existing planets. Things you cannot modify for existing planets include: heightmaps, procedural generation, gravity, or their orbits. You also can't make them into stars or binary focal points (but why would you want to, just delete them and replace them entirely). However this still means there are many things you can do: completely change their atmospheres, give them rings, asteroid belts, comet tails, lava, water, prop details, or signals. +You can also delete parts of an existing planet. Here's part of an example config which would delete the rising sand from Ember Twin: +```json +"name" : "Ember Twin", +"childrenToDestroy" : ["SandSphere_Rising"], +``` + +In `childrenToDestroy` you list the relative paths for the children of the planet's gameObject that you want to delete. + ## How to use New Horizons in other mods First create the following interface in your mod: -``` +```cs public interface INewHorizons { void Create(Dictionary config, IModBehaviour mod); @@ -601,7 +617,7 @@ public interface INewHorizons ``` In your main `ModBehaviour` class you can get the NewHorizons API like so: -``` +```cs INewHorizons NewHorizonsAPI = ModHelper.Interaction.GetModApi("xen.NewHorizons") ```