删除异步,添加新技能

This commit is contained in:
milimoe 2026-01-08 01:34:13 +08:00
parent 7a06a64dd5
commit 765b42155e
Signed by: milimoe
GPG Key ID: 9554D37E4B8991D0
6 changed files with 188 additions and 109 deletions

View File

@ -53,11 +53,11 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
}); });
} }
public async Task SetPreCastSuperSkill(Character character, Skill skill) public void SetPreCastSuperSkill(Character character, Skill skill)
{ {
if (_game != null) if (_game != null)
{ {
await _game.SetPreCastSuperSkill(character, skill); _game.SetPreCastSuperSkill(character, skill);
} }
} }

View File

@ -3,6 +3,7 @@ using Milimoe.FunGame.Core.Api.Utility;
using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface.Entity; using Milimoe.FunGame.Core.Interface.Entity;
using Milimoe.FunGame.Core.Library.Common.Addon; using Milimoe.FunGame.Core.Library.Common.Addon;
using Milimoe.FunGame.Core.Library.Common.Architecture;
using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.Constant;
using Milimoe.FunGame.Core.Model; using Milimoe.FunGame.Core.Model;
using Oshima.Core.Constant; using Oshima.Core.Constant;
@ -60,12 +61,18 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
c.Level = clevel; c.Level = clevel;
c.NormalAttack.Level = mlevel; c.NormalAttack.Level = mlevel;
FunGameService.AddCharacterSkills(c, 1, slevel, slevel); FunGameService.AddCharacterSkills(c, 1, slevel, slevel);
//Skill test = new 钻石星尘 Skill test = new
//{ {
// Character = c, Character = c,
// Level = 8 Level = 8
//}; };
//c.Skills.Add(test); c.Skills.Add(test);
Skill test2 = new
{
Character = c,
Level = 8
};
c.Skills.Add(test2);
foreach (Skill skillLoop in FunGameConstant.Skills) foreach (Skill skillLoop in FunGameConstant.Skills)
{ {
Skill skill = skillLoop.Copy(); Skill skill = skillLoop.Copy();
@ -222,22 +229,22 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
} }
} }
await Controller.SetGameMap(map); await Controller.SetGameMap(map);
_gamingQueue.SelectTargetGrid += GamingQueue_SelectTargetGrid; _gamingQueue.SelectTargetGridEvent += GamingQueue_SelectTargetGrid;
_gamingQueue.CharacterMove += GamingQueue_CharacterMove; _gamingQueue.CharacterMoveEvent += GamingQueue_CharacterMove;
} }
// 绑定事件 // 绑定事件
await Controller.SetQueue(_gamingQueue.HardnessTime); await Controller.SetQueue(_gamingQueue.HardnessTime);
await Controller.SetCharacterStatistics(_gamingQueue.CharacterStatistics); await Controller.SetCharacterStatistics(_gamingQueue.CharacterStatistics);
_gamingQueue.TurnStart += GamingQueue_TurnStart; _gamingQueue.TurnStartEvent += GamingQueue_TurnStart;
_gamingQueue.DecideAction += GamingQueue_DecideAction; _gamingQueue.DecideActionEvent += GamingQueue_DecideAction;
_gamingQueue.SelectNormalAttackTargets += GamingQueue_SelectNormalAttackTargets; _gamingQueue.SelectNormalAttackTargetsEvent += GamingQueue_SelectNormalAttackTargets;
_gamingQueue.SelectSkill += GamingQueue_SelectSkill; _gamingQueue.SelectSkillEvent += GamingQueue_SelectSkill;
_gamingQueue.SelectSkillTargets += GamingQueue_SelectSkillTargets; _gamingQueue.SelectSkillTargetsEvent += GamingQueue_SelectSkillTargets;
_gamingQueue.SelectNonDirectionalSkillTargets += GamingQueue_SelectNonDirectionalSkillTargets; _gamingQueue.SelectNonDirectionalSkillTargetsEvent += GamingQueue_SelectNonDirectionalSkillTargets;
_gamingQueue.SelectItem += GamingQueue_SelectItem; _gamingQueue.SelectItemEvent += GamingQueue_SelectItem;
_gamingQueue.QueueUpdated += GamingQueue_QueueUpdated; _gamingQueue.QueueUpdatedEvent += GamingQueue_QueueUpdated;
_gamingQueue.TurnEnd += GamingQueue_TurnEnd; _gamingQueue.TurnEndEvent += GamingQueue_TurnEnd;
// 总游戏时长 // 总游戏时长
double totalTime = 0; double totalTime = 0;
@ -322,11 +329,11 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
foreach (Character c in characters.Where(c => c != winner && c.HP > 0)) foreach (Character c in characters.Where(c => c != winner && c.HP > 0))
{ {
await Controller.WriteLine("[ " + winner + " ] 对 [ " + c + " ] 造成了 99999999999 点真实伤害。"); await Controller.WriteLine("[ " + winner + " ] 对 [ " + c + " ] 造成了 99999999999 点真实伤害。");
await _gamingQueue.DeathCalculationAsync(winner, c); _gamingQueue.DeathCalculation(winner, c);
} }
if (mgq != null) if (mgq != null)
{ {
await mgq.EndGameInfo(winner); mgq.EndGameInfo(winner);
} }
} }
result.Add(Msg); result.Add(Msg);
@ -334,7 +341,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
} }
// 检查是否有角色可以行动 // 检查是否有角色可以行动
Character? characterToAct = await _gamingQueue.NextCharacterAsync(); Character? characterToAct = _gamingQueue.NextCharacter();
DecisionPoints dp = GetDP(_gamingQueue); DecisionPoints dp = GetDP(_gamingQueue);
await Controller.UpdateQueue(dp); await Controller.UpdateQueue(dp);
await Controller.UpdateCharacterPositionsOnMap(); await Controller.UpdateCharacterPositionsOnMap();
@ -357,7 +364,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
try try
{ {
isGameEnd = await _gamingQueue.ProcessTurnAsync(characterToAct); isGameEnd = _gamingQueue.ProcessTurn(characterToAct);
} }
catch (Exception e) catch (Exception e)
{ {
@ -382,7 +389,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
} }
// 模拟时间流逝 // 模拟时间流逝
double timeLapse = await _gamingQueue.TimeLapse(); double timeLapse = _gamingQueue.TimeLapse();
totalTime += timeLapse; totalTime += timeLapse;
nextDropItemTime -= timeLapse; nextDropItemTime -= timeLapse;
dp = GetDP(_gamingQueue); dp = GetDP(_gamingQueue);
@ -530,7 +537,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
} }
} }
private async Task<Grid> GamingQueue_SelectTargetGrid(GamingQueue queue, Character character, List<Character> enemys, List<Character> teammates, GameMap map, List<Grid> moveRange) private Grid GamingQueue_SelectTargetGrid(GamingQueue queue, Character character, List<Character> enemys, List<Character> teammates, GameMap map, List<Grid> moveRange)
{ {
if (!IsPlayer_OnlyTest(queue, character) || _gamingQueue is null || _gamingQueue.Map is null) return Grid.Empty; if (!IsPlayer_OnlyTest(queue, character) || _gamingQueue is null || _gamingQueue.Map is null) return Grid.Empty;
@ -545,63 +552,63 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
} }
// 通过UI请求目标选择 // 通过UI请求目标选择
Grid? selectedTargetGrid = await Controller.RequestTargetGridSelection( Grid? selectedTargetGrid = SyncAwaiter.WaitResult(Controller.RequestTargetGridSelection(
character, character,
current, current,
_gamingQueue.Map.GetGridsByRange(current, character.MOV) _gamingQueue.Map.GetGridsByRange(current, character.MOV)
); ));
await Controller.ResolveTargetGridSelection(selectedTargetGrid); SyncAwaiter.Wait(Controller.ResolveTargetGridSelection(selectedTargetGrid));
return selectedTargetGrid ?? Grid.Empty; return selectedTargetGrid ?? Grid.Empty;
} }
private async Task GamingQueue_CharacterMove(GamingQueue queue, Character actor, DecisionPoints dp, Grid grid) private void GamingQueue_CharacterMove(GamingQueue queue, Character actor, DecisionPoints dp, Grid grid)
{ {
await Controller.UpdateCharacterPositionsOnMap(); SyncAwaiter.Wait(Controller.UpdateCharacterPositionsOnMap());
} }
private async Task GamingQueue_QueueUpdated(GamingQueue queue, List<Character> characters, Character character, DecisionPoints dp, double hardnessTime, QueueUpdatedReason reason, string msg) private void GamingQueue_QueueUpdated(GamingQueue queue, List<Character> characters, Character character, DecisionPoints dp, double hardnessTime, QueueUpdatedReason reason, string msg)
{ {
if (reason != QueueUpdatedReason.Action) if (reason != QueueUpdatedReason.Action)
{ {
await Controller.UpdateQueue(dp); SyncAwaiter.Wait(Controller.UpdateQueue(dp));
} }
} }
private async Task<bool> GamingQueue_TurnStart(GamingQueue queue, Character character, DecisionPoints dp, List<Character> enemys, List<Character> teammates, List<Skill> skills, List<Item> items) private bool GamingQueue_TurnStart(GamingQueue queue, Character character, DecisionPoints dp, List<Character> enemys, List<Character> teammates, List<Skill> skills, List<Item> items)
{ {
await Controller.UpdateBottomInfoPanel(dp); SyncAwaiter.Wait(Controller.UpdateBottomInfoPanel(dp));
return true; return true;
} }
private async Task<List<Character>> GamingQueue_SelectNormalAttackTargets(GamingQueue queue, Character character, NormalAttack attack, List<Character> enemys, List<Character> teammates, List<Grid> attackRange) private List<Character> GamingQueue_SelectNormalAttackTargets(GamingQueue queue, Character character, NormalAttack attack, List<Character> enemys, List<Character> teammates, List<Grid> attackRange)
{ {
if (!IsPlayer_OnlyTest(queue, character)) return []; if (!IsPlayer_OnlyTest(queue, character)) return [];
// 通过UI请求目标选择 // 通过UI请求目标选择
List<Character> selectedTargets = await Controller.RequestTargetSelection( List<Character> selectedTargets = SyncAwaiter.WaitResult(Controller.RequestTargetSelection(
character, character,
attack, attack,
enemys, enemys,
teammates, teammates,
attackRange attackRange
); ));
await Controller.ResolveTargetSelection(selectedTargets); SyncAwaiter.Wait(Controller.ResolveTargetSelection(selectedTargets));
return selectedTargets ?? []; // 如果取消,返回空列表 return selectedTargets ?? []; // 如果取消,返回空列表
} }
private async Task<Item?> GamingQueue_SelectItem(GamingQueue queue, Character character, List<Item> items) private Item? GamingQueue_SelectItem(GamingQueue queue, Character character, List<Item> items)
{ {
if (!IsPlayer_OnlyTest(queue, character)) return null; if (!IsPlayer_OnlyTest(queue, character)) return null;
// 通过UI请求物品选择 // 通过UI请求物品选择
Item? selectedItem = await Controller.RequestItemSelection(character, items); Item? selectedItem = SyncAwaiter.WaitResult(Controller.RequestItemSelection(character, items));
await Controller.ResolveItemSelection(selectedItem); SyncAwaiter.Wait(Controller.ResolveItemSelection(selectedItem));
return selectedItem; return selectedItem;
} }
private async Task<List<Character>> GamingQueue_SelectSkillTargets(GamingQueue queue, Character caster, Skill skill, List<Character> enemys, List<Character> teammates, List<Grid> castRange) private List<Character> GamingQueue_SelectSkillTargets(GamingQueue queue, Character caster, Skill skill, List<Character> enemys, List<Character> teammates, List<Grid> castRange)
{ {
if (!IsPlayer_OnlyTest(queue, caster)) return []; if (!IsPlayer_OnlyTest(queue, caster)) return [];
@ -611,19 +618,19 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
if (skill.CanSelectSelf) potentialTargets.Add(caster); if (skill.CanSelectSelf) potentialTargets.Add(caster);
// 通过UI请求目标选择 // 通过UI请求目标选择
List<Character>? selectedTargets = await Controller.RequestTargetSelection( List<Character>? selectedTargets = SyncAwaiter.WaitResult(Controller.RequestTargetSelection(
caster, caster,
skill, skill,
enemys, enemys,
teammates, teammates,
castRange castRange
); ));
await Controller.ResolveTargetSelection(selectedTargets); SyncAwaiter.Wait(Controller.ResolveTargetSelection(selectedTargets));
return selectedTargets ?? []; // 如果取消,返回空列表 return selectedTargets ?? []; // 如果取消,返回空列表
} }
private async Task<List<Grid>> GamingQueue_SelectNonDirectionalSkillTargets(GamingQueue queue, Character caster, Skill skill, List<Character> enemys, List<Character> teammates, List<Grid> castRange) private List<Grid> GamingQueue_SelectNonDirectionalSkillTargets(GamingQueue queue, Character caster, Skill skill, List<Character> enemys, List<Character> teammates, List<Grid> castRange)
{ {
if (!IsPlayer_OnlyTest(queue, caster) || _gamingQueue is null || _gamingQueue.Map is null) return []; if (!IsPlayer_OnlyTest(queue, caster) || _gamingQueue is null || _gamingQueue.Map is null) return [];
@ -643,59 +650,59 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
} }
// 通过UI请求目标选择 // 通过UI请求目标选择
List<Grid>? selectedTargets = await Controller.RequestTargetGridsSelection( List<Grid>? selectedTargets = SyncAwaiter.WaitResult(Controller.RequestTargetGridsSelection(
caster, caster,
skill, skill,
enemys, enemys,
teammates, teammates,
current, current,
castRange castRange
); ));
await Controller.ResolveTargetGridsSelection(selectedTargets); SyncAwaiter.Wait(Controller.ResolveTargetGridsSelection(selectedTargets));
return selectedTargets ?? []; // 如果取消,返回空列表 return selectedTargets ?? []; // 如果取消,返回空列表
} }
private async Task<Skill?> GamingQueue_SelectSkill(GamingQueue queue, Character character, List<Skill> skills) private Skill? GamingQueue_SelectSkill(GamingQueue queue, Character character, List<Skill> skills)
{ {
if (!IsPlayer_OnlyTest(queue, character)) return null; if (!IsPlayer_OnlyTest(queue, character)) return null;
// 通过UI请求技能选择 // 通过UI请求技能选择
Skill? selectedSkill = await Controller.RequestSkillSelection(character, skills); Skill? selectedSkill = SyncAwaiter.WaitResult(Controller.RequestSkillSelection(character, skills));
await Controller.ResolveSkillSelection(selectedSkill); SyncAwaiter.Wait(Controller.ResolveSkillSelection(selectedSkill));
return selectedSkill; return selectedSkill;
} }
private async Task GamingQueue_TurnEnd(GamingQueue queue, Character character, DecisionPoints dp) private void GamingQueue_TurnEnd(GamingQueue queue, Character character, DecisionPoints dp)
{ {
double ht = queue.HardnessTime[character]; double ht = queue.HardnessTime[character];
await Controller.SetPredictCharacter(character.NickName, ht); SyncAwaiter.Wait(Controller.SetPredictCharacter(character.NickName, ht));
await Controller.UpdateBottomInfoPanel(dp); SyncAwaiter.Wait(Controller.UpdateBottomInfoPanel(dp));
if (!_fastMode) if (!_fastMode)
{ {
if (IsRoundHasPlayer_OnlyTest(queue, character)) if (IsRoundHasPlayer_OnlyTest(queue, character))
{ {
// 玩家回合结束,等待玩家确认 // 玩家回合结束,等待玩家确认
await Controller.RequestContinuePrompt("你的回合(或与你相关的回合)已结束,请查看本回合日志,然后点击继续. . ."); SyncAwaiter.Wait(Controller.RequestContinuePrompt("你的回合(或与你相关的回合)已结束,请查看本回合日志,然后点击继续. . ."));
await Controller.ResolveContinuePrompt(); SyncAwaiter.Wait(Controller.ResolveContinuePrompt());
} }
else else
{ {
await Controller.RequestCountDownContinuePrompt("该角色的回合已结束. . ."); SyncAwaiter.Wait(Controller.RequestCountDownContinuePrompt("该角色的回合已结束. . ."));
await Controller.ResolveCountDownContinuePrompt(); SyncAwaiter.Wait(Controller.ResolveCountDownContinuePrompt());
} }
} }
else await Task.Delay(100); else Thread.Sleep(100);
} }
private async Task<CharacterActionType> GamingQueue_DecideAction(GamingQueue queue, Character character, DecisionPoints dp , List<Character> enemys, List<Character> teammates, List<Skill> skills, List<Item> items) private CharacterActionType GamingQueue_DecideAction(GamingQueue queue, Character character, DecisionPoints dp , List<Character> enemys, List<Character> teammates, List<Skill> skills, List<Item> items)
{ {
if (IsPlayer_OnlyTest(queue, character)) if (IsPlayer_OnlyTest(queue, character))
{ {
// 通过UI按钮请求行动类型 // 通过UI按钮请求行动类型
await Controller.UpdateCharacterPositionsOnMap(); SyncAwaiter.Wait(Controller.UpdateCharacterPositionsOnMap());
CharacterActionType actionType = await Controller.RequestActionType(character, items); CharacterActionType actionType = SyncAwaiter.WaitResult(Controller.RequestActionType(character, items));
await Controller.ResolveActionType(actionType); SyncAwaiter.Wait(Controller.ResolveActionType(actionType));
return actionType; return actionType;
} }
return CharacterActionType.None; // 非玩家角色由AI处理或默认None return CharacterActionType.None; // 非玩家角色由AI处理或默认None
@ -726,11 +733,11 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
return queue.CustomData.TryGetValue("player", out object? value) && value is Character player && (player == current || (current.CharacterState != CharacterState.Casting && queue.LastRound.Targets.Values.SelectMany(c => c).Any(c => c == player))); return queue.CustomData.TryGetValue("player", out object? value) && value is Character player && (player == current || (current.CharacterState != CharacterState.Casting && queue.LastRound.Targets.Values.SelectMany(c => c).Any(c => c == player)));
} }
public async Task SetPreCastSuperSkill(Character character, Skill skill) public void SetPreCastSuperSkill(Character character, Skill skill)
{ {
if (_gamingQueue is GamingQueue queue) if (_gamingQueue is GamingQueue queue)
{ {
await queue.SetCharacterPreCastSuperSkill(character, skill); queue.SetCharacterPreCastSuperSkill(character, skill);
} }
} }

View File

@ -356,7 +356,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
return; return;
} }
int maxLines = 150; int maxLines = 250;
// 获取 FlowDocument // 获取 FlowDocument
FlowDocument doc = DebugLogRichTextBox.Document; FlowDocument doc = DebugLogRichTextBox.Document;
@ -372,6 +372,9 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
doc.Blocks.Clear(); doc.Blocks.Clear();
} }
// 获取当前滚动位置
double verticalOffsetBefore = DebugLogScrollViewer.VerticalOffset;
// 添加新的段落 // 添加新的段落
Paragraph newParagraph = new(new Run(message)) Paragraph newParagraph = new(new Run(message))
{ {
@ -385,10 +388,40 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
doc.Blocks.Remove(doc.Blocks.FirstBlock); doc.Blocks.Remove(doc.Blocks.FirstBlock);
} }
bool wasAtBottom = verticalOffsetBefore == 0;
if (wasAtBottom)
{
// 滚动到底部 // 滚动到底部
DebugLogRichTextBox.ScrollToEnd(); DebugLogRichTextBox.ScrollToEnd();
DebugLogScrollViewer.ScrollToEnd(); DebugLogScrollViewer.ScrollToEnd();
} }
}
/// <summary>
/// 判断滚动条是否在最底部
/// </summary>
private bool IsScrollViewerAtBottom()
{
// 检查 DebugLogScrollViewer
if (DebugLogScrollViewer != null)
{
// 使用一个小容差值来处理浮点数精度问题
const double tolerance = 0.1;
double verticalOffset = DebugLogScrollViewer.VerticalOffset;
double scrollableHeight = DebugLogScrollViewer.ScrollableHeight;
// 如果可滚动高度很小或为0说明内容不足一屏视为在底部
if (scrollableHeight <= 0)
return true;
// 检查是否已经滚动到底部(容差范围内)
return Math.Abs(verticalOffset - scrollableHeight) <= tolerance;
}
// 如果没有找到滚动条,默认返回 true 以保持原有行为
return true;
}
private void CurrentRoundChanged() private void CurrentRoundChanged()
{ {
@ -1368,7 +1401,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
Skill? skill = PlayerCharacter.Skills.FirstOrDefault(s => s.IsSuperSkill && s.Enable && s.CurrentCD == 0 && s.RealEPCost <= PlayerCharacter.EP); Skill? skill = PlayerCharacter.Skills.FirstOrDefault(s => s.IsSuperSkill && s.Enable && s.CurrentCD == 0 && s.RealEPCost <= PlayerCharacter.EP);
if (skill != null) if (skill != null)
{ {
await _controller.SetPreCastSuperSkill(PlayerCharacter, skill); _controller.SetPreCastSuperSkill(PlayerCharacter, skill);
} }
else else
{ {

View File

@ -0,0 +1,42 @@
namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
{
public static class SyncAwaiter
{
/// <summary>
/// 在同步方法中安全等待一个 Task 完成并获取结果
/// 内部使用 ManualResetEventSlim避免死锁
/// </summary>
public static T WaitResult<T>(Task<T> task)
{
if (task.IsCompleted)
return task.Result;
ManualResetEventSlim mres = new(false);
// 当 task 完成时,设置事件信号
task.ContinueWith(_ =>
{
mres.Set();
}, TaskScheduler.Default);
// 阻塞当前线程直到 task 完成
// 注意:这会阻塞调用线程!
mres.Wait();
// 现在可以安全取 Result不会抛死锁
return task.Result;
}
/// <summary>
/// 无返回值版本
/// </summary>
public static void Wait(Task task)
{
if (task.IsCompleted) return;
ManualResetEventSlim mres = new(false);
task.ContinueWith(_ => mres.Set(), TaskScheduler.Default);
mres.Wait();
}
}
}

View File

@ -37,23 +37,23 @@ namespace Milimoe.FunGame.Testing.Tests
skill.GamingQueue = queue; skill.GamingQueue = queue;
skill.Character = teammate; skill.Character = teammate;
skill.Level += 6; skill.Level += 6;
await skill.OnSkillCasted(queue, teammate, [character], []); skill.OnSkillCasted(queue, teammate, [character], []);
await skill.OnSkillCasted(queue, teammate, [character], []); skill.OnSkillCasted(queue, teammate, [character], []);
Character enemy = new CustomCharacter(1, "敌人"); Character enemy = new CustomCharacter(1, "敌人");
Console.ReadKey(); Console.ReadKey();
enemy.SetLevel(60); enemy.SetLevel(60);
skill = new (enemy); skill = new (enemy);
skill.GamingQueue = queue; skill.GamingQueue = queue;
skill.Level += 8; skill.Level += 8;
await skill.OnSkillCasted(queue, enemy, [teammate], []); skill.OnSkillCasted(queue, enemy, [teammate], []);
queue.CharacterStatistics[teammate] = new CharacterStatistics(); queue.CharacterStatistics[teammate] = new CharacterStatistics();
queue.AddCharacter(teammate, 10); queue.AddCharacter(teammate, 10);
await queue.TimeLapse(); queue.TimeLapse();
Console.WriteLine(teammate.GetInfo()); Console.WriteLine(teammate.GetInfo());
skill = new (enemy); skill = new (enemy);
skill.GamingQueue = queue; skill.GamingQueue = queue;
skill.Level += 8; skill.Level += 8;
await skill.OnSkillCasted(queue, enemy, [character], []); skill.OnSkillCasted(queue, enemy, [character], []);
character.UnEquip(EquipSlotType.Armor); character.UnEquip(EquipSlotType.Armor);
Console.WriteLine(character.GetInfo()); Console.WriteLine(character.GetInfo());
Console.ReadKey(); Console.ReadKey();

View File

@ -21,7 +21,7 @@ namespace Milimoe.FunGame.Testing.Tests
public static bool PrintOut { get; set; } = false; public static bool PrintOut { get; set; } = false;
public static string Msg { get; set; } = ""; public static string Msg { get; set; } = "";
public static async Task<List<string>> StartGame(bool printout, bool isWeb = false) public static List<string> StartGame(bool printout, bool isWeb = false)
{ {
PrintOut = printout; PrintOut = printout;
IsWeb = isWeb; IsWeb = isWeb;
@ -80,7 +80,7 @@ namespace Milimoe.FunGame.Testing.Tests
// 询问玩家需要选择哪个角色 // 询问玩家需要选择哪个角色
Character? player = null; Character? player = null;
await Task.Run(() => Task.Run(() =>
{ {
while (player is null) while (player is null)
{ {
@ -110,14 +110,14 @@ namespace Milimoe.FunGame.Testing.Tests
if (PrintOut) Console.WriteLine(); if (PrintOut) Console.WriteLine();
// 绑定事件 // 绑定事件
gamingQueue.TurnStart += GamingQueue_TurnStart; gamingQueue.TurnStartEvent += GamingQueue_TurnStart;
gamingQueue.DecideAction += GamingQueue_DecideAction; gamingQueue.DecideActionEvent += GamingQueue_DecideAction;
gamingQueue.SelectNormalAttackTargets += GamingQueue_SelectNormalAttackTargets; gamingQueue.SelectNormalAttackTargetsEvent += GamingQueue_SelectNormalAttackTargets;
gamingQueue.SelectSkill += GamingQueue_SelectSkill; gamingQueue.SelectSkillEvent += GamingQueue_SelectSkill;
gamingQueue.SelectSkillTargets += GamingQueue_SelectSkillTargets; gamingQueue.SelectSkillTargetsEvent += GamingQueue_SelectSkillTargets;
gamingQueue.SelectItem += GamingQueue_SelectItem; gamingQueue.SelectItemEvent += GamingQueue_SelectItem;
gamingQueue.QueueUpdated += GamingQueue_QueueUpdated; gamingQueue.QueueUpdatedEvent += GamingQueue_QueueUpdated;
gamingQueue.TurnEnd += GamingQueue_TurnEnd; gamingQueue.TurnEndEvent += GamingQueue_TurnEnd;
// 总游戏时长 // 总游戏时长
double totalTime = 0; double totalTime = 0;
@ -208,15 +208,15 @@ namespace Milimoe.FunGame.Testing.Tests
foreach (Character c in characters.Where(c => c != winner && c.HP > 0)) foreach (Character c in characters.Where(c => c != winner && c.HP > 0))
{ {
WriteLine("[ " + winner + " ] 对 [ " + c + " ] 造成了 99999999999 点真实伤害。"); WriteLine("[ " + winner + " ] 对 [ " + c + " ] 造成了 99999999999 点真实伤害。");
await gamingQueue.DeathCalculationAsync(winner, c); gamingQueue.DeathCalculation(winner, c);
} }
await gamingQueue.EndGameInfo(winner); gamingQueue.EndGameInfo(winner);
result.Add(Msg); result.Add(Msg);
break; break;
} }
// 检查是否有角色可以行动 // 检查是否有角色可以行动
Character? characterToAct = await gamingQueue.NextCharacterAsync(); Character? characterToAct = gamingQueue.NextCharacter();
// 处理回合 // 处理回合
if (characterToAct != null) if (characterToAct != null)
@ -224,7 +224,7 @@ namespace Milimoe.FunGame.Testing.Tests
WriteLine($"=== Round {i++} ==="); WriteLine($"=== Round {i++} ===");
WriteLine("现在是 [ " + characterToAct + " ] 的回合!"); WriteLine("现在是 [ " + characterToAct + " ] 的回合!");
bool isGameEnd = await gamingQueue.ProcessTurnAsync(characterToAct); bool isGameEnd = gamingQueue.ProcessTurn(characterToAct);
if (isGameEnd) if (isGameEnd)
{ {
@ -244,7 +244,7 @@ namespace Milimoe.FunGame.Testing.Tests
} }
// 模拟时间流逝 // 模拟时间流逝
double timeLapse = await gamingQueue.TimeLapse(); double timeLapse = gamingQueue.TimeLapse();
totalTime += timeLapse; totalTime += timeLapse;
nextDropItemTime -= timeLapse; nextDropItemTime -= timeLapse;
@ -397,7 +397,7 @@ namespace Milimoe.FunGame.Testing.Tests
} }
} }
private static async Task GamingQueue_QueueUpdated(GamingQueue queue, List<Character> characters, Character character, DecisionPoints dp, double hardnessTime, QueueUpdatedReason reason, string msg) private static void GamingQueue_QueueUpdated(GamingQueue queue, List<Character> characters, Character character, DecisionPoints dp, double hardnessTime, QueueUpdatedReason reason, string msg)
{ {
if (IsPlayer_OnlyTest(queue, character)) if (IsPlayer_OnlyTest(queue, character))
{ {
@ -412,30 +412,28 @@ namespace Milimoe.FunGame.Testing.Tests
// QueueUpdatedReason.PreCastSuperSkill 是指角色释放了爆发技 // QueueUpdatedReason.PreCastSuperSkill 是指角色释放了爆发技
// 通知玩家,让玩家知道下一次行动需要选择目标 // 通知玩家,让玩家知道下一次行动需要选择目标
Console.WriteLine($"你的下一回合需要选择爆发技目标,知晓请按任意键继续. . ."); Console.WriteLine($"你的下一回合需要选择爆发技目标,知晓请按任意键继续. . .");
await Console.In.ReadLineAsync(); Console.In.ReadLine();
} }
} }
await Task.CompletedTask;
} }
private static async Task<bool> GamingQueue_TurnStart(GamingQueue queue, Character character, DecisionPoints dp, List<Character> enemys, List<Character> teammates, List<Skill> skills, List<Item> items) private static bool GamingQueue_TurnStart(GamingQueue queue, Character character, DecisionPoints dp, List<Character> enemys, List<Character> teammates, List<Skill> skills, List<Item> items)
{ {
if (IsPlayer_OnlyTest(queue, character)) if (IsPlayer_OnlyTest(queue, character))
{ {
// 结束 AI 托管 // 结束 AI 托管
queue.SetCharactersToAIControl(cancel: true, character); queue.SetCharactersToAIControl(cancel: true, character);
await Task.CompletedTask;
} }
// 注意,此事件返回 false 将全程接管此回合。 // 注意,此事件返回 false 将全程接管此回合。
return true; return true;
} }
private static async Task<List<Character>> GamingQueue_SelectNormalAttackTargets(GamingQueue queue, Character character, NormalAttack attack, List<Character> enemys, List<Character> teammates, List<Grid> attackRange) private static List<Character> GamingQueue_SelectNormalAttackTargets(GamingQueue queue, Character character, NormalAttack attack, List<Character> enemys, List<Character> teammates, List<Grid> attackRange)
{ {
List<Character> characters = []; List<Character> characters = [];
if (IsPlayer_OnlyTest(queue, character)) if (IsPlayer_OnlyTest(queue, character))
{ {
await Task.Run(() => Task.Run(() =>
{ {
Console.WriteLine($"你的角色编号:{character.GetIdName()}"); Console.WriteLine($"你的角色编号:{character.GetIdName()}");
Console.WriteLine("【敌对角色列表】" + "\r\n" + string.Join("\r\n", enemys.Select(c => $"{c.GetIdName()}{c.GetSimpleInBattleInfo(queue.HardnessTime[c])}"))); Console.WriteLine("【敌对角色列表】" + "\r\n" + string.Join("\r\n", enemys.Select(c => $"{c.GetIdName()}{c.GetSimpleInBattleInfo(queue.HardnessTime[c])}")));
@ -500,13 +498,13 @@ namespace Milimoe.FunGame.Testing.Tests
return characters; return characters;
} }
private static async Task<Item?> GamingQueue_SelectItem(GamingQueue queue, Character character, List<Item> items) private static Item? GamingQueue_SelectItem(GamingQueue queue, Character character, List<Item> items)
{ {
Item? item = null; Item? item = null;
if (IsPlayer_OnlyTest(queue, character)) if (IsPlayer_OnlyTest(queue, character))
{ {
// 询问玩家需要选择哪个物品 // 询问玩家需要选择哪个物品
await Task.Run(() => Task.Run(() =>
{ {
Console.WriteLine(string.Join("\r\n", items.Select(i => $"{i.GetIdName()}{i}"))); Console.WriteLine(string.Join("\r\n", items.Select(i => $"{i.GetIdName()}{i}")));
while (item is null) while (item is null)
@ -532,12 +530,12 @@ namespace Milimoe.FunGame.Testing.Tests
return item; return item;
} }
private static async Task<List<Character>> GamingQueue_SelectSkillTargets(GamingQueue queue, Character caster, Skill skill, List<Character> enemys, List<Character> teammates, List<Grid> castRange) private static List<Character> GamingQueue_SelectSkillTargets(GamingQueue queue, Character caster, Skill skill, List<Character> enemys, List<Character> teammates, List<Grid> castRange)
{ {
List<Character> characters = []; List<Character> characters = [];
if (IsPlayer_OnlyTest(queue, caster)) if (IsPlayer_OnlyTest(queue, caster))
{ {
await Task.Run(() => Task.Run(() =>
{ {
Console.WriteLine($"你的角色编号:{caster.GetIdName()}"); Console.WriteLine($"你的角色编号:{caster.GetIdName()}");
Console.WriteLine("【敌对角色列表】" + "\r\n" + string.Join("\r\n", enemys.Select(c => $"{c.GetIdName()}{c.GetSimpleInBattleInfo(queue.HardnessTime[c])}"))); Console.WriteLine("【敌对角色列表】" + "\r\n" + string.Join("\r\n", enemys.Select(c => $"{c.GetIdName()}{c.GetSimpleInBattleInfo(queue.HardnessTime[c])}")));
@ -602,13 +600,13 @@ namespace Milimoe.FunGame.Testing.Tests
return characters; return characters;
} }
private static async Task<Skill?> GamingQueue_SelectSkill(GamingQueue queue, Character character, List<Skill> skills) private static Skill? GamingQueue_SelectSkill(GamingQueue queue, Character character, List<Skill> skills)
{ {
Skill? skill = null; Skill? skill = null;
if (IsPlayer_OnlyTest(queue, character)) if (IsPlayer_OnlyTest(queue, character))
{ {
// 询问玩家需要选择哪个技能 // 询问玩家需要选择哪个技能
await Task.Run(() => Task.Run(() =>
{ {
Console.WriteLine(string.Join("\r\n", skills.Select(s => $"{s.GetIdName()}{s}"))); Console.WriteLine(string.Join("\r\n", skills.Select(s => $"{s.GetIdName()}{s}")));
while (skill is null) while (skill is null)
@ -634,23 +632,22 @@ namespace Milimoe.FunGame.Testing.Tests
return skill; return skill;
} }
private static async Task GamingQueue_TurnEnd(GamingQueue queue, Character character, DecisionPoints dp) private static void GamingQueue_TurnEnd(GamingQueue queue, Character character, DecisionPoints dp)
{ {
if (IsRoundHasPlayer_OnlyTest(queue, character)) if (IsRoundHasPlayer_OnlyTest(queue, character))
{ {
// 暂停让玩家查看本回合日志 // 暂停让玩家查看本回合日志
Console.WriteLine("你的回合(或与你相关的回合)已结束,请查看本回合日志,然后按任意键继续. . ."); Console.WriteLine("你的回合(或与你相关的回合)已结束,请查看本回合日志,然后按任意键继续. . .");
await Console.In.ReadLineAsync(); Console.In.ReadLine();
} }
await Task.CompletedTask;
} }
private static async Task<CharacterActionType> GamingQueue_DecideAction(GamingQueue queue, Character character, DecisionPoints dp, List<Character> enemys, List<Character> teammates, List<Skill> skills, List<Item> items) private static CharacterActionType GamingQueue_DecideAction(GamingQueue queue, Character character, DecisionPoints dp, List<Character> enemys, List<Character> teammates, List<Skill> skills, List<Item> items)
{ {
CharacterActionType type = CharacterActionType.None; CharacterActionType type = CharacterActionType.None;
if (IsPlayer_OnlyTest(queue, character)) if (IsPlayer_OnlyTest(queue, character))
{ {
await Task.Run(() => Task.Run(() =>
{ {
Console.WriteLine(character.GetSimpleInfo()); Console.WriteLine(character.GetSimpleInfo());
while (type == CharacterActionType.None) while (type == CharacterActionType.None)