From 2d34ded94dfc822242ae82b8a78b6b180949ccaa Mon Sep 17 00:00:00 2001 From: Alex Evgrashin Date: Fri, 29 Apr 2022 01:03:39 +0300 Subject: [PATCH] Artifact container (#7822) Co-authored-by: Kara --- Content.Client/Entry/IgnoredComponents.cs | 2 + .../Components/ArtifactStorageComponent.cs | 14 +++ .../Components/EntityStorageComponent.cs | 85 +++++++++--------- .../XenoArtifacts/ArtifactComponent.cs | 7 ++ .../XenoArtifacts/ArtifactSystem.cs | 4 + .../SuppressArtifactContainerComponent.cs | 10 +++ .../SuppressArtifactContainerSystem.cs | 30 +++++++ .../Catalog/Cargo/cargo_science.yml | 11 +++ .../Entities/Mobs/Player/admin_ghost.yml | 1 + .../Xenoarchaeology/artifact_equipment.yml | 70 +++++++++++++++ .../Specific/Xenoarchaeology/artifacts.yml | 1 + .../Machines/Computers/computers.yml | 1 + .../artifact.rsi/artifact_container.png | Bin 0 -> 494 bytes .../artifact.rsi/artifact_container_door.png | Bin 0 -> 393 bytes .../artifact.rsi/artifact_container_icon.png | Bin 0 -> 575 bytes .../artifact.rsi/artifact_container_open.png | Bin 0 -> 404 bytes .../Storage/Crates/artifact.rsi/locked.png | Bin 0 -> 198 bytes .../Storage/Crates/artifact.rsi/meta.json | 32 +++++++ .../Storage/Crates/artifact.rsi/unlocked.png | Bin 0 -> 203 bytes .../Storage/Crates/artifact.rsi/welded.png | Bin 0 -> 375 bytes 20 files changed, 226 insertions(+), 42 deletions(-) create mode 100644 Content.Server/Storage/Components/ArtifactStorageComponent.cs create mode 100644 Content.Server/Xenoarchaeology/XenoArtifacts/Equipment/Components/SuppressArtifactContainerComponent.cs create mode 100644 Content.Server/Xenoarchaeology/XenoArtifacts/Equipment/Systems/SuppressArtifactContainerSystem.cs create mode 100644 Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifact_equipment.yml create mode 100644 Resources/Textures/Structures/Storage/Crates/artifact.rsi/artifact_container.png create mode 100644 Resources/Textures/Structures/Storage/Crates/artifact.rsi/artifact_container_door.png create mode 100644 Resources/Textures/Structures/Storage/Crates/artifact.rsi/artifact_container_icon.png create mode 100644 Resources/Textures/Structures/Storage/Crates/artifact.rsi/artifact_container_open.png create mode 100644 Resources/Textures/Structures/Storage/Crates/artifact.rsi/locked.png create mode 100644 Resources/Textures/Structures/Storage/Crates/artifact.rsi/meta.json create mode 100644 Resources/Textures/Structures/Storage/Crates/artifact.rsi/unlocked.png create mode 100644 Resources/Textures/Structures/Storage/Crates/artifact.rsi/welded.png diff --git a/Content.Client/Entry/IgnoredComponents.cs b/Content.Client/Entry/IgnoredComponents.cs index a4ce1012a2..a9a5a765b8 100644 --- a/Content.Client/Entry/IgnoredComponents.cs +++ b/Content.Client/Entry/IgnoredComponents.cs @@ -145,6 +145,7 @@ namespace Content.Client.Entry "VentCritterSpawnLocation", "RadiateArtifact", "TemperatureArtifact", + "SuppressArtifactContainer", "DisposalHolder", "DisposalTagger", "DisposalRouter", @@ -290,6 +291,7 @@ namespace Content.Client.Entry "AmbientOnPowered", "DoorSignalControl", "Wieldable", + "ArtifactStorage", "IncreaseDamageOnWield", "TabletopGame", "LitOnPowered", diff --git a/Content.Server/Storage/Components/ArtifactStorageComponent.cs b/Content.Server/Storage/Components/ArtifactStorageComponent.cs new file mode 100644 index 0000000000..13684aee68 --- /dev/null +++ b/Content.Server/Storage/Components/ArtifactStorageComponent.cs @@ -0,0 +1,14 @@ +using Content.Server.Xenoarchaeology.XenoArtifacts; + +namespace Content.Server.Storage.Components; + +[RegisterComponent] +public sealed class ArtifactStorageComponent : EntityStorageComponent +{ + [Dependency] private readonly IEntityManager _entMan = default!; + + public override bool CanFit(EntityUid entity) + { + return _entMan.HasComponent(entity); + } +} diff --git a/Content.Server/Storage/Components/EntityStorageComponent.cs b/Content.Server/Storage/Components/EntityStorageComponent.cs index 6d223e97e5..626935df9c 100644 --- a/Content.Server/Storage/Components/EntityStorageComponent.cs +++ b/Content.Server/Storage/Components/EntityStorageComponent.cs @@ -232,51 +232,10 @@ namespace Content.Server.Storage.Components if (entity.IsInContainer()) continue; - // conditions are complicated because of pizzabox-related issues, so follow this guide - // 0. Accomplish your goals at all costs. - // 1. AddToContents can block anything - // 2. maximum item count can block anything - // 3. ghosts can NEVER be eaten - // 4. items can always be eaten unless a previous law prevents it - // 5. if this is NOT AN ITEM, then mobs can always be eaten unless unless a previous law prevents it - // 6. if this is an item, then mobs must only be eaten if some other component prevents pick-up interactions while a mob is inside (e.g. foldable) - - // Let's not insert admin ghosts, yeah? This is really a a hack and should be replaced by attempt events - if (_entMan.HasComponent(entity)) - continue; - - // checks - - var targetIsItem = _entMan.HasComponent(entity); - var targetIsMob = _entMan.HasComponent(entity); - var storageIsItem = _entMan.HasComponent(Owner); - - var allowedToEat = false; - - if (targetIsItem) - allowedToEat = true; - - // BEFORE REPLACING THIS WITH, I.E. A PROPERTY: - // Make absolutely 100% sure you have worked out how to stop people ending up in backpacks. - // Seriously, it is insanely hacky and weird to get someone out of a backpack once they end up in there. - // And to be clear, they should NOT be in there. - // For the record, what you need to do is empty the backpack onto a PlacableSurface (table, rack) - if (targetIsMob) - { - if (!storageIsItem) - allowedToEat = true; - else - { - // make an exception if this is a foldable-item that is currently un-folded (e.g., body bags). - allowedToEat = _entMan.TryGetComponent(Owner, out FoldableComponent? foldable) && !foldable.IsFolded; - } - } - - if (!allowedToEat) + if (!CanFit(entity)) continue; // finally, AddToContents - if (!AddToContents(entity)) continue; @@ -292,6 +251,48 @@ namespace Content.Server.Storage.Components LastInternalOpenAttempt = default; } + public virtual bool CanFit(EntityUid entity) + { + // conditions are complicated because of pizzabox-related issues, so follow this guide + // 0. Accomplish your goals at all costs. + // 1. AddToContents can block anything + // 2. maximum item count can block anything + // 3. ghosts can NEVER be eaten + // 4. items can always be eaten unless a previous law prevents it + // 5. if this is NOT AN ITEM, then mobs can always be eaten unless unless a previous law prevents it + // 6. if this is an item, then mobs must only be eaten if some other component prevents pick-up interactions while a mob is inside (e.g. foldable) + + // Let's not insert admin ghosts, yeah? This is really a a hack and should be replaced by attempt events + if (_entMan.HasComponent(entity)) + return false; + + // checks + + var targetIsItem = _entMan.HasComponent(entity); + var targetIsMob = _entMan.HasComponent(entity); + var storageIsItem = _entMan.HasComponent(Owner); + + var allowedToEat = targetIsItem; + + // BEFORE REPLACING THIS WITH, I.E. A PROPERTY: + // Make absolutely 100% sure you have worked out how to stop people ending up in backpacks. + // Seriously, it is insanely hacky and weird to get someone out of a backpack once they end up in there. + // And to be clear, they should NOT be in there. + // For the record, what you need to do is empty the backpack onto a PlacableSurface (table, rack) + if (targetIsMob) + { + if (!storageIsItem) + allowedToEat = true; + else + { + // make an exception if this is a foldable-item that is currently un-folded (e.g., body bags). + allowedToEat = _entMan.TryGetComponent(Owner, out FoldableComponent? foldable) && !foldable.IsFolded; + } + } + + return allowedToEat; + } + protected virtual void OpenStorage() { Open = true; diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactComponent.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactComponent.cs index 06f1816326..17e23c4e81 100644 --- a/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactComponent.cs +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactComponent.cs @@ -28,5 +28,12 @@ public sealed class ArtifactComponent : Component [ViewVariables(VVAccess.ReadWrite)] public double CooldownTime = 10; + /// + /// Is this artifact under some suppression device? + /// If true, will ignore all trigger activations attempts. + /// + [ViewVariables(VVAccess.ReadWrite)] + public bool IsSuppressed; + public TimeSpan LastActivationTime; } diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.cs index a5ed618d1c..365e13d81f 100644 --- a/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.cs +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.cs @@ -49,6 +49,10 @@ public sealed class ArtifactSystem : EntitySystem if (!Resolve(uid, ref component)) return false; + // check if artifact is under suppression field + if (component.IsSuppressed) + return false; + // check if artifact isn't under cooldown var timeDif = _gameTiming.CurTime - component.LastActivationTime; if (timeDif.TotalSeconds < component.CooldownTime) diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/Equipment/Components/SuppressArtifactContainerComponent.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/Equipment/Components/SuppressArtifactContainerComponent.cs new file mode 100644 index 0000000000..fddcf44438 --- /dev/null +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/Equipment/Components/SuppressArtifactContainerComponent.cs @@ -0,0 +1,10 @@ +namespace Content.Server.Xenoarchaeology.XenoArtifacts.Equipment.Components; + +/// +/// Suppress artifact activation, when entity is placed inside this container. +/// +[RegisterComponent] +public sealed class SuppressArtifactContainerComponent : Component +{ + +} diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/Equipment/Systems/SuppressArtifactContainerSystem.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/Equipment/Systems/SuppressArtifactContainerSystem.cs new file mode 100644 index 0000000000..3015b6c11a --- /dev/null +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/Equipment/Systems/SuppressArtifactContainerSystem.cs @@ -0,0 +1,30 @@ +using Content.Server.Xenoarchaeology.XenoArtifacts.Equipment.Components; +using Robust.Shared.Containers; + +namespace Content.Server.Xenoarchaeology.XenoArtifacts.Equipment.Systems; + +public sealed class SuppressArtifactContainerSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnInserted); + SubscribeLocalEvent(OnRemoved); + } + + private void OnInserted(EntityUid uid, SuppressArtifactContainerComponent component, EntInsertedIntoContainerMessage args) + { + if (!TryComp(args.Entity, out ArtifactComponent? artifact)) + return; + + artifact.IsSuppressed = true; + } + + private void OnRemoved(EntityUid uid, SuppressArtifactContainerComponent component, EntRemovedFromContainerMessage args) + { + if (!TryComp(args.Entity, out ArtifactComponent? artifact)) + return; + + artifact.IsSuppressed = false; + } +} diff --git a/Resources/Prototypes/Catalog/Cargo/cargo_science.yml b/Resources/Prototypes/Catalog/Cargo/cargo_science.yml index e69de29bb2..3c10051e62 100644 --- a/Resources/Prototypes/Catalog/Cargo/cargo_science.yml +++ b/Resources/Prototypes/Catalog/Cargo/cargo_science.yml @@ -0,0 +1,11 @@ +- type: cargoProduct + name: "Artifact Container" + id: ArtifactContainer + description: Used to safely contain and move artifacts. + icon: + sprite: Structures/Storage/Crates/artifact.rsi + state: artifact_container_icon + product: CrateArtifactContainer + cost: 2000 + category: Science + group: market diff --git a/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml b/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml index 8f8bfdf7b5..d250376306 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml @@ -162,6 +162,7 @@ - AtmosphericsOxygen - AtmosphericsNitrogen - AtmosphericsCarbonDioxide + - ArtifactContainer - type: CrewMonitoringConsole snap: false precision: 3 diff --git a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifact_equipment.yml b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifact_equipment.yml new file mode 100644 index 0000000000..82d7eeac12 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifact_equipment.yml @@ -0,0 +1,70 @@ +- type: entity + id: CrateArtifactContainer + name: artifact container + description: Used to safely contain and move artifacts. + parent: BaseStructureDynamic + components: + - type: Transform + noRot: true + - type: AccessReader + access: [["Research"], ["Salvage"]] + - type: Lock + - type: Sprite + drawdepth: Objects + netsync: false + sprite: Structures/Storage/Crates/artifact.rsi + layers: + - state: artifact_container + - state: artifact_container_door + map: ["enum.StorageVisualLayers.Door"] + - state: welded + visible: false + map: ["enum.StorageVisualLayers.Welded"] + - state: locked + map: ["enum.StorageVisualLayers.Lock"] + shader: unshaded + - type: InteractionOutline + - type: Physics + - type: Fixtures + fixtures: + - shape: + !type:PhysShapeCircle + radius: 0.45 + mass: 150 + mask: + - Impassable + layer: + - Opaque + - MobImpassable + - SmallImpassable + - type: Icon + sprite: Structures/Storage/Crates/artifact.rsi + state: artifact_container_icon + - type: ArtifactStorage + Capacity: 1 + CanWeldShut: true + - type: SuppressArtifactContainer + - type: PlaceableSurface + - type: Damageable + damageContainer: Inorganic + damageModifierSet: Metallic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - type: PaperLabel + labelSlot: + insertVerbText: Attach Label + ejectVerbText: Remove Label + whitelist: + components: + - Paper + - type: Appearance + visuals: + - type: StorageVisualizer + state_open: artifact_container_open + state_closed: artifact_container_door diff --git a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifacts.yml b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifacts.yml index fdcc689656..97e651d4bd 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifacts.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifacts.yml @@ -6,6 +6,7 @@ abstract: true components: - type: Sprite + drawdepth: SmallObjects sprite: Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi netsync: false state: ano01 diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml index f265df3597..58f5922e33 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml @@ -412,6 +412,7 @@ - AtmosphericsOxygen - AtmosphericsNitrogen - AtmosphericsCarbonDioxide + - ArtifactContainer # - AtmosphericsWaterVapor # - AtmosphericsPlasma # - AtmosphericsTritium diff --git a/Resources/Textures/Structures/Storage/Crates/artifact.rsi/artifact_container.png b/Resources/Textures/Structures/Storage/Crates/artifact.rsi/artifact_container.png new file mode 100644 index 0000000000000000000000000000000000000000..124d7c3321a7b53f5a24c960d9384d5efaec6a74 GIT binary patch literal 494 zcmV(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ-bV)=(RCwC#SFvitFc3Ydf>Mf8nlI6i!5*_Dp85&RT*%TdFr5mW4W6A($mDeC zC=VX|B`J+5rO?D(EL({zh0KfTJDn{Al~LC(!Jy@7f&c&r2lqyv5nz@v zn2e_Y0A-#g2vgTDE61KiVel&;8ZNc-lkpU&>zBA~G71BTv&4{I0BjgCT>)E< z;RW6q1N_)w;8mAptdXGDyuua{I4i$819t}3lCQ1-i`oB#j-07*qoM6N<$f{F0UwEzGB literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Storage/Crates/artifact.rsi/artifact_container_door.png b/Resources/Textures/Structures/Storage/Crates/artifact.rsi/artifact_container_door.png new file mode 100644 index 0000000000000000000000000000000000000000..ad18eb369bdfc027c4973363fde131b6f54bbb30 GIT binary patch literal 393 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?3oVGw3ym^DWNq$1fP z$d`ekN|k}3p_zf<=YJsml7XSrfPvvv0t1893}1{rUgj z{;&g+S{ozVVm^t|11p%_WDjH{JaqiN=)<3nZ+i^PxS5%mo0oQ~-qo?MduG8kpY>S9 z|7VtGb@zXKaPYv=MrnRIgP4xnor>q2^w~2sGz<)Miq!8i-e~I0;NIA=aQ1PR6Q2xt z@4B(Eu}#WMlJzs-U9+ojr=5@U_K6|0vRDNzr>zI_=Vk3|h*E6O7QbN1!n5HC)2?NV zIf@{6e7t|@h)}ktN1oV`siKL`6tA=T9Fbrsu1tKUxu%Afm32o{ieb_zwmpgtIT{Ce z+`_ug8qJXExi#U6P;bcAA2yELPrZbZa?i&PiEPIXw{N`O_F}C_6oWH2 i{~JE(k9(63Fnp=_w(-X+rEkDsWbkzLb6Mw<&;$S>eU<6} literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Storage/Crates/artifact.rsi/artifact_container_icon.png b/Resources/Textures/Structures/Storage/Crates/artifact.rsi/artifact_container_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c5285747a0de7fc4eb5b4f2124093e9729b768dd GIT binary patch literal 575 zcmV-F0>J%=P)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ-#Ysd#RCwCNS3hrpKooy>!O;$mPK=H;F%66^%G8gbvx$qJfOKlo#f5|!KSC$z z(t!cf7{lnuWS7P!HLlX39-eX>2gTzhTgU z1vpp*(C-ZZ0OD}DKv>hw_++>c$F}|jq}i|B`F?Kznr_CJHR;$ExNeKC=;brvt)!!>01P5h%7jfA zkYT(29?k=AAOD)9s1|iRw+6NtLHigN)}oT@KpF5YM%8seRT0SQ0;v&T9mi5@pfnGV z9Tn9gJb*=dnRq@Oe=x@#RZZ5?HW6+RqGFP}ne)IL)55alo`yvkt>{`FDM>qw){O(K z8;ANFs67J6_W}7ny9QV{ma64mH`x&&w^aJ?@~w4pPgpJxs{4BWI{@^{PyTOYUPu4{ N002ovPDHLkV1j_5^j`n~ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Storage/Crates/artifact.rsi/artifact_container_open.png b/Resources/Textures/Structures/Storage/Crates/artifact.rsi/artifact_container_open.png new file mode 100644 index 0000000000000000000000000000000000000000..d7f50625c5bd4a160be1ed30c32b6259050c442e GIT binary patch literal 404 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?3oVGw3ym^DWNq$1fP z$d`ekN|k}3p_zf<=YJsml7XSrfPvvv0t1893}1nQZv* zzR|Nk>Hm~Rn$cpzQ&El9bitDnm{r-UW|e{VY3 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Storage/Crates/artifact.rsi/welded.png b/Resources/Textures/Structures/Storage/Crates/artifact.rsi/welded.png new file mode 100644 index 0000000000000000000000000000000000000000..fce9c8fd94dc17975b98114d44f0b2b70b347ad6 GIT binary patch literal 375 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?3oVGw3ym^DWNq$1fP z$d`ekN|k}3p_zf<=YJsml7XSrfPvvv0t1893erBy;>#jr{q~Gc1n3{&?buCBwPg+h4inJkGQeZ}3iDutLjo zl178M#DhZ{vbWsKW6YSvcK>^IYyNWK?T-x^zF*cXjjflFU|Dl5n_-d0tE*2c_3Wz} zkKgpMzyB!DFPM0C+7Fn{?}R6$unGX^sSn(?T|4r PAQ(Jd{an^LB{Ts5B{`6z literal 0 HcmV?d00001