r2mods/ilspy_dump/ror2_csproj/EntityStates.InfiniteTowerS.../Travelling.cs

252 lines
6.2 KiB
C#

using System.Collections.Generic;
using HG;
using RoR2;
using RoR2.Audio;
using RoR2.Navigation;
using UnityEngine;
using UnityEngine.Networking;
namespace EntityStates.InfiniteTowerSafeWard;
public class Travelling : BaseSafeWardState
{
[SerializeField]
public float radius;
[SerializeField]
public string animationLayerName;
[SerializeField]
public string animationStateName;
[SerializeField]
public string enterSoundString;
[SerializeField]
public float minDistanceToNewLocation;
[SerializeField]
public float maxDistanceToNewLocation;
[SerializeField]
public float travelSpeed;
[SerializeField]
public float travelHeight;
[SerializeField]
public float pathMaxSlope;
[SerializeField]
public float pathMaxJumpHeight;
[SerializeField]
public float pathMaxSpeed;
[SerializeField]
public int pathNodeInclusionPeriod;
[SerializeField]
public string voSoundString;
[SerializeField]
public float minimumVoDelay;
[SerializeField]
public float maximumVoDelay;
[SerializeField]
public LoopSoundDef loopSoundDef;
private LoopSoundManager.SoundLoopPtr loopPtr;
private const HullMask wardHullMask = HullMask.Human;
private const HullClassification pathHullClassification = HullClassification.Human;
private bool didFail;
private NodeGraph groundNodeGraph;
private List<NodeGraph.NodeIndex> potentialEndNodes;
private List<Vector3> catmullRomPoints = new List<Vector3>();
private Vector3 rotationVelocity;
private Path groundPath;
private int catmullRomIndex;
private CatmullRom3 currentCurve;
private float tCurve;
private float voTimer;
private Xoroshiro128Plus rng;
public Travelling()
{
}
public Travelling(Xoroshiro128Plus rng)
{
this.rng = rng;
}
public override void OnEnter()
{
base.OnEnter();
didFail = false;
PlayAnimation(animationLayerName, animationStateName);
Util.PlaySound(enterSoundString, base.gameObject);
ResetVoTimer();
if ((bool)loopSoundDef)
{
loopPtr = LoopSoundManager.PlaySoundLoopLocal(base.gameObject, loopSoundDef);
}
if ((bool)zone)
{
zone.Networkradius = radius;
}
if (NetworkServer.active)
{
groundNodeGraph = SceneInfo.instance.GetNodeGraph(MapNodeGroup.GraphType.Ground);
potentialEndNodes = groundNodeGraph.FindNodesInRangeWithFlagConditions(base.transform.position, 0f, minDistanceToNewLocation, HullMask.Human, NodeFlags.TeleporterOK, NodeFlags.None, preventOverhead: false);
Util.ShuffleList(potentialEndNodes, rng);
List<NodeGraph.NodeIndex> list = groundNodeGraph.FindNodesInRangeWithFlagConditions(base.transform.position, minDistanceToNewLocation, maxDistanceToNewLocation, HullMask.Human, NodeFlags.TeleporterOK, NodeFlags.None, preventOverhead: false);
Util.ShuffleList(list, rng);
potentialEndNodes.AddRange(list);
groundPath = new Path(groundNodeGraph);
}
}
public override void OnExit()
{
LoopSoundManager.StopSoundLoopLocal(loopPtr);
base.OnExit();
}
public override void FixedUpdate()
{
base.FixedUpdate();
voTimer -= GetDeltaTime();
if (voTimer <= 0f)
{
ResetVoTimer();
Util.PlaySound(voSoundString, base.gameObject);
}
if (!NetworkServer.active)
{
return;
}
if (!didFail)
{
if (currentCurve == null)
{
if (potentialEndNodes.Count > 0)
{
EvaluateNextEndpoint();
}
else
{
didFail = true;
Debug.LogError("SafeWard failed to find endpoint!");
}
}
else
{
tCurve = currentCurve.AdvanceTByDistance(tCurve, travelSpeed * GetDeltaTime());
tCurve = Mathf.Min(1f, tCurve);
base.transform.position = currentCurve.Evaluate(tCurve);
Vector3 vector = currentCurve.EvaluateDerivative(tCurve);
vector.y = 0f;
vector = vector.normalized;
Vector3 forward = Vector3.SmoothDamp(base.transform.forward, vector, ref rotationVelocity, 0.5f);
base.transform.forward = forward;
while (tCurve >= 1f && GetRemainingCurveSegmentCount() > 0)
{
tCurve -= 1f;
catmullRomIndex++;
UpdateCurveSegmentPoints();
}
}
}
if (didFail || (GetRemainingCurveSegmentCount() <= 0 && tCurve >= 1f))
{
outer.SetNextState(new Burrow());
}
}
private void EvaluateNextEndpoint()
{
int index = potentialEndNodes.Count - 1;
NodeGraph.NodeIndex nodeIndex = potentialEndNodes[index];
potentialEndNodes.RemoveAt(index);
NodeGraph.PathRequest pathRequest = new NodeGraph.PathRequest
{
startPos = base.transform.position,
endPos = nodeIndex,
hullClassification = HullClassification.Human,
maxJumpHeight = pathMaxJumpHeight,
maxSlope = pathMaxSlope,
maxSpeed = pathMaxSpeed,
path = groundPath
};
PathTask pathTask = groundNodeGraph.ComputePath(pathRequest);
if (pathTask == null || pathTask.status != PathTask.TaskStatus.Complete || !pathTask.wasReachable || pathTask.path.waypointsCount <= 1 || !groundNodeGraph.GetNodePosition(nodeIndex, out var _))
{
return;
}
_ = 1f / (float)(pathTask.path.waypointsCount - 1);
for (int i = 0; i < pathTask.path.waypointsCount; i++)
{
if (i % pathNodeInclusionPeriod != 0 && i != pathTask.path.waypointsCount - 1)
{
continue;
}
Path.Waypoint waypoint = pathTask.path[i];
if (groundNodeGraph.GetNodePosition(waypoint.nodeIndex, out var position2))
{
if (i > 0 && i < pathTask.path.waypointsCount - 1)
{
position2.y += travelHeight;
}
catmullRomPoints.Add(position2);
}
}
if (catmullRomPoints.Count > 1)
{
Vector3 item = 2f * catmullRomPoints[0] - catmullRomPoints[1];
catmullRomPoints.Insert(0, item);
Vector3 item2 = 2f * catmullRomPoints[catmullRomPoints.Count - 1] - catmullRomPoints[catmullRomPoints.Count - 2];
catmullRomPoints.Add(item2);
DirectorCore.instance.AddOccupiedNode(groundNodeGraph, nodeIndex);
catmullRomIndex = 0;
currentCurve = new CatmullRom3();
tCurve = 0f;
UpdateCurveSegmentPoints();
}
else
{
catmullRomPoints.Clear();
}
}
private void UpdateCurveSegmentPoints()
{
currentCurve.SetPoints(catmullRomPoints[catmullRomIndex], catmullRomPoints[catmullRomIndex + 1], catmullRomPoints[catmullRomIndex + 2], catmullRomPoints[catmullRomIndex + 3]);
}
private int GetRemainingCurveSegmentCount()
{
return catmullRomPoints.Count - 4 - catmullRomIndex;
}
private void ResetVoTimer()
{
voTimer = Random.Range(minimumVoDelay, maximumVoDelay);
}
}