Construction System. (#87)
* Construction WiP * Construction kinda works! * Lots more construction work. * It mostly works!
This commit is contained in:
committed by
GitHub
parent
f051078c79
commit
d7074bf74f
@@ -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 System.Linq;
|
||||
using SS14.Shared.Serialization;
|
||||
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||
|
||||
namespace Content.Server.GameObjects
|
||||
{
|
||||
@@ -159,8 +160,8 @@ namespace Content.Server.GameObjects
|
||||
item.RemovedFromSlot();
|
||||
|
||||
// TODO: The item should be dropped to the container our owner is in, if any.
|
||||
var itemTransform = item.Owner.GetComponent<TransformComponent>();
|
||||
itemTransform.LocalPosition = Owner.GetComponent<TransformComponent>().LocalPosition;
|
||||
var itemTransform = item.Owner.GetComponent<ITransformComponent>();
|
||||
itemTransform.LocalPosition = Owner.GetComponent<ITransformComponent>().LocalPosition;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ using SS14.Server.Interfaces.Player;
|
||||
using SS14.Shared.GameObjects;
|
||||
using SS14.Shared.Input;
|
||||
using SS14.Shared.Interfaces.GameObjects;
|
||||
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||
using SS14.Shared.Interfaces.Network;
|
||||
using SS14.Shared.IoC;
|
||||
using SS14.Shared.Serialization;
|
||||
@@ -162,8 +163,8 @@ namespace Content.Server.GameObjects
|
||||
item.RemovedFromSlot();
|
||||
|
||||
// TODO: The item should be dropped to the container our owner is in, if any.
|
||||
var itemTransform = item.Owner.GetComponent<TransformComponent>();
|
||||
itemTransform.LocalPosition = Owner.GetComponent<TransformComponent>().LocalPosition;
|
||||
var itemTransform = item.Owner.GetComponent<ITransformComponent>();
|
||||
itemTransform.LocalPosition = Owner.GetComponent<ITransformComponent>().LocalPosition;
|
||||
Dirty();
|
||||
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)
|
||||
{
|
||||
return Fuel > value;
|
||||
|
||||
@@ -8,6 +8,7 @@ using SS14.Server.Player;
|
||||
using SS14.Shared.Enums;
|
||||
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;
|
||||
@@ -214,8 +215,8 @@ namespace Content.Server.GameObjects
|
||||
var session = playerMan.GetSessionByChannel(netChannel);
|
||||
var playerentity = session.AttachedEntity;
|
||||
|
||||
var ourtransform = Owner.GetComponent<TransformComponent>();
|
||||
var playertransform = playerentity.GetComponent<TransformComponent>();
|
||||
var ourtransform = Owner.GetComponent<ITransformComponent>();
|
||||
var playertransform = playerentity.GetComponent<ITransformComponent>();
|
||||
|
||||
if (playertransform.LocalPosition.InRange(ourtransform.LocalPosition, 2)
|
||||
&& (ourtransform.IsMapTransform || playertransform.ContainsEntity(ourtransform)))
|
||||
@@ -233,7 +234,7 @@ namespace Content.Server.GameObjects
|
||||
return;
|
||||
}
|
||||
|
||||
entity.GetComponent<TransformComponent>().WorldPosition = Owner.GetComponent<TransformComponent>().WorldPosition;
|
||||
entity.GetComponent<ITransformComponent>().WorldPosition = ourtransform.WorldPosition;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -67,8 +67,8 @@ namespace Content.Server.GameObjects.Components.Materials
|
||||
}
|
||||
|
||||
var refl = IoCManager.Resolve<IReflectionManager>();
|
||||
Value = serializer.ReadDataField("mat", "unobtanium");
|
||||
var key = serializer.ReadDataField("key", string.Empty);
|
||||
Value = serializer.ReadDataField<string>("mat");
|
||||
var key = serializer.ReadDataField<string>("key");
|
||||
if (refl.TryParseEnumReference(key, out var @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.Shared.GameObjects;
|
||||
using SS14.Shared.Interfaces.GameObjects;
|
||||
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||
using SS14.Shared.Map;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Power
|
||||
@@ -49,7 +50,7 @@ namespace Content.Server.GameObjects.Components.Power
|
||||
builder.Append(" Providers:\n");
|
||||
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);
|
||||
if (device.Provider == provider)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using SS14.Server.GameObjects;
|
||||
using SS14.Shared.GameObjects;
|
||||
using SS14.Shared.Interfaces.GameObjects;
|
||||
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||
using SS14.Shared.IoC;
|
||||
using SS14.Shared.Serialization;
|
||||
using SS14.Shared.Utility;
|
||||
@@ -240,18 +241,18 @@ namespace Content.Server.GameObjects.Components.Power
|
||||
return;
|
||||
|
||||
//Get the starting value for our loop
|
||||
var position = Owner.GetComponent<TransformComponent>().WorldPosition;
|
||||
var position = Owner.GetComponent<ITransformComponent>().WorldPosition;
|
||||
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 (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)
|
||||
{
|
||||
//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 (distance < bestdistance)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using SS14.Server.GameObjects;
|
||||
using SS14.Server.Interfaces.GameObjects;
|
||||
using SS14.Shared.GameObjects;
|
||||
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||
using SS14.Shared.IoC;
|
||||
using System;
|
||||
using System.Linq;
|
||||
@@ -56,10 +57,10 @@ namespace Content.Server.GameObjects.Components.Power
|
||||
return;
|
||||
}
|
||||
var _emanager = IoCManager.Resolve<IServerEntityManager>();
|
||||
var position = Owner.GetComponent<TransformComponent>().WorldPosition;
|
||||
var position = Owner.GetComponent<ITransformComponent>().WorldPosition;
|
||||
var wires = _emanager.GetEntitiesIntersecting(Owner)
|
||||
.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();
|
||||
if (choose != null)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using SS14.Server.GameObjects;
|
||||
using SS14.Server.Interfaces.GameObjects;
|
||||
using SS14.Shared.Interfaces.GameObjects;
|
||||
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||
using SS14.Shared.IoC;
|
||||
using SS14.Shared.Log;
|
||||
using SS14.Shared.Serialization;
|
||||
@@ -139,7 +140,7 @@ namespace Content.Server.GameObjects.Components.Power
|
||||
|
||||
//Find devices within range to take under our control
|
||||
var _emanager = IoCManager.Resolve<IServerEntityManager>();
|
||||
var position = Owner.GetComponent<TransformComponent>().WorldPosition;
|
||||
var position = Owner.GetComponent<ITransformComponent>().WorldPosition;
|
||||
var entities = _emanager.GetEntitiesInRange(Owner, PowerRange)
|
||||
.Where(x => x.HasComponent<PowerDeviceComponent>());
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ using SS14.Shared.IoC;
|
||||
using System.Linq;
|
||||
using SS14.Shared.Interfaces.GameObjects;
|
||||
using Content.Server.GameObjects.Components.Interactable.Tools;
|
||||
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Power
|
||||
{
|
||||
@@ -44,7 +45,7 @@ namespace Content.Server.GameObjects.Components.Power
|
||||
public void SpreadPowernet()
|
||||
{
|
||||
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
|
||||
.Where(x => x.HasComponent<PowerTransferComponent>());
|
||||
|
||||
|
||||
122
Content.Server/GameObjects/Components/Stack/StackComponent.cs
Normal file
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.GameObjects.EntitySystemMessages;
|
||||
using SS14.Shared.Serialization;
|
||||
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||
|
||||
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)
|
||||
{
|
||||
var location = user.GetComponent<TransformComponent>().LocalPosition;
|
||||
var location = user.GetComponent<ITransformComponent>().LocalPosition;
|
||||
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)
|
||||
{
|
||||
if (!entity.GetComponent<TransformComponent>().IsMapTransform || entity == user)
|
||||
if (!entity.GetComponent<ITransformComponent>().IsMapTransform || entity == user)
|
||||
continue;
|
||||
|
||||
if (entity.TryGetComponent(out DamageableComponent damagecomponent))
|
||||
|
||||
@@ -4,6 +4,7 @@ using SS14.Shared.Audio;
|
||||
using SS14.Shared.GameObjects;
|
||||
using SS14.Shared.GameObjects.EntitySystemMessages;
|
||||
using SS14.Shared.Interfaces.GameObjects;
|
||||
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||
using SS14.Shared.Interfaces.Physics;
|
||||
using SS14.Shared.Interfaces.Timing;
|
||||
using SS14.Shared.IoC;
|
||||
@@ -22,11 +23,11 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan
|
||||
|
||||
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 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);
|
||||
AfterEffects(user, raycastresults, angle);
|
||||
@@ -51,7 +52,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Hitscan
|
||||
Born = time,
|
||||
DeathTime = time + TimeSpan.FromSeconds(1),
|
||||
Size = new Vector2(ray.Distance, 1f),
|
||||
Coordinates = user.GetComponent<TransformComponent>().LocalPosition.Translated(offset),
|
||||
Coordinates = user.GetComponent<ITransformComponent>().LocalPosition.Translated(offset),
|
||||
//Rotated from east facing
|
||||
Rotation = (float)angle.Theta,
|
||||
ColorDelta = new Vector4(0, 0, 0, -1500f),
|
||||
|
||||
@@ -3,6 +3,7 @@ using SS14.Server.GameObjects;
|
||||
using SS14.Server.GameObjects.EntitySystems;
|
||||
using SS14.Server.Interfaces.GameObjects;
|
||||
using SS14.Shared.Interfaces.GameObjects;
|
||||
using SS14.Shared.Interfaces.GameObjects.Components;
|
||||
using SS14.Shared.IoC;
|
||||
using SS14.Shared.Map;
|
||||
using SS14.Shared.Maths;
|
||||
@@ -19,7 +20,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
|
||||
|
||||
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 theta = angle.Theta;
|
||||
@@ -34,7 +35,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
|
||||
projectile.GetComponent<PhysicsComponent>().LinearVelocity = angle.ToVec() * _velocity;
|
||||
|
||||
//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!
|
||||
IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>().Play("/Audio/gunshot_c20.ogg");
|
||||
|
||||
Reference in New Issue
Block a user