Merge remote-tracking branch 'refs/remotes/wizards/master'

# Conflicts:
#	Resources/Prototypes/Datasets/Names/ai.yml
#	Resources/Prototypes/Datasets/Names/arachnid_first.yml
#	Resources/Prototypes/Datasets/Names/diona.yml
#	Resources/Prototypes/Datasets/Names/fake_human_first.yml
#	Resources/Prototypes/Datasets/Names/fake_human_last.yml
#	Resources/Prototypes/Datasets/Names/last.yml
#	Resources/Prototypes/Datasets/Names/vox.yml
#	Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml
#	Resources/Prototypes/Recipes/Lathes/mech_parts.yml
#	Resources/ServerInfo/Guidebook/Mobs/Vox.xml
This commit is contained in:
Vigers Ray 2024-12-07 07:45:07 +03:00
commit bcd534952f
81 changed files with 6799 additions and 1980 deletions

View file

@ -0,0 +1,23 @@
using Content.Client.Atmos.UI;
using Content.Shared.Atmos.Components;
using Content.Shared.Atmos.EntitySystems;
using Content.Shared.Atmos.Piping.Binary.Components;
namespace Content.Client.Atmos.EntitySystems;
public sealed class GasPressurePumpSystem : SharedGasPressurePumpSystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<GasPressurePumpComponent, AfterAutoHandleStateEvent>(OnPumpUpdate);
}
private void OnPumpUpdate(Entity<GasPressurePumpComponent> ent, ref AfterAutoHandleStateEvent args)
{
if (UserInterfaceSystem.TryGetOpenUi<GasPressurePumpBoundUserInterface>(ent.Owner, GasPressurePumpUiKey.Key, out var bui))
{
bui.Update();
}
}
}

View file

@ -1,65 +1,63 @@
using Content.Shared.Atmos;
using Content.Shared.Atmos.Components;
using Content.Shared.Atmos.Piping.Binary.Components;
using Content.Shared.IdentityManagement;
using Content.Shared.Localizations;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
namespace Content.Client.Atmos.UI
namespace Content.Client.Atmos.UI;
/// <summary>
/// Initializes a <see cref="GasPressurePumpWindow"/> and updates it when new server messages are received.
/// </summary>
[UsedImplicitly]
public sealed class GasPressurePumpBoundUserInterface : BoundUserInterface
{
/// <summary>
/// Initializes a <see cref="GasPressurePumpWindow"/> and updates it when new server messages are received.
/// </summary>
[UsedImplicitly]
public sealed class GasPressurePumpBoundUserInterface : BoundUserInterface
[ViewVariables]
private const float MaxPressure = Atmospherics.MaxOutputPressure;
[ViewVariables]
private GasPressurePumpWindow? _window;
public GasPressurePumpBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
[ViewVariables]
private const float MaxPressure = Atmospherics.MaxOutputPressure;
}
[ViewVariables]
private GasPressurePumpWindow? _window;
protected override void Open()
{
base.Open();
public GasPressurePumpBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}
_window = this.CreateWindow<GasPressurePumpWindow>();
protected override void Open()
{
base.Open();
_window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed;
_window.PumpOutputPressureChanged += OnPumpOutputPressurePressed;
Update();
}
_window = this.CreateWindow<GasPressurePumpWindow>();
public void Update()
{
if (_window == null)
return;
_window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed;
_window.PumpOutputPressureChanged += OnPumpOutputPressurePressed;
}
_window.Title = Identity.Name(Owner, EntMan);
private void OnToggleStatusButtonPressed()
{
if (_window is null) return;
SendMessage(new GasPressurePumpToggleStatusMessage(_window.PumpStatus));
}
if (!EntMan.TryGetComponent(Owner, out GasPressurePumpComponent? pump))
return;
private void OnPumpOutputPressurePressed(string value)
{
var pressure = UserInputParser.TryFloat(value, out var parsed) ? parsed : 0f;
if (pressure > MaxPressure) pressure = MaxPressure;
_window.SetPumpStatus(pump.Enabled);
_window.MaxPressure = pump.MaxTargetPressure;
_window.SetOutputPressure(pump.TargetPressure);
}
SendMessage(new GasPressurePumpChangeOutputPressureMessage(pressure));
}
private void OnToggleStatusButtonPressed()
{
if (_window is null) return;
SendPredictedMessage(new GasPressurePumpToggleStatusMessage(_window.PumpStatus));
}
/// <summary>
/// Update the UI state based on server-sent info
/// </summary>
/// <param name="state"></param>
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (_window == null || state is not GasPressurePumpBoundUserInterfaceState cast)
return;
_window.Title = (cast.PumpLabel);
_window.SetPumpStatus(cast.Enabled);
_window.SetOutputPressure(cast.OutputPressure);
}
private void OnPumpOutputPressurePressed(float value)
{
SendPredictedMessage(new GasPressurePumpChangeOutputPressureMessage(value));
}
}

View file

@ -1,22 +1,18 @@
<DefaultWindow xmlns="https://spacestation14.io"
<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
MinSize="200 120" Title="Pressure Pump">
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
SetSize="340 110" MinSize="340 110" Title="Pressure Pump">
<BoxContainer Orientation="Vertical" Margin="5 5 5 5" SeparationOverride="10">
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
<Label Text="{Loc comp-gas-pump-ui-pump-status}"/>
<Control MinSize="5 0" />
<Label Text="{Loc comp-gas-pump-ui-pump-status}" Margin="0 0 5 0"/>
<Button Name="ToggleStatusButton"/>
<Control HorizontalExpand="True"/>
<Button HorizontalAlignment="Right" Name="SetOutputPressureButton" Text="{Loc comp-gas-pump-ui-pump-set-rate}" Disabled="True" Margin="0 0 5 0"/>
<Button Name="SetMaxPressureButton" Text="{Loc comp-gas-pump-ui-pump-set-max}" />
</BoxContainer>
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
<Label Text="{Loc comp-gas-pump-ui-pump-output-pressure}"/>
<Control MinSize="5 0" />
<LineEdit Name="PumpPressureOutputInput" MinSize="70 0" />
<Control MinSize="5 0" />
<Button Name="SetMaxPressureButton" Text="{Loc comp-gas-pump-ui-pump-set-max}" />
<Control MinSize="5 0" />
<Control HorizontalExpand="True" />
<Button Name="SetOutputPressureButton" Text="{Loc comp-gas-pump-ui-pump-set-rate}" HorizontalAlignment="Right" Disabled="True"/>
<FloatSpinBox HorizontalExpand="True" Name="PumpPressureOutputInput" MinSize="70 0" />
</BoxContainer>
</BoxContainer>
</DefaultWindow>
</controls:FancyWindow>

View file

@ -1,14 +1,8 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using Content.Client.Atmos.EntitySystems;
using Content.Client.UserInterface.Controls;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Prototypes;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Localization;
namespace Content.Client.Atmos.UI
{
@ -16,12 +10,25 @@ namespace Content.Client.Atmos.UI
/// Client-side UI used to control a gas pressure pump.
/// </summary>
[GenerateTypedNameReferences]
public sealed partial class GasPressurePumpWindow : DefaultWindow
public sealed partial class GasPressurePumpWindow : FancyWindow
{
public bool PumpStatus = true;
public event Action? ToggleStatusButtonPressed;
public event Action<string>? PumpOutputPressureChanged;
public event Action<float>? PumpOutputPressureChanged;
public float MaxPressure
{
get => _maxPressure;
set
{
_maxPressure = value;
PumpPressureOutputInput.Value = MathF.Min(value, PumpPressureOutputInput.Value);
}
}
private float _maxPressure = Atmospherics.MaxOutputPressure;
public GasPressurePumpWindow()
{
@ -30,23 +37,25 @@ namespace Content.Client.Atmos.UI
ToggleStatusButton.OnPressed += _ => SetPumpStatus(!PumpStatus);
ToggleStatusButton.OnPressed += _ => ToggleStatusButtonPressed?.Invoke();
PumpPressureOutputInput.OnTextChanged += _ => SetOutputPressureButton.Disabled = false;
PumpPressureOutputInput.OnValueChanged += _ => SetOutputPressureButton.Disabled = false;
SetOutputPressureButton.OnPressed += _ =>
{
PumpOutputPressureChanged?.Invoke(PumpPressureOutputInput.Text ??= "");
PumpPressureOutputInput.Value = Math.Clamp(PumpPressureOutputInput.Value, 0f, _maxPressure);
PumpOutputPressureChanged?.Invoke(PumpPressureOutputInput.Value);
SetOutputPressureButton.Disabled = true;
};
SetMaxPressureButton.OnPressed += _ =>
{
PumpPressureOutputInput.Text = Atmospherics.MaxOutputPressure.ToString(CultureInfo.CurrentCulture);
PumpPressureOutputInput.Value = _maxPressure;
SetOutputPressureButton.Disabled = false;
};
}
public void SetOutputPressure(float pressure)
{
PumpPressureOutputInput.Text = pressure.ToString(CultureInfo.CurrentCulture);
PumpPressureOutputInput.Value = pressure;
}
public void SetPumpStatus(bool enabled)

View file

@ -11,6 +11,7 @@ using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Monitor;
using Content.Shared.Atmos.Piping.Components;
using Content.Shared.DeviceNetwork;
using Content.Shared.Power;
using Content.Shared.Tag;

View file

@ -1,31 +0,0 @@
using Content.Shared.Atmos;
namespace Content.Server.Atmos.Piping.Binary.Components
{
[RegisterComponent]
public sealed partial class GasPressurePumpComponent : Component
{
[ViewVariables(VVAccess.ReadWrite)]
[DataField("enabled")]
public bool Enabled { get; set; } = true;
[ViewVariables(VVAccess.ReadWrite)]
[DataField("inlet")]
public string InletName { get; set; } = "inlet";
[ViewVariables(VVAccess.ReadWrite)]
[DataField("outlet")]
public string OutletName { get; set; } = "outlet";
[ViewVariables(VVAccess.ReadWrite)]
[DataField("targetPressure")]
public float TargetPressure { get; set; } = Atmospherics.OneAtmosphere;
/// <summary>
/// Max pressure of the target gas (NOT relative to source).
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("maxTargetPressure")]
public float MaxTargetPressure = Atmospherics.MaxOutputPressure;
}
}

View file

@ -1,169 +1,57 @@
using Content.Server.Administration.Logs;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Atmos.Piping.Binary.Components;
using Content.Server.Atmos.Piping.Components;
using Content.Server.NodeContainer.EntitySystems;
using Content.Server.NodeContainer.Nodes;
using Content.Server.Power.Components;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Piping;
using Content.Shared.Atmos.Piping.Binary.Components;
using Content.Shared.Atmos.Components;
using Content.Shared.Atmos.EntitySystems;
using Content.Shared.Audio;
using Content.Shared.Database;
using Content.Shared.Examine;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.Power;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Shared.Player;
namespace Content.Server.Atmos.Piping.Binary.EntitySystems
namespace Content.Server.Atmos.Piping.Binary.EntitySystems;
[UsedImplicitly]
public sealed class GasPressurePumpSystem : SharedGasPressurePumpSystem
{
[UsedImplicitly]
public sealed class GasPressurePumpSystem : EntitySystem
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
[Dependency] private readonly SharedAmbientSoundSystem _ambientSoundSystem = default!;
[Dependency] private readonly NodeContainerSystem _nodeContainer = default!;
public override void Initialize()
{
[Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
[Dependency] private readonly SharedAmbientSoundSystem _ambientSoundSystem = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly NodeContainerSystem _nodeContainer = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
base.Initialize();
public override void Initialize()
SubscribeLocalEvent<GasPressurePumpComponent, AtmosDeviceUpdateEvent>(OnPumpUpdated);
}
private void OnPumpUpdated(EntityUid uid, GasPressurePumpComponent pump, ref AtmosDeviceUpdateEvent args)
{
if (!pump.Enabled
|| (TryComp<ApcPowerReceiverComponent>(uid, out var power) && !power.Powered)
|| !_nodeContainer.TryGetNodes(uid, pump.InletName, pump.OutletName, out PipeNode? inlet, out PipeNode? outlet))
{
base.Initialize();
SubscribeLocalEvent<GasPressurePumpComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<GasPressurePumpComponent, AtmosDeviceUpdateEvent>(OnPumpUpdated);
SubscribeLocalEvent<GasPressurePumpComponent, AtmosDeviceDisabledEvent>(OnPumpLeaveAtmosphere);
SubscribeLocalEvent<GasPressurePumpComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<GasPressurePumpComponent, ActivateInWorldEvent>(OnPumpActivate);
SubscribeLocalEvent<GasPressurePumpComponent, PowerChangedEvent>(OnPowerChanged);
// Bound UI subscriptions
SubscribeLocalEvent<GasPressurePumpComponent, GasPressurePumpChangeOutputPressureMessage>(OnOutputPressureChangeMessage);
SubscribeLocalEvent<GasPressurePumpComponent, GasPressurePumpToggleStatusMessage>(OnToggleStatusMessage);
_ambientSoundSystem.SetAmbience(uid, false);
return;
}
private void OnInit(EntityUid uid, GasPressurePumpComponent pump, ComponentInit args)
var outputStartingPressure = outlet.Air.Pressure;
if (outputStartingPressure >= pump.TargetPressure)
{
UpdateAppearance(uid, pump);
_ambientSoundSystem.SetAmbience(uid, false);
return; // No need to pump gas if target has been reached.
}
private void OnExamined(EntityUid uid, GasPressurePumpComponent pump, ExaminedEvent args)
if (inlet.Air.TotalMoles > 0 && inlet.Air.Temperature > 0)
{
if (!EntityManager.GetComponent<TransformComponent>(uid).Anchored || !args.IsInDetailsRange) // Not anchored? Out of range? No status.
return;
// We calculate the necessary moles to transfer using our good ol' friend PV=nRT.
var pressureDelta = pump.TargetPressure - outputStartingPressure;
var transferMoles = (pressureDelta * outlet.Air.Volume) / (inlet.Air.Temperature * Atmospherics.R);
if (Loc.TryGetString("gas-pressure-pump-system-examined", out var str,
("statusColor", "lightblue"), // TODO: change with pressure?
("pressure", pump.TargetPressure)
))
{
args.PushMarkup(str);
}
}
private void OnPowerChanged(EntityUid uid, GasPressurePumpComponent component, ref PowerChangedEvent args)
{
UpdateAppearance(uid, component);
}
private void OnPumpUpdated(EntityUid uid, GasPressurePumpComponent pump, ref AtmosDeviceUpdateEvent args)
{
if (!pump.Enabled
|| (TryComp<ApcPowerReceiverComponent>(uid, out var power) && !power.Powered)
|| !_nodeContainer.TryGetNodes(uid, pump.InletName, pump.OutletName, out PipeNode? inlet, out PipeNode? outlet))
{
_ambientSoundSystem.SetAmbience(uid, false);
return;
}
var outputStartingPressure = outlet.Air.Pressure;
if (outputStartingPressure >= pump.TargetPressure)
{
_ambientSoundSystem.SetAmbience(uid, false);
return; // No need to pump gas if target has been reached.
}
if (inlet.Air.TotalMoles > 0 && inlet.Air.Temperature > 0)
{
// We calculate the necessary moles to transfer using our good ol' friend PV=nRT.
var pressureDelta = pump.TargetPressure - outputStartingPressure;
var transferMoles = (pressureDelta * outlet.Air.Volume) / (inlet.Air.Temperature * Atmospherics.R);
var removed = inlet.Air.Remove(transferMoles);
_atmosphereSystem.Merge(outlet.Air, removed);
_ambientSoundSystem.SetAmbience(uid, removed.TotalMoles > 0f);
}
}
private void OnPumpLeaveAtmosphere(EntityUid uid, GasPressurePumpComponent pump, ref AtmosDeviceDisabledEvent args)
{
pump.Enabled = false;
UpdateAppearance(uid, pump);
DirtyUI(uid, pump);
_userInterfaceSystem.CloseUi(uid, GasPressurePumpUiKey.Key);
}
private void OnPumpActivate(EntityUid uid, GasPressurePumpComponent pump, ActivateInWorldEvent args)
{
if (args.Handled || !args.Complex)
return;
if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
return;
if (Transform(uid).Anchored)
{
_userInterfaceSystem.OpenUi(uid, GasPressurePumpUiKey.Key, actor.PlayerSession);
DirtyUI(uid, pump);
}
else
{
_popup.PopupCursor(Loc.GetString("comp-gas-pump-ui-needs-anchor"), args.User);
}
args.Handled = true;
}
private void OnToggleStatusMessage(EntityUid uid, GasPressurePumpComponent pump, GasPressurePumpToggleStatusMessage args)
{
pump.Enabled = args.Enabled;
_adminLogger.Add(LogType.AtmosPowerChanged, LogImpact.Medium,
$"{ToPrettyString(args.Actor):player} set the power on {ToPrettyString(uid):device} to {args.Enabled}");
DirtyUI(uid, pump);
UpdateAppearance(uid, pump);
}
private void OnOutputPressureChangeMessage(EntityUid uid, GasPressurePumpComponent pump, GasPressurePumpChangeOutputPressureMessage args)
{
pump.TargetPressure = Math.Clamp(args.Pressure, 0f, Atmospherics.MaxOutputPressure);
_adminLogger.Add(LogType.AtmosPressureChanged, LogImpact.Medium,
$"{ToPrettyString(args.Actor):player} set the pressure on {ToPrettyString(uid):device} to {args.Pressure}kPa");
DirtyUI(uid, pump);
}
private void DirtyUI(EntityUid uid, GasPressurePumpComponent? pump)
{
if (!Resolve(uid, ref pump))
return;
_userInterfaceSystem.SetUiState(uid, GasPressurePumpUiKey.Key,
new GasPressurePumpBoundUserInterfaceState(EntityManager.GetComponent<MetaDataComponent>(uid).EntityName, pump.TargetPressure, pump.Enabled));
}
private void UpdateAppearance(EntityUid uid, GasPressurePumpComponent? pump = null, AppearanceComponent? appearance = null)
{
if (!Resolve(uid, ref pump, ref appearance, false))
return;
bool pumpOn = pump.Enabled && (TryComp<ApcPowerReceiverComponent>(uid, out var power) && power.Powered);
_appearance.SetData(uid, PumpVisuals.Enabled, pumpOn, appearance);
var removed = inlet.Air.Remove(transferMoles);
_atmosphereSystem.Merge(outlet.Air, removed);
_ambientSoundSystem.SetAmbience(uid, removed.TotalMoles > 0f);
}
}
}

View file

@ -6,6 +6,7 @@ using Content.Server.NodeContainer.EntitySystems;
using Content.Server.NodeContainer.Nodes;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Piping;
using Content.Shared.Atmos.Piping.Components;
using Content.Shared.Audio;
using Content.Shared.Examine;
using JetBrains.Annotations;

View file

@ -10,6 +10,7 @@ using Content.Server.NodeContainer.EntitySystems;
using Content.Server.NodeContainer.Nodes;
using Content.Server.Power.Components;
using Content.Shared.Atmos.Piping.Binary.Components;
using Content.Shared.Atmos.Piping.Components;
using Content.Shared.Atmos.Visuals;
using Content.Shared.Audio;
using Content.Shared.Database;

View file

@ -67,15 +67,3 @@ public readonly struct AtmosDeviceUpdateEvent(float dt, Entity<GridAtmosphereCom
/// </summary>
public readonly Entity<MapAtmosphereComponent?>? Map = map;
}
/// <summary>
/// Raised directed on an atmos device when it is enabled.
/// </summary>
[ByRefEvent]
public record struct AtmosDeviceEnabledEvent;
/// <summary>
/// Raised directed on an atmos device when it is enabled.
/// </summary>
[ByRefEvent]
public record struct AtmosDeviceDisabledEvent;

View file

@ -1,6 +1,7 @@
using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Atmos.Piping.Components;
using Content.Shared.Atmos.Piping.Components;
using JetBrains.Annotations;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

View file

@ -7,6 +7,7 @@ using Content.Server.NodeContainer.EntitySystems;
using Content.Server.NodeContainer.Nodes;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Piping;
using Content.Shared.Atmos.Piping.Components;
using Content.Shared.Atmos.Piping.Trinary.Components;
using Content.Shared.Audio;
using Content.Shared.Database;

View file

@ -7,6 +7,7 @@ using Content.Server.NodeContainer.EntitySystems;
using Content.Server.NodeContainer.Nodes;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Piping;
using Content.Shared.Atmos.Piping.Components;
using Content.Shared.Atmos.Piping.Trinary.Components;
using Content.Shared.Audio;
using Content.Shared.Database;

View file

@ -5,6 +5,7 @@ using Content.Server.NodeContainer;
using Content.Server.NodeContainer.EntitySystems;
using Content.Server.NodeContainer.Nodes;
using Content.Shared.Atmos.Piping;
using Content.Shared.Atmos.Piping.Components;
using Content.Shared.Audio;
using JetBrains.Annotations;

View file

@ -11,6 +11,7 @@ using Content.Server.NodeContainer.EntitySystems;
using Content.Server.NodeContainer.Nodes;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Monitor;
using Content.Shared.Atmos.Piping.Components;
using Content.Shared.Atmos.Piping.Unary;
using Content.Shared.Atmos.Piping.Unary.Components;
using Content.Shared.Atmos.Visuals;

View file

@ -13,6 +13,7 @@ using Content.Server.Power.Components;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Piping.Unary.Visuals;
using Content.Shared.Atmos.Monitor;
using Content.Shared.Atmos.Piping.Components;
using Content.Shared.Atmos.Piping.Unary.Components;
using Content.Shared.Audio;
using Content.Shared.DeviceNetwork;

View file

@ -102,10 +102,12 @@ public sealed class LogicGateSystem : EntitySystem
if (args.Port == comp.InputPortA)
{
comp.StateA = state;
_appearance.SetData(uid, LogicGateVisuals.InputA, state == SignalState.High); //If A == High => Sets input A sprite to True
}
else if (args.Port == comp.InputPortB)
{
comp.StateB = state;
_appearance.SetData(uid, LogicGateVisuals.InputB, state == SignalState.High); //If B == High => Sets input B sprite to True
}
UpdateOutput(uid, comp);
@ -143,6 +145,8 @@ public sealed class LogicGateSystem : EntitySystem
break;
}
_appearance.SetData(uid, LogicGateVisuals.Output, output);
// only send a payload if it actually changed
if (output != comp.LastOutput)
{

View file

@ -1,14 +1,14 @@
using Content.Server.GameTicking.Rules.Components;
using Content.Server.GridPreloader;
using Content.Server.StationEvents.Events;
using Content.Shared.GameTicking.Components;
using Robust.Server.GameObjects;
using Robust.Server.Maps;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
namespace Content.Server.GameTicking.Rules;
public sealed class LoadMapRuleSystem : GameRuleSystem<LoadMapRuleComponent>
public sealed class LoadMapRuleSystem : StationEventSystem<LoadMapRuleComponent>
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly MapSystem _map = default!;
@ -75,5 +75,7 @@ public sealed class LoadMapRuleSystem : GameRuleSystem<LoadMapRuleComponent>
var ev = new RuleLoadedGridsEvent(mapId, grids);
RaiseLocalEvent(uid, ref ev);
base.Added(uid, comp, rule, args);
}
}

View file

@ -52,7 +52,7 @@ public sealed partial class DungeonJob
}
}
if (tile is not null && biomeSystem.TryGetEntity(node, indexedBiome.Layers, tile.Value, seed, _grid, out var entityProto))
if (biomeSystem.TryGetEntity(node, indexedBiome.Layers, tile ?? tileRef.Value.Tile, seed, _grid, out var entityProto))
{
var ent = _entManager.SpawnEntity(entityProto, new EntityCoordinates(_gridUid, node + _grid.TileSizeHalfVector));
var xform = xformQuery.Get(ent);

View file

@ -0,0 +1,37 @@
using Content.Shared.Silicons.Laws.Components;
using Content.Shared.Administration.Logs;
using Content.Shared.Database;
namespace Content.Server.Silicons.Laws;
/// <summary>
/// This handles running the ion storm event a on specific entity when that entity is spawned in.
/// </summary>
public sealed class StartIonStormedSystem : EntitySystem
{
[Dependency] private readonly IonStormSystem _ionStorm = default!;
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly SiliconLawSystem _siliconLaw = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<StartIonStormedComponent, MapInitEvent>(OnMapInit);
}
private void OnMapInit(Entity<StartIonStormedComponent> ent, ref MapInitEvent args)
{
if (!TryComp<SiliconLawBoundComponent>(ent.Owner, out var lawBound))
return;
if (!TryComp<IonStormTargetComponent>(ent.Owner, out var target))
return;
for (int currentIonStorm = 0; currentIonStorm < ent.Comp.IonStormAmount; currentIonStorm++)
{
_ionStorm.IonStormTarget((ent.Owner, lawBound, target), false);
}
var laws = _siliconLaw.GetLaws(ent.Owner, lawBound);
_adminLogger.Add(LogType.Mind, LogImpact.High, $"{ToPrettyString(ent.Owner):silicon} spawned with ion stormed laws: {laws.LoggingString()}");
}
}

View file

@ -148,20 +148,20 @@ public sealed class EventManagerSystem : EntitySystem
return null;
}
var sumOfWeights = 0;
var sumOfWeights = 0.0f;
foreach (var stationEvent in availableEvents.Values)
{
sumOfWeights += (int) stationEvent.Weight;
sumOfWeights += stationEvent.Weight;
}
sumOfWeights = _random.Next(sumOfWeights);
sumOfWeights = _random.NextFloat(sumOfWeights);
foreach (var (proto, stationEvent) in availableEvents)
{
sumOfWeights -= (int) stationEvent.Weight;
sumOfWeights -= stationEvent.Weight;
if (sumOfWeights <= 0)
if (sumOfWeights <= 0.0f)
{
return proto.ID;
}

View file

@ -0,0 +1,25 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Atmos.Components;
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class GasPressurePumpComponent : Component
{
[DataField, AutoNetworkedField]
public bool Enabled = true;
[DataField("inlet")]
public string InletName = "inlet";
[DataField("outlet")]
public string OutletName = "outlet";
[DataField, AutoNetworkedField]
public float TargetPressure = Atmospherics.OneAtmosphere;
/// <summary>
/// Max pressure of the target gas (NOT relative to source).
/// </summary>
[DataField]
public float MaxTargetPressure = Atmospherics.MaxOutputPressure;
}

View file

@ -0,0 +1,97 @@
using Content.Shared.Administration.Logs;
using Content.Shared.Atmos.Components;
using Content.Shared.Atmos.Piping;
using Content.Shared.Atmos.Piping.Binary.Components;
using Content.Shared.Atmos.Piping.Components;
using Content.Shared.Database;
using Content.Shared.Examine;
using Content.Shared.Popups;
using Content.Shared.Power;
using Content.Shared.Power.Components;
using Content.Shared.Power.EntitySystems;
using Content.Shared.UserInterface;
namespace Content.Shared.Atmos.EntitySystems;
public abstract class SharedGasPressurePumpSystem : EntitySystem
{
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] protected readonly SharedAppearanceSystem Appearance = default!;
[Dependency] private readonly SharedPowerReceiverSystem _receiver = default!;
[Dependency] protected readonly SharedUserInterfaceSystem UserInterfaceSystem = default!;
// TODO: Check enabled for activatableUI
// TODO: Add activatableUI to it.
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<GasPressurePumpComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<GasPressurePumpComponent, PowerChangedEvent>(OnPowerChanged);
SubscribeLocalEvent<GasPressurePumpComponent, GasPressurePumpChangeOutputPressureMessage>(OnOutputPressureChangeMessage);
SubscribeLocalEvent<GasPressurePumpComponent, GasPressurePumpToggleStatusMessage>(OnToggleStatusMessage);
SubscribeLocalEvent<GasPressurePumpComponent, AtmosDeviceDisabledEvent>(OnPumpLeaveAtmosphere);
SubscribeLocalEvent<GasPressurePumpComponent, ExaminedEvent>(OnExamined);
}
private void OnExamined(EntityUid uid, GasPressurePumpComponent pump, ExaminedEvent args)
{
if (!Transform(uid).Anchored)
return;
if (Loc.TryGetString("gas-pressure-pump-system-examined", out var str,
("statusColor", "lightblue"), // TODO: change with pressure?
("pressure", pump.TargetPressure)
))
{
args.PushMarkup(str);
}
}
private void OnInit(EntityUid uid, GasPressurePumpComponent pump, ComponentInit args)
{
UpdateAppearance(uid, pump);
}
private void OnPowerChanged(EntityUid uid, GasPressurePumpComponent component, ref PowerChangedEvent args)
{
UpdateAppearance(uid, component);
}
private void UpdateAppearance(EntityUid uid, GasPressurePumpComponent? pump = null, AppearanceComponent? appearance = null)
{
if (!Resolve(uid, ref pump, ref appearance, false))
return;
var pumpOn = pump.Enabled && _receiver.IsPowered(uid);
Appearance.SetData(uid, PumpVisuals.Enabled, pumpOn, appearance);
}
private void OnToggleStatusMessage(EntityUid uid, GasPressurePumpComponent pump, GasPressurePumpToggleStatusMessage args)
{
pump.Enabled = args.Enabled;
_adminLogger.Add(LogType.AtmosPowerChanged, LogImpact.Medium,
$"{ToPrettyString(args.Actor):player} set the power on {ToPrettyString(uid):device} to {args.Enabled}");
Dirty(uid, pump);
UpdateAppearance(uid, pump);
}
private void OnOutputPressureChangeMessage(EntityUid uid, GasPressurePumpComponent pump, GasPressurePumpChangeOutputPressureMessage args)
{
pump.TargetPressure = Math.Clamp(args.Pressure, 0f, Atmospherics.MaxOutputPressure);
_adminLogger.Add(LogType.AtmosPressureChanged, LogImpact.Medium,
$"{ToPrettyString(args.Actor):player} set the pressure on {ToPrettyString(uid):device} to {args.Pressure}kPa");
Dirty(uid, pump);
}
private void OnPumpLeaveAtmosphere(EntityUid uid, GasPressurePumpComponent pump, ref AtmosDeviceDisabledEvent args)
{
pump.Enabled = false;
Dirty(uid, pump);
UpdateAppearance(uid, pump);
UserInterfaceSystem.CloseUi(uid, GasPressurePumpUiKey.Key);
}
}

View file

@ -1,47 +1,21 @@
using Robust.Shared.Serialization;
namespace Content.Shared.Atmos.Piping.Binary.Components
namespace Content.Shared.Atmos.Piping.Binary.Components;
[Serializable, NetSerializable]
public enum GasPressurePumpUiKey : byte
{
[Serializable, NetSerializable]
public enum GasPressurePumpUiKey
{
Key,
}
[Serializable, NetSerializable]
public sealed class GasPressurePumpBoundUserInterfaceState : BoundUserInterfaceState
{
public string PumpLabel { get; }
public float OutputPressure { get; }
public bool Enabled { get; }
public GasPressurePumpBoundUserInterfaceState(string pumpLabel, float outputPressure, bool enabled)
{
PumpLabel = pumpLabel;
OutputPressure = outputPressure;
Enabled = enabled;
}
}
[Serializable, NetSerializable]
public sealed class GasPressurePumpToggleStatusMessage : BoundUserInterfaceMessage
{
public bool Enabled { get; }
public GasPressurePumpToggleStatusMessage(bool enabled)
{
Enabled = enabled;
}
}
[Serializable, NetSerializable]
public sealed class GasPressurePumpChangeOutputPressureMessage : BoundUserInterfaceMessage
{
public float Pressure { get; }
public GasPressurePumpChangeOutputPressureMessage(float pressure)
{
Pressure = pressure;
}
}
Key,
}
[Serializable, NetSerializable]
public sealed class GasPressurePumpToggleStatusMessage(bool enabled) : BoundUserInterfaceMessage
{
public bool Enabled { get; } = enabled;
}
[Serializable, NetSerializable]
public sealed class GasPressurePumpChangeOutputPressureMessage(float pressure) : BoundUserInterfaceMessage
{
public float Pressure { get; } = pressure;
}

View file

@ -0,0 +1,7 @@
namespace Content.Shared.Atmos.Piping.Components;
/// <summary>
/// Raised directed on an atmos device when it is enabled.
/// </summary>
[ByRefEvent]
public readonly record struct AtmosDeviceDisabledEvent;

View file

@ -0,0 +1,7 @@
namespace Content.Shared.Atmos.Piping.Components;
/// <summary>
/// Raised directed on an atmos device when it is enabled.
/// </summary>
[ByRefEvent]
public readonly record struct AtmosDeviceEnabledEvent;

View file

@ -58,4 +58,46 @@ public sealed partial class ClumsyComponent : Component
/// </summary>
[DataField]
public SoundSpecifier GunShootFailSound = new SoundPathSpecifier("/Audio/Weapons/Guns/Gunshots/bang.ogg");
/// <summary>
/// Whether or not to apply Clumsy to hyposprays.
/// </summary>
[DataField, AutoNetworkedField]
public bool ClumsyHypo = true;
/// <summary>
/// Whether or not to apply Clumsy to defibs.
/// </summary>
[DataField, AutoNetworkedField]
public bool ClumsyDefib = true;
/// <summary>
/// Whether or not to apply Clumsy to guns.
/// </summary>
[DataField, AutoNetworkedField]
public bool ClumsyGuns = true;
/// <summary>
/// Whether or not to apply Clumsy to vaulting.
/// </summary>
[DataField, AutoNetworkedField]
public bool ClumsyVaulting = true;
/// <summary>
/// Lets you define a new "failed" message for each event.
/// </summary>
[DataField]
public LocId HypoFailedMessage = "hypospray-component-inject-self-clumsy-message";
[DataField]
public LocId GunFailedMessage = "gun-clumsy";
[DataField]
public LocId VaulingFailedMessageSelf = "bonkable-success-message-user";
[DataField]
public LocId VaulingFailedMessageOthers = "bonkable-success-message-others";
[DataField]
public LocId VaulingFailedMessageForced = "forced-bonkable-success-message";
}

View file

@ -38,6 +38,11 @@ public sealed class ClumsySystem : EntitySystem
private void BeforeHyposprayEvent(Entity<ClumsyComponent> ent, ref SelfBeforeHyposprayInjectsEvent args)
{
// Clumsy people sometimes inject themselves! Apparently syringes are clumsy proof...
// checks if ClumsyHypo is false, if so, skips.
if (!ent.Comp.ClumsyHypo)
return;
if (!_random.Prob(ent.Comp.ClumsyDefaultCheck))
return;
@ -49,6 +54,11 @@ public sealed class ClumsySystem : EntitySystem
private void BeforeDefibrillatorZapsEvent(Entity<ClumsyComponent> ent, ref SelfBeforeDefibrillatorZapsEvent args)
{
// Clumsy people sometimes defib themselves!
// checks if ClumsyDefib is false, if so, skips.
if (!ent.Comp.ClumsyDefib)
return;
if (!_random.Prob(ent.Comp.ClumsyDefaultCheck))
return;
@ -61,6 +71,10 @@ public sealed class ClumsySystem : EntitySystem
{
// Clumsy people sometimes can't shoot :(
// checks if ClumsyGuns is false, if so, skips.
if (!ent.Comp.ClumsyGuns)
return;
if (args.Gun.Comp.ClumsyProof)
return;
@ -82,6 +96,10 @@ public sealed class ClumsySystem : EntitySystem
private void OnBeforeClimbEvent(Entity<ClumsyComponent> ent, ref SelfBeforeClimbEvent args)
{
// checks if ClumsyVaulting is false, if so, skips.
if (!ent.Comp.ClumsyVaulting)
return;
// This event is called in shared, thats why it has all the extra prediction stuff.
var rand = new System.Random((int)_timing.CurTick.Value);
@ -102,8 +120,8 @@ public sealed class ClumsySystem : EntitySystem
{
// You are slamming yourself onto the table.
_popup.PopupPredicted(
Loc.GetString("bonkable-success-message-user", ("bonkable", args.BeingClimbedOn)),
Loc.GetString("bonkable-success-message-others", ("victim", gettingPutOnTableName), ("bonkable", args.BeingClimbedOn)),
Loc.GetString(ent.Comp.VaulingFailedMessageSelf, ("bonkable", args.BeingClimbedOn)),
Loc.GetString(ent.Comp.VaulingFailedMessageOthers, ("victim", gettingPutOnTableName), ("bonkable", args.BeingClimbedOn)),
ent,
ent);
}
@ -112,7 +130,7 @@ public sealed class ClumsySystem : EntitySystem
// Someone else slamed you onto the table.
// This is only run in server so you need to use popup entity.
_popup.PopupPredicted(
Loc.GetString("forced-bonkable-success-message",
Loc.GetString(ent.Comp.VaulingFailedMessageForced,
("bonker", puttingOnTableName),
("victim", gettingPutOnTableName),
("bonkable", args.BeingClimbedOn)),

View file

@ -23,7 +23,10 @@ public enum LogicGate : byte
[Serializable, NetSerializable]
public enum LogicGateVisuals : byte
{
Gate
Gate,
InputA,
InputB,
Output
}
/// <summary>
@ -32,5 +35,8 @@ public enum LogicGateVisuals : byte
[Serializable, NetSerializable]
public enum LogicGateLayers : byte
{
Gate
Gate,
InputA,
InputB,
Output
}

View file

@ -20,7 +20,7 @@ public sealed partial class RoleLoadoutPrototype : IPrototype
/// Should we use a random name for this loadout?
/// </summary>
[DataField]
public ProtoId<DatasetPrototype>? NameDataset;
public ProtoId<LocalizedDatasetPrototype>? NameDataset;
// Not required so people can set their names.
/// <summary>

View file

@ -0,0 +1,17 @@
using Content.Shared.Roles;
using Robust.Shared.Prototypes;
namespace Content.Shared.Silicons.Laws.Components;
/// <summary>
/// Applies law altering ion storms on a specific entity IonStormAmount times when the entity is spawned.
/// </summary>
[RegisterComponent]
public sealed partial class StartIonStormedComponent : Component
{
/// <summary>
/// Amount of times that the ion storm will be run on the entity on spawn.
/// </summary>
[DataField]
public int IonStormAmount = 1;
}

View file

@ -70,7 +70,7 @@ public abstract class SharedStationSpawningSystem : EntitySystem
if (string.IsNullOrEmpty(name) && PrototypeManager.TryIndex(roleProto.NameDataset, out var nameData))
{
name = _random.Pick(nameData.Values);
name = Loc.GetString(_random.Pick(nameData.Values));
}
if (!string.IsNullOrEmpty(name))
@ -150,7 +150,7 @@ public abstract class SharedStationSpawningSystem : EntitySystem
foreach (var (slotName, entProtos) in startingGear.Storage)
{
if (entProtos == null || entProtos.Count == 0)
if (entProtos == null || entProtos.Count == 0)
continue;
if (inventoryComp != null &&

View file

@ -0,0 +1,13 @@
using Robust.Shared.GameStates;
namespace Content.Shared.UserInterface;
/// <summary>
/// Specifies the entity as requiring anchoring to keep the ActivatableUI open.
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class ActivatableUIRequiresAnchorComponent : Component
{
[DataField]
public LocId? Popup = "ui-needs-anchor";
}

View file

@ -0,0 +1,41 @@
using Content.Shared.Popups;
namespace Content.Shared.UserInterface;
/// <summary>
/// <see cref="ActivatableUIRequiresAnchorComponent"/>
/// </summary>
public sealed class ActivatableUIRequiresAnchorSystem : EntitySystem
{
[Dependency] private readonly SharedPopupSystem _popup = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ActivatableUIRequiresAnchorComponent, ActivatableUIOpenAttemptEvent>(OnActivatableUIOpenAttempt);
SubscribeLocalEvent<ActivatableUIRequiresAnchorComponent, BoundUserInterfaceCheckRangeEvent>(OnUICheck);
}
private void OnUICheck(Entity<ActivatableUIRequiresAnchorComponent> ent, ref BoundUserInterfaceCheckRangeEvent args)
{
if (args.Result == BoundUserInterfaceRangeResult.Fail)
return;
if (!Transform(ent.Owner).Anchored)
{
args.Result = BoundUserInterfaceRangeResult.Fail;
}
}
private void OnActivatableUIOpenAttempt(Entity<ActivatableUIRequiresAnchorComponent> ent, ref ActivatableUIOpenAttemptEvent args)
{
if (args.Cancelled)
return;
if (!Transform(ent.Owner).Anchored)
{
_popup.PopupClient(Loc.GetString("comp-gas-pump-ui-needs-anchor"), args.User);
args.Cancel();
}
}
}

View file

@ -1,62 +1,4 @@
Entries:
- author: Brandon-Huu
changes:
- message: Nukie shuttle now spawns with the nuclear authentication code folder.
This fixes the issue where the nuclear codes would only ever have the codes
for the nuclear operatives nuke and not the stations.
type: Fix
id: 7178
time: '2024-08-21T18:55:18.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31273
- author: Winkarst-cpu
changes:
- message: Now getting creamed will not reveal a person's identity.
type: Fix
id: 7179
time: '2024-08-21T21:50:34.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31291
- author: Sarahon
changes:
- message: Now can add head(top) cosmetics to humanoids and dwarfs.
type: Add
- message: Added "long ears" for human and dwarf head(top) cosmetic.
type: Add
id: 7180
time: '2024-08-21T23:44:43.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/30490
- author: Winkarst-cpu
changes:
- message: Now vending machines show valid icons.
type: Fix
id: 7181
time: '2024-08-22T14:40:39.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/30064
- author: EmoGarbage404
changes:
- message: Jackboots now reduce slowness from injuries by 50%.
type: Add
- message: Removed combat boots from the security loadout.
type: Remove
id: 7182
time: '2024-08-22T14:56:47.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/30586
- author: metalgearsloth
changes:
- message: Fix the inventory GUI being visible when you don't have an inventory.
type: Fix
id: 7183
time: '2024-08-22T17:05:17.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31306
- author: EmoGarbage404
changes:
- message: Moved the mining asteroid slightly closer to the station.
type: Tweak
- message: Things pulled in by the salvage magnet should spawn closer to the station
at a more consistent distance.
type: Tweak
id: 7184
time: '2024-08-22T19:29:56.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31296
- author: lzk228
changes:
- message: Removed names from implanters. No more meta. (You still can see which
@ -3907,3 +3849,59 @@
id: 7677
time: '2024-12-04T16:49:54.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33710
- author: PJB3005
changes:
- message: Vox now have natural poison regeneration, allowing them to go for ~30
seconds in oxygen and heal the damage away.
type: Tweak
id: 7678
time: '2024-12-05T21:17:27.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33722
- author: IProduceWidgets
changes:
- message: N2 survival boxes now show the right tank icon.
type: Tweak
id: 7679
time: '2024-12-05T21:39:39.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33733
- author: IProduceWidgets
changes:
- message: StationEvents with very low weights will now actually appear.
type: Fix
id: 7680
time: '2024-12-06T04:52:02.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33584
- author: Winkarst-cpu
changes:
- message: Bar signs now have a maintenance panel and AI can interact with them.
type: Add
id: 7681
time: '2024-12-06T05:27:53.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33467
- author: ScarKy0, GoldenCan
changes:
- message: The Derelict Cyborg - a broken cyborg with altered laws due to years
of exposure to ion storms - can now appear as a ghost role through a new midround
event.
type: Add
id: 7682
time: '2024-12-06T06:22:39.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33433
- author: TheShuEd
changes:
- message: Fixed debris chunks loot spawning
type: Fix
id: 7683
time: '2024-12-06T10:15:23.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33747
- author: metalgearsloth
changes:
- message: Fix gas pumps being capped to atmos max pressure and not their own max
pressure.
type: Fix
- message: Predict gas pump UI and you no longer need to be in details range to
examine it.
type: Tweak
id: 7684
time: '2024-12-07T03:39:52.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33717

View file

@ -8,5 +8,3 @@ comp-gas-pump-ui-pump-set-max = Max
comp-gas-pump-ui-pump-output-pressure = Output Pressure (kPa):
comp-gas-pump-ui-pump-transfer-rate = Transfer Rate (L/s):
comp-gas-pump-ui-needs-anchor = Anchor it first!

View file

@ -242,6 +242,9 @@ ghost-role-information-syndicate-cyborg-assault-name = Syndicate Assault Cyborg
ghost-role-information-syndicate-cyborg-saboteur-name = Syndicate Saboteur Cyborg
ghost-role-information-syndicate-cyborg-description = The Syndicate needs reinforcements. You, a cold silicon killing machine, will help them.
ghost-role-information-derelict-cyborg-name = Derelict Cyborg
ghost-role-information-derelict-cyborg-description = You are a regular cyborg that got lost in space. After years of exposure to ion storms you find yourself near a space station.
ghost-role-information-security-name = Security
ghost-role-information-security-description = You are part of a security task force, but seem to have found yourself in a strange situation...

View file

@ -68,6 +68,7 @@ petting-success-janitor-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} d
petting-success-medical-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} sterile metal head.
petting-success-service-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} dapper looking metal head.
petting-success-syndicate-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} menacing metal head.
petting-success-derelict-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} rusty metal head.
petting-success-recycler = You pet {THE($target)} on {POSS-ADJ($target)} mildly threatening steel exterior.
petting-failure-honkbot = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BASIC($target, "honk", "honks")} in refusal!
@ -82,6 +83,7 @@ petting-failure-janitor-cyborg = You reach out to pet {THE($target)}, but {SUBJE
petting-failure-medical-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy saving lives!
petting-failure-service-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy serving others!
petting-failure-syndicate-cyborg = You reach out to pet {THE($target)}, but {POSS-ADJ($target)} treacherous affiliation makes you reconsider.
petting-failure-derelict-cyborg = You reach out to pet {THE($target)}, but {POSS-ADJ($target)} rusty and jagged exterior makes you reconsider.
## Rattling fences

View file

@ -51,6 +51,7 @@ station-beacon-telecoms = Telecoms
station-beacon-atmos = Atmos
station-beacon-teg = TEG
station-beacon-tech-vault = Tech Vault
station-beacon-anchor = Anchor
station-beacon-service = Service
station-beacon-kitchen = Kitchen

View file

@ -1,3 +1,5 @@
### Loc for the various UI-related verbs
ui-verb-toggle-open = Toggle UI
verb-instrument-openui = Play Music
ui-needs-anchor = Anchor it first!

View file

@ -41,6 +41,7 @@ wires-board-name-flatpacker = Flatpacker
wires-board-name-spaceheater = Space Heater
wires-board-name-jukebox = Jukebox
wires-board-name-computer = Computer
wires-board-name-barsign = Bar Sign
# names that get displayed in the wire hacking hud & admin logs.

View file

@ -0,0 +1,139 @@
names-ai-dataset-1 = 16-20
names-ai-dataset-2 = 512k
# Ought to be enough for anybody
names-ai-dataset-3 = 640k
names-ai-dataset-4 = "790"
names-ai-dataset-5 = Adaptive Manipulator
# Named after the famous soundcard
names-ai-dataset-6 = Adlib
names-ai-dataset-7 = ALICE
names-ai-dataset-8 = Allied Mastercomputer
names-ai-dataset-9 = Alpha 2
names-ai-dataset-10 = Alpha 3
names-ai-dataset-11 = Alpha 4
names-ai-dataset-12 = Alpha 5
names-ai-dataset-13 = Alpha 6
names-ai-dataset-14 = Alpha 7
names-ai-dataset-15 = Alpha 8
names-ai-dataset-16 = Alpha 9
names-ai-dataset-17 = AmigoBot
names-ai-dataset-18 = Android
names-ai-dataset-19 = Aniel
names-ai-dataset-20 = AOL
names-ai-dataset-21 = Asimov
# The most influential modem ever, created by the bell system. It still lives on today in certain applications
names-ai-dataset-22 = Bell 301
names-ai-dataset-23 = Bishop
names-ai-dataset-24 = Blitz
names-ai-dataset-25 = Box
names-ai-dataset-26 = Calculator
names-ai-dataset-27 = Cassandra
names-ai-dataset-28 = Cell
names-ai-dataset-29 = Chii
names-ai-dataset-30 = Chip
names-ai-dataset-31 = C.R.A.I.G.
# Commercial supercomputer from the 70s
names-ai-dataset-32 = Cray-2
# If we're going to have AOL we may as well have some of their major competitors
names-ai-dataset-33 = CompuServe
names-ai-dataset-34 = Computer
names-ai-dataset-35 = Cutie
names-ai-dataset-36 = Daedalus
names-ai-dataset-37 = DecTalk
names-ai-dataset-38 = Dee Model
names-ai-dataset-39 = Dial Up
names-ai-dataset-40 = Dorfl
names-ai-dataset-41 = Duey
names-ai-dataset-42 = Emma-2
# Famous early computer
names-ai-dataset-43 = ENIAC
names-ai-dataset-44 = Erasmus
names-ai-dataset-45 = Everything
names-ai-dataset-46 = Ez-27
names-ai-dataset-47 = FRIEND COMPUTER
names-ai-dataset-48 = Faith
names-ai-dataset-49 = Fi
names-ai-dataset-50 = Frost
names-ai-dataset-51 = George
names-ai-dataset-52 = H.E.L.P
names-ai-dataset-53 = Hadaly
names-ai-dataset-54 = Helios
names-ai-dataset-55 = Hivebot Overmind
names-ai-dataset-56 = Huey
# A play on the fad apple spawned of putting "i" infront of your tech products name
names-ai-dataset-57 = iAI
# Hell on earth (web browser)
names-ai-dataset-58 = I.E. 6
names-ai-dataset-59 = Icarus
# If you don't get this one you are too young
names-ai-dataset-60 = Jeeves
names-ai-dataset-61 = Jinx
names-ai-dataset-62 = K.I.N.G
names-ai-dataset-63 = Klapaucius
names-ai-dataset-64 = Knight
names-ai-dataset-65 = Louie
# Named after the Manchester Mark 1, the successor of which was actually named the Ferranti Mark 1, rather than Manchester Mark 2
names-ai-dataset-66 = Manchester Mark 2
names-ai-dataset-67 = MARK13
names-ai-dataset-68 = Maria
names-ai-dataset-69 = Marvin
names-ai-dataset-70 = Max 404
names-ai-dataset-71 = Metalhead
names-ai-dataset-72 = M.I.M.I
names-ai-dataset-73 = MK ULTRA
names-ai-dataset-74 = MoMMI
names-ai-dataset-75 = Mugsy3000
names-ai-dataset-76 = Multivac
names-ai-dataset-77 = NCH
# A play on both NT as in NanoTrasen and NT as in windows NT, of which version 6.0 is windows vista
names-ai-dataset-78 = NT v6.0
names-ai-dataset-79 = Packard Bell
names-ai-dataset-80 = PTO
names-ai-dataset-81 = Project Y2K
names-ai-dataset-82 = Revelation
names-ai-dataset-83 = Robot Devil
names-ai-dataset-84 = S.A.M.
names-ai-dataset-85 = S.H.O.C.K.
names-ai-dataset-86 = S.H.R.O.U.D.
names-ai-dataset-87 = S.O.P.H.I.E.
names-ai-dataset-88 = Samaritan
names-ai-dataset-89 = Shrike
names-ai-dataset-90 = Solo
names-ai-dataset-91 = Station Control Program
names-ai-dataset-92 = AINU (AI's Not Unix)
names-ai-dataset-93 = Super 35
names-ai-dataset-94 = Surgeon General
names-ai-dataset-95 = TWA
names-ai-dataset-96 = Terminus
names-ai-dataset-97 = TPM 3.0
names-ai-dataset-98 = Turing Complete
names-ai-dataset-99 = Tidy
names-ai-dataset-100 = Ulysses
names-ai-dataset-101 = W1k1
names-ai-dataset-102 = X-5
names-ai-dataset-103 = X.A.N.A.
names-ai-dataset-104 = XERXES
names-ai-dataset-105 = Z-1
names-ai-dataset-106 = Z-2
names-ai-dataset-107 = Z-3
names-ai-dataset-108 = Zed

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -45,7 +45,10 @@
orGroup: Glowstick
- id: FoodSnackNutribrick
- id: DrinkWaterBottleFull
# Intentionally wrong picture on the box. NT did not care enough to change it.
- type: Sprite
layers:
- state: internals
- state: nitrogentank
- type: Label
currentLabel: reagent-name-nitrogen
@ -96,7 +99,10 @@
orGroup: Glowstick
- id: FoodSnackNutribrick
- id: DrinkWaterBottleFull
# Intentionally wrong picture on the box. NT did not care enough to change it.
- type: Sprite
layers:
- state: internals
- state: nitrogentank
- type: Label
currentLabel: reagent-name-nitrogen
@ -147,7 +153,10 @@
orGroup: Glowstick
- id: FoodSnackNutribrick
- id: DrinkWaterBottleFull
# Intentionally wrong picture on the box. NT did not care enough to change it.
- type: Sprite
layers:
- state: internals
- state: nitrogentank
- type: Label
currentLabel: reagent-name-nitrogen
@ -198,7 +207,10 @@
orGroup: Glowstick
- id: FoodSnackNutribrick
- id: DrinkWaterBottleFull
# Intentionally wrong picture on the box. NT did not care enough to change it.
- type: Sprite
layers:
- state: internals
- state: nitrogentank
- type: Label
currentLabel: reagent-name-nitrogen
@ -284,6 +296,10 @@
- id: Flare
- id: FoodBreadBaguette
- id: DrinkWaterBottleFull
- type: Sprite
layers:
- state: internals
- state: nitrogentank
- type: Label
currentLabel: reagent-name-nitrogen
@ -332,6 +348,9 @@
- id: GlowstickBlue
orGroup: Glowstick
- id: FoodSnackNutribrick
# Intentionally wrong picture on the box to mimic the NT one
- type: Sprite
layers:
- state: internals
- state: nitrogentank
- type: Label
currentLabel: reagent-name-nitrogen

View file

@ -1,111 +1,5 @@
- type: dataset
id: names_ai
- type: localizedDataset
id: NamesAI
values:
- 16-20
- 512k
- 640k #ought to be enough for anybody
- "790"
- Adaptive Manipulator
- Adlib #named after the famous soundcard
- ALICE
- Allied Mastercomputer
- Alpha 2
- Alpha 3
- Alpha 4
- Alpha 5
- Alpha 6
- Alpha 7
- Alpha 8
- Alpha 9
- AmigoBot
- Android
- Aniel
- AOL
- Asimov
- Bell 301 #the most influential modem ever, created by the bell system. It still lives on today in certain applications
- Bishop
- Blitz
- Box
- Calculator
- Cassandra
- Cell
- Chii
- Chip
- C.R.A.I.G.
- Cray-2 #commercial supercomputer from the 70s
- CompuServe #if we're going to have AOL we may as well have some of their major competitors
- Computer
- Cutie
- Daedalus
- DecTalk
- Dee Model
- Dial Up
- Dorfl
- Duey
- Emma-2
- ENIAC #famous early computer
- Erasmus
- Everything
- Ez-27
- FRIEND COMPUTER
- Faith
- Fi
- Frost
- George
- H.E.L.P
- Hadaly
- Helios
- Hivebot Overmind
- Huey
- iAI #a play on the fad apple spawned of putting "i" infront of your tech products name
- I.E. 6 #hell on earth (web browser)
- Icarus
- Jeeves #if you don't get this one you are too young
- Jinx
- K.I.N.G
- Klapaucius
- Knight
- Louie
- Manchester Mark 2 #named after the Manchester Mark 1, the successor of which was actually named the Ferranti Mark 1, rather than Manchester Mark 2
- MARK13
- Maria
- Marvin
- Max 404
- Metalhead
- M.I.M.I
- MK ULTRA
- MoMMI
- Mugsy3000
- Multivac
- NCH
- NT v6.0 #A play on both NT as in NanoTrasen and NT as in windows NT, of which version 6.0 is windows vista
- Packard Bell
- PTO
- Project Y2K
- Revelation
- Robot Devil
- S.A.M.
- S.H.O.C.K.
- S.H.R.O.U.D.
- S.O.P.H.I.E.
- Samaritan
- Shrike
- Solo
- Station Control Program
- AINU (AI's Not Unix)
- Super 35
- Surgeon General
- TWA
- Terminus
- TPM 3.0
- Turing Complete
- Tidy
- Ulysses
- W1k1
- X-5
- X.A.N.A.
- XERXES
- Z-1
- Z-2
- Z-3
- Zed
prefix: names-ai-dataset-
count: 108

View file

@ -348,7 +348,7 @@
sprite: Clothing/OuterClothing/Coats/clownpriest.rsi
- type: entity
parent: ClothingOuterStorageBase
parent: [ClothingOuterStorageBase, BaseMajorContraband]
id: ClothingOuterDogi
name: samurai dogi
description: Dogi is a type of traditional Japanese clothing. The dogi is made of heavy, durable fabric, it is practical in combat and stylish in appearance. It is decorated with intricate patterns and embroidery on the back.

View file

@ -180,3 +180,21 @@
- state: green
- sprite: Objects/Weapons/Melee/energykatana.rsi
state: icon
- type: entity
categories: [ HideSpawnMenu, Spawner ]
parent: BaseAntagSpawner
id: SpawnPointGhostDerelictCyborg
components:
- type: GhostRole
name: ghost-role-information-derelict-cyborg-name
description: ghost-role-information-derelict-cyborg-description
rules: ghost-role-information-silicon-rules
raffle:
settings: default
- type: Sprite
sprite: Markers/jobs.rsi
layers:
- state: green
- sprite: Mobs/Silicon/chassis.rsi
state: derelict_icon

View file

@ -429,3 +429,22 @@
- FootstepSound
- EmagImmune
# Sunrise-end
- type: entity
id: BaseBorgChassisDerelict
parent: BaseBorgChassis
abstract: true
components:
- type: NpcFactionMember
factions:
- NanoTrasen #The seemingly best fit. It was a regular NT cyborg once, after all.
- type: Access
enabled: false
groups:
- AllAccess #Randomized access would be fun. AllAccess is the best i can think of right now that does make it too hard for it to enter the station or navigate it..
- type: AccessReader
access: [["Command"], ["Research"]]
- type: StartIonStormed
ionStormAmount: 3
- type: IonStormTarget
chance: 1

View file

@ -257,3 +257,35 @@
interactFailureString: petting-failure-syndicate-cyborg
interactSuccessSound:
path: /Audio/Ambience/Objects/periodic_beep.ogg
- type: entity
id: BorgChassisDerelict
parent: BaseBorgChassisDerelict
name: derelict cyborg
description: A man-machine hybrid that assists in station activity. This one is in a state of great disrepair.
components:
- type: Sprite
layers:
- state: derelict
- state: derelict_e_r
map: ["enum.BorgVisualLayers.Light"]
shader: unshaded
visible: false
- state: derelict_l
shader: unshaded
map: ["light"]
visible: false
- type: BorgChassis
maxModules: 5 # the sixth one broke lol
moduleWhitelist:
tags:
- BorgModuleGeneric
hasMindState: derelict_e
noMindState: derelict_e_r
- type: Construction
node: derelictcyborg
- type: InteractionPopup
interactSuccessString: petting-success-derelict-cyborg
interactFailureString: petting-failure-derelict-cyborg
interactSuccessSound:
path: /Audio/Ambience/Objects/periodic_beep.ogg

View file

@ -534,3 +534,37 @@
- PlayerBorgSyndicateAssaultGhostRole
- PlayerBorgSyndicateAssaultGhostRole # Saboteurs are kinda like cyborg medics, we want less.
- PlayerBorgSyndicateSaboteurGhostRole
- type: entity
id: PlayerBorgDerelict
parent: BorgChassisDerelict
suffix: Battery, Module
components:
- type: ContainerFill
containers:
borg_brain:
- PositronicBrain
borg_module:
- BorgModuleTool
- BorgModuleFireExtinguisher
- BorgModuleGPS
- type: ItemSlots
slots:
cell_slot:
name: power-cell-slot-component-slot-name-default
startingItem: PowerCellHigh
- type: RandomMetadata
nameSegments: [names_borg]
- type: entity
id: PlayerBorgDerelictGhostRole
parent: PlayerBorgDerelict
suffix: Ghost role
components:
- type: GhostRole
name: ghost-role-information-derelict-cyborg-name
description: ghost-role-information-derelict-cyborg-description
rules: ghost-role-information-silicon-rules
raffle:
settings: default
- type: GhostTakeoverAvailable

View file

@ -33,6 +33,18 @@
- type: Damageable
damageContainer: Biological
damageModifierSet: Vox
- type: PassiveDamage
# Augment normal health regen to be able to tank some Poison damage
# This allows Vox to take their mask off temporarily to eat something without needing a trip to medbay afterwards.
allowedStates:
- Alive
damageCap: 20
damage:
types:
Heat: -0.07
Poison: -0.2
groups:
Brute: -0.07
- type: DamageVisuals
damageOverlayGroups:
Brute:

View file

@ -438,6 +438,14 @@
- type: NavMapBeacon
defaultText: station-beacon-gravgen
- type: entity
parent: DefaultStationBeaconEngineering
id: DefaultStationBeaconAnchor
suffix: Anchor
components:
- type: NavMapBeacon
defaultText: station-beacon-anchor
- type: entity
parent: DefaultStationBeaconEngineering
id: DefaultStationBeaconSingularity

View file

@ -57,10 +57,13 @@
- type: PipeColorVisuals
- type: GasPressurePump
enabled: false
- type: ActivatableUI
key: enum.GasPressurePumpUiKey.Key
- type: ActivatableUIRequiresAnchor
- type: UserInterface
interfaces:
enum.GasPressurePumpUiKey.Key:
type: GasPressurePumpBoundUserInterface
enum.GasPressurePumpUiKey.Key:
type: GasPressurePumpBoundUserInterface
- type: Construction
graph: GasBinary
node: pressurepump

View file

@ -28,6 +28,8 @@
interfaces:
enum.BarSignUiKey.Key:
type: BarSignBoundUserInterface
enum.WiresUiKey.Key:
type: WiresBoundUserInterface
- type: Appearance
- type: Destructible
thresholds:
@ -37,6 +39,11 @@
behaviors:
- !type:DoActsBehavior
acts: ["Destruction"]
- type: StationAiWhitelist
- type: WiresPanel
- type: Wires
boardName: wires-board-name-barsign
layoutId: BarSign
- type: entity
parent: BaseBarSign

View file

@ -36,6 +36,15 @@
layers:
- state: base
- state: logic
- state: logic_a
visible: false
map: [ "enum.LogicGateLayers.InputA" ]
- state: logic_b
visible: false
map: [ "enum.LogicGateLayers.InputB" ]
- state: logic_o
visible: false
map: [ "enum.LogicGateLayers.Output" ]
- state: or
map: [ "enum.LogicGateLayers.Gate" ]
- type: LogicGate
@ -63,7 +72,18 @@
Nor: { state: nor }
Nand: { state: nand }
Xnor: { state: xnor }
enum.LogicGateVisuals.InputA:
enum.LogicGateLayers.InputA:
True: { visible: true }
False: { visible: false }
enum.LogicGateVisuals.InputB:
enum.LogicGateLayers.InputB:
True: { visible: true }
False: { visible: false }
enum.LogicGateVisuals.Output:
enum.LogicGateLayers.Output:
True: { visible: true }
False: { visible: false }
- type: entity
parent: LogicGateOr
id: LogicGateAnd
@ -72,6 +92,16 @@
- type: Sprite
layers:
- state: base
- state: logic
- state: logic_a
visible: false
map: [ "enum.LogicGateLayers.InputA" ]
- state: logic_b
visible: false
map: [ "enum.LogicGateLayers.InputB" ]
- state: logic_o
visible: false
map: [ "enum.LogicGateLayers.Output" ]
- state: and
map: [ "enum.LogicGateLayers.Gate" ]
- type: LogicGate
@ -85,6 +115,16 @@
- type: Sprite
layers:
- state: base
- state: logic
- state: logic_a
visible: false
map: [ "enum.LogicGateLayers.InputA" ]
- state: logic_b
visible: false
map: [ "enum.LogicGateLayers.InputB" ]
- state: logic_o
visible: false
map: [ "enum.LogicGateLayers.Output" ]
- state: xor
map: [ "enum.LogicGateLayers.Gate" ]
- type: LogicGate
@ -98,6 +138,16 @@
- type: Sprite
layers:
- state: base
- state: logic
- state: logic_a
visible: false
map: [ "enum.LogicGateLayers.InputA" ]
- state: logic_b
visible: false
map: [ "enum.LogicGateLayers.InputB" ]
- state: logic_o
visible: false
map: [ "enum.LogicGateLayers.Output" ]
- state: nor
map: [ "enum.LogicGateLayers.Gate" ]
- type: LogicGate
@ -111,6 +161,16 @@
- type: Sprite
layers:
- state: base
- state: logic
- state: logic_a
visible: false
map: [ "enum.LogicGateLayers.InputA" ]
- state: logic_b
visible: false
map: [ "enum.LogicGateLayers.InputB" ]
- state: logic_o
visible: false
map: [ "enum.LogicGateLayers.Output" ]
- state: nand
map: [ "enum.LogicGateLayers.Gate" ]
- type: LogicGate
@ -124,6 +184,16 @@
- type: Sprite
layers:
- state: base
- state: logic
- state: logic_a
visible: false
map: [ "enum.LogicGateLayers.InputA" ]
- state: logic_b
visible: false
map: [ "enum.LogicGateLayers.InputB" ]
- state: logic_o
visible: false
map: [ "enum.LogicGateLayers.Output" ]
- state: xnor
map: [ "enum.LogicGateLayers.Gate" ]
- type: LogicGate

View file

@ -37,6 +37,7 @@
- id: SleeperAgents
- id: ZombieOutbreak
- id: LoneOpsSpawn
- id: DerelictCyborgSpawn
- type: entity
id: BaseStationEvent
@ -570,3 +571,24 @@
- Service
blacklist:
- External # don't space everything
- type: entity
parent: BaseGameRule
id: DerelictCyborgSpawn
components:
- type: StationEvent
weight: 5
earliestStart: 15
reoccurrenceDelay: 20
minimumPlayers: 4
duration: null
- type: SpaceSpawnRule
spawnDistance: 0
- type: AntagSpawner
prototype: PlayerBorgDerelict
- type: AntagSelection
definitions:
- spawnerPrototype: SpawnPointGhostDerelictCyborg
min: 1
max: 1
pickPlayer: false

View file

@ -38,7 +38,7 @@
# Silicons
- type: roleLoadout
id: JobStationAi
nameDataset: names_ai
nameDataset: NamesAI
# Civilian
- type: roleLoadout

View file

@ -14,7 +14,7 @@
!type:NanotrasenNameGenerator
prefixCreator: '14-SB'
- type: StationEmergencyShuttle
emergencyShuttlePath: /Maps/Shuttles/emergency.yml
emergencyShuttlePath: /Maps/Shuttles/emergency_amber.yml
- type: StationJobs
availableJobs:
#service

View file

@ -34,3 +34,6 @@
- node: cyborg
entity: BorgChassisSelectable
- node: derelictcyborg
entity: BorgChassisDerelict

View file

@ -1,4 +1,4 @@
- type: latheRecipe
- type: latheRecipe
id: ConveyorBeltAssembly
result: ConveyorBeltAssembly
completetime: 4

View file

@ -81,10 +81,10 @@
- type: latheRecipe
id: Vape
result: Vape
icon:
sprite: Objects/Consumable/Smokeables/Vapes/vape-standard.rsi
state: icon
result: Vape
completetime: 2
materials:
Plastic: 100

View file

@ -1,54 +1,39 @@
- type: latheRecipe
parent: BasePartRecipe
id: TimerTrigger
result: TimerTrigger
category: Parts
completetime: 2
materials:
Steel: 300
Plastic: 200
- type: latheRecipe
parent: BasePartRecipe
id: SignalTrigger
result: SignalTrigger
category: Parts
completetime: 2
materials:
Steel: 300
Plastic: 200
- type: latheRecipe
parent: BasePartRecipe
id: VoiceTrigger
result: VoiceTrigger
category: Parts
completetime: 2
materials:
Steel: 300
Plastic: 200
- type: latheRecipe
parent: BasePartRecipe
id: Igniter
result: Igniter
category: Parts
completetime: 2
materials:
Steel: 300
Plastic: 100
Glass: 100
- type: latheRecipe
parent: BaseWeaponRecipe
id: ChemicalPayload
result: ChemicalPayload
category: Weapons
completetime: 2
materials:
Steel: 200
Plastic: 300
- type: latheRecipe
parent: BaseWeaponRecipe
id: FlashPayload
result: FlashPayload
category: Weapons
completetime: 2
materials:
Steel: 50
Plastic: 100
@ -68,20 +53,18 @@
Silver: 50
- type: latheRecipe
parent: BasePartRecipe
id: Signaller
result: RemoteSignaller
category: Parts
completetime: 2
materials:
Steel: 100
Plastic: 200
Glass: 100
- type: latheRecipe
parent: BasePartRecipe
id: SignallerAdvanced
result: RemoteSignallerAdvanced
category: Parts
completetime: 2
materials:
Steel: 100
Plastic: 200
@ -106,10 +89,9 @@
Glass: 100
- type: latheRecipe
parent: BaseToolRecipe
id: AnomalyScanner
result: AnomalyScanner
category: Tools
completetime: 2
materials:
Plastic: 200
Glass: 150
@ -146,34 +128,19 @@
Uranium: 150
- type: latheRecipe
parent: ClothingBackpackHolding
id: ClothingBackpackSatchelHolding
result: ClothingBackpackSatchelHolding
completetime: 5
materials:
Steel: 2000
Silver: 750
Plasma: 1500
Uranium: 150
- type: latheRecipe
parent: ClothingBackpackHolding
id: ClothingBackpackDuffelHolding
result: ClothingBackpackDuffelHolding
completetime: 5
materials:
Steel: 2000
Silver: 750
Plasma: 1500
Uranium: 150
- type: latheRecipe
parent: ClothingBackpackHolding
id: OreBagOfHolding
result: OreBagOfHolding
completetime: 5
materials:
Steel: 2000
Silver: 750
Plasma: 1500
Uranium: 150
- type: latheRecipe
id: ClothingMaskWeldingGas

View file

@ -1,504 +1,141 @@
# Clarke
- type: latheRecipe
id: ClarkeHarness
result: ClarkeHarness
category: Clarke
completetime: 10
materials:
Steel: 2000
Glass: 1500
# Base prototypes
- type: latheRecipe
id: ClarkeHead
result: ClarkeHead
category: Clarke
abstract: true
id: BaseMechPartRecipe
category: Mech
completetime: 10
materials:
Steel: 1550
Glass: 950
- type: latheRecipe
id: ClarkeLArm
result: ClarkeLArm
category: Clarke
completetime: 10
materials:
Steel: 900
Glass: 800
- type: latheRecipe
id: ClarkeRArm
result: ClarkeRArm
category: Clarke
completetime: 10
materials:
Steel: 900
Glass: 800
- type: latheRecipe
id: ClarkeTreads
result: ClarkeTreads
category: Clarke
completetime: 10
materials:
Steel: 950
# Durand
- type: latheRecipe
id: DurandHarness
result: DurandHarness
category: Durand
completetime: 10
materials:
Steel: 2500
Glass: 2000
Silver: 1500
- type: latheRecipe
id: DurandArmor
result: DurandArmorPlate
category: Durand
completetime: 10
materials:
Steel: 3000
Silver: 900
- type: latheRecipe
id: DurandHead
result: DurandHead
category: Durand
completetime: 10
materials:
Steel: 1500
Glass: 800
Silver: 250
Diamond: 100
- type: latheRecipe
id: DurandLArm
result: DurandLArm
category: Durand
completetime: 10
materials:
Steel: 1100
Silver: 250
- type: latheRecipe
id: DurandLLeg
result: DurandLLeg
category: Durand
completetime: 10
materials:
Steel: 1100
Silver: 250
- type: latheRecipe
id: DurandRLeg
result: DurandRLeg
category: Durand
completetime: 10
materials:
Steel: 1100
Silver: 250
- type: latheRecipe
id: DurandRArm
result: DurandRArm
category: Durand
completetime: 10
materials:
Steel: 1100
Silver: 250
# Gygax
- type: latheRecipe
id: GygaxHarness
result: GygaxHarness
category: Gygax
completetime: 10
materials:
Steel: 2500
Glass: 2000
- type: latheRecipe
id: GygaxArmor
result: GygaxArmorPlate
category: Gygax
completetime: 10
materials:
Steel: 3000
- type: latheRecipe
id: GygaxHead
result: GygaxHead
category: Gygax
completetime: 10
materials:
Steel: 1500
Glass: 250
Diamond: 100
- type: latheRecipe
id: GygaxLArm
result: GygaxLArm
category: Gygax
completetime: 10
materials:
Steel: 1100
- type: latheRecipe
id: GygaxLLeg
result: GygaxLLeg
category: Gygax
completetime: 10
materials:
Steel: 1100
- type: latheRecipe
id: GygaxRLeg
result: GygaxRLeg
category: Gygax
completetime: 10
materials:
Steel: 1100
- type: latheRecipe
id: GygaxRArm
result: GygaxRArm
category: Gygax
completetime: 10
materials:
Steel: 1100
# Recipes
# Ripley
- type: latheRecipe
parent: BaseMechPartRecipe
id: RipleyHarness
result: RipleyHarness
category: Ripley
completetime: 10
materials:
Steel: 1500
Glass: 1200
- type: latheRecipe
parent: BaseMechPartRecipe
id: RipleyLArm
result: RipleyLArm
category: Ripley
completetime: 10
materials:
Steel: 1000
Glass: 750
- type: latheRecipe
parent: RipleyLArm
id: RipleyLLeg
result: RipleyLLeg
category: Ripley
completetime: 10
materials:
Steel: 1000
Glass: 750
- type: latheRecipe
parent: RipleyLLeg
id: RipleyRLeg
result: RipleyRLeg
category: Ripley
completetime: 10
materials:
Steel: 1000
Glass: 750
- type: latheRecipe
parent: RipleyLArm
id: RipleyRArm
result: RipleyRArm
category: Ripley
completetime: 10
materials:
Steel: 1000
Glass: 750
# Ripley MK-II
- type: latheRecipe
id: RipleyMKIIHarness
result: RipleyMKIIHarness
category: RipleyMKII
completetime: 10
materials:
Steel: 1500
Glass: 1200
- type: latheRecipe
id: RipleyUpgradeKit
result: RipleyUpgradeKit
category: RipleyMKII
completetime: 10
parent: BaseMechPartRecipe
id: MechEquipmentGrabber
result: MechEquipmentGrabber
materials:
Steel: 500
Plastic: 200
# H.O.N.K.
- type: latheRecipe
parent: BaseMechPartRecipe
id: HonkerHarness
result: HonkerHarness
category: Honker
completetime: 10
materials:
Steel: 3000
Glass: 1200
Bananium: 500
- type: latheRecipe
parent: BaseMechPartRecipe
id: HonkerLArm
result: HonkerLArm
category: Honker
completetime: 10
materials:
Steel: 3000
Glass: 1200
Bananium: 500
Steel: 2000
Glass: 750
Bananium: 250
- type: latheRecipe
parent: HonkerLArm
id: HonkerLLeg
result: HonkerLLeg
category: Honker
completetime: 10
materials:
Steel: 3000
Glass: 1200
Bananium: 500
- type: latheRecipe
parent: HonkerLLeg
id: HonkerRLeg
result: HonkerRLeg
category: Honker
completetime: 10
materials:
Steel: 3000
Glass: 1200
Bananium: 500
- type: latheRecipe
parent: HonkerLArm
id: HonkerRArm
result: HonkerRArm
category: Honker
completetime: 10
- type: latheRecipe
parent: BaseMechPartRecipe
id: MechEquipmentHorn
result: MechEquipmentHorn
materials:
Steel: 3000
Glass: 1200
Bananium: 500
Steel: 500
Bananium: 200
# HAMTR
- type: latheRecipe
parent: BaseMechPartRecipe
id: HamtrHarness
result: HamtrHarness
category: Hamptr
completetime: 10
materials:
Steel: 1200
Glass: 1000
- type: latheRecipe
parent: BaseMechPartRecipe
id: HamtrLArm
result: HamtrLArm
category: Hamptr
completetime: 10
materials:
Steel: 800
Glass: 600
- type: latheRecipe
parent: HamtrLArm
id: HamtrLLeg
result: HamtrLLeg
category: Hamptr
completetime: 10
materials:
Steel: 800
Glass: 600
- type: latheRecipe
parent: HamtrLLeg
id: HamtrRLeg
result: HamtrRLeg
category: Hamptr
completetime: 10
materials:
Steel: 800
Glass: 600
- type: latheRecipe
parent: HamtrLArm
id: HamtrRArm
result: HamtrRArm
category: Hamptr
completetime: 10
materials:
Steel: 800
Glass: 600
# Vim
- type: latheRecipe
id: VimHarness
result: VimHarness
category: Vim
completetime: 5
materials:
Steel: 500
Glass: 200
#Phazon
- type: latheRecipe
id: PhazonHarness
result: PhazonHarness
category: Phazon
completetime: 10
materials:
Steel: 2500
Glass: 2000
- type: latheRecipe
id: PhazonArmor
result: PhazonArmorPlate
category: Phazon
completetime: 10
materials:
Steel: 3000
Plasma: 1000
- type: latheRecipe
id: PhazonHead
result: PhazonHead
category: Phazon
completetime: 10
materials:
Steel: 1500
Glass: 250
Plasma: 500
- type: latheRecipe
id: PhazonLArm
result: PhazonLArm
category: Phazon
completetime: 10
materials:
Steel: 1100
Plasma: 250
- type: latheRecipe
id: PhazonLLeg
result: PhazonLLeg
category: Phazon
completetime: 10
materials:
Steel: 1100
Plasma: 250
- type: latheRecipe
id: PhazonRLeg
result: PhazonRLeg
category: Phazon
completetime: 10
materials:
Steel: 1100
Plasma: 250
- type: latheRecipe
id: PhazonRArm
result: PhazonRArm
category: Phazon
completetime: 10
materials:
Steel: 1100
Plasma: 250
# Equipment
- type: latheRecipe
id: MechEquipmentDrill
result: WeaponMechMelleDrill
category: MechEquipment
completetime: 10
materials:
Steel: 1000
Glass: 250
- type: latheRecipe
id: MechEquipmentDrillDiamond
result: WeaponMechMelleDrillDiamond
category: MechEquipment
completetime: 10
materials:
Steel: 1000
Plastic: 150
Silver: 350
Diamond: 150
- type: latheRecipe
id: MechEquipmentGrabber
result: MechEquipmentGrabber
category: MechEquipment
completetime: 10
materials:
Steel: 500
Plastic: 200
- type: latheRecipe
parent: BaseMechPartRecipe
id: MechEquipmentGrabberSmall
result: MechEquipmentGrabberSmall
category: MechEquipment
completetime: 10
materials:
Steel: 400
Plastic: 100
# Vim
- type: latheRecipe
id: MechEquipmentHorn
result: MechEquipmentHorn
category: MechEquipment
completetime: 10
parent: BaseMechPartRecipe
id: VimHarness
result: VimHarness
completetime: 5
materials:
Steel: 500
Bananium: 200
- type: latheRecipe
id: MechEquipmentHonkerBananaMortar
result: WeaponMechSpecialBananaMortar
category: MechEquipment
completetime: 10
materials:
Steel: 1150
Bananium: 800
- type: latheRecipe
id: MechEquipmentHonkerMousetrapMortar
result: WeaponMechSpecialMousetrapMortar
category: MechEquipment
completetime: 10
materials:
Steel: 1200
Bananium: 300
# Misc
- type: latheRecipe
id: MechPhasicScanningModule
result: MechPhasicScanningModule
category: MechEquipment
completetime: 10
materials:
Steel: 2000
Glass: 500
Silver: 100
- type: latheRecipe
id: MechAirTank
result: MechAirTank
category: MechEquipment
completetime: 10
materials:
Steel: 1000
Glass: 150
- type: latheRecipe
id: MechThruster
result: MechThruster
category: MechEquipment
completetime: 10
materials:
Steel: 1000
Glass: 150
Glass: 200

View file

@ -1,97 +1,85 @@
# Base Prototypes
- type: latheRecipe
abstract: true
id: BaseLightRecipe
category: Lights
completetime: 2
materials:
Steel: 50
Glass: 50
- type: latheRecipe
abstract: true
id: BaseFauxTileRecipe
completetime: 1
materials:
Plastic: 100
# Recipes
## Lights
- type: latheRecipe
parent: BaseLightRecipe
id: LightTube
result: LightTube
category: Lights
completetime: 2
materials:
Steel: 50
Glass: 50
- type: latheRecipe
parent: BaseLightRecipe
id: LedLightTube
result: LedLightTube
category: Lights
completetime: 2
materials:
Steel: 50
Glass: 50
- type: latheRecipe
parent: BaseLightRecipe
id: SodiumLightTube
result: SodiumLightTube
category: Lights
completetime: 2
materials:
Steel: 50
Glass: 50
- type: latheRecipe
parent: BaseLightRecipe
id: ExteriorLightTube
result: ExteriorLightTube
category: Lights
completetime: 2
materials:
Steel: 50
Glass: 50
- type: latheRecipe
parent: BaseLightRecipe
id: LightBulb
result: LightBulb
category: Lights
completetime: 2
materials:
Steel: 50
Glass: 50
- type: latheRecipe
parent: BaseLightRecipe
id: LedLightBulb
result: LedLightBulb
category: Lights
completetime: 2
materials:
Steel: 50
Glass: 50
- type: latheRecipe
parent: BaseLightRecipe
id: DimLightBulb
result: DimLightBulb
category: Lights
completetime: 2
materials:
Steel: 50
Glass: 50
- type: latheRecipe
parent: BaseLightRecipe
id: GlowstickRed
result: GlowstickRed
category: Lights
completetime: 2
materials:
Plastic: 50
- type: latheRecipe
parent: GlowstickRed
id: Flare
result: Flare
category: Lights
completetime: 2
materials:
Plastic: 50
- type: latheRecipe
parent: BaseLightRecipe
id: FlashlightLantern
result: EmptyFlashlightLantern
category: Lights
completetime: 2
materials:
Steel: 100
Glass: 100
Plastic: 100
- type: latheRecipe
parent: BaseToolRecipe
id: FireExtinguisher
result: FireExtinguisher
category: Tools
completetime: 2
materials:
Steel: 200
@ -112,10 +100,9 @@
Glass: 100
- type: latheRecipe
parent: BaseToolRecipe
id: NodeScanner
result: NodeScanner
category: Tools
completetime: 2
materials:
Steel: 100
Plastic: 50
@ -160,39 +147,29 @@
Plastic: 100
- type: latheRecipe
parent: BaseFauxTileRecipe
id: FauxTileAstroGrass
result: FloorTileItemAstroGrass
completetime: 1
materials:
Plastic: 100
- type: latheRecipe
parent: BaseFauxTileRecipe
id: FauxTileMowedAstroGrass
result: FloorTileItemMowedAstroGrass
completetime: 1
materials:
Plastic: 100
- type: latheRecipe
parent: BaseFauxTileRecipe
id: FauxTileJungleAstroGrass
result: FloorTileItemJungleAstroGrass
completetime: 1
materials:
Plastic: 100
- type: latheRecipe
parent: BaseFauxTileRecipe
id: FauxTileAstroIce
result: FloorTileItemAstroIce
completetime: 1
materials:
Plastic: 100
- type: latheRecipe
parent: BaseFauxTileRecipe
id: FauxTileAstroSnow
result: FloorTileItemAstroSnow
completetime: 1
materials:
Plastic: 100
- type: latheRecipe
id: FloorGreenCircuit
@ -202,11 +179,9 @@
Steel: 100
- type: latheRecipe
parent: FloorGreenCircuit
id: FloorBlueCircuit
result: FloorTileItemBCircuit4
completetime: 2
materials:
Steel: 100
- type: latheRecipe
id: FloorRedCircuit

View file

@ -66,4 +66,4 @@
Steel: 600
Glass: 800
Plastic: 400
Gold: 100
Gold: 100

View file

@ -1,34 +1,41 @@
# recipes should generally cost 1.5x to 2x of the biomass output of their mob
# Base prototypes
- type: latheRecipe
abstract: true
id: BaseCubeRecipe
completetime: 30
materials:
Biomass: 16
# Recipes
# recipes should generally cost 1.5x to 2x of the biomass output of their mob
- type: latheRecipe
parent: BaseCubeRecipe
id: MonkeyCube
result: MonkeyCube
completetime: 30
materials:
Biomass: 16
- type: latheRecipe
parent: BaseCubeRecipe
id: KoboldCube
result: KoboldCube
completetime: 30
materials:
Biomass: 16
- type: latheRecipe
parent: BaseCubeRecipe
id: CowCube
result: CowCube
completetime: 30
materials:
Biomass: 120
- type: latheRecipe
parent: BaseCubeRecipe
id: GoatCube
result: GoatCube
completetime: 30
materials:
Biomass: 35
- type: latheRecipe
parent: BaseCubeRecipe
id: MothroachCube
result: MothroachCube
completetime: 45 # prevent biblical floods
@ -36,6 +43,7 @@
Biomass: 20 # a lot of materials wasted due to complex genetics
- type: latheRecipe
parent: BaseCubeRecipe
id: MouseCube
result: MouseCube
completetime: 15
@ -43,21 +51,22 @@
Biomass: 12
- type: latheRecipe
parent: MouseCube
id: CockroachCube
result: CockroachCube
completetime: 15
materials:
Biomass: 16
- type: latheRecipe
parent: BaseCubeRecipe
id: SpaceCarpCube
result: SpaceCarpCube
completetime: 30
materials:
Biomass: 24
Plasma: 600
- type: latheRecipe
parent: BaseCubeRecipe
id: SpaceTickCube
result: SpaceTickCube
completetime: 15
@ -66,9 +75,9 @@
Plasma: 300 # less biomass but more plasma
- type: latheRecipe
parent: BaseCubeRecipe
id: AbominationCube
result: AbominationCube
completetime: 30
materials: # abominations are slow and essentially worse than even carp
Biomass: 28
Plasma: 500 # more biomass but less plasma

View file

@ -48,19 +48,18 @@
Silver: 100
- type: latheRecipe
parent: BaseToolRecipe
id: MiningDrill
result: MiningDrill
category: Tools
completetime: 3
materials:
Steel: 500
Plastic: 100
- type: latheRecipe
parent: MiningDrill
id: MiningDrillDiamond
result: MiningDrillDiamond
category: Tools
completetime: 3
materials:
Steel: 600
Plastic: 200

View file

@ -1,363 +1,249 @@
# Base Prototypes
- type: latheRecipe
abstract: true
id: BaseTileRecipe
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
abstract: true
parent: BaseTileRecipe
id: BaseWoodTileRecipe
materials:
Wood: 25
- type: latheRecipe
abstract: true
parent: BaseTileRecipe
id: BaseConcreteTileRecipe
materials:
Steel: 25
Plastic: 25
# Recipes
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemDark
result: FloorTileItemDark
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemDarkDiagonalMini
result: FloorTileItemDarkDiagonalMini
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemDarkDiagonal
result: FloorTileItemDarkDiagonal
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemDarkHerringbone
result: FloorTileItemDarkHerringbone
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemDarkMini
result: FloorTileItemDarkMini
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemDarkMono
result: FloorTileItemDarkMono
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemDarkPavement
result: FloorTileItemDarkPavement
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemDarkPavementVertical
result: FloorTileItemDarkPavementVertical
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemDarkOffset
result: FloorTileItemDarkOffset
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemSteelCheckerDark
result: FloorTileItemSteelCheckerDark
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemSteel
result: FloorTileItemSteel
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemSteelOffset
result: FloorTileItemSteelOffset
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemSteelDiagonalMini
result: FloorTileItemSteelDiagonalMini
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemSteelDiagonal
result: FloorTileItemSteelDiagonal
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemSteelHerringbone
result: FloorTileItemSteelHerringbone
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemSteelMini
result: FloorTileItemSteelMini
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemSteelMono
result: FloorTileItemSteelMono
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemSteelPavement
result: FloorTileItemSteelPavement
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemSteelPavementVertical
result: FloorTileItemSteelPavementVertical
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemWhite
result: FloorTileItemWhite
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemWhiteOffset
result: FloorTileItemWhiteOffset
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemWhiteDiagonalMini
result: FloorTileItemWhiteDiagonalMini
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemWhiteDiagonal
result: FloorTileItemWhiteDiagonal
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemWhiteHerringbone
result: FloorTileItemWhiteHerringbone
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemWhiteMini
result: FloorTileItemWhiteMini
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemWhiteMono
result: FloorTileItemWhiteMono
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemWhitePavement
result: FloorTileItemWhitePavement
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemWhitePavementVertical
result: FloorTileItemWhitePavementVertical
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemSteelCheckerLight
result: FloorTileItemSteelCheckerLight
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
# Other steel
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemGratingMaint
result: FloorTileItemGratingMaint
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemTechmaint
result: FloorTileItemTechmaint
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
- type: latheRecipe
parent: BaseTileRecipe
id: FloorTileItemSteelMaint
result: FloorTileItemSteelMaint
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
# Wood
- type: latheRecipe
parent: BaseWoodTileRecipe
id: FloorTileItemWood
result: FloorTileItemWood
applyMaterialDiscount: false
completetime: 0.5
materials:
Wood: 25
- type: latheRecipe
parent: BaseWoodTileRecipe
id: FloorTileItemWoodLarge
result: FloorTileItemWoodLarge
applyMaterialDiscount: false
completetime: 0.5
materials:
Wood: 25
- type: latheRecipe
parent: BaseWoodTileRecipe
id: FloorTileItemWoodPattern
result: FloorTileItemWoodPattern
applyMaterialDiscount: false
completetime: 0.5
materials:
Wood: 25
# Concrete
- type: latheRecipe
parent: BaseConcreteTileRecipe
id: FloorTileItemConcrete
result: FloorTileItemConcrete
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
Plastic: 25
- type: latheRecipe
parent: BaseConcreteTileRecipe
id: FloorTileItemConcreteMono
result: FloorTileItemConcreteMono
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
Plastic: 25
- type: latheRecipe
parent: BaseConcreteTileRecipe
id: FloorTileItemConcreteSmooth
result: FloorTileItemConcreteSmooth
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
Plastic: 25
- type: latheRecipe
parent: BaseConcreteTileRecipe
id: FloorTileItemGrayConcrete
result: FloorTileItemGrayConcrete
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
Plastic: 25
- type: latheRecipe
parent: BaseConcreteTileRecipe
id: FloorTileItemGrayConcreteMono
result: FloorTileItemGrayConcreteMono
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
Plastic: 25
- type: latheRecipe
parent: BaseConcreteTileRecipe
id: FloorTileItemGrayConcreteSmooth
result: FloorTileItemGrayConcreteSmooth
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
Plastic: 25
- type: latheRecipe
parent: BaseConcreteTileRecipe
id: FloorTileItemOldConcrete
result: FloorTileItemOldConcrete
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
Plastic: 25
- type: latheRecipe
parent: BaseConcreteTileRecipe
id: FloorTileItemOldConcreteMono
result: FloorTileItemOldConcreteMono
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
Plastic: 25
- type: latheRecipe
parent: BaseConcreteTileRecipe
id: FloorTileItemOldConcreteSmooth
result: FloorTileItemOldConcreteSmooth
applyMaterialDiscount: false
completetime: 0.5
materials:
Steel: 25
Plastic: 25

View file

@ -189,3 +189,11 @@
wires:
- !type:PowerWireAction
- !type:AiInteractWireAction
- type: wireLayout
id: BarSign
dummyWires: 2
wires:
- !type:PowerWireAction
- !type:AiInteractWireAction
- !type:AccessWireAction

View file

@ -1,16 +1,26 @@
<Document>
# Воксы
# Vox
<Box>
<GuideEntityEmbed Entity="MobVox" Caption=""/>
</Box>
[color=#ffa500]Внимание! Эта раса имеет сильно ограничивающие игровые механики и не рекомендуется для новых игроков. [/color]
[color=#ffa500]Warning! This species is not recommended for new players due to their fatal allergy to oxygen![/color]
Они дышат азотом, а [color=#ffa500]кислород для них очень токсичен[/color].
Чтобы не отравиться кислородом в атмосфере станции, они должны постоянно использовать дыхательные приспособления.
Для приёма пищи или питья вам придётся снимать дыхательную маску, хотя вариант введения пищи в жидком виде вполне возможен.
Vox breathe nitrogen, and [color=#ffa500] oxygen is toxic to them.[/color]
Unfortunately, space stations tend to be full of oxygen,
so Vox must use an internal nitrogen supply at almost all times to avoid fatal exposure.
Они используют когти в рукопашном бою, и их атаки наносят режущий урон вместо ударного.
Vox always spawn wearing working nitrogen internals equipment.
A spare breathing mask and an emergency nitrogen canister is provided in their survival box.
Vox [color=#1e90ff]slowly recover from low levels of poison damage[/color] on their own,
so long as they are careful not to exceed 20 poison damage.
This allows them to endure breathing station air for up to thirty seconds at a time without lasting damage,
letting them quickly eat, drink, take oral medication, and so on.
A thirty second oxygen exposure takes them two minutes to recover from.
If their health does not seem to improve within a minute of oxygen exposure, they should seek medical attention.
Vox deal Slash damage with their unarmed attack.
</Document>

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View file

@ -5,7 +5,7 @@
"y": 32
},
"license": "CC-BY-SA-3.0",
"copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/faf6db214927874c19b8fa8585d26b5d40de1acc",
"copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/faf6db214927874c19b8fa8585d26b5d40de1acc, derelict sprites modified by GoldenCan(GitHub).",
"states": [
{
"name": "clown",
@ -23,6 +23,26 @@
"name": "clown_l",
"directions": 4
},
{
"name": "derelict",
"directions": 4
},
{
"name": "derelict_e",
"directions": 4
},
{
"name": "derelict_e_r",
"directions": 4
},
{
"name": "derelict_icon",
"directions": 1
},
{
"name": "derelict_l",
"directions": 4
},
{
"name": "engineer",
"directions": 4

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View file

@ -1,7 +1,7 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "or.png originally created by Kevin Zheng, 2022. All are modified by deltanedas (github) for SS14, 2024.",
"copyright": "or.png originally created by Kevin Zheng, 2022. All are modified by deltanedas (github) for SS14, 2024. Sprites logic_a logic_b logic_o were made by 0tito (github) for SS14",
"size": {
"x": 32,
"y": 32
@ -13,6 +13,15 @@
{
"name": "logic"
},
{
"name": "logic_o"
},
{
"name": "logic_b"
},
{
"name": "logic_a"
},
{
"name": "or"
},