2500 lines
81 KiB
C#
2500 lines
81 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using DunGen;
|
|
using TMPro;
|
|
using Unity.AI.Navigation;
|
|
using Unity.Netcode;
|
|
using UnityEngine;
|
|
using UnityEngine.AI;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
public class RoundManager : NetworkBehaviour
|
|
{
|
|
public StartOfRound playersManager;
|
|
|
|
public Transform syncedPropsContainer;
|
|
|
|
[Header("Global Game Variables / Balancing")]
|
|
public float scrapValueMultiplier = 1f;
|
|
|
|
public float scrapAmountMultiplier = 1f;
|
|
|
|
public float mapSizeMultiplier = 1f;
|
|
|
|
[Space(5f)]
|
|
[Space(5f)]
|
|
public int currentEnemyPower;
|
|
|
|
public int currentOutsideEnemyPower;
|
|
|
|
public int currentDaytimeEnemyPower;
|
|
|
|
public TimeOfDay timeScript;
|
|
|
|
private int currentHour;
|
|
|
|
public float currentHourTime;
|
|
|
|
[Header("Gameplay events")]
|
|
public List<int> enemySpawnTimes = new List<int>();
|
|
|
|
public int currentEnemySpawnIndex;
|
|
|
|
public bool isSpawningEnemies;
|
|
|
|
public bool begunSpawningEnemies;
|
|
|
|
[Header("Elevator Properties")]
|
|
public bool ElevatorCharging;
|
|
|
|
public float elevatorCharge;
|
|
|
|
public bool ElevatorPowered;
|
|
|
|
public bool elevatorUp;
|
|
|
|
public bool ElevatorLowering;
|
|
|
|
public bool ElevatorRunning;
|
|
|
|
public bool ReturnToSurface;
|
|
|
|
[Header("Elevator Variables")]
|
|
public Animator ElevatorAnimator;
|
|
|
|
public Animator ElevatorLightAnimator;
|
|
|
|
public AudioSource elevatorMotorAudio;
|
|
|
|
public AudioClip startMotor;
|
|
|
|
public Animator PanelButtons;
|
|
|
|
public Animator PanelLights;
|
|
|
|
public AudioSource elevatorButtonsAudio;
|
|
|
|
public AudioClip PressButtonSFX1;
|
|
|
|
public AudioClip PressButtonSFX2;
|
|
|
|
public TextMeshProUGUI PanelScreenText;
|
|
|
|
public Canvas PanelScreen;
|
|
|
|
public NetworkObject lungPlacePosition;
|
|
|
|
public InteractTrigger elevatorSocketTrigger;
|
|
|
|
private Coroutine loadLevelCoroutine;
|
|
|
|
private Coroutine flickerLightsCoroutine;
|
|
|
|
private Coroutine powerLightsCoroutine;
|
|
|
|
[Header("Enemies")]
|
|
public EnemyVent[] allEnemyVents;
|
|
|
|
public List<Anomaly> SpawnedAnomalies = new List<Anomaly>();
|
|
|
|
public List<EnemyAI> SpawnedEnemies = new List<EnemyAI>();
|
|
|
|
private List<int> SpawnProbabilities = new List<int>();
|
|
|
|
public int hourTimeBetweenEnemySpawnBatches = 2;
|
|
|
|
public int numberOfEnemiesInScene;
|
|
|
|
public int minEnemiesToSpawn;
|
|
|
|
public int minOutsideEnemiesToSpawn;
|
|
|
|
[Header("Hazards")]
|
|
public SpawnableMapObject[] spawnableMapObjects;
|
|
|
|
public GameObject mapPropsContainer;
|
|
|
|
public Transform[] shipSpawnPathPoints;
|
|
|
|
public GameObject[] spawnDenialPoints;
|
|
|
|
public string[] possibleCodesForBigDoors;
|
|
|
|
public GameObject quicksandPrefab;
|
|
|
|
public GameObject keyPrefab;
|
|
|
|
[Space(5f)]
|
|
public GameObject[] outsideAINodes;
|
|
|
|
public GameObject[] insideAINodes;
|
|
|
|
[Header("Dungeon generation")]
|
|
public RuntimeDungeon dungeonGenerator;
|
|
|
|
public bool dungeonCompletedGenerating;
|
|
|
|
public bool dungeonFinishedGeneratingForAllPlayers;
|
|
|
|
[Header("Scrap-collection")]
|
|
public Transform spawnedScrapContainer;
|
|
|
|
public int scrapCollectedInLevel;
|
|
|
|
public float totalScrapValueInLevel;
|
|
|
|
public List<GrabbableObject> scrapCollectedThisRound = new List<GrabbableObject>();
|
|
|
|
public SelectableLevel currentLevel;
|
|
|
|
public System.Random LevelRandom;
|
|
|
|
public System.Random AnomalyRandom;
|
|
|
|
public System.Random AnomalyValuesRandom;
|
|
|
|
public System.Random BreakerBoxRandom;
|
|
|
|
public System.Random ScrapValuesRandom;
|
|
|
|
public bool powerOffPermanently;
|
|
|
|
public bool hasInitializedLevelRandomSeed;
|
|
|
|
public List<ulong> playersFinishedGeneratingFloor = new List<ulong>(4);
|
|
|
|
public PowerSwitchEvent onPowerSwitch = new PowerSwitchEvent();
|
|
|
|
public List<Animator> allPoweredLightsAnimators = new List<Animator>();
|
|
|
|
public List<Light> allPoweredLights = new List<Light>();
|
|
|
|
public List<GameObject> spawnedSyncedObjects = new List<GameObject>();
|
|
|
|
public float stabilityMeter;
|
|
|
|
private Coroutine elevatorRunningCoroutine;
|
|
|
|
public int collisionsMask = 2305;
|
|
|
|
public bool cannotSpawnMoreInsideEnemies;
|
|
|
|
private Collider[] noiseOverlapResults = new Collider[20];
|
|
|
|
public Transform tempTransform;
|
|
|
|
public bool GotNavMeshPositionResult;
|
|
|
|
public NavMeshHit navHit;
|
|
|
|
private bool firstTimeSpawningEnemies;
|
|
|
|
private bool firstTimeSpawningOutsideEnemies;
|
|
|
|
private bool firstTimeSpawningDaytimeEnemies;
|
|
|
|
public static RoundManager Instance { get; private set; }
|
|
|
|
private void Awake()
|
|
{
|
|
if (Instance == null)
|
|
{
|
|
Instance = this;
|
|
}
|
|
else
|
|
{
|
|
UnityEngine.Object.Destroy(Instance.gameObject);
|
|
}
|
|
}
|
|
|
|
public void SpawnScrapInLevel()
|
|
{
|
|
List<Item> ScrapToSpawn = new List<Item>();
|
|
List<int> list = new List<int>();
|
|
int num = 0;
|
|
List<int> list2 = new List<int>(currentLevel.spawnableScrap.Count);
|
|
for (int j = 0; j < currentLevel.spawnableScrap.Count; j++)
|
|
{
|
|
list2.Add(currentLevel.spawnableScrap[j].rarity);
|
|
}
|
|
int[] weights = list2.ToArray();
|
|
int num2 = (int)((float)AnomalyRandom.Next(currentLevel.minScrap, currentLevel.maxScrap) * scrapAmountMultiplier);
|
|
for (int k = 0; k < num2; k++)
|
|
{
|
|
ScrapToSpawn.Add(currentLevel.spawnableScrap[GetRandomWeightedIndex(weights)].spawnableItem);
|
|
}
|
|
Debug.Log($"Number of scrap to spawn: {ScrapToSpawn.Count}. minTotalScrapValue: {currentLevel.minTotalScrapValue}. Total value of items: {num}.");
|
|
RandomScrapSpawn randomScrapSpawn = null;
|
|
RandomScrapSpawn[] source = UnityEngine.Object.FindObjectsOfType<RandomScrapSpawn>();
|
|
List<NetworkObjectReference> list3 = new List<NetworkObjectReference>();
|
|
List<RandomScrapSpawn> usedSpawns = new List<RandomScrapSpawn>();
|
|
int i;
|
|
for (i = 0; i < ScrapToSpawn.Count; i++)
|
|
{
|
|
if (ScrapToSpawn[i] == null)
|
|
{
|
|
Debug.Log("Error!!!!! Found null element in list ScrapToSpawn. Skipping it.");
|
|
continue;
|
|
}
|
|
List<RandomScrapSpawn> list4 = ((ScrapToSpawn[i].spawnPositionTypes != null && ScrapToSpawn[i].spawnPositionTypes.Count != 0) ? source.Where((RandomScrapSpawn x) => ScrapToSpawn[i].spawnPositionTypes.Contains(x.spawnableItems) && !x.spawnUsed).ToList() : source.ToList());
|
|
if (list4.Count <= 0)
|
|
{
|
|
Debug.Log("No tiles containing a scrap spawn with item type: " + ScrapToSpawn[i].itemName);
|
|
continue;
|
|
}
|
|
if (usedSpawns.Count > 0 && list4.Contains(randomScrapSpawn))
|
|
{
|
|
list4.RemoveAll((RandomScrapSpawn x) => usedSpawns.Contains(x));
|
|
if (list4.Count <= 0)
|
|
{
|
|
usedSpawns.Clear();
|
|
i--;
|
|
continue;
|
|
}
|
|
}
|
|
randomScrapSpawn = list4[AnomalyRandom.Next(0, list4.Count)];
|
|
usedSpawns.Add(randomScrapSpawn);
|
|
Vector3 position;
|
|
if (randomScrapSpawn.spawnedItemsCopyPosition)
|
|
{
|
|
randomScrapSpawn.spawnUsed = true;
|
|
position = randomScrapSpawn.transform.position;
|
|
}
|
|
else
|
|
{
|
|
position = GetRandomNavMeshPositionInRadiusSpherical(randomScrapSpawn.transform.position, randomScrapSpawn.itemSpawnRange, navHit) + Vector3.up * ScrapToSpawn[i].verticalOffset;
|
|
}
|
|
GameObject obj = UnityEngine.Object.Instantiate(ScrapToSpawn[i].spawnPrefab, position, Quaternion.identity, spawnedScrapContainer);
|
|
GrabbableObject component = obj.GetComponent<GrabbableObject>();
|
|
component.transform.rotation = Quaternion.Euler(component.itemProperties.restingRotation);
|
|
component.fallTime = 0f;
|
|
list.Add((int)((float)AnomalyRandom.Next(ScrapToSpawn[i].minValue, ScrapToSpawn[i].maxValue) * scrapValueMultiplier));
|
|
num += list[list.Count - 1];
|
|
component.scrapValue = list[list.Count - 1];
|
|
NetworkObject component2 = obj.GetComponent<NetworkObject>();
|
|
component2.Spawn();
|
|
list3.Add(component2);
|
|
}
|
|
StartCoroutine(waitForScrapToSpawnToSync(list3.ToArray(), list.ToArray()));
|
|
}
|
|
|
|
private IEnumerator waitForScrapToSpawnToSync(NetworkObjectReference[] spawnedScrap, int[] scrapValues)
|
|
{
|
|
yield return new WaitForSeconds(11f);
|
|
SyncScrapValuesClientRpc(spawnedScrap, scrapValues);
|
|
}
|
|
|
|
[ClientRpc]
|
|
public void SyncScrapValuesClientRpc(NetworkObjectReference[] spawnedScrap, int[] allScrapValue)
|
|
{
|
|
NetworkManager networkManager = base.NetworkManager;
|
|
if ((object)networkManager == null || !networkManager.IsListening)
|
|
{
|
|
return;
|
|
}
|
|
if (__rpc_exec_stage != __RpcExecStage.Client && (networkManager.IsServer || networkManager.IsHost))
|
|
{
|
|
ClientRpcParams clientRpcParams = default(ClientRpcParams);
|
|
FastBufferWriter bufferWriter = __beginSendClientRpc(1659269112u, clientRpcParams, RpcDelivery.Reliable);
|
|
bool value = spawnedScrap != null;
|
|
bufferWriter.WriteValueSafe(in value, default(FastBufferWriter.ForPrimitives));
|
|
if (value)
|
|
{
|
|
bufferWriter.WriteValueSafe(spawnedScrap, default(FastBufferWriter.ForNetworkSerializable));
|
|
}
|
|
bool value2 = allScrapValue != null;
|
|
bufferWriter.WriteValueSafe(in value2, default(FastBufferWriter.ForPrimitives));
|
|
if (value2)
|
|
{
|
|
bufferWriter.WriteValueSafe(allScrapValue, default(FastBufferWriter.ForPrimitives));
|
|
}
|
|
__endSendClientRpc(ref bufferWriter, 1659269112u, clientRpcParams, RpcDelivery.Reliable);
|
|
}
|
|
if (__rpc_exec_stage != __RpcExecStage.Client || (!networkManager.IsClient && !networkManager.IsHost))
|
|
{
|
|
return;
|
|
}
|
|
Debug.Log($"clientRPC scrap values length: {allScrapValue.Length}");
|
|
ScrapValuesRandom = new System.Random(StartOfRound.Instance.randomMapSeed + 210);
|
|
int num = 0;
|
|
for (int i = 0; i < spawnedScrap.Length; i++)
|
|
{
|
|
if (spawnedScrap[i].TryGet(out var networkObject))
|
|
{
|
|
GrabbableObject component = networkObject.GetComponent<GrabbableObject>();
|
|
if (component != null)
|
|
{
|
|
if (i >= allScrapValue.Length)
|
|
{
|
|
Debug.LogError($"spawnedScrap amount exceeded allScrapValue!: {spawnedScrap.Length}");
|
|
break;
|
|
}
|
|
component.SetScrapValue(allScrapValue[i]);
|
|
num += allScrapValue[i];
|
|
if (component.itemProperties.meshVariants.Length != 0)
|
|
{
|
|
component.gameObject.GetComponent<MeshFilter>().mesh = component.itemProperties.meshVariants[ScrapValuesRandom.Next(0, component.itemProperties.meshVariants.Length)];
|
|
}
|
|
try
|
|
{
|
|
if (component.itemProperties.materialVariants.Length != 0)
|
|
{
|
|
component.gameObject.GetComponent<MeshRenderer>().sharedMaterial = component.itemProperties.materialVariants[ScrapValuesRandom.Next(0, component.itemProperties.materialVariants.Length)];
|
|
}
|
|
}
|
|
catch (Exception arg)
|
|
{
|
|
Debug.Log($"Item name: {component.gameObject.name}; {arg}");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("Scrap networkobject object did not contain grabbable object!: " + networkObject.gameObject.name);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"Failed to get networkobject reference for scrap. id: {spawnedScrap[i].NetworkObjectId}");
|
|
}
|
|
}
|
|
totalScrapValueInLevel = num;
|
|
scrapCollectedInLevel = 0;
|
|
}
|
|
|
|
public void SpawnSyncedProps()
|
|
{
|
|
try
|
|
{
|
|
spawnedSyncedObjects.Clear();
|
|
SpawnSyncedObject[] array = UnityEngine.Object.FindObjectsOfType<SpawnSyncedObject>();
|
|
if (array == null)
|
|
{
|
|
return;
|
|
}
|
|
mapPropsContainer = GameObject.FindGameObjectWithTag("MapPropsContainer");
|
|
Debug.Log($"Spawning synced props on server. Length: {array.Length}");
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
GameObject gameObject = UnityEngine.Object.Instantiate(array[i].spawnPrefab, array[i].transform.position, array[i].transform.rotation, mapPropsContainer.transform);
|
|
if (gameObject != null)
|
|
{
|
|
gameObject.GetComponent<NetworkObject>().Spawn(destroyWithScene: true);
|
|
spawnedSyncedObjects.Add(gameObject);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception arg)
|
|
{
|
|
Debug.Log($"Exception! Unable to sync spawned objects on host; {arg}");
|
|
}
|
|
}
|
|
|
|
public void SpawnMapObjects()
|
|
{
|
|
if (currentLevel.spawnableMapObjects.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
mapPropsContainer = GameObject.FindGameObjectWithTag("MapPropsContainer");
|
|
RandomMapObject[] array = UnityEngine.Object.FindObjectsOfType<RandomMapObject>();
|
|
List<RandomMapObject> list = new List<RandomMapObject>();
|
|
for (int i = 0; i < currentLevel.spawnableMapObjects.Length; i++)
|
|
{
|
|
int num = (int)currentLevel.spawnableMapObjects[i].numberToSpawn.Evaluate((float)AnomalyRandom.NextDouble());
|
|
if (num <= 0)
|
|
{
|
|
continue;
|
|
}
|
|
for (int j = 0; j < array.Length; j++)
|
|
{
|
|
if (array[j].spawnablePrefabs.Contains(currentLevel.spawnableMapObjects[i].prefabToSpawn))
|
|
{
|
|
list.Add(array[j]);
|
|
}
|
|
}
|
|
for (int k = 0; k < num; k++)
|
|
{
|
|
RandomMapObject randomMapObject = list[AnomalyRandom.Next(0, list.Count)];
|
|
Vector3 position = randomMapObject.transform.position;
|
|
position = GetRandomNavMeshPositionInRadius(position, randomMapObject.spawnRange);
|
|
GameObject gameObject = UnityEngine.Object.Instantiate(currentLevel.spawnableMapObjects[i].prefabToSpawn, position, Quaternion.identity, mapPropsContainer.transform);
|
|
if (currentLevel.spawnableMapObjects[i].spawnFacingAwayFromWall)
|
|
{
|
|
gameObject.transform.eulerAngles = new Vector3(0f, YRotationThatFacesTheFarthestFromPosition(position + Vector3.up * 0.2f), 0f);
|
|
}
|
|
else
|
|
{
|
|
gameObject.transform.eulerAngles = new Vector3(gameObject.transform.eulerAngles.x, AnomalyRandom.Next(0, 360), gameObject.transform.eulerAngles.z);
|
|
}
|
|
gameObject.GetComponent<NetworkObject>().Spawn(destroyWithScene: true);
|
|
}
|
|
}
|
|
for (int l = 0; l < array.Length; l++)
|
|
{
|
|
UnityEngine.Object.Destroy(array[l].gameObject);
|
|
}
|
|
}
|
|
|
|
public float YRotationThatFacesTheFarthestFromPosition(Vector3 pos, float maxDistance = 25f, int resolution = 6)
|
|
{
|
|
int num = 0;
|
|
float num2 = 0f;
|
|
for (int i = 0; i < 360; i += 360 / resolution)
|
|
{
|
|
tempTransform.eulerAngles = new Vector3(0f, i, 0f);
|
|
if (Physics.Raycast(pos, tempTransform.forward, out var hitInfo, maxDistance, StartOfRound.Instance.collidersAndRoomMask, QueryTriggerInteraction.Ignore))
|
|
{
|
|
if (hitInfo.distance > num2)
|
|
{
|
|
num2 = hitInfo.distance;
|
|
num = i;
|
|
}
|
|
continue;
|
|
}
|
|
num = i;
|
|
break;
|
|
}
|
|
if (!hasInitializedLevelRandomSeed)
|
|
{
|
|
return UnityEngine.Random.Range(num - 15, num + 15);
|
|
}
|
|
return AnomalyRandom.Next(num - 15, num + 15);
|
|
}
|
|
|
|
public float YRotationThatFacesTheNearestFromPosition(Vector3 pos, float maxDistance = 25f, int resolution = 6)
|
|
{
|
|
int num = 0;
|
|
float num2 = 100f;
|
|
bool flag = false;
|
|
for (int i = 0; i < 360; i += 360 / resolution)
|
|
{
|
|
tempTransform.eulerAngles = new Vector3(0f, i, 0f);
|
|
if (!Physics.Raycast(pos, tempTransform.forward, out var hitInfo, maxDistance, StartOfRound.Instance.collidersAndRoomMask, QueryTriggerInteraction.Ignore))
|
|
{
|
|
break;
|
|
}
|
|
flag = true;
|
|
if (hitInfo.distance < num2)
|
|
{
|
|
num2 = hitInfo.distance;
|
|
num = i;
|
|
}
|
|
}
|
|
if (!flag)
|
|
{
|
|
return -777f;
|
|
}
|
|
if (!hasInitializedLevelRandomSeed)
|
|
{
|
|
return UnityEngine.Random.Range(num - 15, num + 15);
|
|
}
|
|
return AnomalyRandom.Next(num - 15, num + 15);
|
|
}
|
|
|
|
public void GenerateNewFloor()
|
|
{
|
|
if (!hasInitializedLevelRandomSeed)
|
|
{
|
|
hasInitializedLevelRandomSeed = true;
|
|
InitializeRandomNumberGenerators();
|
|
}
|
|
dungeonGenerator.Generator.ShouldRandomizeSeed = false;
|
|
dungeonGenerator.Generator.Seed = LevelRandom.Next();
|
|
Debug.Log($"GenerateNewFloor(). Map generator's random seed: {dungeonGenerator.Generator.Seed}");
|
|
dungeonGenerator.Generator.LengthMultiplier = currentLevel.factorySizeMultiplier * mapSizeMultiplier;
|
|
dungeonGenerator.Generate();
|
|
}
|
|
|
|
public void GeneratedFloorPostProcessing()
|
|
{
|
|
if (base.IsServer)
|
|
{
|
|
SpawnScrapInLevel();
|
|
SpawnMapObjects();
|
|
}
|
|
}
|
|
|
|
public void TurnBreakerSwitchesOff()
|
|
{
|
|
BreakerBox breakerBox = UnityEngine.Object.FindObjectOfType<BreakerBox>();
|
|
if (breakerBox != null)
|
|
{
|
|
Debug.Log("Switching breaker switches off");
|
|
breakerBox.SetSwitchesOff();
|
|
SwitchPower(on: false);
|
|
onPowerSwitch.Invoke(arg0: false);
|
|
}
|
|
}
|
|
|
|
public void LoadNewLevel(int randomSeed, SelectableLevel newLevel)
|
|
{
|
|
if (base.IsServer)
|
|
{
|
|
currentLevel = newLevel;
|
|
dungeonFinishedGeneratingForAllPlayers = false;
|
|
playersManager.fullyLoadedPlayers.Clear();
|
|
if (dungeonGenerator != null)
|
|
{
|
|
dungeonGenerator.Generator.OnGenerationStatusChanged -= Generator_OnGenerationStatusChanged;
|
|
}
|
|
if (loadLevelCoroutine != null)
|
|
{
|
|
loadLevelCoroutine = null;
|
|
}
|
|
loadLevelCoroutine = StartCoroutine(LoadNewLevelWait(randomSeed));
|
|
}
|
|
}
|
|
|
|
private IEnumerator LoadNewLevelWait(int randomSeed)
|
|
{
|
|
yield return null;
|
|
yield return null;
|
|
playersFinishedGeneratingFloor.Clear();
|
|
GenerateNewLevelClientRpc(randomSeed, currentLevel.levelID);
|
|
if (currentLevel.spawnEnemiesAndScrap)
|
|
{
|
|
yield return new WaitUntil(() => dungeonCompletedGenerating);
|
|
yield return null;
|
|
yield return new WaitUntil(() => playersFinishedGeneratingFloor.Count >= GameNetworkManager.Instance.connectedPlayers);
|
|
Debug.Log("Players finished generating the new floor");
|
|
}
|
|
yield return null;
|
|
SpawnSyncedProps();
|
|
if (currentLevel.spawnEnemiesAndScrap)
|
|
{
|
|
GeneratedFloorPostProcessing();
|
|
}
|
|
yield return null;
|
|
playersFinishedGeneratingFloor.Clear();
|
|
dungeonFinishedGeneratingForAllPlayers = true;
|
|
RefreshEnemyVents();
|
|
FinishGeneratingNewLevelClientRpc();
|
|
}
|
|
|
|
[ClientRpc]
|
|
public void GenerateNewLevelClientRpc(int randomSeed, int levelID)
|
|
{
|
|
NetworkManager networkManager = base.NetworkManager;
|
|
if ((object)networkManager == null || !networkManager.IsListening)
|
|
{
|
|
return;
|
|
}
|
|
if (__rpc_exec_stage != __RpcExecStage.Client && (networkManager.IsServer || networkManager.IsHost))
|
|
{
|
|
ClientRpcParams clientRpcParams = default(ClientRpcParams);
|
|
FastBufferWriter bufferWriter = __beginSendClientRpc(1193916134u, clientRpcParams, RpcDelivery.Reliable);
|
|
BytePacker.WriteValueBitPacked(bufferWriter, randomSeed);
|
|
BytePacker.WriteValueBitPacked(bufferWriter, levelID);
|
|
__endSendClientRpc(ref bufferWriter, 1193916134u, clientRpcParams, RpcDelivery.Reliable);
|
|
}
|
|
if (__rpc_exec_stage != __RpcExecStage.Client || (!networkManager.IsClient && !networkManager.IsHost))
|
|
{
|
|
return;
|
|
}
|
|
playersManager.randomMapSeed = randomSeed;
|
|
currentLevel = playersManager.levels[levelID];
|
|
hasInitializedLevelRandomSeed = false;
|
|
HUDManager.Instance.loadingText.text = $"Random seed: {randomSeed}";
|
|
HUDManager.Instance.loadingDarkenScreen.enabled = true;
|
|
dungeonCompletedGenerating = false;
|
|
mapPropsContainer = GameObject.FindGameObjectWithTag("MapPropsContainer");
|
|
if (!currentLevel.spawnEnemiesAndScrap)
|
|
{
|
|
return;
|
|
}
|
|
dungeonGenerator = UnityEngine.Object.FindObjectOfType<RuntimeDungeon>(includeInactive: false);
|
|
if (dungeonGenerator != null)
|
|
{
|
|
GenerateNewFloor();
|
|
if (dungeonGenerator.Generator.Status == GenerationStatus.Complete)
|
|
{
|
|
FinishGeneratingLevel();
|
|
Debug.Log("Dungeon finished generating in one frame.");
|
|
}
|
|
else
|
|
{
|
|
dungeonGenerator.Generator.OnGenerationStatusChanged += Generator_OnGenerationStatusChanged;
|
|
Debug.Log("Now listening to dungeon generator status.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"This client could not find dungeon generator! scene count: {SceneManager.sceneCount}");
|
|
}
|
|
}
|
|
|
|
private void FinishGeneratingLevel()
|
|
{
|
|
insideAINodes = GameObject.FindGameObjectsWithTag("AINode");
|
|
outsideAINodes = GameObject.FindGameObjectsWithTag("OutsideAINode");
|
|
dungeonCompletedGenerating = true;
|
|
SetToCurrentLevelWeather();
|
|
SpawnOutsideHazards();
|
|
FinishedGeneratingLevelServerRpc(NetworkManager.Singleton.LocalClientId);
|
|
}
|
|
|
|
private void Generator_OnGenerationStatusChanged(DungeonGenerator generator, GenerationStatus status)
|
|
{
|
|
if (status == GenerationStatus.Complete && !dungeonCompletedGenerating)
|
|
{
|
|
FinishGeneratingLevel();
|
|
Debug.Log("Dungeon has finished generating on this client after multiple frames");
|
|
}
|
|
dungeonGenerator.Generator.OnGenerationStatusChanged -= Generator_OnGenerationStatusChanged;
|
|
}
|
|
|
|
[ServerRpc(RequireOwnership = false)]
|
|
public void FinishedGeneratingLevelServerRpc(ulong clientId)
|
|
{
|
|
NetworkManager networkManager = base.NetworkManager;
|
|
if ((object)networkManager != null && networkManager.IsListening)
|
|
{
|
|
if (__rpc_exec_stage != __RpcExecStage.Server && (networkManager.IsClient || networkManager.IsHost))
|
|
{
|
|
ServerRpcParams serverRpcParams = default(ServerRpcParams);
|
|
FastBufferWriter bufferWriter = __beginSendServerRpc(192551691u, serverRpcParams, RpcDelivery.Reliable);
|
|
BytePacker.WriteValueBitPacked(bufferWriter, clientId);
|
|
__endSendServerRpc(ref bufferWriter, 192551691u, serverRpcParams, RpcDelivery.Reliable);
|
|
}
|
|
if (__rpc_exec_stage == __RpcExecStage.Server && (networkManager.IsServer || networkManager.IsHost))
|
|
{
|
|
playersFinishedGeneratingFloor.Add(clientId);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void DespawnPropsAtEndOfRound(bool despawnAllItems = false)
|
|
{
|
|
if (!base.IsServer)
|
|
{
|
|
return;
|
|
}
|
|
GrabbableObject[] array = UnityEngine.Object.FindObjectsOfType<GrabbableObject>();
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
if (despawnAllItems || (!array[i].isHeld && !array[i].isInShipRoom) || (StartOfRound.Instance.allPlayersDead && array[i].itemProperties.isScrap))
|
|
{
|
|
if (array[i].isHeld && array[i].playerHeldBy != null)
|
|
{
|
|
array[i].playerHeldBy.DropAllHeldItems();
|
|
}
|
|
array[i].gameObject.GetComponent<NetworkObject>().Despawn();
|
|
}
|
|
else
|
|
{
|
|
array[i].scrapPersistedThroughRounds = true;
|
|
}
|
|
if (spawnedSyncedObjects.Contains(array[i].gameObject))
|
|
{
|
|
spawnedSyncedObjects.Remove(array[i].gameObject);
|
|
}
|
|
}
|
|
GameObject[] array2 = GameObject.FindGameObjectsWithTag("TemporaryEffect");
|
|
for (int j = 0; j < array2.Length; j++)
|
|
{
|
|
UnityEngine.Object.Destroy(array2[j]);
|
|
}
|
|
}
|
|
|
|
public void UnloadSceneObjectsEarly()
|
|
{
|
|
if (!base.IsServer)
|
|
{
|
|
return;
|
|
}
|
|
Debug.Log("Despawning props and enemies #3");
|
|
isSpawningEnemies = false;
|
|
EnemyAI[] array = UnityEngine.Object.FindObjectsOfType<EnemyAI>();
|
|
Debug.Log($"Enemies on map: {array.Length}");
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
if (array[i].thisNetworkObject.IsSpawned)
|
|
{
|
|
Debug.Log("Despawning enemy: " + array[i].gameObject.name);
|
|
array[i].thisNetworkObject.Despawn();
|
|
}
|
|
else
|
|
{
|
|
Debug.Log($"{array[i].thisNetworkObject} was not spawned on network, so it could not be removed.");
|
|
}
|
|
}
|
|
SpawnedEnemies.Clear();
|
|
}
|
|
|
|
public override void OnDestroy()
|
|
{
|
|
if (dungeonGenerator != null)
|
|
{
|
|
dungeonGenerator.Generator.OnGenerationStatusChanged -= Generator_OnGenerationStatusChanged;
|
|
}
|
|
base.OnDestroy();
|
|
}
|
|
|
|
[ServerRpc]
|
|
public void FinishGeneratingNewLevelServerRpc()
|
|
{
|
|
NetworkManager networkManager = base.NetworkManager;
|
|
if ((object)networkManager == null || !networkManager.IsListening)
|
|
{
|
|
return;
|
|
}
|
|
if (__rpc_exec_stage != __RpcExecStage.Server && (networkManager.IsClient || networkManager.IsHost))
|
|
{
|
|
if (base.OwnerClientId != networkManager.LocalClientId)
|
|
{
|
|
if (networkManager.LogLevel <= LogLevel.Normal)
|
|
{
|
|
Debug.LogError("Only the owner can invoke a ServerRpc that requires ownership!");
|
|
}
|
|
return;
|
|
}
|
|
ServerRpcParams serverRpcParams = default(ServerRpcParams);
|
|
FastBufferWriter bufferWriter = __beginSendServerRpc(710372063u, serverRpcParams, RpcDelivery.Reliable);
|
|
__endSendServerRpc(ref bufferWriter, 710372063u, serverRpcParams, RpcDelivery.Reliable);
|
|
}
|
|
if (__rpc_exec_stage == __RpcExecStage.Server && (networkManager.IsServer || networkManager.IsHost))
|
|
{
|
|
FinishGeneratingNewLevelClientRpc();
|
|
}
|
|
}
|
|
|
|
private void SetToCurrentLevelWeather()
|
|
{
|
|
TimeOfDay.Instance.currentLevelWeather = currentLevel.currentWeather;
|
|
if (TimeOfDay.Instance.currentLevelWeather == LevelWeatherType.None || currentLevel.randomWeathers == null)
|
|
{
|
|
return;
|
|
}
|
|
for (int i = 0; i < currentLevel.randomWeathers.Length; i++)
|
|
{
|
|
if (currentLevel.randomWeathers[i].weatherType == currentLevel.currentWeather)
|
|
{
|
|
TimeOfDay.Instance.currentWeatherVariable = currentLevel.randomWeathers[i].weatherVariable;
|
|
TimeOfDay.Instance.currentWeatherVariable2 = currentLevel.randomWeathers[i].weatherVariable2;
|
|
}
|
|
}
|
|
}
|
|
|
|
[ClientRpc]
|
|
public void FinishGeneratingNewLevelClientRpc()
|
|
{
|
|
NetworkManager networkManager = base.NetworkManager;
|
|
if ((object)networkManager == null || !networkManager.IsListening)
|
|
{
|
|
return;
|
|
}
|
|
if (__rpc_exec_stage != __RpcExecStage.Client && (networkManager.IsServer || networkManager.IsHost))
|
|
{
|
|
ClientRpcParams clientRpcParams = default(ClientRpcParams);
|
|
FastBufferWriter bufferWriter = __beginSendClientRpc(2729232387u, clientRpcParams, RpcDelivery.Reliable);
|
|
__endSendClientRpc(ref bufferWriter, 2729232387u, clientRpcParams, RpcDelivery.Reliable);
|
|
}
|
|
if (__rpc_exec_stage == __RpcExecStage.Client && (networkManager.IsClient || networkManager.IsHost))
|
|
{
|
|
HUDManager.Instance.loadingText.enabled = false;
|
|
HUDManager.Instance.loadingDarkenScreen.enabled = false;
|
|
RefreshLightsList();
|
|
StartOfRound.Instance.StartCoroutine(playersManager.openingDoorsSequence());
|
|
if (currentLevel.spawnEnemiesAndScrap)
|
|
{
|
|
SetLevelObjectVariables();
|
|
}
|
|
ResetEnemySpawningVariables();
|
|
ResetEnemyTypesSpawnedCounts();
|
|
playersManager.newGameIsLoading = false;
|
|
FlashlightItem.globalFlashlightInterferenceLevel = 0;
|
|
powerOffPermanently = false;
|
|
RefreshEnemiesList();
|
|
if (StartOfRound.Instance.currentLevel.levelIncludesSnowFootprints)
|
|
{
|
|
StartOfRound.Instance.InstantiateFootprintsPooledObjects();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ResetEnemySpawningVariables()
|
|
{
|
|
begunSpawningEnemies = false;
|
|
currentHour = 0;
|
|
cannotSpawnMoreInsideEnemies = false;
|
|
minEnemiesToSpawn = 0;
|
|
minOutsideEnemiesToSpawn = 0;
|
|
}
|
|
|
|
public void ResetEnemyVariables()
|
|
{
|
|
HoarderBugAI.grabbableObjectsInMap.Clear();
|
|
HoarderBugAI.HoarderBugItems.Clear();
|
|
}
|
|
|
|
public void CollectNewScrapForThisRound(GrabbableObject scrapObject)
|
|
{
|
|
if (scrapObject.itemProperties.isScrap && !scrapCollectedThisRound.Contains(scrapObject) && !scrapObject.scrapPersistedThroughRounds)
|
|
{
|
|
scrapCollectedThisRound.Add(scrapObject);
|
|
HUDManager.Instance.AddNewScrapFoundToDisplay(scrapObject);
|
|
}
|
|
}
|
|
|
|
public void DetectElevatorIsRunning()
|
|
{
|
|
if (base.IsServer)
|
|
{
|
|
Debug.Log("Ship is leaving. Despawning props and enemies.");
|
|
if (elevatorRunningCoroutine != null)
|
|
{
|
|
StopCoroutine(elevatorRunningCoroutine);
|
|
}
|
|
elevatorRunningCoroutine = StartCoroutine(DetectElevatorRunning());
|
|
}
|
|
}
|
|
|
|
private IEnumerator DetectElevatorRunning()
|
|
{
|
|
isSpawningEnemies = false;
|
|
yield return new WaitForSeconds(1.5f);
|
|
Debug.Log("Despawning props and enemies #2");
|
|
UnloadSceneObjectsEarly();
|
|
}
|
|
|
|
public void BeginEnemySpawning()
|
|
{
|
|
if (base.IsServer)
|
|
{
|
|
if (allEnemyVents.Length != 0 && currentLevel.maxEnemyPowerCount > 0)
|
|
{
|
|
currentEnemySpawnIndex = 0;
|
|
PlotOutEnemiesForNextHour();
|
|
isSpawningEnemies = true;
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("Not able to spawn enemies on map; no vents were detected or maxEnemyPowerCount is 0.");
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SpawnEnemiesOutside()
|
|
{
|
|
if (currentOutsideEnemyPower > currentLevel.maxOutsideEnemyPowerCount)
|
|
{
|
|
return;
|
|
}
|
|
float num = timeScript.lengthOfHours * (float)currentHour;
|
|
float num2 = currentLevel.outsideEnemySpawnChanceThroughDay.Evaluate(num / timeScript.totalTime);
|
|
float num3 = num2 + (float)Mathf.Abs(TimeOfDay.Instance.daysUntilDeadline - 3) / 1.6f;
|
|
int num4 = Mathf.Clamp(AnomalyRandom.Next((int)(num3 - 3f), (int)(num2 + 3f)), minOutsideEnemiesToSpawn, 20);
|
|
GameObject[] spawnPoints = GameObject.FindGameObjectsWithTag("OutsideAINode");
|
|
for (int i = 0; i < num4; i++)
|
|
{
|
|
GameObject gameObject = SpawnRandomOutsideEnemy(spawnPoints, num);
|
|
if (gameObject != null)
|
|
{
|
|
SpawnedEnemies.Add(gameObject.GetComponent<EnemyAI>());
|
|
gameObject.GetComponent<EnemyAI>().enemyType.numberSpawned++;
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void SpawnDaytimeEnemiesOutside()
|
|
{
|
|
if (currentLevel.DaytimeEnemies == null || currentLevel.DaytimeEnemies.Count <= 0 || currentDaytimeEnemyPower > currentLevel.maxDaytimeEnemyPowerCount)
|
|
{
|
|
return;
|
|
}
|
|
float num = timeScript.lengthOfHours * (float)currentHour;
|
|
float num2 = currentLevel.daytimeEnemySpawnChanceThroughDay.Evaluate(num / timeScript.totalTime);
|
|
Debug.Log($"base chance daytime: {currentLevel.daytimeEnemySpawnChanceThroughDay.Evaluate(num / timeScript.totalTime)}");
|
|
Debug.Log($"timeuptocurrenthour: {num}; totalTime: {timeScript.totalTime}");
|
|
int num3 = Mathf.Clamp(AnomalyRandom.Next((int)(num2 - currentLevel.daytimeEnemiesProbabilityRange), (int)(num2 + currentLevel.daytimeEnemiesProbabilityRange)), 0, 20);
|
|
Debug.Log($"enemies to spawn daytime: {num3}");
|
|
GameObject[] spawnPoints = GameObject.FindGameObjectsWithTag("OutsideAINode");
|
|
for (int i = 0; i < num3; i++)
|
|
{
|
|
GameObject gameObject = SpawnRandomDaytimeEnemy(spawnPoints, num);
|
|
if (gameObject != null)
|
|
{
|
|
SpawnedEnemies.Add(gameObject.GetComponent<EnemyAI>());
|
|
gameObject.GetComponent<EnemyAI>().enemyType.numberSpawned++;
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private GameObject SpawnRandomDaytimeEnemy(GameObject[] spawnPoints, float timeUpToCurrentHour)
|
|
{
|
|
SpawnProbabilities.Clear();
|
|
int num = 0;
|
|
for (int i = 0; i < currentLevel.DaytimeEnemies.Count; i++)
|
|
{
|
|
EnemyType enemyType = currentLevel.DaytimeEnemies[i].enemyType;
|
|
if (firstTimeSpawningDaytimeEnemies)
|
|
{
|
|
enemyType.numberSpawned = 0;
|
|
}
|
|
Debug.Log($"dayimte enemy chance: {enemyType.PowerLevel > currentLevel.maxDaytimeEnemyPowerCount - currentDaytimeEnemyPower}; {enemyType.numberSpawned >= currentLevel.DaytimeEnemies[i].enemyType.MaxCount}; {enemyType.normalizedTimeInDayToLeave < TimeOfDay.Instance.normalizedTimeOfDay}");
|
|
if (enemyType.PowerLevel > currentLevel.maxDaytimeEnemyPowerCount - currentDaytimeEnemyPower || enemyType.numberSpawned >= currentLevel.DaytimeEnemies[i].enemyType.MaxCount || enemyType.normalizedTimeInDayToLeave < TimeOfDay.Instance.normalizedTimeOfDay)
|
|
{
|
|
SpawnProbabilities.Add(0);
|
|
continue;
|
|
}
|
|
int num2 = (int)((float)currentLevel.DaytimeEnemies[i].rarity * enemyType.probabilityCurve.Evaluate(timeUpToCurrentHour / timeScript.totalTime));
|
|
Debug.Log($"Enemy available, probability: {num2}; {currentLevel.DaytimeEnemies[i].rarity} * {enemyType.probabilityCurve.Evaluate(timeUpToCurrentHour / timeScript.totalTime)}");
|
|
Debug.Log($"time up to current hour: {timeUpToCurrentHour}");
|
|
SpawnProbabilities.Add(num2);
|
|
num += num2;
|
|
}
|
|
firstTimeSpawningDaytimeEnemies = false;
|
|
if (num <= 0)
|
|
{
|
|
_ = currentDaytimeEnemyPower;
|
|
_ = currentLevel.maxDaytimeEnemyPowerCount;
|
|
return null;
|
|
}
|
|
int randomWeightedIndex = GetRandomWeightedIndex(SpawnProbabilities.ToArray());
|
|
currentDaytimeEnemyPower += currentLevel.DaytimeEnemies[randomWeightedIndex].enemyType.PowerLevel;
|
|
Vector3 position = spawnPoints[AnomalyRandom.Next(0, spawnPoints.Length)].transform.position;
|
|
position = GetRandomNavMeshPositionInRadius(position, 4f);
|
|
int num3 = 0;
|
|
bool flag = false;
|
|
for (int j = 0; j < spawnPoints.Length - 1; j++)
|
|
{
|
|
for (int k = 0; k < spawnDenialPoints.Length; k++)
|
|
{
|
|
flag = true;
|
|
if (Vector3.Distance(position, spawnDenialPoints[k].transform.position) < 8f)
|
|
{
|
|
num3 = (num3 + 1) % spawnPoints.Length;
|
|
position = spawnPoints[num3].transform.position;
|
|
position = GetRandomNavMeshPositionInRadius(position, 4f);
|
|
flag = false;
|
|
break;
|
|
}
|
|
}
|
|
if (flag)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
GameObject obj = UnityEngine.Object.Instantiate(currentLevel.DaytimeEnemies[randomWeightedIndex].enemyType.enemyPrefab, position, Quaternion.Euler(Vector3.zero));
|
|
obj.gameObject.GetComponentInChildren<NetworkObject>().Spawn(destroyWithScene: true);
|
|
return obj;
|
|
}
|
|
|
|
private GameObject SpawnRandomOutsideEnemy(GameObject[] spawnPoints, float timeUpToCurrentHour)
|
|
{
|
|
SpawnProbabilities.Clear();
|
|
int num = 0;
|
|
for (int i = 0; i < currentLevel.OutsideEnemies.Count; i++)
|
|
{
|
|
EnemyType enemyType = currentLevel.OutsideEnemies[i].enemyType;
|
|
if (firstTimeSpawningOutsideEnemies)
|
|
{
|
|
enemyType.numberSpawned = 0;
|
|
}
|
|
if (enemyType.PowerLevel > currentLevel.maxOutsideEnemyPowerCount - currentOutsideEnemyPower || enemyType.numberSpawned >= enemyType.MaxCount)
|
|
{
|
|
SpawnProbabilities.Add(0);
|
|
continue;
|
|
}
|
|
int num2 = (int)((float)currentLevel.OutsideEnemies[i].rarity * enemyType.probabilityCurve.Evaluate(timeUpToCurrentHour / timeScript.totalTime));
|
|
SpawnProbabilities.Add(num2);
|
|
num += num2;
|
|
}
|
|
firstTimeSpawningOutsideEnemies = false;
|
|
if (num <= 0)
|
|
{
|
|
_ = currentOutsideEnemyPower;
|
|
_ = currentLevel.maxOutsideEnemyPowerCount;
|
|
return null;
|
|
}
|
|
int randomWeightedIndex = GetRandomWeightedIndex(SpawnProbabilities.ToArray());
|
|
currentOutsideEnemyPower += currentLevel.OutsideEnemies[randomWeightedIndex].enemyType.PowerLevel;
|
|
Vector3 position = spawnPoints[AnomalyRandom.Next(0, spawnPoints.Length)].transform.position;
|
|
position = GetRandomNavMeshPositionInRadius(position, 4f);
|
|
int num3 = 0;
|
|
bool flag = false;
|
|
for (int j = 0; j < spawnPoints.Length - 1; j++)
|
|
{
|
|
for (int k = 0; k < spawnDenialPoints.Length; k++)
|
|
{
|
|
flag = true;
|
|
if (Vector3.Distance(position, spawnDenialPoints[k].transform.position) < 8f)
|
|
{
|
|
num3 = (num3 + 1) % spawnPoints.Length;
|
|
position = spawnPoints[num3].transform.position;
|
|
position = GetRandomNavMeshPositionInRadius(position, 4f);
|
|
flag = false;
|
|
break;
|
|
}
|
|
}
|
|
if (flag)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
GameObject obj = UnityEngine.Object.Instantiate(currentLevel.OutsideEnemies[randomWeightedIndex].enemyType.enemyPrefab, position, Quaternion.Euler(Vector3.zero));
|
|
obj.gameObject.GetComponentInChildren<NetworkObject>().Spawn(destroyWithScene: true);
|
|
return obj;
|
|
}
|
|
|
|
public void PlotOutEnemiesForNextHour()
|
|
{
|
|
if (!base.IsServer)
|
|
{
|
|
return;
|
|
}
|
|
List<EnemyVent> list = new List<EnemyVent>();
|
|
for (int i = 0; i < allEnemyVents.Length; i++)
|
|
{
|
|
if (!allEnemyVents[i].occupied)
|
|
{
|
|
list.Add(allEnemyVents[i]);
|
|
}
|
|
}
|
|
enemySpawnTimes.Clear();
|
|
float num = currentLevel.enemySpawnChanceThroughoutDay.Evaluate(timeScript.currentDayTime / timeScript.totalTime);
|
|
float num2 = num + (float)Mathf.Abs(TimeOfDay.Instance.daysUntilDeadline - 3) / 1.6f;
|
|
int value = Mathf.Clamp(AnomalyRandom.Next((int)(num2 - currentLevel.spawnProbabilityRange), (int)(num + currentLevel.spawnProbabilityRange)), minEnemiesToSpawn, 20);
|
|
Debug.Log($"spawn chance range min/max : {(int)(num - currentLevel.spawnProbabilityRange)}, {(int)(num + currentLevel.spawnProbabilityRange)}; time of day percent: {timeScript.currentDayTime / timeScript.totalTime}");
|
|
Debug.Log($"spawn chance range min/max (non integer) : {num - currentLevel.spawnProbabilityRange}, {num + currentLevel.spawnProbabilityRange}");
|
|
value = Mathf.Clamp(value, 0, list.Count);
|
|
Debug.Log($"enemies to spawn: {value}");
|
|
if (currentEnemyPower >= currentLevel.maxEnemyPowerCount)
|
|
{
|
|
cannotSpawnMoreInsideEnemies = true;
|
|
return;
|
|
}
|
|
float num3 = timeScript.lengthOfHours * (float)currentHour;
|
|
for (int j = 0; j < value; j++)
|
|
{
|
|
int num4 = AnomalyRandom.Next((int)(10f + num3), (int)(timeScript.lengthOfHours * (float)hourTimeBetweenEnemySpawnBatches + num3));
|
|
if (!AssignRandomEnemyToVent(list[AnomalyRandom.Next(list.Count)], num4))
|
|
{
|
|
break;
|
|
}
|
|
enemySpawnTimes.Add(num4);
|
|
}
|
|
enemySpawnTimes.Sort();
|
|
}
|
|
|
|
public void LogEnemySpawnTimes(bool couldNotFinish)
|
|
{
|
|
if (couldNotFinish)
|
|
{
|
|
Debug.Log("Stopped assigning enemies to vents early as there was no enemy with a power count low enough to fit.");
|
|
}
|
|
Debug.Log("Enemy spawn times:");
|
|
for (int i = 0; i < enemySpawnTimes.Count; i++)
|
|
{
|
|
Debug.Log($"time {i}: {enemySpawnTimes[i]}");
|
|
}
|
|
}
|
|
|
|
private bool AssignRandomEnemyToVent(EnemyVent vent, float spawnTime)
|
|
{
|
|
SpawnProbabilities.Clear();
|
|
int num = 0;
|
|
for (int i = 0; i < currentLevel.Enemies.Count; i++)
|
|
{
|
|
EnemyType enemyType = currentLevel.Enemies[i].enemyType;
|
|
if (firstTimeSpawningEnemies)
|
|
{
|
|
enemyType.numberSpawned = 0;
|
|
}
|
|
if (EnemyCannotBeSpawned(i))
|
|
{
|
|
SpawnProbabilities.Add(0);
|
|
Debug.Log($"enemy #{i} probability - {0}");
|
|
Debug.Log($"Enemy {i} could not be spawned. current power count is {currentEnemyPower}; max is {currentLevel.maxEnemyPowerCount}.");
|
|
}
|
|
else
|
|
{
|
|
int num2 = (int)((float)currentLevel.Enemies[i].rarity * (enemyType.probabilityCurve.Evaluate(timeScript.normalizedTimeOfDay) * enemyType.numberSpawnedFalloff.Evaluate((float)enemyType.numberSpawned / 10f)));
|
|
SpawnProbabilities.Add(num2);
|
|
Debug.Log($"enemy #{i} probability - {num2}");
|
|
num += num2;
|
|
}
|
|
}
|
|
firstTimeSpawningEnemies = false;
|
|
if (num <= 0)
|
|
{
|
|
if (currentEnemyPower >= currentLevel.maxEnemyPowerCount)
|
|
{
|
|
Debug.Log($"Round manager: No more spawnable enemies. Power count: {currentLevel.maxEnemyPowerCount} Max: {currentLevel.maxEnemyPowerCount}");
|
|
cannotSpawnMoreInsideEnemies = true;
|
|
}
|
|
return false;
|
|
}
|
|
int randomWeightedIndex = GetRandomWeightedIndex(SpawnProbabilities.ToArray());
|
|
Debug.Log("ADDING ENEMY");
|
|
Debug.Log($"random enemy #: {randomWeightedIndex}");
|
|
currentEnemyPower += currentLevel.Enemies[randomWeightedIndex].enemyType.PowerLevel;
|
|
vent.enemyType = currentLevel.Enemies[randomWeightedIndex].enemyType;
|
|
vent.enemyTypeIndex = randomWeightedIndex;
|
|
vent.occupied = true;
|
|
vent.spawnTime = spawnTime;
|
|
if (timeScript.hour - currentHour > 0)
|
|
{
|
|
Debug.Log("RoundManager is catching up to current time! Not syncing vent SFX with clients since enemy will spawn from vent almost immediately.");
|
|
}
|
|
else
|
|
{
|
|
vent.SyncVentSpawnTimeClientRpc((int)spawnTime, randomWeightedIndex);
|
|
}
|
|
currentLevel.Enemies[randomWeightedIndex].enemyType.numberSpawned++;
|
|
return true;
|
|
}
|
|
|
|
private bool EnemyCannotBeSpawned(int enemyIndex)
|
|
{
|
|
if (currentLevel.Enemies[enemyIndex].enemyType.PowerLevel <= currentLevel.maxEnemyPowerCount - currentEnemyPower)
|
|
{
|
|
return currentLevel.Enemies[enemyIndex].enemyType.numberSpawned >= currentLevel.Enemies[enemyIndex].enemyType.MaxCount;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public void InitializeRandomNumberGenerators()
|
|
{
|
|
SoundManager.Instance.InitializeRandom();
|
|
LevelRandom = new System.Random(playersManager.randomMapSeed);
|
|
AnomalyRandom = new System.Random(playersManager.randomMapSeed + 5);
|
|
AnomalyValuesRandom = new System.Random(playersManager.randomMapSeed - 40);
|
|
BreakerBoxRandom = new System.Random(playersManager.randomMapSeed - 20);
|
|
}
|
|
|
|
public void SpawnEnemyFromVent(EnemyVent vent)
|
|
{
|
|
Vector3 position = vent.floorNode.position;
|
|
float y = vent.floorNode.eulerAngles.y;
|
|
SpawnEnemyOnServer(position, y, vent.enemyTypeIndex);
|
|
Debug.Log("Spawned enemy from vent");
|
|
vent.OpenVentClientRpc();
|
|
vent.occupied = false;
|
|
}
|
|
|
|
public void SpawnEnemyOnServer(Vector3 spawnPosition, float yRot, int enemyNumber = -1)
|
|
{
|
|
if (!base.IsServer)
|
|
{
|
|
SpawnEnemyServerRpc(spawnPosition, yRot, enemyNumber);
|
|
}
|
|
else
|
|
{
|
|
SpawnEnemyGameObject(spawnPosition, yRot, enemyNumber);
|
|
}
|
|
}
|
|
|
|
[ServerRpc]
|
|
public void SpawnEnemyServerRpc(Vector3 spawnPosition, float yRot, int enemyNumber)
|
|
{
|
|
NetworkManager networkManager = base.NetworkManager;
|
|
if ((object)networkManager == null || !networkManager.IsListening)
|
|
{
|
|
return;
|
|
}
|
|
if (__rpc_exec_stage != __RpcExecStage.Server && (networkManager.IsClient || networkManager.IsHost))
|
|
{
|
|
if (base.OwnerClientId != networkManager.LocalClientId)
|
|
{
|
|
if (networkManager.LogLevel <= LogLevel.Normal)
|
|
{
|
|
Debug.LogError("Only the owner can invoke a ServerRpc that requires ownership!");
|
|
}
|
|
return;
|
|
}
|
|
ServerRpcParams serverRpcParams = default(ServerRpcParams);
|
|
FastBufferWriter bufferWriter = __beginSendServerRpc(46494176u, serverRpcParams, RpcDelivery.Reliable);
|
|
bufferWriter.WriteValueSafe(in spawnPosition);
|
|
bufferWriter.WriteValueSafe(in yRot, default(FastBufferWriter.ForPrimitives));
|
|
BytePacker.WriteValueBitPacked(bufferWriter, enemyNumber);
|
|
__endSendServerRpc(ref bufferWriter, 46494176u, serverRpcParams, RpcDelivery.Reliable);
|
|
}
|
|
if (__rpc_exec_stage == __RpcExecStage.Server && (networkManager.IsServer || networkManager.IsHost))
|
|
{
|
|
SpawnEnemyGameObject(spawnPosition, yRot, enemyNumber);
|
|
}
|
|
}
|
|
|
|
public void SpawnEnemyGameObject(Vector3 spawnPosition, float yRot, int enemyNumber)
|
|
{
|
|
int index = enemyNumber;
|
|
switch (enemyNumber)
|
|
{
|
|
case -1:
|
|
index = UnityEngine.Random.Range(0, currentLevel.Enemies.Count);
|
|
break;
|
|
case -2:
|
|
{
|
|
GameObject gameObject2 = UnityEngine.Object.Instantiate(currentLevel.DaytimeEnemies[UnityEngine.Random.Range(0, currentLevel.DaytimeEnemies.Count)].enemyType.enemyPrefab, spawnPosition, Quaternion.Euler(new Vector3(0f, yRot, 0f)));
|
|
gameObject2.GetComponentInChildren<NetworkObject>().Spawn(destroyWithScene: true);
|
|
SpawnedEnemies.Add(gameObject2.GetComponent<EnemyAI>());
|
|
return;
|
|
}
|
|
case -3:
|
|
{
|
|
GameObject gameObject = UnityEngine.Object.Instantiate(currentLevel.OutsideEnemies[UnityEngine.Random.Range(0, currentLevel.OutsideEnemies.Count)].enemyType.enemyPrefab, spawnPosition, Quaternion.Euler(new Vector3(0f, yRot, 0f)));
|
|
gameObject.GetComponentInChildren<NetworkObject>().Spawn(destroyWithScene: true);
|
|
SpawnedEnemies.Add(gameObject.GetComponent<EnemyAI>());
|
|
return;
|
|
}
|
|
}
|
|
GameObject gameObject3 = UnityEngine.Object.Instantiate(currentLevel.Enemies[index].enemyType.enemyPrefab, spawnPosition, Quaternion.Euler(new Vector3(0f, yRot, 0f)));
|
|
gameObject3.GetComponentInChildren<NetworkObject>().Spawn(destroyWithScene: true);
|
|
SpawnedEnemies.Add(gameObject3.GetComponent<EnemyAI>());
|
|
}
|
|
|
|
public void DespawnEnemyOnServer(NetworkObject enemyNetworkObject)
|
|
{
|
|
if (!base.IsServer)
|
|
{
|
|
DespawnEnemyServerRpc(enemyNetworkObject);
|
|
}
|
|
else
|
|
{
|
|
DespawnEnemyGameObject(enemyNetworkObject);
|
|
}
|
|
}
|
|
|
|
[ServerRpc(RequireOwnership = false)]
|
|
public void DespawnEnemyServerRpc(NetworkObjectReference enemyNetworkObject)
|
|
{
|
|
NetworkManager networkManager = base.NetworkManager;
|
|
if ((object)networkManager != null && networkManager.IsListening)
|
|
{
|
|
if (__rpc_exec_stage != __RpcExecStage.Server && (networkManager.IsClient || networkManager.IsHost))
|
|
{
|
|
ServerRpcParams serverRpcParams = default(ServerRpcParams);
|
|
FastBufferWriter bufferWriter = __beginSendServerRpc(3840785488u, serverRpcParams, RpcDelivery.Reliable);
|
|
bufferWriter.WriteValueSafe(in enemyNetworkObject, default(FastBufferWriter.ForNetworkSerializable));
|
|
__endSendServerRpc(ref bufferWriter, 3840785488u, serverRpcParams, RpcDelivery.Reliable);
|
|
}
|
|
if (__rpc_exec_stage == __RpcExecStage.Server && (networkManager.IsServer || networkManager.IsHost))
|
|
{
|
|
DespawnEnemyGameObject(enemyNetworkObject);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DespawnEnemyGameObject(NetworkObjectReference enemyNetworkObject)
|
|
{
|
|
if (enemyNetworkObject.TryGet(out var networkObject))
|
|
{
|
|
EnemyAI component = networkObject.gameObject.GetComponent<EnemyAI>();
|
|
SpawnedEnemies.Remove(component);
|
|
if (component.enemyType.isOutsideEnemy)
|
|
{
|
|
currentOutsideEnemyPower -= component.enemyType.PowerLevel;
|
|
}
|
|
else if (component.enemyType.isDaytimeEnemy)
|
|
{
|
|
currentDaytimeEnemyPower -= component.enemyType.PowerLevel;
|
|
}
|
|
else
|
|
{
|
|
currentEnemyPower -= component.enemyType.PowerLevel;
|
|
}
|
|
cannotSpawnMoreInsideEnemies = false;
|
|
component.gameObject.GetComponent<NetworkObject>().Despawn();
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("Round manager despawn enemy gameobject: Could not get network object from reference!");
|
|
}
|
|
}
|
|
|
|
public void SwitchPower(bool on)
|
|
{
|
|
if (!base.IsServer)
|
|
{
|
|
return;
|
|
}
|
|
if (on)
|
|
{
|
|
if (!powerOffPermanently)
|
|
{
|
|
PowerSwitchOnClientRpc();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PowerSwitchOffClientRpc();
|
|
}
|
|
}
|
|
|
|
[ClientRpc]
|
|
public void PowerSwitchOnClientRpc()
|
|
{
|
|
NetworkManager networkManager = base.NetworkManager;
|
|
if ((object)networkManager != null && networkManager.IsListening)
|
|
{
|
|
if (__rpc_exec_stage != __RpcExecStage.Client && (networkManager.IsServer || networkManager.IsHost))
|
|
{
|
|
ClientRpcParams clientRpcParams = default(ClientRpcParams);
|
|
FastBufferWriter bufferWriter = __beginSendClientRpc(1061166170u, clientRpcParams, RpcDelivery.Reliable);
|
|
__endSendClientRpc(ref bufferWriter, 1061166170u, clientRpcParams, RpcDelivery.Reliable);
|
|
}
|
|
if (__rpc_exec_stage == __RpcExecStage.Client && (networkManager.IsClient || networkManager.IsHost))
|
|
{
|
|
onPowerSwitch.Invoke(arg0: true);
|
|
TurnOnAllLights(on: true);
|
|
}
|
|
}
|
|
}
|
|
|
|
[ClientRpc]
|
|
public void PowerSwitchOffClientRpc()
|
|
{
|
|
NetworkManager networkManager = base.NetworkManager;
|
|
if ((object)networkManager != null && networkManager.IsListening)
|
|
{
|
|
if (__rpc_exec_stage != __RpcExecStage.Client && (networkManager.IsServer || networkManager.IsHost))
|
|
{
|
|
ClientRpcParams clientRpcParams = default(ClientRpcParams);
|
|
FastBufferWriter bufferWriter = __beginSendClientRpc(1586488299u, clientRpcParams, RpcDelivery.Reliable);
|
|
__endSendClientRpc(ref bufferWriter, 1586488299u, clientRpcParams, RpcDelivery.Reliable);
|
|
}
|
|
if (__rpc_exec_stage == __RpcExecStage.Client && (networkManager.IsClient || networkManager.IsHost))
|
|
{
|
|
Debug.Log("Calling power switch off event from roundmanager");
|
|
onPowerSwitch.Invoke(arg0: false);
|
|
TurnOnAllLights(on: false);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void TurnOnAllLights(bool on)
|
|
{
|
|
if (powerLightsCoroutine != null)
|
|
{
|
|
StopCoroutine(powerLightsCoroutine);
|
|
}
|
|
powerLightsCoroutine = StartCoroutine(turnOnLights(on));
|
|
}
|
|
|
|
private IEnumerator turnOnLights(bool turnOn)
|
|
{
|
|
yield return null;
|
|
BreakerBox breakerBox = UnityEngine.Object.FindObjectOfType<BreakerBox>();
|
|
if (breakerBox != null)
|
|
{
|
|
breakerBox.thisAudioSource.PlayOneShot(breakerBox.switchPowerSFX);
|
|
breakerBox.isPowerOn = turnOn;
|
|
}
|
|
for (int b = 4; b > 0; b--)
|
|
{
|
|
if (b == 0)
|
|
{
|
|
Debug.Log("b is 0 in loop");
|
|
break;
|
|
}
|
|
for (int i = 0; i < allPoweredLightsAnimators.Count / b; i++)
|
|
{
|
|
allPoweredLightsAnimators[i].SetBool("on", turnOn);
|
|
}
|
|
yield return new WaitForSeconds(0.03f);
|
|
}
|
|
}
|
|
|
|
public void FlickerLights(bool flickerFlashlights = false, bool disableFlashlights = false)
|
|
{
|
|
if (flickerLightsCoroutine != null)
|
|
{
|
|
StopCoroutine(flickerLightsCoroutine);
|
|
}
|
|
flickerLightsCoroutine = StartCoroutine(FlickerPoweredLights(flickerFlashlights, disableFlashlights));
|
|
}
|
|
|
|
private IEnumerator FlickerPoweredLights(bool flickerFlashlights = false, bool disableFlashlights = false)
|
|
{
|
|
Debug.Log("Flickering lights");
|
|
if (flickerFlashlights)
|
|
{
|
|
Debug.Log("Flickering flashlights");
|
|
FlashlightItem.globalFlashlightInterferenceLevel = 1;
|
|
FlashlightItem[] array = UnityEngine.Object.FindObjectsOfType<FlashlightItem>();
|
|
if (array != null)
|
|
{
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
array[i].flashlightAudio.PlayOneShot(array[i].flashlightFlicker);
|
|
WalkieTalkie.TransmitOneShotAudio(array[i].flashlightAudio, array[i].flashlightFlicker, 0.8f);
|
|
if (disableFlashlights && array[i].playerHeldBy != null && array[i].playerHeldBy.isInsideFactory)
|
|
{
|
|
array[i].flashlightInterferenceLevel = 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (allPoweredLightsAnimators.Count > 0 && allPoweredLightsAnimators[0] != null)
|
|
{
|
|
int loopCount = 0;
|
|
int b = 4;
|
|
while (b > 0 && b != 0)
|
|
{
|
|
for (int j = loopCount; j < allPoweredLightsAnimators.Count / b; j++)
|
|
{
|
|
loopCount++;
|
|
allPoweredLightsAnimators[j].SetTrigger("Flicker");
|
|
}
|
|
yield return new WaitForSeconds(0.05f);
|
|
b--;
|
|
}
|
|
}
|
|
if (!flickerFlashlights)
|
|
{
|
|
yield break;
|
|
}
|
|
yield return new WaitForSeconds(0.3f);
|
|
FlashlightItem[] array2 = UnityEngine.Object.FindObjectsOfType<FlashlightItem>();
|
|
if (array2 != null)
|
|
{
|
|
for (int k = 0; k < array2.Length; k++)
|
|
{
|
|
array2[k].flashlightInterferenceLevel = 0;
|
|
}
|
|
}
|
|
FlashlightItem.globalFlashlightInterferenceLevel = 0;
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
RefreshLightsList();
|
|
RefreshEnemyVents();
|
|
timeScript = UnityEngine.Object.FindObjectOfType<TimeOfDay>();
|
|
FlashlightItem.globalFlashlightInterferenceLevel = 0;
|
|
navHit = default(NavMeshHit);
|
|
}
|
|
|
|
private void ResetEnemyTypesSpawnedCounts()
|
|
{
|
|
EnemyAI[] array = UnityEngine.Object.FindObjectsOfType<EnemyAI>();
|
|
for (int i = 0; i < currentLevel.Enemies.Count; i++)
|
|
{
|
|
currentLevel.Enemies[i].enemyType.numberSpawned = 0;
|
|
for (int j = 0; j < array.Length; j++)
|
|
{
|
|
if (array[j].enemyType == currentLevel.Enemies[i].enemyType)
|
|
{
|
|
currentLevel.Enemies[i].enemyType.numberSpawned++;
|
|
}
|
|
}
|
|
}
|
|
for (int k = 0; k < currentLevel.OutsideEnemies.Count; k++)
|
|
{
|
|
currentLevel.OutsideEnemies[k].enemyType.numberSpawned = 0;
|
|
for (int l = 0; l < array.Length; l++)
|
|
{
|
|
if (array[l].enemyType == currentLevel.OutsideEnemies[k].enemyType)
|
|
{
|
|
currentLevel.OutsideEnemies[k].enemyType.numberSpawned++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void RefreshEnemiesList()
|
|
{
|
|
SpawnedEnemies.Clear();
|
|
EnemyAI[] array = UnityEngine.Object.FindObjectsOfType<EnemyAI>();
|
|
SpawnedEnemies.AddRange(array);
|
|
numberOfEnemiesInScene = array.Length;
|
|
firstTimeSpawningEnemies = true;
|
|
firstTimeSpawningOutsideEnemies = true;
|
|
firstTimeSpawningDaytimeEnemies = true;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (!base.IsServer || !dungeonFinishedGeneratingForAllPlayers)
|
|
{
|
|
return;
|
|
}
|
|
if (isSpawningEnemies)
|
|
{
|
|
SpawnInsideEnemiesFromVentsIfReady();
|
|
if (timeScript.hour > currentHour && currentEnemySpawnIndex >= enemySpawnTimes.Count)
|
|
{
|
|
AdvanceHourAndSpawnNewBatchOfEnemies();
|
|
}
|
|
}
|
|
else if (timeScript.currentDayTime > 85f && !begunSpawningEnemies)
|
|
{
|
|
begunSpawningEnemies = true;
|
|
BeginEnemySpawning();
|
|
}
|
|
}
|
|
|
|
private void SpawnInsideEnemiesFromVentsIfReady()
|
|
{
|
|
if (enemySpawnTimes.Count <= currentEnemySpawnIndex || !(timeScript.currentDayTime > (float)enemySpawnTimes[currentEnemySpawnIndex]))
|
|
{
|
|
return;
|
|
}
|
|
for (int i = 0; i < allEnemyVents.Length; i++)
|
|
{
|
|
if (allEnemyVents[i].occupied && timeScript.currentDayTime > allEnemyVents[i].spawnTime)
|
|
{
|
|
Debug.Log("Found enemy vent which has its time up: " + allEnemyVents[i].gameObject.name + ". Spawning " + allEnemyVents[i].enemyType.enemyName + " from vent.");
|
|
SpawnEnemyFromVent(allEnemyVents[i]);
|
|
}
|
|
}
|
|
currentEnemySpawnIndex++;
|
|
}
|
|
|
|
private void AdvanceHourAndSpawnNewBatchOfEnemies()
|
|
{
|
|
currentHour += hourTimeBetweenEnemySpawnBatches;
|
|
SpawnDaytimeEnemiesOutside();
|
|
SpawnEnemiesOutside();
|
|
Debug.Log("Advance hour");
|
|
if (allEnemyVents.Length != 0 && !cannotSpawnMoreInsideEnemies)
|
|
{
|
|
currentEnemySpawnIndex = 0;
|
|
PlotOutEnemiesForNextHour();
|
|
}
|
|
else
|
|
{
|
|
Debug.Log($"Could not spawn more enemies; vents #: {allEnemyVents.Length}. CannotSpawnMoreInsideEnemies: {cannotSpawnMoreInsideEnemies}");
|
|
}
|
|
}
|
|
|
|
public void RefreshLightsList()
|
|
{
|
|
allPoweredLights.Clear();
|
|
allPoweredLightsAnimators.Clear();
|
|
GameObject[] array = GameObject.FindGameObjectsWithTag("PoweredLight");
|
|
if (array == null)
|
|
{
|
|
return;
|
|
}
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
Animator componentInChildren = array[i].GetComponentInChildren<Animator>();
|
|
if (!(componentInChildren == null))
|
|
{
|
|
allPoweredLightsAnimators.Add(componentInChildren);
|
|
allPoweredLights.Add(array[i].GetComponentInChildren<Light>(includeInactive: true));
|
|
}
|
|
}
|
|
for (int j = 0; j < allPoweredLightsAnimators.Count; j++)
|
|
{
|
|
allPoweredLightsAnimators[j].SetFloat("flickerSpeed", UnityEngine.Random.Range(0.6f, 1.4f));
|
|
}
|
|
Debug.Log($"# powered lights: {allPoweredLights.Count}");
|
|
}
|
|
|
|
public void RefreshEnemyVents()
|
|
{
|
|
allEnemyVents = UnityEngine.Object.FindObjectsOfType<EnemyVent>();
|
|
}
|
|
|
|
private void SpawnOutsideHazards()
|
|
{
|
|
System.Random random = new System.Random(StartOfRound.Instance.randomMapSeed + 2);
|
|
outsideAINodes = (from x in GameObject.FindGameObjectsWithTag("OutsideAINode")
|
|
orderby Vector3.Distance(x.transform.position, Vector3.zero)
|
|
select x).ToArray();
|
|
NavMeshHit hit = default(NavMeshHit);
|
|
int num = 0;
|
|
if (TimeOfDay.Instance.currentLevelWeather == LevelWeatherType.Rainy)
|
|
{
|
|
num = random.Next(5, 15);
|
|
if (random.Next(0, 100) < 7)
|
|
{
|
|
num = random.Next(5, 30);
|
|
}
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
Vector3 position = GetRandomNavMeshPositionInBoxPredictable(outsideAINodes[random.Next(0, outsideAINodes.Length)].transform.position, 30f, hit, random) + Vector3.up;
|
|
GameObject gameObject = UnityEngine.Object.Instantiate(quicksandPrefab, position, Quaternion.identity, mapPropsContainer.transform);
|
|
}
|
|
}
|
|
int num2 = 0;
|
|
List<Vector3> list = new List<Vector3>();
|
|
spawnDenialPoints = GameObject.FindGameObjectsWithTag("SpawnDenialPoint");
|
|
if (currentLevel.spawnableOutsideObjects != null)
|
|
{
|
|
for (int j = 0; j < currentLevel.spawnableOutsideObjects.Length; j++)
|
|
{
|
|
num = (int)currentLevel.spawnableOutsideObjects[j].randomAmount.Evaluate((float)random.NextDouble());
|
|
if (random.Next(0, 100) < 20)
|
|
{
|
|
num *= 2;
|
|
}
|
|
for (int k = 0; k < num; k++)
|
|
{
|
|
Vector3 position = GetRandomNavMeshPositionInBoxPredictable(outsideAINodes[random.Next(0, outsideAINodes.Length)].transform.position, 30f, hit, random);
|
|
if (currentLevel.spawnableOutsideObjects[j].spawnableObject.spawnableFloorTags != null)
|
|
{
|
|
bool flag = false;
|
|
if (Physics.Raycast(position + Vector3.up, Vector3.down, out var hitInfo, 5f, StartOfRound.Instance.collidersAndRoomMaskAndDefault))
|
|
{
|
|
for (int l = 0; l < currentLevel.spawnableOutsideObjects[j].spawnableObject.spawnableFloorTags.Length; l++)
|
|
{
|
|
if (hitInfo.collider.transform.CompareTag(currentLevel.spawnableOutsideObjects[j].spawnableObject.spawnableFloorTags[l]))
|
|
{
|
|
flag = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!flag)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
if (NavMesh.FindClosestEdge(position, out hit, -1) && hit.distance < (float)currentLevel.spawnableOutsideObjects[j].spawnableObject.objectWidth)
|
|
{
|
|
Vector3 position2 = hit.position;
|
|
if (!NavMesh.SamplePosition(new Ray(position2, position - position2).GetPoint((float)currentLevel.spawnableOutsideObjects[j].spawnableObject.objectWidth + 0.5f), out hit, 10f, -1))
|
|
{
|
|
continue;
|
|
}
|
|
position = hit.position;
|
|
}
|
|
bool flag2 = false;
|
|
for (int m = 0; m < shipSpawnPathPoints.Length; m++)
|
|
{
|
|
if (Vector3.Distance(shipSpawnPathPoints[m].transform.position, position) < (float)currentLevel.spawnableOutsideObjects[j].spawnableObject.objectWidth + 6f)
|
|
{
|
|
flag2 = true;
|
|
break;
|
|
}
|
|
}
|
|
for (int n = 0; n < spawnDenialPoints.Length; n++)
|
|
{
|
|
if (Vector3.Distance(spawnDenialPoints[n].transform.position, position) < (float)currentLevel.spawnableOutsideObjects[j].spawnableObject.objectWidth + 6f)
|
|
{
|
|
flag2 = true;
|
|
break;
|
|
}
|
|
}
|
|
if (Vector3.Distance(GameObject.FindGameObjectWithTag("ItemShipLandingNode").transform.position, position) < (float)currentLevel.spawnableOutsideObjects[j].spawnableObject.objectWidth + 4f)
|
|
{
|
|
flag2 = true;
|
|
break;
|
|
}
|
|
if (flag2)
|
|
{
|
|
continue;
|
|
}
|
|
if (currentLevel.spawnableOutsideObjects[j].spawnableObject.objectWidth > 4)
|
|
{
|
|
flag2 = false;
|
|
for (int num3 = 0; num3 < list.Count; num3++)
|
|
{
|
|
if (Vector3.Distance(position, list[num3]) < (float)currentLevel.spawnableOutsideObjects[j].spawnableObject.objectWidth)
|
|
{
|
|
flag2 = true;
|
|
break;
|
|
}
|
|
}
|
|
if (flag2)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
list.Add(position);
|
|
GameObject gameObject = UnityEngine.Object.Instantiate(currentLevel.spawnableOutsideObjects[j].spawnableObject.prefabToSpawn, position - Vector3.up * 0.7f, Quaternion.identity, mapPropsContainer.transform);
|
|
num2++;
|
|
if (currentLevel.spawnableOutsideObjects[j].spawnableObject.spawnFacingAwayFromWall)
|
|
{
|
|
gameObject.transform.eulerAngles = new Vector3(0f, YRotationThatFacesTheFarthestFromPosition(position + Vector3.up * 0.2f), 0f);
|
|
}
|
|
else
|
|
{
|
|
gameObject.transform.eulerAngles = new Vector3(gameObject.transform.eulerAngles.x, random.Next(0, 360), gameObject.transform.eulerAngles.z);
|
|
}
|
|
gameObject.transform.localEulerAngles = new Vector3(gameObject.transform.localEulerAngles.x + currentLevel.spawnableOutsideObjects[j].spawnableObject.rotationOffset.x, gameObject.transform.localEulerAngles.y + currentLevel.spawnableOutsideObjects[j].spawnableObject.rotationOffset.y, gameObject.transform.localEulerAngles.z + currentLevel.spawnableOutsideObjects[j].spawnableObject.rotationOffset.z);
|
|
}
|
|
}
|
|
}
|
|
if (num2 > 0)
|
|
{
|
|
GameObject gameObject2 = GameObject.FindGameObjectWithTag("OutsideLevelNavMesh");
|
|
if (gameObject2 != null)
|
|
{
|
|
gameObject2.GetComponent<NavMeshSurface>().BuildNavMesh();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void SpawnRandomStoryLogs()
|
|
{
|
|
}
|
|
|
|
public void SetLevelObjectVariables()
|
|
{
|
|
StartCoroutine(waitForMainEntranceTeleportToSpawn());
|
|
}
|
|
|
|
private IEnumerator waitForMainEntranceTeleportToSpawn()
|
|
{
|
|
float startTime = Time.timeSinceLevelLoad;
|
|
while (FindMainEntrancePosition() == Vector3.zero && Time.timeSinceLevelLoad - startTime < 15f)
|
|
{
|
|
yield return new WaitForSeconds(1f);
|
|
}
|
|
Vector3 vector = FindMainEntrancePosition();
|
|
SetLockedDoors(vector);
|
|
SetSteamValveTimes(vector);
|
|
SetBigDoorCodes(vector);
|
|
SetExitIDs(vector);
|
|
SetPowerOffAtStart();
|
|
}
|
|
|
|
private void SetPowerOffAtStart()
|
|
{
|
|
if (LevelRandom.NextDouble() < 0.07999999821186066)
|
|
{
|
|
TurnBreakerSwitchesOff();
|
|
Debug.Log("Turning lights off at start");
|
|
}
|
|
else
|
|
{
|
|
TurnOnAllLights(on: true);
|
|
Debug.Log("Turning lights on at start");
|
|
}
|
|
}
|
|
|
|
private void SetBigDoorCodes(Vector3 mainEntrancePosition)
|
|
{
|
|
System.Random random = new System.Random(StartOfRound.Instance.randomMapSeed + 17);
|
|
TerminalAccessibleObject[] array = (from x in UnityEngine.Object.FindObjectsOfType<TerminalAccessibleObject>()
|
|
orderby (x.transform.position - mainEntrancePosition).sqrMagnitude
|
|
select x).ToArray();
|
|
int num = 3;
|
|
int num2 = 0;
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
array[i].InitializeValues();
|
|
array[i].SetCodeTo(random.Next(possibleCodesForBigDoors.Length));
|
|
if (array[i].isBigDoor && (num2 < num || random.NextDouble() < 0.2199999988079071))
|
|
{
|
|
num2++;
|
|
array[i].SetDoorOpen(open: true);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void SetExitIDs(Vector3 mainEntrancePosition)
|
|
{
|
|
int num = 1;
|
|
EntranceTeleport[] array = (from x in UnityEngine.Object.FindObjectsOfType<EntranceTeleport>()
|
|
orderby (x.transform.position - mainEntrancePosition).sqrMagnitude
|
|
select x).ToArray();
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
if (array[i].entranceId == 1 && !array[i].isEntranceToBuilding)
|
|
{
|
|
array[i].entranceId = num;
|
|
num++;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void SetSteamValveTimes(Vector3 mainEntrancePosition)
|
|
{
|
|
System.Random random = new System.Random(StartOfRound.Instance.randomMapSeed + 513);
|
|
SteamValveHazard[] array = (from x in UnityEngine.Object.FindObjectsOfType<SteamValveHazard>()
|
|
orderby (x.transform.position - mainEntrancePosition).sqrMagnitude
|
|
select x).ToArray();
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
if (random.NextDouble() < 0.75)
|
|
{
|
|
array[i].valveBurstTime = Mathf.Clamp((float)random.NextDouble(), 0.2f, 1f);
|
|
array[i].valveCrackTime = array[i].valveBurstTime * (float)random.NextDouble();
|
|
array[i].fogSizeMultiplier = Mathf.Clamp((float)random.NextDouble(), 0.6f, 0.98f);
|
|
}
|
|
else if (random.NextDouble() < 0.25)
|
|
{
|
|
array[i].valveCrackTime = Mathf.Clamp((float)random.NextDouble(), 0.3f, 0.9f);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void SetLockedDoors(Vector3 mainEntrancePosition)
|
|
{
|
|
if (mainEntrancePosition == Vector3.zero)
|
|
{
|
|
Debug.Log("Main entrance teleport was not spawned on local client within 12 seconds. Locking doors based on origin instead.");
|
|
}
|
|
List<DoorLock> list = UnityEngine.Object.FindObjectsOfType<DoorLock>().ToList();
|
|
for (int num = list.Count - 1; num >= 0; num--)
|
|
{
|
|
if (list[num].transform.position.y > -160f)
|
|
{
|
|
list.RemoveAt(num);
|
|
}
|
|
}
|
|
list = list.OrderByDescending((DoorLock x) => (mainEntrancePosition - x.transform.position).sqrMagnitude).ToList();
|
|
float num2 = 1.1f;
|
|
int num3 = 0;
|
|
for (int i = 0; i < list.Count; i++)
|
|
{
|
|
if (LevelRandom.NextDouble() < (double)num2)
|
|
{
|
|
float timeToLockPick = Mathf.Clamp(LevelRandom.Next(2, 90), 2f, 32f);
|
|
list[i].LockDoor(timeToLockPick);
|
|
num3++;
|
|
}
|
|
num2 /= 1.55f;
|
|
}
|
|
if (base.IsServer)
|
|
{
|
|
for (int j = 0; j < num3; j++)
|
|
{
|
|
Vector3 randomNavMeshPositionInBoxPredictable = GetRandomNavMeshPositionInBoxPredictable(insideAINodes[AnomalyRandom.Next(0, insideAINodes.Length)].transform.position, 8f, navHit, AnomalyRandom);
|
|
GameObject gameObject = UnityEngine.Object.Instantiate(keyPrefab, randomNavMeshPositionInBoxPredictable, Quaternion.identity, spawnedScrapContainer);
|
|
gameObject.GetComponent<NetworkObject>().Spawn();
|
|
Debug.Log($"Spawning key: {gameObject.name}; isSpawned? : {gameObject.GetComponent<NetworkObject>().IsSpawned}");
|
|
}
|
|
}
|
|
}
|
|
|
|
[ServerRpc]
|
|
public void LightningStrikeServerRpc(Vector3 strikePosition)
|
|
{
|
|
NetworkManager networkManager = base.NetworkManager;
|
|
if ((object)networkManager == null || !networkManager.IsListening)
|
|
{
|
|
return;
|
|
}
|
|
if (__rpc_exec_stage != __RpcExecStage.Server && (networkManager.IsClient || networkManager.IsHost))
|
|
{
|
|
if (base.OwnerClientId != networkManager.LocalClientId)
|
|
{
|
|
if (networkManager.LogLevel <= LogLevel.Normal)
|
|
{
|
|
Debug.LogError("Only the owner can invoke a ServerRpc that requires ownership!");
|
|
}
|
|
return;
|
|
}
|
|
ServerRpcParams serverRpcParams = default(ServerRpcParams);
|
|
FastBufferWriter bufferWriter = __beginSendServerRpc(1145714957u, serverRpcParams, RpcDelivery.Reliable);
|
|
bufferWriter.WriteValueSafe(in strikePosition);
|
|
__endSendServerRpc(ref bufferWriter, 1145714957u, serverRpcParams, RpcDelivery.Reliable);
|
|
}
|
|
if (__rpc_exec_stage == __RpcExecStage.Server && (networkManager.IsServer || networkManager.IsHost))
|
|
{
|
|
LightningStrikeClientRpc(strikePosition);
|
|
}
|
|
}
|
|
|
|
[ClientRpc]
|
|
public void LightningStrikeClientRpc(Vector3 strikePosition)
|
|
{
|
|
NetworkManager networkManager = base.NetworkManager;
|
|
if ((object)networkManager != null && networkManager.IsListening)
|
|
{
|
|
if (__rpc_exec_stage != __RpcExecStage.Client && (networkManager.IsServer || networkManager.IsHost))
|
|
{
|
|
ClientRpcParams clientRpcParams = default(ClientRpcParams);
|
|
FastBufferWriter bufferWriter = __beginSendClientRpc(112447504u, clientRpcParams, RpcDelivery.Reliable);
|
|
bufferWriter.WriteValueSafe(in strikePosition);
|
|
__endSendClientRpc(ref bufferWriter, 112447504u, clientRpcParams, RpcDelivery.Reliable);
|
|
}
|
|
if (__rpc_exec_stage == __RpcExecStage.Client && (networkManager.IsClient || networkManager.IsHost))
|
|
{
|
|
UnityEngine.Object.FindObjectOfType<StormyWeather>(includeInactive: true).LightningStrike(strikePosition, useTargetedObject: true);
|
|
}
|
|
}
|
|
}
|
|
|
|
[ServerRpc]
|
|
public void ShowStaticElectricityWarningServerRpc(NetworkObjectReference warningObject, float timeLeft)
|
|
{
|
|
NetworkManager networkManager = base.NetworkManager;
|
|
if ((object)networkManager == null || !networkManager.IsListening)
|
|
{
|
|
return;
|
|
}
|
|
if (__rpc_exec_stage != __RpcExecStage.Server && (networkManager.IsClient || networkManager.IsHost))
|
|
{
|
|
if (base.OwnerClientId != networkManager.LocalClientId)
|
|
{
|
|
if (networkManager.LogLevel <= LogLevel.Normal)
|
|
{
|
|
Debug.LogError("Only the owner can invoke a ServerRpc that requires ownership!");
|
|
}
|
|
return;
|
|
}
|
|
ServerRpcParams serverRpcParams = default(ServerRpcParams);
|
|
FastBufferWriter bufferWriter = __beginSendServerRpc(445397880u, serverRpcParams, RpcDelivery.Reliable);
|
|
bufferWriter.WriteValueSafe(in warningObject, default(FastBufferWriter.ForNetworkSerializable));
|
|
bufferWriter.WriteValueSafe(in timeLeft, default(FastBufferWriter.ForPrimitives));
|
|
__endSendServerRpc(ref bufferWriter, 445397880u, serverRpcParams, RpcDelivery.Reliable);
|
|
}
|
|
if (__rpc_exec_stage == __RpcExecStage.Server && (networkManager.IsServer || networkManager.IsHost))
|
|
{
|
|
ShowStaticElectricityWarningClientRpc(warningObject, timeLeft);
|
|
}
|
|
}
|
|
|
|
[ClientRpc]
|
|
public void ShowStaticElectricityWarningClientRpc(NetworkObjectReference warningObject, float timeLeft)
|
|
{
|
|
NetworkManager networkManager = base.NetworkManager;
|
|
if ((object)networkManager != null && networkManager.IsListening)
|
|
{
|
|
if (__rpc_exec_stage != __RpcExecStage.Client && (networkManager.IsServer || networkManager.IsHost))
|
|
{
|
|
ClientRpcParams clientRpcParams = default(ClientRpcParams);
|
|
FastBufferWriter bufferWriter = __beginSendClientRpc(3840203489u, clientRpcParams, RpcDelivery.Reliable);
|
|
bufferWriter.WriteValueSafe(in warningObject, default(FastBufferWriter.ForNetworkSerializable));
|
|
bufferWriter.WriteValueSafe(in timeLeft, default(FastBufferWriter.ForPrimitives));
|
|
__endSendClientRpc(ref bufferWriter, 3840203489u, clientRpcParams, RpcDelivery.Reliable);
|
|
}
|
|
if (__rpc_exec_stage == __RpcExecStage.Client && (networkManager.IsClient || networkManager.IsHost) && warningObject.TryGet(out var networkObject))
|
|
{
|
|
UnityEngine.Object.FindObjectOfType<StormyWeather>(includeInactive: true).SetStaticElectricityWarning(networkObject, timeLeft);
|
|
}
|
|
}
|
|
}
|
|
|
|
public Vector3 RandomlyOffsetPosition(Vector3 pos, float maxRadius, float padding = 1f)
|
|
{
|
|
tempTransform.position = pos;
|
|
tempTransform.eulerAngles = Vector3.forward;
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
float num = UnityEngine.Random.Range(-180f, 180f);
|
|
tempTransform.localEulerAngles = new Vector3(0f, tempTransform.localEulerAngles.y + num, 0f);
|
|
Ray ray = new Ray(tempTransform.position, tempTransform.forward);
|
|
if (Physics.Raycast(ray, out var hitInfo, 6f, 2304))
|
|
{
|
|
float num2 = hitInfo.distance - padding;
|
|
if (num2 < 0f)
|
|
{
|
|
return ray.GetPoint(num2);
|
|
}
|
|
float distance = Mathf.Clamp(UnityEngine.Random.Range(0.1f, maxRadius), 0f, num2);
|
|
return ray.GetPoint(distance);
|
|
}
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
public static Vector3 RandomPointInBounds(Bounds bounds)
|
|
{
|
|
return new Vector3(UnityEngine.Random.Range(bounds.min.x, bounds.max.x), UnityEngine.Random.Range(bounds.min.y, bounds.max.y), UnityEngine.Random.Range(bounds.min.z, bounds.max.z));
|
|
}
|
|
|
|
public Vector3 GetNavMeshPosition(Vector3 pos, NavMeshHit navMeshHit = default(NavMeshHit), float sampleRadius = 5f, int areaMask = -1)
|
|
{
|
|
if (NavMesh.SamplePosition(pos, out navMeshHit, sampleRadius, areaMask))
|
|
{
|
|
GotNavMeshPositionResult = true;
|
|
return navMeshHit.position;
|
|
}
|
|
GotNavMeshPositionResult = false;
|
|
return pos;
|
|
}
|
|
|
|
public Transform GetClosestNode(Vector3 pos, bool outside = true)
|
|
{
|
|
GameObject[] array;
|
|
if (outside)
|
|
{
|
|
if (outsideAINodes == null)
|
|
{
|
|
outsideAINodes = GameObject.FindGameObjectsWithTag("OutsideAINode");
|
|
}
|
|
array = outsideAINodes;
|
|
}
|
|
else
|
|
{
|
|
if (insideAINodes == null)
|
|
{
|
|
outsideAINodes = GameObject.FindGameObjectsWithTag("AINode");
|
|
}
|
|
array = insideAINodes;
|
|
}
|
|
float num = 99999f;
|
|
int num2 = 0;
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
float sqrMagnitude = (array[i].transform.position - pos).sqrMagnitude;
|
|
if (sqrMagnitude < num)
|
|
{
|
|
num = sqrMagnitude;
|
|
num2 = i;
|
|
}
|
|
}
|
|
return array[num2].transform;
|
|
}
|
|
|
|
public Vector3 GetRandomNavMeshPositionInRadius(Vector3 pos, float radius = 10f, NavMeshHit navHit = default(NavMeshHit))
|
|
{
|
|
float y = pos.y;
|
|
pos = UnityEngine.Random.insideUnitSphere * radius + pos;
|
|
pos.y = y;
|
|
if (NavMesh.SamplePosition(pos, out navHit, radius, -1))
|
|
{
|
|
return navHit.position;
|
|
}
|
|
Debug.Log("Unable to get random nav mesh position in radius! Returning old pos");
|
|
return pos;
|
|
}
|
|
|
|
public Vector3 GetRandomNavMeshPositionInBoxPredictable(Vector3 pos, float radius = 10f, NavMeshHit navHit = default(NavMeshHit), System.Random randomSeed = null, int layerMask = -1)
|
|
{
|
|
float y = pos.y;
|
|
float x = RandomNumberInRadius(radius, randomSeed);
|
|
float y2 = RandomNumberInRadius(radius, randomSeed);
|
|
float z = RandomNumberInRadius(radius, randomSeed);
|
|
pos = new Vector3(x, y2, z) + pos;
|
|
pos.y = y;
|
|
if (NavMesh.SamplePosition(pos, out navHit, radius, layerMask))
|
|
{
|
|
return navHit.position;
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
public Vector3 GetRandomPositionInBoxPredictable(Vector3 pos, float radius = 10f, System.Random randomSeed = null)
|
|
{
|
|
float x = RandomNumberInRadius(radius, randomSeed);
|
|
float y = RandomNumberInRadius(radius, randomSeed);
|
|
float z = RandomNumberInRadius(radius, randomSeed);
|
|
return new Vector3(x, y, z) + pos;
|
|
}
|
|
|
|
private float RandomNumberInRadius(float radius, System.Random randomSeed)
|
|
{
|
|
return ((float)randomSeed.NextDouble() - 0.5f) * radius;
|
|
}
|
|
|
|
public Vector3 GetRandomNavMeshPositionInRadiusSpherical(Vector3 pos, float radius = 10f, NavMeshHit navHit = default(NavMeshHit))
|
|
{
|
|
pos = UnityEngine.Random.insideUnitSphere * radius + pos;
|
|
if (NavMesh.SamplePosition(pos, out navHit, radius, -1))
|
|
{
|
|
return navHit.position;
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
public Vector3 GetRandomPositionInRadius(Vector3 pos, float minRadius, float radius, System.Random randomGen = null)
|
|
{
|
|
radius *= 2f;
|
|
return new Vector3(pos.x + RandomFloatWithinRadius(minRadius, radius, randomGen), pos.y + RandomFloatWithinRadius(minRadius, radius, randomGen), pos.z + RandomFloatWithinRadius(minRadius, radius, randomGen));
|
|
}
|
|
|
|
private float RandomFloatWithinRadius(float minValue, float radius, System.Random randomGenerator)
|
|
{
|
|
if (randomGenerator == null)
|
|
{
|
|
return UnityEngine.Random.Range(minValue, radius) * ((UnityEngine.Random.value > 0.5f) ? 1f : (-1f));
|
|
}
|
|
return (float)randomGenerator.Next((int)minValue, (int)radius) * ((randomGenerator.NextDouble() > 0.5) ? 1f : (-1f));
|
|
}
|
|
|
|
public static Vector3 AverageOfLivingGroupedPlayerPositions()
|
|
{
|
|
Vector3 zero = Vector3.zero;
|
|
for (int i = 0; i < StartOfRound.Instance.connectedPlayersAmount + 1; i++)
|
|
{
|
|
if (StartOfRound.Instance.allPlayerScripts[i].isPlayerControlled && !StartOfRound.Instance.allPlayerScripts[i].isPlayerAlone)
|
|
{
|
|
zero += StartOfRound.Instance.allPlayerScripts[i].transform.position;
|
|
}
|
|
}
|
|
return zero / (StartOfRound.Instance.connectedPlayersAmount + 1);
|
|
}
|
|
|
|
public void PlayAudibleNoise(Vector3 noisePosition, float noiseRange = 10f, float noiseLoudness = 0.5f, int timesPlayedInSameSpot = 0, bool noiseIsInsideClosedShip = false, int noiseID = 0)
|
|
{
|
|
if (noiseIsInsideClosedShip)
|
|
{
|
|
noiseRange /= 2f;
|
|
}
|
|
int num = Physics.OverlapSphereNonAlloc(noisePosition, noiseRange, noiseOverlapResults, 8912896);
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
if (!noiseOverlapResults[i].transform.TryGetComponent<INoiseListener>(out var component))
|
|
{
|
|
continue;
|
|
}
|
|
if (noiseIsInsideClosedShip)
|
|
{
|
|
EnemyAI component2 = noiseOverlapResults[i].gameObject.GetComponent<EnemyAI>();
|
|
if ((component2 == null || !component2.isInsidePlayerShip) && noiseLoudness < 0.9f)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
component.DetectNoise(noisePosition, noiseLoudness, timesPlayedInSameSpot, noiseID);
|
|
}
|
|
}
|
|
|
|
public static int PlayRandomClip(AudioSource audioSource, AudioClip[] clipsArray, bool randomize = true, float oneShotVolume = 1f)
|
|
{
|
|
if (randomize)
|
|
{
|
|
audioSource.pitch = UnityEngine.Random.Range(0.94f, 1.06f);
|
|
}
|
|
int num = UnityEngine.Random.Range(0, clipsArray.Length);
|
|
audioSource.PlayOneShot(clipsArray[num], UnityEngine.Random.Range(oneShotVolume - 0.18f, oneShotVolume));
|
|
if (audioSource.spatialBlend > 0f)
|
|
{
|
|
Instance.PlayAudibleNoise(audioSource.transform.position, 4f * oneShotVolume, oneShotVolume / 2f, 0, noiseIsInsideClosedShip: true);
|
|
}
|
|
return num;
|
|
}
|
|
|
|
public static Vector3 FindMainEntrancePosition(bool getTeleportPosition = false)
|
|
{
|
|
EntranceTeleport[] array = UnityEngine.Object.FindObjectsOfType<EntranceTeleport>(includeInactive: false);
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
if (array[i].entranceId == 0 && !array[i].isEntranceToBuilding)
|
|
{
|
|
if (getTeleportPosition)
|
|
{
|
|
return array[i].entrancePoint.position;
|
|
}
|
|
return array[i].transform.position;
|
|
}
|
|
}
|
|
Debug.Log("Main entrance position could not be found. Returning origin.");
|
|
return Vector3.zero;
|
|
}
|
|
|
|
public int GetRandomWeightedIndex(int[] weights, System.Random randomSeed = null)
|
|
{
|
|
if (randomSeed == null)
|
|
{
|
|
randomSeed = AnomalyRandom;
|
|
}
|
|
if (weights == null || weights.Length == 0)
|
|
{
|
|
Debug.Log("Could not get random weighted index; array is empty or null.");
|
|
return -1;
|
|
}
|
|
int num = 0;
|
|
for (int i = 0; i < weights.Length; i++)
|
|
{
|
|
if (weights[i] >= 0)
|
|
{
|
|
num += weights[i];
|
|
}
|
|
}
|
|
if (num <= 0)
|
|
{
|
|
return AnomalyRandom.Next(0, weights.Length);
|
|
}
|
|
float num2 = (float)AnomalyRandom.NextDouble();
|
|
float num3 = 0f;
|
|
for (int i = 0; i < weights.Length; i++)
|
|
{
|
|
if (!((float)weights[i] <= 0f))
|
|
{
|
|
num3 += (float)weights[i] / (float)num;
|
|
if (num3 >= num2)
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
Debug.LogError("Error while calculating random weighted index. Choosing randomly. Weights given:");
|
|
for (int i = 0; i < weights.Length; i++)
|
|
{
|
|
Debug.LogError($"{weights[i]},");
|
|
}
|
|
if (!hasInitializedLevelRandomSeed)
|
|
{
|
|
InitializeRandomNumberGenerators();
|
|
}
|
|
return AnomalyRandom.Next(0, weights.Length);
|
|
}
|
|
|
|
public int GetRandomWeightedIndexList(List<int> weights)
|
|
{
|
|
if (weights == null || weights.Count == 0)
|
|
{
|
|
Debug.Log("Could not get random weighted index; array is empty or null.");
|
|
return -1;
|
|
}
|
|
int num = 0;
|
|
for (int i = 0; i < weights.Count; i++)
|
|
{
|
|
if (weights[i] >= 0)
|
|
{
|
|
num += weights[i];
|
|
}
|
|
}
|
|
float value = UnityEngine.Random.value;
|
|
float num2 = 0f;
|
|
for (int i = 0; i < weights.Count; i++)
|
|
{
|
|
if (!((float)weights[i] <= 0f))
|
|
{
|
|
num2 += (float)weights[i] / (float)num;
|
|
if (num2 >= value)
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
Debug.LogError("Error while calculating random weighted index.");
|
|
Debug.Log(weights);
|
|
return -1;
|
|
}
|
|
|
|
public int GetWeightedValue(int indexLength)
|
|
{
|
|
return Mathf.Clamp(UnityEngine.Random.Range(0, indexLength * 2) - (indexLength - 1), 0, indexLength);
|
|
}
|
|
|
|
private static int SortBySize(int p1, int p2)
|
|
{
|
|
return p1.CompareTo(p2);
|
|
}
|
|
|
|
protected override void __initializeVariables()
|
|
{
|
|
base.__initializeVariables();
|
|
}
|
|
|
|
[RuntimeInitializeOnLoadMethod]
|
|
internal static void InitializeRPCS_RoundManager()
|
|
{
|
|
NetworkManager.__rpc_func_table.Add(1659269112u, __rpc_handler_1659269112);
|
|
NetworkManager.__rpc_func_table.Add(1193916134u, __rpc_handler_1193916134);
|
|
NetworkManager.__rpc_func_table.Add(192551691u, __rpc_handler_192551691);
|
|
NetworkManager.__rpc_func_table.Add(710372063u, __rpc_handler_710372063);
|
|
NetworkManager.__rpc_func_table.Add(2729232387u, __rpc_handler_2729232387);
|
|
NetworkManager.__rpc_func_table.Add(46494176u, __rpc_handler_46494176);
|
|
NetworkManager.__rpc_func_table.Add(3840785488u, __rpc_handler_3840785488);
|
|
NetworkManager.__rpc_func_table.Add(1061166170u, __rpc_handler_1061166170);
|
|
NetworkManager.__rpc_func_table.Add(1586488299u, __rpc_handler_1586488299);
|
|
NetworkManager.__rpc_func_table.Add(1145714957u, __rpc_handler_1145714957);
|
|
NetworkManager.__rpc_func_table.Add(112447504u, __rpc_handler_112447504);
|
|
NetworkManager.__rpc_func_table.Add(445397880u, __rpc_handler_445397880);
|
|
NetworkManager.__rpc_func_table.Add(3840203489u, __rpc_handler_3840203489);
|
|
}
|
|
|
|
private static void __rpc_handler_1659269112(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
|
|
{
|
|
NetworkManager networkManager = target.NetworkManager;
|
|
if ((object)networkManager != null && networkManager.IsListening)
|
|
{
|
|
reader.ReadValueSafe(out bool value, default(FastBufferWriter.ForPrimitives));
|
|
NetworkObjectReference[] value2 = null;
|
|
if (value)
|
|
{
|
|
reader.ReadValueSafe(out value2, default(FastBufferWriter.ForNetworkSerializable));
|
|
}
|
|
reader.ReadValueSafe(out bool value3, default(FastBufferWriter.ForPrimitives));
|
|
int[] value4 = null;
|
|
if (value3)
|
|
{
|
|
reader.ReadValueSafe(out value4, default(FastBufferWriter.ForPrimitives));
|
|
}
|
|
target.__rpc_exec_stage = __RpcExecStage.Client;
|
|
((RoundManager)target).SyncScrapValuesClientRpc(value2, value4);
|
|
target.__rpc_exec_stage = __RpcExecStage.None;
|
|
}
|
|
}
|
|
|
|
private static void __rpc_handler_1193916134(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
|
|
{
|
|
NetworkManager networkManager = target.NetworkManager;
|
|
if ((object)networkManager != null && networkManager.IsListening)
|
|
{
|
|
ByteUnpacker.ReadValueBitPacked(reader, out int value);
|
|
ByteUnpacker.ReadValueBitPacked(reader, out int value2);
|
|
target.__rpc_exec_stage = __RpcExecStage.Client;
|
|
((RoundManager)target).GenerateNewLevelClientRpc(value, value2);
|
|
target.__rpc_exec_stage = __RpcExecStage.None;
|
|
}
|
|
}
|
|
|
|
private static void __rpc_handler_192551691(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
|
|
{
|
|
NetworkManager networkManager = target.NetworkManager;
|
|
if ((object)networkManager != null && networkManager.IsListening)
|
|
{
|
|
ByteUnpacker.ReadValueBitPacked(reader, out ulong value);
|
|
target.__rpc_exec_stage = __RpcExecStage.Server;
|
|
((RoundManager)target).FinishedGeneratingLevelServerRpc(value);
|
|
target.__rpc_exec_stage = __RpcExecStage.None;
|
|
}
|
|
}
|
|
|
|
private static void __rpc_handler_710372063(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
|
|
{
|
|
NetworkManager networkManager = target.NetworkManager;
|
|
if ((object)networkManager == null || !networkManager.IsListening)
|
|
{
|
|
return;
|
|
}
|
|
if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
|
|
{
|
|
if (networkManager.LogLevel <= LogLevel.Normal)
|
|
{
|
|
Debug.LogError("Only the owner can invoke a ServerRpc that requires ownership!");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
target.__rpc_exec_stage = __RpcExecStage.Server;
|
|
((RoundManager)target).FinishGeneratingNewLevelServerRpc();
|
|
target.__rpc_exec_stage = __RpcExecStage.None;
|
|
}
|
|
}
|
|
|
|
private static void __rpc_handler_2729232387(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
|
|
{
|
|
NetworkManager networkManager = target.NetworkManager;
|
|
if ((object)networkManager != null && networkManager.IsListening)
|
|
{
|
|
target.__rpc_exec_stage = __RpcExecStage.Client;
|
|
((RoundManager)target).FinishGeneratingNewLevelClientRpc();
|
|
target.__rpc_exec_stage = __RpcExecStage.None;
|
|
}
|
|
}
|
|
|
|
private static void __rpc_handler_46494176(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
|
|
{
|
|
NetworkManager networkManager = target.NetworkManager;
|
|
if ((object)networkManager == null || !networkManager.IsListening)
|
|
{
|
|
return;
|
|
}
|
|
if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
|
|
{
|
|
if (networkManager.LogLevel <= LogLevel.Normal)
|
|
{
|
|
Debug.LogError("Only the owner can invoke a ServerRpc that requires ownership!");
|
|
}
|
|
return;
|
|
}
|
|
reader.ReadValueSafe(out Vector3 value);
|
|
reader.ReadValueSafe(out float value2, default(FastBufferWriter.ForPrimitives));
|
|
ByteUnpacker.ReadValueBitPacked(reader, out int value3);
|
|
target.__rpc_exec_stage = __RpcExecStage.Server;
|
|
((RoundManager)target).SpawnEnemyServerRpc(value, value2, value3);
|
|
target.__rpc_exec_stage = __RpcExecStage.None;
|
|
}
|
|
|
|
private static void __rpc_handler_3840785488(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
|
|
{
|
|
NetworkManager networkManager = target.NetworkManager;
|
|
if ((object)networkManager != null && networkManager.IsListening)
|
|
{
|
|
reader.ReadValueSafe(out NetworkObjectReference value, default(FastBufferWriter.ForNetworkSerializable));
|
|
target.__rpc_exec_stage = __RpcExecStage.Server;
|
|
((RoundManager)target).DespawnEnemyServerRpc(value);
|
|
target.__rpc_exec_stage = __RpcExecStage.None;
|
|
}
|
|
}
|
|
|
|
private static void __rpc_handler_1061166170(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
|
|
{
|
|
NetworkManager networkManager = target.NetworkManager;
|
|
if ((object)networkManager != null && networkManager.IsListening)
|
|
{
|
|
target.__rpc_exec_stage = __RpcExecStage.Client;
|
|
((RoundManager)target).PowerSwitchOnClientRpc();
|
|
target.__rpc_exec_stage = __RpcExecStage.None;
|
|
}
|
|
}
|
|
|
|
private static void __rpc_handler_1586488299(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
|
|
{
|
|
NetworkManager networkManager = target.NetworkManager;
|
|
if ((object)networkManager != null && networkManager.IsListening)
|
|
{
|
|
target.__rpc_exec_stage = __RpcExecStage.Client;
|
|
((RoundManager)target).PowerSwitchOffClientRpc();
|
|
target.__rpc_exec_stage = __RpcExecStage.None;
|
|
}
|
|
}
|
|
|
|
private static void __rpc_handler_1145714957(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
|
|
{
|
|
NetworkManager networkManager = target.NetworkManager;
|
|
if ((object)networkManager == null || !networkManager.IsListening)
|
|
{
|
|
return;
|
|
}
|
|
if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
|
|
{
|
|
if (networkManager.LogLevel <= LogLevel.Normal)
|
|
{
|
|
Debug.LogError("Only the owner can invoke a ServerRpc that requires ownership!");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
reader.ReadValueSafe(out Vector3 value);
|
|
target.__rpc_exec_stage = __RpcExecStage.Server;
|
|
((RoundManager)target).LightningStrikeServerRpc(value);
|
|
target.__rpc_exec_stage = __RpcExecStage.None;
|
|
}
|
|
}
|
|
|
|
private static void __rpc_handler_112447504(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
|
|
{
|
|
NetworkManager networkManager = target.NetworkManager;
|
|
if ((object)networkManager != null && networkManager.IsListening)
|
|
{
|
|
reader.ReadValueSafe(out Vector3 value);
|
|
target.__rpc_exec_stage = __RpcExecStage.Client;
|
|
((RoundManager)target).LightningStrikeClientRpc(value);
|
|
target.__rpc_exec_stage = __RpcExecStage.None;
|
|
}
|
|
}
|
|
|
|
private static void __rpc_handler_445397880(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
|
|
{
|
|
NetworkManager networkManager = target.NetworkManager;
|
|
if ((object)networkManager == null || !networkManager.IsListening)
|
|
{
|
|
return;
|
|
}
|
|
if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
|
|
{
|
|
if (networkManager.LogLevel <= LogLevel.Normal)
|
|
{
|
|
Debug.LogError("Only the owner can invoke a ServerRpc that requires ownership!");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
reader.ReadValueSafe(out NetworkObjectReference value, default(FastBufferWriter.ForNetworkSerializable));
|
|
reader.ReadValueSafe(out float value2, default(FastBufferWriter.ForPrimitives));
|
|
target.__rpc_exec_stage = __RpcExecStage.Server;
|
|
((RoundManager)target).ShowStaticElectricityWarningServerRpc(value, value2);
|
|
target.__rpc_exec_stage = __RpcExecStage.None;
|
|
}
|
|
}
|
|
|
|
private static void __rpc_handler_3840203489(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
|
|
{
|
|
NetworkManager networkManager = target.NetworkManager;
|
|
if ((object)networkManager != null && networkManager.IsListening)
|
|
{
|
|
reader.ReadValueSafe(out NetworkObjectReference value, default(FastBufferWriter.ForNetworkSerializable));
|
|
reader.ReadValueSafe(out float value2, default(FastBufferWriter.ForPrimitives));
|
|
target.__rpc_exec_stage = __RpcExecStage.Client;
|
|
((RoundManager)target).ShowStaticElectricityWarningClientRpc(value, value2);
|
|
target.__rpc_exec_stage = __RpcExecStage.None;
|
|
}
|
|
}
|
|
|
|
protected internal override string __getTypeName()
|
|
{
|
|
return "RoundManager";
|
|
}
|
|
}
|