* Add power cell and weapon chargers Functionality's similar to SS13. The cell charger won't show the discrete charging levels because effort to not make it spam appearance updates over the network. There's some stuff I wasn't sure on: 1. Updating power? Particularly around fixing rounding 2. Duplicating the full and empty sprites as I couldn't figure out a way to not have AppearanceVisualizer throw if the state isn't found 3. I made a BaseCharger abstract class under the assumption that when a mech / borg charger is added it would also inherit from it. 4. GetText currently isn't localized * Address PJB's feedback Updated the BaseCharger * Change nullref exception to invalidoperation * If the user doesn't have hands it will just return instead
184 lines
6.5 KiB
C#
184 lines
6.5 KiB
C#
using System;
|
|
using Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan;
|
|
using Content.Server.GameObjects.EntitySystems;
|
|
using Content.Shared.GameObjects;
|
|
using Content.Shared.GameObjects.Components.Power;
|
|
using Content.Shared.Interfaces;
|
|
using Robust.Server.GameObjects;
|
|
using Robust.Server.GameObjects.Components.Container;
|
|
using Robust.Shared.GameObjects;
|
|
using Robust.Shared.Interfaces.GameObjects;
|
|
using Robust.Shared.IoC;
|
|
using Robust.Shared.Localization;
|
|
using Robust.Shared.Serialization;
|
|
using Robust.Shared.ViewVariables;
|
|
|
|
namespace Content.Server.GameObjects.Components.Power.Chargers
|
|
{
|
|
/// <summary>
|
|
/// This is used for the lasergun / flash rechargers
|
|
/// </summary>
|
|
[RegisterComponent]
|
|
[ComponentReference(typeof(IActivate))]
|
|
[ComponentReference(typeof(IAttackBy))]
|
|
public sealed class WeaponCapacitorChargerComponent : BaseCharger, IActivate, IAttackBy
|
|
{
|
|
public override string Name => "WeaponCapacitorCharger";
|
|
public override double CellChargePercent => _container.ContainedEntity != null ?
|
|
_container.ContainedEntity.GetComponent<HitscanWeaponCapacitorComponent>().Charge /
|
|
_container.ContainedEntity.GetComponent<HitscanWeaponCapacitorComponent>().Capacity * 100 : 0.0f;
|
|
|
|
bool IAttackBy.AttackBy(AttackByEventArgs eventArgs)
|
|
{
|
|
var result = TryInsertItem(eventArgs.AttackWith);
|
|
if (!result)
|
|
{
|
|
var localizationManager = IoCManager.Resolve<ILocalizationManager>();
|
|
eventArgs.User.PopupMessage(Owner, localizationManager.GetString("Unable to insert capacitor"));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void IActivate.Activate(ActivateEventArgs eventArgs)
|
|
{
|
|
RemoveItemToHand(eventArgs.User);
|
|
}
|
|
|
|
[Verb]
|
|
private sealed class InsertVerb : Verb<WeaponCapacitorChargerComponent>
|
|
{
|
|
protected override string GetText(IEntity user, WeaponCapacitorChargerComponent component)
|
|
{
|
|
if (!user.TryGetComponent(out HandsComponent handsComponent) || handsComponent.GetActiveHand == null)
|
|
{
|
|
return "Insert";
|
|
}
|
|
return $"Insert {handsComponent.GetActiveHand.Owner.Name}";
|
|
}
|
|
|
|
protected override VerbVisibility GetVisibility(IEntity user, WeaponCapacitorChargerComponent component)
|
|
{
|
|
if (!user.TryGetComponent(out HandsComponent handsComponent))
|
|
{
|
|
return VerbVisibility.Invisible;
|
|
}
|
|
|
|
if (component._container.ContainedEntity != null || handsComponent.GetActiveHand == null)
|
|
{
|
|
return VerbVisibility.Disabled;
|
|
}
|
|
|
|
return VerbVisibility.Visible;
|
|
}
|
|
|
|
protected override void Activate(IEntity user, WeaponCapacitorChargerComponent component)
|
|
{
|
|
if (!user.TryGetComponent(out HandsComponent handsComponent))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (handsComponent.GetActiveHand == null)
|
|
{
|
|
return;
|
|
}
|
|
var userItem = handsComponent.GetActiveHand.Owner;
|
|
handsComponent.Drop(userItem);
|
|
component.TryInsertItem(userItem);
|
|
}
|
|
}
|
|
|
|
[Verb]
|
|
private sealed class EjectVerb : Verb<WeaponCapacitorChargerComponent>
|
|
{
|
|
protected override string GetText(IEntity user, WeaponCapacitorChargerComponent component)
|
|
{
|
|
if (component._container.ContainedEntity == null)
|
|
{
|
|
return "Eject";
|
|
}
|
|
return $"Eject {component._container.ContainedEntity.Name}";
|
|
}
|
|
|
|
protected override VerbVisibility GetVisibility(IEntity user, WeaponCapacitorChargerComponent component)
|
|
{
|
|
if (component._container.ContainedEntity == null)
|
|
{
|
|
return VerbVisibility.Disabled;
|
|
}
|
|
return VerbVisibility.Visible;
|
|
}
|
|
|
|
protected override void Activate(IEntity user, WeaponCapacitorChargerComponent component)
|
|
{
|
|
component.RemoveItem();
|
|
}
|
|
}
|
|
|
|
public bool TryInsertItem(IEntity entity)
|
|
{
|
|
if (!entity.HasComponent<HitscanWeaponCapacitorComponent>() ||
|
|
_container.ContainedEntity != null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
_heldItem = entity;
|
|
if (!_container.Insert(_heldItem))
|
|
{
|
|
return false;
|
|
}
|
|
UpdateStatus();
|
|
return true;
|
|
}
|
|
|
|
protected override CellChargerStatus GetStatus()
|
|
{
|
|
if (!_powerDevice.Powered)
|
|
{
|
|
return CellChargerStatus.Off;
|
|
}
|
|
|
|
if (_container.ContainedEntity == null)
|
|
{
|
|
return CellChargerStatus.Empty;
|
|
}
|
|
|
|
if (_container.ContainedEntity.TryGetComponent(out HitscanWeaponCapacitorComponent component) &&
|
|
Math.Abs(component.Capacity - component.Charge) < 0.01)
|
|
{
|
|
return CellChargerStatus.Charged;
|
|
}
|
|
|
|
return CellChargerStatus.Charging;
|
|
}
|
|
|
|
protected override void TransferPower(float frameTime)
|
|
{
|
|
// Two numbers: One for how much power actually goes into the device (chargeAmount) and
|
|
// chargeLoss which is how much is drawn from the powernet
|
|
_container.ContainedEntity.TryGetComponent(out HitscanWeaponCapacitorComponent weaponCapacitorComponent);
|
|
var chargeLoss = weaponCapacitorComponent.RequestCharge(frameTime) * _transferRatio;
|
|
_powerDevice.Load = chargeLoss;
|
|
|
|
if (!_powerDevice.Powered)
|
|
{
|
|
// No power: Event should update to Off status
|
|
return;
|
|
}
|
|
|
|
var chargeAmount = chargeLoss * _transferEfficiency;
|
|
|
|
weaponCapacitorComponent.AddCharge(chargeAmount);
|
|
// Just so the sprite won't be set to 99.99999% visibility
|
|
if (weaponCapacitorComponent.Capacity - weaponCapacitorComponent.Charge < 0.01)
|
|
{
|
|
weaponCapacitorComponent.Charge = weaponCapacitorComponent.Capacity;
|
|
}
|
|
UpdateStatus();
|
|
}
|
|
|
|
}
|
|
}
|