diff --git a/Content.Client/Nyanotrasen/Kitchen/Components/DeepFriedComponent.cs b/Content.Client/Nyanotrasen/Kitchen/Components/DeepFriedComponent.cs
new file mode 100644
index 00000000000..a1252cf43ed
--- /dev/null
+++ b/Content.Client/Nyanotrasen/Kitchen/Components/DeepFriedComponent.cs
@@ -0,0 +1,10 @@
+using Content.Shared.Kitchen.Components;
+
+namespace Content.Client.Kitchen.Components
+{
+ [RegisterComponent]
+ //Unnecessary item: [ComponentReference(typeof(SharedDeepFriedComponent))]
+ public sealed partial class DeepFriedComponent : SharedDeepFriedComponent
+ {
+ }
+}
diff --git a/Content.Client/Nyanotrasen/Kitchen/Components/DeepFryerComponent.cs b/Content.Client/Nyanotrasen/Kitchen/Components/DeepFryerComponent.cs
new file mode 100644
index 00000000000..4123eb341ca
--- /dev/null
+++ b/Content.Client/Nyanotrasen/Kitchen/Components/DeepFryerComponent.cs
@@ -0,0 +1,10 @@
+using Content.Shared.Kitchen.Components;
+
+namespace Content.Client.Kitchen.Components
+{
+ [RegisterComponent]
+ // Unnecessary line: [ComponentReference(typeof(SharedDeepFryerComponent))]
+ public sealed partial class DeepFryerComponent : SharedDeepFryerComponent
+ {
+ }
+}
diff --git a/Content.Client/Nyanotrasen/Kitchen/UI/DeepFryerBoundUserInterface.cs b/Content.Client/Nyanotrasen/Kitchen/UI/DeepFryerBoundUserInterface.cs
new file mode 100644
index 00000000000..8db884328e4
--- /dev/null
+++ b/Content.Client/Nyanotrasen/Kitchen/UI/DeepFryerBoundUserInterface.cs
@@ -0,0 +1,64 @@
+using Robust.Client.GameObjects;
+using Content.Shared.Kitchen.UI;
+
+namespace Content.Client.Nyanotrasen.Kitchen.UI
+{
+ public sealed class DeepFryerBoundUserInterface : BoundUserInterface
+ {
+ private DeepFryerWindow? _window;
+
+ private NetEntity[] _entities = default!;
+
+ public DeepFryerBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
+ {
+ base.Open();
+ _window = new DeepFryerWindow();
+ _window.OnClose += Close;
+ _window.ItemList.OnItemSelected += args =>
+ {
+ SendMessage(new DeepFryerRemoveItemMessage(_entities[args.ItemIndex]));
+ };
+ _window.InsertItem.OnPressed += _ =>
+ {
+ SendMessage(new DeepFryerInsertItemMessage());
+ };
+ _window.ScoopVat.OnPressed += _ =>
+ {
+ SendMessage(new DeepFryerScoopVatMessage());
+ };
+ _window.ClearSlag.OnPressed += args =>
+ {
+ SendMessage(new DeepFryerClearSlagMessage());
+ };
+ _window.RemoveAllItems.OnPressed += _ =>
+ {
+ SendMessage(new DeepFryerRemoveAllItemsMessage());
+ };
+ _window.OpenCentered();
+ }
+
+ protected override void UpdateState(BoundUserInterfaceState state)
+ {
+ base.UpdateState(state);
+
+ if (_window == null)
+ return;
+
+ if (state is not DeepFryerBoundUserInterfaceState cast)
+ return;
+
+ _entities = cast.ContainedEntities;
+ _window.UpdateState(cast);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+
+ if (!disposing)
+ return;
+
+ _window?.Dispose();
+ }
+ }
+}
diff --git a/Content.Client/Nyanotrasen/Kitchen/UI/DeepFryerWindow.xaml b/Content.Client/Nyanotrasen/Kitchen/UI/DeepFryerWindow.xaml
new file mode 100644
index 00000000000..6ada0b95baf
--- /dev/null
+++ b/Content.Client/Nyanotrasen/Kitchen/UI/DeepFryerWindow.xaml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content.Client/Nyanotrasen/Kitchen/UI/DeepFryerWindow.xaml.cs b/Content.Client/Nyanotrasen/Kitchen/UI/DeepFryerWindow.xaml.cs
new file mode 100644
index 00000000000..7eb8eabd2ca
--- /dev/null
+++ b/Content.Client/Nyanotrasen/Kitchen/UI/DeepFryerWindow.xaml.cs
@@ -0,0 +1,71 @@
+using Robust.Client.AutoGenerated;
+using Robust.Client.GameObjects;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface.CustomControls;
+using Robust.Client.UserInterface.XAML;
+using Content.Shared.Kitchen.UI;
+
+namespace Content.Client.Nyanotrasen.Kitchen.UI
+{
+ [GenerateTypedNameReferences]
+ [Access(typeof(DeepFryerBoundUserInterface))]
+ public sealed partial class DeepFryerWindow : DefaultWindow
+ {
+ [Dependency] private readonly IEntityManager _entityManager = default!;
+
+ private static readonly Color WarningColor = Color.FromHsv(new Vector4(0.0f, 1.0f, 0.8f, 1.0f));
+
+ public DeepFryerWindow()
+ {
+ RobustXamlLoader.Load(this);
+ IoCManager.InjectDependencies(this);
+ }
+
+ public void UpdateState(DeepFryerBoundUserInterfaceState state)
+ {
+ OilLevel.Value = (float) state.OilLevel;
+ OilPurity.Value = (float) state.OilPurity;
+
+ if (state.OilPurity < state.FryingOilThreshold)
+ {
+ if (OilPurity.ForegroundStyleBoxOverride == null)
+ {
+ OilPurity.ForegroundStyleBoxOverride = new StyleBoxFlat();
+
+ var oilPurityStyle = (StyleBoxFlat) OilPurity.ForegroundStyleBoxOverride;
+ oilPurityStyle.BackgroundColor = WarningColor;
+ }
+ }
+ else
+ {
+ OilPurity.ForegroundStyleBoxOverride = null;
+ }
+
+ ItemList.Clear();
+
+ foreach (var netEntity in state.ContainedEntities)
+ {
+ var entity = _entityManager.GetEntity(netEntity);
+ if (_entityManager.Deleted(entity))
+ continue;
+
+ // Duplicated from MicrowaveBoundUserInterface.cs: keep an eye on that file for when it changes.
+ Texture? texture;
+ if (_entityManager.TryGetComponent(entity, out IconComponent? iconComponent))
+ {
+ texture = _entityManager.System().GetIcon(iconComponent);
+ }
+ else if (_entityManager.TryGetComponent(entity, out SpriteComponent? spriteComponent))
+ {
+ texture = spriteComponent.Icon?.Default;
+ }
+ else
+ {
+ continue;
+ }
+
+ ItemList.AddItem(_entityManager.GetComponent(entity).EntityName, texture);
+ }
+ }
+ }
+}
diff --git a/Content.Client/Nyanotrasen/Kitchen/Visualizers/DeepFriedVisualizer.cs b/Content.Client/Nyanotrasen/Kitchen/Visualizers/DeepFriedVisualizer.cs
new file mode 100644
index 00000000000..58580e3f5ac
--- /dev/null
+++ b/Content.Client/Nyanotrasen/Kitchen/Visualizers/DeepFriedVisualizer.cs
@@ -0,0 +1,73 @@
+using System.Linq;
+using Robust.Client.GameObjects;
+using static Robust.Client.GameObjects.SpriteComponent;
+using Content.Client.Kitchen.Components;
+using Content.Shared.Clothing;
+using Content.Shared.Hands;
+using Content.Shared.Kitchen.Components;
+
+namespace Content.Client.Kitchen.Visualizers
+{
+ public sealed class DeepFriedVisualizerSystem : VisualizerSystem
+ {
+ private readonly static string ShaderName = "Crispy";
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnHeldVisualsUpdated);
+ SubscribeLocalEvent(OnEquipmentVisualsUpdated);
+ }
+
+ protected override void OnAppearanceChange(EntityUid uid, DeepFriedComponent component, ref AppearanceChangeEvent args)
+ {
+ if (args.Sprite == null)
+ return;
+
+ if (!args.Component.TryGetData(DeepFriedVisuals.Fried, out bool isFried))
+ return;
+
+ for (var i = 0; i < args.Sprite.AllLayers.Count(); ++i)
+ args.Sprite.LayerSetShader(i, ShaderName);
+ }
+
+ private void OnHeldVisualsUpdated(EntityUid uid, DeepFriedComponent component, HeldVisualsUpdatedEvent args)
+ {
+ if (args.RevealedLayers.Count == 0)
+ {
+ return;
+ }
+
+ if (!TryComp(args.User, out SpriteComponent? sprite))
+ return;
+
+ foreach (var key in args.RevealedLayers)
+ {
+ if (!sprite.LayerMapTryGet(key, out var index) || sprite[index] is not Layer layer)
+ continue;
+
+ sprite.LayerSetShader(index, ShaderName);
+ }
+ }
+
+ private void OnEquipmentVisualsUpdated(EntityUid uid, DeepFriedComponent component, EquipmentVisualsUpdatedEvent args)
+ {
+ if (args.RevealedLayers.Count == 0)
+ {
+ return;
+ }
+
+ if (!TryComp(args.Equipee, out SpriteComponent? sprite))
+ return;
+
+ foreach (var key in args.RevealedLayers)
+ {
+ if (!sprite.LayerMapTryGet(key, out var index) || sprite[index] is not Layer layer)
+ continue;
+
+ sprite.LayerSetShader(index, ShaderName);
+ }
+ }
+ }
+}
diff --git a/Content.Client/Nyanotrasen/Kitchen/Visualizers/DeepFryerVisualizer.cs b/Content.Client/Nyanotrasen/Kitchen/Visualizers/DeepFryerVisualizer.cs
new file mode 100644
index 00000000000..69f613fc110
--- /dev/null
+++ b/Content.Client/Nyanotrasen/Kitchen/Visualizers/DeepFryerVisualizer.cs
@@ -0,0 +1,21 @@
+using Robust.Client.GameObjects;
+using Content.Client.Chemistry.Visualizers;
+using Content.Client.Kitchen.Components;
+using Content.Shared.Kitchen.Components;
+
+namespace Content.Client.Kitchen.Visualizers
+{
+ public sealed class DeepFryerVisualizerSystem : VisualizerSystem
+ {
+ protected override void OnAppearanceChange(EntityUid uid, DeepFryerComponent component, ref AppearanceChangeEvent args)
+ {
+ if (!args.Component.TryGetData(DeepFryerVisuals.Bubbling, out bool isBubbling) ||
+ !TryComp(uid, out var scvComponent))
+ {
+ return;
+ }
+
+ scvComponent.FillBaseName = isBubbling ? "on-" : "off-";
+ }
+ }
+}
diff --git a/Content.Client/Nyanotrasen/Players/PlayTimeTracking/JobRequirementsManager.Whitelist.cs b/Content.Client/Nyanotrasen/Players/PlayTimeTracking/JobRequirementsManager.Whitelist.cs
new file mode 100644
index 00000000000..9b1f2d203f4
--- /dev/null
+++ b/Content.Client/Nyanotrasen/Players/PlayTimeTracking/JobRequirementsManager.Whitelist.cs
@@ -0,0 +1,22 @@
+using System.Diagnostics.CodeAnalysis;
+using Content.Shared.CCVar;
+using Content.Shared.Players.PlayTimeTracking;
+using Content.Shared.Roles;
+using Robust.Shared.Utility;
+
+namespace Content.Client.Players.PlayTimeTracking;
+
+public sealed partial class JobRequirementsManager
+{
+ private bool _whitelisted = false;
+
+ private void RxWhitelist(MsgWhitelist message)
+ {
+ _whitelisted = message.Whitelisted;
+ }
+
+ public bool IsWhitelisted()
+ {
+ return _whitelisted;
+ }
+}
diff --git a/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs b/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs
index c67c759dfdd..0e559d0f8c8 100644
--- a/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs
+++ b/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs
@@ -14,7 +14,7 @@
namespace Content.Client.Players.PlayTimeTracking;
-public sealed class JobRequirementsManager
+public sealed partial class JobRequirementsManager
{
[Dependency] private readonly IBaseClient _client = default!;
[Dependency] private readonly IClientNetManager _net = default!;
@@ -37,6 +37,7 @@ public void Initialize()
// Yeah the client manager handles role bans and playtime but the server ones are separate DEAL.
_net.RegisterNetMessage(RxRoleBans);
_net.RegisterNetMessage(RxPlayTime);
+ _net.RegisterNetMessage(RxWhitelist);
_client.RunLevelChanged += ClientOnRunLevelChanged;
}
@@ -113,7 +114,7 @@ public bool CheckRoleTime(HashSet? requirements, [NotNullWhen(fa
var reasons = new List();
foreach (var requirement in requirements)
{
- if (JobRequirements.TryRequirementMet(requirement, _roles, out var jobReason, _entManager, _prototypes))
+ if (JobRequirements.TryRequirementMet(requirement, _roles, out var jobReason, _entManager, _prototypes, _whitelisted))
continue;
reasons.Add(jobReason.ToMarkup());
diff --git a/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs b/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs
index c9a64eb0973..369d8aeab94 100644
--- a/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs
+++ b/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs
@@ -642,6 +642,8 @@ private void OnSkinColorOnValueChanged()
var skin = _prototypeManager.Index(Profile.Species).SkinColoration;
+ var skinColor = _prototypeManager.Index(Profile.Species).DefaultSkinTone;
+
switch (skin)
{
case HumanoidSkinColor.HumanToned:
@@ -671,6 +673,7 @@ private void OnSkinColorOnValueChanged()
break;
}
case HumanoidSkinColor.TintedHues:
+ case HumanoidSkinColor.TintedHuesSkin: // DeltaV - Tone blending
{
if (!_rgbSkinColorContainer.Visible)
{
@@ -678,7 +681,12 @@ private void OnSkinColorOnValueChanged()
_rgbSkinColorContainer.Visible = true;
}
- var color = SkinColor.TintedHues(_rgbSkinColorSelector.Color);
+ var color = skin switch // DeltaV - Tone blending
+ {
+ HumanoidSkinColor.TintedHues => SkinColor.TintedHues(_rgbSkinColorSelector.Color),
+ HumanoidSkinColor.TintedHuesSkin => SkinColor.TintedHuesSkin(_rgbSkinColorSelector.Color, skinColor),
+ _ => Color.White
+ };
CMarkings.CurrentSkinColor = color;
Profile = Profile.WithCharacterAppearance(Profile.Appearance.WithSkinColor(color));
diff --git a/Content.IntegrationTests/Tests/Nyanotrasen/DeepFryerTest.cs b/Content.IntegrationTests/Tests/Nyanotrasen/DeepFryerTest.cs
new file mode 100644
index 00000000000..3e1a7ff52c8
--- /dev/null
+++ b/Content.IntegrationTests/Tests/Nyanotrasen/DeepFryerTest.cs
@@ -0,0 +1,58 @@
+#nullable enable annotations
+using Content.Server.Kitchen.Components;
+using Content.Server.Kitchen.EntitySystems;
+using Robust.Shared.GameObjects;
+using Robust.Shared.Reflection;
+
+namespace Content.IntegrationTests.Tests.DeepFryer
+{
+ [TestFixture]
+ [TestOf(typeof(DeepFriedComponent))]
+ [TestOf(typeof(DeepFryerSystem))]
+ [TestOf(typeof(DeepFryerComponent))]
+ public sealed class DeepFryerTest
+ {
+
+ [TestPrototypes]
+ private const string Prototypes = @"
+- type: entity
+ name: DeepFryerDummy
+ id: DeepFryerDummy
+ components:
+ - type: DeepFryer
+ entryDelay: 0
+ draggedEntryDelay: 0
+ flushTime: 0
+ - type: Anchorable
+ - type: ApcPowerReceiver
+ - type: Physics
+ bodyType: Static
+ - type: Fixtures
+ fixtures:
+ fix1:
+ shape:
+ !type:PhysShapeCircle
+ radius: 0.35
+";
+
+ [Test]
+ public async Task Test()
+ {
+ await using var pair = await PoolManager.GetServerClient();
+ var server = pair.Server;
+
+ var testMap = await pair.CreateTestMap();
+
+ EntityUid unitUid = default;
+
+ var entityManager = server.ResolveDependency();
+ var xformSystem = entityManager.System();
+ var deepFryerSystem = entityManager.System();
+ await server.WaitAssertion(() =>
+ {
+ Assert.That(deepFryerSystem, Is.Not.Null);
+ });
+ await pair.CleanReturnAsync();
+ }
+ }
+}
diff --git a/Content.Server/Administration/Systems/AdminSystem.cs b/Content.Server/Administration/Systems/AdminSystem.cs
index 66f7a8999b3..5a3e1d92175 100644
--- a/Content.Server/Administration/Systems/AdminSystem.cs
+++ b/Content.Server/Administration/Systems/AdminSystem.cs
@@ -340,7 +340,7 @@ public void Erase(IPlayerSession player)
_popup.PopupCoordinates(Loc.GetString("admin-erase-popup", ("user", name)), coordinates, PopupType.LargeCaution);
var filter = Filter.Pvs(coordinates, 1, EntityManager, _playerManager);
var audioParams = new AudioParams().WithVolume(3);
- _audio.Play("/Audio/Effects/pop_high.ogg", filter, coordinates, true, audioParams);
+ _audio.Play("/Audio/DeltaV/Misc/reducedtoatmos.ogg", filter, coordinates, true, audioParams);
}
foreach (var item in _inventory.GetHandOrInventoryEntities(entity.Value))
diff --git a/Content.Server/DeltaV/Harpy/HarpySingerSystem.cs b/Content.Server/DeltaV/Harpy/HarpySingerSystem.cs
new file mode 100644
index 00000000000..60eb189a51b
--- /dev/null
+++ b/Content.Server/DeltaV/Harpy/HarpySingerSystem.cs
@@ -0,0 +1,31 @@
+using Content.Server.Instruments;
+using Content.Shared.Mobs;
+using Content.Shared.Mobs.Systems;
+using Robust.Server.GameObjects;
+
+namespace Content.Server.DeltaV.Harpy
+{
+ public sealed class HarpySingerSystem : EntitySystem
+ {
+ [Dependency] private readonly InstrumentSystem _instrument = default!;
+ [Dependency] private readonly MobStateSystem _mobState = default!;
+
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(HarpyStopSinging);
+ }
+
+
+ //Immediately closes the Midi UI window if a Singer is incapacitated
+ private void HarpyStopSinging(EntityUid uid, InstrumentComponent component, MobStateChangedEvent args)
+ {
+ if (HasComp(uid) && TryComp(uid, out var actor) && _mobState.IsIncapacitated(uid))
+ {
+ _instrument.ToggleInstrumentUi(uid, actor.PlayerSession);
+ }
+ }
+ }
+}
diff --git a/Content.Server/DeltaV/NPC/Roboisseur/RoboisseurComponent.cs b/Content.Server/DeltaV/NPC/Roboisseur/RoboisseurComponent.cs
index 5fcb2601e1f..d2419e73e48 100644
--- a/Content.Server/DeltaV/NPC/Roboisseur/RoboisseurComponent.cs
+++ b/Content.Server/DeltaV/NPC/Roboisseur/RoboisseurComponent.cs
@@ -172,6 +172,8 @@ public sealed partial class RoboisseurComponent : Component
"FoodSoupTomatoBlood",
"FoodMothSaladBase",
"FoodPieXeno",
+ "FoodPiePumpkin",
+ "FoodPiePumpkinSlice",
"FoodDonkpocketTeriyakiWarm",
"FoodMothBakedCheese",
"FoodMothTomatoSauce",
diff --git a/Content.Server/GameTicking/GameTicker.Player.cs b/Content.Server/GameTicking/GameTicker.Player.cs
index 3aef1bbe785..9161137a252 100644
--- a/Content.Server/GameTicking/GameTicker.Player.cs
+++ b/Content.Server/GameTicking/GameTicker.Player.cs
@@ -128,6 +128,8 @@ async void SpawnWaitDb()
{
await _userDb.WaitLoadComplete(session);
+ session.ContentData()!.Whitelisted = await _db.GetWhitelistStatusAsync(session.UserId); // Nyanotrasen - Whitelist
+
SpawnPlayer(session, EntityUid.Invalid);
}
diff --git a/Content.Server/Nutrition/EntitySystems/SliceableFoodSystem.cs b/Content.Server/Nutrition/EntitySystems/SliceableFoodSystem.cs
index 81bba0eb79d..e2e054f4fa0 100644
--- a/Content.Server/Nutrition/EntitySystems/SliceableFoodSystem.cs
+++ b/Content.Server/Nutrition/EntitySystems/SliceableFoodSystem.cs
@@ -90,6 +90,12 @@ private bool TrySliceFood(EntityUid uid, EntityUid user, EntityUid usedItem,
component.Count--;
+ //Nyano - Summary: Begin Nyano Code to tell us we've sliced something for Fryer --
+
+ var sliceEvent = new SliceFoodEvent(user, usedItem, uid, sliceUid);
+ RaiseLocalEvent(uid, sliceEvent);
+ //Nyano - End Nyano Code.
+
// If someone makes food proto with 1 slice...
if (component.Count < 1)
{
@@ -160,4 +166,40 @@ private void OnExamined(EntityUid uid, SliceableFoodComponent component, Examine
args.PushMarkup(Loc.GetString("sliceable-food-component-on-examine-remaining-slices-text", ("remainingCount", component.Count)));
}
}
+ //Nyano - Summary: Begin Nyano Code for the sliced food event.
+ public sealed class SliceFoodEvent : EntityEventArgs
+ {
+ ///
+ /// Who did the slicing?
+ ///
+ public EntityUid User;
+
+ ///
+ /// What did the slicing?
+ ///
+ public EntityUid Tool;
+
+ ///
+ /// What has been sliced?
+ ///
+ ///
+ /// This could soon be deleted if there was not enough food left to
+ /// continue slicing.
+ ///
+ public EntityUid Food;
+
+ ///
+ /// What is the slice?
+ ///
+ public EntityUid Slice;
+
+ public SliceFoodEvent(EntityUid user, EntityUid tool, EntityUid food, EntityUid slice)
+ {
+ User = user;
+ Tool = tool;
+ Food = food;
+ Slice = slice;
+ }
+ }
+ //End Nyano Code.
}
diff --git a/Content.Server/Nyanotrasen/Kitchen/Components/DeepFriedComponent.cs b/Content.Server/Nyanotrasen/Kitchen/Components/DeepFriedComponent.cs
new file mode 100644
index 00000000000..3bbb96e65d0
--- /dev/null
+++ b/Content.Server/Nyanotrasen/Kitchen/Components/DeepFriedComponent.cs
@@ -0,0 +1,23 @@
+using Content.Shared.Kitchen.Components;
+
+namespace Content.Server.Kitchen.Components
+{
+ [RegisterComponent]
+ //This line appears to be deprecated. [ComponentReference(typeof(SharedDeepFriedComponent))]
+ public sealed partial class DeepFriedComponent : SharedDeepFriedComponent
+ {
+ ///
+ /// What is the item's base price multiplied by?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("priceCoefficient")]
+ public float PriceCoefficient { get; set; } = 1.0f;
+
+ ///
+ /// What was the entity's original name before any modification?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("originalName")]
+ public string? OriginalName { get; set; }
+ }
+}
diff --git a/Content.Server/Nyanotrasen/Kitchen/Components/DeepFryerComponent.cs b/Content.Server/Nyanotrasen/Kitchen/Components/DeepFryerComponent.cs
new file mode 100644
index 00000000000..07cc96e8e78
--- /dev/null
+++ b/Content.Server/Nyanotrasen/Kitchen/Components/DeepFryerComponent.cs
@@ -0,0 +1,240 @@
+using Robust.Shared.Audio;
+using Robust.Shared.Containers;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set;
+using Content.Server.Kitchen.EntitySystems;
+using Content.Server.Nutrition;
+using Content.Shared.Chemistry.Components;
+using Content.Shared.Chemistry.Reagent;
+using Content.Shared.Construction.Prototypes;
+using Content.Shared.Kitchen.Components;
+using Content.Shared.Nutrition;
+using Content.Shared.FixedPoint;
+using Content.Shared.Whitelist;
+
+namespace Content.Server.Kitchen.Components
+{
+ [RegisterComponent]
+ [Access(typeof(DeepFryerSystem))]
+ // This line appears to be depracted: [ComponentReference(typeof(SharedDeepFryerComponent))]
+ public sealed partial class DeepFryerComponent : SharedDeepFryerComponent
+ {
+ // There are three levels to how the deep fryer treats entities.
+ //
+ // 1. An entity can be rejected by the blacklist and be untouched by
+ // anything other than heat damage.
+ //
+ // 2. An entity can be deep-fried but not turned into an edible. The
+ // change will be mostly cosmetic. Any entity that does not match
+ // the blacklist will fall into this category.
+ //
+ // 3. An entity can be deep-fried and turned into something edible. The
+ // change will permit the item to be permanently destroyed by eating
+ // it.
+
+ ///
+ /// When will the deep fryer layer on the next stage of crispiness?
+ ///
+ [DataField("nextFryTime", customTypeSerializer: typeof(TimeOffsetSerializer))]
+ public TimeSpan NextFryTime { get; set; }
+
+ ///
+ /// How much waste needs to be added at the next update interval?
+ ///
+ public FixedPoint2 WasteToAdd { get; set; } = FixedPoint2.Zero;
+
+ ///
+ /// How often are items in the deep fryer fried?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("fryInterval")]
+ public TimeSpan FryInterval { get; set; } = TimeSpan.FromSeconds(5);
+
+ ///
+ /// What entities cannot be deep-fried no matter what?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("blacklist")]
+ public EntityWhitelist? Blacklist { get; set; }
+
+ ///
+ /// What entities can be deep-fried into being edible?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("whitelist")]
+ public EntityWhitelist? Whitelist { get; set; }
+
+ ///
+ /// What are over-cooked and burned entities turned into?
+ ///
+ ///
+ /// To prevent unwanted destruction of items, only food can be turned
+ /// into this.
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("charredPrototype", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string? CharredPrototype { get; set; }
+
+ ///
+ /// What reagents are considered valid cooking oils?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("fryingOils", customTypeSerializer: typeof(PrototypeIdHashSetSerializer))]
+ public HashSet FryingOils { get; set; } = new();
+
+ ///
+ /// What reagents are added to tasty deep-fried food?
+ /// JJ Comment: I removed Solution from this. Unsure if I need to replace it with something.
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("goodReagents")]
+ public List GoodReagents { get; set; } = new();
+
+ ///
+ /// What reagents are added to terrible deep-fried food?
+ /// JJ Comment: I removed Solution from this. Unsure if I need to replace it with something.
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("badReagents")]
+ public List BadReagents { get; set; } = new();
+
+ ///
+ /// What reagents replace every 1 unit of oil spent on frying?
+ /// JJ Comment: I removed Solution from this. Unsure if I need to replace it with something.
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("wasteReagents")]
+ public List WasteReagents { get; set; } = new();
+
+ ///
+ /// What flavors go well with deep frying?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("goodFlavors", customTypeSerializer: typeof(PrototypeIdHashSetSerializer))]
+ public HashSet GoodFlavors { get; set; } = new();
+
+ ///
+ /// What flavors don't go well with deep frying?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("badFlavors", customTypeSerializer: typeof(PrototypeIdHashSetSerializer))]
+ public HashSet BadFlavors { get; set; } = new();
+
+ ///
+ /// How much is the price coefficiency of a food changed for each good flavor?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("goodFlavorPriceBonus")]
+ public float GoodFlavorPriceBonus { get; set; } = 0.2f;
+
+ ///
+ /// How much is the price coefficiency of a food changed for each bad flavor?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("badFlavorPriceMalus")]
+ public float BadFlavorPriceMalus { get; set; } = -0.3f;
+
+ ///
+ /// What is the name of the solution container for the fryer's oil?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("solution")]
+ public string SolutionName { get; set; } = "vat_oil";
+
+ public Solution Solution { get; set; } = default!;
+
+ ///
+ /// What is the name of the entity container for items inside the deep fryer?
+ ///
+ [DataField("storage")]
+ public string StorageName { get; set; } = "vat_entities";
+
+ public BaseContainer Storage { get; set; } = default!;
+
+ ///
+ /// How much solution should be imparted based on an item's size?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("solutionSizeCoefficient")]
+ public FixedPoint2 SolutionSizeCoefficient { get; set; } = 0.5f;
+
+ ///
+ /// What's the maximum amount of solution that should ever be imparted?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("solutionSplitMax")]
+ public FixedPoint2 SolutionSplitMax { get; set; } = 10f;
+
+ ///
+ /// What percent of the fryer's solution has to be oil in order for it to fry?
+ ///
+ ///
+ /// The chef will have to clean it out occasionally, and if too much
+ /// non-oil reagents are added, the vat will have to be drained.
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("fryingOilThreshold")]
+ public FixedPoint2 FryingOilThreshold { get; set; } = 0.5f;
+
+ ///
+ /// What is the bare minimum number of oil units to prevent the fryer
+ /// from unsafe operation?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("safeOilVolume")]
+ public FixedPoint2 SafeOilVolume { get; set; } = 10f;
+
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("unsafeOilVolumeEffects")]
+ public List UnsafeOilVolumeEffects = new();
+
+ ///
+ /// What is the temperature of the vat when the deep fryer is powered?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("poweredTemperature")]
+ public float PoweredTemperature = 550.0f;
+
+ ///
+ /// How many entities can this deep fryer hold?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ public int StorageMaxEntities = 4;
+
+ ///
+ /// How many entities can be held, at a minimum?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("baseStorageMaxEntities")]
+ public int BaseStorageMaxEntities = 4;
+
+ ///
+ /// What upgradeable machine part dictates the quality of the storage size?
+ ///
+ [DataField("machinePartStorageMax", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string MachinePartStorageMax = "MatterBin";
+
+ ///
+ /// How much extra storage is added per part rating?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("storagePerPartRating")]
+ public int StoragePerPartRating = 4;
+
+ ///
+ /// What sound is played when an item is inserted into hot oil?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("soundInsertItem")]
+ public SoundSpecifier SoundInsertItem = new SoundPathSpecifier("/Audio/Nyanotrasen/Machines/deepfryer_basket_add_item.ogg");
+
+ ///
+ /// What sound is played when an item is removed?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("soundRemoveItem")]
+ public SoundSpecifier SoundRemoveItem = new SoundPathSpecifier("/Audio/Nyanotrasen/Machines/deepfryer_basket_remove_item.ogg");
+ }
+}
diff --git a/Content.Server/Nyanotrasen/Kitchen/Components/ProfessionalChefComponent.cs b/Content.Server/Nyanotrasen/Kitchen/Components/ProfessionalChefComponent.cs
new file mode 100644
index 00000000000..eb04f0d7b30
--- /dev/null
+++ b/Content.Server/Nyanotrasen/Kitchen/Components/ProfessionalChefComponent.cs
@@ -0,0 +1,5 @@
+namespace Content.Server.Kitchen.Components
+{
+ [RegisterComponent]
+ public sealed partial class ProfessionalChefComponent : Component {}
+}
diff --git a/Content.Server/Nyanotrasen/Kitchen/EntitySystems/DeepFryerSystem.cs b/Content.Server/Nyanotrasen/Kitchen/EntitySystems/DeepFryerSystem.cs
new file mode 100644
index 00000000000..299df8b9b7c
--- /dev/null
+++ b/Content.Server/Nyanotrasen/Kitchen/EntitySystems/DeepFryerSystem.cs
@@ -0,0 +1,1065 @@
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Text;
+using Robust.Server.GameObjects;
+using Robust.Shared.Audio;
+using Robust.Shared.Containers;
+using Robust.Shared.Player;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Random;
+using Robust.Shared.Timing;
+using Content.Server.Administration.Logs;
+using Content.Server.Atmos.Components;
+using Content.Server.Atmos.Miasma;
+using Content.Server.Audio;
+using Content.Server.Body.Components;
+using Content.Server.Cargo.Systems;
+using Content.Shared.Chemistry.Components.SolutionManager;
+using Content.Server.Chemistry.EntitySystems;
+using Content.Server.Construction;
+using Content.Server.Construction.Components;
+using Content.Server.DoAfter;
+using Content.Server.Fluids.EntitySystems;
+using Content.Server.Ghost.Roles.Components;
+using Content.Server.Kitchen.Components;
+using Content.Server.NPC.Components;
+using Content.Server.Nutrition.Components;
+using Content.Server.Nutrition.EntitySystems;
+using Content.Server.Paper;
+using Content.Server.Popups;
+using Content.Server.Power.Components;
+using Content.Server.Power.EntitySystems;
+using Content.Server.Temperature.Components;
+using Content.Server.Temperature.Systems;
+using Content.Server.UserInterface;
+using Content.Shared.Atmos.Miasma;
+using Content.Shared.Buckle.Components;
+using Content.Shared.Chemistry.Components;
+using Content.Shared.Chemistry.Reagent;
+using Content.Shared.Damage;
+using Content.Shared.Damage.Prototypes;
+using Content.Shared.Database;
+using Content.Shared.DoAfter;
+using Content.Shared.Destructible;
+using Content.Shared.Examine;
+using Content.Shared.FixedPoint;
+using Content.Shared.Hands.Components;
+using Content.Shared.Hands.EntitySystems;
+using Content.Shared.IdentityManagement;
+using Content.Shared.Interaction;
+using Content.Shared.Item;
+using Content.Shared.Kitchen;
+using Content.Shared.Kitchen.Components;
+using Content.Shared.Kitchen.UI;
+using Content.Shared.Mobs.Components;
+using Content.Shared.Mobs.Systems;
+using Content.Shared.Movement.Events;
+using Content.Shared.Nutrition.Components;
+using Content.Shared.Popups;
+using Content.Shared.Storage;
+using Content.Shared.Throwing;
+using Content.Shared.Tools.Components;
+using FastAccessors;
+using Content.Shared.NPC;
+using Content.Shared.Chemistry.EntitySystems;
+
+namespace Content.Server.Kitchen.EntitySystems
+{
+ public sealed class DeepFryerSystem : EntitySystem
+ {
+ [Dependency] private readonly DamageableSystem _damageableSystem = default!;
+ [Dependency] private readonly DoAfterSystem _doAfterSystem = default!;
+ [Dependency] private readonly IAdminLogManager _adminLogManager = default!;
+ [Dependency] private readonly IGameTiming _gameTimingSystem = default!;
+ [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
+ [Dependency] private readonly IRobustRandom _random = default!;
+ [Dependency] private readonly PopupSystem _popupSystem = default!;
+ [Dependency] private readonly PowerReceiverSystem _powerReceiverSystem = default!;
+ [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
+ [Dependency] private readonly SharedAudioSystem _audioSystem = default!;
+ [Dependency] private readonly SharedContainerSystem _containerSystem = default!;
+ [Dependency] private readonly SharedHandsSystem _handsSystem = default!;
+ [Dependency] private readonly MobStateSystem _mobStateSystem = default!;
+ [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
+ [Dependency] private readonly SolutionTransferSystem _solutionTransferSystem = default!;
+ [Dependency] private readonly PuddleSystem _puddleSystem = default!;
+ [Dependency] private readonly TemperatureSystem _temperature = default!;
+ [Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
+ [Dependency] private readonly AmbientSoundSystem _ambientSoundSystem = default!;
+
+ private static readonly string CookingDamageType = "Heat";
+ private static readonly float CookingDamageAmount = 10.0f;
+ private static readonly float PvsWarningRange = 0.5f;
+ private static readonly float ThrowMissChance = 0.25f;
+ private static readonly int MaximumCrispiness = 2;
+ private static readonly float BloodToProteinRatio = 0.1f;
+ private static readonly string MobFlavorMeat = "meaty";
+ private static readonly AudioParams AudioParamsInsertRemove = new(0.5f, 1f, "Master", 5f, 1.5f, 1f, false, 0f, 0.2f);
+
+ private ISawmill _sawmill = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ _sawmill = Logger.GetSawmill("deepfryer");
+
+ SubscribeLocalEvent(OnInitDeepFryer);
+ SubscribeLocalEvent(OnPowerChange);
+ SubscribeLocalEvent(OnRefreshParts);
+ SubscribeLocalEvent(OnDeconstruct);
+ SubscribeLocalEvent(OnDestruction);
+ SubscribeLocalEvent(OnThrowHitBy);
+ SubscribeLocalEvent(OnSolutionChange);
+ SubscribeLocalEvent(OnRelayMovement);
+ SubscribeLocalEvent(OnInteractUsing);
+
+ SubscribeLocalEvent(OnBeforeActivatableUIOpen);
+ SubscribeLocalEvent(OnRemoveItem);
+ SubscribeLocalEvent(OnInsertItem);
+ SubscribeLocalEvent(OnScoopVat);
+ SubscribeLocalEvent(OnClearSlagStart);
+ SubscribeLocalEvent(OnRemoveAllItems);
+ SubscribeLocalEvent(OnClearSlag);
+
+ SubscribeLocalEvent(OnInitDeepFried);
+ SubscribeLocalEvent(OnExamineFried);
+ SubscribeLocalEvent(OnPriceCalculation);
+ SubscribeLocalEvent(OnSliceDeepFried);
+ }
+
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+
+ foreach (var component in EntityManager.EntityQuery())
+ {
+ var uid = component.Owner;
+
+ if (_gameTimingSystem.CurTime < component.NextFryTime ||
+ !_powerReceiverSystem.IsPowered(uid))
+ {
+ continue;
+ }
+
+ UpdateNextFryTime(uid, component);
+
+ // Heat the vat solution and contained entities.
+ _solutionContainerSystem.SetTemperature(uid, component.Solution, component.PoweredTemperature);
+
+ foreach (var item in component.Storage.ContainedEntities)
+ CookItem(uid, component, item);
+
+ // Do something bad if there's enough heat but not enough oil.
+ var oilVolume = GetOilVolume(uid, component);
+
+ if (oilVolume < component.SafeOilVolume)
+ {
+ foreach (var item in component.Storage.ContainedEntities.ToArray())
+ BurnItem(uid, component, item);
+
+ if (oilVolume > FixedPoint2.Zero)
+ {
+ //JJ Comment - this code block makes the Linter fail, and doesn't seem to be necessary with the changes I made.
+ foreach (var reagent in component.Solution.Contents.ToArray())
+ {
+ _prototypeManager.TryIndex(reagent.Reagent.ToString(), out var proto);
+
+ foreach (var effect in component.UnsafeOilVolumeEffects)
+ {
+ effect.Effect(new ReagentEffectArgs(uid,
+ null,
+ component.Solution,
+ proto!,
+ reagent.Quantity,
+ EntityManager,
+ null,
+ 1f));
+ }
+
+ }
+
+ component.Solution.RemoveAllSolution();
+
+ _popupSystem.PopupEntity(
+ Loc.GetString("deep-fryer-oil-volume-low",
+ ("deepFryer", uid)),
+ uid,
+ PopupType.SmallCaution);
+
+ continue;
+ }
+ }
+
+ // We only alert the chef that there's a problem with oil purity
+ // if there's anything to cook beyond this point.
+ if (!component.Storage.ContainedEntities.Any())
+ {
+ continue;
+ }
+
+ if (GetOilPurity(uid, component) < component.FryingOilThreshold)
+ {
+ _popupSystem.PopupEntity(
+ Loc.GetString("deep-fryer-oil-purity-low",
+ ("deepFryer", uid)),
+ uid,
+ Filter.Pvs(uid, PvsWarningRange),
+ true);
+ continue;
+ }
+
+ foreach (var item in component.Storage.ContainedEntities.ToArray())
+ DeepFry(uid, component, item);
+
+ // After the round of frying, replace the spent oil with a
+ // waste product.
+ if (component.WasteToAdd > FixedPoint2.Zero)
+ {
+ foreach (var reagent in component.WasteReagents)
+ component.Solution.AddReagent(reagent.Reagent.ToString(), reagent.Quantity * component.WasteToAdd);
+
+ component.WasteToAdd = FixedPoint2.Zero;
+
+ _solutionContainerSystem.UpdateChemicals(uid, component.Solution, true);
+ }
+
+ UpdateUserInterface(uid, component);
+ }
+ }
+
+ private void UpdateUserInterface(EntityUid uid, DeepFryerComponent component)
+ {
+ var state = new DeepFryerBoundUserInterfaceState(
+ GetOilLevel(uid, component),
+ GetOilPurity(uid, component),
+ component.FryingOilThreshold,
+ EntityManager.GetNetEntityArray(component.Storage.ContainedEntities.ToArray()));
+
+ if (!_uiSystem.TrySetUiState(uid, DeepFryerUiKey.Key, state))
+ _sawmill.Warning($"{ToPrettyString(uid)} was unable to set UI state.");
+ }
+
+ ///
+ /// Does the deep fryer have hot oil?
+ ///
+ ///
+ /// This is mainly for audio.
+ ///
+ private bool HasBubblingOil(EntityUid uid, DeepFryerComponent component)
+ {
+ return _powerReceiverSystem.IsPowered(uid) && GetOilVolume(uid, component) > FixedPoint2.Zero;
+ }
+
+ private void UpdateAmbientSound(EntityUid uid, DeepFryerComponent component)
+ {
+ _ambientSoundSystem.SetAmbience(uid, HasBubblingOil(uid, component));
+ }
+
+ private void UpdateNextFryTime(EntityUid uid, DeepFryerComponent component)
+ {
+ component.NextFryTime = _gameTimingSystem.CurTime + component.FryInterval;
+ }
+
+ ///
+ /// Make an item look deep-fried.
+ ///
+ private void MakeCrispy(EntityUid item)
+ {
+ EnsureComp(item);
+ EnsureComp(item);
+
+ _appearanceSystem.SetData(item, DeepFriedVisuals.Fried, true);
+ }
+
+ ///
+ /// Turn a dead mob into food.
+ ///
+ ///
+ /// This is meant to be an irreversible process, similar to gibbing.
+ ///
+ public bool TryMakeMobIntoFood(EntityUid mob, MobStateComponent mobStateComponent, bool force = false)
+ {
+ // Don't do anything to mobs until they're dead.
+ if (force || _mobStateSystem.IsDead(mob, mobStateComponent))
+ {
+ RemComp(mob);
+ RemComp(mob);
+ RemComp(mob);
+ RemComp(mob);
+ RemComp(mob);
+ RemComp(mob);
+ RemComp(mob);
+ RemComp(mob);
+ RemComp(mob);
+
+ // Ensure it's Food here, so it passes the whitelist.
+ var mobFoodComponent = EnsureComp(mob);
+ var mobFoodSolution = _solutionContainerSystem.EnsureSolution(mob, mobFoodComponent.Solution, out bool alreadyHadFood);
+
+ // This line here is mainly for mice, because they have a food
+ // component that mirrors how much blood they have, which is
+ // used for the reagent grinder.
+ if (alreadyHadFood)
+ _solutionContainerSystem.RemoveAllSolution(mob, mobFoodSolution);
+
+ if (TryComp(mob, out var bloodstreamComponent))
+ {
+ // Fry off any blood into protein.
+ var bloodSolution = bloodstreamComponent.BloodSolution;
+ var removedBloodQuantity = bloodSolution.RemoveReagent("Blood", FixedPoint2.MaxValue);
+ var proteinQuantity = removedBloodQuantity * BloodToProteinRatio;
+ mobFoodSolution.MaxVolume += proteinQuantity;
+ mobFoodSolution.AddReagent("Protein", proteinQuantity);
+
+ // This is a heuristic. If you had blood, you might just taste meaty.
+ if (removedBloodQuantity > FixedPoint2.Zero)
+ EnsureComp(mob).Flavors.Add(MobFlavorMeat);
+
+ // Bring in whatever chemicals they had in them too.
+ mobFoodSolution.MaxVolume += bloodstreamComponent.ChemicalSolution.Volume;
+ mobFoodSolution.AddSolution(bloodstreamComponent.ChemicalSolution, _prototypeManager);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Make an item actually edible.
+ ///
+ private void MakeEdible(EntityUid uid, DeepFryerComponent component, EntityUid item, FixedPoint2 solutionQuantity)
+ {
+ if (!TryComp(item, out var deepFriedComponent))
+ {
+ _sawmill.Error($"{ToPrettyString(item)} is missing the DeepFriedComponent before being made Edible.");
+ return;
+ }
+
+ // Remove any components that wouldn't make sense anymore.
+ RemComp(item);
+
+ if (TryComp(item, out var paperComponent))
+ {
+ var stringBuilder = new StringBuilder();
+
+ for (var i = 0; i < paperComponent.Content.Length; ++i)
+ {
+ var uchar = paperComponent.Content.Substring(i, 1);
+
+ if (uchar == "\n" || _random.Prob(0.4f))
+ stringBuilder.Append(uchar);
+ else
+ stringBuilder.Append("x");
+ }
+
+ paperComponent.Content = stringBuilder.ToString();
+ }
+
+ var foodComponent = EnsureComp(item);
+ var extraSolution = new Solution();
+ if (TryComp(item, out FlavorProfileComponent? flavorProfileComponent))
+ {
+ HashSet goodFlavors = new(flavorProfileComponent.Flavors);
+ goodFlavors.IntersectWith(component.GoodFlavors);
+
+ HashSet badFlavors = new(flavorProfileComponent.Flavors);
+ badFlavors.IntersectWith(component.BadFlavors);
+
+ deepFriedComponent.PriceCoefficient = Math.Max(0.01f,
+ 1.0f
+ + goodFlavors.Count * component.GoodFlavorPriceBonus
+ - badFlavors.Count * component.BadFlavorPriceMalus);
+
+ if (goodFlavors.Count > 0)
+ foreach (var reagent in component.GoodReagents)
+ {
+ extraSolution.AddReagent(reagent.Reagent.ToString(), reagent.Quantity * goodFlavors.Count);
+
+ // Mask the taste of "medicine."
+ flavorProfileComponent.IgnoreReagents.Add(reagent.Reagent.ToString());
+ }
+
+ if (badFlavors.Count > 0)
+ foreach (var reagent in component.BadReagents)
+ extraSolution.AddReagent(reagent.Reagent.ToString(), reagent.Quantity * badFlavors.Count);
+ }
+ else
+ {
+ flavorProfileComponent = EnsureComp(item);
+ // TODO: Default flavor?
+ }
+
+ // Make sure there's enough room for the fryer solution.
+ var foodContainer = _solutionContainerSystem.EnsureSolution(item, foodComponent.Solution);
+
+ // The solution quantity is used to give the fried food an extra
+ // buffer too, to support injectables or condiments.
+ foodContainer.MaxVolume = 2 * solutionQuantity + foodContainer.Volume + extraSolution.Volume;
+ foodContainer.AddSolution(component.Solution.SplitSolution(solutionQuantity), _prototypeManager);
+ foodContainer.AddSolution(extraSolution, _prototypeManager);
+ _solutionContainerSystem.UpdateChemicals(item, foodContainer, true);
+ }
+
+ ///
+ /// Returns how much total oil is in the vat.
+ ///
+ public FixedPoint2 GetOilVolume(EntityUid uid, DeepFryerComponent component)
+ {
+ var oilVolume = FixedPoint2.Zero;
+
+ foreach (var reagent in component.Solution)
+ if (component.FryingOils.Contains(reagent.Reagent.ToString()))
+ oilVolume += reagent.Quantity;
+
+ return oilVolume;
+ }
+
+ ///
+ /// Returns how much total waste is in the vat.
+ ///
+ public FixedPoint2 GetWasteVolume(EntityUid uid, DeepFryerComponent component)
+ {
+ var wasteVolume = FixedPoint2.Zero;
+
+ foreach (var reagent in component.WasteReagents)
+ {
+ wasteVolume += component.Solution.GetReagentQuantity(reagent.Reagent);
+ }
+
+ return wasteVolume;
+ }
+
+ ///
+ /// Returns a percentage of how much of the total solution is usable oil.
+ ///
+ public FixedPoint2 GetOilPurity(EntityUid uid, DeepFryerComponent component)
+ {
+ return GetOilVolume(uid, component) / component.Solution.Volume;
+ }
+
+ ///
+ /// Returns a percentage of how much of the total volume is usable oil.
+ ///
+ public FixedPoint2 GetOilLevel(EntityUid uid, DeepFryerComponent component)
+ {
+ return GetOilVolume(uid, component) / component.Solution.MaxVolume;
+ }
+
+ ///
+ /// This takes care of anything that would happen to an item with or
+ /// without enough oil.
+ ///
+ private void CookItem(EntityUid uid, DeepFryerComponent component, EntityUid item)
+ {
+ if (TryComp(item, out var tempComp))
+ {
+ // Push the temperature towards what it should be but no higher.
+ var delta = (component.PoweredTemperature - tempComp.CurrentTemperature) * tempComp.HeatCapacity;
+
+ if (delta > 0f)
+ _temperature.ChangeHeat(item, delta, false, tempComp);
+ }
+
+ if (TryComp(item, out var solutions))
+ {
+ foreach (var (_, solution) in solutions.Solutions)
+ {
+ _solutionContainerSystem.SetTemperature(item, solution, component.PoweredTemperature);
+ }
+ }
+
+ // Damage non-food items and mobs.
+ if ((!HasComp(item) || HasComp(item)) &&
+ TryComp(item, out var damageableComponent))
+ {
+ var damage = new DamageSpecifier(_prototypeManager.Index(CookingDamageType), CookingDamageAmount);
+
+ var result = _damageableSystem.TryChangeDamage(item, damage, origin: uid);
+ if (result?.Total > FixedPoint2.Zero)
+ {
+ // TODO: Smoke, waste, sound, or some indication.
+ }
+ }
+ }
+
+ ///
+ /// Destroy a food item and replace it with a charred mess.
+ ///
+ private void BurnItem(EntityUid uid, DeepFryerComponent component, EntityUid item)
+ {
+ if (HasComp(item) &&
+ !HasComp(item) &&
+ MetaData(item).EntityPrototype?.ID != component.CharredPrototype)
+ {
+ var charred = Spawn(component.CharredPrototype, Transform(uid).Coordinates);
+ component.Storage.Insert(charred);
+ Del(item);
+ }
+ }
+
+ private void UpdateDeepFriedName(EntityUid uid, DeepFriedComponent component)
+ {
+ if (component.OriginalName == null)
+ return;
+
+ switch (component.Crispiness)
+ {
+ case 0:
+ // Already handled at OnInitDeepFried.
+ break;
+ case 1:
+ MetaData(uid).EntityName = Loc.GetString("deep-fried-fried-item",
+ ("entity", component.OriginalName));
+ break;
+ default:
+ MetaData(uid).EntityName = Loc.GetString("deep-fried-burned-item",
+ ("entity", component.OriginalName));
+ break;
+ }
+ }
+
+ ///
+ /// Try to deep fry a single item, which can
+ /// - be cancelled by other systems, or
+ /// - fail due to the blacklist, or
+ /// - give it a crispy shader, and possibly also
+ /// - turn it into food.
+ ///
+ private void DeepFry(EntityUid uid, DeepFryerComponent component, EntityUid item)
+ {
+ if (MetaData(item).EntityPrototype?.ID == component.CharredPrototype)
+ return;
+
+ // This item has already been deep-fried, and now it's progressing
+ // into another stage.
+ if (TryComp(item, out var deepFriedComponent))
+ {
+ // TODO: Smoke, waste, sound, or some indication.
+
+ deepFriedComponent.Crispiness += 1;
+
+ if (deepFriedComponent.Crispiness > MaximumCrispiness)
+ {
+ BurnItem(uid, component, item);
+ return;
+ }
+
+ UpdateDeepFriedName(item, deepFriedComponent);
+ return;
+ }
+
+ // Allow entity systems to conditionally forbid an attempt at deep-frying.
+ var attemptEvent = new DeepFryAttemptEvent(uid);
+ RaiseLocalEvent(item, attemptEvent);
+
+ if (attemptEvent.Cancelled)
+ return;
+
+ // The attempt event is allowed to go first before the blacklist check,
+ // just in case the attempt is relevant to any system in the future.
+ //
+ // The blacklist overrides all.
+ if (component.Blacklist != null && component.Blacklist.IsValid(item, EntityManager))
+ {
+ _popupSystem.PopupEntity(
+ Loc.GetString("deep-fryer-blacklist-item-failed",
+ ("item", item), ("deepFryer", uid)),
+ uid,
+ Filter.Pvs(uid, PvsWarningRange),
+ true);
+ return;
+ }
+
+ var beingEvent = new BeingDeepFriedEvent(uid, item);
+ RaiseLocalEvent(item, beingEvent);
+
+ // It's important to check for the MobStateComponent so we know
+ // it's actually a mob, because functions like
+ // MobStateSystem.IsAlive will return false if the entity lacks the
+ // component.
+ if (TryComp(item, out var mobStateComponent))
+ if (!TryMakeMobIntoFood(item, mobStateComponent))
+ return;
+
+ MakeCrispy(item);
+
+ var itemComponent = Comp(item);
+
+ // Determine how much solution to spend on this item.
+ var solutionQuantity = FixedPoint2.Min(
+ component.Solution.Volume,
+ itemComponent.Size * component.SolutionSizeCoefficient);
+
+ if (component.Whitelist != null && component.Whitelist.IsValid(item, EntityManager) ||
+ beingEvent.TurnIntoFood)
+ {
+ MakeEdible(uid, component, item, solutionQuantity);
+ }
+ else
+ {
+ component.Solution.RemoveSolution(solutionQuantity);
+ }
+
+ component.WasteToAdd += solutionQuantity;
+ }
+
+ private void OnInitDeepFryer(EntityUid uid, DeepFryerComponent component, ComponentInit args)
+ {
+ component.Storage = _containerSystem.EnsureContainer(uid, component.StorageName, out bool containerExisted);
+
+ if (!containerExisted)
+ _sawmill.Warning($"{ToPrettyString(uid)} did not have a {component.StorageName} container. It has been created.");
+
+ component.Solution = _solutionContainerSystem.EnsureSolution(uid, component.SolutionName, out bool solutionExisted);
+
+ if (!solutionExisted)
+ _sawmill.Warning($"{ToPrettyString(uid)} did not have a {component.SolutionName} solution container. It has been created.");
+ foreach (var reagent in component.Solution.Contents.ToArray())
+ {
+ //JJ Comment - not sure this works. Need to check if Reagent.ToString is correct.
+ _prototypeManager.TryIndex(reagent.Reagent.ToString(), out var proto);
+ var effectsArgs = new ReagentEffectArgs(uid,
+ null,
+ component.Solution,
+ proto!,
+ reagent.Quantity,
+ EntityManager,
+ null,
+ 1f);
+ foreach (var effect in component.UnsafeOilVolumeEffects)
+ {
+ if (!effect.ShouldApply(effectsArgs, _random))
+ continue;
+ effect.Effect(effectsArgs);
+ }
+ }
+ }
+
+ ///
+ /// Make sure the UI and interval tracker are updated anytime something
+ /// is inserted into one of the baskets.
+ ///
+ ///
+ /// This is used instead of EntInsertedIntoContainerMessage so charred
+ /// items can be inserted into the deep fryer without triggering this
+ /// event.
+ ///
+ private void AfterInsert(EntityUid uid, DeepFryerComponent component, EntityUid item)
+ {
+ if (HasBubblingOil(uid, component))
+ _audioSystem.PlayPvs(component.SoundInsertItem, uid, AudioParamsInsertRemove);
+
+ UpdateNextFryTime(uid, component);
+ UpdateUserInterface(uid, component);
+ }
+
+ private void OnPowerChange(EntityUid uid, DeepFryerComponent component, ref PowerChangedEvent args)
+ {
+ _appearanceSystem.SetData(uid, DeepFryerVisuals.Bubbling, args.Powered);
+ UpdateNextFryTime(uid, component);
+ UpdateAmbientSound(uid, component);
+ }
+
+ private void OnDeconstruct(EntityUid uid, DeepFryerComponent component, MachineDeconstructedEvent args)
+ {
+ // The EmptyOnMachineDeconstruct component handles the entity container for us.
+ _puddleSystem.TrySpillAt(uid, component.Solution, out var _);
+ }
+
+ private void OnDestruction(EntityUid uid, DeepFryerComponent component, DestructionEventArgs args)
+ {
+ _containerSystem.EmptyContainer(component.Storage, true);
+ }
+
+ private void OnRefreshParts(EntityUid uid, DeepFryerComponent component, RefreshPartsEvent args)
+ {
+ var ratingStorage = args.PartRatings[component.MachinePartStorageMax];
+
+ component.StorageMaxEntities = component.BaseStorageMaxEntities + (int) (component.StoragePerPartRating * (ratingStorage - 1));
+ }
+
+ ///
+ /// Allow thrown items to land in a basket.
+ ///
+ private void OnThrowHitBy(EntityUid uid, DeepFryerComponent component, ThrowHitByEvent args)
+ {
+ if (args.Handled)
+ return;
+
+ // Chefs never miss this. :)
+ float missChance = HasComp(args.User) ? 0f : ThrowMissChance;
+
+ if (!CanInsertItem(uid, component, args.Thrown) ||
+ _random.Prob(missChance) ||
+ !component.Storage.Insert(args.Thrown))
+ {
+ _popupSystem.PopupEntity(
+ Loc.GetString("deep-fryer-thrown-missed"),
+ uid);
+
+ if (args.User != null)
+ _adminLogManager.Add(LogType.Action, LogImpact.Low,
+ $"{ToPrettyString(args.User.Value)} threw {ToPrettyString(args.Thrown)} at {ToPrettyString(uid)}, and it missed.");
+
+ return;
+ }
+
+ if (GetOilVolume(uid, component) < component.SafeOilVolume)
+ _popupSystem.PopupEntity(
+ Loc.GetString("deep-fryer-thrown-hit-oil-low"),
+ uid);
+ else
+ _popupSystem.PopupEntity(
+ Loc.GetString("deep-fryer-thrown-hit-oil"),
+ uid);
+
+ if (args.User != null)
+ _adminLogManager.Add(LogType.Action, LogImpact.Low,
+ $"{ToPrettyString(args.User.Value)} threw {ToPrettyString(args.Thrown)} at {ToPrettyString(uid)}, and it landed inside.");
+
+ AfterInsert(uid, component, args.Thrown);
+
+ args.Handled = true;
+ }
+
+ private void OnSolutionChange(EntityUid uid, DeepFryerComponent component, SolutionChangedEvent args)
+ {
+ UpdateUserInterface(uid, component);
+ UpdateAmbientSound(uid, component);
+ }
+
+ private void OnRelayMovement(EntityUid uid, DeepFryerComponent component, ref ContainerRelayMovementEntityEvent args)
+ {
+ if (!component.Storage.Remove(args.Entity, EntityManager, destination: Transform(uid).Coordinates))
+ return;
+
+ _popupSystem.PopupEntity(
+ Loc.GetString("deep-fryer-entity-escape",
+ ("victim", Identity.Entity(args.Entity, EntityManager)),
+ ("deepFryer", uid)),
+ uid,
+ PopupType.SmallCaution);
+ }
+
+ public bool CanInsertItem(EntityUid uid, DeepFryerComponent component, EntityUid item)
+ {
+ // Keep this consistent with the checks in TryInsertItem.
+ return (HasComp(item) &&
+ !HasComp(item) &&
+ component.Storage.ContainedEntities.Count < component.StorageMaxEntities);
+ }
+
+ private bool TryInsertItem(EntityUid uid, DeepFryerComponent component, EntityUid user, EntityUid item)
+ {
+ if (!HasComp(item))
+ {
+ _popupSystem.PopupEntity(
+ Loc.GetString("deep-fryer-interact-using-not-item"),
+ uid,
+ user);
+ return false;
+ }
+
+ if (HasComp(item))
+ {
+ _popupSystem.PopupEntity(
+ Loc.GetString("deep-fryer-storage-no-fit",
+ ("item", item)),
+ uid,
+ user);
+ return false;
+ }
+
+ if (component.Storage.ContainedEntities.Count >= component.StorageMaxEntities)
+ {
+ _popupSystem.PopupEntity(
+ Loc.GetString("deep-fryer-storage-full"),
+ uid,
+ user);
+ return false;
+ }
+
+ if (!_handsSystem.TryDropIntoContainer(user, item, component.Storage))
+ return false;
+
+ AfterInsert(uid, component, item);
+
+ _adminLogManager.Add(LogType.Action, LogImpact.Low,
+ $"{ToPrettyString(user)} put {ToPrettyString(item)} inside {ToPrettyString(uid)}.");
+
+ return true;
+ }
+
+ private void OnInteractUsing(EntityUid uid, DeepFryerComponent component, InteractUsingEvent args)
+ {
+ if (args.Handled)
+ return;
+
+ // By default, allow entities with SolutionTransfer or Tool
+ // components to perform their usual actions. Inserting them (if
+ // the chef really wants to) will be supported through the UI.
+ if (HasComp(args.Used) ||
+ HasComp(args.Used))
+ {
+ return;
+ }
+
+ if (TryInsertItem(uid, component, args.User, args.Used))
+ args.Handled = true;
+ }
+
+ private void OnBeforeActivatableUIOpen(EntityUid uid, DeepFryerComponent component, BeforeActivatableUIOpenEvent args)
+ {
+ UpdateUserInterface(uid, component);
+ }
+
+ private void OnRemoveItem(EntityUid uid, DeepFryerComponent component, DeepFryerRemoveItemMessage args)
+ {
+ var removedItem = EntityManager.GetEntity( args.Item );
+ if (removedItem.Valid) { //JJ Comment - This line should be unnecessary. Some issue is keeping the UI from updating when converting straight to a Burned Mess while the UI is still open. To replicate, put a Raw Meat in the fryer with no oil in it. Wait until it sputters with no effect. It should transform to Burned Mess, but doesn't.
+ if (!component.Storage.Remove(removedItem))
+ return;
+
+ var user = args.Session.AttachedEntity;
+
+ if (user != null)
+ {
+ _handsSystem.TryPickupAnyHand(user.Value, removedItem);
+
+ _adminLogManager.Add(LogType.Action, LogImpact.Low,
+ $"{ToPrettyString(user.Value)} took {ToPrettyString(args.Item)} out of {ToPrettyString(uid)}.");
+ }
+
+ _audioSystem.PlayPvs(component.SoundRemoveItem, uid, AudioParamsInsertRemove);
+
+ UpdateUserInterface(component.Owner, component);
+ }
+ }
+
+ private void OnInsertItem(EntityUid uid, DeepFryerComponent component, DeepFryerInsertItemMessage args)
+ {
+ var user = args.Session.AttachedEntity;
+
+ if (user == null ||
+ !TryComp(user, out var handsComponent) ||
+ handsComponent.ActiveHandEntity == null)
+ {
+ return;
+ }
+
+ if (handsComponent.ActiveHandEntity != null)
+ TryInsertItem(uid, component, user.Value, handsComponent.ActiveHandEntity.Value);
+ }
+
+ ///
+ /// This is a helper function for ScoopVat and ClearSlag.
+ ///
+ private bool TryGetActiveHandSolutionContainer(
+ EntityUid fryer,
+ EntityUid user,
+ [NotNullWhen(true)] out EntityUid? heldItem,
+ [NotNullWhen(true)] out Solution? solution,
+ out FixedPoint2 transferAmount)
+ {
+ heldItem = null;
+ solution = null;
+ transferAmount = FixedPoint2.Zero;
+
+ if (!TryComp(user, out var handsComponent))
+ return false;
+
+ heldItem = handsComponent.ActiveHandEntity;
+
+ if (heldItem == null ||
+ !TryComp(heldItem, out var solutionTransferComponent) ||
+ !_solutionContainerSystem.TryGetRefillableSolution(heldItem.Value, out var refillableSolution) ||
+ !solutionTransferComponent.CanReceive)
+ {
+ _popupSystem.PopupEntity(
+ Loc.GetString("deep-fryer-need-liquid-container-in-hand"),
+ fryer,
+ user);
+
+ return false;
+ }
+
+ solution = refillableSolution;
+ transferAmount = solutionTransferComponent.TransferAmount;
+
+ return true;
+ }
+
+ private void OnScoopVat(EntityUid uid, DeepFryerComponent component, DeepFryerScoopVatMessage args)
+ {
+ var user = args.Session.AttachedEntity;
+
+ if (user == null ||
+ !TryGetActiveHandSolutionContainer(uid, user.Value, out var heldItem, out var heldSolution, out var transferAmount))
+ {
+ return;
+ }
+
+ _solutionTransferSystem.Transfer(user.Value,
+ uid,
+ component.Solution,
+ heldItem.Value,
+ heldSolution,
+ transferAmount);
+
+ // UI update is not necessary here, because the solution change event handles it.
+ }
+
+ private void OnClearSlagStart(EntityUid uid, DeepFryerComponent component, DeepFryerClearSlagMessage args)
+ {
+ var user = args.Session.AttachedEntity;
+
+ if (user == null ||
+ !TryGetActiveHandSolutionContainer(uid, user.Value, out var heldItem, out var heldSolution, out var transferAmount))
+ {
+ return;
+ }
+
+ var wasteVolume = GetWasteVolume(uid, component);
+ if (wasteVolume == FixedPoint2.Zero)
+ {
+ _popupSystem.PopupEntity(
+ Loc.GetString("deep-fryer-oil-no-slag"),
+ uid,
+ user.Value);
+
+ return;
+ }
+
+ var delay = Math.Clamp((float) wasteVolume * 0.1f, 1f, 5f);
+
+ var ev = new ClearSlagDoAfterEvent(heldSolution, transferAmount);
+
+ //JJ Comment - not sure I have DoAfterArgs configured correctly.
+ var doAfterArgs = new DoAfterArgs(EntityManager, user.Value, delay, ev, uid, uid, used: heldItem)
+ {
+ BreakOnDamage = true,
+ BreakOnTargetMove = true,
+ BreakOnUserMove = true,
+ MovementThreshold = 0.25f,
+ NeedHand = true,
+ };
+
+ _doAfterSystem.TryStartDoAfter(doAfterArgs);
+ }
+
+ private void OnRemoveAllItems(EntityUid uid, DeepFryerComponent component, DeepFryerRemoveAllItemsMessage args)
+ {
+ if (component.Storage.ContainedEntities.Count == 0)
+ return;
+
+ _containerSystem.EmptyContainer(component.Storage, false);
+
+ var user = args.Session.AttachedEntity;
+
+ if (user != null)
+ _adminLogManager.Add(LogType.Action, LogImpact.Low,
+ $"{ToPrettyString(user.Value)} removed all items from {ToPrettyString(uid)}.");
+
+ _audioSystem.PlayPvs(component.SoundRemoveItem, uid, AudioParamsInsertRemove);
+
+ UpdateUserInterface(component.Owner, component);
+ }
+
+ private void OnClearSlag(EntityUid uid, DeepFryerComponent component, ClearSlagDoAfterEvent args)
+ {
+ if (args.Handled || args.Cancelled || args.Args.Used == null)
+ return;
+
+ FixedPoint2 reagentCount = component.WasteReagents.Count();
+
+ var removingSolution = new Solution();
+ foreach (var reagent in component.WasteReagents)
+ {
+ var removed = component.Solution.RemoveReagent(reagent.Reagent.ToString(), args.Amount / reagentCount);
+ removingSolution.AddReagent(reagent.Reagent.ToString(), removed);
+ }
+
+ _solutionContainerSystem.UpdateChemicals(uid, component.Solution);
+ _solutionContainerSystem.TryMixAndOverflow(args.Args.Used.Value, args.Solution, removingSolution, args.Solution.MaxVolume, out var _);
+ }
+ private void OnInitDeepFried(EntityUid uid, DeepFriedComponent component, ComponentInit args)
+ {
+ var meta = MetaData(uid);
+ component.OriginalName = meta.EntityName;
+ meta.EntityName = Loc.GetString("deep-fried-crispy-item", ("entity", meta.EntityName));
+ }
+
+ private void OnExamineFried(EntityUid uid, DeepFriedComponent component, ExaminedEvent args)
+ {
+ switch (component.Crispiness)
+ {
+ case 0:
+ args.PushMarkup(Loc.GetString("deep-fried-crispy-item-examine"));
+ break;
+ case 1:
+ args.PushMarkup(Loc.GetString("deep-fried-fried-item-examine"));
+ break;
+ default:
+ args.PushMarkup(Loc.GetString("deep-fried-burned-item-examine"));
+ break;
+ }
+ }
+
+ private void OnPriceCalculation(EntityUid uid, DeepFriedComponent component, ref PriceCalculationEvent args)
+ {
+ args.Price *= component.PriceCoefficient;
+ }
+
+ private void OnSliceDeepFried(EntityUid uid, DeepFriedComponent component, SliceFoodEvent args)
+ {
+ MakeCrispy(args.Slice);
+
+ // Copy relevant values to the slice.
+ var sourceDeepFriedComponent = Comp(args.Food);
+ var sliceDeepFriedComponent = Comp(args.Slice);
+
+ sliceDeepFriedComponent.Crispiness = sourceDeepFriedComponent.Crispiness;
+ sliceDeepFriedComponent.PriceCoefficient = sourceDeepFriedComponent.PriceCoefficient;
+
+ UpdateDeepFriedName(args.Slice, sliceDeepFriedComponent);
+
+ // TODO: Flavor profiles aren't copied to the slices. This should
+ // probably be handled on upstream, but for now let's assume the
+ // oil of the deep fryer is overpowering enough for this small
+ // hack. This is likely the only place where it would be useful.
+ if (TryComp(args.Food, out var sourceFlavorProfileComponent) &&
+ TryComp(args.Slice, out var sliceFlavorProfileComponent))
+ {
+ sliceFlavorProfileComponent.Flavors.UnionWith(sourceFlavorProfileComponent.Flavors);
+ sliceFlavorProfileComponent.IgnoreReagents.UnionWith(sourceFlavorProfileComponent.IgnoreReagents);
+ }
+ }
+ }
+
+
+ public sealed class DeepFryAttemptEvent : CancellableEntityEventArgs
+ {
+ public EntityUid DeepFryer { get; }
+
+ public DeepFryAttemptEvent(EntityUid deepFryer)
+ {
+ DeepFryer = deepFryer;
+ }
+ }
+
+ public sealed class BeingDeepFriedEvent : EntityEventArgs
+ {
+ public EntityUid DeepFryer { get; }
+ public EntityUid Item { get; }
+ public bool TurnIntoFood { get; set; }
+
+ public BeingDeepFriedEvent(EntityUid deepFryer, EntityUid item)
+ {
+ DeepFryer = deepFryer;
+ Item = item;
+ }
+ }
+}
diff --git a/Content.Server/Nyanotrasen/Players/PlayTimeTracking/PlayTimeTrackingManager.Whitelist.cs b/Content.Server/Nyanotrasen/Players/PlayTimeTracking/PlayTimeTrackingManager.Whitelist.cs
new file mode 100644
index 00000000000..335384934ca
--- /dev/null
+++ b/Content.Server/Nyanotrasen/Players/PlayTimeTracking/PlayTimeTrackingManager.Whitelist.cs
@@ -0,0 +1,20 @@
+using Content.Server.Players;
+using Content.Shared.Players.PlayTimeTracking;
+using Robust.Server.Player;
+
+namespace Content.Server.Players.PlayTimeTracking;
+
+public sealed partial class PlayTimeTrackingManager
+{
+ public void SendWhitelistCached(IPlayerSession playerSession)
+ {
+ var whitelist = playerSession.ContentData()?.Whitelisted ?? false;
+
+ var msg = new MsgWhitelist
+ {
+ Whitelisted = whitelist
+ };
+
+ _net.ServerSendMessage(msg, playerSession.ConnectedClient);
+ }
+}
diff --git a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingManager.cs b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingManager.cs
index 50c64e718c3..8708bb69c47 100644
--- a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingManager.cs
+++ b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingManager.cs
@@ -54,7 +54,7 @@ namespace Content.Server.Players.PlayTimeTracking;
/// Operations like refreshing and sending play time info to clients are deferred until the next frame (note: not tick).
///
///
-public sealed class PlayTimeTrackingManager
+public sealed partial class PlayTimeTrackingManager
{
[Dependency] private readonly IServerDbManager _db = default!;
[Dependency] private readonly IServerNetManager _net = default!;
@@ -85,6 +85,7 @@ public void Initialize()
_sawmill = Logger.GetSawmill("play_time");
_net.RegisterNetMessage();
+ _net.RegisterNetMessage(); // Nyanotrasen - Whitelist status
_cfg.OnValueChanged(CCVars.PlayTimeSaveInterval, f => _saveInterval = TimeSpan.FromSeconds(f), true);
}
diff --git a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs
index 13d0794dd5e..7d62c54fc26 100644
--- a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs
+++ b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs
@@ -165,7 +165,9 @@ public bool IsAllowed(IPlayerSession player, string role)
var playTimes = _tracking.GetTrackerTimes(player);
- return JobRequirements.TryRequirementsMet(job, playTimes, out _, EntityManager, _prototypes);
+ var isWhitelisted = player.ContentData()?.Whitelisted ?? false; // DeltaV - Whitelist requirement
+
+ return JobRequirements.TryRequirementsMet(job, playTimes, out _, EntityManager, _prototypes, isWhitelisted);
}
public HashSet GetDisallowedJobs(IPlayerSession player)
@@ -175,6 +177,7 @@ public HashSet GetDisallowedJobs(IPlayerSession player)
return roles;
var playTimes = _tracking.GetTrackerTimes(player);
+ var isWhitelisted = player.ContentData()?.Whitelisted ?? false; // DeltaV - Whitelist requirement
foreach (var job in _prototypes.EnumeratePrototypes())
{
@@ -182,7 +185,7 @@ public HashSet GetDisallowedJobs(IPlayerSession player)
{
foreach (var requirement in job.Requirements)
{
- if (JobRequirements.TryRequirementMet(requirement, playTimes, out _, EntityManager, _prototypes))
+ if (JobRequirements.TryRequirementMet(requirement, playTimes, out _, EntityManager, _prototypes, isWhitelisted))
continue;
goto NoRole;
@@ -209,6 +212,8 @@ public void RemoveDisallowedJobs(NetUserId userId, ref List jobs)
playTimes ??= new Dictionary();
}
+ var isWhitelisted = player.ContentData()?.Whitelisted ?? false; // DeltaV - Whitelist requirement
+
for (var i = 0; i < jobs.Count; i++)
{
var job = jobs[i];
@@ -220,7 +225,7 @@ public void RemoveDisallowedJobs(NetUserId userId, ref List jobs)
foreach (var requirement in jobber.Requirements)
{
- if (JobRequirements.TryRequirementMet(requirement, playTimes, out _, EntityManager, _prototypes))
+ if (JobRequirements.TryRequirementMet(requirement, playTimes, out _, EntityManager, _prototypes, isWhitelisted))
continue;
jobs.RemoveSwap(i);
diff --git a/Content.Server/Whitelist/WhitelistCommands.cs b/Content.Server/Whitelist/WhitelistCommands.cs
index 59b576e7ca4..67d9645414c 100644
--- a/Content.Server/Whitelist/WhitelistCommands.cs
+++ b/Content.Server/Whitelist/WhitelistCommands.cs
@@ -1,7 +1,9 @@
using Content.Server.Administration;
using Content.Server.Database;
+using Content.Server.Players.PlayTimeTracking;
using Content.Shared.Administration;
using Content.Shared.CCVar;
+using Content.Shared.Players;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Console;
@@ -22,6 +24,8 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args)
var db = IoCManager.Resolve();
var loc = IoCManager.Resolve();
+ var player = IoCManager.Resolve();
+ var playtime = IoCManager.Resolve();
var name = args[0];
var data = await loc.LookupIdByNameAsync(name);
@@ -37,6 +41,15 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args)
}
await db.AddToWhitelistAsync(guid);
+
+ // Nyanotrasen - Update whitelist status in player data.
+ if (player.TryGetPlayerDataByUsername(name, out var playerData) &&
+ player.TryGetSessionByUsername(name, out var session))
+ {
+ playerData.ContentData()!.Whitelisted = true;
+ playtime.SendWhitelistCached(session);
+ }
+
shell.WriteLine(Loc.GetString("command-whitelistadd-added", ("username", data.Username)));
return;
}
@@ -58,6 +71,8 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args)
var db = IoCManager.Resolve();
var loc = IoCManager.Resolve();
+ var player = IoCManager.Resolve();
+ var playtime = IoCManager.Resolve();
var name = args[0];
var data = await loc.LookupIdByNameAsync(name);
@@ -73,6 +88,15 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args)
}
await db.RemoveFromWhitelistAsync(guid);
+
+ // Nyanotrasen - Update whitelist status in player data.
+ if (player.TryGetPlayerDataByUsername(name, out var playerData) &&
+ player.TryGetSessionByUsername(name, out var session))
+ {
+ playerData.ContentData()!.Whitelisted = false;
+ playtime.SendWhitelistCached(session);
+ }
+
shell.WriteLine(Loc.GetString("command-whitelistremove-removed", ("username", data.Username)));
return;
}
diff --git a/Content.Shared/DeltaV/Harpy/HarpySingerSystem.cs b/Content.Shared/DeltaV/Harpy/HarpySingerSystem.cs
index bdc378d4e94..50e8b6302c0 100644
--- a/Content.Shared/DeltaV/Harpy/HarpySingerSystem.cs
+++ b/Content.Shared/DeltaV/Harpy/HarpySingerSystem.cs
@@ -25,3 +25,4 @@ private void OnShutdown(EntityUid uid, HarpySingerComponent component, Component
}
}
}
+
diff --git a/Content.Shared/DeltaV/Roles/JobRequirements.Whitelist.cs b/Content.Shared/DeltaV/Roles/JobRequirements.Whitelist.cs
new file mode 100644
index 00000000000..a6e352991e9
--- /dev/null
+++ b/Content.Shared/DeltaV/Roles/JobRequirements.Whitelist.cs
@@ -0,0 +1,11 @@
+using JetBrains.Annotations;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Roles
+{
+ [UsedImplicitly]
+ [Serializable, NetSerializable]
+ public sealed partial class WhitelistRequirement : JobRequirement
+ {
+ }
+}
diff --git a/Content.Shared/Humanoid/HumanoidCharacterAppearance.cs b/Content.Shared/Humanoid/HumanoidCharacterAppearance.cs
index 1ffcd1870be..f1f7de5c11a 100644
--- a/Content.Shared/Humanoid/HumanoidCharacterAppearance.cs
+++ b/Content.Shared/Humanoid/HumanoidCharacterAppearance.cs
@@ -104,6 +104,8 @@ public static HumanoidCharacterAppearance DefaultWithSpecies(string species)
HumanoidSkinColor.HumanToned => Humanoid.SkinColor.HumanSkinTone(speciesPrototype.DefaultHumanSkinTone),
HumanoidSkinColor.Hues => speciesPrototype.DefaultSkinTone,
HumanoidSkinColor.TintedHues => Humanoid.SkinColor.TintedHues(speciesPrototype.DefaultSkinTone),
+ // DeltaV - Blended tint for moths
+ HumanoidSkinColor.TintedHuesSkin => Humanoid.SkinColor.TintedHuesSkin(speciesPrototype.DefaultSkinTone, speciesPrototype.DefaultSkinTone),
_ => Humanoid.SkinColor.ValidHumanSkinTone
};
@@ -153,6 +155,7 @@ public static HumanoidCharacterAppearance Random(string species, Sex sex)
var newEyeColor = random.Pick(RealisticEyeColors);
var skinType = IoCManager.Resolve().Index(species).SkinColoration;
+ var skinTone = IoCManager.Resolve().Index(species).DefaultSkinTone; // DeltaV, required for tone blending
var newSkinColor = Humanoid.SkinColor.ValidHumanSkinTone;
switch (skinType)
@@ -168,6 +171,12 @@ public static HumanoidCharacterAppearance Random(string species, Sex sex)
var bbyte = random.NextByte();
newSkinColor = new Color(rbyte, gbyte, bbyte);
break;
+ case HumanoidSkinColor.TintedHuesSkin: // DeltaV, tone blending
+ rbyte = random.NextByte();
+ gbyte = random.NextByte();
+ bbyte = random.NextByte();
+ newSkinColor = new Color(rbyte, gbyte, bbyte);
+ break;
}
if (skinType == HumanoidSkinColor.TintedHues)
@@ -175,6 +184,11 @@ public static HumanoidCharacterAppearance Random(string species, Sex sex)
newSkinColor = Humanoid.SkinColor.ValidTintedHuesSkinTone(newSkinColor);
}
+ if (skinType == HumanoidSkinColor.TintedHuesSkin) // DeltaV, tone blending
+ {
+ newSkinColor = Humanoid.SkinColor.ValidTintedHuesSkinTone(skinTone, newSkinColor);
+ }
+
return new HumanoidCharacterAppearance(newHairStyle, newHairColor, newFacialHairStyle, newHairColor, newEyeColor, newSkinColor, new ());
float RandomizeColor(float channel)
diff --git a/Content.Shared/Humanoid/SkinColor.cs b/Content.Shared/Humanoid/SkinColor.cs
index 89c78b7ea00..4fc4f5ce2cd 100644
--- a/Content.Shared/Humanoid/SkinColor.cs
+++ b/Content.Shared/Humanoid/SkinColor.cs
@@ -12,9 +12,9 @@ public static class SkinColor
///
/// The color to validate
/// Validated tinted hue skin tone
- public static Color ValidTintedHuesSkinTone(Color color)
+ public static Color ValidTintedHuesSkinTone(Color color, Color? skinTone = null)
{
- return TintedHues(color);
+ return skinTone != null ? TintedHuesSkin(color, skinTone.Value) : TintedHues(color);
}
///
@@ -127,6 +127,25 @@ public static Color TintedHues(Color color)
return Color.FromHsv(newColor);
}
+ ///
+ /// DeltaV - Convert a color to the 'tinted hues' skin tone type, and blend it into skinColor
+ ///
+ /// Color to convert
+ /// The skin color to blend with
+ /// Blending factor (0.0 to 1.0)
+ /// Tinted hue color
+ public static Color TintedHuesSkin(Color color, Color skinColor, float blendFactor = 0.5f)
+ {
+ blendFactor = MathHelper.Clamp(blendFactor, 0.0f, 1.0f);
+
+ var r = MathHelper.Lerp(skinColor.R, color.R, blendFactor);
+ var g = MathHelper.Lerp(skinColor.G, color.G, blendFactor);
+ var b = MathHelper.Lerp(skinColor.B, color.B, blendFactor);
+ var a = color.A;
+
+ return new Color(r, g, b, a);
+ }
+
///
/// Verify if this color is a valid tinted hue color type, or not.
///
@@ -144,6 +163,7 @@ public static bool VerifySkinColor(HumanoidSkinColor type, Color color)
{
HumanoidSkinColor.HumanToned => VerifyHumanSkinTone(color),
HumanoidSkinColor.TintedHues => VerifyTintedHues(color),
+ HumanoidSkinColor.TintedHuesSkin => true, // DeltaV - Tone blending
HumanoidSkinColor.Hues => true,
_ => false,
};
@@ -155,6 +175,7 @@ public static Color ValidSkinTone(HumanoidSkinColor type, Color color)
{
HumanoidSkinColor.HumanToned => ValidHumanSkinTone,
HumanoidSkinColor.TintedHues => ValidTintedHuesSkinTone(color),
+ HumanoidSkinColor.TintedHuesSkin => ValidTintedHuesSkinTone(color), // DeltaV - Tone blending
_ => color
};
}
@@ -165,4 +186,5 @@ public enum HumanoidSkinColor : byte
HumanToned,
Hues,
TintedHues, //This gives a color tint to a humanoid's skin (10% saturation with full hue range).
+ TintedHuesSkin, // DeltaV - Default TintedHues assumes the texture will have the proper skin color, but moths dont
}
diff --git a/Content.Shared/Nyanotrasen/Kitchen/ClearSlagDoAfterEvent.cs b/Content.Shared/Nyanotrasen/Kitchen/ClearSlagDoAfterEvent.cs
new file mode 100644
index 00000000000..e4ecb88d9a4
--- /dev/null
+++ b/Content.Shared/Nyanotrasen/Kitchen/ClearSlagDoAfterEvent.cs
@@ -0,0 +1,29 @@
+using Robust.Shared.Serialization;
+using Content.Shared.Chemistry.Components;
+using Content.Shared.DoAfter;
+using Content.Shared.FixedPoint;
+
+namespace Content.Shared.Kitchen
+{
+ [Serializable, NetSerializable]
+ public sealed partial class ClearSlagDoAfterEvent : DoAfterEvent
+ {
+ [DataField("solution", required: true)]
+ public Solution Solution = default!;
+
+ [DataField("amount", required: true)]
+ public FixedPoint2 Amount;
+
+ private ClearSlagDoAfterEvent()
+ {
+ }
+
+ public ClearSlagDoAfterEvent(Solution solution, FixedPoint2 amount)
+ {
+ Solution = solution;
+ Amount = amount;
+ }
+
+ public override DoAfterEvent Clone() => this;
+ }
+}
diff --git a/Content.Shared/Nyanotrasen/Kitchen/Components/SharedDeepFriedComponent.cs b/Content.Shared/Nyanotrasen/Kitchen/Components/SharedDeepFriedComponent.cs
new file mode 100644
index 00000000000..51eca172981
--- /dev/null
+++ b/Content.Shared/Nyanotrasen/Kitchen/Components/SharedDeepFriedComponent.cs
@@ -0,0 +1,22 @@
+using Robust.Shared.GameStates;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Kitchen.Components
+{
+ [NetworkedComponent]
+ public abstract partial class SharedDeepFriedComponent : Component
+ {
+ ///
+ /// How deep-fried is this item?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("crispiness")]
+ public int Crispiness { get; set; }
+ }
+
+ [Serializable, NetSerializable]
+ public enum DeepFriedVisuals : byte
+ {
+ Fried,
+ }
+}
diff --git a/Content.Shared/Nyanotrasen/Kitchen/Components/SharedDeepFryerComponent.cs b/Content.Shared/Nyanotrasen/Kitchen/Components/SharedDeepFryerComponent.cs
new file mode 100644
index 00000000000..da7319869d9
--- /dev/null
+++ b/Content.Shared/Nyanotrasen/Kitchen/Components/SharedDeepFryerComponent.cs
@@ -0,0 +1,12 @@
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Kitchen.Components
+{
+ public abstract partial class SharedDeepFryerComponent : Component { }
+
+ [Serializable, NetSerializable]
+ public enum DeepFryerVisuals : byte
+ {
+ Bubbling,
+ }
+}
diff --git a/Content.Shared/Nyanotrasen/Kitchen/UI/DeepFryerMessages.cs b/Content.Shared/Nyanotrasen/Kitchen/UI/DeepFryerMessages.cs
new file mode 100644
index 00000000000..fa1df8a71e8
--- /dev/null
+++ b/Content.Shared/Nyanotrasen/Kitchen/UI/DeepFryerMessages.cs
@@ -0,0 +1,67 @@
+using Robust.Shared.Serialization;
+using Content.Shared.FixedPoint;
+
+namespace Content.Shared.Kitchen.UI
+{
+ [Serializable, NetSerializable]
+ public sealed class DeepFryerBoundUserInterfaceState : BoundUserInterfaceState
+ {
+ public readonly FixedPoint2 OilLevel;
+ public readonly FixedPoint2 OilPurity;
+ public readonly FixedPoint2 FryingOilThreshold;
+ public readonly NetEntity[] ContainedEntities;
+
+ public DeepFryerBoundUserInterfaceState(
+ FixedPoint2 oilLevel,
+ FixedPoint2 oilPurity,
+ FixedPoint2 fryingOilThreshold,
+ NetEntity[] containedEntities)
+ {
+ OilLevel = oilLevel;
+ OilPurity = oilPurity;
+ FryingOilThreshold = fryingOilThreshold;
+ ContainedEntities = containedEntities;
+ }
+ }
+
+ [Serializable, NetSerializable]
+ public sealed class DeepFryerRemoveItemMessage : BoundUserInterfaceMessage
+ {
+ public readonly NetEntity Item;
+
+ public DeepFryerRemoveItemMessage(NetEntity item)
+ {
+ Item = item;
+ }
+ }
+
+ [Serializable, NetSerializable]
+ public sealed class DeepFryerInsertItemMessage : BoundUserInterfaceMessage
+ {
+ public DeepFryerInsertItemMessage() { }
+ }
+
+ [Serializable, NetSerializable]
+ public sealed class DeepFryerScoopVatMessage : BoundUserInterfaceMessage
+ {
+ public DeepFryerScoopVatMessage() { }
+ }
+
+ [Serializable, NetSerializable]
+ public sealed class DeepFryerClearSlagMessage : BoundUserInterfaceMessage
+ {
+ public DeepFryerClearSlagMessage() { }
+ }
+
+ [Serializable, NetSerializable]
+ public sealed class DeepFryerRemoveAllItemsMessage : BoundUserInterfaceMessage
+ {
+ public DeepFryerRemoveAllItemsMessage() { }
+ }
+
+ [NetSerializable, Serializable]
+ public enum DeepFryerUiKey
+ {
+ Key
+ }
+}
diff --git a/Content.Shared/Nyanotrasen/Players/PlayTimeTracking/MsgWhitelist.cs b/Content.Shared/Nyanotrasen/Players/PlayTimeTracking/MsgWhitelist.cs
new file mode 100644
index 00000000000..d930828f327
--- /dev/null
+++ b/Content.Shared/Nyanotrasen/Players/PlayTimeTracking/MsgWhitelist.cs
@@ -0,0 +1,25 @@
+using Lidgren.Network;
+using Robust.Shared.Network;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Players.PlayTimeTracking;
+
+///
+/// Sent server -> client to inform the client of their whitelist status.
+///
+public sealed class MsgWhitelist : NetMessage
+{
+ public override MsgGroups MsgGroup => MsgGroups.EntityEvent;
+
+ public bool Whitelisted = false;
+
+ public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer serializer)
+ {
+ Whitelisted = buffer.ReadBoolean();
+ }
+
+ public override void WriteToBuffer(NetOutgoingMessage buffer, IRobustSerializer serializer)
+ {
+ buffer.Write(Whitelisted);
+ }
+}
diff --git a/Content.Shared/Players/PlayerData.cs b/Content.Shared/Players/PlayerData.cs
index c6274c950bd..d94bef2e387 100644
--- a/Content.Shared/Players/PlayerData.cs
+++ b/Content.Shared/Players/PlayerData.cs
@@ -38,6 +38,12 @@ public sealed class PlayerData
///
public bool ExplicitlyDeadminned { get; set; }
+ ///
+ /// Nyanotrasen - Are they whitelisted? Lets us avoid async.
+ ///
+ [ViewVariables]
+ public bool Whitelisted { get; set; }
+
public PlayerData(NetUserId userId, string name)
{
UserId = userId;
diff --git a/Content.Shared/Roles/JobRequirements.cs b/Content.Shared/Roles/JobRequirements.cs
index fc3b759a9c2..2785e988bcd 100644
--- a/Content.Shared/Roles/JobRequirements.cs
+++ b/Content.Shared/Roles/JobRequirements.cs
@@ -2,6 +2,7 @@
using Content.Shared.Players.PlayTimeTracking;
using Content.Shared.Roles.Jobs;
using JetBrains.Annotations;
+using Robust.Shared.Players;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
@@ -76,7 +77,8 @@ public static bool TryRequirementsMet(
Dictionary playTimes,
[NotNullWhen(false)] out FormattedMessage? reason,
IEntityManager entManager,
- IPrototypeManager prototypes)
+ IPrototypeManager prototypes,
+ bool isWhitelisted)
{
reason = null;
if (job.Requirements == null)
@@ -84,7 +86,7 @@ public static bool TryRequirementsMet(
foreach (var requirement in job.Requirements)
{
- if (!TryRequirementMet(requirement, playTimes, out reason, entManager, prototypes))
+ if (!TryRequirementMet(requirement, playTimes, out reason, entManager, prototypes, isWhitelisted))
return false;
}
@@ -99,7 +101,8 @@ public static bool TryRequirementMet(
Dictionary playTimes,
[NotNullWhen(false)] out FormattedMessage? reason,
IEntityManager entManager,
- IPrototypeManager prototypes)
+ IPrototypeManager prototypes,
+ bool isWhitelisted)
{
reason = null;
@@ -216,6 +219,15 @@ public static bool TryRequirementMet(
return true;
}
+ case WhitelistRequirement _: // DeltaV - Whitelist requirement
+ if (isWhitelisted == null)
+ throw new ArgumentNullException(nameof(isWhitelisted), "isWhitelisted cannot be null.");
+
+ if (isWhitelisted)
+ return true;
+
+ reason = FormattedMessage.FromMarkup(Loc.GetString("playtime-deny-reason-not-whitelisted"));
+ return false;
default:
throw new NotImplementedException();
}
diff --git a/Content.Shared/Throwing/ThrowEvents.cs b/Content.Shared/Throwing/ThrowEvents.cs
index fbda80b8ca9..5ea78b862ed 100644
--- a/Content.Shared/Throwing/ThrowEvents.cs
+++ b/Content.Shared/Throwing/ThrowEvents.cs
@@ -5,12 +5,19 @@ namespace Content.Shared.Throwing
///
public abstract class ThrowEvent : HandledEntityEventArgs
{
+ ///Nyano - Summary: Allows us to tell who threw the item. It matters!
+ ///
+ /// The entity that threw .
+ ///
+ public EntityUid? User { get; }
+ // End Nyano code.
public readonly EntityUid Thrown;
public readonly EntityUid Target;
public ThrownItemComponent Component;
- public ThrowEvent(EntityUid thrown, EntityUid target, ThrownItemComponent component)
+ public ThrowEvent(EntityUid? user, EntityUid thrown, EntityUid target, ThrownItemComponent component) //Nyano - Summary: User added.
{
+ User = user; //Nyano - Summary: User added.
Thrown = thrown;
Target = target;
Component = component;
@@ -22,7 +29,7 @@ public ThrowEvent(EntityUid thrown, EntityUid target, ThrownItemComponent compon
///
public sealed class ThrowHitByEvent : ThrowEvent
{
- public ThrowHitByEvent(EntityUid thrown, EntityUid target, ThrownItemComponent component) : base(thrown, target, component)
+ public ThrowHitByEvent(EntityUid? user, EntityUid thrown, EntityUid target, ThrownItemComponent component) : base(user, thrown, target, component) //Nyano - Summary: User added.
{
}
}
@@ -32,7 +39,7 @@ public ThrowHitByEvent(EntityUid thrown, EntityUid target, ThrownItemComponent c
///
public sealed class ThrowDoHitEvent : ThrowEvent
{
- public ThrowDoHitEvent(EntityUid thrown, EntityUid target, ThrownItemComponent component) : base(thrown, target, component)
+ public ThrowDoHitEvent(EntityUid thrown, EntityUid target, ThrownItemComponent component) : base(null, thrown, target, component) //Nyano - Summary: User added.
{
}
}
diff --git a/Content.Shared/Throwing/ThrownItemSystem.cs b/Content.Shared/Throwing/ThrownItemSystem.cs
index d7856543e4a..073252eb927 100644
--- a/Content.Shared/Throwing/ThrownItemSystem.cs
+++ b/Content.Shared/Throwing/ThrownItemSystem.cs
@@ -140,7 +140,10 @@ public void ThrowCollideInteraction(ThrownItemComponent component, EntityUid thr
_adminLogger.Add(LogType.ThrowHit, LogImpact.Low,
$"{ToPrettyString(thrown):thrown} thrown by {ToPrettyString(component.Thrower.Value):thrower} hit {ToPrettyString(target):target}.");
- RaiseLocalEvent(target, new ThrowHitByEvent(thrown, target, component), true);
+ if (component.Thrower is not null)// Nyano - Summary: Gotta check if there was a thrower.
+ RaiseLocalEvent(target, new ThrowHitByEvent(component.Thrower.Value, thrown, target, component), true); // Nyano - Summary: Gotta update for who threw it.
+ else
+ RaiseLocalEvent(target, new ThrowHitByEvent(null, thrown, target, component), true); // Nyano - Summary: No thrower.
RaiseLocalEvent(thrown, new ThrowDoHitEvent(thrown, target, component), true);
}
diff --git a/Resources/Audio/DeltaV/Misc/license.txt b/Resources/Audio/DeltaV/Misc/license.txt
new file mode 100644
index 00000000000..dfc79979a75
--- /dev/null
+++ b/Resources/Audio/DeltaV/Misc/license.txt
@@ -0,0 +1 @@
+reducedtoatmos.ogg is modified from https://www.youtube.com/watch?v=X2QMN0a_TrA
\ No newline at end of file
diff --git a/Resources/Audio/DeltaV/Misc/reducedtoatmos.ogg b/Resources/Audio/DeltaV/Misc/reducedtoatmos.ogg
new file mode 100644
index 00000000000..d22859110c9
Binary files /dev/null and b/Resources/Audio/DeltaV/Misc/reducedtoatmos.ogg differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_bark1.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_bark1.ogg
deleted file mode 100644
index 55a947fbd8c..00000000000
Binary files a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_bark1.ogg and /dev/null differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_bark2.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_bark2.ogg
deleted file mode 100644
index 6cc61c77d94..00000000000
Binary files a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_bark2.ogg and /dev/null differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_bark3.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_bark3.ogg
deleted file mode 100644
index 3eee456323c..00000000000
Binary files a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_bark3.ogg and /dev/null differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_growl1.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_growl1.ogg
deleted file mode 100644
index 82b54cbc546..00000000000
Binary files a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_growl1.ogg and /dev/null differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_growl2.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_growl2.ogg
deleted file mode 100644
index fa48c9f3d8a..00000000000
Binary files a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_growl2.ogg and /dev/null differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_growl3.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_growl3.ogg
deleted file mode 100644
index 1eb5ed9eded..00000000000
Binary files a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_growl3.ogg and /dev/null differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_snarl1.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_snarl1.ogg
deleted file mode 100644
index 171dcb01798..00000000000
Binary files a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_snarl1.ogg and /dev/null differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_snarl2.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_snarl2.ogg
deleted file mode 100644
index 9b1fe916df6..00000000000
Binary files a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_snarl2.ogg and /dev/null differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_snarl3.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_snarl3.ogg
deleted file mode 100644
index 9f9a19817c1..00000000000
Binary files a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_snarl3.ogg and /dev/null differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_whine.ogg b/Resources/Audio/DeltaV/Voice/Vulpakin/dog_whine.ogg
deleted file mode 100644
index 37309ede597..00000000000
Binary files a/Resources/Audio/DeltaV/Voice/Vulpakin/dog_whine.ogg and /dev/null differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/attributions.yml b/Resources/Audio/DeltaV/Voice/Vulpkanin/attributions.yml
similarity index 100%
rename from Resources/Audio/DeltaV/Voice/Vulpakin/attributions.yml
rename to Resources/Audio/DeltaV/Voice/Vulpkanin/attributions.yml
diff --git a/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_bark1.ogg b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_bark1.ogg
new file mode 100644
index 00000000000..8f3b8fe5bff
Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_bark1.ogg differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_bark2.ogg b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_bark2.ogg
new file mode 100644
index 00000000000..ed4d7bc7868
Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_bark2.ogg differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_bark3.ogg b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_bark3.ogg
new file mode 100644
index 00000000000..13aab8edd40
Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_bark3.ogg differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_growl1.ogg b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_growl1.ogg
new file mode 100644
index 00000000000..d2c99e97e7e
Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_growl1.ogg differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_growl2.ogg b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_growl2.ogg
new file mode 100644
index 00000000000..3eb018413a5
Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_growl2.ogg differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_growl3.ogg b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_growl3.ogg
new file mode 100644
index 00000000000..84b505442d2
Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_growl3.ogg differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_snarl1.ogg b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_snarl1.ogg
new file mode 100644
index 00000000000..4493be060cc
Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_snarl1.ogg differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_snarl2.ogg b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_snarl2.ogg
new file mode 100644
index 00000000000..6529e4e05d0
Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_snarl2.ogg differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_snarl3.ogg b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_snarl3.ogg
new file mode 100644
index 00000000000..fb9e4c7ec7b
Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_snarl3.ogg differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_whine.ogg b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_whine.ogg
new file mode 100644
index 00000000000..47f2e8200d7
Binary files /dev/null and b/Resources/Audio/DeltaV/Voice/Vulpkanin/dog_whine.ogg differ
diff --git a/Resources/Audio/DeltaV/Voice/Vulpakin/license.txt b/Resources/Audio/DeltaV/Voice/Vulpkanin/license.txt
similarity index 100%
rename from Resources/Audio/DeltaV/Voice/Vulpakin/license.txt
rename to Resources/Audio/DeltaV/Voice/Vulpkanin/license.txt
diff --git a/Resources/Audio/Nyanotrasen/Machines/attributions.yml b/Resources/Audio/Nyanotrasen/Machines/attributions.yml
index a3cbc35bb7e..e0d8a8f7ea2 100644
--- a/Resources/Audio/Nyanotrasen/Machines/attributions.yml
+++ b/Resources/Audio/Nyanotrasen/Machines/attributions.yml
@@ -5,3 +5,12 @@
copyright: "https://freesound.org/people/soundmary/"
source: "https://freesound.org/people/soundmary/sounds/194994/"
+- files: ["deepfryer_basket_remove_item.ogg"]
+ license: "CC0-1.0"
+ copyright: "637625__kyles__kitchen-restaurant-fries-deep-fryer-basket-pickup-put-down-clack-metal.flac by kyles. This is a cleaned-up clip converted to OGG."
+ source: "https://freesound.org/people/kyles/sounds/637625/"
+
+- files: ["deepfryer_basket_add_item.ogg"]
+ license: "CC0-1.0"
+ copyright: "440587__ursenfuns__deep-fryer.wav by ursenfuns. This is a cleaned and shortened clip converted to OGG."
+ source: "https://freesound.org/people/ursenfuns/sounds/440587/"
diff --git a/Resources/Audio/Nyanotrasen/Machines/deepfryer_basket_add_item.ogg b/Resources/Audio/Nyanotrasen/Machines/deepfryer_basket_add_item.ogg
new file mode 100644
index 00000000000..b936b52df6b
Binary files /dev/null and b/Resources/Audio/Nyanotrasen/Machines/deepfryer_basket_add_item.ogg differ
diff --git a/Resources/Audio/Nyanotrasen/Machines/deepfryer_basket_remove_item.ogg b/Resources/Audio/Nyanotrasen/Machines/deepfryer_basket_remove_item.ogg
new file mode 100644
index 00000000000..fee16fa25c8
Binary files /dev/null and b/Resources/Audio/Nyanotrasen/Machines/deepfryer_basket_remove_item.ogg differ
diff --git a/Resources/Changelog/DeltaVChangelog.yml b/Resources/Changelog/DeltaVChangelog.yml
index 98db6f440ed..10cb911e4dc 100644
--- a/Resources/Changelog/DeltaVChangelog.yml
+++ b/Resources/Changelog/DeltaVChangelog.yml
@@ -1,4 +1,3 @@
-Name: DeltaV
Entries:
- author: DebugOk
changes:
@@ -417,3 +416,33 @@ Entries:
message: Enhanced intrusion defenses have been deployed in electrical systems.
id: 64
time: '2023-10-15T14:07:21.0000000+00:00'
+- author: leonardo-dabepis
+ changes:
+ - type: Add
+ message: added mothamphetamine drink
+ - type: Tweak
+ message: changed "dulleavene" to "health violation"
+ id: 65
+ time: '2023-10-16T23:25:27.0000000+00:00'
+- author: DebugOk
+ changes:
+ - type: Tweak
+ message: >-
+ Moth coloration has been changed, existing characters might look
+ slightly weird
+ id: 66
+ time: '2023-10-17T20:09:27.0000000+00:00'
+- author: Tex
+ changes:
+ - type: Add
+ message: Added scrambled eggs.
+ id: 67
+ time: '2023-10-18T21:07:50.0000000+00:00'
+- author: DebugOk
+ changes:
+ - type: Add
+ message: >-
+ Certain roles require whitelist now. These being the captain, head of
+ security and nukie commander.
+ id: 68
+ time: '2023-10-18T22:23:18.0000000+00:00'
diff --git a/Resources/ConfigPresets/DeltaV/deltav.toml b/Resources/ConfigPresets/DeltaV/deltav.toml
index 5f1275bb818..5229a2ea965 100644
--- a/Resources/ConfigPresets/DeltaV/deltav.toml
+++ b/Resources/ConfigPresets/DeltaV/deltav.toml
@@ -1,6 +1,7 @@
[game]
desc = "Featuring loads of unique content and psionics."
lobbyenabled = true
+lobbyduration = 240
[infolinks]
discord = "https://discord.gg/deltav"
@@ -33,4 +34,4 @@ ramping_average_chaos = 4.5
monstermos_rip_tiles = false
[server]
-id = "deltav"
\ No newline at end of file
+id = "deltav"
diff --git a/Resources/Locale/en-US/deltav/flavors/flavor-profiles.ftl b/Resources/Locale/en-US/deltav/flavors/flavor-profiles.ftl
index bd46a1ecdf2..d4602b99398 100644
--- a/Resources/Locale/en-US/deltav/flavors/flavor-profiles.ftl
+++ b/Resources/Locale/en-US/deltav/flavors/flavor-profiles.ftl
@@ -26,3 +26,4 @@ flavor-complex-greengrass = like a holiday in the sun
flavor-complex-daiquiri = fashionable
flavor-complex-arsonistsbrew = like ash and flame
flavor-complex-dulleavene = ominous
+flavor-complex-pumpkin = like pumpkin
diff --git a/Resources/Locale/en-US/deltav/markings/harpy.ftl b/Resources/Locale/en-US/deltav/markings/harpy.ftl
index 302a24e06fb..c2e9beb5c87 100644
--- a/Resources/Locale/en-US/deltav/markings/harpy.ftl
+++ b/Resources/Locale/en-US/deltav/markings/harpy.ftl
@@ -1,5 +1,32 @@
marking-HarpyWingDefault = Basic Wings
+marking-HarpyWingDefault-harpy = Wings
+
+marking-HarpyWing2Tone = Two Tone Wings
+marking-HarpyWing2Tone-harpy2tone1 = Top Half
+marking-HarpyWing2Tone-harpy2tone2 = Bottom Half
+
+marking-HarpyWing3Tone = Three Tone Wings
+marking-HarpyWing3Tone-harpy3tone1 = Top Third
+marking-HarpyWing3Tone-harpy3tone2 = Middle Third
+marking-HarpyWing3tone-harpy3tone3 = Bottom Third
+
+marking-HarpyWingSpeckled = Speckled Wings
+marking-HarpyWingSpeckled-harpyspeckled1 = Main
+marking-HarpyWingSpeckled-harpyspeckled2 = Speckles
+
+marking-HarpyWingUndertone = Wings with Undertone
+marking-HarpyWingUndertone-harpyundertone1 = Front
+marking-HarpyWingUndertone-harpyundertone2 = Back
+
+marking-HarpyWingTips = Wings with Feather Tips
+marking-HarpyWingTips-harpywingtip1 = Main
+marking-HarpyWingTips-harpywingtip2 = Feathertips
+
marking-HarpyEarsDefault = Feather Tufts
-marking-HarpyTailSwallow = Swallow Tail
-marking-HarpyTailPhoenix = Phoenix Tail
-marking-HarpyTailRooster = Rooster Tail
\ No newline at end of file
+marking-HarpyEarsDefault-harpy_ears_default = Tufts
+
+marking-HarpyTailPhoenix = Basic Tail
+marking-HarpyTailPhoenix-phoenix_tail = Tail
+
+marking-HarpyTailRooster = Rooster Tail
+marking-HarpyTailRooster-rooster_tail = Tail
diff --git a/Resources/Locale/en-US/deltav/reagents/meta/consumable/drink/drinks.ftl b/Resources/Locale/en-US/deltav/reagents/meta/consumable/drink/drinks.ftl
index 1c7990596f4..01822c0a141 100644
--- a/Resources/Locale/en-US/deltav/reagents/meta/consumable/drink/drinks.ftl
+++ b/Resources/Locale/en-US/deltav/reagents/meta/consumable/drink/drinks.ftl
@@ -16,5 +16,8 @@ reagent-desc-daiquiri = A sweet mix of deadrum and lime, a favourite of writers
reagent-name-arsonistsbrew = arsonist's brew
reagent-desc-arsonistsbrew = Take a sip and laugh, while you watch your world burn.
-reagent-name-dulleavene = dulleavene
-reagent-desc-dulleavene = Allegedly it's a cocktail. The warning cone motif seems apt.
+reagent-name-healthviolation = health violation
+reagent-desc-healthviolation = Allegedly it's a cocktail. The warning cone motif seems apt.
+
+reagent-name-mothamphetamine = mothamphetamine
+regagent-desk-mothamphetamine = A strangely... fuzzy drink. It has a chaotic aura.
diff --git a/Resources/Locale/en-US/job/job-names.ftl b/Resources/Locale/en-US/job/job-names.ftl
index 03d4cebc2e0..fd90e49bb1c 100644
--- a/Resources/Locale/en-US/job/job-names.ftl
+++ b/Resources/Locale/en-US/job/job-names.ftl
@@ -33,7 +33,7 @@ job-name-botanist = Botanist
job-name-bartender = Bartender
job-name-passenger = Passenger
job-name-salvagespec = Salvage specialist
-job-name-qm = Head of Logistics
+job-name-qm = Logistics Officer
job-name-cargotech = Cargo Technician
job-name-chef = Chef
job-name-clown = Clown
@@ -83,7 +83,7 @@ JobMusician = Musician
JobParamedic = Paramedic
JobPassenger = Passenger
JobPsychologist = Psychologist
-JobQuartermaster = Head of Logistics
+JobQuartermaster = Logistics Officer
JobReporter = Reporter
JobResearchAssistant = Research Assistant
JobResearchDirector = Mystagogue
diff --git a/Resources/Locale/en-US/job/job-supervisors.ftl b/Resources/Locale/en-US/job/job-supervisors.ftl
index d98fd82c4b5..25a49f643e6 100644
--- a/Resources/Locale/en-US/job/job-supervisors.ftl
+++ b/Resources/Locale/en-US/job/job-supervisors.ftl
@@ -5,7 +5,7 @@ job-supervisors-hos = the head of security
job-supervisors-ce = the chief engineer
job-supervisors-cmo = the chief medical officer
job-supervisors-rd = the mystagogue
-job-supervisors-qm = the head of logistics
+job-supervisors-qm = the logistics officer
job-supervisors-service = chefs, botanists, the bartender, and the head of personnel
job-supervisors-engineering = station engineers, atmospheric technicians, and the chief engineer
job-supervisors-medicine = medical doctors, chemists, and the chief medical officer
diff --git a/Resources/Locale/en-US/nyanotrasen/kitchen/deep-fryer-component.ftl b/Resources/Locale/en-US/nyanotrasen/kitchen/deep-fryer-component.ftl
new file mode 100644
index 00000000000..4d080b0d87e
--- /dev/null
+++ b/Resources/Locale/en-US/nyanotrasen/kitchen/deep-fryer-component.ftl
@@ -0,0 +1,47 @@
+## DeepFryer Entity
+
+deep-fryer-blacklist-item-failed = {CAPITALIZE(THE($item))} fails to be covered in oil.
+deep-fryer-oil-purity-low = {CAPITALIZE(THE($deepFryer))} sputters to no effect.
+deep-fryer-oil-volume-low = {CAPITALIZE(THE($deepFryer))} burns and spews smoke!
+deep-fryer-oil-no-slag = There's no slag to drain.
+
+deep-fryer-storage-full = All of the baskets are full.
+deep-fryer-storage-no-fit = {CAPITALIZE(THE($item))} won't fit inside one of the baskets.
+deep-fryer-interact-using-not-item = That doesn't seem to be an item.
+
+deep-fryer-need-liquid-container-in-hand = You need to first hold a liquid container like a beaker or bowl in your active hand.
+
+deep-fryer-thrown-missed = Missed!
+deep-fryer-thrown-hit-oil = Plop!
+deep-fryer-thrown-hit-oil-low = Plonk!
+
+deep-fryer-entity-escape = {CAPITALIZE(THE($victim))} leaps out of {THE($deepFryer)}!
+
+## DeepFryer UI
+
+deep-fryer-window-title = Deep Fryer
+deep-fryer-label-baskets = Baskets
+deep-fryer-label-oil-level = Oil Level
+deep-fryer-label-oil-purity = Oil Purity
+deep-fryer-button-insert-item = Insert Item
+deep-fryer-button-insert-item-tooltip = Place your held item into one of the deep fryer baskets.
+deep-fryer-button-scoop-vat = Scoop Vat
+deep-fryer-button-scoop-vat-tooltip = Scoop out some liquid from the oil vat. You need to hold a liquid container for this.
+deep-fryer-button-clear-slag = Clear Slag
+deep-fryer-button-clear-slag-tooltip = Clear out some waste from the oil vat. You need to hold a liquid container for this.
+deep-fryer-button-remove-all-items = Remove All Items
+deep-fryer-button-remove-all-items-tooltip = Remove all of the items from the deep fryer baskets at once.
+
+## DeepFriedComponent
+
+deep-fried-crispy-item = crispy {$entity}
+deep-fried-crispy-item-examine = It's covered in a crispy, oily texture.
+
+deep-fried-fried-item = deep-fried {$entity}
+deep-fried-fried-item-examine = It's covered in a thick, crispy layer.
+
+deep-fried-burned-item = burned {$entity}
+deep-fried-burned-item-examine = It's blackened with char.
+
+reagent-name-oil-ghee = ghee
+reagent-desc-oil-ghee = Thick and translucent.
\ No newline at end of file
diff --git a/Resources/Locale/en-US/paper/stamp-component.ftl b/Resources/Locale/en-US/paper/stamp-component.ftl
index e4f7027b5a8..121fa6f5ee3 100644
--- a/Resources/Locale/en-US/paper/stamp-component.ftl
+++ b/Resources/Locale/en-US/paper/stamp-component.ftl
@@ -9,7 +9,7 @@ stamp-component-stamped-name-denied = DENIED
stamp-component-stamped-name-approved = APPROVED
stamp-component-stamped-name-hop = Head of Personnel
stamp-component-stamped-name-hos = Head of Security
-stamp-component-stamped-name-qm = Head of Logistics
+stamp-component-stamped-name-qm = Logistics Officer
stamp-component-stamped-name-rd = Mystagogue
stamp-component-stamped-name-warden = Warden
stamp-component-stamped-name-trader = Trader
diff --git a/Resources/Locale/en-US/players/play-time/whitelist.ftl b/Resources/Locale/en-US/players/play-time/whitelist.ftl
new file mode 100644
index 00000000000..c6a5a9e07a8
--- /dev/null
+++ b/Resources/Locale/en-US/players/play-time/whitelist.ftl
@@ -0,0 +1 @@
+playtime-deny-reason-not-whitelisted = You need to be whitelisted.
diff --git a/Resources/Locale/en-US/prototypes/access/accesses.ftl b/Resources/Locale/en-US/prototypes/access/accesses.ftl
index 1735afeea9b..17f7a7fb053 100644
--- a/Resources/Locale/en-US/prototypes/access/accesses.ftl
+++ b/Resources/Locale/en-US/prototypes/access/accesses.ftl
@@ -20,7 +20,7 @@ id-card-access-level-medical = Medical
id-card-access-level-chemistry = Chemistry
id-card-access-level-paramedic = Paramedic
-id-card-access-level-quartermaster = Head of Logistics
+id-card-access-level-quartermaster = Logistics Officer
id-card-access-level-cargo = Logistics
id-card-access-level-salvage = Salvage
diff --git a/Resources/Locale/en-US/prototypes/catalog/fills/crates/cargo-crates.ftl b/Resources/Locale/en-US/prototypes/catalog/fills/crates/cargo-crates.ftl
index a33878362d2..eefeb9511e2 100644
--- a/Resources/Locale/en-US/prototypes/catalog/fills/crates/cargo-crates.ftl
+++ b/Resources/Locale/en-US/prototypes/catalog/fills/crates/cargo-crates.ftl
@@ -1,2 +1,2 @@
ent-CrateCargoLuxuryHardsuit = luxury mining hardsuit crate
- .desc = Finally, a hardsuit the Head of Logistics could call their own. Centcomm has heard you, now stop asking.
+ .desc = Finally, a hardsuit the Logistics Officer could call their own. Centcomm has heard you, now stop asking.
diff --git a/Resources/Maps/pebble.yml b/Resources/Maps/pebble.yml
index 82073af9140..60cc5b4b7c1 100644
--- a/Resources/Maps/pebble.yml
+++ b/Resources/Maps/pebble.yml
@@ -31813,7 +31813,7 @@ entities:
- pos: 16.5,-6.5
parent: 2
type: Transform
- - name: HoL
+ - name: LO
type: FaxMachine
- uid: 4953
components:
diff --git a/Resources/Prototypes/Catalog/Fills/Crates/food.yml b/Resources/Prototypes/Catalog/Fills/Crates/food.yml
index 215ce59856f..0043b829cac 100644
--- a/Resources/Prototypes/Catalog/Fills/Crates/food.yml
+++ b/Resources/Prototypes/Catalog/Fills/Crates/food.yml
@@ -38,6 +38,12 @@
components:
- type: StorageFill
contents:
+ - id: OilJarCorn #Nyano - Summary: Begin Nyano oils.
+ amount: 1
+ - id: OilJarGhee
+ amount: 1
+ - id: ReagentContainerOliveoil
+ amount: 1 #End Nyano code.
- id: ReagentContainerFlour
amount: 3
- id: ReagentContainerRice
diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml b/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml
index bf75a7e9f5b..ec1c4307c9d 100644
--- a/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml
+++ b/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml
@@ -21,7 +21,7 @@
- id: RubberStampQm
- id: ClothingHeadsetAltCargo
- id: BoxEncryptionKeyCargo
- - id: SpaceCashLuckyBill # DeltaV - HoL steal objective, see Resources/Prototypes/DeltaV/Entities/Objects/Misc/first_bill.yml
+ - id: SpaceCashLuckyBill # DeltaV - LO steal objective, see Resources/Prototypes/DeltaV/Entities/Objects/Misc/first_bill.yml
- id: BoxPDACargo # Delta-V
- type: entity
diff --git a/Resources/Prototypes/DeltaV/Entities/Mobs/Customization/Markings/harpy.yml b/Resources/Prototypes/DeltaV/Entities/Mobs/Customization/Markings/harpy.yml
index e0f37587754..354a969190d 100644
--- a/Resources/Prototypes/DeltaV/Entities/Mobs/Customization/Markings/harpy.yml
+++ b/Resources/Prototypes/DeltaV/Entities/Mobs/Customization/Markings/harpy.yml
@@ -7,18 +7,9 @@
markingCategory: Arms
speciesRestriction: [Harpy]
sprites:
- - sprite: DeltaV/Mobs/Customization/Harpy/harpy_wings_default.rsi
+ - sprite: DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi
state: harpy
-- type: marking
- id: HarpyTailSwallow
- bodyPart: Tail
- markingCategory: Tail
- speciesRestriction: [Harpy]
- sprites:
- - sprite: DeltaV/Mobs/Customization/Harpy/harpy_tails.rsi
- state: harpy_tail_swallow
-
- type: marking
id: HarpyEarsDefault
bodyPart: Head
@@ -45,3 +36,60 @@
sprites:
- sprite: DeltaV/Mobs/Customization/Harpy/harpy_tails.rsi
state: rooster_tail
+
+- type: marking
+ id: HarpyWing2Tone
+ bodyPart: RArm
+ markingCategory: Arms
+ speciesRestriction: [Harpy]
+ sprites:
+ - sprite: DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi
+ state: harpy2tone1
+ - sprite: DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi
+ state: harpy2tone2
+
+- type: marking
+ id: HarpyWing3Tone
+ bodyPart: RArm
+ markingCategory: Arms
+ speciesRestriction: [Harpy]
+ sprites:
+ - sprite: DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi
+ state: harpy3tone1
+ - sprite: DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi
+ state: harpy3tone2
+ - sprite: DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi
+ state: harpy3tone3
+
+- type: marking
+ id: HarpyWingSpeckled
+ bodyPart: RArm
+ markingCategory: Arms
+ speciesRestriction: [Harpy]
+ sprites:
+ - sprite: DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi
+ state: harpyspeckled1
+ - sprite: DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi
+ state: harpyspeckled2
+
+- type: marking
+ id: HarpyWingUndertone
+ bodyPart: RArm
+ markingCategory: Arms
+ speciesRestriction: [Harpy]
+ sprites:
+ - sprite: DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi
+ state: harpyundertone1
+ - sprite: DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi
+ state: harpyundertone2
+
+- type: marking
+ id: HarpyWingTips
+ bodyPart: RArm
+ markingCategory: Arms
+ speciesRestriction: [Harpy]
+ sprites:
+ - sprite: DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi
+ state: harpywingtip1
+ - sprite: DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi
+ state: harpywingtip2
diff --git a/Resources/Prototypes/DeltaV/Entities/Mobs/Species/harpy.yml b/Resources/Prototypes/DeltaV/Entities/Mobs/Species/harpy.yml
index d9fdeca5afb..1a88f172059 100644
--- a/Resources/Prototypes/DeltaV/Entities/Mobs/Species/harpy.yml
+++ b/Resources/Prototypes/DeltaV/Entities/Mobs/Species/harpy.yml
@@ -9,6 +9,16 @@
- type: Instrument
allowPercussion: false
program: 52
+ - type: SwappableInstrument
+ instrumentList:
+ "Voice": {52: 0}
+ "Trumpet": {56: 0}
+ "Electric": {27: 0}
+ "Bass": {33: 0}
+ "Rock": {29: 0}
+ "Acoustic": {24: 0}
+ "Flute": {73: 0}
+ "Sax": {66: 0}
- type: UserInterface
interfaces:
- key: enum.InstrumentUiKey.Key
@@ -151,11 +161,11 @@
- type: entity
id: ActionHarpyPlayMidi
name: Play MIDI
- description: Sing your heart out!
+ description: Sing your heart out! Right click yourself to set an instrument.
noSpawn: true
components:
- type: InstantAction
- checkCanInteract: false
+ checkCanInteract: true
icon: DeltaV/Interface/Actions/harpy_sing.png
event: !type:OpenUiActionEvent
key: enum.InstrumentUiKey.Key
diff --git a/Resources/Prototypes/DeltaV/Entities/Mobs/Species/vulpkanin.yml b/Resources/Prototypes/DeltaV/Entities/Mobs/Species/vulpkanin.yml
index bb25a30471e..63a470e633c 100644
--- a/Resources/Prototypes/DeltaV/Entities/Mobs/Species/vulpkanin.yml
+++ b/Resources/Prototypes/DeltaV/Entities/Mobs/Species/vulpkanin.yml
@@ -90,9 +90,9 @@
coefficient: 0.1
- type: Vocal
sounds:
- Male: MaleVulpakin
- Female: FemaleVulpakin
- Unsexed: MaleVulpakin
+ Male: MaleVulpkanin
+ Female: FemaleVulpkanin
+ Unsexed: MaleVulpkanin
- type: entity
save: false
diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Consumable/Drinks/drinks.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Consumable/Drinks/drinks.yml
index 17385e571e3..05eccedabd8 100644
--- a/Resources/Prototypes/DeltaV/Entities/Objects/Consumable/Drinks/drinks.yml
+++ b/Resources/Prototypes/DeltaV/Entities/Objects/Consumable/Drinks/drinks.yml
@@ -1,7 +1,7 @@
- type: entity
parent: DrinkGlassBase
- id: DrinkDulleaveneGlass
- name: dulleavene glass
+ id: DrinkHealthViolationGlass
+ name: health violation
description: Allegedly it's a cocktail. The warning cone motif seems apt.
components:
- type: SolutionContainerManager
@@ -9,7 +9,7 @@
drink:
maxVol: 30
reagents:
- - ReagentId: Dulleavene
+ - ReagentId: HealthViolation
Quantity: 30
- type: Sprite
sprite: DeltaV/Objects/Consumable/Drinks/dulleavene.rsi
@@ -109,3 +109,19 @@
Quantity: 30
- type: Sprite
sprite: Objects/Consumable/Drinks/kvass.rsi
+
+- type: entity
+ parent: DrinkGlassBase
+ id: DrinkMothamphetamineGlass
+ name: mothamphetamine
+ description: A strangely... Fuzzy drink. It has a chaotic aura.
+ components:
+ - type: SolutionContainerManager
+ solutions:
+ drink:
+ maxVol: 30
+ reagents:
+ - ReagentId: Mothamphetamine
+ Quantity: 30
+ - type: Sprite
+ sprite: DeltaV/Objects/Consumable/Drinks/mothamphetamine.rsi
diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Consumable/Food/Baked/pie.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Consumable/Food/Baked/pie.yml
new file mode 100644
index 00000000000..d86b5142dbf
--- /dev/null
+++ b/Resources/Prototypes/DeltaV/Entities/Objects/Consumable/Food/Baked/pie.yml
@@ -0,0 +1,39 @@
+- type: entity
+ name: pumpkin pie
+ parent: FoodPieBase
+ id: FoodPiePumpkin
+ description: A seasonal favorite, consisting mostly of pumpkin and a handful of spooky spices.
+ components:
+ - type: FlavorProfile
+ flavors:
+ - sweet
+ - pumpkin
+ - type: Sprite
+ layers:
+ - state: tin
+ - sprite: DeltaV/Objects/Consumable/Food/Baked/pie.rsi
+ state: pumpkin
+ - type: SliceableFood
+ slice: FoodPiePumpkinSlice
+ - type: Tag
+ tags:
+ - Fruit
+ - Pie
+
+- type: entity
+ name: slice of pumpkin pie
+ parent: FoodPieSliceBase
+ id: FoodPiePumpkinSlice
+ components:
+ - type: FlavorProfile
+ flavors:
+ - sweet
+ - pumpkin
+ - type: Sprite
+ sprite: DeltaV/Objects/Consumable/Food/Baked/pie.rsi
+ state: pumpkin-slice
+ - type: Tag
+ tags:
+ - Fruit
+ - Pie
+# Tastes like pie, pumpkin.
diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Consumable/Food/soup.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Consumable/Food/soup.yml
new file mode 100644
index 00000000000..01b5be7af0c
--- /dev/null
+++ b/Resources/Prototypes/DeltaV/Entities/Objects/Consumable/Food/soup.yml
@@ -0,0 +1,25 @@
+- type: entity
+ name: scrambled eggs
+ parent: FoodBowlBase
+ id: FoodMealScrambledEggs
+ description: Some cooked eggs with salt. Yummy!
+ components:
+ - type: FlavorProfile
+ flavors:
+ - egg
+ - salty
+ - type: Sprite
+ sprite: DeltaV/Objects/Consumable/Food/scrambledeggs.rsi
+ layers:
+ - state: bowl
+ - state: scrambled-eggs
+ - type: SolutionContainerManager
+ solutions:
+ food:
+ maxVol: 10
+ reagents:
+ - ReagentId: Nutriment
+ Quantity: 5
+ - ReagentId: Protein
+ Quantity: 5
+# Tastes like eggs, butter and salt
diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Misc/first_bill.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Misc/first_bill.yml
index 429e64e40c5..1b89c20ee80 100644
--- a/Resources/Prototypes/DeltaV/Entities/Objects/Misc/first_bill.yml
+++ b/Resources/Prototypes/DeltaV/Entities/Objects/Misc/first_bill.yml
@@ -1,8 +1,8 @@
- type: entity
parent: BaseItem
id: SpaceCashLuckyBill
- name: head of logistics' lucky bill
- description: The first bill ever earned by the Head of Logistics from trading. A small chip is embedded in it.
+ name: logistics officer's lucky bill
+ description: The first bill ever earned by the Logistics Officer from trading. A small chip is embedded in it.
components:
- type: Sprite
sprite: DeltaV/Objects/Misc/first_bill.rsi
diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml
index 556707ed798..8f7e6ce6b2d 100644
--- a/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml
+++ b/Resources/Prototypes/DeltaV/Entities/Objects/Specific/Mail/mail.yml
@@ -165,3 +165,13 @@
- id: BookRandom # The "spawn nothing" in the 'orGroup'
prob: 0.7
orGroup: bookother
+
+- type: entity
+ noSpawn: true
+ parent: BaseMail
+ id: MailPumpkinPie
+ suffix: pumpkinpie
+ components:
+ - type: Mail
+ contents:
+ - id: FoodPiePumpkin
diff --git a/Resources/Prototypes/DeltaV/Flavors/flavors.yml b/Resources/Prototypes/DeltaV/Flavors/flavors.yml
index f3c7876a8af..048747bc5fb 100644
--- a/Resources/Prototypes/DeltaV/Flavors/flavors.yml
+++ b/Resources/Prototypes/DeltaV/Flavors/flavors.yml
@@ -115,3 +115,8 @@
id: arsonistsbrew
flavorType: Complex
description: flavor-complex-arsonistsbrew
+
+- type: flavor
+ id: pumpkin
+ flavorType: Complex
+ description: flavor-complex-pumpkin
diff --git a/Resources/Prototypes/DeltaV/Objectives/traitor.yml b/Resources/Prototypes/DeltaV/Objectives/traitor.yml
index d974564e3d0..a73f7896e2f 100644
--- a/Resources/Prototypes/DeltaV/Objectives/traitor.yml
+++ b/Resources/Prototypes/DeltaV/Objectives/traitor.yml
@@ -1,7 +1,7 @@
-- type: entity # Head of Logistics steal objective.
+- type: entity # Logistics Officer steal objective.
noSpawn: true
parent: BaseTraitorStealObjective
- id: HoLLuckyBillStealObjective
+ id: LOLuckyBillStealObjective
components:
- type: NotJobRequirement
job: Quartermaster
diff --git a/Resources/Prototypes/DeltaV/Reagents/Consumable/Drink/drinks.yml b/Resources/Prototypes/DeltaV/Reagents/Consumable/Drink/drinks.yml
index 1b7bdfaa87c..85a629f2173 100644
--- a/Resources/Prototypes/DeltaV/Reagents/Consumable/Drink/drinks.yml
+++ b/Resources/Prototypes/DeltaV/Reagents/Consumable/Drink/drinks.yml
@@ -1,8 +1,8 @@
- type: reagent
- id: Dulleavene
- name: reagent-name-dulleavene
+ id: HealthViolation
+ name: reagent-name-healthviolation
parent: BaseDrink
- desc: reagent-desc-dulleavene
+ desc: reagent-desc-healthviolation
physicalDesc: reagent-physical-desc-strong-smelling
flavor: dulleavene
color: "#ff7f00"
@@ -147,3 +147,26 @@
metamorphicSprite:
sprite: Objects/Consumable/Drinks/kvass.rsi
state: icon
+
+- type: reagent
+ id: Mothamphetamine
+ name: reagent-name-mothamphetamine
+ parent: BaseDrink
+ desc: reagent-desc-mothamphetamine
+ physicalDesc: reagent-physical-desc-fuzzy
+ flavor: cotton
+ color: "#2fa1ef"
+ metamorphicSprite:
+ sprite: DeltaV/Objects/Consumable/Drinks/mothamphetamine.rsi
+ state: icon
+ metabolisms:
+ Drink:
+ effects:
+ - !type:SatiateThirst
+ factor: 2
+ - !type:AdjustReagent
+ reagent: Ethanol
+ amount: 0.25
+ Poison:
+ effects:
+ - !type:Jitter
diff --git a/Resources/Prototypes/DeltaV/Recipes/Cooking/meal_recipes.yml b/Resources/Prototypes/DeltaV/Recipes/Cooking/meal_recipes.yml
index a64617c0478..95f1fcb538e 100644
--- a/Resources/Prototypes/DeltaV/Recipes/Cooking/meal_recipes.yml
+++ b/Resources/Prototypes/DeltaV/Recipes/Cooking/meal_recipes.yml
@@ -7,3 +7,28 @@
FoodBreadPlainSlice: 2
FoodCheeseSlice: 1
FoodButter: 1
+
+- type: microwaveMealRecipe
+ id: RecipeScrambledEggs
+ name: scrambled eggs recipe
+ result: FoodMealScrambledEggs
+ time: 5
+ reagents:
+ TableSalt: 5
+ solids:
+ FoodBowlBig: 1
+ FoodEgg: 3
+ FoodButter: 1
+
+# - type: microwaveMealRecipe # Add when we have actual pumpkins
+# id: RecipePumpkinPie
+# name: pumpkin pie
+# result: FoodPiePumpkin
+# time: 15
+# reagents:
+# Sugar: 5
+# Milk: 5
+# Egg: 12
+# solids:
+# FoodPumpkin: 1
+# FoodPlateTin: 1
diff --git a/Resources/Prototypes/DeltaV/Recipes/Reactions/drinks.yml b/Resources/Prototypes/DeltaV/Recipes/Reactions/drinks.yml
index 00f8297016f..c33f19be7ce 100644
--- a/Resources/Prototypes/DeltaV/Recipes/Reactions/drinks.yml
+++ b/Resources/Prototypes/DeltaV/Recipes/Reactions/drinks.yml
@@ -1,5 +1,5 @@
- type: reaction
- id: Dulleavene
+ id: HealthViolation
reactants:
GargleBlaster:
amount: 10
@@ -10,7 +10,7 @@
Vermouth:
amount: 1
products:
- Dulleavene: 20
+ HealthViolation: 20
- type: reaction
id: Gunmetal
@@ -76,3 +76,15 @@
amount: 1
products:
ArsonistsBrew: 5
+
+- type: reaction
+ id: Mothamphetamine
+ reactants:
+ FourteenLoko:
+ amount: 1
+ EnergyDrink:
+ amount: 1
+ BlueCuracao:
+ amount: 1
+ products:
+ Mothamphetamine: 3
diff --git a/Resources/Prototypes/DeltaV/SoundCollections/vulpakin.yml b/Resources/Prototypes/DeltaV/SoundCollections/vulpakin.yml
deleted file mode 100644
index df380d2aead..00000000000
--- a/Resources/Prototypes/DeltaV/SoundCollections/vulpakin.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-- type: soundCollection
- id: VulpakinBarks
- files:
- - /Audio/DeltaV/Voice/Vulpakin/dog_bark1.ogg
- - /Audio/DeltaV/Voice/Vulpakin/dog_bark2.ogg
- - /Audio/DeltaV/Voice/Vulpakin/dog_bark3.ogg
-
-- type: soundCollection
- id: VulpakinGrowls
- files:
- - /Audio/DeltaV/Voice/Vulpakin/dog_growl1.ogg
- - /Audio/DeltaV/Voice/Vulpakin/dog_growl2.ogg
- - /Audio/DeltaV/Voice/Vulpakin/dog_growl3.ogg
-
-- type: soundCollection
- id: VulpakinSnarls
- files:
- - /Audio/DeltaV/Voice/Vulpakin/dog_snarl1.ogg
- - /Audio/DeltaV/Voice/Vulpakin/dog_snarl2.ogg
- - /Audio/DeltaV/Voice/Vulpakin/dog_snarl3.ogg
-
-- type: soundCollection
- id: VulpakinWhines
- files:
- - /Audio/DeltaV/Voice/Vulpakin/dog_whine.ogg
-
diff --git a/Resources/Prototypes/DeltaV/SoundCollections/vulpkanin.yml b/Resources/Prototypes/DeltaV/SoundCollections/vulpkanin.yml
new file mode 100644
index 00000000000..6d337e5ffa2
--- /dev/null
+++ b/Resources/Prototypes/DeltaV/SoundCollections/vulpkanin.yml
@@ -0,0 +1,26 @@
+- type: soundCollection
+ id: VulpkaninBarks
+ files:
+ - /Audio/DeltaV/Voice/Vulpkanin/dog_bark1.ogg
+ - /Audio/DeltaV/Voice/Vulpkanin/dog_bark2.ogg
+ - /Audio/DeltaV/Voice/Vulpkanin/dog_bark3.ogg
+
+- type: soundCollection
+ id: VulpkaninGrowls
+ files:
+ - /Audio/DeltaV/Voice/Vulpkanin/dog_growl1.ogg
+ - /Audio/DeltaV/Voice/Vulpkanin/dog_growl2.ogg
+ - /Audio/DeltaV/Voice/Vulpkanin/dog_growl3.ogg
+
+- type: soundCollection
+ id: VulpkaninSnarls
+ files:
+ - /Audio/DeltaV/Voice/Vulpkanin/dog_snarl1.ogg
+ - /Audio/DeltaV/Voice/Vulpkanin/dog_snarl2.ogg
+ - /Audio/DeltaV/Voice/Vulpkanin/dog_snarl3.ogg
+
+- type: soundCollection
+ id: VulpkaninWhines
+ files:
+ - /Audio/DeltaV/Voice/Vulpkanin/dog_whine.ogg
+
diff --git a/Resources/Prototypes/DeltaV/Voice/speech_emote_sounds.yml b/Resources/Prototypes/DeltaV/Voice/speech_emote_sounds.yml
index d1b5d824a75..982a9951c42 100644
--- a/Resources/Prototypes/DeltaV/Voice/speech_emote_sounds.yml
+++ b/Resources/Prototypes/DeltaV/Voice/speech_emote_sounds.yml
@@ -52,9 +52,15 @@
collection: HarpyCaws
Chirp:
collection: HarpyChirps
+ Snarl:
+ collection: VulpkaninSnarls
+ Bark:
+ collection: VulpkaninBarks
+ Whine:
+ collection: VulpkaninWhines
- type: emoteSounds
- id: MaleVulpakin
+ id: MaleVulpkanin
params:
variation: 0.125
sounds:
@@ -71,16 +77,16 @@
Whistle:
collection: Whistles
Growl:
- collection: VulpakinGrowls
+ collection: VulpkaninGrowls
Snarl:
- collection: VulpakinSnarls
+ collection: VulpkaninSnarls
Bark:
- collection: VulpakinBarks
+ collection: VulpkaninBarks
Whine:
- collection: VulpakinWhines
+ collection: VulpkaninWhines
- type: emoteSounds
- id: FemaleVulpakin
+ id: FemaleVulpkanin
params:
variation: 0.125
sounds:
@@ -97,10 +103,10 @@
Whistle:
collection: Whistles
Growl:
- collection: VulpakinGrowls
+ collection: VulpkaninGrowls
Snarl:
- collection: VulpakinSnarls
+ collection: VulpkaninSnarls
Bark:
- collection: VulpakinBarks
+ collection: VulpkaninBarks
Whine:
- collection: VulpakinWhines
+ collection: VulpkaninWhines
diff --git a/Resources/Prototypes/DeltaV/Voice/speech_emotes.yml b/Resources/Prototypes/DeltaV/Voice/speech_emotes.yml
index 7b7b580086c..fd995f49730 100644
--- a/Resources/Prototypes/DeltaV/Voice/speech_emotes.yml
+++ b/Resources/Prototypes/DeltaV/Voice/speech_emotes.yml
@@ -4,45 +4,41 @@
category: Vocal
chatMessages: [booms.]
chatTriggers:
- - boom
- - booms
+ - boom.
- booms.
- booms!
- - booming
- - boomed
+ - booming.
+ - boomed.
- type: emote
id: HonkHarpy
category: Vocal
chatMessages: [honks.]
chatTriggers:
- - honk
- - honks
+ - honk.
- honks.
- honks!
- - honking
- - honked
+ - honking.
+ - honked.
- type: emote
id: Ring
category: Vocal
chatMessages: [rings.]
chatTriggers:
- - ring
- - rings
+ - ring.
- rings.
- rings!
- - ringing
- - ringed
+ - ringing.
+ - ringed.
- type: emote
id: Pew
category: Vocal
chatMessages: [pews.]
chatTriggers:
- - pew
- - pews
- pew.
+ - pews.
- pew!
- type: emote
@@ -50,32 +46,29 @@
category: Vocal
chatMessages: [bangs.]
chatTriggers:
- - bang
- - bangs
+ - bangs.
- bang.
- bang!
- - banging
- - banged
+ - banging.
+ - banged.
- type: emote
id: Beep
category: Vocal
chatMessages: [beeps.]
chatTriggers:
- - beep
- - beeps
+ - beeps.
- beep.
- beep!
- - beeping
- - beeped
+ - beeping.
+ - beeped.
- type: emote
id: Rev
category: Vocal
chatMessages: [revs.]
chatTriggers:
- - rev
- - revs
+ - revs.
- rev.
- rev!
- revving
@@ -86,20 +79,18 @@
category: Vocal
chatMessages: [clicks.]
chatTriggers:
- - click
- - clicks
+ - clicks.
- click.
- click!
- - clicking
- - clicked
+ - clicking.
+ - clicked.
- type: emote
id: Caw
category: Vocal
chatMessages: [caws.]
chatTriggers:
- - caw
- - caws
+ - caws.
- caw.
- caw!
- cawing
@@ -110,44 +101,48 @@
category: Vocal
chatMessages: [chirps.]
chatTriggers:
- - chirp
- - chirps
+ - chirps.
- chirp.
- chirp!
- - chirping
- - chirped
-
-#Vulpakin
+ - chirping.
+ - chirped.
+
+#Vulpkanin
- type: emote
id: Bark
category: Vocal
chatMessages: [barks.]
chatTriggers:
- - bark
- - barks
+ - bark.
+ - bark!
- barks.
- barks!
- - barking
- - barked
+ - barked.
+ - barked!
+ - barking.
+
- type: emote
id: Snarl
category: Vocal
chatMessages: [snarls.]
chatTriggers:
- - snarl
- - snarls
+ - snarl.
+ - snarl!
- snarls.
- snarls!
- - snarling
- - snarled
+ - snarled.
+ - snarled!
+ - snarling.
+
- type: emote
id: Whine
category: Vocal
chatMessages: [whines.]
chatTriggers:
- - whine
- - whines
+ - whine.
+ - whine!
- whines.
- whines!
- - whining
- - whined
+ - whined.
+ - whined!
+ - whining.
diff --git a/Resources/Prototypes/Entities/Clothing/Ears/headsets.yml b/Resources/Prototypes/Entities/Clothing/Ears/headsets.yml
index e4b9ff878a2..82648b0e586 100644
--- a/Resources/Prototypes/Entities/Clothing/Ears/headsets.yml
+++ b/Resources/Prototypes/Entities/Clothing/Ears/headsets.yml
@@ -63,8 +63,8 @@
- type: entity
parent: ClothingHeadsetCargo
id: ClothingHeadsetQM
- name: hol headset # DeltaV - Logistics Department replacing Cargo
- description: A headset used by the head of logistics. # DeltaV - Logistics Department replacing Cargo
+ name: logistics officer's headset # DeltaV - Logistics Department replacing Cargo
+ description: A headset used by the logistics officer. # DeltaV - Logistics Department replacing Cargo
components:
- type: ContainerFill
containers:
diff --git a/Resources/Prototypes/Entities/Clothing/Ears/headsets_alt.yml b/Resources/Prototypes/Entities/Clothing/Ears/headsets_alt.yml
index 4949199bc18..034653089c3 100644
--- a/Resources/Prototypes/Entities/Clothing/Ears/headsets_alt.yml
+++ b/Resources/Prototypes/Entities/Clothing/Ears/headsets_alt.yml
@@ -13,7 +13,7 @@
- type: entity
parent: ClothingHeadsetAlt
id: ClothingHeadsetAltCargo
- name: head of logistics' over-ear headset # DeltaV - Logistics Department replacing Cargo
+ name: logistics officer's over-ear headset # DeltaV - Logistics Department replacing Cargo
components:
- type: ContainerFill
containers:
diff --git a/Resources/Prototypes/Entities/Clothing/Head/hoods.yml b/Resources/Prototypes/Entities/Clothing/Head/hoods.yml
index 54e1b47d7b5..9f63d9e4cad 100644
--- a/Resources/Prototypes/Entities/Clothing/Head/hoods.yml
+++ b/Resources/Prototypes/Entities/Clothing/Head/hoods.yml
@@ -383,7 +383,7 @@
parent: ClothingHeadHatHoodWinterBase
id: ClothingHeadHatHoodWinterQM
noSpawn: true
- name: head of logistics' coat hood # DeltaV - Logistics Department replacing Cargo
+ name: logistics officer's coat hood # DeltaV - Logistics Department replacing Cargo
components:
- type: Sprite
sprite: Clothing/Head/Hoods/Coat/hoodqm.rsi
diff --git a/Resources/Prototypes/Entities/Clothing/Head/soft.yml b/Resources/Prototypes/Entities/Clothing/Head/soft.yml
index 49a6825efe9..c710d46f8eb 100644
--- a/Resources/Prototypes/Entities/Clothing/Head/soft.yml
+++ b/Resources/Prototypes/Entities/Clothing/Head/soft.yml
@@ -50,8 +50,8 @@
- type: entity
parent: ClothingHeadBaseButcherable
id: ClothingHeadHatQMsoft
- name: head of logistics' cap # DeltaV - Logistics Department replacing Cargo
- description: "It's a baseball hat painted in the Head of Logistics' colors."
+ name: logistics officer's cap # DeltaV - Logistics Department replacing Cargo
+ description: "It's a baseball hat painted in the Logistics Officer's colors."
components:
- type: Sprite
sprite: Clothing/Head/Soft/qmsoft.rsi
@@ -61,8 +61,8 @@
- type: entity
parent: ClothingHeadBaseButcherable
id: ClothingHeadHatQMsoftFlipped
- name: head of logistics' cap flipped # DeltaV - Logistics Department replacing Cargo
- description: "It's a baseball hat painted in the Head of Logistics' colors. Flipped."
+ name: logistics officer's cap flipped # DeltaV - Logistics Department replacing Cargo
+ description: "It's a baseball hat painted in the Logistics Officer's colors. Flipped."
components:
- type: Sprite
sprite: Clothing/Head/Soft/qmsoft_flipped.rsi
diff --git a/Resources/Prototypes/Entities/Clothing/Neck/cloaks.yml b/Resources/Prototypes/Entities/Clothing/Neck/cloaks.yml
index 58a94642a74..2111ac63022 100644
--- a/Resources/Prototypes/Entities/Clothing/Neck/cloaks.yml
+++ b/Resources/Prototypes/Entities/Clothing/Neck/cloaks.yml
@@ -46,7 +46,7 @@
- type: entity
parent: ClothingNeckBase
id: ClothingNeckCloakQm
- name: head of logistics' cloak # DeltaV - Logistics Department replacing Cargo
+ name: logistics officer's cloak # DeltaV - Logistics Department replacing Cargo
description: A strong brown cloak with a reflective stripe, while not as fancy as others, it does show your managing skills.
components:
- type: Sprite
diff --git a/Resources/Prototypes/Entities/Clothing/Neck/mantles.yml b/Resources/Prototypes/Entities/Clothing/Neck/mantles.yml
index 97fa8f59447..7b4ab078911 100644
--- a/Resources/Prototypes/Entities/Clothing/Neck/mantles.yml
+++ b/Resources/Prototypes/Entities/Clothing/Neck/mantles.yml
@@ -67,7 +67,7 @@
- type: entity
parent: ClothingNeckBase
id: ClothingNeckMantleQM
- name: head of logistics' mantle # DeltaV - Logistics Department replacing Cargo
+ name: logistics officer's mantle # DeltaV - Logistics Department replacing Cargo
description: For the master of goods and materials to rule over the department, a befitting mantle to show off superiority!
components:
- type: Sprite
diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml
index 7ac6d0ba808..d53fe98a8c1 100644
--- a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml
+++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml
@@ -400,7 +400,7 @@
parent: ClothingOuterHardsuitBase
id: ClothingOuterHardsuitLuxury #DO NOT MAP - https://github.com/space-wizards/space-station-14/pull/19738#issuecomment-1703486738
name: luxury mining hardsuit
- description: A refurbished mining hardsuit, fashioned after the Head of Logistics' colors. Graphene lining provides less protection, but is much easier to move. # DeltaV - Logistics Department replacing Cargo
+ description: A refurbished mining hardsuit, fashioned after the Logistics Officer's colors. Graphene lining provides less protection, but is much easier to move. # DeltaV - Logistics Department replacing Cargo
components:
- type: Sprite
sprite: Clothing/OuterClothing/Hardsuits/luxury.rsi
diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml
index abe474ff922..d897553d44b 100644
--- a/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml
+++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml
@@ -336,7 +336,7 @@
- type: entity
parent: ClothingOuterWinterCoatToggleable
id: ClothingOuterWinterQM
- name: head of logistics' winter coat # DeltaV - Logistics Department replacing Cargo
+ name: logistics officer's winter coat # DeltaV - Logistics Department replacing Cargo
components:
- type: Sprite
sprite: Clothing/OuterClothing/WinterCoats/coatqm.rsi
diff --git a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpskirts.yml b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpskirts.yml
index d8312861bdc..50741519053 100644
--- a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpskirts.yml
+++ b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpskirts.yml
@@ -285,7 +285,7 @@
- type: entity
parent: ClothingUniformSkirtBase
id: ClothingUniformJumpskirtQM
- name: head of logistics' jumpskirt # DeltaV - Logistics Department replacing Cargo
+ name: logistics officer's jumpskirt # DeltaV - Logistics Department replacing Cargo
description: 'What can brown do for you?'
components:
- type: Sprite
@@ -296,7 +296,7 @@
- type: entity
parent: ClothingUniformSkirtBase
id: ClothingUniformJumpskirtQMTurtleneck
- name: head of logistics' turtleneck # DeltaV - Logistics Department replacing Cargo
+ name: logistics officer's turtleneck # DeltaV - Logistics Department replacing Cargo
description: A sharp turtleneck made for the hardy work environment of supply.
components:
- type: Sprite
diff --git a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml
index bd08c07330a..016925ae13e 100644
--- a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml
+++ b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml
@@ -449,7 +449,7 @@
- type: entity
parent: ClothingUniformBase
id: ClothingUniformJumpsuitQM
- name: head of logistics' jumpsuit # DeltaV - Logistics Department replacing Cargo
+ name: logistics officer's jumpsuit # DeltaV - Logistics Department replacing Cargo
description: 'What can brown do for you?'
components:
- type: Sprite
@@ -460,7 +460,7 @@
- type: entity
parent: ClothingUniformBase
id: ClothingUniformJumpsuitQMTurtleneck
- name: head of logistics' turtleneck # DeltaV - Logistics Department replacing Cargo
+ name: logistics officer's turtleneck # DeltaV - Logistics Department replacing Cargo
description: A sharp turtleneck made for the hardy work environment of supply.
components:
- type: Sprite
diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/food_baked_single.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/food_baked_single.yml
index 995048c2dd1..24a2cef61fb 100644
--- a/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/food_baked_single.yml
+++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/food_baked_single.yml
@@ -66,6 +66,7 @@
- FoodPieMeatSlice
- FoodPieCherrySlice
- FoodPieFrostySlice
+ - FoodPiePumpkinSlice # DeltaV - Pumpkin Pie
- FoodTartGrape
- FoodTartCoco
- FoodBakedBrownie
@@ -81,5 +82,7 @@
- FoodTartGapple
- FoodBreadMeatXenoSlice
- FoodPieXenoSlice
- - FoodBakedCannabisBrownie
+ - FoodMothMothmallowSlice # Nyanotrasen - Moth Recipes
+ - FoodMothMoffin # Nyanotrasen - Moth Recipes
+ - FoodBakedCannabisBrownie # Nyanotrasen - Canabis Brownie
rareChance: 0.05
diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/food_baked_whole.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/food_baked_whole.yml
index 7e580db9805..9e4fe495bf0 100644
--- a/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/food_baked_whole.yml
+++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/food_baked_whole.yml
@@ -44,6 +44,8 @@
- FoodPieCherry
- FoodPieMeat
- FoodPieFrosty
+ - FoodPiePumpkin # DeltaV - Pumpkin Pie
+ - FoodMothCheesecakeBalls # Nyanotrasen - Moth Recipes
- FoodBakedBrownieBatch
chance: 0.8
offset: 0.0
@@ -59,5 +61,6 @@
- FoodPiePlump
- FoodBreadMeatXeno
- FoodPieXeno
- - FoodBakedCannabisBrownieBatch
+ - FoodMothMothmallow # Nyanotrasen - Moth Recipes
+ - FoodBakedCannabisBrownieBatch # Nyanotrasen - Canabis Brownie
rareChance: 0.05
diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/food_meal.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/food_meal.yml
index e95fca1d875..53b7cadadfb 100644
--- a/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/food_meal.yml
+++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/food_meal.yml
@@ -28,6 +28,7 @@
- FoodMealRibs
- FoodMealEggsbenedict
- FoodMealOmelette
+ - FoodMealScrambledEggs #DeltaV
- FoodMealFriedegg
- FoodMealQueso
- FoodMealSashimi
@@ -64,6 +65,30 @@
- FoodSoupOnion
- FoodSoupBisque
- FoodSoupBungo
+ - FoodMothHerbyCheese # Nyanotrasen - Moth Recipes
+ - FoodMothSqueakingFry # Nyanotrasen - Moth Recipes
+ - FoodMothChiliCabbageWrap # Nyanotrasen - Moth Recipes
+ - FoodMothBakedCheese # Nyanotrasen - Moth Recipes
+ - FoodMothBakedRice # Nyanotrasen - Moth Recipes
+ - FoodMothGreenLasagne # Nyanotrasen - Moth Recipes
+ - FoodMothBakedCorn # Nyanotrasen - Moth Recipes
+ - FoodMothButteredBakedCorn # Nyanotrasen - Moth Recipes
+ - FoodMothMozzarellaSticks # Nyanotrasen - Moth Recipes
+ - FoodMothMacBalls # Nyanotrasen - Moth Recipes
+ - FoodMothCottonSoup # Nyanotrasen - Moth Recipes
+ - FoodMothCheeseSoup # Nyanotrasen - Moth Recipes
+ - FoodMothSeedSoup # Nyanotrasen - Moth Recipes
+ - FoodMothBeanStew # Nyanotrasen - Moth Recipes
+ - FoodMothOatStew # Nyanotrasen - Moth Recipes
+ - FoodMothHeartburnSoup # Nyanotrasen - Moth Recipes
+ - FoodMothHuaMulanCongee # Nyanotrasen - Moth Recipes
+ - FoodMothCornmealPorridge # Nyanotrasen - Moth Recipes
+ - FoodMothCheesyPorridge # Nyanotrasen - Moth Recipes
+ - FoodMothEggplantPolenta # Nyanotrasen - Moth Recipes
+ - FoodMothCapreseSalad # Nyanotrasen - Moth Recipes
+ - FoodMothFleetSalad # Nyanotrasen - Moth Recipes
+ - FoodMothCottonSalad # Nyanotrasen - Moth Recipes
+ - FoodMothKachumbariSalad # Nyanotrasen - Moth Recipes
chance: 0.8
offset: 0.0
#rare
@@ -86,4 +111,5 @@
- FoodSoupMonkey
- FoodSoupEyeball
- FoodSoupElectron
+ - FoodMothBakedCheesePlatter # Nyanotrasen - Moth Recipes
rareChance: 0.05
diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/food_single.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/food_single.yml
index 5cbc17665cd..026f0a3e125 100644
--- a/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/food_single.yml
+++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/food_single.yml
@@ -46,6 +46,12 @@
- FoodPizzaSassysageSlice
- FoodPizzaPineappleSlice
- FoodPizzaMoldySlice
+ - FoodMothGreenLasagneSlice # Nyanotrasen - Moth Recipes
+ - FoodMothBakedRicePortion # Nyanotrasen - Moth Recipes
+ - FoodMothPizzaFirecrackerSlice # Nyanotrasen - Moth Recipes
+ - FoodMothPizzaFiveCheeseSlice # Nyanotrasen - Moth Recipes
+ - FoodMothPizzaPestoSlice # Nyanotrasen - Moth Recipes
+ - FoodMothPizzaCottonSlice # Nyanotrasen - Moth Recipes
chance: 0.8
offset: 0.0
#rare
@@ -67,4 +73,5 @@
- FoodMeatRatKebab
- FoodMeatRatdoubleKebab
- FoodPizzaArnoldSlice
+ - FoodPizzaCorncobSlice # Nyanotrasen - Corncob Pizza
rareChance: 0.05
diff --git a/Resources/Prototypes/Entities/Markers/Spawners/jobs.yml b/Resources/Prototypes/Entities/Markers/Spawners/jobs.yml
index b1e094c1693..6a581675519 100644
--- a/Resources/Prototypes/Entities/Markers/Spawners/jobs.yml
+++ b/Resources/Prototypes/Entities/Markers/Spawners/jobs.yml
@@ -41,7 +41,7 @@
- type: entity
id: SpawnPointQuartermaster
parent: SpawnPointJobBase
- name: head of logistics # DeltaV - Logistics Department replacing Cargo
+ name: logistics officer # DeltaV - Logistics Department replacing Cargo
components:
- type: SpawnPoint
job_id: Quartermaster
diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/box.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/box.yml
index 990a6815616..0863cf0deda 100644
--- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/box.yml
+++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/box.yml
@@ -260,6 +260,18 @@
- id: FoodPizzaDonkpocket
prob: 0.10
orGroup: Pizza
+ - id: FoodMothPizzaFirecracker # Nyanotrasen - Moth Recipes
+ prob: 0.05
+ orGroup: Pizza
+ - id: FoodMothPizzaFiveCheese # Nyanotrasen - Moth Recipes
+ prob: 0.05
+ orGroup: Pizza
+ - id: FoodMothPizzaPesto # Nyanotrasen - Moth Recipes
+ prob: 0.05
+ orGroup: Pizza
+ - id: FoodPizzaCorncob # Nyanotrasen - Corncob Pizza
+ prob: 0.01
+ orGroup: Pizza
# Nugget
diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml
index 78c91901b26..e11254d768c 100644
--- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml
+++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml
@@ -319,7 +319,7 @@
state: pda-chaplain
- type: entity
- name: head of logistics PDA # DeltaV - Logistics Department replacing Cargo
+ name: logistics officer PDA # DeltaV - Logistics Department replacing Cargo
parent: BasePDA
id: QuartermasterPDA
description: PDA for the guy that directs logistics. # DeltaV - Logistics Department replacing Cargo
diff --git a/Resources/Prototypes/Entities/Objects/Fun/figurines.yml b/Resources/Prototypes/Entities/Objects/Fun/figurines.yml
index d3e89325162..c491ef264b5 100644
--- a/Resources/Prototypes/Entities/Objects/Fun/figurines.yml
+++ b/Resources/Prototypes/Entities/Objects/Fun/figurines.yml
@@ -166,7 +166,7 @@
- type: entity
parent: BaseFigurine
id: ToyFigurineQuartermaster
- name: head of logistics figure # DeltaV - Logistics Department replacing Cargo
+ name: logistics officer figure # DeltaV - Logistics Department replacing Cargo
description: A figurine depicting the glorious head of the Logistics department. # DeltaV - Logistics Department replacing Cargo
components:
- type: Sprite
diff --git a/Resources/Prototypes/Entities/Objects/Misc/bedsheets.yml b/Resources/Prototypes/Entities/Objects/Misc/bedsheets.yml
index 1d259827655..036cacad37f 100644
--- a/Resources/Prototypes/Entities/Objects/Misc/bedsheets.yml
+++ b/Resources/Prototypes/Entities/Objects/Misc/bedsheets.yml
@@ -236,7 +236,7 @@
- type: entity
id: BedsheetQM
parent: BedsheetBase
- name: HoL's bedsheet # DeltaV - Logistics Department replacing Cargo
+ name: LO's bedsheet # DeltaV - Logistics Department replacing Cargo
components:
- type: Sprite
state: sheetqm
diff --git a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml
index ee34ce87163..2520e7e456f 100644
--- a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml
+++ b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml
@@ -212,7 +212,7 @@
- type: entity
parent: IDCardStandard
id: QuartermasterIDCard
- name: head of logistics ID card # DeltaV - Logistics Department replacing Cargo
+ name: logistics officer ID card # DeltaV - Logistics Department replacing Cargo
components:
- type: Sprite
layers:
diff --git a/Resources/Prototypes/Entities/Objects/Misc/paper.yml b/Resources/Prototypes/Entities/Objects/Misc/paper.yml
index ace8505f544..e126e009be5 100644
--- a/Resources/Prototypes/Entities/Objects/Misc/paper.yml
+++ b/Resources/Prototypes/Entities/Objects/Misc/paper.yml
@@ -464,7 +464,7 @@
whitelist:
tags:
- Write
- insertOnInteract: false
+ insertOnInteract: false
- type: Item
sprite: Objects/Misc/clipboard.rsi
size: 10
@@ -661,7 +661,7 @@
state: stamp-mime
- type: entity
- name: head of logistics' rubber stamp # DeltaV - Logistics Department replacing Cargo
+ name: logistics officer's rubber stamp # DeltaV - Logistics Department replacing Cargo
parent: RubberStampBase
id: RubberStampQm
suffix: DO NOT MAP
diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml
index 25c69ca036f..87866c85ba4 100644
--- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml
+++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml
@@ -268,7 +268,7 @@
- type: entity
parent: AirlockCommand
id: AirlockQuartermasterLocked
- suffix: Head of Logistics, Locked # DeltaV - Logistics Department replacing Cargo
+ suffix: Logistics Officer, Locked # DeltaV - Logistics Department replacing Cargo
components:
- type: AccessReader
access: [["Quartermaster"]]
@@ -549,7 +549,7 @@
- type: entity
parent: AirlockCommandGlass
id: AirlockQuartermasterGlassLocked
- suffix: Head of Logistics, Locked # DeltaV - Logistics Department replacing Cargo
+ suffix: Logistics Officer, Locked # DeltaV - Logistics Department replacing Cargo
components:
- type: AccessReader
access: [["Quartermaster"]]
diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml
index 6c15fda0336..53318c41cb1 100644
--- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml
+++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml
@@ -381,7 +381,7 @@
- SalvageMagnetMachineCircuitboard
- StationMapElectronics
# - MetempsychoticMachineCircuitboard
-# - DeepFryerMachineCircuitBoard
+ - DeepFryerMachineCircuitboard
# End Nyano additions
- type: MaterialStorage
whitelist:
diff --git a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml
index 8f6b7a25e60..5f3c4787c9a 100644
--- a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml
+++ b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml
@@ -22,7 +22,7 @@
- type: entity
id: LockerQuarterMaster
parent: LockerBase
- name: head of logistics' locker # DeltaV - Logistics Department replacing Cargo
+ name: logistics officer's locker # DeltaV - Logistics Department replacing Cargo
components:
- type: Appearance
- type: EntityStorageVisuals
diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/Random/devices.yml b/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/Random/devices.yml
index 336341e5684..9b93e8aca31 100644
--- a/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/Random/devices.yml
+++ b/Resources/Prototypes/Nyanotrasen/Entities/Markers/Spawners/Random/devices.yml
@@ -42,7 +42,7 @@
- SolarTrackerElectronics
- Mousetrap
- RadioHandheld
- # - DeepFryerMachineCircuitboard
+ - DeepFryerMachineCircuitboard
- BoozeDispenserMachineCircuitboard
- SodaDispenserMachineCircuitboard
- RemoteSignaller
diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Consumable/Drinks/drinks_oil.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Consumable/Drinks/drinks_oil.yml
new file mode 100644
index 00000000000..ac29d0c6bb0
--- /dev/null
+++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Consumable/Drinks/drinks_oil.yml
@@ -0,0 +1,56 @@
+- type: entity
+ parent: DrinkBottleBaseFull
+ id: BaseOilJar
+ abstract: true
+ components:
+ - type: Sprite
+ sprite: Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi
+ state: icon
+ layers:
+ - state: icon
+ map: ["drinkCanIcon"]
+ - type: Appearance
+ - type: GenericVisualizer
+ visuals:
+ enum.OpenableVisuals.Opened:
+ drinkCanIcon:
+ True: {state: "icon_open"}
+ False: {state: "icon"}
+
+- type: entity
+ parent: BaseOilJar
+ id: OilJarGhee
+ name: jar of ghee
+ description: A large tinted glass jar with a simple label of butter sticks on it.
+ components:
+ - type: Sprite
+ layers:
+ - state: icon
+ map: ["drinkCanIcon"]
+ - state: butter
+ - type: SolutionContainerManager
+ solutions:
+ drink:
+ maxVol: 100
+ reagents:
+ - ReagentId: OilGhee
+ Quantity: 100
+
+- type: entity
+ parent: BaseOilJar
+ id: OilJarCorn
+ name: jar of corn oil
+ description: A large tinted glass jar with a simple label of a corn stalk on it.
+ components:
+ - type: Sprite
+ layers:
+ - state: icon
+ map: ["drinkCanIcon"]
+ - state: corn
+ - type: SolutionContainerManager
+ solutions:
+ drink:
+ maxVol: 100
+ reagents:
+ - ReagentId: Cornoil
+ Quantity: 100
\ No newline at end of file
diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/CircuitBoards/production.yml b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/CircuitBoards/production.yml
index 45a97fe8596..36e8263439c 100644
--- a/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/CircuitBoards/production.yml
+++ b/Resources/Prototypes/Nyanotrasen/Entities/Objects/Devices/CircuitBoards/production.yml
@@ -24,3 +24,23 @@
difficulty: 3
recipes:
- ReverseEngineeringMachineCircuitboard
+
+- type: entity
+ id: DeepFryerMachineCircuitboard
+ parent: BaseMachineCircuitboard
+ name: deep fryer machine board
+ components:
+ - type: Sprite
+ state: service
+ - type: MachineBoard
+ prototype: KitchenDeepFryer
+ requirements:
+ Capacitor: 1
+ MatterBin: 1
+ materialRequirements:
+ Steel: 4
+ Glass: 2
+ Cable: 4
+ - type: ReverseEngineering
+ recipes:
+ - DeepFryerMachineCircuitboard
\ No newline at end of file
diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Structures/Machines/deep_fryer.yml b/Resources/Prototypes/Nyanotrasen/Entities/Structures/Machines/deep_fryer.yml
new file mode 100644
index 00000000000..245ca42068d
--- /dev/null
+++ b/Resources/Prototypes/Nyanotrasen/Entities/Structures/Machines/deep_fryer.yml
@@ -0,0 +1,166 @@
+- type: entity
+ id: KitchenDeepFryer
+ parent: [ BaseMachinePowered, ConstructibleMachine ]
+ name: deep fryer
+ description: An industrial deep fryer. A big hit at state fairs!
+ components:
+ - type: Transform
+ noRot: false
+ - type: Sprite
+ netsync: false
+ sprite: Nyanotrasen/Structures/Machines/deep_fryer.rsi
+ layers:
+ - state: off-0
+ - map: ["enum.SolutionContainerLayers.Fill"]
+ state: off-1
+ - type: AmbientSound
+ volume: -4
+ range: 5
+ enabled: false
+ sound:
+ path: /Audio/Nyanotrasen/Ambience/Objects/deepfryer_sizzling.ogg
+ - type: SolutionContainerVisuals
+ maxFillLevels: 8
+ fillBaseName: off-
+ - type: Anchorable
+ - type: Pullable
+ - type: Rotatable
+ rotateWhilePulling: false
+ - type: Physics
+ bodyType: Static
+ - type: Climbable
+ - type: Fixtures
+ fixtures:
+ fix1:
+ shape:
+ !type:PhysShapeAabb
+ bounds: "-0.30,-0.25,0.30,0.45"
+ density: 600
+ mask:
+ - MachineMask
+ layer:
+ - MachineLayer
+ - type: DeepFryer
+ blacklist:
+ components:
+ # The classic.
+ - NukeDisk
+ # SliceableFood is handled easily enough, but there's not much to be
+ # gained by doing special handling for Stacks, especially since most
+ # of the items that use Stack aren't even remotely edible.
+ - Stack
+ whitelist:
+ components:
+ # It's what meat is.
+ - BodyPart
+ # Some clothes, shoes, uniforms.
+ - Butcherable
+ # It's already food.
+ - Food
+ - Seed
+ # A good source of fiber.
+ - Paper
+ # May as well let actual garbage get turned into food.
+ - SpaceGarbage
+ tags:
+ - Recyclable
+ - Trash
+ - Document
+ charredPrototype: FoodBadRecipe
+ goodReagents:
+ - ReagentId: Omnizine
+ Quantity: 1
+ badReagents:
+ - ReagentId: Toxin
+ Quantity: 2
+ wasteReagents:
+ - ReagentId: Charcoal
+ Quantity: 0.5
+ - ReagentId: Ash
+ Quantity: 0.5
+ # What food items are actually going to be improved by deep-frying?
+ # This is based on flavor profiles.
+ goodFlavors:
+ - bread
+ - bun
+ - donk
+ - dough
+ - fishy
+ - meaty
+ - pasta
+ - potatoes
+ - tofu
+ - onion
+ - mushroom
+ badFlavors:
+ - acid
+ - chocolate
+ - gunpowder
+ - minty
+ - raisins
+ - tea
+ - terrible
+ solution: vat_oil
+ fryingOils:
+ - Cornoil
+ - OilGhee
+ - OilOlive
+ #unsafeOilVolumeEffects: #Can't pass UninitializedSaveTest. Modifies itself on spawn. Very weird.
+ #- !type:AreaReactionEffect
+ # duration: 10
+ # prototypeId: Smoke
+ # sound:
+ # path: /Audio/Effects/smoke.ogg
+ - type: SolutionContainerManager
+ solutions:
+ vat_oil:
+ maxVol: 100
+ - type: DrainableSolution
+ solution: vat_oil
+ - type: ExaminableSolution
+ solution: vat_oil
+ - type: InjectableSolution
+ solution: vat_oil
+ - type: RefillableSolution
+ solution: vat_oil
+ - type: Drink
+ isOpen: true
+ solution: vat_oil
+ - type: Appearance
+ - type: ActivatableUI
+ key: enum.DeepFryerUiKey.Key
+ - type: UserInterface
+ interfaces:
+ - key: enum.DeepFryerUiKey.Key
+ type: DeepFryerBoundUserInterface
+ - type: Destructible
+ thresholds:
+ - trigger:
+ !type:DamageTrigger
+ damage: 200
+ behaviors:
+ - !type:DoActsBehavior
+ acts: ["Destruction"]
+ - !type:PlaySoundBehavior
+ sound:
+ path: /Audio/Effects/metalbreak.ogg
+ - !type:SpillBehavior
+ solution: vat_oil
+ - !type:SpawnEntitiesBehavior
+ spawn:
+ MachineFrameDestroyed:
+ min: 1
+ max: 1
+ - type: ApcPowerReceiver
+ powerLoad: 300
+ - type: Machine
+ board: DeepFryerMachineCircuitboard
+ - type: EmptyOnMachineDeconstruct
+ containers:
+ - vat_entities
+ - type: ContainerContainer
+ containers:
+ vat_entities: !type:Container
+ machine_board: !type:Container
+ machine_parts: !type:Container
+ - type: PowerSwitch
diff --git a/Resources/Prototypes/Nyanotrasen/Reagents/Consumable/Food/condiments.yml b/Resources/Prototypes/Nyanotrasen/Reagents/Consumable/Food/condiments.yml
index 127b8d97a68..a5e859668a0 100644
--- a/Resources/Prototypes/Nyanotrasen/Reagents/Consumable/Food/condiments.yml
+++ b/Resources/Prototypes/Nyanotrasen/Reagents/Consumable/Food/condiments.yml
@@ -60,3 +60,19 @@
- !type:AdjustReagent
reagent: OilOlive
amount: 0.10
+
+- type: reagent
+ id: OilGhee
+ name: reagent-name-oil-ghee
+ group: Foods
+ desc: reagent-desc-oil-ghee
+ physicalDesc: reagent-physical-desc-oily
+ flavor: butter
+ color: gold
+ recognizable: true
+ metabolisms:
+ Food:
+ effects:
+ - !type:AdjustReagent
+ reagent: Nutriment
+ amount: 0.75
diff --git a/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/electronics.yml b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/electronics.yml
index 5b5fd618b03..591b8aec081 100644
--- a/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/electronics.yml
+++ b/Resources/Prototypes/Nyanotrasen/Recipes/Lathes/electronics.yml
@@ -42,3 +42,12 @@
Steel: 100
Glass: 300
Plasma: 200
+
+- type: latheRecipe
+ id: DeepFryerMachineCircuitboard
+ icon: { sprite: Objects/Misc/module.rsi, state: id_mod }
+ result: DeepFryerMachineCircuitboard
+ completetime: 4
+ materials:
+ Steel: 100
+ Glass: 900
\ No newline at end of file
diff --git a/Resources/Prototypes/Nyanotrasen/Recipes/Reactions/food.yml b/Resources/Prototypes/Nyanotrasen/Recipes/Reactions/food.yml
index 1897d1955e3..109c5e0932a 100644
--- a/Resources/Prototypes/Nyanotrasen/Recipes/Reactions/food.yml
+++ b/Resources/Prototypes/Nyanotrasen/Recipes/Reactions/food.yml
@@ -31,4 +31,15 @@
effects:
- !type:CreateEntityReactionEffect
entity: FoodMozzarella
- number: 2
\ No newline at end of file
+ number: 2
+
+- type: reaction
+ id: Ghee
+ impact: Low
+ minTemp: 373
+ reactants:
+ Butter:
+ amount: 1
+ products:
+ OilGhee: 1
+
\ No newline at end of file
diff --git a/Resources/Prototypes/Nyanotrasen/Recipes/Reactions/pyrotechnic.yml b/Resources/Prototypes/Nyanotrasen/Recipes/Reactions/pyrotechnic.yml
new file mode 100644
index 00000000000..b06b5027a7f
--- /dev/null
+++ b/Resources/Prototypes/Nyanotrasen/Recipes/Reactions/pyrotechnic.yml
@@ -0,0 +1,39 @@
+# Because you know someone's going to try putting water in the deep fryer.
+- type: reaction
+ id: HotCornoilAndWater
+ impact: Medium
+ minTemp: 373.15
+ reactants:
+ Cornoil:
+ amount: 1
+ Water:
+ amount: 1
+ effects:
+ - !type:CreateGas
+ gas: WaterVapor
+
+- type: reaction
+ id: HotOilGheeAndWater
+ impact: Medium
+ minTemp: 373.15
+ reactants:
+ OilGhee:
+ amount: 1
+ Water:
+ amount: 1
+ effects:
+ - !type:CreateGas
+ gas: WaterVapor
+
+- type: reaction
+ id: HotOilOliveAndWater
+ impact: Medium
+ minTemp: 373.15
+ reactants:
+ OilOlive:
+ amount: 1
+ Water:
+ amount: 1
+ effects:
+ - !type:CreateGas
+ gas: WaterVapor
diff --git a/Resources/Prototypes/Nyanotrasen/Voice/speech_emotes.yml b/Resources/Prototypes/Nyanotrasen/Voice/speech_emotes.yml
index 21bb428029d..46f1e4a5c7c 100644
--- a/Resources/Prototypes/Nyanotrasen/Voice/speech_emotes.yml
+++ b/Resources/Prototypes/Nyanotrasen/Voice/speech_emotes.yml
@@ -4,30 +4,27 @@
category: Vocal
chatMessages: [hisses.]
chatTriggers:
- - hiss
- - hisses
+ - hiss.
- hisses.
- hisses!
- - hissing
- - hissed
+ - hissing.
+ - hissed.
- type: emote
id: Meow
category: Vocal
chatMessages: [meows.]
chatTriggers:
- - meow
- - meows
+ - meow.
+ - meow!
- meows.
- meows!
- - meowing
- - meowed
- - miau
- - miaus
+ - meowing.
+ - meowed.
+ - miau.
- miaus.
- miaus!
- - nya
- - nyas
+ - nya.
- nyas.
- nyas!
@@ -36,33 +33,31 @@
category: Vocal
chatMessages: [mews.]
chatTriggers:
- - mew
- - mews
+ - mew.
+ - mew!
- mews.
- mews!
- - mewing
- - mewed
+ - mewing.
+ - mewed.
- type: emote
id: Growl
category: Vocal
chatMessages: [growls.]
chatTriggers:
- - growl
- - growls
+ - growl.
- growls.
- growls!
- - growling
- - growled
+ - growling.
+ - growled.
- type: emote
id: Purr
category: Vocal
chatMessages: [purrs.]
chatTriggers:
- - purr
- - purrs
+ - purr.
- purrs.
- purrs!
- - purring
- - purred
+ - purring.
+ - purred.
diff --git a/Resources/Prototypes/Nyanotrasen/mailDeliveries.yml b/Resources/Prototypes/Nyanotrasen/mailDeliveries.yml
index bc59cbb1d63..41335b243c4 100644
--- a/Resources/Prototypes/Nyanotrasen/mailDeliveries.yml
+++ b/Resources/Prototypes/Nyanotrasen/mailDeliveries.yml
@@ -33,6 +33,7 @@
MailMoney: 1
MailMuffins: 1.1
MailMoffins: 0.5
+ MailPumpkinPie: 1 # DeltaV - Pumpkie pie mail
MailNoir: 0.5
MailPAI: 1
MailPlushie: 1
diff --git a/Resources/Prototypes/Objectives/objectiveGroups.yml b/Resources/Prototypes/Objectives/objectiveGroups.yml
index 70b3c2773cd..2dda0fa5728 100644
--- a/Resources/Prototypes/Objectives/objectiveGroups.yml
+++ b/Resources/Prototypes/Objectives/objectiveGroups.yml
@@ -21,7 +21,7 @@
CaptainJetpackStealObjective: 0.5
HandTeleporterStealObjective: 0.5
SecretDocumentsStealObjective: 0.5
- HoLLuckyBillStealObjective: 0.5 # DeltaV - HoL steal objective, see Resources/Prototypes/DeltaV/Objectives/traitor.yml
+ LOLuckyBillStealObjective: 0.5 # DeltaV - LO steal objective, see Resources/Prototypes/DeltaV/Objectives/traitor.yml
HoPBookIanDossierStealObjective: 1 # DeltaV - HoP steal objective, see Resources/Prototypes/DeltaV/Objectives/traitor.yml
- type: weightedRandom
diff --git a/Resources/Prototypes/Reagents/Consumable/Food/ingredients.yml b/Resources/Prototypes/Reagents/Consumable/Food/ingredients.yml
index c9dd15f8165..dfa85240647 100644
--- a/Resources/Prototypes/Reagents/Consumable/Food/ingredients.yml
+++ b/Resources/Prototypes/Reagents/Consumable/Food/ingredients.yml
@@ -141,6 +141,8 @@
flavor: oily
flavorMinimum: 0.05
color: olive
+ meltingPoint: -6.0 #Nyano - Summary: Add melting point for fryer.
+ boilingPoint: 299.0 #Nyano - Summary: Add boiling point for fryer.
recognizable: true
metabolisms:
Food:
diff --git a/Resources/Prototypes/Research/civilianservices.yml b/Resources/Prototypes/Research/civilianservices.yml
index 92087750944..df16de1d341 100644
--- a/Resources/Prototypes/Research/civilianservices.yml
+++ b/Resources/Prototypes/Research/civilianservices.yml
@@ -78,6 +78,7 @@
- ElectricGrillMachineCircuitboard
- BoozeDispenserMachineCircuitboard
- SodaDispenserMachineCircuitboard
+ - DeepFryerMachineCircuitboard #Nyano - Summary: adds deep fryer circuit board to service research.
- type: technology
id: AudioVisualCommunication
diff --git a/Resources/Prototypes/Roles/Antags/nukeops.yml b/Resources/Prototypes/Roles/Antags/nukeops.yml
index bd625e6d81a..f4fae1a8b17 100644
--- a/Resources/Prototypes/Roles/Antags/nukeops.yml
+++ b/Resources/Prototypes/Roles/Antags/nukeops.yml
@@ -33,4 +33,5 @@
- !type:DepartmentTimeRequirement
department: Security
time: 18000 # 5h
+ - !type:WhitelistRequirement # DeltaV - Commander is an "hrp" role
# should be changed to nukie playtime when thats tracked (wyci)
diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/chef.yml b/Resources/Prototypes/Roles/Jobs/Civilian/chef.yml
index 34c4abf30f9..685773ac48a 100644
--- a/Resources/Prototypes/Roles/Jobs/Civilian/chef.yml
+++ b/Resources/Prototypes/Roles/Jobs/Civilian/chef.yml
@@ -16,7 +16,11 @@
- Kitchen
extendedAccess:
- Hydroponics
- - Bar
+ - Bar #Nyano - Summary: After this line, Professional Che is a component to be added. Very important.
+ special:
+ - !type:AddComponentSpecial
+ components:
+ - type: ProfessionalChef #Nyano - End Summary.
- type: startingGear
id: ChefGear
diff --git a/Resources/Prototypes/Roles/Jobs/Command/captain.yml b/Resources/Prototypes/Roles/Jobs/Command/captain.yml
index 620c6e99bf7..027eab699ef 100644
--- a/Resources/Prototypes/Roles/Jobs/Command/captain.yml
+++ b/Resources/Prototypes/Roles/Jobs/Command/captain.yml
@@ -24,6 +24,7 @@
time: 108000 # DeltaV - 30 hours
- !type:OverallPlaytimeRequirement # DeltaV - Playtime requirement
time: 108000 # 30 hours
+ - !type:WhitelistRequirement # DeltaV - Whitelist requirement
weight: 20
startingGear: CaptainGear
icon: "JobIconCaptain"
diff --git a/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml b/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml
index 6dc86e34f64..b6724356945 100644
--- a/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml
+++ b/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml
@@ -15,6 +15,7 @@
time: 36000 # 10 hours
- !type:OverallPlaytimeRequirement
time: 90000 # DeltaV - 25 hours
+ - !type:WhitelistRequirement # DeltaV - Whitelist requirement
weight: 10
startingGear: HoSGear
icon: "JobIconHeadOfSecurity"
@@ -41,7 +42,7 @@
components:
- type: PsionicBonusChance #Nyano - Summary: makes it more likely to become psionic.
flatBonus: 0.025
-
+
- type: startingGear
id: HoSGear
equipment:
diff --git a/Resources/Prototypes/Species/moth.yml b/Resources/Prototypes/Species/moth.yml
index 4f587eb40e0..724c268a0bb 100644
--- a/Resources/Prototypes/Species/moth.yml
+++ b/Resources/Prototypes/Species/moth.yml
@@ -7,7 +7,7 @@
defaultSkinTone: "#ffda93"
markingLimits: MobMothMarkingLimits
dollPrototype: MobMothDummy
- skinColoration: Hues
+ skinColoration: TintedHuesSkin # DeltaV - No rgb moths, literally 1849
maleFirstNames: names_moth_first_male
femaleFirstNames: names_moth_first_female
lastNames: names_moth_last
diff --git a/Resources/ServerInfo/Guidebook/Antagonist/Traitors.xml b/Resources/ServerInfo/Guidebook/Antagonist/Traitors.xml
index 2d022d05ade..dc8e870b03f 100644
--- a/Resources/ServerInfo/Guidebook/Antagonist/Traitors.xml
+++ b/Resources/ServerInfo/Guidebook/Antagonist/Traitors.xml
@@ -78,9 +78,9 @@
- - Steal the Head of Logistics's [color=#a4885c]lucky bill[/color].
+ - Steal the Logistics Officer's [color=#a4885c]lucky bill[/color].
-
+
- Steal the Head of Personnel's [color=#a4885c]Ian Photobook[/color].
diff --git a/Resources/ServerInfo/Guidebook/Jobs.xml b/Resources/ServerInfo/Guidebook/Jobs.xml
index 95534eddbe2..31f32108fff 100644
--- a/Resources/ServerInfo/Guidebook/Jobs.xml
+++ b/Resources/ServerInfo/Guidebook/Jobs.xml
@@ -9,7 +9,7 @@ This department includes the janitor, passengers, clown, mime, musician, chef, b
It primarily functions as folks who entertain, clean, and serve the rest of the crew, with the exception of passengers who have no particular job beyond getting lost in maintenance.
## Logistics
-Logistics consists of the cargo technicians, salvage technicians, and the head of logistics. As a department, it responsible resource distribution and trade, capable of buying and selling things on the galactic market.
+Logistics consists of the cargo technicians, salvage technicians, and the logistics officer. As a department, it responsible resource distribution and trade, capable of buying and selling things on the galactic market.
For the most part, this means they scrounge around the station and assorted wrecks to find materials to sell and redistribute, and purchase materials other departments request.
@@ -34,7 +34,7 @@ Engineering consists of technical assistants, station engineers, atmospheric tec
Engineering is readily equipped to go safely into space, and as such they should always attempt to repair uninhabitable parts of the station.
## Command
-Command consists of the captain, the head of personnel, the head of security, the chief engineer, the chief medical officer, the mystagogue, and the head of logistics. As a department it is responsible for keeping the station and its departments running efficiently.
+Command consists of the captain, the head of personnel, the head of security, the chief engineer, the chief medical officer, the mystagogue, and the logistics officer. As a department it is responsible for keeping the station and its departments running efficiently.
Command members should always be relatively competent in their respective departments and attempt to delegate responsibility and direct work.
diff --git a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_tails.rsi/harpy_tail_swallow.png b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_tails.rsi/harpy_tail_swallow.png
deleted file mode 100644
index 655f973255e..00000000000
Binary files a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_tails.rsi/harpy_tail_swallow.png and /dev/null differ
diff --git a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_tails.rsi/meta.json b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_tails.rsi/meta.json
index 2b469d9ee1a..b795894cae1 100644
--- a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_tails.rsi/meta.json
+++ b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_tails.rsi/meta.json
@@ -1,16 +1,12 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
- "copyright": "Swallow taken from S.P.L.U.R.T at https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13/blob/master/modular_splurt/icons/mob/mam_tails.dmi, Phoenix and Rooster by @leonardo_dabepis",
+ "copyright": "Phoenix and Rooster by @leonardo_dabepis",
"size": {
"x": 32,
"y": 32
},
"states": [
- {
- "name": "harpy_tail_swallow",
- "directions": 4
- },
{
"name": "phoenix_tail",
"directions": 4
diff --git a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpy.png b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpy.png
new file mode 100644
index 00000000000..ce932f0df5f
Binary files /dev/null and b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpy.png differ
diff --git a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpy2tone1.png b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpy2tone1.png
new file mode 100644
index 00000000000..2030ff8cf2d
Binary files /dev/null and b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpy2tone1.png differ
diff --git a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpy2tone2.png b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpy2tone2.png
new file mode 100644
index 00000000000..f8825513a34
Binary files /dev/null and b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpy2tone2.png differ
diff --git a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpy3tone1.png b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpy3tone1.png
new file mode 100644
index 00000000000..4bd00186567
Binary files /dev/null and b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpy3tone1.png differ
diff --git a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpy3tone2.png b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpy3tone2.png
new file mode 100644
index 00000000000..7e431a95b43
Binary files /dev/null and b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpy3tone2.png differ
diff --git a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpy3tone3.png b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpy3tone3.png
new file mode 100644
index 00000000000..477e6873e8f
Binary files /dev/null and b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpy3tone3.png differ
diff --git a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpyspeckled1.png b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpyspeckled1.png
new file mode 100644
index 00000000000..f48d8e6538d
Binary files /dev/null and b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpyspeckled1.png differ
diff --git a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpyspeckled2.png b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpyspeckled2.png
new file mode 100644
index 00000000000..b687a2bf9f0
Binary files /dev/null and b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpyspeckled2.png differ
diff --git a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpyundertone1.png b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpyundertone1.png
new file mode 100644
index 00000000000..7a792111c50
Binary files /dev/null and b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpyundertone1.png differ
diff --git a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpyundertone2.png b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpyundertone2.png
new file mode 100644
index 00000000000..8a753996b72
Binary files /dev/null and b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpyundertone2.png differ
diff --git a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpywingtip1.png b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpywingtip1.png
new file mode 100644
index 00000000000..49f7e0c1353
Binary files /dev/null and b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpywingtip1.png differ
diff --git a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpywingtip2.png b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpywingtip2.png
new file mode 100644
index 00000000000..bde6c006920
Binary files /dev/null and b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/harpywingtip2.png differ
diff --git a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/meta.json b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/meta.json
new file mode 100644
index 00000000000..0785ff1aaa6
--- /dev/null
+++ b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings.rsi/meta.json
@@ -0,0 +1,59 @@
+{
+ "version": 1,
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from S.P.L.U.R.T at commit https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13/commit/285f6f86ac41a6246f250993486effeab8581c2c, edited by @raistlin_jag",
+ "states": [
+ {
+ "name": "harpy",
+ "directions": 4
+ },
+ {
+ "name": "harpy2tone1",
+ "directions": 4
+ },
+ {
+ "name": "harpy2tone2",
+ "directions": 4
+ },
+ {
+ "name": "harpy3tone1",
+ "directions": 4
+ },
+ {
+ "name": "harpy3tone2",
+ "directions": 4
+ },
+ {
+ "name": "harpy3tone3",
+ "directions": 4
+ },
+ {
+ "name": "harpyspeckled1",
+ "directions": 4
+ },
+ {
+ "name": "harpyspeckled2",
+ "directions": 4
+ },
+ {
+ "name": "harpyundertone1",
+ "directions": 4
+ },
+ {
+ "name": "harpyundertone2",
+ "directions": 4
+ },
+ {
+ "name": "harpywingtip1",
+ "directions": 4
+ },
+ {
+ "name": "harpywingtip2",
+ "directions": 4
+ }
+ ]
+}
diff --git a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings_default.rsi/harpy.png b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings_default.rsi/harpy.png
deleted file mode 100644
index c95611d4dae..00000000000
Binary files a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings_default.rsi/harpy.png and /dev/null differ
diff --git a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings_default.rsi/meta.json b/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings_default.rsi/meta.json
deleted file mode 100644
index 896237c4b3d..00000000000
--- a/Resources/Textures/DeltaV/Mobs/Customization/Harpy/harpy_wings_default.rsi/meta.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "version": 1,
- "size": {
- "x": 64,
- "y": 32
- },
- "license": "CC-BY-SA-3.0",
- "copyright": "Taken from S.P.L.U.R.T at commit https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13/commit/285f6f86ac41a6246f250993486effeab8581c2c",
- "states": [
- {
- "name": "harpy",
- "directions": 4
- }
- ]
-}
diff --git a/Resources/Textures/DeltaV/Objects/Consumable/Drinks/mothamphetamine.rsi/icon.png b/Resources/Textures/DeltaV/Objects/Consumable/Drinks/mothamphetamine.rsi/icon.png
new file mode 100644
index 00000000000..ee700239b11
Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Consumable/Drinks/mothamphetamine.rsi/icon.png differ
diff --git a/Resources/Textures/DeltaV/Objects/Consumable/Drinks/mothamphetamine.rsi/meta.json b/Resources/Textures/DeltaV/Objects/Consumable/Drinks/mothamphetamine.rsi/meta.json
new file mode 100644
index 00000000000..507c921294a
--- /dev/null
+++ b/Resources/Textures/DeltaV/Objects/Consumable/Drinks/mothamphetamine.rsi/meta.json
@@ -0,0 +1,14 @@
+{
+ "version": 1,
+ "license": "CC0-1.0",
+ "copyright": "Artwork by @Leonardo_DaBepis. https://leonardo-dabepis.tumblr.com/",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ }
+ ]
+}
diff --git a/Resources/Textures/DeltaV/Objects/Consumable/Food/Baked/pie.rsi/inhand-left.png b/Resources/Textures/DeltaV/Objects/Consumable/Food/Baked/pie.rsi/inhand-left.png
new file mode 100644
index 00000000000..fa40fb33491
Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Consumable/Food/Baked/pie.rsi/inhand-left.png differ
diff --git a/Resources/Textures/DeltaV/Objects/Consumable/Food/Baked/pie.rsi/inhand-right.png b/Resources/Textures/DeltaV/Objects/Consumable/Food/Baked/pie.rsi/inhand-right.png
new file mode 100644
index 00000000000..e08270f864a
Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Consumable/Food/Baked/pie.rsi/inhand-right.png differ
diff --git a/Resources/Textures/DeltaV/Objects/Consumable/Food/Baked/pie.rsi/meta.json b/Resources/Textures/DeltaV/Objects/Consumable/Food/Baked/pie.rsi/meta.json
new file mode 100644
index 00000000000..0bcf8b915a5
--- /dev/null
+++ b/Resources/Textures/DeltaV/Objects/Consumable/Food/Baked/pie.rsi/meta.json
@@ -0,0 +1,25 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "pumpkin-slice taken from https://github.com/fulpstation/fulpstation/commit/64d85bf269fd4e5f3be314bcedc3463cf1d57676 | pumpkin made by rosysyntax",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "pumpkin"
+ },
+ {
+ "name": "pumpkin-slice"
+ },
+ {
+ "name": "inhand-right",
+ "directions": 4
+ },
+ {
+ "name": "inhand-left",
+ "directions": 4
+ }
+ ]
+}
diff --git a/Resources/Textures/DeltaV/Objects/Consumable/Food/Baked/pie.rsi/pumpkin-slice.png b/Resources/Textures/DeltaV/Objects/Consumable/Food/Baked/pie.rsi/pumpkin-slice.png
new file mode 100644
index 00000000000..a07ece057b8
Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Consumable/Food/Baked/pie.rsi/pumpkin-slice.png differ
diff --git a/Resources/Textures/DeltaV/Objects/Consumable/Food/Baked/pie.rsi/pumpkin.png b/Resources/Textures/DeltaV/Objects/Consumable/Food/Baked/pie.rsi/pumpkin.png
new file mode 100644
index 00000000000..ebad31e29d8
Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Consumable/Food/Baked/pie.rsi/pumpkin.png differ
diff --git a/Resources/Textures/DeltaV/Objects/Consumable/Food/scrambledeggs.rsi/bowl.png b/Resources/Textures/DeltaV/Objects/Consumable/Food/scrambledeggs.rsi/bowl.png
new file mode 100644
index 00000000000..9f91f21ff45
Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Consumable/Food/scrambledeggs.rsi/bowl.png differ
diff --git a/Resources/Textures/DeltaV/Objects/Consumable/Food/scrambledeggs.rsi/meta.json b/Resources/Textures/DeltaV/Objects/Consumable/Food/scrambledeggs.rsi/meta.json
new file mode 100644
index 00000000000..01d48684c08
--- /dev/null
+++ b/Resources/Textures/DeltaV/Objects/Consumable/Food/scrambledeggs.rsi/meta.json
@@ -0,0 +1,17 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Bowl taken from tgstation and modified by Swept at https://github.com/tgstation/tgstation/commit/40d75cc340c63582fb66ce15bf75a36115f6bdaa, Eggs made by JudasMaw",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "bowl"
+ },
+ {
+ "name": "scrambled-eggs"
+ }
+ ]
+}
diff --git a/Resources/Textures/DeltaV/Objects/Consumable/Food/scrambledeggs.rsi/scrambled-eggs.png b/Resources/Textures/DeltaV/Objects/Consumable/Food/scrambledeggs.rsi/scrambled-eggs.png
new file mode 100644
index 00000000000..236d490e393
Binary files /dev/null and b/Resources/Textures/DeltaV/Objects/Consumable/Food/scrambledeggs.rsi/scrambled-eggs.png differ
diff --git a/Resources/Textures/Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi/butter.png b/Resources/Textures/Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi/butter.png
new file mode 100644
index 00000000000..4eb940a5321
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi/butter.png differ
diff --git a/Resources/Textures/Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi/corn.png b/Resources/Textures/Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi/corn.png
new file mode 100644
index 00000000000..d4ff1bc4adf
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi/corn.png differ
diff --git a/Resources/Textures/Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi/icon.png b/Resources/Textures/Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi/icon.png
new file mode 100644
index 00000000000..ac67795b586
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi/icon.png differ
diff --git a/Resources/Textures/Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi/icon_open.png b/Resources/Textures/Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi/icon_open.png
new file mode 100644
index 00000000000..d5b9f51a824
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi/icon_open.png differ
diff --git a/Resources/Textures/Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi/meta.json b/Resources/Textures/Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi/meta.json
new file mode 100644
index 00000000000..f4b1f1f3bc4
--- /dev/null
+++ b/Resources/Textures/Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi/meta.json
@@ -0,0 +1,26 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-4.0",
+ "copyright": "@Vordenburg",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "icon_open"
+ },
+ {
+ "name": "butter"
+ },
+ {
+ "name": "corn"
+ },
+ {
+ "name": "olives"
+ }
+ ]
+}
diff --git a/Resources/Textures/Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi/olives.png b/Resources/Textures/Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi/olives.png
new file mode 100644
index 00000000000..55326187c46
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Objects/Consumable/Drinks/oil_jar.rsi/olives.png differ
diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/meta.json b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/meta.json
new file mode 100644
index 00000000000..cfb73331abe
--- /dev/null
+++ b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/meta.json
@@ -0,0 +1,255 @@
+{
+ "version": 1,
+ "license": "CC-BY-NC-SA-3.0",
+ "copyright": "@Vordenburg | significant changes made based on original source: https://github.com/goonstation/goonstation/blob/731bb69de3a835c68b584f0ed36aa4a52620ef3a/icons/obj/kitchen.dmi",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "off-0",
+ "directions": 4
+ },
+ {
+ "name": "off-1",
+ "directions": 4
+ },
+ {
+ "name": "off-2",
+ "directions": 4
+ },
+ {
+ "name": "off-3",
+ "directions": 4
+ },
+ {
+ "name": "off-4",
+ "directions": 4
+ },
+ {
+ "name": "off-5",
+ "directions": 4
+ },
+ {
+ "name": "off-6",
+ "directions": 4
+ },
+ {
+ "name": "off-7",
+ "directions": 4
+ },
+ {
+ "name": "off-8",
+ "directions": 4
+ },
+ {
+ "name": "on-1",
+ "directions": 4,
+ "delays": [
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ]
+ ]
+ },
+ {
+ "name": "on-2",
+ "directions": 4,
+ "delays": [
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ]
+ ]
+ },
+ {
+ "name": "on-3",
+ "directions": 4,
+ "delays": [
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ]
+ ]
+ },
+ {
+ "name": "on-4",
+ "directions": 4,
+ "delays": [
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ]
+ ]
+ },
+ {
+ "name": "on-5",
+ "directions": 4,
+ "delays": [
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ]
+ ]
+ },
+ {
+ "name": "on-6",
+ "directions": 4,
+ "delays": [
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ]
+ ]
+ },
+ {
+ "name": "on-7",
+ "directions": 4,
+ "delays": [
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ]
+ ]
+ },
+ {
+ "name": "on-8",
+ "directions": 4,
+ "delays": [
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ],
+ [
+ 0.1785,
+ 0.1785,
+ 0.1785
+ ]
+ ]
+ }
+ ]
+}
diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-0.png b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-0.png
new file mode 100644
index 00000000000..75b834dba28
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-0.png differ
diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-1.png b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-1.png
new file mode 100644
index 00000000000..42b0cec0f47
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-1.png differ
diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-2.png b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-2.png
new file mode 100644
index 00000000000..8fbe08ff6e6
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-2.png differ
diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-3.png b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-3.png
new file mode 100644
index 00000000000..27d0ff5f3cb
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-3.png differ
diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-4.png b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-4.png
new file mode 100644
index 00000000000..3f0ade9ce56
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-4.png differ
diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-5.png b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-5.png
new file mode 100644
index 00000000000..bf679abbead
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-5.png differ
diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-6.png b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-6.png
new file mode 100644
index 00000000000..b173573edca
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-6.png differ
diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-7.png b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-7.png
new file mode 100644
index 00000000000..34c495ef72d
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-7.png differ
diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-8.png b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-8.png
new file mode 100644
index 00000000000..27c209ac1af
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/off-8.png differ
diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-1.png b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-1.png
new file mode 100644
index 00000000000..9f1b95e7330
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-1.png differ
diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-2.png b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-2.png
new file mode 100644
index 00000000000..4385149c5f9
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-2.png differ
diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-3.png b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-3.png
new file mode 100644
index 00000000000..63a2e8d1db4
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-3.png differ
diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-4.png b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-4.png
new file mode 100644
index 00000000000..6da34ce0347
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-4.png differ
diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-5.png b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-5.png
new file mode 100644
index 00000000000..707b95e9aed
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-5.png differ
diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-6.png b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-6.png
new file mode 100644
index 00000000000..6ad6e09d190
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-6.png differ
diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-7.png b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-7.png
new file mode 100644
index 00000000000..5df86038e12
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-7.png differ
diff --git a/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-8.png b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-8.png
new file mode 100644
index 00000000000..17cf4dca533
Binary files /dev/null and b/Resources/Textures/Nyanotrasen/Structures/Machines/deep_fryer.rsi/on-8.png differ