100 lines
3.3 KiB
C#
100 lines
3.3 KiB
C#
using System.Diagnostics.CodeAnalysis;
|
|
using Content.Server.Power.Components;
|
|
using Content.Server.Power.EntitySystems;
|
|
using Content.Shared.Projectiles;
|
|
using Content.Shared.Weapons.Ranged.Events;
|
|
using Robust.Shared.Containers;
|
|
using Robust.Shared.Utility;
|
|
|
|
namespace Content.Server._White.Crossbow;
|
|
|
|
public sealed class PoweredSystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly SharedContainerSystem _containers = default!;
|
|
[Dependency] private readonly BatterySystem _battery = default!;
|
|
|
|
private const string CellSlot = "cell_slot";
|
|
private const string CrystalSlot = "crystal_slot";
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<PoweredComponent, AmmoShotEvent>(OnShoot);
|
|
}
|
|
|
|
private void OnShoot(EntityUid uid, PoweredComponent component, AmmoShotEvent args)
|
|
{
|
|
if (!TryGetBatteryComponent(uid, out var battery, out var batteryUid))
|
|
return;
|
|
|
|
var (factor, charge) = GetFactor(uid, component, battery, batteryUid.Value);
|
|
|
|
// Чтобы затриггерить взрыв на полную мощь, если есть плазма в батарейке
|
|
_battery.SetCharge(batteryUid.Value, battery.CurrentCharge, battery);
|
|
|
|
_battery.SetCharge(batteryUid.Value, battery.CurrentCharge - charge, battery);
|
|
var damage = component.Damage * factor;
|
|
|
|
foreach (var proj in args.FiredProjectiles)
|
|
{
|
|
EnsureComp<ThrowDamageModifierComponent>(proj).Damage += damage;
|
|
|
|
if (factor == 0)
|
|
continue;
|
|
|
|
var embed = EnsureComp<EmbeddableProjectileComponent>(proj);
|
|
embed.Penetrate = true;
|
|
Dirty(proj, embed);
|
|
}
|
|
}
|
|
|
|
public float GetPowerCoefficient(EntityUid uid)
|
|
{
|
|
if (!TryComp(uid, out PoweredComponent? component) ||
|
|
!TryGetBatteryComponent(uid, out var battery, out var batteryUid))
|
|
return 1f;
|
|
|
|
return 1f + GetFactor(uid, component, battery, batteryUid.Value).Item1;
|
|
}
|
|
|
|
private (float, float) GetFactor(EntityUid uid, PoweredComponent component, BatteryComponent battery, EntityUid batteryUid)
|
|
{
|
|
DebugTools.Assert(component.Charge != 0f);
|
|
var charge = MathF.Min(battery.CurrentCharge, component.Charge);
|
|
var factor = charge / component.Charge;
|
|
var multiplier = 1f;
|
|
|
|
if (TryComp(batteryUid, out RiggableComponent? rig) && rig.IsRigged)
|
|
multiplier += 1f;
|
|
|
|
if (_containers.TryGetContainer(uid, CrystalSlot, out var container) && container is ContainerSlot slot &&
|
|
slot.ContainedEntity.HasValue)
|
|
multiplier += 1f;
|
|
|
|
factor *= multiplier;
|
|
|
|
return (factor, charge);
|
|
}
|
|
|
|
private bool TryGetBatteryComponent(EntityUid uid, [NotNullWhen(true)] out BatteryComponent? battery,
|
|
[NotNullWhen(true)] out EntityUid? batteryUid)
|
|
{
|
|
if (!_containers.TryGetContainer(uid, CellSlot, out var container) ||
|
|
container is not ContainerSlot slot)
|
|
{
|
|
battery = null;
|
|
batteryUid = null;
|
|
return false;
|
|
}
|
|
|
|
batteryUid = slot.ContainedEntity;
|
|
|
|
if (batteryUid != null)
|
|
return TryComp(batteryUid, out battery);
|
|
|
|
battery = null;
|
|
return false;
|
|
}
|
|
}
|