Aetheria/Assets/Scripts/ServerShared/Behaviors/ChargedWeapon.cs
2026-06-21 09:37:54 +01:00

196 lines
6.9 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using static CultMath.math;
public class ChargedWeapon : InstantWeapon
{
private readonly PerformanceStat _chargeTime;
private readonly PerformanceStat _chargeEnergy;
private readonly PerformanceStat _chargeHeat;
private readonly bool _canFireEarly;
private readonly float _failureCharge;
private readonly float _failureDamage;
private readonly float _chargeFiringDamageMultiplier;
private readonly float _chargeFiringSpreadMultiplier;
private readonly float _chargeFiringBurstCountMultiplier;
private readonly float _chargeFiringVisibilityMultiplier;
private readonly float _chargeFiringVelocityMultiplier;
private readonly float _chargeFiringHeatMultiplier;
private bool _charging;
private bool _charged;
private float _charge;
private float _progress;
public float ChargeTime { get; protected set; }
public float ChargeEnergy { get; protected set; }
public float ChargeHeat { get; protected set; }
public override float DamagePerSecond => Damage * _chargeFiringDamageMultiplier / (Cooldown + ChargeTime);
public override float RangeDamagePerSecond(float range)
{
return EvaluateRangeDamage(range, StatConditionMask.Charge, saturate(_charge)) *
lerp(1, _chargeFiringDamageMultiplier, saturate(_charge)) *
_chargeFiringDamageMultiplier /
(Cooldown + ChargeTime);
}
public event Action OnStartCharging;
public event Action OnStopCharging;
public event Action OnCharged;
public event Action OnFailed;
public override void ResetEvents()
{
base.ResetEvents();
OnStartCharging = null;
OnStopCharging = null;
OnCharged = null;
OnFailed = null;
}
public override float Progress => saturate(_charging ? _charge : _cooldown);
public float Charge
{
get => _charge;
}
public bool Charging => _charging;
public bool Charged => _charged;
public ChargedWeapon(RuntimeBehaviorDefinition definition, EquippedItem item) : base(definition, item)
{
_chargeTime = definition.PerformanceStat(21, new PerformanceStat());
_chargeEnergy = definition.PerformanceStat(22, new PerformanceStat());
_chargeHeat = definition.PerformanceStat(23, new PerformanceStat());
_canFireEarly = definition.Bool(24);
_failureCharge = definition.Float(25);
_failureDamage = definition.Float(26, 1);
_chargeFiringDamageMultiplier = definition.Float(27, 1);
_chargeFiringSpreadMultiplier = definition.Float(28, 1);
_chargeFiringBurstCountMultiplier = definition.Float(29, 1);
_chargeFiringVisibilityMultiplier = definition.Float(30, 1);
_chargeFiringVelocityMultiplier = definition.Float(31, 1);
_chargeFiringHeatMultiplier = definition.Float(32, 1);
RegisterChargedWeaponStats();
}
public ChargedWeapon(RuntimeBehaviorDefinition definition, ConsumableItemEffect item) : base(definition, item)
{
_chargeTime = definition.PerformanceStat(21, new PerformanceStat());
_chargeEnergy = definition.PerformanceStat(22, new PerformanceStat());
_chargeHeat = definition.PerformanceStat(23, new PerformanceStat());
_canFireEarly = definition.Bool(24);
_failureCharge = definition.Float(25);
_failureDamage = definition.Float(26, 1);
_chargeFiringDamageMultiplier = definition.Float(27, 1);
_chargeFiringSpreadMultiplier = definition.Float(28, 1);
_chargeFiringBurstCountMultiplier = definition.Float(29, 1);
_chargeFiringVisibilityMultiplier = definition.Float(30, 1);
_chargeFiringVelocityMultiplier = definition.Float(31, 1);
_chargeFiringHeatMultiplier = definition.Float(32, 1);
RegisterChargedWeaponStats();
}
private void RegisterChargedWeaponStats()
{
RegisterPerformanceStat(nameof(ChargeTime), _chargeTime);
RegisterPerformanceStat(nameof(ChargeEnergy), _chargeEnergy);
RegisterPerformanceStat(nameof(ChargeHeat), _chargeHeat);
}
protected override void UpdateStats()
{
base.UpdateStats();
ChargeTime = Evaluate(_chargeTime);
ChargeEnergy = Evaluate(_chargeEnergy);
ChargeHeat = Evaluate(_chargeHeat);
Damage = EvaluateDamage(StatConditionMask.Charge, saturate(_charge)) *
lerp(1, _chargeFiringDamageMultiplier, saturate(_charge));
Heat *= lerp(1, _chargeFiringHeatMultiplier, saturate(_charge));
Spread *= lerp(1, _chargeFiringSpreadMultiplier, saturate(_charge));
BurstCount *= lerp(1, _chargeFiringBurstCountMultiplier, saturate(_charge));
Visibility *= lerp(1, _chargeFiringVisibilityMultiplier, saturate(_charge));
Velocity *= lerp(1, _chargeFiringVelocityMultiplier, saturate(_charge));
}
public override bool Execute(float dt)
{
if (_charging)
{
_charge += dt / ChargeTime;
Item.SetAudioParameter(SpecialAudioParameter.ChargeLevel, saturate(_charge));
if (!_charged)
{
AddHeat(ChargeHeat * (dt / ChargeTime));
if(_charge > 1)
{
_charged = true;
OnCharged?.Invoke();
}
}
if (_failureCharge > 1 && _charge > _failureCharge)
{
_charging = false;
_cooldown = 1;
_coolingDown = true;
_charge = 0;
OnFailed?.Invoke();
Item.FireAudioEvent(ChargedWeaponAudioEvent.Fail);
CauseDamage(_failureDamage);
}
}
return base.Execute(dt);
}
public override void Activate()
{
if(!_charging && !_coolingDown)
{
OnStartCharging?.Invoke();
Item.FireAudioEvent(ChargedWeaponAudioEvent.Start);
_charging = true;
_charged = false;
}
}
public override void Deactivate()
{
if (_charging)
{
if (_canFireEarly || _charge > 1)
{
Trigger();
_charge = 0;
}
OnStopCharging?.Invoke();
Item.FireAudioEvent(ChargedWeaponAudioEvent.Stop);
_charging = false;
}
}
public void RestoreRuntimeState(
bool firing,
int ammo,
int burstRemaining,
float burstTimer,
float burstInterval,
float cooldownProgress,
bool coolingDown,
bool charging,
bool charged,
float charge)
{
base.RestoreRuntimeState(
firing,
ammo,
burstRemaining,
burstTimer,
burstInterval,
cooldownProgress,
coolingDown);
_charging = charging;
_charged = charged;
_charge = charge;
}
}