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"> <DefaultWindow xmlns="https://spacestation14.io">
<BoxContainer Orientation="Horizontal" HorizontalExpand="True"> <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"> <BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="0 0 0 5">
<LineEdit Name="SearchBar" PlaceHolder="Search" HorizontalExpand="True"/> <LineEdit Name="SearchBar" PlaceHolder="Search" HorizontalExpand="True"/>
<OptionButton Name="OptionCategories" Access="Public" MinSize="130 0"/> <OptionButton Name="OptionCategories" Access="Public" MinSize="130 0"/>
</BoxContainer> </BoxContainer>
<ItemList Name="Recipes" Access="Public" SelectMode="Single" VerticalExpand="True"/> <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>
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.6"> <BoxContainer Orientation="Vertical" HorizontalExpand="True">
<Button Name="FavoriteButton" Visible="false" HorizontalExpand="False" <BoxContainer Orientation="Horizontal">
HorizontalAlignment="Right" Margin="0 0 0 15"/> <Button Name="MenuGridViewButton" ToggleMode="True" Text="{Loc construction-menu-grid-view}"/>
<Button Name="FavoriteButton" Visible="false"/>
</BoxContainer>
<Control> <Control>
<BoxContainer Orientation="Vertical" HorizontalExpand="True" Margin="0 0 0 5"> <BoxContainer Orientation="Vertical" HorizontalExpand="True" Margin="0 0 0 5">
<BoxContainer Orientation="Horizontal" Align="Center"> <BoxContainer Orientation="Horizontal" Align="Center">

View File

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

View File

@@ -1,7 +1,8 @@
using System.Linq; using System.Linq;
using System.Numerics;
using Content.Client.Stylesheets;
using Content.Client.UserInterface.Systems.MenuBar.Widgets; using Content.Client.UserInterface.Systems.MenuBar.Widgets;
using Content.Shared.Construction.Prototypes; using Content.Shared.Construction.Prototypes;
using Content.Shared.Tag;
using Content.Shared.Whitelist; using Content.Shared.Whitelist;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Client.Graphics; using Robust.Client.Graphics;
@@ -11,7 +12,6 @@ using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.Controls;
using Robust.Client.Utility; using Robust.Client.Utility;
using Robust.Shared.Enums; using Robust.Shared.Enums;
using Robust.Shared.Graphics;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using static Robust.Client.UserInterface.Controls.BaseButton; using static Robust.Client.UserInterface.Controls.BaseButton;
@@ -33,10 +33,12 @@ namespace Content.Client.Construction.UI
private readonly IConstructionMenuView _constructionView; private readonly IConstructionMenuView _constructionView;
private readonly EntityWhitelistSystem _whitelistSystem; private readonly EntityWhitelistSystem _whitelistSystem;
private readonly SpriteSystem _spriteSystem;
private ConstructionSystem? _constructionSystem; private ConstructionSystem? _constructionSystem;
private ConstructionPrototype? _selected; private ConstructionPrototype? _selected;
private List<ConstructionPrototype> _favoritedRecipes = []; private List<ConstructionPrototype> _favoritedRecipes = [];
private Dictionary<string, TextureButton> _recipeButtons = new();
private string _selectedCategory = string.Empty; private string _selectedCategory = string.Empty;
private string _favoriteCatName = "construction-category-favorites"; private string _favoriteCatName = "construction-category-favorites";
private string _forAllCategoryName = "construction-category-all"; private string _forAllCategoryName = "construction-category-all";
@@ -85,6 +87,7 @@ namespace Content.Client.Construction.UI
IoCManager.InjectDependencies(this); IoCManager.InjectDependencies(this);
_constructionView = new ConstructionMenu(); _constructionView = new ConstructionMenu();
_whitelistSystem = _entManager.System<EntityWhitelistSystem>(); _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 // 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)) if (_systemManager.TryGetEntitySystem<ConstructionSystem>(out var constructionSystem))
@@ -150,12 +153,24 @@ namespace Content.Client.Construction.UI
PopulateInfo(_selected); 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) private void OnViewPopulateRecipes(object? sender, (string search, string catagory) args)
{ {
var (search, category) = args; var (search, category) = args;
var recipesList = _constructionView.Recipes;
recipesList.Clear();
var recipes = new List<ConstructionPrototype>(); var recipes = new List<ConstructionPrototype>();
var isEmptyCategory = string.IsNullOrEmpty(category) || category == _forAllCategoryName; 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)); recipes.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.InvariantCulture));
foreach (var recipe in recipes) var recipesList = _constructionView.Recipes;
{ recipesList.Clear();
recipesList.Add(GetItem(recipe, recipesList));
}
// 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) private void PopulateCategories(string? selectCategory = null)
@@ -257,11 +333,10 @@ namespace Content.Client.Construction.UI
private void PopulateInfo(ConstructionPrototype prototype) private void PopulateInfo(ConstructionPrototype prototype)
{ {
var spriteSys = _systemManager.GetEntitySystem<SpriteSystem>();
_constructionView.ClearRecipeInfo(); _constructionView.ClearRecipeInfo();
_constructionView.SetRecipeInfo( _constructionView.SetRecipeInfo(
prototype.Name, prototype.Description, spriteSys.Frame0(prototype.Icon), prototype.Name, prototype.Description, _spriteSystem.Frame0(prototype.Icon),
prototype.Type != ConstructionType.Item, prototype.Type != ConstructionType.Item,
!_favoritedRecipes.Contains(prototype)); !_favoritedRecipes.Contains(prototype));
@@ -274,7 +349,6 @@ namespace Content.Client.Construction.UI
if (_constructionSystem?.GetGuide(prototype) is not { } guide) if (_constructionSystem?.GetGuide(prototype) is not { } guide)
return; return;
var spriteSys = _systemManager.GetEntitySystem<SpriteSystem>();
foreach (var entry in guide.Entries) 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) // The padding needs to be applied regardless of text length... (See PadLeft documentation)
text = text.PadLeft(text.Length + entry.Padding); 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); 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) return new(itemList)
{ {
Metadata = recipe, Metadata = recipe,
Text = recipe.Name, Text = recipe.Name,
Icon = recipe.Icon.Frame0(), Icon = _spriteSystem.Frame0(recipe.Icon),
TooltipEnabled = true, TooltipEnabled = true,
TooltipText = recipe.Description TooltipText = recipe.Description,
}; };
} }

View File

@@ -31,7 +31,7 @@ namespace Content.Client.Crayon.UI
private void PopulateCrayons() private void PopulateCrayons()
{ {
var crayonDecals = _protoManager.EnumeratePrototypes<DecalPrototype>().Where(x => x.Tags.Contains("crayon")); var crayonDecals = _protoManager.EnumeratePrototypes<DecalPrototype>().Where(x => x.Tags.Contains("crayon"));
_menu?.Populate(crayonDecals); _menu?.Populate(crayonDecals.ToList());
} }
public override void OnProtoReload(PrototypesReloadedEventArgs args) public override void OnProtoReload(PrototypesReloadedEventArgs args)
@@ -44,6 +44,16 @@ namespace Content.Client.Crayon.UI
PopulateCrayons(); 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) protected override void UpdateState(BoundUserInterfaceState state)
{ {
base.UpdateState(state); base.UpdateState(state);

View File

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

View File

@@ -1,8 +1,10 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Content.Client.Stylesheets; using Content.Client.Stylesheets;
using Content.Shared.Crayon; using Content.Shared.Crayon;
using Content.Shared.Decals; using Content.Shared.Decals;
using Robust.Client.AutoGenerated; using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Graphics; using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls; using Robust.Client.UserInterface.CustomControls;
@@ -18,7 +20,12 @@ namespace Content.Client.Crayon.UI
[GenerateTypedNameReferences] [GenerateTypedNameReferences]
public sealed partial class CrayonWindow : DefaultWindow 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 string? _selected;
private Color _color; private Color _color;
@@ -28,8 +35,10 @@ namespace Content.Client.Crayon.UI
public CrayonWindow() public CrayonWindow()
{ {
RobustXamlLoader.Load(this); RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_spriteSystem = _entitySystem.GetEntitySystem<SpriteSystem>();
Search.OnTextChanged += _ => RefreshList(); Search.OnTextChanged += SearchChanged;
ColorSelector.OnColorChanged += SelectColor; ColorSelector.OnColorChanged += SelectColor;
} }
@@ -44,51 +53,94 @@ namespace Content.Client.Crayon.UI
private void RefreshList() private void RefreshList()
{ {
// Clear // Clear
Grid.DisposeAllChildren(); Grids.DisposeAllChildren();
if (_decals == null)
if (_decals == null || _allDecals == null)
return; return;
var filter = Search.Text; 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; continue;
var button = new TextureButton() var label = new Label
{ {
TextureNormal = tex, Text = locName
Name = decal,
ToolTip = decal,
Modulate = _color,
}; };
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() TextureNormal = texture,
{ Name = name,
BackgroundColor = StyleNano.ButtonColorDefault, ToolTip = name,
}, Modulate = _color,
Children = Scale = new System.Numerics.Vector2(2, 2)
{
button,
},
}; };
Grid.AddChild(panelContainer); button.OnPressed += ButtonOnPressed;
}
else if (_selected == name)
{ {
Grid.AddChild(button); 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) private void ButtonOnPressed(ButtonEventArgs obj)
{ {
if (obj.Button.Name == null) return; if (obj.Button.Name == null) return;
_selected = obj.Button.Name; _selected = obj.Button.Name;
_autoSelected = null;
OnSelected?.Invoke(_selected); OnSelected?.Invoke(_selected);
RefreshList(); RefreshList();
} }
@@ -107,12 +159,38 @@ namespace Content.Client.Crayon.UI
RefreshList(); 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) 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(); RefreshList();

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,7 @@
using Content.Shared.Singularity.EntitySystems; using Content.Shared.Singularity.EntitySystems;
using Content.Shared.Singularity.Components; using Content.Shared.Singularity.Components;
namespace Content.Client.Singularity.EntitySystems; namespace Content.Client.Singularity.Systems;
/// <summary> /// <summary>
/// The client-side version of <see cref="SharedEventHorizonSystem"/>. /// 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.GameStates;
using Robust.Shared.Utility; using Robust.Shared.Utility;
namespace Content.Client.Singularity.EntitySystems; namespace Content.Client.Singularity.Systems;
/// <summary> /// <summary>
/// The client-side version of <see cref="SharedSingularitySystem"/>. /// The client-side version of <see cref="SharedSingularitySystem"/>.

View File

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

View File

@@ -28,7 +28,8 @@ namespace Content.Server.Announcements
} }
else 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); chat.DispatchGlobalAnnouncement(message, args[0], colorOverride: Color.Gold);
} }
shell.WriteLine("Sent!"); shell.WriteLine("Sent!");

View File

@@ -184,7 +184,7 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem<AntagSelection
return; return;
var players = _playerManager.Sessions 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(); .ToList();
ChooseAntags((uid, component), players, midround: true); ChooseAntags((uid, component), players, midround: true);

View File

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

View File

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

View File

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

View File

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

View File

@@ -184,6 +184,6 @@ namespace Content.Server.GameTicking
=> UserHasJoinedGame(session.UserId); => UserHasJoinedGame(session.UserId);
public bool UserHasJoinedGame(NetUserId 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.Speech.Components;
using Content.Server.Station.Components; using Content.Server.Station.Components;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.GameTicking;
using Content.Shared.Mind; using Content.Shared.Mind;
using Content.Shared.Players; using Content.Shared.Players;
using Content.Shared.Preferences; using Content.Shared.Preferences;
using Content.Shared.Roles; using Content.Shared.Roles;
using Content.Shared.Roles.Jobs; using Content.Shared.Roles.Jobs;
using JetBrains.Annotations;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Map.Components; using Robust.Shared.Map.Components;
using Robust.Shared.Network; using Robust.Shared.Network;
@@ -455,71 +455,4 @@ namespace Content.Server.GameTicking
#endregion #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.Points;
using Content.Server.RoundEnd; using Content.Server.RoundEnd;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
using Content.Shared.GameTicking;
using Content.Shared.GameTicking.Components; using Content.Shared.GameTicking.Components;
using Content.Shared.Points; using Content.Shared.Points;
using Content.Shared.Storage; using Content.Shared.Storage;

View File

@@ -34,10 +34,11 @@ public sealed class GatewayGeneratorSystem : EntitySystem
[Dependency] private readonly GatewaySystem _gateway = default!; [Dependency] private readonly GatewaySystem _gateway = default!;
[Dependency] private readonly MetaDataSystem _metadata = default!; [Dependency] private readonly MetaDataSystem _metadata = default!;
[Dependency] private readonly SharedMapSystem _maps = default!; [Dependency] private readonly SharedMapSystem _maps = default!;
[Dependency] private readonly SharedSalvageSystem _salvage = default!;
[Dependency] private readonly TileSystem _tile = default!; [Dependency] private readonly TileSystem _tile = default!;
[ValidatePrototypeId<DatasetPrototype>] [ValidatePrototypeId<LocalizedDatasetPrototype>]
private const string PlanetNames = "names_borer"; private const string PlanetNames = "NamesBorer";
// TODO: // TODO:
// Fix shader some more // Fix shader some more
@@ -102,7 +103,7 @@ public sealed class GatewayGeneratorSystem : EntitySystem
var mapId = _mapManager.CreateMap(); var mapId = _mapManager.CreateMap();
var mapUid = _mapManager.GetMapEntityId(mapId); 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); _metadata.SetEntityName(mapUid, gatewayName);
var origin = new Vector2i(random.Next(-MaxOffset, MaxOffset), random.Next(-MaxOffset, MaxOffset)); 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.Components;
using Content.Server.DeviceNetwork.Systems; using Content.Server.DeviceNetwork.Systems;
using Content.Server.Emp; using Content.Server.Emp;
using Content.Server.GameTicking;
using Content.Server.Medical.CrewMonitoring; using Content.Server.Medical.CrewMonitoring;
using Content.Server.Popups; using Content.Server.Popups;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
@@ -14,8 +13,10 @@ using Content.Shared.Damage;
using Content.Shared.DeviceNetwork; using Content.Shared.DeviceNetwork;
using Content.Shared.DoAfter; using Content.Shared.DoAfter;
using Content.Shared.Examine; using Content.Shared.Examine;
using Content.Shared.GameTicking;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Medical.SuitSensor; using Content.Shared.Medical.SuitSensor;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems; using Content.Shared.Mobs.Systems;
using Content.Shared.Verbs; using Content.Shared.Verbs;
@@ -383,7 +384,7 @@ public sealed class SuitSensorSystem : EntitySystem
// Get mob total damage crit threshold // Get mob total damage crit threshold
int? totalDamageThreshold = null; 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(); totalDamageThreshold = critThreshold.Value.Int();
// finally, form suit sensor status // finally, form suit sensor status

View File

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

View File

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

View File

@@ -84,6 +84,6 @@ public sealed partial class PathfindingSystem
public float MaxWiden = 7f; 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) public (bool Success, bool Handled) TryUseUtensil(EntityUid user, EntityUid target, Entity<UtensilComponent> utensil)
{ {
if (!EntityManager.TryGetComponent(target, out FoodComponent? food)) if (!EntityManager.TryGetComponent(target, out FoodComponent? food))
return (false, true); return (false, false);
//Prevents food usage with a wrong utensil //Prevents food usage with a wrong utensil
if ((food.Utensil & utensil.Comp.Types) == 0) if ((food.Utensil & utensil.Comp.Types) == 0)

View File

@@ -53,7 +53,7 @@ public sealed class KillPersonConditionSystem : EntitySystem
return; return;
// no other humans to kill // no other humans to kill
var allHumans = _mind.GetAliveHumansExcept(args.MindId); var allHumans = _mind.GetAliveHumans(args.MindId);
if (allHumans.Count == 0) if (allHumans.Count == 0)
{ {
args.Cancelled = true; args.Cancelled = true;
@@ -77,14 +77,14 @@ public sealed class KillPersonConditionSystem : EntitySystem
return; return;
// no other humans to kill // no other humans to kill
var allHumans = _mind.GetAliveHumansExcept(args.MindId); var allHumans = _mind.GetAliveHumans(args.MindId);
if (allHumans.Count == 0) if (allHumans.Count == 0)
{ {
args.Cancelled = true; args.Cancelled = true;
return; return;
} }
var allHeads = new List<EntityUid>(); var allHeads = new HashSet<Entity<MindComponent>>();
foreach (var person in allHumans) foreach (var person in allHumans)
{ {
if (TryComp<MindComponent>(person, out var mind) && mind.OwnedEntity is { } ent && HasComp<CommandStaffComponent>(ent)) 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 linearInput = Vector2.Zero;
var brakeInput = 0f; var brakeInput = 0f;
var angularInput = 0f; var angularInput = 0f;
var linearCount = 0;
var brakeCount = 0;
var angularCount = 0;
foreach (var (pilotUid, pilot, _, consoleXform) in pilots) foreach (var (pilotUid, pilot, _, consoleXform) in pilots)
{ {
@@ -322,24 +325,27 @@ public sealed class MoverController : SharedMoverController
if (brakes > 0f) if (brakes > 0f)
{ {
brakeInput += brakes; brakeInput += brakes;
brakeCount++;
} }
if (strafe.Length() > 0f) if (strafe.Length() > 0f)
{ {
var offsetRotation = consoleXform.LocalRotation; var offsetRotation = consoleXform.LocalRotation;
linearInput += offsetRotation.RotateVec(strafe); linearInput += offsetRotation.RotateVec(strafe);
linearCount++;
} }
if (rotation != 0f) if (rotation != 0f)
{ {
angularInput += rotation; angularInput += rotation;
angularCount++;
} }
} }
var count = pilots.Count; // Don't slow down the shuttle if there's someone just looking at the console
linearInput /= count; linearInput /= Math.Max(1, linearCount);
angularInput /= count; angularInput /= Math.Max(1, angularCount);
brakeInput /= count; brakeInput /= Math.Max(1, brakeCount);
// Handle shuttle movement // Handle shuttle movement
if (brakeInput > 0f) if (brakeInput > 0f)

View File

@@ -28,7 +28,7 @@ public sealed partial class SalvageSystem
var mission = GetMission(_prototypeManager.Index<SalvageDifficultyPrototype>(missionparams.Difficulty), missionparams.Seed); var mission = GetMission(_prototypeManager.Index<SalvageDifficultyPrototype>(missionparams.Difficulty), missionparams.Seed);
data.NextOffer = _timing.CurTime + mission.Duration + TimeSpan.FromSeconds(1); 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); _audio.PlayPvs(component.PrintSound, uid);
UpdateConsoles((station.Value, data)); UpdateConsoles((station.Value, data));

View File

@@ -104,7 +104,9 @@ public sealed class SpawnSalvageMissionJob : Job<bool>
destComp.BeaconsOnly = true; destComp.BeaconsOnly = true;
destComp.RequireCoordinateDisk = true; destComp.RequireCoordinateDisk = true;
destComp.Enabled = 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); _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 // 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; } public float MaximumDistance { get; }
/// <inheritdoc /> /// <inheritdoc />
public ProtoId<DatasetPrototype>? NameDataset { get; } public ProtoId<LocalizedDatasetPrototype>? NameDataset { get; }
/// <inheritdoc /> /// <inheritdoc />
int MinCount { get; set; } int MinCount { get; set; }
@@ -75,7 +75,7 @@ public sealed class DungeonSpawnGroup : IGridSpawnGroup
public float MaximumDistance { get; } public float MaximumDistance { get; }
/// <inheritdoc /> /// <inheritdoc />
public ProtoId<DatasetPrototype>? NameDataset { get; } public ProtoId<LocalizedDatasetPrototype>? NameDataset { get; }
/// <inheritdoc /> /// <inheritdoc />
public int MinCount { get; set; } = 1; public int MinCount { get; set; } = 1;
@@ -106,7 +106,7 @@ public sealed class GridSpawnGroup : IGridSpawnGroup
/// <inheritdoc /> /// <inheritdoc />
public float MaximumDistance { get; } public float MaximumDistance { get; }
public ProtoId<DatasetPrototype>? NameDataset { get; } public ProtoId<LocalizedDatasetPrototype>? NameDataset { get; }
public int MinCount { get; set; } = 1; public int MinCount { get; set; } = 1;
public int MaxCount { get; set; } = 1; public int MaxCount { get; set; } = 1;
public ComponentRegistry AddComponents { get; set; } = new(); public ComponentRegistry AddComponents { get; set; } = new();

View File

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

View File

@@ -208,7 +208,7 @@ public sealed partial class ShuttleSystem
if (_protoManager.TryIndex(group.NameDataset, out var dataset)) 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) if (group.Hide)

View File

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

View File

@@ -1,7 +1,6 @@
using System.Linq; using System.Linq;
using Content.Server.Administration; using Content.Server.Administration;
using Content.Server.Chat.Managers; using Content.Server.Chat.Managers;
using Content.Server.GameTicking;
using Content.Server.Radio.Components; using Content.Server.Radio.Components;
using Content.Server.Roles; using Content.Server.Roles;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
@@ -9,6 +8,7 @@ using Content.Shared.Administration;
using Content.Shared.Chat; using Content.Shared.Chat;
using Content.Shared.Emag.Components; using Content.Shared.Emag.Components;
using Content.Shared.Emag.Systems; using Content.Shared.Emag.Systems;
using Content.Shared.GameTicking;
using Content.Shared.Mind; using Content.Shared.Mind;
using Content.Shared.Mind.Components; using Content.Shared.Mind.Components;
using Content.Shared.Roles; using Content.Shared.Roles;
@@ -17,6 +17,7 @@ using Content.Shared.Silicons.Laws.Components;
using Content.Shared.Stunnable; using Content.Shared.Stunnable;
using Content.Shared.Wires; using Content.Shared.Wires;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Shared.Audio;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.Player; using Robust.Shared.Player;
using Robust.Shared.Prototypes; 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.ParticleAccelerator.Components;
using Content.Server.Singularity.Components; using Content.Shared.Popups;
using Content.Shared.Singularity.Components; 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.Physics.Events;
using Robust.Shared.Timing;
namespace Content.Server.Singularity.EntitySystems; namespace Content.Server.Singularity.EntitySystems;
public sealed class SingularityGeneratorSystem : EntitySystem public sealed class SingularityGeneratorSystem : SharedSingularityGeneratorSystem
{ {
#region Dependencies #region Dependencies
[Dependency] private readonly IViewVariablesManager _vvm = default!; [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 #endregion Dependencies
public override void Initialize() 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> /// <param name="args">The state of the beginning of the collision.</param>
private void HandleParticleCollide(EntityUid uid, ParticleProjectileComponent component, ref StartCollideEvent args) 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( SetPower(
args.OtherEntity, args.OtherEntity,
singularityGeneratorComponent.Power + component.State switch generatorComp.Power + component.State switch
{ {
ParticleAcceleratorPowerState.Standby => 0, ParticleAcceleratorPowerState.Standby => 0,
ParticleAcceleratorPowerState.Level0 => 1, ParticleAcceleratorPowerState.Level0 => 1,
@@ -113,10 +148,46 @@ public sealed class SingularityGeneratorSystem : EntitySystem
ParticleAcceleratorPowerState.Level3 => 8, ParticleAcceleratorPowerState.Level3 => 8,
_ => 0 _ => 0
}, },
singularityGeneratorComponent generatorComp
); );
EntityManager.QueueDeleteEntity(uid);
} }
EntityManager.QueueDeleteEntity(uid);
} }
#endregion Event Handlers #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.Diagnostics.CodeAnalysis;
using System.IO;
using Content.Server.Access.Systems; using Content.Server.Access.Systems;
using Content.Server.Forensics; using Content.Server.Forensics;
using Content.Server.GameTicking;
using Content.Shared.Access.Components; using Content.Shared.Access.Components;
using Content.Shared.GameTicking;
using Content.Shared.Inventory; using Content.Shared.Inventory;
using Content.Shared.PDA; using Content.Shared.PDA;
using Content.Shared.Preferences; using Content.Shared.Preferences;

View File

@@ -256,6 +256,11 @@ public sealed partial class StoreSystem
RaiseLocalEvent(buyer, listing.ProductEvent); RaiseLocalEvent(buyer, listing.ProductEvent);
} }
if (listing.DisableRefund)
{
component.RefundAllowed = false;
}
//log dat shit. //log dat shit.
_admin.Add(LogType.StorePurchase, _admin.Add(LogType.StorePurchase,
LogImpact.Low, 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.Components;
using Content.Shared.Hands.EntitySystems; using Content.Shared.Hands.EntitySystems;
using Content.Shared.Roles; using Content.Shared.Roles;
using Content.Shared.Traits; using Content.Shared.Traits;
using Content.Shared.Whitelist; using Content.Shared.Whitelist;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager;
namespace Content.Server.Traits; namespace Content.Server.Traits;

View File

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

View File

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

View File

@@ -3,12 +3,23 @@ using Robust.Shared.Serialization;
namespace Content.Shared.Crayon namespace Content.Shared.Crayon
{ {
/// <summary>
/// Component holding the state of a crayon-like component
/// </summary>
[NetworkedComponent, ComponentProtoName("Crayon"), Access(typeof(SharedCrayonSystem))] [NetworkedComponent, ComponentProtoName("Crayon"), Access(typeof(SharedCrayonSystem))]
public abstract partial class SharedCrayonComponent : Component 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; 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] [Serializable, NetSerializable]
public enum CrayonUiKey : byte 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] [Serializable, NetSerializable]
public sealed class CrayonSelectMessage : BoundUserInterfaceMessage 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] [Serializable, NetSerializable]
public sealed class CrayonColorMessage : BoundUserInterfaceMessage 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] [Serializable, NetSerializable]
public enum CrayonVisuals public sealed class CrayonUsedMessage : BoundUserInterfaceMessage
{ {
State, public readonly string DrawnDecal;
Color
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] [Serializable, NetSerializable]
public sealed class CrayonComponentState : ComponentState public sealed class CrayonComponentState : ComponentState
{ {
@@ -60,10 +89,17 @@ namespace Content.Shared.Crayon
Capacity = capacity; Capacity = capacity;
} }
} }
/// <summary>
/// The state of the crayon UI as sent by the server
/// </summary>
[Serializable, NetSerializable] [Serializable, NetSerializable]
public sealed class CrayonBoundUserInterfaceState : BoundUserInterfaceState public sealed class CrayonBoundUserInterfaceState : BoundUserInterfaceState
{ {
public string Selected; public string Selected;
/// <summary>
/// Whether or not the color can be selected
/// </summary>
public bool SelectableColor; public bool SelectableColor;
public Color Color; public Color Color;

View File

@@ -61,6 +61,12 @@ public sealed class DamageExamineSystem : EntitySystem
} }
else 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))); 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] [ByRefEvent]
public record struct GotEmaggedEvent(EntityUid UserUid, bool Handled = false, bool Repeatable = false); public record struct GotEmaggedEvent(EntityUid UserUid, bool Handled = false, bool Repeatable = false);

View File

@@ -66,5 +66,5 @@ public record struct GenerateDnaEvent()
/// <summary> /// <summary>
/// The generated DNA. /// The generated DNA.
/// </summary> /// </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] [DataField]
public bool OnUse = true; 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> /// <summary>
/// Whether the item's toggle can be predicted by the client. /// Whether the item's toggle can be predicted by the client.
/// </summary> /// </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() 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 = () => Act = () =>
{ {
Toggle((ent.Owner, ent.Comp), user, predicted: ent.Comp.Predictable); 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.Actions;
using Content.Shared.Body.Components; using Content.Shared.Body.Components;
using Content.Shared.Body.Systems; using Content.Shared.Body.Systems;
@@ -7,12 +7,17 @@ using Content.Shared.Doors.Components;
using Content.Shared.Doors.Systems; using Content.Shared.Doors.Systems;
using Content.Shared.Hands.Components; using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems; using Content.Shared.Hands.EntitySystems;
using Content.Shared.Humanoid;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Inventory; using Content.Shared.Inventory;
using Content.Shared.Lock; using Content.Shared.Lock;
using Content.Shared.Magic.Components; using Content.Shared.Magic.Components;
using Content.Shared.Magic.Events; using Content.Shared.Magic.Events;
using Content.Shared.Maps; 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.Physics;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Speech.Muting; using Content.Shared.Speech.Muting;
@@ -20,6 +25,7 @@ using Content.Shared.Storage;
using Content.Shared.Tag; using Content.Shared.Tag;
using Content.Shared.Weapons.Ranged.Components; using Content.Shared.Weapons.Ranged.Components;
using Content.Shared.Weapons.Ranged.Systems; using Content.Shared.Weapons.Ranged.Systems;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Map.Components; using Robust.Shared.Map.Components;
using Robust.Shared.Network; using Robust.Shared.Network;
@@ -53,6 +59,9 @@ public abstract class SharedMagicSystem : EntitySystem
[Dependency] private readonly LockSystem _lock = default!; [Dependency] private readonly LockSystem _lock = default!;
[Dependency] private readonly SharedHandsSystem _hands = default!; [Dependency] private readonly SharedHandsSystem _hands = default!;
[Dependency] private readonly TagSystem _tag = 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() public override void Initialize()
{ {
@@ -67,6 +76,7 @@ public abstract class SharedMagicSystem : EntitySystem
SubscribeLocalEvent<SmiteSpellEvent>(OnSmiteSpell); SubscribeLocalEvent<SmiteSpellEvent>(OnSmiteSpell);
SubscribeLocalEvent<KnockSpellEvent>(OnKnockSpell); SubscribeLocalEvent<KnockSpellEvent>(OnKnockSpell);
SubscribeLocalEvent<ChargeSpellEvent>(OnChargeSpell); SubscribeLocalEvent<ChargeSpellEvent>(OnChargeSpell);
SubscribeLocalEvent<RandomGlobalSpawnSpellEvent>(OnRandomGlobalSpawnSpell);
// Spell wishlist // Spell wishlist
// A wishlish of spells that I'd like to implement or planning on implementing in a future PR // 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); _gunSystem.UpdateBasicEntityAmmoCount(wand.Value, basicAmmoComp.Count.Value + ev.Charge, basicAmmoComp);
} }
// End Charge Spells // 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 #endregion
// End Spells // End Spells
#endregion #endregion

View File

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

View File

@@ -26,10 +26,10 @@ public abstract partial class SharedSalvageSystem : EntitySystem
[ValidatePrototypeId<SalvageLootPrototype>] [ValidatePrototypeId<SalvageLootPrototype>]
public const string ExpeditionsLootProto = "SalvageLoot"; 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); 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) public SalvageMission GetMission(SalvageDifficultyPrototype difficulty, int seed)

View File

@@ -56,6 +56,7 @@ public sealed class StationAiVisionSystem : EntitySystem
EntManager = EntityManager, EntManager = EntityManager,
Maps = _maps, Maps = _maps,
System = this, System = this,
VisibleTiles = _singleTiles,
}; };
} }
@@ -278,7 +279,7 @@ public sealed class StationAiVisionSystem : EntitySystem
/// </summary> /// </summary>
private record struct SeedJob() : IRobustJob private record struct SeedJob() : IRobustJob
{ {
public StationAiVisionSystem System; public required StationAiVisionSystem System;
public Entity<MapGridComponent> Grid; public Entity<MapGridComponent> Grid;
public Box2 ExpandedBounds; public Box2 ExpandedBounds;
@@ -293,14 +294,14 @@ public sealed class StationAiVisionSystem : EntitySystem
{ {
public int BatchSize => 1; public int BatchSize => 1;
public IEntityManager EntManager; public required IEntityManager EntManager;
public SharedMapSystem Maps; public required SharedMapSystem Maps;
public StationAiVisionSystem System; public required StationAiVisionSystem System;
public Entity<MapGridComponent> Grid; public Entity<MapGridComponent> Grid;
public List<Entity<StationAiVisionComponent>> Data = new(); 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>> Vis1 = new();
public readonly List<Dictionary<Vector2i, int>> Vis2 = 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<StorageInteractWithItemEvent>(OnInteractWithItem);
SubscribeAllEvent<StorageSetItemLocationEvent>(OnSetItemLocation); SubscribeAllEvent<StorageSetItemLocationEvent>(OnSetItemLocation);
SubscribeAllEvent<StorageInsertItemIntoLocationEvent>(OnInsertItemIntoLocation); SubscribeAllEvent<StorageInsertItemIntoLocationEvent>(OnInsertItemIntoLocation);
SubscribeAllEvent<StorageRemoveItemEvent>(OnRemoveItem);
SubscribeAllEvent<StorageSaveItemLocationEvent>(OnSaveItemLocation); SubscribeAllEvent<StorageSaveItemLocationEvent>(OnSaveItemLocation);
SubscribeLocalEvent<StorageComponent, GotReclaimedEvent>(OnReclaimed); SubscribeLocalEvent<StorageComponent, GotReclaimedEvent>(OnReclaimed);
@@ -639,19 +638,6 @@ public abstract class SharedStorageSystem : EntitySystem
TrySetItemStorageLocation(item!, storage!, msg.Location); 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) 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)) 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] [Serializable, NetSerializable]
public sealed class StorageInsertItemIntoLocationEvent : EntityEventArgs public sealed class StorageInsertItemIntoLocationEvent : EntityEventArgs
{ {

View File

@@ -39,7 +39,8 @@ public partial class ListingData : IEquatable<ListingData>
other.Categories, other.Categories,
other.OriginalCost, other.OriginalCost,
other.RestockTime, other.RestockTime,
other.DiscountDownTo other.DiscountDownTo,
other.DisableRefund
) )
{ {
@@ -63,7 +64,8 @@ public partial class ListingData : IEquatable<ListingData>
HashSet<ProtoId<StoreCategoryPrototype>> categories, HashSet<ProtoId<StoreCategoryPrototype>> categories,
IReadOnlyDictionary<ProtoId<CurrencyPrototype>, FixedPoint2> originalCost, IReadOnlyDictionary<ProtoId<CurrencyPrototype>, FixedPoint2> originalCost,
TimeSpan restockTime, TimeSpan restockTime,
Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> dataDiscountDownTo Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> dataDiscountDownTo,
bool disableRefund
) )
{ {
Name = name; Name = name;
@@ -84,6 +86,7 @@ public partial class ListingData : IEquatable<ListingData>
OriginalCost = originalCost; OriginalCost = originalCost;
RestockTime = restockTime; RestockTime = restockTime;
DiscountDownTo = new Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2>(dataDiscountDownTo); DiscountDownTo = new Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2>(dataDiscountDownTo);
DisableRefund = disableRefund;
} }
[ViewVariables] [ViewVariables]
@@ -194,6 +197,12 @@ public partial class ListingData : IEquatable<ListingData>
[DataField] [DataField]
public Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> DiscountDownTo = new(); 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) public bool Equals(ListingData? listing)
{ {
if (listing == null) if (listing == null)
@@ -287,7 +296,8 @@ public sealed partial class ListingDataWithCostModifiers : ListingData
listingData.Categories, listingData.Categories,
listingData.OriginalCost, listingData.OriginalCost,
listingData.RestockTime, listingData.RestockTime,
listingData.DiscountDownTo listingData.DiscountDownTo,
listingData.DisableRefund
) )
{ {
} }

View File

@@ -1,167 +1,4 @@
Entries: 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 - author: themias
changes: changes:
- message: Added a recipe for croissants - message: Added a recipe for croissants
@@ -3943,3 +3780,147 @@
id: 7613 id: 7613
time: '2024-11-15T23:46:02.0000000+00:00' time: '2024-11-15T23:46:02.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31147 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] [game]
desc = "Official English Space Station 14 servers. Vanilla, roleplay ruleset." desc = "Official English Space Station 14 servers. Vanilla, roleplay ruleset."
lobbyenabled = true lobbyenabled = true
soft_max_players = 70 soft_max_players = 80
panic_bunker.enabled = true panic_bunker.enabled = true
panic_bunker.disable_with_admins = true panic_bunker.disable_with_admins = true
panic_bunker.enable_without_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-clear-all = Clear All
construction-menu-eraser-mode = Eraser Mode construction-menu-eraser-mode = Eraser Mode
construction-menu-craft = Craft 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 ## UI
crayon-window-title = Crayon 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 = It does the following damage:
damage-examine-type = It does the following [color=cyan]{$type}[/color] 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-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-after-interact-refilled-message = {$owner} is now refilled
fire-extinguisher-component-safety-on-message = Its safety is on! 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-ahelp-button = AHelp
ui-lobby-options-button = Options ui-lobby-options-button = Options
ui-lobby-leave-button = Leave 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-knock = AULIE OXIN FIERA
action-speech-spell-smite = EI NATH! action-speech-spell-smite = EI NATH!
action-speech-spell-summon-magicarp = AIE KHUSE EU action-speech-spell-summon-magicarp = AIE KHUSE EU
action-speech-spell-fireball = ONI'SOMA! 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-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-stats-button = Stats
character-setup-gui-character-setup-rules-button = Rules character-setup-gui-character-setup-rules-button = Rules
character-setup-gui-character-setup-close-button = Close 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-name = Fireball
spellbook-fireball-desc = Get most crew exploding with rage when they see this fireball heading toward them! 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-name = Summon Ghosts
spellbook-event-summon-ghosts-description = Who ya gonna call? 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 # Upgrades
spellbook-upgrade-fireball-name = Upgrade Fireball spellbook-upgrade-fireball-name = Upgrade Fireball
spellbook-upgrade-fireball-description = Upgrades Fireball to a maximum of level 3! spellbook-upgrade-fireball-description = Upgrades Fireball to a maximum of level 3!

View File

@@ -665,7 +665,6 @@ entities:
1325: 54,12 1325: 54,12
1326: 53,12 1326: 53,12
1327: 52,12 1327: 52,12
1374: 6,-20
1486: 30,-23 1486: 30,-23
1516: -48,16 1516: -48,16
1517: -47,17 1517: -47,17
@@ -733,6 +732,7 @@ entities:
3954: 13,-14 3954: 13,-14
3979: -56,13 3979: -56,13
3980: -54,13 3980: -54,13
4774: 6,-20
- node: - node:
cleanable: True cleanable: True
color: '#FFFFFFFF' color: '#FFFFFFFF'
@@ -2224,6 +2224,22 @@ entities:
3652: 23,-38 3652: 23,-38
3653: 23,-37 3653: 23,-37
3654: 23,-39 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: - node:
color: '#334E6DC8' color: '#334E6DC8'
id: CheckerNWSE id: CheckerNWSE
@@ -2236,6 +2252,22 @@ entities:
620: -68,17 620: -68,17
621: -69,17 621: -69,17
622: -62,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: - node:
color: '#52B4E996' color: '#52B4E996'
id: CheckerNWSE id: CheckerNWSE
@@ -2833,6 +2865,7 @@ entities:
3856: -11,-14 3856: -11,-14
3947: 13,-14 3947: 13,-14
3948: 12,-11 3948: 12,-11
4778: 9,-22
- node: - node:
color: '#FFFFFFFF' color: '#FFFFFFFF'
id: DirtLight id: DirtLight
@@ -2955,11 +2988,6 @@ entities:
830: -8,-25 830: -8,-25
835: -4,-24 835: -4,-24
836: -1,-25 836: -1,-25
837: 7,-21
889: 7,-20
890: 8,-20
891: 9,-20
892: 9,-21
893: 10,-23 893: 10,-23
895: -6,-23 895: -6,-23
896: -25,-23 896: -25,-23
@@ -2996,7 +3024,6 @@ entities:
1172: 5,8 1172: 5,8
1173: -7,9 1173: -7,9
1174: -8,8 1174: -8,8
1213: 7,-22
1214: 5,-23 1214: 5,-23
1215: 4,-23 1215: 4,-23
1216: 7,-24 1216: 7,-24
@@ -3190,6 +3217,9 @@ entities:
4668: 16,-25 4668: 16,-25
4669: 13,-25 4669: 13,-25
4670: 12,-23 4670: 12,-23
4775: 6,-22
4776: 9,-21
4777: 9,-20
- node: - node:
angle: 3.141592653589793 rad angle: 3.141592653589793 rad
color: '#FFFFFFFF' color: '#FFFFFFFF'
@@ -3243,7 +3273,6 @@ entities:
690: -16,6 690: -16,6
833: -3,-25 833: -3,-25
834: -6,-25 834: -6,-25
1212: 6,-22
1985: -40,-8 1985: -40,-8
2215: 0,13 2215: 0,13
2216: -1,14 2216: -1,14
@@ -3278,6 +3307,7 @@ entities:
4630: -28,-19 4630: -28,-19
4658: 17,-16 4658: 17,-16
4659: 17,-15 4659: 17,-15
4779: 6,-20
- node: - node:
angle: 3.141592653589793 rad angle: 3.141592653589793 rad
color: '#FFFFFFFF' color: '#FFFFFFFF'
@@ -4057,6 +4087,23 @@ entities:
886: -1,-12 886: -1,-12
887: -1,-11 887: -1,-11
888: -1,-10 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: - node:
color: '#52B4E92E' color: '#52B4E92E'
id: QuarterTileOverlayGreyscale id: QuarterTileOverlayGreyscale
@@ -4173,12 +4220,6 @@ entities:
1183: -17,19 1183: -17,19
1184: -17,20 1184: -17,20
1185: -17,21 1185: -17,21
1364: 6,-22
1365: 6,-21
1366: 6,-20
1367: 7,-20
1368: 8,-20
1369: 9,-20
1370: 6,-23 1370: 6,-23
1371: 5,-23 1371: 5,-23
1372: 4,-23 1372: 4,-23
@@ -4352,6 +4393,18 @@ entities:
662: -17,-6 662: -17,-6
698: -18,1 698: -18,1
699: -18,2 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: - node:
color: '#EFCC4196' color: '#EFCC4196'
id: QuarterTileOverlayGreyscale id: QuarterTileOverlayGreyscale
@@ -4395,6 +4448,26 @@ entities:
3886: -29,30 3886: -29,30
3887: -30,30 3887: -30,30
3888: -31,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: - node:
color: '#52B4E92E' color: '#52B4E92E'
id: QuarterTileOverlayGreyscale180 id: QuarterTileOverlayGreyscale180
@@ -4482,9 +4555,6 @@ entities:
1448: -32,7 1448: -32,7
1449: -33,7 1449: -33,7
1450: -34,7 1450: -34,7
1465: 9,-20
1466: 9,-21
1467: 9,-22
1494: -14,-2 1494: -14,-2
1495: -15,-2 1495: -15,-2
1496: -15,-3 1496: -15,-3
@@ -4598,6 +4668,16 @@ entities:
4470: 36,50 4470: 36,50
4521: 44,20 4521: 44,20
4522: 45,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: - node:
color: '#EFB3414A' color: '#EFB3414A'
id: QuarterTileOverlayGreyscale180 id: QuarterTileOverlayGreyscale180
@@ -4631,6 +4711,17 @@ entities:
610: -74,16 610: -74,16
611: -73,16 611: -73,16
612: -72,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: - node:
color: '#52B4E92E' color: '#52B4E92E'
id: QuarterTileOverlayGreyscale270 id: QuarterTileOverlayGreyscale270
@@ -4855,6 +4946,21 @@ entities:
decals: decals:
696: -18,-1 696: -18,-1
697: -18,0 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: - node:
color: '#EFB3414A' color: '#EFB3414A'
id: QuarterTileOverlayGreyscale270 id: QuarterTileOverlayGreyscale270
@@ -4899,6 +5005,23 @@ entities:
874: 1,-19 874: 1,-19
875: 1,-20 875: 1,-20
876: 1,-21 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: - node:
color: '#52B4E92E' color: '#52B4E92E'
id: QuarterTileOverlayGreyscale90 id: QuarterTileOverlayGreyscale90
@@ -5041,7 +5164,6 @@ entities:
1482: 21,-23 1482: 21,-23
1483: 20,-23 1483: 20,-23
1484: 19,-23 1484: 19,-23
1485: 18,-23
1491: -15,1 1491: -15,1
1492: -15,0 1492: -15,0
1493: -14,0 1493: -14,0
@@ -5187,6 +5309,18 @@ entities:
1635: -8,-15 1635: -8,-15
1636: -8,-14 1636: -8,-14
1637: -8,-13 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: - node:
color: '#EFB34160' color: '#EFB34160'
id: QuarterTileOverlayGreyscale90 id: QuarterTileOverlayGreyscale90
@@ -5920,7 +6054,6 @@ entities:
1768: 35,7 1768: 35,7
1779: 2,-25 1779: 2,-25
1780: -2,-25 1780: -2,-25
1781: 18,-25
2543: 39,-35 2543: 39,-35
2994: -41,23 2994: -41,23
3306: -15,48 3306: -15,48
@@ -5946,6 +6079,7 @@ entities:
4103: -18,7 4103: -18,7
4211: -17,32 4211: -17,32
4243: 38,23 4243: 38,23
4828: 18,-25
- node: - node:
color: '#DE3A3A96' color: '#DE3A3A96'
id: WarnLineS id: WarnLineS
@@ -6034,7 +6168,6 @@ entities:
1767: 35,9 1767: 35,9
1777: 2,-23 1777: 2,-23
1778: -2,-23 1778: -2,-23
1782: 18,-23
1890: -42,-2 1890: -42,-2
2063: -27,-23 2063: -27,-23
2110: 0,24 2110: 0,24
@@ -6083,6 +6216,7 @@ entities:
4187: 57,3 4187: 57,3
4213: -17,34 4213: -17,34
4244: 38,25 4244: 38,25
4827: 18,-23
- node: - node:
angle: -3.141592653589793 rad angle: -3.141592653589793 rad
color: '#FFFFFFFF' color: '#FFFFFFFF'
@@ -15564,6 +15698,13 @@ entities:
- type: Transform - type: Transform
pos: 12.5,-25.5 pos: 12.5,-25.5
parent: 60 parent: 60
- proto: BarSpoon
entities:
- uid: 23918
components:
- type: Transform
pos: 9.20146,-36.4394
parent: 60
- proto: BaseGasCondenser - proto: BaseGasCondenser
entities: entities:
- uid: 400 - uid: 400
@@ -49095,6 +49236,26 @@ entities:
- type: Transform - type: Transform
pos: -23.5,16.5 pos: -23.5,16.5
parent: 60 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 - uid: 24171
components: components:
- type: Transform - type: Transform
@@ -49274,6 +49435,31 @@ entities:
parent: 60 parent: 60
- proto: CarpetGreen - proto: CarpetGreen
entities: 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 - uid: 4195
components: components:
- type: Transform - type: Transform
@@ -49621,6 +49807,11 @@ entities:
- type: Transform - type: Transform
pos: 52.5,-44.5 pos: 52.5,-44.5
parent: 60 parent: 60
- uid: 23892
components:
- type: Transform
pos: 21.5,-27.5
parent: 60
- proto: CarpetOrange - proto: CarpetOrange
entities: entities:
- uid: 1071 - uid: 1071
@@ -49764,11 +49955,6 @@ entities:
- type: Transform - type: Transform
pos: -8.5,-12.5 pos: -8.5,-12.5
parent: 60 parent: 60
- uid: 15672
components:
- type: Transform
pos: 20.5,-28.5
parent: 60
- uid: 16543 - uid: 16543
components: components:
- type: Transform - type: Transform
@@ -49839,21 +50025,11 @@ entities:
- type: Transform - type: Transform
pos: 20.5,-30.5 pos: 20.5,-30.5
parent: 60 parent: 60
- uid: 21598
components:
- type: Transform
pos: 18.5,-28.5
parent: 60
- uid: 24409 - uid: 24409
components: components:
- type: Transform - type: Transform
pos: 19.5,-31.5 pos: 19.5,-31.5
parent: 60 parent: 60
- uid: 24410
components:
- type: Transform
pos: 19.5,-28.5
parent: 60
- uid: 24417 - uid: 24417
components: components:
- type: Transform - type: Transform
@@ -57498,12 +57674,6 @@ entities:
rot: -1.5707963267948966 rad rot: -1.5707963267948966 rad
pos: -7.5,25.5 pos: -7.5,25.5
parent: 60 parent: 60
- uid: 14388
components:
- type: Transform
rot: 1.5707963267948966 rad
pos: 18.5,-28.5
parent: 60
- uid: 14389 - uid: 14389
components: components:
- type: Transform - type: Transform
@@ -57639,12 +57809,6 @@ entities:
rot: -1.5707963267948966 rad rot: -1.5707963267948966 rad
pos: 20.5,-29.5 pos: 20.5,-29.5
parent: 60 parent: 60
- uid: 24414
components:
- type: Transform
rot: -1.5707963267948966 rad
pos: 20.5,-28.5
parent: 60
- proto: CheapLighter - proto: CheapLighter
entities: entities:
- uid: 24688 - uid: 24688
@@ -59916,6 +60080,46 @@ entities:
- type: Transform - type: Transform
pos: -15.664602,-30.50866 pos: -15.664602,-30.50866
parent: 60 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 - proto: ClothingHeadHatSkub
entities: entities:
- uid: 6791 - uid: 6791
@@ -60609,6 +60813,48 @@ entities:
- type: Transform - type: Transform
pos: 22.509872,-51.419544 pos: 22.509872,-51.419544
parent: 60 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 - proto: ClothingOuterSkub
entities: entities:
- uid: 6793 - uid: 6793
@@ -61165,12 +61411,6 @@ entities:
rot: -1.5707963267948966 rad rot: -1.5707963267948966 rad
pos: 24.5,-5.5 pos: 24.5,-5.5
parent: 60 parent: 60
- uid: 24349
components:
- type: Transform
rot: -1.5707963267948966 rad
pos: 13.5,-26.5
parent: 60
- proto: CommandmentCircuitBoard - proto: CommandmentCircuitBoard
entities: entities:
- uid: 24825 - uid: 24825
@@ -62937,6 +63177,11 @@ entities:
- type: Transform - type: Transform
pos: -16.5,-29.5 pos: -16.5,-29.5
parent: 60 parent: 60
- uid: 23919
components:
- type: Transform
pos: 20.5,-26.5
parent: 60
- proto: DefaultStationBeacon - proto: DefaultStationBeacon
entities: entities:
- uid: 20983 - uid: 20983
@@ -72222,6 +72467,11 @@ entities:
- type: Transform - type: Transform
pos: -7.5,-2.5 pos: -7.5,-2.5
parent: 60 parent: 60
- uid: 23894
components:
- type: Transform
pos: 18.5,-26.5
parent: 60
- proto: Flare - proto: Flare
entities: entities:
- uid: 9525 - uid: 9525
@@ -73130,6 +73380,13 @@ entities:
- type: Transform - type: Transform
pos: -65.522354,23.506481 pos: -65.522354,23.506481
parent: 60 parent: 60
- proto: FloraTreeChristmas02
entities:
- uid: 23913
components:
- type: Transform
pos: 7.9998736,-21.48742
parent: 60
- proto: FoodApple - proto: FoodApple
entities: entities:
- uid: 7496 - uid: 7496
@@ -73262,10 +73519,10 @@ entities:
parent: 60 parent: 60
- proto: FoodCondimentBottleHotsauce - proto: FoodCondimentBottleHotsauce
entities: entities:
- uid: 23671 - uid: 15672
components: components:
- type: Transform - type: Transform
pos: 21.70029,-26.388956 pos: 11.203171,-26.288023
parent: 60 parent: 60
- proto: FoodFrozenSandwich - proto: FoodFrozenSandwich
entities: entities:
@@ -73374,30 +73631,40 @@ entities:
parent: 60 parent: 60
- proto: FoodPlateSmall - proto: FoodPlateSmall
entities: entities:
- uid: 21775 - uid: 14388
components: components:
- type: Transform - type: Transform
pos: 20.513836,-26.289145 pos: 12.531296,-26.131773
parent: 60 parent: 60
- uid: 21789 - uid: 16144
components: components:
- type: Transform - type: Transform
pos: 20.513836,-26.195395 pos: 12.531296,-26.506773
parent: 60 parent: 60
- uid: 23621 - uid: 21774
components: components:
- type: Transform - type: Transform
pos: 20.513836,-26.382895 pos: 12.531296,-26.381773
parent: 60 parent: 60
- uid: 23629 - uid: 23629
components: components:
- type: Transform - type: Transform
pos: 20.513836,-26.507895 pos: 12.531296,-26.303648
parent: 60 parent: 60
- uid: 23630 - uid: 23667
components: components:
- type: Transform - 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 parent: 60
- proto: FoodPoppy - proto: FoodPoppy
entities: entities:
@@ -73512,20 +73779,20 @@ entities:
parent: 60 parent: 60
- proto: Fork - proto: Fork
entities: entities:
- uid: 2584 - uid: 21598
components: components:
- type: Transform - type: Transform
pos: 21.138836,-26.476645 pos: 11.828171,-26.428648
parent: 60 parent: 60
- uid: 23653 - uid: 21775
components: components:
- type: Transform - type: Transform
pos: 21.138836,-26.476645 pos: 11.828171,-26.428648
parent: 60 parent: 60
- uid: 23665 - uid: 23668
components: components:
- type: Transform - type: Transform
pos: 21.138836,-26.476645 pos: 11.828171,-26.428648
parent: 60 parent: 60
- proto: FuelDispenser - proto: FuelDispenser
entities: entities:
@@ -114793,13 +115060,6 @@ entities:
rot: 1.5707963267948966 rad rot: 1.5707963267948966 rad
pos: -12.5,19.5 pos: -12.5,19.5
parent: 60 parent: 60
- uid: 2278
components:
- type: Transform
pos: 18.5,-26.5
parent: 60
- type: ApcPowerReceiver
powerLoad: 0
- uid: 2279 - uid: 2279
components: components:
- type: Transform - type: Transform
@@ -117916,6 +118176,23 @@ entities:
parent: 60 parent: 60
- type: ApcPowerReceiver - type: ApcPowerReceiver
powerLoad: 0 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 - proto: Protolathe
entities: entities:
- uid: 7081 - uid: 7081
@@ -119477,11 +119754,6 @@ entities:
parent: 60 parent: 60
- proto: RandomVendingDrinks - proto: RandomVendingDrinks
entities: entities:
- uid: 3156
components:
- type: Transform
pos: 8.5,-19.5
parent: 60
- uid: 6319 - uid: 6319
components: components:
- type: Transform - type: Transform
@@ -119507,13 +119779,13 @@ entities:
- type: Transform - type: Transform
pos: -37.5,26.5 pos: -37.5,26.5
parent: 60 parent: 60
- proto: RandomVendingSnacks - uid: 23916
entities:
- uid: 666
components: components:
- type: Transform - type: Transform
pos: 7.5,-19.5 pos: 7.5,-19.5
parent: 60 parent: 60
- proto: RandomVendingSnacks
entities:
- uid: 6320 - uid: 6320
components: components:
- type: Transform - type: Transform
@@ -119529,6 +119801,11 @@ entities:
- type: Transform - type: Transform
pos: -38.5,26.5 pos: -38.5,26.5
parent: 60 parent: 60
- uid: 23917
components:
- type: Transform
pos: 8.5,-19.5
parent: 60
- proto: RCD - proto: RCD
entities: entities:
- uid: 1912 - uid: 1912
@@ -131513,20 +131790,20 @@ entities:
parent: 60 parent: 60
- proto: Spoon - proto: Spoon
entities: entities:
- uid: 23666 - uid: 5786
components: components:
- type: Transform - type: Transform
pos: 21.43571,-26.476645 pos: 11.546921,-26.428648
parent: 60 parent: 60
- uid: 23667 - uid: 23893
components: components:
- type: Transform - type: Transform
pos: 21.43571,-26.476645 pos: 11.546921,-26.428648
parent: 60 parent: 60
- uid: 23668 - uid: 23895
components: components:
- type: Transform - type: Transform
pos: 21.43571,-26.476645 pos: 11.546921,-26.428648
parent: 60 parent: 60
- proto: SprayBottle - proto: SprayBottle
entities: entities:
@@ -134805,11 +135082,6 @@ entities:
rot: -1.5707963267948966 rad rot: -1.5707963267948966 rad
pos: 27.5,-32.5 pos: 27.5,-32.5
parent: 60 parent: 60
- uid: 2569
components:
- type: Transform
pos: 19.5,-26.5
parent: 60
- uid: 2681 - uid: 2681
components: components:
- type: Transform - type: Transform
@@ -135421,11 +135693,6 @@ entities:
- type: Transform - type: Transform
pos: 42.5,-1.5 pos: 42.5,-1.5
parent: 60 parent: 60
- uid: 16144
components:
- type: Transform
pos: 20.5,-26.5
parent: 60
- uid: 16410 - uid: 16410
components: components:
- type: Transform - type: Transform
@@ -135699,15 +135966,25 @@ entities:
- type: Transform - type: Transform
pos: -10.5,-34.5 pos: -10.5,-34.5
parent: 60 parent: 60
- uid: 21789
components:
- type: Transform
pos: 13.5,-26.5
parent: 60
- uid: 23424 - uid: 23424
components: components:
- type: Transform - type: Transform
pos: 47.5,12.5 pos: 47.5,12.5
parent: 60 parent: 60
- uid: 23652 - uid: 23665
components: components:
- type: Transform - 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 parent: 60
- uid: 23838 - uid: 23838
components: components:
@@ -135841,10 +136118,12 @@ entities:
- type: Transform - type: Transform
pos: 19.5,-31.5 pos: 19.5,-31.5
parent: 60 parent: 60
- uid: 24416 - proto: TableFancyGreen
entities:
- uid: 23896
components: components:
- type: Transform - type: Transform
pos: 19.5,-28.5 pos: -27.5,-2.5
parent: 60 parent: 60
- proto: TableGlass - proto: TableGlass
entities: entities:
@@ -136982,12 +137261,6 @@ entities:
- type: Transform - type: Transform
pos: -24.5,19.5 pos: -24.5,19.5
parent: 60 parent: 60
- uid: 24348
components:
- type: Transform
rot: 3.141592653589793 rad
pos: 12.5,-26.5
parent: 60
- proto: TargetSyndicate - proto: TargetSyndicate
entities: entities:
- uid: 10824 - uid: 10824
@@ -138090,11 +138363,6 @@ entities:
- type: Transform - type: Transform
pos: 29.5,-22.5 pos: 29.5,-22.5
parent: 60 parent: 60
- uid: 5786
components:
- type: Transform
pos: 18.5,-26.5
parent: 60
- uid: 6039 - uid: 6039
components: components:
- type: Transform - type: Transform
@@ -138125,6 +138393,11 @@ entities:
- type: Transform - type: Transform
pos: 26.5,-7.5 pos: 26.5,-7.5
parent: 60 parent: 60
- uid: 23630
components:
- type: Transform
pos: 15.5,-26.5
parent: 60
- uid: 25214 - uid: 25214
components: components:
- type: Transform - type: Transform
@@ -138181,10 +138454,10 @@ entities:
parent: 60 parent: 60
- proto: VendingMachineCondiments - proto: VendingMachineCondiments
entities: entities:
- uid: 21774 - uid: 23621
components: components:
- type: Transform - type: Transform
pos: 19.5,-26.5 pos: 13.5,-26.5
parent: 60 parent: 60
- proto: VendingMachineCuraDrobe - proto: VendingMachineCuraDrobe
entities: 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 category: cargoproduct-category-name-armory
group: market 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 - type: cargoProduct
id: TrackingImplant id: TrackingImplant
icon: 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 sprite: Objects/Devices/flatpack.rsi
state: solar-assembly-part state: solar-assembly-part
product: CrateEngineeringSolar product: CrateEngineeringSolar
cost: 525 cost: 1250
category: cargoproduct-category-name-engineering category: cargoproduct-category-name-engineering
group: market group: market

View File

@@ -27,3 +27,13 @@
cost: 800 cost: 800
category: cargoproduct-category-name-science category: cargoproduct-category-name-science
group: market 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 category: cargoproduct-category-name-security
group: market 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 - type: cargoProduct
id: SecuritySupplies id: SecuritySupplies
icon: icon:

View File

@@ -69,3 +69,22 @@
amount: 2 amount: 2
- id: MagazinePistol - id: MagazinePistol
amount: 4 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 id: CrateEngineeringSolar
parent: CrateEngineering parent: CrateEngineering
name: solar assembly crate 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: components:
- type: StorageFill - type: StorageFill
contents: contents:
- id: SolarAssemblyFlatpack - id: SolarAssemblyFlatpack
amount: 6 amount: 10
- id: SheetGlass10
amount: 2
- type: entity - type: entity
id: CrateEngineeringShuttle id: CrateEngineeringShuttle

View File

@@ -12,3 +12,15 @@
amount: 2 amount: 2
- id: ClothingMaskSterile - id: ClothingMaskSterile
amount: 2 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 # - Pepperspray
# - GrenadeTeargas # - 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 - type: entity
id: CrateSecuritySupplies id: CrateSecuritySupplies
parent: CrateSecgear parent: CrateSecgear

View File

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

View File

@@ -1,4 +1,4 @@
# Offensive # Offensive
- type: listing - type: listing
id: SpellbookFireball id: SpellbookFireball
name: spellbook-fireball-name name: spellbook-fireball-name
@@ -132,6 +132,34 @@
- !type:ListingLimitedStockCondition - !type:ListingLimitedStockCondition
stock: 1 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 # Upgrades
- type: listing - type: listing
id: SpellbookFireballUpgrade id: SpellbookFireballUpgrade

View File

@@ -1,72 +1,5 @@
- type: dataset - type: localizedDataset
id: names_borer id: NamesBorer
values: values:
- Alcyonium prefix: names-borer-dataset-
- Anomia count: 69
- 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

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