diff --git a/NewHorizons/Builder/Props/ProjectionBuilder.cs b/NewHorizons/Builder/Props/ProjectionBuilder.cs index cbfa8ba5..259835bf 100644 --- a/NewHorizons/Builder/Props/ProjectionBuilder.cs +++ b/NewHorizons/Builder/Props/ProjectionBuilder.cs @@ -5,7 +5,7 @@ using OWML.Common; using System; using System.Collections.Generic; using UnityEngine; -using static NewHorizons.External.Modules.PropModule; +using static NewHorizons.External.Modules.PropModule; using Logger = NewHorizons.Utility.Logger; namespace NewHorizons.Builder.Props { @@ -18,8 +18,8 @@ namespace NewHorizons.Builder.Props public static void Make(GameObject go, Sector sector, PropModule.ProjectionInfo info, IModBehaviour mod) { if (info.type == "autoProjector") MakeAutoProjector(go, sector, info, mod); - else if (info.type == "slideReel") MakeSlideReel(go, sector, info, mod); - else if (info.type == "playerVisionTorchTarget") MakeMindSlidesTarget(go, sector, info, mod); + else if (info.type == "slideReel") MakeSlideReel(go, sector, info, mod); + else if (info.type == "playerVisionTorchTarget") MakeMindSlidesTarget(go, sector, info, mod); else if (info.type == "standingVisionTorch") MakeStandingVisionTorch(go, sector, info, mod); else Logger.LogError($"Invalid projection type {info.type}"); } @@ -156,120 +156,120 @@ namespace NewHorizons.Builder.Props projectorObj.SetActive(true); } - - // Makes a target for a vision torch to scan - public static GameObject MakeMindSlidesTarget(GameObject planetGO, Sector sector, PropModule.ProjectionInfo info, IModBehaviour mod) - { - // 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"; - GameObject g = DetailBuilder.MakeDetail(planetGO, sector, path, info.position, Vector3.zero, 2, false); - + + // Makes a target for a vision torch to scan + public static GameObject MakeMindSlidesTarget(GameObject planetGO, Sector sector, PropModule.ProjectionInfo info, IModBehaviour mod) + { + // 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"; + GameObject g = DetailBuilder.MakeDetail(planetGO, sector, path, info.position, Vector3.zero, 2, false); + if (g == null) { Logger.LogWarning($"Tried to make a vision torch target but couldn't. Do you have the DLC installed?"); return null; - } - - g.name = "VisionStaffDetector"; - - // The number of slides is unlimited, 15 is only for texturing the actual slide reel item. This is not a slide reel item - SlideInfo[] slides = info.slides; - var slidesCount = slides.Length; - var slideCollection = new SlideCollection(slidesCount); - - - for (int i = 0; i < slidesCount; i++) - { - var slide = new Slide(); - var slideInfo = slides[i]; - - // TODO: do this part asynchronously so that you can load all the slides you want without stalling the game out for 5 days - var texture = ImageUtilities.GetTexture(mod, slideInfo.imagePath); - slide.textureOverride = texture; //ImageUtilities.Invert(texture); - - AddModules(slideInfo, ref slide); - - slideCollection.slides[i] = slide; - } - - // attatch a component to store all the data for the slides that play when a vision torch scans this target - VisionTorchTarget target = g.AddComponent(); - SlideCollectionContainer slideCollectionContainer = g.AddComponent(); - slideCollectionContainer.slideCollection = slideCollection; - target.slideCollection = g.AddComponent(); - target.slideCollection._slideCollectionContainer = slideCollectionContainer; - target.slideCollectionContainer = slideCollectionContainer; - - // Idk why but it wants reveals to be comma delimited not a list - if (info.reveals != null) slideCollectionContainer._shipLogOnComplete = string.Join(",", info.reveals); - - return g; - } - - public static GameObject MakeStandingVisionTorch(GameObject planetGO, Sector sector, PropModule.ProjectionInfo info, IModBehaviour mod) - { - // - // spawn the torch itself - // - - var path = "RingWorld_Body/Sector_RingWorld/Sector_SecretEntrance/Interactibles_SecretEntrance/Experiment_1/VisionTorchApparatus/VisionTorchRoot/Prefab_IP_VisionTorchProjector"; - GameObject standingTorch = DetailBuilder.MakeDetail(planetGO, sector, path, info.position, info.rotation, 1, false); - + } + + g.name = "VisionStaffDetector"; + + // The number of slides is unlimited, 15 is only for texturing the actual slide reel item. This is not a slide reel item + SlideInfo[] slides = info.slides; + var slidesCount = slides.Length; + var slideCollection = new SlideCollection(slidesCount); + + + for (int i = 0; i < slidesCount; i++) + { + var slide = new Slide(); + var slideInfo = slides[i]; + + // TODO: do this part asynchronously so that you can load all the slides you want without stalling the game out for 5 days + var texture = ImageUtilities.GetTexture(mod, slideInfo.imagePath); + slide.textureOverride = texture; //ImageUtilities.Invert(texture); + + AddModules(slideInfo, ref slide); + + slideCollection.slides[i] = slide; + } + + // attatch a component to store all the data for the slides that play when a vision torch scans this target + VisionTorchTarget target = g.AddComponent(); + SlideCollectionContainer slideCollectionContainer = g.AddComponent(); + slideCollectionContainer.slideCollection = slideCollection; + target.slideCollection = g.AddComponent(); + target.slideCollection._slideCollectionContainer = slideCollectionContainer; + target.slideCollectionContainer = slideCollectionContainer; + + // Idk why but it wants reveals to be comma delimited not a list + if (info.reveals != null) slideCollectionContainer._shipLogOnComplete = string.Join(",", info.reveals); + + return g; + } + + public static GameObject MakeStandingVisionTorch(GameObject planetGO, Sector sector, PropModule.ProjectionInfo info, IModBehaviour mod) + { + // + // spawn the torch itself + // + + var path = "RingWorld_Body/Sector_RingWorld/Sector_SecretEntrance/Interactibles_SecretEntrance/Experiment_1/VisionTorchApparatus/VisionTorchRoot/Prefab_IP_VisionTorchProjector"; + GameObject standingTorch = DetailBuilder.MakeDetail(planetGO, sector, path, info.position, info.rotation, 1, false); + if (standingTorch == null) { Logger.LogWarning($"Tried to make a vision torch target but couldn't. Do you have the DLC installed?"); return null; - } - - // - // set some required properties on the torch - // - - MindSlideProjector mindSlideProjector = standingTorch.GetComponent(); - mindSlideProjector._mindProjectorImageEffect = GameObject.Find("Player_Body/PlayerCamera").GetComponent(); - - // - // 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 - SlideInfo[] slides = info.slides; - var slidesCount = slides.Length; - var slideCollection = new SlideCollection(slidesCount); - - for (int i = 0; i < slidesCount; i++) - { - var slide = new Slide(); - var slideInfo = slides[i]; - - // TODO: do this part asynchronously so that you can load all the slides you want without stalling the game out for 5 days - var texture = ImageUtilities.GetTexture(mod, slideInfo.imagePath); - slide.textureOverride = texture; //ImageUtilities.Invert(texture); - - AddModules(slideInfo, ref slide); - - slideCollection.slides[i] = slide; - } - - // set up the containers for the slides - SlideCollectionContainer slideCollectionContainer = standingTorch.AddComponent(); - slideCollectionContainer.slideCollection = slideCollection; - MindSlideCollection mindSlideCollection = standingTorch.AddComponent(); - mindSlideCollection._slideCollectionContainer = slideCollectionContainer; - - // make sure that these slides play when the player wanders into the beam - // _slideCollectionItem is actually a reference to a SlideCollectionContainer. Not a slide reel item - standingTorch.GetComponent()._mindSlideCollection = mindSlideCollection; - mindSlideProjector._slideCollectionItem = slideCollectionContainer; - mindSlideProjector._mindSlideCollection = mindSlideCollection; - mindSlideProjector.SetMindSlideCollection(mindSlideCollection); - - - // Idk why but it wants reveals to be comma delimited not a list - if (info.reveals != null) slideCollectionContainer._shipLogOnComplete = string.Join(",", info.reveals); - - return standingTorch; - } + } + + // + // set some required properties on the torch + // + + MindSlideProjector mindSlideProjector = standingTorch.GetComponent(); + mindSlideProjector._mindProjectorImageEffect = GameObject.Find("Player_Body/PlayerCamera").GetComponent(); + + // + // 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 + SlideInfo[] slides = info.slides; + var slidesCount = slides.Length; + var slideCollection = new SlideCollection(slidesCount); + + for (int i = 0; i < slidesCount; i++) + { + var slide = new Slide(); + var slideInfo = slides[i]; + + // TODO: do this part asynchronously so that you can load all the slides you want without stalling the game out for 5 days + var texture = ImageUtilities.GetTexture(mod, slideInfo.imagePath); + slide.textureOverride = texture; //ImageUtilities.Invert(texture); + + AddModules(slideInfo, ref slide); + + slideCollection.slides[i] = slide; + } + + // set up the containers for the slides + SlideCollectionContainer slideCollectionContainer = standingTorch.AddComponent(); + slideCollectionContainer.slideCollection = slideCollection; + MindSlideCollection mindSlideCollection = standingTorch.AddComponent(); + mindSlideCollection._slideCollectionContainer = slideCollectionContainer; + + // make sure that these slides play when the player wanders into the beam + // _slideCollectionItem is actually a reference to a SlideCollectionContainer. Not a slide reel item + standingTorch.GetComponent()._mindSlideCollection = mindSlideCollection; + mindSlideProjector._slideCollectionItem = slideCollectionContainer; + mindSlideProjector._mindSlideCollection = mindSlideCollection; + mindSlideProjector.SetMindSlideCollection(mindSlideCollection); + + + // Idk why but it wants reveals to be comma delimited not a list + if (info.reveals != null) slideCollectionContainer._shipLogOnComplete = string.Join(",", info.reveals); + + return standingTorch; + } private static void AddModules(PropModule.SlideInfo slideInfo, ref Slide slide) { @@ -318,11 +318,11 @@ namespace NewHorizons.Builder.Props Slide.WriteModules(modules, ref slide._modulesList, ref slide._modulesData, ref slide.lengths); } - } - - public class VisionTorchTarget : MonoBehaviour - { - public MindSlideCollection slideCollection; - public SlideCollectionContainer slideCollectionContainer; + } + + public class VisionTorchTarget : MonoBehaviour + { + public MindSlideCollection slideCollection; + public SlideCollectionContainer slideCollectionContainer; } } diff --git a/NewHorizons/Patches/ToolModeSwapperPatches.cs b/NewHorizons/Patches/ToolModeSwapperPatches.cs index dc102864..90639421 100644 --- a/NewHorizons/Patches/ToolModeSwapperPatches.cs +++ b/NewHorizons/Patches/ToolModeSwapperPatches.cs @@ -1,36 +1,36 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using HarmonyLib; - -namespace NewHorizons.Patches -{ - [HarmonyPatch] - public static class ToolModeSwapperPatches - { - - // Patches ToolModeSwapper.EquipToolMode(ToolMode mode) to deny swaps if you're holding a vision torch. - // This is critical for preventing swapping to the scout launcher (causes memory slides to fail) but it - // just doesn't look right when you switch to other stuff (eg the signalscope), so I'm disabling swapping tools entirely - - // the correct way to do this is to patch ToolModeSwapper.Update to be exactly the same as it is now, but change the below line - // to include a check for "is holding vision torch", but I'm not copy/pasting an entire function, no sir - // if (((_currentToolMode == ToolMode.None || _currentToolMode == ToolMode.Item) && Locator.GetPlayerSuit().IsWearingSuit(includeTrainingSuit: false)) || ((_currentToolMode == ToolMode.None || _currentToolMode == ToolMode.SignalScope) && OWInput.IsInputMode(InputMode.ShipCockpit))) - [HarmonyPrefix] - [HarmonyPatch(typeof(ToolModeSwapper), nameof(ToolModeSwapper.EquipToolMode))] - public static bool ToolModeSwapper_EquipToolMode(ToolModeSwapper __instance, ToolMode mode) - { - bool isHoldingVisionTorch = __instance.GetItemCarryTool()?.GetHeldItemType() == ItemType.VisionTorch; - bool swappingToRestrictedTool = - mode == ToolMode.Probe || - mode == ToolMode.SignalScope || - mode == ToolMode.Translator; - - if (isHoldingVisionTorch && swappingToRestrictedTool) return false; - - return true; - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HarmonyLib; + +namespace NewHorizons.Patches +{ + [HarmonyPatch] + public static class ToolModeSwapperPatches + { + + // Patches ToolModeSwapper.EquipToolMode(ToolMode mode) to deny swaps if you're holding a vision torch. + // This is critical for preventing swapping to the scout launcher (causes memory slides to fail) but it + // just doesn't look right when you switch to other stuff (eg the signalscope), so I'm disabling swapping tools entirely + + // the correct way to do this is to patch ToolModeSwapper.Update to be exactly the same as it is now, but change the below line + // to include a check for "is holding vision torch", but I'm not copy/pasting an entire function, no sir + // if (((_currentToolMode == ToolMode.None || _currentToolMode == ToolMode.Item) && Locator.GetPlayerSuit().IsWearingSuit(includeTrainingSuit: false)) || ((_currentToolMode == ToolMode.None || _currentToolMode == ToolMode.SignalScope) && OWInput.IsInputMode(InputMode.ShipCockpit))) + [HarmonyPrefix] + [HarmonyPatch(typeof(ToolModeSwapper), nameof(ToolModeSwapper.EquipToolMode))] + public static bool ToolModeSwapper_EquipToolMode(ToolModeSwapper __instance, ToolMode mode) + { + bool isHoldingVisionTorch = __instance.GetItemCarryTool()?.GetHeldItemType() == ItemType.VisionTorch; + bool swappingToRestrictedTool = + mode == ToolMode.Probe || + mode == ToolMode.SignalScope || + mode == ToolMode.Translator; + + if (isHoldingVisionTorch && swappingToRestrictedTool) return false; + + return true; + } + } +} diff --git a/NewHorizons/Patches/VisionTorchPatches.cs b/NewHorizons/Patches/VisionTorchPatches.cs index c51e6afe..c715c44f 100644 --- a/NewHorizons/Patches/VisionTorchPatches.cs +++ b/NewHorizons/Patches/VisionTorchPatches.cs @@ -1,75 +1,75 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using HarmonyLib; -using NewHorizons.Builder.Props; -using UnityEngine; - -namespace NewHorizons.Patches -{ - - [HarmonyPatch] - public static class MindProjectorTriggerPatches - { - [HarmonyPrefix] - [HarmonyPatch(typeof(MindProjectorTrigger), nameof(MindProjectorTrigger.OnTriggerVolumeEntry))] - public static bool MindProjectorTrigger_OnTriggerVolumeEntry(MindProjectorTrigger __instance, GameObject hitObj) - { - VisionTorchTarget t = hitObj.GetComponent(); - if (t != null) //(hitObj.CompareTag("PrisonerDetector")) - { - // _slideCollectionItem is actually a reference to a SlideCollectionContainer. Not a slide reel item - __instance._mindProjector._slideCollectionItem = t.slideCollectionContainer; - __instance._mindProjector._mindSlideCollection = t.slideCollection; - __instance._mindProjector.SetMindSlideCollection(t.slideCollection); - - Main.Instance.ModHelper.Console.WriteLine("MIND PROJECTOR CUSTOM TRIGGER"); - __instance.OnBeamStartHitPrisoner.Invoke(); - __instance._mindProjector.Play(reset: true); - __instance._mindProjector.OnProjectionStart += new OWEvent.OWCallback(__instance.OnProjectionStart); - __instance._mindProjector.OnProjectionComplete += new OWEvent.OWCallback(__instance.OnProjectionComplete); - - // __instance._mindProjector._slideCollectionItem.onSlideTextureUpdated += new OWEvent.OWCallback(__instance._mindProjector.OnSlideTextureUpdated); - //__instance._mindProjector._slideCollectionItem.onPlayBeatAudio += new OWEvent.OWCallback(__instance._mindProjector.OnPlayBeatAudio); - //__instance._mindProjector._slideCollectionItem.Initialize(); - - Locator.GetPlayerTransform().GetComponent().LockOn(hitObj.transform, Vector3.zero); - __instance._playerLockedOn = true; - return false; - } - - return true; - } - - // TOOD: OnTriggerVolumeExit - } - - [HarmonyPatch] - public static class VisionTorchItemPatches - { - // This is some dark magic - // this creates a method called base_DropItem that basically just calls OWItem.PickUpItem whenever it (VisionTorchItemPatches.base_PickUpItem) is called - [HarmonyReversePatch] - [HarmonyPatch(typeof(OWItem), nameof(OWItem.DropItem))] - private static void base_DropItem(OWItem instance, Vector3 position, Vector3 normal, Transform parent, Sector sector, IItemDropTarget customDropTarget) { } - - - // Make the vision torch droppable. In the base game you can only drop it if you're in the dream world. - [HarmonyPrefix] - [HarmonyPatch(typeof(VisionTorchItem), nameof(VisionTorchItem.DropItem))] - public static bool VisionTorchItem_DropItem(VisionTorchItem __instance, Vector3 position, Vector3 normal, Transform parent, Sector sector, IItemDropTarget customDropTarget) - { - if (!Locator.GetDreamWorldController().IsInDream()) - { - base_DropItem(__instance, position, normal, parent, sector, customDropTarget); - } - - return true; - } - - // ProbeLauncher.Disable()? - // public override void PickUpItem(Transform holdTranform) - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HarmonyLib; +using NewHorizons.Builder.Props; +using UnityEngine; + +namespace NewHorizons.Patches +{ + + [HarmonyPatch] + public static class MindProjectorTriggerPatches + { + [HarmonyPrefix] + [HarmonyPatch(typeof(MindProjectorTrigger), nameof(MindProjectorTrigger.OnTriggerVolumeEntry))] + public static bool MindProjectorTrigger_OnTriggerVolumeEntry(MindProjectorTrigger __instance, GameObject hitObj) + { + VisionTorchTarget t = hitObj.GetComponent(); + if (t != null) //(hitObj.CompareTag("PrisonerDetector")) + { + // _slideCollectionItem is actually a reference to a SlideCollectionContainer. Not a slide reel item + __instance._mindProjector._slideCollectionItem = t.slideCollectionContainer; + __instance._mindProjector._mindSlideCollection = t.slideCollection; + __instance._mindProjector.SetMindSlideCollection(t.slideCollection); + + Main.Instance.ModHelper.Console.WriteLine("MIND PROJECTOR CUSTOM TRIGGER"); + __instance.OnBeamStartHitPrisoner.Invoke(); + __instance._mindProjector.Play(reset: true); + __instance._mindProjector.OnProjectionStart += new OWEvent.OWCallback(__instance.OnProjectionStart); + __instance._mindProjector.OnProjectionComplete += new OWEvent.OWCallback(__instance.OnProjectionComplete); + + // __instance._mindProjector._slideCollectionItem.onSlideTextureUpdated += new OWEvent.OWCallback(__instance._mindProjector.OnSlideTextureUpdated); + //__instance._mindProjector._slideCollectionItem.onPlayBeatAudio += new OWEvent.OWCallback(__instance._mindProjector.OnPlayBeatAudio); + //__instance._mindProjector._slideCollectionItem.Initialize(); + + Locator.GetPlayerTransform().GetComponent().LockOn(hitObj.transform, Vector3.zero); + __instance._playerLockedOn = true; + return false; + } + + return true; + } + + // TOOD: OnTriggerVolumeExit + } + + [HarmonyPatch] + public static class VisionTorchItemPatches + { + // This is some dark magic + // this creates a method called base_DropItem that basically just calls OWItem.PickUpItem whenever it (VisionTorchItemPatches.base_PickUpItem) is called + [HarmonyReversePatch] + [HarmonyPatch(typeof(OWItem), nameof(OWItem.DropItem))] + private static void base_DropItem(OWItem instance, Vector3 position, Vector3 normal, Transform parent, Sector sector, IItemDropTarget customDropTarget) { } + + + // Make the vision torch droppable. In the base game you can only drop it if you're in the dream world. + [HarmonyPrefix] + [HarmonyPatch(typeof(VisionTorchItem), nameof(VisionTorchItem.DropItem))] + public static bool VisionTorchItem_DropItem(VisionTorchItem __instance, Vector3 position, Vector3 normal, Transform parent, Sector sector, IItemDropTarget customDropTarget) + { + if (!Locator.GetDreamWorldController().IsInDream()) + { + base_DropItem(__instance, position, normal, parent, sector, customDropTarget); + } + + return true; + } + + // ProbeLauncher.Disable()? + // public override void PickUpItem(Transform holdTranform) + } +}