Merge branch 'master' into ion-storm-refactor

This commit is contained in:
metalgearsloth
2024-11-20 18:22:08 +11:00
committed by GitHub
150 changed files with 5700 additions and 2230 deletions

23
.github/workflows/labeler-review.yml vendored Normal file
View File

@@ -0,0 +1,23 @@
name: "Labels: Approved"
on:
pull_request_review:
types: [submitted]
jobs:
add_label:
# Change the repository name after you've made sure the team name is correct for your fork!
if: ${{ (github.repository == 'space-wizards/space-station-14') && (github.event.review.state == 'APPROVED') }}
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: tspascoal/get-user-teams-membership@v3
id: checkUserMember
with:
username: ${{ github.actor }}
team: "content-maintainers,junior-maintainers" # CHANGE TEAM NAME HERE PLEASE <------
GITHUB_TOKEN: ${{ secrets.PAT }}
- if: ${{ steps.checkUserMember.outputs.isTeamMember == 'true' }}
uses: actions-ecosystem/action-add-labels@v1
with:
labels: "PR: Approved"

View File

@@ -1,15 +1,20 @@
<DefaultWindow xmlns="https://spacestation14.io">
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.4" Margin="0 0 5 0">
<BoxContainer Orientation="Vertical" MinWidth="243" Margin="0 0 5 0">
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="0 0 0 5">
<LineEdit Name="SearchBar" PlaceHolder="Search" HorizontalExpand="True"/>
<OptionButton Name="OptionCategories" Access="Public" MinSize="130 0"/>
</BoxContainer>
<ItemList Name="Recipes" Access="Public" SelectMode="Single" VerticalExpand="True"/>
<ScrollContainer Name="RecipesGridScrollContainer" VerticalExpand="True" Access="Public" Visible="False">
<GridContainer Name="RecipesGrid" Columns="5" Access="Public"/>
</ScrollContainer>
</BoxContainer>
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.6">
<Button Name="FavoriteButton" Visible="false" HorizontalExpand="False"
HorizontalAlignment="Right" Margin="0 0 0 15"/>
<BoxContainer Orientation="Vertical" HorizontalExpand="True">
<BoxContainer Orientation="Horizontal">
<Button Name="MenuGridViewButton" ToggleMode="True" Text="{Loc construction-menu-grid-view}"/>
<Button Name="FavoriteButton" Visible="false"/>
</BoxContainer>
<Control>
<BoxContainer Orientation="Vertical" HorizontalExpand="True" Margin="0 0 0 5">
<BoxContainer Orientation="Horizontal" Align="Center">

View File

@@ -25,11 +25,16 @@ namespace Content.Client.Construction.UI
OptionButton OptionCategories { get; }
bool EraseButtonPressed { get; set; }
bool GridViewButtonPressed { get; set; }
bool BuildButtonPressed { get; set; }
ItemList Recipes { get; }
ItemList RecipeStepList { get; }
ScrollContainer RecipesGridScrollContainer { get; }
GridContainer RecipesGrid { get; }
event EventHandler<(string search, string catagory)> PopulateRecipes;
event EventHandler<ItemList.Item?> RecipeSelected;
event EventHandler RecipeFavorited;
@@ -72,9 +77,16 @@ namespace Content.Client.Construction.UI
set => EraseButton.Pressed = value;
}
public bool GridViewButtonPressed
{
get => MenuGridViewButton.Pressed;
set => MenuGridViewButton.Pressed = value;
}
public ConstructionMenu()
{
SetSize = MinSize = new Vector2(720, 320);
SetSize = new Vector2(560, 450);
MinSize = new Vector2(560, 320);
IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this);
@@ -102,6 +114,9 @@ namespace Content.Client.Construction.UI
EraseButton.OnToggled += args => EraseButtonToggled?.Invoke(this, args.Pressed);
FavoriteButton.OnPressed += args => RecipeFavorited?.Invoke(this, EventArgs.Empty);
MenuGridViewButton.OnPressed += _ =>
PopulateRecipes?.Invoke(this, (SearchBar.Text, Categories[OptionCategories.SelectedId]));
}
public event EventHandler? ClearAllGhosts;

View File

@@ -1,7 +1,8 @@
using System.Linq;
using System.Numerics;
using Content.Client.Stylesheets;
using Content.Client.UserInterface.Systems.MenuBar.Widgets;
using Content.Shared.Construction.Prototypes;
using Content.Shared.Tag;
using Content.Shared.Whitelist;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
@@ -11,7 +12,6 @@ using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.Utility;
using Robust.Shared.Enums;
using Robust.Shared.Graphics;
using Robust.Shared.Prototypes;
using static Robust.Client.UserInterface.Controls.BaseButton;
@@ -33,10 +33,12 @@ namespace Content.Client.Construction.UI
private readonly IConstructionMenuView _constructionView;
private readonly EntityWhitelistSystem _whitelistSystem;
private readonly SpriteSystem _spriteSystem;
private ConstructionSystem? _constructionSystem;
private ConstructionPrototype? _selected;
private List<ConstructionPrototype> _favoritedRecipes = [];
private Dictionary<string, TextureButton> _recipeButtons = new();
private string _selectedCategory = string.Empty;
private string _favoriteCatName = "construction-category-favorites";
private string _forAllCategoryName = "construction-category-all";
@@ -85,6 +87,7 @@ namespace Content.Client.Construction.UI
IoCManager.InjectDependencies(this);
_constructionView = new ConstructionMenu();
_whitelistSystem = _entManager.System<EntityWhitelistSystem>();
_spriteSystem = _entManager.System<SpriteSystem>();
// This is required so that if we load after the system is initialized, we can bind to it immediately
if (_systemManager.TryGetEntitySystem<ConstructionSystem>(out var constructionSystem))
@@ -150,12 +153,24 @@ namespace Content.Client.Construction.UI
PopulateInfo(_selected);
}
private void OnGridViewRecipeSelected(object? sender, ConstructionPrototype? recipe)
{
if (recipe is null)
{
_selected = null;
_constructionView.ClearRecipeInfo();
return;
}
_selected = recipe;
if (_placementManager.IsActive && !_placementManager.Eraser) UpdateGhostPlacement();
PopulateInfo(_selected);
}
private void OnViewPopulateRecipes(object? sender, (string search, string catagory) args)
{
var (search, category) = args;
var recipesList = _constructionView.Recipes;
recipesList.Clear();
var recipes = new List<ConstructionPrototype>();
var isEmptyCategory = string.IsNullOrEmpty(category) || category == _forAllCategoryName;
@@ -201,12 +216,73 @@ namespace Content.Client.Construction.UI
recipes.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.InvariantCulture));
foreach (var recipe in recipes)
{
recipesList.Add(GetItem(recipe, recipesList));
}
var recipesList = _constructionView.Recipes;
recipesList.Clear();
// There is apparently no way to set which
var recipesGrid = _constructionView.RecipesGrid;
recipesGrid.RemoveAllChildren();
_constructionView.RecipesGridScrollContainer.Visible = _constructionView.GridViewButtonPressed;
_constructionView.Recipes.Visible = !_constructionView.GridViewButtonPressed;
if (_constructionView.GridViewButtonPressed)
{
foreach (var recipe in recipes)
{
var itemButton = new TextureButton
{
TextureNormal = _spriteSystem.Frame0(recipe.Icon),
VerticalAlignment = Control.VAlignment.Center,
Name = recipe.Name,
ToolTip = recipe.Name,
Scale = new Vector2(1.35f),
ToggleMode = true,
};
var itemButtonPanelContainer = new PanelContainer
{
PanelOverride = new StyleBoxFlat { BackgroundColor = StyleNano.ButtonColorDefault },
Children = { itemButton },
};
itemButton.OnToggled += buttonToggledEventArgs =>
{
SelectGridButton(itemButton, buttonToggledEventArgs.Pressed);
if (buttonToggledEventArgs.Pressed &&
_selected != null &&
_recipeButtons.TryGetValue(_selected.Name, out var oldButton))
{
oldButton.Pressed = false;
SelectGridButton(oldButton, false);
}
OnGridViewRecipeSelected(this, buttonToggledEventArgs.Pressed ? recipe : null);
};
recipesGrid.AddChild(itemButtonPanelContainer);
_recipeButtons[recipe.Name] = itemButton;
var isCurrentButtonSelected = _selected == recipe;
itemButton.Pressed = isCurrentButtonSelected;
SelectGridButton(itemButton, isCurrentButtonSelected);
}
}
else
{
foreach (var recipe in recipes)
{
recipesList.Add(GetItem(recipe, recipesList));
}
}
}
private void SelectGridButton(TextureButton button, bool select)
{
if (button.Parent is not PanelContainer buttonPanel)
return;
button.Modulate = select ? Color.Green : Color.White;
var buttonColor = select ? StyleNano.ButtonColorDefault : Color.Transparent;
buttonPanel.PanelOverride = new StyleBoxFlat { BackgroundColor = buttonColor };
}
private void PopulateCategories(string? selectCategory = null)
@@ -257,11 +333,10 @@ namespace Content.Client.Construction.UI
private void PopulateInfo(ConstructionPrototype prototype)
{
var spriteSys = _systemManager.GetEntitySystem<SpriteSystem>();
_constructionView.ClearRecipeInfo();
_constructionView.SetRecipeInfo(
prototype.Name, prototype.Description, spriteSys.Frame0(prototype.Icon),
prototype.Name, prototype.Description, _spriteSystem.Frame0(prototype.Icon),
prototype.Type != ConstructionType.Item,
!_favoritedRecipes.Contains(prototype));
@@ -274,7 +349,6 @@ namespace Content.Client.Construction.UI
if (_constructionSystem?.GetGuide(prototype) is not { } guide)
return;
var spriteSys = _systemManager.GetEntitySystem<SpriteSystem>();
foreach (var entry in guide.Entries)
{
@@ -290,20 +364,20 @@ namespace Content.Client.Construction.UI
// The padding needs to be applied regardless of text length... (See PadLeft documentation)
text = text.PadLeft(text.Length + entry.Padding);
var icon = entry.Icon != null ? spriteSys.Frame0(entry.Icon) : Texture.Transparent;
var icon = entry.Icon != null ? _spriteSystem.Frame0(entry.Icon) : Texture.Transparent;
stepList.AddItem(text, icon, false);
}
}
private static ItemList.Item GetItem(ConstructionPrototype recipe, ItemList itemList)
private ItemList.Item GetItem(ConstructionPrototype recipe, ItemList itemList)
{
return new(itemList)
{
Metadata = recipe,
Text = recipe.Name,
Icon = recipe.Icon.Frame0(),
Icon = _spriteSystem.Frame0(recipe.Icon),
TooltipEnabled = true,
TooltipText = recipe.Description
TooltipText = recipe.Description,
};
}

View File

@@ -31,7 +31,7 @@ namespace Content.Client.Crayon.UI
private void PopulateCrayons()
{
var crayonDecals = _protoManager.EnumeratePrototypes<DecalPrototype>().Where(x => x.Tags.Contains("crayon"));
_menu?.Populate(crayonDecals);
_menu?.Populate(crayonDecals.ToList());
}
public override void OnProtoReload(PrototypesReloadedEventArgs args)
@@ -44,6 +44,16 @@ namespace Content.Client.Crayon.UI
PopulateCrayons();
}
protected override void ReceiveMessage(BoundUserInterfaceMessage message)
{
base.ReceiveMessage(message);
if (_menu is null || message is not CrayonUsedMessage crayonMessage)
return;
_menu.AdvanceState(crayonMessage.DrawnDecal);
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);

View File

@@ -1,14 +1,13 @@
<DefaultWindow xmlns="https://spacestation14.io"
Title="{Loc 'crayon-window-title'}"
MinSize="250 300"
SetSize="250 300">
MinSize="450 500"
SetSize="450 500">
<BoxContainer Orientation="Vertical">
<ColorSelectorSliders Name="ColorSelector" Visible="False" />
<LineEdit Name="Search" />
<LineEdit Name="Search" Margin="0 0 0 8" PlaceHolder="{Loc 'crayon-window-placeholder'}" />
<ScrollContainer VerticalExpand="True">
<GridContainer Name="Grid" Columns="6">
<!-- Crayon decals get added here by code -->
</GridContainer>
<BoxContainer Name="Grids" Orientation="Vertical">
</BoxContainer>
</ScrollContainer>
</BoxContainer>
</DefaultWindow>

View File

@@ -1,8 +1,10 @@
using System.Collections.Generic;
using System.Linq;
using Content.Client.Stylesheets;
using Content.Shared.Crayon;
using Content.Shared.Decals;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
@@ -18,7 +20,12 @@ namespace Content.Client.Crayon.UI
[GenerateTypedNameReferences]
public sealed partial class CrayonWindow : DefaultWindow
{
private Dictionary<string, Texture>? _decals;
[Dependency] private readonly IEntitySystemManager _entitySystem = default!;
private readonly SpriteSystem _spriteSystem = default!;
private Dictionary<string, List<(string Name, Texture Texture)>>? _decals;
private List<string>? _allDecals;
private string? _autoSelected;
private string? _selected;
private Color _color;
@@ -28,8 +35,10 @@ namespace Content.Client.Crayon.UI
public CrayonWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_spriteSystem = _entitySystem.GetEntitySystem<SpriteSystem>();
Search.OnTextChanged += _ => RefreshList();
Search.OnTextChanged += SearchChanged;
ColorSelector.OnColorChanged += SelectColor;
}
@@ -44,51 +53,94 @@ namespace Content.Client.Crayon.UI
private void RefreshList()
{
// Clear
Grid.DisposeAllChildren();
if (_decals == null)
Grids.DisposeAllChildren();
if (_decals == null || _allDecals == null)
return;
var filter = Search.Text;
foreach (var (decal, tex) in _decals)
var comma = filter.IndexOf(',');
var first = (comma == -1 ? filter : filter[..comma]).Trim();
var names = _decals.Keys.ToList();
names.Sort((a, b) => a == "random" ? 1 : b == "random" ? -1 : a.CompareTo(b));
if (_autoSelected != null && first != _autoSelected && _allDecals.Contains(first))
{
if (!decal.Contains(filter))
_selected = first;
_autoSelected = _selected;
OnSelected?.Invoke(_selected);
}
foreach (var categoryName in names)
{
var locName = Loc.GetString("crayon-category-" + categoryName);
var category = _decals[categoryName].Where(d => locName.Contains(first) || d.Name.Contains(first)).ToList();
if (category.Count == 0)
continue;
var button = new TextureButton()
var label = new Label
{
TextureNormal = tex,
Name = decal,
ToolTip = decal,
Modulate = _color,
Text = locName
};
button.OnPressed += ButtonOnPressed;
if (_selected == decal)
var grid = new GridContainer
{
var panelContainer = new PanelContainer()
Columns = 6,
Margin = new Thickness(0, 0, 0, 16)
};
Grids.AddChild(label);
Grids.AddChild(grid);
foreach (var (name, texture) in category)
{
var button = new TextureButton()
{
PanelOverride = new StyleBoxFlat()
{
BackgroundColor = StyleNano.ButtonColorDefault,
},
Children =
{
button,
},
TextureNormal = texture,
Name = name,
ToolTip = name,
Modulate = _color,
Scale = new System.Numerics.Vector2(2, 2)
};
Grid.AddChild(panelContainer);
}
else
{
Grid.AddChild(button);
button.OnPressed += ButtonOnPressed;
if (_selected == name)
{
var panelContainer = new PanelContainer()
{
PanelOverride = new StyleBoxFlat()
{
BackgroundColor = StyleNano.ButtonColorDefault,
},
Children =
{
button,
},
};
grid.AddChild(panelContainer);
}
else
{
grid.AddChild(button);
}
}
}
}
private void SearchChanged(LineEdit.LineEditEventArgs obj)
{
_autoSelected = ""; // Placeholder to kick off the auto-select in refreshlist()
RefreshList();
}
private void ButtonOnPressed(ButtonEventArgs obj)
{
if (obj.Button.Name == null) return;
_selected = obj.Button.Name;
_autoSelected = null;
OnSelected?.Invoke(_selected);
RefreshList();
}
@@ -107,12 +159,38 @@ namespace Content.Client.Crayon.UI
RefreshList();
}
public void Populate(IEnumerable<DecalPrototype> prototypes)
public void AdvanceState(string drawnDecal)
{
_decals = new Dictionary<string, Texture>();
var filter = Search.Text;
if (!filter.Contains(',') || !filter.Contains(drawnDecal))
return;
var first = filter[..filter.IndexOf(',')].Trim();
if (first.Equals(drawnDecal, StringComparison.InvariantCultureIgnoreCase))
{
Search.Text = filter[(filter.IndexOf(',') + 1)..].Trim();
_autoSelected = first;
}
RefreshList();
}
public void Populate(List<DecalPrototype> prototypes)
{
_decals = [];
_allDecals = [];
prototypes.Sort((a, b) => a.ID.CompareTo(b.ID));
foreach (var decalPrototype in prototypes)
{
_decals.Add(decalPrototype.ID, decalPrototype.Sprite.Frame0());
var category = "random";
if (decalPrototype.Tags.Count > 1 && decalPrototype.Tags[1].StartsWith("crayon-"))
category = decalPrototype.Tags[1].Replace("crayon-", "");
var list = _decals.GetOrNew(category);
list.Add((decalPrototype.ID, _spriteSystem.Frame0(decalPrototype.Sprite)));
_allDecals.Add(decalPrototype.ID);
}
RefreshList();

View File

@@ -279,7 +279,7 @@ public sealed class LobbyUIController : UIController, IOnStateEntered<LobbyState
_profileEditor.OnOpenGuidebook += _guide.OpenHelp;
_characterSetup = new CharacterSetupGui(EntityManager, _prototypeManager, _resourceCache, _preferencesManager, _profileEditor);
_characterSetup = new CharacterSetupGui(_profileEditor);
_characterSetup.CloseButton.OnPressed += _ =>
{

View File

@@ -2,6 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
xmlns:style="clr-namespace:Content.Client.Stylesheets"
xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"
VerticalExpand="True">
<Control>
<PanelContainer Name="BackgroundPanel" />
@@ -10,10 +11,15 @@
<Label Text="{Loc 'character-setup-gui-character-setup-label'}"
Margin="8 0 0 0" VAlign="Center"
StyleClasses="LabelHeadingBigger" />
<Button Name="StatsButton" HorizontalExpand="True"
Text="{Loc 'character-setup-gui-character-setup-stats-button'}"
StyleClasses="ButtonBig"
HorizontalAlignment="Right" />
<cc:CommandButton Name="AdminRemarksButton"
Command="adminremarks"
Text="{Loc 'character-setup-gui-character-setup-adminremarks-button'}"
StyleClasses="ButtonBig" />
<Button Name="RulesButton"
Text="{Loc 'character-setup-gui-character-setup-rules-button'}"
StyleClasses="ButtonBig"/>

View File

@@ -1,6 +1,7 @@
using Content.Client.Info;
using Content.Client.Info.PlaytimeStats;
using Content.Client.Resources;
using Content.Shared.CCVar;
using Content.Shared.Preferences;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
@@ -8,6 +9,7 @@ using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
namespace Content.Client.Lobby.UI
@@ -18,28 +20,23 @@ namespace Content.Client.Lobby.UI
[GenerateTypedNameReferences]
public sealed partial class CharacterSetupGui : Control
{
private readonly IClientPreferencesManager _preferencesManager;
private readonly IEntityManager _entManager;
private readonly IPrototypeManager _protomanager;
[Dependency] private readonly IClientPreferencesManager _preferencesManager = default!;
[Dependency] private readonly IEntityManager _entManager = default!;
[Dependency] private readonly IPrototypeManager _protomanager = default!;
[Dependency] private readonly IResourceCache _resourceCache = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
private readonly Button _createNewCharacterButton;
public event Action<int>? SelectCharacter;
public event Action<int>? DeleteCharacter;
public CharacterSetupGui(
IEntityManager entManager,
IPrototypeManager protoManager,
IResourceCache resourceCache,
IClientPreferencesManager preferencesManager,
HumanoidProfileEditor profileEditor)
public CharacterSetupGui(HumanoidProfileEditor profileEditor)
{
RobustXamlLoader.Load(this);
_preferencesManager = preferencesManager;
_entManager = entManager;
_protomanager = protoManager;
IoCManager.InjectDependencies(this);
var panelTex = resourceCache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png");
var panelTex = _resourceCache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png");
var back = new StyleBoxTexture
{
Texture = panelTex,
@@ -56,7 +53,7 @@ namespace Content.Client.Lobby.UI
_createNewCharacterButton.OnPressed += args =>
{
preferencesManager.CreateCharacter(HumanoidCharacterProfile.Random());
_preferencesManager.CreateCharacter(HumanoidCharacterProfile.Random());
ReloadCharacterPickers();
args.Event.Handle();
};
@@ -65,6 +62,8 @@ namespace Content.Client.Lobby.UI
RulesButton.OnPressed += _ => new RulesAndInfoWindow().Open();
StatsButton.OnPressed += _ => new PlaytimeStatsWindow().OpenCentered();
_cfg.OnValueChanged(CCVars.SeeOwnNotes, p => AdminRemarksButton.Visible = p, true);
}
/// <summary>

View File

@@ -2,7 +2,6 @@ using Content.Client.Message;
using Content.Client.UserInterface.Systems.EscapeMenu;
using Robust.Client.AutoGenerated;
using Robust.Client.Console;
using Robust.Client.State;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.XAML;

View File

@@ -1,7 +1,7 @@
using Content.Shared.Singularity.EntitySystems;
using Content.Shared.Singularity.Components;
namespace Content.Client.Singularity.EntitySystems;
namespace Content.Client.Singularity.Systems;
/// <summary>
/// The client-side version of <see cref="SharedEventHorizonSystem"/>.

View File

@@ -0,0 +1,12 @@
using Content.Shared.Singularity.EntitySystems;
using Content.Shared.Singularity.Components;
namespace Content.Client.Singularity.Systems;
/// <summary>
/// The client-side version of <see cref="SharedSingularityGeneratorSystem"/>.
/// Manages <see cref="SingularityGeneratorComponent"/>s.
/// Exists to make relevant signal handlers (ie: <see cref="SharedSingularityGeneratorSystem.OnEmagged"/>) work on the client.
/// </summary>
public sealed class SingularityGeneratorSystem : SharedSingularityGeneratorSystem
{}

View File

@@ -5,7 +5,7 @@ using Robust.Client.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.Utility;
namespace Content.Client.Singularity.EntitySystems;
namespace Content.Client.Singularity.Systems;
/// <summary>
/// The client-side version of <see cref="SharedSingularitySystem"/>.

View File

@@ -307,12 +307,6 @@ public sealed class StorageUIController : UIController, IOnSystemChanged<Storage
_entity.GetNetEntity(storageEnt),
new ItemStorageLocation(DraggingRotation, position)));
}
else
{
_entity.RaisePredictiveEvent(new StorageRemoveItemEvent(
_entity.GetNetEntity(draggingGhost.Entity),
_entity.GetNetEntity(storageEnt)));
}
_menuDragHelper.EndDrag();
_container?.BuildItemPieces();

View File

@@ -28,7 +28,8 @@ namespace Content.Server.Announcements
}
else
{
var message = string.Join(' ', new ArraySegment<string>(args, 1, args.Length-1));
// Explicit IEnumerable<string> due to overload ambiguity on .NET 9
var message = string.Join(' ', (IEnumerable<string>)new ArraySegment<string>(args, 1, args.Length-1));
chat.DispatchGlobalAnnouncement(message, args[0], colorOverride: Color.Gold);
}
shell.WriteLine("Sent!");

View File

@@ -184,7 +184,7 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem<AntagSelection
return;
var players = _playerManager.Sessions
.Where(x => GameTicker.PlayerGameStatuses[x.UserId] == PlayerGameStatus.JoinedGame)
.Where(x => GameTicker.PlayerGameStatuses.TryGetValue(x.UserId, out var status) && status == PlayerGameStatus.JoinedGame)
.ToList();
ChooseAntags((uid, component), players, midround: true);

View File

@@ -1,6 +1,6 @@
using System.Globalization;
using Content.Server.Chat.Managers;
using Content.Server.Chat.Systems;
using Content.Server.GameTicking;
using Content.Server.Ghost;
using Content.Server.Hands.Systems;
using Content.Server.Inventory;
@@ -14,6 +14,7 @@ using Content.Shared.Bed.Cryostorage;
using Content.Shared.Chat;
using Content.Shared.Climbing.Systems;
using Content.Shared.Database;
using Content.Shared.GameTicking;
using Content.Shared.Hands.Components;
using Content.Shared.Mind.Components;
using Content.Shared.StationRecords;
@@ -26,7 +27,6 @@ using Robust.Shared.Containers;
using Robust.Shared.Enums;
using Robust.Shared.Network;
using Robust.Shared.Player;
using System.Globalization;
namespace Content.Server.Bed.Cryostorage;

View File

@@ -38,6 +38,7 @@ public sealed class SeedExtractorSystem : EntitySystem
args.User, PopupType.Medium);
QueueDel(args.Used);
args.Handled = true;
var amount = _random.Next(seedExtractor.BaseMinSeeds, seedExtractor.BaseMaxSeeds + 1);
var coords = Transform(uid).Coordinates;

View File

@@ -424,7 +424,7 @@ public record struct PriceCalculationEvent()
[ByRefEvent]
public record struct EstimatedPriceCalculationEvent()
{
public EntityPrototype Prototype;
public required EntityPrototype Prototype;
/// <summary>
/// The total price of the entity.

View File

@@ -82,6 +82,8 @@ public sealed class CrayonSystem : SharedCrayonSystem
if (component.DeleteEmpty && component.Charges <= 0)
UseUpCrayon(uid, args.User);
else
_uiSystem.ServerSendUiMessage(uid, SharedCrayonComponent.CrayonUiKey.Key, new CrayonUsedMessage(component.SelectedState));
}
private void OnCrayonUse(EntityUid uid, CrayonComponent component, UseInHandEvent args)

View File

@@ -184,6 +184,6 @@ namespace Content.Server.GameTicking
=> UserHasJoinedGame(session.UserId);
public bool UserHasJoinedGame(NetUserId userId)
=> PlayerGameStatuses[userId] == PlayerGameStatus.JoinedGame;
=> PlayerGameStatuses.TryGetValue(userId, out var status) && status == PlayerGameStatus.JoinedGame;
}
}

View File

@@ -7,12 +7,12 @@ using Content.Server.Spawners.Components;
using Content.Server.Speech.Components;
using Content.Server.Station.Components;
using Content.Shared.Database;
using Content.Shared.GameTicking;
using Content.Shared.Mind;
using Content.Shared.Players;
using Content.Shared.Preferences;
using Content.Shared.Roles;
using Content.Shared.Roles.Jobs;
using JetBrains.Annotations;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Network;
@@ -455,71 +455,4 @@ namespace Content.Server.GameTicking
#endregion
}
/// <summary>
/// Event raised broadcast before a player is spawned by the GameTicker.
/// You can use this event to spawn a player off-station on late-join but also at round start.
/// When this event is handled, the GameTicker will not perform its own player-spawning logic.
/// </summary>
[PublicAPI]
public sealed class PlayerBeforeSpawnEvent : HandledEntityEventArgs
{
public ICommonSession Player { get; }
public HumanoidCharacterProfile Profile { get; }
public string? JobId { get; }
public bool LateJoin { get; }
public EntityUid Station { get; }
public PlayerBeforeSpawnEvent(ICommonSession player,
HumanoidCharacterProfile profile,
string? jobId,
bool lateJoin,
EntityUid station)
{
Player = player;
Profile = profile;
JobId = jobId;
LateJoin = lateJoin;
Station = station;
}
}
/// <summary>
/// Event raised both directed and broadcast when a player has been spawned by the GameTicker.
/// You can use this to handle people late-joining, or to handle people being spawned at round start.
/// Can be used to give random players a role, modify their equipment, etc.
/// </summary>
[PublicAPI]
public sealed class PlayerSpawnCompleteEvent : EntityEventArgs
{
public EntityUid Mob { get; }
public ICommonSession Player { get; }
public string? JobId { get; }
public bool LateJoin { get; }
public bool Silent { get; }
public EntityUid Station { get; }
public HumanoidCharacterProfile Profile { get; }
// Ex. If this is the 27th person to join, this will be 27.
public int JoinOrder { get; }
public PlayerSpawnCompleteEvent(EntityUid mob,
ICommonSession player,
string? jobId,
bool lateJoin,
bool silent,
int joinOrder,
EntityUid station,
HumanoidCharacterProfile profile)
{
Mob = mob;
Player = player;
JobId = jobId;
LateJoin = lateJoin;
Silent = silent;
Station = station;
Profile = profile;
JoinOrder = joinOrder;
}
}
}

View File

@@ -6,6 +6,7 @@ using Content.Server.Mind;
using Content.Server.Points;
using Content.Server.RoundEnd;
using Content.Server.Station.Systems;
using Content.Shared.GameTicking;
using Content.Shared.GameTicking.Components;
using Content.Shared.Points;
using Content.Shared.Storage;

View File

@@ -34,10 +34,11 @@ public sealed class GatewayGeneratorSystem : EntitySystem
[Dependency] private readonly GatewaySystem _gateway = default!;
[Dependency] private readonly MetaDataSystem _metadata = default!;
[Dependency] private readonly SharedMapSystem _maps = default!;
[Dependency] private readonly SharedSalvageSystem _salvage = default!;
[Dependency] private readonly TileSystem _tile = default!;
[ValidatePrototypeId<DatasetPrototype>]
private const string PlanetNames = "names_borer";
[ValidatePrototypeId<LocalizedDatasetPrototype>]
private const string PlanetNames = "NamesBorer";
// TODO:
// Fix shader some more
@@ -102,7 +103,7 @@ public sealed class GatewayGeneratorSystem : EntitySystem
var mapId = _mapManager.CreateMap();
var mapUid = _mapManager.GetMapEntityId(mapId);
var gatewayName = SharedSalvageSystem.GetFTLName(_protoManager.Index<DatasetPrototype>(PlanetNames), seed);
var gatewayName = _salvage.GetFTLName(_protoManager.Index<LocalizedDatasetPrototype>(PlanetNames), seed);
_metadata.SetEntityName(mapUid, gatewayName);
var origin = new Vector2i(random.Next(-MaxOffset, MaxOffset), random.Next(-MaxOffset, MaxOffset));

View File

@@ -4,7 +4,6 @@ using Content.Server.DeviceNetwork;
using Content.Server.DeviceNetwork.Components;
using Content.Server.DeviceNetwork.Systems;
using Content.Server.Emp;
using Content.Server.GameTicking;
using Content.Server.Medical.CrewMonitoring;
using Content.Server.Popups;
using Content.Server.Station.Systems;
@@ -14,8 +13,10 @@ using Content.Shared.Damage;
using Content.Shared.DeviceNetwork;
using Content.Shared.DoAfter;
using Content.Shared.Examine;
using Content.Shared.GameTicking;
using Content.Shared.Interaction;
using Content.Shared.Medical.SuitSensor;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
using Content.Shared.Verbs;
@@ -383,7 +384,7 @@ public sealed class SuitSensorSystem : EntitySystem
// Get mob total damage crit threshold
int? totalDamageThreshold = null;
if (_mobThresholdSystem.TryGetThresholdForState(sensor.User.Value, Shared.Mobs.MobState.Critical, out var critThreshold))
if (_mobThresholdSystem.TryGetThresholdForState(sensor.User.Value, MobState.Critical, out var critThreshold))
totalDamageThreshold = critThreshold.Value.Int();
// finally, form suit sensor status

View File

@@ -11,8 +11,8 @@ public sealed partial class PathfindingSystem
/// </summary>
public record struct BreadthPathArgs()
{
public Vector2i Start;
public List<Vector2i> Ends;
public required Vector2i Start;
public required List<Vector2i> Ends;
public bool Diagonals = false;

View File

@@ -19,7 +19,7 @@ public sealed partial class PathfindingSystem
public List<Vector2i> Points = new();
public List<Vector2i> Path = new();
public Dictionary<Vector2i, Vector2i> CameFrom;
public Dictionary<Vector2i, Vector2i>? CameFrom;
}
public record struct SplinePathArgs(SimplePathArgs Args)

View File

@@ -84,6 +84,6 @@ public sealed partial class PathfindingSystem
public float MaxWiden = 7f;
public List<Vector2i> Path;
public required List<Vector2i> Path;
}
}

View File

@@ -44,7 +44,7 @@ namespace Content.Server.Nutrition.EntitySystems
public (bool Success, bool Handled) TryUseUtensil(EntityUid user, EntityUid target, Entity<UtensilComponent> utensil)
{
if (!EntityManager.TryGetComponent(target, out FoodComponent? food))
return (false, true);
return (false, false);
//Prevents food usage with a wrong utensil
if ((food.Utensil & utensil.Comp.Types) == 0)

View File

@@ -53,7 +53,7 @@ public sealed class KillPersonConditionSystem : EntitySystem
return;
// no other humans to kill
var allHumans = _mind.GetAliveHumansExcept(args.MindId);
var allHumans = _mind.GetAliveHumans(args.MindId);
if (allHumans.Count == 0)
{
args.Cancelled = true;
@@ -77,14 +77,14 @@ public sealed class KillPersonConditionSystem : EntitySystem
return;
// no other humans to kill
var allHumans = _mind.GetAliveHumansExcept(args.MindId);
var allHumans = _mind.GetAliveHumans(args.MindId);
if (allHumans.Count == 0)
{
args.Cancelled = true;
return;
}
var allHeads = new List<EntityUid>();
var allHeads = new HashSet<Entity<MindComponent>>();
foreach (var person in allHumans)
{
if (TryComp<MindComponent>(person, out var mind) && mind.OwnedEntity is { } ent && HasComp<CommandStaffComponent>(ent))

View File

@@ -314,6 +314,9 @@ public sealed class MoverController : SharedMoverController
var linearInput = Vector2.Zero;
var brakeInput = 0f;
var angularInput = 0f;
var linearCount = 0;
var brakeCount = 0;
var angularCount = 0;
foreach (var (pilotUid, pilot, _, consoleXform) in pilots)
{
@@ -322,24 +325,27 @@ public sealed class MoverController : SharedMoverController
if (brakes > 0f)
{
brakeInput += brakes;
brakeCount++;
}
if (strafe.Length() > 0f)
{
var offsetRotation = consoleXform.LocalRotation;
linearInput += offsetRotation.RotateVec(strafe);
linearCount++;
}
if (rotation != 0f)
{
angularInput += rotation;
angularCount++;
}
}
var count = pilots.Count;
linearInput /= count;
angularInput /= count;
brakeInput /= count;
// Don't slow down the shuttle if there's someone just looking at the console
linearInput /= Math.Max(1, linearCount);
angularInput /= Math.Max(1, angularCount);
brakeInput /= Math.Max(1, brakeCount);
// Handle shuttle movement
if (brakeInput > 0f)

View File

@@ -28,7 +28,7 @@ public sealed partial class SalvageSystem
var mission = GetMission(_prototypeManager.Index<SalvageDifficultyPrototype>(missionparams.Difficulty), missionparams.Seed);
data.NextOffer = _timing.CurTime + mission.Duration + TimeSpan.FromSeconds(1);
_labelSystem.Label(cdUid, GetFTLName(_prototypeManager.Index<DatasetPrototype>("names_borer"), missionparams.Seed));
_labelSystem.Label(cdUid, GetFTLName(_prototypeManager.Index<LocalizedDatasetPrototype>("NamesBorer"), missionparams.Seed));
_audio.PlayPvs(component.PrintSound, uid);
UpdateConsoles((station.Value, data));

View File

@@ -104,7 +104,9 @@ public sealed class SpawnSalvageMissionJob : Job<bool>
destComp.BeaconsOnly = true;
destComp.RequireCoordinateDisk = true;
destComp.Enabled = true;
_metaData.SetEntityName(mapUid, SharedSalvageSystem.GetFTLName(_prototypeManager.Index<DatasetPrototype>("names_borer"), _missionParams.Seed));
_metaData.SetEntityName(
mapUid,
_entManager.System<SharedSalvageSystem>().GetFTLName(_prototypeManager.Index<LocalizedDatasetPrototype>("NamesBorer"), _missionParams.Seed));
_entManager.AddComponent<FTLBeaconComponent>(mapUid);
// Saving the mission mapUid to a CD is made optional, in case one is somehow made in a process without a CD entity

View File

@@ -32,7 +32,7 @@ public interface IGridSpawnGroup
public float MaximumDistance { get; }
/// <inheritdoc />
public ProtoId<DatasetPrototype>? NameDataset { get; }
public ProtoId<LocalizedDatasetPrototype>? NameDataset { get; }
/// <inheritdoc />
int MinCount { get; set; }
@@ -75,7 +75,7 @@ public sealed class DungeonSpawnGroup : IGridSpawnGroup
public float MaximumDistance { get; }
/// <inheritdoc />
public ProtoId<DatasetPrototype>? NameDataset { get; }
public ProtoId<LocalizedDatasetPrototype>? NameDataset { get; }
/// <inheritdoc />
public int MinCount { get; set; } = 1;
@@ -106,7 +106,7 @@ public sealed class GridSpawnGroup : IGridSpawnGroup
/// <inheritdoc />
public float MaximumDistance { get; }
public ProtoId<DatasetPrototype>? NameDataset { get; }
public ProtoId<LocalizedDatasetPrototype>? NameDataset { get; }
public int MinCount { get; set; } = 1;
public int MaxCount { get; set; } = 1;
public ComponentRegistry AddComponents { get; set; } = new();

View File

@@ -19,10 +19,10 @@ using Content.Shared.Administration;
using Content.Shared.CCVar;
using Content.Shared.Damage.Components;
using Content.Shared.DeviceNetwork;
using Content.Shared.GameTicking;
using Content.Shared.Mobs.Components;
using Content.Shared.Movement.Components;
using Content.Shared.Parallax.Biomes;
using Content.Shared.Preferences;
using Content.Shared.Salvage;
using Content.Shared.Shuttles.Components;
using Content.Shared.Tiles;

View File

@@ -208,7 +208,7 @@ public sealed partial class ShuttleSystem
if (_protoManager.TryIndex(group.NameDataset, out var dataset))
{
_metadata.SetEntityName(spawned, SharedSalvageSystem.GetFTLName(dataset, _random.Next()));
_metadata.SetEntityName(spawned, _salvage.GetFTLName(dataset, _random.Next()));
}
if (group.Hide)

View File

@@ -8,6 +8,7 @@ using Content.Server.Station.Systems;
using Content.Server.Stunnable;
using Content.Shared.GameTicking;
using Content.Shared.Mobs.Systems;
using Content.Shared.Salvage;
using Content.Shared.Shuttles.Systems;
using Content.Shared.Throwing;
using JetBrains.Annotations;
@@ -51,6 +52,7 @@ public sealed partial class ShuttleSystem : SharedShuttleSystem
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly SharedSalvageSystem _salvage = default!;
[Dependency] private readonly ShuttleConsoleSystem _console = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly StunSystem _stuns = default!;

View File

@@ -1,7 +1,6 @@
using System.Linq;
using Content.Server.Administration;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking;
using Content.Server.Radio.Components;
using Content.Server.Roles;
using Content.Server.Station.Systems;
@@ -9,6 +8,7 @@ using Content.Shared.Administration;
using Content.Shared.Chat;
using Content.Shared.Emag.Components;
using Content.Shared.Emag.Systems;
using Content.Shared.GameTicking;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
using Content.Shared.Roles;
@@ -17,6 +17,7 @@ using Content.Shared.Silicons.Laws.Components;
using Content.Shared.Stunnable;
using Content.Shared.Wires;
using Robust.Server.GameObjects;
using Robust.Shared.Audio;
using Robust.Shared.Containers;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;

View File

@@ -1,33 +0,0 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Content.Server.Singularity.EntitySystems;
namespace Content.Server.Singularity.Components;
[RegisterComponent]
public sealed partial class SingularityGeneratorComponent : Component
{
/// <summary>
/// The amount of power this generator has accumulated.
/// If you want to set this use <see cref="SingularityGeneratorSystem.SetPower"/>
/// </summary>
[DataField("power")]
[Access(friends:typeof(SingularityGeneratorSystem))]
public float Power = 0;
/// <summary>
/// The power threshold at which this generator will spawn a singularity.
/// If you want to set this use <see cref="SingularityGeneratorSystem.SetThreshold"/>
/// </summary>
[DataField("threshold")]
[Access(friends:typeof(SingularityGeneratorSystem))]
public float Threshold = 16;
/// <summary>
/// The prototype ID used to spawn a singularity.
/// </summary>
[DataField("spawnId", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
[ViewVariables(VVAccess.ReadWrite)]
public string? SpawnPrototype = "Singularity";
}

View File

@@ -1,14 +1,23 @@
using Content.Server.ParticleAccelerator.Components;
using Content.Server.Singularity.Components;
using Content.Shared.Popups;
using Content.Shared.Singularity.Components;
using Content.Shared.Singularity.EntitySystems;
using Robust.Server.GameObjects;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Events;
using Robust.Shared.Timing;
namespace Content.Server.Singularity.EntitySystems;
public sealed class SingularityGeneratorSystem : EntitySystem
public sealed class SingularityGeneratorSystem : SharedSingularityGeneratorSystem
{
#region Dependencies
[Dependency] private readonly IViewVariablesManager _vvm = default!;
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
[Dependency] private readonly PhysicsSystem _physics = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly MetaDataSystem _metadata = default!;
#endregion Dependencies
public override void Initialize()
@@ -100,11 +109,37 @@ public sealed class SingularityGeneratorSystem : EntitySystem
/// <param name="args">The state of the beginning of the collision.</param>
private void HandleParticleCollide(EntityUid uid, ParticleProjectileComponent component, ref StartCollideEvent args)
{
if (EntityManager.TryGetComponent<SingularityGeneratorComponent>(args.OtherEntity, out var singularityGeneratorComponent))
if (!EntityManager.TryGetComponent<SingularityGeneratorComponent>(args.OtherEntity, out var generatorComp))
return;
if (_timing.CurTime < _metadata.GetPauseTime(uid) + generatorComp.NextFailsafe && !generatorComp.FailsafeDisabled)
{
EntityManager.QueueDeleteEntity(uid);
return;
}
var contained = true;
if (!generatorComp.FailsafeDisabled)
{
var transform = Transform(args.OtherEntity);
var directions = Enum.GetValues<Direction>().Length;
for (var i = 0; i < directions - 1; i += 2) // Skip every other direction, checking only cardinals
{
if (!CheckContainmentField((Direction)i, new Entity<SingularityGeneratorComponent>(args.OtherEntity, generatorComp), transform))
contained = false;
}
}
if (!contained && !generatorComp.FailsafeDisabled)
{
generatorComp.NextFailsafe = _timing.CurTime + generatorComp.FailsafeCooldown;
PopupSystem.PopupEntity(Loc.GetString("comp-generator-failsafe", ("target", args.OtherEntity)), args.OtherEntity, PopupType.LargeCaution);
}
else
{
SetPower(
args.OtherEntity,
singularityGeneratorComponent.Power + component.State switch
generatorComp.Power + component.State switch
{
ParticleAcceleratorPowerState.Standby => 0,
ParticleAcceleratorPowerState.Level0 => 1,
@@ -113,10 +148,46 @@ public sealed class SingularityGeneratorSystem : EntitySystem
ParticleAcceleratorPowerState.Level3 => 8,
_ => 0
},
singularityGeneratorComponent
generatorComp
);
EntityManager.QueueDeleteEntity(uid);
}
EntityManager.QueueDeleteEntity(uid);
}
#endregion Event Handlers
/// <summary>
/// Checks whether there's a containment field in a given direction away from the generator
/// </summary>
/// <param name="transform">The transform component of the singularity generator.</param>
/// <remarks>Mostly copied from <see cref="ContainmentFieldGeneratorSystem"/> </remarks>
private bool CheckContainmentField(Direction dir, Entity<SingularityGeneratorComponent> generator, TransformComponent transform)
{
var component = generator.Comp;
var (worldPosition, worldRotation) = _transformSystem.GetWorldPositionRotation(transform);
var dirRad = dir.ToAngle() + worldRotation;
var ray = new CollisionRay(worldPosition, dirRad.ToVec(), component.CollisionMask);
var rayCastResults = _physics.IntersectRay(transform.MapID, ray, component.FailsafeDistance, generator, false);
var genQuery = GetEntityQuery<ContainmentFieldComponent>();
RayCastResults? closestResult = null;
foreach (var result in rayCastResults)
{
if (genQuery.HasComponent(result.HitEntity))
closestResult = result;
break;
}
if (closestResult == null)
return false;
var ent = closestResult.Value.HitEntity;
// Check that the field can't be moved. The fields' transform parenting is weird, so skip that
return TryComp<PhysicsComponent>(ent, out var collidableComponent) && collidableComponent.BodyType == BodyType.Static;
}
}

View File

@@ -1,9 +1,8 @@
using System.Diagnostics.CodeAnalysis;
using System.IO;
using Content.Server.Access.Systems;
using Content.Server.Forensics;
using Content.Server.GameTicking;
using Content.Shared.Access.Components;
using Content.Shared.GameTicking;
using Content.Shared.Inventory;
using Content.Shared.PDA;
using Content.Shared.Preferences;

View File

@@ -256,6 +256,11 @@ public sealed partial class StoreSystem
RaiseLocalEvent(buyer, listing.ProductEvent);
}
if (listing.DisableRefund)
{
component.RefundAllowed = false;
}
//log dat shit.
_admin.Add(LogType.StorePurchase,
LogImpact.Low,

View File

@@ -1,11 +1,10 @@
using Content.Server.GameTicking;
using Content.Shared.GameTicking;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Roles;
using Content.Shared.Traits;
using Content.Shared.Whitelist;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager;
namespace Content.Server.Traits;

View File

@@ -33,6 +33,12 @@ public sealed partial class ToggleClothingComponent : Component
/// </summary>
[DataField]
public bool DisableOnUnequip;
/// <summary>
/// If true, the clothes must equip for adding action.
/// </summary>
[DataField]
public bool MustEquip = true;
}
/// <summary>

View File

@@ -39,8 +39,12 @@ public sealed class ToggleClothingSystem : EntitySystem
private void OnGetActions(Entity<ToggleClothingComponent> ent, ref GetItemActionsEvent args)
{
if (args.InHands && ent.Comp.MustEquip)
return;
var ev = new ToggleClothingCheckEvent(args.User);
RaiseLocalEvent(ent, ref ev);
if (!ev.Cancelled)
args.AddAction(ent.Comp.ActionEntity);
}

View File

@@ -3,12 +3,23 @@ using Robust.Shared.Serialization;
namespace Content.Shared.Crayon
{
/// <summary>
/// Component holding the state of a crayon-like component
/// </summary>
[NetworkedComponent, ComponentProtoName("Crayon"), Access(typeof(SharedCrayonSystem))]
public abstract partial class SharedCrayonComponent : Component
{
/// <summary>
/// The ID of currently selected decal prototype that will be placed when the crayon is used
/// </summary>
public string SelectedState { get; set; } = string.Empty;
[DataField("color")] public Color Color;
/// <summary>
/// Color with which the crayon will draw
/// </summary>
[DataField("color")]
public Color Color;
[Serializable, NetSerializable]
public enum CrayonUiKey : byte
@@ -17,6 +28,9 @@ namespace Content.Shared.Crayon
}
}
/// <summary>
/// Used by the client to notify the server about the selected decal ID
/// </summary>
[Serializable, NetSerializable]
public sealed class CrayonSelectMessage : BoundUserInterfaceMessage
{
@@ -27,6 +41,9 @@ namespace Content.Shared.Crayon
}
}
/// <summary>
/// Sets the color of the crayon, used by Rainbow Crayon
/// </summary>
[Serializable, NetSerializable]
public sealed class CrayonColorMessage : BoundUserInterfaceMessage
{
@@ -37,13 +54,25 @@ namespace Content.Shared.Crayon
}
}
/// <summary>
/// Server to CLIENT. Notifies the BUI that a decal with given ID has been drawn.
/// Allows the client UI to advance forward in the client-only ephemeral queue,
/// preventing the crayon from becoming a magic text storage device.
/// </summary>
[Serializable, NetSerializable]
public enum CrayonVisuals
public sealed class CrayonUsedMessage : BoundUserInterfaceMessage
{
State,
Color
public readonly string DrawnDecal;
public CrayonUsedMessage(string drawn)
{
DrawnDecal = drawn;
}
}
/// <summary>
/// Component state, describes how many charges are left in the crayon in the near-hand UI
/// </summary>
[Serializable, NetSerializable]
public sealed class CrayonComponentState : ComponentState
{
@@ -60,10 +89,17 @@ namespace Content.Shared.Crayon
Capacity = capacity;
}
}
/// <summary>
/// The state of the crayon UI as sent by the server
/// </summary>
[Serializable, NetSerializable]
public sealed class CrayonBoundUserInterfaceState : BoundUserInterfaceState
{
public string Selected;
/// <summary>
/// Whether or not the color can be selected
/// </summary>
public bool SelectableColor;
public Color Color;

View File

@@ -61,6 +61,12 @@ public sealed class DamageExamineSystem : EntitySystem
}
else
{
if (damageSpecifier.GetTotal() == FixedPoint2.Zero && !damageSpecifier.AnyPositive())
{
msg.AddMarkupOrThrow(Loc.GetString("damage-none"));
return msg;
}
msg.AddMarkupOrThrow(Loc.GetString("damage-examine-type", ("type", type)));
}

View File

@@ -96,6 +96,13 @@ public sealed class EmagSystem : EntitySystem
}
}
/// <summary>
/// Shows a popup to emag user (client side only!) and adds <see cref="EmaggedComponent"/> to the entity when handled
/// </summary>
/// <param name="UserUid">Emag user</param>
/// <param name="Handled">Did the emagging succeed? Causes a user-only popup to show on client side</param>
/// <param name="Repeatable">Can the entity be emagged more than once? Prevents adding of <see cref="EmaggedComponent"/></param>
/// <remarks>Needs to be handled in shared/client, not just the server, to actually show the emagging popup</remarks>
[ByRefEvent]
public record struct GotEmaggedEvent(EntityUid UserUid, bool Handled = false, bool Repeatable = false);

View File

@@ -66,5 +66,5 @@ public record struct GenerateDnaEvent()
/// <summary>
/// The generated DNA.
/// </summary>
public string DNA;
public required string DNA;
}

View File

@@ -0,0 +1,33 @@
using Content.Shared.Preferences;
using JetBrains.Annotations;
using Robust.Shared.Player;
namespace Content.Shared.GameTicking;
/// <summary>
/// Event raised broadcast before a player is spawned by the GameTicker.
/// You can use this event to spawn a player off-station on late-join but also at round start.
/// When this event is handled, the GameTicker will not perform its own player-spawning logic.
/// </summary>
[PublicAPI]
public sealed class PlayerBeforeSpawnEvent : HandledEntityEventArgs
{
public ICommonSession Player { get; }
public HumanoidCharacterProfile Profile { get; }
public string? JobId { get; }
public bool LateJoin { get; }
public EntityUid Station { get; }
public PlayerBeforeSpawnEvent(ICommonSession player,
HumanoidCharacterProfile profile,
string? jobId,
bool lateJoin,
EntityUid station)
{
Player = player;
Profile = profile;
JobId = jobId;
LateJoin = lateJoin;
Station = station;
}
}

View File

@@ -0,0 +1,44 @@
using Content.Shared.Preferences;
using JetBrains.Annotations;
using Robust.Shared.Player;
namespace Content.Shared.GameTicking;
/// <summary>
/// Event raised both directed and broadcast when a player has been spawned by the GameTicker.
/// You can use this to handle people late-joining, or to handle people being spawned at round start.
/// Can be used to give random players a role, modify their equipment, etc.
/// </summary>
[PublicAPI]
public sealed class PlayerSpawnCompleteEvent : EntityEventArgs
{
public EntityUid Mob { get; }
public ICommonSession Player { get; }
public string? JobId { get; }
public bool LateJoin { get; }
public bool Silent { get; }
public EntityUid Station { get; }
public HumanoidCharacterProfile Profile { get; }
// Ex. If this is the 27th person to join, this will be 27.
public int JoinOrder { get; }
public PlayerSpawnCompleteEvent(EntityUid mob,
ICommonSession player,
string? jobId,
bool lateJoin,
bool silent,
int joinOrder,
EntityUid station,
HumanoidCharacterProfile profile)
{
Mob = mob;
Player = player;
JobId = jobId;
LateJoin = lateJoin;
Silent = silent;
Station = station;
Profile = profile;
JoinOrder = joinOrder;
}
}

View File

@@ -32,6 +32,18 @@ public sealed partial class ItemToggleComponent : Component
[DataField]
public bool OnUse = true;
/// <summary>
/// The localized text to display in the verb to activate.
/// </summary>
[DataField]
public string VerbToggleOn = "item-toggle-activate";
/// <summary>
/// The localized text to display in the verb to de-activate.
/// </summary>
[DataField]
public string VerbToggleOff = "item-toggle-deactivate";
/// <summary>
/// Whether the item's toggle can be predicted by the client.
/// </summary>

View File

@@ -1,18 +0,0 @@
using Content.Shared.Item.ItemToggle;
using Robust.Shared.GameStates;
namespace Content.Shared.Item.ItemToggle.Components;
/// <summary>
/// Adds a verb for toggling something, requires <see cref="ItemToggleComponent"/>.
/// </summary>
[RegisterComponent, NetworkedComponent, Access(typeof(ToggleVerbSystem))]
public sealed partial class ToggleVerbComponent : Component
{
/// <summary>
/// Text the verb will have.
/// Gets passed "entity" as the entity's identity string.
/// </summary>
[DataField(required: true)]
public LocId Text = string.Empty;
}

View File

@@ -78,7 +78,7 @@ public sealed class ItemToggleSystem : EntitySystem
args.Verbs.Add(new ActivationVerb()
{
Text = !ent.Comp.Activated ? Loc.GetString("item-toggle-activate") : Loc.GetString("item-toggle-deactivate"),
Text = !ent.Comp.Activated ? Loc.GetString(ent.Comp.VerbToggleOn) : Loc.GetString(ent.Comp.VerbToggleOff),
Act = () =>
{
Toggle((ent.Owner, ent.Comp), user, predicted: ent.Comp.Predictable);

View File

@@ -1,34 +0,0 @@
using Content.Shared.IdentityManagement;
using Content.Shared.Item.ItemToggle.Components;
using Content.Shared.Verbs;
namespace Content.Shared.Item.ItemToggle;
/// <summary>
/// Adds a verb for toggling something with <see cref="ToggleVerbComponent"/>.
/// </summary>
public sealed class ToggleVerbSystem : EntitySystem
{
[Dependency] private readonly ItemToggleSystem _toggle = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ToggleVerbComponent, GetVerbsEvent<ActivationVerb>>(OnGetVerbs);
}
private void OnGetVerbs(Entity<ToggleVerbComponent> ent, ref GetVerbsEvent<ActivationVerb> args)
{
if (!args.CanAccess || !args.CanInteract)
return;
var name = Identity.Entity(ent, EntityManager);
var user = args.User;
args.Verbs.Add(new ActivationVerb()
{
Text = Loc.GetString(ent.Comp.Text, ("entity", name)),
Act = () => _toggle.Toggle(ent.Owner, user)
});
}
}

View File

@@ -0,0 +1,23 @@
using Content.Shared.Actions;
using Content.Shared.Storage;
using Robust.Shared.Audio;
namespace Content.Shared.Magic.Events;
public sealed partial class RandomGlobalSpawnSpellEvent : InstantActionEvent, ISpeakSpell
{
/// <summary>
/// The list of prototypes this spell can spawn, will select one randomly
/// </summary>
[DataField]
public List<EntitySpawnEntry> Spawns = new();
/// <summary>
/// Sound that will play globally when cast
/// </summary>
[DataField]
public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/Magic/staff_animation.ogg");
[DataField]
public string? Speech { get; private set; }
}

View File

@@ -1,4 +1,4 @@
using System.Numerics;
using System.Numerics;
using Content.Shared.Actions;
using Content.Shared.Body.Components;
using Content.Shared.Body.Systems;
@@ -7,12 +7,17 @@ using Content.Shared.Doors.Components;
using Content.Shared.Doors.Systems;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Humanoid;
using Content.Shared.Interaction;
using Content.Shared.Inventory;
using Content.Shared.Lock;
using Content.Shared.Magic.Components;
using Content.Shared.Magic.Events;
using Content.Shared.Maps;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
using Content.Shared.Physics;
using Content.Shared.Popups;
using Content.Shared.Speech.Muting;
@@ -20,6 +25,7 @@ using Content.Shared.Storage;
using Content.Shared.Tag;
using Content.Shared.Weapons.Ranged.Components;
using Content.Shared.Weapons.Ranged.Systems;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Network;
@@ -53,6 +59,9 @@ public abstract class SharedMagicSystem : EntitySystem
[Dependency] private readonly LockSystem _lock = default!;
[Dependency] private readonly SharedHandsSystem _hands = default!;
[Dependency] private readonly TagSystem _tag = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedMindSystem _mind = default!;
public override void Initialize()
{
@@ -67,6 +76,7 @@ public abstract class SharedMagicSystem : EntitySystem
SubscribeLocalEvent<SmiteSpellEvent>(OnSmiteSpell);
SubscribeLocalEvent<KnockSpellEvent>(OnKnockSpell);
SubscribeLocalEvent<ChargeSpellEvent>(OnChargeSpell);
SubscribeLocalEvent<RandomGlobalSpawnSpellEvent>(OnRandomGlobalSpawnSpell);
// Spell wishlist
// A wishlish of spells that I'd like to implement or planning on implementing in a future PR
@@ -501,6 +511,37 @@ public abstract class SharedMagicSystem : EntitySystem
_gunSystem.UpdateBasicEntityAmmoCount(wand.Value, basicAmmoComp.Count.Value + ev.Charge, basicAmmoComp);
}
// End Charge Spells
#endregion
#region Global Spells
private void OnRandomGlobalSpawnSpell(RandomGlobalSpawnSpellEvent ev)
{
if (!_net.IsServer || ev.Handled || !PassesSpellPrerequisites(ev.Action, ev.Performer) || ev.Spawns is not { } spawns)
return;
ev.Handled = true;
Speak(ev);
var allHumans = _mind.GetAliveHumans();
foreach (var human in allHumans)
{
if (!human.Comp.OwnedEntity.HasValue)
continue;
var ent = human.Comp.OwnedEntity.Value;
var mapCoords = _transform.GetMapCoordinates(ent);
foreach (var spawn in EntitySpawnCollection.GetSpawns(spawns, _random))
{
var spawned = Spawn(spawn, mapCoords);
_hands.PickupOrDrop(ent, spawned);
}
}
_audio.PlayGlobal(ev.Sound, ev.Performer);
}
#endregion
// End Spells
#endregion

View File

@@ -532,22 +532,19 @@ public abstract class SharedMindSystem : EntitySystem
/// <summary>
/// Returns a list of every living humanoid player's minds, except for a single one which is exluded.
/// </summary>
public List<EntityUid> GetAliveHumansExcept(EntityUid exclude)
public HashSet<Entity<MindComponent>> GetAliveHumans(EntityUid? exclude = null)
{
var mindQuery = EntityQuery<MindComponent>();
var allHumans = new List<EntityUid>();
var allHumans = new HashSet<Entity<MindComponent>>();
// HumanoidAppearanceComponent is used to prevent mice, pAIs, etc from being chosen
var query = EntityQueryEnumerator<MindContainerComponent, MobStateComponent, HumanoidAppearanceComponent>();
while (query.MoveNext(out var uid, out var mc, out var mobState, out _))
var query = EntityQueryEnumerator<MobStateComponent, HumanoidAppearanceComponent>();
while (query.MoveNext(out var uid, out var mobState, out _))
{
// the player needs to have a mind and not be the excluded one
if (mc.Mind == null || mc.Mind == exclude)
// the player needs to have a mind and not be the excluded one +
// the player has to be alive
if (!TryGetMind(uid, out var mind, out var mindComp) || mind == exclude || !_mobState.IsAlive(uid, mobState))
continue;
// the player has to be alive
if (_mobState.IsAlive(uid, mobState))
allHumans.Add(mc.Mind.Value);
allHumans.Add(new Entity<MindComponent>(mind, mindComp));
}
return allHumans;

View File

@@ -26,10 +26,10 @@ public abstract partial class SharedSalvageSystem : EntitySystem
[ValidatePrototypeId<SalvageLootPrototype>]
public const string ExpeditionsLootProto = "SalvageLoot";
public static string GetFTLName(DatasetPrototype dataset, int seed)
public string GetFTLName(LocalizedDatasetPrototype dataset, int seed)
{
var random = new System.Random(seed);
return $"{dataset.Values[random.Next(dataset.Values.Count)]}-{random.Next(10, 100)}-{(char) (65 + random.Next(26))}";
return $"{Loc.GetString(dataset.Values[random.Next(dataset.Values.Count)])}-{random.Next(10, 100)}-{(char) (65 + random.Next(26))}";
}
public SalvageMission GetMission(SalvageDifficultyPrototype difficulty, int seed)

View File

@@ -56,6 +56,7 @@ public sealed class StationAiVisionSystem : EntitySystem
EntManager = EntityManager,
Maps = _maps,
System = this,
VisibleTiles = _singleTiles,
};
}
@@ -278,7 +279,7 @@ public sealed class StationAiVisionSystem : EntitySystem
/// </summary>
private record struct SeedJob() : IRobustJob
{
public StationAiVisionSystem System;
public required StationAiVisionSystem System;
public Entity<MapGridComponent> Grid;
public Box2 ExpandedBounds;
@@ -293,14 +294,14 @@ public sealed class StationAiVisionSystem : EntitySystem
{
public int BatchSize => 1;
public IEntityManager EntManager;
public SharedMapSystem Maps;
public StationAiVisionSystem System;
public required IEntityManager EntManager;
public required SharedMapSystem Maps;
public required StationAiVisionSystem System;
public Entity<MapGridComponent> Grid;
public List<Entity<StationAiVisionComponent>> Data = new();
public HashSet<Vector2i> VisibleTiles;
public required HashSet<Vector2i> VisibleTiles;
public readonly List<Dictionary<Vector2i, int>> Vis1 = new();
public readonly List<Dictionary<Vector2i, int>> Vis2 = new();

View File

@@ -0,0 +1,69 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Content.Shared.Physics;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
using Robust.Shared.GameStates;
namespace Content.Shared.Singularity.Components;
[RegisterComponent, AutoGenerateComponentPause, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class SingularityGeneratorComponent : Component
{
/// <summary>
/// The amount of power this generator has accumulated.
/// If you want to set this use <see cref="SingularityGeneratorSystem.SetPower"/>
/// </summary>
[DataField]
public float Power = 0;
/// <summary>
/// The power threshold at which this generator will spawn a singularity.
/// If you want to set this use <see cref="SingularityGeneratorSystem.SetThreshold"/>
/// </summary>
[DataField]
public float Threshold = 16;
/// <summary>
/// Allows the generator to ignore all the failsafe stuff, e.g. when emagged
/// </summary>
[DataField, AutoNetworkedField]
public bool FailsafeDisabled = false;
/// <summary>
/// Maximum distance at which the generator will check for a field at
/// </summary>
[DataField]
public float FailsafeDistance = 16;
/// <summary>
/// The prototype ID used to spawn a singularity.
/// </summary>
[DataField("spawnId", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string? SpawnPrototype = "Singularity";
/// <summary>
/// The masks the raycast should not go through
/// </summary>
[DataField]
public int CollisionMask = (int)CollisionGroup.FullTileMask;
/// <summary>
/// Message to use when there's no containment field on cardinal directions
/// </summary>
[DataField]
public LocId ContainmentFailsafeMessage = "comp-generator-failsafe";
/// <summary>
/// For how long the failsafe will cause the generator to stop working and not issue a failsafe warning
/// </summary>
[DataField]
public TimeSpan FailsafeCooldown = TimeSpan.FromSeconds(10);
/// <summary>
/// How long until the generator can issue a failsafe warning again
/// </summary>
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
[AutoPausedField]
public TimeSpan NextFailsafe = TimeSpan.Zero;
}

View File

@@ -0,0 +1,28 @@
using Content.Shared.Emag.Systems;
using Content.Shared.Popups;
using Content.Shared.Singularity.Components;
namespace Content.Shared.Singularity.EntitySystems;
/// <summary>
/// Shared part of SingularitySingularityGeneratorSystem
/// </summary>
public abstract class SharedSingularityGeneratorSystem : EntitySystem
{
#region Dependencies
[Dependency] protected readonly SharedPopupSystem PopupSystem = default!;
#endregion Dependencies
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SingularityGeneratorComponent, GotEmaggedEvent>(OnEmagged);
}
private void OnEmagged(EntityUid uid, SingularityGeneratorComponent component, ref GotEmaggedEvent args)
{
component.FailsafeDisabled = true;
args.Handled = true;
}
}

View File

@@ -129,7 +129,6 @@ public abstract class SharedStorageSystem : EntitySystem
SubscribeAllEvent<StorageInteractWithItemEvent>(OnInteractWithItem);
SubscribeAllEvent<StorageSetItemLocationEvent>(OnSetItemLocation);
SubscribeAllEvent<StorageInsertItemIntoLocationEvent>(OnInsertItemIntoLocation);
SubscribeAllEvent<StorageRemoveItemEvent>(OnRemoveItem);
SubscribeAllEvent<StorageSaveItemLocationEvent>(OnSaveItemLocation);
SubscribeLocalEvent<StorageComponent, GotReclaimedEvent>(OnReclaimed);
@@ -639,19 +638,6 @@ public abstract class SharedStorageSystem : EntitySystem
TrySetItemStorageLocation(item!, storage!, msg.Location);
}
private void OnRemoveItem(StorageRemoveItemEvent msg, EntitySessionEventArgs args)
{
if (!ValidateInput(args, msg.StorageEnt, msg.ItemEnt, out var player, out var storage, out var item))
return;
_adminLog.Add(
LogType.Storage,
LogImpact.Low,
$"{ToPrettyString(player):player} is removing {ToPrettyString(item):item} from {ToPrettyString(storage):storage}");
TransformSystem.DropNextTo(item.Owner, player.Owner);
Audio.PlayPredicted(storage.Comp.StorageRemoveSound, storage, player, _audioParams);
}
private void OnInsertItemIntoLocation(StorageInsertItemIntoLocationEvent msg, EntitySessionEventArgs args)
{
if (!ValidateInput(args, msg.StorageEnt, msg.ItemEnt, out var player, out var storage, out var item, held: true))

View File

@@ -169,20 +169,6 @@ namespace Content.Shared.Storage
}
}
[Serializable, NetSerializable]
public sealed class StorageRemoveItemEvent : EntityEventArgs
{
public readonly NetEntity ItemEnt;
public readonly NetEntity StorageEnt;
public StorageRemoveItemEvent(NetEntity itemEnt, NetEntity storageEnt)
{
ItemEnt = itemEnt;
StorageEnt = storageEnt;
}
}
[Serializable, NetSerializable]
public sealed class StorageInsertItemIntoLocationEvent : EntityEventArgs
{

View File

@@ -39,7 +39,8 @@ public partial class ListingData : IEquatable<ListingData>
other.Categories,
other.OriginalCost,
other.RestockTime,
other.DiscountDownTo
other.DiscountDownTo,
other.DisableRefund
)
{
@@ -63,7 +64,8 @@ public partial class ListingData : IEquatable<ListingData>
HashSet<ProtoId<StoreCategoryPrototype>> categories,
IReadOnlyDictionary<ProtoId<CurrencyPrototype>, FixedPoint2> originalCost,
TimeSpan restockTime,
Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> dataDiscountDownTo
Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> dataDiscountDownTo,
bool disableRefund
)
{
Name = name;
@@ -84,6 +86,7 @@ public partial class ListingData : IEquatable<ListingData>
OriginalCost = originalCost;
RestockTime = restockTime;
DiscountDownTo = new Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2>(dataDiscountDownTo);
DisableRefund = disableRefund;
}
[ViewVariables]
@@ -194,6 +197,12 @@ public partial class ListingData : IEquatable<ListingData>
[DataField]
public Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> DiscountDownTo = new();
/// <summary>
/// Whether or not to disable refunding for the store when the listing is purchased from it.
/// </summary>
[DataField]
public bool DisableRefund = false;
public bool Equals(ListingData? listing)
{
if (listing == null)
@@ -287,7 +296,8 @@ public sealed partial class ListingDataWithCostModifiers : ListingData
listingData.Categories,
listingData.OriginalCost,
listingData.RestockTime,
listingData.DiscountDownTo
listingData.DiscountDownTo,
listingData.DisableRefund
)
{
}

View File

@@ -1,167 +1,4 @@
Entries:
- author: to4no_fix
changes:
- message: Added a new electropack that shocks when a trigger is triggered
type: Add
- message: Added a new shock collar that shocks when a trigger is triggered
type: Add
- message: Two shock collars and two remote signallers added to the warden's locker
type: Add
- message: Shock collar added as a new target for the thief
type: Add
- message: A new Special Means technology has been added to the Arsenal research
branch at the 1st research level. Its research opens up the possibility of producing
electropacks at security techfab. The cost of technology research is 5000
type: Add
id: 7114
time: '2024-08-15T14:30:39.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/30529
- author: Mervill
changes:
- message: The Gas Analyzer won't spuriously shut down for seemly no reason.
type: Tweak
- message: The Gas Analyzer will always switch to the device tab when a new object
is scanned.
type: Tweak
- message: The Gas Analyzer's interaction range is now equal to the standard interaction
range
type: Fix
- message: Clicking the Gas Analyzer when it's in your hand has proper enable/disable
behavior.
type: Fix
id: 7115
time: '2024-08-15T14:45:13.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/30763
- author: Nimfar11
changes:
- message: Adds a gold toilet
type: Add
- message: Adds a target for the Thief to steal the golden toilet
type: Add
- message: Corrected the sprite image for the normal toilet.
type: Fix
id: 7116
time: '2024-08-15T19:23:59.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31049
- author: themias
changes:
- message: Raw meat cutlets can be cooked on a grill
type: Tweak
id: 7117
time: '2024-08-15T19:30:09.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31048
- author: IProduceWidgets
changes:
- message: Meteor dust should more consistently happen instead of meteors.
type: Tweak
id: 7118
time: '2024-08-15T19:33:17.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31018
- author: Emisse
changes:
- message: Atlas, Cluster, Europa, & Saltern removed from the game.
type: Remove
id: 7119
time: '2024-08-15T21:10:07.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31058
- author: Emisse
changes:
- message: Origin removed from the game.
type: Remove
id: 7120
time: '2024-08-15T22:22:02.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31059
- author: Psychpsyo
changes:
- message: You can now be German on ze space station! (added German accent)
type: Add
id: 7121
time: '2024-08-15T23:30:21.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/30541
- author: EmoGarbage404
changes:
- message: Reduced the amount of ore on the mining asteroid and expeditions.
type: Tweak
- message: Increased the amount of ore on magnet asteroids.
type: Tweak
- message: Each piece of ore now only has enough material to create 1 sheet.
type: Tweak
- message: The salvage magnet now accurately reports the contents of asteroids.
type: Fix
id: 7122
time: '2024-08-16T01:43:54.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/30920
- author: metalgearsloth
changes:
- message: Fix mains light on wires not being lit.
type: Fix
id: 7123
time: '2024-08-16T03:59:46.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31066
- author: IgorAnt028
changes:
- message: The dead and knocked down now stop holding objects
type: Fix
id: 7124
time: '2024-08-16T04:53:34.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31009
- author: SlamBamActionman
changes:
- message: Nar'Sie is satiated; moppable blood will no longer duplicate.
type: Fix
id: 7125
time: '2024-08-16T10:47:53.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/30983
- author: Blackern5000
changes:
- message: Disabler SMGs no longer fit in combat boots
type: Fix
id: 7126
time: '2024-08-17T01:00:21.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31110
- author: Mervill
changes:
- message: Fixed suffocation alerts not appearing.
type: Fix
id: 7127
time: '2024-08-17T02:02:51.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31115
- author: TokenStyle
changes:
- message: Plant's scream mutation now have 10+ scream varieties.
type: Add
id: 7128
time: '2024-08-17T02:09:25.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/30862
- author: Boaz1111
changes:
- message: Phlogiston now also ignites people who consume it.
type: Add
id: 7129
time: '2024-08-17T02:49:11.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/30955
- author: slarticodefast
changes:
- message: Fixed borgs brains being teleported outside their chassis and PAIs outside
a PDA or pocket by the bluespace anomaly.
type: Fix
id: 7130
time: '2024-08-17T04:58:23.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/30744
- author: EmoGarbage404
changes:
- message: You can no longer see wreck names in the salvage magnet UI.
type: Tweak
id: 7131
time: '2024-08-17T05:09:21.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31087
- author: EmoGarbage404
changes:
- message: You can now smelt ores in intervals smaller than 30.
type: Add
id: 7132
time: '2024-08-17T05:12:55.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31074
- author: themias
changes:
- message: Added a recipe for croissants
@@ -3943,3 +3780,147 @@
id: 7613
time: '2024-11-15T23:46:02.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31147
- author: SaphireLattice
changes:
- message: Crayon UI now has categories and queue
type: Add
id: 7614
time: '2024-11-16T03:25:06.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33101
- author: Southbridge
changes:
- message: The BRB sign is now included in the Bureaucracy Crate
type: Add
id: 7615
time: '2024-11-16T03:26:48.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33341
- author: SaphireLattice
changes:
- message: Utensils can finally go into disposals
type: Fix
id: 7616
time: '2024-11-16T03:39:19.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33326
- author: K-Dynamic
changes:
- message: Solar assembly crate now comes with 10 flatpacks and 20 glass to make
expansion and repairs easier, as well as increasing in price from 525 to 1250
spesos.
type: Tweak
id: 7617
time: '2024-11-16T04:30:48.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33019
- author: Aquif
changes:
- message: There is now a button to view your admin remarks in the character editor,
right next to the stats button.
type: Tweak
id: 7618
time: '2024-11-16T05:09:29.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31761
- author: SpaceRox1244
changes:
- message: Closets and lockers now have visuals for being labeled with papers.
type: Add
id: 7619
time: '2024-11-17T03:27:29.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33318
- author: Ubaser
changes:
- message: You can now craft dim light bulbs at an autolathe.
type: Add
id: 7620
time: '2024-11-18T06:32:08.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33383
- author: Ilya246
changes:
- message: Multiple people using one shuttle console will no longer cause the shuttle
to slow down.
type: Fix
id: 7621
time: '2024-11-19T02:59:42.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/32381
- author: ScarKy0
changes:
- message: Secret doors no longer tell you if they're welded shut on examine.
type: Tweak
id: 7622
time: '2024-11-19T05:07:02.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33365
- author: ArZarLordOfMango
changes:
- message: Most toggleable clothing must now be equipped to toggle their actions.
type: Fix
id: 7623
time: '2024-11-19T20:31:38.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/32826
- author: Plykiya
changes:
- message: The SWAT crate from cargo now requires armory access to open.
type: Fix
id: 7624
time: '2024-11-20T00:57:01.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33415
- author: SlamBamActionman
changes:
- message: It's no longer possible to drag an item out of a container's UI to drop
it.
type: Tweak
id: 7625
time: '2024-11-20T01:00:38.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/32706
- author: Plykiya
changes:
- message: The crew monitoring crate now contains a flatpack of the server and computers,
and can be opened with science access instead of engineering access now.
type: Tweak
id: 7626
time: '2024-11-20T01:05:20.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33417
- author: Beck Thompson
changes:
- message: Toggle verbs are no longer duplicated on magboots and fire extinguishers!
type: Fix
id: 7627
time: '2024-11-20T01:53:53.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/32138
- author: qwerltaz
changes:
- message: A new grid item view is available in the construction menu, togglable
with a button.
type: Add
- message: Construction menu default window size was tweaked.
type: Tweak
id: 7628
time: '2024-11-20T01:54:49.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/32577
- author: SpaceLizard24
changes:
- message: Reduced crafting costs of colored light tubes.
type: Tweak
id: 7629
time: '2024-11-20T01:59:31.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33376
- author: thetolbean
changes:
- message: Items with a damage of 0 now have correct damage examination text.
type: Fix
id: 7630
time: '2024-11-20T02:05:15.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33064
- author: SaphireLattice
changes:
- message: The Singularity/Tesla generator now requires being surrounded by containment
fields to activate. This can be disabled with an Emag.
type: Tweak
id: 7631
time: '2024-11-20T05:55:58.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33358
- author: TheWaffleJesus
changes:
- message: You can now craft items with stacks of capacitors without it eating it
all!
type: Fix
id: 7632
time: '2024-11-20T07:18:38.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31966

View File

@@ -4,7 +4,7 @@
[game]
desc = "Official English Space Station 14 servers. Vanilla, roleplay ruleset."
lobbyenabled = true
soft_max_players = 70
soft_max_players = 80
panic_bunker.enabled = true
panic_bunker.disable_with_admins = true
panic_bunker.enable_without_admins = true

File diff suppressed because one or more lines are too long

View File

@@ -1,3 +0,0 @@
# Toggle Magboots Verb
toggle-magboots-verb-get-data-text = Toggle Magboots

View File

@@ -5,3 +5,4 @@ construction-menu-place-ghost = Place construction ghost
construction-menu-clear-all = Clear All
construction-menu-eraser-mode = Eraser Mode
construction-menu-craft = Craft
construction-menu-grid-view = Grid View

View File

@@ -8,3 +8,10 @@ crayon-interact-invalid-location = Can't reach there!
## UI
crayon-window-title = Crayon
crayon-window-placeholder = Search, or queue a comma-separated list of names
crayon-category-1-brushes = Brushes
crayon-category-2-alphanum = Numbers and letters
crayon-category-3-symbols = Symbols
crayon-category-4-info = Signs
crayon-category-5-graffiti = Graffiti
crayon-category-random = Random

View File

@@ -10,3 +10,4 @@ damage-throw = throw
damage-examine = It does the following damage:
damage-examine-type = It does the following [color=cyan]{$type}[/color] damage:
damage-value = - [color=red]{$amount}[/color] units of [color=yellow]{$type}[/color].
damage-none = It does no damage.

View File

@@ -0,0 +1,69 @@
names-borer-dataset-1 = Alcyonium
names-borer-dataset-2 = Anomia
names-borer-dataset-3 = Aphrodita
names-borer-dataset-4 = Arca
names-borer-dataset-5 = Argonauta
names-borer-dataset-6 = Ascaris
names-borer-dataset-7 = Asterias
names-borer-dataset-8 = Buccinum
names-borer-dataset-9 = Bulla
names-borer-dataset-10 = Cardium
names-borer-dataset-11 = Chama
names-borer-dataset-12 = Chiton
names-borer-dataset-13 = Conus
names-borer-dataset-14 = Corallina
names-borer-dataset-15 = Cypraea
names-borer-dataset-16 = Dentalium
names-borer-dataset-17 = Donax
names-borer-dataset-18 = Doris
names-borer-dataset-19 = Echinus
names-borer-dataset-20 = Eschara
names-borer-dataset-21 = Fasciola
names-borer-dataset-22 = Furia
names-borer-dataset-23 = Gordius
names-borer-dataset-24 = Gorgonia
names-borer-dataset-25 = Haliotis
names-borer-dataset-26 = Helix
names-borer-dataset-27 = Hirudo
names-borer-dataset-28 = Holothuria
names-borer-dataset-29 = Hydra
names-borer-dataset-30 = Isis
names-borer-dataset-31 = Lepas
names-borer-dataset-32 = Lernaea
names-borer-dataset-33 = Limax
names-borer-dataset-34 = Lumbricus
names-borer-dataset-35 = Madrepora
names-borer-dataset-36 = Medusa
names-borer-dataset-37 = Millepora
names-borer-dataset-38 = Murex
names-borer-dataset-39 = Myes
names-borer-dataset-40 = Mytilus
names-borer-dataset-41 = Myxine
names-borer-dataset-42 = Nautilus
names-borer-dataset-43 = Nereis
names-borer-dataset-44 = Neritha
names-borer-dataset-45 = Ostrea
names-borer-dataset-46 = Patella
names-borer-dataset-47 = Pennatula
names-borer-dataset-48 = Pholas
names-borer-dataset-49 = Pinna
names-borer-dataset-50 = Priapus
names-borer-dataset-51 = Scyllaea
names-borer-dataset-52 = Sepia
names-borer-dataset-53 = Serpula
names-borer-dataset-54 = Sertularia
names-borer-dataset-55 = Solen
names-borer-dataset-56 = Spondylus
names-borer-dataset-57 = Strombus
names-borer-dataset-58 = Taenia
names-borer-dataset-59 = Tellina
names-borer-dataset-60 = Teredo
names-borer-dataset-61 = Tethys
names-borer-dataset-62 = Triton
names-borer-dataset-63 = Trochus
names-borer-dataset-64 = Tubipora
names-borer-dataset-65 = Tubularia
names-borer-dataset-66 = Turbo
names-borer-dataset-67 = Venus
names-borer-dataset-68 = Voluta
names-borer-dataset-69 = Volvox

View File

@@ -1,3 +1,4 @@
fire-extinguisher-component-after-interact-refilled-message = {$owner} is now refilled
fire-extinguisher-component-safety-on-message = Its safety is on!
fire-extinguisher-component-verb-text = Toggle safety
fire-extinguisher-component-verb-remove = Remove safety
fire-extinguisher-component-verb-engage = Engage safety

View File

@@ -1,4 +1,4 @@
ui-lobby-title = Lobby
ui-lobby-title = Lobby
ui-lobby-ahelp-button = AHelp
ui-lobby-options-button = Options
ui-lobby-leave-button = Leave

View File

@@ -1,5 +1,7 @@
action-speech-spell-forcewall = TARCOL MINTI ZHERI
action-speech-spell-forcewall = TARCOL MINTI ZHERI
action-speech-spell-knock = AULIE OXIN FIERA
action-speech-spell-smite = EI NATH!
action-speech-spell-summon-magicarp = AIE KHUSE EU
action-speech-spell-fireball = ONI'SOMA!
action-speech-spell-summon-guns = YOR'NEE VES-KORFA
action-speech-spell-summon-magic = RYGOIN FEMA-VERECO

View File

@@ -1,4 +1,5 @@
character-setup-gui-character-setup-label = Character setup
character-setup-gui-character-setup-adminremarks-button = Admin Remarks
character-setup-gui-character-setup-stats-button = Stats
character-setup-gui-character-setup-rules-button = Rules
character-setup-gui-character-setup-close-button = Close

View File

@@ -0,0 +1,2 @@
comp-generator-failsafe = The {$target} shakes as the containment failsafe triggers!
comp-generator-failsafe-disabled = Something fizzles out inside of {$target}...

View File

@@ -1,4 +1,4 @@
# Spells
# Spells
spellbook-fireball-name = Fireball
spellbook-fireball-desc = Get most crew exploding with rage when they see this fireball heading toward them!
@@ -33,6 +33,12 @@ spellbook-wand-polymorph-carp-description = For when you need a carp filet quick
spellbook-event-summon-ghosts-name = Summon Ghosts
spellbook-event-summon-ghosts-description = Who ya gonna call?
spellbook-event-summon-guns-name = Summon Guns
spellbook-event-summon-guns-description = AK47s for everyone! Places a random gun in front of everybody. Disables refunds when bought!
spellbook-event-summon-magic-name = Summon Magic
spellbook-event-summon-magic-description = Places a random magical item in front of everybody. Nothing could go wrong! Disables refunds when bought!
# Upgrades
spellbook-upgrade-fireball-name = Upgrade Fireball
spellbook-upgrade-fireball-description = Upgrades Fireball to a maximum of level 3!

View File

@@ -665,7 +665,6 @@ entities:
1325: 54,12
1326: 53,12
1327: 52,12
1374: 6,-20
1486: 30,-23
1516: -48,16
1517: -47,17
@@ -733,6 +732,7 @@ entities:
3954: 13,-14
3979: -56,13
3980: -54,13
4774: 6,-20
- node:
cleanable: True
color: '#FFFFFFFF'
@@ -2224,6 +2224,22 @@ entities:
3652: 23,-38
3653: 23,-37
3654: 23,-39
- node:
color: '#DE3A3A96'
id: CheckerNESW
decals:
4750: 6,-22
4751: 6,-21
4752: 6,-20
4753: 7,-20
4754: 8,-20
4755: 9,-20
4756: 9,-21
4757: 9,-22
4758: 8,-22
4759: 7,-22
4760: 7,-21
4761: 8,-21
- node:
color: '#334E6DC8'
id: CheckerNWSE
@@ -2236,6 +2252,22 @@ entities:
620: -68,17
621: -69,17
622: -62,17
- node:
color: '#43990996'
id: CheckerNWSE
decals:
4762: 6,-22
4763: 6,-21
4764: 6,-20
4765: 7,-20
4766: 7,-21
4767: 7,-22
4768: 8,-22
4769: 8,-21
4770: 8,-20
4771: 9,-20
4772: 9,-21
4773: 9,-22
- node:
color: '#52B4E996'
id: CheckerNWSE
@@ -2833,6 +2865,7 @@ entities:
3856: -11,-14
3947: 13,-14
3948: 12,-11
4778: 9,-22
- node:
color: '#FFFFFFFF'
id: DirtLight
@@ -2955,11 +2988,6 @@ entities:
830: -8,-25
835: -4,-24
836: -1,-25
837: 7,-21
889: 7,-20
890: 8,-20
891: 9,-20
892: 9,-21
893: 10,-23
895: -6,-23
896: -25,-23
@@ -2996,7 +3024,6 @@ entities:
1172: 5,8
1173: -7,9
1174: -8,8
1213: 7,-22
1214: 5,-23
1215: 4,-23
1216: 7,-24
@@ -3190,6 +3217,9 @@ entities:
4668: 16,-25
4669: 13,-25
4670: 12,-23
4775: 6,-22
4776: 9,-21
4777: 9,-20
- node:
angle: 3.141592653589793 rad
color: '#FFFFFFFF'
@@ -3243,7 +3273,6 @@ entities:
690: -16,6
833: -3,-25
834: -6,-25
1212: 6,-22
1985: -40,-8
2215: 0,13
2216: -1,14
@@ -3278,6 +3307,7 @@ entities:
4630: -28,-19
4658: 17,-16
4659: 17,-15
4779: 6,-20
- node:
angle: 3.141592653589793 rad
color: '#FFFFFFFF'
@@ -4057,6 +4087,23 @@ entities:
886: -1,-12
887: -1,-11
888: -1,-10
- node:
color: '#43990996'
id: QuarterTileOverlayGreyscale
decals:
4685: 6,-23
4686: 7,-23
4687: 8,-23
4688: 9,-23
4689: 5,-23
4690: 4,-23
4691: 3,-23
4692: 10,-23
4693: 11,-23
4694: 12,-23
4695: 13,-23
4696: 14,-23
4697: 15,-23
- node:
color: '#52B4E92E'
id: QuarterTileOverlayGreyscale
@@ -4173,12 +4220,6 @@ entities:
1183: -17,19
1184: -17,20
1185: -17,21
1364: 6,-22
1365: 6,-21
1366: 6,-20
1367: 7,-20
1368: 8,-20
1369: 9,-20
1370: 6,-23
1371: 5,-23
1372: 4,-23
@@ -4352,6 +4393,18 @@ entities:
662: -17,-6
698: -18,1
699: -18,2
4813: 29,-23
4814: 28,-23
4815: 27,-23
4816: 26,-23
4817: 25,-23
4818: 24,-23
4819: 23,-23
4820: 22,-23
4821: 21,-23
4822: 20,-23
4823: 19,-23
4824: 18,-23
- node:
color: '#EFCC4196'
id: QuarterTileOverlayGreyscale
@@ -4395,6 +4448,26 @@ entities:
3886: -29,30
3887: -30,30
3888: -31,30
- node:
color: '#43990996'
id: QuarterTileOverlayGreyscale180
decals:
4718: 17,-25
4720: 19,-25
4721: 20,-25
4723: 21,-25
4724: 22,-25
4725: 23,-25
4726: 24,-25
4727: 25,-25
4728: 26,-25
4729: 27,-25
4730: 28,-25
4731: 29,-25
4732: 30,-25
4733: 31,-25
4734: 32,-25
4826: 18,-25
- node:
color: '#52B4E92E'
id: QuarterTileOverlayGreyscale180
@@ -4482,9 +4555,6 @@ entities:
1448: -32,7
1449: -33,7
1450: -34,7
1465: 9,-20
1466: 9,-21
1467: 9,-22
1494: -14,-2
1495: -15,-2
1496: -15,-3
@@ -4598,6 +4668,16 @@ entities:
4470: 36,50
4521: 44,20
4522: 45,20
- node:
color: '#DE3A3A96'
id: QuarterTileOverlayGreyscale180
decals:
4792: 14,-25
4793: 13,-25
4794: 12,-25
4795: 11,-25
4796: 10,-25
4797: 9,-25
- node:
color: '#EFB3414A'
id: QuarterTileOverlayGreyscale180
@@ -4631,6 +4711,17 @@ entities:
610: -74,16
611: -73,16
612: -72,16
- node:
color: '#43990996'
id: QuarterTileOverlayGreyscale270
decals:
4711: 9,-25
4712: 10,-25
4713: 11,-25
4714: 12,-25
4715: 13,-25
4716: 14,-25
4717: 15,-25
- node:
color: '#52B4E92E'
id: QuarterTileOverlayGreyscale270
@@ -4855,6 +4946,21 @@ entities:
decals:
696: -18,-1
697: -18,0
4798: 18,-25
4799: 19,-25
4800: 20,-25
4801: 21,-25
4802: 22,-25
4803: 23,-25
4804: 24,-25
4805: 25,-25
4806: 26,-25
4807: 27,-25
4808: 28,-25
4809: 29,-25
4810: 30,-25
4811: 31,-25
4812: 32,-25
- node:
color: '#EFB3414A'
id: QuarterTileOverlayGreyscale270
@@ -4899,6 +5005,23 @@ entities:
874: 1,-19
875: 1,-20
876: 1,-21
- node:
color: '#43990996'
id: QuarterTileOverlayGreyscale90
decals:
4698: 17,-23
4700: 19,-23
4701: 20,-23
4702: 21,-23
4703: 22,-23
4704: 23,-23
4705: 24,-23
4706: 25,-23
4707: 26,-23
4708: 27,-23
4709: 28,-23
4710: 29,-23
4825: 18,-23
- node:
color: '#52B4E92E'
id: QuarterTileOverlayGreyscale90
@@ -5041,7 +5164,6 @@ entities:
1482: 21,-23
1483: 20,-23
1484: 19,-23
1485: 18,-23
1491: -15,1
1492: -15,0
1493: -14,0
@@ -5187,6 +5309,18 @@ entities:
1635: -8,-15
1636: -8,-14
1637: -8,-13
4780: 3,-23
4781: 4,-23
4782: 5,-23
4783: 6,-23
4784: 7,-23
4785: 8,-23
4786: 9,-23
4787: 10,-23
4788: 11,-23
4789: 12,-23
4790: 13,-23
4791: 14,-23
- node:
color: '#EFB34160'
id: QuarterTileOverlayGreyscale90
@@ -5920,7 +6054,6 @@ entities:
1768: 35,7
1779: 2,-25
1780: -2,-25
1781: 18,-25
2543: 39,-35
2994: -41,23
3306: -15,48
@@ -5946,6 +6079,7 @@ entities:
4103: -18,7
4211: -17,32
4243: 38,23
4828: 18,-25
- node:
color: '#DE3A3A96'
id: WarnLineS
@@ -6034,7 +6168,6 @@ entities:
1767: 35,9
1777: 2,-23
1778: -2,-23
1782: 18,-23
1890: -42,-2
2063: -27,-23
2110: 0,24
@@ -6083,6 +6216,7 @@ entities:
4187: 57,3
4213: -17,34
4244: 38,25
4827: 18,-23
- node:
angle: -3.141592653589793 rad
color: '#FFFFFFFF'
@@ -15564,6 +15698,13 @@ entities:
- type: Transform
pos: 12.5,-25.5
parent: 60
- proto: BarSpoon
entities:
- uid: 23918
components:
- type: Transform
pos: 9.20146,-36.4394
parent: 60
- proto: BaseGasCondenser
entities:
- uid: 400
@@ -49095,6 +49236,26 @@ entities:
- type: Transform
pos: -23.5,16.5
parent: 60
- uid: 23652
components:
- type: Transform
pos: 8.5,-21.5
parent: 60
- uid: 23653
components:
- type: Transform
pos: 7.5,-20.5
parent: 60
- uid: 23914
components:
- type: Transform
pos: 7.5,-21.5
parent: 60
- uid: 23915
components:
- type: Transform
pos: 8.5,-20.5
parent: 60
- uid: 24171
components:
- type: Transform
@@ -49274,6 +49435,31 @@ entities:
parent: 60
- proto: CarpetGreen
entities:
- uid: 666
components:
- type: Transform
pos: 20.5,-27.5
parent: 60
- uid: 2278
components:
- type: Transform
pos: 19.5,-26.5
parent: 60
- uid: 2569
components:
- type: Transform
pos: 20.5,-26.5
parent: 60
- uid: 2584
components:
- type: Transform
pos: 19.5,-27.5
parent: 60
- uid: 3156
components:
- type: Transform
pos: 21.5,-26.5
parent: 60
- uid: 4195
components:
- type: Transform
@@ -49621,6 +49807,11 @@ entities:
- type: Transform
pos: 52.5,-44.5
parent: 60
- uid: 23892
components:
- type: Transform
pos: 21.5,-27.5
parent: 60
- proto: CarpetOrange
entities:
- uid: 1071
@@ -49764,11 +49955,6 @@ entities:
- type: Transform
pos: -8.5,-12.5
parent: 60
- uid: 15672
components:
- type: Transform
pos: 20.5,-28.5
parent: 60
- uid: 16543
components:
- type: Transform
@@ -49839,21 +50025,11 @@ entities:
- type: Transform
pos: 20.5,-30.5
parent: 60
- uid: 21598
components:
- type: Transform
pos: 18.5,-28.5
parent: 60
- uid: 24409
components:
- type: Transform
pos: 19.5,-31.5
parent: 60
- uid: 24410
components:
- type: Transform
pos: 19.5,-28.5
parent: 60
- uid: 24417
components:
- type: Transform
@@ -57498,12 +57674,6 @@ entities:
rot: -1.5707963267948966 rad
pos: -7.5,25.5
parent: 60
- uid: 14388
components:
- type: Transform
rot: 1.5707963267948966 rad
pos: 18.5,-28.5
parent: 60
- uid: 14389
components:
- type: Transform
@@ -57639,12 +57809,6 @@ entities:
rot: -1.5707963267948966 rad
pos: 20.5,-29.5
parent: 60
- uid: 24414
components:
- type: Transform
rot: -1.5707963267948966 rad
pos: 20.5,-28.5
parent: 60
- proto: CheapLighter
entities:
- uid: 24688
@@ -59916,6 +60080,46 @@ entities:
- type: Transform
pos: -15.664602,-30.50866
parent: 60
- uid: 23905
components:
- type: Transform
pos: -27.341524,-2.4224424
parent: 60
- uid: 23906
components:
- type: Transform
pos: -27.341524,-2.4224424
parent: 60
- uid: 23907
components:
- type: Transform
pos: -27.341524,-2.4224424
parent: 60
- uid: 23908
components:
- type: Transform
pos: -27.341524,-2.4224424
parent: 60
- uid: 23909
components:
- type: Transform
pos: -27.341524,-2.4224424
parent: 60
- uid: 23910
components:
- type: Transform
pos: -27.341524,-2.4224424
parent: 60
- uid: 23911
components:
- type: Transform
pos: -27.341524,-2.4224424
parent: 60
- uid: 23912
components:
- type: Transform
pos: -27.341524,-2.4224424
parent: 60
- proto: ClothingHeadHatSkub
entities:
- uid: 6791
@@ -60609,6 +60813,48 @@ entities:
- type: Transform
pos: 22.509872,-51.419544
parent: 60
- proto: ClothingOuterSanta
entities:
- uid: 23897
components:
- type: Transform
pos: -27.591524,-2.2661924
parent: 60
- uid: 23898
components:
- type: Transform
pos: -27.591524,-2.2661924
parent: 60
- uid: 23899
components:
- type: Transform
pos: -27.591524,-2.2661924
parent: 60
- uid: 23900
components:
- type: Transform
pos: -27.591524,-2.2661924
parent: 60
- uid: 23901
components:
- type: Transform
pos: -27.591524,-2.2661924
parent: 60
- uid: 23902
components:
- type: Transform
pos: -27.591524,-2.2661924
parent: 60
- uid: 23903
components:
- type: Transform
pos: -27.591524,-2.2661924
parent: 60
- uid: 23904
components:
- type: Transform
pos: -27.591524,-2.2661924
parent: 60
- proto: ClothingOuterSkub
entities:
- uid: 6793
@@ -61165,12 +61411,6 @@ entities:
rot: -1.5707963267948966 rad
pos: 24.5,-5.5
parent: 60
- uid: 24349
components:
- type: Transform
rot: -1.5707963267948966 rad
pos: 13.5,-26.5
parent: 60
- proto: CommandmentCircuitBoard
entities:
- uid: 24825
@@ -62937,6 +63177,11 @@ entities:
- type: Transform
pos: -16.5,-29.5
parent: 60
- uid: 23919
components:
- type: Transform
pos: 20.5,-26.5
parent: 60
- proto: DefaultStationBeacon
entities:
- uid: 20983
@@ -72222,6 +72467,11 @@ entities:
- type: Transform
pos: -7.5,-2.5
parent: 60
- uid: 23894
components:
- type: Transform
pos: 18.5,-26.5
parent: 60
- proto: Flare
entities:
- uid: 9525
@@ -73130,6 +73380,13 @@ entities:
- type: Transform
pos: -65.522354,23.506481
parent: 60
- proto: FloraTreeChristmas02
entities:
- uid: 23913
components:
- type: Transform
pos: 7.9998736,-21.48742
parent: 60
- proto: FoodApple
entities:
- uid: 7496
@@ -73262,10 +73519,10 @@ entities:
parent: 60
- proto: FoodCondimentBottleHotsauce
entities:
- uid: 23671
- uid: 15672
components:
- type: Transform
pos: 21.70029,-26.388956
pos: 11.203171,-26.288023
parent: 60
- proto: FoodFrozenSandwich
entities:
@@ -73374,30 +73631,40 @@ entities:
parent: 60
- proto: FoodPlateSmall
entities:
- uid: 21775
- uid: 14388
components:
- type: Transform
pos: 20.513836,-26.289145
pos: 12.531296,-26.131773
parent: 60
- uid: 21789
- uid: 16144
components:
- type: Transform
pos: 20.513836,-26.195395
pos: 12.531296,-26.506773
parent: 60
- uid: 23621
- uid: 21774
components:
- type: Transform
pos: 20.513836,-26.382895
pos: 12.531296,-26.381773
parent: 60
- uid: 23629
components:
- type: Transform
pos: 20.513836,-26.507895
pos: 12.531296,-26.303648
parent: 60
- uid: 23630
- uid: 23667
components:
- type: Transform
pos: 20.513836,-26.445395
pos: 12.531296,-26.178648
parent: 60
- uid: 23671
components:
- type: Transform
pos: 12.531296,-26.428648
parent: 60
- uid: 23891
components:
- type: Transform
pos: 12.531296,-26.241148
parent: 60
- proto: FoodPoppy
entities:
@@ -73512,20 +73779,20 @@ entities:
parent: 60
- proto: Fork
entities:
- uid: 2584
- uid: 21598
components:
- type: Transform
pos: 21.138836,-26.476645
pos: 11.828171,-26.428648
parent: 60
- uid: 23653
- uid: 21775
components:
- type: Transform
pos: 21.138836,-26.476645
pos: 11.828171,-26.428648
parent: 60
- uid: 23665
- uid: 23668
components:
- type: Transform
pos: 21.138836,-26.476645
pos: 11.828171,-26.428648
parent: 60
- proto: FuelDispenser
entities:
@@ -114793,13 +115060,6 @@ entities:
rot: 1.5707963267948966 rad
pos: -12.5,19.5
parent: 60
- uid: 2278
components:
- type: Transform
pos: 18.5,-26.5
parent: 60
- type: ApcPowerReceiver
powerLoad: 0
- uid: 2279
components:
- type: Transform
@@ -117916,6 +118176,23 @@ entities:
parent: 60
- type: ApcPowerReceiver
powerLoad: 0
- proto: PresentRandom
entities:
- uid: 23920
components:
- type: Transform
pos: 19.509592,-26.607985
parent: 60
- uid: 23921
components:
- type: Transform
pos: 19.650217,-27.232985
parent: 60
- uid: 23922
components:
- type: Transform
pos: 21.337717,-26.654861
parent: 60
- proto: Protolathe
entities:
- uid: 7081
@@ -119477,11 +119754,6 @@ entities:
parent: 60
- proto: RandomVendingDrinks
entities:
- uid: 3156
components:
- type: Transform
pos: 8.5,-19.5
parent: 60
- uid: 6319
components:
- type: Transform
@@ -119507,13 +119779,13 @@ entities:
- type: Transform
pos: -37.5,26.5
parent: 60
- proto: RandomVendingSnacks
entities:
- uid: 666
- uid: 23916
components:
- type: Transform
pos: 7.5,-19.5
parent: 60
- proto: RandomVendingSnacks
entities:
- uid: 6320
components:
- type: Transform
@@ -119529,6 +119801,11 @@ entities:
- type: Transform
pos: -38.5,26.5
parent: 60
- uid: 23917
components:
- type: Transform
pos: 8.5,-19.5
parent: 60
- proto: RCD
entities:
- uid: 1912
@@ -131513,20 +131790,20 @@ entities:
parent: 60
- proto: Spoon
entities:
- uid: 23666
- uid: 5786
components:
- type: Transform
pos: 21.43571,-26.476645
pos: 11.546921,-26.428648
parent: 60
- uid: 23667
- uid: 23893
components:
- type: Transform
pos: 21.43571,-26.476645
pos: 11.546921,-26.428648
parent: 60
- uid: 23668
- uid: 23895
components:
- type: Transform
pos: 21.43571,-26.476645
pos: 11.546921,-26.428648
parent: 60
- proto: SprayBottle
entities:
@@ -134805,11 +135082,6 @@ entities:
rot: -1.5707963267948966 rad
pos: 27.5,-32.5
parent: 60
- uid: 2569
components:
- type: Transform
pos: 19.5,-26.5
parent: 60
- uid: 2681
components:
- type: Transform
@@ -135421,11 +135693,6 @@ entities:
- type: Transform
pos: 42.5,-1.5
parent: 60
- uid: 16144
components:
- type: Transform
pos: 20.5,-26.5
parent: 60
- uid: 16410
components:
- type: Transform
@@ -135699,15 +135966,25 @@ entities:
- type: Transform
pos: -10.5,-34.5
parent: 60
- uid: 21789
components:
- type: Transform
pos: 13.5,-26.5
parent: 60
- uid: 23424
components:
- type: Transform
pos: 47.5,12.5
parent: 60
- uid: 23652
- uid: 23665
components:
- type: Transform
pos: 21.5,-26.5
pos: 11.5,-26.5
parent: 60
- uid: 23666
components:
- type: Transform
pos: 12.5,-26.5
parent: 60
- uid: 23838
components:
@@ -135841,10 +136118,12 @@ entities:
- type: Transform
pos: 19.5,-31.5
parent: 60
- uid: 24416
- proto: TableFancyGreen
entities:
- uid: 23896
components:
- type: Transform
pos: 19.5,-28.5
pos: -27.5,-2.5
parent: 60
- proto: TableGlass
entities:
@@ -136982,12 +137261,6 @@ entities:
- type: Transform
pos: -24.5,19.5
parent: 60
- uid: 24348
components:
- type: Transform
rot: 3.141592653589793 rad
pos: 12.5,-26.5
parent: 60
- proto: TargetSyndicate
entities:
- uid: 10824
@@ -138090,11 +138363,6 @@ entities:
- type: Transform
pos: 29.5,-22.5
parent: 60
- uid: 5786
components:
- type: Transform
pos: 18.5,-26.5
parent: 60
- uid: 6039
components:
- type: Transform
@@ -138125,6 +138393,11 @@ entities:
- type: Transform
pos: 26.5,-7.5
parent: 60
- uid: 23630
components:
- type: Transform
pos: 15.5,-26.5
parent: 60
- uid: 25214
components:
- type: Transform
@@ -138181,10 +138454,10 @@ entities:
parent: 60
- proto: VendingMachineCondiments
entities:
- uid: 21774
- uid: 23621
components:
- type: Transform
pos: 19.5,-26.5
pos: 13.5,-26.5
parent: 60
- proto: VendingMachineCuraDrobe
entities:

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

View File

@@ -18,6 +18,16 @@
category: cargoproduct-category-name-armory
group: market
- type: cargoProduct
id: SecurityRiot
icon:
sprite: Clothing/OuterClothing/Armor/riot.rsi
state: icon
product: CrateSecurityRiot
cost: 7500
category: cargoproduct-category-name-armory
group: market
- type: cargoProduct
id: TrackingImplant
icon:

View File

@@ -1,9 +0,0 @@
- type: cargoProduct
id: CrewMonitoringBoards
icon:
sprite: Objects/Misc/module.rsi
state: cpuboard
product: CrateCrewMonitoringBoards
cost: 2000
category: cargoproduct-category-name-circuitboards
group: market

View File

@@ -66,7 +66,7 @@
sprite: Objects/Devices/flatpack.rsi
state: solar-assembly-part
product: CrateEngineeringSolar
cost: 525
cost: 1250
category: cargoproduct-category-name-engineering
group: market

View File

@@ -27,3 +27,13 @@
cost: 800
category: cargoproduct-category-name-science
group: market
- type: cargoProduct
id: CrewMonitoring
icon:
sprite: Structures/Machines/server.rsi
state: server
product: CrateCrewMonitoring
cost: 2000
category: cargoproduct-category-name-science
group: market

View File

@@ -28,16 +28,6 @@
category: cargoproduct-category-name-security
group: market
- type: cargoProduct
id: SecurityRiot
icon:
sprite: Clothing/OuterClothing/Armor/riot.rsi
state: icon
product: CrateSecurityRiot
cost: 7500
category: cargoproduct-category-name-security
group: market
- type: cargoProduct
id: SecuritySupplies
icon:

View File

@@ -69,3 +69,22 @@
amount: 2
- id: MagazinePistol
amount: 4
- type: entity
id: CrateSecurityRiot
parent: [ CrateWeaponSecure, BaseRestrictedContraband ]
name: swat crate
description: Contains two sets of riot armor, helmets, shields, and enforcers loaded with beanbags. Extra ammo is included. Requires Armory access to open.
components:
- type: StorageFill
contents:
- id: ClothingOuterArmorRiot
amount: 2
- id: ClothingHeadHelmetRiot
amount: 2
- id: WeaponShotgunEnforcerRubber
amount: 2
- id: BoxBeanbag
amount: 2
- id: RiotShield
amount: 2

View File

@@ -1,12 +0,0 @@
- type: entity
id: CrateCrewMonitoringBoards
parent: CrateEngineeringSecure
name: crew monitoring boards
description: Has two crew monitoring console and server replacements. Requires engineering access to open.
components:
- type: StorageFill
contents:
- id: CrewMonitoringComputerCircuitboard
amount: 2
- id: CrewMonitoringServerMachineCircuitboard
amount: 2

View File

@@ -120,12 +120,14 @@
id: CrateEngineeringSolar
parent: CrateEngineering
name: solar assembly crate
description: Parts for constructing solar panels and trackers.
description: A kit with solar flatpacks and glass to construct ten solar panels.
components:
- type: StorageFill
contents:
- id: SolarAssemblyFlatpack
amount: 6
amount: 10
- id: SheetGlass10
amount: 2
- type: entity
id: CrateEngineeringShuttle

View File

@@ -12,3 +12,15 @@
amount: 2
- id: ClothingMaskSterile
amount: 2
- type: entity
id: CrateCrewMonitoring
parent: CrateScienceSecure
name: crew monitoring crate
description: Contains a flatpack of a crew monitoring server and a few crew monitoring computers. Requires Science access to open.
components:
- type: StorageFill
contents:
- id: CrewMonitoringServerFlatpack
- id: CrewMonitoringComputerFlatpack
amount: 3

View File

@@ -38,26 +38,6 @@
# - Pepperspray
# - GrenadeTeargas
- type: entity
id: CrateSecurityRiot
parent: CrateSecgear
name: swat crate
description: Contains two sets of riot armor, helmets, shields, and enforcers loaded with beanbags. Extra ammo is included. Requires Armory access to open.
components:
- type: StorageFill
contents:
- id: ClothingOuterArmorRiot
amount: 2
- id: ClothingHeadHelmetRiot
amount: 2
- id: WeaponShotgunEnforcerRubber
amount: 2
- id: BoxBeanbag
amount: 2
- id: RiotShield
amount: 2
# - SecGasmask
- type: entity
id: CrateSecuritySupplies
parent: CrateSecgear

View File

@@ -130,6 +130,7 @@
- id: BoxFolderYellow
- id: NewtonCradle
- id: BoxEnvelope
- id: BrbSign
- type: entity
id: CrateServiceFaxMachine

View File

@@ -1,4 +1,4 @@
# Offensive
# Offensive
- type: listing
id: SpellbookFireball
name: spellbook-fireball-name
@@ -132,6 +132,34 @@
- !type:ListingLimitedStockCondition
stock: 1
- type: listing
id: SpellbookEventSummonGuns
name: spellbook-event-summon-guns-name
description: spellbook-event-summon-guns-description
productAction: ActionSummonGuns
cost:
WizCoin: 2
categories:
- SpellbookEvents
conditions:
- !type:ListingLimitedStockCondition
stock: 1
disableRefund: true
- type: listing
id: SpellbookEventSummonMagic
name: spellbook-event-summon-magic-name
description: spellbook-event-summon-magic-description
productAction: ActionSummonMagic
cost:
WizCoin: 2
categories:
- SpellbookEvents
conditions:
- !type:ListingLimitedStockCondition
stock: 1
disableRefund: true
# Upgrades
- type: listing
id: SpellbookFireballUpgrade

View File

@@ -1,72 +1,5 @@
- type: dataset
id: names_borer
- type: localizedDataset
id: NamesBorer
values:
- Alcyonium
- Anomia
- Aphrodita
- Arca
- Argonauta
- Ascaris
- Asterias
- Buccinum
- Bulla
- Cardium
- Chama
- Chiton
- Conus
- Corallina
- Cypraea
- Dentalium
- Donax
- Doris
- Echinus
- Eschara
- Fasciola
- Furia
- Gordius
- Gorgonia
- Haliotis
- Helix
- Hirudo
- Holothuria
- Hydra
- Isis
- Lepas
- Lernaea
- Limax
- Lumbricus
- Madrepora
- Medusa
- Millepora
- Murex
- Myes
- Mytilus
- Myxine
- Nautilus
- Nereis
- Neritha
- Ostrea
- Patella
- Pennatula
- Pholas
- Pinna
- Priapus
- Scyllaea
- Sepia
- Serpula
- Sertularia
- Solen
- Spondylus
- Strombus
- Taenia
- Tellina
- Teredo
- Tethys
- Triton
- Trochus
- Tubipora
- Tubularia
- Turbo
- Venus
- Voluta
- Volvox
prefix: names-borer-dataset-
count: 69

File diff suppressed because it is too large Load Diff

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