Adds FlammableComponent, humans can now catch on fire. (#2115)
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using Content.Shared.GameObjects.Components.Atmos;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.Utility;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Atmos
|
||||
{
|
||||
public class FireVisualizer : AppearanceVisualizer
|
||||
{
|
||||
private int _fireStackAlternateState = 3;
|
||||
private string _normalState;
|
||||
private string _alternateState;
|
||||
|
||||
public override void LoadData(YamlMappingNode node)
|
||||
{
|
||||
base.LoadData(node);
|
||||
|
||||
if (node.TryGetNode("fireStackAlternateState", out var fireStack))
|
||||
{
|
||||
_fireStackAlternateState = fireStack.AsInt();
|
||||
}
|
||||
|
||||
if (node.TryGetNode("normalState", out var normalState))
|
||||
{
|
||||
_normalState = normalState.AsString();
|
||||
}
|
||||
|
||||
if (node.TryGetNode("alternateState", out var alternateState))
|
||||
{
|
||||
_alternateState = alternateState.AsString();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
|
||||
if (component.TryGetData(FireVisuals.OnFire, out bool onFire))
|
||||
{
|
||||
var fireStacks = 0f;
|
||||
|
||||
if (component.TryGetData(FireVisuals.FireStacks, out float stacks))
|
||||
fireStacks = stacks;
|
||||
|
||||
SetOnFire(component, onFire, fireStacks);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetOnFire(AppearanceComponent component, bool onFire, float fireStacks)
|
||||
{
|
||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||
|
||||
sprite.LayerSetVisible(FireVisualLayers.Fire, onFire);
|
||||
|
||||
if(fireStacks > _fireStackAlternateState && !string.IsNullOrEmpty(_alternateState))
|
||||
sprite.LayerSetState(FireVisualLayers.Fire, _alternateState);
|
||||
else
|
||||
sprite.LayerSetState(FireVisualLayers.Fire, _normalState);
|
||||
}
|
||||
}
|
||||
|
||||
public enum FireVisualLayers
|
||||
{
|
||||
Fire
|
||||
}
|
||||
}
|
||||
@@ -2,15 +2,8 @@
|
||||
|
||||
namespace Content.Server.Atmos
|
||||
{
|
||||
public class FireActEvent : EntitySystemMessage
|
||||
public interface IFireAct
|
||||
{
|
||||
public float Temperature { get; }
|
||||
public float Volume { get; }
|
||||
|
||||
public FireActEvent(float temperature, float volume)
|
||||
{
|
||||
Temperature = temperature;
|
||||
Volume = volume;
|
||||
}
|
||||
void FireAct(float temperature, float volume);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -509,7 +509,7 @@ namespace Content.Server.Atmos
|
||||
if (!doReaction)
|
||||
continue;
|
||||
|
||||
reaction = prototype.React(this, holder, _atmosphereSystem.EventBus);
|
||||
reaction = prototype.React(this, holder, _atmosphereSystem.GridTileLookupSystem);
|
||||
if(reaction.HasFlag(ReactionResult.StopReactions))
|
||||
break;
|
||||
}
|
||||
|
||||
10
Content.Server/Atmos/ITemperatureExpose.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Content.Server.Atmos
|
||||
{
|
||||
public interface ITemperatureExpose
|
||||
{
|
||||
void TemperatureExpose(GasMixture air, float exposedTemperature, float exposedVolume);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Shared.Atmos;
|
||||
using Robust.Server.GameObjects.EntitySystems.TileLookup;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
@@ -65,13 +66,13 @@ namespace Content.Server.Atmos.Reactions
|
||||
serializer.DataField(ref _effects, "effects", new List<IGasReactionEffect>());
|
||||
}
|
||||
|
||||
public ReactionResult React(GasMixture mixture, IGasMixtureHolder holder, IEventBus eventBus)
|
||||
public ReactionResult React(GasMixture mixture, IGasMixtureHolder holder, GridTileLookupSystem gridLookup)
|
||||
{
|
||||
var result = ReactionResult.NoReaction;
|
||||
|
||||
foreach (var effect in _effects)
|
||||
{
|
||||
result |= effect.React(mixture, holder, eventBus);
|
||||
result |= effect.React(mixture, holder, gridLookup);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.Atmos;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects.EntitySystems.TileLookup;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
@@ -11,7 +13,7 @@ namespace Content.Server.Atmos.Reactions
|
||||
[UsedImplicitly]
|
||||
public class PhoronFireReaction : IGasReactionEffect
|
||||
{
|
||||
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, IEventBus eventBus)
|
||||
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, GridTileLookupSystem gridTileLookup)
|
||||
{
|
||||
var energyReleased = 0f;
|
||||
var oldHeatCapacity = mixture.HeatCapacity;
|
||||
@@ -72,7 +74,15 @@ namespace Content.Server.Atmos.Reactions
|
||||
{
|
||||
location.HotspotExpose(temperature, mixture.Volume);
|
||||
|
||||
eventBus.QueueEvent(EventSource.Local, new TemperatureExposeEvent(location.GridIndices, location.GridIndex, mixture, temperature, mixture.Volume));
|
||||
foreach (var entity in location.GridIndices.GetEntitiesInTileFast(location.GridIndex, gridTileLookup))
|
||||
{
|
||||
foreach (var temperatureExpose in entity.GetAllComponents<ITemperatureExpose>())
|
||||
{
|
||||
temperatureExpose.TemperatureExpose(mixture, temperature, mixture.Volume);
|
||||
}
|
||||
}
|
||||
|
||||
location.TemperatureExpose(mixture, temperature, mixture.Volume);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#nullable enable
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.Atmos;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects.EntitySystems.TileLookup;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
@@ -14,7 +16,7 @@ namespace Content.Server.Atmos.Reactions
|
||||
{
|
||||
}
|
||||
|
||||
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, IEventBus eventBus)
|
||||
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, GridTileLookupSystem gridTileLookup)
|
||||
{
|
||||
var energyReleased = 0f;
|
||||
var oldHeatCapacity = mixture.HeatCapacity;
|
||||
@@ -67,7 +69,15 @@ namespace Content.Server.Atmos.Reactions
|
||||
{
|
||||
location.HotspotExpose(temperature, mixture.Volume);
|
||||
|
||||
eventBus.QueueEvent(EventSource.Local, new TemperatureExposeEvent(location.GridIndices, location.GridIndex, mixture, temperature, mixture.Volume));
|
||||
foreach (var entity in location.GridIndices.GetEntitiesInTileFast(location.GridIndex, gridTileLookup))
|
||||
{
|
||||
foreach (var temperatureExpose in entity.GetAllComponents<ITemperatureExpose>())
|
||||
{
|
||||
temperatureExpose.TemperatureExpose(mixture, temperature, mixture.Volume);
|
||||
}
|
||||
}
|
||||
|
||||
location.TemperatureExpose(mixture, temperature, mixture.Volume);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Content.Server.Atmos
|
||||
{
|
||||
public class TemperatureExposeEvent : EntitySystemMessage
|
||||
{
|
||||
public MapIndices Indices { get; }
|
||||
public GridId Grid { get; }
|
||||
public GasMixture Air { get; }
|
||||
public float Temperature { get; }
|
||||
public float Volume { get; }
|
||||
|
||||
public TemperatureExposeEvent(MapIndices indices, GridId gridId, GasMixture air, float temperature, float volume)
|
||||
{
|
||||
Indices = indices;
|
||||
Grid = gridId;
|
||||
Air = air;
|
||||
Temperature = temperature;
|
||||
Volume = volume;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -821,8 +821,14 @@ namespace Content.Server.Atmos
|
||||
|
||||
if (tileRef == null) return;
|
||||
|
||||
_gridAtmosphereComponent.Owner.EntityManager.
|
||||
EventBus.QueueEvent(EventSource.Local, new FireActEvent(Hotspot.Temperature, Hotspot.Volume));
|
||||
foreach (var entity in tileRef?.GetEntitiesInTileFast(_gridTileLookupSystem))
|
||||
{
|
||||
foreach (var fireAct in entity.GetAllComponents<IFireAct>())
|
||||
{
|
||||
|
||||
fireAct.FireAct(Hotspot.Temperature, Hotspot.Volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool ConsiderSuperconductivity()
|
||||
|
||||
@@ -5,7 +5,7 @@ using Robust.Shared.GameObjects;
|
||||
namespace Content.Server.GameObjects.Components.Atmos
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents that entity can be exposed to Atmo
|
||||
/// Represents that entity can be exposed to Atmos
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public class AtmosExposedComponent
|
||||
@@ -13,7 +13,7 @@ namespace Content.Server.GameObjects.Components.Atmos
|
||||
{
|
||||
public override string Name => "AtmosExposed";
|
||||
|
||||
public void Update(TileAtmosphere tile, float timeDelta)
|
||||
public void Update(TileAtmosphere tile, float frameDelta)
|
||||
{
|
||||
if (Owner.TryGetComponent<TemperatureComponent>(out var temperatureComponent))
|
||||
{
|
||||
@@ -31,6 +31,10 @@ namespace Content.Server.GameObjects.Components.Atmos
|
||||
barotraumaComponent.Update(tile.Air?.Pressure ?? 0);
|
||||
}
|
||||
|
||||
if (Owner.TryGetComponent<FlammableComponent>(out var flammableComponent))
|
||||
{
|
||||
flammableComponent.Update(tile);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.Atmos;
|
||||
using Content.Server.GameObjects.Components.Mobs;
|
||||
using Content.Server.GameObjects.Components.Temperature;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.GameObjects.Components.Atmos;
|
||||
using Content.Shared.GameObjects.Components.Damage;
|
||||
using Content.Shared.GameObjects.Components.Mobs;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Timers;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Atmos
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class FlammableComponent : SharedFlammableComponent, ICollideBehavior, IFireAct, IReagentReaction
|
||||
{
|
||||
[Dependency] private IEntityManager _entityManager = default!;
|
||||
|
||||
private bool _resisting = false;
|
||||
private readonly List<EntityUid> _collided = new List<EntityUid>();
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool OnFire { get; private set; }
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float FireStacks { get; private set; }
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool FireSpread { get; private set; } = false;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool CanResistFire { get; private set; } = false;
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
base.ExposeData(serializer);
|
||||
serializer.DataField(this, x => x.FireSpread, "fireSpread", false);
|
||||
serializer.DataField(this, x => x.CanResistFire, "canResistFire", false);
|
||||
}
|
||||
|
||||
public void Ignite()
|
||||
{
|
||||
if (FireStacks > 0 && !OnFire)
|
||||
{
|
||||
OnFire = true;
|
||||
|
||||
}
|
||||
|
||||
UpdateAppearance();
|
||||
}
|
||||
|
||||
public void Extinguish()
|
||||
{
|
||||
if (!OnFire) return;
|
||||
OnFire = false;
|
||||
FireStacks = 0;
|
||||
|
||||
_collided.Clear();
|
||||
|
||||
UpdateAppearance();
|
||||
}
|
||||
|
||||
public void AdjustFireStacks(float relativeFireStacks)
|
||||
{
|
||||
FireStacks = MathF.Max(MathF.Min(-10f, FireStacks + relativeFireStacks), 20f);
|
||||
if (OnFire && FireStacks <= 0)
|
||||
Extinguish();
|
||||
|
||||
UpdateAppearance();
|
||||
}
|
||||
|
||||
public void Update(TileAtmosphere tile)
|
||||
{
|
||||
// Slowly dry ourselves off if wet.
|
||||
if (FireStacks < 0)
|
||||
{
|
||||
FireStacks = MathF.Min(0, FireStacks + 1);
|
||||
}
|
||||
|
||||
Owner.TryGetComponent(out ServerStatusEffectsComponent status);
|
||||
|
||||
if (!OnFire)
|
||||
{
|
||||
status?.RemoveStatusEffect(StatusEffect.Fire);
|
||||
return;
|
||||
}
|
||||
|
||||
status?.ChangeStatusEffect(StatusEffect.Fire, "/Textures/Interface/StatusEffects/Fire/fire.png", null);
|
||||
|
||||
if (FireStacks > 0)
|
||||
{
|
||||
if(Owner.TryGetComponent(out TemperatureComponent temp))
|
||||
{
|
||||
temp.ReceiveHeat(200 * FireStacks);
|
||||
}
|
||||
|
||||
if (Owner.TryGetComponent(out IDamageableComponent damageable))
|
||||
{
|
||||
// TODO ATMOS Fire resistance from armor
|
||||
var damage = Math.Min((int) (FireStacks * 2.5f), 10);
|
||||
damageable.ChangeDamage(DamageClass.Burn, damage, false);
|
||||
}
|
||||
|
||||
AdjustFireStacks(-0.1f * (_resisting ? 10f : 1f));
|
||||
}
|
||||
else
|
||||
{
|
||||
Extinguish();
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're in an oxygenless environment, put the fire out.
|
||||
if (tile?.Air?.GetMoles(Gas.Oxygen) < 1f)
|
||||
{
|
||||
Extinguish();
|
||||
return;
|
||||
}
|
||||
|
||||
tile.HotspotExpose(700, 50, true);
|
||||
|
||||
foreach (var uid in _collided.ToArray())
|
||||
{
|
||||
if (!uid.IsValid() || !_entityManager.EntityExists(uid))
|
||||
{
|
||||
_collided.Remove(uid);
|
||||
continue;
|
||||
}
|
||||
|
||||
var entity = _entityManager.GetEntity(uid);
|
||||
var collidable = Owner.GetComponent<ICollidableComponent>();
|
||||
var otherCollidable = entity.GetComponent<ICollidableComponent>();
|
||||
|
||||
if (!collidable.WorldAABB.Intersects(otherCollidable.WorldAABB))
|
||||
{
|
||||
_collided.Remove(uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CollideWith(IEntity collidedWith)
|
||||
{
|
||||
if (!collidedWith.TryGetComponent(out FlammableComponent otherFlammable))
|
||||
return;
|
||||
|
||||
if (!FireSpread || !otherFlammable.FireSpread)
|
||||
return;
|
||||
|
||||
if (OnFire)
|
||||
{
|
||||
if (otherFlammable.OnFire)
|
||||
{
|
||||
var fireSplit = (FireStacks + otherFlammable.FireStacks) / 2;
|
||||
FireStacks = fireSplit;
|
||||
otherFlammable.FireStacks = fireSplit;
|
||||
}
|
||||
else
|
||||
{
|
||||
FireStacks /= 2;
|
||||
otherFlammable.FireStacks += FireStacks;
|
||||
otherFlammable.Ignite();
|
||||
}
|
||||
} else if (otherFlammable.OnFire)
|
||||
{
|
||||
otherFlammable.FireStacks /= 2;
|
||||
FireStacks += otherFlammable.FireStacks;
|
||||
Ignite();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAppearance()
|
||||
{
|
||||
if (Owner.Deleted || !Owner.TryGetComponent(out AppearanceComponent appearanceComponent)) return;
|
||||
appearanceComponent.SetData(FireVisuals.OnFire, OnFire);
|
||||
appearanceComponent.SetData(FireVisuals.FireStacks, FireStacks);
|
||||
}
|
||||
|
||||
public void FireAct(float temperature, float volume)
|
||||
{
|
||||
AdjustFireStacks(3);
|
||||
Ignite();
|
||||
}
|
||||
|
||||
// This needs some improvements...
|
||||
public void Resist()
|
||||
{
|
||||
if (!OnFire || !ActionBlockerSystem.CanInteract(Owner) || _resisting || !Owner.TryGetComponent(out StunnableComponent stunnable)) return;
|
||||
|
||||
_resisting = true;
|
||||
|
||||
Owner.PopupMessage(Loc.GetString("You stop, drop, and roll!"));
|
||||
stunnable.Paralyze(2f);
|
||||
|
||||
Timer.Spawn(2000, () =>
|
||||
{
|
||||
_resisting = false;
|
||||
FireStacks -= 2f;
|
||||
UpdateAppearance();
|
||||
});
|
||||
}
|
||||
|
||||
public ReagentUnit ReagentReactTouch(ReagentPrototype reagent, ReagentUnit volume)
|
||||
{
|
||||
switch (reagent.ID)
|
||||
{
|
||||
case "chem.H2O":
|
||||
Extinguish();
|
||||
AdjustFireStacks(-1.5f);
|
||||
return ReagentUnit.Zero;
|
||||
|
||||
case "chem.WeldingFuel":
|
||||
case "chem.Thermite":
|
||||
case "chem.Phoron":
|
||||
case "chem.Ethanol":
|
||||
AdjustFireStacks(volume.Float() / 10f);
|
||||
return volume;
|
||||
|
||||
default:
|
||||
return ReagentUnit.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.GameObjects.Components.Atmos;
|
||||
using Content.Server.GameObjects.Components.Buckle;
|
||||
using Content.Server.GameObjects.Components.GUI;
|
||||
using Content.Server.GameObjects.Components.Movement;
|
||||
@@ -94,28 +95,30 @@ namespace Content.Server.GameObjects.Components.Mobs
|
||||
{
|
||||
case StatusEffect.Buckled:
|
||||
if (!player.TryGetComponent(out BuckleComponent buckle))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
buckle.TryUnbuckle(player);
|
||||
break;
|
||||
case StatusEffect.Piloting:
|
||||
if (!player.TryGetComponent(out ShuttleControllerComponent controller))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
controller.RemoveController();
|
||||
break;
|
||||
case StatusEffect.Pulling:
|
||||
if (!player.TryGetComponent(out HandsComponent hands))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
hands.StopPull();
|
||||
break;
|
||||
|
||||
case StatusEffect.Fire:
|
||||
if (!player.TryGetComponent(out FlammableComponent flammable))
|
||||
break;
|
||||
|
||||
flammable.Resist();
|
||||
break;
|
||||
|
||||
default:
|
||||
player.PopupMessage(msg.Effect.ToString());
|
||||
break;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Content.Server.GameObjects.Components.Mobs;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.GameObjects.Components.Damage;
|
||||
using Content.Shared.GameObjects.Components.Mobs;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Components;
|
||||
using Robust.Shared.Serialization;
|
||||
@@ -72,11 +74,51 @@ namespace Content.Server.GameObjects.Components.Temperature
|
||||
damageType = DamageType.Cold;
|
||||
}
|
||||
|
||||
if (Owner.TryGetComponent(out ServerStatusEffectsComponent status))
|
||||
{
|
||||
switch(CurrentTemperature)
|
||||
{
|
||||
// Cold strong.
|
||||
case var t when t <= 260:
|
||||
status.ChangeStatusEffect(StatusEffect.Temperature, "/Textures/Interface/StatusEffects/Temperature/cold3.png", null);
|
||||
break;
|
||||
|
||||
// Cold mild.
|
||||
case var t when t <= 280 && t > 260:
|
||||
status.ChangeStatusEffect(StatusEffect.Temperature, "/Textures/Interface/StatusEffects/Temperature/cold2.png", null);
|
||||
break;
|
||||
|
||||
// Cold weak.
|
||||
case var t when t <= 292 && t > 280:
|
||||
status.ChangeStatusEffect(StatusEffect.Temperature, "/Textures/Interface/StatusEffects/Temperature/cold1.png", null);
|
||||
break;
|
||||
|
||||
// Safe.
|
||||
case var t when t <= 327 && t > 292:
|
||||
status.RemoveStatusEffect(StatusEffect.Temperature);
|
||||
break;
|
||||
|
||||
// Heat weak.
|
||||
case var t when t <= 335 && t > 327:
|
||||
status.ChangeStatusEffect(StatusEffect.Temperature, "/Textures/Interface/StatusEffects/Temperature/hot1.png", null);
|
||||
break;
|
||||
|
||||
// Heat mild.
|
||||
case var t when t <= 345 && t > 335:
|
||||
status.ChangeStatusEffect(StatusEffect.Temperature, "/Textures/Interface/StatusEffects/Temperature/hot2.png", null);
|
||||
break;
|
||||
|
||||
// Heat strong.
|
||||
case var t when t > 345:
|
||||
status.ChangeStatusEffect(StatusEffect.Temperature, "/Textures/Interface/StatusEffects/Temperature/hot3.png", null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!damageType.HasValue) return;
|
||||
|
||||
if (!Owner.TryGetComponent(out IDamageableComponent component)) return;
|
||||
component.ChangeDamage(damageType.Value, tempDamage, false);
|
||||
Debug.Write($"Temp is: {CurrentTemperature}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -13,13 +13,14 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
private const float UpdateDelay = 3f;
|
||||
private const float UpdateDelay = 1f;
|
||||
private float _lastUpdate;
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
_lastUpdate += frameTime;
|
||||
if (_lastUpdate < UpdateDelay) return;
|
||||
var atmosSystem = EntitySystemManager.GetEntitySystem<AtmosphereSystem>();
|
||||
|
||||
// creadth: everything exposable by atmos should be updated as well
|
||||
foreach (var atmosExposedComponent in EntityManager.ComponentManager.EntityQuery<AtmosExposedComponent>())
|
||||
{
|
||||
|
||||
@@ -7,9 +7,11 @@ using Content.Server.Atmos.Reactions;
|
||||
using Content.Server.GameObjects.Components.Atmos;
|
||||
using Content.Shared.GameObjects.EntitySystems.Atmos;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects.EntitySystems.TileLookup;
|
||||
using Robust.Server.Interfaces.Timing;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Components.Map;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Map;
|
||||
using Robust.Shared.IoC;
|
||||
@@ -29,6 +31,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
private GasReactionPrototype[] _gasReactions = Array.Empty<GasReactionPrototype>();
|
||||
|
||||
private SpaceGridAtmosphereComponent _spaceAtmos = default!;
|
||||
private GridTileLookupSystem? _gridTileLookup = null;
|
||||
|
||||
/// <summary>
|
||||
/// List of gas reactions ordered by priority.
|
||||
@@ -40,6 +43,8 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
/// </summary>
|
||||
public IEventBus EventBus => _entityManager.EventBus;
|
||||
|
||||
public GridTileLookupSystem GridTileLookupSystem => _gridTileLookup ??= Get<GridTileLookupSystem>();
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#nullable enable
|
||||
using Content.Server.Atmos;
|
||||
using Content.Server.Atmos.Reactions;
|
||||
using Robust.Server.GameObjects.EntitySystems.TileLookup;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.Serialization;
|
||||
|
||||
@@ -8,6 +9,6 @@ namespace Content.Server.Interfaces
|
||||
{
|
||||
public interface IGasReactionEffect : IExposeData
|
||||
{
|
||||
ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, IEventBus eventBus);
|
||||
ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, GridTileLookupSystem gridTileLookup);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Atmos
|
||||
{
|
||||
public class SharedFlammableComponent : Component
|
||||
{
|
||||
public override string Name => "Flammable";
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum FireVisuals
|
||||
{
|
||||
OnFire,
|
||||
FireStacks,
|
||||
}
|
||||
}
|
||||
@@ -57,6 +57,8 @@ namespace Content.Shared.GameObjects.Components.Mobs
|
||||
Hunger,
|
||||
Thirst,
|
||||
Pressure,
|
||||
Fire,
|
||||
Temperature,
|
||||
Stun,
|
||||
Cuffed,
|
||||
Buckled,
|
||||
|
||||
@@ -112,6 +112,7 @@ namespace Content.Shared.GameObjects.Components.Movement
|
||||
{
|
||||
if (!uid.IsValid() || !_entityManager.EntityExists(uid))
|
||||
{
|
||||
_slipped.Remove(uid);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace Content.Shared.Preferences.Appearance
|
||||
RFoot,
|
||||
LFoot,
|
||||
Handcuffs,
|
||||
StencilMask
|
||||
StencilMask,
|
||||
Fire,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,6 +116,10 @@
|
||||
sprite: Effects/creampie.rsi
|
||||
state: creampie_human
|
||||
visible: false
|
||||
- map: ["enum.FireVisualLayers.Fire"]
|
||||
sprite: Mobs/Effects/onfire.rsi
|
||||
state: Generic_mob_burning
|
||||
visible: false
|
||||
- type: Icon
|
||||
sprite: Mobs/Species/Human/parts.rsi
|
||||
state: full
|
||||
@@ -133,6 +137,9 @@
|
||||
- Opaque
|
||||
- MobImpassable
|
||||
- type: AtmosExposed
|
||||
- type: Flammable
|
||||
fireSpread: true
|
||||
canResistFire: true
|
||||
- type: Temperature
|
||||
heatDamageThreshold: 360
|
||||
coldDamageThreshold: 260
|
||||
@@ -163,6 +170,10 @@
|
||||
visuals:
|
||||
- type: RotationVisualizer
|
||||
- type: BuckleVisualizer
|
||||
- type: FireVisualizer
|
||||
normalState: Generic_mob_burning
|
||||
alternateState: Standing
|
||||
fireStackAlternateState: 3
|
||||
- type: CreamPiedVisualizer
|
||||
- type: CombatMode
|
||||
- type: Climbing
|
||||
|
||||
BIN
Resources/Textures/Interface/StatusEffects/Fire/fire.png
Normal file
|
After Width: | Height: | Size: 414 B |
BIN
Resources/Textures/Interface/StatusEffects/Temperature/cold1.png
Normal file
|
After Width: | Height: | Size: 396 B |
BIN
Resources/Textures/Interface/StatusEffects/Temperature/cold2.png
Normal file
|
After Width: | Height: | Size: 388 B |
BIN
Resources/Textures/Interface/StatusEffects/Temperature/cold3.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
Resources/Textures/Interface/StatusEffects/Temperature/hot1.png
Normal file
|
After Width: | Height: | Size: 365 B |
BIN
Resources/Textures/Interface/StatusEffects/Temperature/hot2.png
Normal file
|
After Width: | Height: | Size: 333 B |
BIN
Resources/Textures/Interface/StatusEffects/Temperature/hot3.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
BIN
Resources/Textures/Mobs/Effects/onfire.rsi/Monkey_burning.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
Resources/Textures/Mobs/Effects/onfire.rsi/Standing.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
1
Resources/Textures/Mobs/Effects/onfire.rsi/meta.json
Normal file
@@ -0,0 +1 @@
|
||||
{"version": 1, "size": {"x": 32, "y": 32}, "license": "CC-BY-SA 3.0", "copyright": "Taken from https://github.com/tgstation/tgstation at 0d9c9a8233dfc3fc55edc538955a761a6328bee0", "states": [{"name": "Generic_mob_burning", "directions": 4, "delays": [[0.1, 0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1, 0.1]]}, {"name": "Monkey_burning", "directions": 4, "delays": [[0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1]]}, {"name": "Standing", "directions": 4, "delays": [[0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1], [0.1, 0.1, 0.1, 0.1]]}]}
|
||||
@@ -131,6 +131,7 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=swsl/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=TCMB/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Teleporter/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Thermite/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Thonk/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Transen/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Uncuff/@EntryIndexedValue">True</s:Boolean>
|
||||
|
||||