Files
zeling_v2/Assets/_Game/Scripts/Enemies/LootResolver.cs
T

65 lines
2.6 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;
// 有效权重只算一遍(难度加成),再交由共享原语加权抽取;无正权重时不掉落。
var weights = new float[table.Entries.Length];
for (int i = 0; i < table.Entries.Length; i++)
{
var entry = table.Entries[i];
float w = entry.BaseWeight;
if (isHard && entry.ScaleWithDifficulty) w *= 1.5f;
weights[i] = w;
}
int idx = WeightedPick.Index(weights);
if (idx < 0) return;
var picked = table.Entries[idx];
if (!string.IsNullOrEmpty(picked.ItemId))
CollectibleSpawner.SpawnItem(worldPosition, picked.ItemId);
else if (picked.LingZhuAmount > 0)
CollectibleSpawner.SpawnLingZhu(worldPosition, picked.LingZhuAmount);
}
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);
}
}
}