diff --git a/Content.Server/SS220/Photocopier/PhotocopierSystem.Copying.cs b/Content.Server/SS220/Photocopier/PhotocopierSystem.Copying.cs index 4833faf870f8b9..17ea6964009faf 100644 --- a/Content.Server/SS220/Photocopier/PhotocopierSystem.Copying.cs +++ b/Content.Server/SS220/Photocopier/PhotocopierSystem.Copying.cs @@ -154,20 +154,20 @@ public void FormToDataToCopy( } /// - /// Spawns a copy of paper using data cached in PhotocopierComponent.DataToCopy and PhotocopierComponent.MetaDataToCopy. + /// Spawns a copy of paper using data cached in /// - private void SpawnCopyFromPhotocopier(EntityUid uid, PhotocopierComponent? component = null) + private void SpawnCopyFromPhotocopier(EntityUid uid, int documentIndex, PhotocopierComponent? component = null) { if (!Resolve(uid, ref component)) return; - var printout = component.DataToCopy; - if (printout is null) + if (documentIndex < 0 || documentIndex >= component.DocumentsToCopy.Count) { - _sawmill.Error("Entity " + uid + " tried to spawn a copy of paper, but DataToCopy was null."); + _sawmill.Error($"Entity {uid} tried to spawn a copy of paper, but document index {documentIndex} is out of range, total documents: {component.DocumentsToCopy.Count}."); return; } + var document = component.DocumentsToCopy[documentIndex]; - SpawnCopy(Transform(uid).Coordinates, component.MetaDataToCopy, printout); + SpawnCopy(Transform(uid).Coordinates, document.MetaData, document.Data); } } diff --git a/Content.Server/SS220/Photocopier/PhotocopierSystem.cs b/Content.Server/SS220/Photocopier/PhotocopierSystem.cs index 971bf5eacc1005..5fb1edf03684c8 100644 --- a/Content.Server/SS220/Photocopier/PhotocopierSystem.cs +++ b/Content.Server/SS220/Photocopier/PhotocopierSystem.cs @@ -37,6 +37,7 @@ public sealed partial class PhotocopierSystem : EntitySystem [Dependency] private readonly ChatSystem _chat = default!; [Dependency] private readonly EntityManager _entityManager = default!; [Dependency] private readonly MetaDataSystem _metaData = default!; + [Dependency] private readonly SharedContainerSystem _containerSystem = default!; private FormManager? _specificFormManager; private readonly ISawmill _sawmill = Logger.GetSawmill("photocopier"); @@ -233,7 +234,8 @@ private void OnPrintButtonPressed(EntityUid uid, PhotocopierComponent component, return; FormToDataToCopy(formToCopy, out var dataToCopy, out var metaDataToCopy); - StartPrinting(uid, component, metaDataToCopy, dataToCopy, PhotocopierState.Copying, args.Amount); + QueueDocument(component, new(dataToCopy, metaDataToCopy)); + StartPrinting(uid, component, PhotocopierState.Copying, args.Amount); } private void OnStopButtonPressed(EntityUid uid, PhotocopierComponent component, PhotocopierStopMessage args) @@ -347,7 +349,8 @@ private void TryQueueCopyPhysicalButt( var buttScanData = new ButtScanPhotocopiedData() { ButtTexturePath = speciesPrototype.ButtScanTexture }; dataToCopy.Add(typeof(ButtScanComponent), buttScanData); - if (StartPrinting(uid, component, metaDataToCopy, dataToCopy, PhotocopierState.Copying, amount)) + QueueDocument(component, new(dataToCopy, metaDataToCopy)); + if (StartPrinting(uid, component, PhotocopierState.Copying, amount)) { component.IsCopyingPhysicalButt = true; component.ButtSpecies = humanoidAppearance.Species; @@ -362,15 +365,38 @@ private bool TryQueueCopySlot(EntityUid uid, PhotocopierComponent component, int if (component.PaperSlot.Item is not { } copyEntity) return false; - if (!TryGetPhotocopyableMetaData(copyEntity, out var metaData)) + if ((!TryComp(copyEntity, out var containerManager) || + !TryQueueCopyContainer(component, containerManager, copyEntity)) && + !TryQueueSingleDocumentEntity(component, copyEntity)) + { return false; + } + + StartPrinting(uid, component, PhotocopierState.Copying, amount); + return true; + } + + private bool TryQueueCopyContainer(PhotocopierComponent photocopier, ContainerManagerComponent containerManager, EntityUid copyEntity) + { + var isAny = false; + foreach (var container in _containerSystem.GetAllContainers(copyEntity, containerManager)) + { + foreach (var entity in container.ContainedEntities) + { + isAny |= TryQueueSingleDocumentEntity(photocopier, entity); + } + } + return isAny; + } + private bool TryQueueSingleDocumentEntity(PhotocopierComponent photocopier, EntityUid copyEntity) + { + if (!TryGetPhotocopyableMetaData(copyEntity, out var metaData)) + return false; var dataToCopy = GetDataToCopyFromEntity(copyEntity); if (dataToCopy.Count == 0) return false; - - StartPrinting(uid, component, metaData, dataToCopy, PhotocopierState.Copying, amount); - + QueueDocument(photocopier, new(dataToCopy, metaData)); return true; } @@ -390,19 +416,22 @@ private void StopPrinting(EntityUid uid, PhotocopierComponent component, bool up } } + private void QueueDocument(PhotocopierComponent component, PrintableDocumentData document) + { + component.DocumentsToCopy.Add(document); + } + private bool StartPrinting( EntityUid uid, PhotocopierComponent component, - PhotocopyableMetaData? metaData, - Dictionary? dataToCopy, PhotocopierState state, int amount) { if (amount <= 0) return false; + if (component.DocumentsToCopy.Count == 0) + return false; - component.DataToCopy = dataToCopy; - component.MetaDataToCopy = metaData; component.State = state; component.CopiesQueued = Math.Clamp(amount, 0, component.MaxQueueLength); @@ -419,8 +448,9 @@ private void ResetState(EntityUid uid, PhotocopierComponent component) { component.CopiesQueued = 0; component.PrintingTimeRemaining = 0; - component.DataToCopy = null; - component.MetaDataToCopy = null; + component.CurrentDocumentIndex = 0; + component.CurrentDocumentCopyIndex = 0; + component.DocumentsToCopy.Clear(); component.ButtSpecies = null; component.State = PhotocopierState.Idle; component.IsCopyingPhysicalButt = false; @@ -466,13 +496,18 @@ private void ProcessPrinting(EntityUid uid, float frameTime, PhotocopierComponen if (!isPrinted) return; - SpawnCopyFromPhotocopier(uid, component); + SpawnCopyFromPhotocopier(uid, component.CurrentDocumentIndex, component); tonerCartridge.Charges--; - component.CopiesQueued--; + component.CurrentDocumentCopyIndex++; - if (component.CopiesQueued <= 0) - ResetState(uid, component); //Reset the rest of the fields + if (component.CurrentDocumentCopyIndex >= component.CopiesQueued) + { + component.CurrentDocumentIndex++; + component.CurrentDocumentCopyIndex = 0; + if (component.CurrentDocumentIndex >= component.DocumentsToCopy.Count) + ResetState(uid, component); //Reset the rest of the fields + } UpdateUserInterface(uid, component); TryUpdateVisualState(uid, component); @@ -558,10 +593,13 @@ private void UpdateUserInterface(EntityUid uid, PhotocopierComponent? component var isPaperInserted = component.PaperSlot.Item is not null; var assIsOnScanner = IsHumanoidOnTop(component); + var totalCount = component.CopiesQueued * component.DocumentsToCopy.Count; + var printedCount = component.CurrentDocumentIndex * component.CopiesQueued + component.CurrentDocumentCopyIndex; + var remainingCount = totalCount - printedCount; var state = new PhotocopierUiState( component.PaperSlot.Locked, isPaperInserted, - component.CopiesQueued, + remainingCount, component.FormCollections, tonerAvailable, tonerCapacity, diff --git a/Content.Shared/SS220/Photocopier/PhotocopierComponent.cs b/Content.Shared/SS220/Photocopier/PhotocopierComponent.cs index 0134ae703d2bf8..ceaef9bfef6e1c 100644 --- a/Content.Shared/SS220/Photocopier/PhotocopierComponent.cs +++ b/Content.Shared/SS220/Photocopier/PhotocopierComponent.cs @@ -72,7 +72,7 @@ public sealed partial class PhotocopierComponent : Component }; /// - /// Contains an item to be copied, assumes it's paper + /// Contains an item to be copied, assumes it's paper or container of papers /// [DataField("paperSlot", required: true)] public ItemSlot PaperSlot = new(); @@ -143,17 +143,10 @@ public int MaxQueueLength public bool SusFormsUnlocked = false; /// - /// Contains fields of components that will be copied. - /// Is applied to a new entity that is created as a result of photocopying. + /// Currently queued documents to be copied. /// [ViewVariables] - public Dictionary? DataToCopy; - - /// - /// Contains metadata that will be copied. - /// Is applied to a new entity that is created as a result of photocopying. - /// - public PhotocopyableMetaData? MetaDataToCopy; + public List DocumentsToCopy = new(); /// /// An audio stream of printing sound. @@ -175,11 +168,17 @@ public int MaxQueueLength public float PrintingTimeRemaining; /// - /// Remaining amount of copies to print + /// Total amount of copies to print /// [ViewVariables(VVAccess.ReadOnly)] public int CopiesQueued; + [ViewVariables(VVAccess.ReadOnly)] + public int CurrentDocumentIndex; + + [ViewVariables(VVAccess.ReadOnly)] + public int CurrentDocumentCopyIndex; + [ViewVariables(VVAccess.ReadOnly)] public bool IsCopyingPhysicalButt; @@ -187,3 +186,19 @@ public int MaxQueueLength public float? ManualButtBurnAnimationRemainingTime; } +public struct PrintableDocumentData(Dictionary data, PhotocopyableMetaData metaData) +{ + /// + /// Contains fields of components that will be copied. + /// Is applied to a new entity that is created as a result of photocopying. + /// + [ViewVariables] + public Dictionary Data = data; + + /// + /// Contains metadata that will be copied. + /// Is applied to a new entity that is created as a result of photocopying. + /// + public PhotocopyableMetaData MetaData = metaData; +} + diff --git a/Resources/Prototypes/SS220/Entities/Structures/Machines/photocopier.yml b/Resources/Prototypes/SS220/Entities/Structures/Machines/photocopier.yml index 050eb89cad9ffc..1a7b19cb926c6a 100644 --- a/Resources/Prototypes/SS220/Entities/Structures/Machines/photocopier.yml +++ b/Resources/Prototypes/SS220/Entities/Structures/Machines/photocopier.yml @@ -47,6 +47,8 @@ - FaxableObject - Paper - ButtScan + tags: + - Folder tonerSlot: insertSound: /Audio/Machines/screwdriveropen.ogg ejectSound: /Audio/Machines/screwdriverclose.ogg