Removes the ConstructorComponents and moves the construction blueprint feature into a new ECS system. (#1114)
This commit is contained in:
@@ -1,8 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Client.GameObjects.Components.Construction;
|
using Content.Client.GameObjects.EntitySystems;
|
||||||
using Content.Client.Interfaces.GameObjects;
|
|
||||||
using Content.Shared.Construction;
|
using Content.Shared.Construction;
|
||||||
using Content.Shared.GameObjects.Components.Interactable;
|
using Content.Shared.GameObjects.Components.Interactable;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
@@ -14,7 +13,7 @@ using Robust.Client.UserInterface.Controls;
|
|||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
using Robust.Client.Utility;
|
using Robust.Client.Utility;
|
||||||
using Robust.Shared.Enums;
|
using Robust.Shared.Enums;
|
||||||
using Robust.Shared.Interfaces.GameObjects.Components;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
@@ -24,11 +23,11 @@ namespace Content.Client.Construction
|
|||||||
public class ConstructionMenu : SS14Window
|
public class ConstructionMenu : SS14Window
|
||||||
{
|
{
|
||||||
#pragma warning disable CS0649
|
#pragma warning disable CS0649
|
||||||
[Dependency] readonly IPrototypeManager PrototypeManager;
|
[Dependency] private readonly IPrototypeManager _prototypeManager;
|
||||||
[Dependency] readonly IResourceCache ResourceCache;
|
[Dependency] private readonly IResourceCache _resourceCache;
|
||||||
|
[Dependency] private readonly IEntitySystemManager _systemManager;
|
||||||
#pragma warning restore
|
#pragma warning restore
|
||||||
|
|
||||||
public ConstructorComponent Owner { get; set; }
|
|
||||||
private readonly Button BuildButton;
|
private readonly Button BuildButton;
|
||||||
private readonly Button EraseButton;
|
private readonly Button EraseButton;
|
||||||
private readonly LineEdit SearchBar;
|
private readonly LineEdit SearchBar;
|
||||||
@@ -118,6 +117,7 @@ namespace Content.Client.Construction
|
|||||||
PopulateTree();
|
PopulateTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
@@ -128,7 +128,7 @@ namespace Content.Client.Construction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnItemSelected()
|
private void OnItemSelected()
|
||||||
{
|
{
|
||||||
var prototype = (ConstructionPrototype) RecipeList.Selected.Metadata;
|
var prototype = (ConstructionPrototype) RecipeList.Selected.Metadata;
|
||||||
|
|
||||||
@@ -162,17 +162,17 @@ namespace Content.Client.Construction
|
|||||||
switch (mat.Material)
|
switch (mat.Material)
|
||||||
{
|
{
|
||||||
case ConstructionStepMaterial.MaterialType.Metal:
|
case ConstructionStepMaterial.MaterialType.Metal:
|
||||||
icon = ResourceCache.GetResource<TextureResource>(
|
icon = _resourceCache.GetResource<TextureResource>(
|
||||||
"/Textures/Objects/Materials/sheet_metal.png");
|
"/Textures/Objects/Materials/sheet_metal.png");
|
||||||
text = $"Metal x{mat.Amount}";
|
text = $"Metal x{mat.Amount}";
|
||||||
break;
|
break;
|
||||||
case ConstructionStepMaterial.MaterialType.Glass:
|
case ConstructionStepMaterial.MaterialType.Glass:
|
||||||
icon = ResourceCache.GetResource<TextureResource>(
|
icon = _resourceCache.GetResource<TextureResource>(
|
||||||
"/Textures/Objects/Materials/sheet_glass.png");
|
"/Textures/Objects/Materials/sheet_glass.png");
|
||||||
text = $"Glass x{mat.Amount}";
|
text = $"Glass x{mat.Amount}";
|
||||||
break;
|
break;
|
||||||
case ConstructionStepMaterial.MaterialType.Cable:
|
case ConstructionStepMaterial.MaterialType.Cable:
|
||||||
icon = ResourceCache.GetResource<TextureResource>(
|
icon = _resourceCache.GetResource<TextureResource>(
|
||||||
"/Textures/Objects/Tools/cable_coil.png");
|
"/Textures/Objects/Tools/cable_coil.png");
|
||||||
text = $"Cable Coil x{mat.Amount}";
|
text = $"Cable Coil x{mat.Amount}";
|
||||||
break;
|
break;
|
||||||
@@ -185,25 +185,25 @@ namespace Content.Client.Construction
|
|||||||
switch (tool.ToolQuality)
|
switch (tool.ToolQuality)
|
||||||
{
|
{
|
||||||
case ToolQuality.Anchoring:
|
case ToolQuality.Anchoring:
|
||||||
icon = ResourceCache.GetResource<TextureResource>("/Textures/Objects/Tools/wrench.png");
|
icon = _resourceCache.GetResource<TextureResource>("/Textures/Objects/Tools/wrench.png");
|
||||||
text = "Wrench";
|
text = "Wrench";
|
||||||
break;
|
break;
|
||||||
case ToolQuality.Prying:
|
case ToolQuality.Prying:
|
||||||
icon = ResourceCache.GetResource<TextureResource>("/Textures/Objects/Tools/crowbar.png");
|
icon = _resourceCache.GetResource<TextureResource>("/Textures/Objects/Tools/crowbar.png");
|
||||||
text = "Crowbar";
|
text = "Crowbar";
|
||||||
break;
|
break;
|
||||||
case ToolQuality.Screwing:
|
case ToolQuality.Screwing:
|
||||||
icon = ResourceCache.GetResource<TextureResource>(
|
icon = _resourceCache.GetResource<TextureResource>(
|
||||||
"/Textures/Objects/Tools/screwdriver.png");
|
"/Textures/Objects/Tools/screwdriver.png");
|
||||||
text = "Screwdriver";
|
text = "Screwdriver";
|
||||||
break;
|
break;
|
||||||
case ToolQuality.Welding:
|
case ToolQuality.Welding:
|
||||||
icon = ResourceCache.GetResource<RSIResource>("/Textures/Objects/tools.rsi")
|
icon = _resourceCache.GetResource<RSIResource>("/Textures/Objects/tools.rsi")
|
||||||
.RSI["welder"].Frame0;
|
.RSI["welder"].Frame0;
|
||||||
text = $"Welding tool ({tool.Amount} fuel)";
|
text = $"Welding tool ({tool.Amount} fuel)";
|
||||||
break;
|
break;
|
||||||
case ToolQuality.Cutting:
|
case ToolQuality.Cutting:
|
||||||
icon = ResourceCache.GetResource<TextureResource>(
|
icon = _resourceCache.GetResource<TextureResource>(
|
||||||
"/Textures/Objects/Tools/wirecutter.png");
|
"/Textures/Objects/Tools/wirecutter.png");
|
||||||
text = "Wirecutters";
|
text = "Wirecutters";
|
||||||
break;
|
break;
|
||||||
@@ -221,13 +221,13 @@ namespace Content.Client.Construction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnTextEntered(LineEdit.LineEditEventArgs args)
|
private void OnTextEntered(LineEdit.LineEditEventArgs args)
|
||||||
{
|
{
|
||||||
var str = args.Text;
|
var str = args.Text;
|
||||||
PopulateTree(string.IsNullOrWhiteSpace(str) ? null : str.ToLowerInvariant());
|
PopulateTree(string.IsNullOrWhiteSpace(str) ? null : str.ToLowerInvariant());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnBuildToggled(BaseButton.ButtonToggledEventArgs args)
|
private void OnBuildToggled(BaseButton.ButtonToggledEventArgs args)
|
||||||
{
|
{
|
||||||
if (args.Pressed)
|
if (args.Pressed)
|
||||||
{
|
{
|
||||||
@@ -239,7 +239,8 @@ namespace Content.Client.Construction
|
|||||||
|
|
||||||
if (prototype.Type == ConstructionType.Item)
|
if (prototype.Type == ConstructionType.Item)
|
||||||
{
|
{
|
||||||
Owner.TryStartItemConstruction(prototype.ID);
|
var constructSystem = _systemManager.GetEntitySystem<ConstructionSystem>();
|
||||||
|
constructSystem.TryStartItemConstruction(prototype.ID);
|
||||||
BuildButton.Pressed = false;
|
BuildButton.Pressed = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -250,7 +251,7 @@ namespace Content.Client.Construction
|
|||||||
IsTile = false,
|
IsTile = false,
|
||||||
PlacementOption = prototype.PlacementMode
|
PlacementOption = prototype.PlacementMode
|
||||||
},
|
},
|
||||||
new ConstructionPlacementHijack(prototype, Owner));
|
new ConstructionPlacementHijack(_systemManager.GetEntitySystem<ConstructionSystem>(), prototype));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -262,7 +263,7 @@ namespace Content.Client.Construction
|
|||||||
private void OnEraseToggled(BaseButton.ButtonToggledEventArgs args)
|
private void OnEraseToggled(BaseButton.ButtonToggledEventArgs args)
|
||||||
{
|
{
|
||||||
if (args.Pressed) Placement.Clear();
|
if (args.Pressed) Placement.Clear();
|
||||||
Placement.ToggleEraserHijacked(new ConstructionPlacementHijack(null, Owner));
|
Placement.ToggleEraserHijacked(new ConstructionPlacementHijack(_systemManager.GetEntitySystem<ConstructionSystem>(), null));
|
||||||
EraseButton.Pressed = args.Pressed;
|
EraseButton.Pressed = args.Pressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,12 +273,12 @@ namespace Content.Client.Construction
|
|||||||
EraseButton.Pressed = false;
|
EraseButton.Pressed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopulatePrototypeList()
|
private void PopulatePrototypeList()
|
||||||
{
|
{
|
||||||
RootCategory = new CategoryNode("", null);
|
RootCategory = new CategoryNode("", null);
|
||||||
int count = 1;
|
var count = 1;
|
||||||
|
|
||||||
foreach (var prototype in PrototypeManager.EnumeratePrototypes<ConstructionPrototype>())
|
foreach (var prototype in _prototypeManager.EnumeratePrototypes<ConstructionPrototype>())
|
||||||
{
|
{
|
||||||
var currentNode = RootCategory;
|
var currentNode = RootCategory;
|
||||||
|
|
||||||
@@ -316,7 +317,7 @@ namespace Content.Client.Construction
|
|||||||
Recurse(RootCategory);
|
Recurse(RootCategory);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopulateTree(string searchTerm = null)
|
private void PopulateTree(string searchTerm = null)
|
||||||
{
|
{
|
||||||
RecipeList.Clear();
|
RecipeList.Clear();
|
||||||
|
|
||||||
@@ -378,18 +379,18 @@ namespace Content.Client.Construction
|
|||||||
|
|
||||||
private static int ComparePrototype(ConstructionPrototype x, ConstructionPrototype y)
|
private static int ComparePrototype(ConstructionPrototype x, ConstructionPrototype y)
|
||||||
{
|
{
|
||||||
return String.Compare(x.Name, y.Name, StringComparison.Ordinal);
|
return string.Compare(x.Name, y.Name, StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
class CategoryNode
|
private class CategoryNode
|
||||||
{
|
{
|
||||||
public readonly string Name;
|
public readonly string Name;
|
||||||
public readonly CategoryNode Parent;
|
public readonly CategoryNode Parent;
|
||||||
|
|
||||||
public SortedDictionary<string, CategoryNode>
|
public readonly SortedDictionary<string, CategoryNode>
|
||||||
ChildCategories = new SortedDictionary<string, CategoryNode>();
|
ChildCategories = new SortedDictionary<string, CategoryNode>();
|
||||||
|
|
||||||
public List<ConstructionPrototype> Prototypes = new List<ConstructionPrototype>();
|
public readonly List<ConstructionPrototype> Prototypes = new List<ConstructionPrototype>();
|
||||||
public int FlattenedIndex = -1;
|
public int FlattenedIndex = -1;
|
||||||
|
|
||||||
public CategoryNode(string name, CategoryNode parent)
|
public CategoryNode(string name, CategoryNode parent)
|
||||||
|
|||||||
@@ -1,49 +1,51 @@
|
|||||||
using Content.Client.GameObjects.Components.Construction;
|
using Content.Client.GameObjects.Components.Construction;
|
||||||
|
using Content.Client.GameObjects.EntitySystems;
|
||||||
using Content.Shared.Construction;
|
using Content.Shared.Construction;
|
||||||
using Robust.Client.Interfaces.ResourceManagement;
|
|
||||||
using Robust.Client.Placement;
|
using Robust.Client.Placement;
|
||||||
using Robust.Client.Utility;
|
using Robust.Client.Utility;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
|
|
||||||
namespace Content.Client.Construction
|
namespace Content.Client.Construction
|
||||||
{
|
{
|
||||||
public class ConstructionPlacementHijack : PlacementHijack
|
public class ConstructionPlacementHijack : PlacementHijack
|
||||||
{
|
{
|
||||||
private readonly ConstructionPrototype Prototype;
|
private readonly ConstructionSystem _constructionSystem;
|
||||||
private readonly ConstructorComponent Owner;
|
private readonly ConstructionPrototype _prototype;
|
||||||
|
|
||||||
public ConstructionPlacementHijack(ConstructionPrototype prototype, ConstructorComponent owner)
|
public ConstructionPlacementHijack(ConstructionSystem constructionSystem, ConstructionPrototype prototype)
|
||||||
{
|
{
|
||||||
Prototype = prototype;
|
_constructionSystem = constructionSystem;
|
||||||
Owner = owner;
|
_prototype = prototype;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public override bool HijackPlacementRequest(GridCoordinates coords)
|
public override bool HijackPlacementRequest(GridCoordinates coords)
|
||||||
{
|
{
|
||||||
if (Prototype != null)
|
if (_prototype != null)
|
||||||
{
|
{
|
||||||
var dir = Manager.Direction;
|
var dir = Manager.Direction;
|
||||||
Owner.SpawnGhost(Prototype, coords, dir);
|
_constructionSystem.SpawnGhost(_prototype, coords, dir);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public override bool HijackDeletion(IEntity entity)
|
public override bool HijackDeletion(IEntity entity)
|
||||||
{
|
{
|
||||||
if (entity.TryGetComponent(out ConstructionGhostComponent ghost))
|
if (entity.TryGetComponent(out ConstructionGhostComponent ghost))
|
||||||
{
|
{
|
||||||
Owner.ClearGhost(ghost.GhostID);
|
_constructionSystem.ClearGhost(ghost.GhostID);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
public override void StartHijack(PlacementManager manager)
|
public override void StartHijack(PlacementManager manager)
|
||||||
{
|
{
|
||||||
base.StartHijack(manager);
|
base.StartHijack(manager);
|
||||||
|
|
||||||
manager.CurrentBaseSprite = Prototype.Icon.DirFrame0();
|
manager.CurrentBaseSprite = _prototype.Icon.DirFrame0();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ namespace Content.Client.GameObjects.Components.Construction
|
|||||||
public override string Name => "ConstructionGhost";
|
public override string Name => "ConstructionGhost";
|
||||||
|
|
||||||
[ViewVariables] public ConstructionPrototype Prototype { get; set; }
|
[ViewVariables] public ConstructionPrototype Prototype { get; set; }
|
||||||
[ViewVariables] public ConstructorComponent Master { get; set; }
|
|
||||||
[ViewVariables] public int GhostID { get; set; }
|
[ViewVariables] public int GhostID { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,132 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Content.Client.Construction;
|
|
||||||
using Content.Client.UserInterface;
|
|
||||||
using Content.Shared.Construction;
|
|
||||||
using Content.Shared.GameObjects.Components.Construction;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Client.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects.Components;
|
|
||||||
using Robust.Shared.Interfaces.Network;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Players;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Construction
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
public class ConstructorComponent : SharedConstructorComponent
|
|
||||||
{
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IGameHud _gameHud;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
private int nextId;
|
|
||||||
private readonly Dictionary<int, ConstructionGhostComponent> Ghosts = new Dictionary<int, ConstructionGhostComponent>();
|
|
||||||
public ConstructionMenu ConstructionMenu { get; private set; }
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
Owner.GetComponent<ITransformComponent>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void HandleMessage(ComponentMessage message, IComponent component)
|
|
||||||
{
|
|
||||||
base.HandleMessage(message, component);
|
|
||||||
|
|
||||||
switch (message)
|
|
||||||
{
|
|
||||||
case PlayerAttachedMsg _:
|
|
||||||
if (ConstructionMenu == null)
|
|
||||||
{
|
|
||||||
ConstructionMenu = new ConstructionMenu {Owner = this};
|
|
||||||
ConstructionMenu.OnClose += () => _gameHud.CraftingButtonDown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_gameHud.CraftingButtonVisible = true;
|
|
||||||
_gameHud.CraftingButtonToggled = b =>
|
|
||||||
{
|
|
||||||
if (b)
|
|
||||||
{
|
|
||||||
ConstructionMenu.Open();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ConstructionMenu.Close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PlayerDetachedMsg _:
|
|
||||||
_gameHud.CraftingButtonVisible = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession session = null)
|
|
||||||
{
|
|
||||||
base.HandleNetworkMessage(message, channel, session);
|
|
||||||
|
|
||||||
switch (message)
|
|
||||||
{
|
|
||||||
case AckStructureConstructionMessage ackMsg:
|
|
||||||
ClearGhost(ackMsg.Ack);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnRemove()
|
|
||||||
{
|
|
||||||
ConstructionMenu?.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SpawnGhost(ConstructionPrototype prototype, GridCoordinates loc, Direction dir)
|
|
||||||
{
|
|
||||||
var entMgr = IoCManager.Resolve<IClientEntityManager>();
|
|
||||||
var ghost = entMgr.SpawnEntity("constructionghost", loc);
|
|
||||||
var comp = ghost.GetComponent<ConstructionGhostComponent>();
|
|
||||||
comp.Prototype = prototype;
|
|
||||||
comp.Master = this;
|
|
||||||
comp.GhostID = nextId++;
|
|
||||||
ghost.GetComponent<ITransformComponent>().LocalRotation = dir.ToAngle();
|
|
||||||
var sprite = ghost.GetComponent<SpriteComponent>();
|
|
||||||
sprite.LayerSetSprite(0, prototype.Icon);
|
|
||||||
sprite.LayerSetVisible(0, true);
|
|
||||||
|
|
||||||
Ghosts.Add(comp.GhostID, comp);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void TryStartConstruction(int ghostId)
|
|
||||||
{
|
|
||||||
var ghost = Ghosts[ghostId];
|
|
||||||
var transform = ghost.Owner.GetComponent<ITransformComponent>();
|
|
||||||
var msg = new TryStartStructureConstructionMessage(transform.GridPosition, ghost.Prototype.ID, transform.LocalRotation, ghostId);
|
|
||||||
SendNetworkMessage(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void TryStartItemConstruction(string prototypeName)
|
|
||||||
{
|
|
||||||
var msg = new TryStartItemConstructionMessage(prototypeName);
|
|
||||||
SendNetworkMessage(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ClearGhost(int ghostId)
|
|
||||||
{
|
|
||||||
if (Ghosts.TryGetValue(ghostId, out var ghost))
|
|
||||||
{
|
|
||||||
ghost.Owner.Delete();
|
|
||||||
Ghosts.Remove(ghostId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
196
Content.Client/GameObjects/EntitySystems/ConstructionSystem.cs
Normal file
196
Content.Client/GameObjects/EntitySystems/ConstructionSystem.cs
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Content.Client.Construction;
|
||||||
|
using Content.Client.GameObjects.Components.Construction;
|
||||||
|
using Content.Client.UserInterface;
|
||||||
|
using Content.Shared.Construction;
|
||||||
|
using Content.Shared.Input;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Client.GameObjects.EntitySystems;
|
||||||
|
using Robust.Client.Player;
|
||||||
|
using Robust.Shared.Input;
|
||||||
|
using Robust.Shared.Input.Binding;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
|
||||||
|
namespace Content.Client.GameObjects.EntitySystems
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The client-side implementation of the construction system, which is used for constructing entities in game.
|
||||||
|
/// </summary>
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class ConstructionSystem : Shared.GameObjects.EntitySystems.ConstructionSystem
|
||||||
|
{
|
||||||
|
#pragma warning disable 649
|
||||||
|
[Dependency] private readonly IGameHud _gameHud;
|
||||||
|
[Dependency] private readonly IPlayerManager _playerManager;
|
||||||
|
[Dependency] private readonly IEntityManager _entityManager;
|
||||||
|
#pragma warning restore 649
|
||||||
|
|
||||||
|
private int _nextId;
|
||||||
|
private readonly Dictionary<int, ConstructionGhostComponent> _ghosts = new Dictionary<int, ConstructionGhostComponent>();
|
||||||
|
private ConstructionMenu _constructionMenu;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<PlayerAttachSysMessage>(HandlePlayerAttached);
|
||||||
|
SubscribeNetworkEvent<AckStructureConstructionMessage>(HandleAckStructure);
|
||||||
|
|
||||||
|
CommandBinds.Builder
|
||||||
|
.Bind(ContentKeyFunctions.OpenCraftingMenu,
|
||||||
|
new PointerInputCmdHandler(HandleOpenCraftingMenu))
|
||||||
|
.Bind(EngineKeyFunctions.Use,
|
||||||
|
new PointerInputCmdHandler(HandleUse))
|
||||||
|
.Register<ConstructionSystem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleAckStructure(AckStructureConstructionMessage msg)
|
||||||
|
{
|
||||||
|
ClearGhost(msg.GhostId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandlePlayerAttached(PlayerAttachSysMessage msg)
|
||||||
|
{
|
||||||
|
if (msg.AttachedEntity == null)
|
||||||
|
{
|
||||||
|
_gameHud.CraftingButtonVisible = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_constructionMenu == null)
|
||||||
|
{
|
||||||
|
_constructionMenu = new ConstructionMenu();
|
||||||
|
_constructionMenu.OnClose += () => _gameHud.CraftingButtonDown = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_gameHud.CraftingButtonVisible = true;
|
||||||
|
_gameHud.CraftingButtonToggled = b =>
|
||||||
|
{
|
||||||
|
if (b)
|
||||||
|
{
|
||||||
|
_constructionMenu.Open();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_constructionMenu.Close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void Shutdown()
|
||||||
|
{
|
||||||
|
_constructionMenu?.Dispose();
|
||||||
|
|
||||||
|
CommandBinds.Unregister<ConstructionSystem>();
|
||||||
|
base.Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HandleOpenCraftingMenu(in PointerInputCmdHandler.PointerInputCmdArgs args)
|
||||||
|
{
|
||||||
|
if (_playerManager.LocalPlayer.ControlledEntity == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var menu = _constructionMenu;
|
||||||
|
|
||||||
|
if (menu.IsOpen)
|
||||||
|
{
|
||||||
|
if (menu.IsAtFront())
|
||||||
|
{
|
||||||
|
SetOpenValue(menu, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
menu.MoveToFront();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetOpenValue(menu, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HandleUse(in PointerInputCmdHandler.PointerInputCmdArgs args)
|
||||||
|
{
|
||||||
|
if (!args.EntityUid.IsValid() || !args.EntityUid.IsClientSide())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var entity = _entityManager.GetEntity(args.EntityUid);
|
||||||
|
|
||||||
|
if (!entity.TryGetComponent(out ConstructionGhostComponent ghostComp))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
TryStartConstruction(ghostComp.GhostID);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetOpenValue(ConstructionMenu menu, bool value)
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
_gameHud.CraftingButtonDown = true;
|
||||||
|
menu.OpenCentered();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_gameHud.CraftingButtonDown = false;
|
||||||
|
menu.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a construction ghost at the given location.
|
||||||
|
/// </summary>
|
||||||
|
public void SpawnGhost(ConstructionPrototype prototype, GridCoordinates loc, Direction dir)
|
||||||
|
{
|
||||||
|
var ghost = _entityManager.SpawnEntity("constructionghost", loc);
|
||||||
|
var comp = ghost.GetComponent<ConstructionGhostComponent>();
|
||||||
|
comp.Prototype = prototype;
|
||||||
|
comp.GhostID = _nextId++;
|
||||||
|
ghost.Transform.LocalRotation = dir.ToAngle();
|
||||||
|
var sprite = ghost.GetComponent<SpriteComponent>();
|
||||||
|
sprite.LayerSetSprite(0, prototype.Icon);
|
||||||
|
sprite.LayerSetVisible(0, true);
|
||||||
|
|
||||||
|
_ghosts.Add(comp.GhostID, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TryStartConstruction(int ghostId)
|
||||||
|
{
|
||||||
|
var ghost = _ghosts[ghostId];
|
||||||
|
var transform = ghost.Owner.Transform;
|
||||||
|
var msg = new TryStartStructureConstructionMessage(transform.GridPosition, ghost.Prototype.ID, transform.LocalRotation, ghostId);
|
||||||
|
RaiseNetworkEvent(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts constructing an item underneath the attached entity.
|
||||||
|
/// </summary>
|
||||||
|
public void TryStartItemConstruction(string prototypeName)
|
||||||
|
{
|
||||||
|
RaiseNetworkEvent(new TryStartItemConstructionMessage(prototypeName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a construction ghost entity with the given ID.
|
||||||
|
/// </summary>
|
||||||
|
public void ClearGhost(int ghostId)
|
||||||
|
{
|
||||||
|
if (_ghosts.TryGetValue(ghostId, out var ghost))
|
||||||
|
{
|
||||||
|
ghost.Owner.Delete();
|
||||||
|
_ghosts.Remove(ghostId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
using Content.Client.Construction;
|
|
||||||
using Content.Client.GameObjects.Components.Construction;
|
|
||||||
using Content.Client.UserInterface;
|
|
||||||
using Content.Shared.Input;
|
|
||||||
using Robust.Client.GameObjects.EntitySystems;
|
|
||||||
using Robust.Client.Player;
|
|
||||||
using Robust.Shared.GameObjects.Systems;
|
|
||||||
using Robust.Shared.Input;
|
|
||||||
using Robust.Shared.Input.Binding;
|
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.EntitySystems
|
|
||||||
{
|
|
||||||
public sealed class ConstructorSystem : EntitySystem
|
|
||||||
{
|
|
||||||
#pragma warning disable 649
|
|
||||||
[Dependency] private readonly IGameHud _gameHud;
|
|
||||||
[Dependency] private readonly IPlayerManager _playerManager;
|
|
||||||
[Dependency] private readonly IEntityManager _entityManager;
|
|
||||||
#pragma warning restore 649
|
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
var inputSys = EntitySystemManager.GetEntitySystem<InputSystem>();
|
|
||||||
|
|
||||||
CommandBinds.Builder
|
|
||||||
.Bind(ContentKeyFunctions.OpenCraftingMenu,
|
|
||||||
new PointerInputCmdHandler(HandleOpenCraftingMenu))
|
|
||||||
.Bind(EngineKeyFunctions.Use,
|
|
||||||
new PointerInputCmdHandler(HandleUse))
|
|
||||||
.Register<ConstructorSystem>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
CommandBinds.Unregister<ConstructorSystem>();
|
|
||||||
base.Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool HandleOpenCraftingMenu(in PointerInputCmdHandler.PointerInputCmdArgs args)
|
|
||||||
{
|
|
||||||
if (_playerManager.LocalPlayer.ControlledEntity == null
|
|
||||||
|| !_playerManager.LocalPlayer.ControlledEntity.TryGetComponent(out ConstructorComponent constructor))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var menu = constructor.ConstructionMenu;
|
|
||||||
|
|
||||||
if (menu.IsOpen)
|
|
||||||
{
|
|
||||||
if (menu.IsAtFront())
|
|
||||||
{
|
|
||||||
_setOpenValue(menu, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
menu.MoveToFront();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_setOpenValue(menu, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool HandleUse(in PointerInputCmdHandler.PointerInputCmdArgs args)
|
|
||||||
{
|
|
||||||
if (!args.EntityUid.IsValid() || !args.EntityUid.IsClientSide())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var entity = _entityManager.GetEntity(args.EntityUid);
|
|
||||||
|
|
||||||
if (!entity.TryGetComponent(out ConstructionGhostComponent ghostComp))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ghostComp.Master.TryStartConstruction(ghostComp.GhostID);
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _setOpenValue(ConstructionMenu menu, bool value)
|
|
||||||
{
|
|
||||||
if (value)
|
|
||||||
{
|
|
||||||
_gameHud.CraftingButtonDown = true;
|
|
||||||
menu.OpenCentered();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_gameHud.CraftingButtonDown = false;
|
|
||||||
menu.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,26 +1,28 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Content.Server.GameObjects.Components.Construction;
|
||||||
using Content.Server.GameObjects.Components.Stack;
|
using Content.Server.GameObjects.Components.Stack;
|
||||||
using Content.Server.Utility;
|
using Content.Server.Utility;
|
||||||
using Content.Shared.Construction;
|
using Content.Shared.Construction;
|
||||||
using Content.Shared.GameObjects.Components.Construction;
|
using JetBrains.Annotations;
|
||||||
using Robust.Server.GameObjects.EntitySystems;
|
using Robust.Server.GameObjects.EntitySystems;
|
||||||
using Robust.Server.Interfaces.GameObjects;
|
using Robust.Server.Interfaces.GameObjects;
|
||||||
|
using Robust.Server.Interfaces.Player;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.GameObjects.Systems;
|
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.Interfaces.Network;
|
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Players;
|
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Utility;
|
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Construction
|
namespace Content.Server.GameObjects.EntitySystems
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
/// <summary>
|
||||||
public class ConstructorComponent : SharedConstructorComponent
|
/// The server-side implementation of the construction system, which is used for constructing entities in game.
|
||||||
|
/// </summary>
|
||||||
|
[UsedImplicitly]
|
||||||
|
internal class ConstructionSystem : Shared.GameObjects.EntitySystems.ConstructionSystem
|
||||||
{
|
{
|
||||||
#pragma warning disable 649
|
#pragma warning disable 649
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager;
|
[Dependency] private readonly IPrototypeManager _prototypeManager;
|
||||||
@@ -28,32 +30,41 @@ namespace Content.Server.GameObjects.Components.Construction
|
|||||||
[Dependency] private readonly IServerEntityManager _serverEntityManager;
|
[Dependency] private readonly IServerEntityManager _serverEntityManager;
|
||||||
#pragma warning restore 649
|
#pragma warning restore 649
|
||||||
|
|
||||||
public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession session = null)
|
/// <inheritdoc />
|
||||||
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.HandleNetworkMessage(message, channel, session);
|
base.Initialize();
|
||||||
|
|
||||||
switch (message)
|
SubscribeNetworkEvent<TryStartStructureConstructionMessage>(HandleStartStructureConstruction);
|
||||||
{
|
SubscribeNetworkEvent<TryStartItemConstructionMessage>(HandleStartItemConstruction);
|
||||||
case TryStartStructureConstructionMessage tryStart:
|
|
||||||
TryStartStructureConstruction(tryStart.Location, tryStart.PrototypeName, tryStart.Angle, tryStart.Ack);
|
|
||||||
break;
|
|
||||||
case TryStartItemConstructionMessage tryStart:
|
|
||||||
TryStartItemConstruction(tryStart.PrototypeName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TryStartStructureConstruction(GridCoordinates loc, string prototypeName, Angle angle, int ack)
|
private void HandleStartStructureConstruction(TryStartStructureConstructionMessage msg, EntitySessionEventArgs args)
|
||||||
|
{
|
||||||
|
var placingEnt = args.SenderSession.AttachedEntity;
|
||||||
|
var result = TryStartStructureConstruction(placingEnt, msg.Location, msg.PrototypeName, msg.Angle);
|
||||||
|
if (!result) return;
|
||||||
|
var responseMsg = new AckStructureConstructionMessage(msg.Ack);
|
||||||
|
var channel = ((IPlayerSession) args.SenderSession).ConnectedClient;
|
||||||
|
RaiseNetworkEvent(responseMsg, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleStartItemConstruction(TryStartItemConstructionMessage msg, EntitySessionEventArgs args)
|
||||||
|
{
|
||||||
|
var placingEnt = args.SenderSession.AttachedEntity;
|
||||||
|
TryStartItemConstruction(placingEnt, msg.PrototypeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryStartStructureConstruction(IEntity placingEnt, GridCoordinates loc, string prototypeName, Angle angle)
|
||||||
{
|
{
|
||||||
var prototype = _prototypeManager.Index<ConstructionPrototype>(prototypeName);
|
var prototype = _prototypeManager.Index<ConstructionPrototype>(prototypeName);
|
||||||
|
|
||||||
if (!InteractionChecks.InRangeUnobstructed(Owner, loc.ToMap(_mapManager),
|
if (!InteractionChecks.InRangeUnobstructed(placingEnt, loc.ToMap(_mapManager),
|
||||||
ignoredEnt: Owner, insideBlockerValid: prototype.CanBuildInImpassable))
|
ignoredEnt: placingEnt, insideBlockerValid: prototype.CanBuildInImpassable))
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (prototype.Stages.Count < 2)
|
if (prototype.Stages.Count < 2)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Prototype '{prototypeName}' does not have enough stages.");
|
throw new InvalidOperationException($"Prototype '{prototypeName}' does not have enough stages.");
|
||||||
@@ -66,25 +77,25 @@ namespace Content.Server.GameObjects.Components.Construction
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try to find the stack with the material in the user's hand.
|
// Try to find the stack with the material in the user's hand.
|
||||||
var hands = Owner.GetComponent<HandsComponent>();
|
var hands = placingEnt.GetComponent<HandsComponent>();
|
||||||
var activeHand = hands.GetActiveHand?.Owner;
|
var activeHand = hands.GetActiveHand?.Owner;
|
||||||
if (activeHand == null)
|
if (activeHand == null)
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!activeHand.TryGetComponent(out StackComponent stack) || !ConstructionComponent.MaterialStackValidFor(matStep, stack))
|
if (!activeHand.TryGetComponent(out StackComponent stack) || !ConstructionComponent.MaterialStackValidFor(matStep, stack))
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!stack.Use(matStep.Amount))
|
if (!stack.Use(matStep.Amount))
|
||||||
{
|
{
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// OK WE'RE GOOD CONSTRUCTION STARTED.
|
// OK WE'RE GOOD CONSTRUCTION STARTED.
|
||||||
EntitySystem.Get<AudioSystem>().PlayAtCoords("/Audio/items/deconstruct.ogg", loc);
|
Get<AudioSystem>().PlayAtCoords("/Audio/items/deconstruct.ogg", loc);
|
||||||
if (prototype.Stages.Count == 2)
|
if (prototype.Stages.Count == 2)
|
||||||
{
|
{
|
||||||
// Exactly 2 stages, so don't make an intermediate frame.
|
// Exactly 2 stages, so don't make an intermediate frame.
|
||||||
@@ -99,11 +110,10 @@ namespace Content.Server.GameObjects.Components.Construction
|
|||||||
frame.Transform.LocalRotation = angle;
|
frame.Transform.LocalRotation = angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
var msg = new AckStructureConstructionMessage(ack);
|
return true;
|
||||||
SendNetworkMessage(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TryStartItemConstruction(string prototypeName)
|
private void TryStartItemConstruction(IEntity placingEnt, string prototypeName)
|
||||||
{
|
{
|
||||||
var prototype = _prototypeManager.Index<ConstructionPrototype>(prototypeName);
|
var prototype = _prototypeManager.Index<ConstructionPrototype>(prototypeName);
|
||||||
|
|
||||||
@@ -119,7 +129,7 @@ namespace Content.Server.GameObjects.Components.Construction
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try to find the stack with the material in the user's hand.
|
// Try to find the stack with the material in the user's hand.
|
||||||
var hands = Owner.GetComponent<HandsComponent>();
|
var hands = placingEnt.GetComponent<HandsComponent>();
|
||||||
var activeHand = hands.GetActiveHand?.Owner;
|
var activeHand = hands.GetActiveHand?.Owner;
|
||||||
if (activeHand == null)
|
if (activeHand == null)
|
||||||
{
|
{
|
||||||
@@ -137,17 +147,17 @@ namespace Content.Server.GameObjects.Components.Construction
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OK WE'RE GOOD CONSTRUCTION STARTED.
|
// OK WE'RE GOOD CONSTRUCTION STARTED.
|
||||||
EntitySystem.Get<AudioSystem>().PlayFromEntity("/Audio/items/deconstruct.ogg", Owner);
|
EntitySystem.Get<AudioSystem>().PlayFromEntity("/Audio/items/deconstruct.ogg", placingEnt);
|
||||||
if (prototype.Stages.Count == 2)
|
if (prototype.Stages.Count == 2)
|
||||||
{
|
{
|
||||||
// Exactly 2 stages, so don't make an intermediate frame.
|
// Exactly 2 stages, so don't make an intermediate frame.
|
||||||
var ent = _serverEntityManager.SpawnEntity(prototype.Result, Owner.Transform.GridPosition);
|
var ent = _serverEntityManager.SpawnEntity(prototype.Result, placingEnt.Transform.GridPosition);
|
||||||
hands.PutInHandOrDrop(ent.GetComponent<ItemComponent>());
|
hands.PutInHandOrDrop(ent.GetComponent<ItemComponent>());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//TODO: Make these viable as an item and try putting them in the players hands
|
//TODO: Make these viable as an item and try putting them in the players hands
|
||||||
var frame = _serverEntityManager.SpawnEntity("structureconstructionframe", Owner.Transform.GridPosition);
|
var frame = _serverEntityManager.SpawnEntity("structureconstructionframe", placingEnt.Transform.GridPosition);
|
||||||
var construction = frame.GetComponent<ConstructionComponent>();
|
var construction = frame.GetComponent<ConstructionComponent>();
|
||||||
construction.Init(prototype);
|
construction.Init(prototype);
|
||||||
}
|
}
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Folder Include="GameObjects\Components\Construction\" />
|
||||||
<Folder Include="GameObjects\Components\Trigger\" />
|
<Folder Include="GameObjects\Components\Trigger\" />
|
||||||
<EmbeddedResource Include="Text\Names\*.txt" />
|
<EmbeddedResource Include="Text\Names\*.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
public const uint STORAGE = 1005;
|
public const uint STORAGE = 1005;
|
||||||
public const uint INVENTORY = 1006;
|
public const uint INVENTORY = 1006;
|
||||||
public const uint POWER_DEBUG_TOOL = 1007;
|
public const uint POWER_DEBUG_TOOL = 1007;
|
||||||
public const uint CONSTRUCTOR = 1008;
|
// 1008
|
||||||
|
// 1009
|
||||||
public const uint RANGED_WEAPON = 1010;
|
public const uint RANGED_WEAPON = 1010;
|
||||||
public const uint CAMERA_RECOIL = 1011;
|
public const uint CAMERA_RECOIL = 1011;
|
||||||
public const uint SOUND = 1012;
|
public const uint SOUND = 1012;
|
||||||
|
|||||||
@@ -1,25 +1,22 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.GameObjects.Systems;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.GameObjects.Components.Construction
|
namespace Content.Shared.GameObjects.EntitySystems
|
||||||
{
|
{
|
||||||
/// <summary>
|
[UsedImplicitly]
|
||||||
/// Basically handles the logic of "this mob can do construction".
|
public class ConstructionSystem : EntitySystem
|
||||||
/// </summary>
|
|
||||||
public abstract class SharedConstructorComponent : Component
|
|
||||||
{
|
{
|
||||||
public override string Name => "Constructor";
|
|
||||||
public override uint? NetID => ContentNetIDs.CONSTRUCTOR;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sent client -> server to to tell the server that we started building
|
/// Sent client -> server to to tell the server that we started building
|
||||||
/// a structure-construction.
|
/// a structure-construction.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
protected class TryStartStructureConstructionMessage : ComponentMessage
|
public class TryStartStructureConstructionMessage : EntitySystemMessage
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Position to start building.
|
/// Position to start building.
|
||||||
@@ -40,7 +37,6 @@ namespace Content.Shared.GameObjects.Components.Construction
|
|||||||
|
|
||||||
public TryStartStructureConstructionMessage(GridCoordinates loc, string prototypeName, Angle angle, int ack)
|
public TryStartStructureConstructionMessage(GridCoordinates loc, string prototypeName, Angle angle, int ack)
|
||||||
{
|
{
|
||||||
Directed = true;
|
|
||||||
Location = loc;
|
Location = loc;
|
||||||
PrototypeName = prototypeName;
|
PrototypeName = prototypeName;
|
||||||
Angle = angle;
|
Angle = angle;
|
||||||
@@ -53,7 +49,7 @@ namespace Content.Shared.GameObjects.Components.Construction
|
|||||||
/// an item-construction.
|
/// an item-construction.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
protected class TryStartItemConstructionMessage : ComponentMessage
|
public class TryStartItemConstructionMessage : EntitySystemMessage
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The construction prototype to start building.
|
/// The construction prototype to start building.
|
||||||
@@ -62,21 +58,21 @@ namespace Content.Shared.GameObjects.Components.Construction
|
|||||||
|
|
||||||
public TryStartItemConstructionMessage(string prototypeName)
|
public TryStartItemConstructionMessage(string prototypeName)
|
||||||
{
|
{
|
||||||
Directed = true;
|
|
||||||
PrototypeName = prototypeName;
|
PrototypeName = prototypeName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Send server -> client to tell the client that a ghost has started to be constructed.
|
||||||
|
/// </summary>
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
protected class AckStructureConstructionMessage : ComponentMessage
|
public class AckStructureConstructionMessage : EntitySystemMessage
|
||||||
{
|
{
|
||||||
public readonly int Ack;
|
public readonly int GhostId;
|
||||||
|
|
||||||
public AckStructureConstructionMessage(int ack)
|
public AckStructureConstructionMessage(int ghostId)
|
||||||
{
|
{
|
||||||
Directed = true;
|
GhostId = ghostId;
|
||||||
Ack = ack;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,6 @@
|
|||||||
max_volume: 250
|
max_volume: 250
|
||||||
digestionDelay: 20
|
digestionDelay: 20
|
||||||
- type: Inventory
|
- type: Inventory
|
||||||
- type: Constructor
|
|
||||||
- type: Clickable
|
- type: Clickable
|
||||||
- type: InteractionOutline
|
- type: InteractionOutline
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
|
|||||||
Reference in New Issue
Block a user