Add a fire extinguisher (#1685)

* added a lantern

* Add A Lantern with radiating light

* Added a GasVapor system and made a base for extinguisher spray.

* switched to using solution component for fire extinguisher

* made it so fire extinguisher's can run out of water vapor

* Added actual Gas to Gas Vapor, now getting atmosphere for touched tiles.

* Made it so gasVapor reacts and dissapates on reacting

* GasVapor now dissapates exponentially while traveling

* Added in-hands for fire extinguisher

* Added Spraysound to gasSprayer and to fire extinguisher prototype

* parameterized GasSprayer and GasVapor

* removed un-used imports in gasSprayer and gasVapor components and systems

* removed accidential threading import into gasmixturecomponent

* add a shared extinguisher component for extinguisher spray rotation instead of piggy-backing on RogueArrow

* paremeterized fuelCost and fuel name in GasSprayerComponent

* Paremeterized gasAmount, removed un-used code from gasVaporComponent

* Removed BaseItem Parent from Extinguisher_spray

* added GasVapor and GasSprayer to Ingored Components list

* reduced offset of spawned extinguisher vapor from player

* Update IgnoredComponents.cs

* renamed SharedExtinguisherComponent to SharedGasSprayerComponent and removed reference to RoguePointingArrow

* renamed shareExtinguisherComponent to SharedGasSprayerComponent

* Update Content.Server/Atmos/GasSprayerComponent.cs

Added check for solution component on GasSprayer.

Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>

* Update Content.Server/Atmos/GasSprayerComponent.cs

Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
This commit is contained in:
SoulSloth
2020-08-18 11:45:49 -04:00
committed by GitHub
parent 8ea9e4cd90
commit 7664b30951
19 changed files with 521 additions and 8 deletions

View File

@@ -0,0 +1,74 @@
using Content.Server.GameObjects.Components.Chemistry;
using Content.Server.Interfaces;
using Content.Shared.Chemistry;
using Content.Shared.GameObjects.Components;
using Content.Shared.GameObjects.Components.Pointing;
using Content.Shared.Interfaces.GameObjects.Components;
using Robust.Server.GameObjects;
using Robust.Server.GameObjects.EntitySystems;
using Robust.Server.Interfaces.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Maths;
using Robust.Shared.Serialization;
namespace Content.Server.Atmos
{
[RegisterComponent]
public class GasSprayerComponent : Component, IAfterInteract
{
#pragma warning disable 649
[Dependency] private readonly IServerNotifyManager _notifyManager = default!;
[Dependency] private readonly IServerEntityManager _serverEntityManager = default!;
#pragma warning restore 649
//TODO: create a function that can create a gas based on a solution mix
public override string Name => "GasSprayer";
private string _spraySound;
private string _sprayType;
private string _fuelType;
private string _fuelName;
private int _fuelCost;
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _spraySound, "spraySound", string.Empty);
serializer.DataField(ref _sprayType, "sprayType", string.Empty);
serializer.DataField(ref _fuelType, "fuelType", string.Empty);
serializer.DataField(ref _fuelName, "fuelName", "fuel");
serializer.DataField(ref _fuelCost, "fuelCost", 50);
}
public void AfterInteract(AfterInteractEventArgs eventArgs)
{
if (!Owner.TryGetComponent(out SolutionComponent tank))
return;
if (tank.Solution.GetReagentQuantity(_fuelType) == 0)
{
_notifyManager.PopupMessage(Owner, eventArgs.User,
Loc.GetString("{0:theName} is out of {1}!", Owner, _fuelName));
}
else
{
tank.TryRemoveReagent(_fuelType, ReagentUnit.New(_fuelCost));
var playerPos = eventArgs.User.Transform.GridPosition;
var direction = (eventArgs.ClickLocation.Position - playerPos.Position).Normalized;
playerPos.Offset(direction/2);
var spray = _serverEntityManager.SpawnEntity(_sprayType, playerPos);
spray.GetComponent<AppearanceComponent>()
.SetData(ExtinguisherVisuals.Rotation, direction.ToAngle().Degrees);
spray.GetComponent<GasVaporComponent>().StartMove(direction, 5);
EntitySystem.Get<AudioSystem>().PlayFromEntity(_spraySound, Owner);
}
}
}
}

View File

@@ -0,0 +1,120 @@
using Content.Shared.Physics;
using Content.Server.Atmos.Reactions;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
using Content.Server.GameObjects.Components.Atmos;
using Content.Server.Interfaces;
using Content.Shared.Atmos;
namespace Content.Server.Atmos
{
[RegisterComponent]
class GasVaporComponent : Component, ICollideBehavior, IGasMixtureHolder
{
[Dependency] private readonly IMapManager _mapManager = default!;
public override string Name => "GasVapor";
[ViewVariables] public GasMixture Air { get; set; }
private bool _running;
private Vector2 _direction;
private float _velocity;
private float _disspateTimer = 0;
private float _dissipationInterval;
private Gas _gas;
private float _gasVolume;
private float _gasTemperature;
private float _gasAmount;
public override void Initialize()
{
base.Initialize();
Air = new GasMixture(_gasVolume){Temperature = _gasTemperature};
Air.SetMoles(_gas,_gasAmount);
}
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _dissipationInterval, "dissipationInterval", 1);
serializer.DataField(ref _gas, "gas", Gas.WaterVapor);
serializer.DataField(ref _gasVolume, "gasVolume", 200);
serializer.DataField(ref _gasTemperature, "gasTemperature", Atmospherics.T20C);
serializer.DataField(ref _gasAmount, "gasAmount", 20);
}
public void StartMove(Vector2 dir, float velocity)
{
_running = true;
_direction = dir;
_velocity = velocity;
if (Owner.TryGetComponent(out ICollidableComponent collidable))
{
var controller = collidable.EnsureController<GasVaporController>();
controller.Move(_direction, _velocity);
}
}
public void Update(float frameTime)
{
if (!_running)
return;
if (Owner.TryGetComponent(out ICollidableComponent collidable))
{
var worldBounds = collidable.WorldAABB;
var mapGrid = _mapManager.GetGrid(Owner.Transform.GridID);
var tiles = mapGrid.GetTilesIntersecting(worldBounds);
foreach (var tile in tiles)
{
var pos = tile.GridIndices.ToGridCoordinates(_mapManager, tile.GridIndex);
var atmos = AtmosHelpers.GetTileAtmosphere(pos);
if (atmos.Air == null)
{
return;
}
if (atmos.Air.React(this) != ReactionResult.NoReaction)
{
Owner.Delete();
}
}
}
_disspateTimer += frameTime;
if (_disspateTimer > _dissipationInterval)
{
Air.SetMoles(_gas, Air.TotalMoles/2 );
}
if (Air.TotalMoles < 1)
{
Owner.Delete();
}
}
void ICollideBehavior.CollideWith(IEntity collidedWith)
{
// Check for collision with a impassable object (e.g. wall) and stop
if (collidedWith.TryGetComponent(out ICollidableComponent collidable) &&
(collidable.CollisionLayer & (int) CollisionGroup.Impassable) != 0 &&
collidable.Hard &&
Owner.TryGetComponent(out ICollidableComponent coll))
{
var controller = coll.EnsureController<GasVaporController>();
controller.Stop();
Owner.Delete();
}
}
}
}