Files
Cielonos/Assets/Scripts/MainGame/Items/SupportEquipments/ElectronicNeutralizingBullet.cs
SoulliesOfficial 39b43680a9 爆更
2026-07-18 03:16:20 -04:00

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);
}
}
}