diff --git a/Content.Client/Fax/System/FaxVisualsSystem.cs b/Content.Client/Fax/System/FaxVisualsSystem.cs
new file mode 100644
index 00000000000000..892aec1d95490c
--- /dev/null
+++ b/Content.Client/Fax/System/FaxVisualsSystem.cs
@@ -0,0 +1,48 @@
+using Robust.Client.GameObjects;
+using Content.Shared.Fax.Components;
+using Content.Shared.Fax;
+using Robust.Client.Animations;
+
+namespace Content.Client.Fax.System;
+
+///
+/// Visualizer for the fax machine which displays the correct sprite based on the inserted entity.
+///
+public sealed class FaxVisualsSystem : EntitySystem
+{
+ [Dependency] private readonly AnimationPlayerSystem _player = default!;
+ [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnAppearanceChanged);
+ }
+
+ private void OnAppearanceChanged(EntityUid uid, FaxMachineComponent component, ref AppearanceChangeEvent args)
+ {
+ if (args.Sprite == null)
+ return;
+
+ if (_appearance.TryGetData(uid, FaxMachineVisuals.VisualState, out FaxMachineVisualState visuals) && visuals == FaxMachineVisualState.Inserting)
+ {
+ _player.Play(uid, new Animation()
+ {
+ Length = TimeSpan.FromSeconds(2.4),
+ AnimationTracks =
+ {
+ new AnimationTrackSpriteFlick()
+ {
+ LayerKey = FaxMachineVisuals.VisualState,
+ KeyFrames =
+ {
+ new AnimationTrackSpriteFlick.KeyFrame(component.InsertingState, 0f),
+ new AnimationTrackSpriteFlick.KeyFrame("icon", 2.4f),
+ }
+ }
+ }
+ }, "faxecute");
+ }
+ }
+}
diff --git a/Content.Server/Chemistry/EntitySystems/TransformableContainerSystem.cs b/Content.Server/Chemistry/EntitySystems/TransformableContainerSystem.cs
index 94a3fe2186168a..c375d97b8c3f7e 100644
--- a/Content.Server/Chemistry/EntitySystems/TransformableContainerSystem.cs
+++ b/Content.Server/Chemistry/EntitySystems/TransformableContainerSystem.cs
@@ -20,7 +20,7 @@ public override void Initialize()
SubscribeLocalEvent(OnSolutionChange);
}
- private void OnMapInit(Entity entity, ref MapInitEvent args)
+ private void OnMapInit(Entity entity, ref MapInitEvent args)
{
var meta = MetaData(entity.Owner);
if (string.IsNullOrEmpty(entity.Comp.InitialName))
diff --git a/Content.Server/Fax/AdminUI/AdminFaxEui.cs b/Content.Server/Fax/AdminUI/AdminFaxEui.cs
index c8be6618e45eda..5153e6219565af 100644
--- a/Content.Server/Fax/AdminUI/AdminFaxEui.cs
+++ b/Content.Server/Fax/AdminUI/AdminFaxEui.cs
@@ -1,6 +1,7 @@
using Content.Server.DeviceNetwork.Components;
using Content.Server.EUI;
using Content.Shared.Eui;
+using Content.Shared.Fax.Components;
using Content.Shared.Fax;
using Content.Shared.Follower;
using Content.Shared.Ghost;
diff --git a/Content.Server/Fax/FaxSystem.cs b/Content.Server/Fax/FaxSystem.cs
index f492595444aae5..c21e0db20cc5cf 100644
--- a/Content.Server/Fax/FaxSystem.cs
+++ b/Content.Server/Fax/FaxSystem.cs
@@ -16,7 +16,10 @@
using Content.Shared.Emag.Components;
using Content.Shared.Emag.Systems;
using Content.Shared.Fax;
+using Content.Shared.Fax.Systems;
+using Content.Shared.Fax.Components;
using Content.Shared.Interaction;
+using Content.Shared.Mobs.Components;
using Content.Shared.Paper;
using Robust.Server.GameObjects;
using Robust.Shared.Audio;
@@ -42,6 +45,7 @@ public sealed class FaxSystem : EntitySystem
[Dependency] private readonly UserInterfaceSystem _userInterface = default!;
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly MetaDataSystem _metaData = default!;
+ [Dependency] private readonly FaxecuteSystem _faxecute = default!;
private const string PaperSlotId = "Paper";
@@ -313,12 +317,18 @@ private void OnFileButtonPressed(EntityUid uid, FaxMachineComponent component, F
private void OnCopyButtonPressed(EntityUid uid, FaxMachineComponent component, FaxCopyMessage args)
{
- Copy(uid, component, args);
+ if (HasComp(component.PaperSlot.Item))
+ _faxecute.Faxecute(uid, component); /// when button pressed it will hurt the mob.
+ else
+ Copy(uid, component, args);
}
private void OnSendButtonPressed(EntityUid uid, FaxMachineComponent component, FaxSendMessage args)
{
- Send(uid, component, args.Actor);
+ if (HasComp(component.PaperSlot.Item))
+ _faxecute.Faxecute(uid, component); /// when button pressed it will hurt the mob.
+ else
+ Send(uid, component, args.Actor);
}
private void OnRefreshButtonPressed(EntityUid uid, FaxMachineComponent component, FaxRefreshMessage args)
@@ -336,14 +346,20 @@ private void UpdateAppearance(EntityUid uid, FaxMachineComponent? component = nu
if (!Resolve(uid, ref component))
return;
+ if (TryComp(component.PaperSlot.Item, out var faxable))
+ component.InsertingState = faxable.InsertingState;
+
+
if (component.InsertingTimeRemaining > 0)
+ {
_appearanceSystem.SetData(uid, FaxMachineVisuals.VisualState, FaxMachineVisualState.Inserting);
+ Dirty(uid, component);
+ }
else if (component.PrintingTimeRemaining > 0)
_appearanceSystem.SetData(uid, FaxMachineVisuals.VisualState, FaxMachineVisualState.Printing);
else
_appearanceSystem.SetData(uid, FaxMachineVisuals.VisualState, FaxMachineVisualState.Normal);
}
-
private void UpdateUserInterface(EntityUid uid, FaxMachineComponent? component = null)
{
if (!Resolve(uid, ref component))
@@ -477,7 +493,7 @@ public void Send(EntityUid uid, FaxMachineComponent? component = null, EntityUid
return;
if (!TryComp(sendEntity, out var metadata) ||
- !TryComp(sendEntity, out var paper))
+ !TryComp(sendEntity, out var paper))
return;
var payload = new NetworkPayload()
diff --git a/Content.Server/Nuke/NukeCodePaperSystem.cs b/Content.Server/Nuke/NukeCodePaperSystem.cs
index 8df25feebfabca..c1725536e7cea3 100644
--- a/Content.Server/Nuke/NukeCodePaperSystem.cs
+++ b/Content.Server/Nuke/NukeCodePaperSystem.cs
@@ -1,6 +1,7 @@
using System.Diagnostics.CodeAnalysis;
using Content.Server.Chat.Systems;
using Content.Server.Fax;
+using Content.Shared.Fax.Components;
using Content.Server.Paper;
using Content.Server.Station.Components;
using Content.Server.Station.Systems;
diff --git a/Content.Server/Fax/FaxMachineComponent.cs b/Content.Shared/Fax/Components/FaxMachineComponent.cs
similarity index 84%
rename from Content.Server/Fax/FaxMachineComponent.cs
rename to Content.Shared/Fax/Components/FaxMachineComponent.cs
index d1f269dd37055b..ee9459f5084057 100644
--- a/Content.Server/Fax/FaxMachineComponent.cs
+++ b/Content.Shared/Fax/Components/FaxMachineComponent.cs
@@ -1,12 +1,13 @@
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Paper;
using Robust.Shared.Audio;
+using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
-namespace Content.Server.Fax;
+namespace Content.Shared.Fax.Components;
-[RegisterComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class FaxMachineComponent : Component
{
///
@@ -16,6 +17,13 @@ public sealed partial class FaxMachineComponent : Component
[DataField("name")]
public string FaxName { get; set; } = "Unknown";
+ ///
+ /// Sprite to use when inserting an object.
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField, AutoNetworkedField]
+ public string InsertingState = "inserting";
+
///
/// Device address of fax in network to which data will be send
///
@@ -26,7 +34,7 @@ public sealed partial class FaxMachineComponent : Component
///
/// Contains the item to be sent, assumes it's paper...
///
- [DataField("paperSlot", required: true)]
+ [DataField(required: true)]
public ItemSlot PaperSlot = new();
///
@@ -34,39 +42,39 @@ public sealed partial class FaxMachineComponent : Component
/// This will make it visible to others on the network
///
[ViewVariables(VVAccess.ReadWrite)]
- [DataField("responsePings")]
+ [DataField]
public bool ResponsePings { get; set; } = true;
///
/// Should admins be notified on message receive
///
[ViewVariables(VVAccess.ReadWrite)]
- [DataField("notifyAdmins")]
+ [DataField]
public bool NotifyAdmins { get; set; } = false;
///
/// Should that fax receive nuke codes send by admins. Probably should be captain fax only
///
[ViewVariables(VVAccess.ReadWrite)]
- [DataField("receiveNukeCodes")]
+ [DataField]
public bool ReceiveNukeCodes { get; set; } = false;
///
/// Sound to play when fax has been emagged
///
- [DataField("emagSound")]
+ [DataField]
public SoundSpecifier EmagSound = new SoundCollectionSpecifier("sparks");
///
/// Sound to play when fax printing new message
///
- [DataField("printSound")]
+ [DataField]
public SoundSpecifier PrintSound = new SoundPathSpecifier("/Audio/Machines/printer.ogg");
///
/// Sound to play when fax successfully send message
///
- [DataField("sendSound")]
+ [DataField]
public SoundSpecifier SendSound = new SoundPathSpecifier("/Audio/Machines/high_tech_confirm.ogg");
///
@@ -79,27 +87,27 @@ public sealed partial class FaxMachineComponent : Component
/// Print queue of the incoming message
///
[ViewVariables]
- [DataField("printingQueue")]
+ [DataField]
public Queue PrintingQueue { get; private set; } = new();
///
/// Message sending timeout
///
[ViewVariables]
- [DataField("sendTimeoutRemaining")]
+ [DataField]
public float SendTimeoutRemaining;
///
/// Message sending timeout
///
[ViewVariables]
- [DataField("sendTimeout")]
+ [DataField]
public float SendTimeout = 5f;
///
/// Remaining time of inserting animation
///
- [DataField("insertingTimeRemaining")]
+ [DataField]
public float InsertingTimeRemaining;
///
@@ -111,7 +119,7 @@ public sealed partial class FaxMachineComponent : Component
///
/// Remaining time of printing animation
///
- [DataField("printingTimeRemaining")]
+ [DataField]
public float PrintingTimeRemaining;
///
@@ -124,13 +132,13 @@ public sealed partial class FaxMachineComponent : Component
[DataDefinition]
public sealed partial class FaxPrintout
{
- [DataField("name", required: true)]
+ [DataField(required: true)]
public string Name { get; private set; } = default!;
- [DataField("content", required: true)]
+ [DataField(required: true)]
public string Content { get; private set; } = default!;
- [DataField("prototypeId", customTypeSerializer: typeof(PrototypeIdSerializer), required: true)]
+ [DataField(customTypeSerializer: typeof(PrototypeIdSerializer), required: true)]
public string PrototypeId { get; private set; } = default!;
[DataField("stampState")]
diff --git a/Content.Shared/Fax/Components/FaxableObjectComponent.cs b/Content.Shared/Fax/Components/FaxableObjectComponent.cs
new file mode 100644
index 00000000000000..57b6e610a329d0
--- /dev/null
+++ b/Content.Shared/Fax/Components/FaxableObjectComponent.cs
@@ -0,0 +1,16 @@
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Fax.Components;
+///
+/// Entity with this component can be faxed.
+///
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class FaxableObjectComponent : Component
+{
+ ///
+ /// Sprite to use when inserting an object.
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField, AutoNetworkedField]
+ public string InsertingState = "inserting";
+}
diff --git a/Content.Shared/Fax/Components/FaxecuteComponent.cs b/Content.Shared/Fax/Components/FaxecuteComponent.cs
new file mode 100644
index 00000000000000..9c9bd0302033c0
--- /dev/null
+++ b/Content.Shared/Fax/Components/FaxecuteComponent.cs
@@ -0,0 +1,19 @@
+using Content.Shared.Damage;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Fax.Components;
+
+///
+/// A fax component which stores a damage specifier for attempting to fax a mob.
+///
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class FaxecuteComponent : Component
+{
+
+ ///
+ /// Type of damage dealt when entity is faxecuted.
+ ///
+ [DataField(required: true), AutoNetworkedField]
+ public DamageSpecifier Damage = new();
+}
+
diff --git a/Content.Shared/Fax/DamageOnFaxecuteEvent.cs b/Content.Shared/Fax/DamageOnFaxecuteEvent.cs
new file mode 100644
index 00000000000000..b36f55ab5d2846
--- /dev/null
+++ b/Content.Shared/Fax/DamageOnFaxecuteEvent.cs
@@ -0,0 +1,9 @@
+
+namespace Content.Shared.Fax.Components;
+
+///
+/// Event for killing any mob within the fax machine.
+///
+/// System for handling execution of a mob within fax when copy or send attempt is made.
+///
+public sealed class FaxecuteSystem : EntitySystem
+{
+ [Dependency] private readonly DamageableSystem _damageable = default!;
+ [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ }
+
+ public void Faxecute(EntityUid uid, FaxMachineComponent component, DamageOnFaxecuteEvent? args = null)
+ {
+ var sendEntity = component.PaperSlot.Item;
+ if (sendEntity == null)
+ return;
+
+ if (!TryComp(uid, out var faxecute))
+ return;
+
+ var damageSpec = faxecute.Damage;
+ _damageable.TryChangeDamage(sendEntity, damageSpec);
+ _popupSystem.PopupEntity(Loc.GetString("fax-machine-popup-error", ("target", uid)), uid, PopupType.LargeCaution);
+ return;
+
+ }
+}
diff --git a/Resources/Locale/en-US/fax/fax.ftl b/Resources/Locale/en-US/fax/fax.ftl
index 1f1881a05d6ee9..412f3d7f435304 100644
--- a/Resources/Locale/en-US/fax/fax.ftl
+++ b/Resources/Locale/en-US/fax/fax.ftl
@@ -3,6 +3,8 @@ fax-machine-popup-received = Received correspondence from { $from }.
fax-machine-popup-name-long = Fax name is too long
fax-machine-popup-name-exist = Fax with same name already exist in network
fax-machine-popup-name-set = Fax name has been updated
+fax-machine-popup-error = ERROR - jam in paper feed
+fax-machine-popup-copy-error = ERROR - unable to copy!
fax-machine-dialog-rename = Rename
fax-machine-dialog-field-name = Name
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
index ad5b51d998d1a4..1cf56c29c6aea6 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
@@ -432,6 +432,8 @@
- type: Speech
speechVerb: Moth
speechSounds: Squeak
+ - type: FaxableObject
+ insertingState: inserting_mothroach
- type: MothAccent
- type: Sprite
sprite: Mobs/Animals/mothroach.rsi
@@ -1535,6 +1537,8 @@
rootTask:
task: MouseCompound
- type: Physics
+ - type: FaxableObject
+ insertingState: inserting_mouse
- type: Fixtures
fixtures:
fix1:
@@ -3049,6 +3053,8 @@
- type: Item
size: Tiny
- type: Physics
+ - type: FaxableObject
+ insertingState: inserting_hamster
- type: Fixtures
fixtures:
fix1:
diff --git a/Resources/Prototypes/Entities/Objects/Misc/paper.yml b/Resources/Prototypes/Entities/Objects/Misc/paper.yml
index 08e5e3caafd90a..0c87459164a545 100644
--- a/Resources/Prototypes/Entities/Objects/Misc/paper.yml
+++ b/Resources/Prototypes/Entities/Objects/Misc/paper.yml
@@ -32,6 +32,7 @@
- Trash
- Paper
- type: Appearance
+ - type: FaxableObject
- type: PaperVisuals
- type: Flammable
fireSpread: true
diff --git a/Resources/Prototypes/Entities/Structures/Machines/fax_machine.yml b/Resources/Prototypes/Entities/Structures/Machines/fax_machine.yml
index 583b5e3548a182..36be6451d20947 100644
--- a/Resources/Prototypes/Entities/Structures/Machines/fax_machine.yml
+++ b/Resources/Prototypes/Entities/Structures/Machines/fax_machine.yml
@@ -1,4 +1,4 @@
-- type: entity
+- type: entity
parent: BaseMachinePowered
id: FaxMachineBase
name: long range fax machine
@@ -9,7 +9,7 @@
drawdepth: SmallObjects
layers:
- state: icon
- map: ["base"]
+ map: [ "enum.FaxMachineVisuals.VisualState" ]
- type: Icon
sprite: Structures/Machines/fax_machine.rsi
state: icon
@@ -36,23 +36,27 @@
type: FaxBoundUi
- type: ApcPowerReceiver
powerLoad: 250
+ - type: Faxecute
+ damage:
+ types:
+ Blunt: 100
- type: FaxMachine
paperSlot:
insertSound: /Audio/Machines/scanning.ogg
ejectSound: /Audio/Machines/tray_eject.ogg
whitelist:
components:
- - Paper
+ - FaxableObject #used to be PaperComponent - brainfood1183
- type: GenericVisualizer
visuals:
enum.PowerDeviceVisuals.Powered:
- base:
+ enum.FaxMachineVisuals.VisualState:
True: { state: idle }
False: { state: icon }
enum.FaxMachineVisuals.VisualState:
- base:
- Inserting: { state: inserting }
+ enum.FaxMachineVisuals.VisualState:
Printing: { state: printing }
+ Normal: {state: idle}
- type: ItemSlots
- type: ContainerContainer
containers:
diff --git a/Resources/Textures/Structures/Machines/fax_machine.rsi/inserting_hamster.png b/Resources/Textures/Structures/Machines/fax_machine.rsi/inserting_hamster.png
new file mode 100644
index 00000000000000..5f14e3013fe27a
Binary files /dev/null and b/Resources/Textures/Structures/Machines/fax_machine.rsi/inserting_hamster.png differ
diff --git a/Resources/Textures/Structures/Machines/fax_machine.rsi/inserting_mothroach.png b/Resources/Textures/Structures/Machines/fax_machine.rsi/inserting_mothroach.png
new file mode 100644
index 00000000000000..d034322697ed03
Binary files /dev/null and b/Resources/Textures/Structures/Machines/fax_machine.rsi/inserting_mothroach.png differ
diff --git a/Resources/Textures/Structures/Machines/fax_machine.rsi/inserting_mouse.png b/Resources/Textures/Structures/Machines/fax_machine.rsi/inserting_mouse.png
new file mode 100644
index 00000000000000..7fb87053f3f250
Binary files /dev/null and b/Resources/Textures/Structures/Machines/fax_machine.rsi/inserting_mouse.png differ
diff --git a/Resources/Textures/Structures/Machines/fax_machine.rsi/meta.json b/Resources/Textures/Structures/Machines/fax_machine.rsi/meta.json
index 1a8856301d52af..00681ca6da1de1 100644
--- a/Resources/Textures/Structures/Machines/fax_machine.rsi/meta.json
+++ b/Resources/Textures/Structures/Machines/fax_machine.rsi/meta.json
@@ -40,6 +40,63 @@
]
]
},
+ {
+ "name": "inserting_hamster",
+ "delays": [
+ [
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2
+ ]
+ ]
+ },
+ {
+ "name": "inserting_mothroach",
+ "delays": [
+ [
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2
+ ]
+ ]
+ },
+ {
+ "name": "inserting_mouse",
+ "delays": [
+ [
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2
+ ]
+ ]
+ },
{
"name": "printing",
"delays": [