mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
Add force volumes and give volumes rotation
This commit is contained in:
parent
5aace8408a
commit
4a81798078
119
NewHorizons/Builder/Volumes/ForceVolumeBuilder.cs
Normal file
119
NewHorizons/Builder/Volumes/ForceVolumeBuilder.cs
Normal file
@ -0,0 +1,119 @@
|
||||
using NewHorizons.Builder.Props;
|
||||
using NewHorizons.External;
|
||||
using NewHorizons.External.Modules;
|
||||
using NewHorizons.External.Modules.Volumes.VolumeInfos;
|
||||
using NewHorizons.Utility.OuterWilds;
|
||||
using OWML.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NewHorizons.Builder.Volumes
|
||||
{
|
||||
public static class ForceVolumeBuilder
|
||||
{
|
||||
public static CylindricalForceVolume Make(GameObject planetGO, Sector sector, CylindricalForceVolumeInfo info)
|
||||
{
|
||||
var forceVolume = Make<CylindricalForceVolume>(planetGO, sector, info);
|
||||
forceVolume._acceleration = info.force;
|
||||
forceVolume._localAxis = info.normal ?? Vector3.up;
|
||||
forceVolume._playGravityCrystalAudio = info.playGravityCrystalAudio;
|
||||
forceVolume.gameObject.SetActive(true);
|
||||
return forceVolume;
|
||||
}
|
||||
|
||||
public static DirectionalForceVolume Make(GameObject planetGO, Sector sector, DirectionalForceVolumeInfo info)
|
||||
{
|
||||
var forceVolume = Make<DirectionalForceVolume>(planetGO, sector, info);
|
||||
forceVolume._fieldDirection = info.normal ?? Vector3.up;
|
||||
forceVolume._fieldMagnitude = info.force;
|
||||
forceVolume._affectsAlignment = info.affectsAlignment;
|
||||
forceVolume._offsetCentripetalForce = info.offsetCentripetalForce;
|
||||
forceVolume._playGravityCrystalAudio = info.playGravityCrystalAudio;
|
||||
forceVolume.gameObject.SetActive(true);
|
||||
return forceVolume;
|
||||
}
|
||||
|
||||
public static GravityVolume Make(GameObject planetGO, Sector sector, GravityVolumeInfo info)
|
||||
{
|
||||
var forceVolume = Make<GravityVolume>(planetGO, sector, info);
|
||||
forceVolume._isPlanetGravityVolume = false;
|
||||
forceVolume._setMass = false;
|
||||
forceVolume._surfaceAcceleration = info.force;
|
||||
forceVolume._upperSurfaceRadius = info.upperRadius;
|
||||
forceVolume._lowerSurfaceRadius = info.lowerRadius;
|
||||
forceVolume._cutoffAcceleration = info.minForce;
|
||||
forceVolume._cutoffRadius = info.minRadius;
|
||||
forceVolume._alignmentRadius = info.alignmentRadius ?? info.upperRadius * 1.5f;
|
||||
forceVolume._falloffType = info.fallOff switch
|
||||
{
|
||||
GravityFallOff.Linear => GravityVolume.FalloffType.linear,
|
||||
GravityFallOff.InverseSquared => GravityVolume.FalloffType.inverseSquared,
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
forceVolume.gameObject.SetActive(true);
|
||||
return forceVolume;
|
||||
}
|
||||
|
||||
public static PolarForceVolume Make(GameObject planetGO, Sector sector, PolarForceVolumeInfo info)
|
||||
{
|
||||
var forceVolume = Make<PolarForceVolume>(planetGO, sector, info);
|
||||
forceVolume._acceleration = info.force;
|
||||
forceVolume._localAxis = info.normal ?? Vector3.up;
|
||||
forceVolume._fieldMode = info.tangential ? PolarForceVolume.ForceMode.Tangential : PolarForceVolume.ForceMode.Polar;
|
||||
forceVolume.gameObject.SetActive(true);
|
||||
return forceVolume;
|
||||
}
|
||||
|
||||
public static RadialForceVolume Make(GameObject planetGO, Sector sector, RadialForceVolumeInfo info)
|
||||
{
|
||||
var forceVolume = Make<RadialForceVolume>(planetGO, sector, info);
|
||||
forceVolume._acceleration = info.force;
|
||||
forceVolume._falloff = info.fallOff switch
|
||||
{
|
||||
RadialForceVolumeInfo.FallOff.Constant => RadialForceVolume.Falloff.Constant,
|
||||
RadialForceVolumeInfo.FallOff.Linear => RadialForceVolume.Falloff.Linear,
|
||||
RadialForceVolumeInfo.FallOff.InverseSquared => RadialForceVolume.Falloff.InvSqr,
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
forceVolume.gameObject.SetActive(true);
|
||||
return forceVolume;
|
||||
}
|
||||
|
||||
public static T Make<T>(GameObject planetGO, Sector sector, ForceVolumeInfo info) where T : ForceVolume
|
||||
{
|
||||
var go = GeneralPropBuilder.MakeNew(typeof(T).Name, planetGO, sector, info);
|
||||
go.layer = Layer.BasicEffectVolume;
|
||||
|
||||
var owTriggerVolume = go.AddComponent<OWTriggerVolume>();
|
||||
|
||||
if (info.shape != null)
|
||||
{
|
||||
var shapeOrCol = ShapeBuilder.AddShapeOrCollider(go, info.shape);
|
||||
if (shapeOrCol is Shape shape)
|
||||
owTriggerVolume._shape = shape;
|
||||
else if (shapeOrCol is Collider col)
|
||||
owTriggerVolume._owCollider = col.GetComponent<OWCollider>();
|
||||
}
|
||||
else
|
||||
{
|
||||
var col = go.AddComponent<SphereCollider>();
|
||||
col.radius = info.radius;
|
||||
col.isTrigger = true;
|
||||
var owCollider = go.GetAddComponent<OWCollider>();
|
||||
|
||||
owTriggerVolume._owCollider = owCollider;
|
||||
}
|
||||
|
||||
var forceVolume = go.AddComponent<T>();
|
||||
forceVolume._priority = info.priority;
|
||||
forceVolume._alignmentPriority = info.alignmentPriority;
|
||||
forceVolume._inheritable = info.inheritable;
|
||||
|
||||
return forceVolume;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -112,6 +112,44 @@ namespace NewHorizons.Builder.Volumes
|
||||
FluidVolumeBuilder.Make(go, sector, fluidVolume);
|
||||
}
|
||||
}
|
||||
if (config.Volumes.forces != null)
|
||||
{
|
||||
if (config.Volumes.forces.cylindricalVolumes != null)
|
||||
{
|
||||
foreach (var cylindricalVolume in config.Volumes.forces.cylindricalVolumes)
|
||||
{
|
||||
ForceVolumeBuilder.Make(go, sector, cylindricalVolume);
|
||||
}
|
||||
}
|
||||
if (config.Volumes.forces.directionalVolumes != null)
|
||||
{
|
||||
foreach (var directionalVolume in config.Volumes.forces.directionalVolumes)
|
||||
{
|
||||
ForceVolumeBuilder.Make(go, sector, directionalVolume);
|
||||
}
|
||||
}
|
||||
if (config.Volumes.forces.gravityVolumes != null)
|
||||
{
|
||||
foreach (var gravityVolume in config.Volumes.forces.gravityVolumes)
|
||||
{
|
||||
ForceVolumeBuilder.Make(go, sector, gravityVolume);
|
||||
}
|
||||
}
|
||||
if (config.Volumes.forces.polarVolumes != null)
|
||||
{
|
||||
foreach (var polarVolume in config.Volumes.forces.polarVolumes)
|
||||
{
|
||||
ForceVolumeBuilder.Make(go, sector, polarVolume);
|
||||
}
|
||||
}
|
||||
if (config.Volumes.forces.radialVolumes != null)
|
||||
{
|
||||
foreach (var radialVolume in config.Volumes.forces.radialVolumes)
|
||||
{
|
||||
ForceVolumeBuilder.Make(go, sector, radialVolume);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (config.Volumes.probe != null)
|
||||
{
|
||||
if (config.Volumes.probe.destructionVolumes != null)
|
||||
|
||||
40
NewHorizons/External/Modules/Volumes/ForceModule.cs
vendored
Normal file
40
NewHorizons/External/Modules/Volumes/ForceModule.cs
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
using NewHorizons.External.Modules.Volumes.VolumeInfos;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NewHorizons.External.Modules.Volumes
|
||||
{
|
||||
[JsonObject]
|
||||
public class ForceModule
|
||||
{
|
||||
/// <summary>
|
||||
/// Applies a constant force along the volume's XZ plane towards the volume's center. Affects alignment.
|
||||
/// </summary>
|
||||
public CylindricalForceVolumeInfo[] cylindricalVolumes;
|
||||
|
||||
/// <summary>
|
||||
/// Applies a constant force in the direction of the volume's Y axis. May affect alignment.
|
||||
/// </summary>
|
||||
public DirectionalForceVolumeInfo[] directionalVolumes;
|
||||
|
||||
/// <summary>
|
||||
/// Applies planet-like gravity towards the volume's center with falloff by distance. May affect alignment.
|
||||
/// For actual planetary body gravity, use the properties in the Base module.
|
||||
/// </summary>
|
||||
public GravityVolumeInfo[] gravityVolumes;
|
||||
|
||||
/// <summary>
|
||||
/// Applies a constant force towards the volume's center. Affects alignment.
|
||||
/// </summary>
|
||||
public PolarForceVolumeInfo[] polarVolumes;
|
||||
|
||||
/// <summary>
|
||||
/// Applies a force towards the volume's center with falloff by distance. Affects alignment.
|
||||
/// </summary>
|
||||
public RadialForceVolumeInfo[] radialVolumes;
|
||||
}
|
||||
}
|
||||
24
NewHorizons/External/Modules/Volumes/VolumeInfos/CylindricalForceVolumeInfo.cs
vendored
Normal file
24
NewHorizons/External/Modules/Volumes/VolumeInfos/CylindricalForceVolumeInfo.cs
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
using NewHorizons.External.SerializableData;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NewHorizons.External.Modules.Volumes.VolumeInfos
|
||||
{
|
||||
[JsonObject]
|
||||
public class CylindricalForceVolumeInfo : ForceVolumeInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The direction that the force applied by this volume will be perpendicular to. Defaults to up (0, 1, 0).
|
||||
/// </summary>
|
||||
public MVector3 normal;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to play the gravity crystal audio when the player is in this volume.
|
||||
/// </summary>
|
||||
public bool playGravityCrystalAudio;
|
||||
}
|
||||
}
|
||||
35
NewHorizons/External/Modules/Volumes/VolumeInfos/DirectionalForceVolumeInfo.cs
vendored
Normal file
35
NewHorizons/External/Modules/Volumes/VolumeInfos/DirectionalForceVolumeInfo.cs
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
using NewHorizons.External.SerializableData;
|
||||
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 DirectionalForceVolumeInfo : ForceVolumeInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The direction of the force applied by this volume. Defaults to up (0, 1, 0).
|
||||
/// </summary>
|
||||
public MVector3 normal;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this force volume affects alignment. Defaults to true.
|
||||
/// </summary>
|
||||
[DefaultValue(true)] public bool affectsAlignment = true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the force applied by this volume takes the centripetal force of the volume's parent body into account. Defaults to false.
|
||||
/// </summary>
|
||||
public bool offsetCentripetalForce;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to play the gravity crystal audio when the player is in this volume.
|
||||
/// </summary>
|
||||
public bool playGravityCrystalAudio;
|
||||
}
|
||||
}
|
||||
40
NewHorizons/External/Modules/Volumes/VolumeInfos/ForceVolumeInfo.cs
vendored
Normal file
40
NewHorizons/External/Modules/Volumes/VolumeInfos/ForceVolumeInfo.cs
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
using NewHorizons.External.Modules.Props;
|
||||
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 ForceVolumeInfo : PriorityVolumeInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The shape of this volume. Defaults to a sphere shape with a radius of `radius`.
|
||||
/// </summary>
|
||||
public ShapeInfo shape;
|
||||
|
||||
/// <summary>
|
||||
/// The force applied by this volume. Can be negative to reverse the direction.
|
||||
/// </summary>
|
||||
public float force;
|
||||
|
||||
/// <summary>
|
||||
/// The priority of this force volume for the purposes of alignment.
|
||||
///
|
||||
/// Volumes of higher priority will override volumes of lower priority. Volumes of the same priority will stack like normal.
|
||||
/// Ex: A player in a gravity volume with priority 0, and zero-gravity volume with priority 1, will feel zero gravity.
|
||||
///
|
||||
/// Default value here is 1 instead of 0 so it automatically overrides planet gravity, which is 0 by default.
|
||||
/// </summary>
|
||||
[DefaultValue(1)] public int alignmentPriority = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this force volume is inheritable. The most recently activated inheritable force volume will stack with other force volumes even if their priorities differ.
|
||||
/// </summary>
|
||||
public bool inheritable;
|
||||
}
|
||||
}
|
||||
44
NewHorizons/External/Modules/Volumes/VolumeInfos/GravityVolumeInfo.cs
vendored
Normal file
44
NewHorizons/External/Modules/Volumes/VolumeInfos/GravityVolumeInfo.cs
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
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 GravityVolumeInfo : ForceVolumeInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The upper bounds of the volume's "surface". Above this radius, the force applied by this volume will have falloff applied.
|
||||
/// </summary>
|
||||
public float upperRadius;
|
||||
|
||||
/// <summary>
|
||||
/// The lower bounds of the volume's "surface". Above this radius and below the `upperRadius`, the force applied by this volume will be constant. Defaults to 0.
|
||||
/// </summary>
|
||||
[DefaultValue(0f)] public float lowerRadius;
|
||||
|
||||
/// <summary>
|
||||
/// The volume's force will decrease linearly from `force` to `minForce` as distance decreases from `lowerRadius` to `minRadius`. Defaults to 0.
|
||||
/// </summary>
|
||||
[DefaultValue(0f)] public float minRadius;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum force applied by this volume between `lowerRadius` and `minRadius`. Defaults to 0.
|
||||
/// </summary>
|
||||
[DefaultValue(0f)] public float minForce;
|
||||
|
||||
/// <summary>
|
||||
/// How the force falls off with distance. Most planets use linear but the sun and some moons use inverseSquared.
|
||||
/// </summary>
|
||||
[DefaultValue("linear")] public GravityFallOff fallOff = GravityFallOff.Linear;
|
||||
|
||||
/// <summary>
|
||||
/// The radius where objects will be aligned to the volume's force. Defaults to 1.5x the `upperRadius`. Set to 0 to disable alignment.
|
||||
/// </summary>
|
||||
public float? alignmentRadius;
|
||||
}
|
||||
}
|
||||
23
NewHorizons/External/Modules/Volumes/VolumeInfos/PolarForceVolumeInfo.cs
vendored
Normal file
23
NewHorizons/External/Modules/Volumes/VolumeInfos/PolarForceVolumeInfo.cs
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
using NewHorizons.External.SerializableData;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NewHorizons.External.Modules.Volumes.VolumeInfos
|
||||
{
|
||||
[JsonObject]
|
||||
public class PolarForceVolumeInfo : ForceVolumeInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Tangential mode only. The force applied by this volume will be perpendicular to this direction and the direction to the other body. Defaults to up (0, 1, 0).
|
||||
/// </summary>
|
||||
public MVector3 normal;
|
||||
/// <summary>
|
||||
/// Enables tangential mode. The force applied by this volume will be perpendicular to the normal and the direction to the other body. Defaults to false.
|
||||
/// </summary>
|
||||
public bool tangential;
|
||||
}
|
||||
}
|
||||
32
NewHorizons/External/Modules/Volumes/VolumeInfos/RadialForceVolumeInfo.cs
vendored
Normal file
32
NewHorizons/External/Modules/Volumes/VolumeInfos/RadialForceVolumeInfo.cs
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NewHorizons.External.Modules.Volumes.VolumeInfos
|
||||
{
|
||||
[JsonObject]
|
||||
public class RadialForceVolumeInfo : ForceVolumeInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// How the force falls off with distance. Defaults to linear.
|
||||
/// </summary>
|
||||
[DefaultValue("linear")] public FallOff fallOff = FallOff.Linear;
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public enum FallOff
|
||||
{
|
||||
[EnumMember(Value = @"constant")] Constant = 0,
|
||||
|
||||
[EnumMember(Value = @"linear")] Linear = 1,
|
||||
|
||||
[EnumMember(Value = @"inverseSquared")]
|
||||
InverseSquared = 2
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,7 +4,7 @@ using System.ComponentModel;
|
||||
namespace NewHorizons.External.Modules.Volumes.VolumeInfos
|
||||
{
|
||||
[JsonObject]
|
||||
public class VolumeInfo : GeneralPointPropInfo
|
||||
public class VolumeInfo : GeneralPropInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// The radius of this volume.
|
||||
|
||||
@ -27,6 +27,11 @@ namespace NewHorizons.External.Modules.Volumes
|
||||
/// </summary>
|
||||
public FluidVolumeInfo[] fluidVolumes;
|
||||
|
||||
/// <summary>
|
||||
/// Add force volumes to this planet.
|
||||
/// </summary>
|
||||
public ForceModule forces;
|
||||
|
||||
/// <summary>
|
||||
/// Add hazard volumes to this planet.
|
||||
/// Causes damage to player when inside this volume.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user