Change MakeDetail to take in just DetailInfo and not all the individual parameters

This commit is contained in:
Nick 2022-08-05 18:30:37 -04:00
parent fc1f6e74c6
commit a2da11a64a
9 changed files with 238 additions and 200 deletions

View File

@ -2,6 +2,7 @@ using HarmonyLib;
using NewHorizons.Builder.Props; using NewHorizons.Builder.Props;
using NewHorizons.Components; using NewHorizons.Components;
using NewHorizons.Components.Orbital; using NewHorizons.Components.Orbital;
using NewHorizons.External.Modules;
using NewHorizons.Handlers; using NewHorizons.Handlers;
using NewHorizons.Utility; using NewHorizons.Utility;
using System.Collections.Generic; using System.Collections.Generic;
@ -56,7 +57,11 @@ namespace NewHorizons.Builder.Body
var atmo = SearchUtilities.Find("DB_HubDimension_Body/Sector_HubDimension/Atmosphere_HubDimension").InstantiateInactive(); var atmo = SearchUtilities.Find("DB_HubDimension_Body/Sector_HubDimension/Atmosphere_HubDimension").InstantiateInactive();
var volumes = SearchUtilities.Find("DB_HubDimension_Body/Sector_HubDimension/Volumes_HubDimension").InstantiateInactive(); var volumes = SearchUtilities.Find("DB_HubDimension_Body/Sector_HubDimension/Volumes_HubDimension").InstantiateInactive();
var effects = SearchUtilities.Find("DB_HubDimension_Body/Sector_HubDimension/Effects_HubDimension").InstantiateInactive(); var effects = SearchUtilities.Find("DB_HubDimension_Body/Sector_HubDimension/Effects_HubDimension").InstantiateInactive();
var geometry = DetailBuilder.MakeDetail(go, sector, "DB_HubDimension_Body/Sector_HubDimension/Geometry_HubDimension", Vector3.zero, Vector3.zero, 1, false);
var prefab = SearchUtilities.Find("DB_HubDimension_Body/Sector_HubDimension/Geometry_HubDimension");
var detailInfo = new PropModule.DetailInfo();
var geometry = DetailBuilder.MakeDetail(go, sector, prefab, detailInfo);
var exitWarps = SearchUtilities.Find("DB_HubDimension_Body/Sector_HubDimension/OuterWarp_Hub").InstantiateInactive(); var exitWarps = SearchUtilities.Find("DB_HubDimension_Body/Sector_HubDimension/OuterWarp_Hub").InstantiateInactive();
var repelVolume = SearchUtilities.Find("DB_HubDimension_Body/BrambleRepelVolume").InstantiateInactive(); var repelVolume = SearchUtilities.Find("DB_HubDimension_Body/BrambleRepelVolume").InstantiateInactive();

View File

@ -28,11 +28,13 @@ namespace NewHorizons.Builder.Props
{ {
var prefab = AssetBundleUtilities.LoadPrefab(detail.assetBundle, detail.path, mod); var prefab = AssetBundleUtilities.LoadPrefab(detail.assetBundle, detail.path, mod);
detailGO = MakeDetail(go, sector, prefab, detail.position, detail.rotation, detail.scale, detail.alignToNormal); detailGO = MakeDetail(go, sector, prefab, detail);
} }
else else
{ {
detailGO = MakeDetail(go, sector, detail.path, detail.position, detail.rotation, detail.scale, detail.alignToNormal); var prefab = SearchUtilities.Find(detail.path);
if (prefab == null) Logger.LogError($"Couldn't find detail {detail.path}");
else detailGO = MakeDetail(go, sector, prefab, detail);
} }
if (detailGO == null) return; if (detailGO == null) return;
@ -94,14 +96,7 @@ namespace NewHorizons.Builder.Props
detailInfoToCorrespondingSpawnedGameObject[detail] = detailGO; detailInfoToCorrespondingSpawnedGameObject[detail] = detailGO;
} }
public static GameObject MakeDetail(GameObject go, Sector sector, string propToClone, MVector3 position, MVector3 rotation, float scale, bool alignWithNormal) public static GameObject MakeDetail(GameObject planetGO, Sector sector, GameObject prefab, PropModule.DetailInfo info)
{
var prefab = SearchUtilities.Find(propToClone);
if (prefab == null) Logger.LogError($"Couldn't find detail {propToClone}");
return MakeDetail(go, sector, prefab, position, rotation, scale, alignWithNormal);
}
public static GameObject MakeDetail(GameObject planetGO, Sector sector, GameObject prefab, MVector3 position, MVector3 rotation, float scale, bool alignWithNormal)
{ {
if (prefab == null) return null; if (prefab == null) return null;
@ -111,165 +106,24 @@ namespace NewHorizons.Builder.Props
StreamingHandler.SetUpStreaming(prop, sector); StreamingHandler.SetUpStreaming(prop, sector);
var torchItem = prop.GetComponent<VisionTorchItem>(); var isTorch = prop.GetComponent<VisionTorchItem>() != null;
// Fix vision torch
if (torchItem)
{
torchItem.enabled = true;
torchItem.mindProjectorTrigger.enabled = true;
torchItem.mindSlideProjector._mindProjectorImageEffect = SearchUtilities.Find("Player_Body/PlayerCamera").GetComponent<MindProjectorImageEffect>();
}
foreach (var component in prop.GetComponentsInChildren<Component>(true)) foreach (var component in prop.GetComponentsInChildren<Component>(true))
{ {
/* if (sector == null)
// Enable all children or something
// BUG doesnt work because enabled is a property, not a field
var enabledField = component?.GetType()?.GetField("enabled");
if (enabledField != null && enabledField.FieldType == typeof(bool)) Events.FireOnNextUpdate(() => enabledField.SetValue(component, true));
*/
// Fix a bunch of sector stuff
if (sector != null)
{ {
if (component is Sector s) if (FixUnsectoredComponent(component)) continue;
{
s.SetParentSector(sector);
}
if (component is SectorCullGroup sectorCullGroup)
{
sectorCullGroup._controllingProxy = null;
}
// fix Sector stuff, eg SectorCullGroup (without this, props that have a SectorCullGroup component will become invisible inappropriately)
if (component is ISectorGroup sectorGroup)
{
sectorGroup.SetSector(sector);
}
if (component is GhostIK ik) ik.enabled = false;
if (component is GhostEffects effects) effects.enabled = false;
if (component is DarkMatterVolume)
{
var probeVisuals = component.gameObject.transform.Find("ProbeVisuals");
if (probeVisuals != null) probeVisuals.gameObject.SetActive(true);
}
if (component is SectoredMonoBehaviour behaviour)
{
behaviour.SetSector(sector);
}
/*
else
{
// BUG: this doesnt find the field cuz _sector is private
var sectorField = component?.GetType()?.GetField("_sector");
if (sectorField != null && sectorField.FieldType == typeof(Sector))
{
Events.FireOnNextUpdate(() => sectorField.SetValue(component, sector));
}
}
*/
if (component is AnglerfishController angler)
{
try
{
angler._chaseSpeed += OWPhysics.CalculateOrbitVelocity(planetGO.GetAttachedOWRigidbody(), planetGO.GetComponent<AstroObject>().GetPrimaryBody().GetAttachedOWRigidbody()).magnitude;
}
catch (Exception e)
{
Logger.LogError($"Couldn't update AnglerFish chase speed:\n{e}");
}
}
// Fix slide reel
// softlocks if this object is a vision torch
if (!torchItem && component is SlideCollectionContainer container)
{
sector.OnOccupantEnterSector.AddListener(_ => container.LoadStreamingTextures());
}
if (component is OWItemSocket socket)
{
socket._sector = sector;
}
// fix campfires
if (component is InteractVolume interactVolume)
{
interactVolume._playerCam = GameObject.Find("Player_Body/PlayerCamera").GetComponent<OWCamera>();
}
if (component is PlayerAttachPoint playerAttachPoint)
{
var playerBody = GameObject.Find("Player_Body");
playerAttachPoint._playerController = playerBody.GetComponent<PlayerCharacterController>();
playerAttachPoint._playerOWRigidbody = playerBody.GetComponent<OWRigidbody>();
playerAttachPoint._playerTransform = playerBody.transform;
playerAttachPoint._fpsCamController = GameObject.Find("Player_Body/PlayerCamera").GetComponent<PlayerCameraController>();
}
if (component is NomaiInterfaceOrb orb)
{
orb._parentAstroObject = planetGO.GetComponent<AstroObject>();
orb._parentBody = planetGO.GetComponent<OWRigidbody>();
}
}
else
{
// Remove things that require sectors if the sector is null. Will just keep extending this as things pop up.
if (component is FogLight or SectoredMonoBehaviour)
{
GameObject.DestroyImmediate(component);
continue;
}
} }
else FixSectoredComponent(component, sector, isTorch);
// Fix a bunch of stuff when done loading FixComponent(component, planetGO, prefab.name);
Delay.RunWhen(() => Main.IsSystemReady, () =>
{
try
{
if (component == null) return;
if (component is Animator animator) animator.enabled = true;
else if (component is Collider collider) collider.enabled = true;
else if (component is Renderer renderer) renderer.enabled = true;
else if (component is Shape shape) shape.enabled = true;
else if (component is SectorCullGroup sectorCullGroup)
{
sectorCullGroup._inMapView = false;
sectorCullGroup._isFastForwarding = false;
sectorCullGroup.SetVisible(sectorCullGroup.ShouldBeVisible(), true, false);
}
// If it's not a moving anglerfish make sure the anim controller is regular
else if (component is AnglerfishAnimController angler && angler.GetComponentInParent<AnglerfishController>() == null)
{
Logger.LogVerbose("Enabling anglerfish animation");
// Remove any reference to its angler
if (angler._anglerfishController)
{
angler._anglerfishController.OnChangeAnglerState -= angler.OnChangeAnglerState;
angler._anglerfishController.OnAnglerTurn -= angler.OnAnglerTurn;
angler._anglerfishController.OnAnglerSuspended -= angler.OnAnglerSuspended;
angler._anglerfishController.OnAnglerUnsuspended -= angler.OnAnglerUnsuspended;
}
angler.enabled = true;
angler.OnChangeAnglerState(AnglerfishController.AnglerState.Lurking);
}
}
catch (Exception e)
{
Logger.LogWarning($"Exception when modifying component [{component.GetType().Name}] on [{planetGO.name}] for prop [{prefab.name}]:\n{e}");
}
});
} }
prop.transform.position = position == null ? planetGO.transform.position : planetGO.transform.TransformPoint((Vector3)position); prop.transform.position = info.position == null ? planetGO.transform.position : planetGO.transform.TransformPoint(info.position);
Quaternion rot = rotation == null ? Quaternion.identity : Quaternion.Euler((Vector3)rotation); Quaternion rot = info.rotation == null ? Quaternion.identity : Quaternion.Euler(info.rotation);
if (alignWithNormal)
if (info.alignToNormal)
{ {
// Apply the rotation after aligning it with normal // Apply the rotation after aligning it with normal
var up = planetGO.transform.InverseTransformPoint(prop.transform.position).normalized; var up = planetGO.transform.InverseTransformPoint(prop.transform.position).normalized;
@ -281,11 +135,159 @@ namespace NewHorizons.Builder.Props
prop.transform.rotation = planetGO.transform.TransformRotation(rot); prop.transform.rotation = planetGO.transform.TransformRotation(rot);
} }
prop.transform.localScale = scale != 0 ? Vector3.one * scale : prefab.transform.localScale; prop.transform.localScale = info.scale != 0 ? Vector3.one * info.scale : prefab.transform.localScale;
prop.SetActive(true); prop.SetActive(true);
return prop; return prop;
} }
/// <summary>
/// Fix components that have sectors. Has a specific fix if there is a VisionTorchItem on the object.
/// </summary>
/// <param name="component"></param>
/// <param name="sector"></param>
/// <param name="isTorch"></param>
private static void FixSectoredComponent(Component component, Sector sector, bool isTorch)
{
if (component is Sector s)
{
s.SetParentSector(sector);
}
if (component is SectorCullGroup sectorCullGroup)
{
sectorCullGroup._controllingProxy = null;
}
// fix Sector stuff, eg SectorCullGroup (without this, props that have a SectorCullGroup component will become invisible inappropriately)
if (component is ISectorGroup sectorGroup)
{
sectorGroup.SetSector(sector);
}
if (component is SectoredMonoBehaviour behaviour)
{
behaviour.SetSector(sector);
}
if (component is OWItemSocket socket)
{
socket._sector = sector;
}
// Fix slide reel - Softlocks if this object is a vision torch
if (!isTorch && component is SlideCollectionContainer container)
{
sector.OnOccupantEnterSector.AddListener(_ => container.LoadStreamingTextures());
}
}
/// <summary>
/// Remove things that require sectors if the sector is null. Will just keep extending this as things pop up.
/// Returns true if the object is destroyed
/// </summary>
/// <param name="component"></param>
private static bool FixUnsectoredComponent(Component component)
{
if (component is FogLight or SectoredMonoBehaviour)
{
GameObject.DestroyImmediate(component);
return true;
}
return false;
}
private static void FixComponent(Component component, GameObject planetGO, string prefab)
{
// Fix other components
// I forget why this is here
if (component is GhostIK ik) ik.enabled = false;
if (component is GhostEffects effects) effects.enabled = false;
if (component is DarkMatterVolume)
{
var probeVisuals = component.gameObject.transform.Find("ProbeVisuals");
if (probeVisuals != null) probeVisuals.gameObject.SetActive(true);
}
// Fix anglerfish speed on orbiting planets
if (component is AnglerfishController angler)
{
try
{
angler._chaseSpeed += OWPhysics.CalculateOrbitVelocity(planetGO.GetAttachedOWRigidbody(), planetGO.GetComponent<AstroObject>().GetPrimaryBody().GetAttachedOWRigidbody()).magnitude;
}
catch (Exception e)
{
Logger.LogError($"Couldn't update AnglerFish chase speed:\n{e}");
}
}
// fix campfires
if (component is InteractVolume interactVolume)
{
interactVolume._playerCam = GameObject.Find("Player_Body/PlayerCamera").GetComponent<OWCamera>();
}
if (component is PlayerAttachPoint playerAttachPoint)
{
var playerBody = GameObject.Find("Player_Body");
playerAttachPoint._playerController = playerBody.GetComponent<PlayerCharacterController>();
playerAttachPoint._playerOWRigidbody = playerBody.GetComponent<OWRigidbody>();
playerAttachPoint._playerTransform = playerBody.transform;
playerAttachPoint._fpsCamController = GameObject.Find("Player_Body/PlayerCamera").GetComponent<PlayerCameraController>();
}
if (component is NomaiInterfaceOrb orb)
{
orb._parentAstroObject = planetGO.GetComponent<AstroObject>();
orb._parentBody = planetGO.GetComponent<OWRigidbody>();
}
if (component is VisionTorchItem torchItem)
{
torchItem.enabled = true;
torchItem.mindProjectorTrigger.enabled = true;
torchItem.mindSlideProjector._mindProjectorImageEffect = SearchUtilities.Find("Player_Body/PlayerCamera").GetComponent<MindProjectorImageEffect>();
}
// Fix a bunch of stuff when done loading
Delay.RunWhen(() => Main.IsSystemReady, () =>
{
try
{
if (component == null) return;
if (component is Animator animator) animator.enabled = true;
else if (component is Collider collider) collider.enabled = true;
else if (component is Renderer renderer) renderer.enabled = true;
else if (component is Shape shape) shape.enabled = true;
else if (component is SectorCullGroup sectorCullGroup)
{
sectorCullGroup._inMapView = false;
sectorCullGroup._isFastForwarding = false;
sectorCullGroup.SetVisible(sectorCullGroup.ShouldBeVisible(), true, false);
}
// If it's not a moving anglerfish make sure the anim controller is regular
else if (component is AnglerfishAnimController angler && angler.GetComponentInParent<AnglerfishController>() == null)
{
Logger.LogVerbose("Enabling anglerfish animation");
// Remove any reference to its angler
if (angler._anglerfishController)
{
angler._anglerfishController.OnChangeAnglerState -= angler.OnChangeAnglerState;
angler._anglerfishController.OnAnglerTurn -= angler.OnAnglerTurn;
angler._anglerfishController.OnAnglerSuspended -= angler.OnAnglerSuspended;
angler._anglerfishController.OnAnglerUnsuspended -= angler.OnAnglerUnsuspended;
}
angler.enabled = true;
angler.OnChangeAnglerState(AnglerfishController.AnglerState.Lurking);
}
}
catch (Exception e)
{
Logger.LogWarning($"Exception when modifying component [{component.GetType().Name}] on [{planetGO.name}] for prop [{prefab}]:\n{e}");
}
});
}
} }
} }

View File

@ -276,7 +276,11 @@ namespace NewHorizons.Builder.Props
} }
case PropModule.NomaiTextInfo.NomaiTextType.PreCrashComputer: case PropModule.NomaiTextInfo.NomaiTextType.PreCrashComputer:
{ {
var computerObject = DetailBuilder.MakeDetail(planetGO, sector, _preCrashComputerPrefab, info.position, Vector3.zero, 1, false); var detailInfo = new PropModule.DetailInfo()
{
position = info.position
};
var computerObject = DetailBuilder.MakeDetail(planetGO, sector, _preCrashComputerPrefab, detailInfo);
computerObject.SetActive(false); computerObject.SetActive(false);
if (!string.IsNullOrEmpty(info.rename)) if (!string.IsNullOrEmpty(info.rename))

View File

@ -222,7 +222,13 @@ namespace NewHorizons.Builder.Props
{ {
// spawn a trigger for the vision torch // spawn a trigger for the vision torch
var path = "DreamWorld_Body/Sector_DreamWorld/Sector_Underground/Sector_PrisonCell/Ghosts_PrisonCell/GhostNodeMap_PrisonCell_Lower/Prefab_IP_GhostBird_Prisoner/Ghostbird_IP_ANIM/Ghostbird_Skin_01:Ghostbird_Rig_V01:Base/Ghostbird_Skin_01:Ghostbird_Rig_V01:Root/Ghostbird_Skin_01:Ghostbird_Rig_V01:Spine01/Ghostbird_Skin_01:Ghostbird_Rig_V01:Spine02/Ghostbird_Skin_01:Ghostbird_Rig_V01:Spine03/Ghostbird_Skin_01:Ghostbird_Rig_V01:Spine04/Ghostbird_Skin_01:Ghostbird_Rig_V01:Neck01/Ghostbird_Skin_01:Ghostbird_Rig_V01:Neck02/Ghostbird_Skin_01:Ghostbird_Rig_V01:Head/PrisonerHeadDetector"; var path = "DreamWorld_Body/Sector_DreamWorld/Sector_Underground/Sector_PrisonCell/Ghosts_PrisonCell/GhostNodeMap_PrisonCell_Lower/Prefab_IP_GhostBird_Prisoner/Ghostbird_IP_ANIM/Ghostbird_Skin_01:Ghostbird_Rig_V01:Base/Ghostbird_Skin_01:Ghostbird_Rig_V01:Root/Ghostbird_Skin_01:Ghostbird_Rig_V01:Spine01/Ghostbird_Skin_01:Ghostbird_Rig_V01:Spine02/Ghostbird_Skin_01:Ghostbird_Rig_V01:Spine03/Ghostbird_Skin_01:Ghostbird_Rig_V01:Spine04/Ghostbird_Skin_01:Ghostbird_Rig_V01:Neck01/Ghostbird_Skin_01:Ghostbird_Rig_V01:Neck02/Ghostbird_Skin_01:Ghostbird_Rig_V01:Head/PrisonerHeadDetector";
var g = DetailBuilder.MakeDetail(planetGO, sector, path, info.position, Vector3.zero, 2, false); var prefab = SearchUtilities.Find(path);
var detailInfo = new PropModule.DetailInfo()
{
position = info.position,
scale = 2
};
var g = DetailBuilder.MakeDetail(planetGO, sector, prefab, detailInfo);
if (!string.IsNullOrEmpty(info.parentPath)) if (!string.IsNullOrEmpty(info.parentPath))
{ {
@ -280,12 +286,15 @@ namespace NewHorizons.Builder.Props
public static GameObject MakeStandingVisionTorch(GameObject planetGO, Sector sector, PropModule.ProjectionInfo info, IModBehaviour mod) public static GameObject MakeStandingVisionTorch(GameObject planetGO, Sector sector, PropModule.ProjectionInfo info, IModBehaviour mod)
{ {
// // Spawn the torch itself
// spawn the torch itself
//
var path = "RingWorld_Body/Sector_RingWorld/Sector_SecretEntrance/Interactibles_SecretEntrance/Experiment_1/VisionTorchApparatus/VisionTorchRoot/Prefab_IP_VisionTorchProjector"; var path = "RingWorld_Body/Sector_RingWorld/Sector_SecretEntrance/Interactibles_SecretEntrance/Experiment_1/VisionTorchApparatus/VisionTorchRoot/Prefab_IP_VisionTorchProjector";
var standingTorch = DetailBuilder.MakeDetail(planetGO, sector, path, info.position, info.rotation, 1, false); var prefab = SearchUtilities.Find(path);
var detailInfo = new PropModule.DetailInfo()
{
position = info.position,
rotation = info.rotation
};
var standingTorch = DetailBuilder.MakeDetail(planetGO, sector, prefab, detailInfo);
if (!string.IsNullOrEmpty(info.parentPath)) if (!string.IsNullOrEmpty(info.parentPath))
{ {
@ -306,22 +315,16 @@ namespace NewHorizons.Builder.Props
return null; return null;
} }
// // Set some required properties on the torch
// set some required properties on the torch
//
var mindSlideProjector = standingTorch.GetComponent<MindSlideProjector>(); var mindSlideProjector = standingTorch.GetComponent<MindSlideProjector>();
mindSlideProjector._mindProjectorImageEffect = SearchUtilities.Find("Player_Body/PlayerCamera").GetComponent<MindProjectorImageEffect>(); mindSlideProjector._mindProjectorImageEffect = SearchUtilities.Find("Player_Body/PlayerCamera").GetComponent<MindProjectorImageEffect>();
// setup for visually supporting async texture loading // Setup for visually supporting async texture loading
mindSlideProjector.enabled = false; mindSlideProjector.enabled = false;
var visionBeamEffect = standingTorch.FindChild("VisionBeam"); var visionBeamEffect = standingTorch.FindChild("VisionBeam");
visionBeamEffect.SetActive(false); visionBeamEffect.SetActive(false);
// // Set up slides
// set up slides
//
// The number of slides is unlimited, 15 is only for texturing the actual slide reel item. This is not a slide reel item // The number of slides is unlimited, 15 is only for texturing the actual slide reel item. This is not a slide reel item
var slides = info.slides; var slides = info.slides;
var slidesCount = slides.Length; var slidesCount = slides.Length;
@ -340,8 +343,8 @@ namespace NewHorizons.Builder.Props
slideCollection.slides[i] = slide; slideCollection.slides[i] = slide;
} }
// this variable just lets us track how many of the slides have been loaded. // This variable just lets us track how many of the slides have been loaded.
// this way as soon as the last one is loaded (due to async loading, this may be // This way as soon as the last one is loaded (due to async loading, this may be
// slide 7, or slide 3, or whatever), we can enable the vision torch. This allows us // slide 7, or slide 3, or whatever), we can enable the vision torch. This allows us
// to avoid doing a "is every element in the array `slideCollection.slides` not null" check every time a texture finishes loading // to avoid doing a "is every element in the array `slideCollection.slides` not null" check every time a texture finishes loading
int displaySlidesLoaded = 0; int displaySlidesLoaded = 0;
@ -359,13 +362,13 @@ namespace NewHorizons.Builder.Props
} }
); );
// set up the containers for the slides // Set up the containers for the slides
var slideCollectionContainer = standingTorch.AddComponent<SlideCollectionContainer>(); var slideCollectionContainer = standingTorch.AddComponent<SlideCollectionContainer>();
slideCollectionContainer.slideCollection = slideCollection; slideCollectionContainer.slideCollection = slideCollection;
var mindSlideCollection = standingTorch.AddComponent<MindSlideCollection>(); var mindSlideCollection = standingTorch.AddComponent<MindSlideCollection>();
mindSlideCollection._slideCollectionContainer = slideCollectionContainer; mindSlideCollection._slideCollectionContainer = slideCollectionContainer;
// make sure that these slides play when the player wanders into the beam // Make sure that these slides play when the player wanders into the beam
mindSlideProjector.SetMindSlideCollection(mindSlideCollection); mindSlideProjector.SetMindSlideCollection(mindSlideCollection);

View File

@ -92,7 +92,14 @@ namespace NewHorizons.Builder.Props
point = Quaternion.Euler(90, 0, 0) * point; point = Quaternion.Euler(90, 0, 0) * point;
} }
var prop = DetailBuilder.MakeDetail(go, sector, prefab, (MVector3)(point.normalized * height), null, propInfo.scale, true); var detailInfo = new PropModule.DetailInfo()
{
position = point.normalized * height,
scale = propInfo.scale,
alignToNormal = true
};
var prop = DetailBuilder.MakeDetail(go, sector, prefab, detailInfo);
if (propInfo.offset != null) prop.transform.localPosition += prop.transform.TransformVector(propInfo.offset); if (propInfo.offset != null) prop.transform.localPosition += prop.transform.TransformVector(propInfo.offset);
if (propInfo.rotation != null) prop.transform.rotation *= Quaternion.Euler(propInfo.rotation); if (propInfo.rotation != null) prop.transform.rotation *= Quaternion.Euler(propInfo.rotation);

View File

@ -200,6 +200,11 @@ namespace NewHorizons.External.Modules
/// The path (not including the root planet object) of the parent of this game object. Optional (will default to the root sector). /// The path (not including the root planet object) of the parent of this game object. Optional (will default to the root sector).
/// </summary> /// </summary>
public string parentPath; public string parentPath;
/// <summary>
/// Should this detail stay loaded even if you're outside the sector (good for very large props)
/// </summary>
public bool keepLoaded;
} }
[JsonObject] [JsonObject]

View File

@ -111,7 +111,14 @@ namespace NewHorizons
public GameObject SpawnObject(GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles, public GameObject SpawnObject(GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles,
float scale, bool alignWithNormal) float scale, bool alignWithNormal)
{ {
return DetailBuilder.MakeDetail(planet, sector, propToCopyPath, position, eulerAngles, scale, alignWithNormal); var prefab = SearchUtilities.Find(propToCopyPath);
var detailInfo = new PropModule.DetailInfo() {
position = position,
rotation = eulerAngles,
scale = scale,
alignToNormal = alignWithNormal
};
return DetailBuilder.MakeDetail(planet, sector, prefab, detailInfo);
} }
public AudioSignal SpawnSignal(IModBehaviour mod, GameObject root, string audio, string name, string frequency, public AudioSignal SpawnSignal(IModBehaviour mod, GameObject root, string audio, string name, string frequency,

View File

@ -1,10 +1,10 @@
using HarmonyLib; using HarmonyLib;
using NewHorizons.Builder.Props; using NewHorizons.Builder.Props;
using NewHorizons.Components;
using NewHorizons.External; using NewHorizons.External;
using NewHorizons.Handlers; using NewHorizons.Handlers;
using System; using System;
using UnityEngine; using UnityEngine;
namespace NewHorizons.Patches namespace NewHorizons.Patches
{ {
[HarmonyPatch] [HarmonyPatch]

View File

@ -1,13 +1,10 @@
using NewHorizons.Builder.Props; using NewHorizons.Builder.Props;
using NewHorizons.External.Configs; using NewHorizons.External.Configs;
using System; using NewHorizons.External.Modules;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
using UnityEngine.InputSystem; using UnityEngine.InputSystem;
using static NewHorizons.External.Modules.PropModule;
namespace NewHorizons.Utility.DebugUtilities namespace NewHorizons.Utility.DebugUtilities
{ {
@ -24,7 +21,7 @@ namespace NewHorizons.Utility.DebugUtilities
public AstroObject body; public AstroObject body;
public string system; public string system;
public GameObject gameObject; public GameObject gameObject;
public DetailInfo detailInfo; public PropModule.DetailInfo detailInfo;
} }
// VASE // VASE
@ -108,8 +105,16 @@ namespace NewHorizons.Utility.DebugUtilities
SetCurrentObject(DEFAULT_OBJECT); SetCurrentObject(DEFAULT_OBJECT);
} }
GameObject prop = DetailBuilder.MakeDetail(data.hitBodyGameObject, data.hitBodyGameObject.GetComponentInChildren<Sector>(), currentObject, data.pos, data.norm, 1, false); var planetGO = data.hitBodyGameObject;
PropPlacementData propData = RegisterProp_WithReturn(data.hitBodyGameObject.GetComponent<AstroObject>(), prop); var sector = planetGO.GetComponentInChildren<Sector>();
var prefab = SearchUtilities.Find(currentObject);
var detailInfo = new PropModule.DetailInfo()
{
position = data.pos,
rotation = data.norm,
};
var prop = DetailBuilder.MakeDetail(planetGO, sector, prefab, detailInfo);
var propData = RegisterProp_WithReturn(data.hitBodyGameObject.GetComponent<AstroObject>(), prop);
SetGameObjectRotation(prop, data, playerAbsolutePosition); SetGameObjectRotation(prop, data, playerAbsolutePosition);
} }
@ -156,7 +161,7 @@ namespace NewHorizons.Utility.DebugUtilities
{ {
if (config.starSystem != Main.Instance.CurrentStarSystem) return; if (config.starSystem != Main.Instance.CurrentStarSystem) return;
AstroObject planet = AstroObjectLocator.GetAstroObject(config.name); var planet = AstroObjectLocator.GetAstroObject(config.name);
if (planet == null) return; if (planet == null) return;
if (config.Props == null || config.Props.details == null) return; if (config.Props == null || config.Props.details == null) return;
@ -165,7 +170,7 @@ namespace NewHorizons.Utility.DebugUtilities
foreach (var detail in config.Props.details) foreach (var detail in config.Props.details)
{ {
GameObject spawnedProp = DetailBuilder.GetSpawnedGameObjectByDetailInfo(detail); var spawnedProp = DetailBuilder.GetSpawnedGameObjectByDetailInfo(detail);
if (spawnedProp == null) if (spawnedProp == null)
{ {
@ -173,7 +178,7 @@ namespace NewHorizons.Utility.DebugUtilities
continue; continue;
} }
PropPlacementData data = RegisterProp_WithReturn(astroObject, spawnedProp, detail.path, detail); var data = RegisterProp_WithReturn(astroObject, spawnedProp, detail.path, detail);
// note: we do not support placing props from assetbundles, so they will not be added to the // note: we do not support placing props from assetbundles, so they will not be added to the
// selectable list of placed props // selectable list of placed props
@ -189,7 +194,7 @@ namespace NewHorizons.Utility.DebugUtilities
RegisterProp_WithReturn(body, prop); RegisterProp_WithReturn(body, prop);
} }
private PropPlacementData RegisterProp_WithReturn(AstroObject body, GameObject prop, string propPath = null, DetailInfo detailInfo = null) private PropPlacementData RegisterProp_WithReturn(AstroObject body, GameObject prop, string propPath = null, PropModule.DetailInfo detailInfo = null)
{ {
if (Main.Debug) if (Main.Debug)
{ {
@ -201,7 +206,7 @@ namespace NewHorizons.Utility.DebugUtilities
Logger.LogVerbose($"Adding prop to {Main.Instance.CurrentStarSystem}::{body.name}"); Logger.LogVerbose($"Adding prop to {Main.Instance.CurrentStarSystem}::{body.name}");
detailInfo = detailInfo == null ? new DetailInfo() : detailInfo; detailInfo = detailInfo == null ? new PropModule.DetailInfo() : detailInfo;
detailInfo.path = propPath == null ? currentObject : propPath; detailInfo.path = propPath == null ? currentObject : propPath;
PropPlacementData data = new PropPlacementData PropPlacementData data = new PropPlacementData
@ -216,14 +221,14 @@ namespace NewHorizons.Utility.DebugUtilities
return data; return data;
} }
public Dictionary<AstroObject, DetailInfo[]> GetPropsConfigByBody() public Dictionary<AstroObject, PropModule.DetailInfo[]> GetPropsConfigByBody()
{ {
var groupedProps = props var groupedProps = props
.GroupBy(p => p.system + "." + p.body) .GroupBy(p => p.system + "." + p.body)
.Select(grp => grp.ToList()) .Select(grp => grp.ToList())
.ToList(); .ToList();
Dictionary<AstroObject, DetailInfo[]> propConfigs = new Dictionary<AstroObject, DetailInfo[]>(); Dictionary<AstroObject, PropModule.DetailInfo[]> propConfigs = new Dictionary<AstroObject, PropModule.DetailInfo[]>();
foreach (List<PropPlacementData> bodyProps in groupedProps) foreach (List<PropPlacementData> bodyProps in groupedProps)
{ {
@ -233,7 +238,7 @@ namespace NewHorizons.Utility.DebugUtilities
Logger.LogVerbose("getting prop group for body " + body.name); Logger.LogVerbose("getting prop group for body " + body.name);
//string bodyName = GetAstroObjectName(bodyProps[0].body); //string bodyName = GetAstroObjectName(bodyProps[0].body);
DetailInfo[] infoArray = new DetailInfo[bodyProps.Count]; PropModule.DetailInfo[] infoArray = new PropModule.DetailInfo[bodyProps.Count];
propConfigs[body] = infoArray; propConfigs[body] = infoArray;
for (int i = 0; i < bodyProps.Count; i++) for (int i = 0; i < bodyProps.Count; i++)