S4-07 process 3
- 组件 Tag 数量预算不再写死在 ResolveTagBudget(...) 里,而是走 RarityTagBudget.txt -> DRRarityTagBudget -> RarityTagBudgetRuleRegistry -> InventoryTagRuleService 这条表驱动链。 - TagBudget.txt:1 新增了按品质的 MinCount/MaxCount,预算缓存和加载入口分别在 RarityTagBudgetRuleRegistry.cs:7 和 ProcedurePreload.cs:18。 - 生成逻辑已经接到新规则,InventoryTagRuleService.cs:10 现在会先按 Tag.txt 过滤/加权,再按 RarityTagBudget 决定抽几个 Tag。
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
using GeometryTD.CustomUtility;
|
||||
using GeometryTD.Definition;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace GeometryTD.DataTable
|
||||
{
|
||||
public sealed class DRRarityTagBudget : DataRowBase
|
||||
{
|
||||
private int m_Id;
|
||||
|
||||
public override int Id => m_Id;
|
||||
|
||||
public RarityType Rarity { get; private set; }
|
||||
|
||||
public int MinCount { get; private set; }
|
||||
|
||||
public int MaxCount { get; private set; }
|
||||
|
||||
public override bool ParseDataRow(string dataRowString, object userData)
|
||||
{
|
||||
string[] columnStrings = dataRowString.Split(DataTableExtension.DataSplitSeparators);
|
||||
for (int i = 0; i < columnStrings.Length; i++)
|
||||
{
|
||||
columnStrings[i] = columnStrings[i].Trim(DataTableExtension.DataTrimSeparators);
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
index++;
|
||||
m_Id = int.Parse(columnStrings[index++]);
|
||||
index++;
|
||||
Rarity = EnumUtility<RarityType>.Get(columnStrings[index++]);
|
||||
MinCount = int.Parse(columnStrings[index++]);
|
||||
MaxCount = int.Parse(columnStrings[index++]);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5e6052cd3fe424d8b6ac53c33c063c5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -13,7 +13,8 @@ namespace GeometryTD.Definition
|
||||
InventoryTagSourceType sourceType,
|
||||
long itemInstanceId,
|
||||
int configId,
|
||||
IReadOnlyDictionary<TagType, TagGenerationRuleData> rulesByTag = null)
|
||||
IReadOnlyDictionary<TagType, TagGenerationRuleData> rulesByTag = null,
|
||||
IReadOnlyDictionary<RarityType, RarityTagBudgetRuleData> rarityTagBudgetRulesByRarity = null)
|
||||
{
|
||||
IReadOnlyDictionary<TagType, TagGenerationRuleData> ruleLookup = rulesByTag ?? TagGenerationRuleRegistry.Rules;
|
||||
TagType[] eligibleTags = GetEligibleTags(possibleTags, rarity, ruleLookup);
|
||||
@@ -23,7 +24,7 @@ namespace GeometryTD.Definition
|
||||
}
|
||||
|
||||
Random random = new Random(BuildStableSeed(rarity, sourceType, itemInstanceId, configId));
|
||||
int tagBudget = ResolveTagBudget(rarity, random);
|
||||
int tagBudget = ResolveRarityTagBudget(rarity, random, rarityTagBudgetRulesByRarity);
|
||||
if (tagBudget <= 0)
|
||||
{
|
||||
return Array.Empty<TagType>();
|
||||
@@ -88,26 +89,25 @@ namespace GeometryTD.Definition
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int ResolveTagBudget(RarityType rarity, Random random)
|
||||
public static int ResolveRarityTagBudget(
|
||||
RarityType rarity,
|
||||
Random random,
|
||||
IReadOnlyDictionary<RarityType, RarityTagBudgetRuleData> rarityTagBudgetRulesByRarity = null)
|
||||
{
|
||||
RarityType normalizedRarity = InventoryRarityRuleService.NormalizeComponentRarity(rarity);
|
||||
random ??= new Random(0);
|
||||
IReadOnlyDictionary<RarityType, RarityTagBudgetRuleData> ruleLookup = rarityTagBudgetRulesByRarity ?? RarityTagBudgetRuleRegistry.Rules;
|
||||
RarityTagBudgetRuleData rule = GetRarityTagBudgetRule(normalizedRarity, ruleLookup);
|
||||
|
||||
switch (normalizedRarity)
|
||||
Debug.Assert(rule.MinCount >= 0);
|
||||
Debug.Assert(rule.MaxCount >= rule.MinCount);
|
||||
|
||||
if (rule.MinCount == rule.MaxCount)
|
||||
{
|
||||
case RarityType.White:
|
||||
return random.Next(0, 2);
|
||||
case RarityType.Green:
|
||||
return 1;
|
||||
case RarityType.Blue:
|
||||
return random.Next(1, 3);
|
||||
case RarityType.Purple:
|
||||
return 2;
|
||||
case RarityType.Red:
|
||||
return random.Next(2, 4);
|
||||
default:
|
||||
return 0;
|
||||
return rule.MinCount;
|
||||
}
|
||||
|
||||
random ??= new Random(0);
|
||||
return random.Next(rule.MinCount, rule.MaxCount + 1);
|
||||
}
|
||||
|
||||
private static bool IsSupportedLaunchTag(TagType tagType)
|
||||
@@ -131,6 +131,15 @@ namespace GeometryTD.Definition
|
||||
return false;
|
||||
}
|
||||
|
||||
private static RarityTagBudgetRuleData GetRarityTagBudgetRule(
|
||||
RarityType rarity,
|
||||
IReadOnlyDictionary<RarityType, RarityTagBudgetRuleData> ruleLookup)
|
||||
{
|
||||
Debug.Assert(ruleLookup != null);
|
||||
Debug.Assert(ruleLookup.TryGetValue(rarity, out _));
|
||||
return ruleLookup[rarity];
|
||||
}
|
||||
|
||||
private static int RollWeightedIndex(
|
||||
IReadOnlyList<TagType> pool,
|
||||
IReadOnlyDictionary<TagType, TagGenerationRuleData> ruleLookup,
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace GeometryTD.Definition
|
||||
{
|
||||
public sealed class RarityTagBudgetRuleData
|
||||
{
|
||||
public RarityType Rarity { get; set; }
|
||||
public int MinCount { get; set; }
|
||||
public int MaxCount { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c0b098910eb4f8486d306ecf1812423
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,73 @@
|
||||
using System.Collections.Generic;
|
||||
using GeometryTD.DataTable;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GeometryTD.Definition
|
||||
{
|
||||
public static class RarityTagBudgetRuleRegistry
|
||||
{
|
||||
private static readonly Dictionary<RarityType, RarityTagBudgetRuleData> RulesByRarity = CreateDefaultRules();
|
||||
|
||||
public static IReadOnlyDictionary<RarityType, RarityTagBudgetRuleData> Rules => RulesByRarity;
|
||||
|
||||
public static void ResetToDefaults()
|
||||
{
|
||||
RulesByRarity.Clear();
|
||||
foreach (KeyValuePair<RarityType, RarityTagBudgetRuleData> pair in CreateDefaultRules())
|
||||
{
|
||||
RulesByRarity.Add(pair.Key, pair.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoadFromRows(IEnumerable<DRRarityTagBudget> rows)
|
||||
{
|
||||
ResetToDefaults();
|
||||
foreach (DRRarityTagBudget row in rows)
|
||||
{
|
||||
ApplyRow(row);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryGetRule(RarityType rarity, out RarityTagBudgetRuleData rule)
|
||||
{
|
||||
return RulesByRarity.TryGetValue(rarity, out rule);
|
||||
}
|
||||
|
||||
private static Dictionary<RarityType, RarityTagBudgetRuleData> CreateDefaultRules()
|
||||
{
|
||||
return new Dictionary<RarityType, RarityTagBudgetRuleData>
|
||||
{
|
||||
[RarityType.White] = CreateRule(RarityType.White, 0, 1),
|
||||
[RarityType.Green] = CreateRule(RarityType.Green, 1, 1),
|
||||
[RarityType.Blue] = CreateRule(RarityType.Blue, 1, 2),
|
||||
[RarityType.Purple] = CreateRule(RarityType.Purple, 2, 2),
|
||||
[RarityType.Red] = CreateRule(RarityType.Red, 2, 3)
|
||||
};
|
||||
}
|
||||
|
||||
private static RarityTagBudgetRuleData CreateRule(RarityType rarity, int minCount, int maxCount)
|
||||
{
|
||||
Debug.Assert(rarity >= RarityType.White && rarity <= RarityType.Red);
|
||||
Debug.Assert(minCount >= 0);
|
||||
Debug.Assert(maxCount >= minCount);
|
||||
|
||||
return new RarityTagBudgetRuleData
|
||||
{
|
||||
Rarity = rarity,
|
||||
MinCount = minCount,
|
||||
MaxCount = maxCount
|
||||
};
|
||||
}
|
||||
|
||||
private static void ApplyRow(DRRarityTagBudget row)
|
||||
{
|
||||
Debug.Assert(row != null);
|
||||
Debug.Assert(row.Id > 0);
|
||||
Debug.Assert(row.Rarity >= RarityType.White && row.Rarity <= RarityType.Red);
|
||||
Debug.Assert(row.MinCount >= 0);
|
||||
Debug.Assert(row.MaxCount >= row.MinCount);
|
||||
|
||||
RulesByRarity[row.Rarity] = CreateRule(row.Rarity, row.MinCount, row.MaxCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bc43423fff7c416fa0a8396e670da212
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -31,6 +31,7 @@ namespace GeometryTD.Procedure
|
||||
"ShopPrice",
|
||||
"Sound",
|
||||
"Tag",
|
||||
"RarityTagBudget",
|
||||
"TagConfig",
|
||||
"OutGameDropPool",
|
||||
"UIForm",
|
||||
@@ -213,6 +214,15 @@ namespace GeometryTD.Procedure
|
||||
TagGenerationRuleRegistry.LoadFromRows(tagTable.GetAllDataRows());
|
||||
}
|
||||
}
|
||||
|
||||
if (ne.DataTableAssetName == AssetUtility.GetDataTableAsset("RarityTagBudget", false))
|
||||
{
|
||||
var tagBudgetTable = GameEntry.DataTable.GetDataTable<DRRarityTagBudget>();
|
||||
if (tagBudgetTable != null)
|
||||
{
|
||||
RarityTagBudgetRuleRegistry.LoadFromRows(tagBudgetTable.GetAllDataRows());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLoadDataTableFailure(object sender, GameEventArgs e)
|
||||
|
||||
Reference in New Issue
Block a user