Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using MaoUtility.DILocator.Atr;
- using MaoUtility.MaoExts;
- using RoomsSystem.RoomAndPart;
- using Sirenix.OdinInspector;
- using Sirenix.Utilities;
- using UnityEngine;
- using Random = UnityEngine.Random;
- namespace RoomsSystem
- {
- [DiMark]
- public class EndlessGenerateRoom : MonoBehaviour
- {
- [DiInject] private RoomFactory roomFactory;
- [SerializeField, Min(1)] private int _maxCountRoomByCenter;
- [SerializeField] private Room[] _prefabs;
- [SerializeField] private bool _logInfo;
- public Room Center => _center;
- [SerializeField]private Room _center;
- private HashSet<Room> _rooms;
- private RoomEntity _trackEntity;
- private int _seed;
- [ShowInInspector, ReadOnly]private Dictionary<int, DataRoom> _dataRoomsBySeed;
- private void Start()
- {
- _rooms=new HashSet<Room>();
- _dataRoomsBySeed = new Dictionary<int, DataRoom>();
- }
- public void Init(RoomEntity entity, int? seed = null)
- {
- if (!entity.IsPlayer)
- {
- Debug.LogError("Попытка иницилизировать генератор не игроком");
- return;
- }
- ClearAll();
- _trackEntity = entity;
- _seed = seed != null ? seed.Value : Random.Range(int.MinValue, int.MaxValue);
- _trackEntity.EnterRoom += OnEnterRoom;
- UpdateRoomByCurrent();
- var point = Center.GetPart<PointForPlayer>();
- if (!point) Debug.LogWarning($"У этой комнаты (клик по мне), не точки для игрока", Center);
- else point.SetPlayerPos(entity);
- }
- [Button]
- public void UpdateRoomByCurrent()
- {
- if(_center==null) SpawnFirst(_prefabs.GetRandom());
- HashSet<Room> chekedRooms = new HashSet<Room>();
- HashSet<Room> roomOnCheck = new HashSet<Room>() {Center};
- int radius = 0;
- while (roomOnCheck.Count>0 && radius<_maxCountRoomByCenter)
- {
- HashSet<Room> newRoomSet = new HashSet<Room>();
- if(radius<_maxCountRoomByCenter)
- roomOnCheck.ForEach(room =>
- {
- chekedRooms.Add(room);
- room.ConnectRooms.ForEach(connect =>
- {
- if (connect.Link) return;
- if (_dataRoomsBySeed.ContainsKey(SeedRoom(room)))
- {
- var data = _dataRoomsBySeed[SeedRoom(room)];
- var connectData = data.Points.FirstOrDefault(x => x.SelfGuid == connect.GUID);
- if (connectData != null && connectData.IsValid()) SpawnByConnectData(connect, connectData);
- else RndSpawn();
- }
- else
- {
- RndSpawn();
- }
- void RndSpawn()
- {
- var rnd = GetRandByPoint(connect);
- var prefab = _prefabs[rnd.Next(0, _prefabs.Length)];
- SpawnWithConnect(connect, prefab, ()=>rnd.Next(0, prefab.ConnectRooms.Count));
- }
- });
- room.ConnectRooms.ForEach(connect =>
- {
- if(connect.Link)
- if (!chekedRooms.Contains(connect.Link.Room)) newRoomSet.Add(connect.Link.Room);
- });
- });
- roomOnCheck = newRoomSet;
- radius++;
- }
- roomOnCheck.ForEach(x => chekedRooms.Add(x));
- var collectToDelete = _rooms.Except(chekedRooms);
- _rooms = _rooms.Except(collectToDelete).ToHashSet();
- collectToDelete.ForEach(x => roomFactory.DeleteRoom(x));
- }
- private void SpawnByConnectData(ConnectPointRoom connect, PointConnectData connectData)
- {
- var roomdata = _dataRoomsBySeed[connectData.SeedConnectRoom.Value];
- var prefab = _prefabs.First(x => x.GUID == roomdata.Guid);
- var pointConnect = prefab.ConnectRooms.First(x => x.GUID == connectData.GuidPointConnect);
- SpawnWithConnect(connect, prefab, ()=>prefab.ConnectRooms.ToList().IndexOf(pointConnect));
- }
- private System.Random GetRandByPoint(ConnectPointRoom connect)
- {
- var seed = SeedPoint(connect);
- return new System.Random(seed);
- }
- [Button]
- private void SpawnWithConnect(ConnectPointRoom connectPointRoom, Room prefab, Func<int> getIndex)
- {
- //замена рандома
- int index = getIndex();
- var poinNewRoom = prefab.ConnectRooms.ToArray()[index];
- var transPos = connectPointRoom.GetTransformValue(poinNewRoom);
- if (roomFactory.CheckExistCreate(prefab, transPos.pos, transPos.rotate))
- {
- var r = roomFactory.CreateRoom(prefab, transPos.pos, transPos.rotate);
- r.transform.SetParent(transform);
- var newPoint = r.ConnectRooms.ToArray()[index];
- connectPointRoom.Connect(newPoint);
- _rooms.Add(r);
- _dataRoomsBySeed.TryAdd(SeedRoom(r), new DataRoom(r, this));
- InitDataConnect(connectPointRoom);
- InitDataConnect(newPoint);
- }
- else
- {
- if(_logInfo) Debug.Log("Нельзя создать комнату.");
- }
- void InitDataConnect(ConnectPointRoom first)
- => _dataRoomsBySeed[SeedRoom(first.Room)].Points.First(x=>x.SelfGuid==first.GUID).Init(first);
- }
- private void SpawnFirst(Room prefab)
- {
- _center = roomFactory.CreateRoom(prefab, Vector3.zero, Vector3.zero).With(x => x.transform.SetParent(transform));
- _dataRoomsBySeed.Add(SeedRoom(_center), new DataRoom(_center, this));
- _rooms.Add(_center);
- }
- private int SeedRoom(Room room)
- => _seed + (int)room.transform.position.x + (int)room.transform.position.y + (int)room.transform.position.z;
- private int SeedPoint(ConnectPointRoom point)
- => _seed + (int)point.transform.position.x + (int)point.transform.position.y + (int)point.transform.position.z;
- public void ClearAll()
- {
- _rooms.ForEach(x => roomFactory.DeleteRoom(x));
- _rooms.Clear();
- if (_trackEntity)
- {
- _trackEntity.EnterRoom += OnEnterRoom;
- }
- _trackEntity = null;
- }
- private void OnEnterRoom(Room obj)
- {
- if(obj==Center) return;
- _center = obj;
- UpdateRoomByCurrent();
- }
- [System.Serializable]
- private class DataRoom
- {
- [ShowInInspector]public int Seed { get; private set; }
- [ShowInInspector]public string Guid { get; private set; }
- public PointConnectData[] Points;
- public DataRoom(Room room, EndlessGenerateRoom generator)
- {
- Guid = room.GUID;
- Seed = generator.SeedRoom(room);
- Points = new PointConnectData[room.ConnectRooms.Count];
- int count = 0;
- room.ConnectRooms.ForEach(x =>
- {
- Points[count] = new PointConnectData(x, generator);
- count++;
- });
- }
- }
- [System.Serializable]
- private class PointConnectData
- {
- private EndlessGenerateRoom _gen;
- [ShowInInspector]public string SelfGuid { get; private set; }
- [ShowInInspector]public int? SeedConnectRoom { get; private set; }
- [ShowInInspector]public string GuidPointConnect { get; private set; }
- public PointConnectData(ConnectPointRoom point, EndlessGenerateRoom generator)
- {
- SelfGuid = point.GUID;
- SeedConnectRoom = null;
- GuidPointConnect = null;
- _gen = generator;
- }
- public void Init(ConnectPointRoom otherPoint)
- {
- if (!otherPoint.Link) return;
- if (IsValid()) return;
- GuidPointConnect = otherPoint.Link.GUID;
- SeedConnectRoom = _gen.SeedRoom(otherPoint.Link.Room);
- }
- public bool IsValid() => SeedConnectRoom != null && !string.IsNullOrWhiteSpace(GuidPointConnect);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement