Beds, Medical Beds, Stasis Beds (#6695)
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
namespace Content.Client.Bed;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed class StasisBedVisualsComponent : Component
|
||||
{}
|
||||
22
Content.Client/Bed/StasisBedSystem.cs
Normal file
22
Content.Client/Bed/StasisBedSystem.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Content.Shared.Bed;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.Bed
|
||||
{
|
||||
public sealed class StasisBedSystem : VisualizerSystem<StasisBedVisualsComponent>
|
||||
{
|
||||
protected override void OnAppearanceChange(EntityUid uid, StasisBedVisualsComponent component, ref AppearanceChangeEvent args)
|
||||
{
|
||||
if (TryComp(uid, out SpriteComponent? sprite)
|
||||
&& args.Component.TryGetData(StasisBedVisuals.IsOn, out bool isOn))
|
||||
{
|
||||
sprite.LayerSetVisible(StasisBedVisualLayers.IsOn, isOn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum StasisBedVisualLayers : byte
|
||||
{
|
||||
IsOn,
|
||||
}
|
||||
}
|
||||
@@ -272,6 +272,8 @@ namespace Content.Client.Entry
|
||||
"BeingCloned",
|
||||
"Advertise",
|
||||
"Bible",
|
||||
"HealOnBuckle",
|
||||
"StasisBed",
|
||||
"PowerNetworkBattery",
|
||||
"BatteryCharger",
|
||||
"UnpoweredFlashlight",
|
||||
|
||||
115
Content.Server/Bed/BedSystem.cs
Normal file
115
Content.Server/Bed/BedSystem.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
using Content.Shared.Damage;
|
||||
using Content.Server.Bed.Components;
|
||||
using Content.Server.Buckle.Components;
|
||||
using Content.Server.Body.Systems;
|
||||
using Content.Shared.Buckle.Components;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Bed;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Shared.Emag.Systems;
|
||||
|
||||
namespace Content.Server.Bed
|
||||
{
|
||||
public sealed class BedSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<HealOnBuckleComponent, BuckleChangeEvent>(ManageUpdateList);
|
||||
SubscribeLocalEvent<StasisBedComponent, BuckleChangeEvent>(OnBuckleChange);
|
||||
SubscribeLocalEvent<StasisBedComponent, PowerChangedEvent>(OnPowerChanged);
|
||||
SubscribeLocalEvent<StasisBedComponent, GotEmaggedEvent>(OnEmagged);
|
||||
}
|
||||
|
||||
private void ManageUpdateList(EntityUid uid, HealOnBuckleComponent component, BuckleChangeEvent args)
|
||||
{
|
||||
if (args.Buckling)
|
||||
{
|
||||
AddComp<HealOnBuckleHealingComponent>(uid);
|
||||
return;
|
||||
}
|
||||
|
||||
RemComp<HealOnBuckleHealingComponent>(uid);
|
||||
component.Accumulator = 0;
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
foreach (var healingComp in EntityQuery<HealOnBuckleHealingComponent>(true))
|
||||
{
|
||||
var bed = healingComp.Owner;
|
||||
var bedComponent = EntityManager.GetComponent<HealOnBuckleComponent>(bed);
|
||||
var strapComponent = EntityManager.GetComponent<StrapComponent>(bed);
|
||||
|
||||
bedComponent.Accumulator += frameTime;
|
||||
|
||||
if (bedComponent.Accumulator < bedComponent.HealTime)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
bedComponent.Accumulator -= bedComponent.HealTime;
|
||||
foreach (EntityUid healedEntity in strapComponent.BuckledEntities)
|
||||
{
|
||||
_damageableSystem.TryChangeDamage(healedEntity, bedComponent.Damage, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAppearance(EntityUid uid, bool isOn)
|
||||
{
|
||||
if (!TryComp<AppearanceComponent>(uid, out var appearance))
|
||||
return;
|
||||
|
||||
appearance.SetData(StasisBedVisuals.IsOn, isOn);
|
||||
}
|
||||
|
||||
private void OnBuckleChange(EntityUid uid, StasisBedComponent component, BuckleChangeEvent args)
|
||||
{
|
||||
// In testing this also received an unbuckle event when the bed is destroyed
|
||||
// So don't worry about that
|
||||
if (!TryComp<SharedBodyComponent>(args.BuckledEntity, out var body))
|
||||
return;
|
||||
|
||||
if (TryComp<ApcPowerReceiverComponent>(uid, out var power) && !power.Powered)
|
||||
return;
|
||||
|
||||
var metabolicEvent = new ApplyMetabolicMultiplierEvent()
|
||||
{Uid = args.BuckledEntity, Multiplier = component.Multiplier, Apply = args.Buckling};
|
||||
RaiseLocalEvent(args.BuckledEntity, metabolicEvent, false);
|
||||
}
|
||||
|
||||
private void OnPowerChanged(EntityUid uid, StasisBedComponent component, PowerChangedEvent args)
|
||||
{
|
||||
UpdateAppearance(uid, args.Powered);
|
||||
UpdateMetabolisms(uid, component, args.Powered);
|
||||
}
|
||||
|
||||
private void OnEmagged(EntityUid uid, StasisBedComponent component, GotEmaggedEvent args)
|
||||
{
|
||||
///Repeatable
|
||||
///Reset any metabolisms first so they receive the multiplier correctly
|
||||
UpdateMetabolisms(uid, component, false);
|
||||
component.Multiplier = 1 / component.Multiplier;
|
||||
UpdateMetabolisms(uid, component, true);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void UpdateMetabolisms(EntityUid uid, StasisBedComponent component, bool shouldApply)
|
||||
{
|
||||
if (!TryComp<StrapComponent>(uid, out var strap) || strap.BuckledEntities.Count == 0)
|
||||
return;
|
||||
|
||||
foreach (var buckledEntity in strap.BuckledEntities)
|
||||
{
|
||||
var metabolicEvent = new ApplyMetabolicMultiplierEvent()
|
||||
{Uid = buckledEntity, Multiplier = component.Multiplier, Apply = shouldApply};
|
||||
RaiseLocalEvent(buckledEntity, metabolicEvent, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
17
Content.Server/Bed/Components/HealOnBuckle.cs
Normal file
17
Content.Server/Bed/Components/HealOnBuckle.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Content.Shared.Damage;
|
||||
|
||||
namespace Content.Server.Bed.Components
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed class HealOnBuckleComponent : Component
|
||||
{
|
||||
[DataField("damage", required: true)]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public DamageSpecifier Damage = default!;
|
||||
|
||||
[DataField("healTime", required: false)]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float HealTime = 1f; // How often the bed applies the damage
|
||||
public float Accumulator = 0f; //Time accumulated
|
||||
}
|
||||
}
|
||||
8
Content.Server/Bed/Components/HealOnBuckleHealing.cs
Normal file
8
Content.Server/Bed/Components/HealOnBuckleHealing.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Content.Shared.Damage;
|
||||
|
||||
namespace Content.Server.Bed.Components
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed class HealOnBuckleHealingComponent : Component
|
||||
{}
|
||||
}
|
||||
13
Content.Server/Bed/Components/StasisBedComponent.cs
Normal file
13
Content.Server/Bed/Components/StasisBedComponent.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace Content.Server.Bed.Components
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed class StasisBedComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// What the metabolic update rate will be multiplied by (higher = slower metabolism)
|
||||
/// </summary>
|
||||
[DataField("multiplier", required: true)]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float Multiplier = 10f;
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@ public sealed class BloodstreamSystem : EntitySystem
|
||||
SubscribeLocalEvent<BloodstreamComponent, DamageChangedEvent>(OnDamageChanged);
|
||||
SubscribeLocalEvent<BloodstreamComponent, HealthBeingExaminedEvent>(OnHealthBeingExamined);
|
||||
SubscribeLocalEvent<BloodstreamComponent, BeingGibbedEvent>(OnBeingGibbed);
|
||||
SubscribeLocalEvent<BloodstreamComponent, ApplyMetabolicMultiplierEvent>(OnApplyMetabolicMultiplier);
|
||||
SubscribeLocalEvent<BloodstreamComponent, ReactionAttemptEvent>(OnReactionAttempt);
|
||||
}
|
||||
|
||||
@@ -193,6 +194,19 @@ public sealed class BloodstreamSystem : EntitySystem
|
||||
SpillAllSolutions(uid, component);
|
||||
}
|
||||
|
||||
private void OnApplyMetabolicMultiplier(EntityUid uid, BloodstreamComponent component, ApplyMetabolicMultiplierEvent args)
|
||||
{
|
||||
if (args.Apply)
|
||||
{
|
||||
component.UpdateInterval *= args.Multiplier;
|
||||
return;
|
||||
}
|
||||
component.UpdateInterval /= args.Multiplier;
|
||||
// Reset the accumulator properly
|
||||
if (component.AccumulatedFrametime >= component.UpdateInterval)
|
||||
component.AccumulatedFrametime = component.UpdateInterval;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempt to transfer provided solution to internal solution.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Server.Body.Components;
|
||||
@@ -7,8 +6,6 @@ using Content.Server.Mind.Components;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.MobState.Components;
|
||||
using Content.Shared.Movement.EntitySystems;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server.Body.Systems
|
||||
@@ -22,6 +19,7 @@ namespace Content.Server.Body.Systems
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<BodyComponent, RelayMoveInputEvent>(OnRelayMoveInput);
|
||||
SubscribeLocalEvent<BodyComponent, ApplyMetabolicMultiplierEvent>(OnApplyMetabolicMultiplier);
|
||||
}
|
||||
|
||||
private void OnRelayMoveInput(EntityUid uid, BodyComponent component, RelayMoveInputEvent args)
|
||||
@@ -40,6 +38,15 @@ namespace Content.Server.Body.Systems
|
||||
}
|
||||
}
|
||||
|
||||
private void OnApplyMetabolicMultiplier(EntityUid uid, BodyComponent component, ApplyMetabolicMultiplierEvent args)
|
||||
{
|
||||
foreach (var (part, _) in component.Parts)
|
||||
foreach (var mechanism in part.Mechanisms)
|
||||
{
|
||||
RaiseLocalEvent(mechanism.Owner, args, false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of ValueTuples of <see cref="T"/> and MechanismComponent on each mechanism
|
||||
/// in the given body.
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Linq;
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.Chemistry.Components.SolutionManager;
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Server.Bed;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
@@ -10,8 +11,6 @@ using Content.Shared.Database;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.MobState.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
@@ -30,6 +29,7 @@ namespace Content.Server.Body.Systems
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<MetabolizerComponent, ComponentInit>(OnMetabolizerInit);
|
||||
SubscribeLocalEvent<MetabolizerComponent, ApplyMetabolicMultiplierEvent>(OnApplyMetabolicMultiplier);
|
||||
}
|
||||
|
||||
private void OnMetabolizerInit(EntityUid uid, MetabolizerComponent component, ComponentInit args)
|
||||
@@ -50,6 +50,18 @@ namespace Content.Server.Body.Systems
|
||||
}
|
||||
}
|
||||
|
||||
private void OnApplyMetabolicMultiplier(EntityUid uid, MetabolizerComponent component, ApplyMetabolicMultiplierEvent args)
|
||||
{
|
||||
if (args.Apply)
|
||||
{
|
||||
component.UpdateFrequency *= args.Multiplier;
|
||||
return;
|
||||
}
|
||||
component.UpdateFrequency /= args.Multiplier;
|
||||
// Reset the accumulator properly
|
||||
if (component.AccumulatedFrametime >= component.UpdateFrequency)
|
||||
component.AccumulatedFrametime = component.UpdateFrequency;
|
||||
}
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
@@ -185,4 +197,13 @@ namespace Content.Server.Body.Systems
|
||||
}
|
||||
}
|
||||
}
|
||||
public sealed class ApplyMetabolicMultiplierEvent : EntityEventArgs
|
||||
{
|
||||
// The entity whose metabolism is being modified
|
||||
public EntityUid Uid;
|
||||
// What the metabolism's update rate will be multiplied by
|
||||
public float Multiplier;
|
||||
// Apply this multiplier or ignore / reset it?
|
||||
public bool Apply;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ namespace Content.Server.Body.Systems
|
||||
|
||||
// We want to process lung reagents before we inhale new reagents.
|
||||
UpdatesAfter.Add(typeof(MetabolizerSystem));
|
||||
SubscribeLocalEvent<RespiratorComponent, ApplyMetabolicMultiplierEvent>(OnApplyMetabolicMultiplier);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
@@ -93,7 +94,6 @@ namespace Content.Server.Body.Systems
|
||||
respirator.SuffocationCycles = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void Inhale(EntityUid uid, SharedBodyComponent? body=null)
|
||||
{
|
||||
if (!Resolve(uid, ref body, false))
|
||||
@@ -189,6 +189,26 @@ namespace Content.Server.Body.Systems
|
||||
respirator.Saturation =
|
||||
Math.Clamp(respirator.Saturation, respirator.MinSaturation, respirator.MaxSaturation);
|
||||
}
|
||||
|
||||
private void OnApplyMetabolicMultiplier(EntityUid uid, RespiratorComponent component, ApplyMetabolicMultiplierEvent args)
|
||||
{
|
||||
if (args.Apply)
|
||||
{
|
||||
component.CycleDelay *= args.Multiplier;
|
||||
component.Saturation *= args.Multiplier;
|
||||
component.MaxSaturation *= args.Multiplier;
|
||||
component.MinSaturation *= args.Multiplier;
|
||||
return;
|
||||
}
|
||||
// This way we don't have to worry about it breaking if the stasis bed component is destroyed
|
||||
component.CycleDelay /= args.Multiplier;
|
||||
component.Saturation /= args.Multiplier;
|
||||
component.MaxSaturation /= args.Multiplier;
|
||||
component.MinSaturation /= args.Multiplier;
|
||||
// Reset the accumulator properly
|
||||
if (component.AccumulatedFrametime >= component.CycleDelay)
|
||||
component.AccumulatedFrametime = component.CycleDelay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.Bed;
|
||||
using Content.Server.Chemistry.Components.SolutionManager;
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.Body.Systems
|
||||
@@ -18,6 +17,7 @@ namespace Content.Server.Body.Systems
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<StomachComponent, ComponentInit>(OnComponentInit);
|
||||
SubscribeLocalEvent<StomachComponent, ApplyMetabolicMultiplierEvent>(OnApplyMetabolicMultiplier);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
@@ -76,6 +76,20 @@ namespace Content.Server.Body.Systems
|
||||
}
|
||||
}
|
||||
|
||||
private void OnApplyMetabolicMultiplier(EntityUid uid, StomachComponent component, ApplyMetabolicMultiplierEvent args)
|
||||
{
|
||||
if (args.Apply)
|
||||
{
|
||||
component.UpdateInterval *= args.Multiplier;
|
||||
return;
|
||||
}
|
||||
// This way we don't have to worry about it breaking if the stasis bed component is destroyed
|
||||
component.UpdateInterval /= args.Multiplier;
|
||||
// Reset the accumulator properly
|
||||
if (component.AccumulatedFrameTime >= component.UpdateInterval)
|
||||
component.AccumulatedFrameTime = component.UpdateInterval;
|
||||
}
|
||||
|
||||
private void OnComponentInit(EntityUid uid, StomachComponent component, ComponentInit args)
|
||||
{
|
||||
var solution = _solutionContainerSystem.EnsureSolution(uid, DefaultSolutionName);
|
||||
|
||||
@@ -232,8 +232,9 @@ namespace Content.Server.Buckle.Components
|
||||
|
||||
UpdateBuckleStatus();
|
||||
|
||||
var ev = new BuckleChangeEvent() { Buckling = true, Strap = BuckledTo.Owner };
|
||||
_entMan.EventBus.RaiseLocalEvent(Owner, ev, false);
|
||||
var ev = new BuckleChangeEvent() { Buckling = true, Strap = BuckledTo.Owner, BuckledEntity = Owner };
|
||||
_entMan.EventBus.RaiseLocalEvent(ev.BuckledEntity, ev, false);
|
||||
_entMan.EventBus.RaiseLocalEvent(ev.Strap, ev, false);
|
||||
|
||||
if (_entMan.TryGetComponent(Owner, out SharedPullableComponent? ownerPullable))
|
||||
{
|
||||
@@ -324,8 +325,9 @@ namespace Content.Server.Buckle.Components
|
||||
oldBuckledTo.Remove(this);
|
||||
SoundSystem.Play(Filter.Pvs(Owner), oldBuckledTo.UnbuckleSound.GetSound(), Owner);
|
||||
|
||||
var ev = new BuckleChangeEvent() { Buckling = false, Strap = oldBuckledTo.Owner };
|
||||
var ev = new BuckleChangeEvent() { Buckling = false, Strap = oldBuckledTo.Owner, BuckledEntity = Owner };
|
||||
_entMan.EventBus.RaiseLocalEvent(Owner, ev, false);
|
||||
_entMan.EventBus.RaiseLocalEvent(oldBuckledTo.Owner, ev, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Shared.Disease;
|
||||
using Content.Server.Buckle.Components;
|
||||
using Content.Server.Bed.Components;
|
||||
|
||||
namespace Content.Server.Disease.Cures
|
||||
{
|
||||
@@ -7,7 +8,6 @@ namespace Content.Server.Disease.Cures
|
||||
/// Cures the disease after a certain amount of time
|
||||
/// strapped.
|
||||
/// </summary>
|
||||
/// TODO: Revisit after bed pr merged
|
||||
public sealed class DiseaseBedrestCure : DiseaseCure
|
||||
{
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
@@ -18,7 +18,8 @@ namespace Content.Server.Disease.Cures
|
||||
|
||||
public override bool Cure(DiseaseEffectArgs args)
|
||||
{
|
||||
if (!args.EntityManager.TryGetComponent<BuckleComponent>(args.DiseasedEntity, out var buckle))
|
||||
if (!args.EntityManager.TryGetComponent<BuckleComponent>(args.DiseasedEntity, out var buckle) ||
|
||||
!args.EntityManager.HasComponent<HealOnBuckleComponent>(buckle.BuckledTo?.Owner))
|
||||
return false;
|
||||
if (buckle.Buckled)
|
||||
Ticker++;
|
||||
|
||||
@@ -4,6 +4,7 @@ using Content.Shared.Disease;
|
||||
using Content.Shared.Disease.Components;
|
||||
using Content.Server.Disease.Components;
|
||||
using Content.Server.Clothing.Components;
|
||||
using Content.Server.Body.Systems;
|
||||
using Content.Shared.MobState.Components;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Inventory;
|
||||
@@ -47,6 +48,8 @@ namespace Content.Server.Disease
|
||||
SubscribeLocalEvent<DiseaseProtectionComponent, GotUnequippedEvent>(OnUnequipped);
|
||||
SubscribeLocalEvent<DiseaseVaccineComponent, AfterInteractEvent>(OnAfterInteract);
|
||||
SubscribeLocalEvent<DiseaseVaccineComponent, ExaminedEvent>(OnExamined);
|
||||
// Handling stuff from other systems
|
||||
SubscribeLocalEvent<DiseaseCarrierComponent, ApplyMetabolicMultiplierEvent>(OnApplyMetabolicMultiplier);
|
||||
// Private events stuff
|
||||
SubscribeLocalEvent<TargetVaxxSuccessfulEvent>(OnTargetVaxxSuccessful);
|
||||
SubscribeLocalEvent<VaxxCancelledEvent>(OnVaxxCancelled);
|
||||
@@ -285,6 +288,26 @@ namespace Content.Server.Disease
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void OnApplyMetabolicMultiplier(EntityUid uid, DiseaseCarrierComponent component, ApplyMetabolicMultiplierEvent args)
|
||||
{
|
||||
if (args.Apply)
|
||||
{
|
||||
foreach (var disease in component.Diseases)
|
||||
{
|
||||
disease.TickTime *= args.Multiplier;
|
||||
return;
|
||||
}
|
||||
}
|
||||
foreach (var disease in component.Diseases)
|
||||
{
|
||||
disease.TickTime /= args.Multiplier;
|
||||
if (disease.Accumulator >= disease.TickTime)
|
||||
disease.Accumulator = disease.TickTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Helper functions
|
||||
///
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace Content.Server.Entry
|
||||
"ConstructionGhost",
|
||||
"IconSmooth",
|
||||
"ReinforcedWall",
|
||||
"StasisBedVisuals",
|
||||
"InteractionOutline",
|
||||
"MeleeWeaponArcAnimation",
|
||||
"AnimationsTest",
|
||||
|
||||
10
Content.Shared/Bed/StasisBedVisuals.cs
Normal file
10
Content.Shared/Bed/StasisBedVisuals.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Bed
|
||||
{
|
||||
[Serializable, NetSerializable]
|
||||
public enum StasisBedVisuals : byte
|
||||
{
|
||||
IsOn,
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,8 @@ namespace Content.Shared.Buckle.Components
|
||||
public sealed class BuckleChangeEvent : EntityEventArgs
|
||||
{
|
||||
public EntityUid Strap;
|
||||
|
||||
public EntityUid BuckledEntity;
|
||||
public bool Buckling;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace Content.Shared.Disease
|
||||
/// <summary>
|
||||
/// Controls how often a disease ticks.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public float TickTime = 1f;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -104,17 +104,15 @@
|
||||
- type: technology
|
||||
name: "medical machinery"
|
||||
id: MedicalMachinery
|
||||
description: More machine power for more healing efficiency.
|
||||
description: Machines any self-respecting medbay would need.
|
||||
icon:
|
||||
sprite: Structures/Machines/cloning.rsi
|
||||
state: pod_0
|
||||
requiredPoints: 15000
|
||||
sprite: Structures/dispensers.rsi
|
||||
state: industrial-working
|
||||
requiredPoints: 10000
|
||||
requiredTechnologies:
|
||||
- BiologicalTechnology
|
||||
- ChemistryTechnology
|
||||
unlockedRecipes:
|
||||
- CloningPodMachineCircuitboard
|
||||
- MedicalScannerMachineCircuitboard
|
||||
- ChemMasterMachineCircuitboard
|
||||
- ChemDispenserMachineCircuitboard
|
||||
- CrewMonitoringComputerCircuitboard
|
||||
@@ -122,6 +120,22 @@
|
||||
- DiagnoserMachineCircuitboard
|
||||
- HandheldCrewMonitor
|
||||
|
||||
- type: technology
|
||||
name: "advanced life support systems"
|
||||
id: AdvancedLifeSupport
|
||||
description: The cutting edge of life and death.
|
||||
icon:
|
||||
sprite: Structures/Machines/cloning.rsi
|
||||
state: pod_0
|
||||
requiredPoints: 20000
|
||||
requiredTechnologies:
|
||||
- MedicalMachinery
|
||||
- AdvancedSugery
|
||||
unlockedRecipes:
|
||||
- CloningPodMachineCircuitboard
|
||||
- MedicalScannerMachineCircuitboard
|
||||
- StasisBedMachineCircuitboard
|
||||
|
||||
# Security Technology Tree
|
||||
|
||||
- type: technology
|
||||
@@ -328,7 +342,7 @@
|
||||
- SolarControlComputerCircuitboard
|
||||
- GeneratorPlasmaMachineCircuitboard
|
||||
- GeneratorUraniumMachineCircuitboard
|
||||
|
||||
|
||||
- type: technology
|
||||
name: "compact power technology"
|
||||
id: CompactPowerTechnology
|
||||
|
||||
@@ -312,3 +312,26 @@
|
||||
Amount: 1
|
||||
DefaultPrototype: Beaker
|
||||
ExamineName: Glass Beaker
|
||||
|
||||
- type: entity
|
||||
id: StasisBedMachineCircuitboard
|
||||
parent: BaseMachineCircuitboard
|
||||
name: Stasis Bed (Machine Board)
|
||||
components:
|
||||
- type: MachineBoard
|
||||
prototype: StasisBed
|
||||
requirements:
|
||||
Capacitor: 1
|
||||
Manipulator: 1
|
||||
materialRequirements:
|
||||
Cable: 3
|
||||
tagRequirements:
|
||||
Pipe:
|
||||
Amount: 4
|
||||
DefaultPrototype: GasPipeStraight
|
||||
ExamineName: Pipe
|
||||
Cryobeaker:
|
||||
Amount: 2
|
||||
DefaultPrototype: CryostasisBeaker
|
||||
ExamineName: Cryostasis Beaker
|
||||
|
||||
|
||||
@@ -144,7 +144,11 @@
|
||||
solution: beaker
|
||||
- !type:DoActsBehavior
|
||||
acts: [ "Destruction" ]
|
||||
|
||||
- type: Tag
|
||||
tags:
|
||||
- GlassBeaker
|
||||
- Cryobeaker
|
||||
|
||||
- type: entity
|
||||
name: bluespace beaker
|
||||
parent: BaseBeaker
|
||||
|
||||
@@ -2,8 +2,15 @@
|
||||
name: bed
|
||||
id: Bed
|
||||
parent: BaseStructure
|
||||
description: This is used to lie in, sleep in or strap on.
|
||||
description: This is used to lie in, sleep in or strap on. Resting here provides extremely slow healing.
|
||||
components:
|
||||
- type: HealOnBuckle
|
||||
damage:
|
||||
groups:
|
||||
Brute: -0.2 ## 0.1 per
|
||||
Burn: -0.2
|
||||
types:
|
||||
Poison: -0.1
|
||||
- type: Physics
|
||||
bodyType: Static
|
||||
- type: Fixtures
|
||||
@@ -52,6 +59,25 @@
|
||||
- type: Pullable
|
||||
|
||||
|
||||
- type: entity
|
||||
parent: Bed
|
||||
id: MedicalBed
|
||||
name: medical bed
|
||||
description: A hospital bed for patients to recover in. Resting here provides fairly slow healing.
|
||||
components:
|
||||
- type: Sprite
|
||||
state: bed-MED
|
||||
- type: HealOnBuckle
|
||||
damage:
|
||||
groups:
|
||||
Brute: -0.4 ## 0.2 per
|
||||
Burn: -0.4
|
||||
types:
|
||||
Poison: -0.2
|
||||
- type: Construction
|
||||
graph: bed
|
||||
node: medicalbed
|
||||
|
||||
- type: entity
|
||||
parent: Bed
|
||||
id: DogBed
|
||||
|
||||
@@ -245,6 +245,7 @@
|
||||
- ShuttleConsoleCircuitboard
|
||||
- CircuitImprinterMachineCircuitboard
|
||||
- DawInstrumentMachineCircuitboard
|
||||
- StasisBedMachineCircuitboard
|
||||
- type: Machine
|
||||
board: CircuitImprinterMachineCircuitboard
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
- type: entity
|
||||
id: StasisBed
|
||||
name: stasis bed
|
||||
parent: BaseStructure
|
||||
description: A bed that massively slows down the patient's metabolism, allowing more time to administer a proper treatment for stabilization.
|
||||
components:
|
||||
- type: StasisBed
|
||||
multiplier: 10
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/stasis_bed.rsi
|
||||
netsync: false
|
||||
layers:
|
||||
- state: icon
|
||||
- state: unlit
|
||||
shader: unshaded
|
||||
map: ["enum.StasisBedVisualLayers.IsOn"]
|
||||
- type: StasisBedVisuals
|
||||
- type: Appearance
|
||||
- type: ApcPowerReceiver
|
||||
powerLoad: 1000
|
||||
- type: ExtensionCableReceiver
|
||||
- type: Damageable
|
||||
damageContainer: Inorganic
|
||||
damageModifierSet: Metallic
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
- trigger:
|
||||
!type:DamageTrigger
|
||||
damage: 75
|
||||
behaviors:
|
||||
- !type:DoActsBehavior
|
||||
acts: ["Destruction"]
|
||||
- !type:SpawnEntitiesBehavior
|
||||
spawn:
|
||||
SheetSteel1:
|
||||
min: 1
|
||||
max: 2
|
||||
- type: Strap
|
||||
position: Down
|
||||
rotation: -90
|
||||
- type: Physics
|
||||
bodyType: Static
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
- shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.45,-0.45,0.45,0.05"
|
||||
mass: 25
|
||||
mask:
|
||||
- SmallImpassable
|
||||
|
||||
@@ -20,6 +20,13 @@
|
||||
- material: WoodPlank
|
||||
amount: 10
|
||||
doAfter: 1
|
||||
- to: medicalbed
|
||||
completed:
|
||||
- !type:SnapToGrid { }
|
||||
steps:
|
||||
- material: Plasteel
|
||||
amount: 2
|
||||
doAfter: 1
|
||||
- node: bed
|
||||
entity: Bed
|
||||
edges:
|
||||
@@ -42,3 +49,14 @@
|
||||
steps:
|
||||
- tool: Screwing
|
||||
doAfter: 1
|
||||
- node: medicalbed
|
||||
entity: MedicalBed
|
||||
edges:
|
||||
- to: start
|
||||
completed:
|
||||
- !type:SpawnPrototype
|
||||
prototype: SheetPlasteel1
|
||||
amount: 2
|
||||
steps:
|
||||
- tool: Screwing
|
||||
doAfter: 1
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
canBuildInImpassable: false
|
||||
conditions:
|
||||
- !type:TileNotBlocked
|
||||
|
||||
|
||||
- type: construction
|
||||
name: pilots chair
|
||||
id: chairPilotSeat
|
||||
@@ -294,7 +294,7 @@
|
||||
- type: construction
|
||||
id: Bed
|
||||
name: bed
|
||||
description: This is used to lie in, sleep in or strap on.
|
||||
description: This is used to lie in, sleep in or strap on. Resting here provides extremely slow healing.
|
||||
graph: bed
|
||||
startNode: start
|
||||
targetNode: bed
|
||||
@@ -308,6 +308,23 @@
|
||||
conditions:
|
||||
- !type:TileNotBlocked
|
||||
|
||||
- type: construction
|
||||
id: MedicalBed
|
||||
name: Medical Bed
|
||||
description: A hospital bed for patients to recover in. Resting here provides fairly slow healing.
|
||||
graph: bed
|
||||
startNode: start
|
||||
targetNode: medicalbed
|
||||
category: Furniture
|
||||
icon:
|
||||
sprite: Structures/Furniture/furniture.rsi
|
||||
state: bed-MED
|
||||
objectType: Structure
|
||||
placementMode: SnapgridCenter
|
||||
canBuildInImpassable: false
|
||||
conditions:
|
||||
- !type:TileNotBlocked
|
||||
|
||||
- type: construction
|
||||
id: DogBed
|
||||
name: dog bed
|
||||
|
||||
@@ -185,6 +185,15 @@
|
||||
Steel: 100
|
||||
Glass: 900
|
||||
|
||||
- type: latheRecipe
|
||||
id: StasisBedMachineCircuitboard
|
||||
icon: Objects/Misc/module.rsi/id_mod.png
|
||||
result: StasisBedMachineCircuitboard
|
||||
completetime: 1000
|
||||
materials:
|
||||
Steel: 100
|
||||
Glass: 900
|
||||
Gold: 100
|
||||
# Power
|
||||
- type: latheRecipe
|
||||
id: APCElectronics
|
||||
@@ -203,7 +212,7 @@
|
||||
materials:
|
||||
Steel: 50
|
||||
Glass: 450
|
||||
|
||||
|
||||
- type: latheRecipe
|
||||
id: WallmountSubstationElectronics
|
||||
icon: Objects/Misc/module.rsi/id_mod.png
|
||||
@@ -221,7 +230,7 @@
|
||||
materials:
|
||||
Steel: 100
|
||||
Glass: 900
|
||||
|
||||
|
||||
- type: latheRecipe
|
||||
id: GeneratorPlasmaMachineCircuitboard
|
||||
icon: Objects/Misc/module.rsi/id_mod.png
|
||||
@@ -230,7 +239,7 @@
|
||||
materials:
|
||||
Steel: 50
|
||||
Glass: 350
|
||||
|
||||
|
||||
- type: latheRecipe
|
||||
id: GeneratorUraniumMachineCircuitboard
|
||||
icon: Objects/Misc/module.rsi/id_mod.png
|
||||
@@ -239,7 +248,7 @@
|
||||
materials:
|
||||
Steel: 50
|
||||
Glass: 350
|
||||
|
||||
|
||||
- type: latheRecipe
|
||||
id: WallmountGeneratorElectronics
|
||||
icon: Objects/Misc/module.rsi/id_mod.png
|
||||
@@ -248,7 +257,7 @@
|
||||
materials:
|
||||
Steel: 50
|
||||
Glass: 350
|
||||
|
||||
|
||||
- type: latheRecipe
|
||||
id: WallmountGeneratorAPUElectronics
|
||||
icon: Objects/Misc/module.rsi/id_mod.png
|
||||
@@ -257,7 +266,7 @@
|
||||
materials:
|
||||
Steel: 50
|
||||
Glass: 350
|
||||
|
||||
|
||||
- type: latheRecipe
|
||||
id: SolarControlComputerCircuitboard
|
||||
icon: Objects/Misc/module.rsi/id_mod.png
|
||||
|
||||
@@ -90,6 +90,9 @@
|
||||
- type: Tag
|
||||
id: CrowbarRed
|
||||
|
||||
- type: Tag
|
||||
id: Cryobeaker
|
||||
|
||||
- type: Tag
|
||||
id: ConveyorAssembly
|
||||
|
||||
@@ -221,7 +224,7 @@
|
||||
|
||||
- type: Tag
|
||||
id: Payload # for grenade/bomb crafting
|
||||
|
||||
|
||||
- type: Tag
|
||||
id: PercussionInstrument
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.6 KiB |
@@ -10,6 +10,9 @@
|
||||
{
|
||||
"name": "bed"
|
||||
},
|
||||
{
|
||||
"name": "bed-MED"
|
||||
},
|
||||
{
|
||||
"name": "dogbed"
|
||||
},
|
||||
|
||||
BIN
Resources/Textures/Structures/Machines/stasis_bed.rsi/broken.png
Normal file
BIN
Resources/Textures/Structures/Machines/stasis_bed.rsi/broken.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
BIN
Resources/Textures/Structures/Machines/stasis_bed.rsi/icon.png
Normal file
BIN
Resources/Textures/Structures/Machines/stasis_bed.rsi/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"version": 1,
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/40d89d11ea4a5cb81d61dc1018b46f4e7d32c62a",
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"name": "broken",
|
||||
"delays": [
|
||||
[
|
||||
1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "panel",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "unlit",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "icon",
|
||||
"directions": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
Resources/Textures/Structures/Machines/stasis_bed.rsi/panel.png
Normal file
BIN
Resources/Textures/Structures/Machines/stasis_bed.rsi/panel.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 922 B |
BIN
Resources/Textures/Structures/Machines/stasis_bed.rsi/unlit.png
Normal file
BIN
Resources/Textures/Structures/Machines/stasis_bed.rsi/unlit.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 440 B |
Reference in New Issue
Block a user