Data-oriented Construction System (#2152)
- Powerful - Data-oriented - Approved by PJB - Powered by node graphs and AI pathfinding - Coded by the same nerd who brought you atmos Co-authored-by: Exp <theexp111@gmail.com>
This commit is contained in:
committed by
GitHub
parent
a6647e8de1
commit
745401a41e
68
Content.Server/Construction/Completions/BuildComputer.cs
Normal file
68
Content.Server/Construction/Completions/BuildComputer.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
#nullable enable
|
||||
using System.Threading.Tasks;
|
||||
using Content.Server.GameObjects.Components.Construction;
|
||||
using Content.Shared.Construction;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects.Components.Container;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Server.Construction.Completions
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class BuildComputer : IGraphAction
|
||||
{
|
||||
public string Container { get; private set; } = string.Empty;
|
||||
|
||||
public void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
serializer.DataField(this, x => x.Container, "container", string.Empty);
|
||||
}
|
||||
|
||||
public async Task PerformAction(IEntity entity, IEntity? user)
|
||||
{
|
||||
if (!entity.TryGetComponent(out ContainerManagerComponent? containerManager))
|
||||
{
|
||||
Logger.Warning($"Computer entity {entity} did not have a container manager! Aborting build computer action.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!containerManager.TryGetContainer(Container, out var container))
|
||||
{
|
||||
Logger.Warning($"Computer entity {entity} did not have the specified '{Container}' container! Aborting build computer action.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (container.ContainedEntities.Count != 1)
|
||||
{
|
||||
Logger.Warning($"Computer entity {entity} did not have exactly one item in the specified '{Container}' container! Aborting build computer action.");
|
||||
}
|
||||
|
||||
var board = container.ContainedEntities[0];
|
||||
|
||||
if (!board.TryGetComponent(out ComputerBoardComponent? boardComponent))
|
||||
{
|
||||
Logger.Warning($"Computer entity {entity} had an invalid entity in container \"{Container}\"! Aborting build computer action.");
|
||||
return;
|
||||
}
|
||||
|
||||
var entityManager = entity.EntityManager;
|
||||
container.Remove(board);
|
||||
|
||||
var computer = entityManager.SpawnEntity(boardComponent.Prototype, entity.Transform.Coordinates);
|
||||
computer.Transform.LocalRotation = entity.Transform.LocalRotation;
|
||||
|
||||
var computerContainer = ContainerManagerComponent.Ensure<Container>(Container, computer);
|
||||
computerContainer.Insert(board);
|
||||
|
||||
if (computer.TryGetComponent(out ConstructionComponent? construction))
|
||||
{
|
||||
// We only add this container. If some construction needs to take other containers into account, fix this.
|
||||
construction.AddContainer(Container);
|
||||
}
|
||||
|
||||
entity.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
24
Content.Server/Construction/Completions/DeleteEntity.cs
Normal file
24
Content.Server/Construction/Completions/DeleteEntity.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
#nullable enable
|
||||
using System.Threading.Tasks;
|
||||
using Content.Shared.Construction;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Server.Construction.Completions
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class DeleteEntity : IGraphAction
|
||||
{
|
||||
public void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task PerformAction(IEntity entity, IEntity? user)
|
||||
{
|
||||
if (entity.Deleted) return;
|
||||
|
||||
entity.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
37
Content.Server/Construction/Completions/EmptyContainer.cs
Normal file
37
Content.Server/Construction/Completions/EmptyContainer.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
#nullable enable
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Content.Shared.Construction;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects.Components.Container;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Server.Construction.Completions
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class EmptyContainer : IGraphAction
|
||||
{
|
||||
public string Container { get; private set; } = string.Empty;
|
||||
|
||||
public void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
serializer.DataField(this, x => x.Container, "container", string.Empty);
|
||||
}
|
||||
|
||||
public async Task PerformAction(IEntity entity, IEntity? user)
|
||||
{
|
||||
if (entity.Deleted) return;
|
||||
|
||||
if (!entity.TryGetComponent(out ContainerManagerComponent? containerManager) ||
|
||||
!containerManager.TryGetContainer(Container, out var container)) return;
|
||||
|
||||
foreach (var ent in container.ContainedEntities.ToArray())
|
||||
{
|
||||
if (ent == null || ent.Deleted) continue;
|
||||
container.ForceRemove(ent);
|
||||
ent.Transform.Coordinates = entity.Transform.Coordinates;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
39
Content.Server/Construction/Completions/PlaySound.cs
Normal file
39
Content.Server/Construction/Completions/PlaySound.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
#nullable enable
|
||||
using System.Threading.Tasks;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.Construction;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Server.Construction.Completions
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class PlaySound : IGraphAction
|
||||
{
|
||||
public string SoundCollection { get; private set; } = string.Empty;
|
||||
public string Sound { get; private set; } = string.Empty;
|
||||
|
||||
public void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
serializer.DataField(this, x => x.Sound, "sound", string.Empty);
|
||||
serializer.DataField(this, x => x.SoundCollection, "soundCollection", string.Empty);
|
||||
}
|
||||
|
||||
public async Task PerformAction(IEntity entity, IEntity? user)
|
||||
{
|
||||
var sound = GetSound();
|
||||
|
||||
if (string.IsNullOrEmpty(sound)) return;
|
||||
|
||||
EntitySystem.Get<AudioSystem>().PlayFromEntity(sound, entity, AudioHelpers.WithVariation(0.125f));
|
||||
}
|
||||
|
||||
private string GetSound()
|
||||
{
|
||||
return !string.IsNullOrEmpty(SoundCollection) ? AudioHelpers.GetRandomFileFromSoundCollection(SoundCollection) : Sound;
|
||||
}
|
||||
}
|
||||
}
|
||||
33
Content.Server/Construction/Completions/PopupUser.cs
Normal file
33
Content.Server/Construction/Completions/PopupUser.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
#nullable enable
|
||||
using System.Threading.Tasks;
|
||||
using Content.Shared.Construction;
|
||||
using Content.Shared.Interfaces;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Server.Construction.Completions
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class PopupUser : IGraphAction
|
||||
{
|
||||
public void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
serializer.DataField(this, x => x.Text, "text", string.Empty);
|
||||
serializer.DataField(this, x => x.Cursor, "cursor", false);
|
||||
}
|
||||
|
||||
public bool Cursor { get; private set; } = false;
|
||||
public string Text { get; private set; } = string.Empty;
|
||||
|
||||
public async Task PerformAction(IEntity entity, IEntity? user)
|
||||
{
|
||||
if (user == null) return;
|
||||
|
||||
if(Cursor)
|
||||
user.PopupMessageCursor(Text);
|
||||
else
|
||||
entity.PopupMessage(user, Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
28
Content.Server/Construction/Completions/SetAnchor.cs
Normal file
28
Content.Server/Construction/Completions/SetAnchor.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
#nullable enable
|
||||
using System.Threading.Tasks;
|
||||
using Content.Shared.Construction;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.GameObjects.Components;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Server.Construction.Completions
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class SetAnchor : IGraphAction
|
||||
{
|
||||
public void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
serializer.DataField(this, x => x.Value, "value", true);
|
||||
}
|
||||
|
||||
public bool Value { get; private set; } = true;
|
||||
|
||||
public async Task PerformAction(IEntity entity, IEntity? user)
|
||||
{
|
||||
if (!entity.TryGetComponent(out CollidableComponent? collidable)) return;
|
||||
|
||||
collidable.Anchored = Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
29
Content.Server/Construction/Completions/SnapToGrid.cs
Normal file
29
Content.Server/Construction/Completions/SnapToGrid.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
#nullable enable
|
||||
using System.Threading.Tasks;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.Construction;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.GameObjects.Components.Transform;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Server.Construction.Completions
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class SnapToGrid : IGraphAction
|
||||
{
|
||||
public SnapGridOffset Offset { get; private set; } = SnapGridOffset.Center;
|
||||
|
||||
public void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
serializer.DataField(this, x => x.Offset, "offset", SnapGridOffset.Center);
|
||||
}
|
||||
|
||||
public async Task PerformAction(IEntity entity, IEntity? user)
|
||||
{
|
||||
if (entity.Deleted) return;
|
||||
|
||||
entity.SnapToGrid(Offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Content.Server/Construction/Completions/SpawnPrototype.cs
Normal file
36
Content.Server/Construction/Completions/SpawnPrototype.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
#nullable enable
|
||||
using System.Threading.Tasks;
|
||||
using Content.Shared.Construction;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Server.Construction.Completions
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class SpawnPrototype : IGraphAction
|
||||
{
|
||||
public string Prototype { get; private set; } = string.Empty;
|
||||
public int Amount { get; private set; } = 1;
|
||||
|
||||
public void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
serializer.DataField(this, x => x.Prototype, "prototype", string.Empty);
|
||||
serializer.DataField(this, x => x.Amount, "amount", 1);
|
||||
}
|
||||
|
||||
public async Task PerformAction(IEntity entity, IEntity? user)
|
||||
{
|
||||
if (entity.Deleted || string.IsNullOrEmpty(Prototype)) return;
|
||||
|
||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
||||
var coordinates = entity.Transform.Coordinates;
|
||||
|
||||
for (var i = 0; i < Amount; i++)
|
||||
{
|
||||
entityManager.SpawnEntity(Prototype, coordinates);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
Content.Server/Construction/Completions/SpriteChange.cs
Normal file
33
Content.Server/Construction/Completions/SpriteChange.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
#nullable enable
|
||||
using System.Threading.Tasks;
|
||||
using Content.Shared.Construction;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.Construction.Completions
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class SpriteChange : IGraphAction
|
||||
{
|
||||
public void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
serializer.DataField(this, x => x.SpriteSpecifier, "specifier", SpriteSpecifier.Invalid);
|
||||
serializer.DataField(this, x => x.Layer, "layer", 0);
|
||||
}
|
||||
|
||||
public int Layer { get; private set; } = 0;
|
||||
public SpriteSpecifier? SpriteSpecifier { get; private set; } = SpriteSpecifier.Invalid;
|
||||
|
||||
public async Task PerformAction(IEntity entity, IEntity? user)
|
||||
{
|
||||
if (entity.Deleted || SpriteSpecifier == null || SpriteSpecifier == SpriteSpecifier.Invalid) return;
|
||||
|
||||
if (!entity.TryGetComponent(out SpriteComponent? sprite)) return;
|
||||
|
||||
sprite.LayerSetSprite(Layer, SpriteSpecifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
39
Content.Server/Construction/Completions/SpriteStateChange.cs
Normal file
39
Content.Server/Construction/Completions/SpriteStateChange.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
#nullable enable
|
||||
using System.Threading.Tasks;
|
||||
using Content.Shared.Construction;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.Construction.Completions
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class SpriteStateChange : IGraphAction
|
||||
{
|
||||
|
||||
public void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
serializer.DataField(this, x => x.State, "state", string.Empty);
|
||||
serializer.DataField(this, x => x.Layer, "layer", 0);
|
||||
}
|
||||
|
||||
public int Layer { get; private set; } = 0;
|
||||
public string? State { get; private set; } = string.Empty;
|
||||
|
||||
public async Task StepCompleted(IEntity entity, IEntity user)
|
||||
{
|
||||
await PerformAction(entity, user);
|
||||
}
|
||||
|
||||
public async Task PerformAction(IEntity entity, IEntity? user)
|
||||
{
|
||||
if (entity.Deleted || string.IsNullOrEmpty(State)) return;
|
||||
|
||||
if (!entity.TryGetComponent(out SpriteComponent? sprite)) return;
|
||||
|
||||
sprite.LayerSetState(Layer, State);
|
||||
}
|
||||
}
|
||||
}
|
||||
49
Content.Server/Construction/Completions/VisualizerDataInt.cs
Normal file
49
Content.Server/Construction/Completions/VisualizerDataInt.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
#nullable enable
|
||||
using System.Threading.Tasks;
|
||||
using Content.Shared.Construction;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Reflection;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Server.Construction.Completions
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class VisualizerDataInt : IGraphAction
|
||||
{
|
||||
[Dependency] private readonly IReflectionManager _reflectionManager = default!;
|
||||
|
||||
public VisualizerDataInt()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
}
|
||||
|
||||
public void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
serializer.DataField(this, x => x.Key, "key", string.Empty);
|
||||
serializer.DataField(this, x => x.Data, "data", 0);
|
||||
}
|
||||
|
||||
public string? Key { get; private set; } = string.Empty;
|
||||
public int Data { get; private set; } = 0;
|
||||
|
||||
public async Task PerformAction(IEntity entity, IEntity? user)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Key)) return;
|
||||
|
||||
if (entity.TryGetComponent(out AppearanceComponent? appearance))
|
||||
{
|
||||
if(_reflectionManager.TryParseEnumReference(Key, out var @enum))
|
||||
{
|
||||
appearance.SetData(@enum, Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
appearance.SetData(Key, Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user