using System; using System.Collections.Generic; using System.Linq; using Moonlit.Utils; using UnityEngine; namespace Moonlit.IceFishing { internal class HolesController : Singleton { [Serializable] public enum HitResult { Occupied = 0, Terrain = 1, Unoccupied = 2 } [Serializable] public class HitInfo { public HitResult Result = HitResult.Unoccupied; public List FoundHoles; } [Serializable] private class SaveData { public List holes = new List(); } [Header("Hole")] public GameObject HolePrefab; [SerializeField] private GameObject _HolesParent; public Material iceMaterial; [Header("Random snow to draw")] [SerializeField] private List _DrilledSnowList; [Header("Settings")] public float MinWaterDepth = 1f; public float WaterRaiseTime = 0.2f; public int MaxHoleCount = 100; private string _HoleTag = "Hole"; private string _TerrainTag = "Terrain"; private string _IceTag = "Ice"; private List _Pool = new List(); public string HoleTag { get { return _HoleTag; } } public string TerrainTag { get { return _TerrainTag; } } public string IceTag { get { return _IceTag; } } public string Save() { SaveData saveData = new SaveData(); saveData.holes = (from x in _Pool select x.Data into x where x.IsFinished select x).ToList(); string text = JsonUtility.ToJson(saveData, true); if (string.IsNullOrEmpty(text)) { Debug.LogError("Save data is empty!"); return null; } return text; } public void Load(string saveJson) { RemoveAll(); SaveData saveData = JsonUtility.FromJson(saveJson); for (int i = 0; i < saveData.holes.Count; i++) { Create(saveData.holes[i]); } } public Hole Create(HoleData data) { Hole hole = null; GameObject gameObject = null; if (MaxHoleCount >= 0) { while (_Pool.Count > MaxHoleCount) { UnityEngine.Object.Destroy(_Pool.First().gameObject); _Pool.RemoveAt(0); } if (_Pool.Count == MaxHoleCount) { hole = _Pool.First(); _Pool.RemoveAt(0); gameObject = hole.gameObject; _Pool.Add(hole); } else { gameObject = UnityEngine.Object.Instantiate(HolePrefab, data.Position, Quaternion.identity); gameObject.transform.parent = base.transform; gameObject.name = "Hole"; hole = gameObject.GetComponent(); _Pool.Add(hole); } } hole.Set(data); return hole; } public void Remove(Hole hole) { UnityEngine.Object.Destroy(hole.gameObject); _Pool.Remove(hole); } public void RemoveAll() { foreach (Hole item in _Pool) { UnityEngine.Object.Destroy(item.gameObject); } _Pool.Clear(); } public HitInfo HitCheck(Vector3 position, float radius) { HitInfo hitInfo = new HitInfo(); hitInfo.Result = HitResult.Unoccupied; Vector3 point = position - Vector3.up * Singleton.Instance.MinWaterDepth; Vector3 point2 = position + Vector3.up * 1f; RaycastHit[] source = Physics.CapsuleCastAll(point, point2, radius, Vector3.up); List list = source.Where((RaycastHit x) => x.collider.CompareTag(_HoleTag)).ToList(); if (list.Count > 0) { hitInfo.FoundHoles = list.Select((RaycastHit x) => x.collider.GetComponent()).ToList(); hitInfo.Result = HitResult.Occupied; return hitInfo; } List list2 = source.Where((RaycastHit x) => x.collider.CompareTag(_TerrainTag)).ToList(); List list3 = source.Where((RaycastHit x) => x.collider.gameObject.layer == LayerMask.NameToLayer("Default") || x.collider.gameObject.layer == LayerMask.NameToLayer("Terrain")).ToList(); if (list2.Count > 0 || list3.Count > 0) { hitInfo.Result = HitResult.Terrain; } return hitInfo; } public Vector3 FindIcePosition(Vector3 point) { RaycastHit[] source = (from x in Physics.RaycastAll(point, Vector3.down) where x.collider.CompareTag(_IceTag) select x).ToArray(); if (source.Count() != 0) { point.y = source.Max((RaycastHit x) => x.point.y); return point; } source = (from x in Physics.RaycastAll(point, Vector3.up) where x.collider.CompareTag(_IceTag) select x).ToArray(); if (source.Count() != 0) { point.y = source.Max((RaycastHit x) => x.point.y); return point; } return Vector3.zero; } public float GetIceThickness(Vector3 point) { float num = Math.Abs((Mathf.Sin((point.x + point.y + point.x * point.y) * 0.1f) + 1f) * 0.2f + 0.4f); num = 0.6f; Debug.Log("Ice Thickness: " + num); return num; } public GameObject GetRandomSnowPrefab() { return _DrilledSnowList[UnityEngine.Random.Range(0, _DrilledSnowList.Count)]; } } }