2019-04-05 19:22:38 +02:00
|
|
|
|
using System;
|
2018-08-02 08:29:55 +02:00
|
|
|
|
using System.Collections.Generic;
|
2020-04-29 13:43:07 +02:00
|
|
|
|
using Content.Server.GameObjects.Components.Interactable;
|
2018-08-02 08:29:55 +02:00
|
|
|
|
using Content.Server.GameObjects.Components.Stack;
|
|
|
|
|
|
using Content.Server.GameObjects.EntitySystems;
|
2020-03-06 13:15:44 -06:00
|
|
|
|
using Content.Server.Interfaces;
|
2020-05-23 02:27:31 -07:00
|
|
|
|
using Content.Server.Utility;
|
2018-08-02 08:29:55 +02:00
|
|
|
|
using Content.Shared.Construction;
|
2020-04-12 01:15:16 +02:00
|
|
|
|
using Content.Shared.GameObjects.Components;
|
2020-04-29 13:43:07 +02:00
|
|
|
|
using Content.Shared.GameObjects.Components.Interactable;
|
2019-04-15 21:11:38 -06:00
|
|
|
|
using Robust.Server.GameObjects;
|
|
|
|
|
|
using Robust.Server.GameObjects.EntitySystems;
|
|
|
|
|
|
using Robust.Server.Interfaces.GameObjects;
|
|
|
|
|
|
using Robust.Shared.GameObjects;
|
2020-05-23 02:27:31 -07:00
|
|
|
|
using Robust.Shared.GameObjects.Systems;
|
2019-04-15 21:11:38 -06:00
|
|
|
|
using Robust.Shared.Interfaces.GameObjects;
|
|
|
|
|
|
using Robust.Shared.Interfaces.GameObjects.Components;
|
2019-08-17 21:09:09 +02:00
|
|
|
|
using Robust.Shared.Interfaces.Random;
|
2019-04-15 21:11:38 -06:00
|
|
|
|
using Robust.Shared.IoC;
|
2020-03-06 13:15:44 -06:00
|
|
|
|
using Robust.Shared.Localization;
|
2019-04-15 21:11:38 -06:00
|
|
|
|
using Robust.Shared.ViewVariables;
|
2018-08-02 08:29:55 +02:00
|
|
|
|
using static Content.Shared.Construction.ConstructionStepMaterial;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Content.Server.GameObjects.Components.Construction
|
|
|
|
|
|
{
|
2019-07-31 15:02:36 +02:00
|
|
|
|
[RegisterComponent]
|
2020-05-23 17:23:25 +02:00
|
|
|
|
public class ConstructionComponent : Component, IInteractUsing
|
2018-08-02 08:29:55 +02:00
|
|
|
|
{
|
|
|
|
|
|
public override string Name => "Construction";
|
|
|
|
|
|
|
2018-09-09 15:34:43 +02:00
|
|
|
|
[ViewVariables]
|
2018-08-02 08:29:55 +02:00
|
|
|
|
public ConstructionPrototype Prototype { get; private set; }
|
2018-09-09 15:34:43 +02:00
|
|
|
|
[ViewVariables]
|
2018-08-02 08:29:55 +02:00
|
|
|
|
public int Stage { get; private set; }
|
|
|
|
|
|
|
|
|
|
|
|
SpriteComponent Sprite;
|
|
|
|
|
|
ITransformComponent Transform;
|
|
|
|
|
|
|
|
|
|
|
|
public override void Initialize()
|
|
|
|
|
|
{
|
|
|
|
|
|
base.Initialize();
|
|
|
|
|
|
|
|
|
|
|
|
Sprite = Owner.GetComponent<SpriteComponent>();
|
|
|
|
|
|
Transform = Owner.GetComponent<ITransformComponent>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-23 17:23:25 +02:00
|
|
|
|
public bool InteractUsing(InteractUsingEventArgs eventArgs)
|
2018-08-02 08:29:55 +02:00
|
|
|
|
{
|
2020-05-23 02:27:31 -07:00
|
|
|
|
// default interaction check for AttackBy allows inside blockers, so we will check if its blocked if
|
|
|
|
|
|
// we're not allowed to build on impassable stuff
|
|
|
|
|
|
if (Prototype.CanBuildInImpassable == false)
|
2020-03-03 10:03:58 -06:00
|
|
|
|
{
|
2020-05-23 02:27:31 -07:00
|
|
|
|
if (!InteractionChecks.InRangeUnobstructed(eventArgs, false))
|
|
|
|
|
|
return false;
|
2020-03-03 10:03:58 -06:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-08-02 08:29:55 +02:00
|
|
|
|
var stage = Prototype.Stages[Stage];
|
|
|
|
|
|
|
2020-05-23 18:00:28 +02:00
|
|
|
|
if (TryProcessStep(stage.Forward, eventArgs.Using, eventArgs.User))
|
2018-08-02 08:29:55 +02:00
|
|
|
|
{
|
|
|
|
|
|
Stage++;
|
|
|
|
|
|
if (Stage == Prototype.Stages.Count - 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Oh boy we get to finish construction!
|
|
|
|
|
|
var entMgr = IoCManager.Resolve<IServerEntityManager>();
|
2020-01-24 16:10:48 -08:00
|
|
|
|
var ent = entMgr.SpawnEntity(Prototype.Result, Transform.GridPosition);
|
2018-08-02 08:29:55 +02:00
|
|
|
|
ent.GetComponent<ITransformComponent>().LocalRotation = Transform.LocalRotation;
|
|
|
|
|
|
Owner.Delete();
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
stage = Prototype.Stages[Stage];
|
|
|
|
|
|
if (stage.Icon != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Sprite.LayerSetSprite(0, stage.Icon);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-23 18:00:28 +02:00
|
|
|
|
else if (TryProcessStep(stage.Backward, eventArgs.Using, eventArgs.User))
|
2018-08-02 08:29:55 +02:00
|
|
|
|
{
|
|
|
|
|
|
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;
|
2019-11-21 17:46:37 -05:00
|
|
|
|
if(prototype.Stages[1].Icon != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Sprite.AddLayerWithSprite(prototype.Stages[1].Icon);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Sprite.AddLayerWithSprite(prototype.Icon);
|
|
|
|
|
|
}
|
2020-04-12 01:15:16 +02:00
|
|
|
|
|
2019-11-21 17:46:37 -05:00
|
|
|
|
|
2018-08-02 08:29:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-19 13:55:52 +02:00
|
|
|
|
bool TryProcessStep(ConstructionStep step, IEntity slapped, IEntity user)
|
2018-08-02 08:29:55 +02:00
|
|
|
|
{
|
2019-05-18 17:10:19 -04:00
|
|
|
|
if (step == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2020-05-23 02:27:31 -07:00
|
|
|
|
var sound = EntitySystem.Get<AudioSystem>();
|
2019-03-28 14:31:49 +01:00
|
|
|
|
|
2018-08-02 08:29:55 +02:00
|
|
|
|
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)
|
2020-06-07 08:55:15 -05:00
|
|
|
|
sound.PlayAtCoords("/Audio/items/zip.ogg", Transform.GridPosition);
|
2018-08-02 08:29:55 +02:00
|
|
|
|
else
|
2020-06-07 08:55:15 -05:00
|
|
|
|
sound.PlayAtCoords("/Audio/items/deconstruct.ogg", Transform.GridPosition);
|
2018-08-02 08:29:55 +02:00
|
|
|
|
return true;
|
|
|
|
|
|
case ConstructionStepTool toolStep:
|
2020-04-29 13:43:07 +02:00
|
|
|
|
if (!slapped.TryGetComponent<ToolComponent>(out var tool))
|
|
|
|
|
|
return false;
|
2020-05-19 13:55:52 +02:00
|
|
|
|
|
|
|
|
|
|
// Handle welder manually since tool steps specify fuel amount needed, for some reason.
|
|
|
|
|
|
if (toolStep.ToolQuality.HasFlag(ToolQuality.Welding))
|
|
|
|
|
|
return slapped.TryGetComponent<WelderComponent>(out var welder)
|
|
|
|
|
|
&& welder.UseTool(user, Owner, toolStep.ToolQuality, toolStep.Amount);
|
|
|
|
|
|
|
|
|
|
|
|
return tool.UseTool(user, Owner, toolStep.ToolQuality);
|
2020-04-29 15:34:49 +02:00
|
|
|
|
|
2018-08-02 08:29:55 +02:00
|
|
|
|
default:
|
|
|
|
|
|
throw new NotImplementedException();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-11-13 17:37:46 -05:00
|
|
|
|
private static Dictionary<StackType, MaterialType> StackTypeMap
|
|
|
|
|
|
= new Dictionary<StackType, MaterialType>
|
2018-08-02 08:29:55 +02:00
|
|
|
|
{
|
|
|
|
|
|
{ StackType.Cable, MaterialType.Cable },
|
2020-05-24 16:56:19 +00:00
|
|
|
|
{ StackType.Gold, MaterialType.Gold },
|
2018-08-02 08:29:55 +02:00
|
|
|
|
{ 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;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|