2022-06-01 19:59:58 +10:00
|
|
|
using Content.Server.Power.Components;
|
2022-09-09 09:08:14 +10:00
|
|
|
using Content.Shared.Damage;
|
2023-08-07 12:09:35 +03:00
|
|
|
using Content.Shared.Damage.Events;
|
2023-04-28 02:10:32 +06:00
|
|
|
using Content.Shared.Interaction.Events;
|
2022-09-09 09:08:14 +10:00
|
|
|
using Content.Shared.Weapons.Ranged;
|
2022-06-01 19:59:58 +10:00
|
|
|
using Content.Shared.Weapons.Ranged.Components;
|
2024-01-11 09:44:36 +03:00
|
|
|
using Robust.Server.Audio;
|
2022-06-01 19:59:58 +10:00
|
|
|
|
2022-09-29 15:51:59 +10:00
|
|
|
namespace Content.Server.Weapons.Ranged.Systems;
|
2022-06-01 19:59:58 +10:00
|
|
|
|
|
|
|
|
public sealed partial class GunSystem
|
|
|
|
|
{
|
2024-01-11 09:44:36 +03:00
|
|
|
[Dependency] private readonly AudioSystem _audio = default!;
|
2023-04-28 02:10:32 +06:00
|
|
|
|
2022-06-01 19:59:58 +10:00
|
|
|
protected override void InitializeBattery()
|
|
|
|
|
{
|
|
|
|
|
base.InitializeBattery();
|
|
|
|
|
|
|
|
|
|
// Hitscan
|
|
|
|
|
SubscribeLocalEvent<HitscanBatteryAmmoProviderComponent, ComponentStartup>(OnBatteryStartup);
|
|
|
|
|
SubscribeLocalEvent<HitscanBatteryAmmoProviderComponent, ChargeChangedEvent>(OnBatteryChargeChange);
|
2023-08-07 12:09:35 +03:00
|
|
|
SubscribeLocalEvent<HitscanBatteryAmmoProviderComponent, DamageExamineEvent>(OnBatteryDamageExamine);
|
2022-06-01 19:59:58 +10:00
|
|
|
|
|
|
|
|
// Projectile
|
|
|
|
|
SubscribeLocalEvent<ProjectileBatteryAmmoProviderComponent, ComponentStartup>(OnBatteryStartup);
|
|
|
|
|
SubscribeLocalEvent<ProjectileBatteryAmmoProviderComponent, ChargeChangedEvent>(OnBatteryChargeChange);
|
2023-08-07 12:09:35 +03:00
|
|
|
SubscribeLocalEvent<ProjectileBatteryAmmoProviderComponent, DamageExamineEvent>(OnBatteryDamageExamine);
|
2023-04-28 02:10:32 +06:00
|
|
|
|
|
|
|
|
//TwoModeEnergy
|
|
|
|
|
SubscribeLocalEvent<TwoModeEnergyAmmoProviderComponent, ComponentStartup>(OnBatteryStartup);
|
|
|
|
|
SubscribeLocalEvent<TwoModeEnergyAmmoProviderComponent, ChargeChangedEvent>(OnBatteryChargeChange);
|
2024-01-11 09:44:36 +03:00
|
|
|
SubscribeLocalEvent<TwoModeEnergyAmmoProviderComponent, DamageExamineEvent>(OnBatteryDamageExamine);
|
2023-04-28 02:10:32 +06:00
|
|
|
SubscribeLocalEvent<TwoModeEnergyAmmoProviderComponent, UseInHandEvent>(OnBatteryModeChange);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnBatteryModeChange(EntityUid uid, TwoModeEnergyAmmoProviderComponent component, UseInHandEvent args)
|
|
|
|
|
{
|
|
|
|
|
if (!TryComp<GunComponent>(uid, out var gun))
|
|
|
|
|
return;
|
|
|
|
|
|
2024-01-24 12:58:57 +07:00
|
|
|
switch (component.CurrentMode)
|
2023-04-28 02:10:32 +06:00
|
|
|
{
|
2024-01-24 12:58:57 +07:00
|
|
|
case EnergyModes.Stun:
|
|
|
|
|
component.InStun = false;
|
|
|
|
|
component.CurrentMode = EnergyModes.Laser;
|
|
|
|
|
component.FireCost = component.LaserFireCost;
|
|
|
|
|
gun.SoundGunshot = component.LaserSound;
|
|
|
|
|
gun.ProjectileSpeed = component.LaserProjectileSpeed;
|
|
|
|
|
_audio.PlayPvs(component.ToggleSound, args.User);
|
|
|
|
|
break;
|
|
|
|
|
case EnergyModes.Laser:
|
|
|
|
|
component.InStun = true;
|
|
|
|
|
component.CurrentMode = EnergyModes.Stun;
|
|
|
|
|
component.FireCost = component.StunFireCost;
|
|
|
|
|
gun.SoundGunshot = component.StunSound;
|
|
|
|
|
gun.ProjectileSpeed = component.StunProjectileSpeed;
|
|
|
|
|
_audio.PlayPvs(component.ToggleSound, args.User);
|
|
|
|
|
break;
|
2023-04-28 02:10:32 +06:00
|
|
|
}
|
2024-01-24 12:58:57 +07:00
|
|
|
|
2023-04-28 02:10:32 +06:00
|
|
|
UpdateShots(uid, component);
|
|
|
|
|
UpdateTwoModeAppearance(uid, component);
|
|
|
|
|
UpdateBatteryAppearance(uid, component);
|
|
|
|
|
UpdateAmmoCount(uid);
|
2022-06-01 19:59:58 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnBatteryStartup(EntityUid uid, BatteryAmmoProviderComponent component, ComponentStartup args)
|
|
|
|
|
{
|
|
|
|
|
UpdateShots(uid, component);
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-24 12:58:57 +07:00
|
|
|
private void OnBatteryChargeChange(
|
|
|
|
|
EntityUid uid,
|
|
|
|
|
BatteryAmmoProviderComponent component,
|
|
|
|
|
ref ChargeChangedEvent args)
|
2022-06-01 19:59:58 +10:00
|
|
|
{
|
2023-04-19 22:10:08 +12:00
|
|
|
UpdateShots(uid, component, args.Charge, args.MaxCharge);
|
2022-06-01 19:59:58 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UpdateShots(EntityUid uid, BatteryAmmoProviderComponent component)
|
|
|
|
|
{
|
2023-02-26 18:48:57 +11:00
|
|
|
if (!TryComp<BatteryComponent>(uid, out var battery))
|
|
|
|
|
return;
|
|
|
|
|
|
2024-03-06 00:34:50 -05:00
|
|
|
UpdateShots(uid, component, battery.CurrentCharge, battery.MaxCharge);
|
2022-06-01 19:59:58 +10:00
|
|
|
}
|
|
|
|
|
|
2023-04-19 22:10:08 +12:00
|
|
|
private void UpdateShots(EntityUid uid, BatteryAmmoProviderComponent component, float charge, float maxCharge)
|
2022-06-01 19:59:58 +10:00
|
|
|
{
|
2023-04-19 22:10:08 +12:00
|
|
|
var shots = (int) (charge / component.FireCost);
|
|
|
|
|
var maxShots = (int) (maxCharge / component.FireCost);
|
2022-06-01 19:59:58 +10:00
|
|
|
|
|
|
|
|
if (component.Shots != shots || component.Capacity != maxShots)
|
|
|
|
|
{
|
2024-01-24 12:58:57 +07:00
|
|
|
Dirty(uid, component);
|
2022-06-01 19:59:58 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
component.Shots = shots;
|
|
|
|
|
component.Capacity = maxShots;
|
2023-02-26 18:48:57 +11:00
|
|
|
UpdateBatteryAppearance(uid, component);
|
2022-06-01 19:59:58 +10:00
|
|
|
}
|
|
|
|
|
|
2024-01-24 12:58:57 +07:00
|
|
|
private void OnBatteryDamageExamine(
|
|
|
|
|
EntityUid uid,
|
|
|
|
|
BatteryAmmoProviderComponent component,
|
|
|
|
|
ref DamageExamineEvent args)
|
2022-09-09 09:08:14 +10:00
|
|
|
{
|
|
|
|
|
var damageSpec = GetDamage(component);
|
|
|
|
|
|
|
|
|
|
if (damageSpec == null)
|
|
|
|
|
return;
|
|
|
|
|
|
2024-01-24 12:58:57 +07:00
|
|
|
var damageType = component switch
|
2022-09-09 09:08:14 +10:00
|
|
|
{
|
2024-01-24 12:58:57 +07:00
|
|
|
HitscanBatteryAmmoProviderComponent => Loc.GetString("damage-hitscan"),
|
|
|
|
|
ProjectileBatteryAmmoProviderComponent => Loc.GetString("damage-projectile"),
|
|
|
|
|
TwoModeEnergyAmmoProviderComponent twoMode => Loc.GetString(twoMode.CurrentMode == EnergyModes.Stun
|
|
|
|
|
? "damage-projectile"
|
|
|
|
|
: "damage-hitscan"),
|
|
|
|
|
_ => throw new ArgumentOutOfRangeException()
|
|
|
|
|
};
|
2022-09-09 09:08:14 +10:00
|
|
|
|
2023-08-07 12:09:35 +03:00
|
|
|
_damageExamine.AddDamageExamine(args.Message, damageSpec, damageType);
|
2022-09-09 09:08:14 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private DamageSpecifier? GetDamage(BatteryAmmoProviderComponent component)
|
|
|
|
|
{
|
2024-01-24 12:58:57 +07:00
|
|
|
return component switch
|
2022-09-09 09:08:14 +10:00
|
|
|
{
|
2024-01-24 12:58:57 +07:00
|
|
|
HitscanBatteryAmmoProviderComponent hitscan =>
|
|
|
|
|
ProtoManager.Index<HitscanPrototype>(hitscan.Prototype).Damage,
|
|
|
|
|
ProjectileBatteryAmmoProviderComponent battery => GetProjectileDamage(battery.Prototype),
|
|
|
|
|
TwoModeEnergyAmmoProviderComponent twoMode => GetProjectileDamage(twoMode.CurrentMode == EnergyModes.Laser
|
|
|
|
|
? twoMode.LaserPrototype
|
|
|
|
|
: twoMode.StunPrototype),
|
|
|
|
|
_ => null
|
|
|
|
|
};
|
2022-09-09 09:08:14 +10:00
|
|
|
}
|
|
|
|
|
|
2022-06-01 19:59:58 +10:00
|
|
|
protected override void TakeCharge(EntityUid uid, BatteryAmmoProviderComponent component)
|
|
|
|
|
{
|
2023-04-19 22:10:08 +12:00
|
|
|
// Will raise ChargeChangedEvent
|
|
|
|
|
_battery.UseCharge(uid, component.FireCost);
|
2022-06-01 19:59:58 +10:00
|
|
|
}
|
|
|
|
|
}
|