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);
|
|
}
|
|
}
|
|
}
|