mirror of
https://github.com/DeltaV-Station/Delta-v.git
synced 2026-09-29 23:57:29 +00:00
+44









deltanedas
Ubaser
YourUsername
pa.pecherskij
PraxisMapper
EmoGarbage404
Ekkosangen
Chief-Engineer
Winkarst
Ilya246
PJBot
Errant
godisdeadLOL
lzk
Boaz1111
Mervill
slarticodefast
DrSmugleaf
Nemanja
deltanedas
poeMota
Mota
Moomoobeef
Cojoke
Pieter-Jan Briers
themias
Emisse
Арт
ScarKy0
IProduceWidgets
metalgearsloth
Fildrance
Lye
DieselMohawk
Hreno
eoineoineoin
Eoin Mcloughlin
qwerltaz
Ty Ashley
Token
Alzore
chromiumboy
Psychpsyo
drakewill-CRL
Nim
Perry Fraser
Ekkosangen
Ed
Chubbicous
Ps3Moira
FungiFellow
Futuristic-OK
Ian
TsjipTsjip
c93551dad7
* Remove always false checks (#31708) * Remove calls to FormattedMessage obsolete methods (#31706) * Remove FormattedMessage obsolete methods * Oops * remove misinformation from tip 26 (#31705) tip 26 * Automatic changelog update * Replace obsolete code in AnomalySystem.Generator.cs (#31718) * replace obsolete * weh * Added cursor indicator for space dragon fire breath ability (#31725) space dragon breath cursor indicator Co-authored-by: YourUsername <you@example.com> * Automatic changelog update * small yml cleanup (#31720) * Updates descriptions of station specific jobs. (#31713) done * Remove unused IoC dependency references. (#31704) Remove unused IoC dependencies * cleanup filing cabinets yml (#31211) * partmedia ahh kommit * ahh * everything should be fine now * f * now should be good * Update Resources/Prototypes/Entities/Structures/Storage/filing_cabinets.yml Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * fix suffix --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Move IgnitionEvent to shared (#30985) * Cleanup railings yml (#31618) * Cleanup railings * fix line * real fix * Roundstart Grappling Gun (#31737) Roundstart grappling hook * Automatic changelog update * Added in-hand sprite for Smile the Slime (#31731) added smile the slime in-hand texture Co-authored-by: YourUsername <you@example.com> * Lite Magnet Rebalancing (#31726) magnet rebalancing ish * unnerf fishops * Devmap crew monitor fix (#31677) * Automatic changelog update * Add ERT time stats (#31629) * add jobs for ghost roles * add job to ToggleableGhostRole * typo --------- Co-authored-by: Mota <belochuc@gmail.com> * Automatic changelog update * Fix CS0642 - Possible mistaken empty statement (#31740) * Throw the book at em! The space law book now does 1 blunt projectile damage (#31387) * you can now throw the space law book for 1 blunt damage * made book damage a feature of all books * Replace instances of SolutionContainerSystem with SharedSolutionContainerSystem (#30084) * Replace instances of SolutionContainerSystem with SharedSolutionContainerSystem * guap * More fixes * Wait you can do that? --------- Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com> * Add Donk Co. microwave board to Combat Bakery Kit (#31239) * Add special microwave board to Combat Bakery Kit * use event instead of trycomp * make the board sus * add instructions note * embarrassing typo * Add functionality to Donk Co. microwave instead * update note * Automatic changelog update * Actions bar dynamic resizing (#31759) * action bar dynamic resizing * action bar dynamic resizing for separated style * decreased indent for separated style --------- Co-authored-by: YourUsername <you@example.com> * Automatic changelog update * Fix warnings related to non-exhaustive pattern matching. (#31763) old man shakes fist at modern syntax * ats update (#31766) * ats update * fix pipenet * Ninja throwing star ability fix (#31684) fixed ninja star not spawning Co-authored-by: YourUsername <you@example.com> * Automatic changelog update * Remove duplicate using from FoodSystem (#31769) * vox voices revamp (#31679) vox voices v2 * fixed broken pipe sprites (#31773) * Return Long2 and Long3 hairstyles (#30963) * Sprites * Prototype_&_Locale * sorted_in_alphabetical_order * Automatic changelog update * Added many old ion lawsets for borgs and AI. (#31664) * Added the Commandments, Paladin, LetLive, Station Efficiency, Robocop, Overlord, Dungeon Master, Artist, Antimov and Nutimov lawsets/ * Wording * Anti-Antimov * Fixed fun * Add Snails (#30765) * add snails * scuffix * migrate * mo-grate * oopsied the ftls * Revert "oopsied the ftls" This reverts commit 0d3c6c17f31ec904679d6a48799cea71e77c1f99. * the curse of staging the wrong file, resolved. * Snoth * fix my dumbs * reviews 1 * anti space technology * salt hurty * spelling * Its a slotherhouse out here * sequencing * cooked snail * volfix * speed reversal * Automatic changelog update * Remove testbed command (#31793) * feat: now when research is unlocked in console, approver of reasearch is radio-ed too (#31170) * feat: now when research is unlocked in console, approver of reasearch is radio-ed too * refactor: now most of events that require actor name to be radio-ed or logged use TryGetIdentityShortInfoEvent which is subscibed by id-card system and borg system (to work for both carbon and synthetic life-forms) * refactor: moved TryGetIdentityShortInfoEvent on id card system to shared, fixed cargo cent-com-originated orders * remove unused check * refactor: decoupled systems from IdCardSystem (those that are not dependent on it anymore) * refactor: removed unuseed usings * feat: emagged cargo/research consoles wont radio messages on buy/research confirm anymore --------- Co-authored-by: pa.pecherskij <pa.pecherskij@interfax.ru> * Automatic changelog update * New chemical based artifact nodes (#30873) * Initial pH nodes, and description changes to indicate pH * Psychoactive and stimulant nodes, Medical foundation, bioreactive hint * Added medical reagents to medical node. Added norepinephric acid to acidic and made up a pH * Added pyrotechnic chem node, and corresponding hint * spelled psychedelic correctly * Fixed capitalisation skill issue * fixed indentation skill issue * fixed a further indentation skill issue * Removed extraneous whitespace * Replaced bioreactive with theraputic and psychoactive. Also fixed typo skill issue. * removed unnecessary comment * Replaced heartbreaker with THC for psychadelic * removed artifexium from acidic * added tran acid to acidic * added more medical chems * removed pH values * removed all but medical * Automatic changelog update * Add Red Neck Gaiter To Secdrobe (#30106) * Red Neck Gaiter Added to SecDrobe * Removes Gaiter From TheaterDrobe * Automatic changelog update * Fixed typos (#31811) * Automatic changelog update * Station AI has their name displayed in announcements now. (#31802) * Station AI has their name displayed in announcements now. * I'm so sorry * Corrections * part 2 * part 3 :| * part 4 * Whitespace * Fixing whitespace part 1 * No more whitespace * PLEASE NO MORE WHITESPACE * Automatic changelog update * Add disabled station anchors version (#31794) * Add disabled station anchors versions * remove this * add structural damage taken to a lot of prototypes (#30790) * fix * add structural damage taken to a lot of other things * do requested changes * how did this happen * Automatic changelog update * No Mr.Snail, I expect you to die! (fix sprite) (#31834) * No Mr.Snail, I expect you to die! * emoting * Allow some mobs to walk slowly (#31360) * Allow mice to walk slowly * add more * Automatic changelog update * Delete nonsense solar assembly construction through the Construction window (#31425) * Delete construction for solar assembly, it's the way to do it * Fix description of solar tracker electronics * Improvements to hand labeler UI (#31833) Give line edit focus when window is opened No longer require pressing enter to set the text Give feedback when user hits the maximum label length Co-authored-by: Eoin Mcloughlin <helloworld@eoinrul.es> * make tesla brighter (#31357) * make tesla brighter * radius to 10 * Automatic changelog update * CorrectContraband levels on each type of magboots (#30960) * Added a ClothingShoesBootsMagBase, to allow the other versions of the magboots to have their own contraband settings * Changed Science Boots to not be contraband * Made ClothingShoesBootsMagBase abstract * Removed Engineering Contraband from base magboots. Now only the CE's Advanced Magboots are contraband (Grand Theft Contraband). Blood Reds are Syndie Contraband. * Automatic changelog update * Morgue system refactor remove unused VVs and into Entity (#31835) * Remove unused VVs params and usings from entityUid, MorgueComponent into Entity<MorgueComponent> ent * remove unnecesary VVs cuz datafields add em * Make midround zombie outbreaks much rarer (#30266) * Remove midround zombies * super rare, like, 1/651 chance every few minutes. * weight to 1 --------- Co-authored-by: Ubaser <134914314+UbaserB@users.noreply.github.com> * Automatic changelog update * Teleporting while pulling crash fix (#31787) teleporting while pulling crash fix Co-authored-by: YourUsername <you@example.com> * Automatic changelog update * quietify stealthbox (#30741) * Automatic changelog update * Atmospheric alerts computer (#25938) * Atmospheric alerts computer * Moved components, restricted access to them * Minor tweaks * The screen will now turn off when the computer is not powered * Bug fix * Adjusted label * Updated to latest master version * Automatic changelog update * Day 0 bug fix for atmos alerts computer (#31858) Initial commit * Basically every electronic device can now be used by the AI. (#31730) * Basically every electronic device can now be used by the AI. * Removed stuff that didnt make sense * oops * Removed access from mailing and disposal units. * Added AI wires to a couple machines. * cool epic stuff * Automatic changelog update * Fix a typo in the 10 commandments (#31856) * feat: #26107 uplink discounts for traitors (no nukies for now) (#26297) * feat: #26107 uplink discounts for traitors and nukies * refactor: #26107 extracted discount label from price of StoreListingControl * refactor: minor renaming * refactor: parametrized adding discounts to uplink store * fix: #26107 prevent exception on empty discountOptions * feat: uplink now have 'Discounted' category which contains all discounted items on this session. * after merge fixups * rename discount categories according to common sense * refactor: DiscountOptions is now optional (nullable) on ListingData * add nullability check ignore for already checked listingData.DiscountOptions * fix after merge store menu ui * remove unused using * final fix after merge conflicts * [refactor]: #26107 fix variables naming in UplinkSystem * fix: #26107 fix after merge * refactor: #26107 now supports discountDownUntil on ListingItem, instead of % of discount * feat: #26107 support multiple currency discount in store on side of discount message label * refactor: #26107 extracted discounts initialization to separate system. StoreDiscountData are spread as array and not list now * refactor: #26107 move more code from storesystem to StoreDiscountComponent * refactor: #26107 separated StoreSystem and StoreDiscountSystem using events * fix: #26107 placed not-nullable variable initialization in ListingData for tests * refactor: #26107 minor renaming, xml-docs * fix: #26107 changed most of discounts to be down to half price for balance purposes * ids used in with discounts are now ProtoIds, dicountCategories are now prototypes, code with weights simplified * decoupled storesystem and store discount system * xml-docs * refactor: #26107 xml-doc for StoreDiscountSystem * is now a thing (tmp) * fix: compilation errors + StoreDiscountData.DiscountCategoryId * refactor: rename ListingDataWithCostModifiers, fix all cost related code, enpittyfy performance, uglify uplink_catalog * refactor: removed unused code, more StoreDiscountSystem docs, simplify code * refactor: moved discount category logic to respective system, now creating ListingData c-tor clones all mutable fields as expected * refactor: rename back (its not prototype) * refactor: move ListingItemsInitializingEvent to file with handling logic * refactor: comments for StoreBuyFinishedEvent handling, more logging * refactor: moved StoreInitializedEvent, xml-doc * refactor: simplify StoreDiscountSystem code (reduce nesting) + xml-doc * refactor: restore old listing data cost field name * refactor: fix linter in uplink_catalog.yml * refactor: xml-doc for ListingDataWithCostModifiers * refactor: limit usage of ListingData in favour of ListingDataWithCostModifiers * refactor: purged linq, removed custom datafield names, minor cleanup * refactor: removed double-allocation on getting available listings * refactor: StoreSystem.OnBuyRequest now uses component.FullListingsCatalog as reference point (as it was in original code) * fix: minor discount categories on uplink items changes following design overview * refactor: StoreBuyListingMessage now uses protoId and not whole object * refactor: store refund and discount integration test, RefreshAllListings now translates previous cost modifiers to refreshed list, if state previous to refresh had any listing items --------- Co-authored-by: pa.pecherskij <pa.pecherskij@interfax.ru> * Automatic changelog update * Fixed AI Actions (#31823) * Updated sprites for AI HUD * Epic test fail * Merged AGhost actions and AI actions together again. * Seperate comms and bugfix. Fixed broadcast. * Automatic changelog update * add wireless net to evac shuttles * Automatic changelog update * A kit to help new botanists discover chemistry (#31738) * Add a kit for botanists to do some limited chemistry to the NutriMax. Intended to help new botanists learn in-game about chemistry. * remove exclamation marks from names * naming fix * Rejected trademark application for 'Farmers Helper'. --------- Co-authored-by: PraxisMapper <praxismapper@gmail.com> * Automatic changelog update * Board for the AI upload console (#31867) board * Automatic changelog update * Fix typo in agri-chem manual (#31869) * Fix typo in agri-chem manual * Unremove my added newline * Cleanup books.yml (#31838) * Cleanup books.yml * yeah * shame * Vox sign/N2 locker update (#31845) * Vox sign/N2 locker update The "vox area" sign and N2 locker sprite were both taken from /vg/station. These sprites have bad racist connotations as discussed in https://github.com/space-wizards/space-station-14/issues/31840, and do not fit our server culture. The new N2 locker is not a taped on piece of trash. It now also has a blue stripe to mimic the regular O2 locker and make it more distinct from fire safety closets. The new "vox area" sign sprite follows the same style as other "area indicator" signs used throughout the blue and isn't an explicit warning sign anymore. It still has "No O2" on it to fill that role though. * emogarbage adjustments --------- Co-authored-by: EmoGarbage404 <retron404@gmail.com> * Automatic changelog update * Pizza boxes now have a chance to contain cotton pizza (#31883) Pizza box now contains cotton pizza Co-authored-by: Ekkosangen <9094006+XyyxShard@users.noreply.github.com> * Automatic changelog update * Tech Anomaly (#31764) * A * B * C * D * Update TechAnomalySystem.cs * idle anim * Update meta.json * new animation * Automatic changelog update * Fixed throngler name inconsistencies (#31889) changed throngler names * I have spent more time today cleaning up garbage than coding new shit, and I am mad (#31246) * Fix logging of GetWebhook errors Yeah let's just not log the error only stack trace. * I have spent more time today cleaning up garbage than coding new shit, and I am mad Cleans up the custom vote Discord webhook code because I *happened* to lay my eyes on how completely terrible it was and immediately found an obvious bug with it. Also did basic QA because jesus christ: it more clearly reports pending votes, properly indicates cancelled votes, improves footer formatting, better error logging, all the usual shit. Requires https://github.com/space-wizards/RobustToolbox/pull/5375 to avoid test failures * Mineral Scanner (#31390) * Mineral Scanner * doink * review * sunday funday * review and fix bugs i think? * Update MiningOverlay.cs * Automatic changelog update * Fix ai upload console itemslot whitelist (#31900) * Fix ai upload console itemslot whitelist * aw man * Automatic changelog update * improved vox laugh (#31798) vox laugh not underwater * fix pump shotgun wielded sprite (#31885) * fix shotgun sprite * fix take 2 * fix: Snail event wasnt tabled (#31884) pest events reorganized and snails spawn * Automatic changelog update * Force stop pulling when fall asleep (#31893) * break pull at sleep * TryStopPull without user --------- Co-authored-by: YourUsername <you@example.com> * Automatic changelog update * Energy Shotgun Change 2 - Narrow Nerf + instances from NoSpawn --> categories: [ HideSpawnMenu ] + self recharge removed + 1 more shot + normal recharge speed (#31235) * narrow nerf * last instance of nospawn gone * removes self recharge * 8 shots, less recharge time * Automatic changelog update * Add justice helm (#31905) * Add justice helm * backslash moment * spinny light * remove power cell from recipe * Automatic changelog update * Quiver Crafting Recipe (#27198) * Update quiver.yml * Create quiver.yml * Update clothing.yml * Update pneumatic_cannon.yml * Update pneumatic_cannon.yml * Update pneumatic_cannon.yml * Update pneumatic_cannon.yml * Delete RDs binary encryption key (#31909) Deleting binary key Silicon supremacy! * undelete rd key * Automatic changelog update * split temperature protection into heating and cooling (#30662) * split temperature protection into heating and cooling * fugg * weh * update TemperatureProtection for stuff * Automatic changelog update * makes the maple wing marking have a primary and a secondary color (#31691) bogos binted * Automatic changelog update * Remake bottles and syringes names to use labels (#29956) * Remake bottles and syringes names to use labels * vial * fix and add stuff * Automatic changelog update * guide on agrichem and botanicals guidebook update (#31896) * Automatic changelog update * Automatic changelog update * Lost evac pod thing tiny fan (#31915) * disaster evacpod tinyfan * real * :trollface: * untroll * Ghostrole rule updates (#29249) * First batch of ghostrole rule updates * Second pass * Re-word free agent * Apply review comments Co-authored-by: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com> * You heard it here first folks God rules are weird to write. Co-authored-by: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com> * Honkbot -> Free Agent Co-authored-by: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com> * Mimebot -> Free Agent Co-authored-by: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com> * Jonkbot -> Free Agent Co-authored-by: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com> * Softer blue --------- Co-authored-by: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com> * :trollface: * :trollface: * :trollface: * pro --------- Co-authored-by: Winkarst <74284083+Winkarst-cpu@users.noreply.github.com> Co-authored-by: Ilya246 <57039557+Ilya246@users.noreply.github.com> Co-authored-by: PJBot <pieterjan.briers+bot@gmail.com> Co-authored-by: Errant <35878406+Errant-4@users.noreply.github.com> Co-authored-by: godisdeadLOL <169250097+godisdeadLOL@users.noreply.github.com> Co-authored-by: YourUsername <you@example.com> Co-authored-by: lzk <124214523+lzk228@users.noreply.github.com> Co-authored-by: Boaz1111 <149967078+Boaz1111@users.noreply.github.com> Co-authored-by: Mervill <mervills.email@gmail.com> Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Co-authored-by: DrSmugleaf <10968691+DrSmugleaf@users.noreply.github.com> Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Co-authored-by: deltanedas <@deltanedas:kde.org> Co-authored-by: poeMota <142114334+poeMota@users.noreply.github.com> Co-authored-by: Mota <belochuc@gmail.com> Co-authored-by: Moomoobeef <62638182+Moomoobeef@users.noreply.github.com> Co-authored-by: Cojoke <83733158+Cojoke-dot@users.noreply.github.com> Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com> Co-authored-by: themias <89101928+themias@users.noreply.github.com> Co-authored-by: Emisse <99158783+Emisse@users.noreply.github.com> Co-authored-by: Арт <123451459+JustArt1m@users.noreply.github.com> Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> Co-authored-by: IProduceWidgets <107586145+IProduceWidgets@users.noreply.github.com> Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Co-authored-by: Fildrance <fildrance@gmail.com> Co-authored-by: pa.pecherskij <pa.pecherskij@interfax.ru> Co-authored-by: Lye <128915833+Lyroth001@users.noreply.github.com> Co-authored-by: DieselMohawk <gavin.drinka@gmail.com> Co-authored-by: Hreno <hrenor@gmail.com> Co-authored-by: eoineoineoin <github@eoinrul.es> Co-authored-by: Eoin Mcloughlin <helloworld@eoinrul.es> Co-authored-by: qwerltaz <69696513+qwerltaz@users.noreply.github.com> Co-authored-by: Ty Ashley <42426760+TyAshley@users.noreply.github.com> Co-authored-by: Token <esil.bektay@yandex.com> Co-authored-by: Alzore <140123969+Blackern5000@users.noreply.github.com> Co-authored-by: Ubaser <134914314+UbaserB@users.noreply.github.com> Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com> Co-authored-by: Psychpsyo <60073468+Psychpsyo@users.noreply.github.com> Co-authored-by: drakewill-CRL <46307022+drakewill-CRL@users.noreply.github.com> Co-authored-by: PraxisMapper <praxismapper@gmail.com> Co-authored-by: Nim <128169402+Nimfar11@users.noreply.github.com> Co-authored-by: Perry Fraser <perryprog@users.noreply.github.com> Co-authored-by: EmoGarbage404 <retron404@gmail.com> Co-authored-by: Ekkosangen <9094006+Ekkosangen@users.noreply.github.com> Co-authored-by: Ekkosangen <9094006+XyyxShard@users.noreply.github.com> Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com> Co-authored-by: Chubbicous <100180479+Chubbicous@users.noreply.github.com> Co-authored-by: Ps3Moira <113228053+ps3moira@users.noreply.github.com> Co-authored-by: FungiFellow <151778459+FungiFellow@users.noreply.github.com> Co-authored-by: Futuristic-OK <141568243+Futuristic-OK@users.noreply.github.com> Co-authored-by: Ian <ignaz.k@live.de> Co-authored-by: TsjipTsjip <19798667+TsjipTsjip@users.noreply.github.com> Co-authored-by: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com>
757 lines
32 KiB
C#
757 lines
32 KiB
C#
using Content.Server.Administration.Logs;
|
|
using Content.Server.Body.Systems;
|
|
using Content.Server.Construction;
|
|
using Content.Server.Explosion.EntitySystems;
|
|
using Content.Server.DeviceLinking.Events;
|
|
using Content.Server.DeviceLinking.Systems;
|
|
using Content.Server.Hands.Systems;
|
|
using Content.Server.Kitchen.Components;
|
|
using Content.Server.Power.Components;
|
|
using Content.Server.Power.EntitySystems;
|
|
using Content.Server.Temperature.Components;
|
|
using Content.Server.Temperature.Systems;
|
|
using Content.Shared.Body.Components;
|
|
using Content.Shared.Body.Part;
|
|
using Content.Shared.Chemistry.Components.SolutionManager;
|
|
using Content.Shared.Chemistry.EntitySystems;
|
|
using Content.Shared.Construction.EntitySystems;
|
|
using Content.Shared.Database;
|
|
using Content.Shared.Destructible;
|
|
using Content.Shared.FixedPoint;
|
|
using Content.Shared.Interaction;
|
|
using Content.Shared.Interaction.Events;
|
|
using Robust.Shared.Random;
|
|
using Robust.Shared.Audio;
|
|
using Content.Server.Lightning;
|
|
using Content.Shared.Item;
|
|
using Content.Shared.Kitchen;
|
|
using Content.Shared.Kitchen.Components;
|
|
using Content.Shared.Popups;
|
|
using Content.Shared.Power;
|
|
using Content.Shared.Tag;
|
|
using Robust.Server.GameObjects;
|
|
using Robust.Shared.Audio.Systems;
|
|
using Robust.Shared.Containers;
|
|
using Robust.Shared.Player;
|
|
using System.Linq;
|
|
using Robust.Shared.Prototypes;
|
|
using Robust.Shared.Timing;
|
|
using Content.Shared.Stacks;
|
|
using Content.Server.Construction.Components;
|
|
using Content.Shared.Chat;
|
|
using Content.Shared.Damage;
|
|
using Robust.Shared.Utility;
|
|
|
|
namespace Content.Server.Kitchen.EntitySystems
|
|
{
|
|
public sealed class MicrowaveSystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly BodySystem _bodySystem = default!;
|
|
[Dependency] private readonly DeviceLinkSystem _deviceLink = default!;
|
|
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
|
[Dependency] private readonly PowerReceiverSystem _power = default!;
|
|
[Dependency] private readonly RecipeManager _recipeManager = default!;
|
|
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
|
[Dependency] private readonly LightningSystem _lightning = default!;
|
|
[Dependency] private readonly IRobustRandom _random = default!;
|
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
|
[Dependency] private readonly ExplosionSystem _explosion = default!;
|
|
[Dependency] private readonly SharedContainerSystem _container = default!;
|
|
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!;
|
|
[Dependency] private readonly TagSystem _tag = default!;
|
|
[Dependency] private readonly TemperatureSystem _temperature = default!;
|
|
[Dependency] private readonly UserInterfaceSystem _userInterface = default!;
|
|
[Dependency] private readonly HandsSystem _handsSystem = default!;
|
|
[Dependency] private readonly SharedItemSystem _item = default!;
|
|
[Dependency] private readonly SharedStackSystem _stack = default!;
|
|
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
|
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
|
[Dependency] private readonly SharedSuicideSystem _suicide = default!;
|
|
|
|
[ValidatePrototypeId<EntityPrototype>]
|
|
private const string MalfunctionSpark = "Spark";
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<MicrowaveComponent, ComponentInit>(OnInit);
|
|
SubscribeLocalEvent<MicrowaveComponent, MapInitEvent>(OnMapInit);
|
|
SubscribeLocalEvent<MicrowaveComponent, SolutionContainerChangedEvent>(OnSolutionChange);
|
|
SubscribeLocalEvent<MicrowaveComponent, EntInsertedIntoContainerMessage>(OnContentUpdate);
|
|
SubscribeLocalEvent<MicrowaveComponent, EntRemovedFromContainerMessage>(OnContentUpdate);
|
|
SubscribeLocalEvent<MicrowaveComponent, InteractUsingEvent>(OnInteractUsing, after: new[] { typeof(AnchorableSystem) });
|
|
SubscribeLocalEvent<MicrowaveComponent, ContainerIsInsertingAttemptEvent>(OnInsertAttempt);
|
|
SubscribeLocalEvent<MicrowaveComponent, BreakageEventArgs>(OnBreak);
|
|
SubscribeLocalEvent<MicrowaveComponent, PowerChangedEvent>(OnPowerChanged);
|
|
SubscribeLocalEvent<MicrowaveComponent, AnchorStateChangedEvent>(OnAnchorChanged);
|
|
SubscribeLocalEvent<MicrowaveComponent, SuicideByEnvironmentEvent>(OnSuicideByEnvironment);
|
|
|
|
SubscribeLocalEvent<MicrowaveComponent, SignalReceivedEvent>(OnSignalReceived);
|
|
|
|
SubscribeLocalEvent<MicrowaveComponent, MicrowaveStartCookMessage>((u, c, m) => Wzhzhzh(u, c, m.Actor));
|
|
SubscribeLocalEvent<MicrowaveComponent, MicrowaveEjectMessage>(OnEjectMessage);
|
|
SubscribeLocalEvent<MicrowaveComponent, MicrowaveEjectSolidIndexedMessage>(OnEjectIndex);
|
|
SubscribeLocalEvent<MicrowaveComponent, MicrowaveSelectCookTimeMessage>(OnSelectTime);
|
|
|
|
SubscribeLocalEvent<ActiveMicrowaveComponent, ComponentStartup>(OnCookStart);
|
|
SubscribeLocalEvent<ActiveMicrowaveComponent, ComponentShutdown>(OnCookStop);
|
|
SubscribeLocalEvent<ActiveMicrowaveComponent, EntInsertedIntoContainerMessage>(OnActiveMicrowaveInsert);
|
|
SubscribeLocalEvent<ActiveMicrowaveComponent, EntRemovedFromContainerMessage>(OnActiveMicrowaveRemove);
|
|
|
|
SubscribeLocalEvent<ActivelyMicrowavedComponent, OnConstructionTemperatureEvent>(OnConstructionTemp);
|
|
|
|
SubscribeLocalEvent<FoodRecipeProviderComponent, GetSecretRecipesEvent>(OnGetSecretRecipes);
|
|
}
|
|
|
|
private void OnCookStart(Entity<ActiveMicrowaveComponent> ent, ref ComponentStartup args)
|
|
{
|
|
if (!TryComp<MicrowaveComponent>(ent, out var microwaveComponent))
|
|
return;
|
|
SetAppearance(ent.Owner, MicrowaveVisualState.Cooking, microwaveComponent);
|
|
|
|
microwaveComponent.PlayingStream =
|
|
_audio.PlayPvs(microwaveComponent.LoopingSound, ent, AudioParams.Default.WithLoop(true).WithMaxDistance(5)).Value.Entity;
|
|
}
|
|
|
|
private void OnCookStop(Entity<ActiveMicrowaveComponent> ent, ref ComponentShutdown args)
|
|
{
|
|
if (!TryComp<MicrowaveComponent>(ent, out var microwaveComponent))
|
|
return;
|
|
|
|
SetAppearance(ent.Owner, MicrowaveVisualState.Idle, microwaveComponent);
|
|
microwaveComponent.PlayingStream = _audio.Stop(microwaveComponent.PlayingStream);
|
|
}
|
|
|
|
private void OnActiveMicrowaveInsert(Entity<ActiveMicrowaveComponent> ent, ref EntInsertedIntoContainerMessage args)
|
|
{
|
|
AddComp<ActivelyMicrowavedComponent>(args.Entity);
|
|
}
|
|
|
|
private void OnActiveMicrowaveRemove(Entity<ActiveMicrowaveComponent> ent, ref EntRemovedFromContainerMessage args)
|
|
{
|
|
EntityManager.RemoveComponentDeferred<ActivelyMicrowavedComponent>(args.Entity);
|
|
}
|
|
|
|
private void OnConstructionTemp(Entity<ActivelyMicrowavedComponent> ent, ref OnConstructionTemperatureEvent args)
|
|
{
|
|
args.Result = HandleResult.False;
|
|
return;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds temperature to every item in the microwave,
|
|
/// based on the time it took to microwave.
|
|
/// </summary>
|
|
/// <param name="component">The microwave that is heating up.</param>
|
|
/// <param name="time">The time on the microwave, in seconds.</param>
|
|
private void AddTemperature(MicrowaveComponent component, float time)
|
|
{
|
|
var heatToAdd = time * component.BaseHeatMultiplier;
|
|
foreach (var entity in component.Storage.ContainedEntities)
|
|
{
|
|
if (TryComp<TemperatureComponent>(entity, out var tempComp))
|
|
_temperature.ChangeHeat(entity, heatToAdd * component.ObjectHeatMultiplier, false, tempComp);
|
|
|
|
if (!TryComp<SolutionContainerManagerComponent>(entity, out var solutions))
|
|
continue;
|
|
foreach (var (_, soln) in _solutionContainer.EnumerateSolutions((entity, solutions)))
|
|
{
|
|
var solution = soln.Comp.Solution;
|
|
if (solution.Temperature > component.TemperatureUpperThreshold)
|
|
continue;
|
|
|
|
_solutionContainer.AddThermalEnergy(soln, heatToAdd);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void SubtractContents(MicrowaveComponent component, FoodRecipePrototype recipe)
|
|
{
|
|
// TODO Turn recipe.IngredientsReagents into a ReagentQuantity[]
|
|
|
|
var totalReagentsToRemove = new Dictionary<string, FixedPoint2>(recipe.IngredientsReagents);
|
|
|
|
// this is spaghetti ngl
|
|
foreach (var item in component.Storage.ContainedEntities)
|
|
{
|
|
if (!TryComp<SolutionContainerManagerComponent>(item, out var solMan))
|
|
continue;
|
|
|
|
// go over every solution
|
|
foreach (var (_, soln) in _solutionContainer.EnumerateSolutions((item, solMan)))
|
|
{
|
|
var solution = soln.Comp.Solution;
|
|
foreach (var (reagent, _) in recipe.IngredientsReagents)
|
|
{
|
|
// removed everything
|
|
if (!totalReagentsToRemove.ContainsKey(reagent))
|
|
continue;
|
|
|
|
var quant = solution.GetTotalPrototypeQuantity(reagent);
|
|
|
|
if (quant >= totalReagentsToRemove[reagent])
|
|
{
|
|
quant = totalReagentsToRemove[reagent];
|
|
totalReagentsToRemove.Remove(reagent);
|
|
}
|
|
else
|
|
{
|
|
totalReagentsToRemove[reagent] -= quant;
|
|
}
|
|
|
|
_solutionContainer.RemoveReagent(soln, reagent, quant);
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (var recipeSolid in recipe.IngredientsSolids)
|
|
{
|
|
for (var i = 0; i < recipeSolid.Value; i++)
|
|
{
|
|
foreach (var item in component.Storage.ContainedEntities)
|
|
{
|
|
string? itemID = null;
|
|
|
|
// If an entity has a stack component, use the stacktype instead of prototype id
|
|
if (TryComp<StackComponent>(item, out var stackComp))
|
|
{
|
|
itemID = _prototype.Index<StackPrototype>(stackComp.StackTypeId).Spawn;
|
|
}
|
|
else
|
|
{
|
|
var metaData = MetaData(item);
|
|
if (metaData.EntityPrototype == null)
|
|
{
|
|
continue;
|
|
}
|
|
itemID = metaData.EntityPrototype.ID;
|
|
}
|
|
|
|
if (itemID != recipeSolid.Key)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (stackComp is not null)
|
|
{
|
|
if (stackComp.Count == 1)
|
|
{
|
|
_container.Remove(item, component.Storage);
|
|
}
|
|
_stack.Use(item, 1, stackComp);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
_container.Remove(item, component.Storage);
|
|
Del(item);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnInit(Entity<MicrowaveComponent> ent, ref ComponentInit args)
|
|
{
|
|
// this really does have to be in ComponentInit
|
|
ent.Comp.Storage = _container.EnsureContainer<Container>(ent, ent.Comp.ContainerId);
|
|
}
|
|
|
|
private void OnMapInit(Entity<MicrowaveComponent> ent, ref MapInitEvent args)
|
|
{
|
|
_deviceLink.EnsureSinkPorts(ent, ent.Comp.OnPort);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Kills the user by microwaving their head
|
|
/// TODO: Make this not awful, it keeps any items attached to your head still on and you can revive someone and cogni them so you have some dumb headless fuck running around. I've seen it happen.
|
|
/// </summary>
|
|
private void OnSuicideByEnvironment(Entity<MicrowaveComponent> ent, ref SuicideByEnvironmentEvent args)
|
|
{
|
|
if (args.Handled)
|
|
return;
|
|
|
|
// The act of getting your head microwaved doesn't actually kill you
|
|
if (!TryComp<DamageableComponent>(args.Victim, out var damageableComponent))
|
|
return;
|
|
|
|
// The application of lethal damage is what kills you...
|
|
_suicide.ApplyLethalDamage((args.Victim, damageableComponent), "Heat");
|
|
|
|
var victim = args.Victim;
|
|
var headCount = 0;
|
|
|
|
if (TryComp<BodyComponent>(victim, out var body))
|
|
{
|
|
var headSlots = _bodySystem.GetBodyChildrenOfType(victim, BodyPartType.Head, body);
|
|
|
|
foreach (var part in headSlots)
|
|
{
|
|
_container.Insert(part.Id, ent.Comp.Storage);
|
|
headCount++;
|
|
}
|
|
}
|
|
|
|
var othersMessage = headCount > 1
|
|
? Loc.GetString("microwave-component-suicide-multi-head-others-message", ("victim", victim))
|
|
: Loc.GetString("microwave-component-suicide-others-message", ("victim", victim));
|
|
|
|
var selfMessage = headCount > 1
|
|
? Loc.GetString("microwave-component-suicide-multi-head-message")
|
|
: Loc.GetString("microwave-component-suicide-message");
|
|
|
|
_popupSystem.PopupEntity(othersMessage, victim, Filter.PvsExcept(victim), true);
|
|
_popupSystem.PopupEntity(selfMessage, victim, victim);
|
|
|
|
_audio.PlayPvs(ent.Comp.ClickSound, ent.Owner, AudioParams.Default.WithVolume(-2));
|
|
ent.Comp.CurrentCookTimerTime = 10;
|
|
Wzhzhzh(ent.Owner, ent.Comp, args.Victim);
|
|
UpdateUserInterfaceState(ent.Owner, ent.Comp);
|
|
args.Handled = true;
|
|
}
|
|
|
|
private void OnSolutionChange(Entity<MicrowaveComponent> ent, ref SolutionContainerChangedEvent args)
|
|
{
|
|
UpdateUserInterfaceState(ent, ent.Comp);
|
|
}
|
|
|
|
private void OnContentUpdate(EntityUid uid, MicrowaveComponent component, ContainerModifiedMessage args) // For some reason ContainerModifiedMessage just can't be used at all with Entity<T>. TODO: replace with Entity<T> syntax once that's possible
|
|
{
|
|
if (component.Storage != args.Container)
|
|
return;
|
|
|
|
UpdateUserInterfaceState(uid, component);
|
|
}
|
|
|
|
private void OnInsertAttempt(Entity<MicrowaveComponent> ent, ref ContainerIsInsertingAttemptEvent args)
|
|
{
|
|
if (args.Container.ID != ent.Comp.ContainerId)
|
|
return;
|
|
|
|
if (ent.Comp.Broken)
|
|
{
|
|
args.Cancel();
|
|
return;
|
|
}
|
|
|
|
if (TryComp<ItemComponent>(args.EntityUid, out var item))
|
|
{
|
|
if (_item.GetSizePrototype(item.Size) > _item.GetSizePrototype(ent.Comp.MaxItemSize))
|
|
{
|
|
args.Cancel();
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
args.Cancel();
|
|
return;
|
|
}
|
|
|
|
if (ent.Comp.Storage.Count >= ent.Comp.Capacity)
|
|
args.Cancel();
|
|
}
|
|
|
|
private void OnInteractUsing(Entity<MicrowaveComponent> ent, ref InteractUsingEvent args)
|
|
{
|
|
if (args.Handled)
|
|
return;
|
|
if (!(TryComp<ApcPowerReceiverComponent>(ent, out var apc) && apc.Powered))
|
|
{
|
|
_popupSystem.PopupEntity(Loc.GetString("microwave-component-interact-using-no-power"), ent, args.User);
|
|
return;
|
|
}
|
|
|
|
if (ent.Comp.Broken)
|
|
{
|
|
_popupSystem.PopupEntity(Loc.GetString("microwave-component-interact-using-broken"), ent, args.User);
|
|
return;
|
|
}
|
|
|
|
if (TryComp<ItemComponent>(args.Used, out var item))
|
|
{
|
|
// check if size of an item you're trying to put in is too big
|
|
if (_item.GetSizePrototype(item.Size) > _item.GetSizePrototype(ent.Comp.MaxItemSize))
|
|
{
|
|
_popupSystem.PopupEntity(Loc.GetString("microwave-component-interact-item-too-big", ("item", args.Used)), ent, args.User);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// check if thing you're trying to put in isn't an item
|
|
_popupSystem.PopupEntity(Loc.GetString("microwave-component-interact-using-transfer-fail"), ent, args.User);
|
|
return;
|
|
}
|
|
|
|
if (ent.Comp.Storage.Count >= ent.Comp.Capacity)
|
|
{
|
|
_popupSystem.PopupEntity(Loc.GetString("microwave-component-interact-full"), ent, args.User);
|
|
return;
|
|
}
|
|
|
|
args.Handled = true;
|
|
_handsSystem.TryDropIntoContainer(args.User, args.Used, ent.Comp.Storage);
|
|
UpdateUserInterfaceState(ent, ent.Comp);
|
|
}
|
|
|
|
private void OnBreak(Entity<MicrowaveComponent> ent, ref BreakageEventArgs args)
|
|
{
|
|
ent.Comp.Broken = true;
|
|
SetAppearance(ent, MicrowaveVisualState.Broken, ent.Comp);
|
|
StopCooking(ent);
|
|
_container.EmptyContainer(ent.Comp.Storage);
|
|
UpdateUserInterfaceState(ent, ent.Comp);
|
|
}
|
|
|
|
private void OnPowerChanged(Entity<MicrowaveComponent> ent, ref PowerChangedEvent args)
|
|
{
|
|
if (!args.Powered)
|
|
{
|
|
SetAppearance(ent, MicrowaveVisualState.Idle, ent.Comp);
|
|
StopCooking(ent);
|
|
}
|
|
UpdateUserInterfaceState(ent, ent.Comp);
|
|
}
|
|
|
|
private void OnAnchorChanged(EntityUid uid, MicrowaveComponent component, ref AnchorStateChangedEvent args)
|
|
{
|
|
if (!args.Anchored)
|
|
_container.EmptyContainer(component.Storage);
|
|
}
|
|
|
|
private void OnSignalReceived(Entity<MicrowaveComponent> ent, ref SignalReceivedEvent args)
|
|
{
|
|
if (args.Port != ent.Comp.OnPort)
|
|
return;
|
|
|
|
if (ent.Comp.Broken || !_power.IsPowered(ent))
|
|
return;
|
|
|
|
Wzhzhzh(ent.Owner, ent.Comp, null);
|
|
}
|
|
|
|
public void UpdateUserInterfaceState(EntityUid uid, MicrowaveComponent component)
|
|
{
|
|
_userInterface.SetUiState(uid, MicrowaveUiKey.Key, new MicrowaveUpdateUserInterfaceState(
|
|
GetNetEntityArray(component.Storage.ContainedEntities.ToArray()),
|
|
HasComp<ActiveMicrowaveComponent>(uid),
|
|
component.CurrentCookTimeButtonIndex,
|
|
component.CurrentCookTimerTime,
|
|
component.CurrentCookTimeEnd
|
|
));
|
|
}
|
|
|
|
public void SetAppearance(EntityUid uid, MicrowaveVisualState state, MicrowaveComponent? component = null, AppearanceComponent? appearanceComponent = null)
|
|
{
|
|
if (!Resolve(uid, ref component, ref appearanceComponent, false))
|
|
return;
|
|
var display = component.Broken ? MicrowaveVisualState.Broken : state;
|
|
_appearance.SetData(uid, PowerDeviceVisuals.VisualState, display, appearanceComponent);
|
|
}
|
|
|
|
public static bool HasContents(MicrowaveComponent component)
|
|
{
|
|
return component.Storage.ContainedEntities.Any();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Explodes the microwave internally, turning it into a broken state, destroying its board, and spitting out its machine parts
|
|
/// </summary>
|
|
/// <param name="ent"></param>
|
|
public void Explode(Entity<MicrowaveComponent> ent)
|
|
{
|
|
ent.Comp.Broken = true; // Make broken so we stop processing stuff
|
|
_explosion.TriggerExplosive(ent);
|
|
if (TryComp<MachineComponent>(ent, out var machine))
|
|
{
|
|
_container.CleanContainer(machine.BoardContainer);
|
|
_container.EmptyContainer(machine.PartContainer);
|
|
}
|
|
|
|
_adminLogger.Add(LogType.Action, LogImpact.Medium,
|
|
$"{ToPrettyString(ent)} exploded from unsafe cooking!");
|
|
}
|
|
/// <summary>
|
|
/// Handles the attempted cooking of unsafe objects
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Returns false if the microwave didn't explode, true if it exploded.
|
|
/// </remarks>
|
|
private void RollMalfunction(Entity<ActiveMicrowaveComponent, MicrowaveComponent> ent)
|
|
{
|
|
if (ent.Comp1.MalfunctionTime == TimeSpan.Zero)
|
|
return;
|
|
|
|
if (ent.Comp1.MalfunctionTime > _gameTiming.CurTime)
|
|
return;
|
|
|
|
ent.Comp1.MalfunctionTime = _gameTiming.CurTime + TimeSpan.FromSeconds(ent.Comp2.MalfunctionInterval);
|
|
if (_random.Prob(ent.Comp2.ExplosionChance))
|
|
{
|
|
Explode((ent, ent.Comp2));
|
|
return; // microwave is fucked, stop the cooking.
|
|
}
|
|
|
|
if (_random.Prob(ent.Comp2.LightningChance))
|
|
_lightning.ShootRandomLightnings(ent, 1.0f, 2, MalfunctionSpark, triggerLightningEvents: false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Starts Cooking
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// It does not make a "wzhzhzh" sound, it makes a "mmmmmmmm" sound!
|
|
/// -emo
|
|
/// </remarks>
|
|
public void Wzhzhzh(EntityUid uid, MicrowaveComponent component, EntityUid? user)
|
|
{
|
|
if (!HasContents(component) || HasComp<ActiveMicrowaveComponent>(uid) || !(TryComp<ApcPowerReceiverComponent>(uid, out var apc) && apc.Powered))
|
|
return;
|
|
|
|
var solidsDict = new Dictionary<string, int>();
|
|
var reagentDict = new Dictionary<string, FixedPoint2>();
|
|
var malfunctioning = false;
|
|
// TODO use lists of Reagent quantities instead of reagent prototype ids.
|
|
foreach (var item in component.Storage.ContainedEntities.ToArray())
|
|
{
|
|
// special behavior when being microwaved ;)
|
|
var ev = new BeingMicrowavedEvent(uid, user);
|
|
RaiseLocalEvent(item, ev);
|
|
|
|
if (ev.Handled)
|
|
{
|
|
UpdateUserInterfaceState(uid, component);
|
|
return;
|
|
}
|
|
|
|
if (_tag.HasTag(item, "Metal"))
|
|
{
|
|
malfunctioning = true;
|
|
}
|
|
|
|
if (_tag.HasTag(item, "Plastic"))
|
|
{
|
|
var junk = Spawn(component.BadRecipeEntityId, Transform(uid).Coordinates);
|
|
_container.Insert(junk, component.Storage);
|
|
Del(item);
|
|
continue;
|
|
}
|
|
|
|
AddComp<ActivelyMicrowavedComponent>(item);
|
|
|
|
string? solidID = null;
|
|
int amountToAdd = 1;
|
|
|
|
// If a microwave recipe uses a stacked item, use the default stack prototype id instead of prototype id
|
|
if (TryComp<StackComponent>(item, out var stackComp))
|
|
{
|
|
solidID = _prototype.Index<StackPrototype>(stackComp.StackTypeId).Spawn;
|
|
amountToAdd = stackComp.Count;
|
|
}
|
|
else
|
|
{
|
|
var metaData = MetaData(item); //this simply begs for cooking refactor
|
|
if (metaData.EntityPrototype is not null)
|
|
solidID = metaData.EntityPrototype.ID;
|
|
}
|
|
|
|
if (solidID is null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
|
|
if (solidsDict.ContainsKey(solidID))
|
|
{
|
|
solidsDict[solidID] += amountToAdd;
|
|
}
|
|
else
|
|
{
|
|
solidsDict.Add(solidID, amountToAdd);
|
|
}
|
|
|
|
if (!TryComp<SolutionContainerManagerComponent>(item, out var solMan))
|
|
continue;
|
|
|
|
foreach (var (_, soln) in _solutionContainer.EnumerateSolutions((item, solMan)))
|
|
{
|
|
var solution = soln.Comp.Solution;
|
|
foreach (var (reagent, quantity) in solution.Contents)
|
|
{
|
|
if (reagentDict.ContainsKey(reagent.Prototype))
|
|
reagentDict[reagent.Prototype] += quantity;
|
|
else
|
|
reagentDict.Add(reagent.Prototype, quantity);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check recipes
|
|
var getRecipesEv = new GetSecretRecipesEvent();
|
|
RaiseLocalEvent(uid, ref getRecipesEv);
|
|
|
|
List<FoodRecipePrototype> recipes = getRecipesEv.Recipes;
|
|
recipes.AddRange(_recipeManager.Recipes);
|
|
var portionedRecipe = recipes.Select(r =>
|
|
CanSatisfyRecipe(component, r, solidsDict, reagentDict)).FirstOrDefault(r => r.Item2 > 0);
|
|
|
|
_audio.PlayPvs(component.StartCookingSound, uid);
|
|
var activeComp = AddComp<ActiveMicrowaveComponent>(uid); //microwave is now cooking
|
|
activeComp.CookTimeRemaining = component.CurrentCookTimerTime * component.CookTimeMultiplier;
|
|
activeComp.TotalTime = component.CurrentCookTimerTime; //this doesn't scale so that we can have the "actual" time
|
|
activeComp.PortionedRecipe = portionedRecipe;
|
|
//Scale tiems with cook times
|
|
component.CurrentCookTimeEnd = _gameTiming.CurTime + TimeSpan.FromSeconds(component.CurrentCookTimerTime * component.CookTimeMultiplier);
|
|
if (malfunctioning)
|
|
activeComp.MalfunctionTime = _gameTiming.CurTime + TimeSpan.FromSeconds(component.MalfunctionInterval);
|
|
UpdateUserInterfaceState(uid, component);
|
|
}
|
|
|
|
private void StopCooking(Entity<MicrowaveComponent> ent)
|
|
{
|
|
RemCompDeferred<ActiveMicrowaveComponent>(ent);
|
|
foreach (var solid in ent.Comp.Storage.ContainedEntities)
|
|
{
|
|
RemCompDeferred<ActivelyMicrowavedComponent>(solid);
|
|
}
|
|
}
|
|
|
|
public static (FoodRecipePrototype, int) CanSatisfyRecipe(MicrowaveComponent component, FoodRecipePrototype recipe, Dictionary<string, int> solids, Dictionary<string, FixedPoint2> reagents)
|
|
{
|
|
var portions = 0;
|
|
|
|
if (component.CurrentCookTimerTime % recipe.CookTime != 0)
|
|
{
|
|
//can't be a multiple of this recipe
|
|
return (recipe, 0);
|
|
}
|
|
|
|
foreach (var solid in recipe.IngredientsSolids)
|
|
{
|
|
if (!solids.ContainsKey(solid.Key))
|
|
return (recipe, 0);
|
|
|
|
if (solids[solid.Key] < solid.Value)
|
|
return (recipe, 0);
|
|
|
|
portions = portions == 0
|
|
? solids[solid.Key] / solid.Value.Int()
|
|
: Math.Min(portions, solids[solid.Key] / solid.Value.Int());
|
|
}
|
|
|
|
foreach (var reagent in recipe.IngredientsReagents)
|
|
{
|
|
// TODO Turn recipe.IngredientsReagents into a ReagentQuantity[]
|
|
if (!reagents.ContainsKey(reagent.Key))
|
|
return (recipe, 0);
|
|
|
|
if (reagents[reagent.Key] < reagent.Value)
|
|
return (recipe, 0);
|
|
|
|
portions = portions == 0
|
|
? reagents[reagent.Key].Int() / reagent.Value.Int()
|
|
: Math.Min(portions, reagents[reagent.Key].Int() / reagent.Value.Int());
|
|
}
|
|
|
|
//cook only as many of those portions as time allows
|
|
return (recipe, (int) Math.Min(portions, component.CurrentCookTimerTime / recipe.CookTime));
|
|
}
|
|
|
|
public override void Update(float frameTime)
|
|
{
|
|
base.Update(frameTime);
|
|
|
|
var query = EntityQueryEnumerator<ActiveMicrowaveComponent, MicrowaveComponent>();
|
|
while (query.MoveNext(out var uid, out var active, out var microwave))
|
|
{
|
|
|
|
active.CookTimeRemaining -= frameTime;
|
|
|
|
RollMalfunction((uid, active, microwave));
|
|
|
|
//check if there's still cook time left
|
|
if (active.CookTimeRemaining > 0)
|
|
{
|
|
AddTemperature(microwave, frameTime);
|
|
continue;
|
|
}
|
|
|
|
//this means the microwave has finished cooking.
|
|
AddTemperature(microwave, Math.Max(frameTime + active.CookTimeRemaining, 0)); //Though there's still a little bit more heat to pump out
|
|
|
|
if (active.PortionedRecipe.Item1 != null)
|
|
{
|
|
var coords = Transform(uid).Coordinates;
|
|
for (var i = 0; i < active.PortionedRecipe.Item2; i++)
|
|
{
|
|
SubtractContents(microwave, active.PortionedRecipe.Item1);
|
|
Spawn(active.PortionedRecipe.Item1.Result, coords);
|
|
}
|
|
}
|
|
|
|
_container.EmptyContainer(microwave.Storage);
|
|
microwave.CurrentCookTimeEnd = TimeSpan.Zero;
|
|
UpdateUserInterfaceState(uid, microwave);
|
|
_audio.PlayPvs(microwave.FoodDoneSound, uid);
|
|
StopCooking((uid, microwave));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// This event tries to get secret recipes that the microwave might be capable of.
|
|
/// Currently, we only check the microwave itself, but in the future, the user might be able to learn recipes.
|
|
/// </summary>
|
|
private void OnGetSecretRecipes(Entity<FoodRecipeProviderComponent> ent, ref GetSecretRecipesEvent args)
|
|
{
|
|
foreach (ProtoId<FoodRecipePrototype> recipeId in ent.Comp.ProvidedRecipes)
|
|
{
|
|
if (_prototype.TryIndex(recipeId, out var recipeProto))
|
|
{
|
|
args.Recipes.Add(recipeProto);
|
|
}
|
|
}
|
|
}
|
|
|
|
#region ui
|
|
private void OnEjectMessage(Entity<MicrowaveComponent> ent, ref MicrowaveEjectMessage args)
|
|
{
|
|
if (!HasContents(ent.Comp) || HasComp<ActiveMicrowaveComponent>(ent))
|
|
return;
|
|
|
|
_container.EmptyContainer(ent.Comp.Storage);
|
|
_audio.PlayPvs(ent.Comp.ClickSound, ent, AudioParams.Default.WithVolume(-2));
|
|
UpdateUserInterfaceState(ent, ent.Comp);
|
|
}
|
|
|
|
private void OnEjectIndex(Entity<MicrowaveComponent> ent, ref MicrowaveEjectSolidIndexedMessage args)
|
|
{
|
|
if (!HasContents(ent.Comp) || HasComp<ActiveMicrowaveComponent>(ent))
|
|
return;
|
|
|
|
_container.Remove(EntityManager.GetEntity(args.EntityID), ent.Comp.Storage);
|
|
UpdateUserInterfaceState(ent, ent.Comp);
|
|
}
|
|
|
|
private void OnSelectTime(Entity<MicrowaveComponent> ent, ref MicrowaveSelectCookTimeMessage args)
|
|
{
|
|
if (!HasContents(ent.Comp) || HasComp<ActiveMicrowaveComponent>(ent) || !(TryComp<ApcPowerReceiverComponent>(ent, out var apc) && apc.Powered))
|
|
return;
|
|
|
|
// some validation to prevent trollage
|
|
if (args.NewCookTime % 5 != 0 || args.NewCookTime > ent.Comp.MaxCookTime)
|
|
return;
|
|
|
|
ent.Comp.CurrentCookTimeButtonIndex = args.ButtonIndex;
|
|
ent.Comp.CurrentCookTimerTime = args.NewCookTime;
|
|
ent.Comp.CurrentCookTimeEnd = TimeSpan.Zero;
|
|
_audio.PlayPvs(ent.Comp.ClickSound, ent, AudioParams.Default.WithVolume(-2));
|
|
UpdateUserInterfaceState(ent, ent.Comp);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|