BatteryWeaponPowerCell tweaks (#33500)
* BatteryWeaponPowerCell tweaks * add update ammo ev & shuttle guns tweaks * MilonPL requested changes * revert changes in OnPowerCellChanged * Add events to get charge info & change current charge --------- Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>
This commit is contained in:
@@ -38,4 +38,30 @@ namespace Content.Server.Power.Components
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public readonly record struct ChargeChangedEvent(float Charge, float MaxCharge);
|
||||
|
||||
/// <summary>
|
||||
/// Raised when it is necessary to get information about battery charges.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public sealed class GetChargeEvent : EntityEventArgs
|
||||
{
|
||||
public float CurrentCharge;
|
||||
public float MaxCharge;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised when it is necessary to change the current battery charge to a some value.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public sealed class ChangeChargeEvent : EntityEventArgs
|
||||
{
|
||||
public float OriginalValue;
|
||||
public float ResidualValue;
|
||||
|
||||
public ChangeChargeEvent(float value)
|
||||
{
|
||||
OriginalValue = value;
|
||||
ResidualValue = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ namespace Content.Server.Power.EntitySystems
|
||||
SubscribeLocalEvent<BatteryComponent, RejuvenateEvent>(OnBatteryRejuvenate);
|
||||
SubscribeLocalEvent<BatteryComponent, PriceCalculationEvent>(CalculateBatteryPrice);
|
||||
SubscribeLocalEvent<BatteryComponent, EmpPulseEvent>(OnEmpPulse);
|
||||
SubscribeLocalEvent<BatteryComponent, ChangeChargeEvent>(OnChangeCharge);
|
||||
SubscribeLocalEvent<BatteryComponent, GetChargeEvent>(OnGetCharge);
|
||||
|
||||
SubscribeLocalEvent<NetworkBatteryPreSync>(PreSync);
|
||||
SubscribeLocalEvent<NetworkBatteryPostSync>(PostSync);
|
||||
@@ -116,21 +118,26 @@ namespace Content.Server.Power.EntitySystems
|
||||
TrySetChargeCooldown(uid);
|
||||
}
|
||||
|
||||
private void OnChangeCharge(Entity<BatteryComponent> entity, ref ChangeChargeEvent args)
|
||||
{
|
||||
if (args.ResidualValue == 0)
|
||||
return;
|
||||
|
||||
args.ResidualValue -= ChangeCharge(entity, args.ResidualValue);
|
||||
}
|
||||
|
||||
private void OnGetCharge(Entity<BatteryComponent> entity, ref GetChargeEvent args)
|
||||
{
|
||||
args.CurrentCharge += entity.Comp.CurrentCharge;
|
||||
args.MaxCharge += entity.Comp.MaxCharge;
|
||||
}
|
||||
|
||||
public float UseCharge(EntityUid uid, float value, BatteryComponent? battery = null)
|
||||
{
|
||||
if (value <= 0 || !Resolve(uid, ref battery) || battery.CurrentCharge == 0)
|
||||
if (value <= 0 || !Resolve(uid, ref battery) || battery.CurrentCharge == 0)
|
||||
return 0;
|
||||
|
||||
var newValue = Math.Clamp(0, battery.CurrentCharge - value, battery.MaxCharge);
|
||||
var delta = newValue - battery.CurrentCharge;
|
||||
battery.CurrentCharge = newValue;
|
||||
|
||||
// Apply a cooldown to the entity's self recharge if needed.
|
||||
TrySetChargeCooldown(uid);
|
||||
|
||||
var ev = new ChargeChangedEvent(battery.CurrentCharge, battery.MaxCharge);
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
return delta;
|
||||
return ChangeCharge(uid, -value, battery);
|
||||
}
|
||||
|
||||
public void SetMaxCharge(EntityUid uid, float value, BatteryComponent? battery = null)
|
||||
@@ -164,6 +171,26 @@ namespace Content.Server.Power.EntitySystems
|
||||
var ev = new ChargeChangedEvent(battery.CurrentCharge, battery.MaxCharge);
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the current battery charge by some value
|
||||
/// </summary>
|
||||
public float ChangeCharge(EntityUid uid, float value, BatteryComponent? battery = null)
|
||||
{
|
||||
if (!Resolve(uid, ref battery))
|
||||
return 0;
|
||||
|
||||
var newValue = Math.Clamp(0, battery.CurrentCharge + value, battery.MaxCharge);
|
||||
var delta = newValue - battery.CurrentCharge;
|
||||
battery.CurrentCharge = newValue;
|
||||
|
||||
TrySetChargeCooldown(uid);
|
||||
|
||||
var ev = new ChargeChangedEvent(battery.CurrentCharge, battery.MaxCharge);
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
return delta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the entity has a self recharge and puts it on cooldown if applicable.
|
||||
/// </summary>
|
||||
|
||||
@@ -42,6 +42,9 @@ public sealed partial class PowerCellSystem : SharedPowerCellSystem
|
||||
SubscribeLocalEvent<PowerCellSlotComponent, ExaminedEvent>(OnCellSlotExamined);
|
||||
// funny
|
||||
SubscribeLocalEvent<PowerCellSlotComponent, BeingMicrowavedEvent>(OnSlotMicrowaved);
|
||||
|
||||
SubscribeLocalEvent<PowerCellSlotComponent, GetChargeEvent>(OnGetCharge);
|
||||
SubscribeLocalEvent<PowerCellSlotComponent, ChangeChargeEvent>(OnChangeCharge);
|
||||
}
|
||||
|
||||
private void OnSlotMicrowaved(EntityUid uid, PowerCellSlotComponent component, BeingMicrowavedEvent args)
|
||||
@@ -244,4 +247,20 @@ public sealed partial class PowerCellSystem : SharedPowerCellSystem
|
||||
args.PushMarkup(Loc.GetString("power-cell-component-examine-details-no-battery"));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGetCharge(Entity<PowerCellSlotComponent> entity, ref GetChargeEvent args)
|
||||
{
|
||||
if (!TryGetBatteryFromSlot(entity, out var batteryUid, out _))
|
||||
return;
|
||||
|
||||
RaiseLocalEvent(batteryUid.Value, ref args);
|
||||
}
|
||||
|
||||
private void OnChangeCharge(Entity<PowerCellSlotComponent> entity, ref ChangeChargeEvent args)
|
||||
{
|
||||
if (!TryGetBatteryFromSlot(entity, out var batteryUid, out _))
|
||||
return;
|
||||
|
||||
RaiseLocalEvent(batteryUid.Value, ref args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@ using Content.Server.Power.Components;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Damage.Events;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.PowerCell.Components;
|
||||
using Content.Shared.Projectiles;
|
||||
using Content.Shared.Weapons.Ranged;
|
||||
using Content.Shared.Weapons.Ranged.Components;
|
||||
using Content.Shared.Weapons.Ranged.Events;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Weapons.Ranged.Systems;
|
||||
@@ -19,29 +21,36 @@ public sealed partial class GunSystem
|
||||
SubscribeLocalEvent<HitscanBatteryAmmoProviderComponent, ComponentStartup>(OnBatteryStartup);
|
||||
SubscribeLocalEvent<HitscanBatteryAmmoProviderComponent, ChargeChangedEvent>(OnBatteryChargeChange);
|
||||
SubscribeLocalEvent<HitscanBatteryAmmoProviderComponent, DamageExamineEvent>(OnBatteryDamageExamine);
|
||||
SubscribeLocalEvent<HitscanBatteryAmmoProviderComponent, PowerCellChangedEvent>(OnPowerCellChanged);
|
||||
|
||||
// Projectile
|
||||
SubscribeLocalEvent<ProjectileBatteryAmmoProviderComponent, ComponentStartup>(OnBatteryStartup);
|
||||
SubscribeLocalEvent<ProjectileBatteryAmmoProviderComponent, ChargeChangedEvent>(OnBatteryChargeChange);
|
||||
SubscribeLocalEvent<ProjectileBatteryAmmoProviderComponent, DamageExamineEvent>(OnBatteryDamageExamine);
|
||||
SubscribeLocalEvent<ProjectileBatteryAmmoProviderComponent, PowerCellChangedEvent>(OnPowerCellChanged);
|
||||
}
|
||||
|
||||
private void OnBatteryStartup(EntityUid uid, BatteryAmmoProviderComponent component, ComponentStartup args)
|
||||
private void OnBatteryStartup<T>(Entity<T> entity, ref ComponentStartup args) where T : BatteryAmmoProviderComponent
|
||||
{
|
||||
UpdateShots(uid, component);
|
||||
UpdateShots(entity, entity.Comp);
|
||||
}
|
||||
|
||||
private void OnBatteryChargeChange(EntityUid uid, BatteryAmmoProviderComponent component, ref ChargeChangedEvent args)
|
||||
private void OnBatteryChargeChange<T>(Entity<T> entity, ref ChargeChangedEvent args) where T : BatteryAmmoProviderComponent
|
||||
{
|
||||
UpdateShots(uid, component, args.Charge, args.MaxCharge);
|
||||
UpdateShots(entity, entity.Comp, args.Charge, args.MaxCharge);
|
||||
}
|
||||
|
||||
private void OnPowerCellChanged<T>(Entity<T> entity, ref PowerCellChangedEvent args) where T : BatteryAmmoProviderComponent
|
||||
{
|
||||
UpdateShots(entity, entity.Comp);
|
||||
}
|
||||
|
||||
private void UpdateShots(EntityUid uid, BatteryAmmoProviderComponent component)
|
||||
{
|
||||
if (!TryComp<BatteryComponent>(uid, out var battery))
|
||||
return;
|
||||
var ev = new GetChargeEvent();
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
|
||||
UpdateShots(uid, component, battery.CurrentCharge, battery.MaxCharge);
|
||||
UpdateShots(uid, component, ev.CurrentCharge, ev.MaxCharge);
|
||||
}
|
||||
|
||||
private void UpdateShots(EntityUid uid, BatteryAmmoProviderComponent component, float charge, float maxCharge)
|
||||
@@ -55,18 +64,24 @@ public sealed partial class GunSystem
|
||||
}
|
||||
|
||||
component.Shots = shots;
|
||||
component.Capacity = maxShots;
|
||||
|
||||
if (maxShots > 0)
|
||||
component.Capacity = maxShots;
|
||||
|
||||
UpdateBatteryAppearance(uid, component);
|
||||
|
||||
var updateAmmoEv = new UpdateClientAmmoEvent();
|
||||
RaiseLocalEvent(uid, ref updateAmmoEv);
|
||||
}
|
||||
|
||||
private void OnBatteryDamageExamine(EntityUid uid, BatteryAmmoProviderComponent component, ref DamageExamineEvent args)
|
||||
private void OnBatteryDamageExamine<T>(Entity<T> entity, ref DamageExamineEvent args) where T : BatteryAmmoProviderComponent
|
||||
{
|
||||
var damageSpec = GetDamage(component);
|
||||
var damageSpec = GetDamage(entity.Comp);
|
||||
|
||||
if (damageSpec == null)
|
||||
return;
|
||||
|
||||
var damageType = component switch
|
||||
var damageType = entity.Comp switch
|
||||
{
|
||||
HitscanBatteryAmmoProviderComponent => Loc.GetString("damage-hitscan"),
|
||||
ProjectileBatteryAmmoProviderComponent => Loc.GetString("damage-projectile"),
|
||||
@@ -103,9 +118,9 @@ public sealed partial class GunSystem
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override void TakeCharge(EntityUid uid, BatteryAmmoProviderComponent component)
|
||||
protected override void TakeCharge(Entity<BatteryAmmoProviderComponent> entity)
|
||||
{
|
||||
// Will raise ChargeChangedEvent
|
||||
_battery.UseCharge(uid, component.FireCost);
|
||||
var ev = new ChangeChargeEvent(-entity.Comp.FireCost);
|
||||
RaiseLocalEvent(entity, ref ev);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.Containers;
|
||||
using Content.Server.PowerCell;
|
||||
|
||||
namespace Content.Server.Weapons.Ranged.Systems;
|
||||
|
||||
@@ -34,6 +35,7 @@ public sealed partial class GunSystem : SharedGunSystem
|
||||
[Dependency] private readonly SharedColorFlashEffectSystem _color = default!;
|
||||
[Dependency] private readonly StaminaSystem _stamina = default!;
|
||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||
[Dependency] private readonly PowerCellSystem _powerCell = default!;
|
||||
[Dependency] private readonly SharedMapSystem _map = default!;
|
||||
|
||||
private const float DamagePitchVariation = 0.05f;
|
||||
|
||||
@@ -67,7 +67,7 @@ public abstract partial class SharedGunSystem
|
||||
component.Shots--;
|
||||
}
|
||||
|
||||
TakeCharge(uid, component);
|
||||
TakeCharge((uid, component));
|
||||
UpdateBatteryAppearance(uid, component);
|
||||
Dirty(uid, component);
|
||||
}
|
||||
@@ -81,9 +81,9 @@ public abstract partial class SharedGunSystem
|
||||
/// <summary>
|
||||
/// Update the battery (server-only) whenever fired.
|
||||
/// </summary>
|
||||
protected virtual void TakeCharge(EntityUid uid, BatteryAmmoProviderComponent component)
|
||||
protected virtual void TakeCharge(Entity<BatteryAmmoProviderComponent> entity)
|
||||
{
|
||||
UpdateAmmoCount(uid, prediction: false);
|
||||
UpdateAmmoCount(entity, prediction: false);
|
||||
}
|
||||
|
||||
protected void UpdateBatteryAppearance(EntityUid uid, BatteryAmmoProviderComponent component)
|
||||
|
||||
@@ -33,9 +33,6 @@
|
||||
- type: Appearance
|
||||
- type: PowerCellVisuals
|
||||
- type: Riggable
|
||||
- type: HitscanBatteryAmmoProvider
|
||||
proto: RedLightLaser
|
||||
fireCost: 50
|
||||
|
||||
- type: entity
|
||||
name: potato battery
|
||||
@@ -290,9 +287,6 @@
|
||||
- type: Tag
|
||||
tags:
|
||||
- PowerCage
|
||||
- type: HitscanBatteryAmmoProvider
|
||||
proto: RedShuttleLaser
|
||||
fireCost: 150
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 0.8
|
||||
sprintModifier: 0.8
|
||||
|
||||
@@ -42,10 +42,12 @@
|
||||
- SemiAuto
|
||||
soundGunshot:
|
||||
path: /Audio/Weapons/Guns/Gunshots/laser.ogg
|
||||
- type: MagazineAmmoProvider
|
||||
- type: HitscanBatteryAmmoProvider
|
||||
proto: RedLightLaser
|
||||
fireCost: 50
|
||||
- type: ItemSlots
|
||||
slots:
|
||||
gun_magazine:
|
||||
cell_slot:
|
||||
name: Magazine
|
||||
startingItem: PowerCellSmall
|
||||
insertSound: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg
|
||||
@@ -54,12 +56,14 @@
|
||||
tags:
|
||||
- PowerCell
|
||||
- PowerCellSmall
|
||||
- type: PowerCellSlot
|
||||
cellSlotId: cell_slot
|
||||
- type: Appearance
|
||||
- type: StaticPrice
|
||||
price: 500
|
||||
- type: ContainerContainer
|
||||
containers:
|
||||
gun_magazine: !type:ContainerSlot
|
||||
cell_slot: !type:ContainerSlot
|
||||
|
||||
- type: entity
|
||||
id: BaseWeaponBatterySmall
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
containers:
|
||||
machine_board: !type:Container
|
||||
machine_parts: !type:Container
|
||||
gun_magazine: !type:ContainerSlot
|
||||
cell_slot: !type:ContainerSlot
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
- trigger:
|
||||
@@ -80,9 +80,11 @@
|
||||
zeroVisible: true
|
||||
- type: Machine
|
||||
board: ShuttleGunSvalinnMachineGunCircuitboard
|
||||
- type: PowerCellSlot
|
||||
cellSlotId: cell_slot
|
||||
- type: ItemSlots
|
||||
slots:
|
||||
gun_magazine:
|
||||
cell_slot:
|
||||
name: Magazine
|
||||
insertSound: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg
|
||||
ejectSound: /Audio/Weapons/Guns/MagOut/batrifle_magout.ogg
|
||||
@@ -90,7 +92,9 @@
|
||||
tags:
|
||||
- PowerCell
|
||||
- PowerCellSmall
|
||||
- type: MagazineAmmoProvider
|
||||
- type: HitscanBatteryAmmoProvider
|
||||
proto: RedLightLaser
|
||||
fireCost: 50
|
||||
|
||||
- type: entity
|
||||
id: ShuttleGunPerforator
|
||||
@@ -110,7 +114,7 @@
|
||||
containers:
|
||||
machine_board: !type:Container
|
||||
machine_parts: !type:Container
|
||||
gun_magazine: !type:ContainerSlot
|
||||
cell_slot: !type:ContainerSlot
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
- trigger:
|
||||
@@ -133,16 +137,20 @@
|
||||
zeroVisible: true
|
||||
- type: Machine
|
||||
board: ShuttleGunPerforatorCircuitboard
|
||||
- type: PowerCellSlot
|
||||
cellSlotId: cell_slot
|
||||
- type: ItemSlots
|
||||
slots:
|
||||
gun_magazine:
|
||||
cell_slot:
|
||||
name: Magazine
|
||||
insertSound: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg
|
||||
ejectSound: /Audio/Weapons/Guns/MagOut/batrifle_magout.ogg
|
||||
whitelist:
|
||||
tags:
|
||||
- PowerCage
|
||||
- type: MagazineAmmoProvider
|
||||
- type: HitscanBatteryAmmoProvider
|
||||
proto: RedShuttleLaser
|
||||
fireCost: 150
|
||||
|
||||
# ---- Launchers ----
|
||||
# naming: EXP (Explosion) + conventional power + suffix (g for Grenade, c for RPG Cartridge) + Name
|
||||
|
||||
Reference in New Issue
Block a user