Merge remote-tracking branch 'space-station-14/master'

This commit is contained in:
Ed
2024-04-13 18:59:09 +03:00
74 changed files with 1038 additions and 503 deletions

View File

@@ -9,7 +9,7 @@ indent_style = space
tab_width = 4
# New line preferences
#end_of_line = crlf
end_of_line = crlf:suggestion
insert_final_newline = true
trim_trailing_whitespace = true
@@ -104,6 +104,7 @@ csharp_preferred_modifier_order = public, private, protected, internal, new, abs
# 'using' directive preferences
csharp_using_directive_placement = outside_namespace:silent
csharp_style_namespace_declarations = file_scoped:suggestion
#### C# Formatting Rules ####

View File

@@ -1,5 +1,6 @@
using System.Linq;
using System.Numerics;
using Content.Shared.Atmos;
using Content.Client.UserInterface.Controls;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
@@ -79,7 +80,7 @@ namespace Content.Client.HealthAnalyzer.UI
);
Temperature.Text = Loc.GetString("health-analyzer-window-entity-temperature-text",
("temperature", float.IsNaN(msg.Temperature) ? "N/A" : $"{msg.Temperature - 273f:F1} °C ({msg.Temperature:F1} °K)")
("temperature", float.IsNaN(msg.Temperature) ? "N/A" : $"{msg.Temperature - Atmospherics.T0C:F1} °C ({msg.Temperature:F1} K)")
);
BloodLevel.Text = Loc.GetString("health-analyzer-window-entity-blood-level-text",

View File

@@ -17,7 +17,7 @@ public sealed class StoreBoundUserInterface : BoundUserInterface
private string _windowName = Loc.GetString("store-ui-default-title");
[ViewVariables]
private string _search = "";
private string _search = string.Empty;
[ViewVariables]
private HashSet<ListingData> _listings = new();
@@ -41,7 +41,7 @@ public sealed class StoreBoundUserInterface : BoundUserInterface
_menu.OnCategoryButtonPressed += (_, category) =>
{
_menu.CurrentCategory = category;
SendMessage(new StoreRequestUpdateInterfaceMessage());
_menu?.UpdateListing();
};
_menu.OnWithdrawAttempt += (_, type, amount) =>
@@ -49,11 +49,6 @@ public sealed class StoreBoundUserInterface : BoundUserInterface
SendMessage(new StoreRequestWithdrawMessage(type, amount));
};
_menu.OnRefreshButtonPressed += (_) =>
{
SendMessage(new StoreRequestUpdateInterfaceMessage());
};
_menu.SearchTextUpdated += (_, search) =>
{
_search = search.Trim().ToLowerInvariant();

View File

@@ -15,6 +15,7 @@
Margin="0,0,4,0"
MinSize="48 48"
Stretch="KeepAspectCentered" />
<Control MinWidth="5"/>
<RichTextLabel Name="StoreItemDescription" />
</BoxContainer>
</BoxContainer>

View File

@@ -1,25 +1,91 @@
using Content.Client.GameTicking.Managers;
using Content.Shared.Store;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Graphics;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Client.Store.Ui;
[GenerateTypedNameReferences]
public sealed partial class StoreListingControl : Control
{
public StoreListingControl(string itemName, string itemDescription,
string price, bool canBuy, Texture? texture = null)
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly IEntityManager _entity = default!;
[Dependency] private readonly IGameTiming _timing = default!;
private readonly ClientGameTicker _ticker;
private readonly ListingData _data;
private readonly bool _hasBalance;
private readonly string _price;
public StoreListingControl(ListingData data, string price, bool hasBalance, Texture? texture = null)
{
IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this);
StoreItemName.Text = itemName;
StoreItemDescription.SetMessage(itemDescription);
_ticker = _entity.System<ClientGameTicker>();
StoreItemBuyButton.Text = price;
StoreItemBuyButton.Disabled = !canBuy;
_data = data;
_hasBalance = hasBalance;
_price = price;
StoreItemName.Text = ListingLocalisationHelpers.GetLocalisedNameOrEntityName(_data, _prototype);
StoreItemDescription.SetMessage(ListingLocalisationHelpers.GetLocalisedDescriptionOrEntityDescription(_data, _prototype));
UpdateBuyButtonText();
StoreItemBuyButton.Disabled = !CanBuy();
StoreItemTexture.Texture = texture;
}
private bool CanBuy()
{
if (!_hasBalance)
return false;
var stationTime = _timing.CurTime.Subtract(_ticker.RoundStartTimeSpan);
if (_data.RestockTime > stationTime)
return false;
return true;
}
private void UpdateBuyButtonText()
{
var stationTime = _timing.CurTime.Subtract(_ticker.RoundStartTimeSpan);
if (_data.RestockTime > stationTime)
{
var timeLeftToBuy = stationTime - _data.RestockTime;
StoreItemBuyButton.Text = timeLeftToBuy.Duration().ToString(@"mm\:ss");
}
else
{
StoreItemBuyButton.Text = _price;
}
}
private void UpdateName()
{
var name = ListingLocalisationHelpers.GetLocalisedNameOrEntityName(_data, _prototype);
var stationTime = _timing.CurTime.Subtract(_ticker.RoundStartTimeSpan);
if (_data.RestockTime > stationTime)
{
name += Loc.GetString("store-ui-button-out-of-stock");
}
StoreItemName.Text = name;
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
UpdateBuyButtonText();
UpdateName();
StoreItemBuyButton.Disabled = !CanBuy();
}
}

View File

@@ -12,11 +12,6 @@
HorizontalAlignment="Left"
Access="Public"
HorizontalExpand="True" />
<Button
Name="RefreshButton"
MinWidth="64"
HorizontalAlignment="Right"
Text="Refresh" />
<Button
Name="WithdrawButton"
MinWidth="64"

View File

@@ -1,6 +1,5 @@
using System.Linq;
using Content.Client.Actions;
using Content.Client.GameTicking.Managers;
using Content.Client.Message;
using Content.Shared.FixedPoint;
using Content.Shared.Store;
@@ -11,7 +10,6 @@ using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Client.Store.Ui;
@@ -20,9 +18,6 @@ public sealed partial class StoreMenu : DefaultWindow
{
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IEntitySystemManager _entitySystem = default!;
private readonly ClientGameTicker _gameTicker;
private StoreWithdrawWindow? _withdrawWindow;
@@ -30,21 +25,19 @@ public sealed partial class StoreMenu : DefaultWindow
public event Action<BaseButton.ButtonEventArgs, ListingData>? OnListingButtonPressed;
public event Action<BaseButton.ButtonEventArgs, string>? OnCategoryButtonPressed;
public event Action<BaseButton.ButtonEventArgs, string, int>? OnWithdrawAttempt;
public event Action<BaseButton.ButtonEventArgs>? OnRefreshButtonPressed;
public event Action<BaseButton.ButtonEventArgs>? OnRefundAttempt;
public Dictionary<string, FixedPoint2> Balance = new();
public Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> Balance = new();
public string CurrentCategory = string.Empty;
private List<ListingData> _cachedListings = new();
public StoreMenu(string name)
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_gameTicker = _entitySystem.GetEntitySystem<ClientGameTicker>();
WithdrawButton.OnButtonDown += OnWithdrawButtonDown;
RefreshButton.OnButtonDown += OnRefreshButtonDown;
RefundButton.OnButtonDown += OnRefundButtonDown;
SearchBar.OnTextChanged += _ => SearchTextUpdated?.Invoke(this, SearchBar.Text);
@@ -52,12 +45,12 @@ public sealed partial class StoreMenu : DefaultWindow
Window.Title = name;
}
public void UpdateBalance(Dictionary<string, FixedPoint2> balance)
public void UpdateBalance(Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> balance)
{
Balance = balance;
var currency = balance.ToDictionary(type =>
(type.Key, type.Value), type => _prototypeManager.Index<CurrencyPrototype>(type.Key));
(type.Key, type.Value), type => _prototypeManager.Index(type.Key));
var balanceStr = string.Empty;
foreach (var ((_, amount), proto) in currency)
@@ -80,7 +73,13 @@ public sealed partial class StoreMenu : DefaultWindow
public void UpdateListing(List<ListingData> listings)
{
var sorted = listings.OrderBy(l => l.Priority).ThenBy(l => l.Cost.Values.Sum());
_cachedListings = listings;
UpdateListing();
}
public void UpdateListing()
{
var sorted = _cachedListings.OrderBy(l => l.Priority).ThenBy(l => l.Cost.Values.Sum());
// should probably chunk these out instead. to-do if this clogs the internet tubes.
// maybe read clients prototypes instead?
@@ -96,12 +95,6 @@ public sealed partial class StoreMenu : DefaultWindow
TraitorFooter.Visible = visible;
}
private void OnRefreshButtonDown(BaseButton.ButtonEventArgs args)
{
OnRefreshButtonPressed?.Invoke(args);
}
private void OnWithdrawButtonDown(BaseButton.ButtonEventArgs args)
{
// check if window is already open
@@ -129,10 +122,8 @@ public sealed partial class StoreMenu : DefaultWindow
if (!listing.Categories.Contains(CurrentCategory))
return;
var listingName = ListingLocalisationHelpers.GetLocalisedNameOrEntityName(listing, _prototypeManager);
var listingDesc = ListingLocalisationHelpers.GetLocalisedDescriptionOrEntityDescription(listing, _prototypeManager);
var listingPrice = listing.Cost;
var canBuy = CanBuyListing(Balance, listingPrice);
var hasBalance = HasListingPrice(Balance, listingPrice);
var spriteSys = _entityManager.EntitySysManager.GetEntitySystem<SpriteSystem>();
@@ -154,39 +145,15 @@ public sealed partial class StoreMenu : DefaultWindow
texture = spriteSys.Frame0(action.Icon);
}
}
var listingInStock = ListingInStock(listing);
if (listingInStock != GetListingPriceString(listing))
{
listingName += " (Out of stock)";
canBuy = false;
}
var newListing = new StoreListingControl(listingName, listingDesc, listingInStock, canBuy, texture);
var newListing = new StoreListingControl(listing, GetListingPriceString(listing), hasBalance, texture);
newListing.StoreItemBuyButton.OnButtonDown += args
=> OnListingButtonPressed?.Invoke(args, listing);
StoreListingsContainer.AddChild(newListing);
}
/// <summary>
/// Return time until available or the cost.
/// </summary>
/// <param name="listing"></param>
/// <returns></returns>
public string ListingInStock(ListingData listing)
{
var stationTime = _gameTiming.CurTime.Subtract(_gameTicker.RoundStartTimeSpan);
TimeSpan restockTimeSpan = TimeSpan.FromMinutes(listing.RestockTime);
if (restockTimeSpan > stationTime)
{
var timeLeftToBuy = stationTime - restockTimeSpan;
return timeLeftToBuy.Duration().ToString(@"mm\:ss");
}
return GetListingPriceString(listing);
}
public bool CanBuyListing(Dictionary<string, FixedPoint2> currency, Dictionary<string, FixedPoint2> price)
public bool HasListingPrice(Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> currency, Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> price)
{
foreach (var type in price)
{
@@ -208,7 +175,7 @@ public sealed partial class StoreMenu : DefaultWindow
{
foreach (var (type, amount) in listing.Cost)
{
var currency = _prototypeManager.Index<CurrencyPrototype>(type);
var currency = _prototypeManager.Index(type);
text += Loc.GetString("store-ui-price-display", ("amount", amount),
("currency", Loc.GetString(currency.DisplayName, ("amount", amount))));
}
@@ -229,7 +196,7 @@ public sealed partial class StoreMenu : DefaultWindow
{
foreach (var cat in listing.Categories)
{
var proto = _prototypeManager.Index<StoreCategoryPrototype>(cat);
var proto = _prototypeManager.Index(cat);
if (!allCategories.Contains(proto))
allCategories.Add(proto);
}
@@ -248,12 +215,17 @@ public sealed partial class StoreMenu : DefaultWindow
if (allCategories.Count < 1)
return;
var group = new ButtonGroup();
foreach (var proto in allCategories)
{
var catButton = new StoreCategoryButton
{
Text = Loc.GetString(proto.Name),
Id = proto.ID
Id = proto.ID,
Pressed = proto.ID == CurrentCategory,
Group = group,
ToggleMode = true,
StyleClasses = { "OpenBoth" }
};
catButton.OnPressed += args => OnCategoryButtonPressed?.Invoke(args, catButton.Id);
@@ -269,7 +241,7 @@ public sealed partial class StoreMenu : DefaultWindow
public void UpdateRefund(bool allowRefund)
{
RefundButton.Disabled = !allowRefund;
RefundButton.Visible = allowRefund;
}
private sealed class StoreCategoryButton : Button

View File

@@ -28,12 +28,12 @@ public sealed partial class StoreWithdrawWindow : DefaultWindow
IoCManager.InjectDependencies(this);
}
public void CreateCurrencyButtons(Dictionary<string, FixedPoint2> balance)
public void CreateCurrencyButtons(Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> balance)
{
_validCurrencies.Clear();
foreach (var currency in balance)
{
if (!_prototypeManager.TryIndex<CurrencyPrototype>(currency.Key, out var proto))
if (!_prototypeManager.TryIndex(currency.Key, out var proto))
continue;
_validCurrencies.Add(currency.Value, proto);

View File

@@ -40,7 +40,7 @@ public sealed partial class GunSystem
if (sprite == null) return;
if (!args.AppearanceData.TryGetValue(AmmoVisuals.MagLoaded, out var magloaded) ||
if (args.AppearanceData.TryGetValue(AmmoVisuals.MagLoaded, out var magloaded) &&
magloaded is true)
{
if (!args.AppearanceData.TryGetValue(AmmoVisuals.AmmoMax, out var capacity))

View File

@@ -24,6 +24,14 @@ public sealed partial class AdvertiseComponent : Component
[DataField]
public int MaximumWait { get; private set; } = 10 * 60;
/// <summary>
/// If true, the delay before the first advertisement (at MapInit) will ignore <see cref="MinimumWait"/>
/// and instead be rolled between 0 and <see cref="MaximumWait"/>. This only applies to the initial delay;
/// <see cref="MinimumWait"/> will be respected after that.
/// </summary>
[DataField]
public bool Prewarm = true;
/// <summary>
/// The identifier for the advertisements pack prototype.
/// </summary>

View File

@@ -37,13 +37,14 @@ public sealed class AdvertiseSystem : EntitySystem
private void OnMapInit(EntityUid uid, AdvertiseComponent advert, MapInitEvent args)
{
RandomizeNextAdvertTime(advert);
var prewarm = advert.Prewarm;
RandomizeNextAdvertTime(advert, prewarm);
_nextCheckTime = MathHelper.Min(advert.NextAdvertisementTime, _nextCheckTime);
}
private void RandomizeNextAdvertTime(AdvertiseComponent advert)
private void RandomizeNextAdvertTime(AdvertiseComponent advert, bool prewarm = false)
{
var minDuration = Math.Max(1, advert.MinimumWait);
var minDuration = prewarm ? 0 : Math.Max(1, advert.MinimumWait);
var maxDuration = Math.Max(minDuration, advert.MaximumWait);
var waitDuration = TimeSpan.FromSeconds(_random.Next(minDuration, maxDuration));

View File

@@ -1,11 +1,16 @@
using System.Globalization;
using System.Linq;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking;
using Content.Server.Hands.Systems;
using Content.Server.Inventory;
using Content.Server.Popups;
using Content.Server.Chat.Systems;
using Content.Server.Station.Components;
using Content.Server.Station.Systems;
using Content.Server.StationRecords;
using Content.Server.StationRecords.Systems;
using Content.Shared.StationRecords;
using Content.Shared.UserInterface;
using Content.Shared.Access.Systems;
using Content.Shared.Bed.Cryostorage;
@@ -32,6 +37,7 @@ public sealed class CryostorageSystem : SharedCryostorageSystem
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly AudioSystem _audio = default!;
[Dependency] private readonly AccessReaderSystem _accessReader = default!;
[Dependency] private readonly ChatSystem _chatSystem = default!;
[Dependency] private readonly ClimbSystem _climb = default!;
[Dependency] private readonly ContainerSystem _container = default!;
[Dependency] private readonly GameTicker _gameTicker = default!;
@@ -40,6 +46,7 @@ public sealed class CryostorageSystem : SharedCryostorageSystem
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly StationJobsSystem _stationJobs = default!;
[Dependency] private readonly StationRecordsSystem _stationRecords = default!;
[Dependency] private readonly TransformSystem _transform = default!;
[Dependency] private readonly UserInterfaceSystem _ui = default!;
@@ -163,26 +170,30 @@ public sealed class CryostorageSystem : SharedCryostorageSystem
{
var comp = ent.Comp;
var cryostorageEnt = ent.Comp.Cryostorage;
var station = _station.GetOwningStation(ent);
var name = Name(ent.Owner);
if (!TryComp<CryostorageComponent>(cryostorageEnt, out var cryostorageComponent))
return;
// if we have a session, we use that to add back in all the job slots the player had.
if (userId != null)
{
foreach (var station in _station.GetStationsSet())
foreach (var uniqueStation in _station.GetStationsSet())
{
if (!TryComp<StationJobsComponent>(station, out var stationJobs))
if (!TryComp<StationJobsComponent>(uniqueStation, out var stationJobs))
continue;
if (!_stationJobs.TryGetPlayerJobs(station, userId.Value, out var jobs, stationJobs))
if (!_stationJobs.TryGetPlayerJobs(uniqueStation, userId.Value, out var jobs, stationJobs))
continue;
foreach (var job in jobs)
{
_stationJobs.TryAdjustJobSlot(station, job, 1, clamp: true);
_stationJobs.TryAdjustJobSlot(uniqueStation, job, 1, clamp: true);
}
_stationJobs.TryRemovePlayerJobs(station, userId.Value, stationJobs);
_stationJobs.TryRemovePlayerJobs(uniqueStation, userId.Value, stationJobs);
}
}
@@ -203,12 +214,33 @@ public sealed class CryostorageSystem : SharedCryostorageSystem
_gameTicker.OnGhostAttempt(mind.Value, false);
}
}
comp.AllowReEnteringBody = false;
_transform.SetParent(ent, PausedMap.Value);
cryostorageComponent.StoredPlayers.Add(ent);
Dirty(ent, comp);
UpdateCryostorageUIState((cryostorageEnt.Value, cryostorageComponent));
AdminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(ent):player} was entered into cryostorage inside of {ToPrettyString(cryostorageEnt.Value)}");
if (!TryComp<StationRecordsComponent>(station, out var stationRecords))
return;
var key = new StationRecordKey(_stationRecords.GetRecordByName(station.Value, name) ?? default(uint), station.Value);
var jobName = "Unknown";
if (_stationRecords.TryGetRecord<GeneralStationRecord>(key, out var entry, stationRecords))
jobName = entry.JobTitle;
_stationRecords.RemoveRecord(key, stationRecords);
_chatSystem.DispatchStationAnnouncement(station.Value,
Loc.GetString(
"earlyleave-cryo-announcement",
("character", name),
("job", CultureInfo.CurrentCulture.TextInfo.ToTitleCase(jobName))
), Loc.GetString("earlyleave-cryo-sender"),
playDefaultSound: false
);
}
private void HandleCryostorageReconnection(Entity<CryostorageContainedComponent> entity)

View File

@@ -159,7 +159,6 @@ public sealed class PlantHolderSystem : EntitySystem
if (!_botany.TryGetSeed(seeds, out var seed))
return;
float? seedHealth = seeds.HealthOverride;
var name = Loc.GetString(seed.Name);
var noun = Loc.GetString(seed.Noun);
_popup.PopupCursor(Loc.GetString("plant-holder-component-plant-success-message",
@@ -169,9 +168,9 @@ public sealed class PlantHolderSystem : EntitySystem
component.Seed = seed;
component.Dead = false;
component.Age = 1;
if (seedHealth is float realSeedHealth)
if (seeds.HealthOverride != null)
{
component.Health = realSeedHealth;
component.Health = seeds.HealthOverride.Value;
}
else
{
@@ -288,8 +287,18 @@ public sealed class PlantHolderSystem : EntitySystem
}
component.Health -= (_random.Next(3, 5) * 10);
float? healthOverride;
if (component.Harvest)
{
healthOverride = null;
}
else
{
healthOverride = component.Health;
}
component.Seed.Unique = false;
var seed = _botany.SpawnSeedPacket(component.Seed, Transform(args.User).Coordinates, args.User, component.Health);
var seed = _botany.SpawnSeedPacket(component.Seed, Transform(args.User).Coordinates, args.User, healthOverride);
_randomHelper.RandomOffset(seed, 0.25f);
var displayName = Loc.GetString(component.Seed.DisplayName);
_popup.PopupCursor(Loc.GetString("plant-holder-component-take-sample-message",

View File

@@ -9,7 +9,6 @@ using Content.Shared.Damage.Systems;
using Content.Shared.Explosion;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.IdentityManagement;
using Content.Shared.Input;
using Content.Shared.Inventory.VirtualItem;
using Content.Shared.Movement.Pulling.Components;
@@ -17,8 +16,6 @@ using Content.Shared.Movement.Pulling.Events;
using Content.Shared.Movement.Pulling.Systems;
using Content.Shared.Stacks;
using Content.Shared.Throwing;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.GameStates;
using Robust.Shared.Input.Binding;
using Robust.Shared.Map;
@@ -160,7 +157,7 @@ namespace Content.Server.Hands.Systems
continue;
}
QueueDel(hand.HeldEntity.Value);
TryDrop(args.PullerUid, hand, handsComp: component);
break;
}
}

View File

@@ -1,3 +1,4 @@
using Content.Shared.Damage;
using Robust.Shared.Audio;
namespace Content.Server.ImmovableRod;
@@ -36,4 +37,16 @@ public sealed partial class ImmovableRodComponent : Component
/// </summary>
[DataField("destroyTiles")]
public bool DestroyTiles = true;
/// <summary>
/// If true, this will gib & delete bodies
/// </summary>
[DataField]
public bool ShouldGib = true;
/// <summary>
/// Damage done, if not gibbing
/// </summary>
[DataField]
public DamageSpecifier? Damage;
}

View File

@@ -1,9 +1,10 @@
using Content.Server.Body.Systems;
using Content.Server.Polymorph.Components;
using Content.Server.Popups;
using Content.Shared.Body.Components;
using Content.Shared.Damage;
using Content.Shared.Examine;
using Content.Shared.Popups;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
@@ -22,6 +23,8 @@ public sealed class ImmovableRodSystem : EntitySystem
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly DamageableSystem _damageable = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
public override void Update(float frameTime)
{
@@ -64,11 +67,11 @@ public sealed class ImmovableRodSystem : EntitySystem
var vel = component.DirectionOverride.Degrees switch
{
0f => _random.NextVector2(component.MinSpeed, component.MaxSpeed),
_ => xform.WorldRotation.RotateVec(component.DirectionOverride.ToVec()) * _random.NextFloat(component.MinSpeed, component.MaxSpeed)
_ => _transform.GetWorldRotation(uid).RotateVec(component.DirectionOverride.ToVec()) * _random.NextFloat(component.MinSpeed, component.MaxSpeed)
};
_physics.ApplyLinearImpulse(uid, vel, body: phys);
xform.LocalRotation = (vel - xform.WorldPosition).ToWorldAngle() + MathHelper.PiOver2;
xform.LocalRotation = (vel - _transform.GetWorldPosition(uid)).ToWorldAngle() + MathHelper.PiOver2;
}
}
@@ -94,12 +97,28 @@ public sealed class ImmovableRodSystem : EntitySystem
return;
}
// gib em
// dont delete/hurt self if polymoprhed into a rod
if (TryComp<PolymorphedEntityComponent>(uid, out var polymorphed))
{
if (polymorphed.Parent == ent)
return;
}
// gib or damage em
if (TryComp<BodyComponent>(ent, out var body))
{
component.MobCount++;
_popup.PopupEntity(Loc.GetString("immovable-rod-penetrated-mob", ("rod", uid), ("mob", ent)), uid, PopupType.LargeCaution);
if (!component.ShouldGib)
{
if (component.Damage == null)
return;
_damageable.TryChangeDamage(ent, component.Damage, ignoreResistances: true);
return;
}
_bodySystem.GibBody(ent, body: body);
return;
}

View File

@@ -118,10 +118,12 @@ public sealed partial class PolymorphSystem : EntitySystem
private void OnPolymorphActionEvent(Entity<PolymorphableComponent> ent, ref PolymorphActionEvent args)
{
if (!_proto.TryIndex(args.ProtoId, out var prototype))
if (!_proto.TryIndex(args.ProtoId, out var prototype) || args.Handled)
return;
PolymorphEntity(ent, prototype.Configuration);
args.Handled = true;
}
private void OnRevertPolymorphActionEvent(Entity<PolymorphedEntityComponent> ent,

View File

@@ -66,11 +66,16 @@ public sealed class TegNodeGroup : BaseNodeGroup
public override void LoadNodes(List<Node> groupNodes)
{
DebugTools.Assert(groupNodes.Count <= 3, "The TEG has at most 3 parts");
DebugTools.Assert(_entityManager != null);
base.LoadNodes(groupNodes);
if (groupNodes.Count > 3)
{
// Somehow got more TEG parts. Probably shenanigans. Bail.
return;
}
Generator = groupNodes.OfType<TegNodeGenerator>().SingleOrDefault();
if (Generator != null)
{

View File

@@ -5,7 +5,6 @@ using Content.Server.PDA.Ringer;
using Content.Server.Stack;
using Content.Server.Store.Components;
using Content.Shared.Actions;
using Content.Shared.Administration.Logs;
using Content.Shared.Database;
using Content.Shared.FixedPoint;
using Content.Shared.Hands.EntitySystems;
@@ -99,13 +98,13 @@ public sealed partial class StoreSystem
}
//dictionary for all currencies, including 0 values for currencies on the whitelist
Dictionary<string, FixedPoint2> allCurrency = new();
Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> allCurrency = new();
foreach (var supported in component.CurrencyWhitelist)
{
allCurrency.Add(supported, FixedPoint2.Zero);
if (component.Balance.ContainsKey(supported))
allCurrency[supported] = component.Balance[supported];
if (component.Balance.TryGetValue(supported, out var value))
allCurrency[supported] = value;
}
// TODO: if multiple users are supposed to be able to interact with a single BUI & see different

View File

@@ -1,3 +1,4 @@
using System.Linq;
using Content.Server.Administration.Logs;
using Content.Server.Ensnaring;
using Content.Shared.CombatMode;
@@ -20,7 +21,6 @@ using Content.Shared.Verbs;
using Robust.Server.GameObjects;
using Robust.Shared.Player;
using Robust.Shared.Utility;
using System.Linq;
namespace Content.Server.Strip
{
@@ -111,7 +111,7 @@ namespace Content.Server.Strip
if (TryComp<CombatModeComponent>(user, out var mode) && mode.IsInCombatMode && !openInCombat)
return;
if (TryComp<ActorComponent>(user, out var actor))
if (TryComp<ActorComponent>(user, out var actor) && HasComp<StrippingComponent>(user))
{
if (_userInterfaceSystem.SessionHasOpenUi(strippable, StrippingUiKey.Key, actor.PlayerSession))
return;

View File

@@ -93,6 +93,9 @@ public sealed partial class ActivatableUISystem : EntitySystem
if (component.InHandsOnly)
return;
if (component.AllowedItems != null)
return;
args.Handled = InteractUI(args.User, uid, component);
}
@@ -104,6 +107,9 @@ public sealed partial class ActivatableUISystem : EntitySystem
if (component.RightClickOnly)
return;
if (component.AllowedItems != null)
return;
args.Handled = InteractUI(args.User, uid, component);
}

View File

@@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using Content.Server.Salvage;
using Content.Server.Xenoarchaeology.XenoArtifacts.Triggers.Components;
using Content.Shared.Clothing;
@@ -42,7 +42,7 @@ public sealed class ArtifactMagnetTriggerSystem : EntitySystem
if (!magXform.Coordinates.TryDistance(EntityManager, xform.Coordinates, out var distance))
continue;
if (distance > trigger.Range)
if (distance > trigger.MagbootRange)
continue;
_toActivate.Add(artifactUid);

View File

@@ -301,7 +301,9 @@ public sealed class PullingSystem : EntitySystem
return false;
}
if (pullerComp.NeedsHands && !_handsSystem.TryGetEmptyHand(puller, out _))
if (pullerComp.NeedsHands
&& !_handsSystem.TryGetEmptyHand(puller, out _)
&& pullerComp.Pulling == null)
{
return false;
}
@@ -365,7 +367,7 @@ public sealed class PullingSystem : EntitySystem
return TogglePull(puller.Pulling.Value, pullerUid, pullable);
}
public bool TryStartPull(EntityUid pullerUid, EntityUid pullableUid, EntityUid? user = null,
public bool TryStartPull(EntityUid pullerUid, EntityUid pullableUid,
PullerComponent? pullerComp = null, PullableComponent? pullableComp = null)
{
if (!Resolve(pullerUid, ref pullerComp, false) ||
@@ -387,23 +389,18 @@ public sealed class PullingSystem : EntitySystem
}
// Ensure that the puller is not currently pulling anything.
var oldPullable = pullerComp.Pulling;
if (TryComp<PullableComponent>(pullerComp.Pulling, out var oldPullable)
&& !TryStopPull(pullerComp.Pulling.Value, oldPullable, pullerUid))
return false;
if (oldPullable != null)
{
// Well couldn't stop the old one.
if (!TryStopPull(oldPullable.Value, pullableComp, user))
return false;
}
// Is the pullable currently being pulled by something else?
// Stop anyone else pulling the entity we want to pull
if (pullableComp.Puller != null)
{
// Uhhh
// We're already pulling this item
if (pullableComp.Puller == pullerUid)
return false;
if (!TryStopPull(pullableUid, pullableComp, pullerUid))
if (!TryStopPull(pullableUid, pullableComp, pullableComp.Puller))
return false;
}
@@ -469,7 +466,7 @@ public sealed class PullingSystem : EntitySystem
var pullerUidNull = pullable.Puller;
if (pullerUidNull == null)
return false;
return true;
var msg = new AttemptStopPullingEvent(user);
RaiseLocalEvent(pullableUid, msg, true);

View File

@@ -31,7 +31,7 @@ namespace Content.Shared.Plants
if (args.Handled)
return;
Rustle(uid, component);
Rustle(uid, component, args.User);
args.Handled = _stashSystem.TryHideItem(uid, args.User, args.Used);
}
@@ -40,24 +40,24 @@ namespace Content.Shared.Plants
if (args.Handled)
return;
Rustle(uid, component);
Rustle(uid, component, args.User);
var gotItem = _stashSystem.TryGetItem(uid, args.User);
if (!gotItem)
{
var msg = Loc.GetString("potted-plant-hide-component-interact-hand-got-no-item-message");
_popupSystem.PopupEntity(msg, uid, args.User);
_popupSystem.PopupClient(msg, uid, args.User);
}
args.Handled = gotItem;
}
private void Rustle(EntityUid uid, PottedPlantHideComponent? component = null)
private void Rustle(EntityUid uid, PottedPlantHideComponent? component = null, EntityUid? user = null)
{
if (!Resolve(uid, ref component))
return;
_audio.PlayPvs(component.RustleSound, uid, AudioParams.Default.WithVariation(0.25f));
_audio.PlayPredicted(component.RustleSound, uid, user, AudioParams.Default.WithVariation(0.25f));
}
}
}

View File

@@ -175,7 +175,7 @@ public class RCDSystem : EntitySystem
else
{
var deconstructedTile = _mapSystem.GetTileRef(mapGridData.Value.GridUid, mapGridData.Value.Component, mapGridData.Value.Location);
var protoName = deconstructedTile.IsSpace() ? _deconstructTileProto : _deconstructLatticeProto;
var protoName = !deconstructedTile.IsSpace() ? _deconstructTileProto : _deconstructLatticeProto;
if (_protoManager.TryIndex(protoName, out var deconProto))
{

View File

@@ -11,15 +11,14 @@ public static class ListingLocalisationHelpers
/// </summary>
public static string GetLocalisedNameOrEntityName(ListingData listingData, IPrototypeManager prototypeManager)
{
bool wasLocalised = Loc.TryGetString(listingData.Name, out string? listingName);
var name = string.Empty;
if (!wasLocalised && listingData.ProductEntity != null)
{
var proto = prototypeManager.Index<EntityPrototype>(listingData.ProductEntity);
listingName = proto.Name;
}
if (listingData.Name != null)
name = Loc.GetString(listingData.Name);
else if (listingData.ProductEntity != null)
name = prototypeManager.Index(listingData.ProductEntity.Value).Name;
return listingName ?? listingData.Name;
return name;
}
/// <summary>
@@ -29,14 +28,13 @@ public static class ListingLocalisationHelpers
/// </summary>
public static string GetLocalisedDescriptionOrEntityDescription(ListingData listingData, IPrototypeManager prototypeManager)
{
bool wasLocalised = Loc.TryGetString(listingData.Description, out string? listingDesc);
var desc = string.Empty;
if (!wasLocalised && listingData.ProductEntity != null)
{
var proto = prototypeManager.Index<EntityPrototype>(listingData.ProductEntity);
listingDesc = proto.Description;
}
if (listingData.Description != null)
desc = Loc.GetString(listingData.Description);
else if (listingData.ProductEntity != null)
desc = prototypeManager.Index(listingData.ProductEntity.Value).Description;
return listingDesc ?? listingData.Description;
return desc;
}
}

View File

@@ -2,10 +2,6 @@ using System.Linq;
using Content.Shared.FixedPoint;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
using Robust.Shared.Utility;
namespace Content.Shared.Store;
@@ -26,57 +22,57 @@ public partial class ListingData : IEquatable<ListingData>, ICloneable
/// <summary>
/// The name of the listing. If empty, uses the entity's name (if present)
/// </summary>
[DataField("name")]
public string Name = string.Empty;
[DataField]
public string? Name;
/// <summary>
/// The description of the listing. If empty, uses the entity's description (if present)
/// </summary>
[DataField("description")]
public string Description = string.Empty;
[DataField]
public string? Description;
/// <summary>
/// The categories that this listing applies to. Used for filtering a listing for a store.
/// </summary>
[DataField("categories", required: true, customTypeSerializer: typeof(PrototypeIdListSerializer<StoreCategoryPrototype>))]
public List<string> Categories = new();
[DataField]
public List<ProtoId<StoreCategoryPrototype>> Categories = new();
/// <summary>
/// The cost of the listing. String represents the currency type while the FixedPoint2 represents the amount of that currency.
/// </summary>
[DataField("cost", customTypeSerializer: typeof(PrototypeIdDictionarySerializer<FixedPoint2, CurrencyPrototype>))]
public Dictionary<string, FixedPoint2> Cost = new();
[DataField]
public Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> Cost = new();
/// <summary>
/// Specific customizeable conditions that determine whether or not the listing can be purchased.
/// Specific customizable conditions that determine whether or not the listing can be purchased.
/// </summary>
[NonSerialized]
[DataField("conditions", serverOnly: true)]
[DataField(serverOnly: true)]
public List<ListingCondition>? Conditions;
/// <summary>
/// The icon for the listing. If null, uses the icon for the entity or action.
/// </summary>
[DataField("icon")]
[DataField]
public SpriteSpecifier? Icon;
/// <summary>
/// The priority for what order the listings will show up in on the menu.
/// </summary>
[DataField("priority")]
public int Priority = 0;
[DataField]
public int Priority;
/// <summary>
/// The entity that is given when the listing is purchased.
/// </summary>
[DataField("productEntity", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string? ProductEntity;
[DataField]
public EntProtoId? ProductEntity;
/// <summary>
/// The action that is given when the listing is purchased.
/// </summary>
[DataField("productAction", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string? ProductAction;
[DataField]
public EntProtoId? ProductAction;
/// <summary>
/// The listing ID of the related upgrade listing. Can be used to link a <see cref="ProductAction"/> to an
@@ -95,7 +91,7 @@ public partial class ListingData : IEquatable<ListingData>, ICloneable
/// <summary>
/// The event that is broadcast when the listing is purchased.
/// </summary>
[DataField("productEvent")]
[DataField]
public object? ProductEvent;
[DataField]
@@ -104,13 +100,14 @@ public partial class ListingData : IEquatable<ListingData>, ICloneable
/// <summary>
/// used internally for tracking how many times an item was purchased.
/// </summary>
public int PurchaseAmount = 0;
[DataField]
public int PurchaseAmount;
/// <summary>
/// Used to delay purchase of some items.
/// </summary>
[DataField("restockTime")]
public int RestockTime;
[DataField]
public TimeSpan RestockTime = TimeSpan.Zero;
public bool Equals(ListingData? listing)
{
@@ -173,14 +170,10 @@ public partial class ListingData : IEquatable<ListingData>, ICloneable
}
}
//<inheritdoc>
/// <summary>
/// Defines a set item listing that is available in a store
/// </summary>
[Prototype("listing")]
[Serializable, NetSerializable]
[DataDefinition]
public sealed partial class ListingPrototype : ListingData, IPrototype
{
}
public sealed partial class ListingPrototype : ListingData, IPrototype;

View File

@@ -1,4 +1,5 @@
using Content.Shared.FixedPoint;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared.Store;
@@ -14,13 +15,13 @@ public sealed class StoreUpdateState : BoundUserInterfaceState
{
public readonly HashSet<ListingData> Listings;
public readonly Dictionary<string, FixedPoint2> Balance;
public readonly Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> Balance;
public readonly bool ShowFooter;
public readonly bool AllowRefund;
public StoreUpdateState(HashSet<ListingData> listings, Dictionary<string, FixedPoint2> balance, bool showFooter, bool allowRefund)
public StoreUpdateState(HashSet<ListingData> listings, Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> balance, bool showFooter, bool allowRefund)
{
Listings = listings;
Balance = balance;
@@ -46,9 +47,7 @@ public sealed class StoreInitializeState : BoundUserInterfaceState
[Serializable, NetSerializable]
public sealed class StoreRequestUpdateInterfaceMessage : BoundUserInterfaceMessage
{
public StoreRequestUpdateInterfaceMessage()
{
}
}
[Serializable, NetSerializable]

View File

@@ -43,7 +43,8 @@ public abstract class SharedStrippableSystem : EntitySystem
args.Handled = true;
args.CanDrop |= uid == args.User &&
HasComp<StrippableComponent>(args.Dragged) &&
HasComp<HandsComponent>(args.User);
HasComp<HandsComponent>(args.User) &&
HasComp<StrippingComponent>(args.User);
}
private void OnCanDrop(EntityUid uid, StrippableComponent component, ref CanDropDraggedEvent args)

View File

@@ -34,7 +34,7 @@ public sealed class WieldableSystem : EntitySystem
{
base.Initialize();
SubscribeLocalEvent<WieldableComponent, UseInHandEvent>(OnUseInHand);
SubscribeLocalEvent<WieldableComponent, UseInHandEvent>(OnUseInHand, before: [typeof(SharedGunSystem)]);
SubscribeLocalEvent<WieldableComponent, ItemUnwieldedEvent>(OnItemUnwielded);
SubscribeLocalEvent<WieldableComponent, GotUnequippedHandEvent>(OnItemLeaveHand);
SubscribeLocalEvent<WieldableComponent, VirtualItemDeletedEvent>(OnVirtualItemDeleted);

View File

@@ -2,3 +2,13 @@
license: CC-BY-NC-SA-3.0
copyright: Citadel Station 13
source: https://github.com/Citadel-Station-13/Citadel-Station-13/commit/35a1723e98a60f375df590ca572cc90f1bb80bd5
- files: ["strobeepsilon.ogg"]
license: "CC-BY-SA-3.0"
copyright: "Made by dj-34 (https://github.com/dj-34). Modified by Ko4erga"
source: "https://github.com/ss220-space/Paradise/blob/05043bcfb35c2e7bcf1efbdbfbf976e1a2504bc2/sound/effects/epsilon.ogg"
- files: ["strobe.ogg"]
source: "https://freesound.org/people/blukotek/sounds/431651/"
license: "CC0-1.0"
copyright: "Piotr Zaczek (blukotek) on freesound.org. Modified by Ko4erga"

Binary file not shown.

Binary file not shown.

View File

@@ -1,120 +1,4 @@
Entries:
- author: mirrorcult
changes:
- message: Throwing items now scale a bit when thrown to simulate rising/falling
type: Add
id: 5827
time: '2024-01-30T10:50:41.0000000+00:00'
url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24724
- author: Emisse
changes:
- message: Gemini
type: Remove
id: 5828
time: '2024-01-30T10:54:55.0000000+00:00'
url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24728
- author: CrigCrag
changes:
- message: Added a new large salvage wreck.
type: Add
id: 5829
time: '2024-01-30T10:56:38.0000000+00:00'
url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24656
- author: themias
changes:
- message: Fixed Centcom cargo gifts not being fulfilled
type: Fix
id: 5830
time: '2024-01-30T11:05:20.0000000+00:00'
url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24701
- author: Scribbles0
changes:
- message: You can now make anomaly cores orbit you.
type: Add
id: 5831
time: '2024-01-30T11:12:24.0000000+00:00'
url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24716
- author: MIXnikita
changes:
- message: New sound effects for some shuttle guns
type: Tweak
id: 5832
time: '2024-01-30T13:28:17.0000000+00:00'
url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24714
- author: themias
changes:
- message: Stun batons now toggle off after being drained by an EMP.
type: Fix
id: 5833
time: '2024-01-30T23:04:26.0000000+00:00'
url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24706
- author: Tayrtahn
changes:
- message: Fixed weird rotation while strapped to a bed.
type: Fix
id: 5834
time: '2024-01-30T23:23:31.0000000+00:00'
url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24746
- author: themias
changes:
- message: Some glasses and masks can be worn together to hide your identity.
type: Tweak
id: 5835
time: '2024-01-31T03:49:19.0000000+00:00'
url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24741
- author: mirrorcult
changes:
- message: Throwing recoil reduced further
type: Tweak
id: 5836
time: '2024-01-31T05:00:41.0000000+00:00'
url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24759
- author: mirrorcult
changes:
- message: Various aspects of the station will now be varied automatically at the
start of the round. Expect more trash, some broken/oddly-functioning lights,
and spills (and more stuff in the future).
type: Add
id: 5837
time: '2024-01-31T05:52:35.0000000+00:00'
url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24397
- author: metalgearsloth
changes:
- message: Remove handheld crew monitors in lieu of computers.
type: Remove
id: 5838
time: '2024-01-31T11:23:49.0000000+00:00'
url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24761
- author: Hmeister-real
changes:
- message: You can now Sob and Chortle with emotes
type: Tweak
id: 5839
time: '2024-01-31T11:26:46.0000000+00:00'
url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24585
- author: TheShuEd
changes:
- message: Anomalies can no longer spawn entities in walls or other objects.
type: Fix
id: 5840
time: '2024-01-31T21:05:29.0000000+00:00'
url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24783
- author: EdenTheLiznerd
changes:
- message: The Syndicate has changed around their stock prices and gotten rid of
some old dusty headsets
type: Tweak
id: 5841
time: '2024-02-01T00:28:42.0000000+00:00'
url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24765
- author: metalgearsloth
changes:
- message: Removed vehicles pending rework (the code is bad I was told to make this
more obvious).
type: Remove
id: 5842
time: '2024-02-01T00:33:10.0000000+00:00'
url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24681
- author: Jajsha
changes:
- message: Emagged borgs now recieve laws recontextualizing who's a crew member
@@ -3825,3 +3709,122 @@
id: 6326
time: '2024-04-09T22:20:57.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/26846
- author: notquitehadouken
changes:
- message: Gave botanists droppers for easier chemical moving.
type: Add
id: 6327
time: '2024-04-10T17:28:03.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/26839
- author: botanySupremist
changes:
- message: Clipping harvestable plants now yields undamaged seeds.
type: Add
id: 6328
time: '2024-04-10T17:51:25.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/25541
- author: deltanedas
changes:
- message: Fixed some doors having no access when they should.
type: Fix
id: 6329
time: '2024-04-10T20:06:31.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/26858
- author: Flareguy
changes:
- message: Added emergency nitrogen lockers. You can scarcely find them in public
areas, or scattered around in maintenance tunnels.
type: Add
id: 6330
time: '2024-04-10T21:20:05.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/26752
- author: Jark255
changes:
- message: Door electronics now require network configurators to change their access
settings, rather than doing so by hand.
type: Fix
id: 6331
time: '2024-04-11T12:21:15.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/26888
- author: lunarcomets
changes:
- message: Cryogenic sleep units now remove crew members from the manifest, and
announce when crew members go into cryogenic storage.
type: Tweak
id: 6332
time: '2024-04-11T20:48:46.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/26813
- author: Vermidia
changes:
- message: Salt and Pepper shakers look like shakers.
type: Fix
id: 6333
time: '2024-04-12T06:44:47.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/26899
- author: liltenhead
changes:
- message: Reagent slimes are no longer ghost roles.
type: Remove
id: 6334
time: '2024-04-12T06:50:46.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/26840
- author: TokenStyle
changes:
- message: Notice board can be crafted
type: Add
id: 6335
time: '2024-04-12T06:58:02.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/26847
- author: deltanedas
changes:
- message: Sterile Swabs now come in dispensers making them easier to use.
type: Tweak
id: 6336
time: '2024-04-12T07:15:04.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/24986
- author: Ko4erga
changes:
- message: Strobes added WEE-OOO-WEE-OOO!
type: Add
id: 6337
time: '2024-04-12T08:02:06.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/26083
- author: osjarw
changes:
- message: Magboots no longer activate artifacts from salvage magnet ranges.
type: Fix
id: 6338
time: '2024-04-13T01:46:00.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/26912
- author: Vasilis
changes:
- message: Blood (or anything containing uncooked animal proteins) can only be consumed
by animal stomach's instead of all but human. Attempting to due so will poison
you as intended.
type: Fix
id: 6339
time: '2024-04-13T02:36:29.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/26906
- author: DrSmugleaf
changes:
- message: Fixed incorrect "Cycled" and "Bolted" popups when wielding and unwielding
some guns.
type: Fix
id: 6340
time: '2024-04-13T15:25:54.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/26924
- author: FungiFellow
changes:
- message: Removed Crusher Dagger from Grapple Module
type: Remove
id: 6341
time: '2024-04-13T15:35:10.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/26865
- author: ShadowCommander
changes:
- message: Fixed the pull hotkey not pulling the new entity when you are already
pulling an entity.
type: Fix
id: 6342
time: '2024-04-13T15:36:05.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/26499

View File

@@ -0,0 +1,5 @@
### Announcement
earlyleave-cryo-announcement = {$character} ({$job}) has entered cryogenic storage!
earlyleave-cryo-sender = Station

View File

@@ -6,5 +6,5 @@ store-ui-traitor-flavor = Copyright (C) NT -30643
store-ui-traitor-warning = Operatives must lock their uplinks after use to avoid detection.
store-withdraw-button-ui = Withdraw {$currency}
store-ui-button-out-of-stock = {""} (Out of Stock)
store-not-account-owner = This {$store} is not bound to you!

View File

@@ -88,27 +88,6 @@
- state: box
- state: nitrile
- type: entity
name: sterile swab box
parent: BoxCardboard
id: BoxMouthSwab
components:
- type: Storage
grid:
- 0,0,4,3
- type: StorageFill
contents:
- id: DiseaseSwab
amount: 10
- type: Sprite
layers:
- state: box
- state: swab
- type: GuideHelp
guides:
# - Virology (when it's back)
- Botany
- type: entity
name: body bag box
parent: BoxCardboard

View File

@@ -61,6 +61,21 @@
- id: BoxMRE
prob: 0.1
- type: entity
id: ClosetEmergencyN2FilledRandom
parent: ClosetEmergencyN2
suffix: Filled, Random
components:
- type: StorageFill
contents:
- id: ClothingMaskBreath
- id: EmergencyNitrogenTankFilled
prob: 0.80
orGroup: EmergencyTankOrRegularTank
- id: NitrogenTankFilled
prob: 0.20
orGroup: EmergencyTankOrRegularTank
- type: entity
id: ClosetFireFilled
parent: ClosetFire

View File

@@ -104,6 +104,7 @@
- id: ClothingBeltPlant
- id: PlantBag ##Some maps don't have nutrivend
- id: BoxMouthSwab
- id: Dropper
- id: HandLabeler
- id: ClothingUniformOveralls
- id: ClothingHeadHatTrucker

View File

@@ -6,6 +6,7 @@
HydroponicsToolClippers: 4
HydroponicsToolScythe: 4
HydroponicsToolHatchet: 4
Dropper: 4
PlantBag: 3
PlantBGoneSpray: 20
WeedSpray: 20

View File

@@ -100,7 +100,7 @@
blacklist:
tags:
- NukeOpsUplink
- type: listing
id: UplinkEshield
name: uplink-eshield-name
@@ -314,7 +314,7 @@
Telecrystal: 11
categories:
- UplinkExplosives
restockTime: 30
restockTime: 1800
conditions:
- !type:StoreWhitelistCondition
blacklist:
@@ -478,7 +478,7 @@
Telecrystal: 6
categories:
- UplinkChemicals
- type: listing
id: UplinkHypoDart
name: uplink-hypodart-name
@@ -500,7 +500,7 @@
Telecrystal: 4
categories:
- UplinkChemicals
- type: listing
id: UplinkZombieBundle
name: uplink-zombie-bundle-name
@@ -570,7 +570,7 @@
Telecrystal: 12
categories:
- UplinkChemicals
- type: listing
id: UplinkCigarettes
name: uplink-cigarettes-name
@@ -601,7 +601,7 @@
- SurplusBundle
# Deception
- type: listing
id: UplinkAgentIDCard
name: uplink-agent-id-card-name
@@ -611,7 +611,7 @@
Telecrystal: 3
categories:
- UplinkDeception
- type: listing
id: UplinkStealthBox
name: uplink-stealth-box-name
@@ -639,11 +639,11 @@
description: uplink-binary-translator-key-desc
icon: { sprite: /Textures/Objects/Devices/encryption_keys.rsi, state: rd_label }
productEntity: EncryptionKeyBinary
cost:
cost:
Telecrystal: 1
categories:
- UplinkDeception
- type: listing
id: UplinkCyberpen
name: uplink-cyberpen-name
@@ -663,7 +663,7 @@
Telecrystal: 1
categories:
- UplinkDeception
- type: listing
id: UplinkUltrabrightLantern
name: uplink-ultrabright-lantern-name
@@ -726,7 +726,7 @@
Telecrystal: 8
categories:
- UplinkDisruption
- type: listing
id: UplinkRadioJammer
name: uplink-radio-jammer-name
@@ -766,7 +766,7 @@
Telecrystal: 3
categories:
- UplinkDisruption
- type: listing
id: UplinkToolbox
name: uplink-toolbox-name
@@ -1120,7 +1120,7 @@
whitelist:
tags:
- NukeOpsUplink
- type: listing
id: UplinkUplinkImplanter # uplink uplink real
name: uplink-uplink-implanter-name

View File

@@ -229,6 +229,7 @@
description: It consists of a liquid, and it wants to dissolve you in itself.
components:
- type: GhostRole
prob: 0
description: ghost-role-information-angry-slimes-description
- type: NpcFactionMember
factions:

View File

@@ -2,6 +2,7 @@
parent: DrinkBase
id: DrinkCartonBaseFull
abstract: true
suffix: Full
components:
- type: Openable
sound:

View File

@@ -3,6 +3,7 @@
parent: DrinkBase
id: DrinkBottlePlasticBaseFull
abstract: true
suffix: Full
components:
- type: Tag
tags:
@@ -744,7 +745,7 @@
parent: DrinkBottlePlasticBaseFull
id: DrinkSugarJug
name: sugar jug
suffix: for drinks
suffix: For Drinks, Full
description: some people put this in their coffee...
components:
- type: SolutionContainerManager

View File

@@ -5,6 +5,7 @@
parent: BaseItem
abstract: true
description: An empty bottle.
suffix: Empty
components:
- type: Sprite
state: icon
@@ -93,6 +94,7 @@
parent: BaseItem
abstract: true
description: An empty carton.
suffix: Empty
components:
- type: Sprite
state: icon

View File

@@ -522,7 +522,7 @@
# Shakers
- type: entity
parent: BaseFoodCondimentBottle
parent: BaseFoodCondiment
id: BaseFoodShaker
abstract: true
name: empty shaker
@@ -560,6 +560,8 @@
acts: [ "Destruction" ]
- type: Sprite
state: shaker-empty
- type: RefillableSolution
solution: food
- type: entity
parent: BaseFoodShaker

View File

@@ -17,6 +17,8 @@
whitelist:
tags:
- Burnt
- Cigarette
- Cigar
maxItemSize: Tiny
grid:
- 0,0,9,0
@@ -27,4 +29,4 @@
fillBaseName: icon
maxFillLevels: 10
- type: Appearance
- type: Dumpable
- type: Dumpable

View File

@@ -18,7 +18,7 @@
key: enum.DoorElectronicsConfigurationUiKey.Key
allowedItems:
tags:
- Multitool
- DoorElectronicsConfigurator
- type: UserInterface
interfaces:
- key: enum.DoorElectronicsConfigurationUiKey.Key

View File

@@ -55,6 +55,14 @@
- type: AccessReader
access: [["Hydroponics"]]
- type: entity
parent: DoorElectronics
id: DoorElectronicsLawyer
suffix: Lawyer, Locked
components:
- type: AccessReader
access: [["Lawyer"]]
- type: entity
parent: DoorElectronics
id: DoorElectronicsCaptain
@@ -151,6 +159,14 @@
- type: AccessReader
access: [["Command"]]
- type: entity
parent: DoorElectronics
id: DoorElectronicsCentralCommand
suffix: CentralCommand, Locked
components:
- type: AccessReader
access: [["CentralCommand"]]
- type: entity
parent: DoorElectronics
id: DoorElectronicsChiefMedicalOfficer
@@ -207,6 +223,14 @@
- type: AccessReader
access: [["Security"]]
- type: entity
parent: DoorElectronics
id: DoorElectronicsSecurityLawyer
suffix: Security/Lawyer, Locked
components:
- type: AccessReader
access: [["Security", "Lawyer"]]
- type: entity
parent: DoorElectronics
id: DoorElectronicsDetective
@@ -255,6 +279,14 @@
- type: AccessReader
access: [["SyndicateAgent"]]
- type: entity
parent: DoorElectronics
id: DoorElectronicsNukeop
suffix: Nukeop, Locked
components:
- type: AccessReader
access: [["NuclearOperative"]]
- type: entity
parent: DoorElectronics
id: DoorElectronicsRnDMed

View File

@@ -11,8 +11,6 @@
state: icon
noRot: false
- type: ImmovableRod
- type: TimedDespawn
lifetime: 30.0
- type: Physics
bodyType: Dynamic
linearDamping: 0
@@ -36,8 +34,15 @@
location: immovable rod
- type: entity
id: ImmovableRodDespawn
parent: ImmovableRod
components:
- type: TimedDespawn
lifetime: 30.0
- type: entity
id: ImmovableRodSlow
parent: ImmovableRodDespawn
suffix: Slow
components:
- type: ImmovableRod
@@ -45,7 +50,7 @@
maxSpeed: 5
- type: entity
parent: ImmovableRod
parent: ImmovableRodDespawn
id: ImmovableRodKeepTiles
suffix: Keep Tiles
components:
@@ -53,6 +58,33 @@
destroyTiles: false
hitSoundProbability: 1.0
# For Wizard Polymorph
- type: entity
parent: ImmovableRod
id: ImmovableRodWizard
suffix: Wizard
components:
- type: ImmovableRod
minSpeed: 35
destroyTiles: false
randomizeVelocity: false
shouldGib: false
damage:
types:
Blunt: 200
- type: MovementIgnoreGravity
gravityState: true
- type: InputMover
- type: MovementSpeedModifier
weightlessAcceleration: 5
weightlessModifier: 2
weightlessFriction: 0
friction: 0
frictionNoInput: 0
- type: CanMoveInAir
- type: MovementAlwaysTouching
- type: NoSlip
- type: entity
parent: ImmovableRodKeepTiles
id: ImmovableRodKeepTilesStill

View File

@@ -19,6 +19,27 @@
# - Virology (when it's back)
- Botany
- type: entity
parent: BaseAmmoProvider # this is for cycling swabs out and not spawning 30 entities, trust
id: BoxMouthSwab
name: sterile swab dispenser
description: Dispenses 30 sterile swabs, extremely useful for botany.
components:
- type: Sprite
layers:
- state: boxwide
- state: swab
- type: BallisticAmmoProvider
whitelist:
components:
- BotanySwab
proto: DiseaseSwab
capacity: 30
- type: GuideHelp
guides:
# - Virology (when it's back)
- Botany
- type: entity
parent: BaseItem
id: Vaccine

View File

@@ -222,7 +222,6 @@
- type: ItemBorgModule
items:
- WeaponGrapplingGun
- WeaponCrusherDagger
- HandheldGPSBasic
# engineering modules

View File

@@ -225,6 +225,7 @@
- type: Tag
tags:
- Multitool
- DoorElectronicsConfigurator
- type: PhysicalComposition
materialComposition:
Steel: 100
@@ -266,6 +267,9 @@
- type: ActivatableUI
key: enum.NetworkConfiguratorUiKey.List
inHandsOnly: true
- type: Tag
tags:
- DoorElectronicsConfigurator
- type: UserInterface
interfaces:
- key: enum.NetworkConfiguratorUiKey.List
@@ -343,13 +347,13 @@
description: The rapid construction device can be used to quickly place and remove various station structures and fixtures. Requires compressed matter to function.
components:
- type: RCD
availablePrototypes:
availablePrototypes:
- WallSolid
- FloorSteel
- Plating
- Catwalk
- Grille
- Window
- Window
- WindowDirectional
- WindowReinforcedDirectional
- ReinforcedWindow
@@ -398,7 +402,7 @@
- type: LimitedCharges
charges: 0
- type: RCD
availablePrototypes:
availablePrototypes:
- WallSolid
- FloorSteel
- Plating

View File

@@ -7,19 +7,20 @@
- type: ContainerFill
containers:
board: [ DoorElectronicsService ]
- type: entity
parent: Airlock
id: AirlockLawyerLocked
suffix: Lawyer, Locked
components:
- type: AccessReader
access: [["Lawyer"]]
- type: Wires
layoutId: AirlockService
- type: entity
parent: Airlock
parent: AirlockServiceLocked
id: AirlockLawyerLocked
suffix: Lawyer, Locked
components:
- type: ContainerFill
containers:
board: [ DoorElectronicsLawyer ]
- type: entity
parent: AirlockServiceLocked
id: AirlockTheatreLocked
suffix: Theatre, Locked
components:
@@ -28,7 +29,7 @@
board: [ DoorElectronicsTheatre ]
- type: entity
parent: Airlock
parent: AirlockServiceLocked
id: AirlockChapelLocked
suffix: Chapel, Locked
components:
@@ -37,7 +38,7 @@
board: [ DoorElectronicsChapel ]
- type: entity
parent: Airlock
parent: AirlockServiceLocked
id: AirlockJanitorLocked
suffix: Janitor, Locked
components:
@@ -46,7 +47,7 @@
board: [ DoorElectronicsJanitor ]
- type: entity
parent: Airlock
parent: AirlockServiceLocked
id: AirlockKitchenLocked
suffix: Kitchen, Locked
components:
@@ -55,7 +56,7 @@
board: [ DoorElectronicsKitchen ]
- type: entity
parent: Airlock
parent: AirlockServiceLocked
id: AirlockBarLocked
suffix: Bar, Locked
components:
@@ -64,7 +65,7 @@
board: [ DoorElectronicsBar ]
- type: entity
parent: Airlock
parent: AirlockServiceLocked
id: AirlockHydroponicsLocked
suffix: Hydroponics, Locked
components:
@@ -73,7 +74,7 @@
board: [ DoorElectronicsHydroponics ]
- type: entity
parent: Airlock
parent: AirlockCommandLocked
id: AirlockServiceCaptainLocked
suffix: Captain, Locked
components:
@@ -122,16 +123,18 @@
id: AirlockExternalSyndicateLocked
suffix: External, Syndicate, Locked
components:
- type: AccessReader
access: [["SyndicateAgent"]]
- type: ContainerFill
containers:
board: [ DoorElectronicsSyndicateAgent ]
- type: entity
parent: AirlockExternal
id: AirlockExternalNukeopLocked
suffix: External, Nukeop, Locked
components:
- type: AccessReader
access: [["NuclearOperative"]]
- type: ContainerFill
containers:
board: [ DoorElectronicsNukeop ]
- type: entity
parent: AirlockFreezer
@@ -156,10 +159,9 @@
id: AirlockFreezerHydroponicsLocked
suffix: Hydroponics, Locked
components:
- type: AccessReader
access: [["Hydroponics"]]
- type: Wires
layoutId: AirlockService
- type: ContainerFill
containers:
board: [ DoorElectronicsHydroponics ]
- type: entity
parent: AirlockEngineering
@@ -202,10 +204,9 @@
id: AirlockMiningLocked
suffix: Mining(Salvage), Locked
components:
- type: AccessReader
access: [["Salvage"]]
- type: Wires
layoutId: AirlockService
- type: ContainerFill
containers:
board: [ DoorElectronicsSalvage ]
- type: entity
parent: AirlockMedical
@@ -257,10 +258,9 @@
id: AirlockCentralCommandLocked
suffix: Central Command, Locked
components:
- type: AccessReader
access: [["CentralCommand"]]
- type: Wires
layoutId: AirlockCommand
- type: ContainerFill
containers:
board: [ DoorElectronicsCentralCommand ]
- type: entity
parent: AirlockCommand
@@ -270,8 +270,6 @@
- type: ContainerFill
containers:
board: [ DoorElectronicsCommand ]
- type: Wires
layoutId: AirlockCommand
- type: entity
parent: AirlockCommand
@@ -344,8 +342,6 @@
- type: ContainerFill
containers:
board: [ DoorElectronicsSecurity ]
- type: Wires
layoutId: AirlockSecurity
- type: entity
parent: AirlockSecurity
@@ -355,8 +351,6 @@
- type: ContainerFill
containers:
board: [ DoorElectronicsDetective ]
- type: Wires
layoutId: AirlockSecurity
- type: entity
parent: AirlockSecurity
@@ -366,18 +360,15 @@
- type: ContainerFill
containers:
board: [ DoorElectronicsBrig ]
- type: Wires
layoutId: AirlockSecurity
- type: entity
parent: AirlockSecurity
id: AirlockSecurityLawyerLocked
suffix: Security/Lawyer, Locked
components:
- type: AccessReader
access: [["Security"], ["Lawyer"]]
- type: Wires
layoutId: AirlockSecurity
- type: ContainerFill
containers:
board: [ DoorElectronicsSecurityLawyer ]
- type: entity
parent: AirlockSecurity
@@ -417,26 +408,26 @@
- type: ContainerFill
containers:
board: [ DoorElectronicsService ]
- type: Wires
layoutId: AirlockService
- type: entity
parent: AirlockGlass
parent: AirlockServiceGlassLocked
id: AirlockLawyerGlassLocked
suffix: Lawyer, Locked
components:
- type: AccessReader
access: [["Lawyer"]]
- type: Wires
layoutId: AirlockService
- type: ContainerFill
containers:
board: [ DoorElectronicsLawyer ]
- type: entity
parent: AirlockGlass
parent: AirlockServiceGlassLocked
id: AirlockTheatreGlassLocked
suffix: Theatre, Locked
components:
- type: AccessReader
access: [["Theatre"]]
- type: Wires
layoutId: AirlockService
- type: ContainerFill
containers:
board: [ DoorElectronicsTheatre ]
- type: entity
parent: AirlockGlass
@@ -470,16 +461,18 @@
id: AirlockExternalGlassSyndicateLocked
suffix: External, Glass, Syndicate, Locked
components:
- type: AccessReader
access: [["SyndicateAgent"]]
- type: ContainerFill
containers:
board: [ DoorElectronicsSyndicateAgent ]
- type: entity
parent: AirlockExternalGlass
id: AirlockExternalGlassNukeopLocked
suffix: External, Glass, Nukeop, Locked
components:
- type: AccessReader
access: [["NuclearOperative"]]
- type: ContainerFill
containers:
board: [ DoorElectronicsNukeop ]
- type: entity
parent: AirlockExternalGlass
@@ -500,7 +493,7 @@
board: [ DoorElectronicsAtmospherics ]
- type: entity
parent: AirlockGlass
parent: AirlockServiceGlassLocked
id: AirlockKitchenGlassLocked
suffix: Kitchen, Locked
components:
@@ -509,17 +502,16 @@
board: [ DoorElectronicsKitchen ]
- type: entity
parent: AirlockGlass
parent: AirlockServiceGlassLocked
id: AirlockJanitorGlassLocked
suffix: Janitor, Locked
components:
- type: AccessReader
access: [["Janitor"]]
- type: Wires
layoutId: AirlockService
- type: ContainerFill
containers:
board: [ DoorElectronicsJanitor ]
- type: entity
parent: AirlockGlass
parent: AirlockServiceGlassLocked
id: AirlockHydroGlassLocked
suffix: Hydroponics, Locked
components:
@@ -528,7 +520,7 @@
board: [ DoorElectronicsHydroponics ]
- type: entity
parent: AirlockGlass
parent: AirlockServiceGlassLocked
id: AirlockChapelGlassLocked
suffix: Chapel, Locked
components:
@@ -577,20 +569,18 @@
id: AirlockMiningGlassLocked
suffix: Mining(Salvage), Locked
components:
- type: AccessReader
access: [["Salvage"]]
- type: Wires
layoutId: AirlockCargo
- type: ContainerFill
containers:
board: [ DoorElectronicsSalvage ]
- type: entity
parent: AirlockChemistryGlass
id: AirlockChemistryGlassLocked
suffix: Chemistry, Locked
components:
- type: AccessReader
access: [["Chemistry"]]
- type: Wires
layoutId: AirlockMedical
- type: ContainerFill
containers:
board: [ DoorElectronicsChemistry ]
- type: entity
parent: AirlockMedicalGlass
@@ -633,10 +623,9 @@
id: AirlockCentralCommandGlassLocked
suffix: Central Command, Locked
components:
- type: AccessReader
access: [["CentralCommand"]]
- type: Wires
layoutId: AirlockCommand
- type: ContainerFill
containers:
board: [ DoorElectronicsCentralCommand ]
- type: entity
parent: AirlockCommandGlass
@@ -742,10 +731,9 @@
id: AirlockSecurityLawyerGlassLocked
suffix: Security/Lawyer, Locked
components:
- type: AccessReader
access: [["Security"], ["Lawyer"]]
- type: Wires
layoutId: AirlockSecurity
- type: ContainerFill
containers:
board: [ DoorElectronicsSecurityLawyer ]
- type: entity
parent: AirlockSecurityGlass
@@ -770,16 +758,18 @@
id: AirlockSyndicateGlassLocked
suffix: Syndicate, Locked
components:
- type: AccessReader
access: [["SyndicateAgent"]]
- type: ContainerFill
containers:
board: [ DoorElectronicsSyndicateAgent ]
- type: entity
parent: AirlockSyndicateGlass
id: AirlockSyndicateNukeopGlassLocked
suffix: Nukeop, Locked
components:
- type: AccessReader
access: [["NuclearOperative"]]
- type: ContainerFill
containers:
board: [ DoorElectronicsNukeop ]
# Maintenance Hatches
- type: entity
@@ -855,7 +845,7 @@
board: [ DoorElectronicsAtmospherics ]
- type: entity
parent: AirlockMaint
parent: AirlockMaintServiceLocked
id: AirlockMaintBarLocked
suffix: Bar, Locked
components:
@@ -864,7 +854,7 @@
board: [ DoorElectronicsBar ]
- type: entity
parent: AirlockMaint
parent: AirlockMaintServiceLocked
id: AirlockMaintChapelLocked
suffix: Chapel, Locked
components:
@@ -873,7 +863,7 @@
board: [ DoorElectronicsChapel ]
- type: entity
parent: AirlockMaint
parent: AirlockMaintServiceLocked
id: AirlockMaintHydroLocked
suffix: Hydroponics, Locked
components:
@@ -882,7 +872,7 @@
board: [ DoorElectronicsHydroponics ]
- type: entity
parent: AirlockMaint
parent: AirlockMaintServiceLocked
id: AirlockMaintJanitorLocked
suffix: Janitor, Locked
components:
@@ -891,27 +881,27 @@
board: [ DoorElectronicsJanitor ]
- type: entity
parent: AirlockMaint
parent: AirlockMaintServiceLocked
id: AirlockMaintLawyerLocked
suffix: Lawyer, Locked
components:
- type: AccessReader
access: [["Lawyer"]]
- type: Wires
layoutId: AirlockService
- type: ContainerFill
containers:
board: [ DoorElectronicsLawyer ]
- type: entity
parent: AirlockMaint
id: AirlockMaintServiceLocked
suffix: Service, Locked
components:
- type: AccessReader
access: [["Service"]]
- type: ContainerFill
containers:
board: [ DoorElectronicsService ]
- type: Wires
layoutId: AirlockService
- type: entity
parent: AirlockMaint
parent: AirlockMaintServiceLocked
id: AirlockMaintTheatreLocked
suffix: Theatre, Locked
components:
@@ -920,7 +910,7 @@
board: [ DoorElectronicsTheatre ]
- type: entity
parent: AirlockMaint
parent: AirlockMaintServiceLocked
id: AirlockMaintKitchenLocked
suffix: Kitchen, Locked
components:
@@ -945,9 +935,11 @@
- type: ContainerFill
containers:
board: [ DoorElectronicsMedical ]
- type: Wires
layoutId: AirlockMedical
- type: entity
parent: AirlockMaint
parent: AirlockMaintMedLocked
id: AirlockMaintChemLocked
suffix: Chemistry, Locked
components:
@@ -963,9 +955,11 @@
- type: ContainerFill
containers:
board: [ DoorElectronicsResearch ]
- type: Wires
layoutId: AirlockScience
- type: entity
parent: AirlockMaint
parent: AirlockMaintRnDLocked
id: AirlockMaintRnDMedLocked
suffix: Medical/Science, Locked
components:
@@ -981,9 +975,11 @@
- type: ContainerFill
containers:
board: [ DoorElectronicsSecurity ]
- type: Wires
layoutId: AirlockSecurity
- type: entity
parent: AirlockMaint
parent: AirlockMaintSecLocked
id: AirlockMaintDetectiveLocked
suffix: Detective, Locked
components:
@@ -992,7 +988,7 @@
board: [ DoorElectronicsDetective ]
- type: entity
parent: AirlockMaint
parent: AirlockMaintCommandLocked
id: AirlockMaintHOPLocked
suffix: HeadOfPersonnel, Locked
components:
@@ -1001,7 +997,7 @@
board: [ DoorElectronicsHeadOfPersonnel ]
- type: entity
parent: AirlockMaint
parent: AirlockMaintCommandLocked
id: AirlockMaintCaptainLocked
suffix: Captain, Locked
components:
@@ -1010,70 +1006,69 @@
board: [ DoorElectronicsCaptain ]
- type: entity
parent: AirlockMaint
parent: AirlockMaintCommandLocked
id: AirlockMaintChiefEngineerLocked
suffix: ChiefEngineer, Locked
components:
- type: AccessReader
access: [["ChiefEngineer"]]
- type: Wires
layoutId: AirlockCommand
- type: ContainerFill
containers:
board: [ DoorElectronicsChiefEngineer ]
- type: entity
parent: AirlockMaint
parent: AirlockMaintCommandLocked
id: AirlockMaintChiefMedicalOfficerLocked
suffix: ChiefMedicalOfficer, Locked
components:
- type: AccessReader
access: [["ChiefMedicalOfficer"]]
- type: Wires
layoutId: AirlockCommand
- type: ContainerFill
containers:
board: [ DoorElectronicsChiefMedicalOfficer ]
- type: entity
parent: AirlockMaint
parent: AirlockMaintCommandLocked
id: AirlockMaintHeadOfSecurityLocked
suffix: HeadOfSecurity, Locked
components:
- type: AccessReader
access: [["HeadOfSecurity"]]
- type: Wires
layoutId: AirlockCommand
- type: ContainerFill
containers:
board: [ DoorElectronicsHeadOfSecurity ]
- type: entity
parent: AirlockMaint
parent: AirlockMaintCommandLocked
id: AirlockMaintResearchDirectorLocked
suffix: ResearchDirector, Locked
components:
- type: AccessReader
access: [["ResearchDirector"]]
- type: Wires
layoutId: AirlockCommand
- type: ContainerFill
containers:
board: [ DoorElectronicsResearchDirector ]
- type: entity
parent: AirlockMaint
id: AirlockMaintArmoryLocked
suffix: Armory, Locked
components:
- type: AccessReader
access: [["Armory"]]
- type: ContainerFill
containers:
board: [ DoorElectronicsArmory ]
- type: Wires
layoutId: AirlockSecurity
layoutId: AirlockArmory
- type: entity
parent: AirlockSyndicate
id: AirlockSyndicateLocked
suffix: Syndicate, Locked
components:
- type: AccessReader
access: [["SyndicateAgent"]]
- type: ContainerFill
containers:
board: [ DoorElectronicsSyndicateAgent ]
- type: entity
parent: AirlockSyndicate
id: AirlockSyndicateNukeopLocked
suffix: Nukeop, Locked
components:
- type: AccessReader
access: [["NuclearOperative"]]
- type: ContainerFill
containers:
board: [ DoorElectronicsNukeop ]
# Shuttle airlocks
- type: entity
@@ -1090,16 +1085,18 @@
id: AirlockExternalShuttleSyndicateLocked
suffix: External, Docking, Syndicate, Locked
components:
- type: AccessReader
access: [["SyndicateAgent"]]
- type: ContainerFill
containers:
board: [ DoorElectronicsSyndicateAgent ]
- type: entity
parent: AirlockShuttleSyndicate
id: AirlockExternalShuttleNukeopLocked
suffix: External, Docking, Nukeop, Locked
components:
- type: AccessReader
access: [["NuclearOperative"]]
- type: ContainerFill
containers:
board: [ DoorElectronicsNukeop ]
- type: entity
parent: AirlockGlassShuttle
@@ -1115,42 +1112,44 @@
id: AirlockExternalGlassShuttleSyndicateLocked
suffix: Syndicate, Locked, Glass
components:
- type: AccessReader
access: [["SyndicateAgent"]]
- type: ContainerFill
containers:
board: [ DoorElectronicsSyndicateAgent ]
- type: entity
parent: AirlockGlassShuttleSyndicate
id: AirlockExternalGlassShuttleNukeopLocked
suffix: Nukeop, Locked, Glass
components:
- type: AccessReader
access: [["NuclearOperative"]]
- type: ContainerFill
containers:
board: [ DoorElectronicsNukeop ]
- type: entity
parent: AirlockGlassShuttle
id: AirlockExternalGlassShuttleEmergencyLocked
suffix: External, Emergency, Glass, Docking, Locked
components:
- type: PriorityDock
tag: DockEmergency
- type: ContainerFill
containers:
board: [ DoorElectronicsExternal ]
- type: PriorityDock
tag: DockEmergency
- type: ContainerFill
containers:
board: [ DoorElectronicsExternal ]
- type: entity
parent: AirlockGlassShuttle
id: AirlockExternalGlassShuttleArrivals
suffix: External, Arrivals, Glass, Docking
components:
- type: PriorityDock
tag: DockArrivals
- type: PriorityDock
tag: DockArrivals
- type: entity
parent: AirlockGlassShuttle
id: AirlockExternalGlassShuttleEscape
suffix: External, Escape 3x4, Glass, Docking
components:
- type: GridFill
- type: GridFill
#HighSecDoors
- type: entity
@@ -1158,8 +1157,9 @@
id: HighSecCentralCommandLocked
suffix: Central Command, Locked
components:
- type: AccessReader
access: [["CentralCommand"]]
- type: ContainerFill
containers:
board: [ DoorElectronicsCentralCommand ]
- type: entity
parent: HighSecDoor

View File

@@ -5,6 +5,8 @@
components:
- type: Sprite
sprite: Structures/Doors/Airlocks/Standard/freezer.rsi
- type: Wires
layoutId: AirlockService
- type: entity
parent: Airlock
@@ -15,6 +17,8 @@
sprite: Structures/Doors/Airlocks/Standard/engineering.rsi
- type: PaintableAirlock
department: Engineering
- type: Wires
layoutId: AirlockEngineering
- type: entity
parent: AirlockEngineering
@@ -33,6 +37,8 @@
sprite: Structures/Doors/Airlocks/Standard/cargo.rsi
- type: PaintableAirlock
department: Cargo
- type: Wires
layoutId: AirlockCargo
- type: entity
parent: Airlock
@@ -43,6 +49,8 @@
sprite: Structures/Doors/Airlocks/Standard/medical.rsi
- type: PaintableAirlock
department: Medical
- type: Wires
layoutId: AirlockMedical
- type: entity
parent: AirlockMedical
@@ -66,6 +74,8 @@
sprite: Structures/Doors/Airlocks/Standard/science.rsi
- type: PaintableAirlock
department: Science
- type: Wires
layoutId: AirlockScience
- type: entity
parent: Airlock
@@ -78,6 +88,8 @@
securityLevel: medSecurity
- type: PaintableAirlock
department: Command
- type: Wires
layoutId: AirlockCommand
- type: entity
parent: Airlock
@@ -88,6 +100,8 @@
sprite: Structures/Doors/Airlocks/Standard/security.rsi
- type: PaintableAirlock
department: Security
- type: Wires
layoutId: AirlockSecurity
- type: entity
parent: Airlock
@@ -112,6 +126,8 @@
components:
- type: Sprite
sprite: Structures/Doors/Airlocks/Standard/mining.rsi
- type: Wires
layoutId: AirlockCargo
- type: entity
parent: AirlockCommand # if you get centcom door somehow it counts as command, also inherit panel
@@ -147,6 +163,8 @@
sprite: Structures/Doors/Airlocks/Glass/engineering.rsi
- type: PaintableAirlock
department: Engineering
- type: Wires
layoutId: AirlockEngineering
- type: entity
parent: AirlockGlass
@@ -173,6 +191,8 @@
sprite: Structures/Doors/Airlocks/Glass/cargo.rsi
- type: PaintableAirlock
department: Cargo
- type: Wires
layoutId: AirlockCargo
- type: entity
parent: AirlockGlass
@@ -183,6 +203,8 @@
sprite: Structures/Doors/Airlocks/Glass/medical.rsi
- type: PaintableAirlock
department: Medical
- type: Wires
layoutId: AirlockMedical
- type: entity
parent: AirlockMedicalGlass
@@ -206,6 +228,8 @@
sprite: Structures/Doors/Airlocks/Glass/science.rsi
- type: PaintableAirlock
department: Science
- type: Wires
layoutId: AirlockScience
- type: entity
parent: AirlockGlass
@@ -218,6 +242,8 @@
department: Command
- type: WiresPanelSecurity
securityLevel: medSecurity
- type: Wires
layoutId: AirlockCommand
- type: entity
parent: AirlockGlass
@@ -228,6 +254,8 @@
sprite: Structures/Doors/Airlocks/Glass/security.rsi
- type: PaintableAirlock
department: Security
- type: Wires
layoutId: AirlockSecurity
- type: entity
parent: AirlockSecurityGlass # see standard
@@ -252,5 +280,3 @@
components:
- type: Sprite
sprite: Structures/Doors/Airlocks/Glass/centcomm.rsi
- type: WiresPanelSecurity
securityLevel: medSecurity

View File

@@ -0,0 +1,148 @@
- type: entity
id: AlwaysPoweredStrobeLight
name: strobe
description: "UH?! Sorry, all I can hear is WEE-OOO-WEE-OOO!"
suffix: Always powered
components:
- type: AmbientSound
volume: -15
range: 2
sound:
path: /Audio/Ambience/Objects/light_hum.ogg
- type: MeleeSound
soundGroups:
Brute:
collection: GlassSmash
- type: Transform
anchored: true
- type: Clickable
- type: InteractionOutline
- type: Construction
graph: LightFixture
node: bulbLight
- type: Sprite
sprite: Structures/Wallmounts/Lighting/strobe_light.rsi
drawdepth: WallMountedItems
layers:
- map: ["enum.PoweredLightLayers.Base"]
state: base
- map: ["enum.PoweredLightLayers.Glow"]
state: glow
shader: unshaded
state: base
- type: PointLight
mask: /Textures/Effects/LightMasks/double_cone.png
color: "#FFE4CE"
energy: 5
radius: 10
softness: 1
offset: "0, 0.35"
- type: RotatingLight
- type: Damageable
damageContainer: Inorganic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 100
behaviors: #excess damage, don't spawn entities.
- !type:DoActsBehavior
acts: [ "Destruction" ]
- trigger:
!type:DamageTrigger
damage: 25
behaviors:
- !type:EmptyAllContainersBehaviour
- !type:SpawnEntitiesBehavior
spawn:
SheetSteel1:
min: 1
max: 1
- !type:DoActsBehavior
acts: ["Destruction"]
placement:
mode: SnapgridCenter
snap:
- Wallmount
- type: entity
name: strobe
description: "UH?! Sorry, all I can hear is WEE-OOO-WEE-OOO!"
id: PoweredStrobeLightEmpty
suffix: Empty
parent: AlwaysPoweredStrobeLight
components:
- type: Sprite
sprite: Structures/Wallmounts/Lighting/strobe_light.rsi
state: empty
- type: AmbientSound
enabled: false
- type: PointLight
enabled: false
offset: "0, 0.35"
- type: ContainerContainer
containers:
light_bulb: !type:ContainerSlot
- type: PoweredLight
bulb: Bulb
on: false
damage:
types:
Heat: 5
- type: ApcPowerReceiver
- type: ExtensionCableReceiver
- type: DeviceNetwork
deviceNetId: Wireless
receiveFrequencyId: SmartLight
- type: WirelessNetworkConnection
range: 200
- type: Appearance
- type: PoweredLightVisuals
spriteStateMap:
empty: empty
broken: broken
burned: broken
off: base
on: base
- type: DeviceLinkSink
ports:
- On
- Off
- Toggle
- type: Construction
graph: LightFixture
node: strobeLight
- type: entity
id: PoweredStrobeLightPolice
suffix: "Empty, police"
parent: PoweredStrobeLightEmpty
components:
- type: AmbientSound
volume: 0
range: 10
sound:
path: "/Audio/Effects/Lightning/strobe.ogg"
- type: entity
id: PoweredStrobeLightSiren
suffix: "Empty, siren"
parent: PoweredStrobeLightEmpty
components:
- type: AmbientSound
volume: 0
range: 10
sound:
path: "/Audio/Misc/siren.ogg"
- type: entity
id: PoweredStrobeLightEpsilon
suffix: "Empty, epsilon"
parent: PoweredStrobeLightEmpty
components:
- type: AmbientSound
volume: 0
range: 10
sound:
path: "/Audio/Effects/Lightning/strobeepsilon.ogg"

View File

@@ -19,8 +19,8 @@
damageModifierSet: Metallic
- type: RCDDeconstructable
cost: 2
delay: 2
fx: EffectRCDDeconstruct2
delay: 0
fx: EffectRCDConstruct0
- type: Destructible
thresholds:
- trigger:

View File

@@ -45,8 +45,8 @@
node: power
- type: RCDDeconstructable
cost: 2
delay: 2
fx: EffectRCDDeconstruct2
delay: 0
fx: EffectRCDConstruct0
- type: entity
parent: CableBase

View File

@@ -37,6 +37,19 @@
stateDoorOpen: emergency_open
stateDoorClosed: emergency_door
# Emergency N2 closet
- type: entity
id: ClosetEmergencyN2
name: emergency nitrogen closet
parent: ClosetSteelBase
description: It's full of life-saving equipment. Assuming, that is, that you breathe nitrogen.
components:
- type: Appearance
- type: EntityStorageVisuals
stateBaseClosed: fire
stateDoorOpen: fire_open
stateDoorClosed: n2_door
# Fire safety closet
- type: entity
id: ClosetFire

View File

@@ -2,6 +2,8 @@
id: NoticeBoard
name: notice board
description: Is there a job for a witcher?
placement:
mode: SnapgridCenter
components:
- type: WallMount
- type: Sprite
@@ -53,3 +55,9 @@
- type: ContainerContainer
containers:
storagebase: !type:Container
- type: Tag
tags:
- Wooden
- type: Construction
graph: NoticeBoard
node: noticeBoard

View File

@@ -17,9 +17,9 @@
name: rcd-component-deconstruct
mode: Deconstruct
cost: 2
delay: 1
delay: 0
rotation: Camera
fx: EffectRCDDeconstruct2
fx: EffectRCDConstruct0
- type: rcd
id: DeconstructTile # Hidden prototype - do not add to RCDs

View File

@@ -479,7 +479,9 @@
- !type:PopupMessage
conditions:
- !type:OrganType
type: Human
type: Animal
shouldHave: false
reagent: Protein
type: Local
visualType: MediumCaution
messages: [ "generic-reagent-effect-sick" ]
@@ -488,19 +490,21 @@
probability: 0.1
conditions:
- !type:OrganType
type: Human
type: Animal
shouldHave: false
- !type:HealthChange
conditions:
- !type:OrganType
type: Human
type: Animal
shouldHave: false
damage:
types:
Poison: 1
- !type:AdjustReagent
conditions:
- !type:OrganType
type: Human
shouldHave: false
type: Animal
shouldHave: true
reagent: Protein
amount: 0.5

View File

@@ -0,0 +1,26 @@
- type: constructionGraph
id: NoticeBoard
start: start
graph:
- node: start
actions:
- !type:DestroyEntity {}
edges:
- to: noticeBoard
completed:
- !type:SnapToGrid { }
steps:
- material: WoodPlank
amount: 3
doAfter: 2
- node: noticeBoard
entity: NoticeBoard
edges:
- to: start
completed:
- !type:SpawnPrototype
prototype: MaterialWoodPlank
amount: 3
steps:
- tool: Prying
doAfter: 3

View File

@@ -19,6 +19,11 @@
- material: Steel
amount: 5
doAfter: 2.0
- to: strobeLight
steps:
- material: Steel
amount: 1
doAfter: 2.0
- node: tubeLight
entity: PoweredlightEmpty
edges:
@@ -63,4 +68,19 @@
- !type:SpawnPrototype
prototype: SheetSteel1
amount: 5
- !type:DeleteEntity {}
- node: strobeLight
entity: PoweredStrobeLightEmpty
edges:
- to: start
conditions:
- !type:ContainerEmpty
container: "light_bulb"
steps:
- tool: Screwing
doAfter: 2.0
completed:
- !type:SpawnPrototype
prototype: SheetSteel1
amount: 1
- !type:DeleteEntity {}

View File

@@ -884,3 +884,21 @@
canBuildInImpassable: false
conditions:
- !type:TileNotBlocked
- type: construction
id: NoticeBoard
name: notice board
description: Wooden notice board, can store paper inside itself.
graph: NoticeBoard
startNode: start
targetNode: noticeBoard
category: construction-category-furniture
icon:
sprite: Structures/Wallmounts/noticeboard.rsi
state: noticeboard
objectType: Structure
placementMode: SnapgridCenter
canRotate: true
canBuildInImpassable: false
conditions:
- !type:TileNotBlocked

View File

@@ -1472,6 +1472,24 @@
conditions:
- !type:TileNotBlocked
- type: construction
name: strobe light
id: LightStrobeFixture
graph: LightFixture
startNode: start
targetNode: strobeLight
category: construction-category-structures
description: A wall light fixture. Use light bulbs.
icon:
sprite: Structures/Wallmounts/Lighting/strobe_light.rsi
state: base
objectType: Structure
placementMode: SnapgridCenter
canRotate: true
canBuildInImpassable: false
conditions:
- !type:TileNotBlocked
#conveyor
- type: construction
name: conveyor belt

View File

@@ -523,6 +523,9 @@
- type: Tag
id: DoorElectronics
- type: Tag
id: DoorElectronicsConfigurator
- type: Tag
id: DrinkBottle
@@ -1177,7 +1180,7 @@
- type: Tag
id: SuitEVA
- type: Tag
id: Sunglasses

View File

@@ -4,7 +4,7 @@
"x": 32,
"y": 32
},
"copyright": "Taken from tgstation, brigmedic locker is a resprited CMO locker by PuroSlavKing (Github)",
"copyright": "Taken from tgstation, brigmedic locker is a resprited CMO locker by PuroSlavKing (Github), n2_door state modified by Flareguy from fire_door, using sprites from /vg/station at https://github.com/vgstation-coders/vgstation13/commit/02b9f6894af4419c9f7e699a22c402b086d8067e",
"license": "CC-BY-SA-3.0",
"states": [
{
@@ -398,6 +398,9 @@
{
"name": "mixed_door"
},
{
"name": "n2_door"
},
{
"name": "oldcloset"
},

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,27 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "by Ko4erga (discord)",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "base",
"directions": 4
},
{
"name": "empty",
"directions": 4
},
{
"name": "glow",
"directions": 4
},
{
"name": "broken",
"directions": 4
}
]
}