mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
removed separate CreateVisionTorch function and folded it into the regular Make function
This commit is contained in:
parent
b1688c0a6d
commit
41c8e17f49
@ -1,247 +1,231 @@
|
||||
using NewHorizons.External.Configs;
|
||||
using NewHorizons.External.Modules;
|
||||
using NewHorizons.Handlers;
|
||||
using NewHorizons.Utility;
|
||||
using OWML.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using Logger = NewHorizons.Utility.Logger;
|
||||
namespace NewHorizons.Builder.Props
|
||||
{
|
||||
public static class DetailBuilder
|
||||
{
|
||||
private static readonly string VISION_TORCH_PATH = "DreamWorld_Body/Sector_DreamWorld/Sector_Underground/Sector_PrisonCell/Interactibles_PrisonCell/PrisonerSequence/VisionTorchWallSocket/Prefab_IP_VisionTorchItem";
|
||||
private static Dictionary<PropModule.DetailInfo, GameObject> detailInfoToCorrespondingSpawnedGameObject = new Dictionary<PropModule.DetailInfo, GameObject>();
|
||||
|
||||
public static GameObject GetSpawnedGameObjectByDetailInfo(PropModule.DetailInfo detail)
|
||||
{
|
||||
if (!detailInfoToCorrespondingSpawnedGameObject.ContainsKey(detail)) return null;
|
||||
return detailInfoToCorrespondingSpawnedGameObject[detail];
|
||||
}
|
||||
|
||||
public static void Make(GameObject go, Sector sector, PlanetConfig config, IModBehaviour mod, string uniqueModName, PropModule.DetailInfo detail)
|
||||
{
|
||||
GameObject detailGO = null;
|
||||
|
||||
if (detail.assetBundle != null)
|
||||
{
|
||||
var prefab = AssetBundleUtilities.LoadPrefab(detail.assetBundle, detail.path, mod);
|
||||
|
||||
detailGO = MakeDetail(go, sector, prefab, detail.position, detail.rotation, detail.scale, detail.alignToNormal);
|
||||
}
|
||||
else if (detail.objFilePath != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var prefab = mod.ModHelper.Assets.Get3DObject(detail.objFilePath, detail.mtlFilePath);
|
||||
AssetBundleUtilities.ReplaceShaders(prefab);
|
||||
prefab.SetActive(false);
|
||||
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 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 = detailGO.transform.Find(childPath);
|
||||
if (childObj != null) childObj.gameObject.SetActive(false);
|
||||
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;
|
||||
}
|
||||
|
||||
detailInfoToCorrespondingSpawnedGameObject[detail] = detailGO;
|
||||
}
|
||||
|
||||
public static GameObject MakeDetail(GameObject go, Sector sector, string propToClone, MVector3 position, MVector3 rotation, float scale, bool alignWithNormal)
|
||||
{
|
||||
if (propToClone == VISION_TORCH_PATH) return MakeVisionTorch(go, sector, position, rotation, scale, 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);
|
||||
}
|
||||
|
||||
public static GameObject MakeDetail(GameObject planetGO, Sector sector, GameObject prefab, MVector3 position, MVector3 rotation, float scale, bool alignWithNormal)
|
||||
{
|
||||
if (prefab == null) return null;
|
||||
|
||||
GameObject prop = prefab.InstantiateInactive();
|
||||
prop.transform.parent = sector?.transform ?? planetGO.transform;
|
||||
prop.SetActive(false);
|
||||
|
||||
if (sector != null) sector.OnOccupantEnterSector += (SectorDetector sd) => OWAssetHandler.OnOccupantEnterSector(prop, sd, sector);
|
||||
OWAssetHandler.LoadObject(prop);
|
||||
|
||||
foreach (var component in prop.GetComponents<Component>().Concat(prop.GetComponentsInChildren<Component>()))
|
||||
{
|
||||
// Enable all children or something
|
||||
var enabledField = component?.GetType()?.GetField("enabled");
|
||||
if (enabledField != null && enabledField.FieldType == typeof(bool)) Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => enabledField.SetValue(component, true));
|
||||
|
||||
// Fix a bunch of sector stuff
|
||||
if (sector != null)
|
||||
{
|
||||
if (component is Sector)
|
||||
{
|
||||
(component as Sector)._parentSector = sector;
|
||||
}
|
||||
|
||||
// TODO: Make this work or smthng
|
||||
if (component is GhostIK) (component as GhostIK).enabled = false;
|
||||
if (component is GhostEffects) (component as GhostEffects).enabled = false;
|
||||
|
||||
if (component is DarkMatterVolume)
|
||||
{
|
||||
var probeVisuals = component.gameObject.transform.Find("ProbeVisuals");
|
||||
if (probeVisuals != null) probeVisuals.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
if (component is SectoredMonoBehaviour)
|
||||
{
|
||||
(component as SectoredMonoBehaviour).SetSector(sector);
|
||||
}
|
||||
else
|
||||
{
|
||||
var sectorField = component?.GetType()?.GetField("_sector");
|
||||
if (sectorField != null && sectorField.FieldType == typeof(Sector)) Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => sectorField.SetValue(component, sector));
|
||||
}
|
||||
|
||||
if (component is AnglerfishController)
|
||||
{
|
||||
try
|
||||
{
|
||||
(component as AnglerfishController)._chaseSpeed += OWPhysics.CalculateOrbitVelocity(planetGO.GetAttachedOWRigidbody(), planetGO.GetComponent<AstroObject>().GetPrimaryBody().GetAttachedOWRigidbody()).magnitude;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError($"Couldn't update AnglerFish chase speed: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
// Fix slide reel
|
||||
if (component is SlideCollectionContainer)
|
||||
{
|
||||
sector.OnOccupantEnterSector.AddListener((_) => (component as SlideCollectionContainer).LoadStreamingTextures());
|
||||
}
|
||||
|
||||
if (component is OWItemSocket)
|
||||
{
|
||||
(component as OWItemSocket)._sector = sector;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove things that require sectors. Will just keep extending this as things pop up
|
||||
|
||||
if (component is FogLight || component is SectoredMonoBehaviour)
|
||||
{
|
||||
GameObject.DestroyImmediate(component);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Fix a bunch of stuff when done loading
|
||||
Main.Instance.ModHelper.Events.Unity.RunWhen(() => Main.IsSystemReady, () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (component is Animator) (component as Animator).enabled = true;
|
||||
else if (component is Collider) (component as Collider).enabled = true;
|
||||
else if (component is Renderer) (component as Renderer).enabled = true;
|
||||
else if (component is Shape) (component as Shape).enabled = true;
|
||||
// If it's not a moving anglerfish make sure the anim controller is regular
|
||||
else if (component is AnglerfishAnimController && component.GetComponentInParent<AnglerfishController>() == null)
|
||||
{
|
||||
Logger.Log("Enabling anglerfish animation");
|
||||
var angler = (component as AnglerfishAnimController);
|
||||
// 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}] : {e.Message}, {e.StackTrace}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
prop.transform.position = position == null ? planetGO.transform.position : planetGO.transform.TransformPoint((Vector3)position);
|
||||
|
||||
Quaternion rot = rotation == null ? Quaternion.identity : Quaternion.Euler((Vector3)rotation);
|
||||
if (alignWithNormal)
|
||||
{
|
||||
// Apply the rotation after aligning it with normal
|
||||
var up = planetGO.transform.InverseTransformPoint(prop.transform.position).normalized;
|
||||
prop.transform.rotation = Quaternion.FromToRotation(Vector3.up, up);
|
||||
prop.transform.rotation *= rot;
|
||||
}
|
||||
else
|
||||
{
|
||||
prop.transform.rotation = planetGO.transform.TransformRotation(rot);
|
||||
}
|
||||
|
||||
prop.transform.localScale = scale != 0 ? Vector3.one * scale : prefab.transform.localScale;
|
||||
|
||||
prop.SetActive(true);
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
public static GameObject MakeVisionTorch(GameObject planetGO, Sector sector, MVector3 position, MVector3 rotation, float scale, bool alignWithNormal)
|
||||
{
|
||||
if (!Main.HasDLC)
|
||||
{
|
||||
Logger.LogError("Could not instantiate Prefab_IP_VisionTorchItem, user does not own the DLC.");
|
||||
return null;
|
||||
}
|
||||
|
||||
var prefab = SearchUtilities.Find(VISION_TORCH_PATH);
|
||||
if (prefab == null) Logger.LogError($"Couldn't find detail Prefab_IP_VisionTorchItem");
|
||||
|
||||
GameObject Prefab_IP_VisionTorchItem = MakeDetail(planetGO, sector, prefab, position, rotation, scale, alignWithNormal);
|
||||
|
||||
Prefab_IP_VisionTorchItem.GetComponent<VisionTorchItem>().enabled = true;
|
||||
Prefab_IP_VisionTorchItem.GetComponent<VisionTorchItem>().mindProjectorTrigger.enabled = true;
|
||||
|
||||
Prefab_IP_VisionTorchItem.GetComponent<VisionTorchItem>().mindSlideProjector._mindProjectorImageEffect = GameObject.Find("Player_Body/PlayerCamera").GetComponent<MindProjectorImageEffect>();
|
||||
|
||||
return Prefab_IP_VisionTorchItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
using NewHorizons.External.Configs;
|
||||
using NewHorizons.External.Modules;
|
||||
using NewHorizons.Handlers;
|
||||
using NewHorizons.Utility;
|
||||
using OWML.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using Logger = NewHorizons.Utility.Logger;
|
||||
namespace NewHorizons.Builder.Props
|
||||
{
|
||||
public static class DetailBuilder
|
||||
{
|
||||
private static Dictionary<PropModule.DetailInfo, GameObject> detailInfoToCorrespondingSpawnedGameObject = new Dictionary<PropModule.DetailInfo, GameObject>();
|
||||
|
||||
public static GameObject GetSpawnedGameObjectByDetailInfo(PropModule.DetailInfo detail)
|
||||
{
|
||||
if (!detailInfoToCorrespondingSpawnedGameObject.ContainsKey(detail)) return null;
|
||||
return detailInfoToCorrespondingSpawnedGameObject[detail];
|
||||
}
|
||||
|
||||
public static void Make(GameObject go, Sector sector, PlanetConfig config, IModBehaviour mod, string uniqueModName, PropModule.DetailInfo detail)
|
||||
{
|
||||
GameObject detailGO = null;
|
||||
|
||||
if (detail.assetBundle != null)
|
||||
{
|
||||
var prefab = AssetBundleUtilities.LoadPrefab(detail.assetBundle, detail.path, mod);
|
||||
|
||||
detailGO = MakeDetail(go, sector, prefab, detail.position, detail.rotation, detail.scale, detail.alignToNormal);
|
||||
}
|
||||
else if (detail.objFilePath != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var prefab = mod.ModHelper.Assets.Get3DObject(detail.objFilePath, detail.mtlFilePath);
|
||||
AssetBundleUtilities.ReplaceShaders(prefab);
|
||||
prefab.SetActive(false);
|
||||
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 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 = detailGO.transform.Find(childPath);
|
||||
if (childObj != null) childObj.gameObject.SetActive(false);
|
||||
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;
|
||||
}
|
||||
|
||||
detailInfoToCorrespondingSpawnedGameObject[detail] = detailGO;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public static GameObject MakeDetail(GameObject planetGO, Sector sector, GameObject prefab, MVector3 position, MVector3 rotation, float scale, bool alignWithNormal)
|
||||
{
|
||||
if (prefab == null) return null;
|
||||
|
||||
GameObject prop = prefab.InstantiateInactive();
|
||||
prop.transform.parent = sector?.transform ?? planetGO.transform;
|
||||
prop.SetActive(false);
|
||||
|
||||
if (sector != null) sector.OnOccupantEnterSector += (SectorDetector sd) => OWAssetHandler.OnOccupantEnterSector(prop, sd, sector);
|
||||
OWAssetHandler.LoadObject(prop);
|
||||
|
||||
foreach (var component in prop.GetComponents<Component>().Concat(prop.GetComponentsInChildren<Component>()))
|
||||
{
|
||||
// Enable all children or something
|
||||
var enabledField = component?.GetType()?.GetField("enabled");
|
||||
if (enabledField != null && enabledField.FieldType == typeof(bool)) Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => enabledField.SetValue(component, true));
|
||||
|
||||
// Fix a bunch of sector stuff
|
||||
if (sector != null)
|
||||
{
|
||||
if (component is Sector)
|
||||
{
|
||||
(component as Sector)._parentSector = sector;
|
||||
}
|
||||
|
||||
// TODO: Make this work or smthng
|
||||
if (component is GhostIK) (component as GhostIK).enabled = false;
|
||||
if (component is GhostEffects) (component as GhostEffects).enabled = false;
|
||||
|
||||
if (component is DarkMatterVolume)
|
||||
{
|
||||
var probeVisuals = component.gameObject.transform.Find("ProbeVisuals");
|
||||
if (probeVisuals != null) probeVisuals.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
if (component is SectoredMonoBehaviour)
|
||||
{
|
||||
(component as SectoredMonoBehaviour).SetSector(sector);
|
||||
}
|
||||
else
|
||||
{
|
||||
var sectorField = component?.GetType()?.GetField("_sector");
|
||||
if (sectorField != null && sectorField.FieldType == typeof(Sector)) Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => sectorField.SetValue(component, sector));
|
||||
}
|
||||
|
||||
if (component is AnglerfishController)
|
||||
{
|
||||
try
|
||||
{
|
||||
(component as AnglerfishController)._chaseSpeed += OWPhysics.CalculateOrbitVelocity(planetGO.GetAttachedOWRigidbody(), planetGO.GetComponent<AstroObject>().GetPrimaryBody().GetAttachedOWRigidbody()).magnitude;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError($"Couldn't update AnglerFish chase speed: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
// Fix slide reel
|
||||
if (component is SlideCollectionContainer)
|
||||
{
|
||||
sector.OnOccupantEnterSector.AddListener((_) => (component as SlideCollectionContainer).LoadStreamingTextures());
|
||||
}
|
||||
|
||||
if (component is OWItemSocket)
|
||||
{
|
||||
(component as OWItemSocket)._sector = sector;
|
||||
}
|
||||
|
||||
// Fix vision torch
|
||||
if (component is VisionTorchItem)
|
||||
{
|
||||
(component as VisionTorchItem).enabled = true;
|
||||
(component as VisionTorchItem).mindProjectorTrigger.enabled = true;
|
||||
(component as VisionTorchItem).mindSlideProjector._mindProjectorImageEffect = GameObject.Find("Player_Body/PlayerCamera").GetComponent<MindProjectorImageEffect>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove things that require sectors. Will just keep extending this as things pop up
|
||||
|
||||
if (component is FogLight || component is SectoredMonoBehaviour)
|
||||
{
|
||||
GameObject.DestroyImmediate(component);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Fix a bunch of stuff when done loading
|
||||
Main.Instance.ModHelper.Events.Unity.RunWhen(() => Main.IsSystemReady, () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (component is Animator) (component as Animator).enabled = true;
|
||||
else if (component is Collider) (component as Collider).enabled = true;
|
||||
else if (component is Renderer) (component as Renderer).enabled = true;
|
||||
else if (component is Shape) (component as Shape).enabled = true;
|
||||
// If it's not a moving anglerfish make sure the anim controller is regular
|
||||
else if (component is AnglerfishAnimController && component.GetComponentInParent<AnglerfishController>() == null)
|
||||
{
|
||||
Logger.Log("Enabling anglerfish animation");
|
||||
var angler = (component as AnglerfishAnimController);
|
||||
// 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}] : {e.Message}, {e.StackTrace}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
prop.transform.position = position == null ? planetGO.transform.position : planetGO.transform.TransformPoint((Vector3)position);
|
||||
|
||||
Quaternion rot = rotation == null ? Quaternion.identity : Quaternion.Euler((Vector3)rotation);
|
||||
if (alignWithNormal)
|
||||
{
|
||||
// Apply the rotation after aligning it with normal
|
||||
var up = planetGO.transform.InverseTransformPoint(prop.transform.position).normalized;
|
||||
prop.transform.rotation = Quaternion.FromToRotation(Vector3.up, up);
|
||||
prop.transform.rotation *= rot;
|
||||
}
|
||||
else
|
||||
{
|
||||
prop.transform.rotation = planetGO.transform.TransformRotation(rot);
|
||||
}
|
||||
|
||||
prop.transform.localScale = scale != 0 ? Vector3.one * scale : prefab.transform.localScale;
|
||||
|
||||
prop.SetActive(true);
|
||||
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user