Files
Cielonos/Assets/Scripts/MainGame/Items/MainWeapons/Polychrome/Polychrome.cs
SoulliesOfficial 347237443f FututeWand初步
2026-07-01 06:32:50 -04:00

319 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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>();
_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();
}
/// <summary>
/// 武器切入(换出至 Polychrome时的逻辑入口
/// </summary>
public override void OnSwitchIn()
{
if (_passionSystem.LevelIndex >= 3)
{
List<Enemy> availableEnemies = CombatManager.EnemySm.GetEnemiesInRadius(player.transform.position, 4);
List<Enemy> 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");
});
}
}
/// <summary>
/// 轻攻击(普攻)输入处理
/// </summary>
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");
}
}
}
/// <summary>
/// 重攻击/特殊/闪避反击输入处理
/// </summary>
public override void OnSecondaryPress()
{
if (player.statusSm.HasStatus(StatusType.Stun))
{
return;
}
List<Enemy> 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<Enemy> 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<PhotonWarper>())
{
target = CombatManager.EnemySm.GetBestEnemy(availableEnemies);
}
else
{
List<Enemy> 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);
}
}
}
}
/// <summary>
/// 终极攻击(次元斩)输入处理
/// </summary>
public override void OnSpecialAPress()
{
if (player.statusSm.HasStatus(StatusType.Stun))
{
return;
}
if (functionSm["UltimateAttack"].IsAvailable())
{
PlayTargetedAnimation("UltimateAttack");
functionSm["UltimateAttack"].Execute();
ApplyUltimatePassionBoost();
}
}
/// <summary>
/// 格挡输入处理
/// </summary>
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);
}
}
}
/// <summary>
/// 格挡输入释放
/// </summary>
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<string, string> GetDescriptionArgs()
{
var args = new Dictionary<string, string>();
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<string, string> args, string prefix, string unitKey)
{
if (attackData.attackUnits.TryGetValue(unitKey, out AttackUnit unit))
{
DisplayTextResolver.PopulateAttackArgs(args, prefix, unit, player);
}
}
}
}