using Content.Server.Atmos.EntitySystems; using Content.Server.Temperature.Components; using Content.Shared.Atmos; using Content.Shared.Inventory; using Content.Shared.Rejuvenate; using Content.Shared.Temperature; using Content.Shared.Projectiles; using Content.Shared.Temperature.Components; using Content.Shared.Temperature.HeatContainer; using Content.Shared.Temperature.Systems; namespace Content.Server.Temperature.Systems; public sealed partial class TemperatureSystem : SharedTemperatureSystem { [Dependency] private AtmosphereSystem _atmosphere = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnAtmosExposedUpdate); SubscribeLocalEvent(OnRejuvenate); Subs.SubscribeWithRelay(OnBeforeHeatExchange, held: false); SubscribeLocalEvent(OnInit); SubscribeLocalEvent(ChangeTemperatureOnCollide); InitializeDamage(); } protected override void OnMapInit(Entity entity, ref MapInitEvent args) { base.OnMapInit(entity, ref args); // Make sure entities don't spawn cold! if (_thermalRegulatorQuery.TryComp(entity, out var comp)) entity.Comp.Temperature = comp.NormalBodyTemperature; } public override void Update(float frameTime) { base.Update(frameTime); // conduct heat from the surface to the inside of entities with internal temperatures var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var comp, out var temp)) { // don't do anything if they equalized var diff = Math.Abs(temp.Temperature - comp.Temperature); if (diff < 0.1f) continue; ConductHeat((uid, temp), ref comp, frameTime, comp.Conductance, true); } UpdateDamage(); } private void OnAtmosExposedUpdate(Entity entity, ref AtmosExposedUpdateEvent args) { var transform = args.Transform; if (transform.MapUid == null) return; // TODO ATMOS: Atmos heat containers!!! var atmosContainer = new HeatContainer(_atmosphere.GetHeatCapacity(args.GasMixture, false), args.GasMixture.Temperature); ConductHeat(entity.AsNullable(), ref atmosContainer, args.DeltaTime, args.ConductivityMod); args.GasMixture.Temperature = atmosContainer.Temperature; } private void OnInit(Entity entity, ref MapInitEvent args) { if (!TemperatureQuery.TryComp(entity, out var temp)) return; // TODO: This shouldn't copy temperature component, but this component is so niche it's not worth the effort of fixing. entity.Comp.Temperature = temp.Temperature; entity.Comp.HeatCapacity = temp.HeatCapacity; } private void OnRejuvenate(Entity entity, ref RejuvenateEvent args) { SetTemperature(entity.AsNullable(), _thermalRegulatorQuery.CompOrNull(entity)?.NormalBodyTemperature ?? Atmospherics.T20C); } private void OnBeforeHeatExchange(Entity entity, ref BeforeHeatExchangeEvent args) { // TODO: Proper coverage modifiers!!! This should be its own system which relays to inventory and then based on coverage spits out a modifier! args.HeatTransferModifier *= entity.Comp.Coefficient; } private void ChangeTemperatureOnCollide(Entity ent, ref ProjectileHitEvent args) { ChangeHeat(args.Target, ent.Comp.Heat, ent.Comp.IgnoreHeatResistance);// adjust the temperature } }