Hide on condition (#652)

## Minor features
- Added `activationCondition` and `deactivationCondition` to details,
allowing them to be enabled/disabled depending on a dialogue condition.
Resolves #482.

## Improvements
- If the `path` for a detail is empty it will create an empty game
object now. This can be useful for adding other props to it as its
children.
This commit is contained in:
Noah Pilarski 2023-07-19 21:40:34 -04:00 committed by GitHub
commit c5873aa0ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 153 additions and 2 deletions

View File

@ -1,12 +1,11 @@
using NewHorizons.Builder.Props; using NewHorizons.Builder.Props;
using NewHorizons.External.Modules; using NewHorizons.External.Modules;
using NewHorizons.Utility; using NewHorizons.Utility;
using NewHorizons.Utility.OWML;
using NewHorizons.Utility.OuterWilds; using NewHorizons.Utility.OuterWilds;
using NewHorizons.Utility.OWML;
using System; using System;
using System.Reflection; using System.Reflection;
using UnityEngine; using UnityEngine;
using Steamworks;
namespace NewHorizons.Builder.General namespace NewHorizons.Builder.General
{ {

View File

@ -1,5 +1,6 @@
using NewHorizons.Builder.General; using NewHorizons.Builder.General;
using NewHorizons.Components; using NewHorizons.Components;
using NewHorizons.Components.Props;
using NewHorizons.External.Modules.Props; using NewHorizons.External.Modules.Props;
using NewHorizons.Handlers; using NewHorizons.Handlers;
using NewHorizons.Utility; using NewHorizons.Utility;
@ -210,6 +211,15 @@ namespace NewHorizons.Builder.Props
addPhysics.Radius = detail.physicsRadius; 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; _detailInfoToCorrespondingSpawnedGameObject[detail] = prop;
return prop; return prop;

View File

@ -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<ConditionalObjectActivation>();
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<PlayerCameraEffectController>();
GlobalMessenger<string, bool>.AddListener("DialogueConditionChanged", OnDialogueConditionChanged);
GlobalMessenger.AddListener("ExitConversation", OnExitConversation);
GlobalMessenger.AddListener("EnterConversation", OnEnterConversation);
}
public void OnDestroy()
{
GlobalMessenger<string, bool>.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();
}
}
}

View File

@ -79,6 +79,21 @@ namespace NewHorizons.External.Modules.Props
/// </summary> /// </summary>
public bool ignoreSun; public bool ignoreSun;
/// <summary>
/// Activates this game object when the dialogue condition is met
/// </summary>
public string activationCondition;
/// <summary>
/// Deactivates this game object when the dialogue condition is met
/// </summary>
public string deactivationCondition;
/// <summary>
/// Should the player close their eyes while the activation state changes. Only relevant if activationCondition or deactivationCondition are set.
/// </summary>
[DefaultValue(true)] public bool blinkWhenActiveChanged = true;
[Obsolete("alignToNormal is deprecated. Use alignRadial instead")] public bool alignToNormal; [Obsolete("alignToNormal is deprecated. Use alignRadial instead")] public bool alignToNormal;
} }

View File

@ -1328,6 +1328,19 @@
"ignoreSun": { "ignoreSun": {
"type": "boolean", "type": "boolean",
"description": "Set to true if this object's lighting should ignore the effects of sunlight" "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
} }
} }
}, },