120 lines
5.0 KiB
C#
120 lines
5.0 KiB
C#
using System.Collections.Generic;
|
|
using Cielonos.MainGame.Buffs;
|
|
using Cielonos.MainGame.Buffs.Character;
|
|
using Cielonos.MainGame.Characters;
|
|
using Cielonos.MainGame.UI;
|
|
using DamageNumbersPro;
|
|
using SLSUtilities.FunctionalAnimation;
|
|
using SLSUtilities.WwiseAssistance;
|
|
using UnityEngine;
|
|
|
|
namespace Cielonos.MainGame.Inventory.Collections
|
|
{
|
|
public class ElectronicNeutralizingBullet : SupportEquipmentBase
|
|
{
|
|
private const string ProjectileVfxName = "Projectile";
|
|
private const string DamagePerSecondAttribute = "DamagePerSecond";
|
|
|
|
private Transform _muzzle;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
if (activeAttributeData != null)
|
|
{
|
|
activeAttributeSm = new AttributeSubmodule(this, activeAttributeData);
|
|
}
|
|
}
|
|
|
|
public override void OnObtained()
|
|
{
|
|
base.OnObtained();
|
|
_muzzle = player.bodyPartsSc.AuxiliaryDrone.center;
|
|
}
|
|
|
|
public override void OnPress(List<PlayerInputModifierType> modifiers = default)
|
|
{
|
|
if (!functionSm.mainFunction.IsAvailable())
|
|
{
|
|
PlayerCanvas.SupportEquipmentsUIArea[this].CanNotUseOutlineAnimation();
|
|
return;
|
|
}
|
|
|
|
CharacterBase target = CombatManager.EnemySm.Query(50f)
|
|
.Where(enemy => enemy.buffSm.HasBuff<ElectronicParalysis>())
|
|
.LockonFirst();
|
|
target ??= CombatManager.EnemySm.Query(50f).LockonFirst();
|
|
|
|
GenerateProjectile(target, 50f, _muzzle);
|
|
functionSm.mainFunction.Execute();
|
|
PlayerCanvas.SupportEquipmentsUIArea[this].UseOutlineAnimation();
|
|
}
|
|
|
|
private void GenerateProjectile(CharacterBase target, float speed, Transform muzzle = null)
|
|
{
|
|
muzzle ??= _muzzle;
|
|
vfxData.SpawnMuzzleVFX(ProjectileVfxName, player, muzzle);
|
|
Projectile projectile = vfxData.SpawnVFX(ProjectileVfxName, player, muzzle)
|
|
.GetComponentInChildren<Projectile>();
|
|
|
|
Vector3 direction = muzzle.transform.forward;
|
|
if (target != null)
|
|
{
|
|
direction = (target.CenterPoint.position - projectile.transform.position).normalized;
|
|
}
|
|
|
|
projectile.Initialize(player, this, false, 1, Fraction.Enemy)
|
|
.SetAttackSubmodule<Projectile>(attackData[ProjectileVfxName])
|
|
.SetTimeSubmodule<Projectile>(10f)
|
|
.SetHitSubmodule<Projectile>()
|
|
.SetAdaptiveTraceMoveSubmodule<Projectile>(target, speed, 10f, 60f, 30f, direction)
|
|
.SetRaycastSubmodule<Projectile>(default, 0.25f, 0.5f);
|
|
projectile.SetImpulseSubmodule().WithDynamicForce(20f);
|
|
projectile.hitSm.AddHitSound(AK.EVENTS.ELECTRONICNEUTRALIZINGBULLET_NORMALHIT);
|
|
projectile.eventSm.onHit.Add((hitTarget, hitPosition) =>
|
|
{
|
|
projectile.hitSm.isAutoPlayHitSound = false;
|
|
NeutralizeElectronicParalysis(hitTarget, hitPosition);
|
|
});
|
|
AudioManager.Post(AK.EVENTS.ELECTRONICNEUTRALIZINGBULLET_SHOOT, muzzle.gameObject);
|
|
}
|
|
|
|
private void NeutralizeElectronicParalysis(CharacterBase target, Vector3 hitPosition)
|
|
{
|
|
if (!target.buffSm.TryGetBuff(out ElectronicParalysis paralysis))
|
|
{
|
|
feedbackSc.PlayFeedback("NormalHit");
|
|
AudioManager.Post(AK.EVENTS.ELECTRONICNEUTRALIZINGBULLET_NORMALHIT, hitPosition);
|
|
return;
|
|
}
|
|
|
|
var longestStack = paralysis.independentStackSubmodule.LongestUnit;
|
|
if (longestStack == null) return;
|
|
|
|
BuffContext removeContext = new BuffContext();
|
|
removeContext.Set(Incapacitation.SkipRiseAnimationKey, true);
|
|
paralysis.Remove(removeContext);
|
|
|
|
float remainingTime = Mathf.Max(0f, longestStack.remainingTime);
|
|
float damage = remainingTime * (passiveAttributeSm?.GetItemAttribute(DamagePerSecondAttribute) ?? 0f);
|
|
|
|
if (damage > 0f)
|
|
{
|
|
float ratio = damage / 1000f;
|
|
|
|
Attack.Context context = new Attack.Context(player, target, nameof(ElectronicNeutralizingBullet), hitPosition);
|
|
Attack.Value value = new Attack.Value(ratio >= 1, damage, 0f, Attack.Type.Energy, DisruptionType.Must, Breakthrough.Type.Forced);
|
|
Attack.Result result = new Attack.Result(context, value);
|
|
target.GetHit(Breakthrough.Type.Forced, out _, DisruptionType.Must);
|
|
target.TakeDepletion(result);
|
|
target.TakeDamage(result, out DamageNumber damageNumber);
|
|
damageNumber.SetScale(ratio);
|
|
damageNumber.SetPosition(hitPosition + Vector3.up);
|
|
}
|
|
|
|
feedbackSc.PlayFeedback("EffectiveHit");
|
|
AudioManager.Post(AK.EVENTS.ELECTRONICNEUTRALIZINGBULLET_EFFECTIVEHIT, hitPosition);
|
|
}
|
|
}
|
|
}
|