[feat] Egun

This commit is contained in:
rhailrake
2023-04-28 02:10:32 +06:00
committed by Aviu00
parent 663cae3181
commit 72fa97798f
35 changed files with 425 additions and 15 deletions

View File

@@ -16,7 +16,7 @@ public partial class GunComponent : Component
#region Sound
[ViewVariables(VVAccess.ReadWrite), DataField("soundGunshot")]
public SoundSpecifier? SoundGunshot = new SoundPathSpecifier("/Audio/Weapons/Guns/Gunshots/smg.ogg");
public SoundSpecifier? SoundGunshot { get; set; } = new SoundPathSpecifier("/Audio/Weapons/Guns/Gunshots/smg.ogg");
[ViewVariables(VVAccess.ReadWrite), DataField("soundEmpty")]
public SoundSpecifier? SoundEmpty = new SoundPathSpecifier("/Audio/Weapons/Guns/Empty/empty.ogg");

View File

@@ -0,0 +1,43 @@
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared.Weapons.Ranged.Components;
[RegisterComponent, NetworkedComponent]
public sealed class TwoModeEnergyAmmoProviderComponent : BatteryAmmoProviderComponent
{
[ViewVariables(VVAccess.ReadOnly),
DataField("projProto", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string ProjectilePrototype = default!;
[ViewVariables(VVAccess.ReadOnly),
DataField("hitscanProto", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<HitscanPrototype>))]
public string HitscanPrototype = default!;
[ViewVariables(VVAccess.ReadOnly), DataField("projFireCost")]
public float ProjFireCost = 50;
[ViewVariables(VVAccess.ReadOnly), DataField("hitscanFireCost")]
public float HitscanFireCost = 100;
[ViewVariables(VVAccess.ReadOnly), DataField("currentMode")]
public EnergyModes CurrentMode { get; set; } = EnergyModes.Stun;
[ViewVariables(VVAccess.ReadOnly), DataField("projSound")]
public SoundSpecifier? ProjSound = new SoundPathSpecifier("/Audio/Weapons/Guns/Gunshots/taser2.ogg");
[ViewVariables(VVAccess.ReadOnly), DataField("hitscanSound")]
public SoundSpecifier? HitscanSound = new SoundPathSpecifier("/Audio/Weapons/Guns/Gunshots/laser_cannon.ogg");
public SoundSpecifier? ToggleSound = new SoundPathSpecifier("/Audio/Weapons/Guns/Misc/egun_toggle.ogg");
[ViewVariables(VVAccess.ReadOnly)] public bool InStun = true;
}
public enum EnergyModes
{
Stun,
Laser
}

View File

@@ -1,4 +1,5 @@
using Content.Shared.Examine;
using Content.Shared.Item;
using Content.Shared.Weapons.Ranged.Components;
using Content.Shared.Weapons.Ranged.Events;
using Robust.Shared.GameStates;
@@ -9,6 +10,8 @@ namespace Content.Shared.Weapons.Ranged.Systems;
public abstract partial class SharedGunSystem
{
[Dependency] private readonly SharedItemSystem _item = default!;
protected virtual void InitializeBattery()
{
// Trying to dump comp references hence the below
@@ -25,6 +28,62 @@ public abstract partial class SharedGunSystem
SubscribeLocalEvent<ProjectileBatteryAmmoProviderComponent, TakeAmmoEvent>(OnBatteryTakeAmmo);
SubscribeLocalEvent<ProjectileBatteryAmmoProviderComponent, GetAmmoCountEvent>(OnBatteryAmmoCount);
SubscribeLocalEvent<ProjectileBatteryAmmoProviderComponent, ExaminedEvent>(OnBatteryExamine);
// TwoModeEnergy
SubscribeLocalEvent<TwoModeEnergyAmmoProviderComponent, ComponentInit>(OnTwoModeInit);
SubscribeLocalEvent<TwoModeEnergyAmmoProviderComponent, ComponentGetState>(OnBatteryTwoModeGetState);
SubscribeLocalEvent<TwoModeEnergyAmmoProviderComponent, ComponentHandleState>(OnBatteryTwoModeHandleState);
SubscribeLocalEvent<TwoModeEnergyAmmoProviderComponent, TakeAmmoEvent>(OnBatteryTakeAmmo);
SubscribeLocalEvent<TwoModeEnergyAmmoProviderComponent, GetAmmoCountEvent>(OnBatteryAmmoCount);
SubscribeLocalEvent<TwoModeEnergyAmmoProviderComponent, ExaminedEvent>(OnBatteryExamine);
}
private void OnTwoModeInit(EntityUid uid, TwoModeEnergyAmmoProviderComponent component, ComponentInit args)
{
if (!Timing.IsFirstTimePredicted || !TryComp<AppearanceComponent>(component.Owner, out var appearance)) return;
Appearance.SetData(appearance.Owner, AmmoVisuals.InStun, component.InStun, appearance);
}
private void OnBatteryTwoModeHandleState(EntityUid uid, TwoModeEnergyAmmoProviderComponent component, ref ComponentHandleState args)
{
if (args.Current is not TwoModeComponentState state)
return;
component.Shots = state.Shots;
component.Capacity = state.MaxShots;
component.FireCost = state.FireCost;
component.CurrentMode = state.CurrentMode;
component.InStun = state.InStun;
}
private void OnBatteryTwoModeGetState(EntityUid uid, TwoModeEnergyAmmoProviderComponent component, ref ComponentGetState args)
{
args.State = new TwoModeComponentState()
{
Shots = component.Shots,
MaxShots = component.Capacity,
FireCost = component.FireCost,
CurrentMode = component.CurrentMode,
InStun = component.InStun
};
}
protected void UpdateTwoModeAppearance(EntityUid uid, TwoModeEnergyAmmoProviderComponent component)
{
if (!TryComp<AppearanceComponent>(uid, out var appearance))
return;
if (!TryComp<ItemComponent?>(uid, out var item))
return;
if (component.InStun)
_item.SetHeldPrefix(uid, null, item);
else
_item.SetHeldPrefix(uid, "laser", item);
Appearance.SetData(uid, AmmoVisuals.InStun, component.InStun, appearance);
}
private void OnBatteryHandleState(EntityUid uid, BatteryAmmoProviderComponent component, ref ComponentHandleState args)
@@ -101,6 +160,13 @@ public abstract partial class SharedGunSystem
return (ent, EnsureShootable(ent));
case HitscanBatteryAmmoProviderComponent hitscan:
return (null, ProtoManager.Index<HitscanPrototype>(hitscan.Prototype));
case TwoModeEnergyAmmoProviderComponent twoMode:
if (twoMode.CurrentMode == EnergyModes.Stun)
{
var projEnt = Spawn(twoMode.ProjectilePrototype, coordinates);
return (projEnt, EnsureComp<AmmoComponent>(projEnt));
}
return (null, ProtoManager.Index<HitscanPrototype>(twoMode.HitscanPrototype));
default:
throw new ArgumentOutOfRangeException();
}
@@ -113,4 +179,14 @@ public abstract partial class SharedGunSystem
public int MaxShots;
public float FireCost;
}
[Serializable, NetSerializable]
public sealed class TwoModeComponentState : ComponentState
{
public EnergyModes CurrentMode { get; init; }
public int Shots;
public int MaxShots;
public float FireCost;
public bool InStun;
}
}

View File

@@ -20,9 +20,20 @@ public abstract partial class SharedGunSystem
("mode", GetLocSelector(component.SelectedMode))));
args.PushMarkup(Loc.GetString("gun-fire-rate-examine", ("color", FireRateExamineColor),
("fireRate", $"{component.FireRate:0.0}")));
if (!TryComp<TwoModeEnergyAmmoProviderComponent>(uid, out var comp))
return;
args.PushMarkup(Loc.GetString("gun-twomode-mode-examine", ("color", TwoModeExamineColor),
("mode", GetLocMode(comp.CurrentMode))));
}
}
private object GetLocMode(EnergyModes mode)
{
return Loc.GetString($"gun-twomode-{mode.ToString()}");
}
private string GetLocSelector(SelectiveFire mode)
{
return Loc.GetString($"gun-{mode.ToString()}");

View File

@@ -67,6 +67,7 @@ public abstract partial class SharedGunSystem : EntitySystem
protected const string AmmoExamineColor = "yellow";
protected const string FireRateExamineColor = "yellow";
protected const string ModeExamineColor = "cyan";
protected const string TwoModeExamineColor = "red";
public override void Initialize()
{
@@ -501,4 +502,5 @@ public enum AmmoVisuals : byte
HasAmmo, // used for generic visualizers. c# stuff can just check ammocount != 0
MagLoaded,
BoltClosed,
InStun
}