mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-02-15 01:15:13 +01:00
Merge remote-tracking branch 'wizards/master' into upstream-sync
# Conflicts: # Content.Packaging/ClientPackaging.cs # Content.Server/Administration/Systems/AdminSystem.cs # Content.Server/GameTicking/GameTicker.StatusShell.cs # Content.Shared/Preferences/HumanoidCharacterProfile.cs # Resources/Prototypes/Entities/Stations/base.yml # Resources/Prototypes/Entities/Structures/Machines/lathe.yml # Resources/Textures/Interface/Misc/job_icons.rsi/meta.json # Resources/Textures/Structures/Power/Generation/Singularity/singularity_1.rsi/meta.json # Resources/Textures/Structures/Power/Generation/Singularity/singularity_2.rsi/meta.json # Resources/Textures/Structures/Power/Generation/Singularity/singularity_3.rsi/meta.json # Resources/Textures/Structures/Power/Generation/Singularity/singularity_4.rsi/meta.json # Resources/Textures/Structures/Power/Generation/Singularity/singularity_5.rsi/meta.json # Resources/Textures/Structures/Power/Generation/Singularity/singularity_6.rsi/meta.json
This commit is contained in:
@@ -88,8 +88,9 @@ namespace Content.Client.Access.UI
|
||||
button.Disabled = !interfaceEnabled;
|
||||
if (interfaceEnabled)
|
||||
{
|
||||
button.Pressed = state.TargetAccessReaderIdAccessList?.Contains(accessName) ?? false;
|
||||
button.Disabled = (!state.AllowedModifyAccessList?.Contains(accessName)) ?? true;
|
||||
// Explicit cast because Rider gives a false error otherwise.
|
||||
button.Pressed = state.TargetAccessReaderIdAccessList?.Contains((ProtoId<AccessLevelPrototype>) accessName) ?? false;
|
||||
button.Disabled = (!state.AllowedModifyAccessList?.Contains((ProtoId<AccessLevelPrototype>) accessName)) ?? true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
xmlns:tabs="clr-namespace:Content.Client.Administration.UI.Tabs"
|
||||
xmlns:playerTab="clr-namespace:Content.Client.Administration.UI.Tabs.PlayerTab"
|
||||
xmlns:objectsTab="clr-namespace:Content.Client.Administration.UI.Tabs.ObjectsTab"
|
||||
xmlns:panic="clr-namespace:Content.Client.Administration.UI.Tabs.PanicBunkerTab"
|
||||
xmlns:baby="clr-namespace:Content.Client.Administration.UI.Tabs.BabyJailTab">
|
||||
xmlns:panic="clr-namespace:Content.Client.Administration.UI.Tabs.PanicBunkerTab">
|
||||
<TabContainer Name="MasterTabContainer">
|
||||
<adminTab:AdminTab />
|
||||
<adminbusTab:AdminbusTab />
|
||||
@@ -15,7 +14,6 @@
|
||||
<tabs:RoundTab />
|
||||
<tabs:ServerTab />
|
||||
<panic:PanicBunkerTab Name="PanicBunkerControl" Access="Public" />
|
||||
<baby:BabyJailTab Name="BabyJailControl" Access="Public" />
|
||||
<playerTab:PlayerTab Name="PlayerTabControl" Access="Public" />
|
||||
<objectsTab:ObjectsTab Name="ObjectsTabControl" Access="Public" />
|
||||
</TabContainer>
|
||||
|
||||
@@ -21,10 +21,6 @@ public sealed partial class AdminMenuWindow : DefaultWindow
|
||||
MasterTabContainer.SetTabTitle((int) TabIndex.Round, Loc.GetString("admin-menu-round-tab"));
|
||||
MasterTabContainer.SetTabTitle((int) TabIndex.Server, Loc.GetString("admin-menu-server-tab"));
|
||||
MasterTabContainer.SetTabTitle((int) TabIndex.PanicBunker, Loc.GetString("admin-menu-panic-bunker-tab"));
|
||||
/*
|
||||
* TODO: Remove baby jail code once a more mature gateway process is established. This code is only being issued as a stopgap to help with potential tiding in the immediate future.
|
||||
*/
|
||||
MasterTabContainer.SetTabTitle((int) TabIndex.BabyJail, Loc.GetString("admin-menu-baby-jail-tab"));
|
||||
MasterTabContainer.SetTabTitle((int) TabIndex.Players, Loc.GetString("admin-menu-players-tab"));
|
||||
MasterTabContainer.SetTabTitle((int) TabIndex.Objects, Loc.GetString("admin-menu-objects-tab"));
|
||||
MasterTabContainer.OnTabChanged += OnTabChanged;
|
||||
@@ -52,7 +48,6 @@ public sealed partial class AdminMenuWindow : DefaultWindow
|
||||
Round,
|
||||
Server,
|
||||
PanicBunker,
|
||||
BabyJail,
|
||||
Players,
|
||||
Objects,
|
||||
}
|
||||
|
||||
@@ -130,6 +130,7 @@ namespace Content.Client.Administration.UI
|
||||
}
|
||||
|
||||
var title = string.IsNullOrWhiteSpace(popup.TitleEdit.Text) ? null : popup.TitleEdit.Text;
|
||||
var suspended = popup.SuspendedCheckbox.Pressed;
|
||||
|
||||
if (popup.SourceData is { } src)
|
||||
{
|
||||
@@ -139,7 +140,8 @@ namespace Content.Client.Administration.UI
|
||||
Title = title,
|
||||
PosFlags = pos,
|
||||
NegFlags = neg,
|
||||
RankId = rank
|
||||
RankId = rank,
|
||||
Suspended = suspended,
|
||||
});
|
||||
}
|
||||
else
|
||||
@@ -152,7 +154,8 @@ namespace Content.Client.Administration.UI
|
||||
Title = title,
|
||||
PosFlags = pos,
|
||||
NegFlags = neg,
|
||||
RankId = rank
|
||||
RankId = rank,
|
||||
Suspended = suspended,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -171,7 +174,7 @@ namespace Content.Client.Administration.UI
|
||||
{
|
||||
Id = src,
|
||||
Flags = flags,
|
||||
Name = name
|
||||
Name = name,
|
||||
});
|
||||
}
|
||||
else
|
||||
@@ -351,6 +354,7 @@ namespace Content.Client.Administration.UI
|
||||
public readonly OptionButton RankButton;
|
||||
public readonly Button SaveButton;
|
||||
public readonly Button? RemoveButton;
|
||||
public readonly CheckBox SuspendedCheckbox;
|
||||
|
||||
public readonly Dictionary<AdminFlags, (Button inherit, Button sub, Button plus)> FlagButtons
|
||||
= new();
|
||||
@@ -381,6 +385,12 @@ namespace Content.Client.Administration.UI
|
||||
RankButton = new OptionButton();
|
||||
SaveButton = new Button { Text = Loc.GetString("permissions-eui-edit-admin-window-save-button"), HorizontalAlignment = HAlignment.Right };
|
||||
|
||||
SuspendedCheckbox = new CheckBox
|
||||
{
|
||||
Text = Loc.GetString("permissions-eui-edit-admin-window-suspended"),
|
||||
Pressed = data?.Suspended ?? false,
|
||||
};
|
||||
|
||||
RankButton.AddItem(Loc.GetString("permissions-eui-edit-admin-window-no-rank-button"), NoRank);
|
||||
foreach (var (rId, rank) in ui._ranks)
|
||||
{
|
||||
@@ -488,7 +498,8 @@ namespace Content.Client.Administration.UI
|
||||
{
|
||||
nameControl,
|
||||
TitleEdit,
|
||||
RankButton
|
||||
RankButton,
|
||||
SuspendedCheckbox,
|
||||
}
|
||||
},
|
||||
permGrid
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
<controls:BabyJailStatusWindow
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client.Administration.UI.Tabs.BabyJailTab"
|
||||
Title="{Loc admin-ui-baby-jail-window-title}">
|
||||
<RichTextLabel Name="MessageLabel" Access="Public" />
|
||||
</controls:BabyJailStatusWindow>
|
||||
@@ -1,21 +0,0 @@
|
||||
using Content.Client.Message;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client.Administration.UI.Tabs.BabyJailTab;
|
||||
|
||||
/*
|
||||
* TODO: Remove me once a more mature gateway process is established. This code is only being issued as a stopgap to help with potential tiding in the immediate future.
|
||||
*/
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class BabyJailStatusWindow : FancyWindow
|
||||
{
|
||||
public BabyJailStatusWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
MessageLabel.SetMarkup(Loc.GetString("admin-ui-baby-jail-is-enabled"));
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
<controls:BabyJailTab
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client.Administration.UI.Tabs.BabyJailTab"
|
||||
xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||
Margin="4">
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<cc:CommandButton Name="EnabledButton" Command="babyjail" ToggleMode="True"
|
||||
Text="{Loc admin-ui-baby-jail-disabled}"
|
||||
ToolTip="{Loc admin-ui-baby-jail-tooltip}" />
|
||||
<cc:CommandButton Name="ShowReasonButton" Command="babyjail_show_reason"
|
||||
ToggleMode="True" Text="{Loc admin-ui-baby-jail-show-reason}"
|
||||
ToolTip="{Loc admin-ui-baby-jail-show-reason-tooltip}" />
|
||||
<BoxContainer Orientation="Vertical" Margin="0 10 0 0">
|
||||
<BoxContainer Orientation="Horizontal" Margin="2">
|
||||
<Label Text="{Loc admin-ui-baby-jail-max-account-age}" MinWidth="175" />
|
||||
<LineEdit Name="MaxAccountAge" MinWidth="50" Margin="0 0 5 0" />
|
||||
<Label Text="{Loc generic-minutes}" />
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Horizontal" Margin="2">
|
||||
<Label Text="{Loc admin-ui-baby-jail-max-overall-minutes}" MinWidth="175" />
|
||||
<LineEdit Name="MaxOverallMinutes" MinWidth="50" Margin="0 0 5 0" />
|
||||
<Label Text="{Loc generic-minutes}" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</controls:BabyJailTab>
|
||||
@@ -1,75 +0,0 @@
|
||||
using Content.Shared.Administration.Events;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Console;
|
||||
|
||||
/*
|
||||
* TODO: Remove me once a more mature gateway process is established. This code is only being issued as a stopgap to help with potential tiding in the immediate future.
|
||||
*/
|
||||
|
||||
namespace Content.Client.Administration.UI.Tabs.BabyJailTab;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class BabyJailTab : Control
|
||||
{
|
||||
[Dependency] private readonly IConsoleHost _console = default!;
|
||||
|
||||
private string _maxAccountAge;
|
||||
private string _maxOverallMinutes;
|
||||
|
||||
public BabyJailTab()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
MaxAccountAge.OnTextEntered += args => SendMaxAccountAge(args.Text);
|
||||
MaxAccountAge.OnFocusExit += args => SendMaxAccountAge(args.Text);
|
||||
_maxAccountAge = MaxAccountAge.Text;
|
||||
|
||||
MaxOverallMinutes.OnTextEntered += args => SendMaxOverallMinutes(args.Text);
|
||||
MaxOverallMinutes.OnFocusExit += args => SendMaxOverallMinutes(args.Text);
|
||||
_maxOverallMinutes = MaxOverallMinutes.Text;
|
||||
}
|
||||
|
||||
private void SendMaxAccountAge(string text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text) ||
|
||||
text == _maxAccountAge ||
|
||||
!int.TryParse(text, out var minutes))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_console.ExecuteCommand($"babyjail_max_account_age {minutes}");
|
||||
}
|
||||
|
||||
private void SendMaxOverallMinutes(string text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text) ||
|
||||
text == _maxOverallMinutes ||
|
||||
!int.TryParse(text, out var minutes))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_console.ExecuteCommand($"babyjail_max_overall_minutes {minutes}");
|
||||
}
|
||||
|
||||
public void UpdateStatus(BabyJailStatus status)
|
||||
{
|
||||
EnabledButton.Pressed = status.Enabled;
|
||||
EnabledButton.Text = Loc.GetString(status.Enabled
|
||||
? "admin-ui-baby-jail-enabled"
|
||||
: "admin-ui-baby-jail-disabled"
|
||||
);
|
||||
EnabledButton.ModulateSelfOverride = status.Enabled ? Color.Red : null;
|
||||
ShowReasonButton.Pressed = status.ShowReason;
|
||||
|
||||
MaxAccountAge.Text = status.MaxAccountAgeMinutes.ToString();
|
||||
_maxAccountAge = MaxAccountAge.Text;
|
||||
|
||||
MaxOverallMinutes.Text = status.MaxOverallMinutes.ToString();
|
||||
_maxOverallMinutes = MaxOverallMinutes.Text;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ namespace Content.Client
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
[STAThread]
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
ContentStart.Start(args);
|
||||
|
||||
@@ -3,7 +3,6 @@ using Content.Client.Administration.Systems;
|
||||
using Content.Client.Administration.UI;
|
||||
using Content.Client.Administration.UI.Tabs.ObjectsTab;
|
||||
using Content.Client.Administration.UI.Tabs.PanicBunkerTab;
|
||||
using Content.Client.Administration.UI.Tabs.BabyJailTab;
|
||||
using Content.Client.Administration.UI.Tabs.PlayerTab;
|
||||
using Content.Client.Gameplay;
|
||||
using Content.Client.Lobby;
|
||||
@@ -38,13 +37,11 @@ public sealed class AdminUIController : UIController,
|
||||
private AdminMenuWindow? _window;
|
||||
private MenuButton? AdminButton => UIManager.GetActiveUIWidgetOrNull<MenuBar.Widgets.GameTopMenuBar>()?.AdminButton;
|
||||
private PanicBunkerStatus? _panicBunker;
|
||||
private BabyJailStatus? _babyJail;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeNetworkEvent<PanicBunkerChangedEvent>(OnPanicBunkerUpdated);
|
||||
SubscribeNetworkEvent<BabyJailChangedEvent>(OnBabyJailUpdated);
|
||||
}
|
||||
|
||||
private void OnPanicBunkerUpdated(PanicBunkerChangedEvent msg, EntitySessionEventArgs args)
|
||||
@@ -59,18 +56,6 @@ public sealed class AdminUIController : UIController,
|
||||
}
|
||||
}
|
||||
|
||||
private void OnBabyJailUpdated(BabyJailChangedEvent msg, EntitySessionEventArgs args)
|
||||
{
|
||||
var showDialog = _babyJail == null && msg.Status.Enabled;
|
||||
_babyJail = msg.Status;
|
||||
_window?.BabyJailControl.UpdateStatus(msg.Status);
|
||||
|
||||
if (showDialog)
|
||||
{
|
||||
UIManager.CreateWindow<BabyJailStatusWindow>().OpenCentered();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnStateEntered(GameplayState state)
|
||||
{
|
||||
EnsureWindow();
|
||||
@@ -116,13 +101,6 @@ public sealed class AdminUIController : UIController,
|
||||
if (_panicBunker != null)
|
||||
_window.PanicBunkerControl.UpdateStatus(_panicBunker);
|
||||
|
||||
/*
|
||||
* TODO: Remove baby jail code once a more mature gateway process is established. This code is only being issued as a stopgap to help with potential tiding in the immediate future.
|
||||
*/
|
||||
|
||||
if (_babyJail != null)
|
||||
_window.BabyJailControl.UpdateStatus(_babyJail);
|
||||
|
||||
_window.PlayerTabControl.OnEntryKeyBindDown += PlayerTabEntryKeyBindDown;
|
||||
_window.ObjectsTabControl.OnEntryKeyBindDown += ObjectsTabEntryKeyBindDown;
|
||||
_window.OnOpen += OnWindowOpen;
|
||||
|
||||
@@ -84,9 +84,8 @@ namespace Content.IntegrationTests.Tests
|
||||
"Gate",
|
||||
"Amber",
|
||||
"Loop",
|
||||
"Plasma",
|
||||
"Elkridge"
|
||||
|
||||
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -80,7 +80,13 @@ public static class ClientPackaging
|
||||
var graph = new RobustClientAssetGraph();
|
||||
pass.Dependencies.Add(new AssetPassDependency(graph.Output.Name));
|
||||
|
||||
AssetGraph.CalculateGraph(graph.AllPasses.Append(pass).ToArray(), logger);
|
||||
var dropSvgPass = new AssetPassFilterDrop(f => f.Path.EndsWith(".svg"))
|
||||
{
|
||||
Name = "DropSvgPass",
|
||||
};
|
||||
dropSvgPass.AddDependency(graph.Input).AddBefore(graph.PresetPasses);
|
||||
|
||||
AssetGraph.CalculateGraph([pass, dropSvgPass, ..graph.AllPasses], logger);
|
||||
|
||||
var inputPass = graph.Input;
|
||||
|
||||
@@ -97,7 +103,7 @@ public static class ClientPackaging
|
||||
assemblies, // Corvax-Secrets
|
||||
cancel: cancel);
|
||||
|
||||
await WriteClientResources(contentDir, pass, cancel); // Corvax-Secrets: Support content resource ignore to ignore server-only prototypes
|
||||
await WriteClientResources(contentDir, inputPass, cancel); // Corvax-Secrets: Support content resource ignore to ignore server-only prototypes
|
||||
|
||||
inputPass.InjectFinished();
|
||||
}
|
||||
|
||||
2084
Content.Server.Database/Migrations/Postgres/20241223235939_AdminStatus.Designer.cs
generated
Normal file
2084
Content.Server.Database/Migrations/Postgres/20241223235939_AdminStatus.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Content.Server.Database.Migrations.Postgres
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AdminStatus : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "deadminned",
|
||||
table: "admin",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "suspended",
|
||||
table: "admin",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "deadminned",
|
||||
table: "admin");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "suspended",
|
||||
table: "admin");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,14 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("admin_rank_id");
|
||||
|
||||
b.Property<bool>("Deadminned")
|
||||
.HasColumnType("boolean")
|
||||
.HasColumnName("deadminned");
|
||||
|
||||
b.Property<bool>("Suspended")
|
||||
.HasColumnType("boolean")
|
||||
.HasColumnName("suspended");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("title");
|
||||
|
||||
2007
Content.Server.Database/Migrations/Sqlite/20241223235932_AdminStatus.Designer.cs
generated
Normal file
2007
Content.Server.Database/Migrations/Sqlite/20241223235932_AdminStatus.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Content.Server.Database.Migrations.Sqlite
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AdminStatus : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "deadminned",
|
||||
table: "admin",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "suspended",
|
||||
table: "admin",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "deadminned",
|
||||
table: "admin");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "suspended",
|
||||
table: "admin");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,14 @@ namespace Content.Server.Database.Migrations.Sqlite
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("admin_rank_id");
|
||||
|
||||
b.Property<bool>("Deadminned")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("deadminned");
|
||||
|
||||
b.Property<bool>("Suspended")
|
||||
.HasColumnType("INTEGER")
|
||||
.HasColumnName("suspended");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.HasColumnType("TEXT")
|
||||
.HasColumnName("title");
|
||||
|
||||
@@ -611,6 +611,16 @@ namespace Content.Server.Database
|
||||
[Key] public Guid UserId { get; set; }
|
||||
public string? Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, the admin is voluntarily deadminned. They can re-admin at any time.
|
||||
/// </summary>
|
||||
public bool Deadminned { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, the admin is suspended by an admin with <c>PERMISSIONS</c>. They will not have in-game permissions.
|
||||
/// </summary>
|
||||
public bool Suspended { get; set; }
|
||||
|
||||
public int? AdminRankId { get; set; }
|
||||
public AdminRank? AdminRank { get; set; }
|
||||
public List<AdminFlag> Flags { get; set; } = default!;
|
||||
@@ -964,10 +974,10 @@ namespace Content.Server.Database
|
||||
Full = 2,
|
||||
Panic = 3,
|
||||
/*
|
||||
* TODO: Remove baby jail code once a more mature gateway process is established. This code is only being issued as a stopgap to help with potential tiding in the immediate future.
|
||||
*
|
||||
* If baby jail is removed, please reserve this value for as long as can reasonably be done to prevent causing ambiguity in connection denial reasons.
|
||||
* Reservation by commenting out the value is likely sufficient for this purpose, but may impact projects which depend on SS14 like SS14.Admin.
|
||||
*
|
||||
* Edit: It has
|
||||
*/
|
||||
BabyJail = 4,
|
||||
/// Results from rejected connections with external API checking tools
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.CCVar;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Console;
|
||||
|
||||
/*
|
||||
* TODO: Remove baby jail code once a more mature gateway process is established. This code is only being issued as a stopgap to help with potential tiding in the immediate future.
|
||||
*/
|
||||
|
||||
namespace Content.Server.Administration.Commands;
|
||||
|
||||
[AdminCommand(AdminFlags.Server)]
|
||||
public sealed class BabyJailCommand : LocalizedCommands
|
||||
{
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
|
||||
public override string Command => "babyjail";
|
||||
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
var toggle = Toggle(CCVars.BabyJailEnabled, shell, args, _cfg);
|
||||
if (toggle == null)
|
||||
return;
|
||||
|
||||
shell.WriteLine(Loc.GetString(toggle.Value ? "babyjail-command-enabled" : "babyjail-command-disabled"));
|
||||
}
|
||||
|
||||
public static bool? Toggle(CVarDef<bool> cvar, IConsoleShell shell, string[] args, IConfigurationManager config)
|
||||
{
|
||||
if (args.Length > 1)
|
||||
{
|
||||
shell.WriteError(Loc.GetString("shell-need-between-arguments",("lower", 0), ("upper", 1)));
|
||||
return null;
|
||||
}
|
||||
|
||||
var enabled = config.GetCVar(cvar);
|
||||
|
||||
switch (args.Length)
|
||||
{
|
||||
case 0:
|
||||
enabled = !enabled;
|
||||
break;
|
||||
case 1 when !bool.TryParse(args[0], out enabled):
|
||||
shell.WriteError(Loc.GetString("shell-argument-must-be-boolean"));
|
||||
return null;
|
||||
}
|
||||
|
||||
config.SetCVar(cvar, enabled);
|
||||
|
||||
return enabled;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[AdminCommand(AdminFlags.Server)]
|
||||
public sealed class BabyJailShowReasonCommand : LocalizedCommands
|
||||
{
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
|
||||
public override string Command => "babyjail_show_reason";
|
||||
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
var toggle = BabyJailCommand.Toggle(CCVars.BabyJailShowReason, shell, args, _cfg);
|
||||
if (toggle == null)
|
||||
return;
|
||||
|
||||
shell.WriteLine(Loc.GetString(toggle.Value
|
||||
? "babyjail-command-show-reason-enabled"
|
||||
: "babyjail-command-show-reason-disabled"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
[AdminCommand(AdminFlags.Server)]
|
||||
public sealed class BabyJailMinAccountAgeCommand : LocalizedCommands
|
||||
{
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
|
||||
public override string Command => "babyjail_max_account_age";
|
||||
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
switch (args.Length)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
var current = _cfg.GetCVar(CCVars.BabyJailMaxAccountAge);
|
||||
shell.WriteLine(Loc.GetString("babyjail-command-max-account-age-is", ("minutes", current)));
|
||||
break;
|
||||
}
|
||||
case > 1:
|
||||
shell.WriteError(Loc.GetString("shell-need-between-arguments",("lower", 0), ("upper", 1)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!int.TryParse(args[0], out var minutes))
|
||||
{
|
||||
shell.WriteError(Loc.GetString("shell-argument-must-be-number"));
|
||||
return;
|
||||
}
|
||||
|
||||
_cfg.SetCVar(CCVars.BabyJailMaxAccountAge, minutes);
|
||||
shell.WriteLine(Loc.GetString("babyjail-command-max-account-age-set", ("minutes", minutes)));
|
||||
}
|
||||
}
|
||||
|
||||
[AdminCommand(AdminFlags.Server)]
|
||||
public sealed class BabyJailMinOverallHoursCommand : LocalizedCommands
|
||||
{
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
|
||||
public override string Command => "babyjail_max_overall_minutes";
|
||||
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
switch (args.Length)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
var current = _cfg.GetCVar(CCVars.BabyJailMaxOverallMinutes);
|
||||
shell.WriteLine(Loc.GetString("babyjail-command-max-overall-minutes-is", ("minutes", current)));
|
||||
break;
|
||||
}
|
||||
case > 1:
|
||||
shell.WriteError(Loc.GetString("shell-need-between-arguments",("lower", 0), ("upper", 1)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!int.TryParse(args[0], out var hours))
|
||||
{
|
||||
shell.WriteError(Loc.GetString("shell-argument-must-be-number"));
|
||||
return;
|
||||
}
|
||||
|
||||
_cfg.SetCVar(CCVars.BabyJailMaxOverallMinutes, hours);
|
||||
shell.WriteLine(Loc.GetString("babyjail-command-overall-minutes-set", ("hours", hours)));
|
||||
}
|
||||
}
|
||||
@@ -91,14 +91,29 @@ namespace Content.Server.Administration.Managers
|
||||
_chat.SendAdminAnnouncement(Loc.GetString("admin-manager-self-de-admin-message", ("exAdminName", session.Name)));
|
||||
_chat.DispatchServerMessage(session, Loc.GetString("admin-manager-became-normal-player-message"));
|
||||
|
||||
var plyData = session.ContentData()!;
|
||||
plyData.ExplicitlyDeadminned = true;
|
||||
UpdateDatabaseDeadminnedState(session, true);
|
||||
reg.Data.Active = false;
|
||||
|
||||
SendPermsChangedEvent(session);
|
||||
UpdateAdminStatus(session);
|
||||
}
|
||||
|
||||
private async void UpdateDatabaseDeadminnedState(ICommonSession player, bool newState)
|
||||
{
|
||||
try
|
||||
{
|
||||
// NOTE: This function gets called if you deadmin/readmin from a transient admin status.
|
||||
// (e.g. loginlocal)
|
||||
// In which case there may not be a database record.
|
||||
// The DB function handles this scenario fine, but it's worth noting.
|
||||
await _dbManager.UpdateAdminDeadminnedAsync(player.UserId, newState);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_sawmill.Error("Failed to save deadmin state to database for {Admin}", player.UserId);
|
||||
}
|
||||
}
|
||||
|
||||
public void Stealth(ICommonSession session)
|
||||
{
|
||||
if (!_admins.TryGetValue(session, out var reg))
|
||||
@@ -151,8 +166,7 @@ namespace Content.Server.Administration.Managers
|
||||
|
||||
_chat.DispatchServerMessage(session, Loc.GetString("admin-manager-became-admin-message"));
|
||||
|
||||
var plyData = session.ContentData()!;
|
||||
plyData.ExplicitlyDeadminned = false;
|
||||
UpdateDatabaseDeadminnedState(session, false);
|
||||
reg.Data.Active = true;
|
||||
|
||||
if (!reg.Data.Stealth)
|
||||
@@ -208,13 +222,13 @@ namespace Content.Server.Administration.Managers
|
||||
curAdmin.IsSpecialLogin = special;
|
||||
curAdmin.RankId = rankId;
|
||||
curAdmin.Data = aData;
|
||||
}
|
||||
|
||||
if (!player.ContentData()!.ExplicitlyDeadminned)
|
||||
{
|
||||
aData.Active = true;
|
||||
if (curAdmin.Data.Active)
|
||||
{
|
||||
aData.Active = true;
|
||||
|
||||
_chat.DispatchServerMessage(player, Loc.GetString("admin-manager-admin-permissions-updated-message"));
|
||||
_chat.DispatchServerMessage(player, Loc.GetString("admin-manager-admin-permissions-updated-message"));
|
||||
}
|
||||
}
|
||||
|
||||
if (player.ContentData()!.Stealthed)
|
||||
@@ -381,10 +395,8 @@ namespace Content.Server.Administration.Managers
|
||||
if (session.ContentData()!.Stealthed)
|
||||
reg.Data.Stealth = true;
|
||||
|
||||
if (!session.ContentData()!.ExplicitlyDeadminned)
|
||||
if (reg.Data.Active)
|
||||
{
|
||||
reg.Data.Active = true;
|
||||
|
||||
if (_cfg.GetCVar(CCVars.AdminAnnounceLogin))
|
||||
{
|
||||
if (reg.Data.Stealth)
|
||||
@@ -430,6 +442,7 @@ namespace Content.Server.Administration.Managers
|
||||
{
|
||||
Title = Loc.GetString("admin-manager-admin-data-host-title"),
|
||||
Flags = AdminFlagsHelper.Everything,
|
||||
Active = true,
|
||||
};
|
||||
|
||||
return (data, null, true);
|
||||
@@ -444,6 +457,12 @@ namespace Content.Server.Administration.Managers
|
||||
return null;
|
||||
}
|
||||
|
||||
if (dbData.Suspended)
|
||||
{
|
||||
// Suspended admins don't count.
|
||||
return null;
|
||||
}
|
||||
|
||||
var flags = AdminFlags.None;
|
||||
|
||||
if (dbData.AdminRank != null)
|
||||
@@ -466,7 +485,8 @@ namespace Content.Server.Administration.Managers
|
||||
|
||||
var data = new AdminData
|
||||
{
|
||||
Flags = flags
|
||||
Flags = flags,
|
||||
Active = !dbData.Deadminned,
|
||||
};
|
||||
|
||||
if (dbData.Title != null && _cfg.GetCVar(CCVars.AdminUseCustomNamesAdminRank))
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using Content.Server.Administration.Notes;
|
||||
using Content.Server.Database;
|
||||
using Content.Server.Discord;
|
||||
using Content.Shared.CCVar;
|
||||
using Robust.Server;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Player;
|
||||
using System.Linq;
|
||||
|
||||
namespace Content.Server.Administration.Managers;
|
||||
|
||||
/// <summary>
|
||||
/// This manager sends a webhook notification whenever a player with an active
|
||||
/// watchlist joins the server.
|
||||
/// </summary>
|
||||
public interface IWatchlistWebhookManager
|
||||
{
|
||||
void Initialize();
|
||||
void Update();
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
using Content.Server.Administration.Notes;
|
||||
using Content.Server.Database;
|
||||
using Content.Server.Discord;
|
||||
using Content.Shared.CCVar;
|
||||
using Robust.Server;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Timing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Content.Server.Administration.Managers;
|
||||
|
||||
/// <summary>
|
||||
/// This manager sends a Discord webhook notification whenever a player with an active
|
||||
/// watchlist joins the server.
|
||||
/// </summary>
|
||||
public sealed class WatchlistWebhookManager : IWatchlistWebhookManager
|
||||
{
|
||||
[Dependency] private readonly IAdminNotesManager _adminNotes = default!;
|
||||
[Dependency] private readonly IBaseServer _baseServer = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
[Dependency] private readonly DiscordWebhook _discord = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
|
||||
private string _webhookUrl = default!;
|
||||
private TimeSpan _bufferTime;
|
||||
|
||||
private List<WatchlistConnection> watchlistConnections = new();
|
||||
private TimeSpan? _bufferStartTime;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
_sawmill = Logger.GetSawmill("discord");
|
||||
_cfg.OnValueChanged(CCVars.DiscordWatchlistConnectionBufferTime, SetBufferTime, true);
|
||||
_cfg.OnValueChanged(CCVars.DiscordWatchlistConnectionWebhook, SetWebhookUrl, true);
|
||||
_playerManager.PlayerStatusChanged += OnPlayerStatusChanged;
|
||||
}
|
||||
|
||||
private void SetBufferTime(float bufferTimeSeconds)
|
||||
{
|
||||
_bufferTime = TimeSpan.FromSeconds(bufferTimeSeconds);
|
||||
}
|
||||
|
||||
private void SetWebhookUrl(string webhookUrl)
|
||||
{
|
||||
_webhookUrl = webhookUrl;
|
||||
}
|
||||
|
||||
private async void OnPlayerStatusChanged(object? sender, SessionStatusEventArgs e)
|
||||
{
|
||||
if (e.NewStatus != SessionStatus.Connected)
|
||||
return;
|
||||
|
||||
var watchlists = await _adminNotes.GetActiveWatchlists(e.Session.UserId);
|
||||
|
||||
if (watchlists.Count == 0)
|
||||
return;
|
||||
|
||||
watchlistConnections.Add(new WatchlistConnection(e.Session.Name, watchlists));
|
||||
|
||||
if (_bufferTime > TimeSpan.Zero)
|
||||
{
|
||||
if (_bufferStartTime == null)
|
||||
_bufferStartTime = _gameTiming.RealTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
SendDiscordMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (_bufferStartTime != null && _gameTiming.RealTime > (_bufferStartTime + _bufferTime))
|
||||
{
|
||||
SendDiscordMessage();
|
||||
_bufferStartTime = null;
|
||||
}
|
||||
}
|
||||
|
||||
private async void SendDiscordMessage()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(_webhookUrl))
|
||||
return;
|
||||
|
||||
var webhookData = await _discord.GetWebhook(_webhookUrl);
|
||||
if (webhookData == null)
|
||||
return;
|
||||
|
||||
var webhookIdentifier = webhookData.Value.ToIdentifier();
|
||||
|
||||
var messageBuilder = new StringBuilder(Loc.GetString("discord-watchlist-connection-header",
|
||||
("players", watchlistConnections.Count),
|
||||
("serverName", _baseServer.ServerName)));
|
||||
|
||||
foreach (var connection in watchlistConnections)
|
||||
{
|
||||
messageBuilder.Append('\n');
|
||||
|
||||
var watchlist = connection.Watchlists.First();
|
||||
var expiry = watchlist.ExpirationTime?.ToUnixTimeSeconds();
|
||||
messageBuilder.Append(Loc.GetString("discord-watchlist-connection-entry",
|
||||
("playerName", connection.PlayerName),
|
||||
("message", watchlist.Message),
|
||||
("expiry", expiry ?? 0),
|
||||
("otherWatchlists", connection.Watchlists.Count - 1)));
|
||||
}
|
||||
|
||||
var payload = new WebhookPayload { Content = messageBuilder.ToString() };
|
||||
|
||||
await _discord.CreateMessage(webhookIdentifier, payload);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_sawmill.Error($"Error while sending discord watchlist connection message:\n{e}");
|
||||
}
|
||||
|
||||
// Clear the buffered list regardless of whether the message is sent successfully
|
||||
// This prevents infinitely buffering connections if we fail to send a message
|
||||
watchlistConnections.Clear();
|
||||
}
|
||||
|
||||
private sealed class WatchlistConnection
|
||||
{
|
||||
public string PlayerName;
|
||||
public List<AdminWatchlistRecord> Watchlists;
|
||||
|
||||
public WatchlistConnection(string playerName, List<AdminWatchlistRecord> watchlists)
|
||||
{
|
||||
PlayerName = playerName;
|
||||
Watchlists = watchlists;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,6 @@ public sealed class AdminSystem : EntitySystem
|
||||
|
||||
private readonly HashSet<NetUserId> _roundActivePlayers = new();
|
||||
public readonly PanicBunkerStatus PanicBunker = new();
|
||||
public readonly BabyJailStatus BabyJail = new();
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -85,16 +84,6 @@ public sealed class AdminSystem : EntitySystem
|
||||
Subs.CVar(_config, CCVars.PanicBunkerMinOverallMinutes, OnPanicBunkerMinOverallMinutesChanged, true);
|
||||
Subs.CVar(_config, CCCVars.PanicBunkerDenyVPN, OnPanicBunkerDenyVpnChanged, true); // Corvax-VPNGuard
|
||||
|
||||
/*
|
||||
* TODO: Remove baby jail code once a more mature gateway process is established. This code is only being issued as a stopgap to help with potential tiding in the immediate future.
|
||||
*/
|
||||
|
||||
// Baby Jail Settings
|
||||
Subs.CVar(_config, CCVars.BabyJailEnabled, OnBabyJailChanged, true);
|
||||
Subs.CVar(_config, CCVars.BabyJailShowReason, OnBabyJailShowReasonChanged, true);
|
||||
Subs.CVar(_config, CCVars.BabyJailMaxAccountAge, OnBabyJailMaxAccountAgeChanged, true);
|
||||
Subs.CVar(_config, CCVars.BabyJailMaxOverallMinutes, OnBabyJailMaxOverallMinutesChanged, true);
|
||||
|
||||
SubscribeLocalEvent<IdentityChangedEvent>(OnIdentityChanged);
|
||||
SubscribeLocalEvent<PlayerAttachedEvent>(OnPlayerAttached);
|
||||
SubscribeLocalEvent<PlayerDetachedEvent>(OnPlayerDetached);
|
||||
@@ -281,17 +270,6 @@ public sealed class AdminSystem : EntitySystem
|
||||
SendPanicBunkerStatusAll();
|
||||
}
|
||||
|
||||
private void OnBabyJailChanged(bool enabled)
|
||||
{
|
||||
BabyJail.Enabled = enabled;
|
||||
_chat.SendAdminAlert(Loc.GetString(enabled
|
||||
? "admin-ui-baby-jail-enabled-admin-alert"
|
||||
: "admin-ui-baby-jail-disabled-admin-alert"
|
||||
));
|
||||
|
||||
SendBabyJailStatusAll();
|
||||
}
|
||||
|
||||
private void OnPanicBunkerDisableWithAdminsChanged(bool enabled)
|
||||
{
|
||||
PanicBunker.DisableWithAdmins = enabled;
|
||||
@@ -316,36 +294,18 @@ public sealed class AdminSystem : EntitySystem
|
||||
SendPanicBunkerStatusAll();
|
||||
}
|
||||
|
||||
private void OnBabyJailShowReasonChanged(bool enabled)
|
||||
{
|
||||
BabyJail.ShowReason = enabled;
|
||||
SendBabyJailStatusAll();
|
||||
}
|
||||
|
||||
private void OnPanicBunkerMinAccountAgeChanged(int minutes)
|
||||
{
|
||||
PanicBunker.MinAccountAgeMinutes = minutes;
|
||||
SendPanicBunkerStatusAll();
|
||||
}
|
||||
|
||||
private void OnBabyJailMaxAccountAgeChanged(int minutes)
|
||||
{
|
||||
BabyJail.MaxAccountAgeMinutes = minutes;
|
||||
SendBabyJailStatusAll();
|
||||
}
|
||||
|
||||
private void OnPanicBunkerMinOverallMinutesChanged(int minutes)
|
||||
{
|
||||
PanicBunker.MinOverallMinutes = minutes;
|
||||
SendPanicBunkerStatusAll();
|
||||
}
|
||||
|
||||
private void OnBabyJailMaxOverallMinutesChanged(int minutes)
|
||||
{
|
||||
BabyJail.MaxOverallMinutes = minutes;
|
||||
SendBabyJailStatusAll();
|
||||
}
|
||||
|
||||
// Corvax-VPNGuard-Start
|
||||
private void OnPanicBunkerDenyVpnChanged(bool deny)
|
||||
{
|
||||
@@ -400,15 +360,6 @@ public sealed class AdminSystem : EntitySystem
|
||||
}
|
||||
}
|
||||
|
||||
private void SendBabyJailStatusAll()
|
||||
{
|
||||
var ev = new BabyJailChangedEvent(BabyJail);
|
||||
foreach (var admin in _adminManager.AllAdmins)
|
||||
{
|
||||
RaiseNetworkEvent(ev, admin);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Erases a player from the round.
|
||||
/// This removes them and any trace of them from the round, deleting their
|
||||
|
||||
@@ -76,7 +76,8 @@ namespace Content.Server.Administration.UI
|
||||
Title = p.a.Title,
|
||||
RankId = p.a.AdminRankId,
|
||||
UserId = new NetUserId(p.a.UserId),
|
||||
UserName = p.lastUserName
|
||||
UserName = p.lastUserName,
|
||||
Suspended = p.a.Suspended,
|
||||
}).ToArray(),
|
||||
|
||||
AdminRanks = _adminRanks.ToDictionary(a => a.Id, a => new PermissionsEuiState.AdminRankData
|
||||
@@ -255,6 +256,7 @@ namespace Content.Server.Administration.UI
|
||||
admin.Title = ua.Title;
|
||||
admin.AdminRankId = ua.RankId;
|
||||
admin.Flags = GenAdminFlagList(ua.PosFlags, ua.NegFlags);
|
||||
admin.Suspended = ua.Suspended;
|
||||
|
||||
await _db.UpdateAdminAsync(admin);
|
||||
|
||||
@@ -335,7 +337,8 @@ namespace Content.Server.Administration.UI
|
||||
Flags = GenAdminFlagList(ca.PosFlags, ca.NegFlags),
|
||||
AdminRankId = ca.RankId,
|
||||
UserId = userId.UserId,
|
||||
Title = ca.Title
|
||||
Title = ca.Title,
|
||||
Suspended = ca.Suspended,
|
||||
};
|
||||
|
||||
await _db.AddAdminAsync(admin);
|
||||
|
||||
@@ -101,9 +101,16 @@ namespace Content.Server.Connection
|
||||
time = newTime;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
public async void Update()
|
||||
{
|
||||
_ipintel.Update();
|
||||
try
|
||||
{
|
||||
await _ipintel.Update();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_sawmill.Error("IPIntel update failed:" + e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -303,14 +310,6 @@ namespace Content.Server.Connection
|
||||
}
|
||||
}
|
||||
|
||||
if (_cfg.GetCVar(CCVars.BabyJailEnabled) && adminData == null)
|
||||
{
|
||||
var result = await IsInvalidConnectionDueToBabyJail(userId, e);
|
||||
|
||||
if (result.IsInvalid)
|
||||
return (ConnectionDenyReason.BabyJail, result.Reason, null);
|
||||
}
|
||||
|
||||
var wasInGame = EntitySystem.TryGet<GameTicker>(out var ticker) &&
|
||||
ticker.PlayerGameStatuses.TryGetValue(userId, out var status) &&
|
||||
status == PlayerGameStatus.JoinedGame;
|
||||
@@ -372,72 +371,6 @@ namespace Content.Server.Connection
|
||||
return null;
|
||||
}
|
||||
|
||||
private async Task<(bool IsInvalid, string Reason)> IsInvalidConnectionDueToBabyJail(NetUserId userId, NetConnectingArgs e)
|
||||
{
|
||||
// If you're whitelisted then bypass this whole thing
|
||||
if (await _db.GetWhitelistStatusAsync(userId))
|
||||
return (false, "");
|
||||
|
||||
// Initial cvar retrieval
|
||||
var showReason = _cfg.GetCVar(CCVars.BabyJailShowReason);
|
||||
var reason = _cfg.GetCVar(CCVars.BabyJailCustomReason);
|
||||
var maxAccountAgeMinutes = _cfg.GetCVar(CCVars.BabyJailMaxAccountAge);
|
||||
var maxPlaytimeMinutes = _cfg.GetCVar(CCVars.BabyJailMaxOverallMinutes);
|
||||
|
||||
// Wait some time to lookup data
|
||||
var record = await _db.GetPlayerRecordByUserId(userId);
|
||||
|
||||
// No player record = new account or the DB is having a skill issue
|
||||
if (record == null)
|
||||
return (false, "");
|
||||
|
||||
var isAccountAgeInvalid = record.FirstSeenTime.CompareTo(DateTimeOffset.UtcNow - TimeSpan.FromMinutes(maxAccountAgeMinutes)) <= 0;
|
||||
|
||||
if (isAccountAgeInvalid)
|
||||
{
|
||||
_sawmill.Debug($"Baby jail will deny {userId} for account age {record.FirstSeenTime}"); // Remove on or after 2024-09
|
||||
}
|
||||
|
||||
if (isAccountAgeInvalid && showReason)
|
||||
{
|
||||
var locAccountReason = reason != string.Empty
|
||||
? reason
|
||||
: Loc.GetString("baby-jail-account-denied-reason",
|
||||
("reason",
|
||||
Loc.GetString(
|
||||
"baby-jail-account-reason-account",
|
||||
("minutes", maxAccountAgeMinutes))));
|
||||
|
||||
return (true, locAccountReason);
|
||||
}
|
||||
|
||||
var overallTime = ( await _db.GetPlayTimes(e.UserId)).Find(p => p.Tracker == PlayTimeTrackingShared.TrackerOverall);
|
||||
var isTotalPlaytimeInvalid = overallTime != null && overallTime.TimeSpent.TotalMinutes >= maxPlaytimeMinutes;
|
||||
|
||||
if (isTotalPlaytimeInvalid)
|
||||
{
|
||||
_sawmill.Debug($"Baby jail will deny {userId} for playtime {overallTime!.TimeSpent}"); // Remove on or after 2024-09
|
||||
}
|
||||
|
||||
if (isTotalPlaytimeInvalid && showReason)
|
||||
{
|
||||
var locPlaytimeReason = reason != string.Empty
|
||||
? reason
|
||||
: Loc.GetString("baby-jail-account-denied-reason",
|
||||
("reason",
|
||||
Loc.GetString(
|
||||
"baby-jail-account-reason-overall",
|
||||
("minutes", maxPlaytimeMinutes))));
|
||||
|
||||
return (true, locPlaytimeReason);
|
||||
}
|
||||
|
||||
if (!showReason && isTotalPlaytimeInvalid || isAccountAgeInvalid)
|
||||
return (true, Loc.GetString("baby-jail-account-denied"));
|
||||
|
||||
return (false, "");
|
||||
}
|
||||
|
||||
private bool HasTemporaryBypass(NetUserId user)
|
||||
{
|
||||
return _temporaryBypasses.TryGetValue(user, out var time) && time > _gameTiming.RealTime;
|
||||
|
||||
@@ -38,6 +38,7 @@ public sealed class IPIntel
|
||||
_sawmill = logManager.GetSawmill("ipintel");
|
||||
|
||||
cfg.OnValueChanged(CCVars.GameIPIntelEmail, b => _contactEmail = b, true);
|
||||
cfg.OnValueChanged(CCVars.GameIPIntelEnabled, b => _enabled = b, true);
|
||||
cfg.OnValueChanged(CCVars.GameIPIntelRejectUnknown, b => _rejectUnknown = b, true);
|
||||
cfg.OnValueChanged(CCVars.GameIPIntelRejectBad, b => _rejectBad = b, true);
|
||||
cfg.OnValueChanged(CCVars.GameIPIntelRejectRateLimited, b => _rejectLimited = b, true);
|
||||
@@ -74,6 +75,7 @@ public sealed class IPIntel
|
||||
|
||||
// CCVars
|
||||
private string? _contactEmail;
|
||||
private bool _enabled;
|
||||
private bool _rejectUnknown;
|
||||
private bool _rejectBad;
|
||||
private bool _rejectLimited;
|
||||
@@ -273,12 +275,12 @@ public sealed class IPIntel
|
||||
return _rejectBad ? (true, Loc.GetString("ipintel-suspicious")) : (false, string.Empty);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
public async Task Update()
|
||||
{
|
||||
if (_gameTiming.RealTime >= _nextClean)
|
||||
if (_enabled && _gameTiming.RealTime >= _nextClean)
|
||||
{
|
||||
_nextClean = _gameTiming.RealTime + TimeSpan.FromMinutes(_cleanupMins);
|
||||
_db.CleanIPIntelCache(_cacheDays);
|
||||
await _db.CleanIPIntelCache(_cacheDays);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -759,6 +759,20 @@ namespace Content.Server.Database
|
||||
existing.Flags = admin.Flags;
|
||||
existing.Title = admin.Title;
|
||||
existing.AdminRankId = admin.AdminRankId;
|
||||
existing.Deadminned = admin.Deadminned;
|
||||
existing.Suspended = admin.Suspended;
|
||||
|
||||
await db.DbContext.SaveChangesAsync(cancel);
|
||||
}
|
||||
|
||||
public async Task UpdateAdminDeadminnedAsync(NetUserId userId, bool deadminned, CancellationToken cancel)
|
||||
{
|
||||
await using var db = await GetDb(cancel);
|
||||
|
||||
var adminRecord = db.DbContext.Admin.Where(a => a.UserId == userId);
|
||||
await adminRecord.ExecuteUpdateAsync(
|
||||
set => set.SetProperty(p => p.Deadminned, deadminned),
|
||||
cancellationToken: cancel);
|
||||
|
||||
await db.DbContext.SaveChangesAsync(cancel);
|
||||
}
|
||||
@@ -1782,8 +1796,11 @@ INSERT INTO player_round (players_id, rounds_id) VALUES ({players[player]}, {id}
|
||||
{
|
||||
await using var db = await GetDb();
|
||||
|
||||
// Calculating this here cause otherwise sqlite whines.
|
||||
var cutoffTime = DateTime.UtcNow.Subtract(range);
|
||||
|
||||
await db.DbContext.IPIntelCache
|
||||
.Where(w => DateTime.UtcNow - w.Time >= range)
|
||||
.Where(w => w.Time <= cutoffTime)
|
||||
.ExecuteDeleteAsync();
|
||||
|
||||
await db.DbContext.SaveChangesAsync();
|
||||
|
||||
@@ -217,6 +217,16 @@ namespace Content.Server.Database
|
||||
Task AddAdminAsync(Admin admin, CancellationToken cancel = default);
|
||||
Task UpdateAdminAsync(Admin admin, CancellationToken cancel = default);
|
||||
|
||||
/// <summary>
|
||||
/// Update whether an admin has voluntarily deadminned.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This does nothing if the player is not an admin.
|
||||
/// </remarks>
|
||||
/// <param name="userId">The user ID of the admin.</param>
|
||||
/// <param name="deadminned">Whether the admin is deadminned or not.</param>
|
||||
Task UpdateAdminDeadminnedAsync(NetUserId userId, bool deadminned, CancellationToken cancel = default);
|
||||
|
||||
Task RemoveAdminRankAsync(int rankId, CancellationToken cancel = default);
|
||||
Task AddAdminRankAsync(AdminRank rank, CancellationToken cancel = default);
|
||||
Task UpdateAdminRankAsync(AdminRank rank, CancellationToken cancel = default);
|
||||
@@ -674,6 +684,12 @@ namespace Content.Server.Database
|
||||
return RunDbCommand(() => _db.UpdateAdminAsync(admin, cancel));
|
||||
}
|
||||
|
||||
public Task UpdateAdminDeadminnedAsync(NetUserId userId, bool deadminned, CancellationToken cancel = default)
|
||||
{
|
||||
DbWriteOpsMetric.Inc();
|
||||
return RunDbCommand(() => _db.UpdateAdminDeadminnedAsync(userId, deadminned, cancel));
|
||||
}
|
||||
|
||||
public Task RemoveAdminRankAsync(int rankId, CancellationToken cancel = default)
|
||||
{
|
||||
DbWriteOpsMetric.Inc();
|
||||
|
||||
@@ -49,6 +49,7 @@ namespace Content.Server.Entry
|
||||
private PlayTimeTrackingManager? _playTimeTracking;
|
||||
private IEntitySystemManager? _sysMan;
|
||||
private IServerDbManager? _dbManager;
|
||||
private IWatchlistWebhookManager _watchlistWebhookManager = default!;
|
||||
private IConnectionManager? _connectionManager;
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -97,6 +98,7 @@ namespace Content.Server.Entry
|
||||
_connectionManager = IoCManager.Resolve<IConnectionManager>();
|
||||
_sysMan = IoCManager.Resolve<IEntitySystemManager>();
|
||||
_dbManager = IoCManager.Resolve<IServerDbManager>();
|
||||
_watchlistWebhookManager = IoCManager.Resolve<IWatchlistWebhookManager>();
|
||||
|
||||
logManager.GetSawmill("Storage").Level = LogLevel.Info;
|
||||
logManager.GetSawmill("db.ef").Level = LogLevel.Info;
|
||||
@@ -115,6 +117,7 @@ namespace Content.Server.Entry
|
||||
_voteManager.Initialize();
|
||||
_updateManager.Initialize();
|
||||
_playTimeTracking.Initialize();
|
||||
_watchlistWebhookManager.Initialize();
|
||||
IoCManager.Resolve<JobWhitelistManager>().Initialize();
|
||||
IoCManager.Resolve<PlayerRateLimitManager>().Initialize();
|
||||
}
|
||||
@@ -182,6 +185,7 @@ namespace Content.Server.Entry
|
||||
case ModUpdateLevel.FramePostEngine:
|
||||
_updateManager.Update();
|
||||
_playTimeTracking?.Update();
|
||||
_watchlistWebhookManager.Update();
|
||||
_connectionManager?.Update();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,8 @@ public sealed partial class PuddleSystem
|
||||
Spawn("PuddleSparkle", xformQuery.GetComponent(uid).Coordinates);
|
||||
QueueDel(uid);
|
||||
}
|
||||
|
||||
_solutionContainerSystem.UpdateChemicals(puddle.Solution.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Linq;
|
||||
using System.Text.Json.Nodes;
|
||||
using Content.Corvax.Interfaces.Server;
|
||||
using Content.Shared.CCVar;
|
||||
@@ -45,6 +46,10 @@ namespace Content.Server.GameTicking
|
||||
var players = IoCManager.Instance?.TryResolveType<IServerJoinQueueManager>(out var joinQueueManager) ?? false
|
||||
? joinQueueManager.ActualPlayersCount
|
||||
: _playerManager.PlayerCount;
|
||||
|
||||
players = _cfg.GetCVar(CCVars.AdminsCountInReportedPlayerCount)
|
||||
? players
|
||||
: players - _adminManager.ActiveAdmins.Count();
|
||||
// Corvax-Queue-End
|
||||
|
||||
jObject["name"] = _baseServer.ServerName;
|
||||
@@ -53,12 +58,6 @@ namespace Content.Server.GameTicking
|
||||
jObject["players"] = players; // Corvax-Queue
|
||||
jObject["soft_max_players"] = _cfg.GetCVar(CCVars.SoftMaxPlayers);
|
||||
jObject["panic_bunker"] = _cfg.GetCVar(CCVars.PanicBunkerEnabled);
|
||||
|
||||
/*
|
||||
* TODO: Remove baby jail code once a more mature gateway process is established. This code is only being issued as a stopgap to help with potential tiding in the immediate future.
|
||||
*/
|
||||
|
||||
jObject["baby_jail"] = _cfg.GetCVar(CCVars.BabyJailEnabled);
|
||||
jObject["run_level"] = (int) _runLevel;
|
||||
if (preset != null)
|
||||
jObject["preset"] = Loc.GetString(preset.ModeTitle);
|
||||
|
||||
@@ -21,6 +21,7 @@ using Robust.Shared.Random;
|
||||
using System.Numerics;
|
||||
using Content.Shared.Movement.Pulling.Components;
|
||||
using Content.Shared.Movement.Pulling.Systems;
|
||||
using Content.Server.IdentityManagement;
|
||||
using Content.Shared.Store.Components;
|
||||
using Robust.Shared.Collections;
|
||||
using Robust.Shared.Map.Components;
|
||||
@@ -41,6 +42,7 @@ public sealed class SubdermalImplantSystem : SharedSubdermalImplantSystem
|
||||
[Dependency] private readonly PullingSystem _pullingSystem = default!;
|
||||
[Dependency] private readonly EntityLookupSystem _lookupSystem = default!;
|
||||
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
|
||||
[Dependency] private readonly IdentitySystem _identity = default!;
|
||||
|
||||
private EntityQuery<PhysicsComponent> _physicsQuery;
|
||||
private HashSet<Entity<MapGridComponent>> _targetGrids = [];
|
||||
@@ -211,7 +213,7 @@ public sealed class SubdermalImplantSystem : SharedSubdermalImplantSystem
|
||||
{
|
||||
var newProfile = HumanoidCharacterProfile.RandomWithSpecies(humanoid.Species);
|
||||
_humanoidAppearance.LoadProfile(ent, newProfile, humanoid);
|
||||
_metaData.SetEntityName(ent, newProfile.Name);
|
||||
_metaData.SetEntityName(ent, newProfile.Name, raiseEvents: false); // raising events would update ID card, station record, etc.
|
||||
if (TryComp<DnaComponent>(ent, out var dna))
|
||||
{
|
||||
dna.DNA = _forensicsSystem.GenerateDNA();
|
||||
@@ -223,6 +225,7 @@ public sealed class SubdermalImplantSystem : SharedSubdermalImplantSystem
|
||||
{
|
||||
fingerprint.Fingerprint = _forensicsSystem.GenerateFingerprint();
|
||||
}
|
||||
_identity.QueueIdentityUpdate(ent); // manually queue identity update since we don't raise the event
|
||||
_popup.PopupEntity(Loc.GetString("scramble-implant-activated-popup"), ent, ent);
|
||||
}
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ namespace Content.Server.IoC
|
||||
IoCManager.Register<PlayerRateLimitManager>();
|
||||
IoCManager.Register<SharedPlayerRateLimitManager, PlayerRateLimitManager>();
|
||||
IoCManager.Register<MappingManager>();
|
||||
IoCManager.Register<IWatchlistWebhookManager, WatchlistWebhookManager>();
|
||||
IoCManager.Register<ConnectionManager>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Content.Server.Speech.Components;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class MumbleAccentComponent : Component
|
||||
{
|
||||
|
||||
}
|
||||
25
Content.Server/Speech/EntitySystems/MumbleAccentSystem.cs
Normal file
25
Content.Server/Speech/EntitySystems/MumbleAccentSystem.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using Content.Server.Speech.Components;
|
||||
|
||||
namespace Content.Server.Speech.EntitySystems;
|
||||
|
||||
public sealed class MumbleAccentSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ReplacementAccentSystem _replacement = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<MumbleAccentComponent, AccentGetEvent>(OnAccentGet);
|
||||
}
|
||||
|
||||
public string Accentuate(string message, MumbleAccentComponent component)
|
||||
{
|
||||
return _replacement.ApplyReplacements(message, "mumble");
|
||||
}
|
||||
|
||||
private void OnAccentGet(EntityUid uid, MumbleAccentComponent component, AccentGetEvent args)
|
||||
{
|
||||
args.Message = Accentuate(args.Message, component);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
/*
|
||||
* TODO: Remove baby jail code once a more mature gateway process is established. This code is only being issued as a stopgap to help with potential tiding in the immediate future.
|
||||
*/
|
||||
|
||||
namespace Content.Shared.Administration.Events;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class BabyJailStatus
|
||||
{
|
||||
public bool Enabled;
|
||||
public bool ShowReason;
|
||||
public int MaxAccountAgeMinutes;
|
||||
public int MaxOverallMinutes;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class BabyJailChangedEvent(BabyJailStatus status) : EntityEventArgs
|
||||
{
|
||||
public BabyJailStatus Status = status;
|
||||
}
|
||||
@@ -18,6 +18,7 @@ namespace Content.Shared.Administration
|
||||
public NetUserId UserId;
|
||||
public string? UserName;
|
||||
public string? Title;
|
||||
public bool Suspended;
|
||||
public AdminFlags PosFlags;
|
||||
public AdminFlags NegFlags;
|
||||
public int? RankId;
|
||||
@@ -41,6 +42,7 @@ namespace Content.Shared.Administration
|
||||
public AdminFlags PosFlags;
|
||||
public AdminFlags NegFlags;
|
||||
public int? RankId;
|
||||
public bool Suspended;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
@@ -57,6 +59,7 @@ namespace Content.Shared.Administration
|
||||
public AdminFlags PosFlags;
|
||||
public AdminFlags NegFlags;
|
||||
public int? RankId;
|
||||
public bool Suspended;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -158,6 +158,13 @@ public sealed partial class CCVars
|
||||
public static readonly CVarDef<bool> AdminsCountForMaxPlayers =
|
||||
CVarDef.Create("admin.admins_count_for_max_players", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Should admins be hidden from the player count reported to the launcher/via api?
|
||||
/// This is hub advert safe, in case that's a worry.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> AdminsCountInReportedPlayerCount =
|
||||
CVarDef.Create("admin.admins_count_in_playercount", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Determine if custom rank names are used.
|
||||
/// If it is false, it'd use the actual rank name regardless of the individual's title.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Configuration;
|
||||
|
||||
namespace Content.Shared.CCVar;
|
||||
|
||||
@@ -58,4 +58,18 @@ public sealed partial class CCVars
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> DiscordRoundEndRoleWebhook =
|
||||
CVarDef.Create("discord.round_end_role", string.Empty, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// URL of the Discord webhook which will relay watchlist connection notifications. If left empty, disables the webhook.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> DiscordWatchlistConnectionWebhook =
|
||||
CVarDef.Create("discord.watchlist_connection_webhook", string.Empty, CVar.SERVERONLY | CVar.CONFIDENTIAL);
|
||||
|
||||
/// <summary>
|
||||
/// How long to buffer watchlist connections for, in seconds.
|
||||
/// All connections within this amount of time from the first one will be batched and sent as a single
|
||||
/// Discord notification. If zero, always sends a separate notification for each connection (not recommended).
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> DiscordWatchlistConnectionBufferTime =
|
||||
CVarDef.Create("discord.watchlist_connection_buffer_time", 5f, CVar.SERVERONLY);
|
||||
}
|
||||
|
||||
@@ -198,48 +198,6 @@ public sealed partial class CCVars
|
||||
public static readonly CVarDef<bool> BypassBunkerWhitelist =
|
||||
CVarDef.Create("game.panic_bunker.whitelisted_can_bypass", true, CVar.SERVERONLY);
|
||||
|
||||
/*
|
||||
* TODO: Remove baby jail code once a more mature gateway process is established. This code is only being issued as a stopgap to help with potential tiding in the immediate future.
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Whether the baby jail is currently enabled.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> BabyJailEnabled =
|
||||
CVarDef.Create("game.baby_jail.enabled", false, CVar.NOTIFY | CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// Show reason of disconnect for user or not.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> BabyJailShowReason =
|
||||
CVarDef.Create("game.baby_jail.show_reason", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Maximum age of the account (from server's PoV, so from first-seen date) in minutes that can access baby
|
||||
/// jailed servers.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> BabyJailMaxAccountAge =
|
||||
CVarDef.Create("game.baby_jail.max_account_age", 1440, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Maximum overall played time allowed to access baby jailed servers.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> BabyJailMaxOverallMinutes =
|
||||
CVarDef.Create("game.baby_jail.max_overall_minutes", 120, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// A custom message that will be used for connections denied due to the baby jail.
|
||||
/// If not empty, then will overwrite <see cref="BabyJailShowReason"/>
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> BabyJailCustomReason =
|
||||
CVarDef.Create("game.baby_jail.custom_reason", string.Empty, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Allow bypassing the baby jail if the user is whitelisted.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> BypassBabyJailWhitelist =
|
||||
CVarDef.Create("game.baby_jail.whitelisted_can_bypass", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Enable IPIntel for blocking VPN connections from new players.
|
||||
/// </summary>
|
||||
|
||||
@@ -75,10 +75,10 @@ namespace Content.Shared.Containers.ItemSlots
|
||||
public EntityWhitelist? Blacklist;
|
||||
|
||||
[DataField]
|
||||
public SoundSpecifier InsertSound = new SoundPathSpecifier("/Audio/Weapons/Guns/MagIn/revolver_magin.ogg");
|
||||
public SoundSpecifier? InsertSound = new SoundPathSpecifier("/Audio/Weapons/Guns/MagIn/revolver_magin.ogg");
|
||||
|
||||
[DataField]
|
||||
public SoundSpecifier EjectSound = new SoundPathSpecifier("/Audio/Weapons/Guns/MagOut/revolver_magout.ogg");
|
||||
public SoundSpecifier? EjectSound = new SoundPathSpecifier("/Audio/Weapons/Guns/MagOut/revolver_magout.ogg");
|
||||
|
||||
/// <summary>
|
||||
/// The name of this item slot. This will be shown to the user in the verb menu.
|
||||
|
||||
@@ -589,8 +589,8 @@ public abstract partial class SharedDoorSystem : EntitySystem
|
||||
if (otherPhysics.Comp.CollisionLayer == (int) CollisionGroup.GlassLayer || otherPhysics.Comp.CollisionLayer == (int) CollisionGroup.GlassAirlockLayer || otherPhysics.Comp.CollisionLayer == (int) CollisionGroup.TableLayer)
|
||||
continue;
|
||||
|
||||
//If the colliding entity is a slippable item ignore it by the airlock
|
||||
if (otherPhysics.Comp.CollisionLayer == (int) CollisionGroup.SlipLayer && otherPhysics.Comp.CollisionMask == (int) CollisionGroup.ItemMask)
|
||||
// Ignore low-passable entities.
|
||||
if ((otherPhysics.Comp.CollisionMask & (int)CollisionGroup.LowImpassable) == 0)
|
||||
continue;
|
||||
|
||||
//For when doors need to close over conveyor belts
|
||||
|
||||
@@ -32,12 +32,6 @@ public sealed class ContentPlayerData
|
||||
[ViewVariables, Access(typeof(SharedMindSystem), typeof(SharedGameTicker))]
|
||||
public EntityUid? Mind { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, the player is an admin and they explicitly de-adminned mid-game,
|
||||
/// so they should not regain admin if they reconnect.
|
||||
/// </summary>
|
||||
public bool ExplicitlyDeadminned { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true, the admin will not show up in adminwho except to admins with the <see cref="AdminFlags.Stealth"/> flag.
|
||||
/// </summary>
|
||||
|
||||
@@ -695,5 +695,31 @@ Entries:
|
||||
id: 86
|
||||
time: '2025-01-12T19:41:26.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33339
|
||||
- author: PJB3005
|
||||
changes:
|
||||
- message: Deadmin status is now synchronized to database, making it persistent
|
||||
across server restarts and between multiple game servers.
|
||||
type: Tweak
|
||||
- message: Admins can now be suspended via the permissions panel. This effectively
|
||||
removes their admin status without completely deleting their record.
|
||||
type: Add
|
||||
id: 87
|
||||
time: '2025-01-14T23:46:45.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34048
|
||||
- author: Palladinium
|
||||
changes:
|
||||
- message: Added Discord relay notifications when a watchlisted player connects.
|
||||
type: Add
|
||||
id: 88
|
||||
time: '2025-01-15T00:32:24.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33483
|
||||
- author: Myra
|
||||
changes:
|
||||
- message: Admins are by default now hidden from the reported player count on the
|
||||
launcher.
|
||||
type: Add
|
||||
id: 89
|
||||
time: '2025-01-15T21:10:54.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34406
|
||||
Name: Admin
|
||||
Order: 1
|
||||
|
||||
@@ -1,144 +1,4 @@
|
||||
Entries:
|
||||
- author: EmoGarbage404
|
||||
changes:
|
||||
- message: Firesuits are now worse at keeping in heat and winter clothes make you
|
||||
get warmer quicker.
|
||||
type: Tweak
|
||||
id: 7302
|
||||
time: '2024-09-07T05:37:17.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30662
|
||||
- author: Boaz1111
|
||||
changes:
|
||||
- message: The maple wing marking for moths now have a secondary color palette.
|
||||
type: Tweak
|
||||
id: 7303
|
||||
time: '2024-09-07T05:48:40.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31691
|
||||
- author: lzk228
|
||||
changes:
|
||||
- message: Bottle and syringe names are remade into labels.
|
||||
type: Tweak
|
||||
id: 7304
|
||||
time: '2024-09-07T05:51:36.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/29956
|
||||
- author: Ian321
|
||||
changes:
|
||||
- message: The AgriChem kit now links to the botanical chemicals guidebook.
|
||||
type: Tweak
|
||||
- message: The botanical chemicals guidebook has been expanded.
|
||||
type: Tweak
|
||||
id: 7305
|
||||
time: '2024-09-07T06:23:01.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31896
|
||||
- author: Lank
|
||||
changes:
|
||||
- message: The Antimov and Overseer law boards are no longer available roundstart.
|
||||
type: Remove
|
||||
id: 7306
|
||||
time: '2024-09-07T08:45:51.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31908
|
||||
- author: lzk228
|
||||
changes:
|
||||
- message: Books cannot longer be inserted in crates as paper labels
|
||||
type: Fix
|
||||
id: 7307
|
||||
time: '2024-09-07T13:22:11.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31919
|
||||
- author: qwerltaz
|
||||
changes:
|
||||
- message: Reduced wall closet range. It's now much easier to not close yourself
|
||||
inside by accident.
|
||||
type: Tweak
|
||||
id: 7308
|
||||
time: '2024-09-07T23:44:29.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31933
|
||||
- author: Ilya246
|
||||
changes:
|
||||
- message: Reagents that make you flammable no longer extinguish you.
|
||||
type: Fix
|
||||
id: 7309
|
||||
time: '2024-09-07T23:44:58.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31930
|
||||
- author: LucasTheDrgn
|
||||
changes:
|
||||
- message: Restored functionality to the Industrial Reagent Grinder
|
||||
type: Fix
|
||||
id: 7310
|
||||
time: '2024-09-07T23:47:02.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31903
|
||||
- author: EmoGarbage404
|
||||
changes:
|
||||
- message: Added the biogenerator! Botany can use this machine to create various
|
||||
materials, chemicals, and food items out of the
|
||||
type: Add
|
||||
id: 7311
|
||||
time: '2024-09-08T05:34:22.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30694
|
||||
- author: TheShuEd
|
||||
changes:
|
||||
- message: Returned Taco microwave recipes (people were sad)
|
||||
type: Add
|
||||
- message: added an alternative method of crafting some burgers, through the correct
|
||||
assembly sequence of modular food.
|
||||
type: Add
|
||||
- message: severely cut back on the number of items you can put on burgers, tacos,
|
||||
or kebabs. This had poor design, and things need to be separately resprited
|
||||
by adding them on modular food.
|
||||
type: Tweak
|
||||
id: 7312
|
||||
time: '2024-09-08T06:22:27.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31012
|
||||
- author: metalgearsloth
|
||||
changes:
|
||||
- message: Fix the FTL bubbles sometimes persisting.
|
||||
type: Fix
|
||||
- message: Fix AI eye being able to FTL.
|
||||
type: Fix
|
||||
- message: Fix the AI eye being able to be FTL smashed.
|
||||
type: Fix
|
||||
id: 7313
|
||||
time: '2024-09-08T08:12:24.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31952
|
||||
- author: PopGamer46
|
||||
changes:
|
||||
- message: Fixed being able to craft the justice helmet with a justice helmet
|
||||
type: Fix
|
||||
id: 7314
|
||||
time: '2024-09-08T10:21:55.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31957
|
||||
- author: Killerqu00
|
||||
changes:
|
||||
- message: Seclite is now restricted to security.
|
||||
type: Tweak
|
||||
- message: Handcuffs are now restricted to security and command.
|
||||
type: Tweak
|
||||
- message: Trench whistle is now minor contraband.
|
||||
type: Tweak
|
||||
id: 7315
|
||||
time: '2024-09-08T12:06:01.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31956
|
||||
- author: Psychpsyo
|
||||
changes:
|
||||
- message: The random sentience event should now actually happen again.
|
||||
type: Fix
|
||||
id: 7316
|
||||
time: '2024-09-08T12:10:50.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31953
|
||||
- author: Beck Thompson
|
||||
changes:
|
||||
- message: Gold and silver rings now give a small amount of materials when scrapped.
|
||||
type: Tweak
|
||||
id: 7317
|
||||
time: '2024-09-08T16:10:05.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31847
|
||||
- author: K-Dynamic
|
||||
changes:
|
||||
- message: added missing missing resistance values for directional plasma and uranium
|
||||
windows
|
||||
type: Fix
|
||||
id: 7318
|
||||
time: '2024-09-08T18:08:06.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31975
|
||||
- author: qwerltaz
|
||||
changes:
|
||||
- message: Power cables on the ground are now offset and do not obscure each other
|
||||
@@ -3937,3 +3797,130 @@
|
||||
id: 7801
|
||||
time: '2025-01-12T16:38:41.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34394
|
||||
- author: SlimSlam
|
||||
changes:
|
||||
- message: News Room
|
||||
type: Add
|
||||
id: 7802
|
||||
time: '2025-01-12T23:32:51.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34408
|
||||
- author: Deerstop
|
||||
changes:
|
||||
- message: Improved the readability of the manual valve sprite.
|
||||
type: Tweak
|
||||
id: 7803
|
||||
time: '2025-01-13T07:07:30.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34378
|
||||
- author: JustinWinningham
|
||||
changes:
|
||||
- message: Anomalies no longer block players or APES (or other objects) from passing
|
||||
through them
|
||||
type: Tweak
|
||||
- message: Players can no longer move anomalies with unanchored furniture, closets,
|
||||
etc.
|
||||
type: Fix
|
||||
id: 7804
|
||||
time: '2025-01-13T10:06:57.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34280
|
||||
- author: zHonys
|
||||
changes:
|
||||
- message: Items with collisions (like mousetraps) won't kept doors form opening
|
||||
type: Fix
|
||||
id: 7805
|
||||
time: '2025-01-13T10:07:18.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34045
|
||||
- author: Coolsurf6
|
||||
changes:
|
||||
- message: The "Jazz" style for the Electric Guitar now uses the correct soundfont.
|
||||
type: Tweak
|
||||
id: 7806
|
||||
time: '2025-01-13T10:07:33.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33363
|
||||
- author: southbridge-fur
|
||||
changes:
|
||||
- message: The Pride-O-Mat vending machine has been ported to upstream.
|
||||
type: Add
|
||||
id: 7807
|
||||
time: '2025-01-13T18:49:02.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34412
|
||||
- author: Killerqu00
|
||||
changes:
|
||||
- message: Pet carriers can now be crafted.
|
||||
type: Add
|
||||
id: 7808
|
||||
time: '2025-01-14T22:34:04.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34431
|
||||
- author: themias
|
||||
changes:
|
||||
- message: Fixed muzzles not working on some characters (e.g. dwarves)
|
||||
type: Fix
|
||||
id: 7809
|
||||
time: '2025-01-15T00:10:39.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34419
|
||||
- author: ArtisticRoomba
|
||||
changes:
|
||||
- message: The station anchor machine board can no longer be printed at the circuit
|
||||
imprinter.
|
||||
type: Remove
|
||||
id: 7810
|
||||
time: '2025-01-15T16:26:19.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34358
|
||||
- author: ArtisticRoomba
|
||||
changes:
|
||||
- message: Mime PDA item interactions (insertions/ejections of IDs, pens, etc.)
|
||||
are now silent.
|
||||
type: Tweak
|
||||
id: 7811
|
||||
time: '2025-01-15T18:03:49.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34426
|
||||
- author: Alpaccalypse
|
||||
changes:
|
||||
- message: Smite soda vending machines have been added to the game.
|
||||
type: Add
|
||||
id: 7812
|
||||
time: '2025-01-15T18:20:01.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34420
|
||||
- author: kosticia
|
||||
changes:
|
||||
- message: Bedsheets now can be printed on uniform printer
|
||||
type: Add
|
||||
id: 7813
|
||||
time: '2025-01-15T19:35:59.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34034
|
||||
- author: TheShuEd
|
||||
changes:
|
||||
- message: Christmas anomaly removed
|
||||
type: Remove
|
||||
id: 7814
|
||||
time: '2025-01-15T20:22:32.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34053
|
||||
- author: Kickguy223
|
||||
changes:
|
||||
- message: Puddles will now correctly evaporate
|
||||
type: Fix
|
||||
id: 7815
|
||||
time: '2025-01-15T21:21:20.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34303
|
||||
- author: themias
|
||||
changes:
|
||||
- message: The DNA scrambler implant no longer updates your ID card or station record
|
||||
type: Fix
|
||||
id: 7816
|
||||
time: '2025-01-15T22:49:51.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34091
|
||||
- author: jbox144
|
||||
changes:
|
||||
- message: Added Plasma Station
|
||||
type: Add
|
||||
id: 7817
|
||||
time: '2025-01-16T07:02:14.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33991
|
||||
- author: jbox144
|
||||
changes:
|
||||
- message: Reduced Plasma's minimum population to 20, maximum population to 60
|
||||
type: Tweak
|
||||
- message: Reduced Plasma's clown jobs from 2 to 1
|
||||
type: Tweak
|
||||
id: 7818
|
||||
time: '2025-01-16T08:51:17.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34462
|
||||
|
||||
@@ -12,6 +12,10 @@ panic_bunker.enable_without_admins = true
|
||||
panic_bunker.show_reason = true
|
||||
panic_bunker.custom_reason = "You have not played on a Wizard's Den server long enough to connect to this server. Please play on Wizard's Den Lizard until you have more playtime."
|
||||
|
||||
# IPIntel stuff
|
||||
ipintel_enabled = true
|
||||
ipintel_contact_email = "telecommunications@spacestation14.com"
|
||||
|
||||
[infolinks]
|
||||
bug_report = "https://github.com/space-wizards/space-station-14/issues/new/choose"
|
||||
discord = "https://discord.spacestation14.io"
|
||||
@@ -44,6 +48,6 @@ alert.min_players_sharing_connection = 2
|
||||
max_explosion_range = 5
|
||||
|
||||
[status]
|
||||
privacy_policy_link = "https://account.spacestation14.com/Home/Privacy"
|
||||
privacy_policy_link = "https://spacestation14.com/about/privacy/#game-server-privacy-policy"
|
||||
privacy_policy_identifier = "wizden"
|
||||
privacy_policy_version = "2024-12-22"
|
||||
privacy_policy_version = "2025-01-19"
|
||||
|
||||
@@ -11,12 +11,6 @@ panic_bunker.enabled = false
|
||||
panic_bunker.disable_with_admins = false
|
||||
panic_bunker.enable_without_admins = false
|
||||
panic_bunker.custom_reason = ""
|
||||
baby_jail.enabled = true
|
||||
baby_jail.show_reason = true
|
||||
baby_jail.max_account_age = 5256000 # 10 years. Disabling this check specifically isn't currently supported
|
||||
baby_jail.max_overall_minutes = 3000 # 50 hours
|
||||
baby_jail.custom_reason = "Sorry! Only new and whitelisted players can join this server. Apply to be whitelisted in our Discord server (discord.ss14.io) or try joining another server instead!"
|
||||
baby_jail.whitelisted_can_bypass = true
|
||||
|
||||
[hub]
|
||||
tags = "lang:en,region:am_n_e,rp:low"
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
cmd-babyjail-desc = Toggles the baby jail, which enables stricter restrictions on who's allowed to join the server.
|
||||
cmd-babyjail-help = Usage: babyjail
|
||||
babyjail-command-enabled = Baby jail has been enabled.
|
||||
babyjail-command-disabled = Baby jail has been disabled.
|
||||
|
||||
cmd-babyjail_show_reason-desc = Toggles whether or not to show connecting clients the reason why the baby jail blocked them from joining.
|
||||
cmd-babyjail_show_reason-help = Usage: babyjail_show_reason
|
||||
babyjail-command-show-reason-enabled = The baby jail will now show a reason to users it blocks from connecting.
|
||||
babyjail-command-show-reason-disabled = The baby jail will no longer show a reason to users it blocks from connecting.
|
||||
|
||||
cmd-babyjail_max_account_age-desc = Gets or sets the maximum account age in minutes that an account can have to be allowed to connect with the baby jail enabled.
|
||||
cmd-babyjail_max_account_age-help = Usage: babyjail_max_account_age <minutes>
|
||||
babyjail-command-max-account-age-is = The maximum account age for the baby jail is {$minutes} minutes.
|
||||
babyjail-command-max-account-age-set = Set the maximum account age for the baby jail to {$minutes} minutes.
|
||||
|
||||
cmd-babyjail_max_overall_minutes-desc = Gets or sets the maximum overall playtime in minutes that an account can have to be allowed to connect with the baby jail enabled.
|
||||
cmd-babyjail_max_overall_minutes-help = Usage: babyjail_max_overall_minutes <minutes>
|
||||
babyjail-command-max-overall-minutes-is = The maximum overall playtime for the baby jail is {$minutes} minutes.
|
||||
babyjail-command-max-overall-minutes-set = Set the maximum overall playtime for the baby jail to {$minutes} minutes.
|
||||
@@ -14,6 +14,7 @@ permissions-eui-edit-admin-window-title-edit-placeholder = Custom title, leave b
|
||||
permissions-eui-edit-admin-window-no-rank-button = No rank
|
||||
permissions-eui-edit-admin-rank-window-name-edit-placeholder = Rank name
|
||||
permissions-eui-edit-admin-title-control-text = none
|
||||
permissions-eui-edit-admin-window-suspended = Suspended?
|
||||
permissions-eui-edit-no-rank-text = none
|
||||
permissions-eui-edit-title-button = Edit
|
||||
permissions-eui-edit-admin-rank-button = Edit
|
||||
|
||||
7
Resources/Locale/en-US/advertisements/vending/pride.ftl
Normal file
7
Resources/Locale/en-US/advertisements/vending/pride.ftl
Normal file
@@ -0,0 +1,7 @@
|
||||
advertisement-pride-1 = Be gay do crime!
|
||||
advertisement-pride-2 = Full of colors!
|
||||
advertisement-pride-3 = You are valid!
|
||||
advertisement-pride-4 = The first pride was a riot!
|
||||
thankyou-pride-1 = Slay!
|
||||
thankyou-pride-2 = Knock 'em dead!
|
||||
thankyou-pride-3 = What a glow up!
|
||||
12
Resources/Locale/en-US/advertisements/vending/smite.ftl
Normal file
12
Resources/Locale/en-US/advertisements/vending/smite.ftl
Normal file
@@ -0,0 +1,12 @@
|
||||
advertisement-smite-1 = SMITE! Ban your thirst!
|
||||
advertisement-smite-2 = An eldritch blast of lemon and lime!
|
||||
advertisement-smite-3 = Over 1 million drinks sold!
|
||||
advertisement-smite-4 = SMITE! Roll 2d8 for FLAVOR.
|
||||
advertisement-smite-5 = SMITE! Let's get that paperwork done!
|
||||
advertisement-smite-6 = The janitor has it in for you!
|
||||
advertisement-smite-7 = SMITE! It won't get you hammered.
|
||||
advertisement-smite-8 = It's lemon-lime time!
|
||||
thankyou-smite-1 = Smite makes right!
|
||||
thankyou-smite-2 = You DEFINITELY wanted lemon-lime!
|
||||
thankyou-smite-3 = The office won't know what hit them.
|
||||
thankyou-smite-4 = Banish your thirst.
|
||||
14
Resources/Locale/en-US/discord/watchlist-connections.ftl
Normal file
14
Resources/Locale/en-US/discord/watchlist-connections.ftl
Normal file
@@ -0,0 +1,14 @@
|
||||
discord-watchlist-connection-header =
|
||||
{ $players ->
|
||||
[one] {$players} player on a watchlist has
|
||||
*[other] {$players} players on a watchlist have
|
||||
} connected to {$serverName}
|
||||
|
||||
discord-watchlist-connection-entry = - {$playerName} with message "{$message}"{ $expiry ->
|
||||
[0] {""}
|
||||
*[other] {" "}(expires <t:{$expiry}:R>)
|
||||
}{ $otherWatchlists ->
|
||||
[0] {""}
|
||||
[one] {" "}and {$otherWatchlists} other watchlist
|
||||
*[other] {" "}and {$otherWatchlists} other watchlists
|
||||
}
|
||||
3968
Resources/Maps/Ruins/wrecklaimer.yml
Normal file
3968
Resources/Maps/Ruins/wrecklaimer.yml
Normal file
File diff suppressed because it is too large
Load Diff
1489
Resources/Maps/Shuttles/cargo_plasma.yml
Normal file
1489
Resources/Maps/Shuttles/cargo_plasma.yml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,7 @@ entities:
|
||||
name: NT Evac Log
|
||||
- type: Transform
|
||||
pos: -0.42093527,-0.86894274
|
||||
parent: invalid
|
||||
parent: 637
|
||||
- type: MapGrid
|
||||
chunks:
|
||||
0,0:
|
||||
@@ -804,6 +804,18 @@ entities:
|
||||
chunkSize: 4
|
||||
- type: GasTileOverlay
|
||||
- type: RadiationGridResistance
|
||||
- uid: 637
|
||||
components:
|
||||
- type: MetaData
|
||||
name: Map Entity
|
||||
- type: Transform
|
||||
- type: Map
|
||||
mapPaused: True
|
||||
- type: PhysicsMap
|
||||
- type: GridTree
|
||||
- type: MovedGrids
|
||||
- type: Broadphase
|
||||
- type: OccluderTree
|
||||
- proto: AirAlarm
|
||||
entities:
|
||||
- uid: 577
|
||||
@@ -1130,6 +1142,56 @@ entities:
|
||||
- type: Transform
|
||||
pos: 1.5,-6.5
|
||||
parent: 1
|
||||
- proto: AtmosDeviceFanDirectional
|
||||
entities:
|
||||
- uid: 638
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: -4.5,5.5
|
||||
parent: 1
|
||||
- uid: 639
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: -4.5,3.5
|
||||
parent: 1
|
||||
- uid: 640
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: -4.5,-2.5
|
||||
parent: 1
|
||||
- uid: 641
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: -4.5,-4.5
|
||||
parent: 1
|
||||
- uid: 642
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 5.5,-4.5
|
||||
parent: 1
|
||||
- uid: 643
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 5.5,-2.5
|
||||
parent: 1
|
||||
- uid: 644
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 5.5,3.5
|
||||
parent: 1
|
||||
- uid: 645
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 5.5,5.5
|
||||
parent: 1
|
||||
- proto: AtmosFixBlockerMarker
|
||||
entities:
|
||||
- uid: 615
|
||||
|
||||
7979
Resources/Maps/Shuttles/emergency_plasma.yml
Normal file
7979
Resources/Maps/Shuttles/emergency_plasma.yml
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
14133
Resources/Maps/meta.yml
14133
Resources/Maps/meta.yml
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
167820
Resources/Maps/plasma.yml
Normal file
167820
Resources/Maps/plasma.yml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -150,7 +150,7 @@
|
||||
|
||||
- type: entity
|
||||
id: CrateAirlockKit
|
||||
parent: CrateGenericSteel
|
||||
parent: CrateEngineering
|
||||
name: airlock kit
|
||||
description: A kit for building 6 airlocks, doesn't include tools.
|
||||
components:
|
||||
@@ -215,3 +215,31 @@
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: SpaceHeaterFlatpack
|
||||
|
||||
- type: entityTable
|
||||
id: RandomTechBoardTable
|
||||
table: !type:GroupSelector
|
||||
children:
|
||||
- id: AirAlarmElectronics
|
||||
- id: FireAlarmElectronics
|
||||
- id: DoorElectronics
|
||||
- id: FirelockElectronics
|
||||
- id: APCElectronics
|
||||
- id: SignalTimerElectronics
|
||||
- id: SMESMachineCircuitboard
|
||||
- id: SubstationMachineCircuitboard
|
||||
- id: SpaceVillainArcadeComputerCircuitboard
|
||||
- id: BlockGameArcadeComputerCircuitboard
|
||||
|
||||
- type: entity
|
||||
id: CrateTechBoardRandom
|
||||
parent: CrateEngineering
|
||||
name: surplus boards
|
||||
description: Surplus boards from somewhere.
|
||||
components:
|
||||
- type: EntityTableContainerFill
|
||||
containers:
|
||||
entity_storage: !type:NestedSelector
|
||||
tableId: RandomTechBoardTable
|
||||
rolls: !type:RangeNumberSelector
|
||||
range: 3, 7
|
||||
|
||||
@@ -107,6 +107,52 @@
|
||||
- id: SheetPaper
|
||||
amount: 3
|
||||
|
||||
- type: entityTable
|
||||
id: RandomMaterialCrateTable
|
||||
table: !type:GroupSelector
|
||||
children:
|
||||
- !type:GroupSelector # regular materials, 10
|
||||
weight: 35
|
||||
children:
|
||||
- id: SheetGlass10
|
||||
- id: SheetSteel10
|
||||
- id: SheetPlastic10
|
||||
- !type:GroupSelector # regular materials, stack
|
||||
weight: 30
|
||||
children:
|
||||
- id: SheetGlass
|
||||
- id: SheetSteel
|
||||
- id: SheetPlastic
|
||||
- !type:GroupSelector # secondary materials, stack
|
||||
weight: 30
|
||||
children:
|
||||
- id: MaterialCloth
|
||||
- id: SheetPlasteel
|
||||
- id: MaterialWoodPlank
|
||||
- id: PartRodMetal
|
||||
- !type:GroupSelector # tertiary materials, singles
|
||||
weight: 5
|
||||
children:
|
||||
- id: SheetPlasma1
|
||||
- id: SheetUranium1
|
||||
- id: IngotGold1
|
||||
- id: IngotSilver1
|
||||
|
||||
- type: entity
|
||||
id: CrateMaterialRandom
|
||||
parent: CrateGenericSteel
|
||||
name: surplus materials
|
||||
description: Surplus materials from somewhere.
|
||||
components:
|
||||
- type: EntityTableContainerFill
|
||||
containers:
|
||||
entity_storage: !type:NestedSelector
|
||||
tableId: RandomMaterialCrateTable
|
||||
rolls: !type:RangeNumberSelector
|
||||
range: 1, 3
|
||||
# for some reason, the selector here adds 1 to whatever value it generates,
|
||||
# so this is actually 2-4
|
||||
|
||||
#- type: entity
|
||||
# id: CrateMaterialHFuelTank
|
||||
# name: fueltank crate
|
||||
|
||||
@@ -159,6 +159,9 @@
|
||||
- !type:NestedSelector
|
||||
tableId: SyndieMaintLoot
|
||||
prob: 0.05
|
||||
# Recursive
|
||||
- id: ClosetMaintenanceFilledRandom
|
||||
prob: 0.01
|
||||
|
||||
- type: entity
|
||||
id: ClosetMaintenanceFilledRandom
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
- type: vendingMachineInventory
|
||||
id: PrideDrobeInventory
|
||||
startingInventory:
|
||||
ClothingNeckLGBTPin: 3
|
||||
ClothingNeckAromanticPin: 3
|
||||
ClothingNeckAsexualPin: 3
|
||||
ClothingNeckBisexualPin: 3
|
||||
ClothingNeckGayPin: 3
|
||||
ClothingNeckIntersexPin: 3
|
||||
ClothingNeckLesbianPin: 3
|
||||
ClothingNeckNonBinaryPin: 3
|
||||
ClothingNeckPansexualPin: 3
|
||||
ClothingNeckOmnisexualPin: 3
|
||||
ClothingNeckTransPin: 3
|
||||
ClothingNeckAutismPin: 3
|
||||
ClothingNeckGoldAutismPin: 3
|
||||
PlushieSharkBlue: 2
|
||||
PlushieSharkPink: 2
|
||||
PlushieSharkGrey: 2
|
||||
ClothingNeckCloakAce: 2
|
||||
ClothingNeckCloakAro: 2
|
||||
ClothingNeckCloakBi: 2
|
||||
ClothingNeckCloakEnby: 2
|
||||
ClothingNeckCloakGay: 2
|
||||
ClothingNeckCloakIntersex: 2
|
||||
ClothingNeckCloakLesbian: 2
|
||||
ClothingNeckCloakPan: 2
|
||||
ClothingNeckCloakTrans: 2
|
||||
ClothingHeadHatXmasCrown: 2
|
||||
BedsheetRainbow: 2
|
||||
ClothingNeckHeadphones: 2
|
||||
ClothingHeadHatFlowerWreath: 2
|
||||
ClothingUniformColorRainbow: 2
|
||||
ClothingUnderSocksCoder: 2
|
||||
ClothingUnderSocksBee: 2
|
||||
@@ -0,0 +1,13 @@
|
||||
- type: vendingMachineInventory
|
||||
id: SmiteInventory
|
||||
startingInventory:
|
||||
DrinkLemonLimeCan: 4
|
||||
DrinkLemonLimeCranberryCan: 2
|
||||
DrinkColaCan: 2
|
||||
DrinkSolDryCan: 2
|
||||
contrabandInventory:
|
||||
ToyHammer: 1
|
||||
DrinkStarkistCan: 2
|
||||
emaggedInventory:
|
||||
DrinkNukieCan: 2
|
||||
DrinkChangelingStingCan: 2
|
||||
@@ -88,6 +88,12 @@
|
||||
prefix: advertisement-gibb-
|
||||
count: 8
|
||||
|
||||
- type: localizedDataset
|
||||
id: SmiteAds
|
||||
values:
|
||||
prefix: advertisement-smite-
|
||||
count: 8
|
||||
|
||||
- type: localizedDataset
|
||||
id: CondimentVendAds
|
||||
values:
|
||||
@@ -279,3 +285,9 @@
|
||||
values:
|
||||
prefix: advertisement-medibot-
|
||||
count: 17
|
||||
|
||||
- type: localizedDataset
|
||||
id: PrideDrobeAds
|
||||
values:
|
||||
prefix: advertisement-pride-
|
||||
count: 4
|
||||
|
||||
@@ -46,6 +46,12 @@
|
||||
prefix: thankyou-gibb-
|
||||
count: 4
|
||||
|
||||
- type: localizedDataset
|
||||
id: SmiteGoodbyes
|
||||
values:
|
||||
prefix: thankyou-smite-
|
||||
count: 4
|
||||
|
||||
- type: localizedDataset
|
||||
id: DiscountDansGoodbyes
|
||||
values:
|
||||
@@ -111,3 +117,9 @@
|
||||
values:
|
||||
prefix: thankyou-syndiedrobe-
|
||||
count: 5
|
||||
|
||||
- type: localizedDataset
|
||||
id: PrideDrobeGoodbyes
|
||||
values:
|
||||
prefix: thankyou-pride-
|
||||
count: 3
|
||||
|
||||
@@ -319,8 +319,7 @@
|
||||
unequipDelay: 3
|
||||
- type: IngestionBlocker
|
||||
- type: AddAccentClothing
|
||||
accent: ReplacementAccent
|
||||
replacement: mumble
|
||||
accent: MumbleAccent
|
||||
- type: Construction
|
||||
graph: Muzzle
|
||||
node: muzzle
|
||||
|
||||
@@ -111,6 +111,17 @@
|
||||
- type: Clothing
|
||||
equippedPrefix: pan
|
||||
|
||||
- type: entity
|
||||
parent: ClothingNeckPinBase
|
||||
id: ClothingNeckOmnisexualPin
|
||||
name: omnisexual pin
|
||||
description: Be omni do crime.
|
||||
components:
|
||||
- type: Sprite
|
||||
state: omni
|
||||
- type: Clothing
|
||||
equippedPrefix: omni
|
||||
|
||||
- type: entity
|
||||
parent: ClothingNeckPinBase
|
||||
id: ClothingNeckTransPin
|
||||
@@ -121,7 +132,7 @@
|
||||
state: trans
|
||||
- type: Clothing
|
||||
equippedPrefix: trans
|
||||
|
||||
|
||||
- type: entity
|
||||
parent: ClothingNeckPinBase
|
||||
id: ClothingNeckAutismPin
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
- AnomalyFlora
|
||||
- AnomalyShadow
|
||||
- AnomalyTech
|
||||
- AnomalySanta #Remove in 2025
|
||||
#- AnomalySanta
|
||||
rareChance: 0.3
|
||||
rarePrototypes:
|
||||
- RandomAnomalyInjectorSpawner
|
||||
@@ -67,6 +67,6 @@
|
||||
- AnomalyTrapGravity
|
||||
- AnomalyTrapTech
|
||||
- AnomalyTrapRock
|
||||
- AnomalyTrapSanta # Remove in 2025
|
||||
#- AnomalyTrapSanta
|
||||
chance: 1
|
||||
|
||||
|
||||
|
||||
@@ -3,26 +3,26 @@
|
||||
id: CrateEmptySpawner
|
||||
parent: MarkerBase
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: red
|
||||
- sprite: Structures/Storage/Crates/generic.rsi
|
||||
state: icon
|
||||
- type: RandomSpawner
|
||||
prototypes:
|
||||
- CrateGenericSteel
|
||||
- CratePlastic
|
||||
- CrateFreezer
|
||||
- CrateHydroponics
|
||||
- CrateMedical
|
||||
- CrateRadiation
|
||||
- CrateInternals
|
||||
- CrateElectrical
|
||||
- CrateEngineering
|
||||
- CrateScience
|
||||
- CrateSurgery
|
||||
chance: 0.7
|
||||
offset: 0.0
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: red
|
||||
- sprite: Structures/Storage/Crates/generic.rsi
|
||||
state: icon
|
||||
- type: RandomSpawner
|
||||
prototypes:
|
||||
- CrateGenericSteel
|
||||
- CratePlastic
|
||||
- CrateFreezer
|
||||
- CrateHydroponics
|
||||
- CrateMedical
|
||||
- CrateRadiation
|
||||
- CrateInternals
|
||||
- CrateElectrical
|
||||
- CrateEngineering
|
||||
- CrateScience
|
||||
- CrateSurgery
|
||||
chance: 0.7
|
||||
offset: 0.0
|
||||
|
||||
- type: entity
|
||||
name: Filled Crate Spawner
|
||||
@@ -30,109 +30,112 @@
|
||||
suffix: Low Value
|
||||
parent: MarkerBase
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: red
|
||||
- sprite: Structures/Storage/Crates/o2.rsi
|
||||
state: icon
|
||||
- type: RandomSpawner
|
||||
prototypes:
|
||||
- CrateServiceReplacementLights
|
||||
- CrateServiceBureaucracy
|
||||
- CrateChemistrySupplies
|
||||
- CrateMaterialGlass
|
||||
- CrateMaterialSteel
|
||||
- CrateMaterialPlastic
|
||||
- CrateMaterialWood
|
||||
- CrateMaterialPlasteel
|
||||
- CrateFunArtSupplies
|
||||
- CrateEngineeringCableLV
|
||||
- CrateEngineeringCableMV
|
||||
- CrateEngineeringCableHV
|
||||
- CrateEngineeringCableBulk
|
||||
- CrateEmergencyFire
|
||||
- CrateEmergencyInternals
|
||||
- CrateEmergencyInflatablewall
|
||||
- CrateHydroponicsTools
|
||||
- CrateHydroponicsSeeds
|
||||
chance: 0.7
|
||||
rarePrototypes:
|
||||
- CrateMaterialPlasma
|
||||
- CrateHydroponicsSeedsExotic
|
||||
rareChance: 0.1
|
||||
offset: 0.0
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: red
|
||||
- sprite: Structures/Storage/Crates/o2.rsi
|
||||
state: icon
|
||||
- type: RandomSpawner
|
||||
prototypes:
|
||||
- CrateServiceReplacementLights
|
||||
- CrateServiceBureaucracy
|
||||
- CrateChemistrySupplies
|
||||
- CrateMaterialGlass
|
||||
- CrateMaterialSteel
|
||||
- CrateMaterialPlastic
|
||||
- CrateMaterialWood
|
||||
- CrateMaterialPlasteel
|
||||
- CrateMaterialRandom
|
||||
- CrateFunArtSupplies
|
||||
- CrateEngineeringCableLV
|
||||
- CrateEngineeringCableMV
|
||||
- CrateEngineeringCableHV
|
||||
- CrateEngineeringCableBulk
|
||||
- CrateTechBoardRandom
|
||||
- CrateEmergencyFire
|
||||
- CrateEmergencyInternals
|
||||
- CrateEmergencyInflatablewall
|
||||
- CrateHydroponicsTools
|
||||
- CrateHydroponicsSeeds
|
||||
- PetCarrier
|
||||
chance: 0.7
|
||||
rarePrototypes:
|
||||
- CrateMaterialPlasma
|
||||
- CrateHydroponicsSeedsExotic
|
||||
rareChance: 0.1
|
||||
offset: 0.0
|
||||
|
||||
- type: entity
|
||||
name: random engineering crate spawner
|
||||
id: LootSpawnerRandomCrateEngineering
|
||||
parent: MarkerBase
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: red
|
||||
- sprite: Structures/Storage/Crates/engineering.rsi
|
||||
state: icon
|
||||
- type: RandomSpawner
|
||||
rarePrototypes:
|
||||
- CrateEngineeringSingularityGenerator
|
||||
- CrateEngineeringTeslaGenerator
|
||||
- CrateEngineeringTeslaGroundingRod
|
||||
- CrateEngineeringParticleAccelerator
|
||||
- CrateRCD
|
||||
- CrateEngineeringGear
|
||||
rareChance: 0.2
|
||||
prototypes:
|
||||
- CrateEngineering
|
||||
- CrateElectrical
|
||||
- CrateEngineeringElectricalSupplies
|
||||
- CrateRCDAmmo
|
||||
- CrateEngineeringCableLV
|
||||
- CrateEngineeringCableMV
|
||||
- CrateEngineeringCableHV
|
||||
- CrateEngineeringCableBulk
|
||||
- CrateEngineeringSingularityContainment
|
||||
- CrateEngineeringSingularityCollector
|
||||
- CrateEngineeringTeslaCoil
|
||||
- CrateEngineeringSingularityEmitter
|
||||
- CrateEngineeringGyroscope
|
||||
- CrateEngineeringThruster
|
||||
- CrateEngineeringToolbox
|
||||
- CrateEngineeringShuttle
|
||||
- CrateEngineeringSolar
|
||||
- CrateEngineeringJetpack
|
||||
- CrateEmergencyRadiation
|
||||
- CrateRadiation
|
||||
chance: 0.9
|
||||
offset: 0.0
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: red
|
||||
- sprite: Structures/Storage/Crates/engineering.rsi
|
||||
state: icon
|
||||
- type: RandomSpawner
|
||||
rarePrototypes:
|
||||
- CrateEngineeringSingularityGenerator
|
||||
- CrateEngineeringTeslaGenerator
|
||||
- CrateEngineeringTeslaGroundingRod
|
||||
- CrateEngineeringParticleAccelerator
|
||||
- CrateRCD
|
||||
- CrateEngineeringGear
|
||||
rareChance: 0.2
|
||||
prototypes:
|
||||
- CrateEngineering
|
||||
- CrateElectrical
|
||||
- CrateEngineeringElectricalSupplies
|
||||
- CrateRCDAmmo
|
||||
- CrateEngineeringCableLV
|
||||
- CrateEngineeringCableMV
|
||||
- CrateEngineeringCableHV
|
||||
- CrateEngineeringCableBulk
|
||||
- CrateEngineeringSingularityContainment
|
||||
- CrateEngineeringSingularityCollector
|
||||
- CrateEngineeringTeslaCoil
|
||||
- CrateEngineeringSingularityEmitter
|
||||
- CrateEngineeringGyroscope
|
||||
- CrateEngineeringThruster
|
||||
- CrateEngineeringToolbox
|
||||
- CrateEngineeringShuttle
|
||||
- CrateEngineeringSolar
|
||||
- CrateEngineeringJetpack
|
||||
- CrateEmergencyRadiation
|
||||
- CrateRadiation
|
||||
chance: 0.9
|
||||
offset: 0.0
|
||||
|
||||
- type: entity
|
||||
name: random security crate spawner
|
||||
id: LootSpawnerRandomCrateSecurity
|
||||
parent: MarkerBase
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: red
|
||||
- sprite: Structures/Storage/Crates/sec_gear.rsi
|
||||
state: icon
|
||||
- type: RandomSpawner
|
||||
rarePrototypes: #Very useful stuff we probably don't want random people getting on space ruins often, even if there are hurdles to open it
|
||||
- CrateArmoryShotgun
|
||||
- CrateArmorySMG
|
||||
- CrateSecurityRiot
|
||||
- CrateSecurityNonlethal
|
||||
rareChance: 0.1
|
||||
prototypes:
|
||||
- CrateWeaponSecure
|
||||
- CrateArmoryLaser
|
||||
- CrateArmoryPistols
|
||||
- CrateTrainingBombs
|
||||
- CrateTrackingImplants
|
||||
- CrateSecurityTrackingMindshieldImplants
|
||||
- CrateSecurityHelmet
|
||||
- CrateSecurityArmor
|
||||
- CrateRestraints
|
||||
- CrateEmergencyExplosive
|
||||
- CrateSecurityBiosuit
|
||||
chance: 0.9
|
||||
offset: 0.0
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: red
|
||||
- sprite: Structures/Storage/Crates/sec_gear.rsi
|
||||
state: icon
|
||||
- type: RandomSpawner
|
||||
rarePrototypes: #Very useful stuff we probably don't want random people getting on space ruins often, even if there are hurdles to open it
|
||||
- CrateArmoryShotgun
|
||||
- CrateArmorySMG
|
||||
- CrateSecurityRiot
|
||||
- CrateSecurityNonlethal
|
||||
rareChance: 0.1
|
||||
prototypes:
|
||||
- CrateWeaponSecure
|
||||
- CrateArmoryLaser
|
||||
- CrateArmoryPistols
|
||||
- CrateTrainingBombs
|
||||
- CrateTrackingImplants
|
||||
- CrateSecurityTrackingMindshieldImplants
|
||||
- CrateSecurityHelmet
|
||||
- CrateSecurityArmor
|
||||
- CrateRestraints
|
||||
- CrateEmergencyExplosive
|
||||
- CrateSecurityBiosuit
|
||||
chance: 0.9
|
||||
offset: 0.0
|
||||
|
||||
@@ -149,6 +149,7 @@
|
||||
- id: ClothingNeckLesbianPin
|
||||
- id: ClothingNeckNonBinaryPin
|
||||
- id: ClothingNeckPansexualPin
|
||||
- id: ClothingNeckOmnisexualPin
|
||||
- id: ClothingNeckTransPin
|
||||
- id: ClothingNeckAutismPin
|
||||
- id: ClothingNeckGoldAutismPin
|
||||
@@ -393,3 +394,32 @@
|
||||
- Spaceshroom
|
||||
chance: 0.6
|
||||
offset: 0.0
|
||||
|
||||
|
||||
- type: entityTable
|
||||
id: InsulsTable
|
||||
table: !type:GroupSelector
|
||||
children:
|
||||
- id: ClothingHandsGlovesColorYellowBudget # budget insuls
|
||||
weight: 85
|
||||
- id: ClothingHandsGlovesColorYellow # true insuls
|
||||
weight: 10
|
||||
- id: ClothingHandsGlovesFingerlessInsulated # fingerless
|
||||
weight: 4
|
||||
- id: ClothingHandsGlovesConducting # conducting
|
||||
weight: 1
|
||||
|
||||
- type: entity
|
||||
name: Maint Loot Spawner
|
||||
id: MaintenanceInsulsSpawner
|
||||
suffix: Insuls, safe
|
||||
parent: MarkerBase
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: red
|
||||
- sprite: Clothing/Hands/Gloves/Color/yellow.rsi
|
||||
state: icon
|
||||
- type: EntityTableSpawner
|
||||
table: !type:NestedSelector
|
||||
tableId: InsulsTable
|
||||
|
||||
@@ -6,29 +6,59 @@
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: red
|
||||
- sprite: Structures/Machines/VendingMachines/random.rsi
|
||||
state: any
|
||||
- state: red
|
||||
- sprite: Structures/Machines/VendingMachines/random.rsi
|
||||
state: any
|
||||
- type: RandomSpawner
|
||||
prototypes:
|
||||
- VendingMachineCigs
|
||||
- VendingMachineCoffee
|
||||
- VendingMachineCola
|
||||
- VendingMachineColaRed
|
||||
- VendingMachineColaBlack
|
||||
- VendingMachineDiscount
|
||||
- VendingMachineSnack
|
||||
- VendingMachineSnackBlue
|
||||
- VendingMachineSnackGreen
|
||||
- VendingMachineSnackOrange
|
||||
- VendingMachineSnackTeal
|
||||
- VendingMachineSovietSoda
|
||||
- VendingMachineChang
|
||||
- VendingMachineDonut
|
||||
- VendingMachineShamblersJuice
|
||||
- VendingMachinePwrGame
|
||||
- VendingMachineDrGibb
|
||||
- VendingMachineSoda
|
||||
- VendingMachineStarkist
|
||||
- VendingMachineSpaceUp
|
||||
- VendingMachineChang
|
||||
- VendingMachineCigs
|
||||
- VendingMachineCoffee
|
||||
- VendingMachineCola #Robust Sofdrinks
|
||||
- VendingMachineColaBlack #Robust Sofdrinks [Black]
|
||||
- VendingMachineColaRed #Space Cola
|
||||
- VendingMachineDiscount
|
||||
- VendingMachineDonut
|
||||
- VendingMachineDrGibb
|
||||
- VendingMachinePwrGame
|
||||
- VendingMachineShamblersJuice
|
||||
- VendingMachineSmite
|
||||
- VendingMachineSnack
|
||||
- VendingMachineSnackBlue
|
||||
- VendingMachineSnackGreen
|
||||
- VendingMachineSnackOrange
|
||||
- VendingMachineSnackTeal
|
||||
- VendingMachineSoda #Robust Sofdrinks [Soda]
|
||||
- VendingMachineSovietSoda #Boda
|
||||
- VendingMachineSpaceUp
|
||||
- VendingMachineStarkist
|
||||
chance: 1
|
||||
|
||||
|
||||
- type: entityTable
|
||||
id: ClothingVendorTable
|
||||
table: !type:GroupSelector
|
||||
children:
|
||||
- id: VendingMachineClothing
|
||||
weight: 40
|
||||
- id: VendingMachineWinter
|
||||
weight: 40
|
||||
- id: VendingMachinePride
|
||||
weight: 10
|
||||
- id: VendingMachineTheater
|
||||
weight: 10
|
||||
|
||||
- type: entity
|
||||
id: RandomVendingClothing
|
||||
name: random vending machine spawner
|
||||
suffix: Clothing
|
||||
parent: MarkerBase
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: red
|
||||
- sprite: Structures/Machines/VendingMachines/random.rsi
|
||||
state: clothing
|
||||
- type: EntityTableSpawner
|
||||
table: !type:NestedSelector
|
||||
tableId: ClothingVendorTable
|
||||
|
||||
@@ -12,14 +12,15 @@
|
||||
- type: RandomSpawner
|
||||
prototypes:
|
||||
- VendingMachineCoffee
|
||||
- VendingMachineCola
|
||||
- VendingMachineColaRed
|
||||
- VendingMachineColaBlack
|
||||
- VendingMachineSovietSoda
|
||||
- VendingMachineShamblersJuice
|
||||
- VendingMachinePwrGame
|
||||
- VendingMachineCola #Robust Sofdrinks
|
||||
- VendingMachineColaBlack #Robust Sofdrinks [Black]
|
||||
- VendingMachineColaRed #Space Cola
|
||||
- VendingMachineDrGibb
|
||||
- VendingMachineSoda
|
||||
- VendingMachineStarkist
|
||||
- VendingMachinePwrGame
|
||||
- VendingMachineShamblersJuice
|
||||
- VendingMachineSmite
|
||||
- VendingMachineSoda #Robust Sofdrinks [Soda]
|
||||
- VendingMachineSovietSoda #Boda
|
||||
- VendingMachineSpaceUp
|
||||
- VendingMachineStarkist
|
||||
chance: 1
|
||||
|
||||
@@ -1567,7 +1567,7 @@
|
||||
- type: MobThresholds
|
||||
thresholds:
|
||||
0: Alive
|
||||
75: Critical
|
||||
100: Critical
|
||||
200: Dead
|
||||
- type: NpcFactionMember
|
||||
factions:
|
||||
|
||||
@@ -362,11 +362,35 @@
|
||||
components:
|
||||
- type: Pda
|
||||
id: MimeIDCard
|
||||
idSlot: # rewrite without sound because mime
|
||||
name: ID Card
|
||||
paiSlot:
|
||||
priority: -2
|
||||
ejectSound: null
|
||||
insertSound: null
|
||||
whitelist:
|
||||
components:
|
||||
- PAI
|
||||
idSlot:
|
||||
name: access-id-card-component-default
|
||||
ejectSound: null # mime is silent
|
||||
insertSound: null
|
||||
whitelist:
|
||||
components:
|
||||
- IdCard
|
||||
penSlot:
|
||||
startingItem: Pen
|
||||
priority: -1
|
||||
whitelist:
|
||||
tags:
|
||||
- Write
|
||||
ejectSound: null
|
||||
insertSound: null
|
||||
- type: CartridgeLoader
|
||||
cartridgeSlot:
|
||||
ejectSound: null
|
||||
insertSound: null
|
||||
whitelist:
|
||||
components:
|
||||
- Cartridge
|
||||
- type: Appearance
|
||||
appearanceDataInit:
|
||||
enum.PdaVisuals.PdaType:
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
- type: SwappableInstrument
|
||||
instrumentList:
|
||||
"Clean": {27: 0}
|
||||
"Jazz": {25: 0}
|
||||
"Jazz": {26: 0}
|
||||
"Muted": {28: 0}
|
||||
- type: Sprite
|
||||
sprite: Objects/Fun/Instruments/eguitar.rsi
|
||||
|
||||
@@ -63,4 +63,9 @@
|
||||
- type: ItemSlots
|
||||
- type: Item
|
||||
size: Ginormous
|
||||
sprite: Objects/Storage/petcarrier.rsi
|
||||
sprite: Objects/Storage/petcarrier.rsi
|
||||
- type: Construction
|
||||
graph: PetCarrier
|
||||
node: petCarrier
|
||||
containers:
|
||||
- entity_storage
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
- /Maps/Corvax/Ruins/corvax_ussp_debris.yml
|
||||
- /Maps/Corvax/Ruins/corvax_ussp_asteroid.yml
|
||||
# Corvax-Mapping-End
|
||||
- /Maps/Ruins/wrecklaimer.yml
|
||||
vgroid: !type:DungeonSpawnGroup
|
||||
minimumDistance: 300
|
||||
maximumDistance: 350
|
||||
|
||||
@@ -452,7 +452,6 @@
|
||||
- SodaDispenserMachineCircuitboard
|
||||
- SpaceHeaterMachineCircuitBoard
|
||||
- CutterMachineCircuitboard
|
||||
- StationAnchorCircuitboard
|
||||
- SalvageMagnetMachineCircuitboard
|
||||
dynamicRecipes:
|
||||
- ThermomachineFreezerMachineCircuitBoard
|
||||
@@ -1086,6 +1085,25 @@
|
||||
- CarpetPurple
|
||||
- CarpetCyan
|
||||
- CarpetWhite
|
||||
# Bedsheets
|
||||
- BedsheetBlack
|
||||
- BedsheetBlue
|
||||
- BedsheetBrown
|
||||
- BedsheetGreen
|
||||
- BedsheetGrey
|
||||
- BedsheetOrange
|
||||
- BedsheetPurple
|
||||
- BedsheetRed
|
||||
- BedsheetWhite
|
||||
- BedsheetYellow
|
||||
- BedsheetClown
|
||||
- BedsheetCosmos
|
||||
- BedsheetIan
|
||||
- BedsheetMedical
|
||||
- BedsheetMime
|
||||
- BedsheetNT
|
||||
- BedsheetRainbow
|
||||
- BedsheetBrigmedic
|
||||
# Corvax-Clothing-Start
|
||||
- ClothingHeadHatCapHoS
|
||||
- ClothingHeadHatBeretSecurityMedic
|
||||
@@ -1101,6 +1119,7 @@
|
||||
# Corvax-Clothing-End
|
||||
- type: EmagLatheRecipes
|
||||
emagStaticRecipes:
|
||||
# Clothing
|
||||
- ClothingHeadHatCentcomcap
|
||||
- ClothingHeadHatCentcom
|
||||
- ClothingUniformJumpsuitCentcomAgent
|
||||
@@ -1123,6 +1142,8 @@
|
||||
- ClothingOuterWinterCentcom
|
||||
- ClothingOuterWinterSyndie
|
||||
- ClothingOuterWinterSyndieCap
|
||||
# Bedsheets
|
||||
- BedsheetSyndie
|
||||
- type: MaterialStorage
|
||||
whitelist:
|
||||
tags:
|
||||
|
||||
@@ -137,7 +137,6 @@
|
||||
pack: CondimentVendAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: GenericVendGoodbyes
|
||||
- type: Speech
|
||||
- type: Transform
|
||||
noRot: false
|
||||
|
||||
@@ -156,7 +155,6 @@
|
||||
pack: AmmoVendAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: GenericVendGoodbyes
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Corvax/Structures/Machines/VendingMachines/ammo.rsi
|
||||
layers:
|
||||
@@ -185,7 +183,6 @@
|
||||
pack: BoozeOMatAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: BoozeOMatGoodbyes
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/boozeomat.rsi
|
||||
layers:
|
||||
@@ -220,7 +217,6 @@
|
||||
pack: BruiseOMatAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: BruiseOMatGoodbyes
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/bruiseomat.rsi
|
||||
layers:
|
||||
@@ -320,7 +316,6 @@
|
||||
pack: CigaretteMachineAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: CigaretteMachineGoodbyes
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/cigs.rsi
|
||||
layers:
|
||||
@@ -348,7 +343,6 @@
|
||||
pack: ClothesMateAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: GenericVendGoodbyes
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/clothing.rsi
|
||||
layers:
|
||||
@@ -380,7 +374,6 @@
|
||||
pack: ClothesMateAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: GenericVendGoodbyes
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/winterdrobe.rsi
|
||||
layers:
|
||||
@@ -419,7 +412,6 @@
|
||||
pack: HotDrinksMachineAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: HotDrinksMachineGoodbyes
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/coffee.rsi
|
||||
layers:
|
||||
@@ -459,7 +451,6 @@
|
||||
pack: RobustSoftdrinksAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: RobustSoftdrinksGoodbyes
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/cola.rsi
|
||||
layers:
|
||||
@@ -603,7 +594,6 @@
|
||||
initialStockQuality: 0.33
|
||||
- type: Advertise
|
||||
pack: RobustSoftdrinksAds
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/shamblersjuice.rsi
|
||||
layers:
|
||||
@@ -640,7 +630,6 @@
|
||||
pack: RobustSoftdrinksAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: GenericVendGoodbyes
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/pwrgame.rsi
|
||||
layers:
|
||||
@@ -677,7 +666,6 @@
|
||||
pack: DrGibbAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: DrGibbGoodbyes
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/gib.rsi
|
||||
layers:
|
||||
@@ -693,6 +681,42 @@
|
||||
energy: 1.6
|
||||
color: "#D82929"
|
||||
|
||||
- type: entity
|
||||
parent: VendingMachine
|
||||
id: VendingMachineSmite
|
||||
name: Smite Vendor
|
||||
description: Popular with the administration.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/smite.rsi
|
||||
layers:
|
||||
- state: "off"
|
||||
map: [ "enum.VendingMachineVisualLayers.Base" ]
|
||||
- state: "off"
|
||||
map: [ "enum.VendingMachineVisualLayers.BaseUnshaded" ]
|
||||
shader: unshaded
|
||||
- state: panel
|
||||
map: [ "enum.WiresVisualLayers.MaintenancePanel" ]
|
||||
- type: VendingMachine
|
||||
pack: SmiteInventory
|
||||
dispenseOnHitChance: 0.25
|
||||
dispenseOnHitThreshold: 2
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
ejectState: eject-unshaded
|
||||
denyState: deny-unshaded
|
||||
ejectDelay: 1.9
|
||||
initialStockQuality: 0.33
|
||||
- type: Advertise
|
||||
pack: SmiteAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: SmiteGoodbyes
|
||||
- type: PointLight
|
||||
radius: 1.5
|
||||
energy: 1.6
|
||||
color: "#00E645"
|
||||
|
||||
- type: entity
|
||||
parent: VendingMachine
|
||||
id: VendingMachineDinnerware
|
||||
@@ -774,7 +798,6 @@
|
||||
pack: DiscountDansAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: DiscountDansGoodbyes
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/discount.rsi
|
||||
layers:
|
||||
@@ -991,7 +1014,6 @@
|
||||
pack: GetmoreChocolateCorpAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: GetmoreChocolateCorpGoodbyes
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/snack.rsi
|
||||
layers:
|
||||
@@ -1137,7 +1159,6 @@
|
||||
pack: BodaAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: BodaGoodbyes
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/sovietsoda.rsi
|
||||
layers:
|
||||
@@ -1171,7 +1192,6 @@
|
||||
pack: AutoDrobeAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: GenericVendGoodbyes
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/theater.rsi
|
||||
layers:
|
||||
@@ -1207,7 +1227,6 @@
|
||||
pack: VendomatAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: GenericVendGoodbyes
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/vendomat.rsi
|
||||
layers:
|
||||
@@ -1240,7 +1259,6 @@
|
||||
pack: VendomatAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: GenericVendGoodbyes
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/robotics.rsi
|
||||
layers:
|
||||
@@ -1339,7 +1357,6 @@
|
||||
pack: ChangAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: ChangGoodbyes
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/changs.rsi
|
||||
layers:
|
||||
@@ -1405,7 +1422,6 @@
|
||||
pack: DonutAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: DonutGoodbyes
|
||||
- type: Speech
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/donut.rsi
|
||||
layers:
|
||||
@@ -2102,6 +2118,39 @@
|
||||
- type: AccessReader
|
||||
access: [["Kitchen"], ["Theatre"]]
|
||||
|
||||
# Pride Vending Machine
|
||||
|
||||
- type: entity
|
||||
parent: VendingMachine
|
||||
id: VendingMachinePride
|
||||
name: Pride-O-Mat
|
||||
description: A vending machine containing pride.
|
||||
components:
|
||||
- type: VendingMachine
|
||||
pack: PrideDrobeInventory
|
||||
offState: off
|
||||
brokenState: broken
|
||||
normalState: normal-unshaded
|
||||
- type: Advertise
|
||||
pack: PrideDrobeAds
|
||||
- type: SpeakOnUIClosed
|
||||
pack: PrideDrobeGoodbyes
|
||||
- type: Speech
|
||||
- type: PointLight
|
||||
radius: 1.5
|
||||
energy: 1.3 # reduced energy since the color is pure white
|
||||
color: "#FFFFFF"
|
||||
- type: Sprite
|
||||
sprite: Structures/Machines/VendingMachines/pride.rsi
|
||||
layers:
|
||||
- state: "off"
|
||||
map: ["enum.VendingMachineVisualLayers.Base"]
|
||||
- state: "off"
|
||||
map: ["enum.VendingMachineVisualLayers.BaseUnshaded"]
|
||||
shader: unshaded
|
||||
- state: panel
|
||||
map: ["enum.WiresVisualLayers.MaintenancePanel"]
|
||||
|
||||
# Gas Tank Dispenser
|
||||
|
||||
- type: entity
|
||||
|
||||
@@ -28,9 +28,9 @@
|
||||
radius: 0.35
|
||||
density: 50
|
||||
mask:
|
||||
- MobMask
|
||||
- FlyingMobMask
|
||||
layer:
|
||||
- MobLayer
|
||||
- FlyingMobLayer
|
||||
- type: Sprite
|
||||
noRot: true
|
||||
drawdepth: Effects #it needs to draw over stuff.
|
||||
|
||||
@@ -154,6 +154,12 @@
|
||||
back:
|
||||
- ClothingNeckPansexualPin
|
||||
|
||||
- type: loadout
|
||||
id: ClothingNeckOmnisexualPin
|
||||
storage:
|
||||
back:
|
||||
- ClothingNeckOmnisexualPin
|
||||
|
||||
- type: loadout
|
||||
id: ClothingNeckTransPin
|
||||
storage:
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
- ClothingNeckLesbianPin
|
||||
- ClothingNeckNonBinaryPin
|
||||
- ClothingNeckPansexualPin
|
||||
- ClothingNeckOmnisexualPin
|
||||
- ClothingNeckTransPin
|
||||
- ClothingNeckAutismPin
|
||||
- ClothingNeckGoldAutismPin
|
||||
|
||||
@@ -15,5 +15,6 @@
|
||||
- Oasis
|
||||
- Omega
|
||||
- Packed
|
||||
- Plasma
|
||||
- Reach
|
||||
#- Train
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
Chaplain: [ 1, 1 ]
|
||||
Librarian: [ 1, 1 ]
|
||||
ServiceWorker: [ 2, 2 ]
|
||||
Reporter: [ 1, 1 ]
|
||||
#engineering
|
||||
ChiefEngineer: [ 1, 1 ]
|
||||
AtmosphericTechnician: [ 3, 3 ]
|
||||
|
||||
66
Resources/Prototypes/Maps/plasma.yml
Normal file
66
Resources/Prototypes/Maps/plasma.yml
Normal file
@@ -0,0 +1,66 @@
|
||||
- type: gameMap
|
||||
id: Plasma
|
||||
mapName: 'Plasma'
|
||||
mapPath: /Maps/plasma.yml
|
||||
minPlayers: 20
|
||||
maxPlayers: 60
|
||||
stations:
|
||||
Plasma:
|
||||
stationProto: StandardNanotrasenStation
|
||||
components:
|
||||
- type: StationNameSetup
|
||||
mapNameTemplate: '{0} Plasma {1}'
|
||||
nameGenerator:
|
||||
!type:NanotrasenNameGenerator
|
||||
prefixCreator: '14'
|
||||
- type: StationEmergencyShuttle
|
||||
emergencyShuttlePath: /Maps/Shuttles/emergency_plasma.yml
|
||||
- type: StationCargoShuttle
|
||||
path: /Maps/Shuttles/cargo_plasma.yml
|
||||
- type: StationJobs
|
||||
availableJobs:
|
||||
#service
|
||||
Captain: [ 1, 1 ]
|
||||
HeadOfPersonnel: [ 1, 1 ]
|
||||
Bartender: [ 2, 2 ]
|
||||
Botanist: [ 2, 3 ]
|
||||
Chef: [ 2, 2 ]
|
||||
Janitor: [ 3, 3 ]
|
||||
Chaplain: [ 1, 1 ]
|
||||
Librarian: [ 1, 1 ]
|
||||
ServiceWorker: [ 2, 2 ]
|
||||
Reporter: [ 2, 3 ]
|
||||
#engineering
|
||||
ChiefEngineer: [ 1, 1 ]
|
||||
AtmosphericTechnician: [ 4, 4 ]
|
||||
StationEngineer: [ 4, 4 ]
|
||||
TechnicalAssistant: [ 4, 4 ]
|
||||
#medical
|
||||
ChiefMedicalOfficer: [ 1, 1 ]
|
||||
Chemist: [ 2, 2 ]
|
||||
MedicalDoctor: [ 4, 4 ]
|
||||
Paramedic: [ 2, 2 ]
|
||||
MedicalIntern: [ 4, 4 ]
|
||||
Psychologist: [ 1, 1 ]
|
||||
#science
|
||||
ResearchDirector: [ 1, 1 ]
|
||||
Scientist: [ 4, 4 ]
|
||||
ResearchAssistant: [ 4, 4 ]
|
||||
StationAi: [ 1, 1 ]
|
||||
Borg: [ 2, 4 ]
|
||||
#security
|
||||
HeadOfSecurity: [ 1, 1 ]
|
||||
Warden: [ 1, 1 ]
|
||||
SecurityOfficer: [ 6, 8 ]
|
||||
Detective: [ 1, 2 ]
|
||||
SecurityCadet: [ 4, 4 ]
|
||||
Lawyer: [ 1, 2 ]
|
||||
#supply
|
||||
Quartermaster: [ 1, 1 ]
|
||||
SalvageSpecialist: [ 4, 4 ]
|
||||
CargoTechnician: [ 4, 6 ]
|
||||
#civilian
|
||||
Passenger: [ -1, -1 ]
|
||||
Clown: [ 1, 1 ]
|
||||
Mime: [ 1, 1 ]
|
||||
Musician: [ 1, 1 ]
|
||||
@@ -0,0 +1,16 @@
|
||||
- type: constructionGraph
|
||||
id: PetCarrier
|
||||
start: start
|
||||
graph:
|
||||
- node: start
|
||||
edges:
|
||||
- to: petCarrier
|
||||
steps:
|
||||
- material: Plastic
|
||||
amount: 5
|
||||
doAfter: 7
|
||||
- material: MetalRod
|
||||
amount: 4
|
||||
doAfter: 3
|
||||
- node: petCarrier
|
||||
entity: PetCarrier
|
||||
@@ -227,3 +227,16 @@
|
||||
icon:
|
||||
sprite: Objects/Tools/rolling_pin.rsi
|
||||
state: icon
|
||||
|
||||
- type: construction
|
||||
name: pet carrier
|
||||
id: PetCarrier
|
||||
graph: PetCarrier
|
||||
startNode: start
|
||||
targetNode: petCarrier
|
||||
category: construction-category-misc
|
||||
objectType: Item
|
||||
description: Allows large animals to be carried comfortably.
|
||||
icon:
|
||||
sprite: Objects/Storage/petcarrier.rsi
|
||||
state: icon
|
||||
|
||||
113
Resources/Prototypes/Recipes/Lathes/bedsheets.yml
Normal file
113
Resources/Prototypes/Recipes/Lathes/bedsheets.yml
Normal file
@@ -0,0 +1,113 @@
|
||||
- type: latheRecipe
|
||||
abstract: true
|
||||
id: BaseBedsheetRecipe
|
||||
completetime: 2
|
||||
materials:
|
||||
Cloth: 150
|
||||
|
||||
- type: latheRecipe
|
||||
abstract: true
|
||||
parent: BaseBedsheetRecipe
|
||||
id: BaseSpecifiedBedsheetRecipe
|
||||
materials:
|
||||
Cloth: 150
|
||||
Durathread: 50
|
||||
|
||||
#Base bedsheets
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBedsheetRecipe
|
||||
id: BedsheetBlack
|
||||
result: BedsheetBlack
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBedsheetRecipe
|
||||
id: BedsheetBlue
|
||||
result: BedsheetBlue
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBedsheetRecipe
|
||||
id: BedsheetBrown
|
||||
result: BedsheetBrown
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBedsheetRecipe
|
||||
id: BedsheetGreen
|
||||
result: BedsheetGreen
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBedsheetRecipe
|
||||
id: BedsheetGrey
|
||||
result: BedsheetGrey
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBedsheetRecipe
|
||||
id: BedsheetOrange
|
||||
result: BedsheetOrange
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBedsheetRecipe
|
||||
id: BedsheetPurple
|
||||
result: BedsheetPurple
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBedsheetRecipe
|
||||
id: BedsheetRed
|
||||
result: BedsheetRed
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBedsheetRecipe
|
||||
id: BedsheetWhite
|
||||
result: BedsheetWhite
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBedsheetRecipe
|
||||
id: BedsheetYellow
|
||||
result: BedsheetYellow
|
||||
|
||||
#Specified bedsheets
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseSpecifiedBedsheetRecipe
|
||||
id: BedsheetClown
|
||||
result: BedsheetClown
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseSpecifiedBedsheetRecipe
|
||||
id: BedsheetCosmos
|
||||
result: BedsheetCosmos
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseSpecifiedBedsheetRecipe
|
||||
id: BedsheetIan #I'm not sure that that should be here
|
||||
result: BedsheetIan
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseSpecifiedBedsheetRecipe
|
||||
id: BedsheetMedical
|
||||
result: BedsheetMedical
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseSpecifiedBedsheetRecipe
|
||||
id: BedsheetMime
|
||||
result: BedsheetMime
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseSpecifiedBedsheetRecipe
|
||||
id: BedsheetNT
|
||||
result: BedsheetNT
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseSpecifiedBedsheetRecipe
|
||||
id: BedsheetRainbow
|
||||
result: BedsheetRainbow
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseSpecifiedBedsheetRecipe
|
||||
id: BedsheetBrigmedic
|
||||
result: BedsheetBrigmedic
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseSpecifiedBedsheetRecipe
|
||||
id: BedsheetSyndie
|
||||
result: BedsheetSyndie
|
||||
51
Resources/Prototypes/Recipes/Lathes/carpets.yml
Normal file
51
Resources/Prototypes/Recipes/Lathes/carpets.yml
Normal file
@@ -0,0 +1,51 @@
|
||||
- type: latheRecipe
|
||||
abstract: true
|
||||
id: BaseCarpetRecipe
|
||||
completetime: 1
|
||||
materials:
|
||||
Cloth: 100
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseCarpetRecipe
|
||||
id: Carpet
|
||||
result: FloorCarpetItemRed
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseCarpetRecipe
|
||||
id: CarpetBlack
|
||||
result: FloorCarpetItemBlack
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseCarpetRecipe
|
||||
id: CarpetPink
|
||||
result: FloorCarpetItemPink
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseCarpetRecipe
|
||||
id: CarpetBlue
|
||||
result: FloorCarpetItemBlue
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseCarpetRecipe
|
||||
id: CarpetGreen
|
||||
result: FloorCarpetItemGreen
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseCarpetRecipe
|
||||
id: CarpetOrange
|
||||
result: FloorCarpetItemOrange
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseCarpetRecipe
|
||||
id: CarpetPurple
|
||||
result: FloorCarpetItemPurple
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseCarpetRecipe
|
||||
id: CarpetCyan
|
||||
result: FloorCarpetItemCyan
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseCarpetRecipe
|
||||
id: CarpetWhite
|
||||
result: FloorCarpetItemWhite
|
||||
@@ -38,13 +38,6 @@
|
||||
materials:
|
||||
Cloth: 100
|
||||
|
||||
- type: latheRecipe
|
||||
abstract: true
|
||||
id: BaseCarpetRecipe
|
||||
completetime: 1
|
||||
materials:
|
||||
Cloth: 100
|
||||
|
||||
- type: latheRecipe
|
||||
abstract: true
|
||||
parent: BaseHatRecipe
|
||||
@@ -916,49 +909,3 @@
|
||||
parent: BaseNeckClothingRecipe
|
||||
id: ClothingNeckScarfStripedPurple
|
||||
result: ClothingNeckScarfStripedPurple
|
||||
|
||||
# Carpets
|
||||
- type: latheRecipe
|
||||
parent: BaseCarpetRecipe
|
||||
id: Carpet
|
||||
result: FloorCarpetItemRed
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseCarpetRecipe
|
||||
id: CarpetBlack
|
||||
result: FloorCarpetItemBlack
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseCarpetRecipe
|
||||
id: CarpetPink
|
||||
result: FloorCarpetItemPink
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseCarpetRecipe
|
||||
id: CarpetBlue
|
||||
result: FloorCarpetItemBlue
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseCarpetRecipe
|
||||
id: CarpetGreen
|
||||
result: FloorCarpetItemGreen
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseCarpetRecipe
|
||||
id: CarpetOrange
|
||||
result: FloorCarpetItemOrange
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseCarpetRecipe
|
||||
id: CarpetPurple
|
||||
result: FloorCarpetItemPurple
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseCarpetRecipe
|
||||
id: CarpetCyan
|
||||
result: FloorCarpetItemCyan
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseCarpetRecipe
|
||||
id: CarpetWhite
|
||||
result: FloorCarpetItemWhite
|
||||
|
||||
@@ -584,12 +584,6 @@
|
||||
result: ShuttleGunDusterCircuitboard
|
||||
completetime: 12
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseGoldCircuitboardRecipe
|
||||
id: StationAnchorCircuitboard
|
||||
result: StationAnchorCircuitboard
|
||||
completetime: 8
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseGoldCircuitboardRecipe
|
||||
id: ReagentGrinderIndustrialMachineCircuitboard
|
||||
|
||||
@@ -13,6 +13,6 @@
|
||||
id: ThiefGear
|
||||
storage:
|
||||
back:
|
||||
- ThiefBeacon
|
||||
- ToolboxThief
|
||||
- ClothingHandsChameleonThief
|
||||
- ThiefBeacon
|
||||
|
||||
@@ -368,7 +368,8 @@
|
||||
storage:
|
||||
back:
|
||||
- Hypospray
|
||||
- MedkitAdvancedFilled
|
||||
- MedkitCombatFilled
|
||||
- MedkitCombatFilled
|
||||
- CrowbarRed
|
||||
- OmnizineChemistryBottle
|
||||
- EpinephrineChemistryBottle
|
||||
@@ -391,7 +392,8 @@
|
||||
storage:
|
||||
back:
|
||||
- Hypospray
|
||||
- MedkitAdvancedFilled
|
||||
- MedkitCombatFilled
|
||||
- MedkitCombatFilled
|
||||
- CrowbarRed
|
||||
- OmnizineChemistryBottle
|
||||
- EpinephrineChemistryBottle
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": 1,
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "PixelTK leaves his mark on upstream, BackeTako made the gay, autism pins by Terraspark",
|
||||
"copyright": "PixelTK leaves his mark on upstream, BackeTako made the gay, autism pins by Terraspark, omnisexual pin by juliangiebel",
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
@@ -90,6 +90,13 @@
|
||||
{
|
||||
"name": "trans-equipped-NECK",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "omni"
|
||||
},
|
||||
{
|
||||
"name": "omni-equipped-NECK",
|
||||
"directions": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user