mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
Dream arrival point and dream campfire builders
This commit is contained in:
parent
2b3b7e277e
commit
1be3bf209f
@ -0,0 +1,63 @@
|
||||
using NewHorizons.Components.Props;
|
||||
using NewHorizons.External.Modules.Props;
|
||||
using NewHorizons.External.Modules.Props.EchoesOfTheEye;
|
||||
using NewHorizons.Handlers;
|
||||
using NewHorizons.Utility;
|
||||
using NewHorizons.Utility.OWML;
|
||||
using OWML.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NewHorizons.Builder.Props.EchoesOfTheEye
|
||||
{
|
||||
public static class DreamArrivalPointBuilder
|
||||
{
|
||||
private static GameObject _prefab;
|
||||
|
||||
internal static void InitPrefab()
|
||||
{
|
||||
if (_prefab == null)
|
||||
{
|
||||
_prefab = SearchUtilities.Find("DreamWorld_Body/Sector_DreamWorld/Sector_DreamZone_1/DreamFireHouse_1/Interactibles_DreamFireHouse_1/Prefab_IP_DreamArrivalPoint_Zone1").InstantiateInactive().Rename("Prefab_DreamArrivalPoint").DontDestroyOnLoad();
|
||||
if (_prefab == null)
|
||||
{
|
||||
NHLogger.LogWarning($"Tried to make a dream arrival point but couldn't. Do you have the DLC installed?");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_prefab.AddComponent<DestroyOnDLC>()._destroyOnDLCNotOwned = true;
|
||||
var dreamArrivalPoint = _prefab.GetComponent<DreamArrivalPoint>();
|
||||
dreamArrivalPoint._location = DreamArrivalPoint.Location.Undefined;
|
||||
dreamArrivalPoint._sector = null;
|
||||
dreamArrivalPoint._entrywayVolumes = [];
|
||||
dreamArrivalPoint._raftSpawn = null;
|
||||
dreamArrivalPoint._connectedDreamCampfire = null;
|
||||
dreamArrivalPoint._campfire._sector = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static GameObject Make(GameObject planetGO, Sector sector, DreamArrivalPointInfo info, IModBehaviour mod)
|
||||
{
|
||||
InitPrefab();
|
||||
|
||||
if (_prefab == null || sector == null) return null;
|
||||
|
||||
var arrivalPointObj = DetailBuilder.Make(planetGO, sector, mod, _prefab, new DetailInfo(info));
|
||||
|
||||
StreamingHandler.SetUpStreaming(arrivalPointObj, sector);
|
||||
|
||||
DreamArrivalPoint arrivalPoint = arrivalPointObj.GetComponent<DreamArrivalPoint>();
|
||||
arrivalPoint._sector = arrivalPoint.GetComponentInParent<Sector>();
|
||||
arrivalPoint._location = DreamHandler.GetDreamArrivalLocation(info.id);
|
||||
Locator.RegisterDreamArrivalPoint(arrivalPoint, arrivalPoint._location);
|
||||
|
||||
return arrivalPointObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
using NewHorizons.External.Modules.Props;
|
||||
using NewHorizons.External.Modules.Props.EchoesOfTheEye;
|
||||
using NewHorizons.Handlers;
|
||||
using NewHorizons.Utility;
|
||||
using NewHorizons.Utility.OWML;
|
||||
using OWML.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NewHorizons.Builder.Props.EchoesOfTheEye
|
||||
{
|
||||
public static class DreamCampfireBuilder
|
||||
{
|
||||
private static GameObject _prefab;
|
||||
|
||||
internal static void InitPrefab()
|
||||
{
|
||||
if (_prefab == null)
|
||||
{
|
||||
_prefab = SearchUtilities.Find("RingWorld_Body/Sector_RingInterior/Sector_Zone4/Sector_PrisonDocks/Sector_PrisonInterior/Interactibles_PrisonInterior/Prefab_IP_DreamCampfire").InstantiateInactive().Rename("Prefab_DreamCampfire").DontDestroyOnLoad();
|
||||
if (_prefab == null)
|
||||
{
|
||||
NHLogger.LogWarning($"Tried to make a dream campfire but couldn't. Do you have the DLC installed?");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_prefab.AddComponent<DestroyOnDLC>()._destroyOnDLCNotOwned = true;
|
||||
var campfire = _prefab.GetComponentInChildren<DreamCampfire>();
|
||||
campfire._dreamArrivalLocation = DreamArrivalPoint.Location.Undefined;
|
||||
campfire._sector = null;
|
||||
campfire._entrywayVolumes = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static GameObject Make(GameObject planetGO, Sector sector, DreamCampfireInfo info, IModBehaviour mod)
|
||||
{
|
||||
InitPrefab();
|
||||
|
||||
if (_prefab == null || sector == null) return null;
|
||||
|
||||
var campfireObj = DetailBuilder.Make(planetGO, sector, mod, _prefab, new DetailInfo(info));
|
||||
|
||||
var campfire = campfireObj.GetComponentInChildren<DreamCampfire>();
|
||||
campfire._dreamArrivalLocation = DreamHandler.GetDreamArrivalLocation(info.id);
|
||||
|
||||
Delay.FireInNUpdates(() => {
|
||||
var streaming = campfireObj.GetComponentInChildren<DreamCampfireStreaming>();
|
||||
if (streaming != null)
|
||||
{
|
||||
var targetArrivalPoint = Locator.GetDreamArrivalPoint(campfire._dreamArrivalLocation);
|
||||
if (targetArrivalPoint != null)
|
||||
{
|
||||
var streamingGroup = targetArrivalPoint.transform.root.GetComponentInChildren<StreamingGroup>();
|
||||
if (streamingGroup)
|
||||
{
|
||||
streaming._streamingGroup = streamingGroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 2);
|
||||
|
||||
Locator.RegisterDreamCampfire(campfire, campfire._dreamArrivalLocation);
|
||||
|
||||
return campfireObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
using NewHorizons.Builder.Body;
|
||||
using NewHorizons.Builder.Props.Audio;
|
||||
using NewHorizons.Builder.Props.EchoesOfTheEye;
|
||||
using NewHorizons.Builder.Props.TranslatorText;
|
||||
using NewHorizons.Builder.ShipLog;
|
||||
using NewHorizons.External;
|
||||
@ -101,6 +102,8 @@ namespace NewHorizons.Builder.Props
|
||||
// If a prop has set its parentPath and the parent cannot be found, add it to the next pass and try again later
|
||||
nextPass = new List<Action>();
|
||||
|
||||
if (Main.HasDLC) MakeGeneralProps(go, config.Props.dreamCampfires, (campfire) => DreamCampfireBuilder.Make(go, sector, campfire, mod), (campfire) => campfire.id);
|
||||
if (Main.HasDLC) MakeGeneralProps(go, config.Props.dreamArrivalPoints, (point) => DreamArrivalPointBuilder.Make(go, sector, point, mod), (point) => point.id);
|
||||
MakeGeneralProps(go, config.Props.gravityCannons, (cannon) => GravityCannonBuilder.Make(go, sector, cannon, mod), (cannon) => cannon.shuttleID);
|
||||
MakeGeneralProps(go, config.Props.shuttles, (shuttle) => ShuttleBuilder.Make(go, sector, mod, shuttle), (shuttle) => shuttle.id);
|
||||
MakeGeneralProps(go, config.Props.details, (detail) => DetailBuilder.Make(go, sector, mod, detail), (detail) => detail.path);
|
||||
|
||||
10
NewHorizons/External/Modules/PropModule.cs
vendored
10
NewHorizons/External/Modules/PropModule.cs
vendored
@ -123,6 +123,16 @@ namespace NewHorizons.External.Modules
|
||||
/// </summary>
|
||||
public ShuttleInfo[] shuttles;
|
||||
|
||||
/// <summary>
|
||||
/// Add campfires that allow you to enter the dream world/simulation. Must be paired with a dream arrival point, which can be placed on this planet or elsewhere.
|
||||
/// </summary>
|
||||
public DreamCampfireInfo[] dreamCampfires;
|
||||
|
||||
/// <summary>
|
||||
/// Add the points you will arrive at when entering the dream world/simulation from a paired dream campfire, which can be placed on this planet or elsewhere.
|
||||
/// </summary>
|
||||
public DreamArrivalPointInfo[] dreamArrivalPoints;
|
||||
|
||||
[Obsolete("reveal is deprecated. Use Volumes->revealVolumes instead.")] public RevealVolumeInfo[] reveal;
|
||||
|
||||
[Obsolete("audioVolumes is deprecated. Use Volumes->audioVolumes instead.")] public AudioVolumeInfo[] audioVolumes;
|
||||
|
||||
22
NewHorizons/External/Modules/Props/EchoesOfTheEye/DreamArrivalPointInfo.cs
vendored
Normal file
22
NewHorizons/External/Modules/Props/EchoesOfTheEye/DreamArrivalPointInfo.cs
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NewHorizons.External.Modules.Props.EchoesOfTheEye
|
||||
{
|
||||
[JsonObject]
|
||||
public class DreamArrivalPointInfo : GeneralPropInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique ID for this dream-world arrival point
|
||||
/// </summary>
|
||||
public string id;
|
||||
/// <summary>
|
||||
/// Whether to generate simulation meshes (the models used in the "tronworld" or "matrix" view) for most objects on the current planet by cloning the existing meshes and applying the simulation materials. Leave this off if you are building your own simulation meshes or using existing objects which have them.
|
||||
/// </summary>
|
||||
public bool generateSimulationMeshes;
|
||||
}
|
||||
}
|
||||
18
NewHorizons/External/Modules/Props/EchoesOfTheEye/DreamCampfireInfo.cs
vendored
Normal file
18
NewHorizons/External/Modules/Props/EchoesOfTheEye/DreamCampfireInfo.cs
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NewHorizons.External.Modules.Props.EchoesOfTheEye
|
||||
{
|
||||
[JsonObject]
|
||||
public class DreamCampfireInfo : GeneralPropInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique ID for this dream-world campfire
|
||||
/// </summary>
|
||||
public string id;
|
||||
}
|
||||
}
|
||||
85
NewHorizons/Handlers/DreamHandler.cs
Normal file
85
NewHorizons/Handlers/DreamHandler.cs
Normal file
@ -0,0 +1,85 @@
|
||||
using NewHorizons.Utility;
|
||||
using NewHorizons.Utility.OWML;
|
||||
using OWML.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NewHorizons.Handlers
|
||||
{
|
||||
public static class DreamHandler
|
||||
{
|
||||
public static DreamArrivalPoint.Location GetDreamArrivalLocation(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (EnumUtils.TryParse(id, out DreamArrivalPoint.Location location))
|
||||
{
|
||||
return location;
|
||||
}
|
||||
else
|
||||
{
|
||||
NHLogger.LogVerbose($"Registering new dream arrival location [{id}]");
|
||||
return EnumUtilities.Create<DreamArrivalPoint.Location>(id);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
NHLogger.LogError($"Couldn't load dream arrival location [{id}]:\n{e}");
|
||||
return DreamArrivalPoint.Location.Undefined;
|
||||
}
|
||||
}
|
||||
|
||||
public static void MigrateDreamWorldController()
|
||||
{
|
||||
// Create new DreamWorldController instance since the existing one is disabled
|
||||
var managerObj = new GameObject("DreamWorldManager");
|
||||
managerObj.SetActive(false);
|
||||
var oldDWC = Locator.GetDreamWorldController();
|
||||
var dwc = managerObj.AddComponent<DreamWorldController>();
|
||||
|
||||
var simRootObj = MigrateCopy(oldDWC._primarySimulationRoot.gameObject, managerObj);
|
||||
|
||||
dwc._primarySimulationRoot = simRootObj.transform;
|
||||
dwc._simulationRoots = [simRootObj.transform];
|
||||
dwc._simulationCamera = simRootObj.FindChild("Camera_Simulation").GetComponent<SimulationCamera>();
|
||||
dwc._simulationSphere = simRootObj.FindChild("SimulationSphere").GetComponent<OWRenderer>();
|
||||
|
||||
dwc._tempSkyboxColor = oldDWC._tempSkyboxColor;
|
||||
dwc._sarcophagusController = oldDWC._sarcophagusController;
|
||||
dwc._prisonerDirector = oldDWC._prisonerDirector;
|
||||
|
||||
// These should correspond to the arrival point's attached body
|
||||
dwc._dreamBody = null;
|
||||
dwc._dreamWorldSector = null;
|
||||
dwc._dreamWorldVolume = null;
|
||||
|
||||
// These should correspond to the campfire's attached body
|
||||
dwc._planetBody = null;
|
||||
dwc._ringWorldController = null;
|
||||
|
||||
managerObj.SetActive(true);
|
||||
|
||||
// Run after Start() completes
|
||||
Delay.FireOnNextUpdate(() =>
|
||||
{
|
||||
dwc._dreamBody = null;
|
||||
dwc._dreamWorldSector = null;
|
||||
dwc._dreamWorldVolume = null;
|
||||
dwc._planetBody = null;
|
||||
dwc._ringWorldController = null;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private static GameObject MigrateCopy(GameObject go, GameObject newParent)
|
||||
{
|
||||
var clone = GameObject.Instantiate(go);
|
||||
clone.transform.SetParent(newParent.transform, false);
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -70,6 +70,7 @@ namespace NewHorizons.Handlers
|
||||
if (Main.HasDLC)
|
||||
{
|
||||
StrangerRemoved();
|
||||
DreamWorldRemoved();
|
||||
}
|
||||
|
||||
// Put it back at the center of the universe after banishing it else there are weird graphical bugs
|
||||
@ -90,6 +91,11 @@ namespace NewHorizons.Handlers
|
||||
}
|
||||
}
|
||||
|
||||
private static void DreamWorldRemoved()
|
||||
{
|
||||
DreamHandler.MigrateDreamWorldController();
|
||||
}
|
||||
|
||||
private static void SunRemoved()
|
||||
{
|
||||
var sun = SearchUtilities.Find("Sun_Body").GetComponent<AstroObject>();
|
||||
@ -207,6 +213,9 @@ namespace NewHorizons.Handlers
|
||||
case AstroObject.Name.RingWorld:
|
||||
StrangerRemoved();
|
||||
break;
|
||||
case AstroObject.Name.DreamWorld:
|
||||
DreamWorldRemoved();
|
||||
break;
|
||||
}
|
||||
|
||||
// Always delete the children
|
||||
|
||||
@ -4,6 +4,7 @@ using NewHorizons.Builder.Body;
|
||||
using NewHorizons.Builder.General;
|
||||
using NewHorizons.Builder.Props;
|
||||
using NewHorizons.Builder.Props.Audio;
|
||||
using NewHorizons.Builder.Props.EchoesOfTheEye;
|
||||
using NewHorizons.Builder.Props.TranslatorText;
|
||||
using NewHorizons.Components.Fixers;
|
||||
using NewHorizons.Components.Ship;
|
||||
@ -381,6 +382,8 @@ namespace NewHorizons
|
||||
ProjectionBuilder.InitPrefabs();
|
||||
CloakBuilder.InitPrefab();
|
||||
RaftBuilder.InitPrefab();
|
||||
DreamCampfireBuilder.InitPrefab();
|
||||
DreamArrivalPointBuilder.InitPrefab();
|
||||
}
|
||||
|
||||
WarpPadBuilder.InitPrefabs();
|
||||
|
||||
@ -26,5 +26,40 @@ namespace NewHorizons.Patches.EchoesOfTheEyePatches
|
||||
.Repeat(matcher => matcher.RemoveInstructions(5))
|
||||
.InstructionEnumeration();
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(DreamWorldController.EnterDreamWorld))]
|
||||
public static void DreamWorldController_EnterDreamWorld(DreamWorldController __instance, DreamCampfire dreamCampfire, DreamArrivalPoint arrivalPoint)
|
||||
{
|
||||
var dreamWorldAO = Locator.GetAstroObject(AstroObject.Name.DreamWorld);
|
||||
if (arrivalPoint.GetAttachedOWRigidbody() == dreamWorldAO.GetOWRigidbody())
|
||||
{
|
||||
__instance._dreamBody = dreamWorldAO.GetAttachedOWRigidbody();
|
||||
__instance._dreamWorldSector = dreamWorldAO.GetRootSector();
|
||||
__instance._dreamWorldVolume = __instance._dreamWorldSector.transform.Find("Volumes_DreamWorld").Find("DreamWorldVolume").GetComponent<OWTriggerVolume>();
|
||||
}
|
||||
else
|
||||
{
|
||||
var arrivalAO = arrivalPoint.GetComponentInParent<AstroObject>();
|
||||
__instance._dreamBody = arrivalAO.GetAttachedOWRigidbody();
|
||||
__instance._dreamWorldSector = arrivalAO.GetRootSector();
|
||||
__instance._dreamWorldVolume = arrivalAO._gravityVolume.GetOWTriggerVolume();
|
||||
}
|
||||
|
||||
__instance._primarySimulationRoot.GetComponent<SectorCullGroup>().SetSector(__instance._dreamWorldSector);
|
||||
|
||||
var ringWorldAO = Locator.GetAstroObject(AstroObject.Name.RingWorld);
|
||||
if (dreamCampfire.GetAttachedOWRigidbody() == ringWorldAO.GetOWRigidbody())
|
||||
{
|
||||
__instance._planetBody = ringWorldAO.GetAttachedOWRigidbody();
|
||||
__instance._ringWorldController = ringWorldAO.GetComponent<RingWorldController>();
|
||||
}
|
||||
else
|
||||
{
|
||||
var departureAO = dreamCampfire.GetComponentInParent<AstroObject>();
|
||||
__instance._planetBody = departureAO.GetAttachedOWRigidbody();
|
||||
__instance._ringWorldController = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user