using System.Text; using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Model; using Oshima.FunGame.OshimaModules.Effects.OpenEffects; namespace Oshima.Core.Utils { public class FunGameActionQueue { public ActionQueue ActionQueue { get; set; } = new(); public bool IsWeb { get; set; } = false; public bool PrintOut { get; set; } = false; public bool DeathMatchRoundDetail { get; set; } = false; public List Result { get; } = []; private string _msg = ""; public List StartGame(List characters, bool printout = false, bool isWeb = false, bool deathMatchRoundDetail = false, bool showRoundEndDetail = false, bool showAllRound = false) { Result.Clear(); PrintOut = printout; IsWeb = isWeb; DeathMatchRoundDetail = deathMatchRoundDetail; try { _msg = ""; if (PrintOut) Console.WriteLine(); if (PrintOut) Console.WriteLine("Start!!!"); if (PrintOut) Console.WriteLine(); // 创建顺序表并排序 ActionQueue actionQueue = new(characters, false, WriteLine); if (PrintOut) Console.WriteLine(); // 总游戏时长 double totalTime = 0; // 显示角色信息 if (PrintOut) characters.ForEach(c => Console.WriteLine(c.GetInfo())); // 显示初始顺序表 actionQueue.DisplayQueue(); if (PrintOut) Console.WriteLine(); // 总回合数 int maxRound = 999; // 随机回合奖励 Dictionary> roundRewards = FunGameService.GenerateRoundRewards(maxRound); int i = 1; while (i < maxRound) { _msg = ""; if (i == maxRound - 1) { WriteLine($"=== 终局审判 ==="); Dictionary 他们的血量百分比 = []; foreach (Character c in characters) { 他们的血量百分比.TryAdd(c, c.HP / c.MaxHP); } double max = 他们的血量百分比.Values.Max(); Character winner = 他们的血量百分比.Keys.Where(c => 他们的血量百分比[c] == max).First(); WriteLine("[ " + winner + " ] 成为了天选之人!!"); foreach (Character c in characters.Where(c => c != winner && c.HP > 0)) { WriteLine("[ " + winner + " ] 对 [ " + c + " ] 造成了 99999999999 点真实伤害。"); actionQueue.DeathCalculation(winner, c); } actionQueue.EndGameInfo(winner); Result.Add(_msg); break; } // 检查是否有角色可以行动 Character? characterToAct = actionQueue.NextCharacter(); // 处理回合 if (characterToAct != null) { // 获取回合奖励 List skillRewards = []; if (roundRewards.TryGetValue(i, out List? effectList) && effectList != null) { skillRewards = new(effectList); } WriteLine($"=== Round {i++} ==="); WriteLine($"现在是 [ {characterToAct} ] 的回合!"); // 实际的回合奖励 List realSkillRewards = []; if (skillRewards.Count > 0) { foreach (Skill skill in skillRewards) { Dictionary effectArgs = []; if (FunGameService.RoundRewards.TryGetValue((EffectID)skill.Id, out Dictionary? dict) && dict != null) { effectArgs = new(dict); } Dictionary args = new() { { "skill", skill }, { "values", effectArgs } }; skill.GamingQueue = actionQueue; skill.Effects.Add(Factory.OpenFactory.GetInstance(skill.Id, "", args)); skill.Character = characterToAct; skill.Level = 1; actionQueue.LastRound.RoundRewards.Add(skill); WriteLine($"[ {characterToAct} ] 获得了回合奖励!{skill.Description}".Trim()); if (skill.IsActive) { actionQueue.LastRound.Targets.Add(characterToAct); skill.OnSkillCasted(actionQueue, characterToAct, [characterToAct]); } else { characterToAct.Skills.Add(skill); realSkillRewards.Add(skill); } } } bool isGameEnd = actionQueue.ProcessTurn(characterToAct); if (realSkillRewards.Count > 0) { foreach (Skill skill in realSkillRewards) { foreach (Effect e in skill.Effects) { e.OnEffectLost(characterToAct); characterToAct.Effects.Remove(e); } characterToAct.Skills.Remove(skill); skill.Character = null; } } if (isGameEnd) { Result.Add(_msg); break; } if (showRoundEndDetail) actionQueue.DisplayQueue(); WriteLine(""); } string roundMsg = ""; if (actionQueue.LastRound.HasKill || showAllRound) { roundMsg = _msg; if (!deathMatchRoundDetail) { roundMsg = actionQueue.LastRound.ToString().Trim() + "\r\n"; if (showAllRound) { foreach (Character character in actionQueue.Queue) { roundMsg += $"[ {character} ] 生命值:{character.HP:0.##}/{character.MaxHP:0.##} / 魔法值:{character.MP:0.##}/{character.MaxMP:0.##}\r\n"; } } } _msg = ""; } // 模拟时间流逝 double timeLapse = actionQueue.TimeLapse(); totalTime += timeLapse; if (roundMsg != "") { if (isWeb) { roundMsg += "\r\n" + _msg; } Result.Add(roundMsg); } } if (PrintOut) { Console.WriteLine("--- End ---"); Console.WriteLine($"总游戏时长:{totalTime:0.##}"); Console.WriteLine(""); } // 赛后统计 FunGameService.GetCharacterRating(actionQueue.CharacterStatistics, false, actionQueue.EliminatedTeams); // 统计技术得分,评选 MVP Character? mvp = actionQueue.CharacterStatistics.OrderByDescending(d => d.Value.Rating).Select(d => d.Key).FirstOrDefault(); StringBuilder mvpBuilder = new(); if (mvp != null) { CharacterStatistics stats = actionQueue.CharacterStatistics[mvp]; stats.MVPs++; mvpBuilder.AppendLine($"[ {mvp.ToStringWithLevel()} ]"); mvpBuilder.AppendLine($"技术得分:{stats.Rating:0.0#} / 击杀数:{stats.Kills} / 助攻数:{stats.Assists}{(actionQueue.MaxRespawnTimes != 0 ? " / 死亡数:" + stats.Deaths : "")}"); mvpBuilder.AppendLine($"存活时长:{stats.LiveTime} / 存活回合数:{stats.LiveRound} / 行动回合数:{stats.ActionTurn}"); mvpBuilder.AppendLine($"总计伤害:{stats.TotalDamage} / 总计物理伤害:{stats.TotalPhysicalDamage} / 总计魔法伤害:{stats.TotalMagicDamage}"); mvpBuilder.AppendLine($"总承受伤害:{stats.TotalTakenDamage} / 总承受物理伤害:{stats.TotalTakenPhysicalDamage} / 总承受魔法伤害:{stats.TotalTakenMagicDamage}"); mvpBuilder.Append($"每秒伤害:{stats.DamagePerSecond} / 每回合伤害:{stats.DamagePerTurn}"); } int top = isWeb ? actionQueue.CharacterStatistics.Count : 2; // 回执多少个角色的统计信息 int count = 1; _msg = $"=== 技术得分排行榜 TOP{top} ===\r\n"; foreach (Character character in actionQueue.CharacterStatistics.OrderByDescending(d => d.Value.Rating).Select(d => d.Key)) { StringBuilder builder = new(); CharacterStatistics stats = actionQueue.CharacterStatistics[character]; builder.AppendLine($"{count + ". "}[ {character.ToStringWithLevel()} ]"); builder.AppendLine($"技术得分:{stats.Rating:0.0#} / 击杀数:{stats.Kills} / 助攻数:{stats.Assists}{(actionQueue.MaxRespawnTimes != 0 ? " / 死亡数:" + stats.Deaths : "")}"); builder.AppendLine($"存活时长:{stats.LiveTime} / 存活回合数:{stats.LiveRound} / 行动回合数:{stats.ActionTurn}"); builder.AppendLine($"总计伤害:{stats.TotalDamage} / 总计物理伤害:{stats.TotalPhysicalDamage} / 总计魔法伤害:{stats.TotalMagicDamage}"); builder.AppendLine($"总承受伤害:{stats.TotalTakenDamage} / 总承受物理伤害:{stats.TotalTakenPhysicalDamage} / 总承受魔法伤害:{stats.TotalTakenMagicDamage}"); builder.AppendLine($"每秒伤害:{stats.DamagePerSecond} / 每回合伤害:{stats.DamagePerTurn}"); builder.Append($"生命值:{character.HP:0.##}/{character.MaxHP:0.##} / 魔法值:{character.MP:0.##}/{character.MaxMP:0.##}"); if (count++ <= top) { WriteLine(builder.ToString()); } else { if (PrintOut) Console.WriteLine(builder.ToString()); } if (character.User != null) { character.User.Inventory.Credits += stats.TotalEarnedMoney; } } Result.Add(_msg); // 显示每个角色的信息 if (isWeb) { for (i = actionQueue.Eliminated.Count - 1; i >= 0; i--) { Character character = actionQueue.Eliminated[i]; Result.Add($"=== 角色 [ {character} ] ===\r\n{character.GetInfo()}"); } } return Result; } catch (Exception ex) { Console.WriteLine(ex); return [ex.ToString()]; } } public List StartTeamGame(List teams, int maxRespawnTimes = 0, int maxScoreToWin = 0, bool printout = false, bool isWeb = false, bool deathMatchRoundDetail = false, bool showRoundEndDetail = false, bool showAllRound = false) { Result.Clear(); PrintOut = printout; IsWeb = isWeb; DeathMatchRoundDetail = deathMatchRoundDetail; try { _msg = ""; if (teams.Count > 1) { if (PrintOut) Console.WriteLine(); if (PrintOut) Console.WriteLine("Start!!!"); if (PrintOut) Console.WriteLine(); List characters = [.. teams.SelectMany(t => t.Members)]; // 创建顺序表并排序 ActionQueue actionQueue = new(characters, true, WriteLine) { MaxRespawnTimes = maxRespawnTimes, MaxScoreToWin = maxScoreToWin }; if (PrintOut) Console.WriteLine(); // 总游戏时长 double totalTime = 0; // 显示角色信息 if (PrintOut) characters.ForEach(c => Console.WriteLine(c.GetInfo())); // 添加到团队字典 foreach (Team team in teams) { actionQueue.AddTeam(team.Name, team.Members); Result.Add($"团队【{team}】的成员:\r\n{string.Join("\r\n", team.Members)}\r\n"); } // 显示初始顺序表 actionQueue.DisplayQueue(); if (PrintOut) Console.WriteLine(); // 总回合数 int maxRound = 9999; // 随机回合奖励 Dictionary> roundRewards = FunGameService.GenerateRoundRewards(maxRound); int i = 1; while (i < maxRound) { _msg = ""; if (i == maxRound - 1) { WriteLine("两队打到天昏地暗,流局了!!"); break; } // 检查是否有角色可以行动 Character? characterToAct = actionQueue.NextCharacter(); // 处理回合 if (characterToAct != null) { // 获取回合奖励 List skillRewards = []; if (roundRewards.TryGetValue(i, out List? effectList) && effectList != null) { skillRewards = new(effectList); } WriteLine($"=== Round {i++} ==="); WriteLine("现在是 [ " + characterToAct + "(" + (actionQueue.GetTeam(characterToAct)?.Name ?? "") + ")" + " ] 的回合!"); // 实际的回合奖励 List realSkillRewards = []; if (skillRewards.Count > 0) { foreach (Skill skill in skillRewards) { Dictionary effectArgs = []; if (FunGameService.RoundRewards.TryGetValue((EffectID)skill.Id, out Dictionary? dict) && dict != null) { effectArgs = new(dict); } Dictionary args = new() { { "skill", skill }, { "values", effectArgs } }; skill.GamingQueue = actionQueue; skill.Effects.Add(Factory.OpenFactory.GetInstance(skill.Id, "", args)); skill.Character = characterToAct; skill.Level = 1; actionQueue.LastRound.RoundRewards.Add(skill); WriteLine($"[ {characterToAct} ] 获得了回合奖励!{skill.Description}".Trim()); if (skill.IsActive) { actionQueue.LastRound.Targets.Add(characterToAct); skill.OnSkillCasted(actionQueue, characterToAct, [characterToAct]); } else { characterToAct.Skills.Add(skill); realSkillRewards.Add(skill); } } } bool isGameEnd = actionQueue.ProcessTurn(characterToAct); if (realSkillRewards.Count > 0) { foreach (Skill skill in realSkillRewards) { foreach (Effect e in skill.Effects) { e.OnEffectLost(characterToAct); characterToAct.Effects.Remove(e); } characterToAct.Skills.Remove(skill); skill.Character = null; } } if (isGameEnd) { Result.Add(_msg); break; } if (showRoundEndDetail) actionQueue.DisplayQueue(); WriteLine(""); } string roundMsg = ""; if (actionQueue.LastRound.HasKill || showAllRound) { roundMsg = _msg; if (!deathMatchRoundDetail) { roundMsg = actionQueue.LastRound.ToString().Trim() + $"\r\n" + (actionQueue.LastRound.HasKill ? $"比分:{string.Join(" / ", actionQueue.Teams.Values.Select(t => $"{t.Name}({t.Score})"))}" + $",击杀来自{actionQueue.GetTeam(actionQueue.LastRound.Actor)}\r\n" : ""); if (showAllRound) { Character[] showHPMP = [actionQueue.LastRound.Actor, .. actionQueue.LastRound.Targets]; foreach (Character character in showHPMP) { roundMsg += $"[ {character} ] 生命值:{character.HP:0.##}/{character.MaxHP:0.##} / 魔法值:{character.MP:0.##}/{character.MaxMP:0.##}\r\n"; } } } _msg = ""; } // 模拟时间流逝 double timeLapse = actionQueue.TimeLapse(); totalTime += timeLapse; if (roundMsg != "") { if (deathMatchRoundDetail && isWeb) { roundMsg += "\r\n" + _msg; } Result.Add(roundMsg); } } if (PrintOut) { Console.WriteLine("--- End ---"); Console.WriteLine($"总游戏时长:{totalTime:0.##}"); Console.WriteLine(""); } // 赛后统计 FunGameService.GetCharacterRating(actionQueue.CharacterStatistics, true, actionQueue.EliminatedTeams); // 统计技术得分,评选 MVP StringBuilder mvpBuilder = new(); Character? mvp = actionQueue.CharacterStatistics.OrderByDescending(d => d.Value.Rating).Select(d => d.Key).FirstOrDefault(); if (mvp != null) { CharacterStatistics stats = actionQueue.CharacterStatistics[mvp]; stats.MVPs++; Team? team = actionQueue.GetTeamFromEliminated(mvp); mvpBuilder.AppendLine($"=== 本场比赛最佳角色 ==="); mvpBuilder.AppendLine($"{(team != null ? "[ " + team.Name + " ] " : "")}[ {mvp.ToStringWithLevel()} ]"); mvpBuilder.AppendLine($"技术得分:{stats.Rating:0.0#} / 击杀数:{stats.Kills} / 助攻数:{stats.Assists}{(actionQueue.MaxRespawnTimes != 0 ? " / 死亡数:" + stats.Deaths : "")}"); mvpBuilder.AppendLine($"存活时长:{stats.LiveTime} / 存活回合数:{stats.LiveRound} / 行动回合数:{stats.ActionTurn}"); mvpBuilder.AppendLine($"总计伤害:{stats.TotalDamage} / 总计物理伤害:{stats.TotalPhysicalDamage} / 总计魔法伤害:{stats.TotalMagicDamage}"); mvpBuilder.AppendLine($"总承受伤害:{stats.TotalTakenDamage} / 总承受物理伤害:{stats.TotalTakenPhysicalDamage} / 总承受魔法伤害:{stats.TotalTakenMagicDamage}"); mvpBuilder.Append($"每秒伤害:{stats.DamagePerSecond} / 每回合伤害:{stats.DamagePerTurn}"); } // 赛后数据 StringBuilder ratingBuilder = new(); ratingBuilder.AppendLine($"=== 赛后数据 ==="); foreach (Team team in teams) { ratingBuilder.AppendLine($"☆--- [ {team} ] ---☆"); foreach (Character character in actionQueue.CharacterStatistics.Where(d => team.Members.Contains(d.Key)) .OrderByDescending(d => d.Value.Rating).Select(d => d.Key)) { CharacterStatistics stats = actionQueue.CharacterStatistics[character]; ratingBuilder.AppendLine($"[ {stats.Rating:0.0#} ] {character}({stats.Kills} / {stats.Assists} / {stats.Deaths})"); if (character.User != null) { character.User.Inventory.Credits += stats.TotalEarnedMoney; } } } Result.Add(mvpBuilder.ToString() + "\r\n\r\n" + ratingBuilder.ToString()); } return Result; } catch (Exception ex) { Console.WriteLine(ex); return [ex.ToString()]; } } public void WriteLine(string str) { _msg += str + "\r\n"; if (PrintOut) Console.WriteLine(str); } public static List NewAndStartGame(List characters, bool printout = false, bool isWeb = false, bool deathMatchRoundDetail = false, bool showRoundEndDetail = false, bool showAllRound = false) { return new FunGameActionQueue().StartGame(characters, printout, isWeb, deathMatchRoundDetail, showRoundEndDetail, showAllRound); } public static List NewAndStartTeamGame(List teams, int maxRespawnTimes = 0, int maxScoreToWin = 0, bool printout = false, bool isWeb = false, bool deathMatchRoundDetail = false, bool showRoundEndDetail = false, bool showAllRound = false) { return new FunGameActionQueue().StartTeamGame(teams, maxRespawnTimes, maxScoreToWin, printout, isWeb, deathMatchRoundDetail, showRoundEndDetail, showAllRound); } } }