Adds FlammableComponent, humans can now catch on fire. (#2115)

This commit is contained in:
Víctor Aguilera Puerto
2020-09-22 15:40:04 +02:00
committed by GitHub
parent 4c34a12c67
commit 31e0dfc10c
33 changed files with 457 additions and 54 deletions

View File

@@ -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
}
}

View File

@@ -2,15 +2,8 @@
namespace Content.Server.Atmos namespace Content.Server.Atmos
{ {
public class FireActEvent : EntitySystemMessage public interface IFireAct
{ {
public float Temperature { get; } void FireAct(float temperature, float volume);
public float Volume { get; }
public FireActEvent(float temperature, float volume)
{
Temperature = temperature;
Volume = volume;
}
} }
} }

View File

@@ -509,7 +509,7 @@ namespace Content.Server.Atmos
if (!doReaction) if (!doReaction)
continue; continue;
reaction = prototype.React(this, holder, _atmosphereSystem.EventBus); reaction = prototype.React(this, holder, _atmosphereSystem.GridTileLookupSystem);
if(reaction.HasFlag(ReactionResult.StopReactions)) if(reaction.HasFlag(ReactionResult.StopReactions))
break; break;
} }

View 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);
}
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using Content.Server.Interfaces; using Content.Server.Interfaces;
using Content.Shared.Atmos; using Content.Shared.Atmos;
using Robust.Server.GameObjects.EntitySystems.TileLookup;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
@@ -65,13 +66,13 @@ namespace Content.Server.Atmos.Reactions
serializer.DataField(ref _effects, "effects", new List<IGasReactionEffect>()); 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; var result = ReactionResult.NoReaction;
foreach (var effect in _effects) foreach (var effect in _effects)
{ {
result |= effect.React(mixture, holder, eventBus); result |= effect.React(mixture, holder, gridLookup);
} }
return result; return result;

View File

@@ -1,8 +1,10 @@
#nullable enable #nullable enable
using System; using System;
using Content.Server.Interfaces; using Content.Server.Interfaces;
using Content.Server.Utility;
using Content.Shared.Atmos; using Content.Shared.Atmos;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Server.GameObjects.EntitySystems.TileLookup;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
@@ -11,7 +13,7 @@ namespace Content.Server.Atmos.Reactions
[UsedImplicitly] [UsedImplicitly]
public class PhoronFireReaction : IGasReactionEffect 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 energyReleased = 0f;
var oldHeatCapacity = mixture.HeatCapacity; var oldHeatCapacity = mixture.HeatCapacity;
@@ -72,7 +74,15 @@ namespace Content.Server.Atmos.Reactions
{ {
location.HotspotExpose(temperature, mixture.Volume); 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);
} }
} }

View File

@@ -1,7 +1,9 @@
#nullable enable #nullable enable
using Content.Server.Interfaces; using Content.Server.Interfaces;
using Content.Server.Utility;
using Content.Shared.Atmos; using Content.Shared.Atmos;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Server.GameObjects.EntitySystems.TileLookup;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Serialization; 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 energyReleased = 0f;
var oldHeatCapacity = mixture.HeatCapacity; var oldHeatCapacity = mixture.HeatCapacity;
@@ -67,7 +69,15 @@ namespace Content.Server.Atmos.Reactions
{ {
location.HotspotExpose(temperature, mixture.Volume); 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);
} }
} }

View File

@@ -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;
}
}
}

View File

@@ -821,8 +821,14 @@ namespace Content.Server.Atmos
if (tileRef == null) return; if (tileRef == null) return;
_gridAtmosphereComponent.Owner.EntityManager. foreach (var entity in tileRef?.GetEntitiesInTileFast(_gridTileLookupSystem))
EventBus.QueueEvent(EventSource.Local, new FireActEvent(Hotspot.Temperature, Hotspot.Volume)); {
foreach (var fireAct in entity.GetAllComponents<IFireAct>())
{
fireAct.FireAct(Hotspot.Temperature, Hotspot.Volume);
}
}
} }
private bool ConsiderSuperconductivity() private bool ConsiderSuperconductivity()

View File

@@ -5,7 +5,7 @@ using Robust.Shared.GameObjects;
namespace Content.Server.GameObjects.Components.Atmos namespace Content.Server.GameObjects.Components.Atmos
{ {
/// <summary> /// <summary>
/// Represents that entity can be exposed to Atmo /// Represents that entity can be exposed to Atmos
/// </summary> /// </summary>
[RegisterComponent] [RegisterComponent]
public class AtmosExposedComponent public class AtmosExposedComponent
@@ -13,7 +13,7 @@ namespace Content.Server.GameObjects.Components.Atmos
{ {
public override string Name => "AtmosExposed"; 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)) if (Owner.TryGetComponent<TemperatureComponent>(out var temperatureComponent))
{ {
@@ -31,6 +31,10 @@ namespace Content.Server.GameObjects.Components.Atmos
barotraumaComponent.Update(tile.Air?.Pressure ?? 0); barotraumaComponent.Update(tile.Air?.Pressure ?? 0);
} }
if (Owner.TryGetComponent<FlammableComponent>(out var flammableComponent))
{
flammableComponent.Update(tile);
}
} }
} }

View File

@@ -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;
}
}
}
}

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Content.Server.GameObjects.Components.Atmos;
using Content.Server.GameObjects.Components.Buckle; using Content.Server.GameObjects.Components.Buckle;
using Content.Server.GameObjects.Components.GUI; using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Movement; using Content.Server.GameObjects.Components.Movement;
@@ -94,28 +95,30 @@ namespace Content.Server.GameObjects.Components.Mobs
{ {
case StatusEffect.Buckled: case StatusEffect.Buckled:
if (!player.TryGetComponent(out BuckleComponent buckle)) if (!player.TryGetComponent(out BuckleComponent buckle))
{
break; break;
}
buckle.TryUnbuckle(player); buckle.TryUnbuckle(player);
break; break;
case StatusEffect.Piloting: case StatusEffect.Piloting:
if (!player.TryGetComponent(out ShuttleControllerComponent controller)) if (!player.TryGetComponent(out ShuttleControllerComponent controller))
{
break; break;
}
controller.RemoveController(); controller.RemoveController();
break; break;
case StatusEffect.Pulling: case StatusEffect.Pulling:
if (!player.TryGetComponent(out HandsComponent hands)) if (!player.TryGetComponent(out HandsComponent hands))
{
break; break;
}
hands.StopPull(); hands.StopPull();
break; break;
case StatusEffect.Fire:
if (!player.TryGetComponent(out FlammableComponent flammable))
break;
flammable.Resist();
break;
default: default:
player.PopupMessage(msg.Effect.ToString()); player.PopupMessage(msg.Effect.ToString());
break; break;

View File

@@ -1,8 +1,10 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Content.Server.GameObjects.Components.Mobs;
using Content.Shared.Atmos; using Content.Shared.Atmos;
using Content.Shared.Damage; using Content.Shared.Damage;
using Content.Shared.GameObjects.Components.Damage; using Content.Shared.GameObjects.Components.Damage;
using Content.Shared.GameObjects.Components.Mobs;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components; using Robust.Shared.GameObjects.Components;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
@@ -72,11 +74,51 @@ namespace Content.Server.GameObjects.Components.Temperature
damageType = DamageType.Cold; 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 (!damageType.HasValue) return;
if (!Owner.TryGetComponent(out IDamageableComponent component)) return; if (!Owner.TryGetComponent(out IDamageableComponent component)) return;
component.ChangeDamage(damageType.Value, tempDamage, false); component.ChangeDamage(damageType.Value, tempDamage, false);
Debug.Write($"Temp is: {CurrentTemperature}");
} }
/// <summary> /// <summary>

View File

@@ -13,13 +13,14 @@ namespace Content.Server.GameObjects.EntitySystems
{ {
[Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IEntityManager _entityManager = default!;
private const float UpdateDelay = 3f; private const float UpdateDelay = 1f;
private float _lastUpdate; private float _lastUpdate;
public override void Update(float frameTime) public override void Update(float frameTime)
{ {
_lastUpdate += frameTime; _lastUpdate += frameTime;
if (_lastUpdate < UpdateDelay) return; if (_lastUpdate < UpdateDelay) return;
var atmosSystem = EntitySystemManager.GetEntitySystem<AtmosphereSystem>();
// creadth: everything exposable by atmos should be updated as well // creadth: everything exposable by atmos should be updated as well
foreach (var atmosExposedComponent in EntityManager.ComponentManager.EntityQuery<AtmosExposedComponent>()) foreach (var atmosExposedComponent in EntityManager.ComponentManager.EntityQuery<AtmosExposedComponent>())
{ {

View File

@@ -7,9 +7,11 @@ using Content.Server.Atmos.Reactions;
using Content.Server.GameObjects.Components.Atmos; using Content.Server.GameObjects.Components.Atmos;
using Content.Shared.GameObjects.EntitySystems.Atmos; using Content.Shared.GameObjects.EntitySystems.Atmos;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Server.GameObjects.EntitySystems.TileLookup;
using Robust.Server.Interfaces.Timing; using Robust.Server.Interfaces.Timing;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components.Map; using Robust.Shared.GameObjects.Components.Map;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map; using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC; using Robust.Shared.IoC;
@@ -29,6 +31,7 @@ namespace Content.Server.GameObjects.EntitySystems
private GasReactionPrototype[] _gasReactions = Array.Empty<GasReactionPrototype>(); private GasReactionPrototype[] _gasReactions = Array.Empty<GasReactionPrototype>();
private SpaceGridAtmosphereComponent _spaceAtmos = default!; private SpaceGridAtmosphereComponent _spaceAtmos = default!;
private GridTileLookupSystem? _gridTileLookup = null;
/// <summary> /// <summary>
/// List of gas reactions ordered by priority. /// List of gas reactions ordered by priority.
@@ -40,6 +43,8 @@ namespace Content.Server.GameObjects.EntitySystems
/// </summary> /// </summary>
public IEventBus EventBus => _entityManager.EventBus; public IEventBus EventBus => _entityManager.EventBus;
public GridTileLookupSystem GridTileLookupSystem => _gridTileLookup ??= Get<GridTileLookupSystem>();
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();

View File

@@ -1,6 +1,7 @@
#nullable enable #nullable enable
using Content.Server.Atmos; using Content.Server.Atmos;
using Content.Server.Atmos.Reactions; using Content.Server.Atmos.Reactions;
using Robust.Server.GameObjects.EntitySystems.TileLookup;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.Serialization; using Robust.Shared.Interfaces.Serialization;
@@ -8,6 +9,6 @@ namespace Content.Server.Interfaces
{ {
public interface IGasReactionEffect : IExposeData public interface IGasReactionEffect : IExposeData
{ {
ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, IEventBus eventBus); ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, GridTileLookupSystem gridTileLookup);
} }
} }

View File

@@ -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,
}
}

View File

@@ -57,6 +57,8 @@ namespace Content.Shared.GameObjects.Components.Mobs
Hunger, Hunger,
Thirst, Thirst,
Pressure, Pressure,
Fire,
Temperature,
Stun, Stun,
Cuffed, Cuffed,
Buckled, Buckled,

View File

@@ -112,6 +112,7 @@ namespace Content.Shared.GameObjects.Components.Movement
{ {
if (!uid.IsValid() || !_entityManager.EntityExists(uid)) if (!uid.IsValid() || !_entityManager.EntityExists(uid))
{ {
_slipped.Remove(uid);
continue; continue;
} }

View File

@@ -20,6 +20,7 @@ namespace Content.Shared.Preferences.Appearance
RFoot, RFoot,
LFoot, LFoot,
Handcuffs, Handcuffs,
StencilMask StencilMask,
Fire,
} }
} }

View File

@@ -116,6 +116,10 @@
sprite: Effects/creampie.rsi sprite: Effects/creampie.rsi
state: creampie_human state: creampie_human
visible: false visible: false
- map: ["enum.FireVisualLayers.Fire"]
sprite: Mobs/Effects/onfire.rsi
state: Generic_mob_burning
visible: false
- type: Icon - type: Icon
sprite: Mobs/Species/Human/parts.rsi sprite: Mobs/Species/Human/parts.rsi
state: full state: full
@@ -133,6 +137,9 @@
- Opaque - Opaque
- MobImpassable - MobImpassable
- type: AtmosExposed - type: AtmosExposed
- type: Flammable
fireSpread: true
canResistFire: true
- type: Temperature - type: Temperature
heatDamageThreshold: 360 heatDamageThreshold: 360
coldDamageThreshold: 260 coldDamageThreshold: 260
@@ -163,6 +170,10 @@
visuals: visuals:
- type: RotationVisualizer - type: RotationVisualizer
- type: BuckleVisualizer - type: BuckleVisualizer
- type: FireVisualizer
normalState: Generic_mob_burning
alternateState: Standing
fireStackAlternateState: 3
- type: CreamPiedVisualizer - type: CreamPiedVisualizer
- type: CombatMode - type: CombatMode
- type: Climbing - type: Climbing

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View 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]]}]}

View File

@@ -131,6 +131,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=swsl/@EntryIndexedValue">True</s:Boolean> <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/=TCMB/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Teleporter/@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/=Thonk/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Transen/@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> <s:Boolean x:Key="/Default/UserDictionary/Words/=Uncuff/@EntryIndexedValue">True</s:Boolean>