using Content.Server.Cargo.Systems; using Content.Server.Emp; using Content.Server.Power.Components; using Content.Shared.Examine; using Content.Shared.Rejuvenate; using JetBrains.Annotations; namespace Content.Server.Power.EntitySystems { [UsedImplicitly] public sealed class BatterySystem : EntitySystem { public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnExamine); SubscribeLocalEvent(OnNetBatteryRejuvenate); SubscribeLocalEvent(OnBatteryRejuvenate); SubscribeLocalEvent(CalculateBatteryPrice); SubscribeLocalEvent(OnEmpPulse); SubscribeLocalEvent(PreSync); SubscribeLocalEvent(PostSync); } private void OnNetBatteryRejuvenate(EntityUid uid, PowerNetworkBatteryComponent component, RejuvenateEvent args) { component.NetworkBattery.CurrentStorage = component.NetworkBattery.Capacity; } private void OnBatteryRejuvenate(EntityUid uid, BatteryComponent component, RejuvenateEvent args) { component.CurrentCharge = component.MaxCharge; } private void OnExamine(EntityUid uid, ExaminableBatteryComponent component, ExaminedEvent args) { if (!TryComp(uid, out var batteryComponent)) return; if (args.IsInDetailsRange) { var effectiveMax = batteryComponent.MaxCharge; if (effectiveMax == 0) effectiveMax = 1; var chargeFraction = batteryComponent.CurrentCharge / effectiveMax; var chargePercentRounded = (int) (chargeFraction * 100); args.PushMarkup( Loc.GetString( "examinable-battery-component-examine-detail", ("percent", chargePercentRounded), ("markupPercentColor", "green") ) ); } } private void PreSync(NetworkBatteryPreSync ev) { // Ignoring entity pausing. If the entity was paused, neither component's data should have been changed. var enumerator = AllEntityQuery(); while (enumerator.MoveNext(out var netBat, out var bat)) { netBat.NetworkBattery.Capacity = bat.MaxCharge; netBat.NetworkBattery.CurrentStorage = bat.CurrentCharge; } } private void PostSync(NetworkBatteryPostSync ev) { // Ignoring entity pausing. If the entity was paused, neither component's data should have been changed. var enumerator = AllEntityQuery(); while (enumerator.MoveNext(out var uid, out var netBat, out var bat)) { var netCharge = netBat.NetworkBattery.CurrentStorage; if (MathHelper.CloseTo(bat.CurrentCharge, netCharge)) continue; bat.CurrentCharge = netCharge; } } public override void Update(float frameTime) { foreach (var (comp, batt) in EntityManager.EntityQuery()) { if (!comp.AutoRecharge) continue; if (batt.IsFullyCharged) continue; batt.CurrentCharge += comp.AutoRechargeRate * frameTime; } } /// /// Gets the price for the power contained in an entity's battery. /// private void CalculateBatteryPrice(EntityUid uid, BatteryComponent component, ref PriceCalculationEvent args) { args.Price += component.CurrentCharge * component.PricePerJoule; } private void OnEmpPulse(EntityUid uid, BatteryComponent component, ref EmpPulseEvent args) { args.Affected = true; component.UseCharge(args.EnergyConsumption); } } }