using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Library.Constant; namespace Milimoe.FunGame.Core.Model { public class TeamGamingQueue : GamingQueue { /// /// 当前团灭的团队顺序(第一个是最早死的) /// public List EliminatedTeams => _eliminatedTeams; /// /// 团队及其成员 /// public Dictionary Teams => _teams; /// /// 当前团灭的团队顺序(第一个是最早死的) /// protected readonly List _eliminatedTeams = []; /// /// 团队及其成员 /// protected readonly Dictionary _teams = []; /// /// 添加一个团队 /// /// /// public void AddTeam(string teamName, IEnumerable characters) { if (teamName != "" && characters.Any()) { _teams.Add(teamName, new(teamName, characters)); } } /// /// 获取角色的团队 /// /// public Team? GetTeam(Character character) { foreach (Team team in _teams.Values) { if (team.IsOnThisTeam(character)) { return team; } } return null; } /// /// 从已淘汰的团队中获取角色的团队 /// /// public Team? GetTeamFromEliminated(Character character) { foreach (Team team in _eliminatedTeams) { if (team.IsOnThisTeam(character)) { return team; } } return null; } /// /// 获取某角色的团队成员 /// /// protected override List GetTeammates(Character character) { foreach (string team in _teams.Keys) { if (_teams[team].IsOnThisTeam(character)) { return _teams[team].GetTeammates(character); } } return []; } /// /// 角色行动后 /// /// /// /// protected override async Task AfterCharacterAction(Character character, CharacterActionType type) { // 如果目标都是队友,会考虑非伤害型助攻 Team? team = GetTeam(character); if (team != null) { SetNotDamageAssistTime(character, LastRound.Targets.Where(team.IsOnThisTeam)); } else await Task.CompletedTask; } /// /// 死亡结算时 /// /// /// /// protected override async Task OnDeathCalculation(Character death, Character killer) { Team? team = GetTeam(killer); if (team != null) { team.Score++; } else await Task.CompletedTask; } /// /// 死亡结算后 /// /// /// /// protected override async Task AfterDeathCalculation(Character death, Character killer) { Team? killTeam = GetTeam(killer); Team? deathTeam = GetTeam(death); if (MaxRespawnTimes != 0) { string[] teamActive = [.. Teams.OrderByDescending(kv => kv.Value.Score).Select(kv => { int activeCount = kv.Value.GetActiveCharacters(this).Count; if (kv.Value == killTeam) { activeCount += 1; } return kv.Key + ":" + kv.Value.Score + "(剩余存活人数:" + activeCount + ")"; })]; WriteLine($"\r\n=== 当前死亡竞赛比分 ===\r\n{string.Join("\r\n", teamActive)}"); } if (deathTeam != null) { List remain = deathTeam.GetActiveCharacters(this); int remainCount = remain.Count; if (remainCount == 0) { // 团灭了 _eliminatedTeams.Add(deathTeam); _teams.Remove(deathTeam.Name); } else if (MaxRespawnTimes == 0) { WriteLine($"[ {deathTeam} ] 剩余成员:[ {string.Join(" ] / [ ", remain)} ]({remainCount} 人)"); } } if (killTeam != null) { List actives = killTeam.GetActiveCharacters(this); actives.Add(killer); int remainCount = actives.Count; if (remainCount > 0 && MaxRespawnTimes == 0) { WriteLine($"[ {killTeam} ] 剩余成员:[ {string.Join(" ] / [ ", actives)} ]({remainCount} 人)"); } if (!_teams.Keys.Where(str => str != killTeam.Name).Any()) { // 没有其他的团队了,游戏结束 await EndGameInfo(killTeam); return; } if (MaxScoreToWin > 0 && killTeam.Score >= MaxScoreToWin) { List combinedTeams = [.. _eliminatedTeams, .. _teams.Values]; combinedTeams.Remove(killTeam); _eliminatedTeams.Clear(); _eliminatedTeams.AddRange(combinedTeams.OrderByDescending(t => t.Score)); await EndGameInfo(killTeam); return; } } } /// /// 游戏结束信息 [ 团队版 ] /// public async Task EndGameInfo(Team winner) { winner.IsWinner = true; WriteLine("[ " + winner + " ] 是胜利者。"); if (!await OnGameEndTeamAsync(winner)) { return; } int top = 1; WriteLine(""); WriteLine("=== 排名 ==="); WriteLine(""); _eliminatedTeams.Add(winner); _teams.Remove(winner.Name); for (int i = _eliminatedTeams.Count - 1; i >= 0; i--) { Team team = _eliminatedTeams[i]; string topTeam = ""; if (top == 1) { topTeam = "冠军"; } if (top == 2) { topTeam = "亚军"; } if (top == 3) { topTeam = "季军"; } if (top > 3) { topTeam = $"第 {top} 名"; } topTeam = $"☆--- {topTeam}团队:" + team.Name + " ---☆" + $"(得分:{team.Score})\r\n"; foreach (Character ec in team.Members) { CharacterStatistics statistics = CharacterStatistics[ec]; string respawning = ""; if (ec.HP <= 0) { respawning = "[ " + (_respawnCountdown.TryGetValue(ec, out double time) && time > 0 ? $"{time:0.##} {GameplayEquilibriumConstant.InGameTime}后复活" : "阵亡") + " ] "; } string topCharacter = respawning + ec.ToString() + (statistics.FirstKills > 0 ? " [ 第一滴血 ]" : "") + (_maxContinuousKilling.TryGetValue(ec, out int kills) && kills > 1 ? $" [ {CharacterSet.GetContinuousKilling(kills)} ]" : "") + (_earnedMoney.TryGetValue(ec, out int earned) ? $" [ 已赚取 {earned} {GameplayEquilibriumConstant.InGameCurrency} ]" : "") + $"({statistics.Kills} / {statistics.Assists}{(MaxRespawnTimes != 0 ? " / " + statistics.Deaths : "")})"; topTeam += topCharacter + "\r\n"; if (top == 1) { _stats[ec].Wins += 1; _stats[ec].Top3s += 1; } else if (top == 2) { _stats[ec].Loses += 1; _stats[ec].Top3s += 1; } else if (top == 3) { _stats[ec].Loses += 1; _stats[ec].Top3s += 1; } else { _stats[ec].Loses += 1; } _stats[ec].Plays += 1; _stats[ec].TotalEarnedMoney += earned; _stats[ec].LastRank = top; } WriteLine(topTeam); top++; } WriteLine(""); _isGameEnd = true; } /// /// 创建一个团队游戏队列 /// /// public TeamGamingQueue(Action? writer = null) : base(writer) { } /// /// 创建一个团队游戏队列并初始化行动顺序表 /// /// /// public TeamGamingQueue(List characters, Action? writer = null) : base(characters, writer) { } public delegate Task GameEndTeamEventHandler(TeamGamingQueue queue, Team winner); /// /// 游戏结束事件(团队版) /// public event GameEndTeamEventHandler? GameEndTeam; /// /// 游戏结束事件(团队版) /// /// /// protected async Task OnGameEndTeamAsync(Team winner) { return await (GameEndTeam?.Invoke(this, winner) ?? Task.FromResult(true)); } } }