Construction System. (#87)
* Construction WiP * Construction kinda works! * Lots more construction work. * It mostly works!
56
Content.Client/Construction/ConstructionButton.cs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
using Content.Client.GameObjects.Components.Construction;
|
||||||
|
using SS14.Client.UserInterface;
|
||||||
|
using SS14.Client.UserInterface.Controls;
|
||||||
|
using SS14.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Client.Construction
|
||||||
|
{
|
||||||
|
public class ConstructionButton : Button
|
||||||
|
{
|
||||||
|
protected override ResourcePath ScenePath => new ResourcePath("/Scenes/Construction/ConstructionButton.tscn");
|
||||||
|
|
||||||
|
public ConstructorComponent Owner
|
||||||
|
{
|
||||||
|
get => Menu.Owner;
|
||||||
|
set => Menu.Owner = value;
|
||||||
|
}
|
||||||
|
ConstructionMenu Menu;
|
||||||
|
|
||||||
|
protected override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
OnPressed += IWasPressed;
|
||||||
|
Menu = new ConstructionMenu();
|
||||||
|
Menu.AddToScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IWasPressed(ButtonEventArgs args)
|
||||||
|
{
|
||||||
|
Menu.Open();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddToScreen()
|
||||||
|
{
|
||||||
|
UserInterfaceManager.StateRoot.AddChild(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveFromScreen()
|
||||||
|
{
|
||||||
|
if (Parent != null)
|
||||||
|
{
|
||||||
|
Parent.RemoveChild(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
Menu.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
344
Content.Client/Construction/ConstructionMenu.cs
Normal file
@@ -0,0 +1,344 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Content.Client.GameObjects.Components.Construction;
|
||||||
|
using Content.Shared.Construction;
|
||||||
|
using SS14.Client.GameObjects;
|
||||||
|
using SS14.Client.Graphics;
|
||||||
|
using SS14.Client.Interfaces.GameObjects;
|
||||||
|
using SS14.Client.Interfaces.Placement;
|
||||||
|
using SS14.Client.Interfaces.ResourceManagement;
|
||||||
|
using SS14.Client.Placement;
|
||||||
|
using SS14.Client.ResourceManagement;
|
||||||
|
using SS14.Client.UserInterface;
|
||||||
|
using SS14.Client.UserInterface.Controls;
|
||||||
|
using SS14.Client.UserInterface.CustomControls;
|
||||||
|
using SS14.Client.Utility;
|
||||||
|
using SS14.Shared.Enums;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
|
using SS14.Shared.IoC;
|
||||||
|
using SS14.Shared.Log;
|
||||||
|
using SS14.Shared.Maths;
|
||||||
|
using SS14.Shared.Prototypes;
|
||||||
|
using SS14.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Client.Construction
|
||||||
|
{
|
||||||
|
public class ConstructionMenu : SS14Window
|
||||||
|
{
|
||||||
|
protected override ResourcePath ScenePath => new ResourcePath("/Scenes/Construction/ConstructionMenu.tscn");
|
||||||
|
|
||||||
|
#pragma warning disable CS0649
|
||||||
|
[Dependency]
|
||||||
|
readonly IPrototypeManager PrototypeManager;
|
||||||
|
[Dependency]
|
||||||
|
readonly IResourceCache ResourceCache;
|
||||||
|
#pragma warning restore
|
||||||
|
|
||||||
|
public ConstructorComponent Owner { get; set; }
|
||||||
|
Button BuildButton;
|
||||||
|
Button EraseButton;
|
||||||
|
LineEdit SearchBar;
|
||||||
|
Tree RecipeList;
|
||||||
|
TextureRect InfoIcon;
|
||||||
|
Label InfoLabel;
|
||||||
|
ItemList StepList;
|
||||||
|
|
||||||
|
CategoryNode RootCategory;
|
||||||
|
// This list is flattened in such a way that the top most deepest category is first.
|
||||||
|
List<CategoryNode> FlattenedCategories;
|
||||||
|
PlacementManager Placement;
|
||||||
|
|
||||||
|
protected override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
IoCManager.InjectDependencies(this);
|
||||||
|
Placement = (PlacementManager)IoCManager.Resolve<IPlacementManager>();
|
||||||
|
Placement.PlacementCanceled += OnPlacementCanceled;
|
||||||
|
|
||||||
|
HideOnClose = true;
|
||||||
|
Title = "Construction";
|
||||||
|
Visible = false;
|
||||||
|
var split = Contents.GetChild("HSplitContainer");
|
||||||
|
var rightSide = split.GetChild("Guide");
|
||||||
|
var info = rightSide.GetChild("Info");
|
||||||
|
InfoIcon = info.GetChild<TextureRect>("TextureRect");
|
||||||
|
InfoLabel = info.GetChild<Label>("Label");
|
||||||
|
StepList = rightSide.GetChild<ItemList>("StepsList");
|
||||||
|
var buttons = rightSide.GetChild("Buttons");
|
||||||
|
BuildButton = buttons.GetChild<Button>("BuildButton");
|
||||||
|
BuildButton.OnPressed += OnBuildPressed;
|
||||||
|
EraseButton = buttons.GetChild<Button>("EraseButton");
|
||||||
|
EraseButton.OnToggled += OnEraseToggled;
|
||||||
|
|
||||||
|
var leftSide = split.GetChild("Recipes");
|
||||||
|
SearchBar = leftSide.GetChild<LineEdit>("Search");
|
||||||
|
SearchBar.OnTextChanged += OnTextEntered;
|
||||||
|
RecipeList = leftSide.GetChild<Tree>("Tree");
|
||||||
|
RecipeList.OnItemSelected += OnItemSelected;
|
||||||
|
|
||||||
|
PopulatePrototypeList();
|
||||||
|
PopulateTree();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
base.Dispose(disposing);
|
||||||
|
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
Placement.PlacementCanceled -= OnPlacementCanceled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnItemSelected()
|
||||||
|
{
|
||||||
|
var prototype = (ConstructionPrototype)RecipeList.Selected.Metadata;
|
||||||
|
|
||||||
|
if (prototype == null)
|
||||||
|
{
|
||||||
|
InfoLabel.Text = "";
|
||||||
|
InfoIcon.Texture = null;
|
||||||
|
StepList.Clear();
|
||||||
|
BuildButton.Disabled = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BuildButton.Disabled = false;
|
||||||
|
InfoLabel.Text = prototype.Description;
|
||||||
|
InfoIcon.Texture = prototype.Icon.Frame0();
|
||||||
|
|
||||||
|
StepList.Clear();
|
||||||
|
|
||||||
|
foreach (var forward in prototype.Stages.Select(a => a.Forward))
|
||||||
|
{
|
||||||
|
if (forward == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Texture icon;
|
||||||
|
string text;
|
||||||
|
switch (forward)
|
||||||
|
{
|
||||||
|
case ConstructionStepMaterial mat:
|
||||||
|
switch (mat.Material)
|
||||||
|
{
|
||||||
|
case ConstructionStepMaterial.MaterialType.Metal:
|
||||||
|
icon = ResourceCache.GetResource<TextureResource>("/Textures/Objects/sheet_metal.png");
|
||||||
|
text = $"Metal x{mat.Amount}";
|
||||||
|
break;
|
||||||
|
case ConstructionStepMaterial.MaterialType.Glass:
|
||||||
|
icon = ResourceCache.GetResource<TextureResource>("/Textures/Objects/sheet_glass.png");
|
||||||
|
text = $"Glass x{mat.Amount}";
|
||||||
|
break;
|
||||||
|
case ConstructionStepMaterial.MaterialType.Cable:
|
||||||
|
icon = ResourceCache.GetResource<TextureResource>("/Textures/Objects/cable_coil.png");
|
||||||
|
text = $"Cable Coil x{mat.Amount}";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ConstructionStepTool tool:
|
||||||
|
switch (tool.Tool)
|
||||||
|
{
|
||||||
|
case ConstructionStepTool.ToolType.Wrench:
|
||||||
|
icon = ResourceCache.GetResource<TextureResource>("/Textures/Objects/wrench.png");
|
||||||
|
text = "Wrench";
|
||||||
|
break;
|
||||||
|
case ConstructionStepTool.ToolType.Crowbar:
|
||||||
|
icon = ResourceCache.GetResource<TextureResource>("/Textures/Objects/crowbar.png");
|
||||||
|
text = "Crowbar";
|
||||||
|
break;
|
||||||
|
case ConstructionStepTool.ToolType.Screwdriver:
|
||||||
|
icon = ResourceCache.GetResource<TextureResource>("/Textures/Objects/screwdriver.png");
|
||||||
|
text = "Screwdriver";
|
||||||
|
break;
|
||||||
|
case ConstructionStepTool.ToolType.Welder:
|
||||||
|
icon = ResourceCache.GetResource<RSIResource>("/Textures/Objects/tools.rsi").RSI["welder"].Frame0;
|
||||||
|
text = $"Welding tool ({tool.Amount} fuel)";
|
||||||
|
break;
|
||||||
|
case ConstructionStepTool.ToolType.Wirecutters:
|
||||||
|
icon = ResourceCache.GetResource<TextureResource>("/Textures/Objects/wirecutter.png");
|
||||||
|
text = "Wirecutters";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
StepList.AddItem(text, icon, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnTextEntered(LineEdit.LineEditEventArgs args)
|
||||||
|
{
|
||||||
|
var str = args.Text;
|
||||||
|
PopulateTree(string.IsNullOrWhiteSpace(str) ? null : str.ToLowerInvariant());
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnBuildPressed(Button.ButtonEventArgs args)
|
||||||
|
{
|
||||||
|
var prototype = (ConstructionPrototype)RecipeList.Selected.Metadata;
|
||||||
|
if (prototype == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prototype.Type != ConstructionType.Structure)
|
||||||
|
{
|
||||||
|
// In-hand attackby doesn't exist so this is the best alternative.
|
||||||
|
var loc = Owner.Owner.GetComponent<ITransformComponent>().LocalPosition;
|
||||||
|
Owner.SpawnGhost(prototype, loc, Direction.North);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var hijack = new ConstructionPlacementHijack(prototype, Owner);
|
||||||
|
var info = new PlacementInformation
|
||||||
|
{
|
||||||
|
IsTile = false,
|
||||||
|
PlacementOption = prototype.PlacementMode,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Placement.BeginHijackedPlacing(info, hijack);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEraseToggled(BaseButton.ButtonToggledEventArgs args)
|
||||||
|
{
|
||||||
|
var hijack = new ConstructionPlacementHijack(null, Owner);
|
||||||
|
Placement.ToggleEraserHijacked(hijack);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopulatePrototypeList()
|
||||||
|
{
|
||||||
|
RootCategory = new CategoryNode("", null);
|
||||||
|
int count = 1;
|
||||||
|
|
||||||
|
foreach (var prototype in PrototypeManager.EnumeratePrototypes<ConstructionPrototype>())
|
||||||
|
{
|
||||||
|
var currentNode = RootCategory;
|
||||||
|
|
||||||
|
foreach (var category in prototype.CategorySegments)
|
||||||
|
{
|
||||||
|
if (!currentNode.ChildCategories.TryGetValue(category, out var subNode))
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
subNode = new CategoryNode(category, currentNode);
|
||||||
|
currentNode.ChildCategories.Add(category, subNode);
|
||||||
|
}
|
||||||
|
currentNode = subNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentNode.Prototypes.Add(prototype);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do a pass to sort the prototype lists and flatten the hierarchy.
|
||||||
|
void Recurse(CategoryNode node)
|
||||||
|
{
|
||||||
|
// I give up we're using recursion to flatten this.
|
||||||
|
// There probably IS a way to do it.
|
||||||
|
// I'm too stupid to think of what that way is.
|
||||||
|
foreach (var child in node.ChildCategories.Values)
|
||||||
|
{
|
||||||
|
Recurse(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
node.Prototypes.Sort(ComparePrototype);
|
||||||
|
FlattenedCategories.Add(node);
|
||||||
|
node.FlattenedIndex = FlattenedCategories.Count - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FlattenedCategories = new List<CategoryNode>(count);
|
||||||
|
Recurse(RootCategory);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopulateTree(string searchTerm = null)
|
||||||
|
{
|
||||||
|
RecipeList.Clear();
|
||||||
|
|
||||||
|
var categoryItems = new Tree.Item[FlattenedCategories.Count];
|
||||||
|
categoryItems[RootCategory.FlattenedIndex] = RecipeList.CreateItem();
|
||||||
|
|
||||||
|
// Yay more recursion.
|
||||||
|
Tree.Item ItemForNode(CategoryNode node)
|
||||||
|
{
|
||||||
|
if (categoryItems[node.FlattenedIndex] != null)
|
||||||
|
{
|
||||||
|
return categoryItems[node.FlattenedIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = RecipeList.CreateItem(ItemForNode(node.Parent));
|
||||||
|
item.SetText(0, node.Name);
|
||||||
|
item.SetSelectable(0, false);
|
||||||
|
categoryItems[node.FlattenedIndex] = item;
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var node in FlattenedCategories)
|
||||||
|
{
|
||||||
|
foreach (var prototype in node.Prototypes)
|
||||||
|
{
|
||||||
|
if (searchTerm != null)
|
||||||
|
{
|
||||||
|
var found = false;
|
||||||
|
// TODO: don't run ToLowerInvariant() constantly.
|
||||||
|
if (prototype.Name.ToLowerInvariant().IndexOf(searchTerm) != -1)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var keyw in prototype.Keywords.Concat(prototype.CategorySegments))
|
||||||
|
{
|
||||||
|
// TODO: don't run ToLowerInvariant() constantly.
|
||||||
|
if (keyw.ToLowerInvariant().IndexOf(searchTerm) != -1)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var subItem = RecipeList.CreateItem(ItemForNode(node));
|
||||||
|
subItem.SetText(0, prototype.Name);
|
||||||
|
subItem.Metadata = prototype;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPlacementCanceled(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
EraseButton.Pressed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int ComparePrototype(ConstructionPrototype x, ConstructionPrototype y)
|
||||||
|
{
|
||||||
|
return x.Name.CompareTo(y.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
class CategoryNode
|
||||||
|
{
|
||||||
|
public readonly string Name;
|
||||||
|
public readonly CategoryNode Parent;
|
||||||
|
public SortedDictionary<string, CategoryNode> ChildCategories = new SortedDictionary<string, CategoryNode>();
|
||||||
|
public List<ConstructionPrototype> Prototypes = new List<ConstructionPrototype>();
|
||||||
|
public int FlattenedIndex = -1;
|
||||||
|
|
||||||
|
public CategoryNode(string name, CategoryNode parent)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Parent = parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
62
Content.Client/Construction/ConstructionPlacementHijack.cs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
using Content.Client.GameObjects.Components.Construction;
|
||||||
|
using Content.Shared.Construction;
|
||||||
|
using SS14.Client.Graphics;
|
||||||
|
using SS14.Client.Interfaces.ResourceManagement;
|
||||||
|
using SS14.Client.Placement;
|
||||||
|
using SS14.Client.ResourceManagement;
|
||||||
|
using SS14.Client.Utility;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.IoC;
|
||||||
|
using SS14.Shared.Map;
|
||||||
|
using SS14.Shared.Maths;
|
||||||
|
|
||||||
|
namespace Content.Client.Construction
|
||||||
|
{
|
||||||
|
public class ConstructionPlacementHijack : PlacementHijack
|
||||||
|
{
|
||||||
|
private readonly ConstructionPrototype Prototype;
|
||||||
|
private readonly ConstructorComponent Owner;
|
||||||
|
|
||||||
|
public ConstructionPlacementHijack(ConstructionPrototype prototype, ConstructorComponent owner)
|
||||||
|
{
|
||||||
|
Prototype = prototype;
|
||||||
|
Owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool HijackPlacementRequest(GridLocalCoordinates coords)
|
||||||
|
{
|
||||||
|
if (Prototype != null)
|
||||||
|
{
|
||||||
|
// Stupid god damn Y AXIS.
|
||||||
|
var dir = Manager.Direction;
|
||||||
|
if (dir == Direction.South)
|
||||||
|
{
|
||||||
|
dir = Direction.North;
|
||||||
|
}
|
||||||
|
else if (dir == Direction.North)
|
||||||
|
{
|
||||||
|
dir = Direction.South;
|
||||||
|
}
|
||||||
|
Owner.SpawnGhost(Prototype, coords, dir);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool HijackDeletion(IEntity entity)
|
||||||
|
{
|
||||||
|
if (entity.TryGetComponent(out ConstructionGhostComponent ghost))
|
||||||
|
{
|
||||||
|
Owner.ClearGhost(ghost.GhostID);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void StartHijack(PlacementManager manager)
|
||||||
|
{
|
||||||
|
base.StartHijack(manager);
|
||||||
|
|
||||||
|
var res = IoCManager.Resolve<IResourceCache>();
|
||||||
|
manager.CurrentBaseSprite = Prototype.Icon.DirFrame0();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -63,6 +63,9 @@
|
|||||||
<Reference Include="YamlDotNet, Version=4.3.1.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="YamlDotNet, Version=4.3.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>$(SolutionDir)packages\YamlDotNet.4.3.1\lib\net45\YamlDotNet.dll</HintPath>
|
<HintPath>$(SolutionDir)packages\YamlDotNet.4.3.1\lib\net45\YamlDotNet.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="System.ValueTuple">
|
||||||
|
<HintPath>$(SolutionDir)packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="EntryPoint.cs" />
|
<Compile Include="EntryPoint.cs" />
|
||||||
@@ -107,5 +110,10 @@
|
|||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
<Compile Include="GameObjects\Components\Power\SmesVisualizer2D.cs" />
|
<Compile Include="GameObjects\Components\Power\SmesVisualizer2D.cs" />
|
||||||
<Compile Include="GameObjects\Components\Power\ApcVisualizer2D.cs" />
|
<Compile Include="GameObjects\Components\Power\ApcVisualizer2D.cs" />
|
||||||
|
<Compile Include="Construction\ConstructionMenu.cs" />
|
||||||
|
<Compile Include="Construction\ConstructionButton.cs" />
|
||||||
|
<Compile Include="GameObjects\Components\Construction\ConstructorComponent.cs" />
|
||||||
|
<Compile Include="GameObjects\Components\Construction\ConstructionGhostComponent.cs" />
|
||||||
|
<Compile Include="Construction\ConstructionPlacementHijack.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
using Content.Client.GameObjects;
|
using Content.Client.GameObjects;
|
||||||
|
using Content.Client.GameObjects.Components.Construction;
|
||||||
using Content.Client.GameObjects.Components.Power;
|
using Content.Client.GameObjects.Components.Power;
|
||||||
using Content.Client.GameObjects.Components.Storage;
|
using Content.Client.GameObjects.Components.Storage;
|
||||||
using Content.Client.Interfaces.GameObjects;
|
using Content.Client.Interfaces.GameObjects;
|
||||||
using SS14.Shared.ContentPack;
|
using SS14.Shared.ContentPack;
|
||||||
using SS14.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
using SS14.Shared.IoC;
|
using SS14.Shared.IoC;
|
||||||
|
using SS14.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Client
|
namespace Content.Client
|
||||||
{
|
{
|
||||||
@@ -13,6 +15,7 @@ namespace Content.Client
|
|||||||
public override void Init()
|
public override void Init()
|
||||||
{
|
{
|
||||||
var factory = IoCManager.Resolve<IComponentFactory>();
|
var factory = IoCManager.Resolve<IComponentFactory>();
|
||||||
|
var prototypes = IoCManager.Resolve<IPrototypeManager>();
|
||||||
|
|
||||||
factory.RegisterIgnore("Item");
|
factory.RegisterIgnore("Item");
|
||||||
factory.RegisterIgnore("Interactable");
|
factory.RegisterIgnore("Interactable");
|
||||||
@@ -40,11 +43,18 @@ namespace Content.Client
|
|||||||
factory.RegisterIgnore("Storeable");
|
factory.RegisterIgnore("Storeable");
|
||||||
factory.RegisterIgnore("Clothing");
|
factory.RegisterIgnore("Clothing");
|
||||||
|
|
||||||
|
factory.RegisterIgnore("Material");
|
||||||
|
factory.RegisterIgnore("Stack");
|
||||||
|
|
||||||
factory.Register<HandsComponent>();
|
factory.Register<HandsComponent>();
|
||||||
factory.RegisterReference<HandsComponent, IHandsComponent>();
|
factory.RegisterReference<HandsComponent, IHandsComponent>();
|
||||||
factory.Register<ClientStorageComponent>();
|
factory.Register<ClientStorageComponent>();
|
||||||
factory.Register<ClientInventoryComponent>();
|
factory.Register<ClientInventoryComponent>();
|
||||||
factory.Register<PowerDebugTool>();
|
factory.Register<PowerDebugTool>();
|
||||||
|
factory.Register<ConstructorComponent>();
|
||||||
|
factory.Register<ConstructionGhostComponent>();
|
||||||
|
|
||||||
|
prototypes.RegisterIgnore("material");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using Content.Shared.Construction;
|
||||||
|
using SS14.Shared.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.Network;
|
||||||
|
|
||||||
|
namespace Content.Client.GameObjects.Components.Construction
|
||||||
|
{
|
||||||
|
public class ConstructionGhostComponent : Component
|
||||||
|
{
|
||||||
|
public override string Name => "ConstructionGhost";
|
||||||
|
|
||||||
|
public ConstructionPrototype Prototype { get; set; }
|
||||||
|
public ConstructorComponent Master { get; set; }
|
||||||
|
public int GhostID { get; set; }
|
||||||
|
|
||||||
|
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
|
||||||
|
{
|
||||||
|
base.HandleMessage(message, netChannel, component);
|
||||||
|
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
case ClientEntityClickMsg clickMsg:
|
||||||
|
Master.TryStartConstruction(GhostID);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Content.Client.Construction;
|
||||||
|
using Content.Shared.Construction;
|
||||||
|
using Content.Shared.GameObjects.Components.Construction;
|
||||||
|
using SS14.Client.GameObjects;
|
||||||
|
using SS14.Client.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
|
using SS14.Shared.Interfaces.Network;
|
||||||
|
using SS14.Shared.IoC;
|
||||||
|
using SS14.Shared.Log;
|
||||||
|
using SS14.Shared.Map;
|
||||||
|
using SS14.Shared.Maths;
|
||||||
|
|
||||||
|
namespace Content.Client.GameObjects.Components.Construction
|
||||||
|
{
|
||||||
|
public class ConstructorComponent : SharedConstructorComponent
|
||||||
|
{
|
||||||
|
int nextId;
|
||||||
|
readonly Dictionary<int, ConstructionGhostComponent> Ghosts = new Dictionary<int, ConstructionGhostComponent>();
|
||||||
|
ConstructionButton Button;
|
||||||
|
|
||||||
|
ITransformComponent Transform;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
Transform = Owner.GetComponent<ITransformComponent>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
|
||||||
|
{
|
||||||
|
base.HandleMessage(message, netChannel, component);
|
||||||
|
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
case PlayerAttachedMsg _:
|
||||||
|
if (Button == null)
|
||||||
|
{
|
||||||
|
Button = new ConstructionButton();
|
||||||
|
Button.Owner = this;
|
||||||
|
}
|
||||||
|
Button.AddToScreen();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PlayerDetachedMsg _:
|
||||||
|
Button.RemoveFromScreen();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AckStructureConstructionMessage ackMsg:
|
||||||
|
ClearGhost(ackMsg.Ack);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnRemove()
|
||||||
|
{
|
||||||
|
Button?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SpawnGhost(ConstructionPrototype prototype, GridLocalCoordinates loc, Direction dir)
|
||||||
|
{
|
||||||
|
var entMgr = IoCManager.Resolve<IClientEntityManager>();
|
||||||
|
var ghost = entMgr.ForceSpawnEntityAt("constructionghost", loc);
|
||||||
|
var comp = ghost.GetComponent<ConstructionGhostComponent>();
|
||||||
|
comp.Prototype = prototype;
|
||||||
|
comp.Master = this;
|
||||||
|
comp.GhostID = nextId++;
|
||||||
|
var transform = ghost.GetComponent<ITransformComponent>().LocalRotation = dir.ToAngle();
|
||||||
|
var sprite = ghost.GetComponent<SpriteComponent>();
|
||||||
|
sprite.LayerSetSprite(0, prototype.Icon);
|
||||||
|
sprite.LayerSetShader(0, "unshaded");
|
||||||
|
|
||||||
|
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.LocalPosition, ghost.Prototype.ID, transform.LocalRotation, ghostId);
|
||||||
|
SendNetworkMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearGhost(int ghostId)
|
||||||
|
{
|
||||||
|
if (Ghosts.TryGetValue(ghostId, out var ghost))
|
||||||
|
{
|
||||||
|
ghost.Owner.Delete();
|
||||||
|
Ghosts.Remove(ghostId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -60,7 +60,7 @@ namespace Content.Client.GameObjects
|
|||||||
|
|
||||||
public void UseActiveHand()
|
public void UseActiveHand()
|
||||||
{
|
{
|
||||||
if(GetEntity(ActiveIndex) != null)
|
if (GetEntity(ActiveIndex) != null)
|
||||||
{
|
{
|
||||||
SendNetworkMessage(new ActivateInhandMsg());
|
SendNetworkMessage(new ActivateInhandMsg());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,4 +2,4 @@
|
|||||||
<packages>
|
<packages>
|
||||||
<package id="System.ValueTuple" version="4.4.0" targetFramework="net451" />
|
<package id="System.ValueTuple" version="4.4.0" targetFramework="net451" />
|
||||||
<package id="YamlDotNet" version="4.3.1" targetFramework="net451" />
|
<package id="YamlDotNet" version="4.3.1" targetFramework="net451" />
|
||||||
</packages>
|
</packages>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace Content.Server.AI
|
|||||||
|
|
||||||
private readonly List<IEntity> _workList = new List<IEntity>();
|
private readonly List<IEntity> _workList = new List<IEntity>();
|
||||||
|
|
||||||
private const float MaxAngSpeed = (float) (Math.PI / 2); // how fast our turret can rotate
|
private const float MaxAngSpeed = (float)(Math.PI / 2); // how fast our turret can rotate
|
||||||
private const float ScanPeriod = 1.0f; // tweak this for performance and gameplay experience
|
private const float ScanPeriod = 1.0f; // tweak this for performance and gameplay experience
|
||||||
private float _lastScan;
|
private float _lastScan;
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ namespace Content.Server.AI
|
|||||||
var curTime = _timeMan.CurTime.TotalSeconds;
|
var curTime = _timeMan.CurTime.TotalSeconds;
|
||||||
if (curTime - _lastScan > ScanPeriod)
|
if (curTime - _lastScan > ScanPeriod)
|
||||||
{
|
{
|
||||||
_lastScan = (float) curTime;
|
_lastScan = (float)curTime;
|
||||||
_curTarget = FindBestTarget();
|
_curTarget = FindBestTarget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,9 +72,10 @@ namespace Content.Server.AI
|
|||||||
|
|
||||||
// point me at the target
|
// point me at the target
|
||||||
var tarPos = _curTarget.GetComponent<ITransformComponent>().WorldPosition;
|
var tarPos = _curTarget.GetComponent<ITransformComponent>().WorldPosition;
|
||||||
var myPos = SelfEntity.GetComponent<ITransformComponent>().WorldPosition;
|
var selfTransform = SelfEntity.GetComponent<ITransformComponent>();
|
||||||
|
var myPos = selfTransform.WorldPosition;
|
||||||
|
|
||||||
var curDir = SelfEntity.GetComponent<IServerTransformComponent>().LocalRotation.ToVec();
|
var curDir = selfTransform.LocalRotation.ToVec();
|
||||||
var tarDir = (tarPos - myPos).Normalized;
|
var tarDir = (tarPos - myPos).Normalized;
|
||||||
|
|
||||||
var fwdAng = Vector2.Dot(curDir, tarDir);
|
var fwdAng = Vector2.Dot(curDir, tarDir);
|
||||||
@@ -92,7 +93,7 @@ namespace Content.Server.AI
|
|||||||
newDir = MoveTowards(curDir, tarDir, MaxAngSpeed, frameTime);
|
newDir = MoveTowards(curDir, tarDir, MaxAngSpeed, frameTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
SelfEntity.GetComponent<IServerTransformComponent>().LocalRotation = new Angle(newDir);
|
selfTransform.LocalRotation = new Angle(newDir);
|
||||||
|
|
||||||
if (fwdAng > -0.9999)
|
if (fwdAng > -0.9999)
|
||||||
{
|
{
|
||||||
@@ -105,7 +106,7 @@ namespace Content.Server.AI
|
|||||||
// "best" target is the closest one with LOS
|
// "best" target is the closest one with LOS
|
||||||
|
|
||||||
var ents = _entMan.GetEntitiesInRange(SelfEntity, VisionRadius);
|
var ents = _entMan.GetEntitiesInRange(SelfEntity, VisionRadius);
|
||||||
var myTransform = SelfEntity.GetComponent<IServerTransformComponent>();
|
var myTransform = SelfEntity.GetComponent<ITransformComponent>();
|
||||||
var maxRayLen = VisionRadius * 2.5f; // circle inscribed in square, square diagonal = 2*r*sqrt(2)
|
var maxRayLen = VisionRadius * 2.5f; // circle inscribed in square, square diagonal = 2*r*sqrt(2)
|
||||||
|
|
||||||
_workList.Clear();
|
_workList.Clear();
|
||||||
@@ -116,7 +117,7 @@ namespace Content.Server.AI
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// build the ray
|
// build the ray
|
||||||
var dir = entity.GetComponent<TransformComponent>().WorldPosition - myTransform.WorldPosition;
|
var dir = entity.GetComponent<ITransformComponent>().WorldPosition - myTransform.WorldPosition;
|
||||||
var ray = new Ray(myTransform.WorldPosition, dir.Normalized);
|
var ray = new Ray(myTransform.WorldPosition, dir.Normalized);
|
||||||
|
|
||||||
// cast the ray
|
// cast the ray
|
||||||
|
|||||||
@@ -59,6 +59,9 @@
|
|||||||
<Reference Include="YamlDotNet, Version=4.3.1.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="YamlDotNet, Version=4.3.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>$(SolutionDir)packages\YamlDotNet.4.3.1\lib\net45\YamlDotNet.dll</HintPath>
|
<HintPath>$(SolutionDir)packages\YamlDotNet.4.3.1\lib\net45\YamlDotNet.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="System.ValueTuple">
|
||||||
|
<HintPath>$(SolutionDir)packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="AI\AimShootLifeProcessor.cs" />
|
<Compile Include="AI\AimShootLifeProcessor.cs" />
|
||||||
@@ -146,5 +149,8 @@
|
|||||||
<Compile Include="GameObjects\Components\Power\ApcComponent.cs" />
|
<Compile Include="GameObjects\Components\Power\ApcComponent.cs" />
|
||||||
<Compile Include="Materials\Material.cs" />
|
<Compile Include="Materials\Material.cs" />
|
||||||
<Compile Include="GameObjects\Components\Materials\MaterialComponent.cs" />
|
<Compile Include="GameObjects\Components\Materials\MaterialComponent.cs" />
|
||||||
|
<Compile Include="GameObjects\Components\Stack\StackComponent.cs" />
|
||||||
|
<Compile Include="GameObjects\Components\Construction\ConstructorComponent.cs" />
|
||||||
|
<Compile Include="GameObjects\Components\Construction\ConstructionComponent.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -26,6 +26,8 @@ using Content.Server.GameObjects.Components.Weapon.Ranged.Projectile;
|
|||||||
using Content.Server.GameObjects.Components.Projectiles;
|
using Content.Server.GameObjects.Components.Projectiles;
|
||||||
using Content.Server.GameObjects.Components.Weapon.Melee;
|
using Content.Server.GameObjects.Components.Weapon.Melee;
|
||||||
using Content.Server.GameObjects.Components.Materials;
|
using Content.Server.GameObjects.Components.Materials;
|
||||||
|
using Content.Server.GameObjects.Components.Stack;
|
||||||
|
using Content.Server.GameObjects.Components.Construction;
|
||||||
|
|
||||||
namespace Content.Server
|
namespace Content.Server
|
||||||
{
|
{
|
||||||
@@ -95,6 +97,11 @@ namespace Content.Server
|
|||||||
factory.Register<SmesComponent>();
|
factory.Register<SmesComponent>();
|
||||||
factory.Register<ApcComponent>();
|
factory.Register<ApcComponent>();
|
||||||
factory.Register<MaterialComponent>();
|
factory.Register<MaterialComponent>();
|
||||||
|
factory.Register<StackComponent>();
|
||||||
|
|
||||||
|
factory.Register<ConstructionComponent>();
|
||||||
|
factory.Register<ConstructorComponent>();
|
||||||
|
factory.RegisterIgnore("ConstructionGhost");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -0,0 +1,175 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Content.Server.GameObjects.Components.Interactable.Tools;
|
||||||
|
using Content.Server.GameObjects.Components.Stack;
|
||||||
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Shared.Construction;
|
||||||
|
using SS14.Server.GameObjects;
|
||||||
|
using SS14.Server.GameObjects.EntitySystems;
|
||||||
|
using SS14.Server.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
|
using SS14.Shared.IoC;
|
||||||
|
using static Content.Shared.Construction.ConstructionStepMaterial;
|
||||||
|
using static Content.Shared.Construction.ConstructionStepTool;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Construction
|
||||||
|
{
|
||||||
|
public class ConstructionComponent : Component, IAttackby
|
||||||
|
{
|
||||||
|
public override string Name => "Construction";
|
||||||
|
|
||||||
|
public ConstructionPrototype Prototype { get; private set; }
|
||||||
|
public int Stage { get; private set; }
|
||||||
|
|
||||||
|
SpriteComponent Sprite;
|
||||||
|
ITransformComponent Transform;
|
||||||
|
AudioSystem AudioSystem;
|
||||||
|
Random random;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
Sprite = Owner.GetComponent<SpriteComponent>();
|
||||||
|
Transform = Owner.GetComponent<ITransformComponent>();
|
||||||
|
var systemman = IoCManager.Resolve<IEntitySystemManager>();
|
||||||
|
AudioSystem = systemman.GetEntitySystem<AudioSystem>();
|
||||||
|
random = new Random();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Attackby(IEntity user, IEntity attackwith)
|
||||||
|
{
|
||||||
|
var stage = Prototype.Stages[Stage];
|
||||||
|
|
||||||
|
if (TryProcessStep(stage.Forward, attackwith))
|
||||||
|
{
|
||||||
|
Stage++;
|
||||||
|
if (Stage == Prototype.Stages.Count - 1)
|
||||||
|
{
|
||||||
|
// Oh boy we get to finish construction!
|
||||||
|
var entMgr = IoCManager.Resolve<IServerEntityManager>();
|
||||||
|
var ent = entMgr.ForceSpawnEntityAt(Prototype.Result, Transform.LocalPosition);
|
||||||
|
ent.GetComponent<ITransformComponent>().LocalRotation = Transform.LocalRotation;
|
||||||
|
Owner.Delete();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
stage = Prototype.Stages[Stage];
|
||||||
|
if (stage.Icon != null)
|
||||||
|
{
|
||||||
|
Sprite.LayerSetSprite(0, stage.Icon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (TryProcessStep(stage.Backward, attackwith))
|
||||||
|
{
|
||||||
|
Stage--;
|
||||||
|
if (Stage == 0)
|
||||||
|
{
|
||||||
|
// Deconstruction complete.
|
||||||
|
Owner.Delete();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
stage = Prototype.Stages[Stage];
|
||||||
|
if (stage.Icon != null)
|
||||||
|
{
|
||||||
|
Sprite.LayerSetSprite(0, stage.Icon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Init(ConstructionPrototype prototype)
|
||||||
|
{
|
||||||
|
Prototype = prototype;
|
||||||
|
Stage = 1;
|
||||||
|
Sprite.AddLayerWithSprite(prototype.Stages[1].Icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TryProcessStep(ConstructionStep step, IEntity slapped)
|
||||||
|
{
|
||||||
|
switch (step)
|
||||||
|
{
|
||||||
|
case ConstructionStepMaterial matStep:
|
||||||
|
if (!slapped.TryGetComponent(out StackComponent stack)
|
||||||
|
|| !MaterialStackValidFor(matStep, stack)
|
||||||
|
|| !stack.Use(matStep.Amount))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (matStep.Material == MaterialType.Cable)
|
||||||
|
AudioSystem.Play("/Audio/items/zip.ogg", Transform.LocalPosition);
|
||||||
|
else
|
||||||
|
AudioSystem.Play("/Audio/items/deconstruct.ogg", Transform.LocalPosition);
|
||||||
|
return true;
|
||||||
|
case ConstructionStepTool toolStep:
|
||||||
|
switch (toolStep.Tool)
|
||||||
|
{
|
||||||
|
case ToolType.Crowbar:
|
||||||
|
if (slapped.HasComponent<CrowbarComponent>())
|
||||||
|
{
|
||||||
|
AudioSystem.Play("/Audio/items/crowbar.ogg", Transform.LocalPosition);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case ToolType.Welder:
|
||||||
|
if (slapped.TryGetComponent(out WelderComponent welder) && welder.TryUse(toolStep.Amount))
|
||||||
|
{
|
||||||
|
if (random.NextDouble() > 0.5)
|
||||||
|
AudioSystem.Play("/Audio/items/welder.ogg", Transform.LocalPosition);
|
||||||
|
else
|
||||||
|
AudioSystem.Play("/Audio/items/welder2.ogg", Transform.LocalPosition);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case ToolType.Wrench:
|
||||||
|
if (slapped.HasComponent<WrenchComponent>())
|
||||||
|
{
|
||||||
|
AudioSystem.Play("/Audio/items/ratchet.ogg", Transform.LocalPosition);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case ToolType.Screwdriver:
|
||||||
|
if (slapped.HasComponent<ScrewdriverComponent>())
|
||||||
|
{
|
||||||
|
if (random.NextDouble() > 0.5)
|
||||||
|
AudioSystem.Play("/Audio/items/screwdriver.ogg", Transform.LocalPosition);
|
||||||
|
else
|
||||||
|
AudioSystem.Play("/Audio/items/screwdriver2.ogg", Transform.LocalPosition);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
case ToolType.Wirecutters:
|
||||||
|
if (slapped.HasComponent<WirecutterComponent>())
|
||||||
|
{
|
||||||
|
AudioSystem.Play("/Audio/items/wirecutter.ogg", Transform.LocalPosition);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Dictionary<StackType, ConstructionStepMaterial.MaterialType> StackTypeMap
|
||||||
|
= new Dictionary<StackType, ConstructionStepMaterial.MaterialType>
|
||||||
|
{
|
||||||
|
{ StackType.Cable, MaterialType.Cable },
|
||||||
|
{ StackType.Glass, MaterialType.Glass },
|
||||||
|
{ StackType.Metal, MaterialType.Metal }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Really this should check the actual materials at play..
|
||||||
|
public static bool MaterialStackValidFor(ConstructionStepMaterial step, StackComponent stack)
|
||||||
|
{
|
||||||
|
return StackTypeMap.TryGetValue((StackType)stack.StackType, out var should) && should == step.Material;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Content.Server.GameObjects.Components.Materials;
|
||||||
|
using Content.Server.GameObjects.Components.Stack;
|
||||||
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using Content.Shared.Construction;
|
||||||
|
using Content.Shared.GameObjects.Components.Construction;
|
||||||
|
using SS14.Server.GameObjects;
|
||||||
|
using SS14.Server.GameObjects.EntitySystems;
|
||||||
|
using SS14.Server.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
|
using SS14.Shared.Interfaces.Network;
|
||||||
|
using SS14.Shared.IoC;
|
||||||
|
using SS14.Shared.Map;
|
||||||
|
using SS14.Shared.Maths;
|
||||||
|
using SS14.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Construction
|
||||||
|
{
|
||||||
|
public class ConstructorComponent : SharedConstructorComponent
|
||||||
|
{
|
||||||
|
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
|
||||||
|
{
|
||||||
|
base.HandleMessage(message, netChannel, component);
|
||||||
|
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
case TryStartStructureConstructionMessage tryStart:
|
||||||
|
TryStartStructureConstruction(tryStart.Location, tryStart.PrototypeName, tryStart.Angle, tryStart.Ack);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TryStartStructureConstruction(GridLocalCoordinates loc, string prototypeName, Angle angle, int ack)
|
||||||
|
{
|
||||||
|
var protoMan = IoCManager.Resolve<IPrototypeManager>();
|
||||||
|
var prototype = protoMan.Index<ConstructionPrototype>(prototypeName);
|
||||||
|
|
||||||
|
var transform = Owner.GetComponent<ITransformComponent>();
|
||||||
|
if (!loc.InRange(transform.LocalPosition, InteractionSystem.INTERACTION_RANGE))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prototype.Stages.Count < 2)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Prototype '{prototypeName}' does not have enough stages.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var stage0 = prototype.Stages[0];
|
||||||
|
if (!(stage0.Forward is ConstructionStepMaterial matStep))
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find the stack with the material in the user's hand.
|
||||||
|
var hands = Owner.GetComponent<HandsComponent>();
|
||||||
|
var activeHand = hands.GetActiveHand?.Owner;
|
||||||
|
if (activeHand == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!activeHand.TryGetComponent(out StackComponent stack) || !ConstructionComponent.MaterialStackValidFor(matStep, stack))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stack.Use(matStep.Amount))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// OK WE'RE GOOD CONSTRUCTION STARTED.
|
||||||
|
var entMgr = IoCManager.Resolve<IServerEntityManager>();
|
||||||
|
var AudioSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>();
|
||||||
|
AudioSystem.Play("/Audio/items/deconstruct.ogg", loc);
|
||||||
|
if (prototype.Stages.Count == 2)
|
||||||
|
{
|
||||||
|
// Exactly 2 stages, so don't make an intermediate frame.
|
||||||
|
var ent = entMgr.ForceSpawnEntityAt(prototype.Result, loc);
|
||||||
|
ent.GetComponent<ITransformComponent>().LocalRotation = angle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var frame = entMgr.ForceSpawnEntityAt("structureconstructionframe", loc);
|
||||||
|
var construction = frame.GetComponent<ConstructionComponent>();
|
||||||
|
construction.Init(prototype);
|
||||||
|
frame.GetComponent<ITransformComponent>().LocalRotation = angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
var msg = new AckStructureConstructionMessage(ack);
|
||||||
|
SendNetworkMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ using SS14.Server.Interfaces.Player;
|
|||||||
using SS14.Shared.ContentPack;
|
using SS14.Shared.ContentPack;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using SS14.Shared.Serialization;
|
using SS14.Shared.Serialization;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects
|
namespace Content.Server.GameObjects
|
||||||
{
|
{
|
||||||
@@ -159,8 +160,8 @@ namespace Content.Server.GameObjects
|
|||||||
item.RemovedFromSlot();
|
item.RemovedFromSlot();
|
||||||
|
|
||||||
// TODO: The item should be dropped to the container our owner is in, if any.
|
// TODO: The item should be dropped to the container our owner is in, if any.
|
||||||
var itemTransform = item.Owner.GetComponent<TransformComponent>();
|
var itemTransform = item.Owner.GetComponent<ITransformComponent>();
|
||||||
itemTransform.LocalPosition = Owner.GetComponent<TransformComponent>().LocalPosition;
|
itemTransform.LocalPosition = Owner.GetComponent<ITransformComponent>().LocalPosition;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using SS14.Server.Interfaces.Player;
|
|||||||
using SS14.Shared.GameObjects;
|
using SS14.Shared.GameObjects;
|
||||||
using SS14.Shared.Input;
|
using SS14.Shared.Input;
|
||||||
using SS14.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
using SS14.Shared.Interfaces.Network;
|
using SS14.Shared.Interfaces.Network;
|
||||||
using SS14.Shared.IoC;
|
using SS14.Shared.IoC;
|
||||||
using SS14.Shared.Serialization;
|
using SS14.Shared.Serialization;
|
||||||
@@ -162,8 +163,8 @@ namespace Content.Server.GameObjects
|
|||||||
item.RemovedFromSlot();
|
item.RemovedFromSlot();
|
||||||
|
|
||||||
// TODO: The item should be dropped to the container our owner is in, if any.
|
// TODO: The item should be dropped to the container our owner is in, if any.
|
||||||
var itemTransform = item.Owner.GetComponent<TransformComponent>();
|
var itemTransform = item.Owner.GetComponent<ITransformComponent>();
|
||||||
itemTransform.LocalPosition = Owner.GetComponent<TransformComponent>().LocalPosition;
|
itemTransform.LocalPosition = Owner.GetComponent<ITransformComponent>().LocalPosition;
|
||||||
Dirty();
|
Dirty();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,6 +85,17 @@ namespace Content.Server.GameObjects.Components.Interactable.Tools
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool TryUse(float value)
|
||||||
|
{
|
||||||
|
if (!Activated || !CanUse(value))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fuel -= value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public bool CanUse(float value)
|
public bool CanUse(float value)
|
||||||
{
|
{
|
||||||
return Fuel > value;
|
return Fuel > value;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using SS14.Server.Player;
|
|||||||
using SS14.Shared.Enums;
|
using SS14.Shared.Enums;
|
||||||
using SS14.Shared.GameObjects;
|
using SS14.Shared.GameObjects;
|
||||||
using SS14.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
using SS14.Shared.Interfaces.Network;
|
using SS14.Shared.Interfaces.Network;
|
||||||
using SS14.Shared.IoC;
|
using SS14.Shared.IoC;
|
||||||
using SS14.Shared.Log;
|
using SS14.Shared.Log;
|
||||||
@@ -214,8 +215,8 @@ namespace Content.Server.GameObjects
|
|||||||
var session = playerMan.GetSessionByChannel(netChannel);
|
var session = playerMan.GetSessionByChannel(netChannel);
|
||||||
var playerentity = session.AttachedEntity;
|
var playerentity = session.AttachedEntity;
|
||||||
|
|
||||||
var ourtransform = Owner.GetComponent<TransformComponent>();
|
var ourtransform = Owner.GetComponent<ITransformComponent>();
|
||||||
var playertransform = playerentity.GetComponent<TransformComponent>();
|
var playertransform = playerentity.GetComponent<ITransformComponent>();
|
||||||
|
|
||||||
if (playertransform.LocalPosition.InRange(ourtransform.LocalPosition, 2)
|
if (playertransform.LocalPosition.InRange(ourtransform.LocalPosition, 2)
|
||||||
&& (ourtransform.IsMapTransform || playertransform.ContainsEntity(ourtransform)))
|
&& (ourtransform.IsMapTransform || playertransform.ContainsEntity(ourtransform)))
|
||||||
@@ -233,7 +234,7 @@ namespace Content.Server.GameObjects
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
entity.GetComponent<TransformComponent>().WorldPosition = Owner.GetComponent<TransformComponent>().WorldPosition;
|
entity.GetComponent<ITransformComponent>().WorldPosition = ourtransform.WorldPosition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -67,8 +67,8 @@ namespace Content.Server.GameObjects.Components.Materials
|
|||||||
}
|
}
|
||||||
|
|
||||||
var refl = IoCManager.Resolve<IReflectionManager>();
|
var refl = IoCManager.Resolve<IReflectionManager>();
|
||||||
Value = serializer.ReadDataField("mat", "unobtanium");
|
Value = serializer.ReadDataField<string>("mat");
|
||||||
var key = serializer.ReadDataField("key", string.Empty);
|
var key = serializer.ReadDataField<string>("key");
|
||||||
if (refl.TryParseEnumReference(key, out var @enum))
|
if (refl.TryParseEnumReference(key, out var @enum))
|
||||||
{
|
{
|
||||||
Key = @enum;
|
Key = @enum;
|
||||||
@@ -78,4 +78,9 @@ namespace Content.Server.GameObjects.Components.Materials
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum MaterialKeys
|
||||||
|
{
|
||||||
|
Stack,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Content.Shared.GameObjects.Components.Power;
|
|||||||
using SS14.Server.Interfaces.GameObjects;
|
using SS14.Server.Interfaces.GameObjects;
|
||||||
using SS14.Shared.GameObjects;
|
using SS14.Shared.GameObjects;
|
||||||
using SS14.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
using SS14.Shared.Map;
|
using SS14.Shared.Map;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Power
|
namespace Content.Server.GameObjects.Components.Power
|
||||||
@@ -49,7 +50,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
builder.Append(" Providers:\n");
|
builder.Append(" Providers:\n");
|
||||||
foreach (var provider in device.AvailableProviders)
|
foreach (var provider in device.AvailableProviders)
|
||||||
{
|
{
|
||||||
var providerTransform = provider.Owner.GetComponent<IServerTransformComponent>();
|
var providerTransform = provider.Owner.GetComponent<ITransformComponent>();
|
||||||
builder.AppendFormat(" {0} ({1}) @ {2}", provider.Owner.Name, provider.Owner.Uid, providerTransform.LocalPosition);
|
builder.AppendFormat(" {0} ({1}) @ {2}", provider.Owner.Name, provider.Owner.Uid, providerTransform.LocalPosition);
|
||||||
if (device.Provider == provider)
|
if (device.Provider == provider)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using SS14.Server.GameObjects;
|
using SS14.Server.GameObjects;
|
||||||
using SS14.Shared.GameObjects;
|
using SS14.Shared.GameObjects;
|
||||||
using SS14.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
using SS14.Shared.IoC;
|
using SS14.Shared.IoC;
|
||||||
using SS14.Shared.Serialization;
|
using SS14.Shared.Serialization;
|
||||||
using SS14.Shared.Utility;
|
using SS14.Shared.Utility;
|
||||||
@@ -240,18 +241,18 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
//Get the starting value for our loop
|
//Get the starting value for our loop
|
||||||
var position = Owner.GetComponent<TransformComponent>().WorldPosition;
|
var position = Owner.GetComponent<ITransformComponent>().WorldPosition;
|
||||||
var bestprovider = AvailableProviders[0];
|
var bestprovider = AvailableProviders[0];
|
||||||
|
|
||||||
//If we are already connected to a power provider we need to do a loop to find the nearest one, otherwise skip it and use first entry
|
//If we are already connected to a power provider we need to do a loop to find the nearest one, otherwise skip it and use first entry
|
||||||
if (Connected == DrawTypes.Provider)
|
if (Connected == DrawTypes.Provider)
|
||||||
{
|
{
|
||||||
var bestdistance = (bestprovider.Owner.GetComponent<TransformComponent>().WorldPosition - position).LengthSquared;
|
var bestdistance = (bestprovider.Owner.GetComponent<ITransformComponent>().WorldPosition - position).LengthSquared;
|
||||||
|
|
||||||
foreach (var availprovider in AvailableProviders)
|
foreach (var availprovider in AvailableProviders)
|
||||||
{
|
{
|
||||||
//Find distance to new provider
|
//Find distance to new provider
|
||||||
var distance = (availprovider.Owner.GetComponent<TransformComponent>().WorldPosition - position).LengthSquared;
|
var distance = (availprovider.Owner.GetComponent<ITransformComponent>().WorldPosition - position).LengthSquared;
|
||||||
|
|
||||||
//If new provider distance is shorter it becomes new best possible provider
|
//If new provider distance is shorter it becomes new best possible provider
|
||||||
if (distance < bestdistance)
|
if (distance < bestdistance)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using SS14.Server.GameObjects;
|
using SS14.Server.GameObjects;
|
||||||
using SS14.Server.Interfaces.GameObjects;
|
using SS14.Server.Interfaces.GameObjects;
|
||||||
using SS14.Shared.GameObjects;
|
using SS14.Shared.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
using SS14.Shared.IoC;
|
using SS14.Shared.IoC;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -56,10 +57,10 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var _emanager = IoCManager.Resolve<IServerEntityManager>();
|
var _emanager = IoCManager.Resolve<IServerEntityManager>();
|
||||||
var position = Owner.GetComponent<TransformComponent>().WorldPosition;
|
var position = Owner.GetComponent<ITransformComponent>().WorldPosition;
|
||||||
var wires = _emanager.GetEntitiesIntersecting(Owner)
|
var wires = _emanager.GetEntitiesIntersecting(Owner)
|
||||||
.Where(x => x.HasComponent<PowerTransferComponent>())
|
.Where(x => x.HasComponent<PowerTransferComponent>())
|
||||||
.OrderByDescending(x => (x.GetComponent<TransformComponent>().WorldPosition - position).Length);
|
.OrderByDescending(x => (x.GetComponent<ITransformComponent>().WorldPosition - position).Length);
|
||||||
var choose = wires.FirstOrDefault();
|
var choose = wires.FirstOrDefault();
|
||||||
if (choose != null)
|
if (choose != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using SS14.Server.GameObjects;
|
using SS14.Server.GameObjects;
|
||||||
using SS14.Server.Interfaces.GameObjects;
|
using SS14.Server.Interfaces.GameObjects;
|
||||||
using SS14.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
using SS14.Shared.IoC;
|
using SS14.Shared.IoC;
|
||||||
using SS14.Shared.Log;
|
using SS14.Shared.Log;
|
||||||
using SS14.Shared.Serialization;
|
using SS14.Shared.Serialization;
|
||||||
@@ -139,7 +140,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
|
|
||||||
//Find devices within range to take under our control
|
//Find devices within range to take under our control
|
||||||
var _emanager = IoCManager.Resolve<IServerEntityManager>();
|
var _emanager = IoCManager.Resolve<IServerEntityManager>();
|
||||||
var position = Owner.GetComponent<TransformComponent>().WorldPosition;
|
var position = Owner.GetComponent<ITransformComponent>().WorldPosition;
|
||||||
var entities = _emanager.GetEntitiesInRange(Owner, PowerRange)
|
var entities = _emanager.GetEntitiesInRange(Owner, PowerRange)
|
||||||
.Where(x => x.HasComponent<PowerDeviceComponent>());
|
.Where(x => x.HasComponent<PowerDeviceComponent>());
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using SS14.Shared.IoC;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using SS14.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
using Content.Server.GameObjects.Components.Interactable.Tools;
|
using Content.Server.GameObjects.Components.Interactable.Tools;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Power
|
namespace Content.Server.GameObjects.Components.Power
|
||||||
{
|
{
|
||||||
@@ -44,7 +45,7 @@ namespace Content.Server.GameObjects.Components.Power
|
|||||||
public void SpreadPowernet()
|
public void SpreadPowernet()
|
||||||
{
|
{
|
||||||
var _emanager = IoCManager.Resolve<IServerEntityManager>();
|
var _emanager = IoCManager.Resolve<IServerEntityManager>();
|
||||||
var position = Owner.GetComponent<TransformComponent>().WorldPosition;
|
var position = Owner.GetComponent<ITransformComponent>().WorldPosition;
|
||||||
var wires = _emanager.GetEntitiesInRange(Owner, 1.1f) //arbitrarily low, just scrape things //wip
|
var wires = _emanager.GetEntitiesInRange(Owner, 1.1f) //arbitrarily low, just scrape things //wip
|
||||||
.Where(x => x.HasComponent<PowerTransferComponent>());
|
.Where(x => x.HasComponent<PowerTransferComponent>());
|
||||||
|
|
||||||
|
|||||||
122
Content.Server/GameObjects/Components/Stack/StackComponent.cs
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
using System;
|
||||||
|
using Content.Server.GameObjects.EntitySystems;
|
||||||
|
using SS14.Shared.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.Reflection;
|
||||||
|
using SS14.Shared.IoC;
|
||||||
|
using SS14.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Server.GameObjects.Components.Stack
|
||||||
|
{
|
||||||
|
// TODO: Naming and presentation and such could use some improvement.
|
||||||
|
public class StackComponent : Component, IAttackby, IExamine
|
||||||
|
{
|
||||||
|
private const string SerializationCache = "stack";
|
||||||
|
private int _count = 50;
|
||||||
|
private int _maxCount = 50;
|
||||||
|
|
||||||
|
public override string Name => "Stack";
|
||||||
|
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get => _count;
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
_count = value;
|
||||||
|
if (_count <= 0)
|
||||||
|
{
|
||||||
|
Owner.Delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int MaxCount { get => _maxCount; private set => _maxCount = value; }
|
||||||
|
public int AvailableSpace => MaxCount - Count;
|
||||||
|
|
||||||
|
public object StackType { get; private set; }
|
||||||
|
|
||||||
|
public void Add(int amount)
|
||||||
|
{
|
||||||
|
Count += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Try to use an amount of items on this stack.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="amount"></param>
|
||||||
|
/// <returns>True if there were enough items to remove, false if not in which case nothing was changed.</returns>
|
||||||
|
public bool Use(int amount)
|
||||||
|
{
|
||||||
|
if (Count >= amount)
|
||||||
|
{
|
||||||
|
Count -= amount;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ExposeData(ObjectSerializer serializer)
|
||||||
|
{
|
||||||
|
serializer.DataFieldCached(ref _maxCount, "max", 50);
|
||||||
|
serializer.DataFieldCached(ref _count, "count", MaxCount);
|
||||||
|
|
||||||
|
if (!serializer.Reading)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serializer.TryGetCacheData(SerializationCache, out object stackType))
|
||||||
|
{
|
||||||
|
StackType = stackType;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serializer.TryReadDataFieldCached("stacktype", out string raw))
|
||||||
|
{
|
||||||
|
var refl = IoCManager.Resolve<IReflectionManager>();
|
||||||
|
if (refl.TryParseEnumReference(raw, out var @enum))
|
||||||
|
{
|
||||||
|
stackType = @enum;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stackType = raw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stackType = Owner.Prototype.ID;
|
||||||
|
}
|
||||||
|
serializer.SetCacheData(SerializationCache, stackType);
|
||||||
|
StackType = stackType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Attackby(IEntity user, IEntity attackwith)
|
||||||
|
{
|
||||||
|
if (attackwith.TryGetComponent<StackComponent>(out var stack))
|
||||||
|
{
|
||||||
|
if (!stack.StackType.Equals(StackType))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var toTransfer = Math.Min(Count, stack.AvailableSpace);
|
||||||
|
Count -= toTransfer;
|
||||||
|
stack.Add(toTransfer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Examine()
|
||||||
|
{
|
||||||
|
return $"There are {Count} things in the stack.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum StackType
|
||||||
|
{
|
||||||
|
Metal,
|
||||||
|
Glass,
|
||||||
|
Cable,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ using SS14.Server.Interfaces.GameObjects;
|
|||||||
using SS14.Shared.Interfaces.Timing;
|
using SS14.Shared.Interfaces.Timing;
|
||||||
using SS14.Shared.GameObjects.EntitySystemMessages;
|
using SS14.Shared.GameObjects.EntitySystemMessages;
|
||||||
using SS14.Shared.Serialization;
|
using SS14.Shared.Serialization;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.Components.Weapon.Melee
|
namespace Content.Server.GameObjects.Components.Weapon.Melee
|
||||||
{
|
{
|
||||||
@@ -32,13 +33,13 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee
|
|||||||
|
|
||||||
void IAfterAttack.Afterattack(IEntity user, GridLocalCoordinates clicklocation, IEntity attacked)
|
void IAfterAttack.Afterattack(IEntity user, GridLocalCoordinates clicklocation, IEntity attacked)
|
||||||
{
|
{
|
||||||
var location = user.GetComponent<TransformComponent>().LocalPosition;
|
var location = user.GetComponent<ITransformComponent>().LocalPosition;
|
||||||
var angle = new Angle(clicklocation.ToWorld().Position - location.ToWorld().Position);
|
var angle = new Angle(clicklocation.ToWorld().Position - location.ToWorld().Position);
|
||||||
var entities = IoCManager.Resolve<IServerEntityManager>().GetEntitiesInArc(user.GetComponent<TransformComponent>().LocalPosition, Range, angle, ArcWidth);
|
var entities = IoCManager.Resolve<IServerEntityManager>().GetEntitiesInArc(user.GetComponent<ITransformComponent>().LocalPosition, Range, angle, ArcWidth);
|
||||||
|
|
||||||
foreach (var entity in entities)
|
foreach (var entity in entities)
|
||||||
{
|
{
|
||||||
if (!entity.GetComponent<TransformComponent>().IsMapTransform || entity == user)
|
if (!entity.GetComponent<ITransformComponent>().IsMapTransform || entity == user)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (entity.TryGetComponent(out DamageableComponent damagecomponent))
|
if (entity.TryGetComponent(out DamageableComponent damagecomponent))
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using SS14.Shared.Audio;
|
|||||||
using SS14.Shared.GameObjects;
|
using SS14.Shared.GameObjects;
|
||||||
using SS14.Shared.GameObjects.EntitySystemMessages;
|
using SS14.Shared.GameObjects.EntitySystemMessages;
|
||||||
using SS14.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
using SS14.Shared.Interfaces.Physics;
|
using SS14.Shared.Interfaces.Physics;
|
||||||
using SS14.Shared.Interfaces.Timing;
|
using SS14.Shared.Interfaces.Timing;
|
||||||
using SS14.Shared.IoC;
|
using SS14.Shared.IoC;
|
||||||
@@ -22,11 +23,11 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan
|
|||||||
|
|
||||||
protected override void Fire(IEntity user, GridLocalCoordinates clicklocation)
|
protected override void Fire(IEntity user, GridLocalCoordinates clicklocation)
|
||||||
{
|
{
|
||||||
var userposition = user.GetComponent<TransformComponent>().WorldPosition; //Remember world positions are ephemeral and can only be used instantaneously
|
var userposition = user.GetComponent<ITransformComponent>().WorldPosition; //Remember world positions are ephemeral and can only be used instantaneously
|
||||||
var angle = new Angle(clicklocation.Position - userposition);
|
var angle = new Angle(clicklocation.Position - userposition);
|
||||||
|
|
||||||
var ray = new Ray(userposition, angle.ToVec());
|
var ray = new Ray(userposition, angle.ToVec());
|
||||||
var raycastresults = IoCManager.Resolve<ICollisionManager>().IntersectRay(ray, 20, Owner.GetComponent<TransformComponent>().GetMapTransform().Owner);
|
var raycastresults = IoCManager.Resolve<ICollisionManager>().IntersectRay(ray, 20, Owner.GetComponent<ITransformComponent>().GetMapTransform().Owner);
|
||||||
|
|
||||||
Hit(raycastresults);
|
Hit(raycastresults);
|
||||||
AfterEffects(user, raycastresults, angle);
|
AfterEffects(user, raycastresults, angle);
|
||||||
@@ -51,7 +52,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan
|
|||||||
Born = time,
|
Born = time,
|
||||||
DeathTime = time + TimeSpan.FromSeconds(1),
|
DeathTime = time + TimeSpan.FromSeconds(1),
|
||||||
Size = new Vector2(ray.Distance, 1f),
|
Size = new Vector2(ray.Distance, 1f),
|
||||||
Coordinates = user.GetComponent<TransformComponent>().LocalPosition.Translated(offset),
|
Coordinates = user.GetComponent<ITransformComponent>().LocalPosition.Translated(offset),
|
||||||
//Rotated from east facing
|
//Rotated from east facing
|
||||||
Rotation = (float)angle.Theta,
|
Rotation = (float)angle.Theta,
|
||||||
ColorDelta = new Vector4(0, 0, 0, -1500f),
|
ColorDelta = new Vector4(0, 0, 0, -1500f),
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using SS14.Server.GameObjects;
|
|||||||
using SS14.Server.GameObjects.EntitySystems;
|
using SS14.Server.GameObjects.EntitySystems;
|
||||||
using SS14.Server.Interfaces.GameObjects;
|
using SS14.Server.Interfaces.GameObjects;
|
||||||
using SS14.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
using SS14.Shared.IoC;
|
using SS14.Shared.IoC;
|
||||||
using SS14.Shared.Map;
|
using SS14.Shared.Map;
|
||||||
using SS14.Shared.Maths;
|
using SS14.Shared.Maths;
|
||||||
@@ -19,7 +20,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
|
|||||||
|
|
||||||
protected override void Fire(IEntity user, GridLocalCoordinates clicklocation)
|
protected override void Fire(IEntity user, GridLocalCoordinates clicklocation)
|
||||||
{
|
{
|
||||||
var userposition = user.GetComponent<TransformComponent>().LocalPosition; //Remember world positions are ephemeral and can only be used instantaneously
|
var userposition = user.GetComponent<ITransformComponent>().LocalPosition; //Remember world positions are ephemeral and can only be used instantaneously
|
||||||
var angle = new Angle(clicklocation.Position - userposition.Position);
|
var angle = new Angle(clicklocation.Position - userposition.Position);
|
||||||
|
|
||||||
var theta = angle.Theta;
|
var theta = angle.Theta;
|
||||||
@@ -34,7 +35,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
|
|||||||
projectile.GetComponent<PhysicsComponent>().LinearVelocity = angle.ToVec() * _velocity;
|
projectile.GetComponent<PhysicsComponent>().LinearVelocity = angle.ToVec() * _velocity;
|
||||||
|
|
||||||
//Rotate the bullets sprite to the correct direction, from north facing I guess
|
//Rotate the bullets sprite to the correct direction, from north facing I guess
|
||||||
projectile.GetComponent<TransformComponent>().LocalRotation = angle.Theta;
|
projectile.GetComponent<ITransformComponent>().LocalRotation = angle.Theta;
|
||||||
|
|
||||||
// Sound!
|
// Sound!
|
||||||
IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>().Play("/Audio/gunshot_c20.ogg");
|
IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>().Play("/Audio/gunshot_c20.ogg");
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using SS14.Server.Interfaces.Player;
|
using SS14.Server.Interfaces.Player;
|
||||||
using SS14.Shared.GameObjects;
|
using SS14.Shared.GameObjects;
|
||||||
using SS14.Shared.GameObjects.System;
|
using SS14.Shared.GameObjects.Systems;
|
||||||
using SS14.Shared.Input;
|
using SS14.Shared.Input;
|
||||||
using SS14.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
using SS14.Shared.Interfaces.Network;
|
using SS14.Shared.Interfaces.Network;
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
using SS14.Server.Interfaces.Chat;
|
using SS14.Server.Interfaces.Chat;
|
||||||
using SS14.Server.Interfaces.GameObjects;
|
using SS14.Server.Interfaces.GameObjects;
|
||||||
using SS14.Shared.GameObjects;
|
using SS14.Shared.GameObjects;
|
||||||
using SS14.Shared.GameObjects.System;
|
using SS14.Shared.GameObjects.Systems;
|
||||||
using SS14.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
using SS14.Shared.IoC;
|
using SS14.Shared.IoC;
|
||||||
using SS14.Shared.Log;
|
using SS14.Shared.Log;
|
||||||
using System;
|
using System;
|
||||||
@@ -33,7 +34,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
//Verify player has a transform component
|
//Verify player has a transform component
|
||||||
if (!player.TryGetComponent<IServerTransformComponent>(out var playerTransform))
|
if (!player.TryGetComponent<ITransformComponent>(out var playerTransform))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using Content.Server.Interfaces.GameObjects;
|
using Content.Server.Interfaces.GameObjects;
|
||||||
using SS14.Server.Interfaces.GameObjects;
|
using SS14.Server.Interfaces.GameObjects;
|
||||||
using SS14.Shared.GameObjects;
|
using SS14.Shared.GameObjects;
|
||||||
using SS14.Shared.GameObjects.System;
|
using SS14.Shared.GameObjects.Systems;
|
||||||
using SS14.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -9,6 +9,8 @@ using SS14.Shared.Input;
|
|||||||
using SS14.Shared.Log;
|
using SS14.Shared.Log;
|
||||||
using SS14.Shared.Map;
|
using SS14.Shared.Map;
|
||||||
using SS14.Server.GameObjects;
|
using SS14.Server.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
|
using SS14.Shared.GameObjects.Components.BoundingBox;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.EntitySystems
|
namespace Content.Server.GameObjects.EntitySystems
|
||||||
{
|
{
|
||||||
@@ -87,8 +89,8 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class InteractionSystem : EntitySystem
|
public class InteractionSystem : EntitySystem
|
||||||
{
|
{
|
||||||
private const float INTERACTION_RANGE = 2;
|
public const float INTERACTION_RANGE = 2;
|
||||||
private const float INTERACTION_RANGE_SQUARED = INTERACTION_RANGE * INTERACTION_RANGE;
|
public const float INTERACTION_RANGE_SQUARED = INTERACTION_RANGE * INTERACTION_RANGE;
|
||||||
|
|
||||||
public void UserInteraction(ClickEventMessage msg, IEntity player)
|
public void UserInteraction(ClickEventMessage msg, IEntity player)
|
||||||
{
|
{
|
||||||
@@ -98,7 +100,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
attacked = EntityManager.GetEntity(msg.Uid);
|
attacked = EntityManager.GetEntity(msg.Uid);
|
||||||
|
|
||||||
//Verify player has a transform component
|
//Verify player has a transform component
|
||||||
if (!player.TryGetComponent<IServerTransformComponent>(out var playerTransform))
|
if (!player.TryGetComponent<ITransformComponent>(out var playerTransform))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -136,7 +138,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Verify attacked object is on the map if we managed to click on it somehow
|
//Verify attacked object is on the map if we managed to click on it somehow
|
||||||
if (!attacked.GetComponent<TransformComponent>().IsMapTransform)
|
if (!attacked.GetComponent<ITransformComponent>().IsMapTransform)
|
||||||
{
|
{
|
||||||
Logger.Warning(string.Format("Player named {0} clicked on object {1} that isn't currently on the map somehow", player.Name, attacked.Name));
|
Logger.Warning(string.Format("Player named {0} clicked on object {1} that isn't currently on the map somehow", player.Name, attacked.Name));
|
||||||
return;
|
return;
|
||||||
@@ -154,7 +156,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
|
|
||||||
//RANGEDATTACK/AFTERATTACK: Check distance between user and clicked item, if too large parse it in the ranged function
|
//RANGEDATTACK/AFTERATTACK: Check distance between user and clicked item, if too large parse it in the ranged function
|
||||||
//TODO: have range based upon the item being used? or base it upon some variables of the player himself?
|
//TODO: have range based upon the item being used? or base it upon some variables of the player himself?
|
||||||
var distance = (playerTransform.WorldPosition - attacked.GetComponent<IServerTransformComponent>().WorldPosition).LengthSquared;
|
var distance = (playerTransform.WorldPosition - attacked.GetComponent<ITransformComponent>().WorldPosition).LengthSquared;
|
||||||
if (distance > INTERACTION_RANGE_SQUARED)
|
if (distance > INTERACTION_RANGE_SQUARED)
|
||||||
{
|
{
|
||||||
if (item != null)
|
if (item != null)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using SS14.Shared.GameObjects;
|
using SS14.Shared.GameObjects;
|
||||||
using SS14.Shared.GameObjects.System;
|
using SS14.Shared.GameObjects.Systems;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.EntitySystems
|
namespace Content.Server.GameObjects.EntitySystems
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Content.Server.GameObjects.Components.Power;
|
using Content.Server.GameObjects.Components.Power;
|
||||||
using SS14.Shared.GameObjects;
|
using SS14.Shared.GameObjects;
|
||||||
using SS14.Shared.GameObjects.System;
|
using SS14.Shared.GameObjects.Systems;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.EntitySystems
|
namespace Content.Server.GameObjects.EntitySystems
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Content.Server.GameObjects.Components.Power;
|
using Content.Server.GameObjects.Components.Power;
|
||||||
using SS14.Shared.GameObjects;
|
using SS14.Shared.GameObjects;
|
||||||
using SS14.Shared.GameObjects.System;
|
using SS14.Shared.GameObjects.Systems;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.EntitySystems
|
namespace Content.Server.GameObjects.EntitySystems
|
||||||
{
|
{
|
||||||
@@ -10,7 +10,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
{
|
{
|
||||||
EntityQuery = new TypeEntityQuery(typeof(SmesComponent));
|
EntityQuery = new TypeEntityQuery(typeof(SmesComponent));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float frameTime)
|
public override void Update(float frameTime)
|
||||||
{
|
{
|
||||||
foreach (var entity in RelevantEntities)
|
foreach (var entity in RelevantEntities)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using Content.Server.GameObjects.Components.Power;
|
using Content.Server.GameObjects.Components.Power;
|
||||||
using SS14.Shared.GameObjects.System;
|
using SS14.Shared.GameObjects.Systems;
|
||||||
using SS14.Shared.Interfaces.GameObjects;
|
using SS14.Shared.Interfaces.GameObjects;
|
||||||
using SS14.Shared.IoC;
|
using SS14.Shared.IoC;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Content.Server.GameObjects.Components.Interactable.Tools;
|
using Content.Server.GameObjects.Components.Interactable.Tools;
|
||||||
using SS14.Shared.GameObjects;
|
using SS14.Shared.GameObjects;
|
||||||
using SS14.Shared.GameObjects.System;
|
using SS14.Shared.GameObjects.Systems;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects.EntitySystems
|
namespace Content.Server.GameObjects.EntitySystems
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using SS14.Shared.GameObjects;
|
using SS14.Shared.GameObjects;
|
||||||
using SS14.Shared.GameObjects.System;
|
using SS14.Shared.GameObjects.Systems;
|
||||||
|
|
||||||
namespace Content.Server.GameObjects
|
namespace Content.Server.GameObjects
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using SS14.Server.Interfaces.GameObjects;
|
using SS14.Server.Interfaces.GameObjects;
|
||||||
|
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||||
using SS14.Shared.Interfaces.Map;
|
using SS14.Shared.Interfaces.Map;
|
||||||
using SS14.Shared.IoC;
|
using SS14.Shared.IoC;
|
||||||
using SS14.Shared.Map;
|
using SS14.Shared.Map;
|
||||||
@@ -20,11 +21,12 @@ namespace Content.Server.Placement
|
|||||||
{
|
{
|
||||||
var entMan = IoCManager.Resolve<IServerEntityManager>();
|
var entMan = IoCManager.Resolve<IServerEntityManager>();
|
||||||
var tBase = entMan.SpawnEntity("TurretBase");
|
var tBase = entMan.SpawnEntity("TurretBase");
|
||||||
tBase.GetComponent<IServerTransformComponent>().LocalPosition = new GridLocalCoordinates(localPosition, grid);
|
tBase.GetComponent<ITransformComponent>().LocalPosition = new GridLocalCoordinates(localPosition, grid);
|
||||||
|
|
||||||
var tTop = entMan.SpawnEntity("TurretTopLight");
|
var tTop = entMan.SpawnEntity("TurretTopLight");
|
||||||
tTop.GetComponent<IServerTransformComponent>().LocalPosition = new GridLocalCoordinates(localPosition, grid);
|
var topTransform = tTop.GetComponent<ITransformComponent>();
|
||||||
tTop.GetComponent<IServerTransformComponent>().AttachParent(tBase);
|
topTransform.LocalPosition = new GridLocalCoordinates(localPosition, grid);
|
||||||
|
topTransform.AttachParent(tBase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
221
Content.Shared/Construction/ConstructionPrototype.cs
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using SS14.Shared.Prototypes;
|
||||||
|
using SS14.Shared.Serialization;
|
||||||
|
using SS14.Shared.Utility;
|
||||||
|
using YamlDotNet.RepresentationModel;
|
||||||
|
|
||||||
|
namespace Content.Shared.Construction
|
||||||
|
{
|
||||||
|
[Prototype("construction")]
|
||||||
|
public class ConstructionPrototype : IPrototype, IIndexedPrototype
|
||||||
|
{
|
||||||
|
private string _name;
|
||||||
|
private string _description;
|
||||||
|
private SpriteSpecifier _icon;
|
||||||
|
private List<string> _keywords;
|
||||||
|
private List<string> _categorySegments;
|
||||||
|
private List<ConstructionStage> _stages = new List<ConstructionStage>();
|
||||||
|
private ConstructionType _type;
|
||||||
|
private string _id;
|
||||||
|
private string _result;
|
||||||
|
private string _placementMode;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Friendly name displayed in the construction GUI.
|
||||||
|
/// </summary>
|
||||||
|
public string Name => _name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Useful" description displayed in the construction GUI.
|
||||||
|
/// </summary>
|
||||||
|
public string Description => _description;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Texture path inside the construction GUI.
|
||||||
|
/// </summary>
|
||||||
|
public SpriteSpecifier Icon => _icon;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A list of keywords that are used for searching.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<string> Keywords => _keywords;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The split up segments of the category.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<string> CategorySegments => _categorySegments;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The list of stages of construction.
|
||||||
|
/// Construction is separated into "stages" which is basically a state in a linear FSM.
|
||||||
|
/// The stage has forward and optionally backwards "steps" which are the criteria to move around in the FSM.
|
||||||
|
/// NOTE that the stages are mapped differently than they appear in the prototype.
|
||||||
|
/// In the prototype, the forward step is displayed as "to move into this stage" and reverse "to move out of"
|
||||||
|
/// Stage 0 is considered "construction not started" and last stage is considered "construction is finished".
|
||||||
|
/// As such, neither last or 0 stage have actual stage DATA, only backward/forward steps respectively.
|
||||||
|
/// This would be akward for a YAML prototype because it's always jagged.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<ConstructionStage> Stages => _stages;
|
||||||
|
|
||||||
|
public ConstructionType Type => _type;
|
||||||
|
|
||||||
|
public string ID => _id;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The prototype name of the entity prototype when construction is done.
|
||||||
|
/// </summary>
|
||||||
|
public string Result => _result;
|
||||||
|
|
||||||
|
public string PlacementMode => _placementMode;
|
||||||
|
|
||||||
|
public void LoadFrom(YamlMappingNode mapping)
|
||||||
|
{
|
||||||
|
var ser = YamlObjectSerializer.NewReader(mapping);
|
||||||
|
_name = ser.ReadDataField<string>("name");
|
||||||
|
|
||||||
|
ser.DataField(ref _id, "id", string.Empty);
|
||||||
|
ser.DataField(ref _description, "description", string.Empty);
|
||||||
|
ser.DataField(ref _icon, "icon", SpriteSpecifier.Invalid);
|
||||||
|
ser.DataField(ref _type, "objecttype", ConstructionType.Structure);
|
||||||
|
ser.DataField(ref _result, "result", null);
|
||||||
|
ser.DataField(ref _placementMode, "placementmode", "PlaceFree");
|
||||||
|
|
||||||
|
_keywords = ser.ReadDataField<List<string>>("keywords", new List<string>());
|
||||||
|
{
|
||||||
|
var cat = ser.ReadDataField<string>("category");
|
||||||
|
var split = cat.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
_categorySegments = split.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
SpriteSpecifier nextIcon = null;
|
||||||
|
ConstructionStep nextBackward = null;
|
||||||
|
|
||||||
|
foreach (var stepMap in mapping.GetNode<YamlSequenceNode>("steps").Cast<YamlMappingNode>())
|
||||||
|
{
|
||||||
|
var step = ReadStepPrototype(stepMap);
|
||||||
|
_stages.Add(new ConstructionStage(step, nextIcon, nextBackward));
|
||||||
|
if (stepMap.TryGetNode("icon", out var node))
|
||||||
|
{
|
||||||
|
nextIcon = SpriteSpecifier.FromYaml(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stepMap.TryGetNode("reverse", out YamlMappingNode revMap))
|
||||||
|
{
|
||||||
|
nextBackward = ReadStepPrototype(revMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_stages.Add(new ConstructionStage(null, nextIcon, nextBackward));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstructionStep ReadStepPrototype(YamlMappingNode step)
|
||||||
|
{
|
||||||
|
int amount = 1;
|
||||||
|
|
||||||
|
if (step.TryGetNode("amount", out var node))
|
||||||
|
{
|
||||||
|
amount = node.AsInt();
|
||||||
|
}
|
||||||
|
if (step.TryGetNode("material", out node))
|
||||||
|
{
|
||||||
|
return new ConstructionStepMaterial(
|
||||||
|
node.AsEnum<ConstructionStepMaterial.MaterialType>(),
|
||||||
|
amount
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (step.TryGetNode("tool", out node))
|
||||||
|
{
|
||||||
|
return new ConstructionStepTool(
|
||||||
|
node.AsEnum<ConstructionStepTool.ToolType>(),
|
||||||
|
amount
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InvalidOperationException("Not enough data specified to determine step.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class ConstructionStage
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The icon of the construction frame at this stage.
|
||||||
|
/// </summary>
|
||||||
|
public readonly SpriteSpecifier Icon;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The step that should be completed to move away from this stage to the next one.
|
||||||
|
/// </summary>
|
||||||
|
public readonly ConstructionStep Forward;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The optional step that can be completed to move away from this stage to the previous one.
|
||||||
|
/// </summary>
|
||||||
|
public readonly ConstructionStep Backward;
|
||||||
|
|
||||||
|
public ConstructionStage(ConstructionStep forward, SpriteSpecifier icon = null, ConstructionStep backward = null)
|
||||||
|
{
|
||||||
|
Icon = icon;
|
||||||
|
Forward = forward;
|
||||||
|
Backward = backward;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ConstructionType
|
||||||
|
{
|
||||||
|
Structure,
|
||||||
|
Item,
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class ConstructionStep
|
||||||
|
{
|
||||||
|
public readonly int Amount = 1;
|
||||||
|
|
||||||
|
protected ConstructionStep(int amount)
|
||||||
|
{
|
||||||
|
Amount = amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ConstructionStepTool : ConstructionStep
|
||||||
|
{
|
||||||
|
public readonly ToolType Tool;
|
||||||
|
|
||||||
|
public ConstructionStepTool(ToolType tool, int amount) : base(amount)
|
||||||
|
{
|
||||||
|
Tool = tool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ToolType
|
||||||
|
{
|
||||||
|
Wrench,
|
||||||
|
Welder,
|
||||||
|
Screwdriver,
|
||||||
|
Crowbar,
|
||||||
|
Wirecutters,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ConstructionStepMaterial : ConstructionStep
|
||||||
|
{
|
||||||
|
public readonly MaterialType Material;
|
||||||
|
|
||||||
|
public ConstructionStepMaterial(MaterialType material, int amount) : base(amount)
|
||||||
|
{
|
||||||
|
Material = material;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public enum MaterialType
|
||||||
|
{
|
||||||
|
Metal,
|
||||||
|
Glass,
|
||||||
|
Cable,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -58,6 +58,9 @@
|
|||||||
<Reference Include="YamlDotNet, Version=4.3.1.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="YamlDotNet, Version=4.3.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>$(SolutionDir)packages\YamlDotNet.4.3.1\lib\net45\YamlDotNet.dll</HintPath>
|
<HintPath>$(SolutionDir)packages\YamlDotNet.4.3.1\lib\net45\YamlDotNet.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="System.ValueTuple">
|
||||||
|
<HintPath>$(SolutionDir)packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="EntryPoint.cs" />
|
<Compile Include="EntryPoint.cs" />
|
||||||
@@ -101,6 +104,8 @@
|
|||||||
<Compile Include="Utility\ContentHelpers.cs" />
|
<Compile Include="Utility\ContentHelpers.cs" />
|
||||||
<Compile Include="GameObjects\Components\Power\SharedSmesComponent.cs" />
|
<Compile Include="GameObjects\Components\Power\SharedSmesComponent.cs" />
|
||||||
<Compile Include="GameObjects\Components\Power\SharedApcComponent.cs" />
|
<Compile Include="GameObjects\Components\Power\SharedApcComponent.cs" />
|
||||||
|
<Compile Include="GameObjects\Components\Construction\SharedConstructorComponent.cs" />
|
||||||
|
<Compile Include="Construction\ConstructionPrototype.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
using System;
|
||||||
|
using SS14.Shared.GameObjects;
|
||||||
|
using SS14.Shared.Map;
|
||||||
|
using SS14.Shared.Maths;
|
||||||
|
using SS14.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.GameObjects.Components.Construction
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Basically handles the logic of "this mob can do construction".
|
||||||
|
/// </summary>
|
||||||
|
public abstract class SharedConstructorComponent : Component
|
||||||
|
{
|
||||||
|
public override string Name => "Constructor";
|
||||||
|
public override uint? NetID => ContentNetIDs.CONSTRUCTOR;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sent client -> server to to tell the server that we started building
|
||||||
|
/// a structure-construction.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
protected class TryStartStructureConstructionMessage : ComponentMessage
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Position to start building.
|
||||||
|
/// </summary>
|
||||||
|
public readonly GridLocalCoordinates Location;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The construction prototype to start building.
|
||||||
|
/// </summary>
|
||||||
|
public readonly string PrototypeName;
|
||||||
|
|
||||||
|
public readonly Angle Angle;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Identifier to be sent back in the acknowledgement so that the client can clean up its ghost.
|
||||||
|
/// </summary>
|
||||||
|
public readonly int Ack;
|
||||||
|
|
||||||
|
public TryStartStructureConstructionMessage(GridLocalCoordinates loc, string prototypeName, Angle angle, int ack)
|
||||||
|
{
|
||||||
|
Directed = true;
|
||||||
|
Location = loc;
|
||||||
|
PrototypeName = prototypeName;
|
||||||
|
Angle = angle;
|
||||||
|
Ack = ack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
protected class AckStructureConstructionMessage : ComponentMessage
|
||||||
|
{
|
||||||
|
public readonly int Ack;
|
||||||
|
|
||||||
|
public AckStructureConstructionMessage(int ack)
|
||||||
|
{
|
||||||
|
Directed = true;
|
||||||
|
Ack = ack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,5 +10,6 @@
|
|||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
Resources/Audio/items/crowbar.ogg
Normal file
BIN
Resources/Audio/items/deconstruct.ogg
Normal file
BIN
Resources/Audio/items/ratchet.ogg
Normal file
BIN
Resources/Audio/items/screwdriver.ogg
Normal file
BIN
Resources/Audio/items/screwdriver2.ogg
Normal file
BIN
Resources/Audio/items/welder.ogg
Normal file
BIN
Resources/Audio/items/welder2.ogg
Normal file
BIN
Resources/Audio/items/wirecutter.ogg
Normal file
BIN
Resources/Audio/items/zip.ogg
Normal file
27
Resources/Prototypes/Construction/machines.yml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
- type: construction
|
||||||
|
name: Wall Light
|
||||||
|
id: wall_light
|
||||||
|
keywords: [fixture, lamp]
|
||||||
|
category: Machines
|
||||||
|
description: A simple wall-mounted light fixture.
|
||||||
|
placementmode: SnapgridBorder
|
||||||
|
icon:
|
||||||
|
sprite: Objects/lighting.rsi
|
||||||
|
state: on
|
||||||
|
|
||||||
|
result: poweredlight
|
||||||
|
steps:
|
||||||
|
- material: Metal
|
||||||
|
amount: 1
|
||||||
|
icon:
|
||||||
|
sprite: Objects/lighting.rsi
|
||||||
|
state: construct
|
||||||
|
|
||||||
|
- material: Cable
|
||||||
|
amount: 1
|
||||||
|
icon:
|
||||||
|
sprite: Objects/lighting.rsi
|
||||||
|
state: empty
|
||||||
|
|
||||||
|
- material: Glass
|
||||||
|
amount: 1
|
||||||
57
Resources/Prototypes/Construction/power.yml
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
- type: construction
|
||||||
|
name: SMES
|
||||||
|
id: smes
|
||||||
|
category: Machines/Power
|
||||||
|
keywords: [battery, cell, storage]
|
||||||
|
placementmode: SnapgridCenter
|
||||||
|
description: A SMES is a large battery capable of connecting directly to a power grid.
|
||||||
|
icon:
|
||||||
|
sprite: Buildings/smes.rsi
|
||||||
|
state: smes
|
||||||
|
result: SMES
|
||||||
|
steps:
|
||||||
|
- material: Metal
|
||||||
|
amount: 2
|
||||||
|
icon:
|
||||||
|
sprite: Buildings/smes.rsi
|
||||||
|
state: smes
|
||||||
|
|
||||||
|
- material: Cable
|
||||||
|
amount: 2
|
||||||
|
|
||||||
|
- type: construction
|
||||||
|
name: Generator
|
||||||
|
id: generator
|
||||||
|
category: Machines/Power
|
||||||
|
placementmode: SnapgridCenter
|
||||||
|
description: A portable generator capable of producing power from thin air.
|
||||||
|
icon: Objects/generator.png
|
||||||
|
result: Generator
|
||||||
|
steps:
|
||||||
|
- material: Metal
|
||||||
|
amount: 2
|
||||||
|
icon: Objects/generator.png
|
||||||
|
|
||||||
|
- material: Cable
|
||||||
|
amount: 2
|
||||||
|
|
||||||
|
- type: construction
|
||||||
|
name: APC
|
||||||
|
id: apc
|
||||||
|
category: Machines/Power
|
||||||
|
placementmode: SnapgridCenter
|
||||||
|
description: Provides power from the grid wirelessly to other machines in the area.
|
||||||
|
icon:
|
||||||
|
sprite: Buildings/apc.rsi
|
||||||
|
state: apc0
|
||||||
|
result: APC
|
||||||
|
steps:
|
||||||
|
- material: Metal
|
||||||
|
amount: 2
|
||||||
|
icon:
|
||||||
|
sprite: Buildings/apc.rsi
|
||||||
|
state: apcmaint
|
||||||
|
|
||||||
|
- material: Cable
|
||||||
|
amount: 2
|
||||||
|
|
||||||
31
Resources/Prototypes/Construction/structures.yml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
- type: construction
|
||||||
|
name: Wall
|
||||||
|
id: wall
|
||||||
|
category: Structures
|
||||||
|
description: Keeps the air in and the greytide out.
|
||||||
|
icon: Tiles/wall_texture.png
|
||||||
|
objecttype: Structure
|
||||||
|
result: __engine_wall
|
||||||
|
placementmode: SnapgridBorder
|
||||||
|
steps:
|
||||||
|
- material: Metal
|
||||||
|
amount: 2
|
||||||
|
icon: Buildings/wall_girder.png
|
||||||
|
reverse:
|
||||||
|
tool: Wrench
|
||||||
|
|
||||||
|
- material: Metal
|
||||||
|
amount: 2
|
||||||
|
reverse:
|
||||||
|
tool: Welder
|
||||||
|
|
||||||
|
- type: construction
|
||||||
|
name: Table
|
||||||
|
id: table
|
||||||
|
category: Structures
|
||||||
|
icon: Objects/worktop_single.png
|
||||||
|
result: __engine_worktop
|
||||||
|
placementmode: SnapgridCenter
|
||||||
|
steps:
|
||||||
|
- material: Metal
|
||||||
|
amount: 2
|
||||||
18
Resources/Prototypes/Construction/weapons.yml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
- type: construction
|
||||||
|
name: Crude Spear
|
||||||
|
id: spear
|
||||||
|
category: Items/Weapons
|
||||||
|
keywords: [melee]
|
||||||
|
description: A crude spear for when you need to put holes in somebody.
|
||||||
|
icon: Objects/spear.png
|
||||||
|
objecttype: Item
|
||||||
|
steps:
|
||||||
|
- material: Metal
|
||||||
|
amount: 1
|
||||||
|
|
||||||
|
- material: Cable
|
||||||
|
amount: 3
|
||||||
|
|
||||||
|
# Should probably use a shard but y'know.
|
||||||
|
- material: Glass
|
||||||
|
amount: 1
|
||||||
22
Resources/Prototypes/Entities/Construction.yml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
- type: entity
|
||||||
|
name: spooky ghost
|
||||||
|
id: constructionghost
|
||||||
|
components:
|
||||||
|
- type: Transform
|
||||||
|
- type: Sprite
|
||||||
|
color: '#3F38'
|
||||||
|
- type: ConstructionGhost
|
||||||
|
- type: BoundingBox
|
||||||
|
- type: Clickable
|
||||||
|
baseshader: unshaded
|
||||||
|
selectionshader: selection_outline_unshaded
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: somebody-messed-up frame
|
||||||
|
id: structureconstructionframe
|
||||||
|
components:
|
||||||
|
- type: Transform
|
||||||
|
- type: Sprite
|
||||||
|
- type: Construction
|
||||||
|
- type: BoundingBox
|
||||||
|
- type: Clickable
|
||||||
60
Resources/Prototypes/Entities/Materials.yml
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
- type: entity
|
||||||
|
name: Material Stack
|
||||||
|
id: MaterialStack
|
||||||
|
parent: BaseItem
|
||||||
|
components:
|
||||||
|
- type: Stack
|
||||||
|
- type: Material
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: Steel Sheet
|
||||||
|
id: MetalStack
|
||||||
|
parent: MaterialStack
|
||||||
|
components:
|
||||||
|
- type: Material
|
||||||
|
materials:
|
||||||
|
- key: enum.MaterialKeys.Stack
|
||||||
|
mat: steel
|
||||||
|
- type: Stack
|
||||||
|
stacktype: enum.StackType.Metal
|
||||||
|
- type: Sprite
|
||||||
|
texture: Objects/sheet_metal.png
|
||||||
|
- type: Icon
|
||||||
|
texture: Objects/sheet_metal.png
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: SteelSheet1
|
||||||
|
name: Steel Sheet 1
|
||||||
|
parent: MetalStack
|
||||||
|
components:
|
||||||
|
- type: Stack
|
||||||
|
count: 1
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: Glass Sheet
|
||||||
|
id: GlassStack
|
||||||
|
parent: MaterialStack
|
||||||
|
components:
|
||||||
|
- type: Material
|
||||||
|
materials:
|
||||||
|
- key: enum.MaterialKeys.Stack
|
||||||
|
mat: glass
|
||||||
|
- type: Stack
|
||||||
|
stacktype: enum.StackType.Glass
|
||||||
|
- type: Sprite
|
||||||
|
texture: Objects/sheet_glass.png
|
||||||
|
- type: Icon
|
||||||
|
texture: Objects/sheet_glass.png
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: Cable Coil
|
||||||
|
id: CableStack
|
||||||
|
parent: BaseItem
|
||||||
|
components:
|
||||||
|
- type: Stack
|
||||||
|
stacktype: enum.StackType.Cable
|
||||||
|
- type: Sprite
|
||||||
|
texture: Objects/cable_coil.png
|
||||||
|
color: red
|
||||||
|
- type: Icon
|
||||||
|
texture: Objects/cable_coil.png
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
- left
|
- left
|
||||||
- right
|
- right
|
||||||
- type: Inventory
|
- type: Inventory
|
||||||
|
- type: Constructor
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: MobObserver
|
id: MobObserver
|
||||||
|
|||||||
@@ -114,6 +114,13 @@
|
|||||||
visuals:
|
visuals:
|
||||||
- type: SmesVisualizer2D
|
- type: SmesVisualizer2D
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: smes_dry
|
||||||
|
parent: SMES
|
||||||
|
components:
|
||||||
|
- type: PowerStorage
|
||||||
|
charge: 0
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: WiredMachine
|
id: WiredMachine
|
||||||
name: WiredMachine
|
name: WiredMachine
|
||||||
|
|||||||
@@ -26,3 +26,15 @@
|
|||||||
- type: Item
|
- type: Item
|
||||||
Size: 24
|
Size: 24
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: Spear
|
||||||
|
parent: BaseItem
|
||||||
|
id: Spear
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
texture: Objects/spear.png
|
||||||
|
- type: Icon
|
||||||
|
texture: Objects/spear.png
|
||||||
|
- type: MeleeWeapon
|
||||||
|
- type: Item
|
||||||
|
Size: 24
|
||||||
|
|||||||
26
Resources/Scenes/Construction/ConstructionButton.tscn
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
[gd_scene format=2]
|
||||||
|
|
||||||
|
[node name="Control" type="Button"]
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
margin_left = -110.0
|
||||||
|
margin_top = -70.0
|
||||||
|
margin_right = -50.0
|
||||||
|
margin_bottom = -50.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
focus_mode = 2
|
||||||
|
mouse_filter = 0
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 1
|
||||||
|
toggle_mode = false
|
||||||
|
enabled_focus_mode = 2
|
||||||
|
shortcut = null
|
||||||
|
group = null
|
||||||
|
text = "Crafting"
|
||||||
|
flat = false
|
||||||
|
align = 1
|
||||||
|
|
||||||
273
Resources/Scenes/Construction/ConstructionMenu.tscn
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
[gd_scene load_steps=2 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://Scenes/SS14Window/SS14Window.tscn" type="PackedScene" id=1]
|
||||||
|
|
||||||
|
[node name="SS14Window" index="0" instance=ExtResource( 1 )]
|
||||||
|
margin_left = 99.0
|
||||||
|
margin_right = 583.0
|
||||||
|
margin_bottom = 357.0
|
||||||
|
rect_clip_content = false
|
||||||
|
|
||||||
|
[node name="Contents" parent="." index="0"]
|
||||||
|
rect_clip_content = false
|
||||||
|
|
||||||
|
[node name="HSplitContainer" type="HSplitContainer" parent="Contents" index="0"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 1
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 0
|
||||||
|
split_offset = 15
|
||||||
|
collapsed = false
|
||||||
|
dragger_visibility = 0
|
||||||
|
|
||||||
|
[node name="Recipes" type="VBoxContainer" parent="Contents/HSplitContainer" index="0"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_right = 163.0
|
||||||
|
margin_bottom = 269.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 2
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 1
|
||||||
|
size_flags_stretch_ratio = 0.5
|
||||||
|
alignment = 0
|
||||||
|
_sections_unfolded = [ "Grow Direction", "Size Flags" ]
|
||||||
|
|
||||||
|
[node name="Search" type="LineEdit" parent="Contents/HSplitContainer/Recipes" index="0"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_right = 163.0
|
||||||
|
margin_bottom = 24.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
focus_mode = 2
|
||||||
|
mouse_filter = 0
|
||||||
|
mouse_default_cursor_shape = 1
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 1
|
||||||
|
secret_character = "*"
|
||||||
|
focus_mode = 2
|
||||||
|
context_menu_enabled = true
|
||||||
|
placeholder_text = "Search"
|
||||||
|
placeholder_alpha = 0.6
|
||||||
|
caret_blink = false
|
||||||
|
caret_blink_speed = 0.65
|
||||||
|
caret_position = 0
|
||||||
|
|
||||||
|
[node name="Tree" type="Tree" parent="Contents/HSplitContainer/Recipes" index="1"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_top = 28.0
|
||||||
|
margin_right = 163.0
|
||||||
|
margin_bottom = 269.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = true
|
||||||
|
focus_mode = 2
|
||||||
|
mouse_filter = 0
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 3
|
||||||
|
columns = 1
|
||||||
|
allow_reselect = false
|
||||||
|
allow_rmb_select = false
|
||||||
|
hide_folding = false
|
||||||
|
hide_root = true
|
||||||
|
drop_mode_flags = 0
|
||||||
|
select_mode = 0
|
||||||
|
_sections_unfolded = [ "Mouse" ]
|
||||||
|
|
||||||
|
[node name="Guide" type="VBoxContainer" parent="Contents/HSplitContainer" index="1"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_left = 175.0
|
||||||
|
margin_right = 464.0
|
||||||
|
margin_bottom = 269.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 2
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
alignment = 0
|
||||||
|
|
||||||
|
[node name="Info" type="HBoxContainer" parent="Contents/HSplitContainer/Guide" index="0"]
|
||||||
|
editor/display_folded = true
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_right = 289.0
|
||||||
|
margin_bottom = 14.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 2
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 1
|
||||||
|
alignment = 0
|
||||||
|
|
||||||
|
[node name="TextureRect" type="TextureRect" parent="Contents/HSplitContainer/Guide/Info" index="0"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_bottom = 14.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 2
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 1
|
||||||
|
stretch_mode = 0
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="Contents/HSplitContainer/Guide/Info" index="1"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_left = 4.0
|
||||||
|
margin_right = 289.0
|
||||||
|
margin_bottom = 14.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 2
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 4
|
||||||
|
autowrap = true
|
||||||
|
percent_visible = 1.0
|
||||||
|
lines_skipped = 0
|
||||||
|
max_lines_visible = -1
|
||||||
|
_sections_unfolded = [ "Size Flags" ]
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="Contents/HSplitContainer/Guide" index="1"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_left = 127.0
|
||||||
|
margin_top = 18.0
|
||||||
|
margin_right = 162.0
|
||||||
|
margin_bottom = 32.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 2
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 4
|
||||||
|
size_flags_vertical = 4
|
||||||
|
custom_colors/font_color = Color( 0.505882, 0.505882, 0.505882, 1 )
|
||||||
|
text = "Steps"
|
||||||
|
percent_visible = 1.0
|
||||||
|
lines_skipped = 0
|
||||||
|
max_lines_visible = -1
|
||||||
|
|
||||||
|
[node name="StepsList" type="ItemList" parent="Contents/HSplitContainer/Guide" index="2"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_top = 36.0
|
||||||
|
margin_right = 289.0
|
||||||
|
margin_bottom = 245.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = true
|
||||||
|
focus_mode = 2
|
||||||
|
mouse_filter = 0
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 3
|
||||||
|
items = [ ]
|
||||||
|
select_mode = 0
|
||||||
|
allow_reselect = false
|
||||||
|
icon_mode = 1
|
||||||
|
fixed_icon_size = Vector2( 0, 0 )
|
||||||
|
_sections_unfolded = [ "Icon", "Size Flags" ]
|
||||||
|
|
||||||
|
[node name="Buttons" type="HBoxContainer" parent="Contents/HSplitContainer/Guide" index="3"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_top = 249.0
|
||||||
|
margin_right = 289.0
|
||||||
|
margin_bottom = 269.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
mouse_filter = 1
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 1
|
||||||
|
alignment = 0
|
||||||
|
|
||||||
|
[node name="BuildButton" type="Button" parent="Contents/HSplitContainer/Guide/Buttons" index="0"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_right = 192.0
|
||||||
|
margin_bottom = 20.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
focus_mode = 2
|
||||||
|
mouse_filter = 0
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 1
|
||||||
|
disabled = true
|
||||||
|
toggle_mode = false
|
||||||
|
enabled_focus_mode = 2
|
||||||
|
shortcut = null
|
||||||
|
group = null
|
||||||
|
text = "Build!"
|
||||||
|
flat = false
|
||||||
|
align = 1
|
||||||
|
_sections_unfolded = [ "Size Flags" ]
|
||||||
|
|
||||||
|
[node name="EraseButton" type="Button" parent="Contents/HSplitContainer/Guide/Buttons" index="1"]
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
|
margin_left = 196.0
|
||||||
|
margin_right = 289.0
|
||||||
|
margin_bottom = 20.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
|
rect_clip_content = false
|
||||||
|
focus_mode = 2
|
||||||
|
mouse_filter = 0
|
||||||
|
mouse_default_cursor_shape = 0
|
||||||
|
size_flags_horizontal = 1
|
||||||
|
size_flags_vertical = 1
|
||||||
|
toggle_mode = true
|
||||||
|
enabled_focus_mode = 2
|
||||||
|
shortcut = null
|
||||||
|
group = null
|
||||||
|
text = "Clear Ghosts"
|
||||||
|
flat = false
|
||||||
|
align = 1
|
||||||
|
|
||||||
|
[node name="Header" parent="." index="1"]
|
||||||
|
rect_clip_content = false
|
||||||
|
|
||||||
|
[node name="Header Text" parent="Header" index="0"]
|
||||||
|
rect_clip_content = false
|
||||||
|
|
||||||
|
[node name="CloseButton" parent="Header" index="1"]
|
||||||
|
rect_clip_content = false
|
||||||
|
|
||||||
@@ -1,170 +1 @@
|
|||||||
{
|
{"version":1,"license":"CC-BY-SA-3.0","copyright":"Taken from https://github.com/discordia-space/CEV-Eris/blob/d1e0161af146835f4fb79d21a6200caa9cc842d0/icons/obj/power.dmi and modified.","size":{"x":32,"y":32},"states":[{"name":"smes","select":[],"flags":{},"directions":1},{"name":"smes-display","select":[],"flags":{},"directions":1,"delays":[[0.2,0.2,0.2,0.2,0.2]]},{"name":"smes-crit","select":[],"flags":{},"directions":1,"delays":[[0.2,0.2,0.2,0.2]]},{"name":"smes-oc0","select":[],"flags":{},"directions":1,"delays":[[1]]},{"name":"smes-oc1","select":[],"flags":{},"directions":1,"delays":[[0.5,0.5]]},{"name":"smes-oc2","select":[],"flags":{},"directions":1,"delays":[[0.5,0.5]]},{"name":"smes-og1","select":[],"flags":{},"directions":1,"delays":[[1]]},{"name":"smes-og2","select":[],"flags":{},"directions":1,"delays":[[1]]},{"name":"smes-og3","select":[],"flags":{},"directions":1,"delays":[[1]]},{"name":"smes-og4","select":[],"flags":{},"directions":1,"delays":[[1]]},{"name":"smes-og5","select":[],"flags":{},"directions":1,"delays":[[1]]},{"name":"smes-op0","select":[],"flags":{},"directions":1,"delays":[[1]]},{"name":"smes-op1","select":[],"flags":{},"directions":1,"delays":[[1,1]]},{"name":"smes-op2","select":[],"flags":{},"directions":1,"delays":[[1]]}]}
|
||||||
"version": 1,
|
|
||||||
"license": "CC-BY-SA-3.0",
|
|
||||||
"copyright": "Taken from https://github.com/discordia-space/CEV-Eris/blob/d1e0161af146835f4fb79d21a6200caa9cc842d0/icons/obj/power.dmi and modified.",
|
|
||||||
"size": {
|
|
||||||
"x": 32,
|
|
||||||
"y": 32
|
|
||||||
},
|
|
||||||
"states": [
|
|
||||||
{
|
|
||||||
"name": "smes",
|
|
||||||
"select": [],
|
|
||||||
"flags": {},
|
|
||||||
"directions": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "smes-display",
|
|
||||||
"select": [],
|
|
||||||
"flags": {},
|
|
||||||
"directions": 1,
|
|
||||||
"delays": [
|
|
||||||
[
|
|
||||||
0.2,
|
|
||||||
0.2,
|
|
||||||
0.2,
|
|
||||||
0.2,
|
|
||||||
0.2
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "smes-crit",
|
|
||||||
"select": [],
|
|
||||||
"flags": {},
|
|
||||||
"directions": 1,
|
|
||||||
"delays": [
|
|
||||||
[
|
|
||||||
0.2,
|
|
||||||
0.2,
|
|
||||||
0.2,
|
|
||||||
0.2
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "smes-oc0",
|
|
||||||
"select": [],
|
|
||||||
"flags": {},
|
|
||||||
"directions": 1,
|
|
||||||
"delays": [
|
|
||||||
[
|
|
||||||
1.0
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "smes-oc1",
|
|
||||||
"select": [],
|
|
||||||
"flags": {},
|
|
||||||
"directions": 1,
|
|
||||||
"delays": [
|
|
||||||
[
|
|
||||||
0.5,
|
|
||||||
0.5
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "smes-oc2",
|
|
||||||
"select": [],
|
|
||||||
"flags": {},
|
|
||||||
"directions": 1,
|
|
||||||
"delays": [
|
|
||||||
[
|
|
||||||
0.5,
|
|
||||||
0.5
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "smes-og1",
|
|
||||||
"select": [],
|
|
||||||
"flags": {},
|
|
||||||
"directions": 1,
|
|
||||||
"delays": [
|
|
||||||
[
|
|
||||||
1.0
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "smes-og2",
|
|
||||||
"select": [],
|
|
||||||
"flags": {},
|
|
||||||
"directions": 1,
|
|
||||||
"delays": [
|
|
||||||
[
|
|
||||||
1.0
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "smes-og3",
|
|
||||||
"select": [],
|
|
||||||
"flags": {},
|
|
||||||
"directions": 1,
|
|
||||||
"delays": [
|
|
||||||
[
|
|
||||||
1.0
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "smes-og4",
|
|
||||||
"select": [],
|
|
||||||
"flags": {},
|
|
||||||
"directions": 1,
|
|
||||||
"delays": [
|
|
||||||
[
|
|
||||||
1.0
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "smes-og5",
|
|
||||||
"select": [],
|
|
||||||
"flags": {},
|
|
||||||
"directions": 1,
|
|
||||||
"delays": [
|
|
||||||
[
|
|
||||||
1.0
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "smes-op0",
|
|
||||||
"select": [],
|
|
||||||
"flags": {},
|
|
||||||
"directions": 1,
|
|
||||||
"delays": [
|
|
||||||
[
|
|
||||||
1.0
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "smes-op1",
|
|
||||||
"select": [],
|
|
||||||
"flags": {},
|
|
||||||
"directions": 1,
|
|
||||||
"delays": [
|
|
||||||
[
|
|
||||||
1.0,
|
|
||||||
1.0
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "smes-op2",
|
|
||||||
"select": [],
|
|
||||||
"flags": {},
|
|
||||||
"directions": 1,
|
|
||||||
"delays": [
|
|
||||||
[
|
|
||||||
1.0
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 581 B |
BIN
Resources/Textures/Buildings/wall_girder.png
Normal file
|
After Width: | Height: | Size: 302 B |
BIN
Resources/Textures/Objects/cable_coil.png
Normal file
|
After Width: | Height: | Size: 171 B |
BIN
Resources/Textures/Objects/lighting.rsi/construct.png
Normal file
|
After Width: | Height: | Size: 276 B |
BIN
Resources/Textures/Objects/lighting.rsi/empty.png
Normal file
|
After Width: | Height: | Size: 368 B |
@@ -1,21 +1 @@
|
|||||||
{
|
{"version":1,"size":{"x":32,"y":32},"states":[{"name":"on","select":[],"flags":{},"directions":4},{"name":"off","select":[],"flags":{},"directions":4},{"name":"construct","select":[],"flags":{},"directions":4},{"name":"empty","select":[],"flags":{},"directions":4}]}
|
||||||
"version": 1,
|
|
||||||
"size": {
|
|
||||||
"x": 32,
|
|
||||||
"y": 32
|
|
||||||
},
|
|
||||||
"states": [
|
|
||||||
{
|
|
||||||
"name": "on",
|
|
||||||
"select": [],
|
|
||||||
"flags": {},
|
|
||||||
"directions": 4
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "off",
|
|
||||||
"select": [],
|
|
||||||
"flags": {},
|
|
||||||
"directions": 4
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
BIN
Resources/Textures/Objects/sheet_glass.png
Normal file
|
After Width: | Height: | Size: 781 B |
BIN
Resources/Textures/Objects/sheet_metal.png
Normal file
|
After Width: | Height: | Size: 883 B |
BIN
Resources/Textures/Objects/spear.png
Normal file
|
After Width: | Height: | Size: 171 B |