Files
UltimateFishing/Assets/Scripts/Assembly-CSharp/UltimateWater/Internal/WaterSystem.cs
2026-02-21 16:45:37 +08:00

177 lines
4.3 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
namespace UltimateWater.Internal
{
public sealed class WaterSystem : ApplicationSingleton<WaterSystem>
{
private readonly List<Water> _Waters = new List<Water>();
private readonly List<Water> _BoundlessWaters = new List<Water>();
private static readonly List<Water> _PossibleWaters = new List<Water>();
private static readonly List<Water> _ExcludedWaters = new List<Water>();
private static readonly Collider[] _CollidersBuffer = new Collider[30];
private static int _CurrentId = 1;
private static readonly List<int> _FreeIds = new List<int>();
public List<Water> Waters
{
get
{
return _Waters;
}
}
public List<Water> BoundlessWaters
{
get
{
return _BoundlessWaters;
}
}
public event Action OnQuit;
public static bool IsWaterPossiblyVisible()
{
WaterSystem instance = ApplicationSingleton<WaterSystem>.Instance;
if (instance == null)
{
return false;
}
return instance.Waters.Count != 0;
}
public static void Register(Water water)
{
RequestId(water);
WaterSystem instance = ApplicationSingleton<WaterSystem>.Instance;
if (!(instance == null))
{
if (!instance._Waters.Contains(water))
{
instance._Waters.Add(water);
}
if ((water.Volume == null || water.Volume.Boundless) && !instance._BoundlessWaters.Contains(water))
{
instance._BoundlessWaters.Add(water);
}
}
}
public static void Unregister(Water water)
{
FreeId(water);
WaterSystem instance = ApplicationSingleton<WaterSystem>.Instance;
if (!(instance == null))
{
instance._Waters.Remove(water);
instance._BoundlessWaters.Remove(water);
}
}
public static Water FindWater(Vector3 position, float radius)
{
bool isInsideSubtractiveVolume;
bool isInsideAdditiveVolume;
return FindWater(position, radius, null, out isInsideSubtractiveVolume, out isInsideAdditiveVolume);
}
public static Water FindWater(Vector3 position, float radius, out bool isInsideSubtractiveVolume, out bool isInsideAdditiveVolume)
{
return FindWater(position, radius, null, out isInsideSubtractiveVolume, out isInsideAdditiveVolume);
}
public static Water FindWater(Vector3 position, float radius, List<Water> allowedWaters, out bool isInsideSubtractiveVolume, out bool isInsideAdditiveVolume)
{
isInsideSubtractiveVolume = false;
isInsideAdditiveVolume = false;
int num = Physics.OverlapSphereNonAlloc(position, radius, _CollidersBuffer, 1 << WaterProjectSettings.Instance.WaterCollidersLayer, QueryTriggerInteraction.Collide);
_PossibleWaters.Clear();
_ExcludedWaters.Clear();
for (int i = 0; i < num; i++)
{
WaterVolumeBase waterVolume = WaterVolumeBase.GetWaterVolume(_CollidersBuffer[i]);
if (!(waterVolume != null))
{
continue;
}
if (waterVolume is WaterVolumeAdd)
{
isInsideAdditiveVolume = true;
if (allowedWaters == null || allowedWaters.Contains(waterVolume.Water))
{
_PossibleWaters.Add(waterVolume.Water);
}
}
else
{
isInsideSubtractiveVolume = true;
_ExcludedWaters.Add(waterVolume.Water);
}
}
for (int j = 0; j < _PossibleWaters.Count; j++)
{
if (!_ExcludedWaters.Contains(_PossibleWaters[j]))
{
return _PossibleWaters[j];
}
}
List<Water> boundlessWaters = ApplicationSingleton<WaterSystem>.Instance.BoundlessWaters;
int count = boundlessWaters.Count;
for (int k = 0; k < count; k++)
{
Water water = boundlessWaters[k];
if ((allowedWaters == null || allowedWaters.Contains(water)) && water.Volume.IsPointInsideMainVolume(position, radius) && !_ExcludedWaters.Contains(water))
{
return water;
}
}
return null;
}
protected override void OnDestroy()
{
if (this.OnQuit != null)
{
this.OnQuit();
}
base.OnDestroy();
}
private static bool RequestId(Water water)
{
if (water._WaterId != -1)
{
return false;
}
if (_FreeIds.Count == 0)
{
water._WaterId = _CurrentId++;
}
else
{
int index = _FreeIds.Count - 1;
water._WaterId = _FreeIds[index];
_FreeIds.RemoveAt(index);
}
return true;
}
private static void FreeId(Water water)
{
if (water._WaterId != -1)
{
_FreeIds.Add(water._WaterId);
water._WaterId = -1;
}
}
}
}