mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
More Condition Triggers (#1096)
## Major features - Added `conditionTriggerVolumes` to set a dialogue condition when the player (or scout or ship) enters an area. - Added `interactionVolumes` for interactable objects that set a dialogue condition, play a sound, and/or trigger an animation. ## Minor features - Added `condition` fields to `dreamCandles` and `projectionTotems` to set dialogue conditions when they are lit or extinguished.
This commit is contained in:
commit
fdf78802e9
@ -1,3 +1,4 @@
|
|||||||
|
using NewHorizons.Components.EOTE;
|
||||||
using NewHorizons.External.Modules.Props;
|
using NewHorizons.External.Modules.Props;
|
||||||
using NewHorizons.External.Modules.Props.EchoesOfTheEye;
|
using NewHorizons.External.Modules.Props.EchoesOfTheEye;
|
||||||
using NewHorizons.Handlers;
|
using NewHorizons.Handlers;
|
||||||
@ -70,6 +71,12 @@ namespace NewHorizons.Builder.Props.EchoesOfTheEye
|
|||||||
dreamCandle._startLit = info.startLit;
|
dreamCandle._startLit = info.startLit;
|
||||||
dreamCandle.SetLit(info.startLit, false, true);
|
dreamCandle.SetLit(info.startLit, false, true);
|
||||||
|
|
||||||
|
if (info.condition != null)
|
||||||
|
{
|
||||||
|
var conditionController = dreamCandle.gameObject.AddComponent<DreamLightConditionController>();
|
||||||
|
conditionController.SetFromInfo(info.condition);
|
||||||
|
}
|
||||||
|
|
||||||
return candleObj;
|
return candleObj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
using NewHorizons.Components.EOTE;
|
||||||
using NewHorizons.External.Modules.Props;
|
using NewHorizons.External.Modules.Props;
|
||||||
using NewHorizons.External.Modules.Props.EchoesOfTheEye;
|
using NewHorizons.External.Modules.Props.EchoesOfTheEye;
|
||||||
using NewHorizons.Handlers;
|
using NewHorizons.Handlers;
|
||||||
@ -116,6 +117,13 @@ namespace NewHorizons.Builder.Props.EchoesOfTheEye
|
|||||||
projector._lit = info.startLit;
|
projector._lit = info.startLit;
|
||||||
projector._startLit = info.startLit;
|
projector._startLit = info.startLit;
|
||||||
projector._extinguishOnly = info.extinguishOnly;
|
projector._extinguishOnly = info.extinguishOnly;
|
||||||
|
|
||||||
|
if (info.condition != null)
|
||||||
|
{
|
||||||
|
var conditionController = projector.gameObject.AddComponent<DreamLightConditionController>();
|
||||||
|
conditionController.SetFromInfo(info.condition);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Delay.FireOnNextUpdate(() =>
|
Delay.FireOnNextUpdate(() =>
|
||||||
{
|
{
|
||||||
|
|||||||
25
NewHorizons/Builder/Volumes/ConditionTriggerVolumeBuilder.cs
Normal file
25
NewHorizons/Builder/Volumes/ConditionTriggerVolumeBuilder.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using NewHorizons.Components.Volumes;
|
||||||
|
using NewHorizons.External.Modules.Volumes.VolumeInfos;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NewHorizons.Builder.Volumes
|
||||||
|
{
|
||||||
|
internal static class ConditionTriggerVolumeBuilder
|
||||||
|
{
|
||||||
|
public static ConditionTriggerVolume Make(GameObject planetGO, Sector sector, ConditionTriggerVolumeInfo info)
|
||||||
|
{
|
||||||
|
var volume = VolumeBuilder.Make<ConditionTriggerVolume>(planetGO, sector, info);
|
||||||
|
|
||||||
|
volume.Condition = info.condition;
|
||||||
|
volume.Persistent = info.persistent;
|
||||||
|
volume.Reversible = info.reversible;
|
||||||
|
volume.Player = info.player;
|
||||||
|
volume.Probe = info.probe;
|
||||||
|
volume.Ship = info.ship;
|
||||||
|
|
||||||
|
volume.gameObject.SetActive(true);
|
||||||
|
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
87
NewHorizons/Builder/Volumes/InteractionVolumeBuilder.cs
Normal file
87
NewHorizons/Builder/Volumes/InteractionVolumeBuilder.cs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
using NewHorizons.Components.Volumes;
|
||||||
|
using NewHorizons.External.Modules.Volumes.VolumeInfos;
|
||||||
|
using NewHorizons.Handlers;
|
||||||
|
using NewHorizons.Utility;
|
||||||
|
using NewHorizons.Utility.Files;
|
||||||
|
using NewHorizons.Utility.OuterWilds;
|
||||||
|
using NewHorizons.Utility.OWML;
|
||||||
|
using OWML.Common;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NewHorizons.Builder.Volumes
|
||||||
|
{
|
||||||
|
internal static class InteractionVolumeBuilder
|
||||||
|
{
|
||||||
|
public static InteractReceiver Make(GameObject planetGO, Sector sector, InteractionVolumeInfo info, IModBehaviour mod)
|
||||||
|
{
|
||||||
|
// Interaction volumes must use colliders because the first-person interaction system uses raycasting
|
||||||
|
if (info.shape != null)
|
||||||
|
{
|
||||||
|
info.shape.useShape = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var receiver = VolumeBuilder.Make<InteractReceiver>(planetGO, sector, info);
|
||||||
|
receiver.gameObject.layer = Layer.Interactible;
|
||||||
|
|
||||||
|
receiver._interactRange = info.range;
|
||||||
|
receiver._checkViewAngle = info.maxViewAngle.HasValue;
|
||||||
|
receiver._maxViewAngle = info.maxViewAngle ?? 180f;
|
||||||
|
receiver._usableInShip = info.usableInShip;
|
||||||
|
|
||||||
|
var volume = receiver.gameObject.AddComponent<NHInteractionVolume>();
|
||||||
|
|
||||||
|
volume.Reusable = info.reusable;
|
||||||
|
volume.Condition = info.condition;
|
||||||
|
volume.Persistent = info.persistent;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(info.audio))
|
||||||
|
{
|
||||||
|
var audioSource = receiver.gameObject.AddComponent<AudioSource>();
|
||||||
|
|
||||||
|
// This could be more configurable but this should cover the most common use cases without bloating the info object
|
||||||
|
var owAudioSource = receiver.gameObject.AddComponent<OWAudioSource>();
|
||||||
|
owAudioSource._audioSource = audioSource;
|
||||||
|
owAudioSource.playOnAwake = false;
|
||||||
|
owAudioSource.loop = false;
|
||||||
|
owAudioSource.SetMaxVolume(1f);
|
||||||
|
owAudioSource.SetClipSelectionType(OWAudioSource.ClipSelectionOnPlay.RANDOM);
|
||||||
|
owAudioSource.SetTrack(OWAudioMixer.TrackName.Environment);
|
||||||
|
AudioUtilities.SetAudioClip(owAudioSource, info.audio, mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(info.pathToAnimator))
|
||||||
|
{
|
||||||
|
var animObj = planetGO.transform.Find(info.pathToAnimator);
|
||||||
|
|
||||||
|
if (animObj == null)
|
||||||
|
{
|
||||||
|
NHLogger.LogError($"Couldn't find child of {planetGO.transform.GetPath()} at {info.pathToAnimator}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var animator = animObj.GetComponent<Animator>();
|
||||||
|
if (animator == null)
|
||||||
|
{
|
||||||
|
NHLogger.LogError($"Couldn't find Animator on {animObj.name} at {info.pathToAnimator}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
volume.TargetAnimator = animator;
|
||||||
|
volume.AnimationTrigger = info.animationTrigger;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
receiver.gameObject.SetActive(true);
|
||||||
|
|
||||||
|
var text = TranslationHandler.GetTranslation(info.prompt, TranslationHandler.TextType.UI);
|
||||||
|
Delay.FireOnNextUpdate(() =>
|
||||||
|
{
|
||||||
|
// This NREs if set immediately
|
||||||
|
receiver.ChangePrompt(text);
|
||||||
|
});
|
||||||
|
|
||||||
|
return receiver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -35,6 +35,13 @@ namespace NewHorizons.Builder.Volumes
|
|||||||
AudioVolumeBuilder.Make(go, sector, audioVolume, mod);
|
AudioVolumeBuilder.Make(go, sector, audioVolume, mod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (config.Volumes.conditionTriggerVolumes != null)
|
||||||
|
{
|
||||||
|
foreach (var conditionTriggerVolume in config.Volumes.conditionTriggerVolumes)
|
||||||
|
{
|
||||||
|
ConditionTriggerVolumeBuilder.Make(go, sector, conditionTriggerVolume);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (config.Volumes.dayNightAudioVolumes != null)
|
if (config.Volumes.dayNightAudioVolumes != null)
|
||||||
{
|
{
|
||||||
foreach (var dayNightAudioVolume in config.Volumes.dayNightAudioVolumes)
|
foreach (var dayNightAudioVolume in config.Volumes.dayNightAudioVolumes)
|
||||||
@ -63,6 +70,13 @@ namespace NewHorizons.Builder.Volumes
|
|||||||
VolumeBuilder.MakeAndEnable<MapRestrictionVolume>(go, sector, mapRestrictionVolume);
|
VolumeBuilder.MakeAndEnable<MapRestrictionVolume>(go, sector, mapRestrictionVolume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (config.Volumes.interactionVolumes != null)
|
||||||
|
{
|
||||||
|
foreach (var interactionVolume in config.Volumes.interactionVolumes)
|
||||||
|
{
|
||||||
|
InteractionVolumeBuilder.Make(go, sector, interactionVolume, mod);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (config.Volumes.interferenceVolumes != null)
|
if (config.Volumes.interferenceVolumes != null)
|
||||||
{
|
{
|
||||||
foreach (var interferenceVolume in config.Volumes.interferenceVolumes)
|
foreach (var interferenceVolume in config.Volumes.interferenceVolumes)
|
||||||
|
|||||||
85
NewHorizons/Components/EOTE/DreamLightConditionController.cs
Normal file
85
NewHorizons/Components/EOTE/DreamLightConditionController.cs
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
using NewHorizons.External.Modules.Props.EchoesOfTheEye;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NewHorizons.Components.EOTE
|
||||||
|
{
|
||||||
|
public class DreamLightConditionController : MonoBehaviour
|
||||||
|
{
|
||||||
|
public string Condition { get; set; }
|
||||||
|
public bool Persistent { get; set; }
|
||||||
|
public bool Reversible { get; set; }
|
||||||
|
public bool OnExtinguish { get; set; }
|
||||||
|
|
||||||
|
DreamObjectProjector _projector;
|
||||||
|
DreamCandle _dreamCandle;
|
||||||
|
|
||||||
|
public void SetFromInfo(DreamLightConditionInfo info)
|
||||||
|
{
|
||||||
|
Condition = info.condition;
|
||||||
|
Persistent = info.persistent;
|
||||||
|
Reversible = info.reversible;
|
||||||
|
OnExtinguish = info.onExtinguish;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void Awake()
|
||||||
|
{
|
||||||
|
_projector = GetComponent<DreamObjectProjector>();
|
||||||
|
_projector.OnProjectorLit.AddListener(OnProjectorLit);
|
||||||
|
_projector.OnProjectorExtinguished.AddListener(OnProjectorExtinguished);
|
||||||
|
|
||||||
|
_dreamCandle = GetComponent<DreamCandle>();
|
||||||
|
if (_dreamCandle != null)
|
||||||
|
{
|
||||||
|
_dreamCandle.OnLitStateChanged.AddListener(OnCandleLitStateChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnDestroy()
|
||||||
|
{
|
||||||
|
if (_projector != null)
|
||||||
|
{
|
||||||
|
_projector.OnProjectorLit.RemoveListener(OnProjectorLit);
|
||||||
|
_projector.OnProjectorExtinguished.RemoveListener(OnProjectorExtinguished);
|
||||||
|
}
|
||||||
|
if (_dreamCandle != null)
|
||||||
|
{
|
||||||
|
_dreamCandle.OnLitStateChanged.RemoveListener(OnCandleLitStateChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnProjectorLit()
|
||||||
|
{
|
||||||
|
HandleCondition(!OnExtinguish);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnProjectorExtinguished()
|
||||||
|
{
|
||||||
|
HandleCondition(OnExtinguish);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCandleLitStateChanged()
|
||||||
|
{
|
||||||
|
HandleCondition(OnExtinguish ? !_dreamCandle._lit : _dreamCandle._lit);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleCondition(bool shouldSet)
|
||||||
|
{
|
||||||
|
if (shouldSet || Reversible)
|
||||||
|
{
|
||||||
|
if (Persistent)
|
||||||
|
{
|
||||||
|
PlayerData.SetPersistentCondition(Condition, shouldSet);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DialogueConditionManager.SharedInstance.SetConditionState(Condition, shouldSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
66
NewHorizons/Components/Volumes/ConditionTriggerVolume.cs
Normal file
66
NewHorizons/Components/Volumes/ConditionTriggerVolume.cs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NewHorizons.Components.Volumes
|
||||||
|
{
|
||||||
|
public class ConditionTriggerVolume : BaseVolume
|
||||||
|
{
|
||||||
|
public string Condition { get; set; }
|
||||||
|
public bool Persistent { get; set; }
|
||||||
|
public bool Reversible { get; set; }
|
||||||
|
public bool Player { get; set; } = true;
|
||||||
|
public bool Probe { get; set; }
|
||||||
|
public bool Ship { get; set; }
|
||||||
|
|
||||||
|
public override void OnTriggerVolumeEntry(GameObject hitObj)
|
||||||
|
{
|
||||||
|
if (TestHitObject(hitObj))
|
||||||
|
{
|
||||||
|
if (Persistent)
|
||||||
|
{
|
||||||
|
PlayerData.SetPersistentCondition(Condition, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DialogueConditionManager.SharedInstance.SetConditionState(Condition, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnTriggerVolumeExit(GameObject hitObj)
|
||||||
|
{
|
||||||
|
if (Reversible && TestHitObject(hitObj))
|
||||||
|
{
|
||||||
|
if (Persistent)
|
||||||
|
{
|
||||||
|
PlayerData.SetPersistentCondition(Condition, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DialogueConditionManager.SharedInstance.SetConditionState(Condition, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TestHitObject(GameObject hitObj)
|
||||||
|
{
|
||||||
|
if (Player && hitObj.CompareTag("PlayerDetector"))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (Probe && hitObj.CompareTag("ProbeDetector"))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (Ship && hitObj.CompareTag("ShipDetector"))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
69
NewHorizons/Components/Volumes/NHInteractionVolume.cs
Normal file
69
NewHorizons/Components/Volumes/NHInteractionVolume.cs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NewHorizons.Components.Volumes
|
||||||
|
{
|
||||||
|
public class NHInteractionVolume : MonoBehaviour
|
||||||
|
{
|
||||||
|
public bool Reusable { get; set; }
|
||||||
|
public string Condition { get; set; }
|
||||||
|
public bool Persistent { get; set; }
|
||||||
|
public Animator TargetAnimator { get; set; }
|
||||||
|
public string AnimationTrigger { get; set; }
|
||||||
|
|
||||||
|
InteractReceiver _interactReceiver;
|
||||||
|
OWAudioSource _audioSource;
|
||||||
|
|
||||||
|
protected void Awake()
|
||||||
|
{
|
||||||
|
_interactReceiver = GetComponent<InteractReceiver>();
|
||||||
|
_audioSource = GetComponent<OWAudioSource>();
|
||||||
|
|
||||||
|
_interactReceiver.OnPressInteract += OnInteract;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnDestroy()
|
||||||
|
{
|
||||||
|
_interactReceiver.OnPressInteract -= OnInteract;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnInteract()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(Condition))
|
||||||
|
{
|
||||||
|
if (Persistent)
|
||||||
|
{
|
||||||
|
PlayerData.SetPersistentCondition(Condition, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DialogueConditionManager.SharedInstance.SetConditionState(Condition, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_audioSource != null)
|
||||||
|
{
|
||||||
|
_audioSource.Play();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TargetAnimator)
|
||||||
|
{
|
||||||
|
TargetAnimator.SetTrigger(AnimationTrigger);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Reusable)
|
||||||
|
{
|
||||||
|
_interactReceiver.ResetInteraction();
|
||||||
|
_interactReceiver.EnableInteraction();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_interactReceiver.DisableInteraction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -20,5 +20,10 @@ namespace NewHorizons.External.Modules.Props.EchoesOfTheEye
|
|||||||
/// Whether the candle should start lit or extinguished.
|
/// Whether the candle should start lit or extinguished.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool startLit;
|
public bool startLit;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A condition to set when the candle is lit.
|
||||||
|
/// </summary>
|
||||||
|
public DreamLightConditionInfo condition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
31
NewHorizons/External/Modules/Props/EchoesOfTheEye/DreamLightConditionInfo.cs
vendored
Normal file
31
NewHorizons/External/Modules/Props/EchoesOfTheEye/DreamLightConditionInfo.cs
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NewHorizons.External.Modules.Props.EchoesOfTheEye
|
||||||
|
{
|
||||||
|
public class DreamLightConditionInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the dialogue condition or persistent condition to set when the light is lit.
|
||||||
|
/// </summary>
|
||||||
|
public string condition;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If true, the condition will persist across all future loops until unset.
|
||||||
|
/// </summary>
|
||||||
|
public bool persistent;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to unset the condition when the light is extinguished again.
|
||||||
|
/// </summary>
|
||||||
|
public bool reversible;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to set the condition when the light is extinguished instead. If `reversible` is true, the condition will be unset when the light is lit again.
|
||||||
|
/// </summary>
|
||||||
|
public bool onExtinguish;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -45,5 +45,10 @@ namespace NewHorizons.External.Modules.Props.EchoesOfTheEye
|
|||||||
/// If set, projected objects will be set to fully active or fully disabled instantly instead of smoothly fading lights/renderers/colliders. Use this if the normal behavior is insufficient for the objects you're using.
|
/// If set, projected objects will be set to fully active or fully disabled instantly instead of smoothly fading lights/renderers/colliders. Use this if the normal behavior is insufficient for the objects you're using.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool toggleProjectedObjectsActive;
|
public bool toggleProjectedObjectsActive;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A condition to set when the totem is lit.
|
||||||
|
/// </summary>
|
||||||
|
public DreamLightConditionInfo condition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
39
NewHorizons/External/Modules/Volumes/VolumeInfos/ConditionTriggerVolumeInfo.cs
vendored
Normal file
39
NewHorizons/External/Modules/Volumes/VolumeInfos/ConditionTriggerVolumeInfo.cs
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace NewHorizons.External.Modules.Volumes.VolumeInfos
|
||||||
|
{
|
||||||
|
[JsonObject]
|
||||||
|
public class ConditionTriggerVolumeInfo : VolumeInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the dialogue condition or persistent condition to set when entering the volume.
|
||||||
|
/// </summary>
|
||||||
|
public string condition;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If true, the condition will persist across all future loops until unset.
|
||||||
|
/// </summary>
|
||||||
|
public bool persistent;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to unset the condition when existing the volume.
|
||||||
|
/// </summary>
|
||||||
|
public bool reversible;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to set the condition when the player enters this volume. Defaults to true.
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(true)] public bool player = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to set the condition when the scout probe enters this volume.
|
||||||
|
/// </summary>
|
||||||
|
public bool probe;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to set the condition when the ship enters this volume.
|
||||||
|
/// </summary>
|
||||||
|
public bool ship;
|
||||||
|
}
|
||||||
|
}
|
||||||
65
NewHorizons/External/Modules/Volumes/VolumeInfos/InteractionVolumeInfo.cs
vendored
Normal file
65
NewHorizons/External/Modules/Volumes/VolumeInfos/InteractionVolumeInfo.cs
vendored
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NewHorizons.External.Modules.Volumes.VolumeInfos
|
||||||
|
{
|
||||||
|
[JsonObject]
|
||||||
|
public class InteractionVolumeInfo : VolumeInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The prompt to display when the volume is interacted with.
|
||||||
|
/// </summary>
|
||||||
|
public string prompt;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The range at which the volume can be interacted with.
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(2f)] public float range = 2f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The max view angle (in degrees) the player can see the volume with to interact with it. This will effectively be a cone extending from the volume's center forwards (along the Z axis) based on the volume's rotation.
|
||||||
|
/// If not specified, no view angle restriction will be applied.
|
||||||
|
/// </summary>
|
||||||
|
public float? maxViewAngle;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the volume can be interacted with while in the ship.
|
||||||
|
/// </summary>
|
||||||
|
public bool usableInShip;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the volume can be interacted with multiple times.
|
||||||
|
/// </summary>
|
||||||
|
public bool reusable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the dialogue condition or persistent condition to set when the volume is interacted with.
|
||||||
|
/// </summary>
|
||||||
|
public string condition;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If true, the condition will persist across all future loops until unset.
|
||||||
|
/// </summary>
|
||||||
|
public bool persistent;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A sound to play when the volume is interacted with. Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list.
|
||||||
|
/// </summary>
|
||||||
|
public string audio;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A path to an animator component where an animation will be triggered when the volume is interacted with.
|
||||||
|
/// </summary>
|
||||||
|
public string pathToAnimator;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The name of an animation trigger to set on the animator when the volume is interacted with.
|
||||||
|
/// </summary>
|
||||||
|
public string animationTrigger;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,6 +11,11 @@ namespace NewHorizons.External.Modules.Volumes
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public AudioVolumeInfo[] audioVolumes;
|
public AudioVolumeInfo[] audioVolumes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add condition trigger volumes to this planet. Sets a condition when the player, scout, or ship enters this volume.
|
||||||
|
/// </summary>
|
||||||
|
public ConditionTriggerVolumeInfo[] conditionTriggerVolumes;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add day night audio volumes to this planet. These volumes play a different clip depending on the time of day.
|
/// Add day night audio volumes to this planet. These volumes play a different clip depending on the time of day.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -38,6 +43,12 @@ namespace NewHorizons.External.Modules.Volumes
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public HazardVolumeInfo[] hazardVolumes;
|
public HazardVolumeInfo[] hazardVolumes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add interaction volumes to this planet.
|
||||||
|
/// They can be interacted with by the player to trigger various effects.
|
||||||
|
/// </summary>
|
||||||
|
public InteractionVolumeInfo[] interactionVolumes;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add interference volumes to this planet.
|
/// Add interference volumes to this planet.
|
||||||
/// Hides HUD markers of ship scout/probe and prevents scout photos if you are not inside the volume together with ship or scout probe.
|
/// Hides HUD markers of ship scout/probe and prevents scout photos if you are not inside the volume together with ship or scout probe.
|
||||||
|
|||||||
@ -4571,6 +4571,10 @@
|
|||||||
"startLit": {
|
"startLit": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Whether the candle should start lit or extinguished."
|
"description": "Whether the candle should start lit or extinguished."
|
||||||
|
},
|
||||||
|
"condition": {
|
||||||
|
"description": "A condition to set when the candle is lit.",
|
||||||
|
"$ref": "#/definitions/DreamLightConditionInfo"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -4600,6 +4604,28 @@
|
|||||||
"pile"
|
"pile"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"DreamLightConditionInfo": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"condition": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The name of the dialogue condition or persistent condition to set when the light is lit."
|
||||||
|
},
|
||||||
|
"persistent": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "If true, the condition will persist across all future loops until unset."
|
||||||
|
},
|
||||||
|
"reversible": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether to unset the condition when the light is extinguished again."
|
||||||
|
},
|
||||||
|
"onExtinguish": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether to set the condition when the light is extinguished instead. If `reversible` is true, the condition will be unset when the light is lit again."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"ProjectionTotemInfo": {
|
"ProjectionTotemInfo": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
@ -4667,6 +4693,10 @@
|
|||||||
"toggleProjectedObjectsActive": {
|
"toggleProjectedObjectsActive": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "If set, projected objects will be set to fully active or fully disabled instantly instead of smoothly fading lights/renderers/colliders. Use this if the normal behavior is insufficient for the objects you're using."
|
"description": "If set, projected objects will be set to fully active or fully disabled instantly instead of smoothly fading lights/renderers/colliders. Use this if the normal behavior is insufficient for the objects you're using."
|
||||||
|
},
|
||||||
|
"condition": {
|
||||||
|
"description": "A condition to set when the totem is lit.",
|
||||||
|
"$ref": "#/definitions/DreamLightConditionInfo"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -5365,6 +5395,13 @@
|
|||||||
"$ref": "#/definitions/AudioVolumeInfo"
|
"$ref": "#/definitions/AudioVolumeInfo"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"conditionTriggerVolumes": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Add condition trigger volumes to this planet. Sets a condition when the player, scout, or ship enters this volume.",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/ConditionTriggerVolumeInfo"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dayNightAudioVolumes": {
|
"dayNightAudioVolumes": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"description": "Add day night audio volumes to this planet. These volumes play a different clip depending on the time of day.",
|
"description": "Add day night audio volumes to this planet. These volumes play a different clip depending on the time of day.",
|
||||||
@ -5397,6 +5434,13 @@
|
|||||||
"$ref": "#/definitions/HazardVolumeInfo"
|
"$ref": "#/definitions/HazardVolumeInfo"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"interactionVolumes": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Add interaction volumes to this planet.\nThey can be interacted with by the player to trigger various effects.",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/InteractionVolumeInfo"
|
||||||
|
}
|
||||||
|
},
|
||||||
"interferenceVolumes": {
|
"interferenceVolumes": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"description": "Add interference volumes to this planet.\nHides HUD markers of ship scout/probe and prevents scout photos if you are not inside the volume together with ship or scout probe.",
|
"description": "Add interference volumes to this planet.\nHides HUD markers of ship scout/probe and prevents scout photos if you are not inside the volume together with ship or scout probe.",
|
||||||
@ -5724,6 +5768,74 @@
|
|||||||
"manual"
|
"manual"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"ConditionTriggerVolumeInfo": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"radius": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "The radius of this volume, if a shape is not specified.",
|
||||||
|
"format": "float",
|
||||||
|
"default": 1.0
|
||||||
|
},
|
||||||
|
"shape": {
|
||||||
|
"description": "The shape of this volume. Defaults to a sphere with a radius of `radius` if not specified.",
|
||||||
|
"$ref": "#/definitions/ShapeInfo"
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"description": "Rotation of the object",
|
||||||
|
"$ref": "#/definitions/MVector3"
|
||||||
|
},
|
||||||
|
"alignRadial": {
|
||||||
|
"type": [
|
||||||
|
"boolean",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"description": "Do we try to automatically align this object to stand upright relative to the body's center? Stacks with rotation.\nDefaults to true for geysers, tornados, and volcanoes, and false for everything else."
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"description": "Position of the object",
|
||||||
|
"$ref": "#/definitions/MVector3"
|
||||||
|
},
|
||||||
|
"isRelativeToParent": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether the positional and rotational coordinates are relative to parent instead of the root planet object."
|
||||||
|
},
|
||||||
|
"parentPath": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The relative path from the planet to the parent of this object. Optional (will default to the root sector)."
|
||||||
|
},
|
||||||
|
"rename": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "An optional rename of this object"
|
||||||
|
},
|
||||||
|
"condition": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The name of the dialogue condition or persistent condition to set when entering the volume."
|
||||||
|
},
|
||||||
|
"persistent": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "If true, the condition will persist across all future loops until unset."
|
||||||
|
},
|
||||||
|
"reversible": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether to unset the condition when existing the volume."
|
||||||
|
},
|
||||||
|
"player": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether to set the condition when the player enters this volume. Defaults to true.",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"probe": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether to set the condition when the scout probe enters this volume."
|
||||||
|
},
|
||||||
|
"ship": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether to set the condition when the ship enters this volume."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"DayNightAudioVolumeInfo": {
|
"DayNightAudioVolumeInfo": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
@ -6528,6 +6640,95 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"InteractionVolumeInfo": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"radius": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "The radius of this volume, if a shape is not specified.",
|
||||||
|
"format": "float",
|
||||||
|
"default": 1.0
|
||||||
|
},
|
||||||
|
"shape": {
|
||||||
|
"description": "The shape of this volume. Defaults to a sphere with a radius of `radius` if not specified.",
|
||||||
|
"$ref": "#/definitions/ShapeInfo"
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"description": "Rotation of the object",
|
||||||
|
"$ref": "#/definitions/MVector3"
|
||||||
|
},
|
||||||
|
"alignRadial": {
|
||||||
|
"type": [
|
||||||
|
"boolean",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"description": "Do we try to automatically align this object to stand upright relative to the body's center? Stacks with rotation.\nDefaults to true for geysers, tornados, and volcanoes, and false for everything else."
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"description": "Position of the object",
|
||||||
|
"$ref": "#/definitions/MVector3"
|
||||||
|
},
|
||||||
|
"isRelativeToParent": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether the positional and rotational coordinates are relative to parent instead of the root planet object."
|
||||||
|
},
|
||||||
|
"parentPath": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The relative path from the planet to the parent of this object. Optional (will default to the root sector)."
|
||||||
|
},
|
||||||
|
"rename": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "An optional rename of this object"
|
||||||
|
},
|
||||||
|
"prompt": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The prompt to display when the volume is interacted with."
|
||||||
|
},
|
||||||
|
"range": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "The range at which the volume can be interacted with.",
|
||||||
|
"format": "float",
|
||||||
|
"default": 2.0
|
||||||
|
},
|
||||||
|
"maxViewAngle": {
|
||||||
|
"type": [
|
||||||
|
"null",
|
||||||
|
"number"
|
||||||
|
],
|
||||||
|
"description": "The max view angle (in degrees) the player can see the volume with to interact with it. This will effectively be a cone extending from the volume's center forwards (along the Z axis) based on the volume's rotation.\nIf not specified, no view angle restriction will be applied.",
|
||||||
|
"format": "float"
|
||||||
|
},
|
||||||
|
"usableInShip": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether the volume can be interacted with while in the ship."
|
||||||
|
},
|
||||||
|
"reusable": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether the volume can be interacted with multiple times."
|
||||||
|
},
|
||||||
|
"condition": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The name of the dialogue condition or persistent condition to set when the volume is interacted with."
|
||||||
|
},
|
||||||
|
"persistent": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "If true, the condition will persist across all future loops until unset."
|
||||||
|
},
|
||||||
|
"audio": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "A sound to play when the volume is interacted with. Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list."
|
||||||
|
},
|
||||||
|
"pathToAnimator": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "A path to an animator component where an animation will be triggered when the volume is interacted with. "
|
||||||
|
},
|
||||||
|
"animationTrigger": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The name of an animation trigger to set on the animator when the volume is interacted with."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"VolumeInfo": {
|
"VolumeInfo": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user