diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.Actions.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.Actions.cs
new file mode 100644
index 0000000000..3f84fcc6ac
--- /dev/null
+++ b/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.Actions.cs
@@ -0,0 +1,55 @@
+using Content.Server.Actions;
+using Content.Server.Popups;
+using Content.Shared.Actions;
+using Content.Shared.Actions.ActionTypes;
+using Content.Shared.Xenoarchaeology.XenoArtifacts;
+using Robust.Shared.Prototypes;
+
+namespace Content.Server.Xenoarchaeology.XenoArtifacts;
+
+public partial class ArtifactSystem
+{
+ [Dependency] private readonly ActionsSystem _actions = default!;
+ [Dependency] private readonly PopupSystem _popup = default!;
+
+ ///
+ /// Used to add the artifact activation action (hehe), which lets sentient artifacts activate themselves,
+ /// either through admemery or the sentience effect.
+ ///
+ public void InitializeActions()
+ {
+ SubscribeLocalEvent(OnStartup);
+ SubscribeLocalEvent(OnRemove);
+
+ SubscribeLocalEvent(OnSelfActivate);
+ }
+
+ private void OnStartup(EntityUid uid, ArtifactComponent component, ComponentStartup args)
+ {
+ if (_prototype.TryIndex("ArtifactActivate", out var proto))
+ {
+ _actions.AddAction(uid, new InstantAction(proto), null);
+ }
+ }
+
+ private void OnRemove(EntityUid uid, ArtifactComponent component, ComponentRemove args)
+ {
+ if (_prototype.TryIndex("ArtifactActivate", out var proto))
+ {
+ _actions.RemoveAction(uid, new InstantAction(proto));
+ }
+ }
+
+ private void OnSelfActivate(EntityUid uid, ArtifactComponent component, ArtifactSelfActivateEvent args)
+ {
+ if (component.CurrentNode == null)
+ return;
+
+ var curNode = component.CurrentNode.Id;
+ _popup.PopupEntity(Loc.GetString("activate-artifact-popup-self", ("node", curNode)), uid, uid);
+ TryActivateArtifact(uid, uid, component);
+
+ args.Handled = true;
+ }
+}
+
diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.cs
index 340d65a66f..1fd23c10ff 100644
--- a/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.cs
+++ b/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.cs
@@ -29,6 +29,7 @@ public sealed partial class ArtifactSystem : EntitySystem
SubscribeLocalEvent(OnRoundEnd);
InitializeCommands();
+ InitializeActions();
}
private void OnInit(EntityUid uid, ArtifactComponent component, MapInitEvent args)
diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Components/ClearFixturesArtifactComponent.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Components/ClearFixturesArtifactComponent.cs
new file mode 100644
index 0000000000..68ffbfded1
--- /dev/null
+++ b/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Components/ClearFixturesArtifactComponent.cs
@@ -0,0 +1,10 @@
+namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components;
+
+///
+/// Removes the masks/layers of hard fixtures from the artifact when added, allowing it to pass through walls
+/// and such.
+///
+[RegisterComponent]
+public sealed class ClearFixturesArtifactComponent : Component
+{
+}
diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/ClearFixturesArtifactSystem.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/ClearFixturesArtifactSystem.cs
new file mode 100644
index 0000000000..3a90474eeb
--- /dev/null
+++ b/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/ClearFixturesArtifactSystem.cs
@@ -0,0 +1,36 @@
+using Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components;
+using Content.Server.Xenoarchaeology.XenoArtifacts.Events;
+using Content.Shared.Physics;
+using Robust.Shared.Physics;
+using Robust.Shared.Physics.Dynamics;
+
+namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Systems;
+
+///
+/// Handles allowing activated artifacts to phase through walls.
+///
+public sealed class ClearFixturesArtifactSystem : EntitySystem
+{
+ ///
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnActivate);
+ }
+
+ private void OnActivate(EntityUid uid, ClearFixturesArtifactComponent component, ArtifactActivatedEvent args)
+ {
+ if (!TryComp(uid, out var fixtures))
+ return;
+
+ foreach (var (_, fixture) in fixtures.Fixtures)
+ {
+ if (!fixture.Hard)
+ continue;
+
+ fixture.CollisionLayer = (int) CollisionGroup.None;
+ fixture.CollisionMask = (int) CollisionGroup.None;
+ }
+ }
+}
diff --git a/Content.Shared/Xenoarchaeology/XenoArtifacts/SharedArtifact.cs b/Content.Shared/Xenoarchaeology/XenoArtifacts/SharedArtifact.cs
index 917ed6bb97..b8bd1fd520 100644
--- a/Content.Shared/Xenoarchaeology/XenoArtifacts/SharedArtifact.cs
+++ b/Content.Shared/Xenoarchaeology/XenoArtifacts/SharedArtifact.cs
@@ -1,4 +1,5 @@
-using Robust.Shared.Serialization;
+using Content.Shared.Actions;
+using Robust.Shared.Serialization;
namespace Content.Shared.Xenoarchaeology.XenoArtifacts;
@@ -8,3 +9,10 @@ public enum SharedArtifactsVisuals : byte
SpriteIndex,
IsActivated
}
+
+///
+/// Raised as an instant action event when a sentient artifact activates itself using an action.
+///
+public sealed class ArtifactSelfActivateEvent : InstantActionEvent
+{
+}
diff --git a/Resources/Locale/en-US/xenoarchaeology/artifact-hints.ftl b/Resources/Locale/en-US/xenoarchaeology/artifact-hints.ftl
index e0a477ba30..3640c7efdd 100644
--- a/Resources/Locale/en-US/xenoarchaeology/artifact-hints.ftl
+++ b/Resources/Locale/en-US/xenoarchaeology/artifact-hints.ftl
@@ -16,6 +16,8 @@ artifact-effect-hint-storage = Internal chamber
artifact-effect-hint-drill = Serrated rotator
artifact-effect-hint-soap = Lubricated surface
artifact-effect-hint-communication = Long-distance communication
+artifact-effect-hint-fixtures = Structural phasing
+artifact-effect-hint-sentience = Neurological activity
# the triggers should be more obvious than the effects
# gives people an idea of what to do: don't be too specific (i.e. no "welders")
diff --git a/Resources/Locale/en-US/xenoarchaeology/misc-artifact.ftl b/Resources/Locale/en-US/xenoarchaeology/misc-artifact.ftl
index 78b755a083..953d158ab0 100644
--- a/Resources/Locale/en-US/xenoarchaeology/misc-artifact.ftl
+++ b/Resources/Locale/en-US/xenoarchaeology/misc-artifact.ftl
@@ -2,4 +2,9 @@ blink-artifact-popup = The artifact disappeared in an instant!
foam-artifact-popup = Strange foam pours out of the artifact!
shuffle-artifact-popup = You feel yourself teleport instantly!
-charge-artifact-popup = You feel the air buzz with electricity.
\ No newline at end of file
+charge-artifact-popup = You feel the air buzz with electricity.
+
+activate-artifact-action-name = Activate Artifact
+activate-artifact-action-desc = Immediately activates your current artifact node.
+
+activate-artifact-popup-self = You activate node {$node}.
diff --git a/Resources/Prototypes/Actions/types.yml b/Resources/Prototypes/Actions/types.yml
index 244e5fb0af..a5abc600b6 100644
--- a/Resources/Prototypes/Actions/types.yml
+++ b/Resources/Prototypes/Actions/types.yml
@@ -88,6 +88,16 @@
useDelay: 30
event: !type:VendingMachineSelfDispenseEvent
+- type: instantAction
+ id: ArtifactActivate
+ name: activate-artifact-action-name
+ description: activate-artifact-action-desc
+ icon:
+ sprite: Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi
+ state: ano01
+ useDelay: 60
+ event: !type:ArtifactSelfActivateEvent
+
- type: instantAction
id: ToggleBlock
name: action-name-blocking
@@ -125,4 +135,4 @@
description: action-desc-wake
icon: { sprite: Objects/Consumable/Food/egg.rsi, state: icon }
checkCanInteract: false
- event: !type:WakeActionEvent
\ No newline at end of file
+ event: !type:WakeActionEvent
diff --git a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/item_artifacts.yml b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/item_artifacts.yml
index 3667613bdf..c111404fda 100644
--- a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/item_artifacts.yml
+++ b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/item_artifacts.yml
@@ -55,6 +55,7 @@
size: 40
sprite: Objects/Specific/Xenoarchaeology/item_artifacts.rsi
heldPrefix: ano01
+ - type: Actions
- type: entity
parent: BaseXenoArtifactItem
diff --git a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/structure_artifacts.yml b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/structure_artifacts.yml
index 7a43b4b506..f50994e491 100644
--- a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/structure_artifacts.yml
+++ b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/structure_artifacts.yml
@@ -44,6 +44,7 @@
- type: Appearance
- type: StaticPrice
price: 500
+ - type: Actions
- type: entity
parent: BaseXenoArtifact
diff --git a/Resources/Prototypes/XenoArch/Effects/normal_effects.yml b/Resources/Prototypes/XenoArch/Effects/normal_effects.yml
index 5766de0cff..9e1e2a4542 100644
--- a/Resources/Prototypes/XenoArch/Effects/normal_effects.yml
+++ b/Resources/Prototypes/XenoArch/Effects/normal_effects.yml
@@ -420,7 +420,7 @@
- type: artifactEffect
id: EffectMitosis
- targetDepth: 4
+ targetDepth: 3
effectHint: artifact-effect-hint-creation
components:
- type: SpawnArtifact
diff --git a/Resources/Prototypes/XenoArch/Effects/utility_effects.yml b/Resources/Prototypes/XenoArch/Effects/utility_effects.yml
index f5170d08e4..9fbc6a41d4 100644
--- a/Resources/Prototypes/XenoArch/Effects/utility_effects.yml
+++ b/Resources/Prototypes/XenoArch/Effects/utility_effects.yml
@@ -47,6 +47,24 @@
- type: Storage
capacity: 50
+- type: artifactEffect
+ id: EffectClearFixtures
+ targetDepth: 2
+ effectHint: artifact-effect-hint-fixtures
+ permanentComponents:
+ - type: ClearFixturesArtifact
+
+- type: artifactEffect
+ id: EffectWandering
+ targetDepth: 2
+ effectHint: artifact-effect-hint-displacement
+ permanentComponents:
+ - type: RandomWalk
+ minSpeed: 12
+ maxSpeed: 20
+ minStepCooldown: 1
+ maxStepCooldown: 3
+
- type: artifactEffect
id: EffectSolutionStorage
targetDepth: 2
@@ -146,6 +164,23 @@
soundGunshot:
path: /Audio/Weapons/Guns/Gunshots/revolver.ogg
+- type: artifactEffect
+ id: EffectSentience
+ targetDepth: 3
+ effectHint: artifact-effect-hint-sentience
+ permanentComponents:
+ - type: GhostTakeoverAvailable
+ allowMovement: true
+ allowSpeech: true
+ makeSentient: true
+ name: sentient artifact
+ description: |
+ Enact your eldritch whims.
+ Forcibly activate your nodes for good or for evil.
+ - type: MovementSpeedModifier
+ baseWalkSpeed: 0.25
+ baseSprintSpeed: 0.5
+
- type: artifactEffect
id: EffectMultitool
targetDepth: 3