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

73 lines
2.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}
}