using Cielonos.MainGame.Buffs; using Cielonos.MainGame.Characters; using Cielonos.UI; using SLSFramework.General; using SLSUtilities.FunctionalAnimation; using UnityEngine; namespace Cielonos.MainGame.Inventory.Collections { public partial class Polychrome : MainWeaponBase { public BlockData equipBlockData; public float perfectBlockedTimer; 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(); RegisterFunctionsToAnimSc( LightAttack0, LightAttack1, LightAttack2, LightAttack3, TripleAttack_0, TripleAttack_1, TripleAttack_2, DisruptAttack, HeavyAttack, 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 OnPrimaryPress() { if (player.inputSc.IsHoldingSpecialA && functionSm["TripleAttack"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability()) { comboSm.ResetCombo(); functionSm["TripleAttack"].Execute(); CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5); PlayTargetedAnimation("TripleAttack", target, 1f); //player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward); return; } if (player.landMovementSc.isSprinting && functionSm["LightAttack"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability()) { comboSm.ResetCombo(); 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() && fullBodyFuncAnimSm.CheckPlayability()) { comboSm.NextCombo("L"); functionSm["LightAttack"].Execute(); CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5); PlayTargetedAnimation("LightAttack" + comboSm.GetCurrentNodeName(), target, 1f); //player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward); } } public override void OnSecondaryPress() { if (player.landMovementSc.isJumping && functionSm["HeavyAttack"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability()) { comboSm.ResetCombo(); functionSm["HeavyAttack"].Execute(); PlayTargetedAnimation("AirAttackStart0"); } if (perfectBlockedTimer > 0f && functionSm["HeavyAttack"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability(DisruptionType.ForcedAction)) { perfectBlockedTimer = 0f; comboSm.ResetCombo(); functionSm["HeavyAttack"].Execute(); CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5); PlayTargetedAnimation("ParryAttack", target, 1f); //player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward); return; } if (player.inputSc.IsHoldingSpecialA && functionSm["DisruptAttack"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability()) { comboSm.ResetCombo(); functionSm["DisruptAttack"].Execute(); CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5); PlayTargetedAnimation("DisruptAttack", target, 1f); //player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward); return; } if (functionSm["HeavyAttack"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability()) { comboSm.ResetCombo(); functionSm["HeavyAttack"].Execute(); CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5); PlayTargetedAnimation("HeavyAttack", target, 1f); //player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward); } } public override void OnSpecialBPress() { if (functionSm["Block"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability(DisruptionType.ForcedAction)) { comboSm.ResetCombo(); 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 LightAttack0() => GenerateNormalSlash("LightAttack0", new Vector3(0.5f, 1f, 0)); private void LightAttack1() => GenerateNormalSlash("LightAttack1", new Vector3(-0.5f, -1f, 0)); private void LightAttack2() => GenerateNormalSlash("LightAttack2", new Vector3(0.8f, -1.2f, 0)); private void LightAttack3() => GenerateNormalSlash("LightAttack3", new Vector3(0.5f, 1.5f, 0)); private void TripleAttack_0() => GenerateFastSlash("TripleAttack_0", new Vector3(1f, 0.6f, 0)); private void TripleAttack_1() => GenerateFastSlash("TripleAttack_1", new Vector3(-1f, -0.6f, 0)); private void TripleAttack_2() => GenerateFastSlash("TripleAttack_2", new Vector3(0.6f, 1f, 0)); private void HeavyAttack() => GenerateHeavySlash("HeavyAttack", new Vector3(3, -2, -5)); 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)); private void DisruptAttack() => GenerateDisruptSlash("DisruptAttack", new Vector3(0.6f, 2f, 0)); } public partial class Polychrome { private NormalArea GenerateNormalSlash(string vfxName, Vector3 swingRotation) { NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren(); slash.Initialize(player, this, Fraction.Enemy) .SetAttackSubmodule(attackData["LightAttack"]) .SetTimeSubmodule(1f, 0.04f) .SetHitSubmodule() .SetForceSubmodule(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(); slash.Initialize(player, this, Fraction.Enemy) .SetAttackSubmodule(attackData["LightAttack"]) .SetTimeSubmodule(1f, 0.04f) .SetHitSubmodule() .SetForceSubmodule(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(); slash.Initialize(player, this, Fraction.Enemy) .SetAttackSubmodule(attackData["HeavyAttack"]) .SetTimeSubmodule(1f, 0.04f, 0.2f) .SetHitSubmodule(0.04f, 4) .SetForceSubmodule(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(); slash.Initialize(player, this, Fraction.Enemy) .SetAttackSubmodule(attackData["ParryAttack"]) .SetTimeSubmodule(1f, 0.04f) .SetHitSubmodule() .SetForceSubmodule(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(); slash.Initialize(player, this, Fraction.Enemy) .SetAttackSubmodule(attackData["DisruptAttack"]) .SetTimeSubmodule(1f, 0.04f) .SetHitSubmodule() .SetForceSubmodule(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(); slash.Initialize(player, this, Fraction.Enemy) .SetAttackSubmodule(attackData["LightAttack"]) .SetTimeSubmodule(1f, 0.04f) .SetHitSubmodule() .SetForceSubmodule(3f, true) .SetLinearDirectionMoveModule(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); } } }