FunGame-Testing/Desktop/GameMapTesting/GameMapController.cs
2025-09-03 00:07:29 +08:00

262 lines
9.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Milimoe.FunGame.Core.Entity;
using Milimoe.FunGame.Core.Interface.Entity;
using Milimoe.FunGame.Core.Library.Common.Addon;
using Milimoe.FunGame.Core.Library.Constant;
namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
{
public class GameMapController(GameMapViewer ui)
{
public GameMapViewer UI => ui;
private GameMapTesting? _game;
// 输入请求器实例
private readonly UserInputRequester<long> _characterSelectionRequester = new();
private readonly UserInputRequester<CharacterActionType> _actionTypeRequester = new();
private readonly UserInputRequester<List<Character>> _targetSelectionRequester = new();
private readonly UserInputRequester<long> _skillSelectionRequester = new();
private readonly UserInputRequester<long> _itemSelectionRequester = new();
private readonly UserInputRequester<bool> _continuePromptRequester = new(); // 用于“按任意键继续”提示
public async Task WriteLine(string str = "") => await UI.AppendDebugLog(str);
public async Task Start()
{
_game = new(this);
await _game.StartGame(false);
}
public async Task SetPreCastSuperSkill(Character character, Skill skill)
{
if (_game != null)
{
await _game.SetPreCastSuperSkill(character, skill);
}
}
public void SetPredictCharacter(string name, double ht)
{
UI.Invoke(() => UI.SetPredictCharacter(name, ht));
}
public async Task<long> RequestCharacterSelection(List<Character> availableCharacters)
{
await WriteLine("请选择你想玩的角色。");
return await _characterSelectionRequester.RequestInput(
(callback) => UI.Invoke(() => UI.ShowCharacterSelectionPrompt(availableCharacters, callback))
);
}
public async Task<CharacterActionType> RequestActionType(Character character, List<Item> availableItems)
{
await WriteLine($"现在是 {character.NickName} 的回合,请选择行动。");
return await _actionTypeRequester.RequestInput(
(callback) => UI.Invoke(() => UI.ShowActionButtons(character, availableItems, callback))
);
}
public async Task<List<Character>> RequestTargetSelection(Character actor, List<Character> potentialTargets, ISkill skill, long maxTargets, bool canSelectSelf, bool canSelectEnemy, bool canSelectTeammate)
{
await WriteLine($"请为 {actor.NickName} 选择目标 (最多 {maxTargets} 个)。");
List<Character> targetIds = await _targetSelectionRequester.RequestInput(
(callback) => UI.Invoke(() => UI.ShowTargetSelectionUI(actor, potentialTargets, skill, maxTargets, canSelectSelf, canSelectEnemy, canSelectTeammate, callback))
) ?? [];
if (targetIds == null) return [];
return [.. potentialTargets.Where(targetIds.Contains)];
}
public async Task<Skill?> RequestSkillSelection(Character character, List<Skill> availableSkills)
{
await WriteLine($"请为 {character.NickName} 选择一个技能。");
long? skillId = await _skillSelectionRequester.RequestInput(
(callback) => UI.Invoke(() => UI.ShowSkillSelectionUI(character, callback))
);
return skillId.HasValue ? availableSkills.FirstOrDefault(s => s.Id == skillId.Value) : null;
}
public async Task<Item?> RequestItemSelection(Character character, List<Item> availableItems)
{
await WriteLine($"请为 {character.NickName} 选择一个物品。");
long? itemId = await _itemSelectionRequester.RequestInput(
(callback) => UI.Invoke(() => UI.ShowItemSelectionUI(character, callback))
);
return itemId.HasValue ? availableItems.FirstOrDefault(i => i.Id == itemId.Value) : null;
}
public async Task RequestContinuePrompt(string message)
{
await WriteLine(message);
await _continuePromptRequester.RequestInput(
(callback) => UI.Invoke(() => UI.ShowContinuePrompt(message, callback))
);
}
public async Task RequestCountDownContinuePrompt(string message, int countdownSeconds = 2)
{
await WriteLine(message);
// 调用 _continuePromptRequester 的 RequestInput 方法,它会等待回调被触发
await _continuePromptRequester.RequestInput(
(callback) => UI.Invoke(() => UI.StartCountdownForContinue(countdownSeconds, callback))
);
}
// --- GameMapViewer 调用这些方法来解决 UI 输入 ---
public void ResolveCharacterSelection(long characterId)
{
_characterSelectionRequester.ResolveInput(characterId);
UI.Invoke(() => UI.HideCharacterSelectionPrompt());
}
public void ResolveActionType(CharacterActionType actionType)
{
_actionTypeRequester.ResolveInput(actionType);
UI.Invoke(() => UI.HideActionButtons());
}
public void ResolveTargetSelection(List<Character> targetIds)
{
_targetSelectionRequester.ResolveInput(targetIds);
UI.Invoke(() => UI.HideTargetSelectionUI());
}
public void ResolveSkillSelection(long skillId)
{
_skillSelectionRequester.ResolveInput(skillId);
UI.Invoke(() => UI.HideSkillSelectionUI());
}
public void ResolveItemSelection(long itemId)
{
_itemSelectionRequester.ResolveInput(itemId);
UI.Invoke(() => UI.HideItemSelectionUI());
}
public void ResolveContinuePrompt()
{
_continuePromptRequester.ResolveInput(true); // 任何值都可以只要完成Task
UI.Invoke(() => UI.HideContinuePrompt());
}
public void ResolveCountDownContinuePrompt()
{
_continuePromptRequester.ResolveInput(true);
UI.Invoke(() => UI.HideContinuePrompt());
}
public bool IsTeammate(Character actor, Character target)
{
if (actor == target) return true;
if (_game != null && _game.GamingQueue != null)
{
return _game.GamingQueue.IsTeammate(actor, target);
}
return false;
}
public void UpdateBottomInfoPanel()
{
UI.Invoke(UI.UpdateBottomInfoPanel);
}
public void UpdateQueue()
{
UI.Invoke(UI.UpdateLeftQueuePanel);
}
public void UpdateCharacterPositionsOnMap()
{
UI.Invoke(UI.UpdateCharacterPositionsOnMap);
}
public void SetQueue(Dictionary<Character, double> dict)
{
UI.Invoke(() =>
{
UI.CharacterQueueData = dict;
});
}
public void SetGameMap(GameMap map)
{
UI.Invoke(() =>
{
UI.CurrentGameMap = map;
});
}
public void SetCurrentRound(int round)
{
UI.Invoke(() =>
{
UI.CurrentRound = round;
});
}
public void SetTurnRewards(Dictionary<int, List<Skill>> rewards)
{
UI.Invoke(() =>
{
UI.TurnRewards = rewards;
});
}
public void SetPlayerCharacter(Character character)
{
UI.Invoke(() =>
{
UI.PlayerCharacter = character;
});
}
public void SetCurrentCharacter(Character character)
{
UI.Invoke(() =>
{
UI.CurrentCharacter = character;
});
}
public void SetCharacterStatistics(Dictionary<Character, CharacterStatistics> stats)
{
UI.Invoke(() =>
{
UI.CharacterStatistics = stats;
});
}
}
/// <summary>
/// 辅助类,用于管理异步的用户输入请求。
/// </summary>
/// <typeparam name="T">期望的用户输入类型。</typeparam>
public class UserInputRequester<T>
{
private TaskCompletionSource<T?>? _tcs;
/// <summary>
/// 请求用户输入,并等待结果。
/// </summary>
/// <param name="uiPromptAction">一个Action用于通知UI显示提示并传入一个回调函数供UI完成输入后调用。</param>
/// <returns>用户输入的结果如果用户取消则为null。</returns>
public async Task<T?> RequestInput(Action<Action<T?>> uiPromptAction)
{
_tcs = new TaskCompletionSource<T?>();
// 调用UI动作并传入我们的ResolveInput方法作为回调
// UI将在获取输入后调用此回调
uiPromptAction(ResolveInput);
return await _tcs.Task;
}
/// <summary>
/// 解决用户输入请求将结果传递给等待的Task。
/// </summary>
/// <param name="result">用户输入的结果。</param>
public void ResolveInput(T? result)
{
_tcs?.TrySetResult(result);
_tcs = null; // 清除以防止意外重用
}
}
}