提交修改

This commit is contained in:
Bob.Song
2026-03-19 17:46:58 +08:00
parent 34070d0769
commit f696d08489
5 changed files with 190 additions and 1 deletions

View File

@@ -19,7 +19,6 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Game\Condition\" />
<Folder Include="Game\FishFarm\" />
<Folder Include="Game\Map\Weather\" />
<Folder Include="Generate\ConfigTable\" />

View File

@@ -0,0 +1,9 @@
namespace NB.Game;
/// <summary>
/// 条件判断上下文
/// </summary>
public class ConditionContext
{
}

View File

@@ -0,0 +1,111 @@
using Fantasy;
using Fantasy.Assembly;
using Fantasy.Async;
using Fantasy.DataStructure.Collection;
using Fantasy.Entitas;
using NB.Game;
/// <summary>
/// 条件管理组件 - 参考 ItemUseComponent 设计
/// </summary>
public class ConditionManageComponent : Entity, IAssemblyLifecycle
{
private readonly Dictionary<int, ICondition> _handlers = new();
private readonly OneToManyList<long, int> _assemblyHandlers = new();
public override void Dispose()
{
base.Dispose();
_handlers.Clear();
_assemblyHandlers.Clear();
}
public async FTask Initialize()
{
await AssemblyLifecycle.Add(this);
}
#region Assembly Lifecycle - ItemUseComponent
public async FTask OnLoad(AssemblyManifest assemblyManifest)
{
var tcs = FTask.Create(false);
Scene.ThreadSynchronizationContext.Post(() =>
{
InnerLoad(assemblyManifest);
tcs.SetResult();
});
await tcs;
}
public async FTask OnUnload(AssemblyManifest assemblyManifest)
{
var tcs = FTask.Create(false);
Scene.ThreadSynchronizationContext.Post(() =>
{
InnerUnLoad(assemblyManifest);
tcs.SetResult();
});
await tcs;
}
private void InnerLoad(AssemblyManifest assemblyManifest)
{
var assembly = assemblyManifest.Assembly;
var assemblyIdentity = assemblyManifest.AssemblyManifestId;
foreach (var type in assembly.GetTypes())
{
if (!typeof(ICondition).IsAssignableFrom(type)) continue;
if (type.IsInterface || type.IsAbstract) continue;
var attributes = type.GetCustomAttributes(typeof(ConditionTypeAttribute), false);
if (attributes.Length == 0)
{
Log.Warning($"类型 {type.FullName} 实现了 ICondition但未添加 ConditionTypeAttribute");
continue;
}
var instance = (ICondition)Activator.CreateInstance(type)!;
foreach (ConditionTypeAttribute attr in attributes)
{
_handlers[(int)attr.Type] = instance;
_assemblyHandlers.Add(assemblyIdentity, (int)attr.Type);
}
}
}
private void InnerUnLoad(AssemblyManifest assemblyManifest)
{
var assemblyIdentity = assemblyManifest.AssemblyManifestId;
if (!_assemblyHandlers.TryGetValue(assemblyIdentity, out var handlers)) return;
foreach (var handler in handlers)
{
_handlers.Remove(handler);
}
_assemblyHandlers.Remove(assemblyIdentity);
}
#endregion
#region
/// <summary>
/// 检查单个条件
/// </summary>
public bool Check(ConditionContext context, ConditionParam param, ConditionType type)
{
if (!_handlers.TryGetValue((int)type, out var handler))
{
Log.Warning($"未找到条件处理器: {type}");
return false;
}
return handler.Check(context, param);
}
#endregion
}

View File

@@ -0,0 +1,6 @@
namespace NB.Game;
public class ConditionParam
{
}

View File

@@ -0,0 +1,64 @@
// 条件接口 - 参考 IItemUse 设计模式
namespace NB.Game;
/// <summary>
/// 条件类型属性
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
public sealed class ConditionTypeAttribute : Attribute
{
public ConditionType Type { get; }
public ConditionTypeAttribute(ConditionType type)
{
Type = type;
}
}
/// <summary>
/// 条件类型枚举
/// </summary>
public enum ConditionType
{
// 基础条件
None = 0,
// 玩家条件
PlayerLevel = 1, // 玩家等级
PlayerExp = 2, // 玩家经验
PlayerOnlineTime = 3, // 玩家在线时间
PlayerLoginCount = 4, // 玩家登录次数
// 钓鱼条件
CatchFish = 10, // 钓鱼数量
CatchFishType = 11, // 钓指定类型鱼
CatchFishQuality = 12, // 钓指定品质鱼
// 物品条件
UseItem = 20, // 使用物品
HaveItem = 21, // 拥有物品
SellFish = 22, // 卖鱼
// 社交条件
JoinClub = 30, // 加入俱乐部
SendMessage = 31, // 发送消息
// 计算条件
Formula = 100, // 公式计算
Script = 101, // 脚本计算
}
/// <summary>
/// 条件判断接口
/// </summary>
public interface ICondition
{
/// <summary>
/// 检查条件是否满足
/// </summary>
/// <param name="context">条件上下文</param>
/// <param name="param"></param>
/// <returns>true=满足, false=不满足</returns>
bool Check(ConditionContext context, ConditionParam param);
}