private static void Prefix() { // Check mode, bail if not Anarchy or Team Anarchy. var mode = NetworkMatch.GetMode(); if (mode != MatchMode.ANARCHY && mode != MatchMode.TEAM_ANARCHY) { return; } // Bail if we have spawn points. if (MPRespawn.spawnPointDistances.Count > 0) { return; } // If enabled, get all of the item spawn points and check to see if they can be reused as player spawn points. if (MPRespawn.EnableItemSpawnsAsPlayerSpawns) { for (int i = 0; i < GameManager.m_level_data.m_item_spawn_points.Length; i++) { // TODO: Figure out how to bail when supers are involved. // if (spawn point is super) { // continue; // } var itemSpawnPoint = GameManager.m_level_data.m_item_spawn_points[i]; float largestDistance = 0f; Quaternion largestQuaternion = Quaternion.identity; for (float angle = 0f; angle < 360f; angle += 15f) { var quaternion = Quaternion.Euler(0, angle, 0); if (Physics.Raycast(itemSpawnPoint.position, quaternion * Vector3.forward, out RaycastHit hitInfo, 9999f)) { var distance = hitInfo.distance; if (distance > largestDistance) { largestDistance = distance; largestQuaternion = quaternion; } } } if (largestDistance > 20f) { MPRespawn.spawnPointsFromItems.Add(new MPRespawn.ItemSpawnPoint(i, largestQuaternion)); } } } // Generate a lookup of the distance between spawn points. var spawnPoints = new List <LevelData.SpawnPoint>(); spawnPoints.AddRange(MPRespawn.spawnPointsFromItems.Select(s => s.spawnPoint)); spawnPoints.AddRange(GameManager.m_level_data.m_player_spawn_points); foreach (var spawn1 in spawnPoints) { var position = spawn1.position; var segnum = GameManager.m_level_data.FindSegmentContainingWorldPosition(position); MPRespawn.spawnPointDistances.Add(spawn1, new Dictionary <LevelData.SpawnPoint, float>()); foreach (var spawn2 in spawnPoints) { if (spawn1 == spawn2) { continue; } var position2 = spawn2.position; var segnum2 = GameManager.m_level_data.FindSegmentContainingWorldPosition(position2); var distance = RUtility.FindVec3Distance(position - position2); MPRespawn.spawnPointDistances[spawn1].Add(spawn2, distance); } } }
public static Dictionary <LevelData.SpawnPoint, float> GetRespawnPointScores(MpTeam team, List <LevelData.SpawnPoint> candidates, bool randomness = false) { var m_player_pos = (List <Vector3>)_NetworkSpawnPoints_m_player_pos_Field.GetValue(null); var m_player_team = (List <MpTeam>)_NetworkSpawnPoints_m_player_team_Field.GetValue(null); m_player_pos.Clear(); m_player_team.Clear(); for (int i = 0; i < NetworkManager.m_Players.Count; i++) { if ((float)NetworkManager.m_Players[i].m_hitpoints > 0f && !NetworkManager.m_Players[i].m_spectator) { m_player_pos.Add(NetworkManager.m_Players[i].c_player_ship.c_transform.position); m_player_team.Add(NetworkManager.m_Players[i].m_mp_team); } } m_player_rot.Clear(); for (int i = 0; i < NetworkManager.m_Players.Count; i++) { if ((float)NetworkManager.m_Players[i].m_hitpoints > 0f && !NetworkManager.m_Players[i].m_spectator) { m_player_rot.Add(NetworkManager.m_Players[i].c_player_ship.c_transform.rotation); } } var distances = new Dictionary <LevelData.SpawnPoint, List <float> >(); var playerPositions = (List <Vector3>)_NetworkSpawnPoints_m_player_pos_Field.GetValue(null); var max = float.MinValue; for (int i = 0; i < candidates.Count; i++) { var dist = new List <float>(); var position = candidates[i].position; for (int j = 0; j < playerPositions.Count; j++) { var distance = RUtility.FindVec3Distance(position - playerPositions[j]); if (distance > max) { max = distance; } dist.Add(distance); } for (int j = 0; j < candidates.Count; j++) { if (i == j) { continue; } var distance = MPRespawn.spawnPointDistances[candidates[i]][candidates[j]]; if (distance > max) { max = distance; } } distances.Add(candidates[i], dist); } var scores = new Dictionary <LevelData.SpawnPoint, float>(); for (int i = 0; i < candidates.Count; i++) { var respawnPointScore = GetRespawnPointScore(team, candidates[i], distances[candidates[i]], max); if (randomness) { respawnPointScore *= UnityEngine.Random.Range(0.95f, 1.05f); } scores.Add(candidates[i], respawnPointScore); } return(scores); }