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));
}
}
}