mirror of
https://github.com/milimoe/FunGame-Testing.git
synced 2026-04-20 13:35:03 +00:00
肉鸽主体框架完善
This commit is contained in:
parent
727f13aba6
commit
261a4c4fbd
@ -22,13 +22,14 @@ sm.Load();
|
|||||||
ItemModule im = new();
|
ItemModule im = new();
|
||||||
im.Load();
|
im.Load();
|
||||||
|
|
||||||
Milimoe.FunGame.Testing.Tests.RogueLikeTest rogue = new();
|
|
||||||
await rogue.RogueLike.StartGame();
|
|
||||||
|
|
||||||
FunGameConstant.InitFunGame();
|
FunGameConstant.InitFunGame();
|
||||||
FunGameSimulation.InitFunGameSimulation();
|
FunGameSimulation.InitFunGameSimulation();
|
||||||
FunGameController controller = new(new Logger<FunGameController>(new LoggerFactory()));
|
FunGameController controller = new(new Logger<FunGameController>(new LoggerFactory()));
|
||||||
|
|
||||||
|
Milimoe.FunGame.Testing.Tests.RogueLikeTest rogue = new(controller);
|
||||||
|
await rogue.RogueLike.StartGame();
|
||||||
|
Console.ReadKey();
|
||||||
|
|
||||||
//foreach (OshimaRegion or in FunGameConstant.Regions)
|
//foreach (OshimaRegion or in FunGameConstant.Regions)
|
||||||
//{
|
//{
|
||||||
// Console.WriteLine(or.ToString());
|
// Console.WriteLine(or.ToString());
|
||||||
|
|||||||
@ -35,28 +35,21 @@ namespace Milimoe.FunGame.Testing.Solutions
|
|||||||
{
|
{
|
||||||
Running = true;
|
Running = true;
|
||||||
Dispatcher.StartServer();
|
Dispatcher.StartServer();
|
||||||
AddDialog("???", "探索者,欢迎入职【永恒方舟计划】,我是您的专属 AI,协助您前往指定任务地点开展勘测工作。请问您的名字是?");
|
DataRequestArgs response = await DataRequest(new("login")
|
||||||
string username;
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
username = await GetTextResultsAsync([]);
|
Data =
|
||||||
if (username == "")
|
|
||||||
{
|
{
|
||||||
WriteLine("请输入不为空的字符串。");
|
{ "uid", 1 }
|
||||||
}
|
|
||||||
}
|
|
||||||
while (username == "");
|
|
||||||
DataRequestArgs response = await DataRequest(new("createuser")
|
|
||||||
{
|
|
||||||
Data = new()
|
|
||||||
{
|
|
||||||
{ "username", username }
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (response.Data.TryGetValue("user", out object? value) && value is User user)
|
if (response.Data.TryGetValue("user", out object? value) && value is User user)
|
||||||
{
|
{
|
||||||
User = user;
|
User = user;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
// 初始化菜单指令
|
// 初始化菜单指令
|
||||||
Commands["quit"] = async (args) =>
|
Commands["quit"] = async (args) =>
|
||||||
{
|
{
|
||||||
@ -93,7 +86,6 @@ namespace Milimoe.FunGame.Testing.Solutions
|
|||||||
};
|
};
|
||||||
AddCommandAlias("help", "菜单", "h", "帮助");
|
AddCommandAlias("help", "菜单", "h", "帮助");
|
||||||
AddCommandAlias("start", "开局");
|
AddCommandAlias("start", "开局");
|
||||||
AddDialog("柔哥", $"让我再次欢迎您,{username}。入职手续已办理完毕,接下来,您可以使用菜单了。请您记住我的名字:【柔哥】。");
|
|
||||||
await Help([]);
|
await Help([]);
|
||||||
while (Running)
|
while (Running)
|
||||||
{
|
{
|
||||||
@ -135,10 +127,10 @@ namespace Milimoe.FunGame.Testing.Solutions
|
|||||||
}
|
}
|
||||||
|
|
||||||
public delegate Task ReadInput<T>(Dictionary<string, object> args, List<T> results);
|
public delegate Task ReadInput<T>(Dictionary<string, object> args, List<T> results);
|
||||||
public delegate Task<InquiryResponse> ReadInputInGameResponse(InquiryOptions options);
|
public delegate Task<InquiryResponse> ReadInputInquiryResponse(InquiryOptions options);
|
||||||
public event ReadInput<string>? ReadInputStringHandler;
|
public event ReadInput<string>? ReadInputStringHandler;
|
||||||
public event ReadInput<double>? ReadInputNumberHandler;
|
public event ReadInput<double>? ReadInputNumberHandler;
|
||||||
public event ReadInputInGameResponse? ReadInputInGameResponseHandler;
|
public event ReadInputInquiryResponse? ReadInputInquiryResponseHandler;
|
||||||
|
|
||||||
public async Task<List<string>> GetChoiceResultsAsync(InquiryOptions options, Dictionary<string, object> args)
|
public async Task<List<string>> GetChoiceResultsAsync(InquiryOptions options, Dictionary<string, object> args)
|
||||||
{
|
{
|
||||||
@ -200,10 +192,10 @@ namespace Milimoe.FunGame.Testing.Solutions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<InquiryResponse> GetInGameResponse(InquiryOptions options)
|
public async Task<InquiryResponse> GetInquiryResponse(InquiryOptions options)
|
||||||
{
|
{
|
||||||
if (ReadInputInGameResponseHandler is null) return new(options);
|
if (ReadInputInquiryResponseHandler is null) return new(options);
|
||||||
return await ReadInputInGameResponseHandler.Invoke(options);
|
return await ReadInputInquiryResponseHandler.Invoke(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteLine(string message = "")
|
public void WriteLine(string message = "")
|
||||||
|
|||||||
@ -1,11 +1,17 @@
|
|||||||
using Milimoe.FunGame.Core.Api.Utility;
|
using System.Text;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Milimoe.FunGame.Core.Api.Utility;
|
||||||
using Milimoe.FunGame.Core.Entity;
|
using Milimoe.FunGame.Core.Entity;
|
||||||
|
using Milimoe.FunGame.Core.Interface.Base;
|
||||||
|
using Milimoe.FunGame.Core.Library.Common.Addon;
|
||||||
using Milimoe.FunGame.Core.Library.Constant;
|
using Milimoe.FunGame.Core.Library.Constant;
|
||||||
using Milimoe.FunGame.Core.Model;
|
using Milimoe.FunGame.Core.Model;
|
||||||
using Milimoe.FunGame.Testing.Tests;
|
using Milimoe.FunGame.Testing.Tests;
|
||||||
using Oshima.FunGame.OshimaModules.Characters;
|
using Oshima.FunGame.OshimaModules.Characters;
|
||||||
using Oshima.FunGame.OshimaModules.Models;
|
using Oshima.FunGame.OshimaModules.Models;
|
||||||
using Oshima.FunGame.OshimaModules.Regions;
|
using Oshima.FunGame.OshimaModules.Regions;
|
||||||
|
using Oshima.FunGame.OshimaServers.Service;
|
||||||
|
using Oshima.FunGame.WebAPI.Controllers;
|
||||||
|
|
||||||
namespace Milimoe.FunGame.Testing.Solutions
|
namespace Milimoe.FunGame.Testing.Solutions
|
||||||
{
|
{
|
||||||
@ -18,6 +24,8 @@ namespace Milimoe.FunGame.Testing.Solutions
|
|||||||
public Dictionary<string, User> Users { get; set; } = [];
|
public Dictionary<string, User> Users { get; set; } = [];
|
||||||
public Dictionary<string, RogueLikeGameData> RogueLikeGameDatas { get; set; } = [];
|
public Dictionary<string, RogueLikeGameData> RogueLikeGameDatas { get; set; } = [];
|
||||||
|
|
||||||
|
private readonly FunGameController _controller = dispatcher.Controller;
|
||||||
|
|
||||||
public void ReceiveDataRequest(Guid guid, DataRequestArgs args)
|
public void ReceiveDataRequest(Guid guid, DataRequestArgs args)
|
||||||
{
|
{
|
||||||
Inquiries.Add((guid, args));
|
Inquiries.Add((guid, args));
|
||||||
@ -25,6 +33,8 @@ namespace Milimoe.FunGame.Testing.Solutions
|
|||||||
|
|
||||||
public void WriteLine(string message = "") => Dispatcher.WriteLine(message);
|
public void WriteLine(string message = "") => Dispatcher.WriteLine(message);
|
||||||
|
|
||||||
|
public void AddDialog(string speaker = "", string message = "") => Dispatcher.AddDialog(speaker, message);
|
||||||
|
|
||||||
public async Task DataRequestGuard()
|
public async Task DataRequestGuard()
|
||||||
{
|
{
|
||||||
while (Running)
|
while (Running)
|
||||||
@ -69,23 +79,56 @@ namespace Milimoe.FunGame.Testing.Solutions
|
|||||||
{
|
{
|
||||||
case "createuser":
|
case "createuser":
|
||||||
{
|
{
|
||||||
|
AddDialog("???", "探索者,欢迎入职【永恒方舟计划】,我是您的专属 AI,协助您前往指定任务地点开展勘测工作。请问您的名字是?");
|
||||||
string username = "";
|
string username = "";
|
||||||
if (args.Data.TryGetValue("username", out object? value) && value is string s)
|
do
|
||||||
{
|
{
|
||||||
username = s;
|
InquiryResponse inquiryResponse = await Dispatcher.GetInquiryResponse(new(InquiryType.TextInput, "请问您的名字是?"));
|
||||||
|
if (inquiryResponse.TextResult == "")
|
||||||
|
{
|
||||||
|
WriteLine("请输入不为空的字符串。");
|
||||||
}
|
}
|
||||||
User user = Factory.GetUser(1, username);
|
else
|
||||||
Character character = new CustomCharacter(user.Id, username)
|
{
|
||||||
|
username = inquiryResponse.TextResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (username == "");
|
||||||
|
long uid = Users.Count + 1;
|
||||||
|
PluginConfig pc = FunGameService.GetUserConfig(uid, out _);
|
||||||
|
User user = Factory.GetUser(uid, username);
|
||||||
|
Character character = new CustomCharacter(uid, username)
|
||||||
{
|
{
|
||||||
Level = 1
|
Level = 1
|
||||||
};
|
};
|
||||||
character.Recovery();
|
character.Recovery();
|
||||||
user.Inventory.Characters.Add(character);
|
user.Inventory.Characters.Add(character);
|
||||||
user.Inventory.MainCharacter = character;
|
user.Inventory.MainCharacter = character;
|
||||||
|
pc.Add("user", user);
|
||||||
|
FunGameService.SetUserConfig(uid.ToString(), pc, user);
|
||||||
Users[username] = user;
|
Users[username] = user;
|
||||||
response.Data["user"] = user;
|
response.Data["user"] = user;
|
||||||
|
AddDialog("柔哥", $"让我再次欢迎您,{username}。入职手续已办理完毕,从今以后,您就是【永恒方舟计划】的探员了。请您记住我的名字:【柔哥】,如有任何需要我都会随时提供您帮助。");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "login":
|
||||||
|
{
|
||||||
|
long uid = 0;
|
||||||
|
if (args.Data.TryGetValue("uid", out object? value))
|
||||||
|
{
|
||||||
|
uid = Convert.ToInt64(value);
|
||||||
|
}
|
||||||
|
PluginConfig pc = FunGameService.GetUserConfig(uid, out _);
|
||||||
|
if (pc.ContainsKey("user"))
|
||||||
|
{
|
||||||
|
User user = FunGameService.GetUser(pc);
|
||||||
|
Users[user.Username] = user;
|
||||||
|
response.Data["user"] = user;
|
||||||
|
AddDialog("柔哥", $"{user.Username},欢迎您回到永恒方舟!");
|
||||||
|
}
|
||||||
|
else WriteLine("登录失败,没有找到符合条件的存档。");
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -111,12 +154,17 @@ namespace Milimoe.FunGame.Testing.Solutions
|
|||||||
break;
|
break;
|
||||||
case RogueState.InArk:
|
case RogueState.InArk:
|
||||||
{
|
{
|
||||||
OshimaRegion? region = await ChooseRegion(1);
|
// 玩家选择第一章的地区(从3个1-2★的地区里选一个)
|
||||||
|
OshimaRegion? region = await ChooseRegion(data, 1, 3);
|
||||||
if (region != null)
|
if (region != null)
|
||||||
{
|
{
|
||||||
WriteLine("-- 【永恒方舟计划】进程·Ⅰ:启动 --");
|
WriteLine("-- 【永恒方舟计划】进程·Ⅰ:启动 --");
|
||||||
data.CurrentRegion = region;
|
data.CurrentRegion = region;
|
||||||
data.Chapter1Region = region;
|
data.Chapter1Region = region;
|
||||||
|
data.Region1Map = new RogueLikeMap();
|
||||||
|
data.Region1Map.Load();
|
||||||
|
data.CurrentMap = data.Region1Map;
|
||||||
|
SetupGrid(data, data.CurrentMap);
|
||||||
newState = RogueState.Chapter1InArk;
|
newState = RogueState.Chapter1InArk;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -129,20 +177,24 @@ namespace Milimoe.FunGame.Testing.Solutions
|
|||||||
case RogueState.Chapter1InArk:
|
case RogueState.Chapter1InArk:
|
||||||
{
|
{
|
||||||
WriteLine("探索前的准备。");
|
WriteLine("探索前的准备。");
|
||||||
await RestInArk();
|
await RestInArk(data);
|
||||||
newState = RogueState.ExploringChapter1Area1;
|
newState = RogueState.ExploringChapter1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RogueState.Chapter2InArk:
|
case RogueState.Chapter2InArk:
|
||||||
{
|
{
|
||||||
WriteLine("回到方舟后,我们得到了新的任务。");
|
WriteLine("回到方舟后,我们得到了新的任务。");
|
||||||
// TODO:提供一个菜单,玩家可以选择第二章的地区(随机从3-4★的地区里抽取3个来选一个)
|
// 玩家选择第二章的地区(从3-4★的地区里随机抽取3个来选一个)
|
||||||
OshimaRegion? region = await ChooseRegion(2);
|
OshimaRegion? region = await ChooseRegion(data, 2, 3);
|
||||||
if (region != null)
|
if (region != null)
|
||||||
{
|
{
|
||||||
WriteLine("-- 【永恒方舟计划】进程·Ⅱ:启动 --");
|
WriteLine("-- 【永恒方舟计划】进程·Ⅱ:启动 --");
|
||||||
data.CurrentRegion = region;
|
data.CurrentRegion = region;
|
||||||
data.Chapter2Region = region;
|
data.Chapter2Region = region;
|
||||||
|
data.Region2Map = new RogueLikeMap();
|
||||||
|
data.Region2Map.Load();
|
||||||
|
data.CurrentMap = data.Region2Map;
|
||||||
|
SetupGrid(data, data.CurrentMap);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -151,18 +203,23 @@ namespace Milimoe.FunGame.Testing.Solutions
|
|||||||
WriteLine("结算到目前为止的奖励。");
|
WriteLine("结算到目前为止的奖励。");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
await RestInArk();
|
await RestInArk(data);
|
||||||
newState = RogueState.ExploringChapter2Area1;
|
newState = RogueState.ExploringChapter2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RogueState.Chapter3InArk:
|
case RogueState.Chapter3InArk:
|
||||||
{
|
{
|
||||||
OshimaRegion? region = await ChooseRegion(3);
|
// 玩家选择第三章的地区(从3个5★的地区里选一个)
|
||||||
|
OshimaRegion? region = await ChooseRegion(data, 3, 3);
|
||||||
if (region != null)
|
if (region != null)
|
||||||
{
|
{
|
||||||
WriteLine("-- 【永恒方舟计划】进程·Ⅲ:启动 --");
|
WriteLine("-- 【永恒方舟计划】进程·Ⅲ:启动 --");
|
||||||
data.CurrentRegion = region;
|
data.CurrentRegion = region;
|
||||||
data.Chapter3Region = region;
|
data.Chapter3Region = region;
|
||||||
|
data.Region3Map = new RogueLikeMap();
|
||||||
|
data.Region3Map.Load();
|
||||||
|
data.CurrentMap = data.Region3Map;
|
||||||
|
SetupGrid(data, data.CurrentMap);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -171,34 +228,36 @@ namespace Milimoe.FunGame.Testing.Solutions
|
|||||||
WriteLine("结算到目前为止的奖励。");
|
WriteLine("结算到目前为止的奖励。");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
await RestInArk();
|
await RestInArk(data);
|
||||||
newState = RogueState.ExploringChapter3Area1;
|
newState = RogueState.ExploringChapter3;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RogueState.FinalInArk:
|
case RogueState.FinalInArk:
|
||||||
|
WriteLine("当你乘坐返回舱回到方舟时,柔哥没有来迎接你,环视一周,你没有看到任何探员。");
|
||||||
|
WriteLine("在你走出返回舱的那一刹那,你察觉空气中有一股杀气——你很快意识到,方舟遭到了入侵。");
|
||||||
WriteLine("-- 【永恒方舟计划】紧急事件·夺还:启动 --");
|
WriteLine("-- 【永恒方舟计划】紧急事件·夺还:启动 --");
|
||||||
newState = RogueState.ExploringArk;
|
newState = RogueState.ExploringArk;
|
||||||
break;
|
break;
|
||||||
case RogueState.ExploringChapter1Area1:
|
case RogueState.ExploringChapter1:
|
||||||
newState = await ExploreRegion(data, 1, 1);
|
newState = await ExploreRegion(data, 1);
|
||||||
break;
|
break;
|
||||||
case RogueState.ExploringChapter1Area2:
|
case RogueState.ExploringChapter2:
|
||||||
newState = await ExploreRegion(data, 1, 2);
|
newState = await ExploreRegion(data, 2);
|
||||||
break;
|
break;
|
||||||
case RogueState.ExploringChapter2Area1:
|
case RogueState.ExploringChapter3:
|
||||||
newState = await ExploreRegion(data, 2, 1);
|
newState = await ExploreRegion(data, 3);
|
||||||
break;
|
break;
|
||||||
case RogueState.ExploringChapter2Area2:
|
case RogueState.ArriveChapter1RallyPoint:
|
||||||
newState = await ExploreRegion(data, 2, 2);
|
newState = await ArriveRallyPoint(data, 1);
|
||||||
break;
|
break;
|
||||||
case RogueState.ExploringChapter3Area1:
|
case RogueState.ArriveChapter2RallyPoint:
|
||||||
newState = await ExploreRegion(data, 3, 1);
|
newState = await ArriveRallyPoint(data, 2);
|
||||||
break;
|
break;
|
||||||
case RogueState.ExploringChapter3Area2:
|
case RogueState.ArriveChapter3RallyPoint:
|
||||||
newState = await ExploreRegion(data, 3, 2);
|
newState = await ArriveRallyPoint(data, 3);
|
||||||
break;
|
break;
|
||||||
case RogueState.ExploringArk:
|
case RogueState.ExploringArk:
|
||||||
await ExploreArk();
|
await ExploreArk(data);
|
||||||
newState = RogueState.FinalBossBattle;
|
newState = RogueState.FinalBossBattle;
|
||||||
break;
|
break;
|
||||||
case RogueState.Chapter1BossBattle:
|
case RogueState.Chapter1BossBattle:
|
||||||
@ -243,7 +302,7 @@ namespace Milimoe.FunGame.Testing.Solutions
|
|||||||
return newState;
|
return newState;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<OshimaRegion?> ChooseRegion(int chapter)
|
private async Task<OshimaRegion?> ChooseRegion(RogueLikeGameData data, int chapter, int candidate)
|
||||||
{
|
{
|
||||||
string topic = chapter switch
|
string topic = chapter switch
|
||||||
{
|
{
|
||||||
@ -258,9 +317,9 @@ namespace Milimoe.FunGame.Testing.Solutions
|
|||||||
};
|
};
|
||||||
InquiryOptions options = new(InquiryType.Choice, topic)
|
InquiryOptions options = new(InquiryType.Choice, topic)
|
||||||
{
|
{
|
||||||
Choices = FunGameConstant.Regions.Where(predicate).ToDictionary(r => r.Name, r => r.ToString())
|
Choices = FunGameConstant.Regions.Where(predicate).OrderBy(r => data.Random.Next()).Take(candidate).ToDictionary(r => r.Name, r => r.ToString())
|
||||||
};
|
};
|
||||||
InquiryResponse response = await Dispatcher.GetInGameResponse(options);
|
InquiryResponse response = await Dispatcher.GetInquiryResponse(options);
|
||||||
if (!response.Cancel)
|
if (!response.Cancel)
|
||||||
{
|
{
|
||||||
if (response.Choices.FirstOrDefault() is string regionName)
|
if (response.Choices.FirstOrDefault() is string regionName)
|
||||||
@ -275,7 +334,7 @@ namespace Milimoe.FunGame.Testing.Solutions
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<RogueState> ExploreRegion(RogueLikeGameData data, int chapter, int areaSeq)
|
private async Task<RogueState> ExploreRegion(RogueLikeGameData data, int chapter)
|
||||||
{
|
{
|
||||||
RogueState newState = RogueState.Finish;
|
RogueState newState = RogueState.Finish;
|
||||||
if (data.CurrentRegion is null)
|
if (data.CurrentRegion is null)
|
||||||
@ -283,64 +342,107 @@ namespace Milimoe.FunGame.Testing.Solutions
|
|||||||
WriteLine("突发!小队和方舟失联了!永恒方舟计划终止。");
|
WriteLine("突发!小队和方舟失联了!永恒方舟计划终止。");
|
||||||
return newState;
|
return newState;
|
||||||
}
|
}
|
||||||
if (areaSeq == 1)
|
|
||||||
{
|
|
||||||
WriteLine("正在降落...");
|
WriteLine("正在降落...");
|
||||||
data.CurrentArea = data.CurrentRegion.Areas.OrderByDescending(o => Random.Shared.Next()).First();
|
data.CurrentArea = data.CurrentRegion.Areas.OrderByDescending(o => data.Random.Next()).First();
|
||||||
WriteLine($"在【{data.CurrentRegion.Name}】的【{data.CurrentArea}】区域完成降落!");
|
WriteLine($"在【{data.CurrentRegion.Name}】的【{data.CurrentArea}】区域完成降落!");
|
||||||
}
|
List<Quest> quests = GetQuests(data, data.CurrentRegion, 2);
|
||||||
else if (areaSeq == 2)
|
data.CurrentQuests = quests;
|
||||||
{
|
AddDialog("柔哥", $"我看到您安全着陆了,现在方舟给您下发任务指令:\r\n{string.Join("\r\n", quests.Select(q => q.ToString()))}");
|
||||||
WriteLine("该地区的第一个探索区域任务已完成!正在前往第二个区域……");
|
|
||||||
data.CurrentArea = data.CurrentRegion.Areas.OrderByDescending(o => Random.Shared.Next()).First(a => a != data.CurrentArea);
|
|
||||||
WriteLine($"在【{data.CurrentRegion.Name}】的【{data.CurrentArea}】区域完成降落!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteLine("你误入了神秘地带,与方舟失联,游戏结束。");
|
|
||||||
return newState;
|
|
||||||
}
|
|
||||||
bool fin = false;
|
bool fin = false;
|
||||||
while (!fin)
|
while (!fin)
|
||||||
{
|
{
|
||||||
|
if (data.CurrentMap != null)
|
||||||
|
{
|
||||||
|
DisplayMapInConsole(data.CurrentMap);
|
||||||
|
}
|
||||||
// TODO:开始探索区域,主要抉择
|
// TODO:开始探索区域,主要抉择
|
||||||
fin = true;
|
fin = true;
|
||||||
}
|
}
|
||||||
if (areaSeq == 1)
|
|
||||||
{
|
|
||||||
newState = chapter switch
|
newState = chapter switch
|
||||||
{
|
{
|
||||||
1 => RogueState.ExploringChapter1Area2,
|
1 => RogueState.ArriveChapter1RallyPoint,
|
||||||
2 => RogueState.ExploringChapter2Area2,
|
2 => RogueState.ArriveChapter2RallyPoint,
|
||||||
3 => RogueState.ExploringChapter3Area2,
|
3 => RogueState.ArriveChapter3RallyPoint,
|
||||||
_ => RogueState.Finish,
|
_ => RogueState.Finish,
|
||||||
};
|
};
|
||||||
|
return newState;
|
||||||
}
|
}
|
||||||
else if (areaSeq == 2)
|
|
||||||
|
private static List<Quest> GetQuests(RogueLikeGameData data, OshimaRegion region, int count)
|
||||||
|
{
|
||||||
|
List<Quest> quests = [];
|
||||||
|
|
||||||
|
int immediateQuestCount = data.Random.Next(count + 1);
|
||||||
|
int progressiveQuestCount = count - immediateQuestCount;
|
||||||
|
|
||||||
|
var list = region.ImmediateQuestList.OrderBy(kv => data.Random.Next()).Take(count);
|
||||||
|
foreach (var item in list)
|
||||||
|
{
|
||||||
|
string name = region.ImmediateQuestList.Keys.OrderBy(o => Random.Shared.Next()).First();
|
||||||
|
QuestExploration exploration = region.ImmediateQuestList[name];
|
||||||
|
int difficulty = Random.Shared.Next(3, 11);
|
||||||
|
Quest quest = new()
|
||||||
|
{
|
||||||
|
Id = quests.Count + 1,
|
||||||
|
Name = name,
|
||||||
|
Description = exploration.Description,
|
||||||
|
RegionId = region.Id,
|
||||||
|
NeedyExploreItemName = exploration.Item,
|
||||||
|
QuestType = QuestType.Immediate,
|
||||||
|
Status = QuestState.InProgress
|
||||||
|
};
|
||||||
|
quests.Add(quest);
|
||||||
|
}
|
||||||
|
list = region.ProgressiveQuestList.OrderBy(kv => data.Random.Next()).Take(count);
|
||||||
|
foreach (var item in list)
|
||||||
|
{
|
||||||
|
string name = region.ProgressiveQuestList.Keys.OrderBy(o => Random.Shared.Next()).First();
|
||||||
|
QuestExploration exploration = region.ProgressiveQuestList[name];
|
||||||
|
int maxProgress = Random.Shared.Next(3, 11);
|
||||||
|
Quest quest = new()
|
||||||
|
{
|
||||||
|
Id = quests.Count + 1,
|
||||||
|
Name = name,
|
||||||
|
Description = string.Format(exploration.Description, maxProgress),
|
||||||
|
RegionId = region.Id,
|
||||||
|
NeedyExploreItemName = exploration.Item,
|
||||||
|
QuestType = QuestType.Progressive,
|
||||||
|
Progress = 0,
|
||||||
|
MaxProgress = maxProgress,
|
||||||
|
Status = QuestState.InProgress
|
||||||
|
};
|
||||||
|
quests.Add(quest);
|
||||||
|
}
|
||||||
|
|
||||||
|
return quests;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<RogueState> ArriveRallyPoint(RogueLikeGameData data, int chapter)
|
||||||
{
|
{
|
||||||
WriteLine("BOSS房间出现了!做好准备再继续出发吧。");
|
WriteLine("BOSS房间出现了!做好准备再继续出发吧。");
|
||||||
fin = false;
|
bool fin = false;
|
||||||
while (!fin)
|
while (!fin)
|
||||||
{
|
{
|
||||||
// TODO:BOSS房前的准备,提供菜单
|
// TODO:BOSS房前的准备,提供菜单
|
||||||
fin = true;
|
fin = true;
|
||||||
}
|
}
|
||||||
newState = chapter switch
|
WriteLine("出发!");
|
||||||
|
RogueState newState = chapter switch
|
||||||
{
|
{
|
||||||
1 => RogueState.Chapter1BossBattle,
|
1 => RogueState.Chapter1BossBattle,
|
||||||
2 => RogueState.Chapter2BossBattle,
|
2 => RogueState.Chapter2BossBattle,
|
||||||
3 => RogueState.Chapter3BossBattle,
|
3 => RogueState.Chapter3BossBattle,
|
||||||
_ => RogueState.Finish,
|
_ => RogueState.Finish,
|
||||||
};
|
};
|
||||||
}
|
if (newState == RogueState.Finish)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
WriteLine("你误入了神秘地带,与方舟失联,游戏结束。");
|
WriteLine("你误入了神秘地带,与方舟失联,游戏结束。");
|
||||||
|
return newState;
|
||||||
}
|
}
|
||||||
return newState;
|
return newState;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RestInArk()
|
private async Task RestInArk(RogueLikeGameData data)
|
||||||
{
|
{
|
||||||
bool fin = false;
|
bool fin = false;
|
||||||
while (!fin)
|
while (!fin)
|
||||||
@ -351,16 +453,162 @@ namespace Milimoe.FunGame.Testing.Solutions
|
|||||||
WriteLine("出发!");
|
WriteLine("出发!");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ExploreArk()
|
private async Task ExploreArk(RogueLikeGameData data)
|
||||||
{
|
{
|
||||||
|
data.ArkMap = new RogueLikeMap();
|
||||||
|
data.ArkMap.Load();
|
||||||
|
data.CurrentMap = data.ArkMap;
|
||||||
|
SetupGrid(data, data.CurrentMap);
|
||||||
bool fin = false;
|
bool fin = false;
|
||||||
while (!fin)
|
while (!fin)
|
||||||
{
|
{
|
||||||
|
if (data.CurrentMap != null)
|
||||||
|
{
|
||||||
|
DisplayMapInConsole(data.CurrentMap);
|
||||||
|
}
|
||||||
// TODO:方舟事变,需进行方舟探索和收复功能房间并找到最终BOSS房间
|
// TODO:方舟事变,需进行方舟探索和收复功能房间并找到最终BOSS房间
|
||||||
fin = true;
|
fin = true;
|
||||||
}
|
}
|
||||||
WriteLine("出发!");
|
WriteLine("出发!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DisplayMapInConsole(GameMap map)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new();
|
||||||
|
|
||||||
|
// 打印列坐标
|
||||||
|
sb.Append(" ");
|
||||||
|
for (int x = 0; x < map.Length; x++)
|
||||||
|
{
|
||||||
|
sb.Append($" {x} ");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < map.Width; y++)
|
||||||
|
{
|
||||||
|
// 打印行坐标
|
||||||
|
sb.AppendLine();
|
||||||
|
sb.Append($"{y} ");
|
||||||
|
|
||||||
|
for (int x = 0; x < map.Length; x++)
|
||||||
|
{
|
||||||
|
Grid? grid = map[x, y, 0];
|
||||||
|
|
||||||
|
if (grid is null)
|
||||||
|
{
|
||||||
|
sb.Append(" ");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查格子上是否有角色
|
||||||
|
if (grid.Characters.Count > 0)
|
||||||
|
{
|
||||||
|
// 取第一个角色首字母
|
||||||
|
Character character = grid.Characters.First();
|
||||||
|
string displayChar = character.Name.Length > 0 ? character.Name[0].ToString().ToUpper() : "?";
|
||||||
|
sb.Append($"[{displayChar}] ");
|
||||||
|
}
|
||||||
|
else if (grid.InteractionPoints.Count > 0)
|
||||||
|
{
|
||||||
|
InteractionPoint ip = grid.InteractionPoints.First();
|
||||||
|
string displayChar = ((InteractionPointType)ip.CustomValue).ToString();
|
||||||
|
displayChar = displayChar.Length > 0 ? displayChar[0].ToString().ToUpper() : "?";
|
||||||
|
sb.Append($"<{displayChar}> ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.Append(" . ");
|
||||||
|
}
|
||||||
|
if (x == map.Length - 1) sb.Append('\t');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteLine(sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetupGrid(RogueLikeGameData data, GameMap map)
|
||||||
|
{
|
||||||
|
// 生成交互点,8*8的地图,生成30个交互点
|
||||||
|
int count = 30;
|
||||||
|
Random random = data.Random ?? new();
|
||||||
|
Grid[] grids = [.. map.Grids.Values.OrderBy(o => random.Next()).Take(count)];
|
||||||
|
foreach (Grid grid in grids)
|
||||||
|
{
|
||||||
|
// 这些交互点就是房间
|
||||||
|
InteractionPoint ip = new()
|
||||||
|
{
|
||||||
|
Id = grid.Id,
|
||||||
|
CustomValue = random.Next((int)InteractionPointType.MaxValueMark)
|
||||||
|
};
|
||||||
|
grid.InteractionPoints.Add(ip);
|
||||||
|
switch ((InteractionPointType)ip.CustomValue)
|
||||||
|
{
|
||||||
|
case InteractionPointType.General:
|
||||||
|
grid.CharacterEntered += (character) =>
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case InteractionPointType.Elite:
|
||||||
|
grid.CharacterEntered += (character) =>
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case InteractionPointType.Store:
|
||||||
|
grid.CharacterEntered += (character) =>
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case InteractionPointType.Treasure:
|
||||||
|
grid.CharacterEntered += (character) =>
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case InteractionPointType.Rest:
|
||||||
|
grid.CharacterEntered += (character) =>
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case InteractionPointType.Change:
|
||||||
|
grid.CharacterEntered += (character) =>
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Grid? land = map.Grids.Values.OrderBy(g => random.Next()).FirstOrDefault(g => g.InteractionPoints.Count == 0);
|
||||||
|
if (land != null)
|
||||||
|
{
|
||||||
|
map.SetCharacterCurrentGrid(data.Character, land);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RogueLikeGameData(Character character, int seed = -1)
|
||||||
|
{
|
||||||
|
public RogueState RogueState { get; set; } = RogueState.Init;
|
||||||
|
public Character Character { get; set; } = character;
|
||||||
|
public int Chapter { get; set; } = 1;
|
||||||
|
public OshimaRegion? CurrentRegion { get; set; } = null;
|
||||||
|
public string CurrentArea { get; set; } = "";
|
||||||
|
public List<Quest> CurrentQuests { get; set; } = [];
|
||||||
|
public int RoomId { get; set; } = -1;
|
||||||
|
public OshimaRegion? Chapter1Region { get; set; } = null;
|
||||||
|
public OshimaRegion? Chapter2Region { get; set; } = null;
|
||||||
|
public OshimaRegion? Chapter3Region { get; set; } = null;
|
||||||
|
public int Seed { get; } = -1;
|
||||||
|
public Random Random { get; } = seed == -1 ? new() : new(seed);
|
||||||
|
public GameMap? CurrentMap { get; set; } = null;
|
||||||
|
public GameMap? Region1Map { get; set; } = null;
|
||||||
|
public GameMap? Region2Map { get; set; } = null;
|
||||||
|
public GameMap? Region3Map { get; set; } = null;
|
||||||
|
public GameMap? ArkMap { get; set; } = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum RogueState
|
public enum RogueState
|
||||||
@ -371,12 +619,12 @@ namespace Milimoe.FunGame.Testing.Solutions
|
|||||||
Chapter2InArk,
|
Chapter2InArk,
|
||||||
Chapter3InArk,
|
Chapter3InArk,
|
||||||
FinalInArk,
|
FinalInArk,
|
||||||
ExploringChapter1Area1,
|
ExploringChapter1,
|
||||||
ExploringChapter1Area2,
|
ArriveChapter1RallyPoint,
|
||||||
ExploringChapter2Area1,
|
ExploringChapter2,
|
||||||
ExploringChapter2Area2,
|
ArriveChapter2RallyPoint,
|
||||||
ExploringChapter3Area1,
|
ExploringChapter3,
|
||||||
ExploringChapter3Area2,
|
ArriveChapter3RallyPoint,
|
||||||
ExploringArk,
|
ExploringArk,
|
||||||
Chapter1BossBattle,
|
Chapter1BossBattle,
|
||||||
Chapter2BossBattle,
|
Chapter2BossBattle,
|
||||||
@ -384,4 +632,62 @@ namespace Milimoe.FunGame.Testing.Solutions
|
|||||||
FinalBossBattle,
|
FinalBossBattle,
|
||||||
Finish
|
Finish
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum InteractionPointType
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 普通战斗
|
||||||
|
/// </summary>
|
||||||
|
General,
|
||||||
|
/// <summary>
|
||||||
|
/// 精英
|
||||||
|
/// </summary>
|
||||||
|
Elite,
|
||||||
|
/// <summary>
|
||||||
|
/// 商店
|
||||||
|
/// </summary>
|
||||||
|
Store,
|
||||||
|
/// <summary>
|
||||||
|
/// 宝箱
|
||||||
|
/// </summary>
|
||||||
|
Treasure,
|
||||||
|
/// <summary>
|
||||||
|
/// 休息点
|
||||||
|
/// </summary>
|
||||||
|
Rest,
|
||||||
|
/// <summary>
|
||||||
|
/// 随机事件
|
||||||
|
/// </summary>
|
||||||
|
Change,
|
||||||
|
/// <summary>
|
||||||
|
/// 最大值标记,仅用于生成时限定范围
|
||||||
|
/// </summary>
|
||||||
|
MaxValueMark
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RogueLikeMap : GameMap
|
||||||
|
{
|
||||||
|
public override string Name => "milimoe.fungame.roguelike.map";
|
||||||
|
|
||||||
|
public override string Description => "GameMap for RogueLike";
|
||||||
|
|
||||||
|
public override string Version => "1.0.0";
|
||||||
|
|
||||||
|
public override string Author => "Milimoe";
|
||||||
|
|
||||||
|
public override int Length => 8;
|
||||||
|
|
||||||
|
public override int Width => 8;
|
||||||
|
|
||||||
|
public override int Height => 1;
|
||||||
|
|
||||||
|
public override float Size => 3;
|
||||||
|
|
||||||
|
public RogueLikeGameData? RogueLikeGameData { get; set; } = default;
|
||||||
|
|
||||||
|
public override GameMap InitGamingQueue(IGamingQueue queue)
|
||||||
|
{
|
||||||
|
return new RogueLikeMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
using Milimoe.FunGame.Core.Entity;
|
using Milimoe.FunGame.Core.Model;
|
||||||
using Milimoe.FunGame.Core.Model;
|
|
||||||
using Milimoe.FunGame.Testing.Solutions;
|
using Milimoe.FunGame.Testing.Solutions;
|
||||||
using Oshima.FunGame.OshimaModules.Regions;
|
using Oshima.FunGame.WebAPI.Controllers;
|
||||||
|
|
||||||
namespace Milimoe.FunGame.Testing.Tests
|
namespace Milimoe.FunGame.Testing.Tests
|
||||||
{
|
{
|
||||||
@ -13,16 +12,16 @@ namespace Milimoe.FunGame.Testing.Tests
|
|||||||
public RogueLike RogueLike { get; set; }
|
public RogueLike RogueLike { get; set; }
|
||||||
public RogueLikeServer RogueLikeServer { get; set; }
|
public RogueLikeServer RogueLikeServer { get; set; }
|
||||||
|
|
||||||
public RogueLikeTest()
|
public RogueLikeTest(FunGameController controller)
|
||||||
{
|
{
|
||||||
RogueLikeDispatcher dispatcher = new();
|
RogueLikeDispatcher dispatcher = new(controller);
|
||||||
RogueLike = new(dispatcher);
|
RogueLike = new(dispatcher);
|
||||||
RogueLikeServer = new(dispatcher);
|
RogueLikeServer = new(dispatcher);
|
||||||
dispatcher.RogueLikeInstance = RogueLike;
|
dispatcher.RogueLikeInstance = RogueLike;
|
||||||
dispatcher.RogueLikeServer = RogueLikeServer;
|
dispatcher.RogueLikeServer = RogueLikeServer;
|
||||||
RogueLike.ReadInputStringHandler += RogueLike_ReadInputStringHandler;
|
RogueLike.ReadInputStringHandler += RogueLike_ReadInputStringHandler;
|
||||||
RogueLike.ReadInputNumberHandler += RogueLike_ReadInputNumberHandler;
|
RogueLike.ReadInputNumberHandler += RogueLike_ReadInputNumberHandler;
|
||||||
RogueLike.ReadInputInGameResponseHandler += RogueLike_ReadInputInGameResponseHandler;
|
RogueLike.ReadInputInquiryResponseHandler += RogueLike_ReadInputInGameResponseHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -180,8 +179,9 @@ namespace Milimoe.FunGame.Testing.Tests
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 仅本地测试原型用,实际使用时需替换为网络层
|
/// 仅本地测试原型用,实际使用时需替换为网络层
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class RogueLikeDispatcher
|
public class RogueLikeDispatcher(FunGameController controller)
|
||||||
{
|
{
|
||||||
|
public FunGameController Controller { get; set; } = controller;
|
||||||
public RogueLike? RogueLikeInstance { get; set; } = null;
|
public RogueLike? RogueLikeInstance { get; set; } = null;
|
||||||
public RogueLikeServer? RogueLikeServer { get; set; } = null;
|
public RogueLikeServer? RogueLikeServer { get; set; } = null;
|
||||||
|
|
||||||
@ -193,6 +193,12 @@ namespace Milimoe.FunGame.Testing.Tests
|
|||||||
RogueLikeInstance.WriteLine(str);
|
RogueLikeInstance.WriteLine(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddDialog(string speaker, string message)
|
||||||
|
{
|
||||||
|
if (RogueLikeInstance is null) return;
|
||||||
|
RogueLikeInstance.AddDialog(speaker, message);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<List<string>> GetChoiceResultsAsync(InquiryOptions options, Dictionary<string, object> args)
|
public async Task<List<string>> GetChoiceResultsAsync(InquiryOptions options, Dictionary<string, object> args)
|
||||||
{
|
{
|
||||||
if (RogueLikeInstance is null) return [];
|
if (RogueLikeInstance is null) return [];
|
||||||
@ -211,10 +217,10 @@ namespace Milimoe.FunGame.Testing.Tests
|
|||||||
return await RogueLikeInstance.GetTextResultsAsync(args);
|
return await RogueLikeInstance.GetTextResultsAsync(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<InquiryResponse> GetInGameResponse(InquiryOptions options)
|
public async Task<InquiryResponse> GetInquiryResponse(InquiryOptions options)
|
||||||
{
|
{
|
||||||
if (RogueLikeInstance is null) return new(options);
|
if (RogueLikeInstance is null) return new(options);
|
||||||
return await RogueLikeInstance.GetInGameResponse(options);
|
return await RogueLikeInstance.GetInquiryResponse(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DataRequestComplete(Guid guid, DataRequestArgs response)
|
public async Task DataRequestComplete(Guid guid, DataRequestArgs response)
|
||||||
@ -242,19 +248,6 @@ namespace Milimoe.FunGame.Testing.Tests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RogueLikeGameData(Character character)
|
|
||||||
{
|
|
||||||
public RogueState RogueState { get; set; } = RogueState.Init;
|
|
||||||
public Character Character { get; set; } = character;
|
|
||||||
public int Chapter { get; set; } = 1;
|
|
||||||
public OshimaRegion? CurrentRegion { get; set; } = null;
|
|
||||||
public string CurrentArea { get; set; } = "";
|
|
||||||
public int RoomId { get; set; } = -1;
|
|
||||||
public OshimaRegion? Chapter1Region { get; set; } = null;
|
|
||||||
public OshimaRegion? Chapter2Region { get; set; } = null;
|
|
||||||
public OshimaRegion? Chapter3Region { get; set; } = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DataRequestArgs(string type)
|
public class DataRequestArgs(string type)
|
||||||
{
|
{
|
||||||
public string RequestType { get; } = type;
|
public string RequestType { get; } = type;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user