using System.Collections.Generic; using Cielonos.MainGame.Characters; using Cielonos.MainGame.Effects.Feedback; using Cielonos.MainGame.FunctionalAnimation; using Cielonos.MainGame.UI; using SLSUtilities.Feedback; using SLSUtilities.General; using SLSUtilities.FunctionalAnimation; using UnityEngine; namespace Cielonos.MainGame.Inventory.Collections { public partial class Polychrome : MainWeaponBase { private PassionSystem _passionSystem; private bool _canAirLightAttack; private bool _canAirHeavyAttack; protected override void Update() { if (player.inventorySc.equipmentSm.currentMainWeapon == this) { functionSm?.Update(player.selfTimeSm.DeltaTime); } /*if (Keyboard.current.xKey.wasPressedThisFrame) { SetBlock(); player.reactionSc.blockSm.GetBlockSource("Polychrome_Block").PerfectBlock(null, player.CenterPosition + player.transform.forward); RemoveBlock(); } if (Keyboard.current.zKey.wasPressedThisFrame) { player.reactionSc.dodgeSm.ApplyDodge(DodgeSource.Default(player)); player.reactionSc.dodgeSm.GetCurrentDodgeSource()?.PerfectDodge(null); player.reactionSc.dodgeSm.RemoveDodge("DefaultDodge"); }*/ } public override void OnEquipped() { base.OnEquipped(); _currentKatanaParticle = string.Empty; player.eventSm.onFirstJump.TryAdd(nameof(Polychrome), new PrioritizedAction(() => { _canAirLightAttack = true; _canAirHeavyAttack = true; comboSm["AirLight"].Reset(); })); _passionSystem = CombatManager.GetCombatSystem(); _passionSystem.OnLevelChanged += OnPassionLevelChanged; RegisterFunctionsToAnimSc(StayBlocking); viewObjects["Katana"].SetFadeAnim(0.2f); viewObjects["Saya"].SetFadeAnim(0.2f); UpdateViewObjectVisuals(); } public override void OnUnequipped() { base.OnUnequipped(); _passionSystem.OnLevelChanged -= OnPassionLevelChanged; player.eventSm.onFirstJump.Remove(nameof(Polychrome)); } private void OnPassionLevelChanged(int oldLevel, int newLevel) { UpdateViewObjectVisuals(); } /// /// 武器切入(换出至 Polychrome)时的逻辑入口 /// public override void OnSwitchIn() { if (_passionSystem.LevelIndex >= 3) { List availableEnemies = CombatManager.EnemySm.GetEnemiesInRadius(player.transform.position, 4); List disruptable = CombatManager.EnemySm.GetDisruptableEnemies(availableEnemies); Enemy target = CombatManager.EnemySm.GetScoredEnemies(availableEnemies).ApplyScoreModifier(disruptable, 0f, 1f).BestEnemy(); if (target != null) { comboSm.main.Reset(); PlayDisruptionAttack(target, "B"); } SetBlock(equipBlockData, false); player.selfTimeSm.AddLocalTimer(0.4f, () => RemoveBlock(equipBlockData)); } else { PlayTargetedAnimation("EquipBlock"); SetBlock(equipBlockData); player.selfTimeSm.AddLocalTimer(0.4f, () => { RemoveBlock(equipBlockData); fullBodyFuncAnimSm.Stop("EquipBlock"); }); } } /// /// 轻攻击(普攻)输入处理 /// public override void OnPrimaryPress() { if (player.statusSm.HasStatus(StatusType.Stun) || player.reactionSc.blockSm.HaveBlockSource(blockData.blockName)) { return; } // 空中轻攻击连击 if (player.landMovementSc.isJumping) { if (_canAirLightAttack && functionSm["LightAttack"].IsAvailable()) { string airNodeName = comboSm["AirLight"].GetNextNodeName("L"); if (PlayAirAttackL(airNodeName)) { comboSm["AirLight"].NextCombo("L"); if (comboSm["AirLight"].GetCurrentNodeName() == "L1") { _canAirLightAttack = false; } } } return; } CharacterBase target = CombatManager.EnemySm.GetBestEnemy(5); // 冲刺/奔跑攻击 if (player.landMovementSc.isSprinting && functionSm["LightAttack"].IsAvailable()) { comboSm.main.Reset(); if (PlayRunAttack(target)) { comboSm.main.NextCombo("L"); } return; } // 常规地面轻攻击连击 if (functionSm["LightAttack"].IsAvailable()) { string nextNodeName = comboSm.main.GetNextNodeName("L"); if (PlayNormalAttackL(target, nextNodeName)) { comboSm.main.NextCombo("L"); } } } /// /// 重攻击/特殊/闪避反击输入处理 /// public override void OnSecondaryPress() { if (player.statusSm.HasStatus(StatusType.Stun)) { return; } List availableEnemies = CombatManager.EnemySm.GetEnemiesInRadius(player.transform.position, 4); if (PlayParryAttack(availableEnemies)) return; if (player.reactionSc.blockSm.HaveBlockSource(blockData.blockName)) return; // 空中重攻击下砸 if (player.landMovementSc.isJumping) { if (_canAirHeavyAttack && functionSm["HeavyAttack"].IsAvailable()) { comboSm.main.Reset(); if (PlayAirAttackR()) { _canAirLightAttack = false; _canAirHeavyAttack = false; } } return; } // 颠覆攻击 if (player.inputSc.IsHoldingSpecialB) { if (functionSm["DisruptionAttack"].IsAvailable()) { bool isEnhanced = _passionSystem.LevelIndex >= 3; string suffix = isEnhanced ? "B" : "A"; List disruptable = CombatManager.EnemySm.GetDisruptableEnemies(availableEnemies); Enemy target = CombatManager.EnemySm.GetScoredEnemies(availableEnemies).ApplyScoreModifier(disruptable, 0f, 1f).BestEnemy(); comboSm.main.Reset(); PlayDisruptionAttack(target, suffix); } return; } // 常规地面重攻击连击 if (functionSm["HeavyAttack"].IsAvailable()) { Enemy target; bool shouldWarp = false; string suffix = comboSm.main.GetNextNodeName("R"); // 携带 PhotonWarper 时的中远距离敌人折跃判定 if (!HasExtender()) { target = CombatManager.EnemySm.GetBestEnemy(availableEnemies); } else { List fartherRange = CombatManager.EnemySm.GetEnemiesInRadius(player.transform.position, 15); target = CombatManager.EnemySm.GetBestEnemy(fartherRange); if (target != null && suffix == "RA") { float distance = Vector3.Distance(player.transform.position, target.transform.position); if (distance > 2f) { shouldWarp = true; player.movementSc.SmartTurnToTarget(target, 360, true); } } } if (PlayNormalAttackR(target, suffix)) { comboSm.main.NextCombo("R"); if (shouldWarp) { FuncAnimInterval interval = fullBodyFuncAnimSm.currentData.Interval(IntervalType.Startup); WarpToTarget(target, interval, 1f); } } } } /// /// 终极攻击(次元斩)输入处理 /// public override void OnSpecialAPress() { if (player.statusSm.HasStatus(StatusType.Stun)) { return; } if (functionSm["UltimateAttack"].IsAvailable()) { PlayTargetedAnimation("UltimateAttack"); functionSm["UltimateAttack"].Execute(); ApplyUltimatePassionBoost(); } } /// /// 格挡输入处理 /// public override void OnSpecialCPress() { comboSm.main.Reset(); SetBlock(); if (!player.statusSm.HasStatus(StatusType.Stun)) { CharacterBase target = CombatManager.EnemySm.GetBestEnemy(5); if (fullBodyFuncAnimSm.Stop(DisruptionType.ForcedAction)) { PlayTargetedAnimation("Block", target, 2f, false, true, upperBodyFuncAnimSm, 1f, 0.1f, true); } } } /// /// 格挡输入释放 /// public override void OnSpecialCRelease() { if (upperBodyFuncAnimSm.currentRuntimeFuncAnim is { animationName: "Block" }) { upperBodyFuncAnimSm.Stop(DisruptionType.Must); } player.selfTimeSm.AddLocalTimer(0.04f, () => RemoveBlock()); } } public partial class Polychrome { public override Dictionary GetDescriptionArgs() { var args = new Dictionary(); if (attackData == null) return args; // TODO: 将下列 AttackUnit key 替换为 AttackData ScriptableObject 中的实际 key 名 TryPopulateAttack(args, "light", "ProbingAttack"); // TryPopulateAttack(args, "heavy", "HeavySlash"); // TryPopulateAttack(args, "disruption_a", "DisruptionA"); // TryPopulateAttack(args, "disruption_b", "DisruptionB"); // TryPopulateAttack(args, "disruption_c", "DisruptionC"); return args; } private void TryPopulateAttack(Dictionary args, string prefix, string unitKey) { if (attackData.attackUnits.TryGetValue(unitKey, out AttackUnit unit)) { DisplayTextResolver.PopulateAttackArgs(args, prefix, unit, player); } } } }