Files
Cielonos/Assets/Scripts/MainGame/Items/MainWeapons/Polychrome.cs
SoulliesOfficial 50ee502684 完善
2026-02-13 09:22:11 -05:00

457 lines
18 KiB
C#

using System.Collections.Generic;
using Cielonos.MainGame.Buffs.Character;
using Cielonos.MainGame.Characters;
using Cielonos.MainGame.UI;
using MoreMountains.FeedbacksForThirdParty;
using MoreMountains.FeedbacksForThirdParty.Cielonos;
using SLSUtilities.General;
using SLSUtilities.FunctionalAnimation;
using SLSUtilities.WwiseAssistance;
using UniRx;
using UnityEngine;
namespace Cielonos.MainGame.Inventory.Collections
{
public partial class Polychrome : MainWeaponBase
{
private bool canAirLightAttack;
private bool canAirHeavyAttack;
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();
player.eventSm.onFirstJump.Add("PolyChrome_OnFirstJump", new PrioritizedAction(() =>
{
canAirLightAttack = true;
canAirHeavyAttack = true;
comboSm["AirLight"].Reset();
}));
RegisterFunctionsToAnimSc(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 OnUnequipped()
{
base.OnUnequipped();
player.eventSm.onFirstJump.Remove("PolyChrome_OnFirstJump");
}
public override void OnPrimaryPress()
{
if (player.reactionSc.blockSm.HaveBlockSource(blockData.blockName))
{
return;
}
if (player.landMovementSc.isJumping)
{
if (!canAirLightAttack || !functionSm["LightAttack"].IsAvailable())
{
return;
}
if (PlayTargetedAnimation("AirAttack" + comboSm["AirLight"].GetNextNodeName("L")))
{
comboSm["AirLight"].NextCombo("L");
functionSm["LightAttack"].Execute();
if (comboSm["AirLight"].GetCurrentNodeName() == "L1")
{
canAirLightAttack = false;
}
}
return;
}
if (player.inputSc.IsHoldingSpecialA && functionSm["LightAttack"].IsAvailable())
{
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5);
if (PlayTargetedAnimation("AttackRC", target))
{
comboSm.main.NextCombo("L");
functionSm["LightAttack"].Execute();
}
return;
}
if (player.landMovementSc.isSprinting && functionSm["LightAttack"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability())
{
comboSm.main.Reset();
functionSm["LightAttack"].Execute();
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(8);
PlayTargetedAnimation("RunAttack", target);
comboSm.main.NextCombo("L");
//player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward);
return;
}
if (functionSm["LightAttack"].IsAvailable())
{
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5);
string nextNodeName = comboSm.main.GetNextNodeName("L");
bool keepAdsorption = nextNodeName is "L4" or "L5" or "RC";
if (PlayTargetedAnimation("Attack" + comboSm.main.GetNextNodeName("L"), target, 1f, keepAdsorption))
{
comboSm.main.NextCombo("L");
functionSm["LightAttack"].Execute();
}
//player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward);
}
}
public override void OnSecondaryPress()
{
if (perfectBlockedTimer > 0f && functionSm["HeavyAttack"].IsAvailable())
{
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5);
if (PlayTargetedAnimation("ParryAttack", target))
{
perfectBlockedTimer = 0f;
comboSm.main.Reset();
functionSm["HeavyAttack"].Execute();
}
//player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward);
return;
}
if (player.reactionSc.blockSm.HaveBlockSource(blockData.blockName))
{
return;
}
if (player.landMovementSc.isJumping)
{
if (!canAirHeavyAttack || !functionSm["HeavyAttack"].IsAvailable())
{
return;
}
if (PlayTargetedAnimation("AirAttackRStart"))
{
player.landMovementSc.ExtraJump(10f);
comboSm.main.Reset();
functionSm["HeavyAttack"].Execute();
canAirLightAttack = false;
canAirHeavyAttack = false;
}
return;
}
List<CharacterBase> availableEnemies = BattleManager.EnemySm.GetEnemiesInRadius(player.transform.position, 5);
if (player.inputSc.IsHoldingSpecialA && functionSm["HeavyAttack"].IsAvailable())
{
if (BattleManager.EnemySm.GetDisruptableEnemies(availableEnemies).Count > 0)
{
float duration = fullBodyFuncAnimSm.collection["DisruptionAttack"].Interval(IntervalType.Startup).Duration * 2;
player.feedbackSc["DisruptionBulletTime"].feedback.GetFeedbackOfType<CIF_TimeScaleModifier>().Duration = duration;
player.feedbackSc["DisruptionBulletTime"].feedback.GetFeedbackOfType<MMF_ColorAdjustments_URP>().ShakeDuration = duration;
player.feedbackSc["DisruptionBulletTime"].Play();
}
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(availableEnemies);
if (PlayTargetedAnimation("DisruptionAttack", target))
{
comboSm.main.Reset();
functionSm["HeavyAttack"].Execute();
}
return;
}
if (functionSm["HeavyAttack"].IsAvailable())
{
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5);
if (PlayTargetedAnimation("Attack" + comboSm.main.GetNextNodeName("R"), target))
{
comboSm.main.NextCombo("R");
functionSm["HeavyAttack"].Execute();
}
//player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward);
}
}
public override void OnSpecialCPress()
{
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5);
if (functionSm["Block"].IsAvailable() && fullBodyFuncAnimSm.Stop(DisruptionType.ForcedAction) &&
PlayTargetedAnimation("Block", target, 2f, false, true, upperBodyFuncAnimSm, 1f, 0.1f, true))
{
comboSm.main.Reset();
SetBlock();
}
}
public override void OnSpecialCRelease()
{
if (upperBodyFuncAnimSm.currentRuntimeFuncAnim is { animationName: "Block" })
{
upperBodyFuncAnimSm.Stop(DisruptionType.ForcedAction);
}
player.selfTimeSm.AddLocalTimer(0.04f, () => RemoveBlock());
}
}
public partial class Polychrome
{
private void FAPF_GenerateNormalSlash(RuntimeFuncAnim rtFuncAnim)
{
CustomFunction.PC_StringString p = rtFuncAnim.GetParams<CustomFunction.PC_StringString>();
GenerateNormalSlash(p.str0, attackData[p.str1], Vector3.zero);
}
private void FAPF_GenerateHeavySlash(RuntimeFuncAnim rtFuncAnim)
{
CustomFunction.PC_StringString p = rtFuncAnim.GetParams<CustomFunction.PC_StringString>();
GenerateHeavySlash(p.str0, attackData[p.str1], Vector3.zero);
}
private void FAPF_GenerateParrySlash(RuntimeFuncAnim rtFuncAnim)
{
CustomFunction.PC_StringString p = rtFuncAnim.GetParams<CustomFunction.PC_StringString>();
GenerateParrySlash(p.str0, attackData[p.str1], new Vector3(5, 3, -8));
}
private void FAPF_GenerateDisruptionSlash(RuntimeFuncAnim rtFuncAnim)
{
CustomFunction.PC_StringString p = rtFuncAnim.GetParams<CustomFunction.PC_StringString>();
GenerateDisruptionSlash(p.str0, attackData[p.str1], new Vector3(4, 0, 0));
}
private void FAPF_GenerateMovingSlash(RuntimeFuncAnim rtFuncAnim)
{
CustomFunction.PC_StringString p = rtFuncAnim.GetParams<CustomFunction.PC_StringString>();
GenerateDisruptionSlash(p.str0, attackData[p.str1], new Vector3(4, 0, 0));
}
}
public partial class Polychrome
{
private NormalArea GenerateNormalSlash(string vfxName, AttackUnit attackUnit, Vector3 swingRotation)
{
NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren<NormalArea>();
slash.Initialize<NormalArea>(player, this, Fraction.Enemy)
.SetAttackSubmodule<NormalArea>(attackUnit)
.SetTimeSubmodule<NormalArea>(1f, 0.04f, 0.06f)
.SetHitSubmodule<NormalArea>()
.SetForceSubmodule<NormalArea>(1.5f, true);
slash.hitSm.AddHitSound("NormalHit")
.AddHitEvent((enemy, hitPosition) =>
{
feedbackSc["NormalHit"].Play();
ApplyElectronicParalysis(enemy, attackUnit);
if (attackUnit.unitName == "InstantAttack")
{
if (enemy.buffSm.HasBuff<ElectronicParalysis>())
{
slash.attackSm.attackValue.damage *= 2f;
}
}
});
//Swing("NormalSwing", "NormalSwing", swingRotation);
return slash;
}
/*int progress = Mathf.RoundToInt(attackData["LightAttack"].paramCollection[vfxName]);
Observable.EveryUpdate()
.Where(_ => (enemy.movementSc is AutomataLandMovementSubcontroller subcontroller &&
subcontroller.finalMovementVelocity.y <= 0f))
.First().Subscribe(_ =>
{
(enemy.movementSc as AutomataLandMovementSubcontroller).gravitationalMovement = Vector3.zero;
new VerticalMoveModification(1f, 0.1f).Apply(enemy, player, this);
});*/
private NormalArea GenerateHeavySlash(string vfxName, AttackUnit attackUnit, Vector3 swingRotation)
{
NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren<NormalArea>();
slash.Initialize<NormalArea>(player, this, Fraction.Enemy)
.SetAttackSubmodule<NormalArea>(attackUnit)
.SetTimeSubmodule<NormalArea>(1f, 0.04f, 0.06f)
.SetHitSubmodule<NormalArea>()
.SetForceSubmodule<NormalArea>(3f, true);
slash.hitSm.AddHitSound("HeavyHit")
.AddHitEvent((enemy, hitPosition) =>
{
feedbackSc["HeavyHitFirst"].Play();
ApplyElectronicParalysis(enemy, attackUnit);
});
//Swing("HeavySwing", "HeavySwing", swingRotation);
return slash;
}
private NormalArea GenerateParrySlash(string vfxName, AttackUnit attackUnit, Vector3 swingForce)
{
NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren<NormalArea>();
slash.Initialize<NormalArea>(player, this, Fraction.Enemy)
.SetAttackSubmodule<NormalArea>(attackUnit)
.SetTimeSubmodule<NormalArea>(1f, 0.04f, 0.06f)
.SetHitSubmodule<NormalArea>()
.SetForceSubmodule<NormalArea>(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);
});*/
ApplyElectronicParalysis(enemy, attackUnit);
});
//Swing("HeavySwing", "HeavySwing", swingForce);
return slash;
}
private NormalArea GenerateDisruptionSlash(string vfxName, AttackUnit attackUnit, Vector3 swingForce)
{
NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren<NormalArea>();
slash.Initialize<NormalArea>(player, this, Fraction.Enemy)
.SetAttackSubmodule<NormalArea>(attackUnit)
.SetTimeSubmodule<NormalArea>(1f, 0.04f, 0.06f)
.SetHitSubmodule<NormalArea>()
.SetForceSubmodule<NormalArea>(3f, true);
slash.hitSm.AddHitSound("HeavyHit")
.AddHitEvent((enemy, hitPosition) =>
{
feedbackSc["DisruptHit"].Play();
ApplyElectronicParalysis(enemy, attackUnit);
});
//Swing("HeavySwing", "HeavySwing", swingForce);
return slash;
}
}
public partial class Polychrome
{
public BlockData equipBlockData;
public float perfectBlockedTimer;
string blockAnimName = "BlockL";
private void SetBlock(BlockData blockData = null)
{
blockData ??= this.blockData;
BlockSource blockSource = blockData.CreateBlockSource(player, this);
player.landMovementSc.canDash = false;
player.landMovementSc.canDodge = false;
blockSource.onNormalBlock = (attackArea) =>
{
blockAnimName = blockAnimName == "BlockL" ? "BlockR" : "BlockL";
animationSc.fullBodyFuncAnimSm.Play(blockAnimName, 1, 0);
player.selfTimeSm.ModifyTimeScale(0.06f, 0.4f);
attackArea.creator.selfTimeSm.ModifyTimeScale(0.06f, 0.4f);
if (blockAnimName == "BlockL")
{
feedbackSc["NormalBlockLeft"].Play();
}
else
{
feedbackSc["NormalBlockRight"].Play();
}
if (attackArea is NormalArea)
{
new ElectronicParalysis.Progress(2).Apply(attackArea.creator, player, this);
}
};
blockSource.onPerfectBlock = (attackArea) =>
{
blockAnimName = blockAnimName == "BlockL" ? "BlockR" : "BlockL";
animationSc.fullBodyFuncAnimSm.Play(blockAnimName, 1, 0);
player.selfTimeSm.ModifyTimeScale(0.12f, EaseType.InQuint, 0.2f);
attackArea.creator.selfTimeSm.ModifyTimeScale(0.12f, EaseType.InQuint, 0.2f);
if (blockAnimName == "BlockL")
{
feedbackSc["PerfectBlockLeft"].Play();
}
else
{
feedbackSc["PerfectBlockRight"].Play();
}
perfectBlockedTimer = 0.5f;
if (attackArea is NormalArea)
{
new ElectronicParalysis.Progress(10).Apply(attackArea.creator, player, this);
}
};
player.reactionSc.blockSm.ApplyBlock(blockSource);
}
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.landMovementSc.canDash = true;
player.landMovementSc.canDodge = true;
player.reactionSc.blockSm.RemoveBlock(blockData.blockName);
}
}
public partial class Polychrome
{
private void ApplyElectronicParalysis(CharacterBase enemy, AttackUnit attackUnit)
{
if (attackUnit.TryGetSubModule(out AttackUnit.ParameterSubmodule parameterSubmodule))
{
int progress = parameterSubmodule.GetParameter<int>("EP_Progress");
new ElectronicParalysis.Progress(progress).Apply(enemy, player, this);
}
}
}
}