mirror of
https://github.com/milimoe/FunGame-Testing.git
synced 2025-12-05 00:06:05 +00:00
UI添加了更多信息,添加团队模式
This commit is contained in:
parent
1fc654df06
commit
6a23672af9
@ -1,10 +1,25 @@
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
using Milimoe.FunGame.Core.Entity;
|
||||
using Milimoe.FunGame.Core.Interface.Entity;
|
||||
using Milimoe.FunGame.Core.Library.Constant;
|
||||
|
||||
namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
{
|
||||
public class ToStringConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
// 如果值为 null,返回空字符串,否则返回其 ToString() 结果
|
||||
return value?.ToString()?.Trim() ?? string.Empty;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public class FirstCharConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
@ -111,6 +126,10 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
return s.Level > 0 && s.SkillType != SkillType.Passive && s.Enable && !s.IsInEffect && s.CurrentCD == 0 &&
|
||||
((s.SkillType == SkillType.SuperSkill || s.SkillType == SkillType.Skill) && s.RealEPCost <= character.EP || s.SkillType == SkillType.Magic && s.RealMPCost <= character.MP);
|
||||
}
|
||||
else if (values[0] is NormalAttack a)
|
||||
{
|
||||
return a.Level > 0 && a.Enable;
|
||||
}
|
||||
else if (values[0] is Item i)
|
||||
{
|
||||
return i.IsActive && i.Skills.Active != null && i.Enable && i.IsInGameItem &&
|
||||
|
||||
@ -24,7 +24,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
public async Task Start()
|
||||
{
|
||||
_game = new(this);
|
||||
await _game.StartGame(false);
|
||||
await _game.StartGame(false, true);
|
||||
}
|
||||
|
||||
public async Task SetPreCastSuperSkill(Character character, Skill skill)
|
||||
@ -35,16 +35,26 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPredictCharacter(string name, double ht)
|
||||
public void SetAutoMode(bool cancel, Character character)
|
||||
{
|
||||
UI.Invoke(() => UI.SetPredictCharacter(name, ht));
|
||||
_game?.SetAutoMode(cancel, character);
|
||||
}
|
||||
|
||||
public void SetFastMode(bool on)
|
||||
{
|
||||
_game?.SetFastMode(on);
|
||||
}
|
||||
|
||||
public async Task SetPredictCharacter(string name, double ht)
|
||||
{
|
||||
await UI.InvokeAsync(() => 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))
|
||||
async (callback) => await UI.InvokeAsync(() => UI.ShowCharacterSelectionPrompt(availableCharacters, callback))
|
||||
);
|
||||
}
|
||||
|
||||
@ -52,7 +62,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
{
|
||||
await WriteLine($"现在是 {character.NickName} 的回合,请选择行动。");
|
||||
return await _actionTypeRequester.RequestInput(
|
||||
(callback) => UI.Invoke(() => UI.ShowActionButtons(character, availableItems, callback))
|
||||
async (callback) => await UI.InvokeAsync(() => UI.ShowActionButtons(character, availableItems, callback))
|
||||
);
|
||||
}
|
||||
|
||||
@ -60,17 +70,17 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
{
|
||||
await WriteLine($"请为 {character.NickName} 选择目标 (最多 {skill.CanSelectTargetCount} 个)。");
|
||||
List<Character> targetIds = await _targetSelectionRequester.RequestInput(
|
||||
(callback) => UI.Invoke(() => UI.ShowTargetSelectionUI(character, skill, enemys, teammates, callback))
|
||||
async (callback) => await UI.InvokeAsync(() => UI.ShowTargetSelectionUI(character, skill, enemys, teammates, callback))
|
||||
) ?? [];
|
||||
if (targetIds == null) return [];
|
||||
return [.. enemys.Where(targetIds.Contains), .. teammates.Where(targetIds.Contains)];
|
||||
return [.. enemys.Union(teammates).Union([character]).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))
|
||||
async (callback) => await UI.InvokeAsync(() => UI.ShowSkillSelectionUI(character, callback))
|
||||
);
|
||||
return skillId.HasValue ? availableSkills.FirstOrDefault(s => s.Id == skillId.Value) : null;
|
||||
}
|
||||
@ -79,7 +89,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
{
|
||||
await WriteLine($"请为 {character.NickName} 选择一个物品。");
|
||||
long? itemId = await _itemSelectionRequester.RequestInput(
|
||||
(callback) => UI.Invoke(() => UI.ShowItemSelectionUI(character, callback))
|
||||
async (callback) => await UI.InvokeAsync(() => UI.ShowItemSelectionUI(character, callback))
|
||||
);
|
||||
return itemId.HasValue ? availableItems.FirstOrDefault(i => i.Id == itemId.Value) : null;
|
||||
}
|
||||
@ -88,7 +98,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
{
|
||||
await WriteLine(message);
|
||||
await _continuePromptRequester.RequestInput(
|
||||
(callback) => UI.Invoke(() => UI.ShowContinuePrompt(message, callback))
|
||||
async (callback) => await UI.InvokeAsync(() => UI.ShowContinuePrompt(message, callback))
|
||||
);
|
||||
}
|
||||
|
||||
@ -97,52 +107,52 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
await WriteLine(message);
|
||||
// 调用 _continuePromptRequester 的 RequestInput 方法,它会等待回调被触发
|
||||
await _continuePromptRequester.RequestInput(
|
||||
(callback) => UI.Invoke(() => UI.StartCountdownForContinue(countdownSeconds, callback))
|
||||
async (callback) => await UI.InvokeAsync(() => UI.StartCountdownForContinue(countdownSeconds, callback))
|
||||
);
|
||||
}
|
||||
|
||||
// --- GameMapViewer 调用这些方法来解决 UI 输入 ---
|
||||
|
||||
public void ResolveCharacterSelection(long characterId)
|
||||
public async Task ResolveCharacterSelection(long characterId)
|
||||
{
|
||||
_characterSelectionRequester.ResolveInput(characterId);
|
||||
UI.Invoke(() => UI.HideCharacterSelectionPrompt());
|
||||
await UI.InvokeAsync(() => UI.HideCharacterSelectionPrompt());
|
||||
}
|
||||
|
||||
public void ResolveActionType(CharacterActionType actionType)
|
||||
public async Task ResolveActionType(CharacterActionType actionType)
|
||||
{
|
||||
_actionTypeRequester.ResolveInput(actionType);
|
||||
UI.Invoke(() => UI.HideActionButtons());
|
||||
await UI.InvokeAsync(() => UI.HideActionButtons());
|
||||
}
|
||||
|
||||
public void ResolveTargetSelection(List<Character> targetIds)
|
||||
public async Task ResolveTargetSelection(List<Character> targetIds)
|
||||
{
|
||||
_targetSelectionRequester.ResolveInput(targetIds);
|
||||
UI.Invoke(() => UI.HideTargetSelectionUI());
|
||||
await UI.InvokeAsync(() => UI.HideTargetSelectionUI());
|
||||
}
|
||||
|
||||
public void ResolveSkillSelection(long skillId)
|
||||
public async Task ResolveSkillSelection(long skillId)
|
||||
{
|
||||
_skillSelectionRequester.ResolveInput(skillId);
|
||||
UI.Invoke(() => UI.HideSkillSelectionUI());
|
||||
await UI.InvokeAsync(() => UI.HideSkillSelectionUI());
|
||||
}
|
||||
|
||||
public void ResolveItemSelection(long itemId)
|
||||
public async Task ResolveItemSelection(long itemId)
|
||||
{
|
||||
_itemSelectionRequester.ResolveInput(itemId);
|
||||
UI.Invoke(() => UI.HideItemSelectionUI());
|
||||
await UI.InvokeAsync(() => UI.HideItemSelectionUI());
|
||||
}
|
||||
|
||||
public void ResolveContinuePrompt()
|
||||
public async Task ResolveContinuePrompt()
|
||||
{
|
||||
_continuePromptRequester.ResolveInput(true); // 任何值都可以,只要完成Task
|
||||
UI.Invoke(() => UI.HideContinuePrompt());
|
||||
await UI.InvokeAsync(() => UI.HideContinuePrompt());
|
||||
}
|
||||
|
||||
public void ResolveCountDownContinuePrompt()
|
||||
public async Task ResolveCountDownContinuePrompt()
|
||||
{
|
||||
_continuePromptRequester.ResolveInput(true);
|
||||
UI.Invoke(() => UI.HideContinuePrompt());
|
||||
await UI.InvokeAsync(() => UI.HideContinuePrompt());
|
||||
}
|
||||
|
||||
public bool IsTeammate(Character actor, Character target)
|
||||
@ -157,70 +167,70 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
|
||||
public async Task UpdateBottomInfoPanel()
|
||||
{
|
||||
await UI.Invoke(UI.UpdateBottomInfoPanel);
|
||||
await UI.InvokeAsync(UI.UpdateBottomInfoPanel);
|
||||
}
|
||||
|
||||
public async Task UpdateQueue()
|
||||
{
|
||||
await UI.Invoke(UI.UpdateLeftQueuePanel);
|
||||
await UI.InvokeAsync(UI.UpdateLeftQueuePanelGrid);
|
||||
}
|
||||
|
||||
public async Task UpdateCharacterPositionsOnMap()
|
||||
{
|
||||
await UI.Invoke(UI.UpdateCharacterPositionsOnMap);
|
||||
await UI.InvokeAsync(UI.UpdateCharacterPositionsOnMap);
|
||||
}
|
||||
|
||||
public void SetQueue(Dictionary<Character, double> dict)
|
||||
public async Task SetQueue(Dictionary<Character, double> dict)
|
||||
{
|
||||
UI.Invoke(() =>
|
||||
await UI.InvokeAsync(() =>
|
||||
{
|
||||
UI.CharacterQueueData = dict;
|
||||
});
|
||||
}
|
||||
|
||||
public void SetGameMap(GameMap map)
|
||||
public async Task SetGameMap(GameMap map)
|
||||
{
|
||||
UI.Invoke(() =>
|
||||
await UI.InvokeAsync(() =>
|
||||
{
|
||||
UI.CurrentGameMap = map;
|
||||
});
|
||||
}
|
||||
|
||||
public void SetCurrentRound(int round)
|
||||
public async Task SetCurrentRound(int round)
|
||||
{
|
||||
UI.Invoke(() =>
|
||||
await UI.InvokeAsync(() =>
|
||||
{
|
||||
UI.CurrentRound = round;
|
||||
});
|
||||
}
|
||||
|
||||
public void SetTurnRewards(Dictionary<int, List<Skill>> rewards)
|
||||
public async Task SetTurnRewards(Dictionary<int, List<Skill>> rewards)
|
||||
{
|
||||
UI.Invoke(() =>
|
||||
await UI.InvokeAsync(() =>
|
||||
{
|
||||
UI.TurnRewards = rewards;
|
||||
});
|
||||
}
|
||||
|
||||
public void SetPlayerCharacter(Character character)
|
||||
public async Task SetPlayerCharacter(Character character)
|
||||
{
|
||||
UI.Invoke(() =>
|
||||
await UI.InvokeAsync(() =>
|
||||
{
|
||||
UI.PlayerCharacter = character;
|
||||
});
|
||||
}
|
||||
|
||||
public void SetCurrentCharacter(Character character)
|
||||
public async Task SetCurrentCharacter(Character character)
|
||||
{
|
||||
UI.Invoke(() =>
|
||||
await UI.InvokeAsync(() =>
|
||||
{
|
||||
UI.CurrentCharacter = character;
|
||||
});
|
||||
}
|
||||
|
||||
public void SetCharacterStatistics(Dictionary<Character, CharacterStatistics> stats)
|
||||
public async Task SetCharacterStatistics(Dictionary<Character, CharacterStatistics> stats)
|
||||
{
|
||||
UI.Invoke(() =>
|
||||
await UI.InvokeAsync(() =>
|
||||
{
|
||||
UI.CharacterStatistics = stats;
|
||||
});
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
using System.Text;
|
||||
// using System.Windows; // 不再需要,因为移除了 InputDialog
|
||||
using Milimoe.FunGame.Core.Api.Utility;
|
||||
using Milimoe.FunGame.Core.Entity;
|
||||
using Milimoe.FunGame.Core.Library.Common.Addon;
|
||||
@ -18,12 +17,16 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
public GamingQueue? GamingQueue => _gamingQueue;
|
||||
public GameMapController Controller { get; }
|
||||
public Dictionary<Character, CharacterStatistics> CharacterStatistics { get; } = [];
|
||||
public PluginConfig StatsConfig { get; } = new(nameof(FunGameSimulation), nameof(CharacterStatistics));
|
||||
public static Dictionary<Character, CharacterStatistics> TeamCharacterStatistics { get; } = [];
|
||||
public PluginConfig StatsConfig { get; } = new(nameof(GameMapTesting), nameof(CharacterStatistics));
|
||||
public PluginConfig TeamStatsConfig { get; } = new(nameof(GameMapTesting), nameof(TeamCharacterStatistics));
|
||||
public GameMap GameMap { get; } = new TestMap();
|
||||
public bool IsWeb { get; set; } = false;
|
||||
public bool TeamMode { get; set; } = false;
|
||||
public string Msg { get; set; } = "";
|
||||
|
||||
private GamingQueue? _gamingQueue = null;
|
||||
private bool _fastMode = false;
|
||||
|
||||
public GameMapTesting(GameMapController controller)
|
||||
{
|
||||
@ -31,15 +34,18 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
InitCharacter(); // 初始化角色统计数据
|
||||
}
|
||||
|
||||
public async Task<List<string>> StartGame(bool isWeb = false)
|
||||
public async Task<List<string>> StartGame(bool isWeb = false, bool isTeam = false)
|
||||
{
|
||||
IsWeb = isWeb;
|
||||
TeamMode = isTeam;
|
||||
try
|
||||
{
|
||||
List<string> result = [];
|
||||
Msg = "";
|
||||
List<Character> allCharactersInGame = [.. FunGameConstant.Characters]; // 使用不同的名称以避免与后面的 `characters` 冲突
|
||||
List<Character> allCharactersInGame = [.. FunGameConstant.Characters];
|
||||
await Controller.WriteLine("--- 游戏开始 ---");
|
||||
TeamGamingQueue? tgq = null;
|
||||
MixGamingQueue? mgq = null;
|
||||
|
||||
int clevel = 60;
|
||||
int slevel = 6;
|
||||
@ -70,7 +76,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
// 询问玩家需要选择哪个角色 (通过UI界面选择)
|
||||
Character? player = null;
|
||||
long selectedPlayerId = await Controller.RequestCharacterSelection(characters); // 异步等待UI选择
|
||||
Controller.ResolveCharacterSelection(selectedPlayerId);
|
||||
await Controller.ResolveCharacterSelection(selectedPlayerId);
|
||||
if (selectedPlayerId != -1)
|
||||
{
|
||||
player = characters.FirstOrDefault(c => c.Id == selectedPlayerId);
|
||||
@ -78,9 +84,8 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
{
|
||||
await Controller.WriteLine($"选择了 [ {player} ]!");
|
||||
player.Promotion = 200;
|
||||
Controller.SetCurrentCharacter(player);
|
||||
Controller.SetPlayerCharacter(player);
|
||||
|
||||
await Controller.SetCurrentCharacter(player);
|
||||
await Controller.SetPlayerCharacter(player);
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,10 +95,64 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
}
|
||||
|
||||
// 创建顺序表并排序
|
||||
_gamingQueue = new MixGamingQueue(characters, WriteLine)
|
||||
if (isTeam)
|
||||
{
|
||||
GameplayEquilibriumConstant = OshimaGameModuleConstant.GameplayEquilibriumConstant
|
||||
};
|
||||
tgq = new(characters, WriteLine)
|
||||
{
|
||||
GameplayEquilibriumConstant = OshimaGameModuleConstant.GameplayEquilibriumConstant
|
||||
};
|
||||
_gamingQueue = tgq;
|
||||
await Controller.WriteLine("=== 团队模式随机分组 ===");
|
||||
|
||||
// 打乱角色列表
|
||||
List<Character> shuffledCharacters = [.. characters.OrderBy(c => Random.Shared.Next())];
|
||||
|
||||
// 创建两个团队
|
||||
List<Character> group1 = [];
|
||||
List<Character> group2 = [];
|
||||
|
||||
// 将角色交替分配到两个团队中
|
||||
for (int cid = 0; cid < shuffledCharacters.Count; cid++)
|
||||
{
|
||||
Character thisCharacter = shuffledCharacters[cid];
|
||||
if (cid % 2 == 0)
|
||||
{
|
||||
group1.Add(thisCharacter);
|
||||
}
|
||||
else
|
||||
{
|
||||
group2.Add(thisCharacter);
|
||||
}
|
||||
}
|
||||
|
||||
// 添加到团队字典,第一个为队长
|
||||
tgq.AddTeam($"{group1.First().NickName}的小队", group1);
|
||||
tgq.AddTeam($"{group2.First().NickName}的小队", group2);
|
||||
|
||||
foreach (Team team in tgq.Teams.Values)
|
||||
{
|
||||
await Controller.WriteLine($"团队【{team.Name}】的成员:\r\n{string.Join("\r\n", team.Members)}\r\n");
|
||||
if (team.IsOnThisTeam(player))
|
||||
{
|
||||
foreach (Character c in team.Members.Except([player]))
|
||||
{
|
||||
c.Promotion = 300;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
team.Members.ForEach(c => c.Promotion = 400);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mgq = new MixGamingQueue(characters, WriteLine)
|
||||
{
|
||||
GameplayEquilibriumConstant = OshimaGameModuleConstant.GameplayEquilibriumConstant
|
||||
};
|
||||
_gamingQueue = mgq;
|
||||
}
|
||||
|
||||
// 加载地图和绑定事件
|
||||
_gamingQueue.LoadGameMap(GameMap);
|
||||
@ -114,14 +173,14 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
allocated.Add(grid);
|
||||
map.SetCharacterCurrentGrid(character, grid);
|
||||
}
|
||||
Controller.SetGameMap(map);
|
||||
await Controller.SetGameMap(map);
|
||||
_gamingQueue.SelectTargetGrid += GamingQueue_SelectTargetGrid;
|
||||
_gamingQueue.CharacterMove += GamingQueue_CharacterMove;
|
||||
}
|
||||
|
||||
// 绑定事件
|
||||
Controller.SetQueue(_gamingQueue.HardnessTime);
|
||||
Controller.SetCharacterStatistics(_gamingQueue.CharacterStatistics);
|
||||
await Controller.SetQueue(_gamingQueue.HardnessTime);
|
||||
await Controller.SetCharacterStatistics(_gamingQueue.CharacterStatistics);
|
||||
_gamingQueue.TurnStart += GamingQueue_TurnStart;
|
||||
_gamingQueue.DecideAction += GamingQueue_DecideAction;
|
||||
_gamingQueue.SelectNormalAttackTargets += GamingQueue_SelectNormalAttackTargets;
|
||||
@ -172,7 +231,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
await Controller.WriteLine($"你的角色是 [ {player} ],详细信息:{player.GetInfo()}");
|
||||
|
||||
// 总回合数
|
||||
int maxRound = 999;
|
||||
int maxRound = isTeam ? 9999 : 999;
|
||||
|
||||
// 随机回合奖励
|
||||
Dictionary<long, bool> effects = [];
|
||||
@ -187,7 +246,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
effects.Add(effectID, isActive);
|
||||
}
|
||||
_gamingQueue.InitRoundRewards(maxRound, 1, effects, id => FunGameConstant.RoundRewards[(EffectID)id]);
|
||||
Controller.SetTurnRewards(_gamingQueue.RoundRewards);
|
||||
await Controller.SetTurnRewards(_gamingQueue.RoundRewards);
|
||||
|
||||
int i = 1;
|
||||
while (i < maxRound)
|
||||
@ -195,23 +254,31 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
Msg = "";
|
||||
if (i == maxRound - 1)
|
||||
{
|
||||
await Controller.WriteLine($"=== 终局审判 ===");
|
||||
Dictionary<Character, double> hpPercentage = [];
|
||||
foreach (Character c in characters)
|
||||
if (isTeam)
|
||||
{
|
||||
hpPercentage.TryAdd(c, c.HP / c.MaxHP);
|
||||
WriteLine("两队打到天昏地暗,流局了!!");
|
||||
break;
|
||||
}
|
||||
double max = hpPercentage.Values.Max();
|
||||
Character winner = hpPercentage.Keys.Where(c => hpPercentage[c] == max).First();
|
||||
await Controller.WriteLine("[ " + winner + " ] 成为了天选之人!!");
|
||||
foreach (Character c in characters.Where(c => c != winner && c.HP > 0))
|
||||
else
|
||||
{
|
||||
await Controller.WriteLine("[ " + winner + " ] 对 [ " + c + " ] 造成了 99999999999 点真实伤害。");
|
||||
await _gamingQueue.DeathCalculationAsync(winner, c);
|
||||
}
|
||||
if (_gamingQueue is MixGamingQueue mix)
|
||||
{
|
||||
await mix.EndGameInfo(winner);
|
||||
await Controller.WriteLine($"=== 终局审判 ===");
|
||||
Dictionary<Character, double> hpPercentage = [];
|
||||
foreach (Character c in characters)
|
||||
{
|
||||
hpPercentage.TryAdd(c, c.HP / c.MaxHP);
|
||||
}
|
||||
double max = hpPercentage.Values.Max();
|
||||
Character winner = hpPercentage.Keys.Where(c => hpPercentage[c] == max).First();
|
||||
await Controller.WriteLine("[ " + winner + " ] 成为了天选之人!!");
|
||||
foreach (Character c in characters.Where(c => c != winner && c.HP > 0))
|
||||
{
|
||||
await Controller.WriteLine("[ " + winner + " ] 对 [ " + c + " ] 造成了 99999999999 点真实伤害。");
|
||||
await _gamingQueue.DeathCalculationAsync(winner, c);
|
||||
}
|
||||
if (mgq != null)
|
||||
{
|
||||
await mgq.EndGameInfo(winner);
|
||||
}
|
||||
}
|
||||
result.Add(Msg);
|
||||
break;
|
||||
@ -225,7 +292,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
// 处理回合
|
||||
if (characterToAct != null)
|
||||
{
|
||||
Controller.SetCurrentRound(i);
|
||||
await Controller.SetCurrentRound(i);
|
||||
await Controller.WriteLine($"=== 回合 {i++} ===");
|
||||
await Controller.WriteLine("现在是 [ " + characterToAct + " ] 的回合!");
|
||||
|
||||
@ -286,7 +353,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
await Controller.WriteLine($"总游戏时长:{totalTime:0.##} {_gamingQueue.GameplayEquilibriumConstant.InGameTime}");
|
||||
|
||||
// 赛后统计
|
||||
FunGameService.GetCharacterRating(_gamingQueue.CharacterStatistics, false, []);
|
||||
FunGameService.GetCharacterRating(_gamingQueue.CharacterStatistics, isTeam, tgq != null ? tgq.EliminatedTeams : []);
|
||||
|
||||
// 统计技术得分,评选 MVP
|
||||
Character? mvp = _gamingQueue.CharacterStatistics.OrderByDescending(d => d.Value.Rating).Select(d => d.Key).FirstOrDefault();
|
||||
@ -295,7 +362,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
{
|
||||
CharacterStatistics stats = _gamingQueue.CharacterStatistics[mvp];
|
||||
stats.MVPs++;
|
||||
mvpBuilder.AppendLine($"[ {mvp.ToStringWithLevel()} ]");
|
||||
mvpBuilder.AppendLine($"{(tgq != null ? "[ " + tgq.GetTeamFromEliminated(mvp)?.Name + " ] " : "")}[ {mvp.ToStringWithLevel()} ]");
|
||||
mvpBuilder.AppendLine($"技术得分:{stats.Rating:0.0#} / 击杀数:{stats.Kills} / 助攻数:{stats.Assists}{(_gamingQueue.MaxRespawnTimes != 0 ? " / 死亡数:" + stats.Deaths : "")}");
|
||||
mvpBuilder.AppendLine($"存活时长:{stats.LiveTime:0.##} / 存活回合数:{stats.LiveRound} / 行动回合数:{stats.ActionTurn}");
|
||||
mvpBuilder.AppendLine($"控制时长:{stats.ControlTime:0.##} / 总计治疗:{stats.TotalHeal:0.##} / 护盾抵消:{stats.TotalShield:0.##}");
|
||||
@ -327,7 +394,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
{
|
||||
StringBuilder builder = new();
|
||||
CharacterStatistics stats = _gamingQueue.CharacterStatistics[character];
|
||||
builder.AppendLine($"{(isWeb ? count + ". " : "")}[ {character.ToStringWithLevel()} ]");
|
||||
builder.AppendLine($"{(isWeb ? count + ". " : "")}[ {character.ToStringWithLevel()}{(tgq != null ? "(" + tgq.GetTeamFromEliminated(character)?.Name + ")" : "")} ]");
|
||||
builder.AppendLine($"技术得分:{stats.Rating:0.0#} / 击杀数:{stats.Kills} / 助攻数:{stats.Assists}{(_gamingQueue.MaxRespawnTimes != 0 ? " / 死亡数:" + stats.Deaths : "")}");
|
||||
builder.AppendLine($"存活时长:{stats.LiveTime:0.##} / 存活回合数:{stats.LiveRound} / 行动回合数:{stats.ActionTurn}");
|
||||
builder.AppendLine($"控制时长:{stats.ControlTime:0.##} / 总计治疗:{stats.TotalHeal:0.##} / 护盾抵消:{stats.TotalShield:0.##}");
|
||||
@ -344,7 +411,9 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
await Controller.WriteLine(builder.ToString());
|
||||
}
|
||||
|
||||
CharacterStatistics? totalStats = CharacterStatistics.Where(kv => kv.Key.GetName() == character.GetName()).Select(kv => kv.Value).FirstOrDefault();
|
||||
CharacterStatistics? totalStats = isTeam ?
|
||||
TeamCharacterStatistics.Where(kv => kv.Key.GetName() == character.GetName()).Select(kv => kv.Value).FirstOrDefault() :
|
||||
CharacterStatistics.Where(kv => kv.Key.GetName() == character.GetName()).Select(kv => kv.Value).FirstOrDefault();
|
||||
if (totalStats != null)
|
||||
{
|
||||
UpdateStatistics(totalStats, stats);
|
||||
@ -361,13 +430,27 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
}
|
||||
}
|
||||
|
||||
lock (StatsConfig)
|
||||
if (isTeam)
|
||||
{
|
||||
foreach (Character c in CharacterStatistics.Keys)
|
||||
lock (TeamStatsConfig)
|
||||
{
|
||||
StatsConfig.Add(c.ToStringWithOutUser(), CharacterStatistics[c]);
|
||||
foreach (Character c in TeamCharacterStatistics.Keys)
|
||||
{
|
||||
TeamStatsConfig.Add(c.ToStringWithOutUser(), TeamCharacterStatistics[c]);
|
||||
}
|
||||
TeamStatsConfig.SaveConfig();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lock (StatsConfig)
|
||||
{
|
||||
foreach (Character c in CharacterStatistics.Keys)
|
||||
{
|
||||
StatsConfig.Add(c.ToStringWithOutUser(), CharacterStatistics[c]);
|
||||
}
|
||||
StatsConfig.SaveConfig();
|
||||
}
|
||||
StatsConfig.SaveConfig();
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -400,31 +483,11 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
{
|
||||
await Controller.UpdateQueue();
|
||||
}
|
||||
if (IsPlayer_OnlyTest(queue, character))
|
||||
{
|
||||
//if (reason == QueueUpdatedReason.Action)
|
||||
//{
|
||||
// queue.SetCharactersToAIControl(false, character);
|
||||
//}
|
||||
//if (reason == QueueUpdatedReason.PreCastSuperSkill)
|
||||
//{
|
||||
// // 玩家释放爆发技后,需要等待玩家确认
|
||||
// await Controller.RequestContinuePrompt("你的下一回合需要选择爆发技目标,知晓请点击继续. . .");
|
||||
// Controller.ResolveContinuePrompt();
|
||||
//}
|
||||
}
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task<bool> GamingQueue_TurnStart(GamingQueue queue, Character character, List<Character> enemys, List<Character> teammates, List<Skill> skills, List<Item> items)
|
||||
{
|
||||
await Controller.UpdateBottomInfoPanel();
|
||||
if (IsPlayer_OnlyTest(queue, character))
|
||||
{
|
||||
// 确保玩家角色在回合开始时取消AI托管,以便玩家可以控制
|
||||
//queue.SetCharactersToAIControl(cancel: true, character);
|
||||
}
|
||||
await Task.CompletedTask;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -439,7 +502,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
enemys,
|
||||
teammates
|
||||
);
|
||||
Controller.ResolveTargetSelection(selectedTargets);
|
||||
await Controller.ResolveTargetSelection(selectedTargets);
|
||||
|
||||
return selectedTargets ?? []; // 如果取消,返回空列表
|
||||
}
|
||||
@ -450,7 +513,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
|
||||
// 通过UI请求物品选择
|
||||
Item? selectedItem = await Controller.RequestItemSelection(character, items);
|
||||
Controller.ResolveItemSelection(selectedItem?.Id ?? 0);
|
||||
await Controller.ResolveItemSelection(selectedItem?.Id ?? 0);
|
||||
return selectedItem;
|
||||
}
|
||||
|
||||
@ -470,7 +533,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
enemys,
|
||||
teammates
|
||||
);
|
||||
Controller.ResolveTargetSelection(selectedTargets);
|
||||
await Controller.ResolveTargetSelection(selectedTargets);
|
||||
|
||||
return selectedTargets ?? []; // 如果取消,返回空列表
|
||||
}
|
||||
@ -481,27 +544,30 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
|
||||
// 通过UI请求技能选择
|
||||
Skill? selectedSkill = await Controller.RequestSkillSelection(character, skills);
|
||||
Controller.ResolveSkillSelection(selectedSkill?.Id ?? 0);
|
||||
await Controller.ResolveSkillSelection(selectedSkill?.Id ?? 0);
|
||||
return selectedSkill;
|
||||
}
|
||||
|
||||
private async Task GamingQueue_TurnEnd(GamingQueue queue, Character character)
|
||||
{
|
||||
double ht = queue.HardnessTime[character];
|
||||
Controller.SetPredictCharacter(character.NickName, ht);
|
||||
await Controller.SetPredictCharacter(character.NickName, ht);
|
||||
await Controller.UpdateBottomInfoPanel();
|
||||
if (IsRoundHasPlayer_OnlyTest(queue, character))
|
||||
if (!_fastMode)
|
||||
{
|
||||
// 玩家回合结束,等待玩家确认
|
||||
await Controller.RequestContinuePrompt("你的回合(或与你相关的回合)已结束,请查看本回合日志,然后点击继续. . .");
|
||||
Controller.ResolveContinuePrompt();
|
||||
if (IsRoundHasPlayer_OnlyTest(queue, character))
|
||||
{
|
||||
// 玩家回合结束,等待玩家确认
|
||||
await Controller.RequestContinuePrompt("你的回合(或与你相关的回合)已结束,请查看本回合日志,然后点击继续. . .");
|
||||
await Controller.ResolveContinuePrompt();
|
||||
}
|
||||
else
|
||||
{
|
||||
await Controller.RequestCountDownContinuePrompt("该角色的回合已结束. . .");
|
||||
await Controller.ResolveCountDownContinuePrompt();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await Controller.RequestCountDownContinuePrompt("该角色的回合已结束. . .");
|
||||
Controller.ResolveCountDownContinuePrompt();
|
||||
}
|
||||
await Task.CompletedTask;
|
||||
else await Task.Delay(100);
|
||||
}
|
||||
|
||||
private async Task<CharacterActionType> GamingQueue_DecideAction(GamingQueue queue, Character character, List<Character> enemys, List<Character> teammates, List<Skill> skills, List<Item> items)
|
||||
@ -510,7 +576,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
{
|
||||
// 通过UI按钮请求行动类型
|
||||
CharacterActionType actionType = await Controller.RequestActionType(character, items);
|
||||
Controller.ResolveActionType(actionType);
|
||||
await Controller.ResolveActionType(actionType);
|
||||
return actionType;
|
||||
}
|
||||
return CharacterActionType.None; // 非玩家角色,由AI处理,或默认None
|
||||
@ -534,6 +600,16 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
}
|
||||
}
|
||||
|
||||
public void SetAutoMode(bool cancel, Character character)
|
||||
{
|
||||
_gamingQueue?.SetCharactersToAIControl(cancel, character);
|
||||
}
|
||||
|
||||
public void SetFastMode(bool on)
|
||||
{
|
||||
_fastMode = on;
|
||||
}
|
||||
|
||||
public void WriteLine(string str)
|
||||
{
|
||||
Msg += str + "\r\n";
|
||||
@ -592,9 +668,11 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
foreach (Character c in FunGameConstant.Characters)
|
||||
{
|
||||
CharacterStatistics.Add(c, new());
|
||||
TeamCharacterStatistics.Add(c, new());
|
||||
}
|
||||
|
||||
StatsConfig.LoadConfig();
|
||||
TeamStatsConfig.LoadConfig();
|
||||
foreach (Character character in CharacterStatistics.Keys)
|
||||
{
|
||||
if (StatsConfig.ContainsKey(character.ToStringWithOutUser()))
|
||||
@ -602,6 +680,13 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
CharacterStatistics[character] = StatsConfig.Get<CharacterStatistics>(character.ToStringWithOutUser()) ?? CharacterStatistics[character];
|
||||
}
|
||||
}
|
||||
foreach (Character character in TeamCharacterStatistics.Keys)
|
||||
{
|
||||
if (TeamStatsConfig.ContainsKey(character.ToStringWithOutUser()))
|
||||
{
|
||||
TeamCharacterStatistics[character] = TeamStatsConfig.Get<CharacterStatistics>(character.ToStringWithOutUser()) ?? TeamCharacterStatistics[character];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateStatistics(CharacterStatistics totalStats, CharacterStatistics stats)
|
||||
|
||||
@ -69,6 +69,8 @@
|
||||
<local:SkillItemFormatterConverter x:Key="SkillItemFormatterConverter"/>
|
||||
<!-- 新增:技能/物品可用性判断转换器 -->
|
||||
<local:SkillUsabilityConverter x:Key="SkillUsabilityConverter"/>
|
||||
<!-- 新增:通用ToString转换器 -->
|
||||
<local:ToStringConverter x:Key="ToStringConverter"/>
|
||||
|
||||
<!-- 新增:角色图标的样式 (圆形) -->
|
||||
<Style x:Key="CharacterIconStyle" TargetType="Border">
|
||||
@ -119,28 +121,35 @@
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="0.3*"/>
|
||||
<!-- 左侧动态队列 -->
|
||||
<ColumnDefinition Width="1*"/>
|
||||
<ColumnDefinition Width="0.3*"/>
|
||||
<!-- 地图区域 -->
|
||||
<ColumnDefinition Width="1*"/>
|
||||
<!-- 右侧调试日志 -->
|
||||
<ColumnDefinition Width="0.8*"/>
|
||||
<!-- 新增:右侧调试日志 -->
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<!-- 地图、左侧队列、右侧日志占据的行 -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<!-- 底部信息界面占据的行 -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 左侧动态更新队列面板 -->
|
||||
<Border Grid.Column="0" Grid.Row="0" BorderBrush="LightGray" BorderThickness="1" Margin="5" Padding="5">
|
||||
<StackPanel x:Name="LeftQueuePanel" MinWidth="180" Background="#FFF0F8FF">
|
||||
<!-- AliceBlue -->
|
||||
<TextBlock x:Name="QueueTitle" Text="行动顺序表" Margin="0,0,0,10" FontWeight="Bold" FontSize="14"/>
|
||||
<!-- 将 StackPanel 替换为 Grid -->
|
||||
<Grid x:Name="LeftQueuePanelGrid" MinWidth="180" Background="#FFF0F8FF">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- 标题占据所需高度 -->
|
||||
<RowDefinition Height="*"/>
|
||||
<!-- ScrollViewer 占据剩余所有高度 -->
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" x:Name="QueueTitle" Text="行动顺序表" Margin="0,0,0,10" FontWeight="Bold" FontSize="14"/>
|
||||
|
||||
<!-- 动态内容将在此处添加 -->
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Height="Auto">
|
||||
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
|
||||
<ItemsControl x:Name="CharacterQueueItemsControl" ItemsSource="{Binding CharacterQueueDisplayItems, RelativeSource={RelativeSource AncestorType=UserControl}}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
@ -149,9 +158,16 @@
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="BorderBrush" Value="LightGray"/>
|
||||
<Style.Triggers>
|
||||
<!-- 200:自己,300:队友,400:敌人,1800:下轮预测 -->
|
||||
<DataTrigger Binding="{Binding Character.Promotion}" Value="200">
|
||||
<Setter Property="Background" Value="Bisque"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Character.Promotion}" Value="300">
|
||||
<Setter Property="Background" Value="LightCyan"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Character.Promotion}" Value="400">
|
||||
<Setter Property="Background" Value="MistyRose"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Character.Promotion}" Value="1800">
|
||||
<Setter Property="Background" Value="#FFDDA0DD"/>
|
||||
</DataTrigger>
|
||||
@ -178,39 +194,45 @@
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<!-- 默认背景色 -->
|
||||
<Setter Property="Background" Value="#FF6A5ACD"/>
|
||||
<Setter Property="Background" Value="Salmon"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Character.Promotion}" Value="200">
|
||||
<Setter Property="Background" Value="BurlyWood"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Character.Promotion}" Value="300">
|
||||
<Setter Property="Background" Value="SkyBlue"/>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Character.Promotion}" Value="1800">
|
||||
<Setter Property="Background" Value="#FF228B22"/>
|
||||
<Setter Property="Background" Value="Orchid"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<TextBlock Text="{Binding Character.NickName, Converter={StaticResource FirstCharConverter}}"
|
||||
Foreground="White"
|
||||
FontSize="10"
|
||||
FontWeight="Bold"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
Foreground="White"
|
||||
FontSize="10"
|
||||
FontWeight="Bold"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
|
||||
<!-- 角色名称和等级 -->
|
||||
<TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding Character, Converter={StaticResource CharacterToStringWithLevelConverter}}"
|
||||
FontWeight="SemiBold" FontSize="10" Margin="0,0,0,2"/>
|
||||
FontWeight="SemiBold" FontSize="10" Margin="0,0,0,2"/>
|
||||
|
||||
<!-- ATDelay -->
|
||||
<TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding ATDelay, StringFormat=AT Delay: {0:0.##}}"
|
||||
FontSize="11" Foreground="DimGray"/>
|
||||
FontSize="11" Foreground="DimGray"/>
|
||||
|
||||
<!-- 新增:回合奖励显示 -->
|
||||
<StackPanel Grid.Column="2" Grid.RowSpan="2" VerticalAlignment="Center" Margin="5,0,0,0">
|
||||
<!-- 直接绑定到 ViewModel 的 PredictedTurnNumber -->
|
||||
<TextBlock FontSize="9" Foreground="Gray" HorizontalAlignment="Right"
|
||||
Text="{Binding PredictedTurnNumber, StringFormat=回合: {0}}" />
|
||||
Text="{Binding PredictedTurnNumber, StringFormat=回合: {0}}" />
|
||||
|
||||
<!-- 直接绑定到 ViewModel 的 TurnRewardSkillName -->
|
||||
<TextBlock FontSize="10" Foreground="DarkGreen" FontWeight="SemiBold" HorizontalAlignment="Right"
|
||||
Text="{Binding TurnRewardSkillName}" />
|
||||
Text="{Binding TurnRewardSkillName}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
@ -218,12 +240,12 @@
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- 地图区域 (使用ScrollViewer支持大地图滚动) -->
|
||||
<ScrollViewer Grid.Column="1" Grid.Row="0" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto"
|
||||
Background="#FFE0FFFF">
|
||||
Background="#FFE0FFFF">
|
||||
<Border BorderBrush="DarkGray" BorderThickness="1" Margin="5">
|
||||
<!-- 新增一个Grid来容纳Canvas和调试文本框,实现叠加效果 -->
|
||||
<Grid>
|
||||
@ -235,18 +257,18 @@
|
||||
|
||||
<!-- 格子信息面板,叠加在Canvas之上,位于左侧 -->
|
||||
<Border x:Name="GridInfoPanel"
|
||||
Panel.ZIndex="100"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Margin="10"
|
||||
Width="250"
|
||||
MaxHeight="300"
|
||||
Background="#CCFFFFFF"
|
||||
BorderBrush="DarkGray"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
Padding="10"
|
||||
Visibility="Collapsed">
|
||||
Panel.ZIndex="100"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Margin="10"
|
||||
Width="250"
|
||||
MaxHeight="300"
|
||||
Background="#CCFFFFFF"
|
||||
BorderBrush="DarkGray"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
Padding="10"
|
||||
Visibility="Collapsed">
|
||||
<!-- 初始状态为隐藏 -->
|
||||
<StackPanel>
|
||||
<TextBlock Text="格子信息" FontWeight="Bold" FontSize="14" Margin="0,0,0,5"/>
|
||||
@ -256,15 +278,42 @@
|
||||
<TextBlock x:Name="GridCoordTextBlock" Text="坐标: " Margin="0,2"/>
|
||||
<TextBlock x:Name="GridColorTextBlock" Text="颜色: " Margin="0,2"/>
|
||||
<!-- 新增:格子上的角色列表 -->
|
||||
<TextBlock Text="格子上的角色:" FontWeight="SemiBold" Margin="0,5,0,2"/>
|
||||
<TextBlock Text="格子上的角色:" FontWeight="SemiBold" Margin="0,5,0,2"/>
|
||||
<ItemsControl x:Name="GridCharactersInfoItemsControl">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border BorderBrush="LightGray" BorderThickness="0,0,0,1" Padding="2" Margin="0,2">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding NickName}" FontWeight="SemiBold" Margin="0,0,5,0"/>
|
||||
<StackPanel>
|
||||
<!--<TextBlock Text="{Binding NickName}" FontWeight="SemiBold" Margin="0,0,5,0"/>
|
||||
<TextBlock Text="{Binding HP, StringFormat=HP:{0:0.##}}"/>
|
||||
<TextBlock Text="{Binding MaxHP, StringFormat=/{0:0.##}}" Margin="0,0,5,0"/>
|
||||
<TextBlock Text="{Binding MaxHP, StringFormat=/{0:0.##}}" Margin="0,0,5,0"/>-->
|
||||
|
||||
<!-- 角色名称 -->
|
||||
<TextBlock Text="{Binding NickName}" FontWeight="SemiBold" Margin="0,0,5,0" FontSize="11"/>
|
||||
|
||||
<!-- HP 条 -->
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="0,1">
|
||||
<TextBlock Text="HP:" VerticalAlignment="Center" Width="25" FontSize="9"/>
|
||||
<ProgressBar Value="{Binding HP}" Maximum="{Binding MaxHP}" Height="8" Width="100" Background="LightGray" BorderBrush="Gray" BorderThickness="0.5" Foreground="Green"/>
|
||||
<TextBlock Text="{Binding HP, StringFormat={}{0:0.##}}" Margin="5,0,0,0" VerticalAlignment="Center" FontSize="9"/>
|
||||
<TextBlock Text="{Binding MaxHP, StringFormat=/{0:0.##}}" VerticalAlignment="Center" FontSize="9"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- MP 条 -->
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="0,1">
|
||||
<TextBlock Text="MP:" VerticalAlignment="Center" Width="25" FontSize="9"/>
|
||||
<ProgressBar Value="{Binding MP}" Maximum="{Binding MaxMP}" Height="8" Width="100" Background="LightGray" BorderBrush="Gray" BorderThickness="0.5" Foreground="Blue"/>
|
||||
<TextBlock Text="{Binding MP, StringFormat={}{0:0.##}}" Margin="5,0,0,0" VerticalAlignment="Center" FontSize="9"/>
|
||||
<TextBlock Text="{Binding MaxMP, StringFormat=/{0:0.##}}" VerticalAlignment="Center" FontSize="9"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- EP 条 -->
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="0,1">
|
||||
<TextBlock Text="EP:" VerticalAlignment="Center" Width="25" FontSize="9"/>
|
||||
<ProgressBar Value="{Binding EP}" Maximum="{Binding GameplayEquilibriumConstant.MaxEP}" Height="8" Width="100" Background="LightGray" BorderBrush="Gray" BorderThickness="0.5" Foreground="Orange"/>
|
||||
<TextBlock Text="{Binding EP, StringFormat={}{0:0.##}}" Margin="5,0,0,0" VerticalAlignment="Center" FontSize="9"/>
|
||||
<TextBlock Text="{Binding GameplayEquilibriumConstant.MaxEP, StringFormat=/{0:0.##}}" VerticalAlignment="Center" FontSize="9"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
@ -281,17 +330,17 @@
|
||||
|
||||
<!-- 新增:角色选择面板 (Overlay) -->
|
||||
<Border x:Name="CharacterSelectionOverlay"
|
||||
Panel.ZIndex="200"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Width="400"
|
||||
MaxHeight="600"
|
||||
Background="#DDFFFFFF"
|
||||
BorderBrush="DarkBlue"
|
||||
BorderThickness="2"
|
||||
CornerRadius="10"
|
||||
Padding="20"
|
||||
Visibility="Collapsed">
|
||||
Panel.ZIndex="200"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Width="400"
|
||||
MaxHeight="600"
|
||||
Background="#DDFFFFFF"
|
||||
BorderBrush="DarkBlue"
|
||||
BorderThickness="2"
|
||||
CornerRadius="10"
|
||||
Padding="20"
|
||||
Visibility="Collapsed">
|
||||
<StackPanel>
|
||||
<TextBlock Text="请选择你的角色" FontWeight="Bold" FontSize="16" Margin="0,0,0,10" HorizontalAlignment="Center"/>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="300">
|
||||
@ -299,9 +348,9 @@
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Style="{StaticResource SelectionItemStyle}"
|
||||
Tag="{Binding}"
|
||||
MouseLeftButtonDown="CharacterSelectionItem_MouseLeftButtonDown"
|
||||
MouseEnter="CharacterSelectionItem_MouseEnter">
|
||||
Tag="{Binding}"
|
||||
MouseLeftButtonDown="CharacterSelectionItem_MouseLeftButtonDown"
|
||||
MouseEnter="CharacterSelectionItem_MouseEnter">
|
||||
<TextBlock Text="{Binding NickName}" FontSize="14" FontWeight="SemiBold"/>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
@ -313,14 +362,14 @@
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="200">
|
||||
<!-- 限制详情区域高度 -->
|
||||
<RichTextBox x:Name="CharacterDetailsRichTextBox"
|
||||
IsReadOnly="True"
|
||||
BorderThickness="0"
|
||||
Background="Transparent"
|
||||
Foreground="DimGray"
|
||||
FontSize="11"
|
||||
AcceptsReturn="True"
|
||||
VerticalScrollBarVisibility="Disabled"
|
||||
HorizontalScrollBarVisibility="Disabled">
|
||||
IsReadOnly="True"
|
||||
BorderThickness="0"
|
||||
Background="Transparent"
|
||||
Foreground="DimGray"
|
||||
FontSize="11"
|
||||
AcceptsReturn="True"
|
||||
VerticalScrollBarVisibility="Disabled"
|
||||
HorizontalScrollBarVisibility="Disabled">
|
||||
<FlowDocument>
|
||||
<Paragraph Margin="0">将鼠标悬停在角色名称上以查看详情。</Paragraph>
|
||||
</FlowDocument>
|
||||
@ -331,17 +380,17 @@
|
||||
|
||||
<!-- 新增:技能/物品选择面板 (Overlay) -->
|
||||
<Border x:Name="SkillItemSelectionOverlay"
|
||||
Panel.ZIndex="200"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Width="400"
|
||||
MaxHeight="600"
|
||||
Background="#DDFFFFFF"
|
||||
BorderBrush="DarkGreen"
|
||||
BorderThickness="2"
|
||||
CornerRadius="10"
|
||||
Padding="20"
|
||||
Visibility="Collapsed">
|
||||
Panel.ZIndex="200"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Width="400"
|
||||
MaxHeight="600"
|
||||
Background="#DDFFFFFF"
|
||||
BorderBrush="DarkGreen"
|
||||
BorderThickness="2"
|
||||
CornerRadius="10"
|
||||
Padding="20"
|
||||
Visibility="Collapsed">
|
||||
<StackPanel>
|
||||
<TextBlock x:Name="SkillItemSelectionTitle" Text="请选择技能/物品" FontWeight="Bold" FontSize="16" Margin="0,0,0,10" HorizontalAlignment="Center"/>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="300">
|
||||
@ -349,9 +398,9 @@
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Style="{StaticResource SelectionItemStyle}"
|
||||
Tag="{Binding}"
|
||||
MouseLeftButtonDown="SkillItemSelectionItem_MouseLeftButtonDown"
|
||||
MouseEnter="SkillItemSelectionItem_MouseEnter">
|
||||
Tag="{Binding}"
|
||||
MouseLeftButtonDown="SkillItemSelectionItem_MouseLeftButtonDown"
|
||||
MouseEnter="SkillItemSelectionItem_MouseEnter">
|
||||
<Border.IsEnabled>
|
||||
<MultiBinding Converter="{StaticResource SkillUsabilityConverter}">
|
||||
<Binding Path="."/>
|
||||
@ -369,14 +418,14 @@
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="200">
|
||||
<!-- 限制详情区域高度 -->
|
||||
<RichTextBox x:Name="SkillItemDetailsRichTextBox"
|
||||
IsReadOnly="True"
|
||||
BorderThickness="0"
|
||||
Background="Transparent"
|
||||
Foreground="DimGray"
|
||||
FontSize="11"
|
||||
AcceptsReturn="True"
|
||||
VerticalScrollBarVisibility="Disabled"
|
||||
HorizontalScrollBarVisibility="Disabled">
|
||||
IsReadOnly="True"
|
||||
BorderThickness="0"
|
||||
Background="Transparent"
|
||||
Foreground="DimGray"
|
||||
FontSize="11"
|
||||
AcceptsReturn="True"
|
||||
VerticalScrollBarVisibility="Disabled"
|
||||
HorizontalScrollBarVisibility="Disabled">
|
||||
<FlowDocument>
|
||||
<Paragraph Margin="0">将鼠标悬停在名称上以查看详情。</Paragraph>
|
||||
</FlowDocument>
|
||||
@ -388,18 +437,18 @@
|
||||
|
||||
<!-- 新增:目标选择确认面板 (Overlay) -->
|
||||
<Border x:Name="TargetSelectionOverlay"
|
||||
Panel.ZIndex="200"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Margin="10"
|
||||
Width="250"
|
||||
MaxHeight="300"
|
||||
Background="#CCFFFFFF"
|
||||
BorderBrush="DarkRed"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
Padding="10"
|
||||
Visibility="Collapsed">
|
||||
Panel.ZIndex="200"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Margin="10"
|
||||
Width="250"
|
||||
MaxHeight="300"
|
||||
Background="#CCFFFFFF"
|
||||
BorderBrush="DarkRed"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
Padding="10"
|
||||
Visibility="Collapsed">
|
||||
<StackPanel>
|
||||
<TextBlock x:Name="TargetSelectionTitle" Text="选择目标" FontWeight="Bold" FontSize="14" Margin="0,0,0,5"/>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="200">
|
||||
@ -445,7 +494,7 @@
|
||||
|
||||
<!-- 移除按钮 -->
|
||||
<Button Grid.Column="1" Content="X" Margin="5,0,0,0" Tag="{Binding Id}" Click="RemoveTarget_Click"
|
||||
Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" VerticalAlignment="Center"/>
|
||||
Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
@ -461,17 +510,17 @@
|
||||
|
||||
<!-- 新增:继续提示面板 (Overlay) -->
|
||||
<Border x:Name="ContinuePromptOverlay"
|
||||
Panel.ZIndex="200"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Width="300"
|
||||
Height="150"
|
||||
Background="#DDFFFFFF"
|
||||
BorderBrush="DarkOrange"
|
||||
BorderThickness="2"
|
||||
CornerRadius="10"
|
||||
Padding="20"
|
||||
Visibility="Collapsed">
|
||||
Panel.ZIndex="200"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Width="300"
|
||||
Height="150"
|
||||
Background="#DDFFFFFF"
|
||||
BorderBrush="DarkOrange"
|
||||
BorderThickness="2"
|
||||
CornerRadius="10"
|
||||
Padding="20"
|
||||
Visibility="Collapsed">
|
||||
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
|
||||
<TextBlock x:Name="ContinuePromptTextBlock" Text="请点击继续..." TextWrapping="Wrap" HorizontalAlignment="Center" FontSize="14" Margin="0,0,0,15"/>
|
||||
<Button Content="继续" Width="80" Click="ContinuePromptButton_Click"/>
|
||||
@ -479,17 +528,17 @@
|
||||
</Border>
|
||||
|
||||
<TextBlock x:Name="CountdownTextBlock"
|
||||
Panel.ZIndex="200"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Margin="15"
|
||||
FontSize="18"
|
||||
FontWeight="Bold"
|
||||
Foreground="White"
|
||||
Background="#88000000"
|
||||
Padding="8"
|
||||
Visibility="Collapsed"
|
||||
Text="0 秒后继续..." />
|
||||
Panel.ZIndex="200"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Margin="15"
|
||||
FontSize="18"
|
||||
FontWeight="Bold"
|
||||
Foreground="White"
|
||||
Background="#88000000"
|
||||
Padding="8"
|
||||
Visibility="Collapsed"
|
||||
Text="0 秒后继续..." />
|
||||
|
||||
</Grid>
|
||||
</Border>
|
||||
@ -504,18 +553,18 @@
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Row="0" Text="调试日志" Margin="0,0,0,10" FontWeight="Bold" FontSize="14"/>
|
||||
<ScrollViewer Grid.Row="1" x:Name="DebugLogScrollViewer"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
HorizontalScrollBarVisibility="Disabled">
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
HorizontalScrollBarVisibility="Disabled">
|
||||
<!-- 修改:将 TextBlock 替换为 RichTextBox -->
|
||||
<RichTextBox x:Name="DebugLogRichTextBox"
|
||||
IsReadOnly="True"
|
||||
BorderThickness="0"
|
||||
Background="Transparent"
|
||||
Foreground="DimGray"
|
||||
FontSize="11"
|
||||
AcceptsReturn="True"
|
||||
VerticalScrollBarVisibility="Disabled"
|
||||
HorizontalScrollBarVisibility="Disabled">
|
||||
IsReadOnly="True"
|
||||
BorderThickness="0"
|
||||
Background="Transparent"
|
||||
Foreground="DimGray"
|
||||
FontSize="11"
|
||||
AcceptsReturn="True"
|
||||
VerticalScrollBarVisibility="Disabled"
|
||||
HorizontalScrollBarVisibility="Disabled">
|
||||
<FlowDocument>
|
||||
<Paragraph Margin="0">调试日志:</Paragraph>
|
||||
</FlowDocument>
|
||||
@ -559,16 +608,16 @@
|
||||
|
||||
<!-- 头像框 - 显示字符 -->
|
||||
<Border x:Name="CharacterAvatarBorder" Grid.RowSpan="4" Grid.Column="0" Width="60" Height="60" BorderBrush="DarkGray" BorderThickness="1" CornerRadius="5" Margin="0,0,10,0"
|
||||
Background="#FF6A5ACD">
|
||||
Background="#FF6A5ACD">
|
||||
<!-- 默认背景色,可以根据角色动态改变 -->
|
||||
<Grid>
|
||||
<TextBlock x:Name="CharacterAvatarTextBlock"
|
||||
Text="?"
|
||||
Foreground="White"
|
||||
FontSize="28"
|
||||
FontWeight="Bold"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
Text="?"
|
||||
Foreground="White"
|
||||
FontSize="28"
|
||||
FontWeight="Bold"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
@ -586,7 +635,7 @@
|
||||
<Rectangle x:Name="HpFillRectangle" HorizontalAlignment="Left" Fill="Green" Height="10" RadiusX="2" RadiusY="2"/>
|
||||
<!-- 护盾进度,叠加在HP之上 -->
|
||||
<Rectangle x:Name="ShieldFillRectangle" HorizontalAlignment="Left" Fill="Transparent" Height="10" RadiusX="2" RadiusY="2"
|
||||
Visibility="Collapsed" Panel.ZIndex="1"/>
|
||||
Visibility="Collapsed" Panel.ZIndex="1"/>
|
||||
</Grid>
|
||||
<TextBlock x:Name="HpValueTextBlock" Text="0/0" Margin="5,0,0,0" VerticalAlignment="Center" FontSize="10"/>
|
||||
</StackPanel>
|
||||
@ -652,7 +701,7 @@
|
||||
|
||||
<!-- 新增中间部分:装备和状态 -->
|
||||
<Border Grid.Column="1" BorderBrush="LightGray" BorderThickness="0,0,1,0" Margin="0,0,5,0" Padding="5"
|
||||
x:Name="EquipStatusInfoBorder" MouseLeftButtonDown="EquipStatusInfoBorder_MouseLeftButtonDown">
|
||||
x:Name="EquipStatusInfoBorder" MouseLeftButtonDown="EquipStatusInfoBorder_MouseLeftButtonDown">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<!-- 装备栏 -->
|
||||
<TextBlock Text="装备" FontWeight="Bold" FontSize="14" Margin="0,0,0,5"/>
|
||||
@ -695,18 +744,18 @@
|
||||
<Border BorderBrush="LightGray" BorderThickness="0,1,0,0" Margin="0,10,0,0" Padding="0,10,0,0">
|
||||
<StackPanel>
|
||||
<TextBlock Text="详情描述" FontWeight="Bold" FontSize="14" Margin="0,0,0,5"/>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="80">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" Height="140">
|
||||
<RichTextBox x:Name="DescriptionRichTextBox"
|
||||
IsReadOnly="True"
|
||||
BorderThickness="0"
|
||||
Background="Transparent"
|
||||
Foreground="DimGray"
|
||||
FontSize="11"
|
||||
AcceptsReturn="True"
|
||||
VerticalScrollBarVisibility="Disabled"
|
||||
HorizontalScrollBarVisibility="Disabled">
|
||||
IsReadOnly="True"
|
||||
BorderThickness="0"
|
||||
Background="Transparent"
|
||||
Foreground="DimGray"
|
||||
FontSize="11"
|
||||
AcceptsReturn="True"
|
||||
VerticalScrollBarVisibility="Disabled"
|
||||
HorizontalScrollBarVisibility="Disabled">
|
||||
<FlowDocument>
|
||||
<Paragraph Margin="0">点击装备或状态图标查看详情。</Paragraph>
|
||||
<Paragraph Margin="0">点击装备、状态、技能或物品的图标以查看详情。</Paragraph>
|
||||
</FlowDocument>
|
||||
</RichTextBox>
|
||||
</ScrollViewer>
|
||||
@ -715,36 +764,139 @@
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 右半部分:操作按钮 -->
|
||||
<!-- 右半部分:操作按钮 和 数据统计 (Grid.Column="2") -->
|
||||
<Border Grid.Column="2" Padding="5">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock Text="操作" FontWeight="Bold" FontSize="14" Margin="0,0,0,10"/>
|
||||
<WrapPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
<!-- IsEnabled 默认设置为 False,由代码控制 -->
|
||||
<!-- Tag 属性用于在 Click 事件中识别是哪个动作 -->
|
||||
<Button x:Name="MoveButton" Content="移动" Width="100" Height="30" Margin="5" Click="ActionButton_Click" Tag="{x:Static constant:CharacterActionType.Move}" IsEnabled="False"/>
|
||||
<Button x:Name="AttackButton" Content="普通攻击" Width="100" Height="30" Margin="5" Click="ActionButton_Click" Tag="{x:Static constant:CharacterActionType.NormalAttack}" IsEnabled="False"/>
|
||||
<Button x:Name="SkillButton" Content="战技/魔法" Width="100" Height="30" Margin="5" Click="ActionButton_Click" Tag="{x:Static constant:CharacterActionType.PreCastSkill}" IsEnabled="False"/>
|
||||
<Button x:Name="UseItemButton" Content="使用物品" Width="100" Height="30" Margin="5" Click="ActionButton_Click" Tag="{x:Static constant:CharacterActionType.UseItem}" IsEnabled="False"/>
|
||||
<Button x:Name="EndTurnButton" Content="结束回合" Width="100" Height="30" Margin="5" Click="ActionButton_Click" Tag="{x:Static constant:CharacterActionType.EndTurn}" IsEnabled="False"/>
|
||||
<Button x:Name="PreCastButton" Content="爆发技插队" Width="100" Height="30" Margin="5" Click="PreCastSkillButton_Click" Tag="" IsEnabled="False"/>
|
||||
</WrapPanel>
|
||||
<!-- 将原有的StackPanel替换为Grid,以容纳新的技能/物品区域 -->
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- 新增:技能和物品图标区域 -->
|
||||
<RowDefinition Height="*"/>
|
||||
<!-- 原有的操作按钮和数据统计 -->
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 新增:数据统计 -->
|
||||
<Border BorderBrush="LightGray" BorderThickness="0,1,0,0" Margin="0,10,0,0" Padding="0,10,0,0">
|
||||
<StackPanel>
|
||||
<TextBlock Text="数据统计" FontWeight="Bold" FontSize="14" Margin="0,0,0,5"/>
|
||||
<TextBlock x:Name="StatsRatingKillsAssistsDeathsTextBlock" Style="{StaticResource CharacterAttributeTextStyle}"/>
|
||||
<TextBlock x:Name="StatsLiveTimeRoundTurnTextBlock" Style="{StaticResource CharacterAttributeTextStyle}"/>
|
||||
<TextBlock x:Name="StatsControlHealShieldTextBlock" Style="{StaticResource CharacterAttributeTextStyle}"/>
|
||||
<TextBlock x:Name="StatsTotalDamageTextBlock" Style="{StaticResource CharacterAttributeTextStyle}"/>
|
||||
<TextBlock x:Name="StatsTotalTakenDamageTextBlock" Style="{StaticResource CharacterAttributeTextStyle}"/>
|
||||
<TextBlock x:Name="StatsTrueDamageTextBlock" Style="{StaticResource CharacterAttributeTextStyle}" Visibility="Collapsed"/>
|
||||
<!-- 初始隐藏,有真实伤害时显示 -->
|
||||
<TextBlock x:Name="StatsDamagePerSecondTurnTextBlock" Style="{StaticResource CharacterAttributeTextStyle}"/>
|
||||
</StackPanel>
|
||||
<!-- 新增:技能和物品图标区域 (Grid.Row="0") -->
|
||||
<Border Grid.Row="0" BorderBrush="LightGray" BorderThickness="0,0,0,1" Margin="0,0,0,10" Padding="0,0,0,10">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<!-- 技能列 -->
|
||||
<ColumnDefinition Width="*"/>
|
||||
<!-- 物品列 -->
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 技能图标列表 -->
|
||||
<StackPanel Grid.Column="0" Margin="0,0,5,0">
|
||||
<TextBlock Text="技能" FontWeight="Bold" FontSize="12" Margin="0,0,0,5"/>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="80">
|
||||
<ItemsControl x:Name="CharacterSkillsPanel" ItemsSource="{Binding CharacterSkillsAndItems.Skills, RelativeSource={RelativeSource AncestorType=UserControl}}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapPanel/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Tag="{Binding}"
|
||||
ToolTip="{Binding Converter={StaticResource ToStringConverter}}"
|
||||
MouseLeftButtonDown="SkillIcon_MouseLeftButtonDown">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border" BasedOn="{StaticResource StatusIconStyle}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Value="False">
|
||||
<DataTrigger.Binding>
|
||||
<MultiBinding Converter="{StaticResource SkillUsabilityConverter}">
|
||||
<Binding Path="."/>
|
||||
<Binding ElementName="GameMapViewerControl" Path="CurrentCharacter"/>
|
||||
</MultiBinding>
|
||||
</DataTrigger.Binding>
|
||||
<Setter Property="Opacity" Value="0.5"/>
|
||||
<Setter Property="Background" Value="LightGray"/>
|
||||
<Setter Property="BorderBrush" Value="DimGray"/>
|
||||
<Setter Property="TextElement.Foreground" Value="DimGray"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<TextBlock Text="{Binding Name, Converter={StaticResource FirstCharConverter}}"
|
||||
Style="{StaticResource StatusIconTextStyle}"/>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 物品图标列表 -->
|
||||
<StackPanel Grid.Column="1" Margin="5,0,0,0">
|
||||
<TextBlock Text="物品" FontWeight="Bold" FontSize="12" Margin="0,0,0,5"/>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" MaxHeight="80">
|
||||
<ItemsControl x:Name="CharacterItemsPanel" ItemsSource="{Binding CharacterSkillsAndItems.Items, RelativeSource={RelativeSource AncestorType=UserControl}}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapPanel/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border Tag="{Binding}"
|
||||
ToolTip="{Binding Converter={StaticResource ToStringConverter}}"
|
||||
MouseLeftButtonDown="ItemIcon_MouseLeftButtonDown">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border" BasedOn="{StaticResource StatusIconStyle}">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Enable}" Value="False">
|
||||
<Setter Property="Opacity" Value="0.5"/>
|
||||
<Setter Property="Background" Value="LightGray"/>
|
||||
<Setter Property="BorderBrush" Value="DimGray"/>
|
||||
<Setter Property="TextElement.Foreground" Value="DimGray"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<TextBlock Text="{Binding Name, Converter={StaticResource FirstCharConverter}}"
|
||||
Style="{StaticResource StatusIconTextStyle}"/>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 原有的操作按钮和数据统计 (现在在 Grid.Row="1") -->
|
||||
<StackPanel Grid.Row="1" Orientation="Vertical">
|
||||
<TextBlock Text="操作" FontWeight="Bold" FontSize="14" Margin="0,0,0,10"/>
|
||||
<WrapPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
<!-- IsEnabled 默认设置为 False,由代码控制 -->
|
||||
<!-- Tag 属性用于在 Click 事件中识别是哪个动作 -->
|
||||
<Button x:Name="MoveButton" Content="移动" Width="100" Height="30" Margin="5" Click="ActionButton_Click" Tag="{x:Static constant:CharacterActionType.Move}" IsEnabled="False"/>
|
||||
<Button x:Name="AttackButton" Content="普通攻击" Width="100" Height="30" Margin="5" Click="ActionButton_Click" Tag="{x:Static constant:CharacterActionType.NormalAttack}" IsEnabled="False"/>
|
||||
<Button x:Name="SkillButton" Content="战技/魔法" Width="100" Height="30" Margin="5" Click="ActionButton_Click" Tag="{x:Static constant:CharacterActionType.PreCastSkill}" IsEnabled="False"/>
|
||||
<Button x:Name="UseItemButton" Content="使用物品" Width="100" Height="30" Margin="5" Click="ActionButton_Click" Tag="{x:Static constant:CharacterActionType.UseItem}" IsEnabled="False"/>
|
||||
<Button x:Name="EndTurnButton" Content="结束回合" Width="100" Height="30" Margin="5" Click="ActionButton_Click" Tag="{x:Static constant:CharacterActionType.EndTurn}" IsEnabled="False"/>
|
||||
<Button x:Name="PreCastButton" Content="爆发技插队" Width="100" Height="30" Margin="5" Click="PreCastSkillButton_Click" Tag="" IsEnabled="False"/>
|
||||
<Button x:Name="AutoModeButton" Content="自动模式:关" Width="100" Height="30" Margin="5" Click="AutoModeButton_Click" Tag="" IsEnabled="True"/>
|
||||
<Button x:Name="FastModeButton" Content="快速模式:关" Width="100" Height="30" Margin="5" Click="FastModeButton_Click" Tag="" IsEnabled="True"/>
|
||||
</WrapPanel>
|
||||
|
||||
<!-- 新增:数据统计 -->
|
||||
<Border BorderBrush="LightGray" BorderThickness="0,1,0,0" Margin="0,10,0,0" Padding="0,10,0,0">
|
||||
<StackPanel>
|
||||
<TextBlock Text="数据统计" FontWeight="Bold" FontSize="14" Margin="0,0,0,5"/>
|
||||
<TextBlock x:Name="StatsRatingKillsAssistsDeathsTextBlock" Style="{StaticResource CharacterAttributeTextStyle}"/>
|
||||
<TextBlock x:Name="StatsLiveTimeRoundTurnTextBlock" Style="{StaticResource CharacterAttributeTextStyle}"/>
|
||||
<TextBlock x:Name="StatsControlHealShieldTextBlock" Style="{StaticResource CharacterAttributeTextStyle}"/>
|
||||
<TextBlock x:Name="StatsTotalDamageTextBlock" Style="{StaticResource CharacterAttributeTextStyle}"/>
|
||||
<TextBlock x:Name="StatsTotalTakenDamageTextBlock" Style="{StaticResource CharacterAttributeTextStyle}"/>
|
||||
<TextBlock x:Name="StatsTrueDamageTextBlock" Style="{StaticResource CharacterAttributeTextStyle}" Visibility="Collapsed"/>
|
||||
<!-- 初始隐藏,有真实伤害时显示 -->
|
||||
<TextBlock x:Name="StatsDamagePerSecondTurnTextBlock" Style="{StaticResource CharacterAttributeTextStyle}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
@ -3,21 +3,22 @@ using System.Collections.Specialized;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using System.Xml.Linq;
|
||||
using Milimoe.FunGame.Core.Api.Utility;
|
||||
using Milimoe.FunGame.Core.Entity;
|
||||
using Milimoe.FunGame.Core.Interface.Entity;
|
||||
using Milimoe.FunGame.Core.Library.Common.Addon;
|
||||
using Milimoe.FunGame.Core.Library.Constant;
|
||||
using Milimoe.FunGame.Core.Model;
|
||||
using Oshima.FunGame.OshimaServers.Service;
|
||||
using static Milimoe.FunGame.Core.Library.Constant.General;
|
||||
using Brush = System.Windows.Media.Brush;
|
||||
using Brushes = System.Windows.Media.Brushes;
|
||||
using Button = System.Windows.Controls.Button;
|
||||
using Grid = Milimoe.FunGame.Core.Library.Common.Addon.Grid;
|
||||
using MessageBox = System.Windows.MessageBox;
|
||||
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
|
||||
using Panel = System.Windows.Controls.Panel;
|
||||
using Rectangle = System.Windows.Shapes.Rectangle;
|
||||
@ -67,6 +68,14 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
private bool _isSelectingTargets = false; // 标记当前是否处于目标选择模式
|
||||
private readonly CharacterQueueItem _selectionPredictCharacter = new(Factory.GetCharacter(), 0); // 选择时进行下轮预测(用于行动顺序表显示)
|
||||
|
||||
// 新增:用于跟踪当前高亮的技能和物品图标
|
||||
private Border? _highlightedSkillIcon;
|
||||
private Border? _highlightedItemIcon;
|
||||
|
||||
// 模式
|
||||
private bool _isAutoMode = false;
|
||||
private bool _isFastMode = false;
|
||||
|
||||
public GameMapViewer()
|
||||
{
|
||||
InitializeComponent();
|
||||
@ -112,7 +121,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
get { return (int)GetValue(CurrentRoundProperty); }
|
||||
set { SetValue(CurrentRoundProperty, value); }
|
||||
}
|
||||
|
||||
|
||||
// 回合奖励
|
||||
public static readonly DependencyProperty TurnRewardsProperty =
|
||||
DependencyProperty.Register("TurnRewards", typeof(Dictionary<int, List<Skill>>), typeof(GameMapViewer),
|
||||
@ -123,7 +132,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
get { return (Dictionary<int, List<Skill>>)GetValue(TurnRewardsProperty); }
|
||||
set { SetValue(TurnRewardsProperty, value); }
|
||||
}
|
||||
|
||||
|
||||
// 新增 CurrentCharacter 依赖属性:用于显示当前玩家角色的信息
|
||||
public static readonly DependencyProperty CurrentCharacterProperty =
|
||||
DependencyProperty.Register("CurrentCharacter", typeof(Character), typeof(GameMapViewer),
|
||||
@ -143,6 +152,9 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
// 用于 UI 绑定的 ViewModel 集合
|
||||
public ObservableCollection<CharacterQueueItemViewModel> CharacterQueueDisplayItems { get; } = [];
|
||||
|
||||
// 技能组
|
||||
public CharacterSkillsAndItemsViewModel CharacterSkillsAndItems { get; set; } = new();
|
||||
|
||||
public Character? CurrentCharacter
|
||||
{
|
||||
get { return (Character)GetValue(CurrentCharacterProperty); }
|
||||
@ -199,23 +211,25 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
set { SetValue(MaxRespawnTimesProperty, value); }
|
||||
}
|
||||
|
||||
|
||||
public void Invoke(Action action)
|
||||
public async Task InvokeAsync(Action action)
|
||||
{
|
||||
if (!this.Dispatcher.CheckAccess())
|
||||
{
|
||||
this.Dispatcher.Invoke(() => action());
|
||||
await this.Dispatcher.InvokeAsync(action);
|
||||
}
|
||||
else
|
||||
{
|
||||
action();
|
||||
}
|
||||
else action();
|
||||
}
|
||||
|
||||
public async Task Invoke(Func<Task> action)
|
||||
public async Task InvokeAsync(Func<Task> task)
|
||||
{
|
||||
if (!this.Dispatcher.CheckAccess())
|
||||
{
|
||||
await this.Dispatcher.InvokeAsync(async () => await action());
|
||||
await this.Dispatcher.InvokeAsync(task);
|
||||
}
|
||||
else await action();
|
||||
else await task();
|
||||
}
|
||||
|
||||
// 原有的 ShowInput 方法不再用于游戏逻辑,可以删除或保留用于其他非游戏逻辑的通用输入
|
||||
@ -288,17 +302,15 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
GameMapViewer viewer = (GameMapViewer)d;
|
||||
_ = viewer.UpdateBottomInfoPanel();
|
||||
_ = viewer.UpdateCharacterStatisticsPanel(); // 角色改变时也更新统计面板
|
||||
// 角色改变时,清除装备/状态描述
|
||||
SetRichTextBoxText(viewer.DescriptionRichTextBox, "点击装备或状态图标查看详情。");
|
||||
viewer.ClearEquipSlotHighlights();
|
||||
viewer.ClearStatusIconHighlights();
|
||||
// 角色改变时,清除装备/状态/技能/物品描述和高亮
|
||||
viewer.ResetDescriptionAndHighlights(); // 使用新的重置方法
|
||||
}
|
||||
|
||||
// 新增:当CharacterQueueData属性改变时,更新左侧队列面板
|
||||
private static void OnCharacterQueueDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
GameMapViewer viewer = (GameMapViewer)d;
|
||||
_ = viewer.UpdateLeftQueuePanel();
|
||||
_ = viewer.UpdateLeftQueuePanelGrid();
|
||||
}
|
||||
|
||||
// 新增:当CharacterStatistics属性改变时,更新数据统计面板
|
||||
@ -521,6 +533,20 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
_uiElementToCharacter.Add(characterBorder, character);
|
||||
}
|
||||
|
||||
// 清除所有角色的高亮
|
||||
foreach (Character character in _characterToUiElement.Keys)
|
||||
{
|
||||
Border border = _characterToUiElement[character];
|
||||
border.BorderBrush = character.Promotion switch
|
||||
{
|
||||
200 => Brushes.BurlyWood,
|
||||
300 => Brushes.SkyBlue,
|
||||
400 => Brushes.Orchid,
|
||||
_ => Brushes.Salmon
|
||||
};
|
||||
border.BorderThickness = new Thickness(2);
|
||||
}
|
||||
|
||||
// 如果处于目标选择模式,重新应用高亮
|
||||
if (_isSelectingTargets)
|
||||
{
|
||||
@ -531,12 +557,12 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
/// <summary>
|
||||
/// 更新左侧动态队列面板,显示角色及其AT Delay。
|
||||
/// </summary>
|
||||
public async Task UpdateLeftQueuePanel()
|
||||
public async Task UpdateLeftQueuePanelGrid()
|
||||
{
|
||||
// 确保在UI线程上执行
|
||||
if (!this.Dispatcher.CheckAccess())
|
||||
{
|
||||
await this.Dispatcher.InvokeAsync(async () => await UpdateLeftQueuePanel());
|
||||
await this.Dispatcher.InvokeAsync(async () => await UpdateLeftQueuePanelGrid());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -569,10 +595,8 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
return;
|
||||
}
|
||||
|
||||
// 每次更新面板时,清除装备/状态描述和高亮
|
||||
SetRichTextBoxText(DescriptionRichTextBox, "点击装备或状态图标查看详情。"); // 新代码
|
||||
ClearEquipSlotHighlights();
|
||||
ClearStatusIconHighlights();
|
||||
// 每次更新面板时,清除所有描述和高亮
|
||||
ResetDescriptionAndHighlights(true);
|
||||
|
||||
Character? character = CurrentCharacter;
|
||||
if (character != null)
|
||||
@ -667,10 +691,15 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
}
|
||||
}
|
||||
|
||||
// 更新技能组
|
||||
CharacterSkillsAndItems.Skills = [character.NormalAttack, .. character.Skills];
|
||||
CharacterSkillsAndItems.Items = [.. character.Items];
|
||||
|
||||
// --- 更新其他角色属性 ---
|
||||
bool showGrowth = false; // 假设不显示成长值
|
||||
|
||||
AttackTextBlock.Text = $"攻击力:{character.ATK:0.##}" + (character.ExATK != 0 ? $" [{character.BaseATK:0.##} {(character.ExATK >= 0 ? "+" : "-")} {Math.Abs(character.ExATK):0.##}]" : "");
|
||||
double exATK = character.ExATK + character.ExATK2 + character.ExATK3;
|
||||
AttackTextBlock.Text = $"攻击力:{character.ATK:0.##}" + (exATK != 0 ? $" [{character.BaseATK:0.##} {(exATK >= 0 ? "+" : "-")} {Math.Abs(exATK):0.##}]" : "");
|
||||
|
||||
double exDEF = character.ExDEF + character.ExDEF2 + character.ExDEF3;
|
||||
PhysicalDefTextBlock.Text = $"物理护甲:{character.DEF:0.##}" + (exDEF != 0 ? $" [{character.BaseDEF:0.##} {(exDEF >= 0 ? "+" : "-")} {Math.Abs(exDEF):0.##}]" : "") + $" ({character.PDR * 100:0.##}%)";
|
||||
@ -731,6 +760,10 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
// 清空状态条
|
||||
CharacterEffectsPanel.Children.Clear();
|
||||
|
||||
// 清空技能组
|
||||
CharacterSkillsAndItems.Skills = [];
|
||||
CharacterSkillsAndItems.Items = [];
|
||||
|
||||
// 清空角色属性
|
||||
AttackTextBlock.Text = "攻击力:";
|
||||
PhysicalDefTextBlock.Text = "物理护甲:";
|
||||
@ -979,7 +1012,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
{
|
||||
CurrentCharacter = PlayerCharacter;
|
||||
}
|
||||
// 新增:关闭格子信息面板时,重置装备/状态描述和高亮
|
||||
// 新增:关闭格子信息面板时,重置装备/状态/技能/物品描述和高亮
|
||||
ResetDescriptionAndHighlights();
|
||||
}
|
||||
|
||||
@ -1001,6 +1034,9 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
{
|
||||
ClearEquipSlotHighlights();
|
||||
ClearStatusIconHighlights();
|
||||
ClearSkillIconHighlights();
|
||||
ClearItemIconHighlights();
|
||||
|
||||
clickedBorder.BorderBrush = Brushes.Blue;
|
||||
clickedBorder.BorderThickness = new Thickness(2);
|
||||
|
||||
@ -1054,6 +1090,9 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
{
|
||||
ClearStatusIconHighlights(); // 清除所有状态图标的旧高亮
|
||||
ClearEquipSlotHighlights(); // 清除所有装备槽位的旧高亮
|
||||
ClearSkillIconHighlights(); // 清除技能图标高亮
|
||||
ClearItemIconHighlights(); // 清除物品图标高亮
|
||||
|
||||
clickedBorder.BorderBrush = Brushes.Blue; // 高亮当前点击的状态图标
|
||||
clickedBorder.BorderThickness = new Thickness(1.5);
|
||||
|
||||
@ -1069,11 +1108,106 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
{
|
||||
foreach (Border border in CharacterEffectsPanel.Children.OfType<Border>())
|
||||
{
|
||||
border.BorderBrush = Brushes.Gray;
|
||||
border.BorderThickness = new Thickness(0.5);
|
||||
// 获取默认样式,以便恢复默认边框颜色和粗细
|
||||
Style defaultStyle = (Style)this.FindResource("StatusIconStyle");
|
||||
border.BorderBrush = (Brush)(defaultStyle.Setters.OfType<Setter>().FirstOrDefault(s => s.Property == Border.BorderBrushProperty)?.Value ?? Brushes.Gray);
|
||||
border.BorderThickness = (Thickness)(defaultStyle.Setters.OfType<Setter>().FirstOrDefault(s => s.Property == Border.BorderThicknessProperty)?.Value ?? new Thickness(0.5));
|
||||
}
|
||||
}
|
||||
|
||||
// --- 新增:技能图标点击事件和辅助方法 ---
|
||||
private void SkillIcon_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (sender is Border clickedBorder && clickedBorder.Tag is ISkill skill)
|
||||
{
|
||||
ClearSkillIconHighlights();
|
||||
ClearItemIconHighlights();
|
||||
ClearEquipSlotHighlights();
|
||||
ClearStatusIconHighlights();
|
||||
|
||||
_highlightedSkillIcon = clickedBorder;
|
||||
_highlightedSkillIcon.BorderBrush = Brushes.Blue;
|
||||
_highlightedSkillIcon.BorderThickness = new Thickness(1.5);
|
||||
|
||||
SetRichTextBoxText(DescriptionRichTextBox, skill.ToString() ?? "");
|
||||
_ = AppendDebugLog($"查看技能: {skill.Name}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除所有技能图标的边框高亮。
|
||||
/// </summary>
|
||||
private void ClearSkillIconHighlights()
|
||||
{
|
||||
if (_highlightedSkillIcon != null)
|
||||
{
|
||||
Style defaultStyle = (Style)this.FindResource("StatusIconStyle");
|
||||
_highlightedSkillIcon.BorderBrush = (Brush)(defaultStyle.Setters.OfType<Setter>().FirstOrDefault(s => s.Property == Border.BorderBrushProperty)?.Value ?? Brushes.Gray);
|
||||
_highlightedSkillIcon.BorderThickness = (Thickness)(defaultStyle.Setters.OfType<Setter>().FirstOrDefault(s => s.Property == Border.BorderThicknessProperty)?.Value ?? new Thickness(0.5));
|
||||
_highlightedSkillIcon = null;
|
||||
}
|
||||
// 遍历 ItemsControl 中的所有生成的容器,确保所有图标都恢复默认样式
|
||||
if (CharacterSkillsPanel.ItemsSource != null)
|
||||
{
|
||||
foreach (var item in CharacterSkillsPanel.ItemsSource)
|
||||
{
|
||||
if (CharacterSkillsPanel.ItemContainerGenerator.ContainerFromItem(item) is Border border)
|
||||
{
|
||||
Style defaultStyle = (Style)this.FindResource("StatusIconStyle");
|
||||
border.BorderBrush = (Brush)(defaultStyle.Setters.OfType<Setter>().FirstOrDefault(s => s.Property == Border.BorderBrushProperty)?.Value ?? Brushes.Gray);
|
||||
border.BorderThickness = (Thickness)(defaultStyle.Setters.OfType<Setter>().FirstOrDefault(s => s.Property == Border.BorderThicknessProperty)?.Value ?? new Thickness(0.5));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- 新增:物品图标点击事件和辅助方法 ---
|
||||
private void ItemIcon_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (sender is Border clickedBorder && clickedBorder.Tag is Item item)
|
||||
{
|
||||
ClearSkillIconHighlights();
|
||||
ClearItemIconHighlights();
|
||||
ClearEquipSlotHighlights();
|
||||
ClearStatusIconHighlights();
|
||||
|
||||
_highlightedItemIcon = clickedBorder;
|
||||
_highlightedItemIcon.BorderBrush = Brushes.Blue;
|
||||
_highlightedItemIcon.BorderThickness = new Thickness(1.5);
|
||||
|
||||
SetRichTextBoxText(DescriptionRichTextBox, item.ToString() ?? "");
|
||||
_ = AppendDebugLog($"查看物品: {item.Name}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除所有物品图标的边框高亮。
|
||||
/// </summary>
|
||||
private void ClearItemIconHighlights()
|
||||
{
|
||||
if (_highlightedItemIcon != null)
|
||||
{
|
||||
Style defaultStyle = (Style)this.FindResource("StatusIconStyle");
|
||||
_highlightedItemIcon.BorderBrush = (Brush)(defaultStyle.Setters.OfType<Setter>().FirstOrDefault(s => s.Property == Border.BorderBrushProperty)?.Value ?? Brushes.Gray);
|
||||
_highlightedItemIcon.BorderThickness = (Thickness)(defaultStyle.Setters.OfType<Setter>().FirstOrDefault(s => s.Property == Border.BorderThicknessProperty)?.Value ?? new Thickness(0.5));
|
||||
_highlightedItemIcon = null;
|
||||
}
|
||||
// 遍历 ItemsControl 中的所有生成的容器,确保所有图标都恢复默认样式
|
||||
if (CharacterItemsPanel.ItemsSource != null)
|
||||
{
|
||||
foreach (var item in CharacterItemsPanel.ItemsSource)
|
||||
{
|
||||
if (CharacterItemsPanel.ItemContainerGenerator.ContainerFromItem(item) is Border border)
|
||||
{
|
||||
Style defaultStyle = (Style)this.FindResource("StatusIconStyle");
|
||||
border.BorderBrush = (Brush)(defaultStyle.Setters.OfType<Setter>().FirstOrDefault(s => s.Property == Border.BorderBrushProperty)?.Value ?? Brushes.Gray);
|
||||
border.BorderThickness = (Thickness)(defaultStyle.Setters.OfType<Setter>().FirstOrDefault(s => s.Property == Border.BorderThicknessProperty)?.Value ?? new Thickness(0.5));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --- 操作按钮 (底部右侧) ---
|
||||
|
||||
/// <summary>
|
||||
@ -1099,7 +1233,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
_resolveActionType?.Invoke(actionType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 预释放爆发技的特殊处理。
|
||||
/// </summary>
|
||||
@ -1123,6 +1257,59 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自动模式(托管)的特殊处理。
|
||||
/// </summary>
|
||||
private async void AutoModeButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (PlayerCharacter != null)
|
||||
{
|
||||
_isAutoMode = !_isAutoMode;
|
||||
AutoModeButton.Content = _isAutoMode ? "自动模式:开" : "自动模式:关";
|
||||
_controller.SetAutoMode(!_isAutoMode, PlayerCharacter);
|
||||
await AppendDebugLog($"已切换到{(_isAutoMode ? "自动模式" : "手动模式")}。");
|
||||
if (_resolveActionType != null)
|
||||
{
|
||||
MessageBoxResult result = MessageBox.Show(
|
||||
"是否跳过当前回合?AI将代替你操作。",
|
||||
"自动模式跳过当前回合确认",
|
||||
MessageBoxButton.YesNo,
|
||||
MessageBoxImage.Question
|
||||
);
|
||||
if (result == MessageBoxResult.Yes)
|
||||
{
|
||||
_resolveActionType.Invoke(GamingQueue.GetActionType(0.33, 0.33, 0.34));
|
||||
}
|
||||
else
|
||||
{
|
||||
await AppendDebugLog("自动模式将在下一回合开始接管你的回合。");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await AppendDebugLog("找不到角色。");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 快速模式(仅看我的回合)的特殊处理。
|
||||
/// </summary>
|
||||
private async void FastModeButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (PlayerCharacter != null)
|
||||
{
|
||||
_isFastMode = !_isFastMode;
|
||||
FastModeButton.Content = _isFastMode ? "快速模式:开" : "快速模式:关";
|
||||
_controller.SetFastMode(_isFastMode);
|
||||
await AppendDebugLog($"已切换到{(_isFastMode ? "快速模式" : "正常模式")}。");
|
||||
}
|
||||
else
|
||||
{
|
||||
await AppendDebugLog("找不到角色。");
|
||||
}
|
||||
}
|
||||
|
||||
// --- UI 提示方法 (由 GameMapController 调用) ---
|
||||
|
||||
/// <summary>
|
||||
@ -1134,7 +1321,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
{
|
||||
_resolveCharacterSelection = callback;
|
||||
CharacterSelectionItemsControl.ItemsSource = availableCharacters;
|
||||
SetRichTextBoxText(CharacterDetailsRichTextBox, "将鼠标悬停在角色名称上查看详情。");
|
||||
SetRichTextBoxText(CharacterDetailsRichTextBox, "将鼠标悬停在角色名称上以查看详情。");
|
||||
CharacterSelectionOverlay.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
@ -1436,13 +1623,6 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
/// </summary>
|
||||
private void UpdateCharacterHighlights()
|
||||
{
|
||||
// 清除所有角色的高亮
|
||||
foreach (var border in _characterToUiElement.Values)
|
||||
{
|
||||
border.BorderBrush = Brushes.DarkBlue; // 默认颜色
|
||||
border.BorderThickness = new Thickness(1.5);
|
||||
}
|
||||
|
||||
// 高亮潜在目标(黄色边框)
|
||||
if (_potentialTargetsForSelection != null)
|
||||
{
|
||||
@ -1451,7 +1631,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
if (_characterToUiElement.TryGetValue(potentialTarget, out Border? border))
|
||||
{
|
||||
border.BorderBrush = Brushes.Yellow;
|
||||
border.BorderThickness = new Thickness(2);
|
||||
border.BorderThickness = new Thickness(4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1462,7 +1642,7 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
if (_characterToUiElement.TryGetValue(selectedTarget, out Border? border))
|
||||
{
|
||||
border.BorderBrush = Brushes.Red; // 已选目标颜色
|
||||
border.BorderThickness = new Thickness(3);
|
||||
border.BorderThickness = new Thickness(6);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1604,11 +1784,16 @@ namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetDescriptionAndHighlights()
|
||||
/// <summary>
|
||||
/// 重置所有描述文本框并清除所有高亮。
|
||||
/// </summary>
|
||||
private void ResetDescriptionAndHighlights(bool clearHightlightsOnly = false)
|
||||
{
|
||||
SetRichTextBoxText(DescriptionRichTextBox, "点击装备或状态图标查看详情。");
|
||||
if (!clearHightlightsOnly) SetRichTextBoxText(DescriptionRichTextBox, "点击装备、状态、技能或物品的图标以查看详情。");
|
||||
ClearEquipSlotHighlights();
|
||||
ClearStatusIconHighlights();
|
||||
ClearSkillIconHighlights();
|
||||
ClearItemIconHighlights();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -1,9 +1,47 @@
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Milimoe.FunGame.Core.Entity;
|
||||
using Milimoe.FunGame.Core.Interface.Entity;
|
||||
|
||||
namespace Milimoe.FunGame.Testing.Desktop.GameMapTesting
|
||||
{
|
||||
public class CharacterSkillsAndItemsViewModel : INotifyPropertyChanged
|
||||
{
|
||||
public List<ISkill> Skills
|
||||
{
|
||||
get => _skills;
|
||||
set
|
||||
{
|
||||
if (_skills != value)
|
||||
{
|
||||
_skills = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
private List<ISkill> _skills = [];
|
||||
|
||||
public List<Item> Items
|
||||
{
|
||||
get => _items;
|
||||
set
|
||||
{
|
||||
if (_items != value)
|
||||
{
|
||||
_items = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
private List<Item> _items = [];
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
|
||||
public class CharacterQueueItemViewModel(CharacterQueueItem model, Func<Dictionary<int, List<Skill>>> getTurnRewards) : INotifyPropertyChanged
|
||||
{
|
||||
public CharacterQueueItem Model { get; } = model ?? throw new ArgumentNullException(nameof(model));
|
||||
Loading…
x
Reference in New Issue
Block a user