From 56d2dc6756875abc202d93dca7b4aca2ca490925 Mon Sep 17 00:00:00 2001 From: milimoe Date: Wed, 16 Apr 2025 01:24:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=B9=E8=A1=8C=E5=8A=A8=E9=A1=BA=E5=BA=8F?= =?UTF-8?q?=E8=A1=A8=E4=B8=AD=E7=9A=84=E9=83=A8=E5=88=86=E7=89=B9=E6=95=88?= =?UTF-8?q?=E9=92=A9=E5=AD=90=E5=81=9A=E4=BF=AE=E6=94=B9=EF=BC=9B=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=88=A4=E6=96=AD=E8=A7=92=E8=89=B2=E6=98=AF=E5=90=A6?= =?UTF-8?q?=E5=A4=84=E4=BA=8E=20AI=20=E6=8E=A7=E5=88=B6=E4=B8=8B=E7=9A=84?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Entity/Skill/Effect.cs | 49 ++++++++++---- Entity/Skill/Skill.cs | 12 +++- Interface/Base/IGamingQueue.cs | 6 ++ Library/SQLScript/Entity/RoomQuery.cs | 2 +- Model/ActionQueue.cs | 97 ++++++++++++++++----------- 5 files changed, 113 insertions(+), 53 deletions(-) diff --git a/Entity/Skill/Effect.cs b/Entity/Skill/Effect.cs index 1d9640a..c85d9ff 100644 --- a/Entity/Skill/Effect.cs +++ b/Entity/Skill/Effect.cs @@ -341,10 +341,11 @@ namespace Milimoe.FunGame.Core.Entity /// /// 闪避检定前触发 /// - /// + /// + /// /// /// 返回 false 表示不进行闪避检定 - public virtual bool BeforeEvadeCheck(Character character, ref double throwingBonus) + public virtual bool BeforeEvadeCheck(Character actor, Character enemy, ref double throwingBonus) { return true; } @@ -352,11 +353,11 @@ namespace Milimoe.FunGame.Core.Entity /// /// 在触发闪避时 /// - /// - /// + /// + /// /// /// 返回 true 表示无视闪避 - public virtual bool OnEvadedTriggered(Character attacker, Character evader, double dice) + public virtual bool OnEvadedTriggered(Character actor, Character enemy, double dice) { return false; } @@ -364,10 +365,11 @@ namespace Milimoe.FunGame.Core.Entity /// /// 暴击检定前触发 /// - /// + /// + /// /// /// 返回 false 表示不进行暴击检定 - public virtual bool BeforeCriticalCheck(Character character, ref double throwingBonus) + public virtual bool BeforeCriticalCheck(Character actor, Character enemy, ref double throwingBonus) { return true; } @@ -375,9 +377,10 @@ namespace Milimoe.FunGame.Core.Entity /// /// 在触发暴击时 /// - /// + /// + /// /// - public virtual void OnCriticalDamageTriggered(Character character, double dice) + public virtual void OnCriticalDamageTriggered(Character actor, Character enemy, double dice) { } @@ -401,10 +404,22 @@ namespace Milimoe.FunGame.Core.Entity /// /// /// - /// 返回 true 表示更改生效 - public virtual bool AlterEnemyListBeforeAction(Character character, List enemys, List teammates, List skills, Dictionary continuousKilling, Dictionary earnedMoney) + public virtual void AlterSelectListBeforeAction(Character character, List enemys, List teammates, List skills, Dictionary continuousKilling, Dictionary earnedMoney) { - return false; + + } + + /// + /// 开始选择目标前,修改可选择的 , 列表 + /// 有两种,使用时注意判断是 还是 + /// + /// + /// + /// + /// + public virtual void AlterSelectListBeforeSelection(Character character, ISkill skill, List enemys, List teammates) + { + } /// @@ -462,6 +477,16 @@ namespace Milimoe.FunGame.Core.Entity GamingQueue?.InterruptCastingAsync(caster, interrupter); } + /// + /// 检查角色是否在 AI 控制状态 + /// + /// + /// + public bool IsCharacterInAIControlling(Character character) + { + return GamingQueue?.IsCharacterInAIControlling(character) ?? false; + } + /// /// 返回特效详情 /// diff --git a/Entity/Skill/Skill.cs b/Entity/Skill/Skill.cs index 16da57c..e4c6933 100644 --- a/Entity/Skill/Skill.cs +++ b/Entity/Skill/Skill.cs @@ -370,7 +370,7 @@ namespace Milimoe.FunGame.Core.Entity } /// - /// 触发技能效果 + /// 触发技能效果 [ 局内版 ] /// /// /// @@ -397,6 +397,16 @@ namespace Milimoe.FunGame.Core.Entity } } + /// + /// 检查角色是否在 AI 控制状态 + /// + /// + /// + public bool IsCharacterInAIControlling(Character character) + { + return GamingQueue?.IsCharacterInAIControlling(character) ?? false; + } + /// /// 被动技能,需要重写此方法,返回被动特效给角色 [ 此方法会在技能学习时触发 ] /// diff --git a/Interface/Base/IGamingQueue.cs b/Interface/Base/IGamingQueue.cs index 2486ddc..03af429 100644 --- a/Interface/Base/IGamingQueue.cs +++ b/Interface/Base/IGamingQueue.cs @@ -159,5 +159,11 @@ namespace Milimoe.FunGame.Core.Interface.Base /// /// public Task> SelectTargetsAsync(Character character, NormalAttack attack, List enemys, List teammates); + + /// + /// 检查角色是否在 AI 控制状态 + /// + /// + public bool IsCharacterInAIControlling(Character character); } } diff --git a/Library/SQLScript/Entity/RoomQuery.cs b/Library/SQLScript/Entity/RoomQuery.cs index 7ca520d..a1b1564 100644 --- a/Library/SQLScript/Entity/RoomQuery.cs +++ b/Library/SQLScript/Entity/RoomQuery.cs @@ -122,7 +122,7 @@ namespace Milimoe.FunGame.Core.Library.SQLScript.Entity return $"{Command_Delete} {Command_From} {TableName} {builder}"; } } - return $"{Command_Delete} {Command_From} {TableName} {Command_Where} 1 = 0"; + return $"{Command_Delete} {Command_From} {TableName}"; } public static string Delete_QuitRoom(SQLHelper SQLHelper, string Roomid, long RoomMaster) diff --git a/Model/ActionQueue.cs b/Model/ActionQueue.cs index 6be4f97..95a2df4 100644 --- a/Model/ActionQueue.cs +++ b/Model/ActionQueue.cs @@ -13,7 +13,7 @@ namespace Milimoe.FunGame.Core.Model /// /// 使用的游戏平衡常数 /// - public EquilibriumConstant GameplayEquilibriumConstant { get; } = General.GameplayEquilibriumConstant; + public EquilibriumConstant GameplayEquilibriumConstant { get; set; } = General.GameplayEquilibriumConstant; /// /// 用于文本输出 @@ -658,9 +658,9 @@ namespace Milimoe.FunGame.Core.Model { CharacterActionType actionTypeTemp = CharacterActionType.None; effects = [.. character.Effects.Where(e => e.Level > 0)]; - foreach (Effect e in effects) + foreach (Effect effect in effects) { - actionTypeTemp = e.AlterActionTypeBeforeAction(character, character.CharacterState, ref canUseItem, ref canCastSkill, ref pUseItem, ref pCastSkill, ref pNormalAttack); + actionTypeTemp = effect.AlterActionTypeBeforeAction(character, character.CharacterState, ref canUseItem, ref canCastSkill, ref pUseItem, ref pCastSkill, ref pNormalAttack); } if (actionTypeTemp != CharacterActionType.None && actionTypeTemp != CharacterActionType.CastSkill && actionTypeTemp != CharacterActionType.CastSuperSkill) { @@ -769,30 +769,25 @@ namespace Milimoe.FunGame.Core.Model } } - List enemysTemp = [.. enemys]; - List teammatesTemp = [.. teammates]; - List skillsTemp = [.. skills]; Dictionary continuousKillingTemp = new(_continuousKilling); Dictionary earnedMoneyTemp = new(_earnedMoney); effects = [.. character.Effects.Where(e => e.Level > 0)]; - foreach (Effect e in effects) + foreach (Effect effect in effects) { - if (e.AlterEnemyListBeforeAction(character, enemysTemp, teammatesTemp, skillsTemp, continuousKillingTemp, earnedMoneyTemp)) - { - enemys = [.. enemysTemp.Distinct()]; - teammates = [.. teammatesTemp.Distinct()]; - skills = [.. skillsTemp.Distinct()]; - } + effect.AlterSelectListBeforeAction(character, enemys, teammates, skills, continuousKillingTemp, earnedMoneyTemp); } if (type == CharacterActionType.NormalAttack) { // 使用普通攻击逻辑 List targets = await SelectTargetsAsync(character, character.NormalAttack, enemys, teammates); - if (targets.Count == 0 && _charactersInAI.Contains(character) && enemys.Count > 0) + if (targets.Count == 0 && _charactersInAI.Contains(character)) { - // 如果没有选取目标,且角色在 AI 控制下,则随机选取一个目标 - targets = [enemys[Random.Shared.Next(enemys.Count)]]; + // 如果没有选取目标,且角色在 AI 控制下,则随机选取目标 + if (enemys.Count > character.NormalAttack.CanSelectTargetCount) + targets = [.. enemys.OrderBy(o => Random.Shared.Next(enemys.Count)).Take(character.NormalAttack.CanSelectTargetCount)]; + else + targets = [.. enemys]; } if (targets.Count > 0) { @@ -1078,7 +1073,7 @@ namespace Milimoe.FunGame.Core.Model RemoveRoundRewards(TotalRound, character, rewards); // 有人想要插队吗? - await WillPreCastSuperSkill(character); + await WillPreCastSuperSkill(); // 回合结束事件 await OnTurnEndAsync(character); @@ -1374,9 +1369,10 @@ namespace Milimoe.FunGame.Core.Model /// public DamageResult CalculatePhysicalDamage(Character actor, Character enemy, bool isNormalAttack, double expectedDamage, out double finalDamage) { + List characters = [actor, enemy]; bool isMagic = false; MagicType magicType = MagicType.None; - List effects = [.. actor.Effects.Union(enemy.Effects).Where(e => e.Level > 0)]; + List effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0))]; foreach (Effect effect in effects) { effect.AlterDamageTypeBeforeCalculation(actor, enemy, ref isNormalAttack, ref isMagic, ref magicType); @@ -1401,10 +1397,10 @@ namespace Milimoe.FunGame.Core.Model bool checkCritical = true; if (isNormalAttack) { - effects = [.. actor.Effects.Where(e => e.Level > 0)]; + effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0))]; foreach (Effect effect in effects) { - checkEvade = effect.BeforeEvadeCheck(actor, ref throwingBonus); + checkEvade = effect.BeforeEvadeCheck(actor, enemy, ref throwingBonus); } if (checkEvade) @@ -1413,7 +1409,6 @@ namespace Milimoe.FunGame.Core.Model if (dice < (enemy.EvadeRate + throwingBonus)) { finalDamage = 0; - List characters = [actor, enemy]; bool isAlterEvaded = false; effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0))]; foreach (Effect effect in effects) @@ -1442,10 +1437,10 @@ namespace Milimoe.FunGame.Core.Model finalDamage = expectedDamage * (1 - Calculation.PercentageCheck(physicalDamageReduction + enemy.ExPDR)); // 暴击判定 - effects = [.. actor.Effects.Where(e => e.Level > 0)]; + effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0))]; foreach (Effect effect in effects) { - checkCritical = effect.BeforeCriticalCheck(actor, ref throwingBonus); + checkCritical = effect.BeforeCriticalCheck(actor, enemy, ref throwingBonus); } if (checkCritical) @@ -1455,10 +1450,10 @@ namespace Milimoe.FunGame.Core.Model { finalDamage *= actor.CritDMG; // 暴击伤害倍率加成 WriteLine("暴击生效!!"); - effects = [.. actor.Effects.Where(e => e.Level > 0)]; + effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0))]; foreach (Effect effect in effects) { - effect.OnCriticalDamageTriggered(actor, dice); + effect.OnCriticalDamageTriggered(actor, enemy, dice); } return DamageResult.Critical; } @@ -1480,8 +1475,9 @@ namespace Milimoe.FunGame.Core.Model /// public DamageResult CalculateMagicalDamage(Character actor, Character enemy, bool isNormalAttack, MagicType magicType, double expectedDamage, out double finalDamage) { + List characters = [actor, enemy]; bool isMagic = true; - List effects = [.. actor.Effects.Union(enemy.Effects).Where(e => e.Level > 0)]; + List effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0))]; foreach (Effect effect in effects) { effect.AlterDamageTypeBeforeCalculation(actor, enemy, ref isNormalAttack, ref isMagic, ref magicType); @@ -1492,7 +1488,7 @@ namespace Milimoe.FunGame.Core.Model } Dictionary totalDamageBonus = []; - effects = [.. actor.Effects.Union(enemy.Effects).Where(e => e.Level > 0)]; + effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0))]; foreach (Effect effect in effects) { double damageBonus = effect.AlterExpectedDamageBeforeCalculation(actor, enemy, expectedDamage, isNormalAttack, true, magicType, totalDamageBonus); @@ -1506,10 +1502,10 @@ namespace Milimoe.FunGame.Core.Model bool checkCritical = true; if (isNormalAttack) { - effects = [.. actor.Effects.Where(e => e.Level > 0)]; + effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0))]; foreach (Effect effect in effects) { - checkEvade = effect.BeforeEvadeCheck(actor, ref throwingBonus); + checkEvade = effect.BeforeEvadeCheck(actor, enemy, ref throwingBonus); } if (checkEvade) @@ -1518,7 +1514,6 @@ namespace Milimoe.FunGame.Core.Model if (dice < (enemy.EvadeRate + throwingBonus)) { finalDamage = 0; - List characters = [actor, enemy]; bool isAlterEvaded = false; effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0))]; foreach (Effect effect in effects) @@ -1557,10 +1552,10 @@ namespace Milimoe.FunGame.Core.Model finalDamage = expectedDamage * (1 - MDF); // 暴击判定 - effects = [.. actor.Effects.Where(e => e.Level > 0)]; + effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0))]; foreach (Effect effect in effects) { - checkCritical = effect.BeforeCriticalCheck(actor, ref throwingBonus); + checkCritical = effect.BeforeCriticalCheck(actor, enemy, ref throwingBonus); } if (checkCritical) @@ -1570,10 +1565,10 @@ namespace Milimoe.FunGame.Core.Model { finalDamage *= actor.CritDMG; // 暴击伤害倍率加成 WriteLine("暴击生效!!"); - effects = [.. actor.Effects.Where(e => e.Level > 0)]; + effects = [.. characters.SelectMany(c => c.Effects.Where(e => e.Level > 0))]; foreach (Effect effect in effects) { - effect.OnCriticalDamageTriggered(actor, dice); + effect.OnCriticalDamageTriggered(actor, enemy, dice); } return DamageResult.Critical; } @@ -2062,9 +2057,8 @@ namespace Milimoe.FunGame.Core.Model /// /// 是否在回合外释放爆发技插队(仅自动化,手动设置请调用:) /// - /// 当前正在行动的角色 /// - public async Task WillPreCastSuperSkill(Character character) + public async Task WillPreCastSuperSkill() { // 选取所有 AI 控制角色 foreach (Character other in _queue.Where(c => c.CharacterState == CharacterState.Actionable && _charactersInAI.Contains(c)).ToList()) @@ -2102,10 +2096,15 @@ namespace Milimoe.FunGame.Core.Model if (skill != null) { WriteLine($"[ {caster} ] 的施法被 [ {interrupter} ] 打断了!!"); - List effects = [.. skill.Effects.Where(e => e.Level > 0)]; - foreach (Effect e in effects) + List effects = [.. caster.Effects.Where(e => e.Level > 0)]; + foreach (Effect effect in effects) { - e.OnSkillCastInterrupted(caster, skill, interrupter); + effect.OnSkillCastInterrupted(caster, skill, interrupter); + } + effects = [.. interrupter.Effects.Where(e => e.Level > 0)]; + foreach (Effect effect in effects) + { + effect.OnSkillCastInterrupted(caster, skill, interrupter); } } await OnInterruptCastingAsync(caster, skill, interrupter); @@ -2370,6 +2369,16 @@ namespace Milimoe.FunGame.Core.Model } } + /// + /// 检查角色是否在 AI 控制状态 + /// + /// + /// + public bool IsCharacterInAIControlling(Character character) + { + return _charactersInAI.Contains(character); + } + /// /// 初始化回合奖励 /// @@ -2481,6 +2490,11 @@ namespace Milimoe.FunGame.Core.Model /// public virtual async Task> SelectTargetsAsync(Character caster, Skill skill, List enemys, List teammates) { + List effects = [.. caster.Effects.Where(e => e.Level > 0)]; + foreach (Effect effect in effects) + { + effect.AlterSelectListBeforeSelection(caster, skill, enemys, teammates); + } List targets = await OnSelectSkillTargetsAsync(caster, skill, enemys, teammates); if (targets.Count == 0 && _charactersInAI.Contains(caster)) { @@ -2499,6 +2513,11 @@ namespace Milimoe.FunGame.Core.Model /// public virtual async Task> SelectTargetsAsync(Character character, NormalAttack attack, List enemys, List teammates) { + List effects = [.. character.Effects.Where(e => e.Level > 0)]; + foreach (Effect effect in effects) + { + effect.AlterSelectListBeforeSelection(character, attack, enemys, teammates); + } List targets = await OnSelectNormalAttackTargetsAsync(character, attack, enemys, teammates); return targets; }