Nubody (1/3) - Ipc removal (#5840)
* Reapply "Nubody Merge" (#5807) This reverts commitd62f7cef10. * Revert "Nubody Merge (#5670)" This reverts commitb465cfb3fd. * Revert "IPC fibers (#4968)" This reverts commitc2b42211f0. * Revert "IPC Polymorph fix (#4545)" This reverts commitfa03d8c655. * Revert "fix IPC not having humanoid emotes (#4445)" This reverts commit216fdf999f. * Revert "ipc heat/cold (#4306)" This reverts commitfafd5cf816. * Revert "ipc cables (#4283)" This reverts commit54958039a1. * Revert "feat: ipcs now have dynamic power draw based off movement speed (#3917)" This reverts commit71e8b7e64b. * Revert "fix ipcs not being able to disarm (#3374)" This reverts commit764c4dcf54. * Revert "make steel heal caustic for ipcs (#3206)" This reverts commit450ac82550. * Revert "add missing ipc survival boxes (#3065)" This reverts commit888c9cdb00. * Revert "make borgs use ipc repairing (#3064)" This reverts commitf77a49dd0b. * Revert "added ipc plushie (batteries not included) (#3023)" This reverts commit743cdbb606. * Revert "Update hud.yml to add ipcs to diagnostic hud (#3019)" This reverts commit7220643531. * Revert "Tweak IPCs (#2979)" This reverts commit98b47476de. * Revert "fix nukies ipc test fail (#2957)" This reverts commit4a1acbf863. * Revert "fix ipc nukies not getting comms (#2884)" This reverts commit8a2254770e. * Revert "fix ipc encryption key mispredict (#2879)" This reverts commitf08726efc1. * remove oil * Revert "Merge pull request #2800 from Spielern/port-ipc" This reverts commit822fa4312c, reversing changes made tofe4c23c702. * Remove and Fix rest of IPC Hangons causing crashes * Integration test Errors * Expand migration file with removed IPC stuff * IPC Leg was found and migrated to naught * motorkinds need to inherit an actual species base * forgot the alerts * irrelevant coscult code * excess casualties --------- Co-authored-by: Janet Blackquill <uhhadd@gmail.com>
This commit is contained in:
parent
fcab8ccb1e
commit
1f8afb9ba6
|
|
@ -2,7 +2,6 @@ using System.Diagnostics.CodeAnalysis;
|
|||
using System.Linq;
|
||||
using Content.Client.DisplacementMap;
|
||||
using Content.Client.Inventory;
|
||||
using Content.Shared._DV.Silicon.IPC; // DeltaV - IPC Snouts
|
||||
using Content.Shared.Clothing;
|
||||
using Content.Shared.Clothing.Components;
|
||||
using Content.Shared.Clothing.EntitySystems;
|
||||
|
|
@ -103,12 +102,8 @@ public sealed class ClientClothingSystem : ClothingSystem
|
|||
|
||||
List<PrototypeLayerData>? layers = null;
|
||||
|
||||
// Begin DeltaV Additions - IPC snouts
|
||||
var speciesId = inventory.SpeciesId;
|
||||
|
||||
if (TryComp(args.Equipee, out SnoutHelmetComponent? helmetComponent) && helmetComponent.EnableAlternateHelmet)
|
||||
speciesId = helmetComponent.ReplacementRace;
|
||||
|
||||
// first attempt to get species specific data.
|
||||
if (speciesId != null)
|
||||
item.ClothingVisuals.TryGetValue($"{args.Slot}-{speciesId}", out layers);
|
||||
|
|
@ -120,7 +115,6 @@ public sealed class ClientClothingSystem : ClothingSystem
|
|||
if (!TryGetDefaultVisuals(uid, item, args.Slot, speciesId, out layers))
|
||||
return;
|
||||
}
|
||||
// End DeltaV Additions
|
||||
|
||||
// add each layer to the visuals
|
||||
var i = 0;
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
using Content.Shared._DV.Silicon.IPC;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Humanoid.Markings;
|
||||
|
||||
namespace Content.Client._DV.Silicon.IPC;
|
||||
|
||||
public sealed class SnoutHelmetSystem : EntitySystem
|
||||
{
|
||||
private const MarkingCategories MarkingToQuery = MarkingCategories.Snout;
|
||||
private const int MaximumMarkingCount = 0;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<SnoutHelmetComponent, ComponentStartup>(OnComponentStartup);
|
||||
}
|
||||
|
||||
private void OnComponentStartup(EntityUid uid, SnoutHelmetComponent component, ComponentStartup args)
|
||||
{
|
||||
if (TryComp(uid, out HumanoidAppearanceComponent? humanoidAppearanceComponent) &&
|
||||
humanoidAppearanceComponent.ClientOldMarkings.Markings.TryGetValue(MarkingToQuery, out var markings) &&
|
||||
markings.Count > MaximumMarkingCount)
|
||||
{
|
||||
component.EnableAlternateHelmet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
using Content.Client.Alerts;
|
||||
using Content.Shared._EE.Silicon.Components;
|
||||
using Content.Shared._EE.Silicon.Systems;
|
||||
|
||||
namespace Content.Client._DV.Silicon.Charge;
|
||||
|
||||
public sealed class SiliconChargeSystem : SharedSiliconChargeSystem
|
||||
{
|
||||
[Dependency] private readonly ClientAlertsSystem _alerts = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<SiliconComponent, ComponentInit>(OnSiliconInit);
|
||||
SubscribeLocalEvent<SiliconComponent, SiliconChargeStateUpdateEvent>(OnSiliconChargeStateUpdate);
|
||||
}
|
||||
|
||||
private void OnSiliconInit(EntityUid uid, SiliconComponent component, ComponentInit args)
|
||||
{
|
||||
if (!component.BatteryPowered)
|
||||
return;
|
||||
|
||||
_alerts.ShowAlert(uid, component.BatteryAlert, component.ChargeState);
|
||||
}
|
||||
|
||||
private void OnSiliconChargeStateUpdate(EntityUid uid, SiliconComponent component, SiliconChargeStateUpdateEvent ev)
|
||||
{
|
||||
_alerts.ShowAlert(uid, component.BatteryAlert, ev.ChargePercent);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
using Content.Client.Alerts;
|
||||
using Content.Shared._EE.Silicon.Components;
|
||||
using Content.Shared._DV.Silicons.Charge;
|
||||
|
||||
namespace Content.Client._DV.Silicon.Charge;
|
||||
|
||||
public sealed class SiliconDrainSystem : SharedSiliconDrainSystem
|
||||
{
|
||||
[Dependency] private readonly ClientAlertsSystem _alerts = default!;
|
||||
|
||||
protected override void UpdateChargeIcon(Entity<SiliconComponent> ent, short chargePercent)
|
||||
{
|
||||
// If you can't find a battery, set the indicator and skip it.
|
||||
if (!TryGetSiliconBattery(ent, out _))
|
||||
{
|
||||
if (_alerts.IsShowingAlert(ent.Owner, ent.Comp.BatteryAlert))
|
||||
{
|
||||
_alerts.ClearAlert(ent.Owner, ent.Comp.BatteryAlert);
|
||||
_alerts.ShowAlert(ent.Owner, ent.Comp.NoBatteryAlert);
|
||||
}
|
||||
}
|
||||
// If the battery was replaced and the no battery indicator is showing, replace the indicator
|
||||
else if (_alerts.IsShowingAlert(ent.Owner, ent.Comp.NoBatteryAlert))
|
||||
{
|
||||
_alerts.ClearAlert(ent.Owner, ent.Comp.NoBatteryAlert);
|
||||
_alerts.ShowAlert(ent.Owner, ent.Comp.BatteryAlert, chargePercent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -87,12 +87,8 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.Mobs
|
|||
Assert.That(clientAlertsUI.AlertContainer.ChildCount, Is.GreaterThanOrEqualTo(3));
|
||||
var alertControls = clientAlertsUI.AlertContainer.Children.Select(c => (AlertControl) c);
|
||||
var alertIDs = alertControls.Select(ac => ac.Alert.ID).ToArray();
|
||||
// Goobstation - IPC have BorgHealth instead of HumanHealth
|
||||
var expectedDebugIDs = new[] { "Debug1", "Debug2" };
|
||||
var expectedHealthIDs = new[] { "BorgHealth", "HumanHealth" };
|
||||
|
||||
Assert.That(alertIDs, Is.SupersetOf(expectedDebugIDs));
|
||||
Assert.That(alertIDs, Has.Some.Matches<string>(item => expectedHealthIDs.Contains(item)));
|
||||
var expectedIDs = new[] { "HumanHealth", "Debug1", "Debug2" };
|
||||
Assert.That(alertIDs, Is.SupersetOf(expectedIDs));
|
||||
});
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
|
|
@ -108,12 +104,8 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.Mobs
|
|||
Assert.That(clientAlertsUI.AlertContainer.ChildCount, Is.GreaterThanOrEqualTo(2));
|
||||
var alertControls = clientAlertsUI.AlertContainer.Children.Select(c => (AlertControl) c);
|
||||
var alertIDs = alertControls.Select(ac => ac.Alert.ID).ToArray();
|
||||
// Goobstation - IPC have BorgHealth instead of HumanHealth
|
||||
var expectedDebugIDs = new[] { "Debug2" };
|
||||
var expectedHealthIDs = new[] { "BorgHealth", "HumanHealth" };
|
||||
|
||||
Assert.That(alertIDs, Is.SupersetOf(expectedDebugIDs));
|
||||
Assert.That(alertIDs, Has.Some.Matches<string>(item => expectedHealthIDs.Contains(item)));
|
||||
var expectedIDs = new[] { "HumanHealth", "Debug2" };
|
||||
Assert.That(alertIDs, Is.SupersetOf(expectedIDs));
|
||||
});
|
||||
|
||||
await pair.CleanReturnAsync();
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ using Content.Shared.Station.Components;
|
|||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Content.Shared._EE.Silicon.Components; // Goobstation
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.IntegrationTests.Tests.GameRules;
|
||||
|
|
@ -230,15 +229,12 @@ public sealed class NukeOpsTest
|
|||
var totalSeconds = 30;
|
||||
var totalTicks = (int) Math.Ceiling(totalSeconds / server.Timing.TickPeriod.TotalSeconds);
|
||||
var increment = 5;
|
||||
var resp = entMan.GetComponent<RespiratorComponent>(player);
|
||||
var damage = entMan.GetComponent<DamageableComponent>(player);
|
||||
for (var tick = 0; tick < totalTicks; tick += increment)
|
||||
{
|
||||
await pair.RunTicksSync(increment);
|
||||
if (!entMan.HasComponent<SiliconComponent>(player)) // Goobstation - IPC
|
||||
{
|
||||
var resp = entMan.GetComponent<RespiratorComponent>(player);
|
||||
Assert.That(resp.SuffocationCycles, Is.LessThanOrEqualTo(resp.SuffocationCycleThreshold));
|
||||
}
|
||||
Assert.That(resp.SuffocationCycles, Is.LessThanOrEqualTo(resp.SuffocationCycleThreshold));
|
||||
Assert.That(damage.TotalDamage, Is.EqualTo(FixedPoint2.Zero));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using Content.Server.Ghost;
|
||||
using Content.Shared._EE.Silicon.Components; // EE
|
||||
using Content.Server.Hands.Systems;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Chat;
|
||||
|
|
@ -173,10 +172,7 @@ public sealed class SuicideSystem : EntitySystem
|
|||
return;
|
||||
}
|
||||
|
||||
if (HasComp<SiliconComponent>(victim)) // Goobstation
|
||||
args.DamageType ??= "Shock";
|
||||
else
|
||||
args.DamageType ??= "Bloodloss";
|
||||
args.DamageType ??= "Bloodloss";
|
||||
_suicide.ApplyLethalDamage(victim, args.DamageType);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ using Content.Server.Materials;
|
|||
using Content.Server.Popups;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Shared._DV.Psionics.Components; // DeltaV
|
||||
using Content.Shared._EE.Silicon.Components; // Goobstation
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
|
|
@ -163,9 +162,6 @@ public sealed class CloningPodSystem : EntitySystem
|
|||
if (!TryComp<PhysicsComponent>(bodyToClone, out var physics))
|
||||
return false;
|
||||
|
||||
if (HasComp<SiliconComponent>(bodyToClone))
|
||||
return false; // Goobstation: Don't clone IPCs.
|
||||
|
||||
var cloningCost = (int)Math.Round(physics.FixturesMass);
|
||||
|
||||
if (_configManager.GetCVar(CCVars.BiomassEasyMode))
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@ using Content.Shared.Roles;
|
|||
using Content.Shared.Station;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Content.Shared._DV.Silicon.IPC; // DeltaV
|
||||
using Content.Shared.Radio.Components; // Goobstation
|
||||
|
||||
namespace Content.Server.Clothing.Systems;
|
||||
|
||||
|
|
@ -109,14 +107,6 @@ public sealed class OutfitSystem : EntitySystem
|
|||
_spawningSystem.EquipRoleLoadout(target, roleLoadout, jobProto);
|
||||
}
|
||||
|
||||
// Begin DeltaV/Goob Additions
|
||||
if (EntityManager.HasComponent<EncryptionKeyHolderComponent>(target))
|
||||
{
|
||||
var encryption = EntityManager.System<InternalEncryptionKeySpawner>();
|
||||
encryption.TryInsertEncryptionKey(target, startingGear);
|
||||
}
|
||||
// End DeltaV/Goob Additions
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem
|
|||
|| !DoCommonElectrocution(uid, sourceUid, shockDamage, time, refresh, siemensCoefficient, statusEffects))
|
||||
return false;
|
||||
|
||||
RaiseLocalEvent(uid, new ElectrocutedEvent(uid, sourceUid, siemensCoefficient, shockDamage), true); // Goobstation
|
||||
RaiseLocalEvent(uid, new ElectrocutedEvent(uid, sourceUid, siemensCoefficient), true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -349,7 +349,7 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem
|
|||
electrocutionComponent.Electrocuting = uid;
|
||||
electrocutionComponent.Source = sourceUid;
|
||||
|
||||
RaiseLocalEvent(uid, new ElectrocutedEvent(uid, sourceUid, siemensCoefficient, shockDamage), true); // Goobstation
|
||||
RaiseLocalEvent(uid, new ElectrocutedEvent(uid, sourceUid, siemensCoefficient), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public sealed partial class DeathgaspComponent : Component
|
|||
/// </summary>
|
||||
[DataField("prototype", customTypeSerializer:typeof(PrototypeIdSerializer<EmotePrototype>))]
|
||||
public string Prototype = "DefaultDeathgasp";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Goobstation: Makes sure that the deathgasp is only displayed if the entity went critical before dying
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -21,9 +21,7 @@ public sealed class DeathgaspSystem: EntitySystem
|
|||
private void OnMobStateChanged(EntityUid uid, DeathgaspComponent component, MobStateChangedEvent args)
|
||||
{
|
||||
// don't deathgasp if they arent going straight from crit to dead
|
||||
if (component.NeedsCritical // Goobstation
|
||||
&& args.OldMobState != MobState.Critical
|
||||
|| args.NewMobState != MobState.Dead)
|
||||
if (args.NewMobState != MobState.Dead || args.OldMobState != MobState.Critical)
|
||||
return;
|
||||
|
||||
Deathgasp(uid, component);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ using Content.Server.Light.EntitySystems;
|
|||
using Content.Server.Stunnable;
|
||||
using Content.Shared._DV.CosmicCult;
|
||||
using Content.Shared._DV.CosmicCult.Components;
|
||||
using Content.Shared._EE.Silicon.Components;
|
||||
using Content.Shared.Effects;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Light.Components;
|
||||
|
|
@ -70,7 +69,7 @@ public sealed class CosmicGlareSystem : EntitySystem
|
|||
|
||||
_flash.Flash(targetEnt, uid, args.Action, uid.Comp.CosmicGlareDuration, uid.Comp.CosmicGlarePenalty, false, false, uid.Comp.CosmicGlareStun, ignoreProtection: uid.Comp.CosmicEmpowered);
|
||||
|
||||
if (HasComp<BorgChassisComponent>(targetEnt) || HasComp<SiliconComponent>(targetEnt)) //For paralyzing borgs and IPCs specifically.
|
||||
if (HasComp<BorgChassisComponent>(targetEnt)) //For paralyzing borgs and IPCs specifically.
|
||||
{
|
||||
_stun.TryUpdateParalyzeDuration(targetEnt, uid.Comp.CosmicGlareDuration / 2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ using Content.Server.Radio;
|
|||
using Content.Server.Station.Systems;
|
||||
using Content.Shared._DV.CosmicCult.Components;
|
||||
using Content.Shared._DV.CosmicCult;
|
||||
using Content.Server._EE.Radio;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Eye;
|
||||
|
|
@ -94,8 +93,6 @@ public sealed partial class CosmicCultSystem : SharedCosmicCultSystem
|
|||
SubscribeLocalEvent<CosmicImposingComponent, ComponentRemove>(OnEndImposition);
|
||||
SubscribeLocalEvent<CosmicImposingComponent, RefreshMovementSpeedModifiersEvent>(OnImpositionMoveSpeed);
|
||||
|
||||
SubscribeLocalEvent<CosmicCultComponent, EncryptionChannelsChangedEvent>(OnTransmitterChannelsChangedCult, after: new[] { typeof(IntrinsicRadioKeySystem) });
|
||||
|
||||
SubscribeLocalEvent<RadioSendAttemptEvent>(OnRadioSendAttempt);
|
||||
SubscribeLocalEvent<CosmicJammerComponent, AnchorStateChangedEvent>(OnJammerAnchorStateChange);
|
||||
|
||||
|
|
@ -250,23 +247,6 @@ public sealed partial class CosmicCultSystem : SharedCosmicCultSystem
|
|||
#endregion
|
||||
|
||||
#region Edge cases
|
||||
/// <summary>
|
||||
/// Edge Case to handle IPCs losing astral murmur after panel operations.
|
||||
/// </summary>
|
||||
private void OnTransmitterChannelsChangedCult(EntityUid uid, CosmicCultComponent component, EncryptionChannelsChangedEvent args)
|
||||
{
|
||||
if (!TryComp<IntrinsicRadioTransmitterComponent>(uid, out IntrinsicRadioTransmitterComponent? transmitter) || !TryComp<ActiveRadioComponent>(uid, out ActiveRadioComponent? activeRadio))
|
||||
return;
|
||||
|
||||
if (transmitter.Channels.Contains(CosmicRadio) && activeRadio.Channels.Contains(CosmicRadio))
|
||||
return;
|
||||
|
||||
transmitter.Channels.Add(CosmicRadio);
|
||||
activeRadio.Channels.Add(CosmicRadio);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When a cultist gets polymorphed, ensure that the resulting entity has all the necessary components. Mostly there for kitsune my behated.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
using Content.Shared._EE.Silicon.Systems;
|
||||
|
||||
namespace Content.Server._DV.Silicon.Charge;
|
||||
|
||||
public sealed class SiliconChargeSystem : SharedSiliconChargeSystem;
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
using Content.Shared._DV.Silicons.Charge;
|
||||
using Content.Shared._EE.Silicon.Components;
|
||||
|
||||
namespace Content.Server._DV.Silicons.Charge;
|
||||
|
||||
public sealed class SiliconDrainSystem : SharedSiliconDrainSystem
|
||||
{
|
||||
protected override void UpdateChargeIcon(Entity<SiliconComponent> ent, short chargePercent)
|
||||
{
|
||||
// No-op on Server
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
namespace Content.Server._EE.Power.Components;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class BatteryDrinkerComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Is this drinker allowed to drink batteries not tagged as <see cref="BatteryDrinkSource"/>?
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool DrinkAll;
|
||||
|
||||
/// <summary>
|
||||
/// How long it takes to drink from a battery, in seconds.
|
||||
/// Is multiplied by the source.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float DrinkSpeed = 1.5f;
|
||||
|
||||
/// <summary>
|
||||
/// The multiplier for the amount of power to attempt to drink.
|
||||
/// Default amount is 1000
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float DrinkMultiplier = 5f;
|
||||
|
||||
/// <summary>
|
||||
/// The multiplier for how long it takes to drink a non-source battery, if <see cref="DrinkAll"/> is true.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float DrinkAllMultiplier = 2.5f;
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
using System.Numerics;
|
||||
|
||||
namespace Content.Server._EE.Power.Components;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class RandomBatteryChargeComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The minimum and maximum max charge the battery can have.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public Vector2 BatteryMaxMinMax = new(0.85f, 1.15f);
|
||||
|
||||
/// <summary>
|
||||
/// The minimum and maximum current charge the battery can have.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public Vector2 BatteryChargeMinMax = new(1f, 1f);
|
||||
|
||||
/// <summary>
|
||||
/// False if the randomized charge of the battery should be a multiple of the preexisting current charge of the battery.
|
||||
/// True if the randomized charge of the battery should be a multiple of the max charge of the battery post max charge randomization.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool BasedOnMaxCharge = true;
|
||||
}
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
using System.Linq;
|
||||
using Content.Shared.Power.Components;
|
||||
using Content.Shared.Containers.ItemSlots;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.PowerCell.Components;
|
||||
using Content.Shared._EE.Silicon;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.Utility;
|
||||
using Content.Server._EE.Silicon.Charge;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared.Popups;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Containers;
|
||||
using Content.Server._EE.Power.Components;
|
||||
using Content.Server._EE.Silicon;
|
||||
using Content.Shared.Power.EntitySystems;
|
||||
using Content.Shared.PowerCell;
|
||||
|
||||
namespace Content.Server._EE.Power;
|
||||
|
||||
public sealed class BatteryDrinkerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedBatterySystem _battery = default!;
|
||||
[Dependency] private readonly PopupSystem _popup = default!;
|
||||
[Dependency] private readonly PowerCellSystem _powerCell = default!; // DeltaV - people with augment power cells can drink batteries
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<BatteryComponent, GetVerbsEvent<AlternativeVerb>>(AddAltVerb);
|
||||
|
||||
SubscribeLocalEvent<BatteryDrinkerComponent, BatteryDrinkerDoAfterEvent>(OnDoAfter);
|
||||
}
|
||||
|
||||
private void AddAltVerb(EntityUid uid, BatteryComponent batteryComponent, GetVerbsEvent<AlternativeVerb> args)
|
||||
{
|
||||
if (!args.CanAccess || !args.CanInteract)
|
||||
return;
|
||||
|
||||
if (!TryComp<BatteryDrinkerComponent>(args.User, out var drinkerComp) ||
|
||||
!TestDrinkableBattery(uid, drinkerComp) ||
|
||||
// DeltaV - people with augment power cells can drink batteries
|
||||
!_powerCell.TryGetBatteryFromEntityOrSlot(args.User, out _))
|
||||
return;
|
||||
|
||||
AlternativeVerb verb = new()
|
||||
{
|
||||
Act = () => DrinkBattery(uid, args.User, drinkerComp),
|
||||
Text = Loc.GetString("battery-drinker-verb-drink"),
|
||||
Icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/VerbIcons/smite.svg.192dpi.png")),
|
||||
};
|
||||
|
||||
args.Verbs.Add(verb);
|
||||
}
|
||||
|
||||
private bool TestDrinkableBattery(EntityUid target, BatteryDrinkerComponent drinkerComp)
|
||||
{
|
||||
if (!drinkerComp.DrinkAll && !HasComp<BatteryDrinkerSourceComponent>(target))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void DrinkBattery(EntityUid target, EntityUid user, BatteryDrinkerComponent drinkerComp)
|
||||
{
|
||||
var doAfterTime = drinkerComp.DrinkSpeed;
|
||||
|
||||
if (TryComp<BatteryDrinkerSourceComponent>(target, out var sourceComp))
|
||||
doAfterTime *= sourceComp.DrinkSpeedMulti;
|
||||
else
|
||||
doAfterTime *= drinkerComp.DrinkAllMultiplier;
|
||||
|
||||
var args = new DoAfterArgs(EntityManager, user, doAfterTime, new BatteryDrinkerDoAfterEvent(), user, target) // TODO: Make this doafter loop, once we merge Upstream.
|
||||
{
|
||||
BreakOnDamage = true,
|
||||
BreakOnMove = true,
|
||||
Broadcast = false,
|
||||
DistanceThreshold = 1.35f,
|
||||
RequireCanInteract = true,
|
||||
CancelDuplicate = false
|
||||
};
|
||||
|
||||
_doAfter.TryStartDoAfter(args);
|
||||
}
|
||||
|
||||
private void OnDoAfter(EntityUid uid, BatteryDrinkerComponent drinkerComp, DoAfterEvent args)
|
||||
{
|
||||
if (args.Cancelled || args.Target == null)
|
||||
return;
|
||||
|
||||
var source = args.Target.Value;
|
||||
var drinker = uid;
|
||||
var sourceBattery = Comp<BatteryComponent>(source);
|
||||
|
||||
// Begin DeltaV - people with augment power cells can drink batteries
|
||||
if (!_powerCell.TryGetBatteryFromEntityOrSlot(drinker, out var augmentBattery))
|
||||
return;
|
||||
|
||||
TryComp<BatteryDrinkerSourceComponent>(source, out var sourceComp);
|
||||
var augmentCharge = _battery.GetCharge(augmentBattery.Value.Owner);
|
||||
// End DeltaV - people with augment power cells can drink batteries
|
||||
|
||||
var sourceCharge = _battery.GetCharge((source, sourceBattery));
|
||||
var amountToDrink = drinkerComp.DrinkMultiplier * 1000;
|
||||
|
||||
amountToDrink = MathF.Min(amountToDrink, sourceCharge);
|
||||
amountToDrink = MathF.Min(amountToDrink, augmentBattery.Value.Comp!.MaxCharge - augmentCharge); // DeltaV - people with augment power cells can drink batteries
|
||||
|
||||
if (sourceComp != null && sourceComp.MaxAmount > 0)
|
||||
amountToDrink = MathF.Min(amountToDrink, (float) sourceComp.MaxAmount);
|
||||
|
||||
if (amountToDrink <= 0)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("battery-drinker-empty", ("target", source)), drinker, drinker);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_battery.TryUseCharge(source, amountToDrink))
|
||||
_battery.SetCharge(augmentBattery.Value.AsNullable(), augmentCharge + amountToDrink); // DeltaV - people with augment power cells can drink batteries
|
||||
else
|
||||
{
|
||||
_battery.SetCharge(augmentBattery.Value.AsNullable(), sourceCharge + augmentCharge); // DeltaV - people with augment power cells can drink batteries
|
||||
_battery.SetCharge(source, 0);
|
||||
}
|
||||
|
||||
if (sourceComp != null && sourceComp.DrinkSound != null){
|
||||
_popup.PopupEntity(Loc.GetString("ipc-recharge-tip"), drinker, drinker, PopupType.SmallCaution);
|
||||
_audio.PlayPvs(sourceComp.DrinkSound, source);
|
||||
Spawn("EffectSparks", Transform(source).Coordinates);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
using Content.Server.Electrocution;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared.Power.Components;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Shared.Electrocution;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
using Content.Server._EE.Power.Components;
|
||||
|
||||
namespace Content.Server._EE.Power.Systems;
|
||||
|
||||
public sealed class BatteryElectrocuteChargeSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly PopupSystem _popup = default!;
|
||||
[Dependency] private readonly BatterySystem _battery = default!;
|
||||
|
||||
// Yes, this is absurdly small for a reason.
|
||||
public const float ElectrifiedDamagePerWatt = 0.0015f;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<BatteryComponent, ElectrocutedEvent>(OnElectrocuted);
|
||||
}
|
||||
|
||||
private void OnElectrocuted(EntityUid uid, BatteryComponent battery, ElectrocutedEvent args)
|
||||
{
|
||||
if (args.ShockDamage == null || args.ShockDamage <= 0)
|
||||
return;
|
||||
|
||||
var charge = Math.Min(args.ShockDamage.Value * args.SiemensCoefficient
|
||||
/ ElectrifiedDamagePerWatt * 2,
|
||||
battery.MaxCharge * 0.25f)
|
||||
* _random.NextFloat(0.75f, 1.25f);
|
||||
|
||||
_battery.SetCharge(uid, _battery.GetCharge((uid, battery)) + charge);
|
||||
|
||||
_popup.PopupEntity(Loc.GetString("battery-electrocute-charge"), uid, uid);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
using Content.Shared._DV.CosmicCult.Components;
|
||||
using Content.Shared.Implants.Components; // DeltaV
|
||||
using Content.Shared.Radio;
|
||||
using Content.Shared.Radio.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._EE.Radio;
|
||||
|
||||
public sealed class IntrinsicRadioKeySystem : EntitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<IntrinsicRadioTransmitterComponent, EncryptionChannelsChangedEvent>(OnTransmitterChannelsChanged);
|
||||
SubscribeLocalEvent<ActiveRadioComponent, EncryptionChannelsChangedEvent>(OnReceiverChannelsChanged);
|
||||
}
|
||||
|
||||
private void OnTransmitterChannelsChanged(EntityUid uid, IntrinsicRadioTransmitterComponent component, EncryptionChannelsChangedEvent args)
|
||||
{
|
||||
UpdateChannels(uid, args.Component, ref component.Channels);
|
||||
}
|
||||
|
||||
private void OnReceiverChannelsChanged(EntityUid uid, ActiveRadioComponent component, EncryptionChannelsChangedEvent args)
|
||||
{
|
||||
UpdateChannels(uid, args.Component, ref component.Channels);
|
||||
}
|
||||
|
||||
private void UpdateChannels(EntityUid uid, EncryptionKeyHolderComponent keyHolderComp, ref HashSet<ProtoId<RadioChannelPrototype>> channels) // DeltaV - passthrough uid
|
||||
{
|
||||
channels.Clear();
|
||||
channels.UnionWith(keyHolderComp.Channels);
|
||||
|
||||
// Begin DeltaV Additions - Ensure radio implants continue to function
|
||||
if (TryComp<ImplantedComponent>(uid, out var implantedComp))
|
||||
{
|
||||
foreach (var implant in implantedComp.ImplantContainer.ContainedEntities)
|
||||
{
|
||||
if (!TryComp<RadioImplantComponent>(implant, out var radio))
|
||||
continue;
|
||||
|
||||
/*
|
||||
Active added channels should already contain everything this implant
|
||||
has added, so we can simply just add them back.
|
||||
*/
|
||||
channels.UnionWith(radio.ActiveAddedChannels);
|
||||
}
|
||||
}
|
||||
// End DeltaV Additions
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
namespace Content.Server._EE.Silicons.BatteryLocking;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class BatterySlotRequiresLockComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public string ItemSlot = string.Empty;
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
using Content.Shared.Containers.ItemSlots;
|
||||
using Content.Shared.Ghost;
|
||||
using Content.Shared.Lock;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared._EE.Silicon.Components;
|
||||
using Content.Shared.IdentityManagement;
|
||||
|
||||
namespace Content.Server._EE.Silicons.BatteryLocking;
|
||||
|
||||
public sealed class BatterySlotRequiresLockSystem : EntitySystem
|
||||
|
||||
{
|
||||
[Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<BatterySlotRequiresLockComponent, LockToggledEvent>(LockToggled);
|
||||
SubscribeLocalEvent<BatterySlotRequiresLockComponent, LockToggleAttemptEvent>(LockToggleAttempted);
|
||||
|
||||
}
|
||||
private void LockToggled(EntityUid uid, BatterySlotRequiresLockComponent component, LockToggledEvent args)
|
||||
{
|
||||
if (!TryComp<LockComponent>(uid, out var lockComp)
|
||||
|| !TryComp<ItemSlotsComponent>(uid, out var itemslots)
|
||||
|| !_itemSlotsSystem.TryGetSlot(uid, component.ItemSlot, out var slot, itemslots))
|
||||
return;
|
||||
|
||||
_itemSlotsSystem.SetLock(uid, slot, lockComp.Locked, itemslots);
|
||||
}
|
||||
|
||||
private void LockToggleAttempted(EntityUid uid, BatterySlotRequiresLockComponent component, LockToggleAttemptEvent args)
|
||||
{
|
||||
if (args.Cancelled)
|
||||
return;
|
||||
|
||||
if (args.User == uid || !HasComp<SiliconComponent>(uid))
|
||||
return;
|
||||
|
||||
if (HasComp<GhostComponent>(args.User)) // Prevent admin ghosts from triggering popup
|
||||
return;
|
||||
|
||||
_popupSystem.PopupEntity(Loc.GetString("batteryslotrequireslock-component-alert-owner", ("user", Identity.Entity(args.User, EntityManager))), uid, uid, PopupType.Large);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
namespace Content.Server._EE.Silicon.BlindHealing;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class BlindHealingComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public int DoAfterDelay = 3;
|
||||
|
||||
/// <summary>
|
||||
/// A multiplier that will be applied to the above if an entity is repairing themselves.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float SelfHealPenalty = 4f;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not an entity is allowed to repair itself.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool AllowSelfHeal = true;
|
||||
|
||||
[DataField(required: true)]
|
||||
public List<string> DamageContainers;
|
||||
}
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.Cargo.Components;
|
||||
using Content.Server.Stack;
|
||||
using Content.Shared._EE.Silicon.BlindHealing;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Damage.Components;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Eye.Blinding.Components;
|
||||
using Content.Shared.Eye.Blinding.Systems;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Interaction.Events;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Stacks;
|
||||
|
||||
namespace Content.Server._EE.Silicon.BlindHealing;
|
||||
|
||||
public sealed class BlindHealingSystem : SharedBlindHealingSystem
|
||||
{
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||
[Dependency] private readonly BlindableSystem _blindableSystem = default!;
|
||||
[Dependency] private readonly StackSystem _stackSystem = default!;
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<BlindHealingComponent, UseInHandEvent>(OnUse);
|
||||
SubscribeLocalEvent<BlindHealingComponent, AfterInteractEvent>(OnInteract);
|
||||
SubscribeLocalEvent<BlindHealingComponent, HealingDoAfterEvent>(OnHealingFinished);
|
||||
}
|
||||
|
||||
private void OnHealingFinished(EntityUid uid, BlindHealingComponent component, HealingDoAfterEvent args)
|
||||
{
|
||||
if (args.Cancelled || args.Target == null
|
||||
|| !TryComp<BlindableComponent>(args.Target, out var blindComp)
|
||||
|| blindComp is { EyeDamage: 0 })
|
||||
return;
|
||||
|
||||
if (TryComp<StackComponent>(uid, out var stackComponent)
|
||||
&& TryComp<StackPriceComponent>(uid, out var stackPrice))
|
||||
{
|
||||
var count = _stackSystem.GetCount((uid, stackComponent));
|
||||
_stackSystem.SetCount((uid, stackComponent), (int)(count - stackPrice.Price));
|
||||
}
|
||||
|
||||
_blindableSystem.AdjustEyeDamage((args.Target.Value, blindComp), -blindComp.EyeDamage);
|
||||
|
||||
_adminLogger.Add(LogType.Healed, $"{ToPrettyString(args.User):user} repaired {ToPrettyString(uid):target}'s vision");
|
||||
|
||||
var str = Loc.GetString("comp-repairable-repair",
|
||||
("target", uid),
|
||||
("tool", args.Used!));
|
||||
_popup.PopupEntity(str, uid, args.User);
|
||||
|
||||
}
|
||||
|
||||
private bool TryHealBlindness(EntityUid uid, EntityUid user, EntityUid target, float delay)
|
||||
{
|
||||
var doAfterEventArgs =
|
||||
new DoAfterArgs(EntityManager, user, delay, new HealingDoAfterEvent(), uid, target: target, used: uid)
|
||||
{
|
||||
NeedHand = true,
|
||||
BreakOnMove = true,
|
||||
BreakOnWeightlessMove = false,
|
||||
};
|
||||
|
||||
_doAfter.TryStartDoAfter(doAfterEventArgs);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnInteract(EntityUid uid, BlindHealingComponent component, ref AfterInteractEvent args)
|
||||
{
|
||||
|
||||
if (args.Handled
|
||||
|| !TryComp<DamageableComponent>(args.User, out var damageable)
|
||||
|| damageable.DamageContainerID != null && !component.DamageContainers.Contains(damageable.DamageContainerID)
|
||||
|| !TryComp<BlindableComponent>(args.User, out var blindcomp)
|
||||
|| blindcomp.EyeDamage == 0
|
||||
|| args.User == args.Target && !component.AllowSelfHeal)
|
||||
return;
|
||||
|
||||
TryHealBlindness(uid, args.User, args.User,
|
||||
args.User == args.Target
|
||||
? component.DoAfterDelay * component.SelfHealPenalty
|
||||
: component.DoAfterDelay);
|
||||
}
|
||||
|
||||
private void OnUse(EntityUid uid, BlindHealingComponent component, ref UseInHandEvent args)
|
||||
{
|
||||
if (args.Handled
|
||||
|| !TryComp<DamageableComponent>(args.User, out var damageable)
|
||||
|| damageable.DamageContainerID != null && !component.DamageContainers.Contains(damageable.DamageContainerID)
|
||||
|| !TryComp<BlindableComponent>(args.User, out var blindcomp)
|
||||
|| blindcomp.EyeDamage == 0
|
||||
|| !component.AllowSelfHeal)
|
||||
return;
|
||||
|
||||
TryHealBlindness(uid, args.User, args.User,
|
||||
component.DoAfterDelay * component.SelfHealPenalty);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
using Robust.Shared.Audio;
|
||||
|
||||
namespace Content.Server._EE.Silicon.Charge;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class BatteryDrinkerSourceComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The max amount of power this source can provide in one sip.
|
||||
/// No limit if null.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int? MaxAmount = null;
|
||||
|
||||
/// <summary>
|
||||
/// The multiplier for the drink speed.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float DrinkSpeedMulti = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// The sound to play when the battery gets drunk from.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier? DrinkSound = new SoundCollectionSpecifier("sparks");
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.Lightning;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server._DV.Silicons.Charge; // DeltaV - Moved IPC charge to shared and split into server/client
|
||||
using Content.Shared._EE.Silicon.DeadStartupButton;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Electrocution;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Random;
|
||||
using Content.Shared.Damage.Components;
|
||||
using Content.Shared.PowerCell;
|
||||
using Content.Shared.Power.EntitySystems;
|
||||
|
||||
namespace Content.Server._EE.Silicon.DeadStartupButton;
|
||||
|
||||
public sealed class DeadStartupButtonSystem : SharedDeadStartupButtonSystem
|
||||
{
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
[Dependency] private readonly MobThresholdSystem _mobThreshold = default!;
|
||||
[Dependency] private readonly PopupSystem _popup = default!;
|
||||
[Dependency] private readonly IRobustRandom _robustRandom = default!;
|
||||
[Dependency] private readonly LightningSystem _lightning = default!;
|
||||
[Dependency] private readonly SiliconDrainSystem _siliconChargeSystem = default!; // DeltaV - Renamed type from "Charge" to "Drain" to disambiguate
|
||||
[Dependency] private readonly PowerCellSystem _powerCell = default!;
|
||||
[Dependency] private readonly SharedBatterySystem _battery = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<DeadStartupButtonComponent, OnDoAfterButtonPressedEvent>(OnDoAfter);
|
||||
SubscribeLocalEvent<DeadStartupButtonComponent, ElectrocutedEvent>(OnElectrocuted);
|
||||
SubscribeLocalEvent<DeadStartupButtonComponent, MobStateChangedEvent>(OnMobStateChanged);
|
||||
|
||||
}
|
||||
|
||||
private void OnDoAfter(EntityUid uid, DeadStartupButtonComponent comp, OnDoAfterButtonPressedEvent args)
|
||||
{
|
||||
if (args.Handled || args.Cancelled
|
||||
|| !TryComp<MobStateComponent>(uid, out var mobStateComponent)
|
||||
|| !_mobState.IsDead(uid, mobStateComponent)
|
||||
|| !TryComp<MobThresholdsComponent>(uid, out var mobThresholdsComponent)
|
||||
|| !TryComp<DamageableComponent>(uid, out var damageable)
|
||||
|| !_mobThreshold.TryGetThresholdForState(uid, MobState.Critical, out var criticalThreshold, mobThresholdsComponent))
|
||||
return;
|
||||
|
||||
if (damageable.TotalDamage < criticalThreshold)
|
||||
_mobState.ChangeMobState(uid, MobState.Alive, mobStateComponent);
|
||||
else
|
||||
{
|
||||
_audio.PlayPvs(comp.BuzzSound, uid, AudioParams.Default.WithVariation(0.05f));
|
||||
_popup.PopupEntity(Loc.GetString("dead-startup-system-reboot-failed", ("target", MetaData(uid).EntityName)), uid);
|
||||
Spawn("EffectSparks", Transform(uid).Coordinates);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnElectrocuted(EntityUid uid, DeadStartupButtonComponent comp, ElectrocutedEvent args)
|
||||
{
|
||||
if (!TryComp<MobStateComponent>(uid, out var mobStateComponent)
|
||||
|| !_mobState.IsDead(uid, mobStateComponent)
|
||||
|| !_siliconChargeSystem.TryGetSiliconBattery(uid, out var bateria))
|
||||
return;
|
||||
|
||||
var charge = _battery.GetCharge(bateria.Value.AsNullable());
|
||||
if (charge <= 0)
|
||||
return;
|
||||
|
||||
_lightning.ShootRandomLightnings(uid, 2, 4);
|
||||
_powerCell.TryUseCharge(uid, charge);
|
||||
|
||||
}
|
||||
|
||||
private void OnMobStateChanged(EntityUid uid, DeadStartupButtonComponent comp, MobStateChangedEvent args)
|
||||
{
|
||||
if (args.NewMobState != MobState.Alive)
|
||||
return;
|
||||
|
||||
_popup.PopupEntity(Loc.GetString("dead-startup-system-reboot-success", ("target", MetaData(uid).EntityName)), uid);
|
||||
_audio.PlayPvs(comp.Sound, uid);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
namespace Content.Server._EE.Silicon.Death;
|
||||
|
||||
/// <summary>
|
||||
/// Marks a Silicon as becoming incapacitated when they run out of battery charge.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Uses the Silicon System's charge states to do so, so make sure they're a battery powered Silicon.
|
||||
/// </remarks>
|
||||
[RegisterComponent]
|
||||
public sealed partial class SiliconDownOnDeadComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Is this Silicon currently dead?
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
public bool Dead;
|
||||
}
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
using Content.Shared.Power.Components;
|
||||
using Content.Shared._EE.Silicon.Systems;
|
||||
using Content.Shared.Bed.Sleep;
|
||||
using Content.Server._DV.Silicons.Charge; // DeltaV - Moved IPC charge to shared and split into server/client
|
||||
using Content.Server.Humanoid;
|
||||
using Content.Shared.Humanoid;
|
||||
|
||||
namespace Content.Server._EE.Silicon.Death;
|
||||
|
||||
public sealed class SiliconDeathSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SleepingSystem _sleep = default!;
|
||||
[Dependency] private readonly SiliconDrainSystem _silicon = default!; // DeltaV - Renamed type from "Charge" to "Drain" to disambiguate
|
||||
[Dependency] private readonly HumanoidAppearanceSystem _humanoidAppearanceSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<SiliconDownOnDeadComponent, SiliconChargeStateUpdateEvent>(OnSiliconChargeStateUpdate);
|
||||
}
|
||||
|
||||
private void OnSiliconChargeStateUpdate(EntityUid uid, SiliconDownOnDeadComponent siliconDeadComp, SiliconChargeStateUpdateEvent args)
|
||||
{
|
||||
if (!_silicon.TryGetSiliconBattery(uid, out var batteryComp))
|
||||
{
|
||||
SiliconDead(uid, siliconDeadComp, batteryComp, uid);
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.ChargePercent == 0 && siliconDeadComp.Dead)
|
||||
return;
|
||||
|
||||
if (args.ChargePercent == 0 && !siliconDeadComp.Dead)
|
||||
SiliconDead(uid, siliconDeadComp, batteryComp, uid);
|
||||
else if (args.ChargePercent != 0 && siliconDeadComp.Dead)
|
||||
SiliconUnDead(uid, siliconDeadComp, batteryComp, uid);
|
||||
}
|
||||
|
||||
private void SiliconDead(EntityUid uid, SiliconDownOnDeadComponent siliconDeadComp, BatteryComponent? batteryComp, EntityUid batteryUid)
|
||||
{
|
||||
var deadEvent = new SiliconChargeDyingEvent(uid, batteryComp, batteryUid);
|
||||
RaiseLocalEvent(uid, deadEvent);
|
||||
|
||||
if (deadEvent.Cancelled)
|
||||
return;
|
||||
|
||||
EntityManager.EnsureComponent<SleepingComponent>(uid);
|
||||
EntityManager.EnsureComponent<ForcedSleepingStatusEffectComponent>(uid);
|
||||
|
||||
if (TryComp(uid, out HumanoidAppearanceComponent? humanoidAppearanceComponent))
|
||||
{
|
||||
var layers = HumanoidVisualLayersExtension.Sublayers(HumanoidVisualLayers.HeadSide);
|
||||
_humanoidAppearanceSystem.SetLayersVisibility((uid, humanoidAppearanceComponent), layers, visible: false);
|
||||
}
|
||||
|
||||
siliconDeadComp.Dead = true;
|
||||
|
||||
RaiseLocalEvent(uid, new SiliconChargeDeathEvent(uid, batteryComp, batteryUid));
|
||||
}
|
||||
|
||||
private void SiliconUnDead(EntityUid uid, SiliconDownOnDeadComponent siliconDeadComp, BatteryComponent? batteryComp, EntityUid batteryUid)
|
||||
{
|
||||
RemComp<ForcedSleepingStatusEffectComponent>(uid);
|
||||
_sleep.TryWaking(uid, true, null);
|
||||
|
||||
siliconDeadComp.Dead = false;
|
||||
|
||||
RaiseLocalEvent(uid, new SiliconChargeAliveEvent(uid, batteryComp, batteryUid));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A cancellable event raised when a Silicon is about to go down due to charge.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This probably shouldn't be modified unless you intend to fill the Silicon's battery,
|
||||
/// as otherwise it'll just be triggered again next frame.
|
||||
/// </remarks>
|
||||
public sealed class SiliconChargeDyingEvent : CancellableEntityEventArgs
|
||||
{
|
||||
public EntityUid SiliconUid { get; }
|
||||
public BatteryComponent? BatteryComp { get; }
|
||||
public EntityUid BatteryUid { get; }
|
||||
|
||||
public SiliconChargeDyingEvent(EntityUid siliconUid, BatteryComponent? batteryComp, EntityUid batteryUid)
|
||||
{
|
||||
SiliconUid = siliconUid;
|
||||
BatteryComp = batteryComp;
|
||||
BatteryUid = batteryUid;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An event raised after a Silicon has gone down due to charge.
|
||||
/// </summary>
|
||||
public sealed class SiliconChargeDeathEvent : EntityEventArgs
|
||||
{
|
||||
public EntityUid SiliconUid { get; }
|
||||
public BatteryComponent? BatteryComp { get; }
|
||||
public EntityUid BatteryUid { get; }
|
||||
|
||||
public SiliconChargeDeathEvent(EntityUid siliconUid, BatteryComponent? batteryComp, EntityUid batteryUid)
|
||||
{
|
||||
SiliconUid = siliconUid;
|
||||
BatteryComp = batteryComp;
|
||||
BatteryUid = batteryUid;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An event raised after a Silicon has reawoken due to an increase in charge.
|
||||
/// </summary>
|
||||
public sealed class SiliconChargeAliveEvent : EntityEventArgs
|
||||
{
|
||||
public EntityUid SiliconUid { get; }
|
||||
public BatteryComponent? BatteryComp { get; }
|
||||
public EntityUid BatteryUid { get; }
|
||||
|
||||
public SiliconChargeAliveEvent(EntityUid siliconUid, BatteryComponent? batteryComp, EntityUid batteryUid)
|
||||
{
|
||||
SiliconUid = siliconUid;
|
||||
BatteryComp = batteryComp;
|
||||
BatteryUid = batteryUid;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
using Content.Server.Popups;
|
||||
using Content.Shared._EE.Silicon.EmitBuzzWhileDamaged;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Damage.Components;
|
||||
|
||||
namespace Content.Server._EE.Silicon.EmitBuzzOnCrit;
|
||||
|
||||
/// <summary>
|
||||
/// This handles the buzzing popup and sound of a silicon based race when it is pretty damaged.
|
||||
/// </summary>
|
||||
public sealed class EmitBuzzWhileDamagedSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
[Dependency] private readonly MobThresholdSystem _mobThreshold = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly IRobustRandom _robustRandom = default!;
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
var query = EntityQueryEnumerator<EmitBuzzWhileDamagedComponent, MobStateComponent, MobThresholdsComponent, DamageableComponent>();
|
||||
|
||||
while (query.MoveNext(out var uid, out var emitBuzzOnCritComponent, out var mobStateComponent, out var thresholdsComponent, out var damageableComponent))
|
||||
{
|
||||
|
||||
if (_mobState.IsDead(uid, mobStateComponent)
|
||||
|| !_mobThreshold.TryGetThresholdForState(uid, MobState.Critical, out var threshold, thresholdsComponent)
|
||||
|| damageableComponent.TotalDamage < threshold / 2)
|
||||
continue;
|
||||
|
||||
emitBuzzOnCritComponent.AccumulatedFrametime += frameTime;
|
||||
|
||||
if (emitBuzzOnCritComponent.AccumulatedFrametime < emitBuzzOnCritComponent.CycleDelay)
|
||||
continue;
|
||||
|
||||
emitBuzzOnCritComponent.AccumulatedFrametime -= emitBuzzOnCritComponent.CycleDelay;
|
||||
|
||||
if (_gameTiming.CurTime <= emitBuzzOnCritComponent.LastBuzzPopupTime + emitBuzzOnCritComponent.BuzzPopupCooldown)
|
||||
continue;
|
||||
|
||||
// Start buzzing
|
||||
emitBuzzOnCritComponent.LastBuzzPopupTime = _gameTiming.CurTime;
|
||||
_popupSystem.PopupEntity(Loc.GetString("silicon-behavior-buzz"), uid);
|
||||
Spawn("EffectSparks", Transform(uid).Coordinates);
|
||||
_audio.PlayPvs(emitBuzzOnCritComponent.Sound, uid, AudioHelpers.WithVariation(0.05f, _robustRandom));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
namespace Content.Server._EE.Silicon.EncryptionHolderRequiresLock;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class EncryptionHolderRequiresLockComponent : Component
|
||||
{
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
using Content.Shared.Lock;
|
||||
using Content.Shared.Radio.Components;
|
||||
using Content.Shared.Radio.EntitySystems;
|
||||
|
||||
namespace Content.Server._EE.Silicon.EncryptionHolderRequiresLock;
|
||||
|
||||
public sealed class EncryptionHolderRequiresLockSystem : EntitySystem
|
||||
|
||||
{
|
||||
[Dependency] private readonly EncryptionKeySystem _encryptionKeySystem = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<EncryptionHolderRequiresLockComponent, LockToggledEvent>(LockToggled);
|
||||
|
||||
}
|
||||
private void LockToggled(EntityUid uid, EncryptionHolderRequiresLockComponent component, LockToggledEvent args)
|
||||
{
|
||||
if (!TryComp<LockComponent>(uid, out var lockComp)
|
||||
|| !TryComp<EncryptionKeyHolderComponent>(uid, out var keyHolder))
|
||||
return;
|
||||
|
||||
keyHolder.KeysUnlocked = !lockComp.Locked;
|
||||
Dirty(uid, keyHolder); // DeltaV
|
||||
_encryptionKeySystem.UpdateChannels(uid, keyHolder);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
using Robust.Shared.Audio;
|
||||
|
||||
namespace Content.Server._EE.Silicon;
|
||||
|
||||
/// <summary>
|
||||
/// Applies a <see cref="SpamEmitSoundComponent"/> to a Silicon when its battery is drained, and removes it when it's not.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class SiliconEmitSoundOnDrainedComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public SoundSpecifier Sound = default!;
|
||||
|
||||
[DataField]
|
||||
public TimeSpan MinInterval = TimeSpan.FromSeconds(8);
|
||||
|
||||
[DataField]
|
||||
public TimeSpan MaxInterval = TimeSpan.FromSeconds(15);
|
||||
|
||||
[DataField]
|
||||
public float PlayChance = 1f;
|
||||
|
||||
[DataField]
|
||||
public string? PopUp;
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
using Content.Server._EE.Silicon.Death;
|
||||
using Content.Shared.Sound.Components;
|
||||
using Content.Server.Sound;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared._EE.Silicon.Systems;
|
||||
|
||||
namespace Content.Server._EE.Silicon;
|
||||
|
||||
public sealed class EmitSoundOnCritSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly EmitSoundSystem _emitSound = default!;
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<SiliconEmitSoundOnDrainedComponent, SiliconChargeDeathEvent>(OnDeath);
|
||||
SubscribeLocalEvent<SiliconEmitSoundOnDrainedComponent, SiliconChargeAliveEvent>(OnAlive);
|
||||
SubscribeLocalEvent<SiliconEmitSoundOnDrainedComponent, MobStateChangedEvent>(OnStateChange);
|
||||
}
|
||||
|
||||
private void OnDeath(EntityUid uid, SiliconEmitSoundOnDrainedComponent component, SiliconChargeDeathEvent args)
|
||||
{
|
||||
var spamComp = EnsureComp<SpamEmitSoundComponent>(uid);
|
||||
|
||||
spamComp.MinInterval = component.MinInterval;
|
||||
spamComp.MaxInterval = component.MaxInterval;
|
||||
spamComp.PopUp = component.PopUp;
|
||||
spamComp.Sound = component.Sound;
|
||||
_emitSound.SetEnabled((uid, spamComp), true);
|
||||
}
|
||||
|
||||
private void OnAlive(EntityUid uid, SiliconEmitSoundOnDrainedComponent component, SiliconChargeAliveEvent args)
|
||||
{
|
||||
RemComp<SpamEmitSoundComponent>(uid); // This component is bad and I don't feel like making a janky work around because of it.
|
||||
// If you give something the SiliconEmitSoundOnDrainedComponent, know that it can't have the SpamEmitSoundComponent, and any other systems that play with it will just be broken.
|
||||
}
|
||||
|
||||
public void OnStateChange(EntityUid uid, SiliconEmitSoundOnDrainedComponent component, MobStateChangedEvent args)
|
||||
{
|
||||
if (args.NewMobState != MobState.Dead)
|
||||
return;
|
||||
|
||||
RemComp<SpamEmitSoundComponent>(uid);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
using Content.Shared.Damage;
|
||||
using Content.Shared.Tools;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
namespace Content.Server._EE.Silicon.WeldingHealable
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed partial class WeldingHealableComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// DeltaV: Disables self-healing with any type of WeldingHealing item.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool AllowSelfHeal = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,125 +0,0 @@
|
|||
using Content.Server._EE.Silicon.WeldingHealing;
|
||||
using Content.Server.Body.Systems; // DeltaV
|
||||
using Content.Shared.Tools.Components;
|
||||
using Content.Shared._EE.Silicon.WeldingHealing;
|
||||
using Content.Shared.Chemistry.Components.SolutionManager;
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Shared.Damage.Components;
|
||||
using Content.Shared.Damage.Systems;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Tools;
|
||||
using Content.Shared._Shitmed.Targeting;
|
||||
using Content.Shared.Body.Systems;
|
||||
using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem;
|
||||
|
||||
namespace Content.Server._EE.Silicon.WeldingHealable;
|
||||
|
||||
public sealed class WeldingHealableSystem : SharedWeldingHealableSystem
|
||||
{
|
||||
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
|
||||
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!;
|
||||
[Dependency] private readonly BloodstreamSystem _bloodstream = default!; // DeltaV
|
||||
|
||||
[Dependency] private readonly SharedBodySystem _bodySystem = default!;
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<WeldingHealableComponent, InteractUsingEvent>(Repair);
|
||||
SubscribeLocalEvent<WeldingHealableComponent, SiliconRepairFinishedEvent>(OnRepairFinished);
|
||||
}
|
||||
|
||||
private void OnRepairFinished(EntityUid uid, WeldingHealableComponent healableComponent, SiliconRepairFinishedEvent args)
|
||||
{
|
||||
if (args.Cancelled || args.Used == null
|
||||
|| !TryComp<DamageableComponent>(args.Target, out var damageable)
|
||||
|| !TryComp<WeldingHealingComponent>(args.Used, out var component)
|
||||
|| damageable.DamageContainerID is null
|
||||
|| !component.DamageContainers.Contains(damageable.DamageContainerID)
|
||||
|| !HasDamage((args.Target.Value, damageable), component, args.User)
|
||||
|| !TryComp<WelderComponent>(args.Used, out var welder)
|
||||
|| !TryComp<SolutionContainerManagerComponent>(args.Used, out var solutionContainer)
|
||||
|| !_solutionContainer.TryGetSolution(((EntityUid) args.Used, solutionContainer), welder.FuelSolutionName, out var solution))
|
||||
return;
|
||||
|
||||
_damageableSystem.TryChangeDamage(uid, component.Damage, true, false, origin: args.User);
|
||||
|
||||
_solutionContainer.RemoveReagent(solution.Value, welder.FuelReagent, component.FuelCost);
|
||||
|
||||
// Begin DeltaV Additions - stop bleeding on weld
|
||||
if (component.bleedingModifier != 0)
|
||||
{
|
||||
_bloodstream.TryModifyBleedAmount(uid, component.bleedingModifier);
|
||||
}
|
||||
// End DeltaV Additions
|
||||
|
||||
var str = Loc.GetString("comp-repairable-repair",
|
||||
("target", uid),
|
||||
("tool", args.Used!));
|
||||
_popup.PopupEntity(str, uid, args.User);
|
||||
|
||||
if (!args.Used.HasValue)
|
||||
return;
|
||||
|
||||
args.Handled = _toolSystem.UseTool
|
||||
(args.Used.Value,
|
||||
args.User,
|
||||
uid,
|
||||
args.Delay,
|
||||
component.QualityNeeded,
|
||||
new SiliconRepairFinishedEvent
|
||||
{
|
||||
Delay = args.Delay
|
||||
});
|
||||
}
|
||||
private async void Repair(EntityUid uid, WeldingHealableComponent healableComponent, InteractUsingEvent args)
|
||||
{
|
||||
if (args.Handled
|
||||
|| !EntityManager.TryGetComponent(args.Used, out WeldingHealingComponent? component)
|
||||
|| !EntityManager.TryGetComponent(args.Target, out DamageableComponent? damageable)
|
||||
|| damageable.DamageContainerID is null
|
||||
|| !component.DamageContainers.Contains(damageable.DamageContainerID)
|
||||
|| !HasDamage((args.Target, damageable), component, args.User)
|
||||
|| !_toolSystem.HasQuality(args.Used, component.QualityNeeded)
|
||||
|| args.User == args.Target && !(component.AllowSelfHeal && healableComponent.AllowSelfHeal)) // DeltaV - self heal disabled by WeldingHealable
|
||||
return;
|
||||
|
||||
float delay = args.User == args.Target
|
||||
? component.DoAfterDelay * component.SelfHealPenalty
|
||||
: component.DoAfterDelay;
|
||||
|
||||
args.Handled = _toolSystem.UseTool
|
||||
(args.Used,
|
||||
args.User,
|
||||
args.Target,
|
||||
delay,
|
||||
component.QualityNeeded,
|
||||
new SiliconRepairFinishedEvent
|
||||
{
|
||||
Delay = delay,
|
||||
});
|
||||
}
|
||||
|
||||
private bool HasDamage(Entity<DamageableComponent> damageable, WeldingHealingComponent healable, EntityUid user)
|
||||
{
|
||||
if (healable.Damage.DamageDict is null)
|
||||
return false;
|
||||
|
||||
foreach (var type in healable.Damage.DamageDict)
|
||||
if (damageable.Comp.Damage.DamageDict[type.Key].Value > 0)
|
||||
return true;
|
||||
|
||||
// In case the healer is a humanoid entity with targeting, we run the check on the targeted parts.
|
||||
if (!TryComp(user, out TargetingComponent? targeting))
|
||||
return false;
|
||||
var (targetType, targetSymmetry) = _bodySystem.ConvertTargetBodyPart(targeting.Target);
|
||||
foreach (var part in _bodySystem.GetBodyChildrenOfType(damageable, targetType, symmetry: targetSymmetry))
|
||||
if (TryComp<DamageableComponent>(part.Id, out var damageablePart))
|
||||
foreach (var type in healable.Damage.DamageDict)
|
||||
if (damageablePart.Damage.DamageDict[type.Key].Value > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
using Content.Shared.Damage;
|
||||
using Content.Shared.Tools;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
namespace Content.Server._EE.Silicon.WeldingHealing
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed partial class WeldingHealingComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// All the damage to change information is stored in this <see cref="DamageSpecifier"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If this data-field is specified, it will change damage by this amount instead of setting all damage to 0.
|
||||
/// in order to heal/repair the damage values have to be negative.
|
||||
/// </remarks>
|
||||
|
||||
[DataField(required: true)]
|
||||
public DamageSpecifier Damage;
|
||||
|
||||
/// <summary>
|
||||
/// DeltaV: Modifies bleeding stacks by this after welding.
|
||||
/// This should generally be negative.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float bleedingModifier = 0.0f;
|
||||
|
||||
[DataField(customTypeSerializer:typeof(PrototypeIdSerializer<ToolQualityPrototype>))]
|
||||
public string QualityNeeded = "Welding";
|
||||
|
||||
/// <summary>
|
||||
/// The fuel amount needed to repair physical related damage
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int FuelCost = 15;
|
||||
|
||||
[DataField]
|
||||
public int DoAfterDelay = 3;
|
||||
|
||||
/// <summary>
|
||||
/// A multiplier that will be applied to the above if an entity is repairing themselves.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float SelfHealPenalty = 4f;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not an entity is allowed to repair itself.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool AllowSelfHeal = true;
|
||||
|
||||
[DataField(required: true)]
|
||||
public List<string> DamageContainers;
|
||||
}
|
||||
}
|
||||
|
|
@ -34,7 +34,6 @@ using Robust.Shared.Audio.Systems;
|
|||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Utility;
|
||||
using Content.Shared._EE.Silicon.Components;
|
||||
using Content.Shared.StatusEffectNew; // DeltaV - Clause status effects
|
||||
|
||||
namespace Content.Server._Goobstation.Devil.Contract;
|
||||
|
|
@ -238,7 +237,6 @@ public sealed partial class DevilContractSystem : EntitySystem
|
|||
public bool IsUserValid(EntityUid user, out string failReason)
|
||||
{
|
||||
if (HasComp<CondemnedComponent>(user)
|
||||
|| HasComp<SiliconComponent>(user)
|
||||
|| HasComp<BorgChassisComponent>(user))
|
||||
{
|
||||
failReason = Loc.GetString("devil-contract-no-soul-sign-failed");
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@ using Robust.Shared.Random;
|
|||
using Robust.Shared.Timing;
|
||||
using Content.Shared.Body.Part;
|
||||
using Content.Server.Bible.Components;
|
||||
using Content.Shared._EE.Silicon.Components;
|
||||
|
||||
namespace Content.Server._Goobstation.Devil;
|
||||
|
||||
|
|
@ -215,7 +214,6 @@ public sealed partial class DevilSystem : EntitySystem
|
|||
// Other Devils and entities without souls have no authority over you.
|
||||
if (HasComp<DevilComponent>(args.Source)
|
||||
|| HasComp<CondemnedComponent>(args.Source)
|
||||
|| HasComp<SiliconComponent>(args.Source)
|
||||
|| args.Source == devil.Owner)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
using Content.Shared.Atmos;
|
||||
|
||||
namespace Content.Server._Goobstation.Temperature;
|
||||
|
||||
/// <summary>
|
||||
/// Kills an entity when its temperature goes over a threshold.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(KillOnOverheatSystem))]
|
||||
public sealed partial class KillOnOverheatComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public float OverheatThreshold = Atmospherics.T0C + 110f;
|
||||
|
||||
[DataField]
|
||||
public LocId OverheatPopup = "ipc-overheat-popup";
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
using Content.Shared.Temperature.Components;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Popups;
|
||||
|
||||
namespace Content.Server._Goobstation.Temperature;
|
||||
|
||||
public sealed class KillOnOverheatSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly MobStateSystem _mob = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
var query = EntityQueryEnumerator<KillOnOverheatComponent, TemperatureComponent, MobStateComponent>();
|
||||
while (query.MoveNext(out var uid, out var comp, out var temp, out var mob))
|
||||
{
|
||||
if (mob.CurrentState == MobState.Dead || temp.CurrentTemperature < comp.OverheatThreshold)
|
||||
continue;
|
||||
|
||||
var msg = Loc.GetString(comp.OverheatPopup, ("name", Identity.Name(uid, EntityManager)));
|
||||
_popup.PopupEntity(msg, uid, PopupType.LargeCaution);
|
||||
_mob.ChangeMobState(uid, MobState.Dead, mob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
using Content.Shared._EE.Silicon.Components; // Goobstation
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Bed.Components;
|
||||
using Content.Shared.Bed.Sleep;
|
||||
|
|
@ -151,8 +150,7 @@ public sealed class BedSystem : EntitySystem
|
|||
|
||||
foreach (var healedEntity in strapComponent.BuckledEntities)
|
||||
{
|
||||
if (_mobStateSystem.IsDead(healedEntity)
|
||||
|| HasComp<SiliconComponent>(healedEntity)) // Goobstation)
|
||||
if (_mobStateSystem.IsDead(healedEntity))
|
||||
continue;
|
||||
|
||||
var damage = bedComponent.Damage;
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ public partial class SharedBodySystem
|
|||
cameFromEntities[connection] = childPart;
|
||||
|
||||
var childPartComponent = Comp<BodyPartComponent>(childPart);
|
||||
TryCreatePartSlot(parentEntity, connection, childPartComponent.PartType, out var partSlot, parentPartComponent);
|
||||
var partSlot = CreatePartSlot(parentEntity, connection, childPartComponent.PartType, parentPartComponent);
|
||||
// Shitmed Change Start
|
||||
childPartComponent.ParentSlot = partSlot;
|
||||
Dirty(childPart, childPartComponent);
|
||||
|
|
@ -214,7 +214,7 @@ public partial class SharedBodySystem
|
|||
{
|
||||
foreach (var (organSlotId, organProto) in organs)
|
||||
{
|
||||
TryCreateOrganSlot(ent, organSlotId, out var slot); // Shitmed Change
|
||||
var slot = CreateOrganSlot((ent, ent), organSlotId);
|
||||
SpawnInContainerOrDrop(organProto, ent, GetOrganContainerId(organSlotId));
|
||||
|
||||
if (slot is null)
|
||||
|
|
|
|||
|
|
@ -115,13 +115,7 @@ public partial class SharedBodySystem
|
|||
|
||||
Containers.EnsureContainer<ContainerSlot>(parent.Value, GetOrganContainerId(slotId));
|
||||
slot = new OrganSlot(slotId);
|
||||
// Shitmed Change Start
|
||||
if (!part.Organs.ContainsKey(slotId)
|
||||
&& !part.Organs.TryAdd(slotId, slot.Value))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
// Shitmed Change End
|
||||
return part.Organs.TryAdd(slotId, slot.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -530,8 +530,7 @@ public partial class SharedBodySystem
|
|||
Containers.EnsureContainer<ContainerSlot>(partId.Value, GetPartSlotContainerId(slotId));
|
||||
slot = new BodyPartSlot(slotId, partType);
|
||||
|
||||
if (!part.Children.ContainsKey(slotId) // Shitmed Change
|
||||
&& !part.Children.TryAdd(slotId, slot.Value))
|
||||
if (!part.Children.TryAdd(slotId, slot.Value))
|
||||
return false;
|
||||
|
||||
Dirty(partId.Value, part);
|
||||
|
|
|
|||
|
|
@ -37,11 +37,4 @@ public sealed partial class CCVars : CVars
|
|||
/// </summary>
|
||||
public static readonly CVarDef<bool> DebugPow3rDisableParallel =
|
||||
CVarDef.Create("debug.pow3r_disable_parallel", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Goobstation: The amount of time between NPC Silicons draining their battery in seconds.
|
||||
/// TODO: Move this to the proper file. I dunno which, just not the main one.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> SiliconNpcUpdateTime =
|
||||
CVarDef.Create("silicon.npcupdatetime", 1.5f, CVar.SERVER | CVar.REPLICATED); // DeltaV - Move IPC charge to shared
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,14 +24,12 @@ namespace Content.Shared.Electrocution
|
|||
public readonly EntityUid TargetUid;
|
||||
public readonly EntityUid? SourceUid;
|
||||
public readonly float SiemensCoefficient;
|
||||
public readonly float? ShockDamage = null; // Goobstation
|
||||
|
||||
public ElectrocutedEvent(EntityUid targetUid, EntityUid? sourceUid, float siemensCoefficient, float shockDamage) // Goobstation
|
||||
public ElectrocutedEvent(EntityUid targetUid, EntityUid? sourceUid, float siemensCoefficient)
|
||||
{
|
||||
TargetUid = targetUid;
|
||||
SourceUid = sourceUid;
|
||||
SiemensCoefficient = siemensCoefficient;
|
||||
ShockDamage = shockDamage; // Goobstation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,9 +43,6 @@ namespace Content.Shared.Humanoid
|
|||
case SpeciesNaming.FirstDashFirst:
|
||||
return Loc.GetString("namepreset-firstdashfirst",
|
||||
("first1", GetFirstName(speciesProto, gender)), ("first2", GetFirstName(speciesProto, gender)));
|
||||
case SpeciesNaming.FirstDashLast: // Goobstation
|
||||
return Loc.GetString("namepreset-firstdashlast",
|
||||
("first", GetFirstName(speciesProto, gender)), ("last", GetLastName(speciesProto)));
|
||||
case SpeciesNaming.LastFirst: // DeltaV: Rodentia name scheme
|
||||
return Loc.GetString("namepreset-lastfirst",
|
||||
("last", GetLastName(speciesProto)), ("first", GetFirstName(speciesProto, gender)));
|
||||
|
|
|
|||
|
|
@ -180,5 +180,4 @@ public enum SpeciesNaming : byte
|
|||
//End of Nyano - Summary: for Oni naming
|
||||
TheFirstofLast,
|
||||
LastFirst, // DeltaV
|
||||
FirstDashLast, // Goobstation
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,16 +22,6 @@ using Robust.Shared.Network;
|
|||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
// Goobstation Change
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared._Goobstation.CCVar;
|
||||
using Content.Shared.Weapons.Ranged.Events;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.Inventory.VirtualItem;
|
||||
using Robust.Shared.Configuration;
|
||||
using Content.Shared.Implants.Components;
|
||||
|
||||
namespace Content.Shared.Mech.EntitySystems;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -50,12 +40,6 @@ public abstract partial class SharedMechSystem : EntitySystem
|
|||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
[Dependency] private readonly SharedHandsSystem _hands = default!; // Goobstation Change
|
||||
[Dependency] private readonly SharedVirtualItemSystem _virtualItem = default!; // Goobstation Change
|
||||
[Dependency] private readonly IConfigurationManager _config = default!; // Goobstation Change
|
||||
|
||||
// Goobstation: Local variable for checking if mech guns can be used out of them.
|
||||
private bool _canUseMechGunOutside;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
|
|
@ -74,8 +58,6 @@ public abstract partial class SharedMechSystem : EntitySystem
|
|||
SubscribeLocalEvent<MechPilotComponent, CanAttackFromContainerEvent>(OnCanAttackFromContainer);
|
||||
SubscribeLocalEvent<MechPilotComponent, AttackAttemptEvent>(OnAttackAttempt);
|
||||
SubscribeLocalEvent<MechPilotComponent, EntGotRemovedFromContainerMessage>(OnEntGotRemovedFromContainer);
|
||||
SubscribeLocalEvent<MechEquipmentComponent, ShotAttemptedEvent>(OnShotAttempted); // Goobstation
|
||||
Subs.CVar(_config, GoobCVars.MechGunOutsideMech, value => _canUseMechGunOutside = value, true); // Goobstation
|
||||
|
||||
InitializeRelay();
|
||||
}
|
||||
|
|
@ -410,10 +392,10 @@ public abstract partial class SharedMechSystem : EntitySystem
|
|||
SetupUser(uid, toInsert.Value);
|
||||
_container.Insert(toInsert.Value, component.PilotSlot);
|
||||
UpdateAppearance(uid, component);
|
||||
UpdateHands(toInsert.Value, uid, true); // Goobstation
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to eject the current pilot from the mech
|
||||
/// </summary>
|
||||
|
|
@ -435,49 +417,9 @@ public abstract partial class SharedMechSystem : EntitySystem
|
|||
RemoveUser(uid, pilot.Value);
|
||||
_container.RemoveEntity(uid, pilot.Value);
|
||||
UpdateAppearance(uid, component);
|
||||
UpdateHands(pilot.Value, uid, false); // Goobstation
|
||||
return true;
|
||||
}
|
||||
|
||||
// Goobstation Change Start
|
||||
private void UpdateHands(EntityUid uid, EntityUid mech, bool active)
|
||||
{
|
||||
if (!TryComp<HandsComponent>(uid, out var handsComponent))
|
||||
return;
|
||||
if (active)
|
||||
BlockHands(uid, mech, handsComponent);
|
||||
else
|
||||
FreeHands(uid, mech);
|
||||
}
|
||||
private void BlockHands(EntityUid uid, EntityUid mech, HandsComponent handsComponent)
|
||||
{
|
||||
var freeHands = 0;
|
||||
foreach (var hand in _hands.EnumerateHands((uid, handsComponent)))
|
||||
{
|
||||
var heldEnt = _hands.GetHeldItem((uid, handsComponent), hand); // DV - hand refactor fixes
|
||||
if (heldEnt == null)
|
||||
{
|
||||
freeHands++;
|
||||
continue;
|
||||
}
|
||||
// Is this entity removable? (they might have handcuffs on)
|
||||
if (HasComp<UnremoveableComponent>(heldEnt) && heldEnt != mech)
|
||||
continue;
|
||||
_hands.DoDrop((uid, handsComponent), hand, true); // DV - hand refactor fixes
|
||||
freeHands++;
|
||||
if (freeHands == 2)
|
||||
break;
|
||||
}
|
||||
if (_virtualItem.TrySpawnVirtualItemInHand(mech, uid, out var virtItem1))
|
||||
EnsureComp<UnremoveableComponent>(virtItem1.Value);
|
||||
if (_virtualItem.TrySpawnVirtualItemInHand(mech, uid, out var virtItem2))
|
||||
EnsureComp<UnremoveableComponent>(virtItem2.Value);
|
||||
}
|
||||
private void FreeHands(EntityUid uid, EntityUid mech)
|
||||
{
|
||||
_virtualItem.DeleteInHandsMatching(uid, mech);
|
||||
}
|
||||
// Goobstation Change End
|
||||
private void OnGetMeleeWeapon(EntityUid uid, MechPilotComponent component, GetMeleeWeaponEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
|
|
@ -502,20 +444,6 @@ public abstract partial class SharedMechSystem : EntitySystem
|
|||
args.Cancel();
|
||||
}
|
||||
|
||||
// Goobstation: Prevent guns being used out of mechs if CCVAR is set.
|
||||
private void OnShotAttempted(EntityUid uid, MechEquipmentComponent component, ref ShotAttemptedEvent args)
|
||||
{
|
||||
if (!component.EquipmentOwner.HasValue
|
||||
|| !HasComp<MechComponent>(component.EquipmentOwner.Value))
|
||||
{
|
||||
if (!_canUseMechGunOutside)
|
||||
args.Cancel();
|
||||
return;
|
||||
}
|
||||
var ev = new HandleMechEquipmentBatteryEvent();
|
||||
RaiseLocalEvent(uid, ev);
|
||||
}
|
||||
|
||||
private void UpdateAppearance(EntityUid uid, MechComponent? component = null,
|
||||
AppearanceComponent? appearance = null)
|
||||
{
|
||||
|
|
@ -575,12 +503,3 @@ public sealed partial class MechExitEvent : SimpleDoAfterEvent
|
|||
public sealed partial class MechEntryEvent : SimpleDoAfterEvent
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Event raised when an user attempts to fire a mech weapon to check if its battery is drained
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class HandleMechEquipmentBatteryEvent : EntityEventArgs
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Shared._DV.Mind; // DeltaV
|
||||
using Content.Shared._EE.Silicon.Components; // Goobstation
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Emoting;
|
||||
|
|
@ -612,7 +611,7 @@ public abstract partial class SharedMindSystem : EntitySystem
|
|||
/// Returns a list of every living humanoid player's minds, except for a single one which is exluded.
|
||||
/// A new hashset is allocated for every call, consider using <see cref="AddAliveHumans"/> instead.
|
||||
/// </summary>
|
||||
public HashSet<Entity<MindComponent>> GetAliveHumans(EntityUid? exclude = null, bool excludeSilicon = false) // Goobstation - Add excludeSilicon
|
||||
public HashSet<Entity<MindComponent>> GetAliveHumans(EntityUid? exclude = null)
|
||||
{
|
||||
var allHumans = new HashSet<Entity<MindComponent>>();
|
||||
AddAliveHumans(allHumans, exclude);
|
||||
|
|
@ -633,11 +632,6 @@ public abstract partial class SharedMindSystem : EntitySystem
|
|||
if (!TryGetMind(uid, out var mind, out var mindComp) || mind == exclude || !_mobState.IsAlive(uid, mobState))
|
||||
continue;
|
||||
|
||||
// Goobstation: Skip IPCs from selections
|
||||
if (excludeSilicon && HasComp<SiliconComponent>(uid))
|
||||
continue;
|
||||
// END Goobstation
|
||||
|
||||
allHumans.Add((mind, mindComp));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,11 +49,4 @@ public sealed partial class EncryptionKeyHolderComponent : Component
|
|||
/// </summary>
|
||||
[ViewVariables]
|
||||
public string? DefaultChannel;
|
||||
|
||||
/// <summary>
|
||||
/// Goobstation: Whether or not the headset can be examined to see the encryption keys while the keys aren't accessible.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("examineWhileLocked")]
|
||||
public bool ExamineWhileLocked = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,9 +166,7 @@ public sealed partial class EncryptionKeySystem : EntitySystem
|
|||
|
||||
private void OnHolderExamined(EntityUid uid, EncryptionKeyHolderComponent component, ExaminedEvent args)
|
||||
{
|
||||
if (!args.IsInDetailsRange
|
||||
|| !component.ExamineWhileLocked && !component.KeysUnlocked // Goobstation
|
||||
|| !component.ExamineWhileLocked && TryComp<WiresPanelComponent>(uid, out var panel) && !panel.Open) // Goobstation
|
||||
if (!args.IsInDetailsRange)
|
||||
return;
|
||||
|
||||
if (component.KeyContainer.ContainedEntities.Count == 0)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using System.Linq;
|
||||
using Content.Shared._DV.Silicon.IPC; // DeltaV
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.Inventory;
|
||||
|
|
@ -24,7 +23,6 @@ public abstract class SharedStationSpawningSystem : EntitySystem
|
|||
[Dependency] private readonly MetaDataSystem _metadata = default!;
|
||||
[Dependency] private readonly SharedStorageSystem _storage = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _xformSystem = default!;
|
||||
[Dependency] private readonly InternalEncryptionKeySpawner _internalEncryption = default!; // DeltaV
|
||||
|
||||
private EntityQuery<HandsComponent> _handsQuery;
|
||||
private EntityQuery<InventoryComponent> _inventoryQuery;
|
||||
|
|
@ -106,12 +104,6 @@ public abstract class SharedStationSpawningSystem : EntitySystem
|
|||
/// </summary>
|
||||
public void EquipStartingGear(EntityUid entity, StartingGearPrototype? startingGear, bool raiseEvent = true)
|
||||
{
|
||||
// Begin DeltaV Additions: Fix nukie IPCs not having comms
|
||||
if (startingGear is not {} proto)
|
||||
return;
|
||||
|
||||
_internalEncryption.TryInsertEncryptionKey(entity, proto);
|
||||
// End DeltaV Additions
|
||||
EquipStartingGear(entity, (IEquipmentLoadout?) startingGear, raiseEvent);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ public sealed partial class MeleeWeaponComponent : Component
|
|||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool ResistanceBypass = false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Base damage for this weapon. Can be modified via heavy damage or other means.
|
||||
/// </summary>
|
||||
|
|
@ -183,10 +183,6 @@ public sealed partial class MeleeWeaponComponent : Component
|
|||
public float HeavyPartDamageMultiplier = 0.5f;
|
||||
|
||||
// Shitmed Change End
|
||||
|
||||
// Goobstation
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool CanWideSwing = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -227,8 +227,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
|||
return;
|
||||
|
||||
if (!TryGetWeapon(user, out var weaponUid, out var weapon) ||
|
||||
weaponUid != GetEntity(msg.Weapon) ||
|
||||
!weapon.CanWideSwing) // Goobstation Change
|
||||
weaponUid != GetEntity(msg.Weapon))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
using Content.Shared.Containers;
|
||||
using Content.Shared.Radio.Components;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Shared.Containers;
|
||||
|
||||
namespace Content.Shared._DV.Silicon.IPC;
|
||||
|
||||
public sealed class InternalEncryptionKeySpawner : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an IPC's encryption key from starting gear headset.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Doesn't support a profile's loadouts, have fun.
|
||||
/// </remarks>
|
||||
public void TryInsertEncryptionKey(EntityUid target, StartingGearPrototype startingGear)
|
||||
{
|
||||
if (!TryComp<EncryptionKeyHolderComponent>(target, out var keyHolder)
|
||||
|| !startingGear.Equipment.TryGetValue("ears", out var headsetId)
|
||||
|| string.IsNullOrEmpty(headsetId))
|
||||
return;
|
||||
|
||||
var headset = Spawn(headsetId, Transform(target).Coordinates);
|
||||
if (!HasComp<EncryptionKeyHolderComponent>(headset)
|
||||
|| !TryComp<ContainerFillComponent>(headset, out var fillComp)
|
||||
|| !fillComp.Containers.TryGetValue(EncryptionKeyHolderComponent.KeyContainerName, out var defaultKeys))
|
||||
return;
|
||||
|
||||
_container.CleanContainer(keyHolder.KeyContainer);
|
||||
|
||||
foreach (var key in defaultKeys)
|
||||
{
|
||||
SpawnInContainerOrDrop(key, target, keyHolder.KeyContainer.ID);
|
||||
}
|
||||
|
||||
Del(headset);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
namespace Content.Shared._DV.Silicon.IPC;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class SnoutHelmetComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public bool EnableAlternateHelmet;
|
||||
|
||||
[DataField(readOnly: true)]
|
||||
public string? ReplacementRace;
|
||||
}
|
||||
|
|
@ -1,182 +0,0 @@
|
|||
using Robust.Shared.Random;
|
||||
using Content.Shared._EE.Silicon.Components;
|
||||
using Content.Shared.Power.Components;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared._EE.Silicon.Systems;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Mind.Components;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Utility;
|
||||
using SharedCVars = Content.Shared.CCVar.CCVars;
|
||||
using Content.Shared.PowerCell.Components;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.PowerCell;
|
||||
using Content.Shared.Power.EntitySystems;
|
||||
// Begin TheDen - IPC Dynamic Power draw
|
||||
using Content.Shared.Movement.Components;
|
||||
using Robust.Shared.Physics.Components;
|
||||
// End TheDen
|
||||
|
||||
namespace Content.Shared._DV.Silicons.Charge;
|
||||
|
||||
public abstract class SharedSiliconDrainSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
[Dependency] private readonly MovementSpeedModifierSystem _moveMod = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IConfigurationManager _config = default!;
|
||||
[Dependency] private readonly PowerCellSystem _powerCell = default!;
|
||||
[Dependency] private readonly SharedJetpackSystem _jetpack = default!; // TheDen - IPC Dynamic Power draw
|
||||
[Dependency] private readonly SharedBatterySystem _battery = default!;
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<SiliconComponent, ComponentStartup>(OnSiliconStartup);
|
||||
}
|
||||
|
||||
public bool TryGetSiliconBattery(EntityUid silicon, [NotNullWhen(true)] out Entity<BatteryComponent>? batteryComp)
|
||||
{
|
||||
batteryComp = null;
|
||||
if (!HasComp<SiliconComponent>(silicon))
|
||||
return false;
|
||||
|
||||
|
||||
// try get a battery directly on the inserted entity
|
||||
if (TryComp<BatteryComponent>(silicon, out var comp))
|
||||
{
|
||||
batteryComp = (silicon, comp);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_powerCell.TryGetBatteryFromSlot(silicon, out batteryComp))
|
||||
return true;
|
||||
|
||||
|
||||
//DebugTools.Assert("SiliconComponent does not contain Battery");
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OnSiliconStartup(EntityUid uid, SiliconComponent component, ComponentStartup args)
|
||||
{
|
||||
if (!HasComp<PowerCellSlotComponent>(uid))
|
||||
return;
|
||||
|
||||
if (component.EntityType.GetType() != typeof(SiliconType))
|
||||
DebugTools.Assert("SiliconComponent.EntityType is not a SiliconType enum.");
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
// For each siliconComp entity with a battery component, drain their charge.
|
||||
var query = EntityQueryEnumerator<SiliconComponent>();
|
||||
while (query.MoveNext(out var silicon, out var siliconComp))
|
||||
{
|
||||
if (_mobState.IsDead(silicon)
|
||||
|| !siliconComp.BatteryPowered)
|
||||
continue;
|
||||
|
||||
// Check if the Silicon is an NPC, and if so, follow the delay as specified in the CVAR.
|
||||
if (siliconComp.EntityType.Equals(SiliconType.Npc))
|
||||
{
|
||||
var updateTime = _config.GetCVar(SharedCVars.SiliconNpcUpdateTime);
|
||||
if (_timing.CurTime - siliconComp.LastDrainTime < TimeSpan.FromSeconds(updateTime))
|
||||
continue;
|
||||
|
||||
siliconComp.LastDrainTime = _timing.CurTime;
|
||||
}
|
||||
|
||||
// If you can't find a battery, set the indicator and skip it.
|
||||
if (!TryGetSiliconBattery(silicon, out var batteryComp))
|
||||
{
|
||||
UpdateChargeState(silicon, 0, siliconComp);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the silicon ghosted or is SSD while still being powered, skip it.
|
||||
if (TryComp<MindContainerComponent>(silicon, out var mindContComp)
|
||||
&& !mindContComp.HasMind)
|
||||
continue;
|
||||
|
||||
var drainRate = siliconComp.DrainPerSecond;
|
||||
|
||||
// All multipliers will be subtracted by 1, and then added together, and then multiplied by the drain rate. This is then added to the base drain rate.
|
||||
// This is to stop exponential increases, while still allowing for less-than-one multipliers.
|
||||
var drainRateFinalAddi = 0f;
|
||||
|
||||
// TODO: Devise a method of adding multis where other systems can alter the drain rate.
|
||||
// Maybe use something similar to refreshmovespeedmodifiers, where it's stored in the component.
|
||||
// Maybe it doesn't matter, and stuff should just use static drain?
|
||||
if (!siliconComp.EntityType.Equals(SiliconType.Npc)) // Don't bother checking heat if it's an NPC. It's a waste of time, and it'd be delayed due to the update time.
|
||||
{
|
||||
drainRateFinalAddi += SiliconMovementEffects(silicon, siliconComp); // TheDen - IPC Dynamic Power draw // Removes between 90% and 0% of the total power draw.
|
||||
}
|
||||
|
||||
// DeltaV - Sanity check
|
||||
if (float.IsNaN(drainRateFinalAddi))
|
||||
drainRateFinalAddi = 0f;
|
||||
|
||||
// Ensures that the drain rate is at least 10% of normal,
|
||||
// and would allow at least 4 minutes of life with a max charge, to prevent cheese.
|
||||
drainRate += Math.Clamp(drainRateFinalAddi, drainRate * -0.9f, batteryComp.Value.Comp.MaxCharge / 240);
|
||||
|
||||
// Drain the battery.
|
||||
_powerCell.TryUseCharge(silicon, frameTime * drainRate);
|
||||
|
||||
// Figure out the current state of the Silicon.
|
||||
var chargePercent = (short)MathF.Round(_battery.GetCharge(batteryComp.Value.AsNullable()) / batteryComp.Value.Comp.MaxCharge * 10f);
|
||||
|
||||
UpdateChargeState(silicon, chargePercent, siliconComp);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///Makes sure the entity is showing the right charge alert
|
||||
/// </summary>
|
||||
/// <param name="ent">The silicon whose charge to check</param>
|
||||
/// <param name="chargePercent">Charge level, normalized to range 0-100</param>
|
||||
protected abstract void UpdateChargeIcon(Entity<SiliconComponent> ent, short chargePercent);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if anything needs to be updated, and updates it.
|
||||
/// </summary>
|
||||
public void UpdateChargeState(EntityUid uid, short chargePercent, SiliconComponent component)
|
||||
{
|
||||
component.ChargeState = chargePercent;
|
||||
|
||||
RaiseLocalEvent(uid, new SiliconChargeStateUpdateEvent(chargePercent));
|
||||
|
||||
_moveMod.RefreshMovementSpeedModifiers(uid);
|
||||
UpdateChargeIcon((uid, component), chargePercent);
|
||||
}
|
||||
|
||||
// TheDen - IPC Dynamic Power draw
|
||||
private float SiliconMovementEffects(EntityUid silicon, SiliconComponent siliconComp)
|
||||
{
|
||||
// Calculate dynamic power draw.
|
||||
if (!TryComp(silicon, out MovementSpeedModifierComponent? movement) ||
|
||||
!TryComp(silicon, out PhysicsComponent? physics) ||
|
||||
!TryComp(silicon, out InputMoverComponent? input))
|
||||
return 0;
|
||||
|
||||
if (input.HeldMoveButtons == MoveButtons.None || _jetpack.IsUserFlying(silicon)) // If nothing is being held or jet packing
|
||||
{
|
||||
return siliconComp.DrainPerSecond * siliconComp.IdleDrainReduction * (-1); // Reduces draw by idle drain reduction
|
||||
}
|
||||
|
||||
// DeltaV - Prevent divide by zero errors, smh
|
||||
if (movement.CurrentSprintSpeed == 0)
|
||||
return 0;
|
||||
|
||||
// LinearVelocity is relative to the parent
|
||||
return Math.Clamp(
|
||||
siliconComp.DrainPerSecond * ((physics.LinearVelocity.Length() / movement.CurrentSprintSpeed) - 1), // Power draw changes as a negative percentage of the movement
|
||||
siliconComp.DrainPerSecond * siliconComp.IdleDrainReduction * (-1), // Should be a maximum of the idle drain reduction (negative)
|
||||
0f); // Minimum reduction is no change to power draw
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
using Content.Shared.DoAfter;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._EE.Silicon;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class BatteryDrinkerDoAfterEvent : SimpleDoAfterEvent
|
||||
{
|
||||
public BatteryDrinkerDoAfterEvent()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
using Content.Shared.DoAfter;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._EE.Silicon.BlindHealing;
|
||||
|
||||
public abstract partial class SharedBlindHealingSystem : EntitySystem
|
||||
{
|
||||
[Serializable, NetSerializable]
|
||||
protected sealed partial class HealingDoAfterEvent : SimpleDoAfterEvent
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,125 +0,0 @@
|
|||
using Robust.Shared.GameStates;
|
||||
using Content.Shared._EE.Silicon.Systems;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Content.Shared.Alert;
|
||||
|
||||
namespace Content.Shared._EE.Silicon.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Component for defining a mob as a robot.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class SiliconComponent : Component
|
||||
{
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
public short ChargeState = 10;
|
||||
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
public float OverheatAccumulator = 0.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The last time the Silicon was drained.
|
||||
/// Used for NPC Silicons to avoid over updating.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Time between drains can be specified in
|
||||
/// <see cref="SimpleStationCcvars.SiliconNpc"/>
|
||||
/// </remarks>
|
||||
public TimeSpan LastDrainTime = TimeSpan.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// The Silicon's battery slot, if it has one.
|
||||
/// </summary>
|
||||
|
||||
/// <summary>
|
||||
/// Is the Silicon currently dead?
|
||||
/// </summary>
|
||||
public bool Dead = false;
|
||||
|
||||
// BatterySystem took issue with how this was used, so I'm coming back to it at a later date, when more foundational Silicon stuff is implemented.
|
||||
// /// <summary>
|
||||
// /// The entity to get the battery from.
|
||||
// /// </summary>
|
||||
// public EntityUid BatteryOverride? = EntityUid.Invalid;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The type of silicon this is.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Any new types of Silicons should be added to the enum.
|
||||
/// Setting this to Npc will delay charge state updates by LastDrainTime and skip battery heat calculations
|
||||
/// </remarks>
|
||||
[DataField(customTypeSerializer: typeof(EnumSerializer))]
|
||||
public Enum EntityType = SiliconType.Npc;
|
||||
|
||||
/// <summary>
|
||||
/// Is this silicon battery powered?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If true, should go along with a battery component. One will not be added automatically.
|
||||
/// </remarks>
|
||||
[DataField]
|
||||
public bool BatteryPowered = false;
|
||||
|
||||
/// <summary>
|
||||
/// How much power is drained by this Silicon every second by default.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float DrainPerSecond = 50f;
|
||||
|
||||
// TheDen - Dynamic IPC Power Draw
|
||||
/// <summary>
|
||||
/// How much less power is used while being idle.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Relative to the DrainPerSecond.
|
||||
/// 0 is no reduction. 1 is 100% reduction. 0.5 is 50% reduction.
|
||||
/// Currently, 90% reduction is as high as we can go without changing code in C#
|
||||
/// </remarks>
|
||||
[DataField]
|
||||
public float IdleDrainReduction = 0.6f;
|
||||
|
||||
/// <summary>
|
||||
/// The percentages at which the silicon will enter each state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The Silicon will always be Full at 100%.
|
||||
/// Setting a value to null will disable that state.
|
||||
/// Setting Critical to 0 will cause the Silicon to never enter the dead state.
|
||||
/// </remarks>
|
||||
[DataField]
|
||||
public float? ChargeThresholdMid = 0.5f;
|
||||
|
||||
/// <inheritdoc cref="ChargeThresholdMid"/>
|
||||
[DataField]
|
||||
public float? ChargeThresholdLow = 0.25f;
|
||||
|
||||
/// <inheritdoc cref="ChargeThresholdMid"/>
|
||||
[DataField]
|
||||
public float? ChargeThresholdCritical = 0.1f;
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> BatteryAlert = "BorgBattery";
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> NoBatteryAlert = "BorgBatteryNone";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The amount the Silicon will be slowed at each charge state.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public Dictionary<int, float> SpeedModifierThresholds = default!;
|
||||
|
||||
[DataField]
|
||||
public float FireStackMultiplier = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not a Silicon will cancel all sleep events.
|
||||
/// Maybe you want an android that can sleep as well as drink APCs? I'm not going to judge.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool DoSiliconsDreamOfElectricSheep;
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
using Robust.Shared.Audio;
|
||||
|
||||
namespace Content.Shared._EE.Silicon.DeadStartupButton;
|
||||
|
||||
/// <summary>
|
||||
/// This is used for...
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class DeadStartupButtonComponent : Component
|
||||
{
|
||||
[DataField("verbText")]
|
||||
public string VerbText = "dead-startup-button-verb";
|
||||
|
||||
[DataField("sound")]
|
||||
public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/Effects/Arcade/newgame.ogg");
|
||||
|
||||
[DataField("buttonSound")]
|
||||
public SoundSpecifier ButtonSound = new SoundPathSpecifier("/Audio/Machines/button.ogg");
|
||||
|
||||
[DataField("doAfterInterval"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public float DoAfterInterval = 1f;
|
||||
|
||||
[DataField("buzzSound")]
|
||||
public SoundSpecifier BuzzSound = new SoundCollectionSpecifier("buzzes");
|
||||
|
||||
[DataField("verbPriority"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public int VerbPriority = 1;
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared._EE.Silicon.DeadStartupButton;
|
||||
|
||||
/// <summary>
|
||||
/// This creates a Button that can be activated after an entity, usually a silicon or an IPC, died.
|
||||
/// This will activate a doAfter and then revive the entity, playing a custom afterward sound.
|
||||
/// </summary>
|
||||
public abstract partial class SharedDeadStartupButtonSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
|
||||
[Dependency] private readonly INetManager _net = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<DeadStartupButtonComponent, GetVerbsEvent<AlternativeVerb>>(AddTurnOnVerb);
|
||||
}
|
||||
|
||||
private void AddTurnOnVerb(EntityUid uid, DeadStartupButtonComponent component, GetVerbsEvent<AlternativeVerb> args)
|
||||
{
|
||||
if (!_mobState.IsDead(uid)
|
||||
|| !args.CanAccess || !args.CanInteract || args.Hands == null)
|
||||
return;
|
||||
|
||||
if (!TryComp(uid, out MobStateComponent? mobStateComponent) || !_mobState.IsDead(uid, mobStateComponent))
|
||||
return;
|
||||
|
||||
args.Verbs.Add(new AlternativeVerb()
|
||||
{
|
||||
Act = () => TryStartup(args.User, uid, component),
|
||||
Text = Loc.GetString(component.VerbText),
|
||||
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/Spare/poweronoff.svg.192dpi.png")),
|
||||
Priority = component.VerbPriority
|
||||
});
|
||||
}
|
||||
|
||||
private void TryStartup(EntityUid user, EntityUid target, DeadStartupButtonComponent comp)
|
||||
{
|
||||
if (!_net.IsServer)
|
||||
return;
|
||||
_audio.PlayPvs(comp.ButtonSound, target);
|
||||
var args = new DoAfterArgs(EntityManager, user, comp.DoAfterInterval, new OnDoAfterButtonPressedEvent(), target, target:target)
|
||||
{
|
||||
BreakOnDamage = true,
|
||||
BreakOnMove = true,
|
||||
};
|
||||
_doAfterSystem.TryStartDoAfter(args);
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class OnDoAfterButtonPressedEvent : SimpleDoAfterEvent
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using Robust.Shared.Audio;
|
||||
|
||||
namespace Content.Shared._EE.Silicon.EmitBuzzWhileDamaged;
|
||||
|
||||
/// <summary>
|
||||
/// This is used for controlling the cadence of the buzzing emitted by EmitBuzzOnCritSystem.
|
||||
/// This component is used by mechanical species that can get to critical health.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class EmitBuzzWhileDamagedComponent : Component
|
||||
{
|
||||
[DataField("buzzPopupCooldown")]
|
||||
public TimeSpan BuzzPopupCooldown { get; private set; } = TimeSpan.FromSeconds(8);
|
||||
|
||||
[ViewVariables]
|
||||
public TimeSpan LastBuzzPopupTime;
|
||||
|
||||
[DataField("cycleDelay")]
|
||||
public float CycleDelay = 2.0f;
|
||||
|
||||
public float AccumulatedFrametime;
|
||||
|
||||
[DataField("sound")]
|
||||
public SoundSpecifier Sound = new SoundCollectionSpecifier("buzzes");
|
||||
}
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
using Content.Shared._EE.Silicon.Components;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Bed.Sleep;
|
||||
using Robust.Shared.Serialization;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Containers.ItemSlots;
|
||||
using Content.Shared.PowerCell.Components;
|
||||
|
||||
namespace Content.Shared._EE.Silicon.Systems;
|
||||
|
||||
|
||||
public abstract class SharedSiliconChargeSystem : EntitySystem // DeltaV - Make class abstract to split into Client/Server
|
||||
{
|
||||
// [Dependency] private readonly AlertsSystem _alertsSystem = default!; // DeltaV - Moved alert handling to Client
|
||||
[Dependency] private readonly ItemSlotsSystem _itemSlots = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
// Begin DeltaV - Moved alert handling to Client
|
||||
// SubscribeLocalEvent<SiliconComponent, ComponentInit>(OnSiliconInit);
|
||||
// SubscribeLocalEvent<SiliconComponent, SiliconChargeStateUpdateEvent>(OnSiliconChargeStateUpdate);
|
||||
// End DeltaV - Moved alert handling to Client
|
||||
SubscribeLocalEvent<SiliconComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovespeed);
|
||||
SubscribeLocalEvent<SiliconComponent, ItemSlotInsertAttemptEvent>(OnItemSlotInsertAttempt);
|
||||
SubscribeLocalEvent<SiliconComponent, ItemSlotEjectAttemptEvent>(OnItemSlotEjectAttempt);
|
||||
SubscribeLocalEvent<SiliconComponent, TryingToSleepEvent>(OnTryingToSleep);
|
||||
}
|
||||
|
||||
private void OnItemSlotInsertAttempt(EntityUid uid, SiliconComponent component, ref ItemSlotInsertAttemptEvent args)
|
||||
{
|
||||
if (args.Cancelled
|
||||
|| !TryComp<PowerCellSlotComponent>(uid, out var cellSlotComp)
|
||||
|| !_itemSlots.TryGetSlot(uid, cellSlotComp.CellSlotId, out var cellSlot)
|
||||
|| cellSlot != args.Slot || args.User != uid)
|
||||
return;
|
||||
|
||||
args.Cancelled = true;
|
||||
}
|
||||
|
||||
private void OnItemSlotEjectAttempt(EntityUid uid, SiliconComponent component, ref ItemSlotEjectAttemptEvent args)
|
||||
{
|
||||
if (args.Cancelled
|
||||
|| !TryComp<PowerCellSlotComponent>(uid, out var cellSlotComp)
|
||||
|| !_itemSlots.TryGetSlot(uid, cellSlotComp.CellSlotId, out var cellSlot)
|
||||
|| cellSlot != args.Slot || args.User != uid)
|
||||
return;
|
||||
|
||||
args.Cancelled = true;
|
||||
}
|
||||
|
||||
// Begin DeltaV - Moved alert handling to Client
|
||||
// private void OnSiliconInit(EntityUid uid, SiliconComponent component, ComponentInit args)
|
||||
// {
|
||||
// if (!component.BatteryPowered)
|
||||
// return;
|
||||
|
||||
// _alertsSystem.ShowAlert(uid, component.BatteryAlert, component.ChargeState);
|
||||
// }
|
||||
|
||||
// private void OnSiliconChargeStateUpdate(EntityUid uid, SiliconComponent component, SiliconChargeStateUpdateEvent ev)
|
||||
// {
|
||||
// _alertsSystem.ShowAlert(uid, component.BatteryAlert, ev.ChargePercent);
|
||||
// }
|
||||
// End DeltaV - Moved alert handling to Client
|
||||
|
||||
private void OnRefreshMovespeed(EntityUid uid, SiliconComponent component, RefreshMovementSpeedModifiersEvent args)
|
||||
{
|
||||
if (!component.BatteryPowered)
|
||||
return;
|
||||
|
||||
var closest = 0;
|
||||
|
||||
foreach (var state in component.SpeedModifierThresholds)
|
||||
if (component.ChargeState >= state.Key && state.Key > closest)
|
||||
closest = state.Key;
|
||||
|
||||
var speedMod = component.SpeedModifierThresholds[closest];
|
||||
|
||||
args.ModifySpeed(speedMod, speedMod);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Silicon entities can now also be Living player entities. We may want to prevent them from sleeping if they can't sleep.
|
||||
/// </summary>
|
||||
private void OnTryingToSleep(EntityUid uid, SiliconComponent component, ref TryingToSleepEvent args)
|
||||
{
|
||||
args.Cancelled = !component.DoSiliconsDreamOfElectricSheep;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public enum SiliconType
|
||||
{
|
||||
Player,
|
||||
GhostRole,
|
||||
Npc,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event raised when a Silicon's charge state needs to be updated.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class SiliconChargeStateUpdateEvent : EntityEventArgs
|
||||
{
|
||||
public short ChargePercent { get; }
|
||||
|
||||
public SiliconChargeStateUpdateEvent(short chargePercent)
|
||||
{
|
||||
ChargePercent = chargePercent;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
using Content.Shared.DoAfter;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._EE.Silicon.WeldingHealing;
|
||||
|
||||
public abstract partial class SharedWeldingHealableSystem : EntitySystem
|
||||
{
|
||||
[Serializable, NetSerializable]
|
||||
protected sealed partial class SiliconRepairFinishedEvent : SimpleDoAfterEvent
|
||||
{
|
||||
public float Delay;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,14 +0,0 @@
|
|||
- files: ["beep_500.ogg", "beep_2000.ogg"]
|
||||
license: "CC0-1.0"
|
||||
copyright: "Synthesized in Audacity by BasedUser."
|
||||
source: "https://github.com/ekrixi-14/ekrixi"
|
||||
|
||||
- files: ["pai_whistle.ogg"]
|
||||
license: "CC-BY-4.0"
|
||||
copyright: "Source sound by hubismal@GitHub, modified in Audacity by BasedUser."
|
||||
source: "https://github.com/space-wizards/space-station-14/commit/3421e4f4de2613df1e92a4169a778335bc9faac4"
|
||||
|
||||
- files: ["whirr1.ogg", "whirr2.ogg", "whirr3.ogg"]
|
||||
license: "CC0-1.0"
|
||||
copyright: "Taken from source, spectrally modified and clipped"
|
||||
source: "https://freesound.org/people/sad3d/sounds/500168/"
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -3001,12 +3001,6 @@ accent-anglish-replacement-1002 = foxfolk
|
|||
accent-anglish-words-1003 = diona
|
||||
accent-anglish-replacement-1003 = woodwight
|
||||
|
||||
accent-anglish-words-1004 = IPC
|
||||
accent-anglish-replacement-1004 = wileman
|
||||
|
||||
accent-anglish-words-1005 = IPCs
|
||||
accent-anglish-replacement-1005 = wilemen
|
||||
|
||||
accent-anglish-words-1006 = reptile
|
||||
accent-anglish-replacement-1006 = slinkend
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
# IPC
|
||||
fibers-steel = steel
|
||||
# Borg, coloured with the chassis colour for non-generic borgs
|
||||
fibers-plasteel = plasteel
|
||||
fibers-degraded-plasteel = degraded plasteel
|
||||
|
|
|
|||
|
|
@ -171,6 +171,3 @@ loadout-group-gladiator-outerclothing = Gladiator outer clothing
|
|||
loadout-group-boxer-jumpsuit = Boxer jumpsuit
|
||||
loadout-group-boxer-gloves = Boxer gloves
|
||||
loadout-group-boxer-mask = Wrestling mask
|
||||
|
||||
# Species
|
||||
loadout-group-humanoid-silicon = Silicon-friendly survival box
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
uplink-omnipatch-kit-name = OmniPatch Kit
|
||||
uplink-omnipatch-kit-desc = A collection of microbots specifically curated to repair machine entities, crucial for any long term operation.
|
||||
|
||||
uplink-firebugs-friend-name = Firebug's Friend
|
||||
uplink-firebugs-friend-desc = A bottle containing a flammable chemical cocktail, perfect for throwing at your foes.
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
silicon-behavior-buzz = Bzzzzt...
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +0,0 @@
|
|||
silicon-emote-deathgasp = seizes up and falls limp, {POSS-ADJ($entity)} lights sputtering into darkness...
|
||||
chat-emote-msg-deathgasp-silicon = suddenly goes silent, with a hiss of grinding servos and a screech of dying myomers.
|
||||
# DeltaV
|
||||
chat-emote-name-whirr = Whirr
|
||||
# DeltaV
|
||||
chat-emote-name-boop = Boop
|
||||
|
|
@ -1 +0,0 @@
|
|||
batteryslotrequireslock-component-alert-owner = {$user} is messing with your maintenance panel!
|
||||
|
|
@ -1 +0,0 @@
|
|||
battery-electrocute-charge = The battery surges with energy!
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
battery-drinker-verb-drink = Drain
|
||||
battery-drinker-empty = {CAPITALIZE(THE($target))} is already empty!
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
ipc-recharge-tip = You charged a litte of your battery.
|
||||
dead-startup-button-verb = Reboot
|
||||
dead-startup-system-reboot-success = {$target}'s system was rebooted.
|
||||
dead-startup-system-reboot-failed = {$target}'s chassis is way too damaged.
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
marking-RobotAntennaTv = Tv
|
||||
marking-RobotAntennaTv-ipc_antenna_tv = TV
|
||||
marking-RobotAntennaTesla = Tesla
|
||||
marking-RobotAntennaTesla-ipc_antenna_tesla = Tesla
|
||||
marking-RobotAntennaLightb = Light (alt)
|
||||
marking-RobotAntennaLight = Light
|
||||
marking-RobotAntennaCyberhead = Cyberhead
|
||||
marking-RobotAntennaCyberhead-ipc_antenna_cyberhead = Cyberhead
|
||||
marking-RobotAntennaSidelights = Sidelights
|
||||
marking-RobotAntennaAntlers = Antlers
|
||||
marking-RobotAntennaAntlers-ipc_antenna_antlers = Antlers
|
||||
marking-RobotAntennaDroneeyes = Drone Eyes
|
||||
marking-RobotAntennaDroneeyes-ipc_antenna_droneeyes = Drone Eyes
|
||||
marking-RobotAntennaCrowned = Crowned
|
||||
marking-RobotAntennaCrowned-ipc_antenna_crowned = Crown
|
||||
marking-RobotAntennaTowers = Towers
|
||||
marking-RobotAntennaTowers-ipc_antenna_towers = Towers
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue