Some work

This commit is contained in:
Víctor Aguilera Puerto
2020-08-19 12:23:42 +02:00
parent 259762717b
commit 5190c04944
40 changed files with 586 additions and 52 deletions

View File

@@ -2,6 +2,7 @@
using Content.Client.GameObjects.Components.Wires; using Content.Client.GameObjects.Components.Wires;
using Content.Shared.Audio; using Content.Shared.Audio;
using Content.Shared.GameObjects.Components.Doors; using Content.Shared.GameObjects.Components.Doors;
using JetBrains.Annotations;
using Robust.Client.Animations; using Robust.Client.Animations;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Client.GameObjects.Components.Animations; using Robust.Client.GameObjects.Components.Animations;
@@ -12,6 +13,7 @@ using YamlDotNet.RepresentationModel;
namespace Content.Client.GameObjects.Components.Doors namespace Content.Client.GameObjects.Components.Doors
{ {
[UsedImplicitly]
public class AirlockVisualizer : AppearanceVisualizer public class AirlockVisualizer : AppearanceVisualizer
{ {
private const string AnimationKey = "airlock_animation"; private const string AnimationKey = "airlock_animation";
@@ -24,11 +26,17 @@ namespace Content.Client.GameObjects.Components.Doors
{ {
base.LoadData(node); base.LoadData(node);
var delay = 0.8f;
var openSound = node.GetNode("open_sound").AsString(); var openSound = node.GetNode("open_sound").AsString();
var closeSound = node.GetNode("close_sound").AsString(); var closeSound = node.GetNode("close_sound").AsString();
var denySound = node.GetNode("deny_sound").AsString(); var denySound = node.GetNode("deny_sound").AsString();
if (node.TryGetNode("animation_time", out var yamlNode))
{
delay = yamlNode.AsFloat();
}
CloseAnimation = new Animation {Length = TimeSpan.FromSeconds(0.8f)}; CloseAnimation = new Animation {Length = TimeSpan.FromSeconds(delay)};
{ {
var flick = new AnimationTrackSpriteFlick(); var flick = new AnimationTrackSpriteFlick();
CloseAnimation.AnimationTracks.Add(flick); CloseAnimation.AnimationTracks.Add(flick);
@@ -50,7 +58,7 @@ namespace Content.Client.GameObjects.Components.Doors
sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(closeSound, 0)); sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(closeSound, 0));
} }
OpenAnimation = new Animation {Length = TimeSpan.FromSeconds(0.8f)}; OpenAnimation = new Animation {Length = TimeSpan.FromSeconds(delay)};
{ {
var flick = new AnimationTrackSpriteFlick(); var flick = new AnimationTrackSpriteFlick();
OpenAnimation.AnimationTracks.Add(flick); OpenAnimation.AnimationTracks.Add(flick);

View File

@@ -45,6 +45,12 @@ namespace Content.Server.Atmos
/// </summary> /// </summary>
void FixVacuum(MapIndices indices); void FixVacuum(MapIndices indices);
/// <summary>
/// Revalidates indices immediately.
/// </summary>
/// <param name="indices"></param>
void Revalidate(MapIndices indices);
/// <summary> /// <summary>
/// Adds an active tile so it becomes processed every update until it becomes inactive. /// Adds an active tile so it becomes processed every update until it becomes inactive.
/// Also makes the tile excited. /// Also makes the tile excited.

View File

@@ -1051,6 +1051,25 @@ namespace Content.Server.Atmos
private void ConsiderFirelocks(TileAtmosphere other) private void ConsiderFirelocks(TileAtmosphere other)
{ {
// TODO ATMOS firelocks! // TODO ATMOS firelocks!
var reconsiderAdjacent = false;
foreach (var entity in GridIndices.GetEntitiesInTile(GridIndex))
{
if (!entity.TryGetComponent(out FirelockComponent firelock)) continue;
reconsiderAdjacent |= firelock.EmergencyPressureStop();
}
foreach (var entity in other.GridIndices.GetEntitiesInTile(other.GridIndex))
{
if (!entity.TryGetComponent(out FirelockComponent firelock)) continue;
reconsiderAdjacent |= firelock.EmergencyPressureStop();
}
if (reconsiderAdjacent)
{
UpdateAdjacent();
other.UpdateAdjacent();
}
} }
private void React() private void React()

View File

@@ -28,7 +28,7 @@ namespace Content.Server.GameObjects.Components.Atmos
set set
{ {
_airBlocked = value; _airBlocked = value;
EntitySystem.Get<AtmosphereSystem>().GetGridAtmosphere(Owner.Transform.GridID)?.Invalidate(_snapGrid.Position); EntitySystem.Get<AtmosphereSystem>().GetGridAtmosphere(Owner.Transform.GridID)?.Revalidate(_snapGrid.Position);
} }
} }

View File

@@ -0,0 +1,85 @@
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Doors;
using Content.Server.GameObjects.Components.Interactable;
using Content.Shared.GameObjects.Components.Doors;
using Content.Shared.GameObjects.Components.Interactable;
using Content.Shared.Interfaces.GameObjects.Components;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components;
using Robust.Shared.Interfaces.GameObjects;
namespace Content.Server.GameObjects.Components.Atmos
{
[RegisterComponent]
public class FirelockComponent : ServerDoorComponent, IInteractUsing, IActivate, ICollideBehavior
{
public override string Name => "Firelock";
public override void Initialize()
{
base.Initialize();
}
public void CollideWith(IEntity collidedWith)
{
// We do nothing.
}
public void Activate(ActivateEventArgs eventArgs)
{
// We do nothing.
}
protected override void Startup()
{
base.Startup();
var airtightComponent = Owner.EnsureComponent<AirtightComponent>();
var collidableComponent = Owner.GetComponent<ICollidableComponent>();
Safety = false;
airtightComponent.AirBlocked = false;
collidableComponent.Hard = false;
if (Occludes && Owner.TryGetComponent(out OccluderComponent occluder))
{
occluder.Enabled = false;
}
State = DoorState.Open;
SetAppearance(DoorVisualState.Open);
}
public bool EmergencyPressureStop()
{
var closed = State == DoorState.Open && Close();
if(closed)
Owner.GetComponent<AirtightComponent>().AirBlocked = true;
return closed;
}
public override void Deny()
{
}
public override bool CanClose(IEntity user) => true;
public override bool CanOpen(IEntity user) => true;
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
{
if (!eventArgs.Using.TryGetComponent<ToolComponent>(out var tool))
return false;
if (!await tool.UseTool(eventArgs.User, Owner, 3f, ToolQuality.Prying)) return false;
if (State == DoorState.Closed)
Open();
else if (State == DoorState.Open)
Close();
return true;
}
}
}

View File

@@ -147,55 +147,62 @@ namespace Content.Server.GameObjects.Components.Atmos
{ {
foreach (var indices in _invalidatedCoords.ToArray()) foreach (var indices in _invalidatedCoords.ToArray())
{ {
var tile = GetTile(indices); Revalidate(indices);
AddActiveTile(tile);
if (tile == null)
{
tile = new TileAtmosphere(this, _grid.Index, indices, new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C});
_tiles[indices] = tile;
}
if (IsSpace(indices))
{
tile.Air = new GasMixture(GetVolumeForCells(1));
tile.Air.MarkImmutable();
_tiles[indices] = tile;
} else if (IsAirBlocked(indices))
{
tile.Air = null;
}
else
{
var obs = GetObstructingComponent(indices);
if (obs != null)
{
if (tile.Air == null && obs.FixVacuum)
{
FixVacuum(tile.GridIndices);
}
}
tile.Air ??= new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C};
}
tile.UpdateAdjacent();
tile.UpdateVisuals();
foreach (var direction in Cardinal)
{
var otherIndices = indices.Offset(direction);
var otherTile = GetTile(otherIndices);
AddActiveTile(otherTile);
otherTile?.UpdateAdjacent(direction.GetOpposite());
}
} }
_invalidatedCoords.Clear(); _invalidatedCoords.Clear();
} }
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Revalidate(MapIndices indices)
{
var tile = GetTile(indices);
AddActiveTile(tile);
if (tile == null)
{
tile = new TileAtmosphere(this, _grid.Index, indices, new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C});
_tiles[indices] = tile;
}
if (IsSpace(indices))
{
tile.Air = new GasMixture(GetVolumeForCells(1));
tile.Air.MarkImmutable();
_tiles[indices] = tile;
} else if (IsAirBlocked(indices))
{
tile.Air = null;
}
else
{
var obs = GetObstructingComponent(indices);
if (obs != null)
{
if (tile.Air == null && obs.FixVacuum)
{
FixVacuum(tile.GridIndices);
}
}
tile.Air ??= new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C};
}
tile.UpdateAdjacent();
tile.UpdateVisuals();
foreach (var direction in Cardinal)
{
var otherIndices = indices.Offset(direction);
var otherTile = GetTile(otherIndices);
AddActiveTile(otherTile);
otherTile?.UpdateAdjacent(direction.GetOpposite());
}
}
/// <inheritdoc /> /// <inheritdoc />
public void FixVacuum(MapIndices indices) public void FixVacuum(MapIndices indices)
{ {

View File

@@ -61,6 +61,8 @@ namespace Content.Server.GameObjects.Components.Doors
[ViewVariables] private bool _occludes; [ViewVariables] private bool _occludes;
public bool Occludes => _occludes;
public override void ExposeData(ObjectSerializer serializer) public override void ExposeData(ObjectSerializer serializer)
{ {
base.ExposeData(serializer); base.ExposeData(serializer);
@@ -133,7 +135,7 @@ namespace Content.Server.GameObjects.Components.Doors
} }
} }
private void SetAppearance(DoorVisualState state) protected void SetAppearance(DoorVisualState state)
{ {
if (_appearance != null || Owner.TryGetComponent(out _appearance)) if (_appearance != null || Owner.TryGetComponent(out _appearance))
_appearance.SetData(DoorVisuals.VisualState, state); _appearance.SetData(DoorVisuals.VisualState, state);
@@ -144,7 +146,7 @@ namespace Content.Server.GameObjects.Components.Doors
return true; return true;
} }
public bool CanOpen(IEntity user) public virtual bool CanOpen(IEntity user)
{ {
if (!CanOpen()) return false; if (!CanOpen()) return false;
if (!Owner.TryGetComponent(out AccessReader accessReader)) if (!Owner.TryGetComponent(out AccessReader accessReader))
@@ -205,7 +207,7 @@ namespace Content.Server.GameObjects.Components.Doors
return true; return true;
} }
public bool CanClose(IEntity user) public virtual bool CanClose(IEntity user)
{ {
if (!CanClose()) return false; if (!CanClose()) return false;
if (!Owner.TryGetComponent(out AccessReader accessReader)) if (!Owner.TryGetComponent(out AccessReader accessReader))

View File

@@ -1,5 +1,7 @@
#nullable enable #nullable enable
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using Content.Shared.Physics; using Content.Shared.Physics;
using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map; using Robust.Shared.Interfaces.Map;
@@ -62,6 +64,7 @@ namespace Content.Shared.Maps
/// <summary> /// <summary>
/// Helper that returns all entities in a turf. /// Helper that returns all entities in a turf.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IEnumerable<IEntity> GetEntitiesInTile(this TileRef turf, bool approximate = false) public static IEnumerable<IEntity> GetEntitiesInTile(this TileRef turf, bool approximate = false)
{ {
var entityManager = IoCManager.Resolve<IEntityManager>(); var entityManager = IoCManager.Resolve<IEntityManager>();
@@ -69,6 +72,32 @@ namespace Content.Shared.Maps
return entityManager.GetEntitiesIntersecting(turf.MapIndex, GetWorldTileBox(turf), approximate); return entityManager.GetEntitiesIntersecting(turf.MapIndex, GetWorldTileBox(turf), approximate);
} }
/// <summary>
/// Helper that returns all entities in a turf.
/// </summary>
public static IEnumerable<IEntity> GetEntitiesInTile(this GridCoordinates coordinates, bool approximate = false)
{
var turf = coordinates.GetTileRef();
if (turf == null)
return Enumerable.Empty<IEntity>();
return GetEntitiesInTile(turf.Value);
}
/// <summary>
/// Helper that returns all entities in a turf.
/// </summary>
public static IEnumerable<IEntity> GetEntitiesInTile(this MapIndices indices, GridId gridId, bool approximate = false)
{
var turf = indices.GetTileRef(gridId);
if (turf == null)
return Enumerable.Empty<IEntity>();
return GetEntitiesInTile(turf.Value);
}
/// <summary> /// <summary>
/// Checks if a turf has something dense on it. /// Checks if a turf has something dense on it.
/// </summary> /// </summary>

View File

@@ -54,7 +54,6 @@
type: WiresBoundUserInterface type: WiresBoundUserInterface
- type: Airtight - type: Airtight
fixVacuum: true fixVacuum: true
adjacentAtmosphere: true
- type: Occluder - type: Occluder
- type: SnapGrid - type: SnapGrid
offset: Center offset: Center

View File

@@ -0,0 +1,74 @@
- type: entity
id: Firelock
name: firelock
description: Apply crowbar.
components:
- type: Clickable
- type: InteractionOutline
- type: Sprite
netsync: false
drawdepth: Mobs # They're on the same layer as mobs, perspective.
sprite: Constructible/Structures/Doors/firelock.rsi
layers:
- state: closed
map: ["enum.DoorVisualLayers.Base"]
- state: closed_unlit
shader: unshaded
map: ["enum.DoorVisualLayers.BaseUnlit"]
- state: bolted
shader: unshaded
map: ["enum.DoorVisualLayers.BaseBolted"]
- state: panel_open
map: ["enum.WiresVisualLayers.MaintenancePanel"]
- type: Icon
sprite: Constructible/Structures/Doors/firelock.rsi
state: closed
- type: Collidable
shapes:
- !type:PhysShapeAabb
bounds: "-0.49,-0.49,0.49,0.49" # don't want this colliding with walls or they won't close
mask:
- MobImpassable
layer:
- Opaque
- Impassable
- MobImpassable
- VaultImpassable
- SmallImpassable
- type: Firelock
- type: Appearance
visuals:
- type: AirlockVisualizer
open_sound: /Audio/Machines/airlock_open.ogg
close_sound: /Audio/Machines/airlock_close.ogg
deny_sound: /Audio/Machines/airlock_deny.ogg
animation_time: 0.6
- type: WiresVisualizer
- type: Wires
BoardName: "Firelock Control"
LayoutId: Firelock
- type: UserInterface
interfaces:
- key: enum.WiresUiKey.Key
type: WiresBoundUserInterface
- type: Airtight
fixVacuum: true
- type: Occluder
- type: SnapGrid
offset: Center
placement:
mode: SnapgridCenter
- type: entity
id: FirelockGlass
parent: Firelock
name: glass firelock
components:
- type: Firelock
occludes: false
- type: Occluder
enabled: false
- type: Sprite
sprite: Constructible/Structures/Doors/firelock_glass.rsi
- type: Icon
sprite: Constructible/Structures/Doors/firelock_glass.rsi

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,170 @@
{
"version": 1,
"size": {
"x": 32,
"y": 32
},
"license": "CC-BY-SA 3.0",
"copyright": "Taken from https://github.com/tgstation/tgstation at 04e43d8c1d5097fdb697addd4395fb849dd341bd",
"states": [
{
"name": "closed",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "closing",
"directions": 1,
"delays": [
[
0.2,
0.2,
0.2,
0.2,
0.2,
0.2
]
]
},
{
"name": "deny",
"directions": 1,
"delays": [
[
0.1,
0.1,
0.1
]
]
},
{
"name": "frame1",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "frame2",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "frame3",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "frame4",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "locked",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "open",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "opening",
"directions": 1,
"delays": [
[
0.2,
0.2,
0.2,
0.2,
0.2,
0.2
]
]
},
{
"name": "panel_closing",
"directions": 1,
"delays": [
[
0.1,
0.1,
0.07,
0.07,
0.07,
0.07,
0.27
]
]
},
{
"name": "panel_open",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "panel_opening",
"directions": 1,
"delays": [
[
0.2,
0.07,
0.07,
0.07,
0.07,
0.07,
0.2
]
]
},
{
"name": "welded",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "welded_open",
"directions": 1,
"delays": [
[
1.0
]
]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 639 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,134 @@
{
"version": 1,
"size": {
"x": 32,
"y": 32
},
"license": "CC-BY-SA 3.0",
"copyright": "Taken from https://github.com/tgstation/tgstation at 04e43d8c1d5097fdb697addd4395fb849dd341bd",
"states": [
{
"name": "closed",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "closing",
"directions": 1,
"delays": [
[
0.2,
0.2,
0.2,
0.2,
0.2,
0.2
]
]
},
{
"name": "deny",
"directions": 1,
"delays": [
[
0.1,
0.1,
0.1
]
]
},
{
"name": "locked",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "open",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "opening",
"directions": 1,
"delays": [
[
0.2,
0.2,
0.2,
0.2,
0.2,
0.2
]
]
},
{
"name": "panel_closing",
"directions": 1,
"delays": [
[
0.1,
0.1,
0.07,
0.07,
0.07,
0.07,
0.27
]
]
},
{
"name": "panel_open",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "panel_opening",
"directions": 1,
"delays": [
[
0.2,
0.07,
0.07,
0.07,
0.07,
0.07,
0.2
]
]
},
{
"name": "welded",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "welded_open",
"directions": 1,
"delays": [
[
1.0
]
]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 563 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

View File

@@ -51,6 +51,7 @@
<s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue">&lt;data&gt;&lt;IncludeFilters /&gt;&lt;ExcludeFilters&gt;&lt;Filter ModuleMask="Lidgren.Network" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;/ExcludeFilters&gt;&lt;/data&gt;</s:String> <s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue">&lt;data&gt;&lt;IncludeFilters /&gt;&lt;ExcludeFilters&gt;&lt;Filter ModuleMask="Lidgren.Network" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;/ExcludeFilters&gt;&lt;/data&gt;</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Collidable/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Collidable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Cooldowns/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Cooldowns/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Firelock/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=firelocks/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=firelocks/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=diminishingly/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=diminishingly/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=flashable/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=flashable/@EntryIndexedValue">True</s:Boolean>