225 lines
9.1 KiB
C#
225 lines
9.1 KiB
C#
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using static CultMath.math;
|
|
using float4 = CultMath.float4;
|
|
|
|
public abstract class Weapon : Behavior, IActivatedBehavior
|
|
{
|
|
private readonly PerformanceStat _damage;
|
|
private readonly PerformanceStat _penetration;
|
|
private readonly PerformanceStat _damageSpread;
|
|
private readonly PerformanceStat _minRange;
|
|
private readonly PerformanceStat _range;
|
|
private readonly PerformanceStat _energy;
|
|
private readonly PerformanceStat _heat;
|
|
private readonly PerformanceStat _visibility;
|
|
private readonly PerformanceStat _spread;
|
|
private readonly PerformanceStat _velocity;
|
|
private PerformanceStat _guidedProjectileThrust;
|
|
private PerformanceStat _guidedProjectileVelocity;
|
|
|
|
public abstract float DamagePerSecond { get; }
|
|
public abstract float RangeDamagePerSecond(float range);
|
|
public abstract int Ammo { get; }
|
|
public DamageType DamageType { get; }
|
|
public string EffectPrefab { get; }
|
|
public string AmmoItemKey { get; }
|
|
public int MagazineSize { get; }
|
|
protected float ReloadTime { get; }
|
|
protected BezierCurve DamageCurve { get; }
|
|
public bool UsesAmmo => !string.IsNullOrWhiteSpace(AmmoItemKey);
|
|
public GuidedProjectileTargetMode GuidedProjectileTargeting { get; private set; }
|
|
public bool HasGuidedProjectileProfile => GuidedProjectileTargeting != GuidedProjectileTargetMode.None;
|
|
public float4[] GuidedProjectileGuidanceCurve { get; private set; }
|
|
public float4[] GuidedProjectileLiftCurve { get; private set; }
|
|
public float4[] GuidedProjectileThrustCurve { get; private set; }
|
|
public float GuidedProjectileDodgeFrequency { get; private set; }
|
|
|
|
public float Damage { get; protected set; }
|
|
public float Penetration { get; protected set; }
|
|
public float DamageSpread { get; protected set; }
|
|
public float MinRange { get; protected set; }
|
|
public float Range { get; protected set; }
|
|
public float Energy { get; protected set; }
|
|
public float Heat { get; protected set; }
|
|
public float Visibility { get; protected set; }
|
|
public float Spread { get; protected set; }
|
|
public float Velocity { get; protected set; }
|
|
|
|
protected bool _firing;
|
|
|
|
public bool Firing
|
|
{
|
|
get => _firing;
|
|
}
|
|
|
|
public Weapon(RuntimeBehaviorDefinition definition, EquippedItem item) : base(definition, item)
|
|
{
|
|
_damage = definition.PerformanceStat(2, new PerformanceStat());
|
|
_penetration = definition.PerformanceStat(3, new PerformanceStat());
|
|
_damageSpread = definition.PerformanceStat(4, new PerformanceStat());
|
|
_minRange = definition.PerformanceStat(5, new PerformanceStat());
|
|
_range = definition.PerformanceStat(6, new PerformanceStat());
|
|
_energy = definition.PerformanceStat(9, new PerformanceStat());
|
|
_heat = definition.PerformanceStat(10, new PerformanceStat());
|
|
_visibility = definition.PerformanceStat(11, new PerformanceStat());
|
|
_spread = definition.PerformanceStat(15, new PerformanceStat());
|
|
_velocity = definition.PerformanceStat(16, new PerformanceStat());
|
|
DamageType = definition.Enum(1, default(DamageType));
|
|
DamageCurve = definition.BezierCurve(7, null);
|
|
EffectPrefab = definition.String(8);
|
|
AmmoItemKey = definition.ItemKey(12);
|
|
MagazineSize = definition.Int(13);
|
|
ReloadTime = definition.Float(14, 1);
|
|
RegisterWeaponStats();
|
|
InitializeGuidedProjectileProfile(definition);
|
|
}
|
|
|
|
public Weapon(RuntimeBehaviorDefinition definition, ConsumableItemEffect item) : base(definition, item)
|
|
{
|
|
_damage = definition.PerformanceStat(2, new PerformanceStat());
|
|
_penetration = definition.PerformanceStat(3, new PerformanceStat());
|
|
_damageSpread = definition.PerformanceStat(4, new PerformanceStat());
|
|
_minRange = definition.PerformanceStat(5, new PerformanceStat());
|
|
_range = definition.PerformanceStat(6, new PerformanceStat());
|
|
_energy = definition.PerformanceStat(9, new PerformanceStat());
|
|
_heat = definition.PerformanceStat(10, new PerformanceStat());
|
|
_visibility = definition.PerformanceStat(11, new PerformanceStat());
|
|
_spread = definition.PerformanceStat(15, new PerformanceStat());
|
|
_velocity = definition.PerformanceStat(16, new PerformanceStat());
|
|
DamageType = definition.Enum(1, default(DamageType));
|
|
DamageCurve = definition.BezierCurve(7, null);
|
|
EffectPrefab = definition.String(8);
|
|
AmmoItemKey = definition.ItemKey(12);
|
|
MagazineSize = definition.Int(13);
|
|
ReloadTime = definition.Float(14, 1);
|
|
RegisterWeaponStats();
|
|
InitializeGuidedProjectileProfile(definition);
|
|
}
|
|
|
|
private void RegisterWeaponStats()
|
|
{
|
|
RegisterPerformanceStat(nameof(Damage), _damage);
|
|
RegisterPerformanceStat(nameof(Penetration), _penetration);
|
|
RegisterPerformanceStat(nameof(DamageSpread), _damageSpread);
|
|
RegisterPerformanceStat(nameof(MinRange), _minRange);
|
|
RegisterPerformanceStat(nameof(Range), _range);
|
|
RegisterPerformanceStat(nameof(Energy), _energy);
|
|
RegisterPerformanceStat(nameof(Heat), _heat);
|
|
RegisterPerformanceStat(nameof(Visibility), _visibility);
|
|
RegisterPerformanceStat(nameof(Spread), _spread);
|
|
RegisterPerformanceStat(nameof(Velocity), _velocity);
|
|
}
|
|
|
|
private void InitializeGuidedProjectileProfile(RuntimeBehaviorDefinition definition)
|
|
{
|
|
if (string.Equals(definition.Kind, "Launcher"))
|
|
{
|
|
GuidedProjectileTargeting = GuidedProjectileTargetMode.TargetEntity;
|
|
GuidedProjectileGuidanceCurve = definition.Float4Array(26, null);
|
|
GuidedProjectileThrustCurve = definition.Float4Array(27, null);
|
|
GuidedProjectileLiftCurve = definition.Float4Array(28, null);
|
|
_guidedProjectileThrust = definition.PerformanceStat(29, new PerformanceStat());
|
|
GuidedProjectileDodgeFrequency = definition.Float(30);
|
|
_guidedProjectileVelocity = definition.PerformanceStat(31, new PerformanceStat());
|
|
}
|
|
else if (string.Equals(definition.Kind, "GuidedWeapon"))
|
|
{
|
|
GuidedProjectileTargeting = GuidedProjectileTargetMode.LookDirection;
|
|
GuidedProjectileGuidanceCurve = definition.Float4Array(21, null);
|
|
GuidedProjectileThrustCurve = definition.Float4Array(22, null);
|
|
GuidedProjectileLiftCurve = definition.Float4Array(23, null);
|
|
_guidedProjectileThrust = definition.PerformanceStat(24, new PerformanceStat());
|
|
GuidedProjectileDodgeFrequency = definition.Float(25);
|
|
_guidedProjectileVelocity = definition.PerformanceStat(26, new PerformanceStat());
|
|
}
|
|
|
|
RegisterPerformanceStat("Thrust", _guidedProjectileThrust);
|
|
RegisterPerformanceStat("MissileVelocity", _guidedProjectileVelocity);
|
|
}
|
|
|
|
protected virtual void UpdateStats()
|
|
{
|
|
Damage = Evaluate(_damage);
|
|
Penetration = Evaluate(_penetration);
|
|
DamageSpread = Evaluate(_damageSpread);
|
|
MinRange = Evaluate(_minRange);
|
|
Range = Evaluate(_range);
|
|
Energy = Evaluate(_energy);
|
|
Heat = Evaluate(_heat);
|
|
Visibility = Evaluate(_visibility);
|
|
Spread = Evaluate(_spread);
|
|
Velocity = Evaluate(_velocity);
|
|
}
|
|
|
|
protected float EvaluateRangeDamage(float range)
|
|
{
|
|
var normalizedRange = saturate(unlerp(MinRange, Range, range));
|
|
return Evaluate(_damage, StatConditionMask.Range, normalizedRange) *
|
|
DamageCurve.Evaluate(normalizedRange);
|
|
}
|
|
|
|
protected float EvaluateRangeDamage(float range, StatConditionMask condition, float value)
|
|
{
|
|
var normalizedRange = saturate(unlerp(MinRange, Range, range));
|
|
return Evaluate(_damage, StatConditionMask.Range, normalizedRange, condition, value) *
|
|
DamageCurve.Evaluate(normalizedRange);
|
|
}
|
|
|
|
protected float EvaluateDamage(StatConditionMask condition, float value)
|
|
{
|
|
return Evaluate(_damage, condition, value);
|
|
}
|
|
|
|
public override bool Execute(float dt)
|
|
{
|
|
UpdateStats();
|
|
return true;
|
|
}
|
|
|
|
public virtual void Activate()
|
|
{
|
|
_firing = true;
|
|
}
|
|
|
|
public virtual void Deactivate()
|
|
{
|
|
_firing = false;
|
|
}
|
|
|
|
public virtual void RestoreRuntimeState(bool firing)
|
|
{
|
|
_firing = firing;
|
|
}
|
|
|
|
public float EvaluateRange()
|
|
{
|
|
return Evaluate(_range);
|
|
}
|
|
|
|
public float EvaluateVelocity()
|
|
{
|
|
return Evaluate(_velocity);
|
|
}
|
|
|
|
public float EvaluateGuidedProjectileThrust()
|
|
{
|
|
return _guidedProjectileThrust == null ? 0 : Evaluate(_guidedProjectileThrust);
|
|
}
|
|
|
|
public float EvaluateGuidedProjectileVelocity()
|
|
{
|
|
return _guidedProjectileVelocity == null ? 0 : Evaluate(_guidedProjectileVelocity);
|
|
}
|
|
}
|
|
|
|
public enum GuidedProjectileTargetMode
|
|
{
|
|
None,
|
|
TargetEntity,
|
|
LookDirection
|
|
}
|