添加攻击受限和让施法者目标丢失的打断施法方法

This commit is contained in:
milimoe 2025-04-17 00:17:17 +08:00
parent 56d2dc6756
commit f4320e8212
Signed by: milimoe
GPG Key ID: 05D280912DA6C69E
5 changed files with 92 additions and 31 deletions

View File

@ -1778,6 +1778,7 @@ namespace Milimoe.FunGame.Core.Entity
bool isActionRestricted = false;
bool isBattleRestricted = false;
bool isSkillRestricted = false;
bool isAttackRestricted = false;
IEnumerable<CharacterState> states = CharacterEffectStates.Values.SelectMany(list => list);
// 根据持有的特效判断角色所处的状态
@ -1785,12 +1786,13 @@ namespace Milimoe.FunGame.Core.Entity
isActionRestricted = states.Any(state => state == CharacterState.ActionRestricted);
isBattleRestricted = states.Any(state => state == CharacterState.BattleRestricted);
isSkillRestricted = states.Any(state => state == CharacterState.SkillRestricted);
isAttackRestricted = states.Any(state => state == CharacterState.AttackRestricted);
IEnumerable<EffectType> types = CharacterEffectTypes.Values.SelectMany(list => list);
// 判断角色的控制效果
IsUnselectable = types.Any(type => type == EffectType.Unselectable);
bool isControl = isNotActionable || isActionRestricted || isBattleRestricted || isSkillRestricted;
bool isControl = isNotActionable || isActionRestricted || isBattleRestricted || isSkillRestricted || isAttackRestricted;
bool isCasting = CharacterState == CharacterState.Casting;
bool isPreCastSuperSkill = CharacterState == CharacterState.PreCastSuperSkill;
@ -1810,6 +1812,10 @@ namespace Milimoe.FunGame.Core.Entity
{
CharacterState = CharacterState.SkillRestricted;
}
else if (isAttackRestricted)
{
CharacterState = CharacterState.AttackRestricted;
}
if (!isControl && !isCasting && !isPreCastSuperSkill)
{

View File

@ -308,6 +308,7 @@ namespace Milimoe.FunGame.Core.Entity
{
selectable.AddRange(enemys);
}
if (CanSelectTeammate)
{
selectable.AddRange(teammates);
@ -430,7 +431,7 @@ namespace Milimoe.FunGame.Core.Entity
builder.AppendLine("技能描述:" + (Level == 0 && GeneralDescription.Trim() != "" ? GeneralDescription : Description));
if (CurrentCD > 0)
{
builder.AppendLine($"正在冷却:剩余 {CurrentCD:0.##} 时间");
builder.AppendLine($"正在冷却:剩余 {CurrentCD:0.##} {GameplayEquilibriumConstant.InGameTime}");
}
if (!Enable)
{

View File

@ -130,6 +130,12 @@ namespace Milimoe.FunGame.Core.Interface.Base
/// <param name="interrupter"></param>
public Task InterruptCastingAsync(Character caster, Character interrupter);
/// <summary>
/// 打断施法 [ 用于使敌人目标丢失 ]
/// </summary>
/// <param name="interrupter"></param>
public Task InterruptCastingAsync(Character interrupter);
/// <summary>
/// 使用物品
/// </summary>

View File

@ -58,6 +58,11 @@ namespace Milimoe.FunGame.Core.Library.Constant
/// </summary>
SkillRestricted,
/// <summary>
/// 攻击受限 [ 战斗相关 ]
/// </summary>
AttackRestricted,
/// <summary>
/// 处于吟唱中 [ 战斗相关 ] [ 技能相关 ]
/// </summary>

View File

@ -741,6 +741,15 @@ namespace Milimoe.FunGame.Core.Model
pCastSkill = 0;
}
}
else if (character.CharacterState == CharacterState.AttackRestricted)
{
// 攻击受限,无法普通攻击,可以使用技能,可以使用物品
pNormalAttack = 0;
if (!canUseItem)
{
pUseItem = 0;
}
}
// 模组可以通过此事件来决定角色的行动
type = await OnDecideActionAsync(character, enemys, teammates, skills, items);
@ -778,6 +787,15 @@ namespace Milimoe.FunGame.Core.Model
}
if (type == CharacterActionType.NormalAttack)
{
if (character.CharacterState == CharacterState.NotActionable ||
character.CharacterState == CharacterState.ActionRestricted ||
character.CharacterState == CharacterState.BattleRestricted ||
character.CharacterState == CharacterState.AttackRestricted)
{
WriteLine($"角色 [ {character} ] 状态为:{CharacterSet.GetCharacterState(character.CharacterState)},无法使用普通攻击!");
}
else
{
// 使用普通攻击逻辑
List<Character> targets = await SelectTargetsAsync(character, character.NormalAttack, enemys, teammates);
@ -805,6 +823,7 @@ namespace Milimoe.FunGame.Core.Model
}
}
}
}
else if (type == CharacterActionType.PreCastSkill)
{
// 预使用技能,即开始吟唱逻辑
@ -1022,8 +1041,16 @@ namespace Milimoe.FunGame.Core.Model
// 统一在回合结束时处理角色的死亡
await ProcessCharacterDeathAsync(character);
// 移除回合奖励
RemoveRoundRewards(TotalRound, character, rewards);
if (_isGameEnd)
{
// 回合结束事件
await OnTurnEndAsync(character);
await AfterTurnAsync(character);
return _isGameEnd;
}
@ -1069,9 +1096,6 @@ namespace Milimoe.FunGame.Core.Model
}
}
// 移除回合奖励
RemoveRoundRewards(TotalRound, character, rewards);
// 有人想要插队吗?
await WillPreCastSuperSkill();
@ -1895,6 +1919,7 @@ namespace Milimoe.FunGame.Core.Model
/// </summary>
public async Task EndGameInfo(Team winner)
{
winner.IsWinner = true;
WriteLine("[ " + winner + " ] 是胜利者。");
if (!await OnGameEndTeamAsync(winner))
@ -2095,20 +2120,38 @@ namespace Milimoe.FunGame.Core.Model
}
if (skill != null)
{
WriteLine($"[ {caster} ] 的施法被 [ {interrupter} ] 打断了!!");
List<Effect> effects = [.. caster.Effects.Where(e => e.Level > 0)];
WriteLine($"[ {caster} ] 的{(skill.IsSuperSkill ? "" : "")}被 [ {interrupter} ] 打断了!!");
List<Effect> effects = [.. caster.Effects.Union(interrupter.Effects).Where(e => e.Level > 0)];
foreach (Effect effect in effects)
{
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);
}
}
/// <summary>
/// 打断施法 [ 用于使敌人目标丢失 ]
/// </summary>
/// <param name="interrupter"></param>
public async Task InterruptCastingAsync(Character interrupter)
{
foreach (Character caster in _castingSkills.Keys)
{
SkillTarget skillTarget = _castingSkills[caster];
if (skillTarget.Targets.Contains(interrupter))
{
Skill skill = skillTarget.Skill;
WriteLine($"[ {interrupter} ] 打断了 [ {caster} ] 的施法!!");
List<Effect> effects = [.. caster.Effects.Union(interrupter.Effects).Where(e => e.Level > 0)];
foreach (Effect effect in effects)
{
effect.OnSkillCastInterrupted(caster, skill, interrupter);
}
await OnInterruptCastingAsync(caster, skill, interrupter);
}
}
}
/// <summary>
/// 通过概率计算角色要干嘛
@ -2657,7 +2700,7 @@ namespace Milimoe.FunGame.Core.Model
/// <param name="skill"></param>
/// <param name="interrupter"></param>
/// <returns></returns>
protected async Task OnInterruptCastingAsync(Character cast, Skill? skill, Character interrupter)
protected async Task OnInterruptCastingAsync(Character cast, Skill skill, Character interrupter)
{
await (InterruptCasting?.Invoke(this, cast, skill, interrupter) ?? Task.CompletedTask);
}