From 3ede915cc41f44b558c9fd345ce092bfa4772ea7 Mon Sep 17 00:00:00 2001 From: Nick Date: Wed, 19 Jul 2023 21:21:29 -0400 Subject: [PATCH 1/2] Implement conditional object activation --- .../Builder/General/SpawnPointBuilder.cs | 3 +- NewHorizons/Builder/Props/DetailBuilder.cs | 10 ++ .../Props/ConditionalObjectActivation.cs | 114 ++++++++++++++++++ .../External/Modules/Props/DetailInfo.cs | 15 +++ 4 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 NewHorizons/Components/Props/ConditionalObjectActivation.cs diff --git a/NewHorizons/Builder/General/SpawnPointBuilder.cs b/NewHorizons/Builder/General/SpawnPointBuilder.cs index 591defb4..a53dc7b5 100644 --- a/NewHorizons/Builder/General/SpawnPointBuilder.cs +++ b/NewHorizons/Builder/General/SpawnPointBuilder.cs @@ -1,12 +1,11 @@ using NewHorizons.Builder.Props; using NewHorizons.External.Modules; using NewHorizons.Utility; -using NewHorizons.Utility.OWML; using NewHorizons.Utility.OuterWilds; +using NewHorizons.Utility.OWML; using System; using System.Reflection; using UnityEngine; -using Steamworks; namespace NewHorizons.Builder.General { diff --git a/NewHorizons/Builder/Props/DetailBuilder.cs b/NewHorizons/Builder/Props/DetailBuilder.cs index 1a82eb4d..d17da642 100644 --- a/NewHorizons/Builder/Props/DetailBuilder.cs +++ b/NewHorizons/Builder/Props/DetailBuilder.cs @@ -1,5 +1,6 @@ using NewHorizons.Builder.General; using NewHorizons.Components; +using NewHorizons.Components.Props; using NewHorizons.External.Modules.Props; using NewHorizons.Handlers; using NewHorizons.Utility; @@ -210,6 +211,15 @@ namespace NewHorizons.Builder.Props addPhysics.Radius = detail.physicsRadius; } + if (!string.IsNullOrEmpty(detail.activationCondition)) + { + ConditionalObjectActivation.SetUp(prop, detail.activationCondition, detail.blinkWhenActiveChanged, true); + } + if (!string.IsNullOrEmpty(detail.deactivationCondition)) + { + ConditionalObjectActivation.SetUp(prop, detail.deactivationCondition, detail.blinkWhenActiveChanged, false); + } + _detailInfoToCorrespondingSpawnedGameObject[detail] = prop; return prop; diff --git a/NewHorizons/Components/Props/ConditionalObjectActivation.cs b/NewHorizons/Components/Props/ConditionalObjectActivation.cs new file mode 100644 index 00000000..41f07ca9 --- /dev/null +++ b/NewHorizons/Components/Props/ConditionalObjectActivation.cs @@ -0,0 +1,114 @@ +using NewHorizons.Utility.OWML; +using System.Collections; +using UnityEngine; + +namespace NewHorizons.Components.Props +{ + public class ConditionalObjectActivation : MonoBehaviour + { + public GameObject GameObject; + public string DialogueCondition; + public bool CloseEyes; + public bool SetActiveWithCondition; + + private PlayerCameraEffectController _playerCameraEffectController; + private bool _changeConditionOnExitConversation; + private bool _inConversation; + + public static void SetUp(GameObject go, string condition, bool closeEyes, bool setActiveWithCondition) + { + var conditionalObjectActivationGO = new GameObject($"{go.name}_{condition}"); + var component = conditionalObjectActivationGO.AddComponent(); + component.GameObject = go; + component.DialogueCondition = condition; + component.CloseEyes = closeEyes; + component.SetActiveWithCondition = setActiveWithCondition; + } + + public void Start() + { + var currentConditionState = DialogueConditionManager.SharedInstance.GetConditionState(DialogueCondition); + + // Would just call OnDialogueConditionChanged but maybe theres an activator and deactivator for this object so we have to be more careful + if (SetActiveWithCondition && !currentConditionState) GameObject.SetActive(false); + if (!SetActiveWithCondition && currentConditionState) GameObject.SetActive(false); + } + + public void Awake() + { + _playerCameraEffectController = GameObject.FindObjectOfType(); + GlobalMessenger.AddListener("DialogueConditionChanged", OnDialogueConditionChanged); + GlobalMessenger.AddListener("ExitConversation", OnExitConversation); + GlobalMessenger.AddListener("EnterConversation", OnEnterConversation); + } + + public void OnDestroy() + { + GlobalMessenger.RemoveListener("DialogueConditionChanged", OnDialogueConditionChanged); + GlobalMessenger.RemoveListener("ExitConversation", OnExitConversation); + GlobalMessenger.RemoveListener("EnterConversation", OnEnterConversation); + } + + public void OnExitConversation() + { + _inConversation = false; + if (_changeConditionOnExitConversation) + { + OnDialogueConditionChanged(DialogueCondition, DialogueConditionManager.SharedInstance.GetConditionState(DialogueCondition)); + _changeConditionOnExitConversation = false; + } + } + + public void OnEnterConversation() + { + _inConversation = true; + } + + public void OnDialogueConditionChanged(string condition, bool state) + { + if (condition == DialogueCondition) + { + if (_inConversation) + { + _changeConditionOnExitConversation = true; + } + else + { + SetActive(SetActiveWithCondition == state); + } + } + } + + public void SetActive(bool active) + { + if (CloseEyes) + { + Delay.StartCoroutine(Coroutine(active)); + } + else + { + GameObject.SetActive(active); + } + } + + private IEnumerator Coroutine(bool active) + { + OWInput.ChangeInputMode(InputMode.None); + Locator.GetPauseCommandListener().AddPauseCommandLock(); + + _playerCameraEffectController.CloseEyes(0.7f); + yield return new WaitForSeconds(0.7f); + + // Eyes closed: swap character state + GameObject.SetActive(active); + + yield return new WaitForSeconds(0.3f); + + // Open eyes + _playerCameraEffectController.OpenEyes(0.7f); + + OWInput.ChangeInputMode(InputMode.Character); + Locator.GetPauseCommandListener().RemovePauseCommandLock(); + } + } +} diff --git a/NewHorizons/External/Modules/Props/DetailInfo.cs b/NewHorizons/External/Modules/Props/DetailInfo.cs index 2ca4d99e..6c8e1cf3 100644 --- a/NewHorizons/External/Modules/Props/DetailInfo.cs +++ b/NewHorizons/External/Modules/Props/DetailInfo.cs @@ -79,6 +79,21 @@ namespace NewHorizons.External.Modules.Props /// public bool ignoreSun; + /// + /// Activates this game object when the dialogue condition is met + /// + public string activationCondition; + + /// + /// Deactivates this game object when the dialogue condition is met + /// + public string deactivationCondition; + + /// + /// Should the player close their eyes while the activation state changes. Only relevant if activationCondition or deactivationCondition are set. + /// + [DefaultValue(true)] public bool blinkWhenActiveChanged = true; + [Obsolete("alignToNormal is deprecated. Use alignRadial instead")] public bool alignToNormal; } From d97d75e602acf5941d0f2b47835a09c7bb087f4f Mon Sep 17 00:00:00 2001 From: Ben C Date: Thu, 20 Jul 2023 01:23:39 +0000 Subject: [PATCH 2/2] Updated Schemas --- NewHorizons/Schemas/body_schema.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/NewHorizons/Schemas/body_schema.json b/NewHorizons/Schemas/body_schema.json index 8974ffde..b8c835e9 100644 --- a/NewHorizons/Schemas/body_schema.json +++ b/NewHorizons/Schemas/body_schema.json @@ -1328,6 +1328,19 @@ "ignoreSun": { "type": "boolean", "description": "Set to true if this object's lighting should ignore the effects of sunlight" + }, + "activationCondition": { + "type": "string", + "description": "Activates this game object when the dialogue condition is met" + }, + "deactivationCondition": { + "type": "string", + "description": "Deactivates this game object when the dialogue condition is met" + }, + "blinkWhenActiveChanged": { + "type": "boolean", + "description": "Should the player close their eyes while the activation state changes. Only relevant if activationCondition or deactivationCondition are set.", + "default": true } } },