Files
Cielonos/Assets/Scripts/MainGame/Items/MainWeapons/Polychrome.cs
SoulliesOfficial 7ee2894a63 整合SLSUtilities
2026-01-17 11:35:49 -05:00

436 lines
17 KiB
C#

using AutoLOD.MeshDecimator.QualityMeshDecimator.Internal;
using Cielonos.MainGame.Buffs;
using Cielonos.MainGame.Characters;
using Cielonos.MainGame.FunctionalAnimation;
using Cielonos.UI;
using SLSFramework.General;
using SLSUtilities.FunctionalAnimation;
using SoftCircuits.Collections;
using Unity.Cinemachine;
using UnityEngine;
using UnityEngine.Rendering;
namespace Cielonos.MainGame.Inventory.Collections
{
public partial class Polychrome : MainWeaponBase
{
public BlockData equipBlockData;
public float perfectBlockedTimer;
private bool canAirLightAttack;
private bool canAirHeavyAttack;
protected override void Update()
{
if (player.inventorySc.equipmentSm.currentMainWeapon == this)
{
functionSm?.Update(player.selfTimeSm.DeltaTime);
perfectBlockedTimer -= player.selfTimeSm.DeltaTime;
}
}
public override void OnEquipped()
{
base.OnEquipped();
player.eventSm.onFirstJump.Add("PolyChrome_OnFirstJump", new PrioritizedAction(() =>
{
canAirLightAttack = true;
canAirHeavyAttack = true;
comboSm["AirLight"].Reset();
}));
RegisterFunctionsToAnimSc();
RegisterFunctionsToAnimSc(ImpaleLine, RunAttack, ParryAttack, StayBlocking);
viewObjects["Katana"].SetFadeAnim(0.2f);
viewObjects["Saya"].SetFadeAnim(0.2f);
PlayerCanvas.Instance.mainWeaponUIArea.displayer.SetFrameOutline(0.4f);
PlayTargetedAnimation("EquipBlock");
SetBlock(equipBlockData);
player.selfTimeSm.AddLocalTimer(0.4f, () =>
{
RemoveBlock(equipBlockData);
fullBodyFuncAnimSm.Stop("EquipBlock");
});
}
public override void OnUnequipped()
{
base.OnUnequipped();
player.eventSm.onFirstJump.Remove("PolyChrome_OnFirstJump");
}
public override void OnPrimaryPress()
{
if (player.landMovementSc.isJumping)
{
if (!canAirLightAttack || !functionSm["LightAttack"].IsAvailable())
{
return;
}
if (PlayTargetedAnimation("AirLightAttack" + comboSm["AirLight"].GetNextNodeName("L")))
{
comboSm["AirLight"].NextCombo("L");
functionSm["LightAttack"].Execute();
if (comboSm["AirLight"].GetCurrentNodeName() == "1")
{
canAirLightAttack = false;
}
}
return;
}
if (player.landMovementSc.isSprinting && functionSm["LightAttack"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability())
{
comboSm.main.Reset();
functionSm["LightAttack"].Execute();
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(8);
PlayTargetedAnimation("RunAttack", target, 1f);
//player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward);
return;
}
if (functionSm["LightAttack"].IsAvailable())
{
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5);
if (PlayTargetedAnimation("Attack" + comboSm.main.GetNextNodeName("L"), target))
{
comboSm.main.NextCombo("L");
functionSm["LightAttack"].Execute();
}
//player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward);
}
}
public override void OnSecondaryPress()
{
if (player.landMovementSc.isJumping)
{
if (!canAirHeavyAttack || !functionSm["HeavyAttack"].IsAvailable())
{
return;
}
if (PlayTargetedAnimation("AirHeavyAttackStart"))
{
player.landMovementSc.ExtraJump();
comboSm.main.Reset();
functionSm["HeavyAttack"].Execute();
canAirLightAttack = false;
canAirHeavyAttack = false;
}
return;
}
if (perfectBlockedTimer > 0f && functionSm["HeavyAttack"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability(DisruptionType.ForcedAction))
{
perfectBlockedTimer = 0f;
comboSm.main.Reset();
functionSm["HeavyAttack"].Execute();
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5);
PlayTargetedAnimation("ParryAttack", target, 1f);
//player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward);
return;
}
if (functionSm["HeavyAttack"].IsAvailable())
{
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5);
if (PlayTargetedAnimation("Attack" + comboSm.main.GetNextNodeName("R"), target))
{
comboSm.main.NextCombo("R");
functionSm["HeavyAttack"].Execute();
}
//player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward);
}
}
public override void OnSpecialAPress()
{
if (PlayTargetedAnimation("SkillA"))
{
comboSm.main.Reset();
}
}
public override void OnSpecialBPress()
{
if (functionSm["Block"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability(DisruptionType.ForcedAction))
{
comboSm.main.Reset();
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5);
PlayTargetedAnimation("Block", target, 2f, true, null, 1f, 0.1f, true);
SetBlock();
player.movementSc.canMove.Modify(false);
player.movementSc.canRotate.Modify(false);
}
}
public override void OnSpecialBRelease()
{
if (fullBodyFuncAnimSm.currentRuntimeFuncAnim is { animationName: "Block" })
{
fullBodyFuncAnimSm.Stop(DisruptionType.ForcedAction);
}
player.selfTimeSm.AddLocalTimer(0.1f, () => RemoveBlock());
player.movementSc.canMove.Modify(true);
player.movementSc.canRotate.Modify(true);
}
}
public partial class Polychrome
{
private void FAPF_GenerateNormalSlash(RuntimeFuncAnim rtFuncAnim)
{
CustomFunction.PC_String p = rtFuncAnim.GetParams<CustomFunction.PC_String>();
GenerateNormalSlash(p.str0, Vector3.zero);
}
private void FAPF_GenerateHeavySlash(RuntimeFuncAnim rtFuncAnim)
{
CustomFunction.PC_String p = rtFuncAnim.GetParams<CustomFunction.PC_String>();
GenerateHeavySlash(p.str0, Vector3.zero);
}
private void ImpaleLine() => GenerateHeavySlash("ImpaleLine", new Vector3(0, 1f, 0));
private void RunAttack() => GenerateMoveSlash("RunAttack", new Vector3(1f, 0.6f, 0), player.transform.forward * 10f);
private void ParryAttack() => GenerateParrySlash("ParryAttack", new Vector3(5, 3, -8));
}
public partial class Polychrome
{
private NormalArea GenerateNormalSlash(string vfxName, Vector3 swingRotation)
{
NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren<NormalArea>();
slash.Initialize<NormalArea>(player, this, Fraction.Enemy)
.SetAttackSubmodule<NormalArea>(attackData["LightAttack"])
.SetTimeSubmodule<NormalArea>(1f, 0.04f)
.SetHitSubmodule<NormalArea>()
.SetForceSubmodule<NormalArea>(3f, true);
slash.hitSm
.AddHitSound("NormalHit")
.AddHitEvent((enemy, hitPosition) =>
{
feedbackSc["NormalHit"].Play();
new ElectronicDisturbance(2).Apply(enemy);
});
Swing("NormalSwing", "NormalSwing", swingRotation);
return slash;
}
private NormalArea GenerateFastSlash(string vfxName, Vector3 swingForce)
{
NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren<NormalArea>();
slash.Initialize<NormalArea>(player, this, Fraction.Enemy)
.SetAttackSubmodule<NormalArea>(attackData["LightAttack"])
.SetTimeSubmodule<NormalArea>(1f, 0.04f)
.SetHitSubmodule<NormalArea>()
.SetForceSubmodule<NormalArea>(3f, true);
string hitFeedbackName = vfxName != "TripleAttack_2" ? "FastHitFirsts" : "FastHitFinal";
slash.hitSm
.AddHitSound("NormalHit")
.AddHitEvent((enemy, hitPosition) =>
{
feedbackSc[hitFeedbackName].Play();
new ElectronicDisturbance(2).Apply(enemy);
if (enemy.statusSm.HasStatus(StatusType.Incapacitation))
{
slash.attackSm.attackValue.damage *= 5f;
}
});
Swing("NormalSwing", "NormalSwing", swingForce);
return slash;
}
private NormalArea GenerateHeavySlash(string vfxName, Vector3 swingRotation)
{
NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren<NormalArea>();
slash.Initialize<NormalArea>(player, this, Fraction.Enemy)
.SetAttackSubmodule<NormalArea>(attackData["HeavyAttack"])
.SetTimeSubmodule<NormalArea>(1f, 0.04f, 0.2f)
.SetHitSubmodule<NormalArea>(0.04f, 4)
.SetForceSubmodule<NormalArea>(3f, true);
slash.hitSm
.AddHitSound("HeavyHit")
.AddHitEvent((enemy, hitPosition) =>
{
feedbackSc["HeavyHitFirst"].Play();
new ElectronicDisturbance(25).Apply(enemy);
}, 0)
.AddHitEvent((enemy, hitPosition) =>
{
feedbackSc["HeavyHitFollows"].Play();
new ElectronicDisturbance(25).Apply(enemy);
}, 1, 2, 3);
Swing("HeavySwing", "HeavySwing", swingRotation);
return slash;
}
private NormalArea GenerateParrySlash(string vfxName, Vector3 swingForce)
{
NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren<NormalArea>();
slash.Initialize<NormalArea>(player, this, Fraction.Enemy)
.SetAttackSubmodule<NormalArea>(attackData["ParryAttack"])
.SetTimeSubmodule<NormalArea>(1f, 0.04f)
.SetHitSubmodule<NormalArea>()
.SetForceSubmodule<NormalArea>(3f, true);
slash.hitSm
.AddHitSound("HeavyHit")
.AddHitEvent((enemy, hitPosition) =>
{
feedbackSc["ParryHit"].Play();
player.selfTimeSm.ModifyTimeScale(0.12f);
enemy.selfTimeSm.ModifyTimeScale(0.12f);
player.selfTimeSm.AddGlobalTimer(0.12f, () =>
{
player.selfTimeSm.ModifyTimeScale(0.2f, 0.3f);
enemy.selfTimeSm.ModifyTimeScale(0.2f, 0.3f);
});
new ElectronicDisturbance(5).Apply(enemy);
});
Swing("HeavySwing", "HeavySwing", swingForce);
return slash;
}
private NormalArea GenerateDisruptSlash(string vfxName, Vector3 swingForce)
{
NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren<NormalArea>();
slash.Initialize<NormalArea>(player, this, Fraction.Enemy)
.SetAttackSubmodule<NormalArea>(attackData["DisruptAttack"])
.SetTimeSubmodule<NormalArea>(1f, 0.04f)
.SetHitSubmodule<NormalArea>()
.SetForceSubmodule<NormalArea>(3f, true);
slash.hitSm
.AddHitSound("HeavyHit")
.AddHitEvent((enemy, hitPosition) =>
{
feedbackSc["DisruptHit"].Play();
new ElectronicDisturbance(5).Apply(enemy);
});
Swing("HeavySwing", "HeavySwing", swingForce);
return slash;
}
private void GenerateMoveSlash(string vfxName, Vector3 swingForce, Vector3 moveVelocity)
{
NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren<NormalArea>();
slash.Initialize<NormalArea>(player, this, Fraction.Enemy)
.SetAttackSubmodule<NormalArea>(attackData["LightAttack"])
.SetTimeSubmodule<NormalArea>(1f, 0.04f)
.SetHitSubmodule<NormalArea>()
.SetForceSubmodule<NormalArea>(3f, true)
.SetLinearDirectionMoveModule<NormalArea>(moveVelocity.normalized, moveVelocity.magnitude, -20f, false);
slash.hitSm
.AddHitSound("NormalHit")
.AddHitEvent((enemy, hitPosition) =>
{
feedbackSc["NormalHit"].Play();
new ElectronicDisturbance(2).Apply(enemy);
});
Swing("NormalSwing", "NormalSwing", swingForce);
}
string parryAnimName = "ParryL";
private void SetBlock(BlockData blockData = null)
{
blockData ??= this.blockData;
BlockSource blockSource = blockData.CreateBlockSource(player, this);
blockSource.onNormalBlock = (attackArea) =>
{
parryAnimName = parryAnimName == "ParryL" ? "ParryR" : "ParryL";
animationSc.fullBodyFuncAnimSm.Play(parryAnimName, 1, 0);
player.selfTimeSm.ModifyTimeScale(0.06f, 0.4f);
attackArea.creator.selfTimeSm.ModifyTimeScale(0.06f, 0.4f);
if (parryAnimName == "ParryL")
{
feedbackSc["NormalBlockLeft"].Play();
}
else
{
feedbackSc["NormalBlockRight"].Play();
}
if (attackArea is NormalArea)
{
new ElectronicDisturbance(2).Apply(attackArea.creator);
}
};
blockSource.onPerfectBlock = (attackArea) =>
{
parryAnimName = parryAnimName == "ParryL" ? "ParryR" : "ParryL";
animationSc.fullBodyFuncAnimSm.Play(parryAnimName, 1, 0);
player.selfTimeSm.ModifyTimeScale(0.12f, EaseType.InQuint, 0.2f);
attackArea.creator.selfTimeSm.ModifyTimeScale(0.12f, EaseType.InQuint, 0.2f);
if (parryAnimName == "ParryL")
{
feedbackSc["PerfectBlockLeft"].Play();
}
else
{
feedbackSc["PerfectBlockRight"].Play();
}
perfectBlockedTimer = 0.5f;
if (attackArea is NormalArea)
{
new ElectronicDisturbance(10).Apply(attackArea.creator);
}
//Debug.Break();
};
player.reactionSc.blockSm.ApplyBlock(blockSource);
//blockDisposable?.Dispose();
}
private void StayBlocking()
{
if (player.inputSc.IsHoldingSpecialB)
{
player.movementSc.canMove.Modify(true);
player.movementSc.canRotate.Modify(true);
OnSpecialBPress();
}
}
private void RemoveBlock(BlockData blockData = null)
{
blockData ??= this.blockData;
player.reactionSc.blockSm.RemoveBlock(blockData.blockName);
}
}
}