Files
taptap2024_GJ_chidouren/Assets/Scripts/System/RandomPool/CommonRandomPool.cs

409 lines
14 KiB
C#
Raw Normal View History

2024-10-16 00:03:41 +08:00
using System;
using System.Collections.Generic;
using System.RandomPool;
using Game;
using UnityEngine;
namespace Game.Data
{
/// <summary>
/// 通用随机池,基于权重随机
/// </summary>
public class CommonRandomPool<T> where T : class
{
protected Dictionary<int, CommonRandomGroup<T>> _randomGroups;
protected LevelRandom _levelRandom;
protected int _poolId;
protected int _seedId;
public LevelRandom LevelRandom => this._levelRandom;
public int ValidRofCount
{
get
{
int count = 0;
foreach (var randomGroupsValue in _randomGroups.Values)
{
count += randomGroupsValue.ValidRofCount;
}
return count;
}
}
public CommonRandomPool(CommonPoolConfig<T> config, int poolId, int seedId)
{
this._poolId = poolId;
this._seedId = seedId;
this._randomGroups = new Dictionary<int, CommonRandomGroup<T>>();
foreach (var contentsKey in config.poolContents.Keys)
{
var nodes = config.poolContents[contentsKey];
CommonRandomGroup<T> randomGroup = config.CreateGroup(this._poolId);
foreach (var node in nodes)
{
randomGroup.PutItem(node);
}
this._randomGroups[contentsKey] = randomGroup;
}
foreach (var groupsValue in this._randomGroups.Values)
{
groupsValue?.SetMask(-1);
}
this._levelRandom = new LevelRandom(config.poolLevelWeight , new List<int>(this._randomGroups.Keys));
}
public void PutNode(RandomNode<T> node , int quality)
{
if (_randomGroups.ContainsKey(quality))
{
var commonRandomGroup = _randomGroups[quality];
commonRandomGroup.PutItem(node);
commonRandomGroup.SetMask(-1);
}
}
public RandomNode<T> GetNode(int key , int quality)
{
if (_randomGroups.ContainsKey(quality))
{
var commonRandomGroup = _randomGroups[quality];
return commonRandomGroup.GetItem(key);
}
return null;
}
public void ResetNodeWeight(int quality ,int key , int weight)
{
if (this._randomGroups.TryGetValue (quality, out var commonRandomGroup))
{
commonRandomGroup.ResetItemWeight (key , weight);
commonRandomGroup.SetMask (-1);
}
}
public void ResetQualityWeight(int quality , int weight)
{
this._levelRandom.SetWeight (quality , weight);
}
public void PutNodes(List<RandomNode<T>> nodes , int quality)
{
if (this._randomGroups.TryGetValue (quality, out var commonRandomGroup))
{
foreach (var node in nodes)
{
commonRandomGroup.PutItem(node);
}
commonRandomGroup.SetMask(-1);
}
}
//回收随机节点
public void PullNode(int key , int quality)
{
if (_randomGroups.ContainsKey(quality))
{
var commonRandomGroup = _randomGroups[quality];
commonRandomGroup.PullItem(key);
commonRandomGroup.SetMask(-1);
}
}
public void RemoveNode(int key , int quality)
{
if (_randomGroups.ContainsKey(quality))
{
var commonRandomGroup = _randomGroups[quality];
commonRandomGroup.RemoveItem(key);
commonRandomGroup.SetMask(-1);
}
}
public void RemoveNode(int key)
{
foreach (int itemQuality in Enum.GetValues(typeof(int)))
{
RemoveNode(key , itemQuality);
}
}
public List<T> RandomItems(int maskCount, int count, bool isSign = false , object customMask = null )
{
List<T> nodes = new List<T>();
List<int> disableList = new List<int>();
for (int i = 0; i < count; i++)
{
var node = this.RandomNode(maskCount, disableList , customMask);
if (node != null)
{
nodes.Add(node.value);
if (isSign)
{
disableList.Add(node.key);
}
}
}
return nodes;
}
public List<T> RandomItems(int maskCount, int count, bool isSign, IList<int> qualities, IList<int> disableKeys , object customMask = null)
{
List<T> nodes = new List<T>();
List<int> disableList = new List<int>();
if (disableKeys != null)
{
disableList.AddRange(disableKeys);
}
for (int i = 0; i < count; i++)
{
RandomNode<T> node = null;
if (qualities?.Count > i)
{
node = this.RandomNode(maskCount, qualities[i], disableList , customMask);
}
if (node == null)
{
node = this.RandomNode(maskCount, disableList , customMask);
}
if (node != null)
{
nodes.Add(node.value);
if (isSign)
{
disableList.Add(node.key);
}
}
}
return nodes;
}
/// <summary>
/// 指定稀有度安全随机一个物品,如果指定稀有度没有满足条件,则递减一个稀有度重新随机,直到正确数据出一个物品,也可能会出现所有稀有度都无法满足条件,返回空
/// </summary>
/// <param name="maskCount"></param>
/// <param name="quality"></param>
/// <param name="disableKeys"></param>
/// <param name="customMask"></param>
/// <returns></returns>
public T RandomItem(int maskCount, int quality, IList<int> disableKeys = null, object customMask = null)
{
var maxCount = 10;
var levelMasks = new List<int>();
foreach (var groupsKey in this._randomGroups.Keys)
{
if (!this._randomGroups[groupsKey].SetMask(maskCount, disableKeys , customMask))
{
levelMasks.Add(groupsKey);
}
}
for (int i = (int)quality; i >= 0; i--)
{
var level = (int)i;
if (!levelMasks.Contains(level) && this._randomGroups.ContainsKey(level) && this._randomGroups[level].ValidRofCount > 0)
{
while (maxCount-- > 0)
{
var node = this._randomGroups[level].RandomItem(this._poolId, this._seedId);
if (node == null)
{
continue;
}
return node;
}
}
}
Debug.LogError($"随机条件不满足 poolId:{this._poolId} maskID: {maskCount}");
return null;
}
public T RandomItem(int maskCount, IList<int> disableKeys = null, object customMask = null)
{
var maxCount = 10;
var levelMasks = new List<int>();
foreach (var groupsKey in this._randomGroups.Keys)
{
if (!this._randomGroups[groupsKey].SetMask(maskCount, disableKeys , customMask))
{
levelMasks.Add(groupsKey);
}
}
var level = this._levelRandom.RandomItemLevel(this._seedId, levelMasks);
if (this._randomGroups.ContainsKey(level) && this._randomGroups[level].ValidRofCount > 0)
{
while (maxCount-- > 0)
{
var node = this._randomGroups[level].RandomItem(this._poolId, this._seedId);
if (node == null)
{
continue;
}
return node;
}
}
Debug.LogError($"随机条件不满足 poolId:{this._poolId} maskID: {maskCount}");
return null;
}
/// <summary>
/// 随机一组有效的稀有度数据,用于后续随机
/// </summary>
/// <param name="count">数据长度</param>
/// <param name="maxQuality">最大稀有度限制</param>
/// <param name="qualities">期望能出现的稀有度</param>
/// <param name="randomGroup"></param>
/// <returns></returns>
public List<int> CustomRandomQuality(int count,
int maxQuality,
IList<int> qualities = null , int randomGroup = 0)
{
List<int> finalQualities = new List<int>();
if (qualities != null)
{
finalQualities.AddRange(qualities);
}
List<int> levelMasks = new List<int>();
bool isTr = false;
foreach (int value in Enum.GetValues(typeof(int)))
{
if (isTr)
levelMasks.Add(value);
else
isTr = value == maxQuality;
}
for (int i = finalQualities.Count; i < count; i++)
{
finalQualities.Add(this.LevelRandom.RandomItemLevel((int) randomGroup, levelMasks));
}
return finalQualities;
}
/// <summary>
/// 随机一个指定稀有度的节点
/// </summary>
/// <param name="maskCount"></param>
/// <param name="quality"></param>
/// <param name="disableKeys"></param>
/// <param name="customMask"></param>
/// <returns></returns>
public RandomNode<T> RandomNode(int maskCount, int quality, IList<int> disableKeys = null , object customMask = null)
{
if (this._randomGroups.ContainsKey(quality))
{
if (this._randomGroups[quality].SetMask(maskCount, disableKeys , customMask))
{
return this._randomGroups[quality].RandomNode(this._poolId, this._seedId);
}
}
return null;
}
public RandomNode<T> RandomNode(int maskCount, List<int> qualities, IList<int> disableKeys = null , object customMask = null)
{
var levelMasks = new List<int>();
foreach (var groupsKey in this._randomGroups.Keys)
{
if (!qualities.Contains(groupsKey) || !this._randomGroups[groupsKey].SetMask(maskCount, disableKeys , customMask))
{
levelMasks.Add(groupsKey);
}
}
var level = this._levelRandom.RandomItemLevel(this._seedId, levelMasks);
if (this._randomGroups.ContainsKey(level) && this._randomGroups[level].ValidRofCount > 0)
{
return this._randomGroups[level].RandomNode(this._poolId, this._seedId);
}
return null;
}
public RandomNode<T> RandomNode(int maskCount, IList<int> disableKeys = null, object customMask = null)
{
var maxCount = 10;
var levelMasks = new List<int>();
foreach (var groupsKey in this._randomGroups.Keys)
{
if (!this._randomGroups[groupsKey].SetMask(maskCount, disableKeys , customMask))
{
levelMasks.Add(groupsKey);
}
}
var level = this._levelRandom.RandomItemLevel(this._seedId, levelMasks);
if (this._randomGroups.ContainsKey(level) && this._randomGroups[level].ValidRofCount > 0)
{
while (maxCount-- > 0)
{
var node = this._randomGroups[level].RandomNode(this._poolId, this._seedId);
if (node == null)
{
continue;
}
return node;
}
}
Debug.LogError($"随机条件不满足 poolId:{this._poolId} maskID: {maskCount}");
return null;
}
/// <summary>
/// 获取该随机池中当前指定稀有度下的有效数
/// </summary>
/// <param name="quality"></param>
/// <param name="maskCount"></param>
/// <param name="disableKeys"></param>
/// <param name="customMask"></param>
/// <returns></returns>
public int GetPoolValidCount(int quality, int maskCount , IList<int> disableKeys = null, object customMask = null)
{
if (this._randomGroups.ContainsKey(quality))
{
if (this._randomGroups[quality].SetMask(maskCount , disableKeys , customMask))
{
return this._randomGroups[quality].ValidRofCount;
}
}
return 0;
}
/// <summary>
/// 获取该随机池中当前总共的有效数
/// </summary>
/// <param name="maskCount"></param>
/// <param name="disableKeys"></param>
/// <param name="customMask"></param>
/// <returns></returns>
public int GetPoolValidCount(int maskCount , IList<int> disableKeys = null, object customMask = null)
{
int count = 0;
foreach (var groupsKey in this._randomGroups.Keys)
{
var randomGroup = this._randomGroups[groupsKey];
if (!randomGroup.SetMask(maskCount, disableKeys , customMask))
{
count += randomGroup.ValidRofCount;
}
}
return count;
}
}
}