r2mods/ilspy_dump/ror2_csproj/RoR2/VoidRaidGauntletController.cs

611 lines
16 KiB
C#

using System;
using System.Runtime.InteropServices;
using RoR2.Audio;
using RoR2.Navigation;
using UnityEngine;
using UnityEngine.Networking;
namespace RoR2;
public class VoidRaidGauntletController : NetworkBehaviour
{
[Serializable]
public class GauntletInfo
{
public Transform startPoint;
public Transform effectRoot;
public float startRadius = 100f;
public MapZone exitZone;
public MapZone entranceZone;
public string gateName;
}
[Serializable]
public class DonutInfo
{
public GameObject root;
public Transform returnPoint;
public float returnRadius = 1000f;
public Transform crabPosition;
public CombatDirector combatDirector;
}
[SerializeField]
private DonutInfo initialDonut;
[SerializeField]
private DonutInfo[] followingDonuts;
[SerializeField]
private GauntletInfo[] gauntlets;
[SerializeField]
private BuffDef requiredBuffToKill;
[SerializeField]
private GameObject donutSkyboxObject;
[SerializeField]
private GameObject gauntletSkyboxObject;
[SerializeField]
private GameObject gauntletEffectPrefab;
[SerializeField]
private int initialSpawnSpiderSteps = 4;
[SerializeField]
private int maxInitialSpawnPoints = 16;
[SerializeField]
public InteractableSpawnCard outroPortalSpawnCard;
[SerializeField]
public float minOutroPortalDistance;
[SerializeField]
public float maxOutroPortalDistance;
[SerializeField]
private InteractableSpawnCard gauntletExtranceSpawnCard;
[SerializeField]
private ScriptedCombatEncounter[] phaseEncounters;
[SerializeField]
private LoopSoundDef gauntletActiveLoop;
private GauntletInfo previousGauntlet;
private DonutInfo previousDonut;
private GauntletInfo currentGauntlet;
private DonutInfo currentDonut;
private CharacterBody bossBody;
private LoopSoundManager.SoundLoopPtr gauntletActiveLoopPtr;
[SyncVar(hook = "TryShuffleData")]
private ulong rngSeed;
private bool hasShuffled;
private int gauntletIndex;
private static int kRpcRpcStartActiveSoundLoop;
private static int kRpcRpcActivateGate;
private static int kRpcRpcActivateDonut;
private static int kRpcRpcTryShuffleData;
public static VoidRaidGauntletController instance { get; private set; }
public ulong NetworkrngSeed
{
get
{
return rngSeed;
}
[param: In]
set
{
if (NetworkServer.localClientActive && !base.syncVarHookGuard)
{
base.syncVarHookGuard = true;
TryShuffleData(value);
base.syncVarHookGuard = false;
}
SetSyncVar(value, ref rngSeed, 1u);
}
}
public void SetCurrentDonutCombatDirectorEnabled(bool isEnabled)
{
if ((bool)currentDonut?.combatDirector)
{
currentDonut.combatDirector.enabled = isEnabled;
}
}
public bool TryOpenGauntlet(Vector3 entrancePosition, NetworkInstanceId bossMasterId)
{
if (gauntletIndex >= phaseEncounters.Length)
{
return false;
}
if (bossMasterId != NetworkInstanceId.Invalid)
{
ScriptedCombatEncounter scriptedCombatEncounter = phaseEncounters[gauntletIndex];
if (!scriptedCombatEncounter || scriptedCombatEncounter.combatSquad.memberCount != 0 || !scriptedCombatEncounter.combatSquad.HasContainedMember(bossMasterId))
{
return false;
}
}
int destinationGauntletIndex = gauntletIndex;
previousGauntlet = currentGauntlet;
previousDonut = currentDonut;
if (previousDonut != null && (bool)previousDonut.combatDirector)
{
previousDonut.combatDirector.monsterCredit = 0f;
previousDonut.combatDirector.enabled = false;
}
int num = gauntletIndex % followingDonuts.Length;
currentDonut = followingDonuts[num];
currentGauntlet = gauntlets[gauntletIndex % gauntlets.Length];
gauntletIndex++;
CallRpcTryShuffleData(rngSeed);
if ((bool)currentDonut.root)
{
currentDonut.root.SetActive(value: true);
CallRpcActivateDonut(num);
}
if (SceneInfo.instance != null && !string.IsNullOrEmpty(currentGauntlet?.gateName))
{
SceneInfo.instance.SetGateState(currentGauntlet.gateName, gateEnabled: true);
CallRpcActivateGate(currentGauntlet?.gateName);
}
if ((bool)currentGauntlet.effectRoot && (bool)gauntletEffectPrefab)
{
EffectData effectData = new EffectData
{
origin = currentGauntlet.effectRoot.position,
rotation = currentGauntlet.effectRoot.rotation
};
EffectManager.SpawnEffect(gauntletEffectPrefab, effectData, transmit: false);
}
if ((bool)previousDonut?.combatDirector)
{
previousDonut.combatDirector.enabled = false;
}
Xoroshiro128Plus rng = new Xoroshiro128Plus(rngSeed + (ulong)gauntletIndex);
DirectorPlacementRule placementRule = new DirectorPlacementRule
{
placementMode = DirectorPlacementRule.PlacementMode.NearestNode,
position = entrancePosition
};
DirectorSpawnRequest directorSpawnRequest = new DirectorSpawnRequest(gauntletExtranceSpawnCard, placementRule, rng);
directorSpawnRequest.onSpawnedServer = delegate(SpawnCard.SpawnResult result)
{
OnEntranceSpawned(result, destinationGauntletIndex);
};
DirectorCore.instance.TrySpawnObject(directorSpawnRequest);
return true;
}
private void OnEntranceSpawned(SpawnCard.SpawnResult result, int destinationGauntletIndex)
{
if (result.success)
{
CallRpcStartActiveSoundLoop();
currentGauntlet.entranceZone = result.spawnedInstance.GetComponentInChildren<MapZone>();
result.spawnedInstance.GetComponent<VoidRaidGauntletEntranceController>().SetGauntletIndex(destinationGauntletIndex);
}
}
private void OnEnable()
{
instance = SingletonHelper.Assign(instance, this);
SceneDirector.onPreGeneratePlayerSpawnPointsServer += OnPreGeneratePlayerSpawnPointsServer;
}
private void OnDisable()
{
StopActiveSoundLoop();
SceneDirector.onPreGeneratePlayerSpawnPointsServer -= OnPreGeneratePlayerSpawnPointsServer;
instance = SingletonHelper.Unassign(instance, this);
}
private void OnPreGeneratePlayerSpawnPointsServer(SceneDirector sceneDirector, ref Action generationMethod)
{
generationMethod = GeneratePlayerSpawnPointsServer;
}
private void GeneratePlayerSpawnPointsServer()
{
if (!SceneInfo.instance || initialDonut == null || !initialDonut.returnPoint)
{
return;
}
Transform returnPoint = initialDonut.returnPoint;
Vector3 position = returnPoint.position;
NodeGraph groundNodes = SceneInfo.instance.groundNodes;
if (!groundNodes)
{
Debug.LogError("VoidRaidGauntletController.GeneratePlayerSpawnPointsServer: No ground nodegraph found to place spawn points.", this);
return;
}
NodeGraphSpider nodeGraphSpider = new NodeGraphSpider(groundNodes, HullMask.Human);
nodeGraphSpider.AddNodeForNextStep(groundNodes.FindClosestNode(position, HullClassification.Human));
for (int i = 0; i < initialSpawnSpiderSteps; i++)
{
nodeGraphSpider.PerformStep();
if (nodeGraphSpider.collectedSteps.Count > maxInitialSpawnPoints)
{
break;
}
}
for (int j = 0; j < nodeGraphSpider.collectedSteps.Count; j++)
{
NodeGraphSpider.StepInfo stepInfo = nodeGraphSpider.collectedSteps[j];
groundNodes.GetNodePosition(stepInfo.node, out var position2);
Quaternion rotation = returnPoint.rotation;
SpawnPoint.AddSpawnPoint(position2, rotation);
}
}
private void Start()
{
previousDonut = initialDonut;
DonutInfo[] array = followingDonuts;
foreach (DonutInfo donutInfo in array)
{
if ((bool)donutInfo?.root)
{
donutInfo.root.SetActive(value: false);
}
}
if (NetworkServer.active)
{
TryShuffleData(Run.instance.stageRng.nextUlong);
CallRpcTryShuffleData(rngSeed);
}
}
public override void OnStartServer()
{
base.OnStartServer();
CallRpcTryShuffleData(rngSeed);
}
private void TryShuffleData(ulong seed)
{
NetworkrngSeed = seed;
if (hasShuffled)
{
return;
}
Xoroshiro128Plus rng = new Xoroshiro128Plus(seed);
Util.ShuffleArray(followingDonuts, rng);
Util.ShuffleArray(gauntlets, rng);
for (int i = 1; i < phaseEncounters.Length && i - 1 < followingDonuts.Length; i++)
{
DonutInfo donutInfo = followingDonuts[i - 1];
ScriptedCombatEncounter scriptedCombatEncounter = phaseEncounters[i];
int encounterIndex = i;
scriptedCombatEncounter.onBeginEncounter += delegate(ScriptedCombatEncounter argEncounter)
{
OnBeginEncounter(argEncounter, encounterIndex);
};
if (scriptedCombatEncounter.spawns.Length != 0)
{
scriptedCombatEncounter.spawns[0].explicitSpawnPosition = donutInfo.crabPosition;
}
}
for (int j = 0; j < gauntlets.Length && j < followingDonuts.Length; j++)
{
GauntletInfo gauntletInfo = gauntlets[j];
DonutInfo donutInfo2 = followingDonuts[j];
if ((bool)gauntletInfo.exitZone && (bool)donutInfo2.returnPoint)
{
gauntletInfo.exitZone.explicitDestination = donutInfo2.returnPoint;
gauntletInfo.exitZone.destinationIdealRadius = donutInfo2.returnRadius;
}
}
hasShuffled = true;
}
private void OnBeginEncounter(ScriptedCombatEncounter encounter, int encounterIndex)
{
while (gauntletIndex < encounterIndex)
{
TryOpenGauntlet(currentDonut.crabPosition.position, NetworkInstanceId.Invalid);
}
}
public void SpawnOutroPortal()
{
if (NetworkServer.active && currentDonut != null && (bool)currentDonut.returnPoint)
{
Xoroshiro128Plus rng = new Xoroshiro128Plus(rngSeed + 1);
DirectorPlacementRule placementRule = new DirectorPlacementRule
{
placementMode = DirectorPlacementRule.PlacementMode.Approximate,
minDistance = minOutroPortalDistance,
maxDistance = maxOutroPortalDistance,
spawnOnTarget = currentDonut.returnPoint
};
DirectorSpawnRequest directorSpawnRequest = new DirectorSpawnRequest(outroPortalSpawnCard, placementRule, rng);
DirectorCore.instance.TrySpawnObject(directorSpawnRequest);
}
}
[ClientRpc]
private void RpcStartActiveSoundLoop()
{
if ((bool)gauntletActiveLoop)
{
gauntletActiveLoopPtr = LoopSoundManager.PlaySoundLoopLocal(RoR2Application.instance.gameObject, gauntletActiveLoop);
}
}
[ClientRpc]
private void RpcActivateGate(string gateName)
{
if (!string.IsNullOrEmpty(gateName))
{
SceneInfo.instance.SetGateState(gateName, gateEnabled: true);
}
}
[ClientRpc]
private void RpcActivateDonut(int donutIndex)
{
if (donutIndex < followingDonuts.Length)
{
followingDonuts[donutIndex]?.root.SetActive(value: true);
}
}
[ClientRpc]
private void RpcTryShuffleData(ulong seed)
{
TryShuffleData(seed);
}
private void StopActiveSoundLoop()
{
if ((bool)gauntletActiveLoop)
{
LoopSoundManager.StopSoundLoopLocal(gauntletActiveLoopPtr);
}
}
private void SetSkyboxToGauntlet()
{
if ((bool)donutSkyboxObject)
{
donutSkyboxObject.SetActive(value: false);
}
if ((bool)gauntletSkyboxObject)
{
gauntletSkyboxObject.SetActive(value: true);
}
}
private void SetSkyboxToDonut()
{
if ((bool)donutSkyboxObject)
{
donutSkyboxObject.SetActive(value: true);
}
if ((bool)gauntletSkyboxObject)
{
gauntletSkyboxObject.SetActive(value: false);
}
}
public void OnAuthorityPlayerEnter()
{
SetSkyboxToGauntlet();
}
public void OnAuthorityPlayerExit()
{
SetSkyboxToDonut();
StopActiveSoundLoop();
}
public void PointZoneToGauntlet(int destinationGauntletIndex, MapZone zone)
{
if (destinationGauntletIndex < gauntlets.Length)
{
GauntletInfo gauntletInfo = gauntlets[destinationGauntletIndex];
zone.explicitDestination = gauntletInfo.startPoint;
zone.destinationIdealRadius = gauntletInfo.startRadius;
}
}
private void UNetVersion()
{
}
protected static void InvokeRpcRpcStartActiveSoundLoop(NetworkBehaviour obj, NetworkReader reader)
{
if (!NetworkClient.active)
{
Debug.LogError("RPC RpcStartActiveSoundLoop called on server.");
}
else
{
((VoidRaidGauntletController)obj).RpcStartActiveSoundLoop();
}
}
protected static void InvokeRpcRpcActivateGate(NetworkBehaviour obj, NetworkReader reader)
{
if (!NetworkClient.active)
{
Debug.LogError("RPC RpcActivateGate called on server.");
}
else
{
((VoidRaidGauntletController)obj).RpcActivateGate(reader.ReadString());
}
}
protected static void InvokeRpcRpcActivateDonut(NetworkBehaviour obj, NetworkReader reader)
{
if (!NetworkClient.active)
{
Debug.LogError("RPC RpcActivateDonut called on server.");
}
else
{
((VoidRaidGauntletController)obj).RpcActivateDonut((int)reader.ReadPackedUInt32());
}
}
protected static void InvokeRpcRpcTryShuffleData(NetworkBehaviour obj, NetworkReader reader)
{
if (!NetworkClient.active)
{
Debug.LogError("RPC RpcTryShuffleData called on server.");
}
else
{
((VoidRaidGauntletController)obj).RpcTryShuffleData(reader.ReadPackedUInt64());
}
}
public void CallRpcStartActiveSoundLoop()
{
if (!NetworkServer.active)
{
Debug.LogError("RPC Function RpcStartActiveSoundLoop called on client.");
return;
}
NetworkWriter networkWriter = new NetworkWriter();
networkWriter.Write((short)0);
networkWriter.Write((short)2);
networkWriter.WritePackedUInt32((uint)kRpcRpcStartActiveSoundLoop);
networkWriter.Write(GetComponent<NetworkIdentity>().netId);
SendRPCInternal(networkWriter, 0, "RpcStartActiveSoundLoop");
}
public void CallRpcActivateGate(string gateName)
{
if (!NetworkServer.active)
{
Debug.LogError("RPC Function RpcActivateGate called on client.");
return;
}
NetworkWriter networkWriter = new NetworkWriter();
networkWriter.Write((short)0);
networkWriter.Write((short)2);
networkWriter.WritePackedUInt32((uint)kRpcRpcActivateGate);
networkWriter.Write(GetComponent<NetworkIdentity>().netId);
networkWriter.Write(gateName);
SendRPCInternal(networkWriter, 0, "RpcActivateGate");
}
public void CallRpcActivateDonut(int donutIndex)
{
if (!NetworkServer.active)
{
Debug.LogError("RPC Function RpcActivateDonut called on client.");
return;
}
NetworkWriter networkWriter = new NetworkWriter();
networkWriter.Write((short)0);
networkWriter.Write((short)2);
networkWriter.WritePackedUInt32((uint)kRpcRpcActivateDonut);
networkWriter.Write(GetComponent<NetworkIdentity>().netId);
networkWriter.WritePackedUInt32((uint)donutIndex);
SendRPCInternal(networkWriter, 0, "RpcActivateDonut");
}
public void CallRpcTryShuffleData(ulong seed)
{
if (!NetworkServer.active)
{
Debug.LogError("RPC Function RpcTryShuffleData called on client.");
return;
}
NetworkWriter networkWriter = new NetworkWriter();
networkWriter.Write((short)0);
networkWriter.Write((short)2);
networkWriter.WritePackedUInt32((uint)kRpcRpcTryShuffleData);
networkWriter.Write(GetComponent<NetworkIdentity>().netId);
networkWriter.WritePackedUInt64(seed);
SendRPCInternal(networkWriter, 0, "RpcTryShuffleData");
}
static VoidRaidGauntletController()
{
kRpcRpcStartActiveSoundLoop = -755317963;
NetworkBehaviour.RegisterRpcDelegate(typeof(VoidRaidGauntletController), kRpcRpcStartActiveSoundLoop, InvokeRpcRpcStartActiveSoundLoop);
kRpcRpcActivateGate = -1148984728;
NetworkBehaviour.RegisterRpcDelegate(typeof(VoidRaidGauntletController), kRpcRpcActivateGate, InvokeRpcRpcActivateGate);
kRpcRpcActivateDonut = -1261146843;
NetworkBehaviour.RegisterRpcDelegate(typeof(VoidRaidGauntletController), kRpcRpcActivateDonut, InvokeRpcRpcActivateDonut);
kRpcRpcTryShuffleData = 20528402;
NetworkBehaviour.RegisterRpcDelegate(typeof(VoidRaidGauntletController), kRpcRpcTryShuffleData, InvokeRpcRpcTryShuffleData);
NetworkCRC.RegisterBehaviour("VoidRaidGauntletController", 0);
}
public override bool OnSerialize(NetworkWriter writer, bool forceAll)
{
if (forceAll)
{
writer.WritePackedUInt64(rngSeed);
return true;
}
bool flag = false;
if ((base.syncVarDirtyBits & (true ? 1u : 0u)) != 0)
{
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
flag = true;
}
writer.WritePackedUInt64(rngSeed);
}
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
}
return flag;
}
public override void OnDeserialize(NetworkReader reader, bool initialState)
{
if (initialState)
{
rngSeed = reader.ReadPackedUInt64();
return;
}
int num = (int)reader.ReadPackedUInt32();
if (((uint)num & (true ? 1u : 0u)) != 0)
{
TryShuffleData(reader.ReadPackedUInt64());
}
}
public override void PreStartClient()
{
}
}