调整 OutGameDropPool 表定义 + 添加部分组件定义

This commit is contained in:
SepComet
2026-03-13 10:08:12 +08:00
parent 26aaa945a9
commit 0c92fd9886
13 changed files with 265 additions and 110 deletions
@@ -19,9 +19,14 @@ namespace GeometryTD.CustomComponent
_dropPoolTable = dropPoolTable;
}
public bool TryRollRow(int displayPhaseIndex, LevelThemeType themeType, out DROutGameDropPool selectedRow)
public bool TryRollRow(
int displayPhaseIndex,
LevelThemeType themeType,
out DROutGameDropPool selectedRow,
out RarityType selectedRarity)
{
selectedRow = null;
selectedRarity = RarityType.None;
DROutGameDropPool[] allRows = _dropPoolTable.GetAllDataRows();
if (allRows == null || allRows.Length <= 0)
@@ -35,22 +40,30 @@ namespace GeometryTD.CustomComponent
return false;
}
RarityType selectedRarity = RollRarity(displayPhaseIndex);
selectedRarity = RollRarity(displayPhaseIndex);
if (selectedRarity == RarityType.None)
{
return false;
}
int totalWeight = 0;
DROutGameDropPool fallbackRow = null;
for (int i = 0; i < _eligibleRowBuffer.Count; i++)
{
DROutGameDropPool row = _eligibleRowBuffer[i];
if (row.Rarity != selectedRarity)
if (!IsEligibleAtPhase(row, selectedRarity, displayPhaseIndex))
{
continue;
}
totalWeight += Mathf.Max(1, row.Weight);
int rowWeight = row.GetWeight(selectedRarity);
if (rowWeight <= 0)
{
continue;
}
fallbackRow = row;
totalWeight += rowWeight;
}
if (totalWeight <= 0)
@@ -62,12 +75,18 @@ namespace GeometryTD.CustomComponent
int cumulativeWeight = 0;
foreach (var row in _eligibleRowBuffer)
{
if (row.Rarity != selectedRarity)
if (!IsEligibleAtPhase(row, selectedRarity, displayPhaseIndex))
{
continue;
}
cumulativeWeight += Mathf.Max(1, row.Weight);
int rowWeight = row.GetWeight(selectedRarity);
if (rowWeight <= 0)
{
continue;
}
cumulativeWeight += rowWeight;
if (randomWeight <= cumulativeWeight)
{
selectedRow = row;
@@ -75,7 +94,7 @@ namespace GeometryTD.CustomComponent
}
}
selectedRow = _eligibleRowBuffer[_eligibleRowBuffer.Count - 1];
selectedRow = fallbackRow;
return selectedRow != null;
}
@@ -99,7 +118,7 @@ namespace GeometryTD.CustomComponent
continue;
}
if (displayPhaseIndex < row.MinPhase || displayPhaseIndex > row.MaxPhase)
if (!IsEligibleAtPhase(row, displayPhaseIndex))
{
continue;
}
@@ -116,20 +135,35 @@ namespace GeometryTD.CustomComponent
for (int i = 0; i < _eligibleRowBuffer.Count; i++)
{
DROutGameDropPool row = _eligibleRowBuffer[i];
float curveWeight = GetRarityCurveWeight(row.Rarity, phaseT);
if (curveWeight <= 0f)
for (int rarityIndex = (int)RarityType.White; rarityIndex <= (int)RarityType.Red; rarityIndex++)
{
continue;
}
RarityType rarity = (RarityType)rarityIndex;
if (!IsEligibleAtPhase(row, rarity, displayPhaseIndex))
{
continue;
}
float rowWeight = Mathf.Max(1, row.Weight) * curveWeight;
if (_rarityWeightBuffer.TryGetValue(row.Rarity, out float existingWeight))
{
_rarityWeightBuffer[row.Rarity] = existingWeight + rowWeight;
}
else
{
_rarityWeightBuffer[row.Rarity] = rowWeight;
int rowWeight = row.GetWeight(rarity);
if (rowWeight <= 0)
{
continue;
}
float curveWeight = GetRarityCurveWeight(rarity, phaseT);
if (curveWeight <= 0f)
{
continue;
}
float rarityWeight = rowWeight * curveWeight;
if (_rarityWeightBuffer.TryGetValue(rarity, out float existingWeight))
{
_rarityWeightBuffer[rarity] = existingWeight + rarityWeight;
}
else
{
_rarityWeightBuffer[rarity] = rarityWeight;
}
}
}
@@ -163,6 +197,32 @@ namespace GeometryTD.CustomComponent
return RarityType.None;
}
private static bool IsEligibleAtPhase(DROutGameDropPool row, int displayPhaseIndex)
{
for (int rarityIndex = (int)RarityType.White; rarityIndex <= (int)RarityType.Red; rarityIndex++)
{
RarityType rarity = (RarityType)rarityIndex;
if (IsEligibleAtPhase(row, rarity, displayPhaseIndex))
{
return true;
}
}
return false;
}
private static bool IsEligibleAtPhase(DROutGameDropPool row, RarityType rarity, int displayPhaseIndex)
{
if (row.GetWeight(rarity) <= 0)
{
return false;
}
int minPhase = row.GetMinPhase(rarity);
int maxPhase = row.GetMaxPhase(rarity);
return displayPhaseIndex >= minPhase && displayPhaseIndex <= maxPhase;
}
private static float GetRarityCurveWeight(RarityType rarityType, float phaseT)
{
float hump = Mathf.Exp(-Mathf.Pow((phaseT - 0.35f) / 0.28f, 2f));
@@ -183,4 +243,4 @@ namespace GeometryTD.CustomComponent
}
}
}
}
}
@@ -183,16 +183,26 @@ namespace GeometryTD.CustomComponent
droppedItem = null;
DropPoolRoller dropPoolRoller = EnsureDropPoolRoller();
int phaseIndex = Mathf.Max(1, displayPhaseIndex);
if (!dropPoolRoller.TryRollRow(phaseIndex, themeType, out DROutGameDropPool selectedRow) || selectedRow == null)
if (!dropPoolRoller.TryRollRow(
phaseIndex,
themeType,
out DROutGameDropPool selectedRow,
out RarityType selectedRarity) || selectedRow == null)
{
return false;
}
return TryBuildDropItem(selectedRow, InventoryTagSourceType.Drop, AllocateDropTagOrdinal(), out droppedItem);
return TryBuildDropItem(
selectedRow,
selectedRarity,
InventoryTagSourceType.Drop,
AllocateDropTagOrdinal(),
out droppedItem);
}
private bool TryBuildDropItem(
DROutGameDropPool row,
RarityType rarity,
InventoryTagSourceType sourceType,
int localOrdinal,
out TowerCompItemData droppedItem)
@@ -215,7 +225,7 @@ namespace GeometryTD.CustomComponent
droppedItem = ComponentItemFactory.CreateMuzzle(
config,
AllocateTempInstanceId(),
row.Rarity,
rarity,
CreateRandomContext(sourceType, localOrdinal, config.Id));
return true;
}
@@ -231,7 +241,7 @@ namespace GeometryTD.CustomComponent
droppedItem = ComponentItemFactory.CreateBearing(
config,
AllocateTempInstanceId(),
row.Rarity,
rarity,
CreateRandomContext(sourceType, localOrdinal, config.Id));
return true;
}
@@ -247,7 +257,7 @@ namespace GeometryTD.CustomComponent
droppedItem = ComponentItemFactory.CreateBase(
config,
AllocateTempInstanceId(),
row.Rarity,
rarity,
CreateRandomContext(sourceType, localOrdinal, config.Id));
return true;
}
@@ -265,9 +275,14 @@ namespace GeometryTD.CustomComponent
return _nextRewardTagOrdinal++;
}
private TowerCompItemData BuildRewardCandidateItem(DROutGameDropPool row)
private TowerCompItemData BuildRewardCandidateItem(DROutGameDropPool row, RarityType rarity)
{
if (!TryBuildDropItem(row, InventoryTagSourceType.Reward, AllocateRewardTagOrdinal(), out TowerCompItemData droppedItem))
if (!TryBuildDropItem(
row,
rarity,
InventoryTagSourceType.Reward,
AllocateRewardTagOrdinal(),
out TowerCompItemData droppedItem))
{
return null;
}
@@ -19,7 +19,7 @@ namespace GeometryTD.CustomComponent
int displayPhaseIndex,
LevelThemeType themeType,
int candidateCount,
Func<DROutGameDropPool, TowerCompItemData> buildRewardItem)
Func<DROutGameDropPool, RarityType, TowerCompItemData> buildRewardItem)
{
int resolvedCount = Mathf.Max(0, candidateCount);
if (resolvedCount <= 0)
@@ -28,7 +28,7 @@ namespace GeometryTD.CustomComponent
}
List<TowerCompItemData> candidates = new List<TowerCompItemData>(resolvedCount);
HashSet<int> selectedPoolRowIds = new HashSet<int>();
HashSet<long> selectedPoolEntryKeys = new HashSet<long>();
int maxAttempts = Mathf.Max(resolvedCount * 6, resolvedCount);
int phaseIndex = Mathf.Max(1, displayPhaseIndex);
@@ -36,17 +36,21 @@ namespace GeometryTD.CustomComponent
while (candidates.Count < resolvedCount && attempts < maxAttempts)
{
attempts++;
if (!_dropPoolRoller.TryRollRow(phaseIndex, themeType, out DROutGameDropPool selectedRow) || selectedRow == null)
if (!_dropPoolRoller.TryRollRow(
phaseIndex,
themeType,
out DROutGameDropPool selectedRow,
out RarityType selectedRarity) || selectedRow == null)
{
break;
}
if (!selectedPoolRowIds.Add(selectedRow.Id))
if (!selectedPoolEntryKeys.Add(BuildSelectionKey(selectedRow.Id, selectedRarity)))
{
continue;
}
TowerCompItemData candidate = buildRewardItem(selectedRow);
TowerCompItemData candidate = buildRewardItem(selectedRow, selectedRarity);
if (candidate == null)
{
continue;
@@ -59,12 +63,16 @@ namespace GeometryTD.CustomComponent
while (candidates.Count < resolvedCount && attempts < maxAttempts)
{
attempts++;
if (!_dropPoolRoller.TryRollRow(phaseIndex, themeType, out DROutGameDropPool selectedRow) || selectedRow == null)
if (!_dropPoolRoller.TryRollRow(
phaseIndex,
themeType,
out DROutGameDropPool selectedRow,
out RarityType selectedRarity) || selectedRow == null)
{
break;
}
TowerCompItemData candidate = buildRewardItem(selectedRow);
TowerCompItemData candidate = buildRewardItem(selectedRow, selectedRarity);
if (candidate == null)
{
continue;
@@ -75,5 +83,10 @@ namespace GeometryTD.CustomComponent
return candidates;
}
private static long BuildSelectionKey(int rowId, RarityType rarity)
{
return ((long)rowId << 32) | (uint)rarity;
}
}
}