Files
taptap2024_GJ_chidouren/Assets/Scripts/System/RandomPool/CommonRandomPool.cs
2024-10-16 00:03:41 +08:00

409 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
}
}