2026-03-20 12:07:44 -04:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using Cielonos.MainGame.Buffs.Character;
|
2026-05-23 08:27:50 -04:00
|
|
|
|
using Cielonos.MainGame.Inventory;
|
2026-03-20 12:07:44 -04:00
|
|
|
|
using Cielonos.MainGame.UI;
|
|
|
|
|
|
using Lean.Pool;
|
|
|
|
|
|
using SLSUtilities.FunctionalAnimation;
|
|
|
|
|
|
using SLSUtilities.General;
|
|
|
|
|
|
using SLSUtilities.WwiseAssistance;
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Cielonos.MainGame.Characters
|
|
|
|
|
|
{
|
|
|
|
|
|
public partial class LegionCenturion : Enemy
|
|
|
|
|
|
{
|
|
|
|
|
|
protected override void Start()
|
|
|
|
|
|
{
|
|
|
|
|
|
base.Start();
|
2026-05-10 11:47:55 -04:00
|
|
|
|
PlayerCanvas.EnemyInfoUIArea.CreateInfoUnit(this);
|
2026-03-20 12:07:44 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected override void InitializeSubmodules()
|
|
|
|
|
|
{
|
|
|
|
|
|
base.InitializeSubmodules();
|
|
|
|
|
|
eventSm.onGetBreakthrough.Add("GetBreakthrough_Weak", new PrioritizedAction<AttackAreaBase>(attackArea =>
|
|
|
|
|
|
{
|
|
|
|
|
|
new Weak(5).Apply(this);
|
2026-05-23 08:27:50 -04:00
|
|
|
|
GetHit(Breakthrough.Type.Forced, out _, DisruptionType.ForcedExternal, funcAnimName: "KnockBack");
|
2026-03-20 12:07:44 -04:00
|
|
|
|
}));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public partial class LegionCenturion
|
|
|
|
|
|
{
|
|
|
|
|
|
private void FAPF_DodgeStart(RuntimeFuncAnim rtFuncAnim) => DodgeStart();
|
|
|
|
|
|
|
|
|
|
|
|
private void FAPF_DodgeEnd(RuntimeFuncAnim rtFuncAnim) => DodgeEnd();
|
|
|
|
|
|
|
|
|
|
|
|
private void FAPF_SetBlock(RuntimeFuncAnim rtFuncAnim) => SetBlock();
|
|
|
|
|
|
|
|
|
|
|
|
private void FAPF_RemoveBlock(RuntimeFuncAnim rtFuncAnim) => RemoveBlock();
|
|
|
|
|
|
|
|
|
|
|
|
private void FAPF_GenerateNormalSlash(RuntimeFuncAnim rtFuncAnim)
|
|
|
|
|
|
{
|
|
|
|
|
|
CustomFunction.PC_StringString p = rtFuncAnim.GetParams<CustomFunction.PC_StringString>();
|
|
|
|
|
|
GenerateNormalSlash(p.str0, attackData[p.str1]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void FAPF_GeneratePowerfulSlash(RuntimeFuncAnim rtFuncAnim)
|
|
|
|
|
|
{
|
|
|
|
|
|
CustomFunction.PC_StringString p = rtFuncAnim.GetParams<CustomFunction.PC_StringString>();
|
|
|
|
|
|
GeneratePowerfulSlash(p.str0, attackData[p.str1]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void FAPF_GenerateFlawSlash(RuntimeFuncAnim rtFuncAnim)
|
|
|
|
|
|
{
|
|
|
|
|
|
CustomFunction.PC_StringString p = rtFuncAnim.GetParams<CustomFunction.PC_StringString>();
|
|
|
|
|
|
NormalArea area = GenerateNormalSlash(p.str0, attackData[p.str1]);
|
|
|
|
|
|
area.reactionSm.SetBlockActions(blocker =>
|
|
|
|
|
|
{
|
|
|
|
|
|
new Weak(5).Apply(this);
|
2026-05-23 08:27:50 -04:00
|
|
|
|
GetHit(Breakthrough.Type.Forced, out _, DisruptionType.ForcedExternal, funcAnimName: "KnockBack");
|
2026-03-20 12:07:44 -04:00
|
|
|
|
behaviorSc.DispatchContextEvent("FlawSlashBlocked");
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void FAPF_GenerateNormalMovingSlash (RuntimeFuncAnim rtFuncAnim)
|
|
|
|
|
|
{
|
|
|
|
|
|
CustomFunction.PC_StringStringFloat p = rtFuncAnim.GetParams<CustomFunction.PC_StringStringFloat>();
|
|
|
|
|
|
GenerateMovingSlash(p.str0, attackData[p.str1], p.float0, transform.forward);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void FAPF_GeneratePowerfulMovingSlash (RuntimeFuncAnim rtFuncAnim)
|
|
|
|
|
|
{
|
|
|
|
|
|
CustomFunction.PC_StringStringFloat p = rtFuncAnim.GetParams<CustomFunction.PC_StringStringFloat>();
|
|
|
|
|
|
GenerateMovingSlash(p.str0, attackData[p.str1], p.float0, transform.forward);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void FAPF_GenerateTripleMovingSlashes(RuntimeFuncAnim rtFuncAnim)
|
|
|
|
|
|
{
|
|
|
|
|
|
CustomFunction.PC_StringStringFloat p = rtFuncAnim.GetParams<CustomFunction.PC_StringStringFloat>();
|
|
|
|
|
|
GenerateTripleMovingSlashes(p.str0, attackData[p.str1], p.float0, transform.forward);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void FAPF_GenerateRingMovingSlashes(RuntimeFuncAnim rtFuncAnim)
|
|
|
|
|
|
{
|
|
|
|
|
|
CustomFunction.PC_StringStringFloat p = rtFuncAnim.GetParams<CustomFunction.PC_StringStringFloat>();
|
|
|
|
|
|
GenerateRingMovingSlashes(p.str0, attackData[p.str1], p.float0, transform.forward);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void FAPF_GenerateNormalPrick(RuntimeFuncAnim rtFuncAnim)
|
|
|
|
|
|
{
|
|
|
|
|
|
CustomFunction.PC_StringString p = rtFuncAnim.GetParams<CustomFunction.PC_StringString>();
|
|
|
|
|
|
GenerateNormalSlash(p.str0, attackData[p.str1]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void FAPF_GeneratePowerfulPrick(RuntimeFuncAnim rtFuncAnim)
|
|
|
|
|
|
{
|
|
|
|
|
|
CustomFunction.PC_StringString p = rtFuncAnim.GetParams<CustomFunction.PC_StringString>();
|
|
|
|
|
|
GeneratePowerfulSlash(p.str0, attackData[p.str1]);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public partial class LegionCenturion
|
|
|
|
|
|
{
|
|
|
|
|
|
private void DodgeStart()
|
|
|
|
|
|
{
|
|
|
|
|
|
movementSc.isDashing = true;
|
|
|
|
|
|
DodgeSource defaultDodge = DodgeSource.Default(this);
|
|
|
|
|
|
reactionSc.dodgeSm.ApplyDodge(defaultDodge);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void DodgeEnd()
|
|
|
|
|
|
{
|
|
|
|
|
|
movementSc.isDashing = false;
|
|
|
|
|
|
movementSc.dashMoveMultiplier = 1;
|
|
|
|
|
|
reactionSc.dodgeSm.RemoveDodge("DefaultDodge");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void SetBlock()
|
|
|
|
|
|
{
|
|
|
|
|
|
BlockSource blockSource = blockData.CreateBlockSource(this);
|
|
|
|
|
|
movementSc.canDash = false;
|
|
|
|
|
|
movementSc.canDodge = false;
|
|
|
|
|
|
blockSource.onNormalBlock = (attackArea) =>
|
|
|
|
|
|
{
|
2026-06-05 04:21:00 -04:00
|
|
|
|
AudioManager.Post(AK.EVENTS.POLYCHROME_NORMALBLOCK, CenterPosition);
|
2026-05-23 08:27:50 -04:00
|
|
|
|
attackArea.creator.movementSc.impulseSm.ApplyImpulse(-attackArea.creator.transform.forward * 3f);
|
|
|
|
|
|
attackArea.creator.GetHit(Breakthrough.Type.Medium, out _);
|
2026-03-20 12:07:44 -04:00
|
|
|
|
};
|
|
|
|
|
|
reactionSc.blockSm.ApplyBlock(blockSource);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void RemoveBlock()
|
|
|
|
|
|
{
|
|
|
|
|
|
movementSc.canDash = true;
|
|
|
|
|
|
movementSc.canDodge = true;
|
|
|
|
|
|
reactionSc.blockSm.RemoveBlock(blockData.blockName);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public partial class LegionCenturion
|
|
|
|
|
|
{
|
|
|
|
|
|
private NormalArea GenerateNormalSlash(string vfxName, AttackUnit attackUnit)
|
|
|
|
|
|
{
|
2026-05-23 08:27:50 -04:00
|
|
|
|
NormalArea slash = vfxData.SpawnVFX(vfxName, this).GetComponentInChildren<NormalArea>();
|
2026-03-20 12:07:44 -04:00
|
|
|
|
|
2026-05-23 08:27:50 -04:00
|
|
|
|
slash.Initialize<NormalArea>(this, Fraction.Player)
|
2026-03-20 12:07:44 -04:00
|
|
|
|
.SetAttackSubmodule<NormalArea>(attackUnit)
|
|
|
|
|
|
.SetTimeSubmodule<NormalArea>(1f)
|
2026-05-23 08:27:50 -04:00
|
|
|
|
.SetHitSubmodule<NormalArea>();
|
|
|
|
|
|
slash.SetImpulseSubmodule().WithCustomForce(transform.forward);
|
2026-03-20 12:07:44 -04:00
|
|
|
|
slash.hitSm.AddHitSound(AK.EVENTS.POLYCHROME_LIGHTATTACKHIT);
|
|
|
|
|
|
return slash;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private NormalArea GeneratePowerfulSlash(string vfxName, AttackUnit attackUnit)
|
|
|
|
|
|
{
|
2026-05-23 08:27:50 -04:00
|
|
|
|
NormalArea slash = vfxData.SpawnVFX(vfxName, this).GetComponentInChildren<NormalArea>();
|
2026-03-20 12:07:44 -04:00
|
|
|
|
|
2026-05-23 08:27:50 -04:00
|
|
|
|
slash.Initialize<NormalArea>(this, Fraction.Player)
|
2026-03-20 12:07:44 -04:00
|
|
|
|
.SetAttackSubmodule<NormalArea>(attackUnit)
|
|
|
|
|
|
.SetTimeSubmodule<NormalArea>(1f)
|
|
|
|
|
|
.SetHitSubmodule<NormalArea>()
|
|
|
|
|
|
.SetReactionSubmodule<NormalArea>(false, false, true, true, true, false, false);
|
2026-05-23 08:27:50 -04:00
|
|
|
|
slash.SetImpulseSubmodule().WithCustomForce(transform.forward);
|
2026-03-20 12:07:44 -04:00
|
|
|
|
slash.hitSm.AddHitSound(AK.EVENTS.POLYCHROME_HEAVYATTACKLHIT);
|
|
|
|
|
|
return slash;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private NormalArea GenerateMovingSlash(string vfxName, AttackUnit attackUnit, float speed, Vector3 direction)
|
|
|
|
|
|
{
|
2026-05-23 08:27:50 -04:00
|
|
|
|
NormalArea slash = vfxData.SpawnVFX(vfxName, this).GetComponentInChildren<NormalArea>();
|
2026-03-20 12:07:44 -04:00
|
|
|
|
GameObject blockVFX = vfxData.Get(vfxName).otherVFXList[0];
|
2026-05-23 08:27:50 -04:00
|
|
|
|
slash.Initialize<NormalArea>(this, Fraction.Player)
|
2026-03-20 12:07:44 -04:00
|
|
|
|
.SetAttackSubmodule<NormalArea>(attackUnit)
|
|
|
|
|
|
.SetTimeSubmodule<NormalArea>(10f, 0.2f, 9.6f)
|
|
|
|
|
|
.SetHitSubmodule<NormalArea>()
|
|
|
|
|
|
.SetTransformSubmodule<NormalArea>()
|
2026-05-23 08:27:50 -04:00
|
|
|
|
.SetLinearDirectionMoveModule<NormalArea>(direction, speed, speed * 0.05f, false, true, false);
|
|
|
|
|
|
slash.SetImpulseSubmodule().WithDynamicForce(2);
|
2026-03-20 12:07:44 -04:00
|
|
|
|
slash.transformSm.ApplyScaleMove(Vector3.one, Vector3.one * 2f, 10f, EaseType.OutQuad);
|
|
|
|
|
|
slash.hitSm.AddHitSound(AK.EVENTS.POLYCHROME_LIGHTATTACKHIT);
|
|
|
|
|
|
slash.reactionSm.hasPerfectWindowTime = false;
|
|
|
|
|
|
slash.reactionSm.generalBlockAction = blocker =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var blockTransform = VFXObject.Spawn(blockVFX, this, slash.topParent.transform).transform;
|
|
|
|
|
|
blockTransform.SetParent(null);
|
|
|
|
|
|
LeanPool.Despawn(slash.topParent.gameObject);
|
|
|
|
|
|
};
|
|
|
|
|
|
return slash;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void GenerateTripleMovingSlashes(string vfxName, AttackUnit attackUnit, float speed, Vector3 forwardDirection)
|
|
|
|
|
|
{
|
|
|
|
|
|
//向三个方向生成斩击,分别是forwardDirection和相对于forwardDirection旋转45度的两个方向
|
|
|
|
|
|
List<Vector3> directions = new List<Vector3>();
|
|
|
|
|
|
for (int i = -1; i < 2; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
float angle = i * 45f;
|
|
|
|
|
|
Vector3 dir = Quaternion.Euler(0, angle, 0) * forwardDirection;
|
|
|
|
|
|
directions.Add(dir);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var dir in directions)
|
|
|
|
|
|
{
|
|
|
|
|
|
GenerateMovingSlash(vfxName, attackUnit, speed, dir).topParent.forward = dir;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void GenerateRingMovingSlashes(string vfxName, AttackUnit attackUnit, float speed, Vector3 forwardDirection)
|
|
|
|
|
|
{
|
|
|
|
|
|
//向八个方向生成向外扩散的斩击
|
|
|
|
|
|
List<Vector3> directions = new List<Vector3>();
|
|
|
|
|
|
for (int i = 0; i < 8; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
float angle = i * 45f;
|
|
|
|
|
|
Vector3 dir = Quaternion.Euler(0, angle, 0) * forwardDirection;
|
|
|
|
|
|
directions.Add(dir);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var dir in directions)
|
|
|
|
|
|
{
|
|
|
|
|
|
GenerateMovingSlash(vfxName, attackUnit, speed, dir).topParent.forward = dir;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public partial class LegionCenturion
|
|
|
|
|
|
{
|
2026-05-23 08:27:50 -04:00
|
|
|
|
protected override string GetHitFuncAnimName(Breakthrough.Type breakthroughType, Vector3 direction)
|
2026-03-20 12:07:44 -04:00
|
|
|
|
{
|
|
|
|
|
|
string funcAnimName = base.GetHitFuncAnimName(breakthroughType, direction);
|
|
|
|
|
|
|
|
|
|
|
|
if (funcAnimName == "GetHitHeavyFront")
|
|
|
|
|
|
{
|
|
|
|
|
|
int randomIndex = Random.Range(0, 2);
|
|
|
|
|
|
funcAnimName = funcAnimName + randomIndex.ToString();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return funcAnimName;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|