73 lines
2.7 KiB
C#
73 lines
2.7 KiB
C#
using UnityEngine;
|
||
using BaseGames.Core;
|
||
using BaseGames.Core.Events;
|
||
using BaseGames.World;
|
||
|
||
namespace BaseGames.Enemies
|
||
{
|
||
/// <summary>
|
||
/// 战利品解算器(静态工具类)。
|
||
/// 根据 <see cref="LootTableSO"/> 和当前难度决定掉落内容。
|
||
/// </summary>
|
||
public static class LootResolver
|
||
{
|
||
/// <summary>
|
||
/// 解算并执行战利品掉落。
|
||
/// <para>保底 LingZhu:直接加入玩家(通过事件频道)或在 <paramref name="worldPosition"/> 生成拾取物。</para>
|
||
/// <para>随机物品:加权随机后通过 CollectibleSpawner 实例化拾取物。</para>
|
||
/// </summary>
|
||
public static void Resolve(LootTableSO table, Vector2 worldPosition)
|
||
{
|
||
if (table == null) return;
|
||
|
||
// 保底 LingZhu
|
||
int guaranteedLingZhu = Random.Range(table.GuaranteedLingZhuMin, table.GuaranteedLingZhuMax + 1);
|
||
ApplyDifficultyLingZhuScale(ref guaranteedLingZhu);
|
||
if (guaranteedLingZhu > 0)
|
||
CollectibleSpawner.SpawnLingZhu(worldPosition, guaranteedLingZhu);
|
||
|
||
// 加权随机物品掉落
|
||
if (table.Entries == null || table.Entries.Length == 0) return;
|
||
|
||
var dm = ServiceLocator.GetOrDefault<IDifficultyService>();
|
||
bool isHard = dm != null &&
|
||
(int)dm.CurrentLevel >= (int)DifficultyLevel.Hard;
|
||
|
||
float totalWeight = 0f;
|
||
foreach (var entry in table.Entries)
|
||
{
|
||
float w = entry.BaseWeight;
|
||
if (isHard && entry.ScaleWithDifficulty) w *= 1.5f;
|
||
totalWeight += w;
|
||
}
|
||
|
||
if (totalWeight <= 0f) return;
|
||
|
||
float roll = Random.Range(0f, totalWeight);
|
||
float accum = 0f;
|
||
foreach (var entry in table.Entries)
|
||
{
|
||
float w = entry.BaseWeight;
|
||
if (isHard && entry.ScaleWithDifficulty) w *= 1.5f;
|
||
accum += w;
|
||
if (roll <= accum)
|
||
{
|
||
if (!string.IsNullOrEmpty(entry.ItemId))
|
||
CollectibleSpawner.SpawnItem(worldPosition, entry.ItemId);
|
||
else if (entry.LingZhuAmount > 0)
|
||
CollectibleSpawner.SpawnLingZhu(worldPosition, entry.LingZhuAmount);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
private static void ApplyDifficultyLingZhuScale(ref int lingZhu)
|
||
{
|
||
var dm = ServiceLocator.GetOrDefault<IDifficultyService>();
|
||
if (dm?.CurrentScaler == null) return;
|
||
float mult = dm.CurrentScaler.LingZhuDropMultiplier;
|
||
lingZhu = Mathf.RoundToInt(lingZhu * mult);
|
||
}
|
||
}
|
||
}
|