Files
Cielonos/Assets/Scripts/MainGame/AttackArea/Submodules/ReactionSubmodule.cs
2026-05-10 11:47:55 -04:00

212 lines
7.9 KiB
C#

using System;
using Cielonos.MainGame.Characters;
using SLSUtilities.General;
using UnityEngine;
namespace Cielonos.MainGame
{
public partial class ReactionSubmodule : AttackAreaSubmoduleBase
{
public ReactionSubmodule(AttackAreaBase owner) : base(owner)
{
SetBlock();
SetDodge();
SetReflection();
}
}
public partial class ReactionSubmodule
{
public bool canBeBlocked;
public bool canBreakBlock;
public bool hasPerfectWindowTime;
public bool hasPerfectBlock;
public Action<CharacterBase> generalBlockAction;
public Action<CharacterBase> normalBlockAction;
public Action<CharacterBase> perfectBlockAction;
public Action<CharacterBase> breakBlockAction;
public AttackAreaBase SetBlock(bool canBeBlocked = true, bool hasPerfectBlock = true, bool canBreakBlock = false)
{
this.canBeBlocked = canBeBlocked;
this.hasPerfectBlock = hasPerfectBlock;
this.hasPerfectWindowTime = true;
this.canBreakBlock = canBreakBlock;
return attackArea;
}
public AttackAreaBase SetBlockActions(Action<CharacterBase> generalBlockAction = null,
Action<CharacterBase> breakBlockAction = null)
{
this.generalBlockAction = generalBlockAction;
this.breakBlockAction = breakBlockAction;
return attackArea;
}
public AttackAreaBase SetBlockActions(Action<CharacterBase> normalBlockAction,
Action<CharacterBase> perfectBlockAction, Action<CharacterBase> breakBlockAction)
{
this.normalBlockAction = normalBlockAction;
this.perfectBlockAction = perfectBlockAction;
this.breakBlockAction = breakBlockAction;
return attackArea;
}
public bool CheckBlock(CharacterBase blocker, CharacterBase attacker, Vector3 hitPosition)
{
BlockSubmodule characterBlockSm = blocker?.reactionSc?.blockSm;
if (characterBlockSm == null) return false;
if (characterBlockSm.isBlocking)
{
/*if (canBeBlocked)
{
}*/
BlockSource firstBlockSource;
if (hasPerfectBlock && (!hasPerfectWindowTime || owner.timeSm.enablingTimer <= 0.2f)
&& characterBlockSm.isPerfectBlocking)
{
firstBlockSource = characterBlockSm.blockSources.Find(source =>
source.perfectBlockBreakType > attackArea.attackSm.attackValue.breakthroughType && source.isDuringPerfectBlock);
if (firstBlockSource != null)
{
firstBlockSource.PerfectBlock(attackArea, hitPosition);
generalBlockAction?.Invoke(blocker);
perfectBlockAction?.Invoke(blocker);
blocker.eventSm.onBlockSuccess.Invoke(attackArea, firstBlockSource);
blocker.eventSm.onPerfectBlockSuccess.Invoke(attackArea, firstBlockSource);
return true;
}
}
else
{
firstBlockSource = characterBlockSm.blockSources.Find(source =>
source.normalBlockBreakType > attackArea.attackSm.attackValue.breakthroughType);
if (firstBlockSource != null)
{
firstBlockSource.NormalBlock(attackArea, hitPosition);
generalBlockAction?.Invoke(blocker);
normalBlockAction?.Invoke(blocker);
blocker.eventSm.onBlockSuccess.Invoke(attackArea, firstBlockSource);
blocker.eventSm.onNormalBlockSuccess.Invoke(attackArea, firstBlockSource);
return true;
}
}
//格挡被突破
breakBlockAction?.Invoke(blocker);
return false;
}
return false;
}
}
public partial class ReactionSubmodule
{
public bool canBeDodged;
public bool canBreakDodge;
public bool hasPerfectDodge;
public Action<CharacterBase> normalDodgeAction;
public Action<CharacterBase> perfectDodgeAction;
public Action<CharacterBase> breakDodgeAction;
public AttackAreaBase SetDodge(bool canBeDodged = true, bool hasPerfectDodge = true, bool canBreakDodge = false)
{
this.canBeDodged = canBeDodged;
this.hasPerfectDodge = hasPerfectDodge;
this.canBreakDodge = canBreakDodge;
return attackArea;
}
public AttackAreaBase SetDodgeActions(Action<CharacterBase> normalDodgeAction = null,
Action<CharacterBase> perfectDodgeAction = null, Action<CharacterBase> breakDodgeAction = null)
{
this.normalDodgeAction = normalDodgeAction;
this.perfectDodgeAction = perfectDodgeAction;
this.breakDodgeAction = breakDodgeAction;
return attackArea;
}
public bool CheckDodge(CharacterBase dodger)
{
DodgeSubmodule characterDodgeSm = dodger?.reactionSc?.dodgeSm;
if (characterDodgeSm == null) return false;
if (characterDodgeSm.isDodging)
{
if (canBeDodged)
{
DodgeSource firstDodgeSource;
if (hasPerfectDodge && owner.timeSm.enablingTimer <= 0.2f && characterDodgeSm.isPerfectDodging)
{
firstDodgeSource = characterDodgeSm.dodgeSources.Find(source => source.isDuringPerfectDodge);
firstDodgeSource.PerfectDodge();
perfectDodgeAction?.Invoke(dodger);
// 触发完美闪避成功事件
dodger.eventSm.onPerfectDodgeSuccess.Invoke(owner, firstDodgeSource);
}
else
{
firstDodgeSource = characterDodgeSm.dodgeSources[0];
firstDodgeSource.NormalDodge();
normalDodgeAction?.Invoke(dodger);
// 触发普通闪避成功事件
dodger.eventSm.onNormalDodgeSuccess.Invoke(owner, firstDodgeSource);
}
return true;
}
if (canBreakDodge)
{
breakDodgeAction?.Invoke(dodger);
return false;
}
}
return false;
}
}
public partial class ReactionSubmodule
{
public bool canBeReflected;
public AttackAreaBase SetReflection(bool canBeReflected = false)
{
this.canBeReflected = canBeReflected;
return attackArea;
}
public bool CheckReflection(CharacterBase reflector)
{
ReflectionSubmodule characterReflectionSm = reflector?.reactionSc?.reflectionSm;
if (characterReflectionSm == null) return false;
if (characterReflectionSm.isReflecting)
{
if (canBeReflected)
{
foreach (ReflectionSource source in characterReflectionSm.reflectionSources)
{
if (source.condition == null || source.condition(attackArea))
{
source.onReflection(attackArea);
return true;
}
}
}
}
return false;
}
}
}