添加探索系统;添加魔法卡礼包、练级回状态;

This commit is contained in:
milimoe 2025-06-29 18:10:01 +08:00
parent ff010370fc
commit 0414ed5fca
Signed by: milimoe
GPG Key ID: 9554D37E4B8991D0
13 changed files with 934 additions and 169 deletions

View File

@ -162,19 +162,20 @@ namespace Oshima.FunGame.OshimaModules.Items
public override long Id => (long)GiftBoxID.;
public override string Name => "魔法卡礼包";
public override string Description => Skills.Active?.Description ?? "";
public int Count => _count;
public int Count { get; set; } = 1;
public Dictionary<string, int> Gifts { get; set; } = [];
private readonly int _count = 1;
private const string GiftName = "与礼包同品质、随机属性、随机魔法技能的魔法卡";
public (QualityType type = QualityType.White, int count = 1, User? user = null, int remainUseTimes = 1) : base(ItemType.GiftBox)
{
QualityType = type;
Others.Add("QualityType", (int)type);
_count = count;
Count = count;
Others.Add("Count", count);
User = user;
.Init(this, new()
{
{ "与礼包同品质、随机属性、随机魔法技能的魔法卡", count }
{ GiftName, count }
}, remainUseTimes);
}
@ -184,6 +185,11 @@ namespace Oshima.FunGame.OshimaModules.Items
{
QualityType = (QualityType)qualityType;
}
if (Others.TryGetValue("Count", out value) && int.TryParse(value.ToString(), out int count))
{
Count = count;
Gifts[GiftName] = count;
}
}
}

View File

@ -21,6 +21,10 @@ namespace Oshima.FunGame.OshimaModules.Regions
Crops.Add(new(180101, "星银合金", "锻造物品的材料。", "银辉城特有的金属材料,拥有银色的光泽和坚固的质地。能够吸收和储存能量,是建造城市和制造武器的理想材料。"));
Crops.Add(new(180102, "液态月光", "锻造物品的材料。", "散发着柔和光芒的液体,如同月光般清澈。蕴含悖论引擎的能量,能够影响现实的结构。"));
Crops.Add(new(180103, "星辉凝露", "锻造物品的材料。", "星辉水母散发的凝露,蕴含重构重力的能量,能够暂时扭曲局部空间法则。"));
NPCs.Add("莉娅");
NPCs.Add("沉默守卫G-7");
Areas.Add("悖论深井");
Areas.Add("星屑回廊");
}
}
@ -39,6 +43,10 @@ namespace Oshima.FunGame.OshimaModules.Regions
Units.Add(new(20401, "冰霜傀儡"));
Crops.Add(new(180401, "时霜药剂", "锻造物品的材料。", "能够减缓时间流逝的药剂,维持神智清醒但可能导致记忆混乱和时间感知错乱。"));
Crops.Add(new(180402, "冰封记忆", "锻造物品的材料。", "冰封的古代战争幻象碎片,触碰时引发强烈记忆回溯与认知扭曲。"));
NPCs.Add("艾萨克");
NPCs.Add("冻伤的信使");
Areas.Add("时钟哨塔");
Areas.Add("记忆回廊");
}
}
@ -57,6 +65,10 @@ namespace Oshima.FunGame.OshimaModules.Regions
Characters.Add(new(10601, "镜像之主"));
Units.Add(new(20601, "镜像守卫"));
Crops.Add(new(180601, "量子纠缠碎片", "锻造物品的材料。", "瞳孔状传送门的微观残片,能够引发量子纠缠现象,连接平行时空。"));
NPCs.Add("奥尔加");
NPCs.Add("溺亡观测者");
Areas.Add("倒影城");
Areas.Add("千瞳之巢");
}
}
@ -78,6 +90,10 @@ namespace Oshima.FunGame.OshimaModules.Regions
Units.Add(new(20702, "时之蝎"));
Crops.Add(new(180701, "时间碎片", "锻造物品的材料。", "时间残骸形成的晶体,拥有不规则形状和模糊纹路,会随机重组周围时空。"));
Crops.Add(new(180702, "时凝液", "锻造物品的材料。", "时漏仙人掌分泌的粘稠液体,能够加速或减缓局部时间流逝,但难以控制。"));
NPCs.Add("卖沙人");
NPCs.Add("循环勘探队");
Areas.Add("昨日之城");
Areas.Add("时漏绿洲");
}
}
@ -95,6 +111,10 @@ namespace Oshima.FunGame.OshimaModules.Regions
Characters.Add(new(10801, "梦魇之主"));
Units.Add(new(20801, "思维寄生虫"));
Crops.Add(new(180801, "梦境碎片", "锻造物品的材料。", "能够改变认知的梦境残留物,摄入后会混淆现实与虚幻的边界。"));
NPCs.Add("认知矫正师");
NPCs.Add("洛伦佐");
Areas.Add("梦境交易所");
Areas.Add("​​幻疡医院");
}
}
}

View File

@ -20,6 +20,10 @@ namespace Oshima.FunGame.OshimaModules.Regions
Units.Add(new(20202, "蜜蜡蜂"));
Crops.Add(new(180201, "荧蓝汁液", "锻造物品的材料。", "林海特有树木的汁液,拥有荧蓝色的光泽。能够吸收和储存能量,是珍贵的炼金材料。"));
Crops.Add(new(180202, "可编程蜜蜡", "锻造物品的材料。", "脉轮圣树分泌的树脂,拥有记忆塑性能力,能够编程实现特定功能。"));
NPCs.Add("老祭司苔藓须");
NPCs.Add("封喉歌者");
Areas.Add("古龙沉眠地穴");
Areas.Add("立体蜂巢市集");
}
}
@ -37,6 +41,10 @@ namespace Oshima.FunGame.OshimaModules.Regions
Characters.Add(new(10901, "共生母体"));
Units.Add(new(20901, "沼泽毒虫"));
Crops.Add(new(180901, "菌类样本", "锻造物品的材料。", "共生母体上生长的奇异菌类,能释放麻痹毒素,具有高度研究价值。"));
NPCs.Add("伊芙琳");
NPCs.Add("溃烂猎人");
Areas.Add("母体神经丛​​");
Areas.Add("诱捕菌林");
}
}
@ -58,6 +66,12 @@ namespace Oshima.FunGame.OshimaModules.Regions
Units.Add(new(21002, "浮空岛灵", [(r => r.Weather == "永夜")]));
Crops.Add(new(181001, "影玫瑰", "锻造物品的材料。", "永夜侧绽放的奇异植物,散发幽光,只在绝对黑暗中盛开。", QualityType.White, [(r => r.Weather == "永夜")]));
Crops.Add(new(181002, "星锚晶石", "锻造物品的材料。", "引雷柱上脱落的晶体碎片,蕴含空间束缚能量,能暂时固定空间结构。", QualityType.White, [(r => r.Weather == "永昼")]));
NPCs.Add("守夜人卡尔");
NPCs.Add("星锚祭司​​");
Areas.Add("永昼庭园​​");
Areas.Add("永夜墓园");
Areas.Add("星锚之地");
Areas.Add("中央之岛");
}
}
@ -80,6 +94,10 @@ namespace Oshima.FunGame.OshimaModules.Regions
Crops.Add(new(181101, "晶化记忆孢子", "锻造物品的材料。", "红杉散发的记忆载体,吸入后可能体验亡者临终经历。"));
Crops.Add(new(181102, "虚空骨髓", "锻造物品的材料。", "骨骼深处的虚空物质,散发扭曲精神的空间能量。"));
Crops.Add(new(181103, "神经蕨类", "锻造物品的材料。", "寄生在骸骨上的蕨类植物,根系连接骸骨神经,触碰引发剧烈幻觉。"));
NPCs.Add("骸骨诗人");
NPCs.Add("\"船长\"");
Areas.Add("骸鲸观星台");
Areas.Add("幽灵船坞");
}
}
}

View File

@ -20,6 +20,10 @@ namespace Oshima.FunGame.OshimaModules.Regions
Units.Add(new(20502, "改造士兵"));
Crops.Add(new(180501, "机械核心碎片", "锻造物品的材料。", "上古机械文明的能量核心,蕴含强大动力但可能触发自毁程序。"));
Crops.Add(new(180502, "活体魔力血", "锻造物品的材料。", "具有自我修复能力的液态魔力,接触会导致身体不可预知的异变。"));
NPCs.Add("\"噬罪者\"");
NPCs.Add("7号改造体");
Areas.Add("​​忏悔教堂​​");
Areas.Add("造物车间");
}
}
}

View File

@ -20,6 +20,10 @@ namespace Oshima.FunGame.OshimaModules.Regions
Units.Add(new(20302, "火焰元素"));
Crops.Add(new(180301, "活体金属苔藓", "锻造物品的材料。", "具有金属质感的生命体,能够自我修复和繁殖,是研究金属生命的珍贵样本。"));
Crops.Add(new(180302, "深渊火钻", "锻造物品的材料。", "火山深处开采的珍稀矿石,只有被矿工灵魂烙印认可者才能安全触碰。"));
NPCs.Add("\"铁颚\"巴拉克");
NPCs.Add("苔丝夫人");
Areas.Add("鱿熔血池​​");
Areas.Add("活体锻炉");
}
}
}

View File

@ -21,6 +21,11 @@ namespace Oshima.FunGame.OshimaModules.Regions
Crops.Add(new(181201, "泰坦符文石", "锻造物品的材料。", "裁决尖碑脱落的法则碎片,蕴含世界调试规则,解读需强大精神力。"));
Crops.Add(new(181202, "神经宝石", "锻造物品的材料。", "与矿脉神经相连的晶体,开采时引发山体剧痛和精神污染。"));
Crops.Add(new(181203, "矿脉神经纤维", "锻造物品的材料。", "连接神经宝石的活体纤维,触碰导致剧烈痛苦和神经感染。"));
NPCs.Add("泰坦刻录员");
NPCs.Add("矿痛共生体");
Areas.Add("神经矿脉​​");
Areas.Add("雷霆王座");
Areas.Add("裁决矩阵");
}
}
}

View File

@ -7,6 +7,7 @@ using Milimoe.FunGame.Core.Library.Common.Addon;
using Milimoe.FunGame.Core.Library.Constant;
using Oshima.Core.Configs;
using Oshima.Core.Constant;
using Oshima.FunGame.OshimaServers.Model;
using Oshima.FunGame.OshimaServers.Service;
using TaskScheduler = Milimoe.FunGame.Core.Api.Utility.TaskScheduler;
@ -141,12 +142,28 @@ namespace Oshima.FunGame.OshimaServers
User user = FunGameService.GetUser(pc);
// 将用户存入缓存
FunGameConstant.UserIdAndUsername[user.Id] = user;
bool updateQuest = false;
bool updateExplore = false;
// 任务结算
EntityModuleConfig<Quest> quests = new("quests", user.Id.ToString());
quests.LoadConfig();
if (quests.Count > 0 && FunGameService.SettleQuest(user, quests))
{
quests.SaveConfig();
updateQuest = true;
}
// 探索结算
List<ExploreModel> list = pc.Get<List<ExploreModel>>("exploring") ?? [];
if (list.Count > 0)
{
updateExplore = FunGameService.SettleExploreAll(list, user);
if (updateExplore)
{
pc.Add("exploring", list);
}
}
if (updateQuest || updateExplore)
{
user.LastTime = DateTime.Now;
pc.Add("user", user);
pc.SaveConfig();
@ -178,6 +195,8 @@ namespace Oshima.FunGame.OshimaServers
});
Task.Run(() =>
{
// 刷新每天登录
FunGameService.UserNotice.Clear();
// 刷新签到
string directoryPath = $@"{AppDomain.CurrentDomain.BaseDirectory}configs/saved";
if (Directory.Exists(directoryPath))
@ -189,6 +208,8 @@ namespace Oshima.FunGame.OshimaServers
PluginConfig pc = new("saved", fileName);
pc.LoadConfig();
pc.Add("signed", false);
pc.Add("logon", false);
pc.Add("exploreTimes", FunGameConstant.MaxExploreTimes);
pc.SaveConfig();
}
Controller.WriteLine("刷新签到");
@ -212,25 +233,6 @@ namespace Oshima.FunGame.OshimaServers
Controller.WriteLine("刷新商店");
}
});
Task.Run(() =>
{
// 刷新每天登录
FunGameService.UserNotice.Clear();
string directoryPath = $@"{AppDomain.CurrentDomain.BaseDirectory}configs/saved";
if (Directory.Exists(directoryPath))
{
string[] filePaths = Directory.GetFiles(directoryPath);
foreach (string filePath in filePaths)
{
string fileName = Path.GetFileNameWithoutExtension(filePath);
PluginConfig pc = new("saved", fileName);
pc.LoadConfig();
pc.Add("logon", false);
pc.SaveConfig();
}
Controller.WriteLine("刷新每天登录");
}
});
// 刷新活动缓存
FunGameService.GetEventCenter();
});

View File

@ -0,0 +1,42 @@
using System.Text;
using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Library.Constant;
using Oshima.FunGame.OshimaServers.Service;
namespace Oshima.FunGame.OshimaServers.Model
{
public class ExploreModel()
{
public Guid Guid { get; set; } = Guid.NewGuid();
public long RegionId { get; set; } = 0;
public IEnumerable<long> CharacterIds { get; set; } = [];
public DateTime? StartTime { get; set; } = null;
public ExploreResult Result { get; set; } = ExploreResult.Nothing;
public string String { get; set; } = "";
public double CreditsAward { get; set; } = 0;
public double MaterialsAward { get; set; } = 0;
public Dictionary<string, int> Awards { get; set; } = [];
public bool FightWin { get; set; } = false;
public double[] AfterFightHPs { get; set; } = [];
public string GetExploreInfo(IEnumerable<Character> inventoryCharacters, IEnumerable<Region> regions)
{
StringBuilder sb = new();
if (CharacterIds.Any())
{
if (regions.FirstOrDefault(r => r.Id == RegionId) is Region region)
{
sb.AppendLine($"☆--- 正在探索 {RegionId} 号地区:{region.Name} ---☆");
if (StartTime != null)
{
sb.AppendLine($"探索时间:{StartTime.Value.ToString(General.GeneralDateTimeFormatChinese)}");
}
sb.AppendLine($"探索角色:{FunGameService.GetCharacterGroupInfoByInventorySequence(inventoryCharacters, CharacterIds, "")}");
}
}
return sb.ToString().Trim();
}
}
}

View File

@ -12,6 +12,7 @@ namespace Oshima.FunGame.OshimaServers.Service
public const int ItemsPerPage1 = 6;
public const int ItemsPerPage2 = 10;
public const int ExploreTime = 2;
public const int MaxExploreTimes = 12;
public static List<Character> Characters { get; } = [];
public static List<Skill> Skills { get; } = [];
public static List<Skill> PassiveSkills { get; } = [];
@ -551,33 +552,37 @@ namespace Oshima.FunGame.OshimaServers.Service
];
/// <summary>
/// 参数说明:{0} 奖励内容字符串,{1} 出现的敌人名称,{2} 出现的NPC名称{3} 出现的物品名称
/// 参数说明:{0} 奖励内容字符串,{1} 敌人名称,{2} NPC名称{3} 物品名称1{4} 地点名称1{5} 物品名称1{6} 地点名称2
/// </summary>
public static Dictionary<string, ExploreResult> ExploreString { get; } = new()
{
{ "哎呀,这波啊,这波是探了个寂寞!不过…好像也不是完全没有收获?奖励:{0}", ExploreResult.General },
{ "你以为会一无所获?哼,天真!虽然也没啥大用,但至少…获得了:{0}", ExploreResult.General },
{ "恭喜你!成功在荒野中迷路!奖励…等等,好像是:{0}?算了,凑合着用吧!", ExploreResult.General },
{ "你凝视着远方…远方也凝视着你…然后,你获得了:{ 0}!这大概就是命运吧。", ExploreResult.General },
{ "探索结果:空气,阳光,还有…奖励:{ 0}!看来今天运气还不错?", ExploreResult.General },
// General - 带奖励的普通结果
{ "当{3}的光芒洒满{4}时,{6}显露出了被封印的{0},你快马加鞭冲了上去夺走!", ExploreResult.General },
{ "{2}的低语在风中消散,但留在你手中的是闪耀的{0}", ExploreResult.General },
{ "恭喜你!成功在荒野中迷路!奖励…等等,好像是:{0}?至少不是空手而归…", ExploreResult.General },
{ "你凝视着远方,远方也凝视着你…然后,你获得了:{0}!这大概就是命运吧。", ExploreResult.General },
{ "探索结果:空气,阳光,还有…奖励:{0}!看来今天运气还不错?", ExploreResult.General },
{ "啥也没找到,白跑一趟!下次记得带上指南针!", ExploreResult.Nothing },
{ "空空如也,一无所获。看来这地方已经被搜刮干净了!", ExploreResult.Nothing },
{ "你对着空地发呆了半天,然后决定回家。今天就当无事发生。", ExploreResult.Nothing },
{ "探索失败!你被自己的影子吓了一跳,然后落荒而逃。", ExploreResult.Nothing },
{ "你努力寻找着什么,但最终只找到了自己的寂寞。", ExploreResult.Nothing },
// Nothing - 无收获
{ "风沙抹去了所有痕迹,只有{3}见证过你的到来。(什么也没有获得)", ExploreResult.Nothing },
{ "{4}地牢里的封印纹丝未动,仿佛在嘲笑着你的徒劳……(什么也没有获得)", ExploreResult.Nothing },
{ "在你的注视下,{4}的宝藏已被{2}掠夺一空。(什么也没有获得)", ExploreResult.Nothing },
{ "你对着空地发呆了半天,只剩冰冷的{4}和你的失望。(什么也没有获得)", ExploreResult.Nothing },
{ "在空荡的回响中传来讥笑,原来{4}的秘宝不过是个传说。(什么也没有获得)", ExploreResult.Nothing },
{ "前方高能!遭遇了{ 1}!准备好迎接一场史诗般的…菜鸡互啄!", ExploreResult.Fight },
{ "警告!{ 1} 正在接近!是时候展现真正的技术了…逃跑技术!", ExploreResult.Fight },
{ "战斗警报!{ 1} 想要和你一较高下!拿出你的勇气…或者直接认输吧!", ExploreResult.Fight },
{ "不好了!{ 1} 出现了!快使用你的绝招…装死!", ExploreResult.Fight },
{ "危险!{ 1} 来袭!但是…你好像忘了带武器?", ExploreResult.Fight },
// Fight - 遭遇敌人
{ "{4}的地面突然裂开,{1}扑向了你!迎接战斗吧!", ExploreResult.Fight },
{ "当你触碰{3}时,{1}的咆哮震撼着{4}", ExploreResult.Fight },
{ "原来这里真的有危险……是{1}守卫着{4},不得不战了!", ExploreResult.Fight },
{ "在探索{4}的某处时,身旁的墙突然破裂,{1}从阴影中降临!", ExploreResult.Fight },
{ "你惊动了{1}{4}瞬间化作战场!", ExploreResult.Fight },
{ "发财了!竟然捡到了{ 0}!看来今天出门踩到狗屎了!", ExploreResult.Earned },
{ "哇!{ 0}!这一定是上天赐予我的!感谢老天爷!", ExploreResult.Earned },
{ "你简直不敢相信自己的眼睛!{ 0}!这运气也太好了吧!", ExploreResult.Earned },
{ "天降横财!{ 0}!看来以后要多出门走走了!", ExploreResult.Earned },
{ "惊喜!{ 0}!这一定是隐藏的宝藏!", ExploreResult.Earned }
// Earned - 珍贵收获
{ "当{3}发出诡异的光芒照亮{4}时,藏在其中的{0}突然落入你手中!", ExploreResult.Earned },
{ "祝福应验!{4}深处的{0}为你所有!", ExploreResult.Earned },
{ "解开{4}地牢中的谜题后,{0}终于显现!", ExploreResult.Earned },
{ "屏障消散,至宝{0}光芒万丈,自觉地飞进了你的口袋!", ExploreResult.Earned },
{ "在偶遇{1}和{2}的遭遇战时,你渔翁得利抢到了:{0}", ExploreResult.Earned }
};
public static Dictionary<QualityType, double> DrawCardProbabilities { get; } = new()

View File

@ -43,7 +43,7 @@
{"抽卡/十连抽卡", "金币抽卡1000/次)"},
{"材料抽卡/材料十连抽卡", "材料抽卡5/次)"},
{"兑换金币 <材料数>", "1材料=200金币"},
{"使用 <名称> <数量> [角色] [角色序号]", "使用物品(可指定角色)"},
{"使用 <名称> <数量> [角色] [角色序号]", "使用物品(可指定角色)举例:使用大经验书 100 角色1"},
{"使用 <序号> [角色] [角色序号]", "使用物品(可指定角色)"},
{"使用魔法卡 <物品序号> <卡包序号>", "使用指定魔法卡"},
{"合成魔法卡 <{序号...}>", "3张魔法卡合成空格隔开"},
@ -69,8 +69,7 @@
{"世界地图", "查看当前地图"},
{"主城", "查看主城信息"},
{"查地区 <序号>", "查看指定地区信息"},
{"探索 <序号>", "主战角色探索指定地区"},
{"小队探索 <序号>", "小队探索指定地区4*单人消耗和奖励)"},
{"探索 <地区序号> <{角色序号...}>", "探索指定地区(可多角色)"}
};
public static Dictionary<string, string> ClubHelp { get; } = new() {

View File

@ -9,13 +9,15 @@ using Oshima.FunGame.OshimaModules.Effects.OpenEffects;
using Oshima.FunGame.OshimaModules.Items;
using Oshima.FunGame.OshimaModules.Regions;
using Oshima.FunGame.OshimaModules.Skills;
using Oshima.FunGame.OshimaModules.Units;
using Oshima.FunGame.OshimaServers.Model;
namespace Oshima.FunGame.OshimaServers.Service
{
public class FunGameService
{
public static HashSet<Activity> Activities { get; } = [];
public static Dictionary<long, List<string>> UserNotice { get; } = [];
public static Dictionary<long, HashSet<string>> UserNotice { get; } = [];
public static Dictionary<int, Character> Bosses { get; } = [];
public static ServerPluginLoader? ServerPluginLoader { get; set; } = null;
public static WebAPIPluginLoader? WebAPIPluginLoader { get; set; } = null;
@ -602,9 +604,12 @@ namespace Oshima.FunGame.OshimaServers.Service
public static void AddNotice(long userId, params string[] notices)
{
if (UserNotice.TryGetValue(userId, out List<string>? list) && list != null)
if (UserNotice.TryGetValue(userId, out HashSet<string>? list) && list != null)
{
list.AddRange(notices);
foreach (string notice in notices)
{
list.Add(notice);
}
}
else UserNotice[userId] = [.. notices];
}
@ -1281,7 +1286,7 @@ namespace Oshima.FunGame.OshimaServers.Service
}
}
public static string GetTrainingInfo(TimeSpan diff, bool isPre, out int totalExperience, out int smallBookCount, out int mediumBookCount, out int largeBookCount)
public static string GetTrainingInfo(TimeSpan diff, Character character, bool isPre, out int totalExperience, out int smallBookCount, out int mediumBookCount, out int largeBookCount)
{
int totalMinutes = (int)diff.TotalMinutes;
@ -1317,7 +1322,11 @@ namespace Oshima.FunGame.OshimaServers.Service
largeBookCount = Math.Min(1, (trainingHours - 24) / 1);
}
double TotalHR = Math.Min(character.MaxHP, character.HR * diff.TotalSeconds);
double TotalMR = Math.Min(character.MaxMP, character.MR * diff.TotalSeconds);
return $"练级时长:{totalMinutes} 分钟,{(isPre ? "" : "")}获得:{totalExperience} 点经验值,{smallBookCount} 本小经验书,{mediumBookCount} 本中经验书,{largeBookCount} 本大经验书。" +
$"回复角色 {TotalHR:0.##} 点生命值和 {TotalMR:0.##} 点魔法值。" +
$"{(isPre ? " 1440 24" : "")}";
}
@ -1391,9 +1400,19 @@ namespace Oshima.FunGame.OshimaServers.Service
int sLevel = General.GameplayEquilibriumConstant.MaxSkillLevel / cutRate;
int mLevel = General.GameplayEquilibriumConstant.MaxMagicLevel / cutRate;
int naLevel = General.GameplayEquilibriumConstant.MaxNormalAttackLevel / cutRate;
boss.NormalAttack.ExHardnessTime = -4;
EnhanceBoss(boss, weapons, armors, shoes, accessory, consumables, cLevel, sLevel, mLevel, naLevel);
Bosses[nowIndex] = boss;
}
}
}
private static void EnhanceBoss(Character boss, Item[] weapons, Item[] armors, Item[] shoes, Item[] accessory, Item[] consumables,
int cLevel, int sLevel, int mLevel, int naLevel, bool enhanceHPMP = true, bool enhanceCRCRD = true)
{
boss.Level = cLevel;
boss.NormalAttack.Level = naLevel;
boss.NormalAttack.ExHardnessTime = -4;
Item? a = null, b = null, c = null, d = null, d2 = null;
if (weapons.Length > 0)
{
@ -1447,6 +1466,20 @@ namespace Oshima.FunGame.OshimaServers.Service
Skill bossSkill = Factory.OpenFactory.GetInstance<Skill>(0, "BOSS专属被动", []);
bossSkill.Level = 1;
bossSkill.Character = boss;
double exHP2 = 1.5;
double exMP2 = 0.8;
if (!enhanceHPMP)
{
exHP2 = 0;
exMP2 = 0;
}
double exCR = 0.35;
double exCRD = 0.9;
if (!enhanceCRCRD)
{
exCR = 0.15;
exCRD = 0.4;
}
Effect effect = Factory.OpenFactory.GetInstance<Effect>((long)EffectID.DynamicsEffect, "", new()
{
{ "skill", bossSkill },
@ -1454,14 +1487,14 @@ namespace Oshima.FunGame.OshimaServers.Service
"values",
new Dictionary<string, object>()
{
{ "exatk", 200 / cutRate },
{ "exdef", 200 / cutRate },
{ "exhp2", 1.5 },
{ "exmp2", 0.8 },
{ "exhr", 8 / cutRate },
{ "exmr", 4 / cutRate },
{ "excr", 0.35 },
{ "excrd", 0.9 },
{ "exatk", 3.4 * cLevel },
{ "exdef", 3.4 * cLevel },
{ "exhp2", exHP2 },
{ "exmp2", exMP2 },
{ "exhr", 0.15 * cLevel },
{ "exmr", 0.1 * cLevel },
{ "excr", exCR },
{ "excrd", exCRD },
{ "excdr", 0.25 },
{ "exacc", 0.25 }
}
@ -1496,10 +1529,6 @@ namespace Oshima.FunGame.OshimaServers.Service
boss.Recovery();
SetCharacterPrimaryAttribute(boss);
Bosses[nowIndex] = boss;
}
}
}
public static Dictionary<int, List<Skill>> GenerateRoundRewards(int maxRound)
@ -1969,13 +1998,348 @@ namespace Oshima.FunGame.OshimaServers.Service
return "该活动已删除!";
}
public static string GetSquadInfo(IEnumerable<Character> inventory, HashSet<long> squadIds)
public static string GetSquadInfo(IEnumerable<Character> inventory, IEnumerable<long> squadIds, string separator = "\r\n")
{
Character[] squad = [.. inventory.Where(c => squadIds.Contains(c.Id))];
Dictionary<Character, int> characters = inventory
.Select((character, index) => new { character, index })
.ToDictionary(x => x.character, x => x.index + 1);
return $"{(squad.Length > 0 ? string.Join("\r\n", squad.Select(c => $"#{characters[c]}. {c}")) : "")}";
return $"{(squad.Length > 0 ? string.Join(separator, squad.Select(c => $"#{characters[c]}. {c}")) : "")}";
}
public static string GetCharacterGroupInfoByInventorySequence(IEnumerable<Character> inventory, IEnumerable<long> characterIds, string separator = "\r\n")
{
Dictionary<Character, int> characters = [];
Character[] loop = [.. inventory];
for (int i = 1; i <= loop.Length; i++)
{
if (characterIds.Contains(i))
{
characters[loop[i - 1]] = i;
}
}
return $"{(characters.Count > 0 ? string.Join(separator, characters.Keys.Select(c => $"#{characters[c]}. {c}")) : "")}";
}
public static async Task<ExploreModel> GenerateExploreModel(OshimaRegion region, long[] characterIds, User user)
{
int characterCount = characterIds.Length;
ExploreModel model = new()
{
RegionId = region.Id,
CharacterIds = characterIds,
StartTime = DateTime.Now
};
// 直接保存探索奖励,但是要等到探索结束后发放
int random = Random.Shared.Next(FunGameConstant.ExploreString.Count);
string exploreString = FunGameConstant.ExploreString.Keys.ToArray()[random];
// 出现的NPC
random = Random.Shared.Next(region.NPCs.Count + 1);
string npc = random == region.NPCs.Count ? GenerateRandomChineseUserName() : region.NPCs[random];
// 探索的子区域
random = Random.Shared.Next(region.Areas.Count);
string area1 = region.Areas[random];
random = Random.Shared.Next(region.Areas.Count);
string area2 = region.Areas[random];
// 出现的物品
List<Item> items = [.. region.Crops.Union(region.Items)];
random = Random.Shared.Next(items.Count);
string item1 = items[random].Name;
random = Random.Shared.Next(items.Count);
string item2 = items[random].Name;
// 筛选敌人
int diff = region.Difficulty switch
{
RarityType.OneStar => 1,
RarityType.TwoStar => 2,
RarityType.ThreeStar => 3,
RarityType.FourStar => 4,
_ => 5
};
List<Character> enemys = [];
Character enemy;
if (region.Characters.Count > 0 && region.Units.Count > 0)
{
random = Random.Shared.Next(2);
if (random == 0)
{
enemy = region.Characters.OrderBy(o => Random.Shared.Next()).First().Copy();
enemy.ExHPPercentage += 0.5;
enemys.Add(enemy);
}
else
{
switch (diff)
{
case 1:
case 2:
enemy = region.Units.OrderBy(o => Random.Shared.Next()).First();
enemys.Add(enemy.Copy());
break;
case 3:
case 4:
enemy = region.Units.OrderBy(o => Random.Shared.Next()).First();
enemys.Add(enemy.Copy());
enemy = region.Units.OrderBy(o => Random.Shared.Next()).First();
enemys.Add(enemy.Copy());
break;
case 5:
default:
enemy = region.Units.OrderBy(o => Random.Shared.Next()).First();
enemys.Add(enemy.Copy());
enemy = region.Units.OrderBy(o => Random.Shared.Next()).First();
enemys.Add(enemy.Copy());
enemy = region.Units.OrderBy(o => Random.Shared.Next()).First();
enemys.Add(enemy.Copy());
break;
}
}
}
else
{
enemy = new RegionCharacter(long.Parse(Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 8)), GenerateRandomChineseUserName());
enemys.Add(enemy);
}
// 生成奖励
string award = "";
model.Result = FunGameConstant.ExploreString[exploreString];
switch (model.Result)
{
case ExploreResult.General:
switch (Random.Shared.Next(3))
{
case 0:
int credits = 0;
for (int i = 0; i < characterCount; i++)
{
credits += Random.Shared.Next(500, 1000) * diff;
}
model.CreditsAward = credits;
award = $" {credits} {General.GameplayEquilibriumConstant.InGameCurrency}";
break;
case 1:
int materials = 0;
for (int i = 0; i < characterCount; i++)
{
materials += 2 * diff;
}
model.MaterialsAward = materials;
award = $" {materials} {General.GameplayEquilibriumConstant.InGameMaterial}";
break;
case 2:
Item item = FunGameConstant.ExploreItems[region][Random.Shared.Next(FunGameConstant.ExploreItems[region].Count)];
int count = 0;
for (int i = 0; i < characterCount; i++)
{
count += Math.Max(1, Random.Shared.Next(1, 4) * diff / 2);
}
model.Awards[item.Name] = count;
award = $" {count} 个{item.Name}";
break;
default:
break;
}
int exp = 0;
for (int i = 0; i < characterCount; i++)
{
exp += Random.Shared.Next(300, 700) * diff;
}
model.Awards["exp"] = exp;
award += $",并额外获得了 {exp} 点经验值(探索队员们平分)";
break;
case ExploreResult.Fight:
// 小队信息
Character[] squad = [.. user.Inventory.Characters.Where((c, index) => characterIds.Contains(index + 1)).Select(c => CharacterBuilder.Build(c, false, true, user.Inventory, FunGameConstant.AllItems, FunGameConstant.AllSkills, false))];
if (squad.All(c => c.HP <= 0))
{
model.Result = ExploreResult.Nothing;
exploreString = $"探索小队遭遇强大的敌人{enemy.Name}偷袭,狼狈而逃!(什么也没有获得,请检查角色的状态)";
}
else
{
// 生成敌人
Item[] weapons = [.. FunGameConstant.Equipment.Where(i => i.Id.ToString().StartsWith("11") && (int)i.QualityType == 5)];
Item[] armors = [.. FunGameConstant.Equipment.Where(i => i.Id.ToString().StartsWith("12") && (int)i.QualityType == 5)];
Item[] shoes = [.. FunGameConstant.Equipment.Where(i => i.Id.ToString().StartsWith("13") && (int)i.QualityType == 5)];
Item[] accessory = [.. FunGameConstant.Equipment.Where(i => i.Id.ToString().StartsWith("14") && (int)i.QualityType == 5)];
Item[] consumables = [.. FunGameConstant.AllItems.Where(i => i.ItemType == ItemType.Consumable && i.IsInGameItem)];
int cLevel = diff * 12;
int sLevel = diff + 1;
int mLevel = region.Difficulty switch
{
RarityType.OneStar => 1,
RarityType.TwoStar => 2,
RarityType.ThreeStar => 4,
RarityType.FourStar => 6,
_ => 8
};
int naLevel = mLevel;
foreach (Character enemy_loop in enemys)
{
EnhanceBoss(enemy_loop, weapons, armors, shoes, accessory, consumables, cLevel, sLevel, mLevel, naLevel, false, false);
}
// 开始战斗
Team team1 = new($"{user.Username}的探索小队", squad);
Team team2 = new($"{region.Name}", enemys);
List<string> msgs = await FunGameActionQueue.NewAndStartTeamGame([team1, team2], showAllRound: true);
if (msgs.Count > 2)
{
msgs = msgs[^2..];
}
if (enemy.HP <= 0)
{
model.FightWin = true;
int credits = 0;
for (int i = 0; i < characterCount; i++)
{
credits += Random.Shared.Next(1000, 1500) * diff;
}
model.CreditsAward = credits;
exp = 0;
for (int i = 0; i < characterCount; i++)
{
exp += Random.Shared.Next(600, 1000) * diff;
}
model.Awards["exp"] = exp;
int materials = 0;
for (int i = 0; i < characterCount; i++)
{
materials += Random.Shared.Next(4, 7) * diff;
}
model.MaterialsAward = materials;
Item item = FunGameConstant.ExploreItems[region][Random.Shared.Next(FunGameConstant.ExploreItems[region].Count)];
int count = 0;
for (int i = 0; i < characterCount; i++)
{
count += Math.Max(1, Random.Shared.Next(1, 4) * diff / 2);
}
model.Awards[item.Name] = count;
award = $"{credits} {General.GameplayEquilibriumConstant.InGameCurrency}" + $"{exp} 点经验值(探索队员们平分)," +
$"{materials} {General.GameplayEquilibriumConstant.InGameMaterial}" + $"以及 {count} 个{item.Name}";
exploreString = $"{exploreString}\r\n{string.Join("\r\n", msgs)}\r\n探索小队战胜了{enemy.Name}!获得了:{award}";
}
else
{
Item item = FunGameConstant.ExploreItems[region][Random.Shared.Next(FunGameConstant.ExploreItems[region].Count)];
model.Awards[item.Name] = characterCount;
award = $"{characterCount} 个{item.Name}";
exploreString = $"{exploreString}\r\n{string.Join("\r\n", msgs)}\r\n探索小队未能战胜{enemy.Name},但是获得了补偿:{award}";
}
model.AfterFightHPs = [.. squad.Select(c => c.HP)];
}
break;
case ExploreResult.Earned:
Item? itemEarned = region.Items.OrderBy(o => Random.Shared.Next()).FirstOrDefault();
if (itemEarned is null)
{
model.Result = ExploreResult.Nothing;
exploreString = "你在探索中发现了一个神秘的物品,但它似乎无法辨认。(什么也没有获得)";
}
else
{
model.Awards[itemEarned.Name] = 1;
award = itemEarned.Name;
}
break;
case ExploreResult.Event:
break;
case ExploreResult.Nothing:
default:
break;
}
model.String = string.Format(exploreString, award, enemy.Name, npc, item1, area1, item2, area2);
return model;
}
public static bool SettleExplore(Guid exploreId, List<ExploreModel> list, User user, out string msg)
{
bool result = false;
msg = "";
ExploreModel? model = list.FirstOrDefault(m => m.Guid == exploreId);
if (model != null)
{
result = true;
msg = model.String;
if (model.CreditsAward > 0)
{
user.Inventory.Credits += model.CreditsAward;
}
if (model.MaterialsAward > 0)
{
user.Inventory.Materials += model.MaterialsAward;
}
Character[] inventory = [.. user.Inventory.Characters];
foreach (string name in model.Awards.Keys)
{
if (name == "exp")
{
double exp = (double)model.Awards[name] / model.CharacterIds.Count();
foreach (long cid in model.CharacterIds)
{
if (cid > 0 && cid <= inventory.Length)
{
Character character = inventory[(int)cid - 1];
character.EXP += exp;
}
}
continue;
}
Item? item = FunGameConstant.AllItems.FirstOrDefault(i => i.Name == name);
if (item != null)
{
for (int i = 0; i < model.Awards[name]; i++)
{
Item newItem = item.Copy();
newItem.User = user;
SetSellAndTradeTime(newItem);
user.Inventory.Items.Add(newItem);
}
}
}
if (model.AfterFightHPs.Length > 0)
{
int hpIndex = 0;
foreach (long cid in model.CharacterIds)
{
if (cid > 0 && cid <= inventory.Length && hpIndex < model.AfterFightHPs.Length)
{
Character character = inventory[(int)cid - 1];
character.HP = model.AfterFightHPs[hpIndex++];
}
}
}
}
return result;
}
public static bool SettleExploreAll(List<ExploreModel> list, User user)
{
bool settle = false;
List<Guid> remove = [];
foreach (ExploreModel model in list)
{
if (model.StartTime.HasValue && (DateTime.Now - model.StartTime.Value).TotalMinutes > FunGameConstant.ExploreTime + 5)
{
if (SettleExplore(model.Guid, list, user, out string msg))
{
settle = true;
AddNotice(user.Id, $"你上次未完成的探索已被自动结算:{msg}");
remove.Add(model.Guid);
}
}
}
foreach (Guid guid in remove)
{
list.RemoveAll(m => m.Guid == guid);
}
return settle;
}
}
}

View File

@ -13,6 +13,7 @@ using Oshima.Core.Configs;
using Oshima.FunGame.OshimaModules.Characters;
using Oshima.FunGame.OshimaModules.Items;
using Oshima.FunGame.OshimaModules.Regions;
using Oshima.FunGame.OshimaServers.Model;
using Oshima.FunGame.OshimaServers.Service;
namespace Oshima.FunGame.WebAPI.Controllers
@ -3022,11 +3023,13 @@ namespace Oshima.FunGame.WebAPI.Controllers
user.Inventory.Training.Remove(cid);
TimeSpan diff = now - time;
string msg = FunGameService.GetTrainingInfo(diff, false, out int totalExperience, out int smallBookCount, out int mediumBookCount, out int largeBookCount);
string msg = FunGameService.GetTrainingInfo(diff, character, false, out int totalExperience, out int smallBookCount, out int mediumBookCount, out int largeBookCount);
if (totalExperience > 0)
{
character.EXP += totalExperience;
character.HP += character.HR * diff.TotalSeconds;
character.MP += character.MR * diff.TotalSeconds;
}
for (int i = 0; i < smallBookCount; i++)
@ -3095,7 +3098,7 @@ namespace Oshima.FunGame.WebAPI.Controllers
if (character != null)
{
TimeSpan diff = now - time;
string msg = FunGameService.GetTrainingInfo(diff, true, out int totalExperience, out int smallBookCount, out int mediumBookCount, out int largeBookCount);
string msg = FunGameService.GetTrainingInfo(diff, character, true, out int totalExperience, out int smallBookCount, out int mediumBookCount, out int largeBookCount);
return $"角色 [ {character} ] 正在练级中,{msg}\r\n确认无误后请输入【练级结算】领取奖励";
}
@ -5230,10 +5233,13 @@ namespace Oshima.FunGame.WebAPI.Controllers
}
[HttpPost("exploreregion")]
public string ExploreRegion([FromQuery] long? uid = null, [FromQuery] long? id = null)
public async Task<(string, Guid)> ExploreRegion([FromQuery] long? uid = null, [FromQuery] long? id = null, [FromBody] long[]? cids = null)
{
Guid exploreId = Guid.Empty;
long userid = uid ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11));
long regionid = id ?? 0;
long[] characterIds = cids ?? [];
int characterCount = characterIds.Length;
PluginConfig pc = new("saved", userid.ToString());
pc.LoadConfig();
@ -5243,13 +5249,249 @@ namespace Oshima.FunGame.WebAPI.Controllers
{
User user = FunGameService.GetUser(pc);
if (regionid > 0 && regionid <= FunGameConstant.Regions.Count && FunGameConstant.Regions.FirstOrDefault(r => r.Id == regionid) is OshimaRegion region)
// 检查角色存在
List<long> invalid = [];
foreach (long cid in characterIds)
{
msg = $"开始探索【{region.Name}】,探索时间:{FunGameConstant.ExploreTime} 分钟。(骗你的,其实还没做)";
if (cid > 0 && cid <= user.Inventory.Characters.Count)
{
// do nothing
}
else
{
return $"没有找到与这个序号相对应的地区!";
invalid.Add(cid);
}
}
if (invalid.Count > 0)
{
msg = $"没有找到与输入序号相对应的角色:{string.Join("", invalid)}。";
}
// 检查探索次数
if (pc.TryGetValue("exploreTimes", out object? value) && int.TryParse(value.ToString(), out int exploreTimes))
{
if (exploreTimes <= 0)
{
exploreTimes = 0;
msg = $"今日的探索次数已用完,无法再继续探索。";
}
else if (characterCount > exploreTimes)
{
msg = $"你选择的角色数量超过了剩余的探索次数({exploreTimes} 次),请减少选择的角色数量。需要注意:探索角色越多,奖励越多,但是会扣除相应的探索次数。";
}
}
else
{
exploreTimes = FunGameConstant.MaxExploreTimes;
}
// 检查角色是否正在探索
List<ExploreModel> list = pc.Get<List<ExploreModel>>("exploring") ?? [];
if (list.Count > 0)
{
string msg2 = "";
List<Guid> remove = [];
foreach (ExploreModel model in list)
{
// 可能要结算先前的超时探索
if (model.StartTime.HasValue && (DateTime.Now - model.StartTime.Value).TotalMinutes > FunGameConstant.ExploreTime + 5)
{
if (FunGameService.SettleExplore(model.Guid, list, user, out string notice))
{
if (notice != "")
{
if (msg2 != "") msg2 += "\r\n";
msg2 += $"你上次未完成的探索已被自动结算{notice}";
}
remove.Add(model.Guid);
}
}
IEnumerable<long> exploring = model.CharacterIds.Intersect(characterIds);
if (exploring.Any())
{
if (msg2 != "") msg2 += "\r\n";
msg2 += $"你暂时无法使用以下角色进行探索:[ {FunGameService.GetCharacterGroupInfoByInventorySequence(user.Inventory.Characters, exploring, " ] / [ ")} ]" +
$"因为这些角色已经参与了另一场探索:\r\n{model.GetExploreInfo(user.Inventory.Characters, FunGameConstant.Regions)}";
}
}
foreach (Guid guid in remove)
{
list.RemoveAll(m => m.Guid == guid);
}
if (msg2 != "")
{
if (msg != "") msg += "\r\n";
msg += msg2;
}
}
if (msg == "")
{
exploreTimes -= characterCount;
if (regionid > 0 && regionid <= FunGameConstant.Regions.Count && FunGameConstant.Regions.FirstOrDefault(r => r.Id == regionid) is OshimaRegion region)
{
msg = $"开始探索【{region.Name}】,探索时间预计 {FunGameConstant.ExploreTime} 分钟(系统会自动结算,届时会有提示)。" +
$"探索成员:[ {FunGameService.GetCharacterGroupInfoByInventorySequence(user.Inventory.Characters, characterIds, " ] / [ ")} ]";
ExploreModel model = await FunGameService.GenerateExploreModel(region, characterIds, user);
exploreId = model.Guid;
list.Add(model);
}
else
{
return ($"没有找到与这个序号相对应的地区!", exploreId);
}
}
if (exploreTimes > 0)
{
if (msg != "") msg += "\r\n";
msg += $"本次扣除探索次数 {characterCount} 次,你的剩余探索次数:{exploreTimes} 次。需要注意:探索角色越多,奖励越多,但是会扣除相应的探索次数。";
}
user.LastTime = DateTime.Now;
pc.Add("user", user);
pc.Add("exploreTimes", exploreTimes);
pc.Add("exploring", list);
pc.SaveConfig();
return (msg, exploreId);
}
else
{
return (noSaved, exploreId);
}
}
[HttpGet("exploreinfo")]
public string GetExploreInfo([FromQuery] long? uid = null)
{
long userid = uid ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11));
PluginConfig pc = new("saved", userid.ToString());
pc.LoadConfig();
string msg = "";
if (pc.Count > 0)
{
User user = FunGameService.GetUser(pc);
// 检查探索次数
if (pc.TryGetValue("exploreTimes", out object? value) && int.TryParse(value.ToString(), out int exploreTimes))
{
if (exploreTimes <= 0)
{
exploreTimes = 0;
msg = $"今日的探索次数已用完,无法再继续探索。";
}
}
else
{
exploreTimes = FunGameConstant.MaxExploreTimes;
}
List<ExploreModel> list = pc.Get<List<ExploreModel>>("exploring") ?? [];
if (list.Count > 0)
{
string msg2 = "";
foreach (ExploreModel model in list)
{
if (msg2 != "") msg2 += "\r\n";
msg2 += model.GetExploreInfo(user.Inventory.Characters, FunGameConstant.Regions);
}
if (msg2 != "")
{
if (msg != "") msg += "\r\n";
msg += $"你目前有以下角色正在探索中:\r\n{msg2}";
}
}
else
{
msg = $"你目前没有角色正在探索。";
}
if (exploreTimes > 0)
{
if (msg != "") msg += "\r\n";
msg += $"你的剩余探索次数:{exploreTimes} 次。";
}
user.LastTime = DateTime.Now;
pc.Add("user", user);
pc.SaveConfig();
return msg;
}
else
{
return noSaved;
}
}
[HttpPost("exploresettleall")]
public string SettleExploreAll([FromQuery] long? uid = null)
{
long userid = uid ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11));
PluginConfig pc = new("saved", userid.ToString());
pc.LoadConfig();
string msg;
if (pc.Count > 0)
{
User user = FunGameService.GetUser(pc);
List<ExploreModel> list = pc.Get<List<ExploreModel>>("exploring") ?? [];
if (list.Count > 0)
{
if (FunGameService.SettleExploreAll(list, user))
{
pc.Add("exploring", list);
msg = $"已完成探索结算。";
}
else
{
msg = $"没有需要结算的探索。";
}
}
else
{
msg = $"你目前没有角色正在探索。";
}
user.LastTime = DateTime.Now;
pc.Add("user", user);
pc.SaveConfig();
return msg;
}
else
{
return noSaved;
}
}
[HttpPost("exploresettle")]
public string SettleExplore(Guid exploreId, [FromQuery] long? uid = null)
{
long userid = uid ?? Convert.ToInt64("10" + Verification.CreateVerifyCode(VerifyCodeType.NumberVerifyCode, 11));
PluginConfig pc = new("saved", userid.ToString());
pc.LoadConfig();
string msg = "";
if (pc.Count > 0)
{
User user = FunGameService.GetUser(pc);
List<ExploreModel> list = pc.Get<List<ExploreModel>>("exploring") ?? [];
if (list.Count > 0)
{
if (FunGameService.SettleExplore(exploreId, list, user, out msg))
{
list.RemoveAll(m => m.Guid == exploreId);
}
pc.Add("exploring", list);
}
user.LastTime = DateTime.Now;

View File

@ -44,7 +44,7 @@ namespace Oshima.FunGame.WebAPI.Services
content = content.Trim();
await Service.SendC2CMessageAsync(msg.OpenId, content, msgType, media, msg.Id, msgSeq);
}
if (msg.FunGameUID > 0 && FunGameService.UserNotice.TryGetValue(msg.FunGameUID, out List<string>? msgs) && msgs != null)
if (msg.FunGameUID > 0 && FunGameService.UserNotice.TryGetValue(msg.FunGameUID, out HashSet<string>? msgs) && msgs != null)
{
FunGameService.UserNotice.Remove(msg.FunGameUID);
await SendAsync(msg, "每日登录提醒", string.Join("\r\n", msgs), msgType, media, 5);
@ -2052,17 +2052,64 @@ namespace Oshima.FunGame.WebAPI.Services
return result;
}
if (e.Detail == "探索信息")
{
string msg = Controller.GetExploreInfo(uid);
if (msg != "")
{
await SendAsync(e, "探索信息", string.Join("\r\n", msg));
}
return result;
}
if (e.Detail == "探索结算")
{
string msg = Controller.SettleExploreAll(uid);
if (msg != "")
{
await SendAsync(e, "探索结算", string.Join("\r\n", msg));
}
return result;
}
if (e.Detail.StartsWith("探索") || e.Detail.StartsWith("前往"))
{
string detail = e.Detail.Replace("探索", "").Replace("前往", "").Trim();
string msg = "";
if (int.TryParse(detail, out int cid))
Guid eid = Guid.Empty;
string[] strings = detail.Split(' ', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
List<int> cindexs = [];
foreach (string s in strings)
{
msg = Controller.ExploreRegion(uid, cid);
if (int.TryParse(s, out int c))
{
cindexs.Add(c);
}
}
if (cindexs.Count > 1 && cindexs.Count <= 5)
{
(msg, eid) = await Controller.ExploreRegion(uid, cindexs[0], [.. cindexs.Skip(1).Select(id => (long)id)]);
if (msg.Trim() != "")
{
await SendAsync(e, "探索", msg);
}
_ = Task.Run(async () =>
{
await Task.Delay(FunGameConstant.ExploreTime * 60 * 1000);
msg = Controller.SettleExplore(eid, uid);
if (msg.Trim() != "")
{
await SendAsync(e, "探索", msg, msgSeq: 2);
}
});
}
else if (cindexs.Count > 5)
{
await SendAsync(e, "探索", "一次探索只能指定至多 4 个角色,需要注意:探索角色越多,奖励越多,但是会扣除相应的探索次数。");
}
else
{
await SendAsync(e, "探索", "探索指令格式错误,正确格式为:探索 <地区序号> <{角色序号...}>");
}
return result;
}
@ -2078,12 +2125,19 @@ namespace Oshima.FunGame.WebAPI.Services
}
if (e.Detail == "毕业礼包")
{
if (FunGameService.Activities.FirstOrDefault(a => a.Name == "毕业季") is Activity activity && activity.Status == ActivityState.InProgress)
{
string msg = Controller.CreateGiftBox(uid, "毕业礼包", true, 2);
if (msg != "")
{
await SendAsync(e, "毕业礼包", string.Join("\r\n", msg));
}
}
else
{
await SendAsync(e, "毕业礼包", "活动不存在或已过期。");
}
return result;
}