using System.Collections.Generic; using Cielonos.MainGame.Characters; using Cielonos.MainGame.Effects.Feedback; using Cielonos.MainGame.FunctionalAnimation; using SLSUtilities.Feedback; using SLSUtilities.FunctionalAnimation; using SLSUtilities.General; using UnityEngine; namespace Cielonos.MainGame.Inventory.Collections { public partial class Polychrome { private bool PlayAirAttackL(string nodeName) { bool played = PlayTargetedAnimation("AirAttack" + nodeName); if (played) { ApplyPhotonAcceleratorIfEquipped(); functionSm["LightAttack"].Execute(); } return played; } private bool PlayRunAttack(CharacterBase target) { bool played = PlayTargetedAnimation("RunAttack", target); if (played) { ApplyPhotonAcceleratorIfEquipped(); functionSm["LightAttack"].Execute(); } return played; } private bool PlayNormalAttackL(CharacterBase target, string nextNodeName) { bool keepAdsorption = nextNodeName is "L4" or "L5"; bool played = PlayTargetedAnimation("Attack" + nextNodeName, target, 1f, keepAdsorption); if (played) { ApplyPhotonAcceleratorIfEquipped(); float totalTime = 0f; CombatManager.EnemySm.activeEnemiesList.ForEach(enemy => (enemy as Enemy)!.behaviorSc.DispatchContextEvent("PlayerLightAttack", totalTime)); functionSm["LightAttack"].Execute(); } return played; } private bool PlayAirAttackR() { bool played = PlayTargetedAnimation("AirAttackRStart"); if (played) { player.landMovementSc.ExtraJump(10f); functionSm["HeavyAttack"].Execute(); } return played; } private bool PlayNormalAttackR(Enemy target, string suffix) { bool keepAdsorption = suffix is "RC"; bool played = PlayTargetedAnimation("Attack" + suffix, target, 1f, keepAdsorption); if (played) { float totalTime = fullBodyFuncAnimSm.GetIntervalScaledDuration(IntervalType.Startup) - 0.2f; CombatManager.EnemySm.activeEnemiesList.ForEach(enemy => enemy!.behaviorSc.DispatchContextEvent("PlayerHeavyAttack", totalTime)); functionSm["HeavyAttack"].Execute(); } return played; } private void WarpToTarget(Enemy target, FuncAnimInterval interval, float multiplier = 1f) { float warpDuration = interval.Duration / multiplier; fullBodyFuncAnimSm.currentRuntimeFuncAnim.AddAnimEvent(interval.StartTime, new SetFuncAnimSpeed(multiplier)); fullBodyFuncAnimSm.currentRuntimeFuncAnim.AddAnimEvent(interval.EndTime, new SetFuncAnimSpeed(1)); player.movementSc.Teleport(target, warpDuration); } private void PlayDisruptionAttack(Enemy target, string suffix) { string animName = "DisruptionAttack" + suffix; bool played = PlayTargetedAnimation(animName, target); if (played) { FeedbackClip timeScaleModifierClip = player.feedbackSc.GetFeedbackData("DisruptionStartup").Clip("Time"); float duration = fullBodyFuncAnimSm.collection[animName].Interval(IntervalType.Startup).Duration * 2; timeScaleModifierClip.duration = duration; player.feedbackSc.PlayFeedback("DisruptionStartup"); if(suffix == "B") _passionSystem.DecreasePassion(100, false); functionSm["DisruptionAttack"].Execute(); } } private bool PlayParryAttack(List availableEnemies) { BlockSubmodule blockSm = player.reactionSc.blockSm; if (!blockSm.afterPerfectBlockTimer.isCompleted) { Enemy blockedTarget = blockSm.perfectBlockedTarget as Enemy; if (TryPlayParryAttack(blockedTarget, availableEnemies)) { blockSm.afterPerfectBlockTimer.Complete(); RemoveBlock(); return true; } } DodgeSubmodule dodgeSm = player.reactionSc.dodgeSm; if (!dodgeSm.afterPerfectDodgeTimer.isCompleted) { Enemy dodgedTarget = dodgeSm.perfectDodgedTarget as Enemy; if (TryPlayParryAttack(dodgedTarget, availableEnemies)) { dodgeSm.afterPerfectDodgeTimer.Complete(); return true; } } return false; bool TryPlayParryAttack(Enemy parryTarget, List enemies) { if (parryTarget != null && !enemies.Contains(parryTarget)) { float distance = Vector3.Distance(player.transform.position, parryTarget.transform.position); return PlayTargetedAnimation(distance > 2f ? "DodgeParryAttack" : "BlockParryAttack", parryTarget); } return PlayTargetedAnimation("BlockParryAttack"); } } } public partial class Polychrome { private void ApplyPhotonAcceleratorIfEquipped() { if (HasExtender()) { FuncAnimInterval interval = fullBodyFuncAnimSm.currentData.Interval(IntervalType.Startup); if (interval != null) { fullBodyFuncAnimSm.currentRuntimeFuncAnim.AddAnimEvent( interval.StartTime, new SetFuncAnimSpeed(1.5f, SetFuncAnimSpeed.SpeedApplyMode.Multiply)); fullBodyFuncAnimSm.currentRuntimeFuncAnim.AddAnimEvent( interval.EndTime, new SetFuncAnimSpeed(1f / 1.5f, SetFuncAnimSpeed.SpeedApplyMode.Multiply)); } } } private void ApplyUltimatePassionBoost() { if (HasExtender()) { var passionSystem = _passionSystem; if (passionSystem != null) { int currentLevel = passionSystem.LevelIndex; float currentPercent = passionSystem.Percent; float targetIncrease = 100f; if (currentLevel == 0) // C level { targetIncrease = 200f - currentPercent; } float amplifier = player.attributeSm[CharacterAttribute.PassionIncreaseAmplifier]; float multiplier = passionSystem.passionLevels[currentLevel].increaseMultiplier; float divisor = multiplier * (1f + amplifier); if (divisor > 0.001f) { float baseAmount = targetIncrease / divisor; passionSystem.IncreasePassion(baseAmount, true); } } } } } public partial class Polychrome { private string _currentKatanaParticle; private void UpdateViewObjectVisuals() { if (_passionSystem == null) return; int level = _passionSystem.LevelIndex; // 开关粒子特效 if (level < 3) // C, B,A级 { if (_currentKatanaParticle != string.Empty) { GetParticle().Stop(); _currentKatanaParticle = string.Empty; } } else if (level <= 4) // S,SS级 (2) { if (_currentKatanaParticle != "ParticleStage0") { if (_currentKatanaParticle != string.Empty) { GetParticle().Stop(); } _currentKatanaParticle = "ParticleStage0"; GetParticle().Play(); } } else // SSS级及以上 { if (_currentKatanaParticle != "ParticleStage1") { if (_currentKatanaParticle != string.Empty) { GetParticle().Stop(); } _currentKatanaParticle = "ParticleStage1"; GetParticle().Play(); } } return; ParticleSystem GetParticle() { return viewObjects["Katana"].functionalParts.TryGetValue(_currentKatanaParticle, out GameObject particleObj) ? particleObj.GetComponent() : null; } } } }