diff --git a/Entity/Character/Character.cs b/Entity/Character/Character.cs index ab07f1b..ffd098d 100644 --- a/Entity/Character/Character.cs +++ b/Entity/Character/Character.cs @@ -749,11 +749,17 @@ namespace Milimoe.FunGame.Core.Entity public double ExCDR { get; set; } = 0; /// - /// 攻击距离 [ 与技能和物品相关 ] [ 单位:格 ] + /// 攻击距离 [ 与技能和物品相关 ] [ 单位:格(半径) ] /// [InitOptional] - public double ATR { get; set; } = 1; - + public int ATR { get; set; } = 1; + + /// + /// 行动力/可移动距离 [ 与技能和物品相关 ] [ 单位:格(半径) ] + /// + [InitOptional] + public int MOV { get; set; } = 5; + /// /// 暴击率(%) = [ 与敏捷相关 ] + 额外暴击率(%) /// @@ -2017,6 +2023,7 @@ namespace Milimoe.FunGame.Core.Entity c.Lifesteal = Lifesteal; c.Shield = Shield.Copy(); c.ATR = ATR; + c.MOV = MOV; c.MagicType = MagicType; c.ImmuneType = ImmuneType; } @@ -2126,6 +2133,7 @@ namespace Milimoe.FunGame.Core.Entity ExAccelerationCoefficient = c.ExAccelerationCoefficient; ExCDR = c.ExCDR; ATR = c.ATR; + MOV = c.MOV; ExCritRate = c.ExCritRate; ExCritDMG = c.ExCritDMG; ExEvadeRate = c.ExEvadeRate; diff --git a/Entity/Skill/Effect.cs b/Entity/Skill/Effect.cs index f5ba582..514f097 100644 --- a/Entity/Skill/Effect.cs +++ b/Entity/Skill/Effect.cs @@ -2,6 +2,7 @@ using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Interface.Base; using Milimoe.FunGame.Core.Interface.Entity; +using Milimoe.FunGame.Core.Library.Common.Addon; using Milimoe.FunGame.Core.Library.Constant; namespace Milimoe.FunGame.Core.Entity @@ -387,6 +388,16 @@ namespace Milimoe.FunGame.Core.Entity } + /// + /// 时间流逝时 [ 地图用 ] + /// + /// + /// + public virtual void OnTimeElapsed(Grid grid, double elapsed) + { + + } + /// /// 在完成伤害结算后 /// @@ -542,6 +553,18 @@ namespace Milimoe.FunGame.Core.Entity } + /// + /// 开始选择移动目标前 + /// + /// + /// + /// + /// + public virtual void BeforeSelectTargetGrid(Character character, List enemys, List teammates, GameMap map) + { + + } + /// /// 开始选择目标前,修改可选择的 , 列表 /// 有两种,使用时注意判断是 还是 diff --git a/Entity/Skill/Skill.cs b/Entity/Skill/Skill.cs index f4bfe72..f43a527 100644 --- a/Entity/Skill/Skill.cs +++ b/Entity/Skill/Skill.cs @@ -90,6 +90,11 @@ namespace Milimoe.FunGame.Core.Entity /// public bool IsMagic => SkillType == SkillType.Magic; + /// + /// 是否无视施法距离(全图施法),魔法默认为 true,战技默认为 false + /// + public bool CastAnyWhere { get; set; } = false; + /// /// 施法距离 [ 单位:格 ] /// @@ -254,6 +259,7 @@ namespace Milimoe.FunGame.Core.Entity protected Skill(SkillType type, Character? character = null) { SkillType = type; + CastAnyWhere = SkillType == SkillType.Magic; Character = character; } diff --git a/Interface/Base/IGamingQueue.cs b/Interface/Base/IGamingQueue.cs index 3c6d468..695bf54 100644 --- a/Interface/Base/IGamingQueue.cs +++ b/Interface/Base/IGamingQueue.cs @@ -154,6 +154,16 @@ namespace Milimoe.FunGame.Core.Interface.Base /// public Task UseItemAsync(Item item, Character caster, List enemys, List teammates); + /// + /// 选取移动目标 + /// + /// + /// + /// + /// + /// + public Task SelectTargetGridAsync(Character character, List enemys, List teammates, GameMap map); + /// /// 选取技能目标 /// diff --git a/Library/Common/Addon/Example/ExampleGameModule.cs b/Library/Common/Addon/Example/ExampleGameModule.cs index 992634c..0ad8370 100644 --- a/Library/Common/Addon/Example/ExampleGameModule.cs +++ b/Library/Common/Addon/Example/ExampleGameModule.cs @@ -319,13 +319,36 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon.Example public override string Author => "FunGamer"; - public override float Length => 12.0f; + public override int Length => 12; - public override float Width => 12.0f; + public override int Width => 12; - public override float Height => 6.0f; + public override int Height => 6; public override float Size => 4.0f; + + public override GameMap InitGamingQueue(IGamingQueue queue) + { + // 因为模组在模组管理器中都是单例的,所以每次游戏都需要返回一个新的地图对象给队列 + GameMap map = new ExampleGameMap(); + + // 做一些绑定,以便介入游戏队列 + /// 但是,传入的 queue 可能不是 ,要做类型检查 + // 不使用框架的实现时,需要地图作者与游戏队列的作者做好适配 + if (queue is GamingQueue gq) + { + gq.SelectTargetGrid += Gq_SelectTargetGrid; + } + + return map; + } + + private async Task Gq_SelectTargetGrid(GamingQueue queue, Character character, List enemys, List teammates, GameMap map) + { + // 介入选择,假设这里更新界面,让玩家选择目的地 + await Task.CompletedTask; + return Grid.Empty; + } } /// diff --git a/Library/Common/Addon/GameMap.cs b/Library/Common/Addon/GameMap.cs index 84bf570..e9cccee 100644 --- a/Library/Common/Addon/GameMap.cs +++ b/Library/Common/Addon/GameMap.cs @@ -1,5 +1,7 @@ using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Interface.Addons; +using Milimoe.FunGame.Core.Interface.Base; namespace Milimoe.FunGame.Core.Library.Common.Addon { @@ -28,17 +30,17 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon /// /// 长度 /// - public abstract float Length { get; } + public abstract int Length { get; } /// /// 宽度 /// - public abstract float Width { get; } + public abstract int Width { get; } /// /// 高度 /// - public abstract float Height { get; } + public abstract int Height { get; } /// /// 格子大小 @@ -49,6 +51,16 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon /// 格子集 /// public Dictionary Grids { get; } = []; + + /// + /// 格子集(基于坐标) + /// + public Dictionary<(int x, int y, int z), Grid> GridsByCoordinate { get; } = []; + + /// + /// 角色集 + /// + public Dictionary Characters { get; } = []; /// /// 使用坐标获取格子,0号格子的坐标是(0, 0),如果你还有高度的话,则是(0, 0, 0) @@ -57,14 +69,34 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon /// /// /// - public Grid this[float x, float y, float z = 0] => Grids.Values.Where(g => g.X == x && g.Y == y && g.Z == z).FirstOrDefault(); + public Grid? this[int x, int y, int z = 0] + { + get + { + if (GridsByCoordinate.TryGetValue((x, y, z), out Grid? grid)) + { + return grid; + } + return null; + } + } /// - /// 使用坐标获取格子,从0号开始 + /// 使用编号获取格子,从0号开始 /// /// /// - public Grid this[int id] => Grids[id]; + public Grid? this[long id] + { + get + { + if (Grids.TryGetValue(id, out Grid? grid)) + { + return grid; + } + return null; + } + } /// /// 加载标记 @@ -88,13 +120,15 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon // 地图加载后,不允许再次加载此地图 IsLoaded = true; // 生成格子 - for (float x = 0; x < Length; x++) + for (int x = 0; x < Length; x++) { - for (float y = 0; y < Width; y++) + for (int y = 0; y < Width; y++) { - for (float z = 0; z < Height; z++) + for (int z = 0; z < Height; z++) { - Grids.Add(Grids.Count, new(Grids.Count, x, y, z)); + Grid grid = new(Grids.Count, x, y, z); + Grids.Add(Grids.Count, grid); + GridsByCoordinate.Add((x, y, z), grid); } } } @@ -118,5 +152,221 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon { return true; } + + /// + /// 获取角色当前所在的格子 + /// + /// + /// + public Grid? GetCharacterCurrentGrid(Character character) + { + if (Characters.TryGetValue(character, out Grid? current)) + { + return current; + } + return null; + } + + /// + /// 强制设置角色当前所在的格子 + /// + /// + /// + /// + public bool SetCharacterCurrentGrid(Character character, Grid target) + { + Grid? current = GetCharacterCurrentGrid(character); + current?.Characters.Remove(character); + if (Grids.ContainsValue(target)) + { + target.Characters.Add(character); + Characters[character] = target; + return true; + } + return false; + } + + /// + /// 将角色从地图中移除 + /// + /// + /// + public void RemoveCharacter(Character character) + { + Grid? current = GetCharacterCurrentGrid(character); + current?.Characters.Remove(character); + Characters[character] = Grid.Empty; + } + + /// + /// 获取以某个格子为中心,一定范围内的格子(曼哈顿距离),只考虑同一平面的格子,不包含中心格子。 + /// + /// + /// + /// + public virtual List GetGridsByRange(Grid grid, int range) + { + List grids = []; + + for (int dx = -range; dx <= range; ++dx) + { + for (int dy = -range; dy <= range; ++dy) + { + //限制在中心点周围范围内 + if (Math.Abs(dx) + Math.Abs(dy) <= range) + { + //检查是否在棋盘范围内 + int x = grid.X; + int y = grid.Y; + int z = grid.Z; + if (GridsByCoordinate.TryGetValue((x, y, z), out Grid? select) && select != null) + { + grids.Add(select); + } + } + } + } + grids.RemoveAll(g => g.Id == grid.Id); + + return grids; + } + + /// + /// 设置角色移动 + /// + /// + /// + /// + /// 移动的步数,只算平面移动步数 + public virtual int CharacterMove(Character character, Grid? current, Grid target) + { + if (current is null || current.Id < 0 || target.Id < 0 || !Grids.ContainsValue(target)) + { + return -1; + } + + Grid? realGrid = GetCharacterCurrentGrid(character); + + if (current.Id == target.Id) + { + return 0; + } + + // 记录走到某个格子时的步数 + Queue<(Grid grid, int steps)> queue = new(); + // 记录已访问的格子 + HashSet visited = []; + + // 将起始格子加入队列,步数为0,并标记为已访问 + queue.Enqueue((current, 0)); + visited.Add(current.Id); + + while (queue.Count > 0) + { + var (currentGrid, currentSteps) = queue.Dequeue(); + + // 如果当前格子就是目标格子,则找到了最短路径 + if (currentGrid.Id == target.Id) + { + realGrid?.Characters.Remove(character); + current.Characters.Remove(character); + target.Characters.Add(character); + Characters[character] = target; + return currentSteps; + } + + // 定义平面移动的四个方向 + (int dx, int dy)[] directions = [ + (0, 1), // 上 + (0, -1), // 下 + (1, 0), // 右 + (-1, 0) // 左 + ]; + + foreach (var (dx, dy) in directions) + { + int nextX = currentGrid.X + dx; + int nextY = currentGrid.Y + dy; + int nextZ = currentGrid.Z; + + // 尝试获取相邻格子 + Grid? neighborGrid = this[nextX, nextY, nextZ]; + + // 如果相邻格子存在且未被访问过 + if (neighborGrid != null && !visited.Contains(neighborGrid.Id)) + { + visited.Add(neighborGrid.Id); + queue.Enqueue((neighborGrid, currentSteps + 1)); + } + } + } + + return -1; + } + + /// + /// 初始化游戏队列 + /// + /// + public virtual GameMap InitGamingQueue(IGamingQueue queue) + { + return this; + } + + /// + /// 在事件流逝前处理 + /// + /// + protected virtual void BeforeTimeElapsed(ref double timeToReduce) + { + + } + + /// + /// 在事件流逝后处理 + /// + /// + protected virtual void AfterTimeElapsed(ref double timeToReduce) + { + + } + + /// + /// 时间流逝时,处理格子上的特效 + /// + /// + public void OnTimeElapsed(double timeToReduce) + { + BeforeTimeElapsed(ref timeToReduce); + + foreach (Grid grid in Grids.Values) + { + List effects = [.. grid.Effects]; + foreach (Effect effect in effects) + { + if (effect.Durative) + { + if (effect.RemainDuration < timeToReduce) + { + // 移除特效前也完成剩余时间内的效果 + effect.OnTimeElapsed(grid, effect.RemainDuration); + effect.RemainDuration = 0; + grid.Effects.Remove(effect); + } + else + { + effect.RemainDuration -= timeToReduce; + effect.OnTimeElapsed(grid, timeToReduce); + } + } + else + { + effect.OnTimeElapsed(grid, timeToReduce); + } + } + } + + AfterTimeElapsed(ref timeToReduce); + } } } diff --git a/Library/Common/Addon/Grid.cs b/Library/Common/Addon/Grid.cs index 96c771a..2640717 100644 --- a/Library/Common/Addon/Grid.cs +++ b/Library/Common/Addon/Grid.cs @@ -3,8 +3,13 @@ using Milimoe.FunGame.Core.Entity; namespace Milimoe.FunGame.Core.Library.Common.Addon { - public struct Grid(int id, float x, float y, float z) + public class Grid(int id, int x, int y, int z) { + /// + /// 空格子 + /// + public static Grid Empty { get; } = new Grid(-1, 0, 0, 0); + /// /// 格子编号 /// @@ -13,17 +18,17 @@ namespace Milimoe.FunGame.Core.Library.Common.Addon /// /// 格子在地图中的x坐标 /// - public float X { get; } = x; + public int X { get; } = x; /// /// 格子在地图中的y坐标 /// - public float Y { get; } = y; + public int Y { get; } = y; /// /// 格子在地图中的z坐标 /// - public float Z { get; } = z; + public int Z { get; } = z; /// /// 是谁站在这格子上? diff --git a/Library/Common/JsonConverter/CharacterConverter.cs b/Library/Common/JsonConverter/CharacterConverter.cs index bb33128..abca358 100644 --- a/Library/Common/JsonConverter/CharacterConverter.cs +++ b/Library/Common/JsonConverter/CharacterConverter.cs @@ -198,7 +198,10 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter result.ExCDR = reader.GetDouble(); break; case nameof(Character.ATR): - result.ATR = reader.GetDouble(); + result.ATR = reader.GetInt32(); + break; + case nameof(Character.MOV): + result.MOV = reader.GetInt32(); break; case nameof(Character.ExCritRate): result.ExCritRate = reader.GetDouble(); @@ -309,6 +312,7 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter writer.WriteNumber(nameof(Character.ExAccelerationCoefficient), value.ExAccelerationCoefficient); writer.WriteNumber(nameof(Character.ExCDR), value.ExCDR); writer.WriteNumber(nameof(Character.ATR), value.ATR); + writer.WriteNumber(nameof(Character.MOV), value.MOV); writer.WriteNumber(nameof(Character.ExCritRate), value.ExCritRate); writer.WriteNumber(nameof(Character.ExCritDMG), value.ExCritDMG); writer.WriteNumber(nameof(Character.ExEvadeRate), value.ExEvadeRate); diff --git a/Library/Common/JsonConverter/SkillConverter.cs b/Library/Common/JsonConverter/SkillConverter.cs index d7b3d26..1b88430 100644 --- a/Library/Common/JsonConverter/SkillConverter.cs +++ b/Library/Common/JsonConverter/SkillConverter.cs @@ -41,6 +41,9 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter case nameof(Skill.Level): result.Level = reader.GetInt32(); break; + case nameof(Skill.CastAnyWhere): + result.CastAnyWhere = reader.GetBoolean(); + break; case nameof(Skill.CastRange): result.CastRange = reader.GetInt32(); break; @@ -128,6 +131,7 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter if (value.GeneralDescription.Length > 0) writer.WriteString(nameof(Skill.GeneralDescription), value.GeneralDescription); if (value.Slogan.Length > 0) writer.WriteString(nameof(Skill.Slogan), value.Slogan); if (value.Level > 0) writer.WriteNumber(nameof(Skill.Level), value.Level); + writer.WriteBoolean(nameof(Skill.CastAnyWhere), value.CastAnyWhere); writer.WriteNumber(nameof(Skill.CastRange), value.CastRange); if (value.CanSelectSelf) writer.WriteBoolean(nameof(Skill.CanSelectSelf), value.CanSelectSelf); if (!value.CanSelectEnemy) writer.WriteBoolean(nameof(Skill.CanSelectEnemy), value.CanSelectEnemy); diff --git a/Model/GamingQueue.cs b/Model/GamingQueue.cs index bee9a44..2d058af 100644 --- a/Model/GamingQueue.cs +++ b/Model/GamingQueue.cs @@ -296,7 +296,7 @@ namespace Milimoe.FunGame.Core.Model #endregion - #region 战棋地图(#TODO) + #region 战棋地图 /// /// 加载地图 @@ -304,7 +304,7 @@ namespace Milimoe.FunGame.Core.Model /// public void LoadGameMap(GameMap map) { - _map = map; + _map = map.InitGamingQueue(this); } #endregion @@ -665,6 +665,9 @@ namespace Milimoe.FunGame.Core.Model } } + // 处理地图上的特效 + _map?.OnTimeElapsed(timeToReduce); + // 移除到时间的特效 List effects = [.. character.Effects]; foreach (Effect effect in effects) @@ -782,7 +785,7 @@ namespace Milimoe.FunGame.Core.Model List rewards = GetRoundRewards(TotalRound, character); // 基础硬直时间 - double baseTime = 10; + double baseTime = 0; bool isCheckProtected = true; // 队友列表 @@ -824,6 +827,14 @@ namespace Milimoe.FunGame.Core.Model bool decided = false; // 最大取消次数 int cancelTimes = 3; + // 此变量控制角色移动后可以继续选择其他的行动 + bool moved = false; + + Grid? currentGrid = null; + if (_map != null) + { + currentGrid = _map.GetCharacterCurrentGrid(character); + } // 行动开始前,可以修改可选取的角色列表 Dictionary continuousKillingTemp = new(_continuousKilling); @@ -847,7 +858,8 @@ namespace Milimoe.FunGame.Core.Model bool isAI = CharactersInAI.Contains(character); while (!decided && (!isAI || cancelTimes > 0)) { - cancelTimes--; + if (moved) moved = false; + else cancelTimes--; type = CharacterActionType.None; // 是否能使用物品和释放技能 @@ -1008,7 +1020,7 @@ namespace Milimoe.FunGame.Core.Model await OnCharacterNormalAttackAsync(character, targets); character.NormalAttack.Attack(this, character, targets); - baseTime = character.NormalAttack.RealHardnessTime; + baseTime += character.NormalAttack.RealHardnessTime; effects = [.. character.Effects.Where(e => e.IsInEffect)]; foreach (Effect effect in effects) { @@ -1055,7 +1067,7 @@ namespace Milimoe.FunGame.Core.Model await OnCharacterPreCastSkillAsync(character, skillTarget); _castingSkills[character] = skillTarget; - baseTime = skill.RealCastTime; + baseTime += skill.RealCastTime; skill.OnSkillCasting(this, character, targets); } } @@ -1083,7 +1095,7 @@ namespace Milimoe.FunGame.Core.Model skill.BeforeSkillCasted(); character.EP -= cost; - baseTime = skill.RealHardnessTime; + baseTime += skill.RealHardnessTime; skill.CurrentCD = skill.RealCD; skill.Enable = false; LastRound.SkillCost = $"{-cost:0.##} EP"; @@ -1131,7 +1143,7 @@ namespace Milimoe.FunGame.Core.Model skill.BeforeSkillCasted(); character.MP -= cost; - baseTime = skill.RealHardnessTime; + baseTime += skill.RealHardnessTime; skill.CurrentCD = skill.RealCD; skill.Enable = false; LastRound.SkillCost = $"{-cost:0.##} MP"; @@ -1146,7 +1158,7 @@ namespace Milimoe.FunGame.Core.Model { WriteLine($"[ {character} ] 放弃释放技能!"); // 放弃释放技能会获得3的硬直时间 - baseTime = 3; + if (baseTime == 0) baseTime = 3; } effects = [.. character.Effects.Where(e => e.IsInEffect)]; @@ -1184,7 +1196,7 @@ namespace Milimoe.FunGame.Core.Model skill.BeforeSkillCasted(); character.EP -= cost; - baseTime = skill.RealHardnessTime; + baseTime += skill.RealHardnessTime; skill.CurrentCD = skill.RealCD; skill.Enable = false; LastRound.SkillCost = $"{-cost:0.##} EP"; @@ -1199,7 +1211,7 @@ namespace Milimoe.FunGame.Core.Model { WriteLine($"[ {character} ] 因能量不足放弃释放爆发技!"); // 放弃释放技能会获得3的硬直时间 - baseTime = 3; + if (baseTime == 0) baseTime = 3; } effects = [.. character.Effects.Where(e => e.IsInEffect)]; @@ -1224,7 +1236,7 @@ namespace Milimoe.FunGame.Core.Model { decided = true; LastRound.Item = item; - baseTime = skill.RealHardnessTime > 0 ? skill.RealHardnessTime : 5; + baseTime += skill.RealHardnessTime > 0 ? skill.RealHardnessTime : 5; effects = [.. character.Effects.Where(e => e.IsInEffect)]; foreach (Effect effect in effects) { @@ -1235,7 +1247,7 @@ namespace Milimoe.FunGame.Core.Model } else if (type == CharacterActionType.EndTurn) { - baseTime = 3; + baseTime += 3; if (character.CharacterState == CharacterState.NotActionable || character.CharacterState == CharacterState.ActionRestricted || character.CharacterState == CharacterState.BattleRestricted) @@ -1249,13 +1261,23 @@ namespace Milimoe.FunGame.Core.Model } else if (type == CharacterActionType.Move) { - baseTime = 3; - decided = true; - WriteLine($"[ {character} ] 进行了移动,并结束了回合!"); - await OnCharacterMoveAsync(character); + if (_map != null) + { + baseTime += 4; + Grid target = await SelectTargetGridAsync(character, enemys, teammates, _map); + if (target.Id != -1) + { + int steps = _map.CharacterMove(character, currentGrid, target); + if (steps > 4) baseTime += 0.7 * steps; + moved = true; + WriteLine($"[ {character} ] 移动了 {steps} 步!"); + await OnCharacterMoveAsync(character, target); + } + } } else { + if (baseTime == 0) baseTime += 10; decided = true; WriteLine($"[ {character} ] 完全行动不能!"); } @@ -2278,6 +2300,37 @@ namespace Milimoe.FunGame.Core.Model return CharacterActionType.EndTurn; } + /// + /// 选取移动目标 + /// + /// + /// + /// + /// + /// + public async Task SelectTargetGridAsync(Character character, List enemys, List teammates, GameMap map) + { + List effects = [.. character.Effects.Where(e => e.IsInEffect)]; + foreach (Effect effect in effects) + { + effect.BeforeSelectTargetGrid(character, enemys, teammates, map); + } + Grid target = await OnSelectTargetGridAsync(character, enemys, teammates, map); + if (target.Id != -1) + { + return target; + } + if (map.Characters.TryGetValue(character, out Grid? current) && current != null) + { + List grids = map.GetGridsByRange(current, character.MOV); + if (grids.Count > 0) + { + return grids[Random.Shared.Next(grids.Count)]; + } + } + return Grid.Empty; + } + /// /// 选取技能目标 /// @@ -3269,6 +3322,24 @@ namespace Milimoe.FunGame.Core.Model return await (SelectItem?.Invoke(this, character, items) ?? Task.FromResult(null)); } + public delegate Task SelectTargetGridEventHandler(GamingQueue queue, Character character, List enemys, List teammates, GameMap map); + /// + /// 选取移动目标事件 + /// + public event SelectTargetGridEventHandler? SelectTargetGrid; + /// + /// 选取移动目标事件 + /// + /// + /// + /// + /// + /// + protected async Task OnSelectTargetGridAsync(Character character, List enemys, List teammates, GameMap map) + { + return await (SelectTargetGrid?.Invoke(this, character, enemys, teammates, map) ?? Task.FromResult(Grid.Empty)); + } + public delegate Task> SelectSkillTargetsEventHandler(GamingQueue queue, Character caster, Skill skill, List enemys, List teammates); /// /// 选取技能目标事件 @@ -3543,7 +3614,7 @@ namespace Milimoe.FunGame.Core.Model await (CharacterGiveUp?.Invoke(this, actor) ?? Task.CompletedTask); } - public delegate Task CharacterMoveEventHandler(GamingQueue queue, Character actor); + public delegate Task CharacterMoveEventHandler(GamingQueue queue, Character actor, Grid grid); /// /// 角色移动事件 /// @@ -3552,10 +3623,11 @@ namespace Milimoe.FunGame.Core.Model /// 角色移动事件 /// /// + /// /// - protected async Task OnCharacterMoveAsync(Character actor) + protected async Task OnCharacterMoveAsync(Character actor, Grid grid) { - await (CharacterMove?.Invoke(this, actor) ?? Task.CompletedTask); + await (CharacterMove?.Invoke(this, actor, grid) ?? Task.CompletedTask); } public delegate Task GameEndEventHandler(GamingQueue queue, Character winner);