391 lines
16 KiB
C#
391 lines
16 KiB
C#
using Cielonos.MainGame.Buffs;
|
|
using Cielonos.MainGame.Characters;
|
|
using Cielonos.UI;
|
|
using SLSFramework.General;
|
|
using SLSUtilities.FunctionalAnimation;
|
|
using UnityEngine;
|
|
|
|
namespace Cielonos.MainGame.Inventory.Collections
|
|
{
|
|
public partial class Polychrome : MainWeaponBase
|
|
{
|
|
public BlockData equipBlockData;
|
|
public float perfectBlockedTimer;
|
|
|
|
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();
|
|
RegisterFunctionsToAnimSc(
|
|
LightAttack0, LightAttack1, LightAttack2, LightAttack3,
|
|
TripleAttack_0, TripleAttack_1, TripleAttack_2,
|
|
DisruptAttack, HeavyAttack, RunAttack, ParryAttack, 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 OnPrimaryPress()
|
|
{
|
|
if (player.inputSc.IsHoldingSpecialA && functionSm["TripleAttack"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability())
|
|
{
|
|
comboSm.ResetCombo();
|
|
functionSm["TripleAttack"].Execute();
|
|
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5);
|
|
PlayTargetedAnimation("TripleAttack", target, 1f);
|
|
//player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward);
|
|
return;
|
|
}
|
|
|
|
if (player.landMovementSc.isSprinting && functionSm["LightAttack"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability())
|
|
{
|
|
comboSm.ResetCombo();
|
|
functionSm["LightAttack"].Execute();
|
|
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(8);
|
|
PlayTargetedAnimation("RunAttack", target, 1f);
|
|
//player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward);
|
|
return;
|
|
}
|
|
|
|
if (functionSm["LightAttack"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability())
|
|
{
|
|
comboSm.NextCombo("L");
|
|
functionSm["LightAttack"].Execute();
|
|
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5);
|
|
PlayTargetedAnimation("LightAttack" + comboSm.GetCurrentNodeName(), target, 1f);
|
|
//player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward);
|
|
}
|
|
}
|
|
|
|
public override void OnSecondaryPress()
|
|
{
|
|
if (player.landMovementSc.isJumping && functionSm["HeavyAttack"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability())
|
|
{
|
|
comboSm.ResetCombo();
|
|
functionSm["HeavyAttack"].Execute();
|
|
PlayTargetedAnimation("AirAttackStart0");
|
|
}
|
|
|
|
if (perfectBlockedTimer > 0f && functionSm["HeavyAttack"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability(DisruptionType.ForcedAction))
|
|
{
|
|
perfectBlockedTimer = 0f;
|
|
comboSm.ResetCombo();
|
|
functionSm["HeavyAttack"].Execute();
|
|
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5);
|
|
PlayTargetedAnimation("ParryAttack", target, 1f);
|
|
//player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward);
|
|
return;
|
|
}
|
|
|
|
if (player.inputSc.IsHoldingSpecialA &&
|
|
functionSm["DisruptAttack"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability())
|
|
{
|
|
comboSm.ResetCombo();
|
|
functionSm["DisruptAttack"].Execute();
|
|
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5);
|
|
PlayTargetedAnimation("DisruptAttack", target, 1f);
|
|
//player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward);
|
|
return;
|
|
}
|
|
|
|
if (functionSm["HeavyAttack"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability())
|
|
{
|
|
comboSm.ResetCombo();
|
|
functionSm["HeavyAttack"].Execute();
|
|
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5);
|
|
PlayTargetedAnimation("HeavyAttack", target, 1f);
|
|
//player.viewSc.cameraRotationSm.TriggerCameraRecenter(player.transform.forward);
|
|
}
|
|
}
|
|
|
|
public override void OnSpecialBPress()
|
|
{
|
|
if (functionSm["Block"].IsAvailable() && fullBodyFuncAnimSm.CheckPlayability(DisruptionType.ForcedAction))
|
|
{
|
|
comboSm.ResetCombo();
|
|
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(5);
|
|
PlayTargetedAnimation("Block", target, 2f, true, null, 1f, 0.1f, true);
|
|
SetBlock();
|
|
player.movementSc.canMove.Modify(false);
|
|
player.movementSc.canRotate.Modify(false);
|
|
}
|
|
}
|
|
|
|
public override void OnSpecialBRelease()
|
|
{
|
|
if (fullBodyFuncAnimSm.currentRuntimeFuncAnim is { animationName: "Block" })
|
|
{
|
|
fullBodyFuncAnimSm.Stop(DisruptionType.ForcedAction);
|
|
}
|
|
|
|
player.selfTimeSm.AddLocalTimer(0.1f, () => RemoveBlock());
|
|
player.movementSc.canMove.Modify(true);
|
|
player.movementSc.canRotate.Modify(true);
|
|
}
|
|
}
|
|
|
|
public partial class Polychrome
|
|
{
|
|
private void LightAttack0() => GenerateNormalSlash("LightAttack0", new Vector3(0.5f, 1f, 0));
|
|
private void LightAttack1() => GenerateNormalSlash("LightAttack1", new Vector3(-0.5f, -1f, 0));
|
|
private void LightAttack2() => GenerateNormalSlash("LightAttack2", new Vector3(0.8f, -1.2f, 0));
|
|
private void LightAttack3() => GenerateNormalSlash("LightAttack3", new Vector3(0.5f, 1.5f, 0));
|
|
private void TripleAttack_0() => GenerateFastSlash("TripleAttack_0", new Vector3(1f, 0.6f, 0));
|
|
private void TripleAttack_1() => GenerateFastSlash("TripleAttack_1", new Vector3(-1f, -0.6f, 0));
|
|
private void TripleAttack_2() => GenerateFastSlash("TripleAttack_2", new Vector3(0.6f, 1f, 0));
|
|
private void HeavyAttack() => GenerateHeavySlash("HeavyAttack", new Vector3(3, -2, -5));
|
|
private void RunAttack() => GenerateMoveSlash("RunAttack", new Vector3(1f, 0.6f, 0), player.transform.forward * 10f);
|
|
private void ParryAttack() => GenerateParrySlash("ParryAttack", new Vector3(5, 3, -8));
|
|
private void DisruptAttack() => GenerateDisruptSlash("DisruptAttack", new Vector3(0.6f, 2f, 0));
|
|
}
|
|
|
|
public partial class Polychrome
|
|
{
|
|
private NormalArea GenerateNormalSlash(string vfxName, Vector3 swingRotation)
|
|
{
|
|
NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren<NormalArea>();
|
|
|
|
slash.Initialize<NormalArea>(player, this, Fraction.Enemy)
|
|
.SetAttackSubmodule<NormalArea>(attackData["LightAttack"])
|
|
.SetTimeSubmodule<NormalArea>(1f, 0.04f)
|
|
.SetHitSubmodule<NormalArea>()
|
|
.SetForceSubmodule<NormalArea>(3f, true);
|
|
|
|
slash.hitSm
|
|
.AddHitSound("NormalHit")
|
|
.AddHitEvent((enemy, hitPosition) =>
|
|
{
|
|
feedbackSc["NormalHit"].Play();
|
|
new ElectronicDisturbance(2).Apply(enemy);
|
|
});
|
|
|
|
Swing("NormalSwing", "NormalSwing", swingRotation);
|
|
|
|
return slash;
|
|
}
|
|
|
|
private NormalArea GenerateFastSlash(string vfxName, Vector3 swingForce)
|
|
{
|
|
NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren<NormalArea>();
|
|
|
|
slash.Initialize<NormalArea>(player, this, Fraction.Enemy)
|
|
.SetAttackSubmodule<NormalArea>(attackData["LightAttack"])
|
|
.SetTimeSubmodule<NormalArea>(1f, 0.04f)
|
|
.SetHitSubmodule<NormalArea>()
|
|
.SetForceSubmodule<NormalArea>(3f, true);
|
|
|
|
|
|
string hitFeedbackName = vfxName != "TripleAttack_2" ? "FastHitFirsts" : "FastHitFinal";
|
|
|
|
slash.hitSm
|
|
.AddHitSound("NormalHit")
|
|
.AddHitEvent((enemy, hitPosition) =>
|
|
{
|
|
feedbackSc[hitFeedbackName].Play();
|
|
new ElectronicDisturbance(2).Apply(enemy);
|
|
|
|
if (enemy.statusSm.HasStatus(StatusType.Incapacitation))
|
|
{
|
|
slash.attackSm.attackValue.damage *= 5f;
|
|
}
|
|
});
|
|
|
|
Swing("NormalSwing", "NormalSwing", swingForce);
|
|
|
|
return slash;
|
|
}
|
|
|
|
private NormalArea GenerateHeavySlash(string vfxName, Vector3 swingRotation)
|
|
{
|
|
NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren<NormalArea>();
|
|
|
|
slash.Initialize<NormalArea>(player, this, Fraction.Enemy)
|
|
.SetAttackSubmodule<NormalArea>(attackData["HeavyAttack"])
|
|
.SetTimeSubmodule<NormalArea>(1f, 0.04f, 0.2f)
|
|
.SetHitSubmodule<NormalArea>(0.04f, 4)
|
|
.SetForceSubmodule<NormalArea>(3f, true);
|
|
|
|
slash.hitSm
|
|
.AddHitSound("HeavyHit")
|
|
.AddHitEvent((enemy, hitPosition) =>
|
|
{
|
|
feedbackSc["HeavyHitFirst"].Play();
|
|
new ElectronicDisturbance(25).Apply(enemy);
|
|
}, 0)
|
|
.AddHitEvent((enemy, hitPosition) =>
|
|
{
|
|
feedbackSc["HeavyHitFollows"].Play();
|
|
new ElectronicDisturbance(25).Apply(enemy);
|
|
}, 1, 2, 3);
|
|
|
|
Swing("HeavySwing", "HeavySwing", swingRotation);
|
|
|
|
return slash;
|
|
}
|
|
|
|
private NormalArea GenerateParrySlash(string vfxName, Vector3 swingForce)
|
|
{
|
|
NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren<NormalArea>();
|
|
|
|
slash.Initialize<NormalArea>(player, this, Fraction.Enemy)
|
|
.SetAttackSubmodule<NormalArea>(attackData["ParryAttack"])
|
|
.SetTimeSubmodule<NormalArea>(1f, 0.04f)
|
|
.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);
|
|
});
|
|
new ElectronicDisturbance(5).Apply(enemy);
|
|
});
|
|
|
|
Swing("HeavySwing", "HeavySwing", swingForce);
|
|
|
|
return slash;
|
|
}
|
|
|
|
private NormalArea GenerateDisruptSlash(string vfxName, Vector3 swingForce)
|
|
{
|
|
NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren<NormalArea>();
|
|
|
|
slash.Initialize<NormalArea>(player, this, Fraction.Enemy)
|
|
.SetAttackSubmodule<NormalArea>(attackData["DisruptAttack"])
|
|
.SetTimeSubmodule<NormalArea>(1f, 0.04f)
|
|
.SetHitSubmodule<NormalArea>()
|
|
.SetForceSubmodule<NormalArea>(3f, true);
|
|
|
|
slash.hitSm
|
|
.AddHitSound("HeavyHit")
|
|
.AddHitEvent((enemy, hitPosition) =>
|
|
{
|
|
feedbackSc["DisruptHit"].Play();
|
|
new ElectronicDisturbance(5).Apply(enemy);
|
|
});
|
|
|
|
Swing("HeavySwing", "HeavySwing", swingForce);
|
|
|
|
return slash;
|
|
}
|
|
|
|
private void GenerateMoveSlash(string vfxName, Vector3 swingForce, Vector3 moveVelocity)
|
|
{
|
|
NormalArea slash = vfxData.SpawnVFX(vfxName).GetComponentInChildren<NormalArea>();
|
|
|
|
slash.Initialize<NormalArea>(player, this, Fraction.Enemy)
|
|
.SetAttackSubmodule<NormalArea>(attackData["LightAttack"])
|
|
.SetTimeSubmodule<NormalArea>(1f, 0.04f)
|
|
.SetHitSubmodule<NormalArea>()
|
|
.SetForceSubmodule<NormalArea>(3f, true)
|
|
.SetLinearDirectionMoveModule<NormalArea>(moveVelocity.normalized, moveVelocity.magnitude, -20f, false);
|
|
|
|
slash.hitSm
|
|
.AddHitSound("NormalHit")
|
|
.AddHitEvent((enemy, hitPosition) =>
|
|
{
|
|
feedbackSc["NormalHit"].Play();
|
|
new ElectronicDisturbance(2).Apply(enemy);
|
|
});
|
|
|
|
Swing("NormalSwing", "NormalSwing", swingForce);
|
|
}
|
|
|
|
string parryAnimName = "ParryL";
|
|
|
|
private void SetBlock(BlockData blockData = null)
|
|
{
|
|
blockData ??= this.blockData;
|
|
BlockSource blockSource = blockData.CreateBlockSource(player, this);
|
|
blockSource.onNormalBlock = (attackArea) =>
|
|
{
|
|
parryAnimName = parryAnimName == "ParryL" ? "ParryR" : "ParryL";
|
|
animationSc.fullBodyFuncAnimSm.Play(parryAnimName, 1, 0);
|
|
player.selfTimeSm.ModifyTimeScale(0.06f, 0.4f);
|
|
attackArea.creator.selfTimeSm.ModifyTimeScale(0.06f, 0.4f);
|
|
|
|
if (parryAnimName == "ParryL")
|
|
{
|
|
feedbackSc["NormalBlockLeft"].Play();
|
|
}
|
|
else
|
|
{
|
|
feedbackSc["NormalBlockRight"].Play();
|
|
}
|
|
|
|
if (attackArea is NormalArea)
|
|
{
|
|
new ElectronicDisturbance(2).Apply(attackArea.creator);
|
|
}
|
|
};
|
|
blockSource.onPerfectBlock = (attackArea) =>
|
|
{
|
|
parryAnimName = parryAnimName == "ParryL" ? "ParryR" : "ParryL";
|
|
animationSc.fullBodyFuncAnimSm.Play(parryAnimName, 1, 0);
|
|
player.selfTimeSm.ModifyTimeScale(0.12f, EaseType.InQuint, 0.2f);
|
|
attackArea.creator.selfTimeSm.ModifyTimeScale(0.12f, EaseType.InQuint, 0.2f);
|
|
|
|
if (parryAnimName == "ParryL")
|
|
{
|
|
feedbackSc["PerfectBlockLeft"].Play();
|
|
}
|
|
else
|
|
{
|
|
feedbackSc["PerfectBlockRight"].Play();
|
|
}
|
|
|
|
perfectBlockedTimer = 0.5f;
|
|
if (attackArea is NormalArea)
|
|
{
|
|
new ElectronicDisturbance(10).Apply(attackArea.creator);
|
|
}
|
|
|
|
//Debug.Break();
|
|
};
|
|
player.reactionSc.blockSm.ApplyBlock(blockSource);
|
|
//blockDisposable?.Dispose();
|
|
}
|
|
|
|
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.reactionSc.blockSm.RemoveBlock(blockData.blockName);
|
|
}
|
|
}
|
|
} |