25 Commits

Author SHA1 Message Date
tommy
86eeafebf6 oh my 2025-11-29 20:57:46 -05:00
tommy
33e6f83d6b remove duplicate planet prototype 2025-11-27 19:09:54 -05:00
2a085b7e64 Merge pull request 'Lavaland.' (#2) from lavaland into master
Reviewed-on: #2
2025-11-28 01:02:59 +01:00
tommy
fe19eca8ca aaaa 2025-11-27 18:53:41 -05:00
tommy
d45c22ac6b We're done here. Again. This time it's doner than done. 2025-11-27 18:44:36 -05:00
tommy
5a8b515eb5 add bluespace shelter capsules (#2566) (2) 2025-11-27 16:02:57 -05:00
deltanedas
41d0338fcc add bluespace shelter capsules (#2566)
* move mining_voucher.yml into Salvage folder

* add ShelterCapsuleComponent and system

* add shelter capsules

* add capsules to vendor and voucher

* :trollface:

* add admin logging and delete lava

* mv wire

* changes for namespace refactor

* remove dupe voucher

* add smoke when deploying

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>
2025-11-27 16:02:52 -05:00
tommy
653bc57aef aeiou 2025-11-27 15:17:20 -05:00
tommy
c79bd1822f ore bag 2025-11-27 15:15:00 -05:00
tommy
c2801fc5db ash storms p2 2025-11-27 15:13:55 -05:00
deltanedas
800fd928b8 ash storms just the facts 2025-11-27 15:12:43 -05:00
tommy
cef7597e8d We're done here. 2025-11-27 14:36:45 -05:00
deltanedas
f42c2ae11b salvage points shop (#2510)
* add conscription bag

* add gar mesons

* remove salvage vendor restock

* add code for shop vendors

* make salvage vendor a shop vendor

* ui fixes

* :trollface:

* update locker and vendor inventory

* add mining hardsuit for 3k

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>
2025-11-26 23:09:08 -05:00
deltanedas
1c2f200762 add mining points (#2419)
* add mining points

* add claim points button to oreproc

* funny

* its over

* :trollface:

* xml fail

Signed-off-by: deltanedas <39013340+deltanedas@users.noreply.github.com>

---------

Signed-off-by: deltanedas <39013340+deltanedas@users.noreply.github.com>
Co-authored-by: deltanedas <@deltanedas:kde.org>
2025-11-26 22:55:56 -05:00
tommy
3e33dc5936 Port DeltaV Lavaland Initial (2) 2025-11-26 22:38:52 -05:00
deltanedas
da7cf45fa6 Port DeltaV Lavaland Initial 2025-11-26 22:38:40 -05:00
tommy
8d66d0bc7c wall and windowening (paradise walls and windows) 2025-11-26 21:17:23 -05:00
hereelabs
bd8bbdcbe7 part 2 of materials fixes that stuff 2025-11-26 19:15:53 -05:00
tommy
86cf6ef2c4 part 1 of materials stacks 2025-11-26 16:51:21 -05:00
=
2eb6888fac stack sprites 2025-11-26 16:32:19 -05:00
=
cef0e84bff basic 2025-11-26 15:50:57 -05:00
=
a6f8c868fd Basic RSI fixes 2025-11-26 15:43:08 -05:00
=
9e53d064f2 yes 2025-11-26 15:35:17 -05:00
=
1a7dca3aac dirty steel floor fix 2025-11-26 15:27:56 -05:00
=
e91df813d2 parallax update 2025-11-26 15:21:59 -05:00
365 changed files with 65167 additions and 42521 deletions

View File

@@ -0,0 +1,5 @@
using Content.Shared.DeltaV.Shuttles.Systems;
namespace Content.Client.DeltaV.Shuttles.Systems;
public sealed class DockingConsoleSystem : SharedDockingConsoleSystem;

View File

@@ -0,0 +1,38 @@
using Content.Shared.DeltaV.Shuttles;
namespace Content.Client.DeltaV.Shuttles.UI;
public sealed class DockingConsoleBoundUserInterface : BoundUserInterface
{
[ViewVariables]
private DockingConsoleWindow? _window;
public DockingConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}
protected override void Open()
{
base.Open();
_window = new DockingConsoleWindow(Owner);
_window.OnFTL += index => SendMessage(new DockingConsoleFTLMessage(index));
_window.OnClose += Close;
_window.OpenCentered();
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (state is DockingConsoleState cast)
_window?.UpdateState(cast);
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
_window?.Orphan();
}
}

View File

@@ -0,0 +1,17 @@
<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
SetSize="500 500">
<BoxContainer Orientation="Vertical">
<ScrollContainer SetHeight="256" HorizontalExpand="True">
<ItemList Name="Destinations"/> <!-- Populated from comp.Destinations -->
</ScrollContainer>
<controls:StripeBack MinSize="48 48">
<Label Text="{Loc 'shuttle-console-ftl-label'}" VerticalExpand="True" HorizontalAlignment="Center"/>
</controls:StripeBack>
<Label Name="MapFTLState" Text="{Loc 'shuttle-console-ftl-state-Available'}" VerticalAlignment="Stretch" HorizontalAlignment="Center"/>
<ProgressBar Name="FTLBar" HorizontalExpand="True" Margin="5" MinValue="0.0" MaxValue="1.0" Value="1.0" SetHeight="32"/>
<controls:StripeBack HorizontalExpand="True">
<Button Name="FTLButton" Text="{Loc 'docking-console-ftl'}" Disabled="True" SetSize="128 48" Margin="5"/>
</controls:StripeBack>
</BoxContainer>
</controls:FancyWindow>

View File

@@ -0,0 +1,112 @@
using Content.Client.UserInterface.Controls;
using Content.Shared.Access.Systems;
using Content.Shared.DeltaV.Shuttles;
using Content.Shared.DeltaV.Shuttles.Components;
using Content.Shared.Shuttles.Systems;
using Content.Shared.Timing;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Timing;
namespace Content.Client.DeltaV.Shuttles.UI;
[GenerateTypedNameReferences]
public sealed partial class DockingConsoleWindow : FancyWindow
{
[Dependency] private readonly IEntityManager _entMan = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IPlayerManager _player = default!;
private readonly AccessReaderSystem _access;
public event Action<int>? OnFTL;
private readonly EntityUid _owner;
private readonly StyleBoxFlat _ftlStyle;
private FTLState _state;
private int? _selected;
private StartEndTime _ftlTime;
public DockingConsoleWindow(EntityUid owner)
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_access = _entMan.System<AccessReaderSystem>();
_owner = owner;
_ftlStyle = new StyleBoxFlat(Color.LimeGreen);
FTLBar.ForegroundStyleBoxOverride = _ftlStyle;
if (!_entMan.TryGetComponent<DockingConsoleComponent>(owner, out var comp))
return;
Title = Loc.GetString(comp.WindowTitle);
if (!comp.HasShuttle)
{
MapFTLState.Text = Loc.GetString("docking-console-no-shuttle");
_ftlStyle.BackgroundColor = Color.FromHex("#B02E26");
return;
}
Destinations.OnItemSelected += args => _selected = args.ItemIndex;
Destinations.OnItemDeselected += _ => _selected = null;
FTLButton.OnPressed += _ =>
{
if (_selected is {} index)
OnFTL?.Invoke(index);
};
}
public void UpdateState(DockingConsoleState state)
{
_state = state.FTLState;
_ftlTime = state.FTLTime;
MapFTLState.Text = Loc.GetString($"shuttle-console-ftl-state-{_state.ToString()}");
_ftlStyle.BackgroundColor = Color.FromHex(_state switch
{
FTLState.Available => "#80C71F",
FTLState.Starting => "#169C9C",
FTLState.Travelling => "#8932B8",
FTLState.Arriving => "#F9801D",
_ => "#B02E26" // cooldown and fallback
});
UpdateButton();
if (Destinations.Count == state.Destinations.Count)
return;
Destinations.Clear();
foreach (var dest in state.Destinations)
{
Destinations.AddItem(dest.Name);
}
}
private void UpdateButton()
{
FTLButton.Disabled = _selected == null || _state != FTLState.Available || !HasAccess();
}
private bool HasAccess()
{
return _player.LocalSession?.AttachedEntity is {} player && _access.IsAllowed(player, _owner);
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
UpdateButton();
var progress = _ftlTime.ProgressAt(_timing.CurTime);
FTLBar.Value = float.IsFinite(progress) ? progress : 1;
}
}

View File

@@ -0,0 +1,123 @@
using Content.Shared.DeltaV.VendingMachines;
using Content.Shared.VendingMachines;
using Robust.Client.Animations;
using Robust.Client.GameObjects;
namespace Content.Client.DeltaV.VendingMachines;
public sealed class ShopVendorSystem : SharedShopVendorSystem
{
[Dependency] private readonly AnimationPlayerSystem _animationPlayer = default!;
[Dependency] private readonly AppearanceSystem _appearance = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ShopVendorComponent, AppearanceChangeEvent>(OnAppearanceChange);
SubscribeLocalEvent<ShopVendorComponent, AnimationCompletedEvent>(OnAnimationCompleted);
}
// copied from vending machines because its not reusable in other systems :)
private void OnAnimationCompleted(Entity<ShopVendorComponent> ent, ref AnimationCompletedEvent args)
{
UpdateAppearance((ent, ent.Comp));
}
private void OnAppearanceChange(Entity<ShopVendorComponent> ent, ref AppearanceChangeEvent args)
{
UpdateAppearance((ent, ent.Comp, args.Sprite));
}
private void UpdateAppearance(Entity<ShopVendorComponent, SpriteComponent?> ent)
{
if (!Resolve(ent, ref ent.Comp2))
return;
if (!_appearance.TryGetData<VendingMachineVisualState>(ent, VendingMachineVisuals.VisualState, out var state))
state = VendingMachineVisualState.Normal;
var sprite = ent.Comp2;
SetLayerState(VendingMachineVisualLayers.Base, ent.Comp1.OffState, sprite);
SetLayerState(VendingMachineVisualLayers.Screen, ent.Comp1.ScreenState, sprite);
switch (state)
{
case VendingMachineVisualState.Normal:
SetLayerState(VendingMachineVisualLayers.BaseUnshaded, ent.Comp1.NormalState, sprite);
break;
case VendingMachineVisualState.Deny:
if (ent.Comp1.LoopDenyAnimation)
SetLayerState(VendingMachineVisualLayers.BaseUnshaded, ent.Comp1.DenyState, sprite);
else
PlayAnimation(ent, VendingMachineVisualLayers.BaseUnshaded, ent.Comp1.DenyState, ent.Comp1.DenyDelay, sprite);
break;
case VendingMachineVisualState.Eject:
PlayAnimation(ent, VendingMachineVisualLayers.BaseUnshaded, ent.Comp1.EjectState, ent.Comp1.EjectDelay, sprite);
break;
case VendingMachineVisualState.Broken:
HideLayers(sprite);
SetLayerState(VendingMachineVisualLayers.Base, ent.Comp1.BrokenState, sprite);
break;
case VendingMachineVisualState.Off:
HideLayers(sprite);
break;
}
}
private static void SetLayerState(VendingMachineVisualLayers layer, string? state, SpriteComponent sprite)
{
if (state == null)
return;
sprite.LayerSetVisible(layer, true);
sprite.LayerSetAutoAnimated(layer, true);
sprite.LayerSetState(layer, state);
}
private void PlayAnimation(EntityUid uid, VendingMachineVisualLayers layer, string? state, TimeSpan time, SpriteComponent sprite)
{
if (state == null || _animationPlayer.HasRunningAnimation(uid, state))
return;
var animation = GetAnimation(layer, state, time);
sprite.LayerSetVisible(layer, true);
_animationPlayer.Play(uid, animation, state);
}
private static Animation GetAnimation(VendingMachineVisualLayers layer, string state, TimeSpan time)
{
return new Animation
{
Length = time,
AnimationTracks =
{
new AnimationTrackSpriteFlick
{
LayerKey = layer,
KeyFrames =
{
new AnimationTrackSpriteFlick.KeyFrame(state, 0f)
}
}
}
};
}
private static void HideLayers(SpriteComponent sprite)
{
HideLayer(VendingMachineVisualLayers.BaseUnshaded, sprite);
HideLayer(VendingMachineVisualLayers.Screen, sprite);
}
private static void HideLayer(VendingMachineVisualLayers layer, SpriteComponent sprite)
{
if (!sprite.LayerMapTryGet(layer, out var actualLayer))
return;
sprite.LayerSetVisible(actualLayer, false);
}
}

View File

@@ -0,0 +1,25 @@
using Content.Shared.DeltaV.VendingMachines;
using Robust.Client.UserInterface;
namespace Content.Client.DeltaV.VendingMachines.UI;
public sealed class ShopVendorBoundUserInterface : BoundUserInterface
{
[ViewVariables]
private ShopVendorWindow? _window;
public ShopVendorBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}
protected override void Open()
{
base.Open();
_window = this.CreateWindow<ShopVendorWindow>();
_window.SetEntity(Owner);
_window.OpenCenteredLeft();
_window.Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName;
_window.OnItemSelected += index => SendMessage(new ShopVendorPurchaseMessage(index));
}
}

View File

@@ -0,0 +1,13 @@
<BoxContainer xmlns="https://spacestation14.io"
Orientation="Horizontal"
HorizontalExpand="True"
SeparationOverride="4">
<EntityPrototypeView
Name="ItemPrototype"
Margin="4 0 0 0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
MinSize="32 32"/>
<Label Name="NameLabel" SizeFlagsStretchRatio="3" HorizontalExpand="True" ClipText="True"/>
<Label Name="CostLabel" SizeFlagsStretchRatio="3" HorizontalAlignment="Right" Margin="8 0"/>
</BoxContainer>

View File

@@ -0,0 +1,21 @@
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
namespace Content.Client.DeltaV.VendingMachines.UI;
[GenerateTypedNameReferences]
public sealed partial class ShopVendorItem : BoxContainer
{
public ShopVendorItem(EntProtoId entProto, string text, uint cost)
{
RobustXamlLoader.Load(this);
ItemPrototype.SetPrototype(entProto);
NameLabel.Text = text;
CostLabel.Text = cost.ToString();
}
}

View File

@@ -0,0 +1,24 @@
<controls:FancyWindow
xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
MinHeight="210">
<BoxContainer Name="MainContainer" Orientation="Vertical">
<BoxContainer Orientation="Horizontal">
<LineEdit Name="SearchBar" PlaceHolder="{Loc 'vending-machine-component-search-filter'}" HorizontalExpand="True" Margin="4 4"/>
<Label Name="BalanceLabel" Margin="4 4"/>
</BoxContainer>
<controls:SearchListContainer Name="VendingContents" VerticalExpand="True" Margin="4 4"/>
<!-- Footer -->
<BoxContainer Orientation="Vertical">
<PanelContainer StyleClasses="LowDivider" />
<BoxContainer Orientation="Horizontal" Margin="10 2 5 0" VerticalAlignment="Bottom">
<Label Text="{Loc 'shop-vendor-flavor-left'}" StyleClasses="WindowFooterText" />
<Label Text="{Loc 'shop-vendor-flavor-right'}" StyleClasses="WindowFooterText"
HorizontalAlignment="Right" HorizontalExpand="True" Margin="0 0 5 0" />
<TextureRect StyleClasses="NTLogoDark" Stretch="KeepAspectCentered"
VerticalAlignment="Center" HorizontalAlignment="Right" SetSize="19 19"/>
</BoxContainer>
</BoxContainer>
</BoxContainer>
</controls:FancyWindow>

View File

@@ -0,0 +1,147 @@
using Content.Client.UserInterface.Controls;
using Content.Shared.DeltaV.VendingMachines;
using Content.Shared.Stacks;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using System.Numerics;
namespace Content.Client.DeltaV.VendingMachines.UI;
[GenerateTypedNameReferences]
public sealed partial class ShopVendorWindow : FancyWindow
{
[Dependency] private readonly IComponentFactory _factory = default!;
[Dependency] private readonly IEntityManager _entMan = default!;
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
private readonly ShopVendorSystem _vendor;
/// <summary>
/// Event fired with the listing index to purchase.
/// </summary>
public event Action<int>? OnItemSelected;
private EntityUid _owner;
private readonly StyleBoxFlat _style = new() { BackgroundColor = new Color(70, 73, 102) };
private readonly StyleBoxFlat _styleBroke = new() { BackgroundColor = Color.FromHex("#303133") };
private readonly List<ListContainerButton> _buttons = new();
private uint _balance = 1;
public ShopVendorWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_vendor = _entMan.System<ShopVendorSystem>();
VendingContents.SearchBar = SearchBar;
VendingContents.DataFilterCondition += DataFilterCondition;
VendingContents.GenerateItem += GenerateButton;
VendingContents.ItemKeyBindDown += (args, data) => OnItemSelected?.Invoke(((ShopVendorListingData) data).Index);
}
public void SetEntity(EntityUid owner)
{
_owner = owner;
if (!_entMan.TryGetComponent<ShopVendorComponent>(owner, out var comp))
return;
var pack = _proto.Index(comp.Pack);
Populate(pack.Listings);
UpdateBalance();
}
private void UpdateBalance(uint balance)
{
if (_balance == balance)
return;
_balance = balance;
BalanceLabel.Text = Loc.GetString("shop-vendor-balance", ("points", balance));
// disable items that are too expensive to buy
foreach (var button in _buttons)
{
if (button.Data is ShopVendorListingData data)
button.Disabled = data.Cost > balance;
button.StyleBoxOverride = button.Disabled ? _styleBroke : _style;
}
}
private void UpdateBalance()
{
if (_player.LocalEntity is {} user)
UpdateBalance(_vendor.GetBalance(_owner, user));
}
private bool DataFilterCondition(string filter, ListData data)
{
if (data is not ShopVendorListingData { Text: var text })
return false;
if (string.IsNullOrEmpty(filter))
return true;
return text.Contains(filter, StringComparison.CurrentCultureIgnoreCase);
}
private void GenerateButton(ListData data, ListContainerButton button)
{
if (data is not ShopVendorListingData cast)
return;
_buttons.Add(button);
button.AddChild(new ShopVendorItem(cast.ItemId, cast.Text, cast.Cost));
button.ToolTip = cast.Text;
button.Disabled = cast.Cost > _balance;
button.StyleBoxOverride = button.Disabled ? _styleBroke : _style;
}
public void Populate(List<ShopListing> listings)
{
var longestEntry = string.Empty;
var listData = new List<ShopVendorListingData>();
for (var i = 0; i < listings.Count; i++)
{
var listing = listings[i];
var proto = _proto.Index(listing.Id);
var text = proto.Name;
if (proto.TryGetComponent<StackComponent>(out var stack, _factory) && stack.Count > 1)
{
text += " ";
text += Loc.GetString("shop-vendor-stack-suffix", ("count", stack.Count));
}
listData.Add(new ShopVendorListingData(i, listing.Id, text, listing.Cost));
}
_buttons.Clear();
VendingContents.PopulateList(listData);
SetSizeAfterUpdate(longestEntry.Length, listings.Count);
}
private void SetSizeAfterUpdate(int longestEntryLength, int contentCount)
{
SetSize = new Vector2(Math.Clamp((longestEntryLength + 2) * 12, 250, 400),
Math.Clamp(contentCount * 50, 150, 350));
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
UpdateBalance();
}
}
public record ShopVendorListingData(int Index, EntProtoId ItemId, string Text, uint Cost) : ListData;

View File

@@ -1,3 +1,4 @@
using Content.Shared.DeltaV.Salvage; // DeltaV
using Content.Shared.Lathe;
using Content.Shared.Research.Components;
using JetBrains.Annotations;
@@ -34,6 +35,8 @@ namespace Content.Client.Lathe.UI
_menu.QueueMoveUpAction += index => SendMessage(new LatheMoveRequestMessage(index, -1));
_menu.QueueMoveDownAction += index => SendMessage(new LatheMoveRequestMessage(index, 1));
_menu.DeleteFabricatingAction += () => SendMessage(new LatheAbortFabricationMessage());
_menu.OnClaimMiningPoints += () => SendMessage(new LatheClaimMiningPointsMessage()); // DeltaV
}
protected override void UpdateState(BoundUserInterfaceState state)

View File

@@ -151,6 +151,12 @@
<ui:MaterialStorageControl Name="MaterialsList" SizeFlagsStretchRatio="8"/>
</BoxContainer>
</PanelContainer>
<!-- Begin DeltaV Additions: Mining points -->
<BoxContainer Orientation="Horizontal" Name="MiningPointsContainer" Visible="False">
<Label Name="MiningPointsLabel" HorizontalExpand="True"/>
<Button Name="MiningPointsClaimButton" Text="{Loc 'lathe-menu-mining-points-claim-button'}"/>
</BoxContainer>
<!-- End DeltaV Additions: Mining points -->
</BoxContainer>
</BoxContainer>

View File

@@ -1,17 +1,21 @@
using System.Linq;
using System.Text;
using Content.Client.Materials;
using Content.Shared.DeltaV.Salvage.Components; // DeltaV
using Content.Shared.DeltaV.Salvage.Systems; // DeltaV
using Content.Shared.Lathe;
using Content.Shared.Lathe.Prototypes;
using Content.Shared.Research.Prototypes;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Player; // DeltaV
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
using Robust.Shared.Timing; // DeltaV
namespace Content.Client.Lathe.UI;
@@ -19,11 +23,13 @@ namespace Content.Client.Lathe.UI;
public sealed partial class LatheMenu : DefaultWindow
{
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IPlayerManager _player = default!; // DeltaV
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
private readonly SpriteSystem _spriteSystem;
private readonly LatheSystem _lathe;
private readonly MaterialStorageSystem _materialStorage;
private readonly MiningPointsSystem _miningPoints; // DeltaV
public event Action<BaseButton.ButtonEventArgs>? OnServerListButtonPressed;
public event Action<string, int>? RecipeQueueAction;
@@ -31,15 +37,16 @@ public sealed partial class LatheMenu : DefaultWindow
public event Action<int>? QueueMoveUpAction;
public event Action<int>? QueueMoveDownAction;
public event Action? DeleteFabricatingAction;
public event Action? OnClaimMiningPoints; // DeltaV
public List<ProtoId<LatheRecipePrototype>> Recipes = new();
public List<ProtoId<LatheCategoryPrototype>>? Categories;
public ProtoId<LatheCategoryPrototype>? CurrentCategory;
public EntityUid Entity;
private uint? _lastMiningPoints; // DeltaV: used to avoid Loc.GetString every frame
public LatheMenu()
{
RobustXamlLoader.Load(this);
@@ -48,6 +55,7 @@ public sealed partial class LatheMenu : DefaultWindow
_spriteSystem = _entityManager.System<SpriteSystem>();
_lathe = _entityManager.System<LatheSystem>();
_materialStorage = _entityManager.System<MaterialStorageSystem>();
_miningPoints = _entityManager.System<MiningPointsSystem>(); // DeltaV
SearchBar.OnTextChanged += _ =>
{
@@ -86,9 +94,52 @@ public sealed partial class LatheMenu : DefaultWindow
AmountLineEdit.SetText(latheComponent.DefaultProductionAmount.ToString());
}
// Begin DeltaV Additions: Mining points UI
MiningPointsContainer.Visible = _entityManager.TryGetComponent<MiningPointsComponent>(Entity, out var points);
MiningPointsClaimButton.OnPressed += _ => OnClaimMiningPoints?.Invoke();
if (points != null)
UpdateMiningPoints(points.Points);
// End DeltaV Additions
MaterialsList.SetOwner(Entity);
}
/// <summary>
/// DeltaV: Updates the UI elements for mining points.
/// </summary>
private void UpdateMiningPoints(uint points)
{
MiningPointsClaimButton.Disabled = points == 0 ||
_player.LocalSession?.AttachedEntity is not {} player ||
_miningPoints.TryFindIdCard(player) == null;
if (points == _lastMiningPoints)
return;
_lastMiningPoints = points;
MiningPointsLabel.Text = Loc.GetString("lathe-menu-mining-points", ("points", points));
}
protected override void Opened()
{
base.Opened();
if (_entityManager.TryGetComponent<LatheComponent>(Entity, out var latheComp))
{
AmountLineEdit.SetText(latheComp.DefaultProductionAmount.ToString());
}
}
/// <summary>
/// DeltaV: Update mining points UI whenever it changes.
/// </summary>
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
if (_entityManager.TryGetComponent<MiningPointsComponent>(Entity, out var points))
UpdateMiningPoints(points.Points);
}
/// <summary>
/// Populates the list of all the recipes
/// </summary>

View File

@@ -0,0 +1,5 @@
using Content.Shared._DV.Salvage.Systems;
namespace Content.Client._DV.Salvage.Systems;
public sealed class ShelterCapsuleSystem : SharedShelterCapsuleSystem;

View File

@@ -0,0 +1,74 @@
using Content.Server.Atmos.EntitySystems;
using Content.Server.Parallax;
using Content.Shared.DeltaV.Planet;
using Content.Shared.Parallax.Biomes;
using Robust.Shared.EntitySerialization.Systems;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Server.DeltaV.Planet;
public sealed class PlanetSystem : EntitySystem
{
[Dependency] private readonly AtmosphereSystem _atmos = default!;
[Dependency] private readonly BiomeSystem _biome = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly MapLoaderSystem _mapLoader = default!;
[Dependency] private readonly MetaDataSystem _meta = default!;
[Dependency] private readonly SharedMapSystem _map = default!;
private readonly List<(Vector2i, Tile)> _setTiles = new();
/// <summary>
/// Spawn a planet map from a planet prototype.
/// </summary>
public EntityUid SpawnPlanet(ProtoId<PlanetPrototype> id, bool runMapInit = true)
{
var planet = _proto.Index(id);
var map = _map.CreateMap(out _, runMapInit: runMapInit);
_biome.EnsurePlanet(map, _proto.Index(planet.Biome), mapLight: planet.MapLight);
// add each marker layer
var biome = Comp<BiomeComponent>(map);
foreach (var layer in planet.BiomeMarkerLayers)
{
_biome.AddMarkerLayer(map, biome, layer);
}
if (planet.AddedComponents is {} added)
EntityManager.AddComponents(map, added);
_atmos.SetMapAtmosphere(map, false, planet.Atmosphere);
_meta.SetEntityName(map, Loc.GetString(planet.MapName));
return map;
}
/// <summary>
/// Spawns an initialized planet map from a planet prototype and loads a grid onto it.
/// Returns the map entity if loading succeeded.
/// </summary>
public EntityUid? LoadPlanet(ProtoId<PlanetPrototype> id, ResPath path)
{
var map = SpawnPlanet(id, runMapInit: false);
var mapId = Comp<MapComponent>(map).MapId;
if (!_mapLoader.TryLoadGrid(mapId, path, out var grid))
{
Log.Error($"Failed to load planet grid {path} for planet {id}!");
Del(map);
return null;
}
// don't want rocks spawning inside the base
_setTiles.Clear();
var aabb = Comp<MapGridComponent>(grid.Value).LocalAABB;
_biome.ReserveTiles(map, aabb.Enlarged(0.2f), _setTiles);
_map.InitializeMap(map);
return map;
}
}

View File

@@ -0,0 +1,177 @@
using Content.Server.Shuttles.Components;
using Content.Server.Shuttles.Events;
using Content.Server.Shuttles.Systems;
using Content.Server.Station.Systems;
using Content.Shared.DeltaV.Shuttles;
using Content.Shared.DeltaV.Shuttles.Components;
using Content.Shared.DeltaV.Shuttles.Systems;
using Content.Shared.Shuttles.Components;
using Content.Shared.Shuttles.Systems;
using Content.Shared.Station.Components;
using Content.Shared.Timing;
using Content.Shared.Whitelist;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
namespace Content.Server.DeltaV.Shuttles.Systems;
public sealed class DockingConsoleSystem : SharedDockingConsoleSystem
{
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
[Dependency] private readonly SharedMapSystem _map = default!;
[Dependency] private readonly SharedUserInterfaceSystem _ui = default!;
[Dependency] private readonly ShuttleSystem _shuttle = default!;
[Dependency] private readonly StationSystem _station = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DockEvent>(OnDock);
SubscribeLocalEvent<UndockEvent>(OnUndock);
Subs.BuiEvents<DockingConsoleComponent>(DockingConsoleUiKey.Key, subs =>
{
subs.Event<BoundUIOpenedEvent>(OnOpened);
subs.Event<DockingConsoleFTLMessage>(OnFTL);
});
}
private void OnDock(DockEvent args)
{
UpdateConsoles(args.GridAUid, args.GridBUid);
}
private void OnUndock(UndockEvent args)
{
UpdateConsoles(args.GridAUid, args.GridBUid);
}
private void OnOpened(Entity<DockingConsoleComponent> ent, ref BoundUIOpenedEvent args)
{
if (TerminatingOrDeleted(ent.Comp.Shuttle))
UpdateShuttle(ent);
UpdateUI(ent);
}
private void UpdateConsoles(EntityUid gridA, EntityUid gridB)
{
UpdateConsolesUsing(gridA);
UpdateConsolesUsing(gridB);
}
/// <summary>
/// Update the UI of every console that is using a certain shuttle.
/// </summary>
public void UpdateConsolesUsing(EntityUid shuttle)
{
if (!HasComp<DockingShuttleComponent>(shuttle))
return;
var query = EntityQueryEnumerator<DockingConsoleComponent>();
while (query.MoveNext(out var uid, out var comp))
{
if (comp.Shuttle == shuttle)
UpdateUI((uid, comp));
}
}
private void UpdateUI(Entity<DockingConsoleComponent> ent)
{
if (ent.Comp.Shuttle is not {} shuttle)
return;
var ftlState = FTLState.Available;
StartEndTime ftlTime = default;
List<DockingDestination> destinations = new();
if (TryComp<FTLComponent>(shuttle, out var ftl))
{
ftlState = ftl.State;
ftlTime = _shuttle.GetStateTime(ftl);
}
if (TryComp<DockingShuttleComponent>(shuttle, out var docking))
{
destinations = docking.Destinations;
}
var state = new DockingConsoleState(ftlState, ftlTime, destinations);
_ui.SetUiState(ent.Owner, DockingConsoleUiKey.Key, state);
}
private void OnFTL(Entity<DockingConsoleComponent> ent, ref DockingConsoleFTLMessage args)
{
if (ent.Comp.Shuttle is not {} shuttle || !TryComp<DockingShuttleComponent>(shuttle, out var docking))
return;
if (args.Index < 0 || args.Index > docking.Destinations.Count)
return;
var dest = docking.Destinations[args.Index];
var map = dest.Map;
// can't FTL if its already there or somehow failed whitelist
if (map == Transform(shuttle).MapID || !_shuttle.CanFTLTo(shuttle, map, ent))
return;
if (FindLargestGrid(map) is not {} grid)
return;
Log.Debug($"{ToPrettyString(args.Actor):user} is FTL-docking {ToPrettyString(shuttle):shuttle} to {ToPrettyString(grid):grid}");
_shuttle.FTLToDock(shuttle, Comp<ShuttleComponent>(shuttle), grid, priorityTag: ent.Comp.DockTag);
UpdateUI(ent);
}
private EntityUid? FindLargestGrid(MapId map)
{
EntityUid? largestGrid = null;
var largestSize = 0f;
if (_station.GetStationInMap(map) is {} station)
{
// prevent picking vgroid and stuff
return _station.GetLargestGrid(station); // May need to get the StationDataComponent if this doesn't work
}
var query = EntityQueryEnumerator<MapGridComponent, TransformComponent>();
while (query.MoveNext(out var gridUid, out var grid, out var xform))
{
if (xform.MapID != map)
continue;
var size = grid.LocalAABB.Size.LengthSquared();
if (size < largestSize)
continue;
largestSize = size;
largestGrid = gridUid;
}
return largestGrid;
}
private void UpdateShuttle(Entity<DockingConsoleComponent> ent)
{
var hadShuttle = ent.Comp.HasShuttle;
// no error if it cant find one since it would fail every test as shuttle.grid_fill is false in dev
ent.Comp.Shuttle = FindShuttle(ent.Comp.ShuttleWhitelist);
ent.Comp.HasShuttle = ent.Comp.Shuttle != null;
if (ent.Comp.HasShuttle != hadShuttle)
Dirty(ent);
}
private EntityUid? FindShuttle(EntityWhitelist whitelist)
{
var query = EntityQueryEnumerator<DockingShuttleComponent>();
while (query.MoveNext(out var uid, out _))
{
if (_whitelist.IsValid(whitelist, uid))
return uid;
}
return null;
}
}

View File

@@ -0,0 +1,79 @@
using Content.Server.Shuttles.Events;
using Content.Server.Station.Systems;
using Content.Shared.DeltaV.Shuttles.Components;
using Content.Shared.DeltaV.Shuttles.Systems;
using Content.Shared.Shuttles.Components;
using Content.Shared.Station.Components;
using Content.Shared.Whitelist;
using Robust.Shared.Map.Components;
using System.Linq;
namespace Content.Server.DeltaV.Shuttles.Systems;
public sealed class DockingShuttleSystem : SharedDockingShuttleSystem
{
[Dependency] private readonly DockingConsoleSystem _console = default!;
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
[Dependency] private readonly StationSystem _station = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DockingShuttleComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<DockingShuttleComponent, FTLStartedEvent>(OnFTLStarted);
SubscribeLocalEvent<DockingShuttleComponent, FTLCompletedEvent>(OnFTLCompleted);
SubscribeLocalEvent<StationGridAddedEvent>(OnStationGridAdded);
}
private void OnMapInit(Entity<DockingShuttleComponent> ent, ref MapInitEvent args)
{
// add any whitelisted destinations that it can FTL to
// since it needs a whitelist, this excludes the station
var query = EntityQueryEnumerator<FTLDestinationComponent, MapComponent>();
while (query.MoveNext(out var mapUid, out var dest, out var map))
{
if (!dest.Enabled || _whitelist.IsWhitelistFailOrNull(dest.Whitelist, ent))
continue;
ent.Comp.Destinations.Add(new DockingDestination()
{
Name = Name(mapUid),
Map = map.MapId
});
}
}
private void OnFTLStarted(Entity<DockingShuttleComponent> ent, ref FTLStartedEvent args)
{
_console.UpdateConsolesUsing(ent);
}
private void OnFTLCompleted(Entity<DockingShuttleComponent> ent, ref FTLCompletedEvent args)
{
_console.UpdateConsolesUsing(ent);
}
private void OnStationGridAdded(StationGridAddedEvent args)
{
var uid = args.GridId;
if (!TryComp<DockingShuttleComponent>(uid, out var comp))
return;
// only add the destination once
if (comp.Station != null)
return;
if (_station.GetOwningStation(uid) is not {} station || !TryComp<StationDataComponent>(station, out var data))
return;
// add the source station as a destination
comp.Station = station;
comp.Destinations.Add(new DockingDestination()
{
Name = Name(station),
Map = Transform(data.Grids.First()).MapID
});
}
}

View File

@@ -0,0 +1,32 @@
using Content.Server.DeltaV.Station.Systems;
using Content.Shared.DeltaV.Planet;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Server.DeltaV.Station.Components;
/// <summary>
/// Loads a planet map on mapinit and spawns a grid on it (e.g. a mining base).
/// The map can then be FTLd to by any shuttle matching its whitelist.
/// </summary>
[RegisterComponent, Access(typeof(StationPlanetSpawnerSystem))]
public sealed partial class StationPlanetSpawnerComponent : Component
{
/// <summary>
/// The planet to create.
/// </summary>
[DataField(required: true)]
public ProtoId<PlanetPrototype> Planet;
/// <summary>
/// Path to the grid to load onto the map.
/// </summary>
[DataField(required: true)]
public ResPath? GridPath;
/// <summary>
/// The map that was loaded.
/// </summary>
[DataField]
public EntityUid? Map;
}

View File

@@ -0,0 +1,30 @@
using Content.Server.DeltaV.Planet;
using Content.Server.DeltaV.Station.Components;
namespace Content.Server.DeltaV.Station.Systems;
public sealed class StationPlanetSpawnerSystem : EntitySystem
{
[Dependency] private readonly PlanetSystem _planet = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<StationPlanetSpawnerComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<StationPlanetSpawnerComponent, ComponentShutdown>(OnShutdown);
}
private void OnMapInit(Entity<StationPlanetSpawnerComponent> ent, ref MapInitEvent args)
{
if (ent.Comp.GridPath is not {} path)
return;
ent.Comp.Map = _planet.LoadPlanet(ent.Comp.Planet, path);
}
private void OnShutdown(Entity<StationPlanetSpawnerComponent> ent, ref ComponentShutdown args)
{
QueueDel(ent.Comp.Map);
}
}

View File

@@ -0,0 +1,47 @@
using Content.Server.Advertise.EntitySystems;
using Content.Shared.Advertise.Components;
using Content.Shared.DeltaV.VendingMachines;
namespace Content.Server.DeltaV.VendingMachines;
public sealed class ShopVendorSystem : SharedShopVendorSystem
{
[Dependency] private readonly SpeakOnUIClosedSystem _speakOnUIClosed = default!;
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<ShopVendorComponent, TransformComponent>();
var now = Timing.CurTime;
while (query.MoveNext(out var uid, out var comp, out var xform))
{
var ent = (uid, comp);
var dirty = false;
if (comp.Ejecting is {} ejecting && now > comp.NextEject)
{
Spawn(ejecting, xform.Coordinates);
comp.Ejecting = null;
dirty = true;
}
if (comp.Denying && now > comp.NextDeny)
{
comp.Denying = false;
dirty = true;
}
if (dirty)
{
Dirty(uid, comp);
UpdateVisuals(ent);
}
}
}
protected override void AfterPurchase(Entity<ShopVendorComponent> ent)
{
if (TryComp<SpeakOnUIClosedComponent>(ent, out var speak))
_speakOnUIClosed.TrySetFlag((ent.Owner, speak));
}
}

View File

@@ -0,0 +1,83 @@
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Content.Shared.Weather;
using Content.Shared.Whitelist;
using Robust.Shared.Map.Components;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Shared.DeltaV.Weather;
/// <summary>
/// Handles weather damage for exposed entities.
/// </summary>
public sealed partial class WeatherEffectsSystem : EntitySystem
{
[Dependency] private readonly DamageableSystem _damageable = default!;
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly SharedMapSystem _map = default!;
[Dependency] private readonly SharedWeatherSystem _weather = default!;
private EntityQuery<MapGridComponent> _gridQuery;
public override void Initialize()
{
base.Initialize();
_gridQuery = GetEntityQuery<MapGridComponent>();
}
public override void Update(float frameTime)
{
base.Update(frameTime);
var now = _timing.CurTime;
var query = EntityQueryEnumerator<WeatherComponent>();
while (query.MoveNext(out var map, out var weather))
{
if (now < weather.NextUpdate)
continue;
weather.NextUpdate = now + weather.UpdateDelay;
foreach (var (id, data) in weather.Weather)
{
// start and end do no damage
if (data.State != WeatherState.Running)
continue;
UpdateDamage(map, id);
}
}
}
private void UpdateDamage(EntityUid map, ProtoId<WeatherPrototype> id)
{
var weather = _proto.Index(id);
if (weather.Damage is not {} damage)
return;
var query = EntityQueryEnumerator<MobStateComponent, TransformComponent>();
while (query.MoveNext(out var uid, out var mob, out var xform))
{
// Dead bodies aren't revivable anyways!
if (xform.MapUid != map)
continue;
// if not in space, check for being indoors
if (xform.GridUid is {} gridUid && _gridQuery.TryComp(gridUid, out var grid))
{
var tile = _map.GetTileRef((gridUid, grid), xform.Coordinates);
if (!_weather.CanWeatherAffect(gridUid, grid, tile))
continue;
}
if (_whitelist.IsBlacklistFailOrNull(weather.DamageBlacklist, uid))
_damageable.TryChangeDamage(uid, damage, interruptsDoAfters: false);
}
}
}

View File

@@ -0,0 +1,58 @@
using Content.Shared.Destructible.Thresholds;
using Content.Shared.Weather;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Server.DeltaV.Weather;
/// <summary>
/// Makes weather randomly happen every so often.
/// </summary>
[RegisterComponent, Access(typeof(WeatherSchedulerSystem))]
[AutoGenerateComponentPause]
public sealed partial class WeatherSchedulerComponent : Component
{
/// <summary>
/// Weather stages to schedule.
/// </summary>
[DataField(required: true)]
public List<WeatherStage> Stages = new();
/// <summary>
/// The index of <see cref="Stages"/> to use next, wraps back to the start.
/// </summary>
[DataField]
public int Stage;
/// <summary>
/// When to go to the next step of the schedule.
/// </summary>
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
public TimeSpan NextUpdate;
}
/// <summary>
/// A stage in a weather schedule.
/// </summary>
[Serializable, DataDefinition]
public partial struct WeatherStage
{
/// <summary>
/// A range of how long the stage can last for, in seconds.
/// </summary>
[DataField(required: true)]
public MinMax Duration = new(0, 0);
/// <summary>
/// The weather prototype to add, or null for clear weather.
/// </summary>
[DataField]
public ProtoId<WeatherPrototype>? Weather;
/// <summary>
/// Alert message to send in chat for players on the map when it starts.
/// </summary>
[DataField]
public LocId? Message;
}

View File

@@ -0,0 +1,75 @@
using Content.Server.Chat.Managers;
using Content.Shared.Chat;
using Content.Shared.Weather;
using Robust.Shared.Map.Components;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Timing;
namespace Content.Server.DeltaV.Weather;
public sealed class WeatherSchedulerSystem : EntitySystem
{
[Dependency] private readonly IChatManager _chat = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly SharedWeatherSystem _weather = default!;
public override void Update(float frameTime)
{
base.Update(frameTime);
var now = _timing.CurTime;
var query = EntityQueryEnumerator<WeatherSchedulerComponent>();
while (query.MoveNext(out var map, out var comp))
{
if (now < comp.NextUpdate)
continue;
if (comp.Stage >= comp.Stages.Count)
comp.Stage = 0;
var stage = comp.Stages[comp.Stage++];
var duration = stage.Duration.Next(_random);
comp.NextUpdate = now + TimeSpan.FromSeconds(duration);
var mapId = Comp<MapComponent>(map).MapId;
if (stage.Weather is {} weather)
{
var ending = comp.NextUpdate;
// crossfade weather so as one ends the next starts
if (HasWeather(comp, comp.Stage - 1))
ending += WeatherComponent.ShutdownTime;
if (HasWeather(comp, comp.Stage + 1))
ending += WeatherComponent.StartupTime;
_weather.SetWeather(mapId, _proto.Index(weather), ending);
}
if (stage.Message is {} message)
{
var msg = Loc.GetString(message);
_chat.ChatMessageToManyFiltered(
Filter.BroadcastMap(mapId),
ChatChannel.Radio,
msg,
msg,
map,
false,
true,
null);
}
}
}
private bool HasWeather(WeatherSchedulerComponent comp, int stage)
{
if (stage < 0)
stage = comp.Stages.Count + stage;
else if (stage >= comp.Stages.Count)
stage %= comp.Stages.Count;
return comp.Stages[stage].Weather != null;
}
}

View File

@@ -0,0 +1,109 @@
using Content.Server.Fluids.EntitySystems;
using Content.Server.Procedural;
using Content.Shared.Administration.Logs;
using Content.Shared.Chemistry.Components;
using Content.Shared.Database;
using Content.Shared._DV.Salvage.Components;
using Content.Shared._DV.Salvage.Systems;
using Content.Shared.Maps;
using Content.Shared.Physics;
using Robust.Shared.Map.Components;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Prototypes;
using System.Numerics;
namespace Content.Server._DV.Salvage.Systems;
public sealed class ShelterCapsuleSystem : SharedShelterCapsuleSystem
{
[Dependency] private readonly DungeonSystem _dungeon = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly SharedMapSystem _map = default!;
[Dependency] private readonly SmokeSystem _smoke = default!;
public static readonly EntProtoId SmokePrototype = "Smoke";
private EntityQuery<FixturesComponent> _fixturesQuery;
private HashSet<EntityUid> _entities = new();
public override void Initialize()
{
base.Initialize();
_fixturesQuery = GetEntityQuery<FixturesComponent>();
}
protected override LocId? TrySpawnRoom(Entity<ShelterCapsuleComponent> ent)
{
var xform = Transform(ent);
if (xform.GridUid is not {} gridUid || !TryComp<MapGridComponent>(gridUid, out var grid))
return "shelter-capsule-error-space";
var center = _map.LocalToTile(gridUid, grid, xform.Coordinates);
var room = _proto.Index(ent.Comp.Room);
var origin = center - room.Size / 2;
// check that every tile it needs isn't blocked
var mask = (int) CollisionGroup.MobMask;
if (IsAreaBlocked(gridUid, center, room.Size, mask))
return "shelter-capsule-error-obstructed";
// check that it isn't on space or SpawnRoom will crash
for (int y = 0; y < room.Size.Y; y++)
{
for (int x = 0; x < room.Size.X; x++)
{
var pos = origin + new Vector2i(x, y);
var tile = _map.GetTileRef((gridUid, grid), pos);
if (tile.Tile.IsEmpty)
return "shelter-capsule-error-space";
}
}
var user = ent.Comp.User;
_adminLogger.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(user):user} expanded {ToPrettyString(ent):capsule} at {center} on {ToPrettyString(gridUid):grid}");
_dungeon.SpawnRoom(gridUid,
grid,
origin,
room,
new Random(),
null,
clearExisting: true); // already checked for mobs and structures here
var smoke = Spawn(SmokePrototype, xform.Coordinates);
var spreadAmount = (int) room.Size.Length * 2;
_smoke.StartSmoke(smoke, new Solution(), 3f, spreadAmount);
QueueDel(ent);
return null;
}
private bool IsAreaBlocked(EntityUid grid, Vector2i center, Vector2i size, int mask)
{
// This is scaled to 95 % so it doesn't encompass walls on other tiles.
var aabb = Box2.CenteredAround(center, size * 0.95f);
_entities.Clear();
_lookup.GetLocalEntitiesIntersecting(grid, aabb, _entities, LookupFlags.Dynamic | LookupFlags.Static);
foreach (var uid in _entities)
{
// don't care about non-physical entities
if (!_fixturesQuery.TryComp(uid, out var fixtures))
continue;
foreach (var fixture in fixtures.Fixtures.Values)
{
if (!fixture.Hard)
continue;
if ((fixture.CollisionLayer & mask) != 0)
return true;
}
}
return false; // no entities colliding with the mask found
}
}

View File

@@ -0,0 +1,49 @@
using Content.Shared.Atmos;
using Content.Shared.Parallax.Biomes;
using Content.Shared.Parallax.Biomes.Markers;
using Robust.Shared.Prototypes;
namespace Content.Shared.DeltaV.Planet;
[Prototype]
public sealed partial class PlanetPrototype : IPrototype
{
[IdDataField]
public string ID { get; set; } = string.Empty;
/// <summary>
/// The biome to create the planet with.
/// </summary>
[DataField(required: true)]
public ProtoId<BiomeTemplatePrototype> Biome;
/// <summary>
/// Name to give to the map.
/// </summary>
[DataField(required: true)]
public LocId MapName;
/// <summary>
/// Ambient lighting for the map.
/// </summary>
[DataField]
public Color MapLight = Color.FromHex("#D8B059");
/// <summary>
/// Components to add to the map.
/// </summary>
[DataField]
public ComponentRegistry? AddedComponents;
/// <summary>
/// The gas mixture to use for the atmosphere.
/// </summary>
[DataField(required: true)]
public GasMixture Atmosphere = new();
/// <summary>
/// Biome layers to add to the map, i.e. ores.
/// </summary>
[DataField]
public List<ProtoId<BiomeMarkerLayerPrototype>> BiomeMarkerLayers = new();
}

View File

@@ -0,0 +1,26 @@
using Content.Shared.DeltaV.Salvage.Systems;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
namespace Content.Shared.DeltaV.Salvage.Components;
/// <summary>
/// Stores mining points for a holder, such as an ID card or ore processor.
/// Mining points are gained by smelting ore and redeeming them to your ID card.
/// </summary>
[RegisterComponent, NetworkedComponent, Access(typeof(MiningPointsSystem))]
[AutoGenerateComponentState]
public sealed partial class MiningPointsComponent : Component
{
/// <summary>
/// The number of points stored.
/// </summary>
[DataField, AutoNetworkedField]
public uint Points;
/// <summary>
/// Sound played when successfully transferring points to another holder.
/// </summary>
[DataField]
public SoundSpecifier? TransferSound;
}

View File

@@ -0,0 +1,9 @@
using Robust.Shared.GameStates;
namespace Content.Shared.DeltaV.Salvage.Components;
/// <summary>
/// Adds points to <see cref="MiningPointsComponent"/> when making a recipe that has miningPoints set.
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class MiningPointsLatheComponent : Component;

View File

@@ -0,0 +1,39 @@
using Content.Shared._DV.Salvage.Systems;
using Content.Shared.Procedural;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared._DV.Salvage.Components;
/// <summary>
/// Spawns a dungeon room after a delay when used and deletes itself.
/// </summary>
[RegisterComponent, NetworkedComponent, Access(typeof(SharedShelterCapsuleSystem))]
[AutoGenerateComponentPause]
public sealed partial class ShelterCapsuleComponent : Component
{
/// <summary>
/// The room to spawn.
/// </summary>
[DataField(required: true)]
public ProtoId<DungeonRoomPrototype> Room;
/// <summary>
/// How long to wait between using and spawning the room.
/// </summary>
[DataField]
public TimeSpan Delay = TimeSpan.FromSeconds(5);
/// <summary>
/// When to next spawn the room, also used to ignore activating multiple times.
/// </summary>
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
public TimeSpan? NextSpawn;
/// <summary>
/// The user of the capsule, used for logging.
/// </summary>
[DataField]
public EntityUid? User;
}

View File

@@ -0,0 +1,9 @@
using Robust.Shared.Serialization;
namespace Content.Shared.DeltaV.Salvage;
/// <summary>
/// Message for a lathe to transfer its mining points to the user's id card.
/// </summary>
[Serializable, NetSerializable]
public sealed class LatheClaimMiningPointsMessage : BoundUserInterfaceMessage;

View File

@@ -0,0 +1,121 @@
using Content.Shared.Access.Systems;
using Content.Shared.DeltaV.Salvage.Components;
using Content.Shared.Lathe;
using Robust.Shared.Audio.Systems;
namespace Content.Shared.DeltaV.Salvage.Systems;
public sealed class MiningPointsSystem : EntitySystem
{
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedIdCardSystem _idCard = default!;
private EntityQuery<MiningPointsComponent> _query;
public override void Initialize()
{
base.Initialize();
_query = GetEntityQuery<MiningPointsComponent>();
SubscribeLocalEvent<MiningPointsLatheComponent, LatheStartPrintingEvent>(OnStartPrinting);
Subs.BuiEvents<MiningPointsLatheComponent>(LatheUiKey.Key, subs =>
{
subs.Event<LatheClaimMiningPointsMessage>(OnClaimMiningPoints);
});
}
#region Event Handlers
private void OnStartPrinting(Entity<MiningPointsLatheComponent> ent, ref LatheStartPrintingEvent args)
{
var points = args.Recipe.MiningPoints;
if (points > 0)
AddPoints(ent.Owner, points);
}
private void OnClaimMiningPoints(Entity<MiningPointsLatheComponent> ent, ref LatheClaimMiningPointsMessage args)
{
var user = args.Actor;
if (TryFindIdCard(user) is {} dest)
TransferAll(ent.Owner, dest);
}
#endregion
#region Public API
/// <summary>
/// Tries to find the user's id card and gets its <see cref="MiningPointsComponent"/>.
/// </summary>
/// <remarks>
/// Component is nullable for easy usage with the API due to Entity&lt;T&gt; not being usable for Entity&lt;T?&gt; arguments.
/// </remarks>
public Entity<MiningPointsComponent?>? TryFindIdCard(EntityUid user)
{
if (!_idCard.TryFindIdCard(user, out var idCard))
return null;
if (!_query.TryComp(idCard, out var comp))
return null;
return (idCard, comp);
}
/// <summary>
/// Removes points from a holder, returning true if it succeeded.
/// </summary>
public bool RemovePoints(Entity<MiningPointsComponent?> ent, uint amount)
{
if (!_query.Resolve(ent, ref ent.Comp) || amount > ent.Comp.Points)
return false;
ent.Comp.Points -= amount;
Dirty(ent);
return true;
}
/// <summary>
/// Add points to a holder.
/// </summary>
public bool AddPoints(Entity<MiningPointsComponent?> ent, uint amount)
{
if (!_query.Resolve(ent, ref ent.Comp))
return false;
ent.Comp.Points += amount;
Dirty(ent);
return true;
}
/// <summary>
/// Transfer a number of points from source to destination.
/// Returns true if the transfer succeeded.
/// </summary>
public bool Transfer(Entity<MiningPointsComponent?> src, Entity<MiningPointsComponent?> dest, uint amount)
{
// don't make a sound or anything
if (amount == 0)
return true;
if (!_query.Resolve(src, ref src.Comp) || !_query.Resolve(dest, ref dest.Comp))
return false;
if (!RemovePoints(src, amount))
return false;
AddPoints(dest, amount);
_audio.PlayPvs(src.Comp.TransferSound, src);
return true;
}
/// <summary>
/// Transfers all points from source to destination.
/// Returns true if the transfer succeeded.
/// </summary>
public bool TransferAll(Entity<MiningPointsComponent?> src, Entity<MiningPointsComponent?> dest)
{
return _query.Resolve(src, ref src.Comp) && Transfer(src, dest, src.Comp.Points);
}
#endregion
}

View File

@@ -0,0 +1,66 @@
using Content.Shared._DV.Salvage.Components;
using Content.Shared.Interaction.Events;
using Content.Shared.Popups;
using Robust.Shared.Timing;
namespace Content.Shared._DV.Salvage.Systems;
/// <summary>
/// Handles interaction for shelter capsules.
/// Room spawning is done serverside.
/// </summary>
public abstract class SharedShelterCapsuleSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ShelterCapsuleComponent, UseInHandEvent>(OnUse);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
var now = _timing.CurTime;
var query = EntityQueryEnumerator<ShelterCapsuleComponent>();
while (query.MoveNext(out var uid, out var comp))
{
if (comp.NextSpawn is not {} nextSpawn || now < nextSpawn)
continue;
comp.User = null;
comp.NextSpawn = null;
if (TrySpawnRoom((uid, comp)) is {} id)
{
var msg = Loc.GetString(id, ("capsule", uid));
_popup.PopupEntity(msg, uid, PopupType.LargeCaution);
}
}
}
/// <summary>
/// Spawn the room, returning a locale string for an error. It gets "capsule" passed.
/// </summary>
protected virtual LocId? TrySpawnRoom(Entity<ShelterCapsuleComponent> ent)
{
return null;
}
private void OnUse(Entity<ShelterCapsuleComponent> ent, ref UseInHandEvent args)
{
if (args.Handled || ent.Comp.NextSpawn != null)
return;
args.Handled = true;
var msg = Loc.GetString("shelter-capsule-warning", ("capsule", ent));
_popup.PopupPredicted(msg, ent, args.User, PopupType.LargeCaution);
ent.Comp.User = args.User;
ent.Comp.NextSpawn = _timing.CurTime + ent.Comp.Delay;
}
}

View File

@@ -0,0 +1,48 @@
using Content.Shared.DeltaV.Shuttles.Systems;
using Content.Shared.Tag;
using Content.Shared.Whitelist;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Shared.DeltaV.Shuttles.Components;
/// <summary>
/// A shuttle console that can only ftl-dock between 2 grids.
/// The shuttle used must have <see cref="DockingShuttleComponent"/>.
/// </summary>
[RegisterComponent, NetworkedComponent, Access(typeof(SharedDockingConsoleSystem))]
[AutoGenerateComponentState]
public sealed partial class DockingConsoleComponent : Component
{
/// <summary>
/// Title of the window to use
/// </summary>
[DataField(required: true)]
public LocId WindowTitle;
/// <summary>
/// Airlock tag that it will prioritize docking to.
/// </summary>
[DataField(required: true)]
public ProtoId<TagPrototype> DockTag;
/// <summary>
/// A whitelist the shuttle has to match to be piloted.
/// </summary>
[DataField(required: true)]
public EntityWhitelist ShuttleWhitelist = new();
/// <summary>
/// The shuttle that matches <see cref="ShuttleWhitelist"/>.
/// If this is null a shuttle was not found and this console does nothing.
/// </summary>
[DataField]
public EntityUid? Shuttle;
/// <summary>
/// Whether <see cref="Shuttle"/> is set on the server or not.
/// Client can't use Shuttle outside of PVS range so that isn't networked.
/// </summary>
[DataField, AutoNetworkedField]
public bool HasShuttle;
}

View File

@@ -0,0 +1,46 @@
using Content.Shared.DeltaV.Shuttles.Systems;
using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Serialization;
namespace Content.Shared.DeltaV.Shuttles.Components;
/// <summary>
/// Component that stores destinations a docking-only shuttle can use.
/// Used by <see cref="DockingConsoleComponent"/> to access destinations.
/// </summary>
[RegisterComponent, NetworkedComponent, Access(typeof(SharedDockingShuttleSystem))]
public sealed partial class DockingShuttleComponent : Component
{
/// <summary>
/// The station this shuttle belongs to.
/// </summary>
[DataField]
public EntityUid? Station;
/// <summary>
/// Every destination this console can FTL to.
/// </summary>
[DataField]
public List<DockingDestination> Destinations = new();
}
/// <summary>
/// A map a shuttle can FTL to.
/// Created automatically on shuttle mapinit.
/// </summary>
[DataDefinition, Serializable, NetSerializable]
public partial struct DockingDestination
{
/// <summary>
/// The name of the destination to use in UI.
/// </summary>
[DataField]
public LocId Name;
/// <summary>
/// The map ID.
/// </summary>
[DataField]
public MapId Map;
}

View File

@@ -0,0 +1,10 @@
using Robust.Shared.GameStates;
namespace Content.Shared.DeltaV.Shuttles.Components;
/// <summary>
/// Marker component for the mining shuttle grid.
/// Used for lavaland's FTL whitelist.
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class MiningShuttleComponent : Component;

View File

@@ -0,0 +1,30 @@
using Content.Shared.DeltaV.Shuttles.Components;
using Content.Shared.Shuttles.Systems;
using Content.Shared.Timing;
using Robust.Shared.Serialization;
namespace Content.Shared.DeltaV.Shuttles;
[Serializable, NetSerializable]
public enum DockingConsoleUiKey : byte
{
Key
}
[Serializable, NetSerializable]
public sealed class DockingConsoleState(FTLState ftlState, StartEndTime ftlTime, List<DockingDestination> destinations) : BoundUserInterfaceState
{
public FTLState FTLState = ftlState;
public StartEndTime FTLTime = ftlTime;
public List<DockingDestination> Destinations = destinations;
}
[Serializable, NetSerializable]
public sealed class DockingConsoleFTLMessage(int index) : BoundUserInterfaceMessage
{
public int Index = index;
}
[Serializable, NetSerializable]
public sealed class DockingConsoleShuttleCheckMessage : BoundUserInterfaceMessage;

View File

@@ -0,0 +1,3 @@
namespace Content.Shared.DeltaV.Shuttles.Systems;
public abstract class SharedDockingConsoleSystem : EntitySystem;

View File

@@ -0,0 +1,3 @@
namespace Content.Shared.DeltaV.Shuttles.Systems;
public abstract class SharedDockingShuttleSystem : EntitySystem;

View File

@@ -0,0 +1,9 @@
using Robust.Shared.GameStates;
namespace Content.Shared.DeltaV.VendingMachines;
/// <summary>
/// Makes a <see cref="ShopVendorComponent"/> use mining points to buy items.
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class PointsVendorComponent : Component;

View File

@@ -0,0 +1,181 @@
using Content.Shared.Access.Systems;
using Content.Shared.DeltaV.Salvage.Systems;
using Content.Shared.Destructible;
using Content.Shared.Popups;
using Content.Shared.Power;
using Content.Shared.Power.EntitySystems;
using Content.Shared.UserInterface;
using Content.Shared.VendingMachines;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Shared.DeltaV.VendingMachines;
public abstract class SharedShopVendorSystem : EntitySystem
{
[Dependency] private readonly AccessReaderSystem _access = default!;
[Dependency] private readonly MiningPointsSystem _points = default!;
[Dependency] protected readonly IGameTiming Timing = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedPointLightSystem _light = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly SharedPowerReceiverSystem _power = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<PointsVendorComponent, ShopVendorBalanceEvent>(OnPointsBalance);
SubscribeLocalEvent<PointsVendorComponent, ShopVendorPurchaseEvent>(OnPointsPurchase);
SubscribeLocalEvent<ShopVendorComponent, PowerChangedEvent>(OnPowerChanged);
SubscribeLocalEvent<ShopVendorComponent, BreakageEventArgs>(OnBreak);
SubscribeLocalEvent<ShopVendorComponent, ActivatableUIOpenAttemptEvent>(OnOpenAttempt);
Subs.BuiEvents<ShopVendorComponent>(VendingMachineUiKey.Key, subs =>
{
subs.Event<ShopVendorPurchaseMessage>(OnPurchase);
});
}
#region Public API
public uint GetBalance(EntityUid uid, EntityUid user)
{
var ev = new ShopVendorBalanceEvent(user);
RaiseLocalEvent(uid, ref ev);
return ev.Balance;
}
#endregion
#region Balance adapters
private void OnPointsBalance(Entity<PointsVendorComponent> ent, ref ShopVendorBalanceEvent args)
{
args.Balance = _points.TryFindIdCard(args.User)?.Comp?.Points ?? 0;
}
private void OnPointsPurchase(Entity<PointsVendorComponent> ent, ref ShopVendorPurchaseEvent args)
{
if (_points.TryFindIdCard(args.User) is {} idCard && _points.RemovePoints(idCard, args.Cost))
args.Paid = true;
}
#endregion
private void OnPowerChanged(Entity<ShopVendorComponent> ent, ref PowerChangedEvent args)
{
UpdateVisuals(ent);
}
private void OnBreak(Entity<ShopVendorComponent> ent, ref BreakageEventArgs args)
{
ent.Comp.Broken = true;
UpdateVisuals(ent);
}
private void OnOpenAttempt(Entity<ShopVendorComponent> ent, ref ActivatableUIOpenAttemptEvent args)
{
if (ent.Comp.Broken)
args.Cancel();
}
private void OnPurchase(Entity<ShopVendorComponent> ent, ref ShopVendorPurchaseMessage args)
{
if (ent.Comp.Ejecting != null || ent.Comp.Broken || !_power.IsPowered(ent.Owner))
return;
var pack = _proto.Index(ent.Comp.Pack);
if (args.Index < 0 || args.Index >= pack.Listings.Count)
return;
var user = args.Actor;
if (!_access.IsAllowed(user, ent))
{
Deny(ent, user);
return;
}
var listing = pack.Listings[args.Index];
var ev = new ShopVendorPurchaseEvent(user, listing.Cost);
RaiseLocalEvent(ent, ref ev);
if (!ev.Paid)
{
Deny(ent, user);
return;
}
ent.Comp.Ejecting = listing.Id;
ent.Comp.NextEject = Timing.CurTime + ent.Comp.EjectDelay;
Dirty(ent);
_audio.PlayPvs(ent.Comp.PurchaseSound, ent);
UpdateVisuals(ent);
Log.Debug($"Player {ToPrettyString(user):user} purchased {listing.Id} from {ToPrettyString(ent):vendor}");
AfterPurchase(ent);
}
protected virtual void AfterPurchase(Entity<ShopVendorComponent> ent)
{
}
private void Deny(Entity<ShopVendorComponent> ent, EntityUid user)
{
_popup.PopupClient(Loc.GetString("vending-machine-component-try-eject-access-denied"), ent, user);
if (ent.Comp.Denying)
return;
ent.Comp.Denying = true;
ent.Comp.NextDeny = Timing.CurTime + ent.Comp.DenyDelay;
Dirty(ent);
_audio.PlayPvs(ent.Comp.DenySound, ent);
UpdateVisuals(ent);
}
protected void UpdateVisuals(Entity<ShopVendorComponent> ent)
{
var state = VendingMachineVisualState.Normal;
var lit = true;
if (ent.Comp.Broken)
{
state = VendingMachineVisualState.Broken;
lit = false;
}
else if (ent.Comp.Ejecting != null)
{
state = VendingMachineVisualState.Eject;
}
else if (ent.Comp.Denying)
{
state = VendingMachineVisualState.Deny;
}
else if (!_power.IsPowered(ent.Owner))
{
state = VendingMachineVisualState.Off;
lit = true;
}
_light.SetEnabled(ent, lit);
_appearance.SetData(ent, VendingMachineVisuals.VisualState, state);
}
}
/// <summary>
/// Raised on a shop vendor to get its current balance.
/// A currency component sets Balance to whatever it is.
/// </summary>
[ByRefEvent]
public record struct ShopVendorBalanceEvent(EntityUid User, uint Balance = 0);
/// <summary>
/// Raised on a shop vendor when trying to purchase an item.
/// A currency component sets Paid to true if the user successfully paid for it.
/// </summary>
[ByRefEvent]
public record struct ShopVendorPurchaseEvent(EntityUid User, uint Cost, bool Paid = false);

View File

@@ -0,0 +1,23 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared.DeltaV.VendingMachines;
/// <summary>
/// Similar to <c>VendingMachineInventoryPrototype</c> but for <see cref="ShopVendorComponent"/>.
/// </summary>
[Prototype]
public sealed class ShopInventoryPrototype : IPrototype
{
[IdDataField]
public string ID { get; private set; } = default!;
/// <summary>
/// The item listings for sale.
/// </summary>
[DataField(required: true)]
public List<ShopListing> Listings = new();
}
[DataRecord, Serializable]
public record struct ShopListing(EntProtoId Id, uint Cost);

View File

@@ -0,0 +1,96 @@
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared.DeltaV.VendingMachines;
/// <summary>
/// A vending machine that sells items for a currency controlled by events.
/// Does not need restocking.
/// Another component must handle <see cref="ShopVendorBalanceEvent"/> and <see cref="ShopVendorPurchaseEvent"/> to work.
/// </summary>
[RegisterComponent, NetworkedComponent, Access(typeof(SharedShopVendorSystem))]
[AutoGenerateComponentState, AutoGenerateComponentPause]
public sealed partial class ShopVendorComponent : Component
{
/// <summary>
/// The inventory prototype to sell.
/// </summary>
[DataField(required: true)]
public ProtoId<ShopInventoryPrototype> Pack;
[DataField, AutoNetworkedField]
public bool Broken;
[DataField, AutoNetworkedField]
public bool Denying;
/// <summary>
/// Item being ejected, or null if it isn't.
/// </summary>
[DataField, AutoNetworkedField]
public EntProtoId? Ejecting;
/// <summary>
/// How long to wait before flashing denied again.
/// </summary>
[DataField]
public TimeSpan DenyDelay = TimeSpan.FromSeconds(2);
/// <summary>
/// How long to wait before another item can be bought
/// </summary>
[DataField]
public TimeSpan EjectDelay = TimeSpan.FromSeconds(1.2);
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan NextDeny;
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan NextEject;
[DataField]
public SoundSpecifier PurchaseSound = new SoundPathSpecifier("/Audio/Machines/machine_vend.ogg")
{
Params = new AudioParams
{
Volume = -4f,
Variation = 0.15f
}
};
[DataField]
public SoundSpecifier DenySound = new SoundPathSpecifier("/Audio/Machines/custom_deny.ogg")
{
Params = new AudioParams
{
Volume = -2f
}
};
#region Visuals
[DataField]
public bool LoopDenyAnimation = true;
[DataField]
public string? OffState;
[DataField]
public string? ScreenState;
[DataField]
public string? NormalState;
[DataField]
public string? DenyState;
[DataField]
public string? EjectState;
[DataField]
public string? BrokenState;
#endregion
}

View File

@@ -0,0 +1,9 @@
using Robust.Shared.Serialization;
namespace Content.Shared.DeltaV.VendingMachines;
[Serializable, NetSerializable]
public sealed class ShopVendorPurchaseMessage(int index) : BoundUserInterfaceMessage
{
public readonly int Index = index;
}

View File

@@ -0,0 +1,9 @@
using Robust.Shared.GameStates;
namespace Content.Shared.DeltaV.Weather.Components;
/// <summary>
/// Makes an entity not take damage from ash storms.
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class AshStormImmuneComponent : Component;

View File

@@ -69,5 +69,13 @@ namespace Content.Shared.Research.Prototypes
/// </summary>
[DataField]
public List<ProtoId<LatheCategoryPrototype>> Categories = new();
public ProtoId<LatheCategoryPrototype>? Category;
/// <summary>
/// DeltaV: Number of mining points this recipe adds to an oreproc when printed.
/// Scales with stack count.
/// </summary>
[DataField]
public uint MiningPoints;
}
}

View File

@@ -38,6 +38,7 @@ public abstract class SharedWeatherSystem : EntitySystem
if (weather.EndTime != null)
weather.EndTime = weather.EndTime.Value + args.PausedTime;
}
component.NextUpdate += args.PausedTime; // DeltaV
}
public bool CanWeatherAffect(EntityUid uid, MapGridComponent grid, TileRef tileRef, RoofComponent? roofComp = null)

View File

@@ -14,6 +14,18 @@ public sealed partial class WeatherComponent : Component
[DataField]
public Dictionary<ProtoId<WeatherPrototype>, WeatherData> Weather = new();
/// <summary>
/// DeltaV: How long to wait between updating weather effects.
/// </summary>
[DataField]
public TimeSpan UpdateDelay = TimeSpan.FromSeconds(1);
/// <summary>
/// DeltaV: When to next update weather effects (damage).
/// </summary>
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan NextUpdate = TimeSpan.Zero;
public static readonly TimeSpan StartupTime = TimeSpan.FromSeconds(15);
public static readonly TimeSpan ShutdownTime = TimeSpan.FromSeconds(15);
}

View File

@@ -1,3 +1,5 @@
using Content.Shared.Damage;
using Content.Shared.Whitelist;
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
@@ -20,4 +22,17 @@ public sealed partial class WeatherPrototype : IPrototype
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("sound")]
public SoundSpecifier? Sound;
/// <summary>
/// DeltaV: Damage you can take from being in this weather.
/// Only applies when weather has fully set in.
/// </summary>
[DataField]
public DamageSpecifier? Damage;
/// <summary>
/// DeltaV: Don't damage entities that match this blacklist.
/// </summary>
[DataField]
public EntityWhitelist? DamageBlacklist;
}

View File

@@ -0,0 +1,3 @@
shelter-capsule-warning = {THE($capsule)} begins to shake. Stand back!
shelter-capsule-error-space = {THE($capsule)} needs ground to deploy on!
shelter-capsule-error-obstructed = {THE($capsule)} is obstructed, clear the area first!

View File

@@ -0,0 +1,2 @@
lathe-menu-mining-points = Mining Points: {$points}
lathe-menu-mining-points-claim-button = Claim Points

View File

@@ -0,0 +1,7 @@
docking-console-no-shuttle = No Shuttle Detected
docking-console-ftl = FTL
mining-console-window-title = Mining Shuttle Console
shuttle-destination-lavaland = Lavaland
shuttle-destination-glacier-surface = Glacier Surface

View File

@@ -0,0 +1,4 @@
shop-vendor-balance = Balance: {$points}
shop-vendor-stack-suffix = x{$count}
shop-vendor-flavor-left = All payments are secure
shop-vendor-flavor-right = v1.2

View File

@@ -0,0 +1,3 @@
ash-storm-telegraph = [color=red][bold]An eerie moan rises on the wind. Sheets of burning ash blacken the horizon. Seek shelter.[/bold][/color]
ash-storm-alert = [color=red][bolditalic]Smoldering clouds of scorching ash billow down around you! Get inside![/bolditalic][/color]
ash-storm-clearing = [color=red]The shrieking wind whips away the last of the ash and falls to its usual murmur. It should be safe to go outside now.[/color]

View File

@@ -7,14 +7,14 @@ game-ticker-unknown-role = Unknown
game-ticker-delay-start = Round start has been delayed for {$seconds} seconds.
game-ticker-pause-start = Round start has been paused.
game-ticker-pause-start-resumed = Round start countdown is now resumed.
game-ticker-player-join-game-message = Welcome to Space Station 14! If this is your first time playing, be sure to read the game rules, and don't be afraid to ask for help in LOOC (local OOC) or OOC (usually available only between rounds).
game-ticker-get-info-text = Hi and welcome to [color=white]Space Station 14![/color]
game-ticker-player-join-game-message = Welcome to TBD Station 14! If this is your first time playing, be sure to read the rules, and don't be afraid to ask for help in LOOC (local OOC, only for people near you) or OOC (global, can be heard from anywhere by anyone)!
game-ticker-get-info-text = Hi and welcome to [color=white]TBD Station 14![/color]
The current round is: [color=white]#{$roundId}[/color]
The current player count is: [color=white]{$playerCount}[/color]
The current map is: [color=white]{$mapName}[/color]
The current game mode is: [color=white]{$gmTitle}[/color]
>[color=yellow]{$desc}[/color]
game-ticker-get-info-preround-text = Hi and welcome to [color=white]Space Station 14![/color]
game-ticker-get-info-preround-text = Hi and welcome to [color=white]TBD Station 14![/color]
The current round is: [color=white]#{$roundId}[/color]
The current player count is: [color=white]{$playerCount}[/color] ([color=white]{$readyCount}[/color] {$readyCount ->
[one] is

View File

@@ -1,6 +1,6 @@
### Connecting dialog when you start up the game
connecting-title = Space Station 14
connecting-title = TBD Station 14
connecting-exit = Exit
connecting-retry = Retry
connecting-reconnect = Reconnect
@@ -11,7 +11,7 @@ connecting-in-progress = Connecting to server...
connecting-disconnected = Disconnected from server:
connecting-tip = Don't die!
connecting-window-tip = Tip { $numberTip }
connecting-version = ver 0.1
connecting-version = ver 0.67
connecting-fail-reason = Failed to connect to server:
{ $reason }
connecting-state-NotConnecting = Not connecting

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,495 @@
meta:
format: 6
postmapinit: false
tilemap:
0: Space
74: FloorMono
84: FloorReinforced
89: FloorShuttleBlue
98: FloorSteel
130: Lattice
131: Plating
entities:
- proto: ""
entities:
- uid: 1
components:
- type: MetaData
name: Mining Shuttle
- type: Transform
- type: MapGrid
chunks:
0,0:
ind: 0,0
tiles: YgAAAAAAYgAAAAAASgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYgAAAAAAYgAAAAAAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWQAAAAAAWQAAAAAAgwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVAAAAAAAgwAAAAAAggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
version: 6
0,-1:
ind: 0,-1
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgwAAAAAAgwAAAAAAggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVAAAAAAAWQAAAAAAgwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWQAAAAAAWQAAAAAAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
version: 6
-1,-1:
ind: -1,-1
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAggAAAAAAgwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgwAAAAAAWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVAAAAAAAWQAAAAAA
version: 6
-1,0:
ind: -1,0
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgwAAAAAAYgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVAAAAAAAYgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgwAAAAAAWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAggAAAAAAgwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
version: 6
- type: Broadphase
- type: Physics
bodyStatus: InAir
angularDamping: 0.05
linearDamping: 0.05
fixedRotation: False
bodyType: Dynamic
- type: Fixtures
fixtures: {}
- type: OccluderTree
- type: SpreaderGrid
- type: Shuttle
- type: MiningShuttle
- type: DockingShuttle
destinations: []
- type: ProtectedGrid
- type: Gravity
gravityShakeSound: !type:SoundPathSpecifier
path: /Audio/Effects/alert.ogg
- type: GridPathfinding
- type: DecalGrid
chunkCollection:
version: 2
nodes: []
- type: GridAtmosphere
version: 2
data:
tiles:
0,0:
0: 823
1: 16384
0,-1:
0: 13072
1: 64
-1,0:
0: 2184
1: 16384
-1,-1:
0: 34816
1: 64
uniqueMixes:
- volume: 2500
temperature: 293.15
moles:
- 21.824879
- 82.10312
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- volume: 2500
immutable: True
moles:
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
chunkSize: 4
- type: GasTileOverlay
- type: RadiationGridResistance
- proto: AirlockShuttle
entities:
- uid: 2
components:
- type: Transform
rot: 1.5707963267948966 rad
pos: 2.5,0.5
parent: 1
- proto: APCBasic
entities:
- uid: 3
components:
- type: Transform
rot: -1.5707963267948966 rad
pos: 2.5,-1.5
parent: 1
- proto: AtmosDeviceFanDirectional
entities:
- uid: 4
components:
- type: Transform
rot: 1.5707963267948966 rad
pos: 2.5,0.5
parent: 1
- proto: CableApcExtension
entities:
- uid: 5
components:
- type: Transform
pos: 2.5,-1.5
parent: 1
- uid: 6
components:
- type: Transform
pos: 1.5,-1.5
parent: 1
- uid: 7
components:
- type: Transform
pos: 0.5,-1.5
parent: 1
- uid: 8
components:
- type: Transform
pos: 0.5,-0.5
parent: 1
- uid: 9
components:
- type: Transform
pos: 0.5,0.5
parent: 1
- uid: 10
components:
- type: Transform
pos: 0.5,1.5
parent: 1
- uid: 11
components:
- type: Transform
pos: 0.5,2.5
parent: 1
- proto: CableHV
entities:
- uid: 12
components:
- type: Transform
pos: -0.5,-2.5
parent: 1
- uid: 13
components:
- type: Transform
pos: -0.5,-1.5
parent: 1
- uid: 14
components:
- type: Transform
pos: -1.5,-1.5
parent: 1
- proto: CableMV
entities:
- uid: 15
components:
- type: Transform
pos: -1.5,-1.5
parent: 1
- uid: 16
components:
- type: Transform
pos: 0.5,-1.5
parent: 1
- uid: 17
components:
- type: Transform
pos: 1.5,-1.5
parent: 1
- uid: 18
components:
- type: Transform
pos: 2.5,-1.5
parent: 1
- uid: 19
components:
- type: Transform
pos: -0.5,-1.5
parent: 1
- proto: ChairPilotSeat
entities:
- uid: 20
components:
- type: Transform
rot: 3.141592653589793 rad
pos: 0.5,1.5
parent: 1
- uid: 21
components:
- type: Transform
rot: 3.141592653589793 rad
pos: -0.5,-0.5
parent: 1
- uid: 22
components:
- type: Transform
rot: 3.141592653589793 rad
pos: 0.5,-0.5
parent: 1
- uid: 23
components:
- type: Transform
rot: 3.141592653589793 rad
pos: 1.5,-0.5
parent: 1
- proto: ComputerShuttleMining
entities:
- uid: 24
components:
- type: Transform
pos: 0.5,2.5
parent: 1
- proto: CrateGenericSteel
entities:
- uid: 25
components:
- type: Transform
pos: -0.5,-1.5
parent: 1
- proto: GasPassiveVent
entities:
- uid: 26
components:
- type: Transform
rot: 3.141592653589793 rad
pos: 0.5,-2.5
parent: 1
- type: AtmosPipeColor
color: '#990000FF'
- proto: GasPipeStraight
entities:
- uid: 27
components:
- type: Transform
pos: 0.5,-0.5
parent: 1
- type: AtmosPipeColor
color: '#990000FF'
- uid: 28
components:
- type: Transform
pos: 0.5,-1.5
parent: 1
- type: AtmosPipeColor
color: '#990000FF'
- proto: GasVentScrubber
entities:
- uid: 29
components:
- type: Transform
pos: 0.5,0.5
parent: 1
- type: AtmosPipeColor
color: '#990000FF'
- proto: GeneratorWallmountBasic
entities:
- uid: 30
components:
- type: Transform
pos: -0.5,-2.5
parent: 1
- proto: GravityGeneratorMini
entities:
- uid: 63
components:
- type: Transform
pos: 0.5,-1.5
parent: 1
- proto: Grille
entities:
- uid: 31
components:
- type: Transform
pos: -1.5,-0.5
parent: 1
- uid: 32
components:
- type: Transform
pos: -1.5,1.5
parent: 1
- uid: 33
components:
- type: Transform
pos: 2.5,1.5
parent: 1
- uid: 34
components:
- type: Transform
pos: 2.5,-0.5
parent: 1
- uid: 35
components:
- type: Transform
pos: 0.5,3.5
parent: 1
- proto: OreBox
entities:
- uid: 36
components:
- type: Transform
pos: 1.5,-1.5
parent: 1
- proto: Poweredlight
entities:
- uid: 37
components:
- type: Transform
rot: 1.5707963267948966 rad
pos: -0.5,0.5
parent: 1
- proto: ShuttleWindow
entities:
- uid: 38
components:
- type: Transform
pos: 2.5,1.5
parent: 1
- uid: 39
components:
- type: Transform
pos: 0.5,3.5
parent: 1
- uid: 40
components:
- type: Transform
pos: -1.5,1.5
parent: 1
- uid: 41
components:
- type: Transform
pos: -1.5,-0.5
parent: 1
- uid: 42
components:
- type: Transform
pos: 2.5,-0.5
parent: 1
- proto: SubstationWallBasic
entities:
- uid: 43
components:
- type: Transform
rot: 1.5707963267948966 rad
pos: -1.5,-1.5
parent: 1
- proto: Table
entities:
- uid: 44
components:
- type: Transform
pos: -0.5,2.5
parent: 1
- uid: 45
components:
- type: Transform
pos: 1.5,2.5
parent: 1
- proto: Thruster
entities:
- uid: 46
components:
- type: Transform
rot: 3.141592653589793 rad
pos: 0.5,-2.5
parent: 1
- proto: WallShuttle
entities:
- uid: 47
components:
- type: Transform
pos: 2.5,2.5
parent: 1
- uid: 48
components:
- type: Transform
pos: 1.5,3.5
parent: 1
- uid: 49
components:
- type: Transform
pos: -0.5,3.5
parent: 1
- uid: 50
components:
- type: Transform
pos: -1.5,2.5
parent: 1
- uid: 51
components:
- type: Transform
pos: -1.5,0.5
parent: 1
- uid: 52
components:
- type: Transform
pos: -1.5,-1.5
parent: 1
- uid: 53
components:
- type: Transform
pos: -0.5,-2.5
parent: 1
- uid: 54
components:
- type: Transform
pos: 1.5,-2.5
parent: 1
- uid: 55
components:
- type: Transform
pos: 2.5,-1.5
parent: 1
- proto: WallShuttleDiagonal
entities:
- uid: 56
components:
- type: Transform
rot: -1.5707963267948966 rad
pos: 2.5,3.5
parent: 1
- uid: 57
components:
- type: Transform
rot: 3.141592653589793 rad
pos: 2.5,-2.5
parent: 1
- uid: 58
components:
- type: Transform
rot: 1.5707963267948966 rad
pos: -1.5,-2.5
parent: 1
- uid: 59
components:
- type: Transform
pos: -1.5,3.5
parent: 1
- proto: WindowReinforcedDirectional
entities:
- uid: 60
components:
- type: Transform
rot: 1.5707963267948966 rad
pos: 0.5,-1.5
parent: 1
- uid: 61
components:
- type: Transform
rot: -1.5707963267948966 rad
pos: 0.5,-1.5
parent: 1
- uid: 62
components:
- type: Transform
rot: 3.141592653589793 rad
pos: 0.5,-1.5
parent: 1
...

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -4,8 +4,8 @@ meta:
engineVersion: 268.0.0
forkId: ""
forkVersion: ""
time: 11/24/2025 21:47:10
entityCount: 2899
time: 11/27/2025 18:20:30
entityCount: 2900
maps:
- 1
grids:
@@ -107,7 +107,7 @@ entities:
version: 7
-1,1:
ind: -1,1
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAAAAAAAfQAAAAAAAH0AAAAAAAB9AAAAAAAAbQAAAAAAAH4AAAAAAAB+AAAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAAH4AAAAAAABtAAAAAAAAfgAAAAAAAG0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAAAAAAAfQAAAAAAAH0AAAAAAAB9AAAAAAAAbQAAAAAAAH4AAAAAAAB+AAAAAAAAbQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAAH4AAAAAAABtAAAAAAAAfgAAAAAAAG0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
version: 7
-1,-2:
ind: -1,-2
@@ -1069,7 +1069,7 @@ entities:
-2,4:
0: 14
-1,4:
1: 175
1: 47
0,-5:
1: 24576
0: 3584
@@ -1582,14 +1582,8 @@ entities:
rot: 1.5707963267948966 rad
pos: 13.5,13.5
parent: 2
- proto: AirlockExternalGlassShuttleLocked
- proto: AirlockExternalGlassShuttleMining
entities:
- uid: 44
components:
- type: Transform
rot: 3.141592653589793 rad
pos: -0.5,17.5
parent: 2
- uid: 45
components:
- type: Transform
@@ -1977,12 +1971,6 @@ entities:
rot: 3.141592653589793 rad
pos: -2.5,17.5
parent: 2
- uid: 100
components:
- type: Transform
rot: 3.141592653589793 rad
pos: -0.5,17.5
parent: 2
- uid: 101
components:
- type: Transform
@@ -4402,6 +4390,11 @@ entities:
- type: Transform
pos: -4.5,-14.5
parent: 2
- uid: 2900
components:
- type: Transform
pos: -5.5,10.5
parent: 2
- proto: CableHV
entities:
- uid: 571
@@ -6857,11 +6850,6 @@ entities:
- type: Transform
pos: -0.5,15.5
parent: 2
- uid: 1053
components:
- type: Transform
pos: -0.5,16.5
parent: 2
- uid: 1054
components:
- type: Transform
@@ -7790,6 +7778,13 @@ entities:
- type: Transform
pos: 2.5,13.5
parent: 2
- proto: ComputerShuttleMining
entities:
- uid: 1053
components:
- type: Transform
pos: -0.5,16.5
parent: 2
- proto: ComputerSurveillanceCameraMonitor
entities:
- uid: 1200
@@ -12183,6 +12178,11 @@ entities:
radius: 175.75
- proto: Grille
entities:
- uid: 44
components:
- type: Transform
pos: -0.5,17.5
parent: 2
- uid: 1812
components:
- type: Transform
@@ -14758,6 +14758,11 @@ entities:
parent: 2
- proto: ShuttleWindow
entities:
- uid: 100
components:
- type: Transform
pos: -0.5,17.5
parent: 2
- uid: 2183
components:
- type: Transform

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,50 @@
# TODO: will need updating with shitmed
- type: body
name: ashwalker
id: AshWalker
root: torso
slots:
head:
part: HeadReptilian
connections:
- torso
organs:
brain: OrganHumanBrain
eyes: OrganHumanEyes
torso:
part: TorsoReptilian
organs:
heart: OrganAnimalHeart
lungs: OrganAshWalkerLungs
stomach: OrganReptilianStomach
liver: OrganAnimalLiver
kidneys: OrganHumanKidneys
connections:
- right arm
- left arm
- right leg
- left leg
right arm:
part: RightArmReptilian
connections:
- right hand
left arm:
part: LeftArmReptilian
connections:
- left hand
right hand:
part: RightHandReptilian
left hand:
part: LeftHandReptilian
right leg:
part: RightLegReptilian
connections:
- right foot
left leg:
part: LeftLegReptilian
connections:
- left foot
right foot:
part: RightFootReptilian
left foot:
part: LeftFootReptilian

View File

@@ -146,15 +146,15 @@
category: cargoproduct-category-name-service
group: market
- type: cargoProduct
id: CrateVendingMachineRestockSalvageEquipment
icon:
sprite: Objects/Specific/Service/vending_machine_restock.rsi
state: base
product: CrateVendingMachineRestockSalvageEquipmentFilled
cost: 1500
category: cargoproduct-category-name-engineering
group: market
#- type: cargoProduct # DeltaV: Salvage vendor doesn't have stock anymore
# id: CrateVendingMachineRestockSalvageEquipment
# icon:
# sprite: Objects/Specific/Service/vending_machine_restock.rsi
# state: base
# product: CrateVendingMachineRestockSalvageEquipmentFilled
# cost: 1000
# category: cargoproduct-category-name-engineering
# group: market
- type: cargoProduct
id: CrateVendingMachineRestockSecTech

View File

@@ -154,16 +154,15 @@
id: VendingMachineRestockRobustSoftdrinks
amount: 2
- type: entity
id: CrateVendingMachineRestockSalvageEquipmentFilled
parent: CrateGenericSteel
name: Salvage restock crate
description: Contains a restock box for the salvage vendor.
components:
- type: EntityTableContainerFill
containers:
entity_storage:
id: VendingMachineRestockSalvageEquipment
#- type: entity # DeltaV: Salvage vendor doesn't have stock anymore
# id: CrateVendingMachineRestockSalvageEquipmentFilled
# parent: CrateGenericSteel
# name: Salvage restock crate
# description: Contains a restock box for the salvage vendor.
# components:
# - type: StorageFill
# contents:
# - id: VendingMachineRestockSalvageEquipment
- type: entity
id: CrateVendingMachineRestockSecTechFilled

View File

@@ -11,6 +11,11 @@
id: LockerFillSalvageSpecialist
table: !type:AllSelector
children:
- id: OreBag
- id: Pickaxe
- id: WeaponProtoKineticAccelerator
- id: FlashlightSeclite
- id: ClothingEyesGlassesMeson
- id: ClothingBeltUtilityFilled
- id: SurvivalKnife
- id: HandheldGPSBasic

View File

@@ -6,6 +6,7 @@
- id: BoxFolderQmClipboard
- id: BoxQMCircuitboards
- id: BoxQMStamps
- id: MiningShuttleConsoleCircuitboard
- id: CigPackGreen
prob: 0.50
- id: ClothingHeadsetAltCargo

View File

@@ -0,0 +1,9 @@
- type: entity
parent: OrganAnimalLungs
id: OrganAshWalkerLungs
name: ashwalker lungs
description: These lungs are adapted from isolation in lavaland, capable of withstanding the low oxygen content and ash storms.
components:
- type: Lung
saturationLoss: 0.5
# TODO SHITMED: add AshStormImmune when transplanted

View File

@@ -0,0 +1,18 @@
- type: entity
parent: ClothingBackpackDuffelSalvage
id: ClothingBackpackDuffelSalvageConscription
name: mining conscription kit
description: A duffel bag containing everything a crewmember needs to support a shaft miner in the field.
components:
- type: StorageFill
contents:
- id: ClothingEyesGlassesMeson
- id: MineralScanner
- id: OreBag
- id: ClothingUniformJumpsuitSalvageSpecialist
- id: EncryptionKeyCargo
- id: ClothingMaskGasExplorer
- id: SalvageIDCard
- id: WeaponProtoKineticAccelerator
- id: SurvivalKnife
- id: FlashlightSeclite

View File

@@ -0,0 +1,56 @@
- type: shopInventory
id: SalvageVendorInventory
listings:
# TODO: marker beacons 1/10/30 for 10 each
- id: DrinkWhiskeyBottleFull
cost: 100
- id: DrinkAbsintheBottleFull
cost: 100
- id: CigarGold
cost: 150
- id: Soap
cost: 200
- id: SeismicCharge
cost: 250
- id: WeaponGrapplingGun
cost: 300
# TODO: laser pointer 300, toy facehugger 300
# TODO: stabilizing serum for 400
- id: FultonBeacon
cost: 400
- id: ShelterCapsule
cost: 400
- id: ClothingEyesGlassesGarMeson
cost: 500
- id: ClothingBeltSalvageWebbing
cost: 500
- id: MedkitBruteFilled
cost: 600
- id: MedkitBurnFilled
cost: 600
# TODO: salvage 5g, 3 implants and a locator for 600
# TODO: wormhole jaunter for 750
- id: WeaponCrusher
cost: 750
- id: WeaponProtoKineticAccelerator
cost: 750
- id: AdvancedMineralScanner
cost: 800
# TODO: resonator for 800
- id: Fulton
cost: 1000
# TODO: lazarus injector for 1k
- id: ClothingBackpackDuffelSalvageConscription
cost: 1500
- id: SpaceCash1000
cost: 2000
# TODO: super resonator for 2500
# TODO: jump boots for 2500
- id: ClothingOuterHardsuitSalvage
cost: 3000
- id: ShelterCapsuleLuxury
cost: 3000
- id: ShelterCapsuleBar
cost: 10000
# TODO: pka mods
# TODO: mining drone stuff

View File

@@ -0,0 +1,7 @@
- type: entity
parent: ClothingEyesGlassesGar
id: ClothingEyesGlassesGarMeson
name: gar mesons
description: Do the impossible, see the invisible!
components:
- type: EyeProtection

View File

@@ -0,0 +1,11 @@
- type: entity
save: false
parent: MobReptilian
id: MobAshWalker
name: Urist McAsh
suffix: ""
components:
- type: Body
prototype: AshWalker
- type: AshStormImmune
# TODO: shitmed stuff so you can steal ashwalker lungs

View File

@@ -0,0 +1,10 @@
- type: entity
parent: BaseComputerCircuitboard
id: MiningShuttleConsoleCircuitboard
name: mining shuttle console board
description: A printed circuit board for a mining shuttle console.
components:
- type: Sprite
state: cpu_supply
- type: ComputerBoard
prototype: ComputerShuttleMining

View File

@@ -0,0 +1,7 @@
- type: entity
abstract: true
id: BaseStationLavaland
components:
- type: StationPlanetSpawner
planet: Lavaland
gridPath: /Maps/Nonstations/_TBD/lavaland_base.yml

View File

@@ -0,0 +1,24 @@
# this goes on lavaland, unlimited
- type: entity
parent: AirlockGlassShuttle
id: AirlockExternalGlassShuttleMining
suffix: External, Mining, Glass, Docking, Locked
components:
- type: PriorityDock
tag: DockMining
- type: ContainerFill
containers:
board: [ DoorElectronicsExternal ]
# 1 per map, this spawns the mining shuttle
- type: entity
parent: AirlockExternalGlassShuttleMining
id: AirlockExternalGlassShuttleMiningFilled
suffix: Mining, Filled, Locked
components:
- type: GridFill
path: /Maps/Shuttles/DeltaV/mining.yml
addComponents:
- type: IFF
flags:
- HideLabel

View File

@@ -0,0 +1,50 @@
- type: entity
abstract: true
parent: BaseComputer
id: BaseComputerDocking
components:
- type: Sprite
layers:
- map: [ "computerLayerBody" ]
state: computer
- map: [ "computerLayerKeyboard" ]
state: generic_keyboard
- map: [ "computerLayerScreen" ]
state: shuttle
- map: ["computerLayerKeys" ]
state: generic_keys
- map: [ "enum.WiresVisualLayers.MaintenancePanel" ]
state: generic_panel_open
- type: ActivatableUI
key: enum.DockingConsoleUiKey.Key
- type: UserInterface
interfaces:
enum.DockingConsoleUiKey.Key:
type: DockingConsoleBoundUserInterface
enum.WiresUiKey.Key:
type: WiresBoundUserInterface
- type: WorldLoader
radius: 256
- type: DockingConsole
- type: PointLight
radius: 1.5
energy: 1.6
color: "#43ccb5"
- type: entity
parent: BaseComputerDocking
id: ComputerShuttleMining
name: mining shuttle console
description: Used to pilot the mining shuttle to and from the mining base.
components:
- type: DockingConsole
windowTitle: mining-console-window-title
dockTag: DockMining
shuttleWhitelist:
components:
- MiningShuttle
- type: Computer
board: MiningShuttleConsoleCircuitboard
- type: AccessReader
access:
- [ Salvage ]

View File

@@ -0,0 +1,7 @@
- type: wireLayout
id: ShopVendor
wires:
- !type:AiInteractWireAction
- !type:PowerWireAction
- !type:AccessWireAction
- !type:LogWireAction

View File

@@ -0,0 +1,75 @@
- type: planet
id: Lavaland
biome: Lava
mapName: shuttle-destination-lavaland
mapLight: "#A34931"
addedComponents:
- type: FTLDestination
whitelist:
components:
- MiningShuttle
- type: WeatherScheduler # Regular ash storms
stages:
- duration: # 5-10 minutes of calm
min: 300
max: 600
- weather: AshfallLight # ash starts to fall, 30 second warning
message: ash-storm-telegraph
duration:
min: 30
max: 30
- weather: Ashfall # 1-2 minutes of damaging storm
message: ash-storm-alert
duration:
min: 60
max: 120
- weather: AshfallLight # ash clears away for 30 seconds
message: ash-storm-clearing
duration:
min: 30
max: 30
atmosphere:
volume: 2500
temperature: 353.15 # 80C
moles: # 120kPa, 14% O2 (unbreathable)
- 14.38346
- 88.35554
biomeMarkerLayers:
- OreIron
- OreQuartz
- OreCoal
- OreGold
- OreSilver
- OrePlasmaLow
- OreUranium
- OreDiamondLow
- OreArtifactFragment
- WatchersLavaland
- GoliathsLavaland
- type: planet
id: GlacierSurface
biome: Snow
mapName: shuttle-destination-glacier-surface
mapLight: "#2B3153"
addedComponents:
- type: FTLDestination
whitelist:
components:
- MiningShuttle
atmosphere:
volume: 2500
temperature: 180 # -93, extreme cold
moles: # 119kPa, 21% O2
- 42
- 158
biomeMarkerLayers:
- OreIron
- OreQuartz
- OreCoal
- OreGold
- OreSilver
- OrePlasma
- OreUraniumLow
- OreDiamond
- OreArtifactFragment

View File

@@ -0,0 +1,2 @@
- type: Tag
id: DockMining

View File

@@ -6,9 +6,9 @@
description: A sheet of glass, used often on the station in various applications.
components:
- type: Sprite
sprite: Objects/Materials/Sheets/glass.rsi
sprite: _TBD/Objects/stack_objects.rsi
- type: Item
sprite: Objects/Materials/Sheets/glass.rsi
sprite: _TBD/Objects/stack_objects.rsi
size: Normal
- type: StaticPrice
price: 0
@@ -62,16 +62,16 @@
stackType: Glass
baseLayer: base
layerStates:
- glass
- glass_2
- glass_3
- sheet-glass_1
- sheet-glass_2
- sheet-glass_3
- type: Sprite
state: glass_3
state: sheet-glass_3
layers:
- state: glass_3
- state: sheet-glass_3
map: ["base"]
- type: Item
heldPrefix: glass
heldPrefix: sheet-glass_1
- type: FloorTile
outputs:
- FloorGlass
@@ -93,7 +93,7 @@
suffix: 10
components:
- type: Sprite
state: glass
state: sheet-glass_1
- type: Stack
stackType: Glass
count: 10
@@ -104,7 +104,7 @@
suffix: Single
components:
- type: Sprite
state: glass
state: sheet-glass_1
- type: Stack
stackType: Glass
count: 1
@@ -123,16 +123,16 @@
stackType: ReinforcedGlass
baseLayer: base
layerStates:
- rglass
- rglass_2
- rglass_3
- sheet-rglass_1
- sheet-rglass_2
- sheet-rglass_3
- type: Sprite
state: rglass_3
state: sheet-rglass_3
layers:
- state: rglass_3
- state: sheet-rglass_3
map: ["base"]
- type: Item
heldPrefix: rglass
heldPrefix: sheet-rglass_1
- type: FloorTile
outputs:
- FloorRGlass
@@ -171,12 +171,12 @@
suffix: Single
components:
- type: Sprite
state: rglass
state: sheet-rglass_1
- type: Stack
stackType: ReinforcedGlass
count: 1
- type: Extractable
grindableSolutionName: rglass
grindableSolutionName: sheet-rglass_1
- type: SolutionContainerManager
solutions:
rglass:
@@ -203,16 +203,16 @@
stackType: PlasmaGlass
baseLayer: base
layerStates:
- pglass
- pglass_2
- pglass_3
- sheet-pglass_1
- sheet-pglass_2
- sheet-pglass_3
- type: Sprite
state: pglass_3
state: sheet-pglass_3
layers:
- state: pglass_3
- state: sheet-pglass_3
map: ["base"]
- type: Item
heldPrefix: pglass
heldPrefix: sheet-pglass_1
- type: Construction
graph: Glass
node: SheetPGlass
@@ -248,7 +248,7 @@
suffix: Single
components:
- type: Sprite
state: pglass
state: sheet-pglass_1
- type: Stack
stackType: PlasmaGlass
count: 1
@@ -278,16 +278,16 @@
stackType: ReinforcedPlasmaGlass
baseLayer: base
layerStates:
- rpglass
- rpglass_2
- rpglass_3
- sheet-prglass_1
- sheet-prglass_2
- sheet-prglass_3
- type: Sprite
state: rpglass_3
state: sheet-prglass_3
layers:
- state: rpglass_3
- state: sheet-prglass_3
map: ["base"]
- type: Item
heldPrefix: rpglass
heldPrefix: sheet-prglass_1
- type: Construction
graph: Glass
node: SheetRPGlass
@@ -314,7 +314,7 @@
suffix: Single
components:
- type: Sprite
state: rpglass
state: sheet-prglass_1
- type: Stack
stackType: ReinforcedPlasmaGlass
count: 1
@@ -333,16 +333,16 @@
stackType: UraniumGlass
baseLayer: base
layerStates:
- uglass
- uglass_2
- uglass_3
- sheet-uglass_1
- sheet-uglass_2
- sheet-uglass_3
- type: Sprite
state: uglass_3
state: sheet-uglass_3
layers:
- state: uglass_3
- state: sheet-uglass_3
map: ["base"]
- type: Item
heldPrefix: uglass
heldPrefix: sheet-uglass_1
- type: Construction
graph: Glass
node: SheetUGlass
@@ -389,7 +389,7 @@
suffix: Single
components:
- type: Sprite
state: uglass
state: sheet-uglass_1
- type: Stack
stackType: UraniumGlass
count: 1
@@ -407,16 +407,16 @@
stackType: ReinforcedUraniumGlass
baseLayer: base
layerStates:
- ruglass
- ruglass_2
- ruglass_3
- sheet-urglass_1
- sheet-urglass_2
- sheet-urglass_3
- type: Sprite
state: ruglass_3
state: sheet-urglass_3
layers:
- state: ruglass_3
- state: sheet-urglass_3
map: ["base"]
- type: Item
heldPrefix: ruglass
heldPrefix: sheet-urglass
- type: Construction
graph: Glass
node: SheetRUGlass
@@ -443,7 +443,7 @@
suffix: Single
components:
- type: Sprite
state: ruglass
state: sheet-urglass_1
- type: Stack
stackType: ReinforcedUraniumGlass
count: 1
@@ -466,6 +466,7 @@
- cglass_2
- cglass_3
- type: Sprite
sprite: Objects/Materials/Sheets/glass.rsi
state: cglass_3
layers:
- state: cglass_3
@@ -520,6 +521,7 @@
suffix: Single
components:
- type: Sprite
sprite: Objects/Materials/Sheets/glass.rsi
state: cglass
- type: Stack
stackType: ClockworkGlass

View File

@@ -5,9 +5,9 @@
description: A sheet of metal, used often on the station in various applications.
components:
- type: Sprite
sprite: Objects/Materials/Sheets/metal.rsi
sprite: _TBD/Objects/stack_objects.rsi
- type: Item
sprite: Objects/Materials/Sheets/metal.rsi
sprite: _TBD/Objects/stack_objects.rsi
size: Normal
- type: StaticPrice
price: 0
@@ -49,16 +49,16 @@
stackType: Steel
baseLayer: base
layerStates:
- steel
- steel_2
- steel_3
- sheet-metal_1
- sheet-metal_2
- sheet-metal_3
- type: Sprite
state: steel_3
state: sheet-metal_3
layers:
- state: steel_3
- state: sheet-metal_3
map: ["base"]
- type: Item
heldPrefix: steel
heldPrefix: sheet-metal_1
- type: Appearance
- type: Extractable
grindableSolutionName: steel
@@ -78,7 +78,7 @@
suffix: 10
components:
- type: Sprite
state: steel
state: sheet-metal_1
- type: Stack
stackType: Steel
count: 10
@@ -90,7 +90,7 @@
suffix: Single
components:
- type: Sprite
state: steel
state: sheet-metal_1
- type: Stack
stackType: Steel
count: 1
@@ -114,6 +114,7 @@
- brass_2
- brass_3
- type: Sprite
sprite: Objects/Materials/Sheets/metal.rsi
state: brass_3
layers:
- state: brass_3
@@ -142,6 +143,7 @@
suffix: 10
components:
- type: Sprite
sprite: Objects/Materials/Sheets/metal.rsi
state: brass
- type: Stack
stackType: Brass
@@ -154,6 +156,7 @@
suffix: Single
components:
- type: Sprite
sprite: Objects/Materials/Sheets/metal.rsi
state: brass
- type: Stack
stackType: Brass
@@ -173,13 +176,13 @@
stackType: Plasteel
baseLayer: base
layerStates:
- plasteel
- plasteel_2
- plasteel_3
- sheet-plasteel_1
- sheet-plasteel_2
- sheet-plasteel_3
- type: Sprite
state: plasteel_3
state: sheet-plasteel_3
layers:
- state: plasteel_3
- state: sheet-plasteel_3
map: ["base"]
- type: Item
heldPrefix: plasteel
@@ -205,7 +208,7 @@
suffix: 10
components:
- type: Sprite
state: plasteel
state: sheet-plasteel_1
- type: Stack
stackType: Plasteel
count: 10
@@ -217,7 +220,7 @@
suffix: Single
components:
- type: Sprite
state: plasteel
state: sheet-plasteel_1
- type: Stack
stackType: Plasteel
count: 1

View File

@@ -5,9 +5,9 @@
description: A sheet of material, used often on the station in various applications.
components:
- type: Sprite
sprite: Objects/Materials/Sheets/other.rsi
sprite: _TBD/Objects/stack_objects.rsi
- type: Item
sprite: Objects/Materials/Sheets/other.rsi
sprite: _TBD/Objects/stack_objects.rsi
size: Normal
- type: Tag
tags:
@@ -38,20 +38,20 @@
stackType: Paper
baseLayer: base
layerStates:
- paper
- paper_2
- paper_3
- sheet-paper_1
- sheet-paper_2
- sheet-paper_3
- type: Material
- type: PhysicalComposition
materialComposition:
Paper: 100
- type: Sprite
state: paper_3
state: sheet-paper_3
layers:
- state: paper_3
- state: sheet-paper_3
map: ["base"]
- type: Item
heldPrefix: paper
heldPrefix: sheet-paper_1
- type: Appearance
- type: Extractable
grindableSolutionName: paper
@@ -70,7 +70,7 @@
suffix: Single
components:
- type: Sprite
state: paper
state: sheet-paper_1
- type: Stack
count: 1
@@ -88,16 +88,16 @@
stackType: Plasma
baseLayer: base
layerStates:
- plasma
- plasma_2
- plasma_3
- sheet-plasma_1
- sheet-plasma_2
- sheet-plasma_3
- type: Sprite
state: plasma_3
state: sheet-plasma_3
layers:
- state: plasma_3
- state: sheet-plasma_3
map: ["base"]
- type: Item
heldPrefix: plasma
heldPrefix: sheet-plasma_1
- type: Appearance
- type: Extractable
grindableSolutionName: plasma
@@ -115,7 +115,7 @@
suffix: 10
components:
- type: Sprite
state: plasma
state: sheet-plasma_1
- type: Stack
count: 10
@@ -126,7 +126,7 @@
suffix: Single
components:
- type: Sprite
state: plasma
state: sheet-plasma_1
- type: Stack
count: 1
@@ -149,16 +149,16 @@
stackType: Plastic
baseLayer: base
layerStates:
- plastic
- plastic_2
- plastic_3
- sheet-plastic_1
- sheet-plastic_2
- sheet-plastic_3
- type: Sprite
state: plastic_3
state: sheet-plastic_3
layers:
- state: plastic_3
- state: sheet-plastic_3
map: ["base"]
- type: Item
heldPrefix: plastic
heldPrefix: sheet-plastic_1
- type: Appearance
- type: Extractable
grindableSolutionName: plastic
@@ -179,7 +179,7 @@
suffix: 10
components:
- type: Sprite
state: plastic
state: sheet-plastic_1
- type: Stack
count: 10
@@ -190,7 +190,7 @@
suffix: Single
components:
- type: Sprite
state: plastic
state: sheet-plastic_1
- type: Stack
count: 1
@@ -211,17 +211,17 @@
stackType: Uranium
baseLayer: base
layerStates:
- uranium
- uranium_2
- uranium_3
- sheet-uranium_1
- sheet-uranium_2
- sheet-uranium_3
- type: Sprite
state: uranium_3
state: sheet-uranium_3
layers:
- state: uranium_3
- state: sheet-uranium_3
map: ["base"]
- type: Appearance
- type: Item
heldPrefix: uranium
heldPrefix: sheet-uranium_1
- type: Extractable
grindableSolutionName: food
- type: SolutionContainerManager

View File

@@ -5,9 +5,9 @@
description: A heavy metal ingot stamped with the Nanotrasen logo.
components:
- type: Sprite
sprite: Objects/Materials/ingots.rsi
sprite: _TBD/Objects/stack_objects.rsi
- type: Item
sprite: Objects/Materials/ingots.rsi
sprite: _TBD/Objects/stack_objects.rsi
size: Normal
- type: StaticPrice
price: 0
@@ -41,16 +41,16 @@
stackType: Gold
baseLayer: base
layerStates:
- gold
- gold_2
- gold_3
- sheet-gold_1
- sheet-gold_2
- sheet-gold_3
- type: Sprite
state: gold_3
state: sheet-gold_3
layers:
- state: gold_3
- state: sheet-gold_3
map: ["base"]
- type: Item
heldPrefix: gold
heldPrefix: sheet-gold_1
- type: Appearance
- type: Extractable
grindableSolutionName: gold
@@ -68,7 +68,7 @@
suffix: Single
components:
- type: Sprite
state: gold
state: sheet-gold_1
- type: Stack
count: 1
@@ -86,16 +86,16 @@
stackType: Silver
baseLayer: base
layerStates:
- silver
- silver_2
- silver_3
- sheet-silver_1
- sheet-silver_2
- sheet-silver_3
- type: Sprite
state: silver_3
layers:
- state: silver_3
map: ["base"]
- type: Item
heldPrefix: silver
heldPrefix: sheet-silver_1
- type: Appearance
- type: Extractable
grindableSolutionName: gold
@@ -113,6 +113,6 @@
suffix: Single
components:
- type: Sprite
state: silver
state: sheet-silver_1
- type: Stack
count: 1

View File

@@ -25,6 +25,7 @@
- WhitelistChameleonIdCard
- type: StealTarget
stealGroup: IDCard
- type: MiningPoints # DeltaV
#IDs with layers

View File

@@ -232,7 +232,7 @@
description: A light fixture.
components:
- type: LightBulb
color: "#FFE4CE" # 5000K color temp
color: "#FFFFFF" # 5000K color temp
lightEnergy: 0.8
lightRadius: 10
lightSoftness: 1

View File

@@ -14,7 +14,7 @@
slots:
- belt
- type: Item
size: Ginormous
size: Huge # DeltaV: Was Ginormous, lets it fit in conscription bag
- type: Storage
maxItemSize: Normal
grid:

View File

@@ -363,6 +363,7 @@
- state: refill_sec
- type: entity
abstract: true # DeltaV: Salvage vendor doesn't have stock anymore
parent: BaseVendingMachineRestock
id: VendingMachineRestockSalvageEquipment
name: Salvage Vendor restock box

View File

@@ -53,6 +53,14 @@
path: /Maps/Shuttles/cargo.yml
- type: GridSpawn
groups:
mining: !type:GridSpawnGroup
addComponents:
- type: ProtectedGrid
paths:
- /Maps/Shuttles/DeltaV/mining.yml
reclaimer: !type:GridSpawnGroup
paths:
- /Maps/Shuttles/mining.yml
trade: !type:GridSpawnGroup
addComponents:
- type: ProtectedGrid

View File

@@ -27,6 +27,7 @@
- BaseStationAllEventsEligible
- BaseStationNanotrasen
- BaseStationDeliveries
- BaseStationLavaland # DeltaV
categories: [ HideSpawnMenu ]
components:
- type: Transform

View File

@@ -603,6 +603,10 @@
staticPacks:
- OreSmelting
- RGlassSmelting
- type: MiningPoints # DeltaV - Source of mining points for miners
transferSound:
path: /Audio/Effects/Cargo/ping.ogg
- type: MiningPointsLathe # DeltaV
- type: entity
parent: OreProcessor

View File

@@ -1464,12 +1464,12 @@
name: Salvage Vendor
description: A dwarf's best friend!
components:
- type: VendingMachine
pack: SalvageEquipmentInventory
offState: off
brokenState: broken
normalState: normal-unshaded
denyState: deny-unshaded
#- type: VendingMachine # DeltaV: Use mining points instead of limited stock
# pack: SalvageEquipmentInventory
# offState: off
# brokenState: broken
# normalState: normal-unshaded
# denyState: deny-unshaded
- type: Sprite
sprite: Structures/Machines/VendingMachines/mining.rsi
layers:
@@ -1484,6 +1484,21 @@
radius: 1.5
energy: 3.0
color: "#b89f25"
- type: ShopVendor # DeltaV
pack: SalvageVendorInventory
offState: off
brokenState: broken
normalState: normal-unshaded
denyState: deny-unshaded
- type: PointsVendor # DeltaV
- type: UserInterface # DeltaV: Replace vending machine BUI with shop vendor
interfaces:
enum.VendingMachineUiKey.Key:
type: ShopVendorBoundUserInterface
enum.WiresUiKey.Key:
type: WiresBoundUserInterface
- type: Wires # DeltaV: Use shop vendor wires layout
layoutId: ShopVendor
- type: AccessReader
access: [["Salvage"]]
- type: GuideHelp

View File

@@ -589,9 +589,9 @@
name: reinforced wall
components:
- type: Sprite
sprite: Structures/Walls/solid.rsi
sprite: _TBD/Structures/Walls/solid.rsi
- type: Icon
sprite: Structures/Walls/solid.rsi
sprite: _TBD/Structures/Walls/solid.rsi
state: rgeneric
- type: Construction
graph: Girder
@@ -659,9 +659,9 @@
suffix: rusted
components:
- type: Sprite
sprite: Structures/Walls/solid_rust.rsi
sprite: _TBD/Structures/Walls/solid_rust.rsi
- type: Icon
sprite: Structures/Walls/solid_rust.rsi
sprite: _TBD/Structures/Walls/solid_rust.rsi
state: rgeneric
- type: Construction
graph: Girder
@@ -699,10 +699,10 @@
components:
- type: Sprite
drawdepth: Walls
sprite: Structures/Walls/reinforced_diagonal.rsi
sprite: _TBD/Structures/Walls/reinforced_diagonal.rsi
state: state0
- type: Icon
sprite: Structures/Walls/reinforced_diagonal.rsi
sprite: _TBD/Structures/Walls/reinforced_diagonal.rsi
state: state0
- type: Damageable
damageContainer: StructuralInorganic
@@ -981,13 +981,13 @@
name: solid wall
components:
- type: Sprite
sprite: Structures/Walls/solid.rsi
sprite: _TBD/Structures/Walls/solid.rsi
- type: WallReplacementMarker
- type: Construction
graph: Girder
node: wall
- type: Icon
sprite: Structures/Walls/solid.rsi
sprite: _TBD/Structures/Walls/solid.rsi
- type: RCDDeconstructable
cost: 6
delay: 8
@@ -1025,10 +1025,10 @@
components:
- type: Sprite
drawdepth: Walls
sprite: Structures/Walls/solid_diagonal.rsi
sprite: _TBD/Structures/Walls/solid_diagonal.rsi
state: state0
- type: Icon
sprite: Structures/Walls/solid_diagonal.rsi
sprite: _TBD/Structures/Walls/solid_diagonal.rsi
state: state0
- type: Destructible
thresholds:
@@ -1059,9 +1059,9 @@
suffix: rusted
components:
- type: Sprite
sprite: Structures/Walls/solid_rust.rsi
sprite: _TBD/Structures/Walls/solid_rust.rsi
- type: Icon
sprite: Structures/Walls/solid_rust.rsi
sprite: _TBD/Structures/Walls/solid_rust.rsi
state: full
- type: Construction
graph: Girder

View File

@@ -5,9 +5,9 @@
components:
- type: Sprite
drawdepth: WallTops
sprite: Structures/Windows/plasma_window.rsi
sprite: _TBD/Structures/Windows/plasma_window.rsi
- type: Icon
sprite: Structures/Windows/plasma_window.rsi
sprite: _TBD/Structures/Windows/plasma_window.rsi
- type: Damageable
damageContainer: StructuralInorganic
damageModifierSet: Glass
@@ -120,7 +120,7 @@
components:
- type: Sprite
drawdepth: WallTops
sprite: Structures/Windows/plasma_diagonal.rsi
sprite: _TBD/Structures/Windows/plasma_diagonal.rsi
state: state0
- type: Tag
tags:
@@ -128,10 +128,10 @@
- Window
- type: IconSmooth
mode: Diagonal
key: windows
key: walls
base: state
- type: Icon
sprite: Structures/Windows/plasma_diagonal.rsi
sprite: _TBD/Structures/Windows/plasma_diagonal.rsi
state: state0
- type: Fixtures
fixtures:

View File

@@ -5,9 +5,9 @@
components:
- type: Sprite
drawdepth: WallTops
sprite: Structures/Windows/reinforced_window.rsi
sprite: _TBD/Structures/Windows/reinforced_window.rsi
- type: Icon
sprite: Structures/Windows/reinforced_window.rsi
sprite: _TBD/Structures/Windows/reinforced_window.rsi
- type: Repairable
fuelCost: 10
doAfterDelay: 2
@@ -127,7 +127,7 @@
components:
- type: Sprite
drawdepth: WallTops
sprite: Structures/Windows/reinforced_window_diagonal.rsi
sprite: _TBD/Structures/Windows/reinforced_window_diagonal.rsi
state: state0
- type: Tag
tags:
@@ -135,10 +135,10 @@
- Window
- type: IconSmooth
mode: Diagonal
key: windows
key: walls
base: state
- type: Icon
sprite: Structures/Windows/reinforced_window_diagonal.rsi
sprite: _TBD/Structures/Windows/reinforced_window_diagonal.rsi
state: state0
- type: Fixtures
fixtures:

View File

@@ -5,9 +5,9 @@
components:
- type: Sprite
drawdepth: WallTops
sprite: Structures/Windows/reinforced_plasma_window.rsi
sprite: _TBD/Structures/Windows/reinforced_plasma_window.rsi
- type: Icon
sprite: Structures/Windows/reinforced_plasma_window.rsi
sprite: _TBD/Structures/Windows/reinforced_plasma_window.rsi
- type: Damageable
damageContainer: StructuralInorganic
damageModifierSet: RGlass
@@ -125,7 +125,7 @@
components:
- type: Sprite
drawdepth: WallTops
sprite: Structures/Windows/reinforced_plasma_diagonal.rsi
sprite: _TBD/Structures/Windows/reinforced_plasma_diagonal.rsi
state: state0
- type: Tag
tags:
@@ -133,10 +133,10 @@
- Window
- type: IconSmooth
mode: Diagonal
key: windows
key: walls
base: state
- type: Icon
sprite: Structures/Windows/reinforced_plasma_diagonal.rsi
sprite: _TBD/Structures/Windows/reinforced_plasma_diagonal.rsi
state: state0
- type: Fixtures
fixtures:

View File

@@ -5,9 +5,9 @@
components:
- type: Sprite
drawdepth: WallTops
sprite: Structures/Windows/reinforced_uranium_window.rsi
sprite: _TBD/Structures/Windows/reinforced_uranium_window.rsi
- type: Icon
sprite: Structures/Windows/reinforced_uranium_window.rsi
sprite: _TBD/Structures/Windows/reinforced_uranium_window.rsi
- type: Damageable
damageContainer: StructuralInorganic
damageModifierSet: RGlass
@@ -122,7 +122,7 @@
components:
- type: Sprite
drawdepth: WallTops
sprite: Structures/Windows/reinforced_uranium_diagonal.rsi
sprite: _TBD/Structures/Windows/reinforced_uranium_diagonal.rsi
state: state0
- type: Tag
tags:
@@ -130,10 +130,10 @@
- Window
- type: IconSmooth
mode: Diagonal
key: windows
key: walls
base: state
- type: Icon
sprite: Structures/Windows/reinforced_uranium_diagonal.rsi
sprite: _TBD/Structures/Windows/reinforced_uranium_diagonal.rsi
state: state0
- type: Fixtures
fixtures:

View File

@@ -5,9 +5,9 @@
components:
- type: Sprite
drawdepth: WallTops
sprite: Structures/Windows/uranium_window.rsi
sprite: _TBD/Structures/Windows/uranium_window.rsi
- type: Icon
sprite: Structures/Windows/uranium_window.rsi
sprite: _TBD/Structures/Windows/uranium_window.rsi
state: full
- type: Damageable
damageContainer: StructuralInorganic
@@ -115,7 +115,7 @@
components:
- type: Sprite
drawdepth: WallTops
sprite: Structures/Windows/uranium_window_diagonal.rsi
sprite: _TBD/Structures/Windows/uranium_window_diagonal.rsi
state: state0
- type: Tag
tags:
@@ -123,10 +123,10 @@
- Window
- type: IconSmooth
mode: Diagonal
key: windows
key: walls
base: state
- type: Icon
sprite: Structures/Windows/uranium_window_diagonal.rsi
sprite: _TBD/Structures/Windows/uranium_window_diagonal.rsi
state: state0
- type: Fixtures
fixtures:

View File

@@ -24,9 +24,9 @@
- Window
- type: Sprite
drawdepth: WallTops
sprite: Structures/Windows/window.rsi
sprite: _TBD/Structures/Windows/window.rsi
- type: Icon
sprite: Structures/Windows/window.rsi
sprite: _TBD/Structures/Windows/window.rsi
state: full
- type: Physics
bodyType: Static
@@ -76,7 +76,7 @@
acts: [ "Destruction" ]
- type: Airtight
- type: IconSmooth
key: windows
key: walls
base: window
- type: InteractionPopup
interactSuccessString: comp-window-knock
@@ -104,9 +104,9 @@
components:
- type: Sprite
drawdepth: WallTops
sprite: Structures/Windows/tinted_window.rsi
sprite: _TBD/Structures/Windows/tinted_window.rsi
- type: Icon
sprite: Structures/Windows/tinted_window.rsi
sprite: _TBD/Structures/Windows/tinted_window.rsi
- type: IconSmooth
base: twindow
- type: Construction
@@ -256,7 +256,7 @@
components:
- type: Sprite
drawdepth: WallTops
sprite: Structures/Windows/window_diagonal.rsi
sprite: _TBD/Structures/Windows/window_diagonal.rsi
state: state0
- type: Tag
tags:
@@ -264,10 +264,10 @@
- Window
- type: IconSmooth
mode: Diagonal
key: windows
key: walls
base: state
- type: Icon
sprite: Structures/Windows/window_diagonal.rsi
sprite: _TBD/Structures/Windows/window_diagonal.rsi
state: state0
- type: Fixtures
fixtures:

View File

@@ -38,7 +38,7 @@
- texture:
!type:ImageParallaxTextureSource
path: "/Textures/Parallaxes/Asteroids.png"
slowness: 0.998046875
slowness: 0.974352
scale: "1, 1"
layersLQ:
- texture:

View File

@@ -7,9 +7,15 @@
- type: biomeMarkerLayer
id: WatchersLavaland
prototype: MobWatcherLavaland
minGroupSize: 3
minGroupSize: 2
maxGroupSize: 3
- type: biomeMarkerLayer
id: GoliathsLavaland
prototype: MobGoliath
minGroupSize: 1
maxGroupSize: 2
- type: biomeMarkerLayer
id: WatchersIcewing
prototype: MobWatcherIcewing

View File

@@ -656,13 +656,18 @@
startNode: start
targetNode: Catwalk
category: construction-category-structures
conditions:
- !type:TileNotBlocked
failIfSpace: false
- !type:TileType
targets:
- Lattice
- Plating
description: Just like a lattice. Except it looks better.
# DeltaV - This prevented building catwalk over lava
#conditions:
#- !type:TileNotBlocked
# failIfSpace: false
#- !type:TileType
# targets:
# - Lattice
# - Plating
icon:
sprite: Structures/catwalk.rsi
state: catwalk_preview
objectType: Structure
placementMode: SnapgridCenter
canBuildInImpassable: false

Some files were not shown because too many files have changed in this diff Show More