Skip to content

Commit

Permalink
Merge pull request #391 from TheArturZh/upstream-merge-31
Browse files Browse the repository at this point in the history
Upstream merge 31
  • Loading branch information
TheArturZh authored Oct 2, 2023
2 parents 65725ec + bad7eda commit 28afec6
Show file tree
Hide file tree
Showing 35 changed files with 82,149 additions and 97,934 deletions.
2 changes: 1 addition & 1 deletion Content.Server/Doors/Systems/AirlockSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ private void OnBeforePry(EntityUid uid, AirlockComponent component, ref BeforePr
{
if (this.IsPowered(uid, EntityManager) && !args.PryPowered)
{
Popup.PopupClient(Loc.GetString("airlock-component-cannot-pry-is-powered-message"), uid, args.User);
Popup.PopupEntity(Loc.GetString("airlock-component-cannot-pry-is-powered-message"), uid, args.User);
args.Cancelled = true;
}
}
Expand Down
1 change: 1 addition & 0 deletions Content.Server/ImmovableRod/ImmovableRodSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ private void OnCollide(EntityUid uid, ImmovableRodComponent component, ref Start

_popup.PopupEntity(Loc.GetString("immovable-rod-penetrated-mob", ("rod", uid), ("mob", ent)), uid, PopupType.LargeCaution);
_bodySystem.GibBody(ent, body: body);
return;
}

QueueDel(ent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@
[RegisterComponent]
public sealed partial class ContainerTemperatureDamageThresholdsComponent: Component
{
[DataField("heatDamageThreshold")]
[ViewVariables(VVAccess.ReadWrite)]
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float? HeatDamageThreshold;

[DataField("coldDamageThreshold")]
[ViewVariables(VVAccess.ReadWrite)]
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float? ColdDamageThreshold;
}
24 changes: 24 additions & 0 deletions Content.Server/Temperature/Components/EntityHeaterComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Content.Server.Temperature.Systems;
using Content.Shared.Temperature;

namespace Content.Server.Temperature.Components;

/// <summary>
/// Adds thermal energy to entities with <see cref="TemperatureComponent"/> placed on it.
/// </summary>
[RegisterComponent, Access(typeof(EntityHeaterSystem))]
public sealed partial class EntityHeaterComponent : Component
{
/// <summary>
/// Power used when heating at the high setting.
/// Low and medium are 33% and 66% respectively.
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float Power = 2400f;

/// <summary>
/// Current setting of the heater. If it is off or unpowered it won't heat anything.
/// </summary>
[DataField]
public EntityHeaterSetting Setting = EntityHeaterSetting.Off;
}
124 changes: 60 additions & 64 deletions Content.Server/Temperature/Components/TemperatureComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,84 +4,80 @@
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;

namespace Content.Server.Temperature.Components
namespace Content.Server.Temperature.Components;

/// <summary>
/// Handles changing temperature,
/// informing others of the current temperature,
/// and taking fire damage from high temperature.
/// </summary>
[RegisterComponent]
public sealed partial class TemperatureComponent : Component
{
/// <summary>
/// Handles changing temperature,
/// informing others of the current temperature,
/// and taking fire damage from high temperature.
/// </summary>
[RegisterComponent]
public sealed partial class TemperatureComponent : Component
{
[ViewVariables(VVAccess.ReadWrite)]
[DataField("currentTemperature")]
public float CurrentTemperature { get; set; } = Atmospherics.T20C;
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float CurrentTemperature = Atmospherics.T20C;

[DataField("heatDamageThreshold")]
[ViewVariables(VVAccess.ReadWrite)]
public float HeatDamageThreshold = 360f;
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float HeatDamageThreshold = 360f;

[DataField("coldDamageThreshold")]
[ViewVariables(VVAccess.ReadWrite)]
public float ColdDamageThreshold = 260f;
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float ColdDamageThreshold = 260f;

/// <summary>
/// Overrides HeatDamageThreshold if the entity's within a parent with the TemperatureDamageThresholdsComponent component.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float? ParentHeatDamageThreshold;
/// <summary>
/// Overrides HeatDamageThreshold if the entity's within a parent with the TemperatureDamageThresholdsComponent component.
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float? ParentHeatDamageThreshold;

/// <summary>
/// Overrides ColdDamageThreshold if the entity's within a parent with the TemperatureDamageThresholdsComponent component.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float? ParentColdDamageThreshold;
/// <summary>
/// Overrides ColdDamageThreshold if the entity's within a parent with the TemperatureDamageThresholdsComponent component.
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float? ParentColdDamageThreshold;

[DataField("specificHeat")]
[ViewVariables(VVAccess.ReadWrite)]
public float SpecificHeat = 50f;
/// <summary>
/// Heat capacity per kg of mass.
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float SpecificHeat = 50f;

/// <summary>
/// How well does the air surrounding you merge into your body temperature?
/// </summary>
[DataField("atmosTemperatureTransferEfficiency")]
[ViewVariables(VVAccess.ReadWrite)]
public float AtmosTemperatureTransferEfficiency = 0.1f;
/// <summary>
/// How well does the air surrounding you merge into your body temperature?
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float AtmosTemperatureTransferEfficiency = 0.1f;

[ViewVariables] public float HeatCapacity
[ViewVariables] public float HeatCapacity
{
get
{
get
if (IoCManager.Resolve<IEntityManager>().TryGetComponent<PhysicsComponent>(Owner, out var physics) && physics.FixturesMass != 0)
{
if (IoCManager.Resolve<IEntityManager>().TryGetComponent<PhysicsComponent>(Owner, out var physics) && physics.FixturesMass != 0)
{
return SpecificHeat * physics.FixturesMass;
}

return Atmospherics.MinimumHeatCapacity;
return SpecificHeat * physics.FixturesMass;
}

return Atmospherics.MinimumHeatCapacity;
}
}

[DataField("coldDamage")]
[ViewVariables(VVAccess.ReadWrite)]
public DamageSpecifier ColdDamage = new();
[DataField, ViewVariables(VVAccess.ReadWrite)]
public DamageSpecifier ColdDamage = new();

[DataField("heatDamage")]
[ViewVariables(VVAccess.ReadWrite)]
public DamageSpecifier HeatDamage = new();
[DataField, ViewVariables(VVAccess.ReadWrite)]
public DamageSpecifier HeatDamage = new();

/// <summary>
/// Temperature won't do more than this amount of damage per second.
///
/// Okay it genuinely reaches this basically immediately for a plasma fire.
/// </summary>
[DataField("damageCap")]
[ViewVariables(VVAccess.ReadWrite)]
public FixedPoint2 DamageCap = FixedPoint2.New(8);
/// <summary>
/// Temperature won't do more than this amount of damage per second.
/// </summary>
/// <remarks>
/// Okay it genuinely reaches this basically immediately for a plasma fire.
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public FixedPoint2 DamageCap = FixedPoint2.New(8);

/// <summary>
/// Used to keep track of when damage starts/stops. Useful for logs.
/// </summary>
public bool TakingDamage = false;
}
/// <summary>
/// Used to keep track of when damage starts/stops. Useful for logs.
/// </summary>
[DataField]
public bool TakingDamage = false;
}
111 changes: 111 additions & 0 deletions Content.Server/Temperature/Systems/EntityHeaterSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using Content.Server.Power.Components;
using Content.Server.Temperature.Components;
using Content.Shared.Examine;
using Content.Shared.Placeable;
using Content.Shared.Popups;
using Content.Shared.Temperature;
using Content.Shared.Verbs;

namespace Content.Server.Temperature.Systems;

/// <summary>
/// Handles <see cref="EntityHeaterComponent"/> updating and events.
/// </summary>
public sealed class EntityHeaterSystem : EntitySystem
{
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly TemperatureSystem _temperature = default!;

private readonly int SettingCount = Enum.GetValues(typeof(EntityHeaterSetting)).Length;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<EntityHeaterComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<EntityHeaterComponent, GetVerbsEvent<AlternativeVerb>>(OnGetVerbs);
SubscribeLocalEvent<EntityHeaterComponent, PowerChangedEvent>(OnPowerChanged);
}

public override void Update(float deltaTime)
{
var query = EntityQueryEnumerator<EntityHeaterComponent, ItemPlacerComponent, ApcPowerReceiverComponent>();
while (query.MoveNext(out var uid, out var comp, out var placer, out var power))
{
if (!power.Powered)
continue;

// don't divide by total entities since its a big grill
// excess would just be wasted in the air but that's not worth simulating
// if you want a heater thermomachine just use that...
var energy = power.PowerReceived * deltaTime;
foreach (var ent in placer.PlacedEntities)
{
_temperature.ChangeHeat(ent, energy);
}
}
}

private void OnExamined(EntityUid uid, EntityHeaterComponent comp, ExaminedEvent args)
{
if (!args.IsInDetailsRange)
return;

args.PushMarkup(Loc.GetString("entity-heater-examined", ("setting", comp.Setting)));
}

private void OnGetVerbs(EntityUid uid, EntityHeaterComponent comp, GetVerbsEvent<AlternativeVerb> args)
{
if (!args.CanAccess || !args.CanInteract)
return;

var setting = (int) comp.Setting;
setting++;
setting %= SettingCount;
var nextSetting = (EntityHeaterSetting) setting;

args.Verbs.Add(new AlternativeVerb()
{
Text = Loc.GetString("entity-heater-switch-setting", ("setting", nextSetting)),
Act = () =>
{
ChangeSetting(uid, nextSetting, comp);
_popup.PopupEntity(Loc.GetString("entity-heater-switched-setting", ("setting", nextSetting)), uid, args.User);
}
});
}

private void OnPowerChanged(EntityUid uid, EntityHeaterComponent comp, ref PowerChangedEvent args)
{
// disable heating element glowing layer if theres no power
// doesn't actually turn it off since that would be annoying
var setting = args.Powered ? comp.Setting : EntityHeaterSetting.Off;
_appearance.SetData(uid, EntityHeaterVisuals.Setting, setting);
}

private void ChangeSetting(EntityUid uid, EntityHeaterSetting setting, EntityHeaterComponent? comp = null, ApcPowerReceiverComponent? power = null)
{
if (!Resolve(uid, ref comp, ref power))
return;

comp.Setting = setting;
power.Load = SettingPower(setting, comp.Power);
_appearance.SetData(uid, EntityHeaterVisuals.Setting, setting);
}

private float SettingPower(EntityHeaterSetting setting, float max)
{
switch (setting)
{
case EntityHeaterSetting.Low:
return max / 3f;
case EntityHeaterSetting.Medium:
return max * 2f / 3f;
case EntityHeaterSetting.High:
return max;
default:
return 0f;
}
}
}
Loading

0 comments on commit 28afec6

Please sign in to comment.