2024-03-19 21:51:11 +03:00
|
|
|
using System;
|
|
|
|
using System.Collections;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
2024-03-20 00:58:47 +03:00
|
|
|
using Mirror;
|
2024-03-20 15:39:48 +03:00
|
|
|
using Unity.AI.Navigation;
|
2024-03-19 21:51:11 +03:00
|
|
|
using UnityEngine;
|
|
|
|
using UnityEngine.Serialization;
|
|
|
|
using Random = UnityEngine.Random;
|
|
|
|
|
|
|
|
namespace Level.BuildModules
|
|
|
|
{
|
2024-03-20 00:58:47 +03:00
|
|
|
public class ProceduralPrefabs : NetworkBehaviour
|
2024-03-19 21:51:11 +03:00
|
|
|
{
|
2024-03-20 18:03:21 +03:00
|
|
|
public Room[] roomPrefabs;
|
|
|
|
public Room startingRoom;
|
2024-03-19 21:51:11 +03:00
|
|
|
|
2024-03-20 21:17:05 +03:00
|
|
|
public GameObject cubePrefab;
|
|
|
|
|
2024-03-19 21:51:11 +03:00
|
|
|
private Room[,] _spawnedRooms;
|
2024-03-20 18:03:21 +03:00
|
|
|
public List<Room> flattenSpawnedRooms = new();
|
2024-03-19 21:51:11 +03:00
|
|
|
|
2024-03-20 00:58:47 +03:00
|
|
|
private int _size;
|
2024-03-19 21:51:11 +03:00
|
|
|
|
|
|
|
private int _startCellX = 0;
|
|
|
|
private int _startCellY = 0;
|
2024-03-21 18:28:37 +03:00
|
|
|
|
|
|
|
public event Action levelBuilded;
|
2024-03-20 00:58:47 +03:00
|
|
|
|
|
|
|
private CustomNetworkManager networkManager;
|
|
|
|
|
|
|
|
public GameObject enemyPrefab;
|
|
|
|
|
|
|
|
private List<Vector3> _enemySpawnPoses = new();
|
|
|
|
public List<GameObject> enemyList = new();
|
2024-03-21 18:28:37 +03:00
|
|
|
|
2024-03-20 18:03:21 +03:00
|
|
|
private IEnumerator Start()
|
2024-03-19 21:51:11 +03:00
|
|
|
{
|
2024-03-20 18:03:21 +03:00
|
|
|
if(!isServer) yield break;
|
2024-03-21 18:28:37 +03:00
|
|
|
|
|
|
|
networkManager = NetworkManager.singleton.GetComponent<CustomNetworkManager>();
|
|
|
|
|
|
|
|
levelBuilded += CheckGameStart;
|
|
|
|
|
|
|
|
while (networkManager.players.Count != networkManager.maxConnections)
|
|
|
|
{
|
|
|
|
yield return new WaitForSecondsRealtime(1f);
|
|
|
|
}
|
2024-03-20 00:58:47 +03:00
|
|
|
|
|
|
|
_size = PlayerPrefs.GetInt("LevelSize");
|
|
|
|
_spawnedRooms = new Room[_size, _size];
|
2024-03-19 21:51:11 +03:00
|
|
|
_spawnedRooms[_startCellX, _startCellY] = startingRoom;
|
|
|
|
|
2024-03-20 00:58:47 +03:00
|
|
|
for (int i = 0; i < _size; i++)
|
2024-03-19 21:51:11 +03:00
|
|
|
{
|
2024-03-20 18:03:21 +03:00
|
|
|
if (_size > 200)
|
|
|
|
{
|
|
|
|
yield return new WaitForSecondsRealtime(0.1f);
|
|
|
|
}
|
2024-03-21 18:28:37 +03:00
|
|
|
|
2024-03-19 21:51:11 +03:00
|
|
|
PlaceOneRoom();
|
|
|
|
}
|
2024-03-20 00:58:47 +03:00
|
|
|
|
2024-03-21 18:28:37 +03:00
|
|
|
yield return new WaitForSecondsRealtime(1f); //Time for good build navmesh
|
|
|
|
|
2024-03-20 18:03:21 +03:00
|
|
|
print("<---Rooms Spawned--->");
|
|
|
|
|
|
|
|
flattenSpawnedRooms[0].GetComponent<NavMeshSurface>().BuildNavMesh();
|
|
|
|
|
|
|
|
print("<---Surface builded--->");
|
2024-03-21 18:28:37 +03:00
|
|
|
|
|
|
|
yield return new WaitForSecondsRealtime(3f); //Time before start game
|
2024-03-20 18:03:21 +03:00
|
|
|
|
2024-03-21 18:28:37 +03:00
|
|
|
levelBuilded?.Invoke();
|
2024-03-20 18:03:21 +03:00
|
|
|
}
|
|
|
|
|
2024-03-21 18:28:37 +03:00
|
|
|
private void CheckGameStart()
|
2024-03-20 18:03:21 +03:00
|
|
|
{
|
2024-03-20 19:15:58 +03:00
|
|
|
if (enemyList.Count == networkManager.maxMonsters) return;
|
2024-03-21 18:28:37 +03:00
|
|
|
|
2024-03-20 00:58:47 +03:00
|
|
|
if (networkManager.players.Count == networkManager.maxConnections)
|
|
|
|
{
|
2024-03-20 21:17:05 +03:00
|
|
|
MonsterSpawn();
|
|
|
|
|
|
|
|
CubeSpawn();
|
2024-03-21 18:28:37 +03:00
|
|
|
|
|
|
|
NetworkGameManager.singleton.RpcPlaySound(GameSounds.StartSound);
|
|
|
|
|
|
|
|
print("Game started");
|
2024-03-20 00:58:47 +03:00
|
|
|
}
|
2024-03-20 21:17:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
private void CubeSpawn()
|
|
|
|
{
|
|
|
|
Vector3 pos = _enemySpawnPoses[Random.Range(0, _enemySpawnPoses.Count)];
|
|
|
|
GameObject go = Instantiate(cubePrefab, pos, Quaternion.identity);
|
|
|
|
go.GetComponent<PropBehaviour>().Original = true;
|
|
|
|
|
|
|
|
NetworkServer.Spawn(go);
|
|
|
|
enemyList.Add(go);
|
2024-03-20 18:03:21 +03:00
|
|
|
|
2024-03-20 21:17:05 +03:00
|
|
|
print("<---Cube spawned--->");
|
|
|
|
}
|
|
|
|
|
|
|
|
private void MonsterSpawn()
|
|
|
|
{
|
|
|
|
for (int i = 0; i < networkManager.maxMonsters; i++)
|
|
|
|
{
|
|
|
|
Vector3 pos = _enemySpawnPoses[Random.Range(0, _enemySpawnPoses.Count)];
|
|
|
|
GameObject go = Instantiate(enemyPrefab, pos, Quaternion.identity);
|
|
|
|
|
|
|
|
NetworkServer.Spawn(go);
|
|
|
|
enemyList.Add(go);
|
|
|
|
}
|
|
|
|
|
2024-03-20 18:03:21 +03:00
|
|
|
print("<---Monster spawned--->");
|
2024-03-19 21:51:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
private void PlaceOneRoom()
|
|
|
|
{
|
|
|
|
HashSet<Vector2Int> vacantPlaces = new HashSet<Vector2Int>();
|
|
|
|
for (int x = 0; x < _spawnedRooms.GetLength(0); x++)
|
|
|
|
{
|
|
|
|
for (int y = 0; y < _spawnedRooms.GetLength(1); y++)
|
|
|
|
{
|
|
|
|
if (_spawnedRooms[x, y] == null) continue;
|
|
|
|
|
|
|
|
AddVacantPlaceIfValid(x - 1, y, vacantPlaces);
|
|
|
|
AddVacantPlaceIfValid(x, y - 1, vacantPlaces);
|
|
|
|
AddVacantPlaceIfValid(x + 1, y, vacantPlaces);
|
|
|
|
AddVacantPlaceIfValid(x, y + 1, vacantPlaces);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-21 18:28:37 +03:00
|
|
|
Room newRoom = Instantiate(roomPrefabs[Random.Range(0, roomPrefabs.Length)], startingRoom.transform, false);
|
2024-03-20 00:58:47 +03:00
|
|
|
NetworkServer.Spawn(newRoom.gameObject);
|
2024-03-21 15:16:40 +03:00
|
|
|
|
2024-03-19 21:51:11 +03:00
|
|
|
int limit = 500;
|
|
|
|
while (limit-- > 0)
|
|
|
|
{
|
|
|
|
Vector2Int position = vacantPlaces.ElementAt(Random.Range(0, vacantPlaces.Count));
|
|
|
|
// newRoom.RotateRandomly();
|
|
|
|
|
|
|
|
if (ConnectToSomething(newRoom, position))
|
|
|
|
{
|
|
|
|
newRoom.transform.position = new Vector3(position.x - _startCellX, 0, position.y - _startCellY) * newRoom.roomSize;
|
|
|
|
_spawnedRooms[position.x, position.y] = newRoom;
|
2024-03-20 18:03:21 +03:00
|
|
|
flattenSpawnedRooms.Add(newRoom);
|
|
|
|
_enemySpawnPoses.Add(newRoom.transform.position);
|
2024-03-19 21:51:11 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-20 00:58:47 +03:00
|
|
|
NetworkServer.Destroy(newRoom.gameObject);
|
2024-03-19 21:51:11 +03:00
|
|
|
Destroy(newRoom.gameObject);
|
|
|
|
}
|
|
|
|
|
2024-03-20 00:58:47 +03:00
|
|
|
private void AddVacantPlaceIfValid(int x, int y, HashSet<Vector2Int> vacantPlaces)
|
2024-03-19 21:51:11 +03:00
|
|
|
{
|
2024-03-20 00:58:47 +03:00
|
|
|
if (x >= 0 && x < _spawnedRooms.GetLength(0) && y >= 0 && y < _spawnedRooms.GetLength(1) &&
|
|
|
|
_spawnedRooms[x, y] == null)
|
|
|
|
{
|
|
|
|
vacantPlaces.Add(new Vector2Int(x, y));
|
|
|
|
}
|
2024-03-19 21:51:11 +03:00
|
|
|
}
|
|
|
|
|
2024-03-20 00:58:47 +03:00
|
|
|
private bool ConnectToSomething(Room room, Vector2Int p)
|
|
|
|
{
|
|
|
|
List<Vector2Int> neighbours = new List<Vector2Int>();
|
2024-03-19 21:51:11 +03:00
|
|
|
|
2024-03-20 00:58:47 +03:00
|
|
|
AddNeighbourIfValid(room.DoorU, p.x, p.y + 1, Vector2Int.up, neighbours);
|
|
|
|
AddNeighbourIfValid(room.DoorD, p.x, p.y - 1, Vector2Int.down, neighbours);
|
|
|
|
AddNeighbourIfValid(room.DoorR, p.x + 1, p.y, Vector2Int.right, neighbours);
|
|
|
|
AddNeighbourIfValid(room.DoorL, p.x - 1, p.y, Vector2Int.left, neighbours);
|
|
|
|
|
|
|
|
AddNeighbourIfValid(room.DoorU2, p.x, p.y + 1, Vector2Int.up, neighbours);
|
|
|
|
AddNeighbourIfValid(room.DoorD2, p.x, p.y - 1, Vector2Int.down, neighbours);
|
|
|
|
AddNeighbourIfValid(room.DoorR2, p.x + 1, p.y, Vector2Int.right, neighbours);
|
|
|
|
AddNeighbourIfValid(room.DoorL2, p.x - 1, p.y, Vector2Int.left, neighbours);
|
|
|
|
|
|
|
|
AddNeighbourIfValid(room.DoorU3, p.x, p.y + 1, Vector2Int.up, neighbours);
|
|
|
|
AddNeighbourIfValid(room.DoorD3, p.x, p.y - 1, Vector2Int.down, neighbours);
|
|
|
|
AddNeighbourIfValid(room.DoorR3, p.x + 1, p.y, Vector2Int.right, neighbours);
|
|
|
|
AddNeighbourIfValid(room.DoorL3, p.x - 1, p.y, Vector2Int.left, neighbours);
|
2024-03-19 21:51:11 +03:00
|
|
|
|
2024-03-20 00:58:47 +03:00
|
|
|
if (neighbours.Count == 0) return false;
|
2024-03-19 21:51:11 +03:00
|
|
|
|
2024-03-20 00:58:47 +03:00
|
|
|
Vector2Int selectedDirection = neighbours[Random.Range(0, neighbours.Count)];
|
|
|
|
Room selectedRoom = _spawnedRooms[p.x + selectedDirection.x, p.y + selectedDirection.y];
|
2024-03-19 21:51:11 +03:00
|
|
|
|
2024-03-20 00:58:47 +03:00
|
|
|
DisableDoors(room, selectedRoom, selectedDirection);
|
2024-03-20 18:57:25 +03:00
|
|
|
room.Finish();
|
2024-03-19 21:51:11 +03:00
|
|
|
|
2024-03-20 00:58:47 +03:00
|
|
|
return true;
|
2024-03-19 21:51:11 +03:00
|
|
|
}
|
|
|
|
|
2024-03-20 00:58:47 +03:00
|
|
|
private void AddNeighbourIfValid(GameObject door, int x, int y, Vector2Int direction, List<Vector2Int> neighbours)
|
2024-03-19 21:51:11 +03:00
|
|
|
{
|
2024-03-20 00:58:47 +03:00
|
|
|
if (door != null && x >= 0 && x <= _spawnedRooms.GetLength(0) - 1 && y >= 0 &&
|
|
|
|
y <= _spawnedRooms.GetLength(1) - 1 && _spawnedRooms[x, y] != null)
|
2024-03-19 21:51:11 +03:00
|
|
|
{
|
2024-03-20 00:58:47 +03:00
|
|
|
neighbours.Add(direction);
|
2024-03-19 21:51:11 +03:00
|
|
|
}
|
|
|
|
}
|
2024-03-20 00:58:47 +03:00
|
|
|
|
|
|
|
private void DisableDoors(Room room, Room selectedRoom, Vector2Int direction)
|
2024-03-19 21:51:11 +03:00
|
|
|
{
|
2024-03-20 00:58:47 +03:00
|
|
|
int rand = Random.Range(1, 4);
|
|
|
|
|
|
|
|
if (direction == Vector2Int.up)
|
2024-03-19 21:51:11 +03:00
|
|
|
{
|
2024-03-20 00:58:47 +03:00
|
|
|
switch (rand)
|
|
|
|
{
|
|
|
|
case 1 :
|
2024-03-20 18:57:25 +03:00
|
|
|
room.DisableDoor(RoomDoor.U);
|
|
|
|
selectedRoom.DisableDoor(RoomDoor.D);
|
2024-03-20 00:58:47 +03:00
|
|
|
break;
|
|
|
|
case 2 :
|
2024-03-20 18:57:25 +03:00
|
|
|
room.DisableDoor(RoomDoor.U2);
|
|
|
|
selectedRoom.DisableDoor(RoomDoor.D2);
|
2024-03-20 00:58:47 +03:00
|
|
|
break;
|
|
|
|
case 3 :
|
2024-03-20 18:57:25 +03:00
|
|
|
room.DisableDoor(RoomDoor.U3);
|
|
|
|
selectedRoom.DisableDoor(RoomDoor.D3);
|
2024-03-20 00:58:47 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2024-03-19 21:51:11 +03:00
|
|
|
}
|
2024-03-20 00:58:47 +03:00
|
|
|
else if (direction == Vector2Int.down)
|
2024-03-19 21:51:11 +03:00
|
|
|
{
|
2024-03-20 00:58:47 +03:00
|
|
|
switch (rand)
|
|
|
|
{
|
|
|
|
case 1 :
|
2024-03-20 18:57:25 +03:00
|
|
|
room.DisableDoor(RoomDoor.D);
|
|
|
|
selectedRoom.DisableDoor(RoomDoor.U);
|
2024-03-20 00:58:47 +03:00
|
|
|
break;
|
|
|
|
case 2 :
|
2024-03-20 18:57:25 +03:00
|
|
|
room.DisableDoor(RoomDoor.D2);
|
|
|
|
selectedRoom.DisableDoor(RoomDoor.U2);
|
2024-03-20 00:58:47 +03:00
|
|
|
break;
|
|
|
|
case 3 :
|
2024-03-20 18:57:25 +03:00
|
|
|
room.DisableDoor(RoomDoor.D3);
|
|
|
|
selectedRoom.DisableDoor(RoomDoor.U3);
|
2024-03-20 00:58:47 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2024-03-19 21:51:11 +03:00
|
|
|
}
|
2024-03-20 00:58:47 +03:00
|
|
|
else if (direction == Vector2Int.right)
|
|
|
|
{
|
|
|
|
switch (rand)
|
|
|
|
{
|
|
|
|
case 1 :
|
2024-03-20 18:57:25 +03:00
|
|
|
room.DisableDoor(RoomDoor.R);
|
|
|
|
selectedRoom.DisableDoor(RoomDoor.L);
|
2024-03-20 00:58:47 +03:00
|
|
|
break;
|
|
|
|
case 2 :
|
2024-03-20 18:57:25 +03:00
|
|
|
room.DisableDoor(RoomDoor.R2);
|
|
|
|
selectedRoom.DisableDoor(RoomDoor.L2);
|
2024-03-20 00:58:47 +03:00
|
|
|
break;
|
|
|
|
case 3 :
|
2024-03-20 18:57:25 +03:00
|
|
|
room.DisableDoor(RoomDoor.R3);
|
|
|
|
selectedRoom.DisableDoor(RoomDoor.L3);
|
2024-03-20 00:58:47 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (direction == Vector2Int.left)
|
2024-03-19 21:51:11 +03:00
|
|
|
{
|
2024-03-20 00:58:47 +03:00
|
|
|
switch (rand)
|
|
|
|
{
|
|
|
|
case 1 :
|
2024-03-20 18:57:25 +03:00
|
|
|
room.DisableDoor(RoomDoor.L);
|
|
|
|
selectedRoom.DisableDoor(RoomDoor.R);
|
2024-03-20 00:58:47 +03:00
|
|
|
break;
|
|
|
|
case 2 :
|
2024-03-20 18:57:25 +03:00
|
|
|
room.DisableDoor(RoomDoor.L2);
|
|
|
|
selectedRoom.DisableDoor(RoomDoor.R2);
|
2024-03-20 00:58:47 +03:00
|
|
|
break;
|
|
|
|
case 3 :
|
2024-03-20 18:57:25 +03:00
|
|
|
room.DisableDoor(RoomDoor.L3);
|
|
|
|
selectedRoom.DisableDoor(RoomDoor.R3);
|
2024-03-20 00:58:47 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2024-03-19 21:51:11 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|