mirror of
https://github.com/milimoe/FunGame-Testing.git
synced 2025-04-23 12:49:34 +08:00
添加活动和活动中心,添加单位,修改任务系统
This commit is contained in:
parent
7bc06f1440
commit
e24346bf57
@ -1,177 +0,0 @@
|
||||
using Milimoe.FunGame.Core.Entity;
|
||||
using Milimoe.FunGame.Core.Library.Constant;
|
||||
|
||||
namespace Milimoe.FunGame.Testing.Solutions
|
||||
{
|
||||
public enum ActivityState
|
||||
{
|
||||
Future,
|
||||
Upcoming,
|
||||
InProgress,
|
||||
Ended
|
||||
}
|
||||
|
||||
public enum RedeemResult
|
||||
{
|
||||
Success,
|
||||
StockNotEnough,
|
||||
PointsNotEnough
|
||||
}
|
||||
|
||||
public class Activity(long id, string name, DateTime startTime, DateTime endTime)
|
||||
{
|
||||
public long Id { get; set; } = id;
|
||||
public string Name { get; set; } = name;
|
||||
public DateTime StartTime { get; set; } = startTime;
|
||||
public DateTime EndTime { get; set; } = endTime;
|
||||
public ActivityState State { get; private set; } = ActivityState.Future;
|
||||
public List<Quest> Quests { get; set; } = [];
|
||||
public Store Store { get; set; } = new Store();
|
||||
|
||||
// 事件
|
||||
public event EventHandler<UserAccessEventArgs>? UserAccessCheck;
|
||||
|
||||
public void UpdateState()
|
||||
{
|
||||
ActivityState newState;
|
||||
DateTime now = DateTime.Now;
|
||||
|
||||
if (now < StartTime)
|
||||
{
|
||||
newState = ActivityState.Future;
|
||||
}
|
||||
else if (now >= StartTime && now < StartTime.AddHours(1))
|
||||
{
|
||||
newState = ActivityState.Upcoming;
|
||||
}
|
||||
else if (now >= StartTime && now < EndTime)
|
||||
{
|
||||
newState = ActivityState.InProgress;
|
||||
}
|
||||
else
|
||||
{
|
||||
newState = ActivityState.Ended;
|
||||
}
|
||||
|
||||
if (State != newState)
|
||||
{
|
||||
State = newState;
|
||||
}
|
||||
}
|
||||
|
||||
public bool AllowUserAccess(long userId)
|
||||
{
|
||||
UserAccessEventArgs args = new(userId, State, StartTime, EndTime);
|
||||
UserAccessCheck?.Invoke(this, args);
|
||||
return args.AllowAccess;
|
||||
}
|
||||
|
||||
public void AddQuest(Quest quest)
|
||||
{
|
||||
Quests.Add(quest);
|
||||
}
|
||||
|
||||
public void RemoveQuest(Quest quest)
|
||||
{
|
||||
Quests.Remove(quest);
|
||||
}
|
||||
|
||||
public void UpdateQuestStatus(long questId, QuestState newStatus)
|
||||
{
|
||||
var quest = Quests.FirstOrDefault(q => q.Id == questId);
|
||||
if (quest != null)
|
||||
{
|
||||
quest.Status = newStatus;
|
||||
Console.WriteLine($"活动状态已改变为:{newStatus}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class UserAccessEventArgs(long userId, ActivityState activityState, DateTime startTime, DateTime endTime) : EventArgs
|
||||
{
|
||||
public long UserId { get; } = userId;
|
||||
public ActivityState ActivityState { get; } = activityState;
|
||||
public DateTime StartTime { get; } = startTime;
|
||||
public DateTime EndTime { get; } = endTime;
|
||||
public bool AllowAccess { get; set; } = false; // 默认不允许访问
|
||||
}
|
||||
|
||||
public class Points(long userId, int amount = 0)
|
||||
{
|
||||
public long UserId { get; set; } = userId;
|
||||
public int Amount { get; set; } = amount;
|
||||
|
||||
public void AddPoints(int amount)
|
||||
{
|
||||
Amount += amount;
|
||||
}
|
||||
|
||||
public void RemovePoints(int amount)
|
||||
{
|
||||
if (Amount >= amount)
|
||||
{
|
||||
Amount -= amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("积分不足!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Store
|
||||
{
|
||||
public List<Item> Items { get; set; } = [];
|
||||
public Dictionary<long, int> ItemPrices { get; set; } = []; // ItemId, Price
|
||||
public Dictionary<long, int> ItemStocks { get; set; } = []; // ItemId, Stock
|
||||
|
||||
/// <summary>
|
||||
/// 添加物品到商店
|
||||
/// </summary>
|
||||
/// <param name="item">物品</param>
|
||||
/// <param name="price">价格</param>
|
||||
/// <param name="stock">库存</param>
|
||||
public void AddItem(Item item, int price, int stock)
|
||||
{
|
||||
Items.Add(item);
|
||||
ItemPrices[item.Id] = price;
|
||||
ItemStocks[item.Id] = stock;
|
||||
}
|
||||
|
||||
public void RemoveItem(Item item)
|
||||
{
|
||||
Items.Remove(item);
|
||||
ItemPrices.Remove(item.Id);
|
||||
ItemStocks.Remove(item.Id);
|
||||
}
|
||||
|
||||
public RedeemResult TryRedeemItem(Points points, long itemId)
|
||||
{
|
||||
if (!ItemPrices.TryGetValue(itemId, out int price))
|
||||
{
|
||||
throw new ArgumentException($"商品 {itemId} 不存在!");
|
||||
}
|
||||
|
||||
if (!ItemStocks.TryGetValue(itemId, out int stock))
|
||||
{
|
||||
throw new ArgumentException($"商品 {itemId} 不存在!");
|
||||
}
|
||||
|
||||
if (stock <= 0)
|
||||
{
|
||||
return RedeemResult.StockNotEnough; // 库存不足
|
||||
}
|
||||
|
||||
if (points.Amount < price)
|
||||
{
|
||||
return RedeemResult.PointsNotEnough; // 积分不足
|
||||
}
|
||||
|
||||
points.RemovePoints(price);
|
||||
ItemStocks[itemId]--; // 减少库存
|
||||
// 可选:记录兑换记录
|
||||
return RedeemResult.Success; // 兑换成功
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,9 +1,7 @@
|
||||
using Milimoe.FunGame.Core.Api.Utility;
|
||||
using Milimoe.FunGame.Core.Entity;
|
||||
using Milimoe.FunGame.Core.Library.Constant;
|
||||
using Milimoe.FunGame.Testing.Solutions;
|
||||
using ActivityState = Milimoe.FunGame.Testing.Solutions.ActivityState;
|
||||
using RedeemResult = Milimoe.FunGame.Testing.Solutions.RedeemResult;
|
||||
using Milimoe.FunGame.Core.Model;
|
||||
|
||||
namespace Milimoe.FunGame.Testing.Tests
|
||||
{
|
||||
@ -11,99 +9,260 @@ namespace Milimoe.FunGame.Testing.Tests
|
||||
{
|
||||
public ActivityExample()
|
||||
{
|
||||
// 创建活动
|
||||
Activity activity = new(1, "新年活动", new DateTime(2025, 1, 1, 0, 0, 0), new DateTime(2025, 1, 15, 23, 59, 59));
|
||||
DateTime date1 = new(2025, 1, 1, 0, 0, 0);
|
||||
DateTime date1End = new(2025, 1, 15, 23, 59, 59);
|
||||
DateTime date2 = new(2025, 1, 16, 0, 0, 0);
|
||||
DateTime date2End = new(2025, 1, 31, 23, 59, 59);
|
||||
DateTime date3 = new(2025, 2, 1, 0, 0, 0);
|
||||
DateTime date3End = new(2025, 2, 9, 23, 59, 59);
|
||||
|
||||
// 添加任务
|
||||
Quest continuousQuest = new()
|
||||
for (int i = 1; i <= 3; i++)
|
||||
{
|
||||
Activity activity;
|
||||
// 创建活动
|
||||
if (i == 1)
|
||||
{
|
||||
activity = new(i, $"新年活动-阶段{i}", date1, date1End);
|
||||
}
|
||||
else if (i == 2)
|
||||
{
|
||||
activity = new(i, $"新年活动-阶段{i}", date2, date2End);
|
||||
}
|
||||
else
|
||||
{
|
||||
activity = new(i, $"新年活动-阶段{i}", date3, date3End);
|
||||
}
|
||||
|
||||
// 添加任务,需要注意的是,这些任务是全服玩家参与的任务,而不是每个玩家自己的任务。
|
||||
/// 如果需要添加玩家自己的任务,需要做额外工作,可使用 <see cref="EntityModuleConfig{Quest}"> 类。
|
||||
Quest quest = new()
|
||||
{
|
||||
Id = 1,
|
||||
Name = "每日登录",
|
||||
Description = "每日登录游戏",
|
||||
EstimatedMinutes = 1,
|
||||
Awards = new Dictionary<string, int> { { "积分", 10 } },
|
||||
QuestType = QuestType.Continuous
|
||||
};
|
||||
Quest immediateQuest = new()
|
||||
{
|
||||
Id = 2,
|
||||
Name = "新手引导",
|
||||
Description = "完成新手引导",
|
||||
Awards = new Dictionary<string, int> { { "积分", 20 } },
|
||||
QuestType = QuestType.Immediate
|
||||
};
|
||||
Quest progressiveQuest = new()
|
||||
{
|
||||
Id = 3,
|
||||
Name = "击败Boss",
|
||||
Description = "击败Boss",
|
||||
Awards = new Dictionary<string, int> { { "积分", 30 } },
|
||||
Description = "全服玩家累计击败100个Boss",
|
||||
CreditsAward = 10000,
|
||||
MaterialsAward = 800,
|
||||
Awards = [],
|
||||
QuestType = QuestType.Progressive,
|
||||
MaxProgress = 10,
|
||||
Progress = 5
|
||||
MaxProgress = 100
|
||||
};
|
||||
activity.AddQuest(continuousQuest);
|
||||
activity.AddQuest(immediateQuest);
|
||||
activity.AddQuest(progressiveQuest);
|
||||
activity.Quests.Add(quest);
|
||||
|
||||
// 添加商店物品
|
||||
Item item1 = Factory.GetItem();
|
||||
item1.Id = 1;
|
||||
item1.Name = "金币";
|
||||
item1.Description = "游戏金币";
|
||||
Item item2 = Factory.GetItem();
|
||||
item2.Id = 2;
|
||||
item2.Name = "道具";
|
||||
item2.Description = "游戏道具";
|
||||
activity.Store.AddItem(item1, 100, 10);
|
||||
activity.Store.AddItem(item2, 200, 10);
|
||||
// 纳入活动中心管理
|
||||
EventCenter.Instance.AddActivity("新年活动", activity);
|
||||
}
|
||||
|
||||
// 订阅玩家获取活动信息事件
|
||||
EventCenter.Instance.RegisterUserGetActivityInfoEventHandler("新年活动", e =>
|
||||
{
|
||||
// 玩家获取活动信息时,需要显示对应其账号的任务信息
|
||||
// 首先,使用 EntityModuleConfig 创建一个存档管理器
|
||||
EntityModuleConfig<Quest> quests = new(e.Activity.Name, e.UserId.ToString());
|
||||
// 获取任务列表,如果没有,我们需要为之生成
|
||||
quests.LoadConfig();
|
||||
if (quests.Count == 0)
|
||||
{
|
||||
GenerateQuest(quests);
|
||||
}
|
||||
SyncQuestStateToActivity(e.Activity, quests);
|
||||
// 先显示活动的信息
|
||||
Console.WriteLine(e.Activity.ToString(false));
|
||||
// 再显示任务信息
|
||||
List<Quest> list = new(e.Activity.Quests);
|
||||
list.AddRange(quests.Values);
|
||||
Console.WriteLine("=== 任务列表 ===");
|
||||
Console.WriteLine(string.Join("\r\n", list));
|
||||
});
|
||||
|
||||
// 订阅用户访问检查事件
|
||||
activity.UserAccessCheck += (sender, e) =>
|
||||
EventCenter.Instance.RegisterUserAccessEventHandler("新年活动", e =>
|
||||
{
|
||||
if (e.ActivityState == ActivityState.InProgress)
|
||||
{
|
||||
e.AllowAccess = true; // 只有进行中状态才允许访问
|
||||
// 只有进行中状态才允许访问
|
||||
e.AllowAccess = true;
|
||||
// 实现活动逻辑,例如触发打BOSS任务
|
||||
if (e.QuestId == 1 && e.Activity.Quests.FirstOrDefault(q => q.Id == 1) is Quest quest)
|
||||
{
|
||||
if (quest.Status == QuestState.InProgress)
|
||||
{
|
||||
if (Random.Shared.Next(3) > 1)
|
||||
{
|
||||
Console.WriteLine($"用户 {e.UserId} 挑战 Boss 成功!");
|
||||
quest.Progress++;
|
||||
if (quest.Progress >= quest.MaxProgress)
|
||||
{
|
||||
quest.Progress = quest.MaxProgress;
|
||||
quest.Status = QuestState.Completed;
|
||||
Console.WriteLine($"任务 [ {quest.Name} ] 完成!全服玩家将获得奖励【{quest.AwardsString}】!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"用户 {e.UserId} 挑战 Boss 失败,下次再来吧。");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"用户 {e.UserId} 尝试做任务 [ {quest.Name} ] ,但是这个任务的状态为 {CommonSet.GetQuestStatus(quest.Status)} ,做任务失败!");
|
||||
}
|
||||
}
|
||||
// 接上文,开发者可以在此事件中创建 EntityModuleConfig 对象来为玩家定制任务
|
||||
// 现在,我们判断当用户访问的不是全服活动时,如何处理定制任务
|
||||
if (e.QuestId != 1)
|
||||
{
|
||||
// 首先,使用 EntityModuleConfig 创建一个存档管理器
|
||||
EntityModuleConfig<Quest> quests = new(e.Activity.Name, e.UserId.ToString());
|
||||
// 获取任务列表,如果没有,我们需要为之生成
|
||||
quests.LoadConfig();
|
||||
if (quests.Count == 0)
|
||||
{
|
||||
GenerateQuest(quests);
|
||||
}
|
||||
SyncQuestStateToActivity(e.Activity, quests);
|
||||
// 找任务
|
||||
if (quests.Values.FirstOrDefault(q => q.Id == e.QuestId) is Quest quest2)
|
||||
{
|
||||
// 写任务的逻辑
|
||||
Console.WriteLine($"用户 {e.UserId} 尝试做任务 [ {quest2.Name} ]");
|
||||
if (quest2.QuestType == QuestType.Continuous)
|
||||
{
|
||||
// 注意:持续性任务比较特别,需要在持续时间结束后自动结算
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(1000 * 60 * quest2.EstimatedMinutes);
|
||||
// 需要做特殊处理
|
||||
});
|
||||
}
|
||||
// 做了任务后要保存
|
||||
quests.SaveConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"用户 {e.UserId} 尝试访问活动,但当前状态为 {e.ActivityState},不允许访问。");
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// 模拟用户访问
|
||||
long userId = 123;
|
||||
Points points = new(userId, 30000);
|
||||
while (true)
|
||||
string input = Console.ReadLine() ?? "";
|
||||
while (input.Trim() != "quit")
|
||||
{
|
||||
activity.UpdateState(); // 定时更新活动状态
|
||||
if (activity.AllowUserAccess(userId))
|
||||
if (input == "1")
|
||||
{
|
||||
Console.WriteLine(string.Join("\r\n", activity.Quests));
|
||||
|
||||
Console.WriteLine($"用户 {userId} 成功访问活动!");
|
||||
// 模拟用户兑换物品
|
||||
RedeemResult result = activity.Store.TryRedeemItem(points, 1);
|
||||
switch (result)
|
||||
Activity? a = EventCenter.Instance.GetActivity("新年活动", "新年活动-阶段1");
|
||||
if (a != null && a.AllowUserAccess(userId))
|
||||
{
|
||||
case RedeemResult.Success:
|
||||
Console.WriteLine($"用户 {userId} 成功兑换了 {item1.Name}!");
|
||||
break;
|
||||
case RedeemResult.StockNotEnough:
|
||||
Console.WriteLine($"用户 {userId} 兑换 {item1.Name} 失败,库存不足!");
|
||||
break;
|
||||
case RedeemResult.PointsNotEnough:
|
||||
Console.WriteLine($"用户 {userId} 兑换 {item1.Name} 失败,积分不足!");
|
||||
break;
|
||||
Console.WriteLine($"用户 {userId} 成功访问活动 {a.Name}!");
|
||||
}
|
||||
}
|
||||
else if (input == "2")
|
||||
{
|
||||
Activity? a = EventCenter.Instance.GetActivity("新年活动", "新年活动-阶段2");
|
||||
if (a != null && a.AllowUserAccess(userId))
|
||||
{
|
||||
Console.WriteLine($"用户 {userId} 成功访问活动 {a.Name}!");
|
||||
}
|
||||
}
|
||||
else if (input == "31")
|
||||
{
|
||||
Activity? a = EventCenter.Instance.GetActivity("新年活动", "新年活动-阶段3");
|
||||
if (a != null && a.AllowUserAccess(userId, 1))
|
||||
{
|
||||
Console.WriteLine($"用户 {userId} 成功访问活动 {a.Name} 和任务1!");
|
||||
}
|
||||
}
|
||||
else if (input == "32")
|
||||
{
|
||||
Activity? a = EventCenter.Instance.GetActivity("新年活动", "新年活动-阶段3");
|
||||
if (a != null && a.AllowUserAccess(userId, 2))
|
||||
{
|
||||
Console.WriteLine($"用户 {userId} 成功访问活动 {a.Name} 和任务2!");
|
||||
}
|
||||
}
|
||||
else if (input == "33")
|
||||
{
|
||||
Activity? a = EventCenter.Instance.GetActivity("新年活动", "新年活动-阶段3");
|
||||
if (a != null && a.AllowUserAccess(userId, 3))
|
||||
{
|
||||
Console.WriteLine($"用户 {userId} 成功访问活动 {a.Name} 和任务3!");
|
||||
}
|
||||
}
|
||||
else if (input == "4")
|
||||
{
|
||||
// 显示所有活动
|
||||
Console.WriteLine($"新年活动正在火热进行中!");
|
||||
foreach (Activity activity in EventCenter.Instance["新年活动"])
|
||||
{
|
||||
activity.GetActivityInfo(userId);
|
||||
}
|
||||
Store? store = EventCenter.Instance.GetStore("新年活动");
|
||||
if (store != null)
|
||||
{
|
||||
Console.WriteLine($"新年活动商店:[ {store.Name} ],请游玩活动项目后进入商店兑换纪念品!");
|
||||
}
|
||||
}
|
||||
input = Console.ReadLine() ?? "";
|
||||
}
|
||||
|
||||
Console.WriteLine($"用户 {userId} 当前积分:{points.Amount}");
|
||||
|
||||
EventCenter.Instance.UnRegisterUserAccess("新年活动");
|
||||
EventCenter.Instance.UnRegisterUserGetActivityInfo("新年活动");
|
||||
}
|
||||
|
||||
//Thread.Sleep(1000); // 每秒检查一次
|
||||
Console.ReadLine();
|
||||
private void GenerateQuest(EntityModuleConfig<Quest> quests)
|
||||
{
|
||||
// 生成任务
|
||||
quests.Add("签到", new()
|
||||
{
|
||||
Id = 2,
|
||||
Name = "签到",
|
||||
Description = "每日登录游戏即可完成签到",
|
||||
CreditsAward = 10,
|
||||
MaterialsAward = 10,
|
||||
Awards = [],
|
||||
QuestType = QuestType.Immediate
|
||||
});
|
||||
quests.Add("新手引导", new()
|
||||
{
|
||||
Id = 3,
|
||||
Name = "新手引导",
|
||||
Description = "完成新手引导",
|
||||
EstimatedMinutes = 1,
|
||||
CreditsAward = 10,
|
||||
MaterialsAward = 10,
|
||||
Awards = [],
|
||||
QuestType = QuestType.Continuous
|
||||
});
|
||||
// 保存,下次会读取
|
||||
quests.SaveConfig();
|
||||
}
|
||||
|
||||
private void SyncQuestStateToActivity(Activity activity, EntityModuleConfig<Quest> quests)
|
||||
{
|
||||
// 使任务的状态与活动同步
|
||||
foreach (Quest quest in quests.Values)
|
||||
{
|
||||
if (activity.Status == ActivityState.InProgress)
|
||||
{
|
||||
// 只有进度式任务需要修改进行状态,其他类型是开始任务时修改
|
||||
if (quest.Status == QuestState.NotStarted && quest.QuestType == QuestType.Progressive)
|
||||
{
|
||||
quest.Status = QuestState.InProgress;
|
||||
}
|
||||
}
|
||||
else if (activity.Status == ActivityState.Ended)
|
||||
{
|
||||
// 活动结束了,还没开始或者没做完的任务就不能再做了,标记为未完成
|
||||
if (quest.Status == QuestState.NotStarted || quest.Status == QuestState.InProgress)
|
||||
{
|
||||
quest.Status = QuestState.Missed;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 保存,下次会读取
|
||||
quests.SaveConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user