mirror of
https://github.com/DeltaV-Station/Delta-v.git
synced 2026-09-30 16:17:27 +00:00
* Remove discard functionality from the ChemMaster This duplicates other methods of discarding chemicals, including the drain conventionally given to chemistry labs. Any problems it solves are miniscule compared to the severe UI error that is having a destructive action without confirmation attached to a mode, the most common source of user error. * Improve animal cube interactions (#31668) * Working on dehydrate recipes to renew animal cubes * Added remaining cube dehydration recipes * Add OnExamine to RehydratableSystem.cs, need to add functionality to check total volume vs current volume to determine if 'soaked' text needs to be displayed * Added logic to append text to the description when the wrong reagent has been added to a compressed animal cube * Re-adding deleted summary * Update default SolutionName to be correct * Remove cube recipes to prevent infinite nutrient generation * Add OnMicrowaved event to RehydratableSystem.cs in order to clear solution of cube when microwaved. CURRENT ERROR REQUIRES REFACTOR OF MICROWAVECOMPONENT * Subscribe to microwave event * Refactor of MicrowaveComponent.cs to be in shared folder, accessible to RehydratableSystem.cs. Updated imports * Modify cube to only dehydrate in microwave when cooked for at least 5 seconds * now using event to check access to fingerprint * Tweak - Reflective vest and Energy Katana should reflect only in correct slots (#31902) * ReflectComponentLogicFix Added bool InRightPlace and updated relevant system * Using SlotFlags * prevent friendly fire for dragon/carp (#32231) * add NoFriendlyFire * make zombies use NoFriendlyFire * no friendly fire for dragon * let dragon kill naughty fish and validhunting syndies * add button to print logprobe logs (#32255) * add EntityName at the bottom of LogProbe * add button to print logprobe logs * Add camera mod to diagnostic hud (#32254) * ai-glass * weh to protect against bad grammar * transmutation into diagnostic hud * Apply forensics when loading with an ammo box * inaprovaline metabolizes slower * :trollface: --------- Co-authored-by: Janet Blackquill <uhhadd@gmail.com> Co-authored-by: Preston Smith <Blackfoot03@outlook.com> Co-authored-by: YourUsername <you@example.com> Co-authored-by: BIGZi0348 <svalker0348@gmail.com> Co-authored-by: deltanedas <@deltanedas:kde.org> Co-authored-by: ArZarLordOfMango <arzarchannel@gmail.com> Co-authored-by: themias <themias5@gmail.com> Co-authored-by: Alzore <blackern5000@gmail.com>
248 lines
9.0 KiB
C#
248 lines
9.0 KiB
C#
using Content.Server.Emp;
|
|
using Content.Server.Power.Components;
|
|
using Content.Shared.Examine;
|
|
using Content.Shared.PowerCell;
|
|
using Content.Shared.PowerCell.Components;
|
|
using Content.Shared.Rounding;
|
|
using Robust.Shared.Containers;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using Content.Shared.Kitchen.Components;
|
|
using Content.Server.Power.EntitySystems;
|
|
using Content.Server.UserInterface;
|
|
using Content.Shared.Containers.ItemSlots;
|
|
using Content.Shared.Popups;
|
|
using ActivatableUISystem = Content.Shared.UserInterface.ActivatableUISystem;
|
|
|
|
namespace Content.Server.PowerCell;
|
|
|
|
/// <summary>
|
|
/// Handles Power cells
|
|
/// </summary>
|
|
public sealed partial class PowerCellSystem : SharedPowerCellSystem
|
|
{
|
|
[Dependency] private readonly ActivatableUISystem _activatable = default!;
|
|
[Dependency] private readonly BatterySystem _battery = default!;
|
|
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
|
[Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!;
|
|
[Dependency] private readonly SharedAppearanceSystem _sharedAppearanceSystem = default!;
|
|
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
|
[Dependency] private readonly RiggableSystem _riggableSystem = default!;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<PowerCellComponent, ChargeChangedEvent>(OnChargeChanged);
|
|
SubscribeLocalEvent<PowerCellComponent, ExaminedEvent>(OnCellExamined);
|
|
SubscribeLocalEvent<PowerCellComponent, EmpAttemptEvent>(OnCellEmpAttempt);
|
|
|
|
SubscribeLocalEvent<PowerCellDrawComponent, ChargeChangedEvent>(OnDrawChargeChanged);
|
|
SubscribeLocalEvent<PowerCellDrawComponent, PowerCellChangedEvent>(OnDrawCellChanged);
|
|
|
|
SubscribeLocalEvent<PowerCellSlotComponent, ExaminedEvent>(OnCellSlotExamined);
|
|
// funny
|
|
SubscribeLocalEvent<PowerCellSlotComponent, BeingMicrowavedEvent>(OnSlotMicrowaved);
|
|
}
|
|
|
|
private void OnSlotMicrowaved(EntityUid uid, PowerCellSlotComponent component, BeingMicrowavedEvent args)
|
|
{
|
|
if (!_itemSlotsSystem.TryGetSlot(uid, component.CellSlotId, out var slot))
|
|
return;
|
|
|
|
if (slot.Item == null)
|
|
return;
|
|
|
|
RaiseLocalEvent(slot.Item.Value, args);
|
|
}
|
|
|
|
private void OnChargeChanged(EntityUid uid, PowerCellComponent component, ref ChargeChangedEvent args)
|
|
{
|
|
if (TryComp<RiggableComponent>(uid, out var rig) && rig.IsRigged)
|
|
{
|
|
_riggableSystem.Explode(uid, cause: null);
|
|
return;
|
|
}
|
|
|
|
var frac = args.Charge / args.MaxCharge;
|
|
var level = (byte)ContentHelpers.RoundToNearestLevels(frac, 1, PowerCellComponent.PowerCellVisualsLevels);
|
|
_sharedAppearanceSystem.SetData(uid, PowerCellVisuals.ChargeLevel, level);
|
|
|
|
// If this power cell is inside a cell-slot, inform that entity that the power has changed (for updating visuals n such).
|
|
if (_containerSystem.TryGetContainingContainer((uid, null, null), out var container)
|
|
&& TryComp(container.Owner, out PowerCellSlotComponent? slot)
|
|
&& _itemSlotsSystem.TryGetSlot(container.Owner, slot.CellSlotId, out var itemSlot))
|
|
{
|
|
if (itemSlot.Item == uid)
|
|
RaiseLocalEvent(container.Owner, new PowerCellChangedEvent(false));
|
|
}
|
|
}
|
|
|
|
protected override void OnCellRemoved(EntityUid uid, PowerCellSlotComponent component, EntRemovedFromContainerMessage args)
|
|
{
|
|
base.OnCellRemoved(uid, component, args);
|
|
|
|
if (args.Container.ID != component.CellSlotId)
|
|
return;
|
|
|
|
var ev = new PowerCellSlotEmptyEvent();
|
|
RaiseLocalEvent(uid, ref ev);
|
|
}
|
|
|
|
#region Activatable
|
|
/// <inheritdoc/>
|
|
public override bool HasActivatableCharge(EntityUid uid, PowerCellDrawComponent? battery = null, PowerCellSlotComponent? cell = null, EntityUid? user = null)
|
|
{
|
|
// Default to true if we don't have the components.
|
|
if (!Resolve(uid, ref battery, ref cell, false))
|
|
return true;
|
|
|
|
return HasCharge(uid, battery.UseRate, cell, user);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tries to use the <see cref="PowerCellDrawComponent.UseRate"/> for this entity.
|
|
/// </summary>
|
|
/// <param name="user">Popup to this user with the relevant detail if specified.</param>
|
|
public bool TryUseActivatableCharge(EntityUid uid, PowerCellDrawComponent? battery = null, PowerCellSlotComponent? cell = null, EntityUid? user = null)
|
|
{
|
|
// Default to true if we don't have the components.
|
|
if (!Resolve(uid, ref battery, ref cell, false))
|
|
return true;
|
|
|
|
if (TryUseCharge(uid, battery.UseRate, cell, user))
|
|
{
|
|
_sharedAppearanceSystem.SetData(uid, PowerCellSlotVisuals.Enabled, HasActivatableCharge(uid, battery, cell, user));
|
|
_activatable.CheckUsage(uid);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public override bool HasDrawCharge(
|
|
EntityUid uid,
|
|
PowerCellDrawComponent? battery = null,
|
|
PowerCellSlotComponent? cell = null,
|
|
EntityUid? user = null)
|
|
{
|
|
if (!Resolve(uid, ref battery, ref cell, false))
|
|
return true;
|
|
|
|
return HasCharge(uid, battery.DrawRate, cell, user);
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Returns whether the entity has a slotted battery and charge for the requested action.
|
|
/// </summary>
|
|
/// <param name="user">Popup to this user with the relevant detail if specified.</param>
|
|
public bool HasCharge(EntityUid uid, float charge, PowerCellSlotComponent? component = null, EntityUid? user = null)
|
|
{
|
|
if (!TryGetBatteryFromSlot(uid, out var battery, component))
|
|
{
|
|
if (user != null)
|
|
_popup.PopupEntity(Loc.GetString("power-cell-no-battery"), uid, user.Value);
|
|
|
|
return false;
|
|
}
|
|
|
|
if (battery.CurrentCharge < charge)
|
|
{
|
|
if (user != null)
|
|
_popup.PopupEntity(Loc.GetString("power-cell-insufficient"), uid, user.Value);
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tries to use charge from a slotted battery.
|
|
/// </summary>
|
|
public bool TryUseCharge(EntityUid uid, float charge, PowerCellSlotComponent? component = null, EntityUid? user = null)
|
|
{
|
|
if (!TryGetBatteryFromSlot(uid, out var batteryEnt, out var battery, component))
|
|
{
|
|
if (user != null)
|
|
_popup.PopupEntity(Loc.GetString("power-cell-no-battery"), uid, user.Value);
|
|
|
|
return false;
|
|
}
|
|
|
|
if (!_battery.TryUseCharge(batteryEnt.Value, charge, battery))
|
|
{
|
|
if (user != null)
|
|
_popup.PopupEntity(Loc.GetString("power-cell-insufficient"), uid, user.Value);
|
|
|
|
return false;
|
|
}
|
|
|
|
_sharedAppearanceSystem.SetData(uid, PowerCellSlotVisuals.Enabled, battery.CurrentCharge > 0);
|
|
return true;
|
|
}
|
|
|
|
public bool TryGetBatteryFromSlot(EntityUid uid, [NotNullWhen(true)] out BatteryComponent? battery, PowerCellSlotComponent? component = null)
|
|
{
|
|
return TryGetBatteryFromSlot(uid, out _, out battery, component);
|
|
}
|
|
|
|
public bool TryGetBatteryFromSlot(EntityUid uid,
|
|
[NotNullWhen(true)] out EntityUid? batteryEnt,
|
|
[NotNullWhen(true)] out BatteryComponent? battery,
|
|
PowerCellSlotComponent? component = null)
|
|
{
|
|
if (!Resolve(uid, ref component, false))
|
|
{
|
|
batteryEnt = null;
|
|
battery = null;
|
|
return false;
|
|
}
|
|
|
|
if (_itemSlotsSystem.TryGetSlot(uid, component.CellSlotId, out ItemSlot? slot))
|
|
{
|
|
batteryEnt = slot.Item;
|
|
return TryComp(slot.Item, out battery);
|
|
}
|
|
|
|
batteryEnt = null;
|
|
battery = null;
|
|
return false;
|
|
}
|
|
|
|
private void OnCellExamined(EntityUid uid, PowerCellComponent component, ExaminedEvent args)
|
|
{
|
|
TryComp<BatteryComponent>(uid, out var battery);
|
|
OnBatteryExamined(uid, battery, args);
|
|
}
|
|
|
|
private void OnCellEmpAttempt(EntityUid uid, PowerCellComponent component, EmpAttemptEvent args)
|
|
{
|
|
var parent = Transform(uid).ParentUid;
|
|
// relay the attempt event to the slot so it can cancel it
|
|
if (HasComp<PowerCellSlotComponent>(parent))
|
|
RaiseLocalEvent(parent, args);
|
|
}
|
|
|
|
private void OnCellSlotExamined(EntityUid uid, PowerCellSlotComponent component, ExaminedEvent args)
|
|
{
|
|
TryGetBatteryFromSlot(uid, out var battery);
|
|
OnBatteryExamined(uid, battery, args);
|
|
}
|
|
|
|
private void OnBatteryExamined(EntityUid uid, BatteryComponent? component, ExaminedEvent args)
|
|
{
|
|
if (component != null)
|
|
{
|
|
var charge = component.CurrentCharge / component.MaxCharge * 100;
|
|
args.PushMarkup(Loc.GetString("power-cell-component-examine-details", ("currentCharge", $"{charge:F0}")));
|
|
}
|
|
else
|
|
{
|
|
args.PushMarkup(Loc.GetString("power-cell-component-examine-details-no-battery"));
|
|
}
|
|
}
|
|
}
|