236 lines
8.9 KiB
C#
236 lines
8.9 KiB
C#
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<TimeScaleModifierAction>("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<Enemy> 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<Enemy> 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<PhotonAccelerator>())
|
||
{
|
||
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<DisorderedPhotonCollector>())
|
||
{
|
||
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<ParticleSystem>() : null;
|
||
}
|
||
}
|
||
}
|
||
} |