r2mods/ilspy_dump/ror2_csproj/WeightedSelection.cs

168 lines
2.8 KiB
C#
Raw Normal View History

2024-10-04 07:26:37 +00:00
using System;
using UnityEngine;
public class WeightedSelection<T>
{
[Serializable]
public struct ChoiceInfo
{
public T value;
public float weight;
}
[SerializeField]
[HideInInspector]
public ChoiceInfo[] choices;
[HideInInspector]
[SerializeField]
private int _count;
[SerializeField]
[HideInInspector]
private float totalWeight;
private const int minCapacity = 8;
public int Count
{
get
{
return _count;
}
private set
{
_count = value;
}
}
public int Capacity
{
get
{
return choices.Length;
}
set
{
if (value < 8 || value < Count)
{
throw new ArgumentOutOfRangeException("value");
}
ChoiceInfo[] sourceArray = choices;
choices = new ChoiceInfo[value];
Array.Copy(sourceArray, choices, Count);
}
}
public WeightedSelection(int capacity = 8)
{
choices = new ChoiceInfo[capacity];
}
public void AddChoice(T value, float weight)
{
AddChoice(new ChoiceInfo
{
value = value,
weight = weight
});
}
public void AddChoice(ChoiceInfo choice)
{
if (Count == Capacity)
{
Capacity *= 2;
}
choices[Count++] = choice;
totalWeight += choice.weight;
}
public void RemoveChoice(int choiceIndex)
{
if (choiceIndex < 0 || Count <= choiceIndex)
{
throw new ArgumentOutOfRangeException("choiceIndex");
}
int i = choiceIndex;
for (int num = Count - 1; i < num; i++)
{
choices[i] = choices[i + 1];
}
choices[--Count] = default(ChoiceInfo);
RecalculateTotalWeight();
}
public void ModifyChoiceWeight(int choiceIndex, float newWeight)
{
choices[choiceIndex].weight = newWeight;
RecalculateTotalWeight();
}
public void Clear()
{
for (int i = 0; i < Count; i++)
{
choices[i] = default(ChoiceInfo);
}
Count = 0;
totalWeight = 0f;
}
private void RecalculateTotalWeight()
{
totalWeight = 0f;
for (int i = 0; i < Count; i++)
{
totalWeight += choices[i].weight;
}
}
public T Evaluate(float normalizedIndex)
{
int num = EvaluateToChoiceIndex(normalizedIndex);
return choices[num].value;
}
public int EvaluateToChoiceIndex(float normalizedIndex)
{
return EvaluateToChoiceIndex(normalizedIndex, null);
}
public int EvaluateToChoiceIndex(float normalizedIndex, int[] ignoreIndices)
{
if (Count == 0)
{
throw new InvalidOperationException("Cannot call Evaluate without available choices.");
}
float num = totalWeight;
if (ignoreIndices != null)
{
foreach (int num2 in ignoreIndices)
{
num -= choices[num2].weight;
}
}
float num3 = normalizedIndex * num;
float num4 = 0f;
for (int j = 0; j < Count; j++)
{
if (ignoreIndices == null || Array.IndexOf(ignoreIndices, j) == -1)
{
num4 += choices[j].weight;
if (num3 < num4)
{
return j;
}
}
}
return Count - 1;
}
public ChoiceInfo GetChoice(int i)
{
return choices[i];
}
}