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